@classic-homes/agent-chat 0.2.0 → 0.3.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 (54) hide show
  1. package/README.md +14 -2
  2. package/dist/body-lock.d.ts +2 -0
  3. package/dist/body-lock.d.ts.map +1 -0
  4. package/dist/body-lock.js +27 -0
  5. package/dist/components/AgentChat.svelte +22 -9
  6. package/dist/components/AgentChat.svelte.d.ts +6 -0
  7. package/dist/components/AgentChat.svelte.d.ts.map +1 -1
  8. package/dist/components/ArtifactChip.svelte +45 -0
  9. package/dist/components/ArtifactChip.svelte.d.ts +14 -0
  10. package/dist/components/ArtifactChip.svelte.d.ts.map +1 -0
  11. package/dist/components/AssistantMessage.svelte +179 -0
  12. package/dist/components/AssistantMessage.svelte.d.ts +25 -0
  13. package/dist/components/AssistantMessage.svelte.d.ts.map +1 -0
  14. package/dist/components/ConversationDialogs.svelte +23 -3
  15. package/dist/components/ConversationDialogs.svelte.d.ts.map +1 -1
  16. package/dist/components/Markdown.svelte +88 -5
  17. package/dist/components/Markdown.svelte.d.ts +10 -1
  18. package/dist/components/Markdown.svelte.d.ts.map +1 -1
  19. package/dist/components/MessageActions.svelte +56 -0
  20. package/dist/components/MessageActions.svelte.d.ts +17 -0
  21. package/dist/components/MessageActions.svelte.d.ts.map +1 -0
  22. package/dist/components/MessageFiles.svelte +83 -0
  23. package/dist/components/MessageFiles.svelte.d.ts +14 -0
  24. package/dist/components/MessageFiles.svelte.d.ts.map +1 -0
  25. package/dist/components/MessageItem.svelte +11 -144
  26. package/dist/components/MessageItem.svelte.d.ts +3 -0
  27. package/dist/components/MessageItem.svelte.d.ts.map +1 -1
  28. package/dist/components/MessageList.svelte +99 -30
  29. package/dist/components/MessageList.svelte.d.ts +1 -0
  30. package/dist/components/MessageList.svelte.d.ts.map +1 -1
  31. package/dist/components/ProposalCard.svelte +39 -0
  32. package/dist/components/ProposalCard.svelte.d.ts +13 -0
  33. package/dist/components/ProposalCard.svelte.d.ts.map +1 -0
  34. package/dist/components/UserMessage.svelte +46 -0
  35. package/dist/components/UserMessage.svelte.d.ts +10 -0
  36. package/dist/components/UserMessage.svelte.d.ts.map +1 -0
  37. package/dist/components/live-fixes.svelte.test.d.ts +2 -0
  38. package/dist/components/live-fixes.svelte.test.d.ts.map +1 -0
  39. package/dist/components/live-fixes.svelte.test.js +127 -0
  40. package/dist/components/messages.svelte.test.d.ts +2 -0
  41. package/dist/components/messages.svelte.test.d.ts.map +1 -0
  42. package/dist/components/messages.svelte.test.js +202 -0
  43. package/dist/index.d.ts +8 -0
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +8 -0
  46. package/dist/markdown.d.ts.map +1 -1
  47. package/dist/markdown.js +12 -4
  48. package/dist/message-format.d.ts +30 -0
  49. package/dist/message-format.d.ts.map +1 -0
  50. package/dist/message-format.js +118 -0
  51. package/dist/session.svelte.d.ts +9 -0
  52. package/dist/session.svelte.d.ts.map +1 -1
  53. package/dist/session.svelte.js +6 -0
  54. package/package.json +3 -3
@@ -0,0 +1,118 @@
1
+ export function formatBytes(n) {
2
+ if (n < 1024)
3
+ return `${n} B`;
4
+ if (n < 1048576)
5
+ return `${Math.round(n / 1024)} KB`;
6
+ return `${(n / 1048576).toFixed(1)} MB`;
7
+ }
8
+ /** "3:42 PM" in the viewer's locale. */
9
+ export function formatTime(ts, locale) {
10
+ return new Date(ts).toLocaleTimeString(locale, { hour: 'numeric', minute: '2-digit' });
11
+ }
12
+ /** Full date and time, for tooltips. */
13
+ export function formatDateTime(ts, locale) {
14
+ return new Date(ts).toLocaleString(locale, {
15
+ weekday: 'short',
16
+ month: 'short',
17
+ day: 'numeric',
18
+ year: 'numeric',
19
+ hour: 'numeric',
20
+ minute: '2-digit',
21
+ });
22
+ }
23
+ function startOfDay(ts) {
24
+ const d = new Date(ts);
25
+ d.setHours(0, 0, 0, 0);
26
+ return d.getTime();
27
+ }
28
+ /** "Today", "Yesterday", or a short date ("Mon, Nov 3"; the year only when it differs). */
29
+ export function formatDay(ts, now = Date.now(), locale) {
30
+ const days = Math.round((startOfDay(now) - startOfDay(ts)) / 86_400_000);
31
+ if (days === 0)
32
+ return 'Today';
33
+ if (days === 1)
34
+ return 'Yesterday';
35
+ const sameYear = new Date(ts).getFullYear() === new Date(now).getFullYear();
36
+ return new Date(ts).toLocaleDateString(locale, {
37
+ weekday: 'short',
38
+ month: 'short',
39
+ day: 'numeric',
40
+ ...(sameYear ? {} : { year: 'numeric' }),
41
+ });
42
+ }
43
+ /** Indexes of messages that start a new calendar day (the first message always does). */
44
+ export function daySeparators(messages) {
45
+ const starts = new Set();
46
+ let previous;
47
+ messages.forEach((m, i) => {
48
+ const day = startOfDay(m.createdAt);
49
+ if (day !== previous)
50
+ starts.add(i);
51
+ previous = day;
52
+ });
53
+ return starts;
54
+ }
55
+ export function artifactIcon(mediaType) {
56
+ switch (mediaType) {
57
+ case 'text/html':
58
+ case 'application/vnd.ant.react':
59
+ return 'layout';
60
+ case 'application/vnd.ant.code':
61
+ return 'file-code';
62
+ case 'application/vnd.ant.mermaid':
63
+ return 'git-branch';
64
+ case 'image/svg+xml':
65
+ return 'image';
66
+ default:
67
+ return 'file-text';
68
+ }
69
+ }
70
+ export function artifactKind(mediaType) {
71
+ switch (mediaType) {
72
+ case 'text/html':
73
+ return 'Page';
74
+ case 'application/vnd.ant.react':
75
+ return 'Interactive';
76
+ case 'application/vnd.ant.code':
77
+ return 'Code';
78
+ case 'application/vnd.ant.mermaid':
79
+ return 'Diagram';
80
+ case 'image/svg+xml':
81
+ return 'Image';
82
+ default:
83
+ return 'Document';
84
+ }
85
+ }
86
+ export function fileIcon(mimeType) {
87
+ if (mimeType.startsWith('image/'))
88
+ return 'image';
89
+ if (mimeType.startsWith('video/'))
90
+ return 'video';
91
+ if (mimeType.startsWith('audio/'))
92
+ return 'music';
93
+ if (/spreadsheet|excel|csv/.test(mimeType))
94
+ return 'table';
95
+ if (/json|javascript|typescript|xml|x-python|x-sh/.test(mimeType))
96
+ return 'file-code';
97
+ if (/pdf|word|document|text\//.test(mimeType))
98
+ return 'file-text';
99
+ return 'file';
100
+ }
101
+ /** Read-only description of a proposed document edit; applying happens in the Office add-in. */
102
+ export function describeProposal(op) {
103
+ switch (op.kind) {
104
+ case 'excel.writeRange':
105
+ return {
106
+ action: op.write.type === 'formulas' ? 'Write formulas' : 'Write values',
107
+ host: 'Excel',
108
+ target: `${op.target.sheet}!${op.target.address}`,
109
+ };
110
+ case 'word.insertText':
111
+ return {
112
+ action: op.location === 'before' ? 'Insert text before' : 'Insert text after',
113
+ host: 'Word',
114
+ };
115
+ case 'word.replaceSelection':
116
+ return { action: 'Replace selection', host: 'Word' };
117
+ }
118
+ }
@@ -13,6 +13,15 @@ export interface ChatSessionOptions {
13
13
  onConversationStarted?: (conversationId: string) => void;
14
14
  onToolResult?: (name: string, status: string) => void;
15
15
  onEvent?: (event: ChatEvent) => void;
16
+ /**
17
+ * A turn stopped streaming (done, error, cancelled or cut short), with its final status.
18
+ * Hosts refresh what the turn may have changed, e.g. the conversation list's running flag.
19
+ */
20
+ onTurnEnd?: (info: {
21
+ requestId: string;
22
+ conversationId: string | null;
23
+ status: string;
24
+ }) => void;
16
25
  }
17
26
  export type SessionStatus = 'idle' | 'loading' | 'streaming';
18
27
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"session.svelte.d.ts","sourceRoot":"","sources":["../src/lib/session.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EACV,QAAQ,EACR,WAAW,EACX,SAAS,EAET,UAAU,EACV,eAAe,EACf,OAAO,EACR,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAKL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,mGAAmG;IACnG,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,eAAe,GAAG,IAAI,GAAG,SAAS,CAAC;IACtD,qBAAqB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,CAAC;AAE7D;;;GAGG;AACH,qBAAa,WAAW;IACtB,QAAQ,gBAA6B;IACrC,MAAM,gBAAiC;IACvC,cAAc,gBAA+B;IAC7C,gGAAgG;IAChG,oBAAoB,gBAA+B;IACnD,IAAI,8BAA8C;IAClD,SAAS,qBAAyC;IAClD,YAAY;;;;;;QAAyB;IAErC,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEjC,OAAO,EAAE,kBAAkB;IAMvC,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,OAAO,IAAI,gBAAgB,GAAG,SAAS,CAG1C;IAED,yFAAyF;IACnF,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA+B3C,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,EAAE,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA0B5E;;;;OAIG;IACG,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ7C,+FAA+F;IACzF,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa9C,MAAM,IAAI,IAAI;YAOA,GAAG;IAmDjB,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,MAAM;CAKf;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAE1E"}
1
+ {"version":3,"file":"session.svelte.d.ts","sourceRoot":"","sources":["../src/lib/session.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EACV,QAAQ,EACR,WAAW,EACX,SAAS,EAET,UAAU,EACV,eAAe,EACf,OAAO,EACR,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAKL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,mGAAmG;IACnG,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,eAAe,GAAG,IAAI,GAAG,SAAS,CAAC;IACtD,qBAAqB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACrC;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAClG;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,CAAC;AAE7D;;;GAGG;AACH,qBAAa,WAAW;IACtB,QAAQ,gBAA6B;IACrC,MAAM,gBAAiC;IACvC,cAAc,gBAA+B;IAC7C,gGAAgG;IAChG,oBAAoB,gBAA+B;IACnD,IAAI,8BAA8C;IAClD,SAAS,qBAAyC;IAClD,YAAY;;;;;;QAAyB;IAErC,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEjC,OAAO,EAAE,kBAAkB;IAMvC,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,OAAO,IAAI,gBAAgB,GAAG,SAAS,CAG1C;IAED,yFAAyF;IACnF,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA+B3C,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,EAAE,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA0B5E;;;;OAIG;IACG,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ7C,+FAA+F;IACzF,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa9C,MAAM,IAAI,IAAI;YAOA,GAAG;IA2DjB,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,MAAM;CAKf;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAE1E"}
@@ -156,6 +156,12 @@ export class ChatSession {
156
156
  finally {
157
157
  this.controller = undefined;
158
158
  this.status = 'idle';
159
+ const final = this.messages.find((m) => m.role === 'assistant' && m.requestId === requestId);
160
+ this.options.onTurnEnd?.({
161
+ requestId,
162
+ conversationId: this.conversationId,
163
+ status: final?.status ?? 'done',
164
+ });
159
165
  }
160
166
  }
161
167
  toolName(requestId, callId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classic-homes/agent-chat",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Svelte 5 chat UI for Classic Agent: session state, message list, composer, tool timeline, artifacts and MCP-UI sandbox frames. Consumed by the Classic App.",
@@ -17,8 +17,8 @@
17
17
  "dist"
18
18
  ],
19
19
  "dependencies": {
20
- "@classic-homes/agent-client": "0.2.0",
21
- "@classic-homes/agent-contracts": "0.2.0",
20
+ "@classic-homes/agent-client": "0.3.0",
21
+ "@classic-homes/agent-contracts": "0.3.0",
22
22
  "dompurify": "3.4.17"
23
23
  },
24
24
  "peerDependencies": {