@agent-native/core 0.19.1 → 0.20.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 (167) hide show
  1. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  2. package/dist/agent/engine/builder-engine.js +12 -1
  3. package/dist/agent/engine/builder-engine.js.map +1 -1
  4. package/dist/agent/production-agent.d.ts.map +1 -1
  5. package/dist/agent/production-agent.js +5 -0
  6. package/dist/agent/production-agent.js.map +1 -1
  7. package/dist/agent/thread-data-builder.d.ts +17 -0
  8. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  9. package/dist/agent/thread-data-builder.js +210 -0
  10. package/dist/agent/thread-data-builder.js.map +1 -1
  11. package/dist/cli/code-agent-executor.d.ts +2 -0
  12. package/dist/cli/code-agent-executor.d.ts.map +1 -1
  13. package/dist/cli/code-agent-executor.js +39 -1
  14. package/dist/cli/code-agent-executor.js.map +1 -1
  15. package/dist/cli/code-agent-runs.d.ts +3 -0
  16. package/dist/cli/code-agent-runs.d.ts.map +1 -1
  17. package/dist/cli/code-agent-runs.js +3 -0
  18. package/dist/cli/code-agent-runs.js.map +1 -1
  19. package/dist/cli/connect.d.ts +3 -2
  20. package/dist/cli/connect.d.ts.map +1 -1
  21. package/dist/cli/connect.js +12 -8
  22. package/dist/cli/connect.js.map +1 -1
  23. package/dist/cli/mcp-config-writers.d.ts +3 -3
  24. package/dist/cli/mcp-config-writers.d.ts.map +1 -1
  25. package/dist/cli/mcp-config-writers.js +19 -8
  26. package/dist/cli/mcp-config-writers.js.map +1 -1
  27. package/dist/client/AgentPanel.d.ts.map +1 -1
  28. package/dist/client/AgentPanel.js +8 -3
  29. package/dist/client/AgentPanel.js.map +1 -1
  30. package/dist/client/AssistantChat.d.ts +58 -0
  31. package/dist/client/AssistantChat.d.ts.map +1 -1
  32. package/dist/client/AssistantChat.js +122 -50
  33. package/dist/client/AssistantChat.js.map +1 -1
  34. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  35. package/dist/client/agent-chat-adapter.js +172 -13
  36. package/dist/client/agent-chat-adapter.js.map +1 -1
  37. package/dist/client/agent-sidebar-state.d.ts +2 -0
  38. package/dist/client/agent-sidebar-state.d.ts.map +1 -1
  39. package/dist/client/agent-sidebar-state.js +32 -0
  40. package/dist/client/agent-sidebar-state.js.map +1 -1
  41. package/dist/client/code-agent-chat-adapter.d.ts +81 -0
  42. package/dist/client/code-agent-chat-adapter.d.ts.map +1 -0
  43. package/dist/client/code-agent-chat-adapter.js +297 -0
  44. package/dist/client/code-agent-chat-adapter.js.map +1 -0
  45. package/dist/client/composer/PromptComposer.d.ts +11 -0
  46. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  47. package/dist/client/composer/PromptComposer.js +7 -3
  48. package/dist/client/composer/PromptComposer.js.map +1 -1
  49. package/dist/client/composer/TiptapComposer.d.ts +12 -1
  50. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  51. package/dist/client/composer/TiptapComposer.js +16 -7
  52. package/dist/client/composer/TiptapComposer.js.map +1 -1
  53. package/dist/client/composer/index.d.ts +1 -0
  54. package/dist/client/composer/index.d.ts.map +1 -1
  55. package/dist/client/composer/index.js +1 -0
  56. package/dist/client/composer/index.js.map +1 -1
  57. package/dist/client/composer/prompt-attachments.d.ts +11 -0
  58. package/dist/client/composer/prompt-attachments.d.ts.map +1 -0
  59. package/dist/client/composer/prompt-attachments.js +45 -0
  60. package/dist/client/composer/prompt-attachments.js.map +1 -0
  61. package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
  62. package/dist/client/conversation/AgentConversation.js +124 -1
  63. package/dist/client/conversation/AgentConversation.js.map +1 -1
  64. package/dist/client/conversation/code-agent-transcript.d.ts +25 -0
  65. package/dist/client/conversation/code-agent-transcript.d.ts.map +1 -0
  66. package/dist/client/conversation/code-agent-transcript.js +200 -0
  67. package/dist/client/conversation/code-agent-transcript.js.map +1 -0
  68. package/dist/client/conversation/index.d.ts +2 -1
  69. package/dist/client/conversation/index.d.ts.map +1 -1
  70. package/dist/client/conversation/index.js +1 -0
  71. package/dist/client/conversation/index.js.map +1 -1
  72. package/dist/client/conversation/types.d.ts +8 -0
  73. package/dist/client/conversation/types.d.ts.map +1 -1
  74. package/dist/client/conversation/types.js.map +1 -1
  75. package/dist/client/conversation/use-near-bottom-autoscroll.d.ts.map +1 -1
  76. package/dist/client/conversation/use-near-bottom-autoscroll.js +26 -9
  77. package/dist/client/conversation/use-near-bottom-autoscroll.js.map +1 -1
  78. package/dist/client/index.d.ts +5 -2
  79. package/dist/client/index.d.ts.map +1 -1
  80. package/dist/client/index.js +5 -2
  81. package/dist/client/index.js.map +1 -1
  82. package/dist/client/settings/useBuilderStatus.d.ts +2 -0
  83. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  84. package/dist/client/settings/useBuilderStatus.js +21 -3
  85. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  86. package/dist/client/settings/useBuilderStatus.spec.js +16 -2
  87. package/dist/client/settings/useBuilderStatus.spec.js.map +1 -1
  88. package/dist/client/sse-event-processor.d.ts.map +1 -1
  89. package/dist/client/sse-event-processor.js +3 -0
  90. package/dist/client/sse-event-processor.js.map +1 -1
  91. package/dist/client/use-chat-models.d.ts +6 -1
  92. package/dist/client/use-chat-models.d.ts.map +1 -1
  93. package/dist/client/use-chat-models.js +7 -3
  94. package/dist/client/use-chat-models.js.map +1 -1
  95. package/dist/client/use-chat-models.spec.d.ts +2 -0
  96. package/dist/client/use-chat-models.spec.d.ts.map +1 -0
  97. package/dist/client/use-chat-models.spec.js +39 -0
  98. package/dist/client/use-chat-models.spec.js.map +1 -0
  99. package/dist/code-agents/background-controller.d.ts.map +1 -1
  100. package/dist/code-agents/background-controller.js +16 -0
  101. package/dist/code-agents/background-controller.js.map +1 -1
  102. package/dist/code-agents/index.d.ts +2 -0
  103. package/dist/code-agents/index.d.ts.map +1 -1
  104. package/dist/code-agents/index.js +2 -0
  105. package/dist/code-agents/index.js.map +1 -1
  106. package/dist/code-agents/prompt-attachments.d.ts +11 -0
  107. package/dist/code-agents/prompt-attachments.d.ts.map +1 -0
  108. package/dist/code-agents/prompt-attachments.js +23 -0
  109. package/dist/code-agents/prompt-attachments.js.map +1 -0
  110. package/dist/code-agents/transcript-normalizer.js +14 -5
  111. package/dist/code-agents/transcript-normalizer.js.map +1 -1
  112. package/dist/code-agents/transcript-order.d.ts +16 -0
  113. package/dist/code-agents/transcript-order.d.ts.map +1 -0
  114. package/dist/code-agents/transcript-order.js +47 -0
  115. package/dist/code-agents/transcript-order.js.map +1 -0
  116. package/dist/extensions/routes.d.ts.map +1 -1
  117. package/dist/extensions/routes.js +18 -14
  118. package/dist/extensions/routes.js.map +1 -1
  119. package/dist/mcp/build-server.d.ts +33 -1
  120. package/dist/mcp/build-server.d.ts.map +1 -1
  121. package/dist/mcp/build-server.js +39 -12
  122. package/dist/mcp/build-server.js.map +1 -1
  123. package/dist/mcp/builtin-tools.d.ts +3 -1
  124. package/dist/mcp/builtin-tools.d.ts.map +1 -1
  125. package/dist/mcp/builtin-tools.js +40 -10
  126. package/dist/mcp/builtin-tools.js.map +1 -1
  127. package/dist/mcp/connect-route.d.ts.map +1 -1
  128. package/dist/mcp/connect-route.js +299 -97
  129. package/dist/mcp/connect-route.js.map +1 -1
  130. package/dist/mcp/server.d.ts.map +1 -1
  131. package/dist/mcp/server.js +17 -3
  132. package/dist/mcp/server.js.map +1 -1
  133. package/dist/secrets/substitution.d.ts +18 -0
  134. package/dist/secrets/substitution.d.ts.map +1 -1
  135. package/dist/secrets/substitution.js +74 -0
  136. package/dist/secrets/substitution.js.map +1 -1
  137. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  138. package/dist/server/agent-chat-plugin.js +33 -0
  139. package/dist/server/agent-chat-plugin.js.map +1 -1
  140. package/dist/server/auth.d.ts +8 -0
  141. package/dist/server/auth.d.ts.map +1 -1
  142. package/dist/server/auth.js +8 -1
  143. package/dist/server/auth.js.map +1 -1
  144. package/dist/server/deep-link.d.ts +0 -18
  145. package/dist/server/deep-link.d.ts.map +1 -1
  146. package/dist/server/deep-link.js +2 -1
  147. package/dist/server/deep-link.js.map +1 -1
  148. package/dist/server/open-route.d.ts.map +1 -1
  149. package/dist/server/open-route.js +23 -4
  150. package/dist/server/open-route.js.map +1 -1
  151. package/dist/shared/agent-sidebar-url.d.ts +6 -0
  152. package/dist/shared/agent-sidebar-url.d.ts.map +1 -0
  153. package/dist/shared/agent-sidebar-url.js +37 -0
  154. package/dist/shared/agent-sidebar-url.js.map +1 -0
  155. package/dist/shared/index.d.ts +1 -0
  156. package/dist/shared/index.d.ts.map +1 -1
  157. package/dist/shared/index.js +1 -0
  158. package/dist/shared/index.js.map +1 -1
  159. package/dist/styles/agent-conversation.css +403 -0
  160. package/dist/styles/agent-native.css +2 -0
  161. package/dist/vite/client.d.ts.map +1 -1
  162. package/dist/vite/client.js +1 -0
  163. package/dist/vite/client.js.map +1 -1
  164. package/docs/content/external-agents.md +27 -6
  165. package/docs/content/mcp-clients.md +2 -0
  166. package/docs/content/mcp-protocol.md +4 -2
  167. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/composer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EACL,kBAAkB,EAClB,KAAK,uBAAuB,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EACL,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,GACjC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EACV,0BAA0B,EAC1B,UAAU,EACV,WAAW,EACX,WAAW,EACX,SAAS,EACT,YAAY,GACb,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/composer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EACL,kBAAkB,EAClB,KAAK,uBAAuB,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EACL,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,GACjC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,mCAAmC,EACnC,kCAAkC,EAClC,+BAA+B,EAC/B,2BAA2B,EAC3B,2BAA2B,EAC3B,yBAAyB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,gCAAgC,GACtC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EACV,0BAA0B,EAC1B,UAAU,EACV,WAAW,EACX,WAAW,EACX,SAAS,EACT,YAAY,GACb,MAAM,YAAY,CAAC"}
@@ -4,6 +4,7 @@ export { MentionReference } from "./extensions/MentionReference.js";
4
4
  export { AgentComposerFrame, } from "./AgentComposerFrame.js";
5
5
  export { TiptapComposer } from "./TiptapComposer.js";
6
6
  export { PromptComposer, } from "./PromptComposer.js";
7
+ export { AGENT_PROMPT_MAX_INLINE_IMAGE_BYTES, AGENT_PROMPT_MAX_INLINE_TEXT_CHARS, escapePromptAttachmentAttribute, formatPromptWithAttachments, isInlineableAgentPromptFile, readAgentPromptAttachment, } from "./prompt-attachments.js";
7
8
  export { MentionPopover } from "./MentionPopover.js";
8
9
  export { useMentionSearch } from "./use-mention-search.js";
9
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/composer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EACL,kBAAkB,GAEnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAA6B,MAAM,qBAAqB,CAAC;AAChF,OAAO,EACL,cAAc,GAIf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC","sourcesContent":["export { FileReference } from \"./extensions/FileReference.js\";\nexport { SkillReference } from \"./extensions/SkillReference.js\";\nexport { MentionReference } from \"./extensions/MentionReference.js\";\nexport {\n AgentComposerFrame,\n type AgentComposerFrameProps,\n} from \"./AgentComposerFrame.js\";\nexport { TiptapComposer, type TiptapComposerHandle } from \"./TiptapComposer.js\";\nexport {\n PromptComposer,\n type PromptComposerProps,\n type PromptComposerFile,\n type PromptComposerSubmitOptions,\n} from \"./PromptComposer.js\";\nexport { MentionPopover } from \"./MentionPopover.js\";\nexport { useMentionSearch } from \"./use-mention-search.js\";\nexport type {\n AgentComposerLayoutVariant,\n FileResult,\n SkillResult,\n MentionItem,\n Reference,\n SlashCommand,\n} from \"./types.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/composer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EACL,kBAAkB,GAEnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAA6B,MAAM,qBAAqB,CAAC;AAChF,OAAO,EACL,cAAc,GAIf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,mCAAmC,EACnC,kCAAkC,EAClC,+BAA+B,EAC/B,2BAA2B,EAC3B,2BAA2B,EAC3B,yBAAyB,GAG1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC","sourcesContent":["export { FileReference } from \"./extensions/FileReference.js\";\nexport { SkillReference } from \"./extensions/SkillReference.js\";\nexport { MentionReference } from \"./extensions/MentionReference.js\";\nexport {\n AgentComposerFrame,\n type AgentComposerFrameProps,\n} from \"./AgentComposerFrame.js\";\nexport { TiptapComposer, type TiptapComposerHandle } from \"./TiptapComposer.js\";\nexport {\n PromptComposer,\n type PromptComposerProps,\n type PromptComposerFile,\n type PromptComposerSubmitOptions,\n} from \"./PromptComposer.js\";\nexport {\n AGENT_PROMPT_MAX_INLINE_IMAGE_BYTES,\n AGENT_PROMPT_MAX_INLINE_TEXT_CHARS,\n escapePromptAttachmentAttribute,\n formatPromptWithAttachments,\n isInlineableAgentPromptFile,\n readAgentPromptAttachment,\n type AgentPromptAttachment,\n type ReadAgentPromptAttachmentOptions,\n} from \"./prompt-attachments.js\";\nexport { MentionPopover } from \"./MentionPopover.js\";\nexport { useMentionSearch } from \"./use-mention-search.js\";\nexport type {\n AgentComposerLayoutVariant,\n FileResult,\n SkillResult,\n MentionItem,\n Reference,\n SlashCommand,\n} from \"./types.js\";\n"]}
@@ -0,0 +1,11 @@
1
+ import { formatPromptWithAttachments, escapePromptAttachmentAttribute, type AgentPromptAttachment } from "../../code-agents/prompt-attachments.js";
2
+ export { formatPromptWithAttachments, escapePromptAttachmentAttribute, type AgentPromptAttachment, };
3
+ export declare const AGENT_PROMPT_MAX_INLINE_TEXT_CHARS = 60000;
4
+ export declare const AGENT_PROMPT_MAX_INLINE_IMAGE_BYTES: number;
5
+ export interface ReadAgentPromptAttachmentOptions {
6
+ maxInlineTextChars?: number;
7
+ maxInlineImageBytes?: number;
8
+ }
9
+ export declare function readAgentPromptAttachment(file: File, options?: ReadAgentPromptAttachmentOptions): Promise<AgentPromptAttachment>;
10
+ export declare function isInlineableAgentPromptFile(file: File): boolean;
11
+ //# sourceMappingURL=prompt-attachments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-attachments.d.ts","sourceRoot":"","sources":["../../../src/client/composer/prompt-attachments.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,+BAA+B,EAC/B,KAAK,qBAAqB,EAC3B,MAAM,yCAAyC,CAAC;AAEjD,OAAO,EACL,2BAA2B,EAC3B,+BAA+B,EAC/B,KAAK,qBAAqB,GAC3B,CAAC;AAEF,eAAO,MAAM,kCAAkC,QAAS,CAAC;AACzD,eAAO,MAAM,mCAAmC,QAAkB,CAAC;AAEnE,MAAM,WAAW,gCAAgC;IAC/C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,IAAI,EACV,OAAO,GAAE,gCAAqC,GAC7C,OAAO,CAAC,qBAAqB,CAAC,CA6BhC;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAK/D"}
@@ -0,0 +1,45 @@
1
+ import { formatPromptWithAttachments, escapePromptAttachmentAttribute, } from "../../code-agents/prompt-attachments.js";
2
+ export { formatPromptWithAttachments, escapePromptAttachmentAttribute, };
3
+ export const AGENT_PROMPT_MAX_INLINE_TEXT_CHARS = 60_000;
4
+ export const AGENT_PROMPT_MAX_INLINE_IMAGE_BYTES = 2 * 1024 * 1024;
5
+ export async function readAgentPromptAttachment(file, options = {}) {
6
+ const maxInlineTextChars = options.maxInlineTextChars ?? AGENT_PROMPT_MAX_INLINE_TEXT_CHARS;
7
+ const maxInlineImageBytes = options.maxInlineImageBytes ?? AGENT_PROMPT_MAX_INLINE_IMAGE_BYTES;
8
+ const attachment = {
9
+ name: file.name,
10
+ type: file.type || undefined,
11
+ size: file.size,
12
+ };
13
+ if (isInlineableAgentPromptFile(file) && file.size <= maxInlineTextChars) {
14
+ try {
15
+ attachment.text = await file.text();
16
+ }
17
+ catch {
18
+ // Keep the filename-only attachment if the browser cannot read it.
19
+ }
20
+ }
21
+ else if (file.type.startsWith("image/") &&
22
+ file.size <= maxInlineImageBytes) {
23
+ try {
24
+ attachment.dataUrl = await readFileAsDataUrl(file);
25
+ }
26
+ catch {
27
+ // Keep the filename-only attachment if the browser cannot read it.
28
+ }
29
+ }
30
+ return attachment;
31
+ }
32
+ export function isInlineableAgentPromptFile(file) {
33
+ if (file.type.startsWith("text/"))
34
+ return true;
35
+ return /\.(cjs|css|csv|html|js|json|jsx|md|mdx|mjs|sql|tsx?|txt|xml|yaml|yml)$/i.test(file.name);
36
+ }
37
+ function readFileAsDataUrl(file) {
38
+ return new Promise((resolve, reject) => {
39
+ const reader = new FileReader();
40
+ reader.onload = () => resolve(String(reader.result ?? ""));
41
+ reader.onerror = () => reject(reader.error ?? new Error("Could not read file"));
42
+ reader.readAsDataURL(file);
43
+ });
44
+ }
45
+ //# sourceMappingURL=prompt-attachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-attachments.js","sourceRoot":"","sources":["../../../src/client/composer/prompt-attachments.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,+BAA+B,GAEhC,MAAM,yCAAyC,CAAC;AAEjD,OAAO,EACL,2BAA2B,EAC3B,+BAA+B,GAEhC,CAAC;AAEF,MAAM,CAAC,MAAM,kCAAkC,GAAG,MAAM,CAAC;AACzD,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAOnE,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,IAAU,EACV,UAA4C,EAAE;IAE9C,MAAM,kBAAkB,GACtB,OAAO,CAAC,kBAAkB,IAAI,kCAAkC,CAAC;IACnE,MAAM,mBAAmB,GACvB,OAAO,CAAC,mBAAmB,IAAI,mCAAmC,CAAC;IACrE,MAAM,UAAU,GAA0B;QACxC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,SAAS;QAC5B,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC;IAEF,IAAI,2BAA2B,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,kBAAkB,EAAE,CAAC;QACzE,IAAI,CAAC;YACH,UAAU,CAAC,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;QACrE,CAAC;IACH,CAAC;SAAM,IACL,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,IAAI,IAAI,mBAAmB,EAChC,CAAC;QACD,IAAI,CAAC;YACH,UAAU,CAAC,OAAO,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACrD,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;QACrE,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,IAAU;IACpD,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,OAAO,yEAAyE,CAAC,IAAI,CACnF,IAAI,CAAC,IAAI,CACV,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAU;IACnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE,CACpB,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import {\n formatPromptWithAttachments,\n escapePromptAttachmentAttribute,\n type AgentPromptAttachment,\n} from \"../../code-agents/prompt-attachments.js\";\n\nexport {\n formatPromptWithAttachments,\n escapePromptAttachmentAttribute,\n type AgentPromptAttachment,\n};\n\nexport const AGENT_PROMPT_MAX_INLINE_TEXT_CHARS = 60_000;\nexport const AGENT_PROMPT_MAX_INLINE_IMAGE_BYTES = 2 * 1024 * 1024;\n\nexport interface ReadAgentPromptAttachmentOptions {\n maxInlineTextChars?: number;\n maxInlineImageBytes?: number;\n}\n\nexport async function readAgentPromptAttachment(\n file: File,\n options: ReadAgentPromptAttachmentOptions = {},\n): Promise<AgentPromptAttachment> {\n const maxInlineTextChars =\n options.maxInlineTextChars ?? AGENT_PROMPT_MAX_INLINE_TEXT_CHARS;\n const maxInlineImageBytes =\n options.maxInlineImageBytes ?? AGENT_PROMPT_MAX_INLINE_IMAGE_BYTES;\n const attachment: AgentPromptAttachment = {\n name: file.name,\n type: file.type || undefined,\n size: file.size,\n };\n\n if (isInlineableAgentPromptFile(file) && file.size <= maxInlineTextChars) {\n try {\n attachment.text = await file.text();\n } catch {\n // Keep the filename-only attachment if the browser cannot read it.\n }\n } else if (\n file.type.startsWith(\"image/\") &&\n file.size <= maxInlineImageBytes\n ) {\n try {\n attachment.dataUrl = await readFileAsDataUrl(file);\n } catch {\n // Keep the filename-only attachment if the browser cannot read it.\n }\n }\n\n return attachment;\n}\n\nexport function isInlineableAgentPromptFile(file: File): boolean {\n if (file.type.startsWith(\"text/\")) return true;\n return /\\.(cjs|css|csv|html|js|json|jsx|md|mdx|mjs|sql|tsx?|txt|xml|yaml|yml)$/i.test(\n file.name,\n );\n}\n\nfunction readFileAsDataUrl(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(String(reader.result ?? \"\"));\n reader.onerror = () =>\n reject(reader.error ?? new Error(\"Could not read file\"));\n reader.readAsDataURL(file);\n });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"AgentConversation.d.ts","sourceRoot":"","sources":["../../../src/client/conversation/AgentConversation.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAgB1B,OAAO,KAAK,EAEV,wBAAwB,EAIzB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,wBAAwB,EAAE,CAAC;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,OAAe,EACf,KAAK,EACL,SAAiB,EACjB,SAAS,EACT,iBAAiB,EACjB,UAA8B,EAC9B,gBAAgB,EAChB,QAAQ,GACT,EAAE,sBAAsB,2CAoDxB;AAoBD,wBAAgB,4BAA4B,CAAC,EAC3C,OAAO,GACR,EAAE;IACD,OAAO,EAAE,wBAAwB,CAAC;CACnC,2CAkBA"}
1
+ {"version":3,"file":"AgentConversation.d.ts","sourceRoot":"","sources":["../../../src/client/conversation/AgentConversation.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAgBnD,OAAO,KAAK,EAGV,wBAAwB,EAIzB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,wBAAwB,EAAE,CAAC;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,OAAe,EACf,KAAK,EACL,SAAiB,EACjB,SAAS,EACT,iBAAiB,EACjB,UAA8B,EAC9B,gBAAgB,EAChB,QAAQ,GACT,EAAE,sBAAsB,2CAoDxB;AAoBD,wBAAgB,4BAA4B,CAAC,EAC3C,OAAO,GACR,EAAE;IACD,OAAO,EAAE,wBAAwB,CAAC;CACnC,2CA4BA"}
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import React, { useEffect, useState } from "react";
2
3
  import ReactMarkdown, { defaultUrlTransform } from "react-markdown";
3
4
  import remarkGfm from "remark-gfm";
4
5
  import { IconAlertTriangle, IconArrowDown, IconCheck, IconChevronDown, IconCircleX, IconClock, IconExternalLink, IconLoader2, IconTool, } from "@tabler/icons-react";
@@ -17,7 +18,7 @@ function ConversationEmpty({ icon, title, description, }) {
17
18
  }
18
19
  export function AgentConversationMessageView({ message, }) {
19
20
  const parts = message.parts ?? legacyPartsForMessage(message);
20
- return (_jsx("article", { className: cn("agent-conversation-message", `agent-conversation-message--${message.role}`, message.pending && "agent-conversation-message--pending"), children: _jsx("div", { className: "agent-conversation-message__body", children: parts.map((part) => (_jsx(ConversationMessagePartView, { part: part }, part.id))) }) }));
21
+ return (_jsxs("article", { className: cn("agent-conversation-message", `agent-conversation-message--${message.role}`, message.pending && "agent-conversation-message--pending"), children: [message.attachments && message.attachments.length > 0 && (_jsx("div", { className: "agent-conversation-message__attachments", children: message.attachments.map((attachment, i) => (_jsx(ConversationAttachmentChip, { attachment: attachment }, `${attachment.name}-${i}`))) })), _jsx("div", { className: "agent-conversation-message__body", children: parts.map((part) => (_jsx(ConversationMessagePartView, { part: part }, part.id))) })] }));
21
22
  }
22
23
  function legacyPartsForMessage(message) {
23
24
  return [
@@ -50,6 +51,91 @@ function legacyPartsForMessage(message) {
50
51
  function ConversationMessagePartView({ part, }) {
51
52
  return (_jsx("div", { className: cn("agent-conversation-message__part", `agent-conversation-message__part--${part.type}`), children: part.type === "text" ? (_jsx(ConversationMarkdown, { text: part.text })) : part.type === "tool" ? (_jsx(ConversationToolCall, { tool: part.tool })) : part.type === "notice" ? (_jsx(ConversationNotice, { notice: part.notice })) : (_jsx(ConversationArtifact, { artifact: part.artifact })) }));
52
53
  }
54
+ let _highlighterLoader = null;
55
+ function loadConversationHighlighter() {
56
+ if (!_highlighterLoader) {
57
+ _highlighterLoader = (async () => {
58
+ const [{ createHighlighterCore }, { createOnigurumaEngine }] = await Promise.all([
59
+ import("shiki/core"),
60
+ import("shiki/engine/oniguruma"),
61
+ ]);
62
+ return createHighlighterCore({
63
+ themes: [
64
+ import("shiki/themes/github-light-default.mjs"),
65
+ import("shiki/themes/github-dark-default.mjs"),
66
+ ],
67
+ langs: [
68
+ import("shiki/langs/javascript.mjs"),
69
+ import("shiki/langs/typescript.mjs"),
70
+ import("shiki/langs/jsx.mjs"),
71
+ import("shiki/langs/tsx.mjs"),
72
+ import("shiki/langs/json.mjs"),
73
+ import("shiki/langs/css.mjs"),
74
+ import("shiki/langs/html.mjs"),
75
+ import("shiki/langs/markdown.mjs"),
76
+ import("shiki/langs/bash.mjs"),
77
+ import("shiki/langs/shellscript.mjs"),
78
+ import("shiki/langs/python.mjs"),
79
+ import("shiki/langs/yaml.mjs"),
80
+ import("shiki/langs/sql.mjs"),
81
+ ],
82
+ engine: createOnigurumaEngine(import("shiki/wasm")),
83
+ });
84
+ })().catch((err) => {
85
+ _highlighterLoader = null;
86
+ throw err;
87
+ });
88
+ }
89
+ return _highlighterLoader;
90
+ }
91
+ const LANG_ALIASES = {
92
+ js: "javascript",
93
+ ts: "typescript",
94
+ sh: "bash",
95
+ shell: "bash",
96
+ zsh: "bash",
97
+ py: "python",
98
+ yml: "yaml",
99
+ md: "markdown",
100
+ bq: "sql",
101
+ bigquery: "sql",
102
+ };
103
+ function HighlightedCodeBlock({ code, lang }) {
104
+ const [html, setHtml] = useState(null);
105
+ useEffect(() => {
106
+ let cancelled = false;
107
+ loadConversationHighlighter()
108
+ .then((highlighter) => {
109
+ const requested = (lang || "text").toLowerCase();
110
+ const resolved = LANG_ALIASES[requested] ?? requested;
111
+ const loaded = highlighter.getLoadedLanguages();
112
+ const finalLang = loaded.includes(resolved) ? resolved : "text";
113
+ return highlighter.codeToHtml(code, {
114
+ lang: finalLang,
115
+ themes: {
116
+ light: "github-light-default",
117
+ dark: "github-dark-default",
118
+ },
119
+ defaultColor: false,
120
+ });
121
+ })
122
+ .then((out) => {
123
+ if (!cancelled)
124
+ setHtml(out);
125
+ })
126
+ .catch(() => {
127
+ if (!cancelled)
128
+ setHtml(null);
129
+ });
130
+ return () => {
131
+ cancelled = true;
132
+ };
133
+ }, [code, lang]);
134
+ if (html) {
135
+ return (_jsx("div", { className: "agent-conversation-shiki", dangerouslySetInnerHTML: { __html: html } }));
136
+ }
137
+ return (_jsx("pre", { children: _jsx("code", { className: lang ? `language-${lang}` : undefined, children: code }) }));
138
+ }
53
139
  function ConversationMarkdown({ text }) {
54
140
  return (_jsx("div", { className: "agent-conversation-markdown", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], urlTransform: (url) => {
55
141
  if (url.startsWith("file://"))
@@ -59,8 +145,32 @@ function ConversationMarkdown({ text }) {
59
145
  a({ children, href }) {
60
146
  return (_jsx("a", { href: href, target: "_blank", rel: "noreferrer", onClick: (event) => openMarkdownLink(event, href), children: children }));
61
147
  },
148
+ pre(props) {
149
+ const { children, ...rest } = props;
150
+ if (React.isValidElement(children)) {
151
+ const childProps = children.props;
152
+ const langMatch = (childProps.className ?? "").match(/\blanguage-([\w+-]+)\b/);
153
+ if (langMatch) {
154
+ const code = extractCodeText(childProps.children).replace(/\n$/, "");
155
+ return _jsx(HighlightedCodeBlock, { code: code, lang: langMatch[1] });
156
+ }
157
+ }
158
+ return _jsx("pre", { ...rest, children: children });
159
+ },
62
160
  }, children: text }) }));
63
161
  }
162
+ function extractCodeText(node) {
163
+ if (typeof node === "string")
164
+ return node;
165
+ if (typeof node === "number")
166
+ return String(node);
167
+ if (Array.isArray(node))
168
+ return node.map(extractCodeText).join("");
169
+ if (React.isValidElement(node)) {
170
+ return extractCodeText(node.props.children);
171
+ }
172
+ return "";
173
+ }
64
174
  function openMarkdownLink(event, href) {
65
175
  if (!href)
66
176
  return;
@@ -91,4 +201,17 @@ function ConversationNotice({ notice }) {
91
201
  function ConversationArtifact({ artifact, }) {
92
202
  return (_jsxs("div", { className: "agent-conversation-artifact", children: [_jsx(IconTool, { size: 14 }), artifact.path ? (_jsx("code", { children: artifact.path })) : (_jsx("span", { children: artifact.label })), artifact.url && (_jsxs("a", { href: artifact.url, target: "_blank", rel: "noreferrer", children: [_jsx(IconExternalLink, { size: 13 }), "Open"] }))] }));
93
203
  }
204
+ function ConversationAttachmentChip({ attachment, }) {
205
+ if (attachment.dataUrl) {
206
+ return (_jsxs("div", { className: "agent-conversation-attachment agent-conversation-attachment--image", children: [_jsx("img", { src: attachment.dataUrl, alt: attachment.name, className: "agent-conversation-attachment__image" }), _jsx("span", { className: "agent-conversation-attachment__name", children: attachment.name })] }));
207
+ }
208
+ return (_jsxs("div", { className: "agent-conversation-attachment agent-conversation-attachment--file", children: [_jsx("span", { className: "agent-conversation-attachment__name", children: attachment.name }), attachment.size !== undefined && (_jsx("span", { className: "agent-conversation-attachment__size", children: formatBytes(attachment.size) }))] }));
209
+ }
210
+ function formatBytes(bytes) {
211
+ if (bytes < 1024)
212
+ return `${bytes} B`;
213
+ if (bytes < 1024 * 1024)
214
+ return `${(bytes / 1024).toFixed(1)} KB`;
215
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
216
+ }
94
217
  //# sourceMappingURL=AgentConversation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AgentConversation.js","sourceRoot":"","sources":["../../../src/client/conversation/AgentConversation.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from \"react\";\nimport ReactMarkdown, { defaultUrlTransform } from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport {\n IconAlertTriangle,\n IconArrowDown,\n IconCheck,\n IconChevronDown,\n IconCircleX,\n IconClock,\n IconExternalLink,\n IconLoader2,\n IconTool,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport { useNearBottomAutoscroll } from \"./use-near-bottom-autoscroll.js\";\nimport type {\n AgentConversationArtifact,\n AgentConversationMessage,\n AgentConversationMessagePart,\n AgentConversationNotice,\n AgentConversationToolCall,\n} from \"./types.js\";\n\nexport interface AgentConversationProps {\n messages: AgentConversationMessage[];\n loading?: boolean;\n error?: string | null;\n streaming?: boolean;\n className?: string;\n timelineClassName?: string;\n emptyTitle?: string;\n emptyDescription?: string;\n composer?: React.ReactNode;\n}\n\nexport function AgentConversation({\n messages,\n loading = false,\n error,\n streaming = false,\n className,\n timelineClassName,\n emptyTitle = \"No messages yet\",\n emptyDescription,\n composer,\n}: AgentConversationProps) {\n const followKey = `${messages.length}:${\n messages[messages.length - 1]?.text?.length ?? 0\n }`;\n const { scrollRef, showScrollToBottom, scrollToBottom } =\n useNearBottomAutoscroll<HTMLDivElement>({\n followKey,\n streaming,\n });\n\n return (\n <section className={cn(\"agent-conversation\", className)}>\n {error && (\n <div className=\"agent-conversation__error\" role=\"alert\">\n <IconAlertTriangle size={15} strokeWidth={1.8} />\n <span>{error}</span>\n </div>\n )}\n <div\n ref={scrollRef}\n className={cn(\"agent-conversation__timeline\", timelineClassName)}\n >\n {loading && messages.length === 0 ? (\n <ConversationEmpty\n icon={<IconLoader2 size={17} className=\"agent-conversation-spin\" />}\n title=\"Loading session...\"\n />\n ) : messages.length === 0 ? (\n <ConversationEmpty\n icon={<IconClock size={18} />}\n title={emptyTitle}\n description={emptyDescription}\n />\n ) : (\n messages.map((message) => (\n <AgentConversationMessageView key={message.id} message={message} />\n ))\n )}\n </div>\n {showScrollToBottom && (\n <button\n type=\"button\"\n className=\"agent-conversation__scroll-bottom\"\n onClick={scrollToBottom}\n aria-label=\"Scroll to bottom\"\n >\n <IconArrowDown size={15} strokeWidth={1.9} />\n </button>\n )}\n {composer}\n </section>\n );\n}\n\nfunction ConversationEmpty({\n icon,\n title,\n description,\n}: {\n icon: React.ReactNode;\n title: string;\n description?: string;\n}) {\n return (\n <div className=\"agent-conversation__empty\">\n {icon}\n <p>{title}</p>\n {description && <span>{description}</span>}\n </div>\n );\n}\n\nexport function AgentConversationMessageView({\n message,\n}: {\n message: AgentConversationMessage;\n}) {\n const parts = message.parts ?? legacyPartsForMessage(message);\n\n return (\n <article\n className={cn(\n \"agent-conversation-message\",\n `agent-conversation-message--${message.role}`,\n message.pending && \"agent-conversation-message--pending\",\n )}\n >\n <div className=\"agent-conversation-message__body\">\n {parts.map((part) => (\n <ConversationMessagePartView key={part.id} part={part} />\n ))}\n </div>\n </article>\n );\n}\n\nfunction legacyPartsForMessage(\n message: AgentConversationMessage,\n): AgentConversationMessagePart[] {\n return [\n ...(message.text\n ? [\n {\n id: `${message.id}-text`,\n type: \"text\" as const,\n text: message.text,\n },\n ]\n : []),\n ...(message.tools ?? []).map((tool) => ({\n id: `${message.id}-tool-${tool.id}`,\n type: \"tool\" as const,\n tool,\n })),\n ...(message.notices ?? []).map((notice) => ({\n id: `${message.id}-notice-${notice.id}`,\n type: \"notice\" as const,\n notice,\n })),\n ...(message.artifacts ?? []).map((artifact) => ({\n id: `${message.id}-artifact-${artifact.id}`,\n type: \"artifact\" as const,\n artifact,\n })),\n ];\n}\n\nfunction ConversationMessagePartView({\n part,\n}: {\n part: AgentConversationMessagePart;\n}) {\n return (\n <div\n className={cn(\n \"agent-conversation-message__part\",\n `agent-conversation-message__part--${part.type}`,\n )}\n >\n {part.type === \"text\" ? (\n <ConversationMarkdown text={part.text} />\n ) : part.type === \"tool\" ? (\n <ConversationToolCall tool={part.tool} />\n ) : part.type === \"notice\" ? (\n <ConversationNotice notice={part.notice} />\n ) : (\n <ConversationArtifact artifact={part.artifact} />\n )}\n </div>\n );\n}\n\nfunction ConversationMarkdown({ text }: { text: string }) {\n return (\n <div className=\"agent-conversation-markdown\">\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n urlTransform={(url) => {\n if (url.startsWith(\"file://\")) return url;\n return defaultUrlTransform(url);\n }}\n components={{\n a({ children, href }) {\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noreferrer\"\n onClick={(event) => openMarkdownLink(event, href)}\n >\n {children}\n </a>\n );\n },\n }}\n >\n {text}\n </ReactMarkdown>\n </div>\n );\n}\n\nfunction openMarkdownLink(\n event: React.MouseEvent<HTMLAnchorElement>,\n href: string | undefined,\n) {\n if (!href) return;\n\n let url: URL;\n try {\n url = new URL(href, window.location.href);\n } catch {\n return;\n }\n\n if (![\"http:\", \"https:\", \"mailto:\", \"tel:\"].includes(url.protocol)) return;\n event.preventDefault();\n window.open(url.href, \"_blank\", \"noopener,noreferrer\");\n}\n\nfunction ConversationToolCall({ tool }: { tool: AgentConversationToolCall }) {\n const hasDetails = Boolean(tool.input || tool.result);\n const icon =\n tool.state === \"running\" || tool.state === \"activity\" ? (\n <IconLoader2 size={14} className=\"agent-conversation-spin\" />\n ) : tool.state === \"errored\" ? (\n <IconCircleX size={14} />\n ) : (\n <IconCheck size={14} />\n );\n\n const content = (\n <>\n <span className=\"agent-conversation-tool__icon\">{icon}</span>\n <span className=\"agent-conversation-tool__name\">{tool.name}</span>\n {tool.summary && (\n <span className=\"agent-conversation-tool__summary\">{tool.summary}</span>\n )}\n </>\n );\n\n if (!hasDetails) {\n return <div className=\"agent-conversation-tool\">{content}</div>;\n }\n\n return (\n <details className=\"agent-conversation-tool\">\n <summary>\n {content}\n <IconChevronDown\n size={13}\n className=\"agent-conversation-tool__chevron\"\n />\n </summary>\n <div className=\"agent-conversation-tool__details\">\n {tool.input && (\n <pre>\n <strong>input</strong>\n {tool.input}\n </pre>\n )}\n {tool.result && (\n <pre>\n <strong>result</strong>\n {tool.result}\n </pre>\n )}\n </div>\n </details>\n );\n}\n\nfunction ConversationNotice({ notice }: { notice: AgentConversationNotice }) {\n return (\n <div\n className={cn(\n \"agent-conversation-notice\",\n `agent-conversation-notice--${notice.tone}`,\n )}\n >\n <IconAlertTriangle size={15} />\n <div>\n {notice.title && <strong>{notice.title}</strong>}\n <span>{notice.text}</span>\n </div>\n {notice.action}\n </div>\n );\n}\n\nfunction ConversationArtifact({\n artifact,\n}: {\n artifact: AgentConversationArtifact;\n}) {\n return (\n <div className=\"agent-conversation-artifact\">\n <IconTool size={14} />\n {artifact.path ? (\n <code>{artifact.path}</code>\n ) : (\n <span>{artifact.label}</span>\n )}\n {artifact.url && (\n <a href={artifact.url} target=\"_blank\" rel=\"noreferrer\">\n <IconExternalLink size={13} />\n Open\n </a>\n )}\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"AgentConversation.js","sourceRoot":"","sources":["../../../src/client/conversation/AgentConversation.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useEffect, useState } from \"react\";\nimport ReactMarkdown, { defaultUrlTransform } from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport {\n IconAlertTriangle,\n IconArrowDown,\n IconCheck,\n IconChevronDown,\n IconCircleX,\n IconClock,\n IconExternalLink,\n IconLoader2,\n IconTool,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport { useNearBottomAutoscroll } from \"./use-near-bottom-autoscroll.js\";\nimport type {\n AgentConversationAttachment,\n AgentConversationArtifact,\n AgentConversationMessage,\n AgentConversationMessagePart,\n AgentConversationNotice,\n AgentConversationToolCall,\n} from \"./types.js\";\n\nexport interface AgentConversationProps {\n messages: AgentConversationMessage[];\n loading?: boolean;\n error?: string | null;\n streaming?: boolean;\n className?: string;\n timelineClassName?: string;\n emptyTitle?: string;\n emptyDescription?: string;\n composer?: React.ReactNode;\n}\n\nexport function AgentConversation({\n messages,\n loading = false,\n error,\n streaming = false,\n className,\n timelineClassName,\n emptyTitle = \"No messages yet\",\n emptyDescription,\n composer,\n}: AgentConversationProps) {\n const followKey = `${messages.length}:${\n messages[messages.length - 1]?.text?.length ?? 0\n }`;\n const { scrollRef, showScrollToBottom, scrollToBottom } =\n useNearBottomAutoscroll<HTMLDivElement>({\n followKey,\n streaming,\n });\n\n return (\n <section className={cn(\"agent-conversation\", className)}>\n {error && (\n <div className=\"agent-conversation__error\" role=\"alert\">\n <IconAlertTriangle size={15} strokeWidth={1.8} />\n <span>{error}</span>\n </div>\n )}\n <div\n ref={scrollRef}\n className={cn(\"agent-conversation__timeline\", timelineClassName)}\n >\n {loading && messages.length === 0 ? (\n <ConversationEmpty\n icon={<IconLoader2 size={17} className=\"agent-conversation-spin\" />}\n title=\"Loading session...\"\n />\n ) : messages.length === 0 ? (\n <ConversationEmpty\n icon={<IconClock size={18} />}\n title={emptyTitle}\n description={emptyDescription}\n />\n ) : (\n messages.map((message) => (\n <AgentConversationMessageView key={message.id} message={message} />\n ))\n )}\n </div>\n {showScrollToBottom && (\n <button\n type=\"button\"\n className=\"agent-conversation__scroll-bottom\"\n onClick={scrollToBottom}\n aria-label=\"Scroll to bottom\"\n >\n <IconArrowDown size={15} strokeWidth={1.9} />\n </button>\n )}\n {composer}\n </section>\n );\n}\n\nfunction ConversationEmpty({\n icon,\n title,\n description,\n}: {\n icon: React.ReactNode;\n title: string;\n description?: string;\n}) {\n return (\n <div className=\"agent-conversation__empty\">\n {icon}\n <p>{title}</p>\n {description && <span>{description}</span>}\n </div>\n );\n}\n\nexport function AgentConversationMessageView({\n message,\n}: {\n message: AgentConversationMessage;\n}) {\n const parts = message.parts ?? legacyPartsForMessage(message);\n\n return (\n <article\n className={cn(\n \"agent-conversation-message\",\n `agent-conversation-message--${message.role}`,\n message.pending && \"agent-conversation-message--pending\",\n )}\n >\n {message.attachments && message.attachments.length > 0 && (\n <div className=\"agent-conversation-message__attachments\">\n {message.attachments.map((attachment, i) => (\n <ConversationAttachmentChip\n key={`${attachment.name}-${i}`}\n attachment={attachment}\n />\n ))}\n </div>\n )}\n <div className=\"agent-conversation-message__body\">\n {parts.map((part) => (\n <ConversationMessagePartView key={part.id} part={part} />\n ))}\n </div>\n </article>\n );\n}\n\nfunction legacyPartsForMessage(\n message: AgentConversationMessage,\n): AgentConversationMessagePart[] {\n return [\n ...(message.text\n ? [\n {\n id: `${message.id}-text`,\n type: \"text\" as const,\n text: message.text,\n },\n ]\n : []),\n ...(message.tools ?? []).map((tool) => ({\n id: `${message.id}-tool-${tool.id}`,\n type: \"tool\" as const,\n tool,\n })),\n ...(message.notices ?? []).map((notice) => ({\n id: `${message.id}-notice-${notice.id}`,\n type: \"notice\" as const,\n notice,\n })),\n ...(message.artifacts ?? []).map((artifact) => ({\n id: `${message.id}-artifact-${artifact.id}`,\n type: \"artifact\" as const,\n artifact,\n })),\n ];\n}\n\nfunction ConversationMessagePartView({\n part,\n}: {\n part: AgentConversationMessagePart;\n}) {\n return (\n <div\n className={cn(\n \"agent-conversation-message__part\",\n `agent-conversation-message__part--${part.type}`,\n )}\n >\n {part.type === \"text\" ? (\n <ConversationMarkdown text={part.text} />\n ) : part.type === \"tool\" ? (\n <ConversationToolCall tool={part.tool} />\n ) : part.type === \"notice\" ? (\n <ConversationNotice notice={part.notice} />\n ) : (\n <ConversationArtifact artifact={part.artifact} />\n )}\n </div>\n );\n}\n\n// ─── Shiki syntax highlighter (lazy-loaded) ──────────────────────────────────\ntype ShikiHighlighter = {\n codeToHtml: (\n code: string,\n options: {\n lang: string;\n themes: { light: string; dark: string };\n defaultColor?: false | \"light\" | \"dark\";\n },\n ) => string | Promise<string>;\n getLoadedLanguages: () => string[];\n};\n\nlet _highlighterLoader: Promise<ShikiHighlighter> | null = null;\nfunction loadConversationHighlighter(): Promise<ShikiHighlighter> {\n if (!_highlighterLoader) {\n _highlighterLoader = (async () => {\n const [{ createHighlighterCore }, { createOnigurumaEngine }] =\n await Promise.all([\n import(\"shiki/core\"),\n import(\"shiki/engine/oniguruma\"),\n ]);\n return createHighlighterCore({\n themes: [\n import(\"shiki/themes/github-light-default.mjs\"),\n import(\"shiki/themes/github-dark-default.mjs\"),\n ],\n langs: [\n import(\"shiki/langs/javascript.mjs\"),\n import(\"shiki/langs/typescript.mjs\"),\n import(\"shiki/langs/jsx.mjs\"),\n import(\"shiki/langs/tsx.mjs\"),\n import(\"shiki/langs/json.mjs\"),\n import(\"shiki/langs/css.mjs\"),\n import(\"shiki/langs/html.mjs\"),\n import(\"shiki/langs/markdown.mjs\"),\n import(\"shiki/langs/bash.mjs\"),\n import(\"shiki/langs/shellscript.mjs\"),\n import(\"shiki/langs/python.mjs\"),\n import(\"shiki/langs/yaml.mjs\"),\n import(\"shiki/langs/sql.mjs\"),\n ],\n engine: createOnigurumaEngine(import(\"shiki/wasm\")),\n }) as unknown as Promise<ShikiHighlighter>;\n })().catch((err) => {\n _highlighterLoader = null;\n throw err;\n });\n }\n return _highlighterLoader;\n}\n\nconst LANG_ALIASES: Record<string, string> = {\n js: \"javascript\",\n ts: \"typescript\",\n sh: \"bash\",\n shell: \"bash\",\n zsh: \"bash\",\n py: \"python\",\n yml: \"yaml\",\n md: \"markdown\",\n bq: \"sql\",\n bigquery: \"sql\",\n};\n\nfunction HighlightedCodeBlock({ code, lang }: { code: string; lang: string }) {\n const [html, setHtml] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n loadConversationHighlighter()\n .then((highlighter) => {\n const requested = (lang || \"text\").toLowerCase();\n const resolved = LANG_ALIASES[requested] ?? requested;\n const loaded = highlighter.getLoadedLanguages();\n const finalLang = loaded.includes(resolved) ? resolved : \"text\";\n return highlighter.codeToHtml(code, {\n lang: finalLang,\n themes: {\n light: \"github-light-default\",\n dark: \"github-dark-default\",\n },\n defaultColor: false,\n });\n })\n .then((out) => {\n if (!cancelled) setHtml(out as string);\n })\n .catch(() => {\n if (!cancelled) setHtml(null);\n });\n return () => {\n cancelled = true;\n };\n }, [code, lang]);\n\n if (html) {\n return (\n <div\n className=\"agent-conversation-shiki\"\n dangerouslySetInnerHTML={{ __html: html }}\n />\n );\n }\n return (\n <pre>\n <code className={lang ? `language-${lang}` : undefined}>{code}</code>\n </pre>\n );\n}\n\nfunction ConversationMarkdown({ text }: { text: string }) {\n return (\n <div className=\"agent-conversation-markdown\">\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n urlTransform={(url) => {\n if (url.startsWith(\"file://\")) return url;\n return defaultUrlTransform(url);\n }}\n components={{\n a({ children, href }) {\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noreferrer\"\n onClick={(event) => openMarkdownLink(event, href)}\n >\n {children}\n </a>\n );\n },\n pre(props: React.HTMLAttributes<HTMLPreElement>) {\n const { children, ...rest } = props;\n if (React.isValidElement(children)) {\n const childProps = children.props as {\n className?: string;\n children?: React.ReactNode;\n };\n const langMatch = (childProps.className ?? \"\").match(\n /\\blanguage-([\\w+-]+)\\b/,\n );\n if (langMatch) {\n const code = extractCodeText(childProps.children).replace(\n /\\n$/,\n \"\",\n );\n return <HighlightedCodeBlock code={code} lang={langMatch[1]} />;\n }\n }\n return <pre {...rest}>{children}</pre>;\n },\n }}\n >\n {text}\n </ReactMarkdown>\n </div>\n );\n}\n\nfunction extractCodeText(node: React.ReactNode): string {\n if (typeof node === \"string\") return node;\n if (typeof node === \"number\") return String(node);\n if (Array.isArray(node)) return node.map(extractCodeText).join(\"\");\n if (React.isValidElement(node)) {\n return extractCodeText(\n (node.props as { children?: React.ReactNode }).children,\n );\n }\n return \"\";\n}\n\nfunction openMarkdownLink(\n event: React.MouseEvent<HTMLAnchorElement>,\n href: string | undefined,\n) {\n if (!href) return;\n\n let url: URL;\n try {\n url = new URL(href, window.location.href);\n } catch {\n return;\n }\n\n if (![\"http:\", \"https:\", \"mailto:\", \"tel:\"].includes(url.protocol)) return;\n event.preventDefault();\n window.open(url.href, \"_blank\", \"noopener,noreferrer\");\n}\n\nfunction ConversationToolCall({ tool }: { tool: AgentConversationToolCall }) {\n const hasDetails = Boolean(tool.input || tool.result);\n const icon =\n tool.state === \"running\" || tool.state === \"activity\" ? (\n <IconLoader2 size={14} className=\"agent-conversation-spin\" />\n ) : tool.state === \"errored\" ? (\n <IconCircleX size={14} />\n ) : (\n <IconCheck size={14} />\n );\n\n const content = (\n <>\n <span className=\"agent-conversation-tool__icon\">{icon}</span>\n <span className=\"agent-conversation-tool__name\">{tool.name}</span>\n {tool.summary && (\n <span className=\"agent-conversation-tool__summary\">{tool.summary}</span>\n )}\n </>\n );\n\n if (!hasDetails) {\n return <div className=\"agent-conversation-tool\">{content}</div>;\n }\n\n return (\n <details className=\"agent-conversation-tool\">\n <summary>\n {content}\n <IconChevronDown\n size={13}\n className=\"agent-conversation-tool__chevron\"\n />\n </summary>\n <div className=\"agent-conversation-tool__details\">\n {tool.input && (\n <pre>\n <strong>input</strong>\n {tool.input}\n </pre>\n )}\n {tool.result && (\n <pre>\n <strong>result</strong>\n {tool.result}\n </pre>\n )}\n </div>\n </details>\n );\n}\n\nfunction ConversationNotice({ notice }: { notice: AgentConversationNotice }) {\n return (\n <div\n className={cn(\n \"agent-conversation-notice\",\n `agent-conversation-notice--${notice.tone}`,\n )}\n >\n <IconAlertTriangle size={15} />\n <div>\n {notice.title && <strong>{notice.title}</strong>}\n <span>{notice.text}</span>\n </div>\n {notice.action}\n </div>\n );\n}\n\nfunction ConversationArtifact({\n artifact,\n}: {\n artifact: AgentConversationArtifact;\n}) {\n return (\n <div className=\"agent-conversation-artifact\">\n <IconTool size={14} />\n {artifact.path ? (\n <code>{artifact.path}</code>\n ) : (\n <span>{artifact.label}</span>\n )}\n {artifact.url && (\n <a href={artifact.url} target=\"_blank\" rel=\"noreferrer\">\n <IconExternalLink size={13} />\n Open\n </a>\n )}\n </div>\n );\n}\n\nfunction ConversationAttachmentChip({\n attachment,\n}: {\n attachment: AgentConversationAttachment;\n}) {\n if (attachment.dataUrl) {\n return (\n <div className=\"agent-conversation-attachment agent-conversation-attachment--image\">\n <img\n src={attachment.dataUrl}\n alt={attachment.name}\n className=\"agent-conversation-attachment__image\"\n />\n <span className=\"agent-conversation-attachment__name\">\n {attachment.name}\n </span>\n </div>\n );\n }\n return (\n <div className=\"agent-conversation-attachment agent-conversation-attachment--file\">\n <span className=\"agent-conversation-attachment__name\">\n {attachment.name}\n </span>\n {attachment.size !== undefined && (\n <span className=\"agent-conversation-attachment__size\">\n {formatBytes(attachment.size)}\n </span>\n )}\n </div>\n );\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n"]}
@@ -0,0 +1,25 @@
1
+ import type { AgentConversationMessage } from "./types.js";
2
+ export type CodeAgentConversationTranscriptEventType = "user" | "system" | "artifact" | "status" | "note";
3
+ /**
4
+ * Browser/UI transcript event shape used by Code-style hosts. It accepts both
5
+ * the local Code UI field names (`type`, `text`) and the core transcript-store
6
+ * field names (`kind`, `message`) so hosts can pass through either shape.
7
+ */
8
+ export interface CodeAgentConversationTranscriptEvent {
9
+ id: string;
10
+ runId: string;
11
+ type?: CodeAgentConversationTranscriptEventType;
12
+ kind?: CodeAgentConversationTranscriptEventType;
13
+ title?: string;
14
+ text?: string;
15
+ message?: string;
16
+ createdAt: string;
17
+ artifactPath?: string;
18
+ artifactUrl?: string;
19
+ metadata?: Record<string, unknown>;
20
+ }
21
+ export interface NormalizeCodeAgentTranscriptOptions {
22
+ hideCredentialMessages?: boolean;
23
+ }
24
+ export declare function normalizeCodeAgentTranscriptForConversation(events: readonly CodeAgentConversationTranscriptEvent[], options?: NormalizeCodeAgentTranscriptOptions): AgentConversationMessage[];
25
+ //# sourceMappingURL=code-agent-transcript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-agent-transcript.d.ts","sourceRoot":"","sources":["../../../src/client/conversation/code-agent-transcript.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAGV,wBAAwB,EAIzB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,wCAAwC,GAChD,MAAM,GACN,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,MAAM,CAAC;AAEX;;;;GAIG;AACH,MAAM,WAAW,oCAAoC;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,wCAAwC,CAAC;IAChD,IAAI,CAAC,EAAE,wCAAwC,CAAC;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,mCAAmC;IAClD,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,wBAAgB,2CAA2C,CACzD,MAAM,EAAE,SAAS,oCAAoC,EAAE,EACvD,OAAO,GAAE,mCAAwC,GAChD,wBAAwB,EAAE,CAsF5B"}
@@ -0,0 +1,200 @@
1
+ import { normalizeCodeAgentTranscript, } from "../../code-agents/transcript-normalizer.js";
2
+ export function normalizeCodeAgentTranscriptForConversation(events, options = {}) {
3
+ const normalized = normalizeCodeAgentTranscript(events.map(toCoreTranscriptEvent));
4
+ const messages = [];
5
+ const assistantByTurn = new Map();
6
+ const assistantForItem = (item) => {
7
+ const existing = assistantByTurn.get(item.turnIndex);
8
+ if (existing)
9
+ return existing;
10
+ const message = {
11
+ id: `assistant-${item.id}`,
12
+ role: "assistant",
13
+ createdAt: item.createdAt,
14
+ text: "",
15
+ parts: [],
16
+ tools: [],
17
+ notices: [],
18
+ artifacts: [],
19
+ };
20
+ assistantByTurn.set(item.turnIndex, message);
21
+ messages.push(message);
22
+ return message;
23
+ };
24
+ for (const item of normalized.items) {
25
+ if (item.type === "user") {
26
+ const attachments = extractAttachments(item.events);
27
+ messages.push({
28
+ id: item.id,
29
+ role: "user",
30
+ text: item.text,
31
+ createdAt: item.createdAt,
32
+ pending: item.events.some((event) => event.metadata?.pending === true),
33
+ ...(attachments.length > 0 ? { attachments } : {}),
34
+ });
35
+ continue;
36
+ }
37
+ const assistant = assistantForItem(item);
38
+ if (item.type === "assistant") {
39
+ appendPart(assistant, {
40
+ id: item.id,
41
+ type: "text",
42
+ text: item.text,
43
+ });
44
+ assistant.text = `${assistant.text ?? ""}${item.text}`;
45
+ }
46
+ else if (item.type === "tool") {
47
+ const tool = toConversationTool(item);
48
+ appendPart(assistant, {
49
+ id: item.id,
50
+ type: "tool",
51
+ tool,
52
+ });
53
+ assistant.tools = [...(assistant.tools ?? []), tool];
54
+ }
55
+ else if (item.type === "status") {
56
+ const artifact = toConversationArtifact(item);
57
+ if (artifact) {
58
+ appendPart(assistant, {
59
+ id: item.id,
60
+ type: "artifact",
61
+ artifact,
62
+ });
63
+ assistant.artifacts = [...(assistant.artifacts ?? []), artifact];
64
+ }
65
+ else {
66
+ const notice = toConversationNotice(item, options);
67
+ if (notice) {
68
+ appendPart(assistant, {
69
+ id: item.id,
70
+ type: "notice",
71
+ notice,
72
+ });
73
+ assistant.notices = [...(assistant.notices ?? []), notice];
74
+ }
75
+ }
76
+ }
77
+ }
78
+ return messages.filter((message) => message.text?.trim() ||
79
+ message.parts?.length ||
80
+ message.tools?.length ||
81
+ message.notices?.length ||
82
+ message.artifacts?.length);
83
+ }
84
+ function appendPart(message, part) {
85
+ message.parts = [...(message.parts ?? []), part];
86
+ }
87
+ function toCoreTranscriptEvent(event) {
88
+ return {
89
+ schemaVersion: 1,
90
+ id: event.id,
91
+ runId: event.runId,
92
+ kind: (event.kind ??
93
+ event.type ??
94
+ "status"),
95
+ message: event.message ?? event.text ?? "",
96
+ createdAt: event.createdAt,
97
+ metadata: {
98
+ ...(event.metadata ?? {}),
99
+ ...(event.title ? { title: event.title } : {}),
100
+ ...(event.artifactPath ? { artifactPath: event.artifactPath } : {}),
101
+ ...(event.artifactUrl ? { artifactUrl: event.artifactUrl } : {}),
102
+ },
103
+ };
104
+ }
105
+ function toConversationTool(item) {
106
+ return {
107
+ id: item.id,
108
+ name: item.tool ?? "tool",
109
+ state: item.state === "completed"
110
+ ? "completed"
111
+ : item.state === "activity"
112
+ ? "activity"
113
+ : "running",
114
+ input: preview(item.input),
115
+ result: preview(item.result),
116
+ summary: item.state === "completed"
117
+ ? "finished"
118
+ : item.state === "activity"
119
+ ? "working"
120
+ : "started",
121
+ };
122
+ }
123
+ function toConversationNotice(item, options) {
124
+ if (options.hideCredentialMessages && isCredentialText(item.text))
125
+ return null;
126
+ if (item.level === "info" && item.statusKind !== "note")
127
+ return null;
128
+ return {
129
+ id: item.id,
130
+ tone: item.level === "error"
131
+ ? "error"
132
+ : item.level === "warning" || item.level === "approval"
133
+ ? "warning"
134
+ : "info",
135
+ title: item.level === "approval"
136
+ ? "Approval pending"
137
+ : item.statusKind === "note"
138
+ ? "Note"
139
+ : undefined,
140
+ text: item.text,
141
+ };
142
+ }
143
+ function toConversationArtifact(item) {
144
+ if (item.statusKind !== "artifact")
145
+ return null;
146
+ const event = item.events[0];
147
+ const artifactPath = stringMetadata(event?.metadata, "artifactPath") ??
148
+ stringMetadata(event?.metadata, "path");
149
+ const artifactUrl = stringMetadata(event?.metadata, "artifactUrl");
150
+ return {
151
+ id: item.id,
152
+ label: item.text || "Artifact",
153
+ path: artifactPath,
154
+ url: artifactUrl,
155
+ };
156
+ }
157
+ function preview(value) {
158
+ if (value === undefined || value === null)
159
+ return undefined;
160
+ const text = typeof value === "string" ? value : (JSON.stringify(value, null, 2) ?? "");
161
+ const trimmed = text.trim();
162
+ if (!trimmed)
163
+ return undefined;
164
+ return trimmed.length > 1800 ? `${trimmed.slice(0, 1800)}\n...` : trimmed;
165
+ }
166
+ function stringMetadata(metadata, key) {
167
+ const value = metadata?.[key];
168
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
169
+ }
170
+ function isCredentialText(value) {
171
+ return /No LLM provider key was found|Missing credentials/i.test(value);
172
+ }
173
+ function extractAttachments(events) {
174
+ for (const event of events) {
175
+ const raw = event.metadata?.attachments;
176
+ if (!Array.isArray(raw) || raw.length === 0)
177
+ continue;
178
+ const result = [];
179
+ for (const item of raw) {
180
+ if (!item || typeof item !== "object")
181
+ continue;
182
+ const record = item;
183
+ const name = typeof record.name === "string" ? record.name : undefined;
184
+ if (!name)
185
+ continue;
186
+ const attachment = { name };
187
+ if (typeof record.type === "string")
188
+ attachment.type = record.type;
189
+ if (typeof record.size === "number")
190
+ attachment.size = record.size;
191
+ if (typeof record.dataUrl === "string")
192
+ attachment.dataUrl = record.dataUrl;
193
+ result.push(attachment);
194
+ }
195
+ if (result.length > 0)
196
+ return result;
197
+ }
198
+ return [];
199
+ }
200
+ //# sourceMappingURL=code-agent-transcript.js.map