@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,175 @@
1
+ <script lang="ts">
2
+ /**
3
+ * AgentSelector - Agent picker UI
4
+ * Grid/list of available agents with avatars, names, and descriptions.
5
+ * Disabled state for unavailable agents.
6
+ */
7
+ import { useI18n } from '@happyvertical/smrt-ui/i18n';
8
+ import { M } from '../../i18n.js';
9
+ import type { AgentDescriptor } from '../../types.js';
10
+ import Avatar from '../shared/Avatar.svelte';
11
+
12
+ export interface Props {
13
+ /** Available agents */
14
+ agents: AgentDescriptor[];
15
+ /** Select an agent */
16
+ onselect: (agentId: string) => void;
17
+ }
18
+
19
+ const { agents, onselect }: Props = $props();
20
+
21
+ const { t } = useI18n();
22
+ </script>
23
+
24
+ <div class="agent-selector" aria-label={t(M['chat.agent_selector.select_an_agent'])}>
25
+ <h3 class="agent-selector__title">{t(M['chat.agent_selector.title'])}</h3>
26
+
27
+ <div class="agent-selector__grid" role="listbox" aria-label={t(M['chat.agent_selector.available_agents'])}>
28
+ {#each agents as agent (agent.id)}
29
+ <button
30
+ class="agent-selector__card"
31
+ class:agent-selector__card--unavailable={!agent.isAvailable}
32
+ type="button"
33
+ role="option"
34
+ aria-selected={false}
35
+ aria-disabled={!agent.isAvailable}
36
+ disabled={!agent.isAvailable}
37
+ onclick={() => onselect(agent.id)}
38
+ >
39
+ <Avatar
40
+ name={agent.name}
41
+ avatarUrl={agent.avatarUrl}
42
+ size="lg"
43
+ />
44
+
45
+ <div class="agent-selector__card-body">
46
+ <span class="agent-selector__card-name">{agent.name}</span>
47
+ <span class="agent-selector__card-desc">{agent.description}</span>
48
+ </div>
49
+
50
+ {#if !agent.isAvailable}
51
+ <span class="agent-selector__unavailable-badge">Unavailable</span>
52
+ {/if}
53
+ </button>
54
+ {/each}
55
+ </div>
56
+
57
+ {#if agents.length === 0}
58
+ <div class="agent-selector__empty">
59
+ <span class="agent-selector__empty-text">{t(M['chat.agent_selector.empty'])}</span>
60
+ </div>
61
+ {/if}
62
+ </div>
63
+
64
+ <style>
65
+ .agent-selector {
66
+ display: flex;
67
+ flex-direction: column;
68
+ gap: var(--smrt-spacing-4, 16px);
69
+ padding: var(--smrt-spacing-4, 16px);
70
+ }
71
+
72
+ .agent-selector__title {
73
+ font: var(--smrt-typography-title-medium-font, 600 1rem/1.25 sans-serif);
74
+ color: var(--smrt-color-on-surface, #1a1c1e);
75
+ margin: 0;
76
+ }
77
+
78
+ .agent-selector__grid {
79
+ display: grid;
80
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
81
+ gap: var(--smrt-spacing-3, 12px);
82
+ }
83
+
84
+ .agent-selector__card {
85
+ display: flex;
86
+ align-items: flex-start;
87
+ gap: var(--smrt-spacing-3, 12px);
88
+ padding: var(--smrt-spacing-4, 16px);
89
+ background: var(--smrt-color-surface-container-low, #f7f7fb);
90
+ border: 1px solid var(--smrt-color-outline-variant, #c4c6d0);
91
+ border-radius: var(--smrt-radius-large, 12px);
92
+ cursor: pointer;
93
+ text-align: left;
94
+ color: var(--smrt-color-on-surface, #1a1c1e);
95
+ position: relative;
96
+ transition:
97
+ background var(--smrt-duration-short2, 150ms),
98
+ box-shadow var(--smrt-duration-short2, 150ms),
99
+ border-color var(--smrt-duration-short2, 150ms);
100
+ }
101
+
102
+ .agent-selector__card:hover:not(:disabled) {
103
+ background: var(--smrt-color-surface-container, #f0f0f4);
104
+ border-color: var(--smrt-color-primary, #005ac1);
105
+ box-shadow: var(--smrt-elevation-1, 0 1px 3px rgba(0, 0, 0, 0.1));
106
+ }
107
+
108
+ .agent-selector__card:focus-visible {
109
+ outline: 2px solid var(--smrt-color-primary, #005ac1);
110
+ outline-offset: -2px;
111
+ }
112
+
113
+ .agent-selector__card--unavailable {
114
+ opacity: 0.55;
115
+ cursor: not-allowed;
116
+ }
117
+
118
+ .agent-selector__card-body {
119
+ flex: 1;
120
+ display: flex;
121
+ flex-direction: column;
122
+ gap: var(--smrt-spacing-1, 4px);
123
+ min-width: 0;
124
+ }
125
+
126
+ .agent-selector__card-name {
127
+ font: var(--smrt-typography-title-small-font, 600 0.875rem/1.25 sans-serif);
128
+ color: var(--smrt-color-on-surface, #1a1c1e);
129
+ }
130
+
131
+ .agent-selector__card-desc {
132
+ font: var(--smrt-typography-body-small-font, 0.8125rem/1.4 sans-serif);
133
+ color: var(--smrt-color-on-surface-variant, #43474e);
134
+ display: -webkit-box;
135
+ -webkit-line-clamp: 2;
136
+ line-clamp: 2;
137
+ -webkit-box-orient: vertical;
138
+ overflow: hidden;
139
+ }
140
+
141
+ .agent-selector__unavailable-badge {
142
+ position: absolute;
143
+ top: 8px;
144
+ right: 8px;
145
+ font: var(--smrt-typography-label-small-font, 500 0.6875rem/1 sans-serif);
146
+ color: var(--smrt-color-outline, #74777f);
147
+ background: var(--smrt-color-surface-variant, #e1e2ec);
148
+ padding: var(--smrt-spacing-1, 4px) var(--smrt-spacing-2, 8px);
149
+ border-radius: var(--smrt-radius-full, 9999px);
150
+ }
151
+
152
+ .agent-selector__empty {
153
+ display: flex;
154
+ align-items: center;
155
+ justify-content: center;
156
+ padding: var(--smrt-spacing-10, 40px);
157
+ }
158
+
159
+ .agent-selector__empty-text {
160
+ font: var(--smrt-typography-body-medium-font, 0.875rem/1.4 sans-serif);
161
+ color: var(--smrt-color-outline, #74777f);
162
+ }
163
+
164
+ @media (max-width: 480px) {
165
+ .agent-selector__grid {
166
+ grid-template-columns: 1fr;
167
+ }
168
+ }
169
+
170
+ @media (prefers-reduced-motion: reduce) {
171
+ .agent-selector__card {
172
+ transition: none;
173
+ }
174
+ }
175
+ </style>
@@ -0,0 +1,11 @@
1
+ import type { AgentDescriptor } from '../../types.js';
2
+ export interface Props {
3
+ /** Available agents */
4
+ agents: AgentDescriptor[];
5
+ /** Select an agent */
6
+ onselect: (agentId: string) => void;
7
+ }
8
+ declare const AgentSelector: import("svelte").Component<Props, {}, "">;
9
+ type AgentSelector = ReturnType<typeof AgentSelector>;
10
+ export default AgentSelector;
11
+ //# sourceMappingURL=AgentSelector.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentSelector.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/agent/AgentSelector.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAItD,MAAM,WAAW,KAAK;IACpB,uBAAuB;IACvB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,sBAAsB;IACtB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AA6CD,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -0,0 +1,322 @@
1
+ <script lang="ts">
2
+ /**
3
+ * AgentSessionPanel - Session management sidebar
4
+ * Lists past agent sessions with status, message count, and allowed tools.
5
+ * Allows selecting an existing session or creating a new one.
6
+ */
7
+ import { useI18n } from '@happyvertical/smrt-ui/i18n';
8
+ import { M } from '../../i18n.js';
9
+ import type { AgentSessionData } from '../../types.js';
10
+ import Avatar from '../shared/Avatar.svelte';
11
+
12
+ const { t } = useI18n();
13
+
14
+ export interface Props {
15
+ /** Available sessions */
16
+ sessions: AgentSessionData[];
17
+ /** Currently active session ID */
18
+ currentSessionId?: string;
19
+ /** Select a session */
20
+ onselectsession: (sessionId: string) => void;
21
+ /** Create a new session */
22
+ onnewsession?: () => void;
23
+ }
24
+
25
+ const { sessions, currentSessionId, onselectsession, onnewsession }: Props =
26
+ $props();
27
+
28
+ function formatDate(date: string | Date): string {
29
+ const d = typeof date === 'string' ? new Date(date) : date;
30
+ const now = new Date();
31
+ const isToday = d.toDateString() === now.toDateString();
32
+ if (isToday) {
33
+ return d.toLocaleTimeString('en-US', {
34
+ hour: 'numeric',
35
+ minute: '2-digit',
36
+ });
37
+ }
38
+ return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
39
+ }
40
+
41
+ const statusLabel: Record<string, string> = {
42
+ active: 'Active',
43
+ closed: 'Closed',
44
+ expired: 'Expired',
45
+ };
46
+ </script>
47
+
48
+ <aside class="session-panel" aria-label={t(M['chat.agent_session_panel.sessions'])}>
49
+ <div class="session-panel__header">
50
+ <h2 class="session-panel__title">Sessions</h2>
51
+ {#if onnewsession}
52
+ <button
53
+ class="session-panel__new-btn"
54
+ type="button"
55
+ onclick={onnewsession}
56
+ aria-label={t(M['chat.agent_session_panel.new_session'])}
57
+ title={t(M['chat.agent_session_panel.new_session'])}
58
+ >
59
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
60
+ <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />
61
+ </svg>
62
+ </button>
63
+ {/if}
64
+ </div>
65
+
66
+ <div class="session-panel__list" role="listbox" aria-label={t(M['chat.agent_session_panel.session_list'])}>
67
+ {#each sessions as session (session.id)}
68
+ {@const isCurrent = session.id === currentSessionId}
69
+ <button
70
+ class="session-panel__item"
71
+ class:session-panel__item--active={isCurrent}
72
+ type="button"
73
+ role="option"
74
+ aria-selected={isCurrent}
75
+ onclick={() => onselectsession(session.id)}
76
+ >
77
+ <Avatar
78
+ name={session.agentName}
79
+ avatarUrl={session.agentAvatarUrl}
80
+ size="sm"
81
+ />
82
+
83
+ <div class="session-panel__item-body">
84
+ <div class="session-panel__item-header">
85
+ <span class="session-panel__item-name">{session.agentName}</span>
86
+ <time class="session-panel__item-date">
87
+ {formatDate(session.createdAt)}
88
+ </time>
89
+ </div>
90
+
91
+ <div class="session-panel__item-meta">
92
+ <span
93
+ class="session-panel__item-status"
94
+ class:session-panel__item-status--active={session.status === 'active'}
95
+ class:session-panel__item-status--closed={session.status === 'closed'}
96
+ class:session-panel__item-status--expired={session.status === 'expired'}
97
+ >
98
+ {statusLabel[session.status] ?? session.status}
99
+ </span>
100
+ <span class="session-panel__item-count">
101
+ {session.messageCount} msg{session.messageCount !== 1 ? 's' : ''}
102
+ </span>
103
+ </div>
104
+
105
+ {#if session.allowedTools.length > 0}
106
+ <div class="session-panel__item-tools">
107
+ {#each session.allowedTools.slice(0, 3) as tool}
108
+ <span class="session-panel__tool-chip">{tool}</span>
109
+ {/each}
110
+ {#if session.allowedTools.length > 3}
111
+ <span class="session-panel__tool-chip session-panel__tool-chip--more">
112
+ +{session.allowedTools.length - 3}
113
+ </span>
114
+ {/if}
115
+ </div>
116
+ {/if}
117
+ </div>
118
+ </button>
119
+ {/each}
120
+
121
+ {#if sessions.length === 0}
122
+ <div class="session-panel__empty">
123
+ <span class="session-panel__empty-text">{t(M['chat.agent_session_panel.empty'])}</span>
124
+ </div>
125
+ {/if}
126
+ </div>
127
+ </aside>
128
+
129
+ <style>
130
+ .session-panel {
131
+ display: flex;
132
+ flex-direction: column;
133
+ height: 100%;
134
+ width: 280px;
135
+ background: var(--smrt-color-surface-container, #f0f0f4);
136
+ border-right: 1px solid var(--smrt-color-outline-variant, #c4c6d0);
137
+ overflow: hidden;
138
+ }
139
+
140
+ .session-panel__header {
141
+ display: flex;
142
+ align-items: center;
143
+ justify-content: space-between;
144
+ padding: var(--smrt-spacing-4, 16px);
145
+ border-bottom: 1px solid var(--smrt-color-outline-variant, #c4c6d0);
146
+ flex-shrink: 0;
147
+ }
148
+
149
+ .session-panel__title {
150
+ font: var(--smrt-typography-title-medium-font, 600 1rem/1.25 sans-serif);
151
+ color: var(--smrt-color-on-surface, #1a1c1e);
152
+ margin: 0;
153
+ }
154
+
155
+ .session-panel__new-btn {
156
+ display: inline-flex;
157
+ align-items: center;
158
+ justify-content: center;
159
+ width: 36px;
160
+ height: 36px;
161
+ border: none;
162
+ background: var(--smrt-color-primary, #005ac1);
163
+ color: var(--smrt-color-on-primary, #ffffff);
164
+ border-radius: var(--smrt-radius-full, 9999px);
165
+ cursor: pointer;
166
+ transition: opacity var(--smrt-duration-short2, 150ms);
167
+ }
168
+
169
+ .session-panel__new-btn:hover {
170
+ opacity: 0.85;
171
+ }
172
+
173
+ .session-panel__new-btn:focus-visible {
174
+ outline: 2px solid var(--smrt-color-primary, #005ac1);
175
+ outline-offset: 2px;
176
+ }
177
+
178
+ .session-panel__list {
179
+ flex: 1;
180
+ overflow-y: auto;
181
+ padding: var(--smrt-spacing-2, 8px);
182
+ display: flex;
183
+ flex-direction: column;
184
+ gap: var(--smrt-spacing-1, 4px);
185
+ }
186
+
187
+ .session-panel__item {
188
+ display: flex;
189
+ align-items: flex-start;
190
+ gap: var(--smrt-spacing-3, 12px);
191
+ width: 100%;
192
+ padding: var(--smrt-spacing-3, 12px);
193
+ border: none;
194
+ background: transparent;
195
+ border-radius: var(--smrt-radius-medium, 8px);
196
+ cursor: pointer;
197
+ text-align: left;
198
+ color: var(--smrt-color-on-surface, #1a1c1e);
199
+ transition: background var(--smrt-duration-short2, 150ms);
200
+ }
201
+
202
+ .session-panel__item:hover {
203
+ background: var(--smrt-color-surface-container-high, #e6e6ea);
204
+ }
205
+
206
+ .session-panel__item--active {
207
+ background: var(--smrt-color-secondary-container, #d7e3f7);
208
+ }
209
+
210
+ .session-panel__item--active:hover {
211
+ background: var(--smrt-color-secondary-container, #d7e3f7);
212
+ }
213
+
214
+ .session-panel__item:focus-visible {
215
+ outline: 2px solid var(--smrt-color-primary, #005ac1);
216
+ outline-offset: -2px;
217
+ }
218
+
219
+ .session-panel__item-body {
220
+ flex: 1;
221
+ display: flex;
222
+ flex-direction: column;
223
+ gap: var(--smrt-spacing-1, 4px);
224
+ min-width: 0;
225
+ }
226
+
227
+ .session-panel__item-header {
228
+ display: flex;
229
+ align-items: center;
230
+ justify-content: space-between;
231
+ gap: var(--smrt-spacing-2, 8px);
232
+ }
233
+
234
+ .session-panel__item-name {
235
+ font: var(--smrt-typography-label-large-font, 500 0.875rem/1.25 sans-serif);
236
+ white-space: nowrap;
237
+ overflow: hidden;
238
+ text-overflow: ellipsis;
239
+ }
240
+
241
+ .session-panel__item-date {
242
+ font: var(--smrt-typography-label-small-font, 500 0.6875rem/1 sans-serif);
243
+ color: var(--smrt-color-outline, #74777f);
244
+ flex-shrink: 0;
245
+ }
246
+
247
+ .session-panel__item-meta {
248
+ display: flex;
249
+ align-items: center;
250
+ gap: var(--smrt-spacing-2, 8px);
251
+ }
252
+
253
+ .session-panel__item-status {
254
+ font: var(--smrt-typography-label-small-font, 500 0.6875rem/1 sans-serif);
255
+ padding: var(--smrt-spacing-1, 4px) var(--smrt-spacing-2, 8px);
256
+ border-radius: var(--smrt-radius-full, 9999px);
257
+ background: var(--smrt-color-surface-variant, #e1e2ec);
258
+ color: var(--smrt-color-on-surface-variant, #43474e);
259
+ }
260
+
261
+ .session-panel__item-status--active {
262
+ background: var(--smrt-color-success-container, #e8f5e9);
263
+ color: var(--smrt-color-on-success-container, #2e7d32);
264
+ }
265
+
266
+ .session-panel__item-status--closed {
267
+ background: var(--smrt-color-surface-variant, #e1e2ec);
268
+ color: var(--smrt-color-on-surface-variant, #43474e);
269
+ }
270
+
271
+ .session-panel__item-status--expired {
272
+ background: var(--smrt-color-error-container, #ffdad6);
273
+ color: var(--smrt-color-on-error-container, #410002);
274
+ }
275
+
276
+ .session-panel__item-count {
277
+ font: var(--smrt-typography-label-small-font, 500 0.6875rem/1 sans-serif);
278
+ color: var(--smrt-color-outline, #74777f);
279
+ }
280
+
281
+ .session-panel__item-tools {
282
+ display: flex;
283
+ flex-wrap: wrap;
284
+ gap: var(--smrt-spacing-1, 4px);
285
+ margin-top: var(--smrt-spacing-1, 4px);
286
+ }
287
+
288
+ .session-panel__tool-chip {
289
+ font-size: var(--smrt-typography-label-small-size, 0.625rem);
290
+ font-weight: var(--smrt-typography-weight-medium, 500);
291
+ padding: var(--smrt-spacing-1, 4px) var(--smrt-spacing-2, 8px);
292
+ border-radius: var(--smrt-radius-small, 4px);
293
+ background: var(--smrt-color-surface-container-highest, #dddde1);
294
+ color: var(--smrt-color-on-surface-variant, #43474e);
295
+ white-space: nowrap;
296
+ }
297
+
298
+ .session-panel__tool-chip--more {
299
+ background: var(--smrt-color-primary-container, #d6e3ff);
300
+ color: var(--smrt-color-on-primary-container, #001a41);
301
+ }
302
+
303
+ .session-panel__empty {
304
+ display: flex;
305
+ align-items: center;
306
+ justify-content: center;
307
+ height: 100%;
308
+ min-height: 80px;
309
+ }
310
+
311
+ .session-panel__empty-text {
312
+ font: var(--smrt-typography-body-small-font, 0.8125rem/1.4 sans-serif);
313
+ color: var(--smrt-color-outline, #74777f);
314
+ }
315
+
316
+ @media (prefers-reduced-motion: reduce) {
317
+ .session-panel__item,
318
+ .session-panel__new-btn {
319
+ transition: none;
320
+ }
321
+ }
322
+ </style>
@@ -0,0 +1,15 @@
1
+ import type { AgentSessionData } from '../../types.js';
2
+ export interface Props {
3
+ /** Available sessions */
4
+ sessions: AgentSessionData[];
5
+ /** Currently active session ID */
6
+ currentSessionId?: string;
7
+ /** Select a session */
8
+ onselectsession: (sessionId: string) => void;
9
+ /** Create a new session */
10
+ onnewsession?: () => void;
11
+ }
12
+ declare const AgentSessionPanel: import("svelte").Component<Props, {}, "">;
13
+ type AgentSessionPanel = ReturnType<typeof AgentSessionPanel>;
14
+ export default AgentSessionPanel;
15
+ //# sourceMappingURL=AgentSessionPanel.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentSessionPanel.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/agent/AgentSessionPanel.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIvD,MAAM,WAAW,KAAK;IACpB,yBAAyB;IACzB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,kCAAkC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uBAAuB;IACvB,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,2BAA2B;IAC3B,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAiGD,QAAA,MAAM,iBAAiB,2CAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}