@happyvertical/smrt-chat 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/AGENTS.md +35 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/README.md +163 -0
  5. package/dist/__smrt-register__.d.ts +2 -0
  6. package/dist/__smrt-register__.d.ts.map +1 -0
  7. package/dist/chunks/ChatService-Dpzc1Pa5.js +2044 -0
  8. package/dist/chunks/ChatService-Dpzc1Pa5.js.map +1 -0
  9. package/dist/collections/AgentSessionCollection.d.ts +57 -0
  10. package/dist/collections/AgentSessionCollection.d.ts.map +1 -0
  11. package/dist/collections/ChatMessageCollection.d.ts +79 -0
  12. package/dist/collections/ChatMessageCollection.d.ts.map +1 -0
  13. package/dist/collections/ChatParticipantCollection.d.ts +26 -0
  14. package/dist/collections/ChatParticipantCollection.d.ts.map +1 -0
  15. package/dist/collections/ChatReactionCollection.d.ts +23 -0
  16. package/dist/collections/ChatReactionCollection.d.ts.map +1 -0
  17. package/dist/collections/ChatRoomCollection.d.ts +43 -0
  18. package/dist/collections/ChatRoomCollection.d.ts.map +1 -0
  19. package/dist/collections/ChatThreadCollection.d.ts +9 -0
  20. package/dist/collections/ChatThreadCollection.d.ts.map +1 -0
  21. package/dist/index.d.ts +5 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +18 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/internal/agent-runtime.d.ts +16 -0
  26. package/dist/internal/agent-runtime.d.ts.map +1 -0
  27. package/dist/internal/agent-runtime.js +5 -0
  28. package/dist/internal/agent-runtime.js.map +1 -0
  29. package/dist/manifest.json +2811 -0
  30. package/dist/models/AgentSession.d.ts +70 -0
  31. package/dist/models/AgentSession.d.ts.map +1 -0
  32. package/dist/models/ChatMessage.d.ts +55 -0
  33. package/dist/models/ChatMessage.d.ts.map +1 -0
  34. package/dist/models/ChatParticipant.d.ts +32 -0
  35. package/dist/models/ChatParticipant.d.ts.map +1 -0
  36. package/dist/models/ChatReaction.d.ts +19 -0
  37. package/dist/models/ChatReaction.d.ts.map +1 -0
  38. package/dist/models/ChatRoom.d.ts +44 -0
  39. package/dist/models/ChatRoom.d.ts.map +1 -0
  40. package/dist/models/ChatThread.d.ts +24 -0
  41. package/dist/models/ChatThread.d.ts.map +1 -0
  42. package/dist/models/index.d.ts +7 -0
  43. package/dist/models/index.d.ts.map +1 -0
  44. package/dist/playground.d.ts +2 -0
  45. package/dist/playground.d.ts.map +1 -0
  46. package/dist/playground.js +166 -0
  47. package/dist/playground.js.map +1 -0
  48. package/dist/services/ChatService.d.ts +390 -0
  49. package/dist/services/ChatService.d.ts.map +1 -0
  50. package/dist/services/index.d.ts +2 -0
  51. package/dist/services/index.d.ts.map +1 -0
  52. package/dist/smrt-knowledge.json +1507 -0
  53. package/dist/svelte/components/agent/AgentChat.svelte +542 -0
  54. package/dist/svelte/components/agent/AgentChat.svelte.d.ts +21 -0
  55. package/dist/svelte/components/agent/AgentChat.svelte.d.ts.map +1 -0
  56. package/dist/svelte/components/agent/AgentSelector.svelte +175 -0
  57. package/dist/svelte/components/agent/AgentSelector.svelte.d.ts +11 -0
  58. package/dist/svelte/components/agent/AgentSelector.svelte.d.ts.map +1 -0
  59. package/dist/svelte/components/agent/AgentSessionPanel.svelte +322 -0
  60. package/dist/svelte/components/agent/AgentSessionPanel.svelte.d.ts +15 -0
  61. package/dist/svelte/components/agent/AgentSessionPanel.svelte.d.ts.map +1 -0
  62. package/dist/svelte/components/agent/ToolCallDisplay.svelte +335 -0
  63. package/dist/svelte/components/agent/ToolCallDisplay.svelte.d.ts +9 -0
  64. package/dist/svelte/components/agent/ToolCallDisplay.svelte.d.ts.map +1 -0
  65. package/dist/svelte/components/agent/message-blocks.d.ts +12 -0
  66. package/dist/svelte/components/agent/message-blocks.d.ts.map +1 -0
  67. package/dist/svelte/components/agent/message-blocks.js +41 -0
  68. package/dist/svelte/components/agent/message-blocks.test.js +31 -0
  69. package/dist/svelte/components/dialogs/RoomCreateDialog.svelte +403 -0
  70. package/dist/svelte/components/dialogs/RoomCreateDialog.svelte.d.ts +16 -0
  71. package/dist/svelte/components/dialogs/RoomCreateDialog.svelte.d.ts.map +1 -0
  72. package/dist/svelte/components/dialogs/SearchMessages.svelte +457 -0
  73. package/dist/svelte/components/dialogs/SearchMessages.svelte.d.ts +17 -0
  74. package/dist/svelte/components/dialogs/SearchMessages.svelte.d.ts.map +1 -0
  75. package/dist/svelte/components/layout/ChatLayout.svelte +150 -0
  76. package/dist/svelte/components/layout/ChatLayout.svelte.d.ts +18 -0
  77. package/dist/svelte/components/layout/ChatLayout.svelte.d.ts.map +1 -0
  78. package/dist/svelte/components/layout/MemberList.svelte +389 -0
  79. package/dist/svelte/components/layout/MemberList.svelte.d.ts +11 -0
  80. package/dist/svelte/components/layout/MemberList.svelte.d.ts.map +1 -0
  81. package/dist/svelte/components/layout/RoomHeader.svelte +241 -0
  82. package/dist/svelte/components/layout/RoomHeader.svelte.d.ts +15 -0
  83. package/dist/svelte/components/layout/RoomHeader.svelte.d.ts.map +1 -0
  84. package/dist/svelte/components/layout/RoomList.svelte +471 -0
  85. package/dist/svelte/components/layout/RoomList.svelte.d.ts +15 -0
  86. package/dist/svelte/components/layout/RoomList.svelte.d.ts.map +1 -0
  87. package/dist/svelte/components/messages/MessageInput.svelte +232 -0
  88. package/dist/svelte/components/messages/MessageInput.svelte.d.ts +20 -0
  89. package/dist/svelte/components/messages/MessageInput.svelte.d.ts.map +1 -0
  90. package/dist/svelte/components/messages/MessageItem.svelte +431 -0
  91. package/dist/svelte/components/messages/MessageItem.svelte.d.ts +19 -0
  92. package/dist/svelte/components/messages/MessageItem.svelte.d.ts.map +1 -0
  93. package/dist/svelte/components/messages/MessageList.svelte +129 -0
  94. package/dist/svelte/components/messages/MessageList.svelte.d.ts +17 -0
  95. package/dist/svelte/components/messages/MessageList.svelte.d.ts.map +1 -0
  96. package/dist/svelte/components/messages/ThreadPanel.svelte +156 -0
  97. package/dist/svelte/components/messages/ThreadPanel.svelte.d.ts +17 -0
  98. package/dist/svelte/components/messages/ThreadPanel.svelte.d.ts.map +1 -0
  99. package/dist/svelte/components/messages/__tests__/MessageInput.test.js +38 -0
  100. package/dist/svelte/components/shared/Avatar.svelte +30 -0
  101. package/dist/svelte/components/shared/Avatar.svelte.d.ts +14 -0
  102. package/dist/svelte/components/shared/Avatar.svelte.d.ts.map +1 -0
  103. package/dist/svelte/components/shared/FileUpload.svelte +382 -0
  104. package/dist/svelte/components/shared/FileUpload.svelte.d.ts +14 -0
  105. package/dist/svelte/components/shared/FileUpload.svelte.d.ts.map +1 -0
  106. package/dist/svelte/components/shared/LinkPreview.svelte +108 -0
  107. package/dist/svelte/components/shared/LinkPreview.svelte.d.ts +18 -0
  108. package/dist/svelte/components/shared/LinkPreview.svelte.d.ts.map +1 -0
  109. package/dist/svelte/components/shared/MentionAutocomplete.svelte +168 -0
  110. package/dist/svelte/components/shared/MentionAutocomplete.svelte.d.ts +18 -0
  111. package/dist/svelte/components/shared/MentionAutocomplete.svelte.d.ts.map +1 -0
  112. package/dist/svelte/components/shared/MessageBubble.svelte +81 -0
  113. package/dist/svelte/components/shared/MessageBubble.svelte.d.ts +16 -0
  114. package/dist/svelte/components/shared/MessageBubble.svelte.d.ts.map +1 -0
  115. package/dist/svelte/components/shared/ReactionPicker.svelte +103 -0
  116. package/dist/svelte/components/shared/ReactionPicker.svelte.d.ts +10 -0
  117. package/dist/svelte/components/shared/ReactionPicker.svelte.d.ts.map +1 -0
  118. package/dist/svelte/components/shared/ReadReceipts.svelte +127 -0
  119. package/dist/svelte/components/shared/ReadReceipts.svelte.d.ts +13 -0
  120. package/dist/svelte/components/shared/ReadReceipts.svelte.d.ts.map +1 -0
  121. package/dist/svelte/components/shared/TypingIndicator.svelte +90 -0
  122. package/dist/svelte/components/shared/TypingIndicator.svelte.d.ts +12 -0
  123. package/dist/svelte/components/shared/TypingIndicator.svelte.d.ts.map +1 -0
  124. package/dist/svelte/components/shared/UserPresence.svelte +65 -0
  125. package/dist/svelte/components/shared/UserPresence.svelte.d.ts +13 -0
  126. package/dist/svelte/components/shared/UserPresence.svelte.d.ts.map +1 -0
  127. package/dist/svelte/components/shared/__tests__/Avatar.test.js +20 -0
  128. package/dist/svelte/components/shared/__tests__/LinkPreview.test.js +29 -0
  129. package/dist/svelte/components/shared/__tests__/MessageBubble.test.js +21 -0
  130. package/dist/svelte/components/shared/__tests__/ReactionPicker.test.js +35 -0
  131. package/dist/svelte/components/shared/__tests__/ReadReceipts.test.js +28 -0
  132. package/dist/svelte/components/shared/__tests__/TypingIndicator.test.js +27 -0
  133. package/dist/svelte/components/shared/__tests__/UserPresence.test.js +23 -0
  134. package/dist/svelte/components/tabs/ChatTab.svelte +240 -0
  135. package/dist/svelte/components/tabs/ChatTab.svelte.d.ts +21 -0
  136. package/dist/svelte/components/tabs/ChatTab.svelte.d.ts.map +1 -0
  137. package/dist/svelte/components/tabs/ChatTabList.svelte +158 -0
  138. package/dist/svelte/components/tabs/ChatTabList.svelte.d.ts +13 -0
  139. package/dist/svelte/components/tabs/ChatTabList.svelte.d.ts.map +1 -0
  140. package/dist/svelte/components/tabs/ChatTabs.svelte +88 -0
  141. package/dist/svelte/components/tabs/ChatTabs.svelte.d.ts +21 -0
  142. package/dist/svelte/components/tabs/ChatTabs.svelte.d.ts.map +1 -0
  143. package/dist/svelte/components/tabs/MiniChat.svelte +253 -0
  144. package/dist/svelte/components/tabs/MiniChat.svelte.d.ts +15 -0
  145. package/dist/svelte/components/tabs/MiniChat.svelte.d.ts.map +1 -0
  146. package/dist/svelte/i18n.d.ts +51 -0
  147. package/dist/svelte/i18n.d.ts.map +1 -0
  148. package/dist/svelte/i18n.js +72 -0
  149. package/dist/svelte/i18n.messages.d.ts +50 -0
  150. package/dist/svelte/i18n.messages.d.ts.map +1 -0
  151. package/dist/svelte/i18n.messages.js +69 -0
  152. package/dist/svelte/index.d.ts +48 -0
  153. package/dist/svelte/index.d.ts.map +1 -0
  154. package/dist/svelte/index.js +117 -0
  155. package/dist/svelte/playground.d.ts +171 -0
  156. package/dist/svelte/playground.d.ts.map +1 -0
  157. package/dist/svelte/playground.js +161 -0
  158. package/dist/svelte/types.d.ts +116 -0
  159. package/dist/svelte/types.d.ts.map +1 -0
  160. package/dist/svelte/types.js +1 -0
  161. package/dist/types.d.ts +99 -0
  162. package/dist/types.d.ts.map +1 -0
  163. package/dist/types.js +2 -0
  164. package/dist/types.js.map +1 -0
  165. package/dist/ui.d.ts +4 -0
  166. package/dist/ui.d.ts.map +1 -0
  167. package/dist/ui.js +92 -0
  168. package/dist/ui.js.map +1 -0
  169. package/package.json +95 -0
@@ -0,0 +1,542 @@
1
+ <script lang="ts">
2
+ /**
3
+ * AgentChat - Full agent conversation interface
4
+ * Shows agent info header, message list with tool call displays, and input bar.
5
+ * Agent messages are styled differently from user messages.
6
+ */
7
+
8
+ import { useI18n } from '@happyvertical/smrt-ui/i18n';
9
+ import { M } from '../../i18n.js';
10
+ import type {
11
+ AgentSessionData,
12
+ ChatMessageData,
13
+ ToolCallDisplayData,
14
+ } from '../../types.js';
15
+ import Avatar from '../shared/Avatar.svelte';
16
+ import { parseAgentMessageBlocks } from './message-blocks.js';
17
+ import ToolCallDisplay from './ToolCallDisplay.svelte';
18
+
19
+ const { t } = useI18n();
20
+
21
+ export interface Props {
22
+ /** Agent session data */
23
+ session: AgentSessionData;
24
+ /** Messages in this conversation */
25
+ messages: ChatMessageData[];
26
+ /** Current user's profile ID */
27
+ currentProfileId: string;
28
+ /** Whether the AI is currently processing */
29
+ loading?: boolean;
30
+ /** Send a message to the agent */
31
+ onsend: (content: string) => void;
32
+ /** Apply suggested markdown edit to host */
33
+ onapplychange?: (content: string) => void;
34
+ /** Close the agent chat */
35
+ onclose?: () => void;
36
+ }
37
+
38
+ const {
39
+ session,
40
+ messages,
41
+ currentProfileId,
42
+ loading = false,
43
+ onsend,
44
+ onapplychange,
45
+ onclose,
46
+ }: Props = $props();
47
+
48
+ let inputValue = $state('');
49
+ let messageContainer: HTMLDivElement | undefined = $state();
50
+
51
+ const isActive = $derived(session.status === 'active');
52
+
53
+ let diffDialogFields = $state<Record<string, string> | null>(null);
54
+ let diffDialog: HTMLDialogElement | undefined = $state();
55
+
56
+ function showDiff(fields: Record<string, string>) {
57
+ diffDialogFields = fields;
58
+ diffDialog?.showModal();
59
+ }
60
+
61
+ function closeDiff() {
62
+ diffDialog?.close();
63
+ diffDialogFields = null;
64
+ }
65
+
66
+ function handleSubmit(event: Event) {
67
+ event.preventDefault();
68
+ const trimmed = inputValue.trim();
69
+ if (!trimmed || !isActive) return;
70
+ onsend(trimmed);
71
+ inputValue = '';
72
+ }
73
+
74
+ function handleKeydown(event: KeyboardEvent) {
75
+ if (event.key === 'Enter' && !event.shiftKey) {
76
+ event.preventDefault();
77
+ handleSubmit(event);
78
+ }
79
+ }
80
+
81
+ function formatTime(date: string | Date): string {
82
+ const d = typeof date === 'string' ? new Date(date) : date;
83
+ return d.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' });
84
+ }
85
+
86
+ $effect(() => {
87
+ if (messages.length && messageContainer) {
88
+ messageContainer.scrollTop = 0;
89
+ }
90
+ });
91
+ </script>
92
+
93
+ <div class="agent-chat" aria-label={t(M['chat.agent_chat.conversation'])}>
94
+ <form class="agent-chat__input-bar" onsubmit={(e) => handleSubmit(e)}>
95
+ {#if !isActive}
96
+ <div class="agent-chat__inactive-notice">
97
+ {t(M['chat.agent_chat.inactive_notice'], { status: session.status })}
98
+ </div>
99
+ {:else}
100
+ <textarea
101
+ class="agent-chat__input"
102
+ placeholder={t(M['chat.agent_chat.input_placeholder'])}
103
+ bind:value={inputValue}
104
+ onkeydown={handleKeydown}
105
+ rows={1}
106
+ disabled={!isActive}
107
+ aria-label={t(M['chat.agent_chat.message_input'])}
108
+ ></textarea>
109
+ <button
110
+ class="agent-chat__send-btn"
111
+ type="submit"
112
+ disabled={!inputValue.trim() || !isActive}
113
+ aria-label={t(M['chat.agent_chat.send_message'])}
114
+ >
115
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
116
+ <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" />
117
+ </svg>
118
+ </button>
119
+ {/if}
120
+ </form>
121
+
122
+ <div
123
+ class="agent-chat__messages"
124
+ bind:this={messageContainer}
125
+ role="log"
126
+ aria-label={t(M['chat.agent_chat.messages'])}
127
+ >
128
+ {#each messages as msg (msg.id)}
129
+ {@const isUser = msg.role === 'user'}
130
+ {@const isToolCall = msg.messageType === 'tool_call' || msg.messageType === 'tool_result'}
131
+
132
+ {#if isToolCall && msg.toolCallData}
133
+ <div class="agent-chat__tool-row">
134
+ <ToolCallDisplay toolCall={msg.toolCallData} />
135
+ </div>
136
+ {:else}
137
+ <div
138
+ class="agent-chat__msg"
139
+ class:agent-chat__msg--user={isUser}
140
+ class:agent-chat__msg--agent={!isUser && !isToolCall}
141
+ class:agent-chat__msg--system={msg.role === 'system'}
142
+ >
143
+ <div class="agent-chat__bubble" class:agent-chat__bubble--user={isUser} class:agent-chat__bubble--agent={!isUser}>
144
+ <div class="agent-chat__msg-content">
145
+ {#if isUser}
146
+ {msg.content}
147
+ {:else}
148
+ {#each parseAgentMessageBlocks(msg.content || '') as block}
149
+ {#if block.type === 'text'}
150
+ <span class="text-block">{block.content}</span>
151
+ {:else if block.type === 'fields'}
152
+ <div class="field-update-block">
153
+ <span class="applied-badge">{t(M['chat.agent_chat.updated_fields'], { count: Object.keys(block.fields).length, plural: Object.keys(block.fields).length !== 1 ? 's' : '' })}</span>
154
+ <button class="diff-btn" type="button" onclick={() => showDiff(block.fields)}>Diff</button>
155
+ </div>
156
+ {:else if block.type === 'markdown'}
157
+ <div class="markdown-block">
158
+ <pre class="markdown-block__content"><code>{block.content}</code></pre>
159
+ {#if onapplychange}
160
+ <button
161
+ class="diff-btn"
162
+ type="button"
163
+ onclick={() => onapplychange(block.content)}
164
+ >
165
+ Apply
166
+ </button>
167
+ {/if}
168
+ </div>
169
+ {/if}
170
+ {/each}
171
+ {/if}
172
+ </div>
173
+ <time class="agent-chat__msg-time">{formatTime(msg.createdAt)}</time>
174
+ </div>
175
+ </div>
176
+ {/if}
177
+ {/each}
178
+
179
+ {#if loading}
180
+ <div class="agent-chat__msg agent-chat__msg--agent">
181
+ <div class="agent-chat__bubble agent-chat__bubble--agent agent-chat__thinking">
182
+ <span class="thinking-dots">
183
+ <span></span><span></span><span></span>
184
+ </span>
185
+ </div>
186
+ </div>
187
+ {/if}
188
+
189
+ {#if messages.length === 0 && !loading}
190
+ <div class="agent-chat__empty">
191
+ <span class="agent-chat__empty-text">{t(M['chat.agent_chat.empty'])}</span>
192
+ </div>
193
+ {/if}
194
+ </div>
195
+ </div>
196
+
197
+ <!-- Diff Modal -->
198
+ <dialog bind:this={diffDialog} class="diff-dialog">
199
+ <div class="diff-dialog__header">
200
+ <h4>{t(M['chat.agent_chat.field_changes'])}</h4>
201
+ <button class="diff-dialog__close" type="button" onclick={closeDiff}>✕</button>
202
+ </div>
203
+ {#if diffDialogFields}
204
+ <div class="diff-dialog__body">
205
+ {#each Object.entries(diffDialogFields) as [field, value]}
206
+ <div class="diff-field">
207
+ <span class="diff-field__name">{field}</span>
208
+ <pre class="diff-field__value">{value}</pre>
209
+ </div>
210
+ {/each}
211
+ </div>
212
+ {/if}
213
+ </dialog>
214
+
215
+ <style>
216
+ .agent-chat {
217
+ display: flex;
218
+ flex-direction: column;
219
+ height: 100%;
220
+ background: var(--smrt-color-surface, #fefbff);
221
+ color: var(--smrt-color-on-surface, #1a1c1e);
222
+ }
223
+
224
+ .agent-chat__messages {
225
+ flex: 1;
226
+ overflow-y: auto;
227
+ padding: var(--smrt-spacing-2, 8px) var(--smrt-spacing-3, 12px);
228
+ display: flex;
229
+ flex-direction: column-reverse;
230
+ gap: var(--smrt-spacing-2, 8px);
231
+ }
232
+
233
+ .agent-chat__msg {
234
+ display: flex;
235
+ max-width: 95%;
236
+ }
237
+
238
+ .agent-chat__msg--user {
239
+ align-self: flex-end;
240
+ }
241
+
242
+ .agent-chat__msg--agent {
243
+ align-self: flex-start;
244
+ }
245
+
246
+ .agent-chat__msg--system {
247
+ align-self: center;
248
+ max-width: 90%;
249
+ }
250
+
251
+ .agent-chat__tool-row {
252
+ width: 100%;
253
+ padding: var(--smrt-spacing-1, 4px) 0;
254
+ }
255
+
256
+ .agent-chat__bubble {
257
+ display: flex;
258
+ flex-direction: column;
259
+ gap: var(--smrt-spacing-1, 4px);
260
+ padding: var(--smrt-spacing-2, 8px) var(--smrt-spacing-3, 12px);
261
+ border-radius: var(--smrt-radius-lg, 12px);
262
+ word-break: break-word;
263
+ font-size: var(--smrt-typography-body-medium-size, 0.8125rem);
264
+ line-height: var(--smrt-typography-body-medium-line-height, 1.45);
265
+ }
266
+
267
+ .agent-chat__bubble--user {
268
+ background: var(--smrt-color-primary-container, #d6e3ff);
269
+ color: var(--smrt-color-on-primary-container, #001a41);
270
+ border-bottom-right-radius: var(--smrt-radius-sm, 4px);
271
+ }
272
+
273
+ .agent-chat__bubble--agent {
274
+ background: var(--smrt-color-surface-container-high, #e6e6ea);
275
+ color: var(--smrt-color-on-surface, #1a1c1e);
276
+ border-bottom-left-radius: var(--smrt-radius-sm, 4px);
277
+ }
278
+
279
+ .agent-chat__msg--system .agent-chat__bubble {
280
+ background: var(--smrt-color-surface-variant, #e1e2ec);
281
+ color: var(--smrt-color-on-surface-variant, #43474e);
282
+ font-style: italic;
283
+ text-align: center;
284
+ }
285
+
286
+ .agent-chat__msg-content {
287
+ white-space: pre-wrap;
288
+ }
289
+
290
+ .agent-chat__msg-time {
291
+ font-size: var(--smrt-typography-label-small-size, 0.5625rem);
292
+ color: var(--smrt-color-outline, #74777f);
293
+ align-self: flex-end;
294
+ line-height: 1;
295
+ }
296
+
297
+ .agent-chat__empty {
298
+ display: flex;
299
+ align-items: center;
300
+ justify-content: center;
301
+ height: 100%;
302
+ min-height: 80px;
303
+ }
304
+
305
+ .agent-chat__empty-text {
306
+ font-size: var(--smrt-typography-body-medium-size, 0.8125rem);
307
+ color: var(--smrt-color-outline, #74777f);
308
+ }
309
+
310
+ .agent-chat__input-bar {
311
+ display: flex;
312
+ align-items: flex-end;
313
+ gap: var(--smrt-spacing-2, 8px);
314
+ padding: var(--smrt-spacing-2, 8px) var(--smrt-spacing-3, 12px);
315
+ background: var(--smrt-color-surface, #fefbff);
316
+ flex-shrink: 0;
317
+ }
318
+
319
+ .agent-chat__inactive-notice {
320
+ flex: 1;
321
+ text-align: center;
322
+ padding: var(--smrt-spacing-2, 8px);
323
+ font-size: var(--smrt-typography-body-small-size, 0.75rem);
324
+ color: var(--smrt-color-outline, #74777f);
325
+ font-style: italic;
326
+ }
327
+
328
+ .agent-chat__input {
329
+ flex: 1;
330
+ border: none;
331
+ border-radius: var(--smrt-radius-md, 8px);
332
+ padding: var(--smrt-spacing-2, 8px) var(--smrt-spacing-3, 12px);
333
+ font-size: var(--smrt-typography-body-medium-size, 0.8125rem);
334
+ line-height: var(--smrt-typography-body-medium-line-height, 1.4);
335
+ color: var(--smrt-color-on-surface, #1a1c1e);
336
+ background: var(--smrt-color-surface-container-low, #f7f7fb);
337
+ resize: none;
338
+ outline: none;
339
+ min-height: 34px;
340
+ max-height: 80px;
341
+ }
342
+
343
+ .agent-chat__input:focus {
344
+ outline: none;
345
+ background: var(--smrt-color-surface-variant, #e1e2ec);
346
+ }
347
+
348
+ .agent-chat__input::placeholder {
349
+ color: var(--smrt-color-outline, #74777f);
350
+ }
351
+
352
+ .agent-chat__send-btn {
353
+ display: inline-flex;
354
+ align-items: center;
355
+ justify-content: center;
356
+ width: 34px;
357
+ height: 34px;
358
+ border: none;
359
+ background: var(--smrt-color-primary, #005ac1);
360
+ color: var(--smrt-color-on-primary, #ffffff);
361
+ border-radius: var(--smrt-radius-full, 9999px);
362
+ cursor: pointer;
363
+ flex-shrink: 0;
364
+ transition: opacity 150ms;
365
+ }
366
+
367
+ .agent-chat__send-btn:disabled {
368
+ opacity: 0.4;
369
+ cursor: not-allowed;
370
+ }
371
+
372
+ .agent-chat__send-btn:not(:disabled):hover {
373
+ opacity: 0.85;
374
+ }
375
+
376
+ .applied-badge {
377
+ display: inline-flex;
378
+ align-items: center;
379
+ padding: var(--smrt-spacing-1, 4px) var(--smrt-spacing-2, 8px);
380
+ font-size: var(--smrt-typography-label-small-size, 0.6875rem);
381
+ font-weight: var(--smrt-typography-weight-semibold, 600);
382
+ color: var(--smrt-color-on-success-container, #16a34a);
383
+ background: var(--smrt-color-success-container, #f0fdf4);
384
+ border: 1px solid var(--smrt-color-success, #bbf7d0);
385
+ border-radius: var(--smrt-radius-full, 9999px);
386
+ }
387
+
388
+ .field-update-block {
389
+ display: flex;
390
+ align-items: center;
391
+ gap: var(--smrt-spacing-2, 8px);
392
+ padding: var(--smrt-spacing-1, 4px) 0;
393
+ }
394
+
395
+ .markdown-block {
396
+ display: flex;
397
+ flex-direction: column;
398
+ gap: var(--smrt-spacing-2, 8px);
399
+ padding: var(--smrt-spacing-1, 4px) 0;
400
+ }
401
+
402
+ .markdown-block__content {
403
+ margin: 0;
404
+ padding: var(--smrt-spacing-3, 12px);
405
+ border-radius: var(--smrt-radius-lg, 12px);
406
+ background: color-mix(in srgb, var(--smrt-color-surface-container-low, #f4f2f6) 85%, white);
407
+ overflow-x: auto;
408
+ white-space: pre-wrap;
409
+ word-break: break-word;
410
+ font-size: var(--smrt-typography-body-medium-size, 0.875rem);
411
+ line-height: var(--smrt-typography-body-medium-line-height, 1.45);
412
+ }
413
+
414
+ .diff-btn {
415
+ padding: var(--smrt-spacing-1, 4px) var(--smrt-spacing-2, 8px);
416
+ font-size: var(--smrt-typography-label-small-size, 0.625rem);
417
+ font-weight: var(--smrt-typography-weight-semibold, 600);
418
+ border: 1px solid var(--smrt-color-outline-variant, #c4c6d0);
419
+ border-radius: var(--smrt-radius-full, 9999px);
420
+ background: none;
421
+ color: var(--smrt-color-on-surface-variant, #43474e);
422
+ cursor: pointer;
423
+ transition: background 0.15s;
424
+ }
425
+
426
+ .diff-btn:hover {
427
+ background: var(--smrt-color-surface-variant, #e1e2ec);
428
+ color: var(--smrt-color-primary, #005ac1);
429
+ }
430
+
431
+ .diff-dialog {
432
+ border: none;
433
+ border-radius: var(--smrt-radius-lg, 12px);
434
+ padding: 0;
435
+ width: min(420px, 90vw);
436
+ max-height: 60vh;
437
+ box-shadow: var(--smrt-elevation-5, 0 8px 32px color-mix(in srgb, var(--smrt-color-shadow) 18%, transparent));
438
+ background: var(--smrt-color-surface, #fefbff);
439
+ color: var(--smrt-color-on-surface, #1a1c1e);
440
+ }
441
+
442
+ .diff-dialog::backdrop {
443
+ background: var(--smrt-color-scrim, rgba(0, 0, 0, 0.3));
444
+ }
445
+
446
+ .diff-dialog__header {
447
+ display: flex;
448
+ align-items: center;
449
+ justify-content: space-between;
450
+ padding: var(--smrt-spacing-3, 12px) var(--smrt-spacing-4, 16px);
451
+ border-bottom: 1px solid var(--smrt-color-outline-variant, #c4c6d0);
452
+ }
453
+
454
+ .diff-dialog__header h4 {
455
+ margin: 0;
456
+ font-size: var(--smrt-typography-title-small-size, 0.875rem);
457
+ font-weight: var(--smrt-typography-weight-semibold, 600);
458
+ }
459
+
460
+ .diff-dialog__close {
461
+ background: none;
462
+ border: none;
463
+ font-size: var(--smrt-typography-body-large-size, 1rem);
464
+ cursor: pointer;
465
+ color: var(--smrt-color-outline, #74777f);
466
+ padding: var(--smrt-spacing-1, 4px) var(--smrt-spacing-2, 8px);
467
+ border-radius: var(--smrt-radius-sm, 4px);
468
+ }
469
+
470
+ .diff-dialog__close:hover {
471
+ background: var(--smrt-color-surface-variant, #e1e2ec);
472
+ }
473
+
474
+ .diff-dialog__body {
475
+ padding: var(--smrt-spacing-3, 12px) var(--smrt-spacing-4, 16px);
476
+ overflow-y: auto;
477
+ max-height: calc(60vh - 60px);
478
+ }
479
+
480
+ .diff-field {
481
+ margin-bottom: var(--smrt-spacing-3, 12px);
482
+ }
483
+
484
+ .diff-field:last-child {
485
+ margin-bottom: 0;
486
+ }
487
+
488
+ .diff-field__name {
489
+ display: block;
490
+ font-size: var(--smrt-typography-label-small-size, 0.6875rem);
491
+ font-weight: var(--smrt-typography-weight-semibold, 600);
492
+ text-transform: uppercase;
493
+ letter-spacing: var(--smrt-typography-label-small-tracking, 0.04em);
494
+ color: var(--smrt-color-outline, #74777f);
495
+ margin-bottom: var(--smrt-spacing-1, 4px);
496
+ }
497
+
498
+ .diff-field__value {
499
+ margin: 0;
500
+ padding: var(--smrt-spacing-2, 8px) var(--smrt-spacing-3, 12px);
501
+ font-size: var(--smrt-typography-body-small-size, 0.75rem);
502
+ line-height: var(--smrt-typography-body-small-line-height, 1.5);
503
+ background: var(--smrt-color-surface-container-low, #f7f7fb);
504
+ border-radius: var(--smrt-radius-md, 8px);
505
+ white-space: pre-wrap;
506
+ word-break: break-word;
507
+ font-family: inherit;
508
+ max-height: 200px;
509
+ overflow-y: auto;
510
+ }
511
+
512
+ .agent-chat__thinking {
513
+ padding: var(--smrt-spacing-3, 12px) var(--smrt-spacing-4, 16px);
514
+ }
515
+
516
+ .thinking-dots {
517
+ display: inline-flex;
518
+ gap: var(--smrt-spacing-1, 4px);
519
+ align-items: center;
520
+ }
521
+
522
+ .thinking-dots span {
523
+ width: 6px;
524
+ height: 6px;
525
+ border-radius: var(--smrt-radius-full, 9999px);
526
+ background: var(--smrt-color-outline, #74777f);
527
+ animation: thinking-bounce 1.2s ease-in-out infinite;
528
+ }
529
+
530
+ .thinking-dots span:nth-child(2) {
531
+ animation-delay: 0.15s;
532
+ }
533
+
534
+ .thinking-dots span:nth-child(3) {
535
+ animation-delay: 0.3s;
536
+ }
537
+
538
+ @keyframes thinking-bounce {
539
+ 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
540
+ 30% { transform: translateY(-4px); opacity: 1; }
541
+ }
542
+ </style>
@@ -0,0 +1,21 @@
1
+ import type { AgentSessionData, ChatMessageData } from '../../types.js';
2
+ export interface Props {
3
+ /** Agent session data */
4
+ session: AgentSessionData;
5
+ /** Messages in this conversation */
6
+ messages: ChatMessageData[];
7
+ /** Current user's profile ID */
8
+ currentProfileId: string;
9
+ /** Whether the AI is currently processing */
10
+ loading?: boolean;
11
+ /** Send a message to the agent */
12
+ onsend: (content: string) => void;
13
+ /** Apply suggested markdown edit to host */
14
+ onapplychange?: (content: string) => void;
15
+ /** Close the agent chat */
16
+ onclose?: () => void;
17
+ }
18
+ declare const AgentChat: import("svelte").Component<Props, {}, "">;
19
+ type AgentChat = ReturnType<typeof AgentChat>;
20
+ export default AgentChat;
21
+ //# sourceMappingURL=AgentChat.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentChat.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/agent/AgentChat.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EAEhB,MAAM,gBAAgB,CAAC;AAMxB,MAAM,WAAW,KAAK;IACpB,yBAAyB;IACzB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,oCAAoC;IACpC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,gCAAgC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kCAAkC;IAClC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,4CAA4C;IAC5C,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,2BAA2B;IAC3B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAwKD,QAAA,MAAM,SAAS,2CAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}