@agent-native/core 0.19.3 → 0.20.1
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.
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +12 -1
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +5 -0
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +17 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +210 -0
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/cli/code-agent-executor.d.ts +2 -0
- package/dist/cli/code-agent-executor.d.ts.map +1 -1
- package/dist/cli/code-agent-executor.js +39 -1
- package/dist/cli/code-agent-executor.js.map +1 -1
- package/dist/cli/code-agent-runs.d.ts +3 -0
- package/dist/cli/code-agent-runs.d.ts.map +1 -1
- package/dist/cli/code-agent-runs.js +3 -0
- package/dist/cli/code-agent-runs.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +8 -3
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +58 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +122 -50
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +172 -13
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-sidebar-state.d.ts +2 -0
- package/dist/client/agent-sidebar-state.d.ts.map +1 -1
- package/dist/client/agent-sidebar-state.js +32 -0
- package/dist/client/agent-sidebar-state.js.map +1 -1
- package/dist/client/code-agent-chat-adapter.d.ts +81 -0
- package/dist/client/code-agent-chat-adapter.d.ts.map +1 -0
- package/dist/client/code-agent-chat-adapter.js +297 -0
- package/dist/client/code-agent-chat-adapter.js.map +1 -0
- package/dist/client/composer/PromptComposer.d.ts +11 -0
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +7 -3
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +12 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +16 -7
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/index.d.ts +1 -0
- package/dist/client/composer/index.d.ts.map +1 -1
- package/dist/client/composer/index.js +1 -0
- package/dist/client/composer/index.js.map +1 -1
- package/dist/client/composer/prompt-attachments.d.ts +11 -0
- package/dist/client/composer/prompt-attachments.d.ts.map +1 -0
- package/dist/client/composer/prompt-attachments.js +45 -0
- package/dist/client/composer/prompt-attachments.js.map +1 -0
- package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
- package/dist/client/conversation/AgentConversation.js +124 -1
- package/dist/client/conversation/AgentConversation.js.map +1 -1
- package/dist/client/conversation/code-agent-transcript.d.ts +25 -0
- package/dist/client/conversation/code-agent-transcript.d.ts.map +1 -0
- package/dist/client/conversation/code-agent-transcript.js +200 -0
- package/dist/client/conversation/code-agent-transcript.js.map +1 -0
- package/dist/client/conversation/index.d.ts +2 -1
- package/dist/client/conversation/index.d.ts.map +1 -1
- package/dist/client/conversation/index.js +1 -0
- package/dist/client/conversation/index.js.map +1 -1
- package/dist/client/conversation/types.d.ts +8 -0
- package/dist/client/conversation/types.d.ts.map +1 -1
- package/dist/client/conversation/types.js.map +1 -1
- package/dist/client/conversation/use-near-bottom-autoscroll.d.ts.map +1 -1
- package/dist/client/conversation/use-near-bottom-autoscroll.js +26 -9
- package/dist/client/conversation/use-near-bottom-autoscroll.js.map +1 -1
- package/dist/client/index.d.ts +5 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +5 -2
- package/dist/client/index.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +2 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +21 -3
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.spec.js +16 -2
- package/dist/client/settings/useBuilderStatus.spec.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +3 -0
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/use-chat-models.d.ts +6 -1
- package/dist/client/use-chat-models.d.ts.map +1 -1
- package/dist/client/use-chat-models.js +7 -3
- package/dist/client/use-chat-models.js.map +1 -1
- package/dist/client/use-chat-models.spec.d.ts +2 -0
- package/dist/client/use-chat-models.spec.d.ts.map +1 -0
- package/dist/client/use-chat-models.spec.js +39 -0
- package/dist/client/use-chat-models.spec.js.map +1 -0
- package/dist/code-agents/background-controller.d.ts.map +1 -1
- package/dist/code-agents/background-controller.js +16 -0
- package/dist/code-agents/background-controller.js.map +1 -1
- package/dist/code-agents/index.d.ts +2 -0
- package/dist/code-agents/index.d.ts.map +1 -1
- package/dist/code-agents/index.js +2 -0
- package/dist/code-agents/index.js.map +1 -1
- package/dist/code-agents/prompt-attachments.d.ts +11 -0
- package/dist/code-agents/prompt-attachments.d.ts.map +1 -0
- package/dist/code-agents/prompt-attachments.js +23 -0
- package/dist/code-agents/prompt-attachments.js.map +1 -0
- package/dist/code-agents/transcript-normalizer.js +14 -5
- package/dist/code-agents/transcript-normalizer.js.map +1 -1
- package/dist/code-agents/transcript-order.d.ts +16 -0
- package/dist/code-agents/transcript-order.d.ts.map +1 -0
- package/dist/code-agents/transcript-order.js +47 -0
- package/dist/code-agents/transcript-order.js.map +1 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +1 -0
- package/dist/db/client.js.map +1 -1
- package/dist/extensions/routes.d.ts.map +1 -1
- package/dist/extensions/routes.js +18 -14
- package/dist/extensions/routes.js.map +1 -1
- package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -1
- package/dist/integrations/pending-tasks-retry-job.js +11 -1
- package/dist/integrations/pending-tasks-retry-job.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +6 -1
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +6 -2
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/secrets/substitution.d.ts +18 -0
- package/dist/secrets/substitution.d.ts.map +1 -1
- package/dist/secrets/substitution.js +74 -0
- package/dist/secrets/substitution.js.map +1 -1
- package/dist/server/deep-link.d.ts +0 -18
- package/dist/server/deep-link.d.ts.map +1 -1
- package/dist/server/deep-link.js +2 -1
- package/dist/server/deep-link.js.map +1 -1
- package/dist/server/open-route.d.ts.map +1 -1
- package/dist/server/open-route.js +23 -4
- package/dist/server/open-route.js.map +1 -1
- package/dist/shared/agent-sidebar-url.d.ts +6 -0
- package/dist/shared/agent-sidebar-url.d.ts.map +1 -0
- package/dist/shared/agent-sidebar-url.js +37 -0
- package/dist/shared/agent-sidebar-url.js.map +1 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +1 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/styles/agent-conversation.css +403 -0
- package/dist/styles/agent-native.css +2 -0
- 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,
|
|
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 (
|
|
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
|