@agent-native/core 0.32.2 → 0.32.17
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/README.md +3 -1
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +48 -10
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +12 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +104 -6
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/cli/app-skill.js +2 -2
- package/dist/cli/app-skill.js.map +1 -1
- package/dist/cli/code-agent-executor.d.ts.map +1 -1
- package/dist/cli/code-agent-executor.js +6 -1
- package/dist/cli/code-agent-executor.js.map +1 -1
- package/dist/cli/code-agent-output-smoother.d.ts +7 -0
- package/dist/cli/code-agent-output-smoother.d.ts.map +1 -0
- package/dist/cli/code-agent-output-smoother.js +111 -0
- package/dist/cli/code-agent-output-smoother.js.map +1 -0
- package/dist/cli/connect.d.ts.map +1 -1
- package/dist/cli/connect.js +5 -0
- package/dist/cli/connect.js.map +1 -1
- package/dist/cli/migrate.d.ts.map +1 -1
- package/dist/cli/migrate.js +17 -42
- package/dist/cli/migrate.js.map +1 -1
- package/dist/cli/skills.d.ts +23 -2
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +405 -41
- package/dist/cli/skills.js.map +1 -1
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +7 -105
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +41 -7
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AgentTaskCard.d.ts.map +1 -1
- package/dist/client/AgentTaskCard.js +0 -28
- package/dist/client/AgentTaskCard.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +8 -23
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +359 -205
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +254 -14
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +14 -9
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-chat.d.ts +24 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +73 -0
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/assistant-ui-recovery.d.ts +34 -0
- package/dist/client/assistant-ui-recovery.d.ts.map +1 -0
- package/dist/client/assistant-ui-recovery.js +122 -0
- package/dist/client/assistant-ui-recovery.js.map +1 -0
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +7 -1
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +7 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +22 -2
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/frame-protocol.d.ts +6 -2
- package/dist/client/frame-protocol.d.ts.map +1 -1
- package/dist/client/frame-protocol.js.map +1 -1
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +2 -1
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/progress/RunsTray.d.ts +13 -3
- package/dist/client/progress/RunsTray.d.ts.map +1 -1
- package/dist/client/progress/RunsTray.js +105 -36
- package/dist/client/progress/RunsTray.js.map +1 -1
- package/dist/client/route-warmup.d.ts +61 -0
- package/dist/client/route-warmup.d.ts.map +1 -0
- package/dist/client/route-warmup.js +456 -0
- package/dist/client/route-warmup.js.map +1 -0
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +2 -1
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +5 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +10 -4
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/use-action.d.ts +1 -0
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +22 -4
- package/dist/client/use-action.js.map +1 -1
- package/dist/code-agents/background-run.d.ts +2 -0
- package/dist/code-agents/background-run.d.ts.map +1 -1
- package/dist/code-agents/background-run.js.map +1 -1
- package/dist/db/client.d.ts +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +25 -1
- package/dist/db/client.js.map +1 -1
- package/dist/deploy/build.d.ts +4 -0
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +171 -14
- package/dist/deploy/build.js.map +1 -1
- package/dist/deploy/immutable-assets.d.ts +1 -0
- package/dist/deploy/immutable-assets.d.ts.map +1 -1
- package/dist/deploy/immutable-assets.js +1 -0
- package/dist/deploy/immutable-assets.js.map +1 -1
- package/dist/index.browser.d.ts +1 -1
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/connect-route.d.ts.map +1 -1
- package/dist/mcp/connect-route.js +118 -82
- package/dist/mcp/connect-route.js.map +1 -1
- package/dist/progress/routes.d.ts.map +1 -1
- package/dist/progress/routes.js +1 -0
- package/dist/progress/routes.js.map +1 -1
- package/dist/progress/store.d.ts +13 -0
- package/dist/progress/store.d.ts.map +1 -1
- package/dist/progress/store.js +18 -0
- package/dist/progress/store.js.map +1 -1
- package/dist/progress/types.d.ts +2 -0
- package/dist/progress/types.d.ts.map +1 -1
- package/dist/progress/types.js.map +1 -1
- package/dist/scripts/db/wipe-leaked-builder-keys.d.ts +2 -2
- package/dist/scripts/db/wipe-leaked-builder-keys.d.ts.map +1 -1
- package/dist/scripts/db/wipe-leaked-builder-keys.js +14 -3
- package/dist/scripts/db/wipe-leaked-builder-keys.js.map +1 -1
- package/dist/server/action-routes.d.ts +1 -0
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +36 -2
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +123 -25
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +14 -1
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/agent-teams-run-queue.d.ts +80 -0
- package/dist/server/agent-teams-run-queue.d.ts.map +1 -0
- package/dist/server/agent-teams-run-queue.js +208 -0
- package/dist/server/agent-teams-run-queue.js.map +1 -0
- package/dist/server/agent-teams.d.ts +67 -0
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +607 -180
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/auth-marketing.d.ts.map +1 -1
- package/dist/server/auth-marketing.js +0 -64
- package/dist/server/auth-marketing.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +67 -14
- package/dist/server/auth.js.map +1 -1
- package/dist/server/builder-browser.d.ts +12 -2
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +24 -0
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +66 -5
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +10 -0
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +82 -3
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/csrf.js +3 -0
- package/dist/server/csrf.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/onboarding-html.d.ts +1 -0
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +14 -1
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/self-dispatch.d.ts +44 -0
- package/dist/server/self-dispatch.d.ts.map +1 -0
- package/dist/server/self-dispatch.js +113 -0
- package/dist/server/self-dispatch.js.map +1 -0
- package/dist/server/social-og-image.d.ts +14 -0
- package/dist/server/social-og-image.d.ts.map +1 -0
- package/dist/server/social-og-image.js +251 -0
- package/dist/server/social-og-image.js.map +1 -0
- package/dist/server/ssr-handler.d.ts +1 -1
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +27 -11
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/shared/cache-control.d.ts +7 -0
- package/dist/shared/cache-control.d.ts.map +1 -1
- package/dist/shared/cache-control.js +7 -0
- package/dist/shared/cache-control.js.map +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/route-warmup-config.d.ts +28 -0
- package/dist/shared/route-warmup-config.d.ts.map +1 -0
- package/dist/shared/route-warmup-config.js +58 -0
- package/dist/shared/route-warmup-config.js.map +1 -0
- package/dist/shared/social-meta.d.ts +5 -0
- package/dist/shared/social-meta.d.ts.map +1 -1
- package/dist/shared/social-meta.js +36 -2
- package/dist/shared/social-meta.js.map +1 -1
- package/dist/shared/streaming-text-smoothing.d.ts +12 -0
- package/dist/shared/streaming-text-smoothing.d.ts.map +1 -0
- package/dist/shared/streaming-text-smoothing.js +52 -0
- package/dist/shared/streaming-text-smoothing.js.map +1 -0
- package/dist/styles/agent-native.css +4 -4
- package/dist/templates/default/AGENTS.md +9 -4
- package/dist/templates/default/DEVELOPING.md +15 -1
- package/dist/templates/workspace-core/AGENTS.md +7 -3
- package/dist/templates/workspace-root/AGENTS.md +7 -3
- package/dist/vite/client.d.ts +13 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +26 -0
- package/dist/vite/client.js.map +1 -1
- package/dist/vite/index.d.ts +1 -0
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js.map +1 -1
- package/docs/content/client.md +62 -1
- package/docs/content/code-agents-ui.md +6 -13
- package/docs/content/context-awareness.md +186 -21
- package/docs/content/deployment.md +8 -11
- package/docs/content/dispatch.md +1 -1
- package/docs/content/external-agents.md +32 -2
- package/docs/content/migration-workbench.md +4 -21
- package/docs/content/multi-app-workspace.md +1 -1
- package/docs/content/recurring-jobs.md +1 -1
- package/docs/content/security.md +0 -1
- package/docs/content/sharing.md +1 -3
- package/docs/content/skills-guide.md +12 -10
- package/docs/content/template-assets.md +21 -1
- package/docs/content/template-design.md +23 -5
- package/docs/content/template-dispatch.md +1 -1
- package/package.json +2 -1
- package/src/templates/default/AGENTS.md +9 -4
- package/src/templates/default/DEVELOPING.md +15 -1
- package/src/templates/workspace-core/AGENTS.md +7 -3
- package/src/templates/workspace-root/AGENTS.md +7 -3
|
@@ -63,11 +63,35 @@ export interface AgentChatMessage {
|
|
|
63
63
|
*/
|
|
64
64
|
background?: boolean;
|
|
65
65
|
}
|
|
66
|
+
export interface AgentChatContextItem {
|
|
67
|
+
/** Stable key used to replace an existing context nugget. */
|
|
68
|
+
key: string;
|
|
69
|
+
/** Short label shown in the composer context chip. */
|
|
70
|
+
title: string;
|
|
71
|
+
/** Hidden context included with the next submitted prompt. */
|
|
72
|
+
context: string;
|
|
73
|
+
}
|
|
74
|
+
export interface AgentChatContextMessage extends AgentChatContextItem {
|
|
75
|
+
/**
|
|
76
|
+
* Whether to open the agent sidebar if it's currently hidden.
|
|
77
|
+
* Defaults to true so the user can see the staged context.
|
|
78
|
+
*/
|
|
79
|
+
openSidebar?: boolean;
|
|
80
|
+
}
|
|
66
81
|
/** Generate a unique tab ID */
|
|
67
82
|
export declare function generateTabId(): string;
|
|
83
|
+
export declare function normalizeAgentChatContextItem(item: unknown): AgentChatContextItem | null;
|
|
84
|
+
export declare function formatAgentChatContextItemsForPrompt(items: readonly AgentChatContextItem[]): string;
|
|
85
|
+
export declare function appendAgentChatContextToMessage(message: string, context: string): string;
|
|
68
86
|
/**
|
|
69
87
|
* Send a message to the agent chat via postMessage.
|
|
70
88
|
* Returns the stable tabId for tracking this chat run.
|
|
71
89
|
*/
|
|
72
90
|
export declare function sendToAgentChat(opts: AgentChatMessage): string;
|
|
91
|
+
/**
|
|
92
|
+
* Add or replace a keyed context nugget in the active agent chat composer.
|
|
93
|
+
* The context is not submitted until the user sends the prompt.
|
|
94
|
+
*/
|
|
95
|
+
export declare function setContextToAgentChat(opts: AgentChatContextMessage): void;
|
|
96
|
+
export declare const addContextToAgentChat: typeof setContextToAgentChat;
|
|
73
97
|
//# sourceMappingURL=agent-chat.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-chat.d.ts","sourceRoot":"","sources":["../../src/client/agent-chat.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAcrE,MAAM,WAAW,gBAAgB;IAC/B,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,yCAAyC;IACzC,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,kFAAkF;IAClF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6FAA6F;IAC7F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"agent-chat.d.ts","sourceRoot":"","sources":["../../src/client/agent-chat.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAcrE,MAAM,WAAW,gBAAgB;IAC/B,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,yCAAyC;IACzC,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,kFAAkF;IAClF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6FAA6F;IAC7F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,6DAA6D;IAC7D,GAAG,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,uBAAwB,SAAQ,oBAAoB;IACnE;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA4BD,+BAA+B;AAC/B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,OAAO,GACZ,oBAAoB,GAAG,IAAI,CAkB7B;AAED,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,SAAS,oBAAoB,EAAE,GACrC,MAAM,CAMR;AAED,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,MAAM,CAIR;AAuBD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CA8E9D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,uBAAuB,GAAG,IAAI,CAoCzE;AAED,eAAO,MAAM,qBAAqB,8BAAwB,CAAC"}
|
|
@@ -11,6 +11,7 @@ import { isEmbedAuthActive, isEmbedMcpChatBridgeActive, markEmbedMcpChatBridgeAc
|
|
|
11
11
|
import { sendMcpAppHostMessage } from "./mcp-app-host.js";
|
|
12
12
|
import { isInBuilderFrame, isTrustedBuilderMessage, sendToBuilderChat, } from "./builder-frame.js";
|
|
13
13
|
const AGENT_CHAT_MESSAGE_TYPE = "agentNative.submitChat";
|
|
14
|
+
const AGENT_CHAT_CONTEXT_MESSAGE_TYPE = "agentNative.setChatContext";
|
|
14
15
|
const AGENT_PANEL_PREPARE_EVENT = "agent-panel:prepare";
|
|
15
16
|
/**
|
|
16
17
|
* Listen for chatRunning messages from the frame (postMessage)
|
|
@@ -33,6 +34,38 @@ if (typeof window !== "undefined") {
|
|
|
33
34
|
export function generateTabId() {
|
|
34
35
|
return `chat-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
35
36
|
}
|
|
37
|
+
export function normalizeAgentChatContextItem(item) {
|
|
38
|
+
if (typeof item !== "object" || item === null)
|
|
39
|
+
return null;
|
|
40
|
+
const candidate = item;
|
|
41
|
+
if (typeof candidate.key !== "string" ||
|
|
42
|
+
typeof candidate.context !== "string" ||
|
|
43
|
+
typeof candidate.title !== "string") {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const key = candidate.key.trim();
|
|
47
|
+
const context = candidate.context.trim();
|
|
48
|
+
if (!key || !context)
|
|
49
|
+
return null;
|
|
50
|
+
return {
|
|
51
|
+
key,
|
|
52
|
+
title: candidate.title.trim() || key,
|
|
53
|
+
context,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export function formatAgentChatContextItemsForPrompt(items) {
|
|
57
|
+
return items
|
|
58
|
+
.map(normalizeAgentChatContextItem)
|
|
59
|
+
.filter((item) => item !== null)
|
|
60
|
+
.map((item) => [`## ${item.title}`, item.context].join("\n"))
|
|
61
|
+
.join("\n\n");
|
|
62
|
+
}
|
|
63
|
+
export function appendAgentChatContextToMessage(message, context) {
|
|
64
|
+
const trimmedContext = context.trim();
|
|
65
|
+
if (!trimmedContext)
|
|
66
|
+
return message;
|
|
67
|
+
return `${message.trim()}\n\n<context>\n${trimmedContext}\n</context>`;
|
|
68
|
+
}
|
|
36
69
|
function isMcpAppChatBridgeEnabled() {
|
|
37
70
|
if (typeof window === "undefined" || window.parent === window)
|
|
38
71
|
return false;
|
|
@@ -124,4 +157,44 @@ export function sendToAgentChat(opts) {
|
|
|
124
157
|
}
|
|
125
158
|
return tabId;
|
|
126
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Add or replace a keyed context nugget in the active agent chat composer.
|
|
162
|
+
* The context is not submitted until the user sends the prompt.
|
|
163
|
+
*/
|
|
164
|
+
export function setContextToAgentChat(opts) {
|
|
165
|
+
const item = normalizeAgentChatContextItem(opts);
|
|
166
|
+
if (!item || typeof window === "undefined")
|
|
167
|
+
return;
|
|
168
|
+
const payload = {
|
|
169
|
+
type: AGENT_CHAT_CONTEXT_MESSAGE_TYPE,
|
|
170
|
+
data: item,
|
|
171
|
+
};
|
|
172
|
+
const shouldOpenSidebar = opts.openSidebar !== false;
|
|
173
|
+
const targetSelf = isInBuilderFrame() || isDirectMcpAppEmbedSession();
|
|
174
|
+
const target = targetSelf
|
|
175
|
+
? window
|
|
176
|
+
: window.parent !== window
|
|
177
|
+
? window.parent
|
|
178
|
+
: window;
|
|
179
|
+
const targetOrigin = targetSelf
|
|
180
|
+
? window.location.origin
|
|
181
|
+
: getFramePostMessageTargetOrigin() || window.location.origin;
|
|
182
|
+
if (shouldOpenSidebar) {
|
|
183
|
+
window.dispatchEvent(new CustomEvent("agent-panel:set-mode", {
|
|
184
|
+
detail: { mode: "chat" },
|
|
185
|
+
}));
|
|
186
|
+
window.dispatchEvent(new CustomEvent("agent-panel:open"));
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
window.dispatchEvent(new CustomEvent(AGENT_PANEL_PREPARE_EVENT));
|
|
190
|
+
}
|
|
191
|
+
const postToTarget = () => target.postMessage(payload, targetOrigin);
|
|
192
|
+
if (target === window) {
|
|
193
|
+
setTimeout(postToTarget, 0);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
postToTarget();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
export const addContextToAgentChat = setContextToAgentChat;
|
|
127
200
|
//# sourceMappingURL=agent-chat.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-chat.js","sourceRoot":"","sources":["../../src/client/agent-chat.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Agent Chat Bridge (browser)\n *\n * Sends structured messages to the agent chat from UI interactions.\n * Messages are sent via postMessage to the parent window (or self if top-level).\n * Builder frames are special: code requests go to Builder, but content prompts\n * stay inside the embedded app so its own AgentSidebar can receive them.\n */\n\nimport {\n getFramePostMessageTargetOrigin,\n isTrustedFrameMessage,\n} from \"./frame.js\";\nimport type { ReasoningEffort } from \"../shared/reasoning-effort.js\";\nimport {\n isEmbedAuthActive,\n isEmbedMcpChatBridgeActive,\n markEmbedMcpChatBridgeActive,\n readEmbedMcpChatBridgeFlagFromUrl,\n} from \"./embed-auth.js\";\nimport { sendMcpAppHostMessage } from \"./mcp-app-host.js\";\nimport {\n isInBuilderFrame,\n isTrustedBuilderMessage,\n sendToBuilderChat,\n} from \"./builder-frame.js\";\n\nexport interface AgentChatMessage {\n /** The visible prompt message sent to the chat */\n message: string;\n /** Hidden context appended to the message (not shown in chat UI) */\n context?: string;\n /** true = auto-submit, false = prefill only, omit = use project setting */\n submit?: boolean;\n /** Optional project slug for structured context */\n projectSlug?: string;\n /** Optional preset name for downstream consumers */\n preset?: string;\n /** Optional reference image paths */\n referenceImagePaths?: string[];\n /** Optional uploaded reference images */\n uploadedReferenceImages?: string[];\n /** Optional image data URLs to include in the submitted chat message */\n images?: string[];\n /** Stable tab identifier — auto-generated if omitted */\n tabId?: string;\n /**\n * Message routing type:\n * - \"content\" (default): stays in the embedded app agent for content/data operations\n * - \"code\": routes to the code editing frame (Agent Native Desktop or Builder.io)\n *\n * When type is \"code\" and no frame is connected, a dialog is shown.\n * `requiresCode: true` is treated as `type: \"code\"` for backward compatibility.\n */\n type?: \"content\" | \"code\";\n /** @deprecated Use `type: \"code\"` instead. If true, treated as `type: \"code\"`. */\n requiresCode?: boolean;\n /** Model preference for this sub-agent (e.g. \"claude-haiku-4-5\"). Uses default if omitted */\n model?: string;\n /** Engine preference paired with model for cross-provider switches. */\n engine?: string;\n /** Reasoning effort preference paired with model. */\n effort?: ReasoningEffort;\n /** Scoped system prompt additions for this sub-agent */\n instructions?: string;\n /**\n * Whether to open the agent sidebar if it's currently hidden.\n * Defaults to true — submitting a chat should make the response visible.\n * Pass `false` for background/silent sends that shouldn't pop the UI open.\n */\n openSidebar?: boolean;\n /**\n * When true, opens a new chat tab before sending the message.\n * Use for creation requests (create tool, dashboard, etc.) that deserve\n * their own isolated thread rather than cluttering an existing conversation.\n */\n newTab?: boolean;\n /**\n * When true with newTab, creates the tab in the background without\n * focusing it or opening the sidebar. The message runs silently.\n */\n background?: boolean;\n}\n\nconst AGENT_CHAT_MESSAGE_TYPE = \"agentNative.submitChat\";\nconst AGENT_PANEL_PREPARE_EVENT = \"agent-panel:prepare\";\n\n/**\n * Listen for chatRunning messages from the frame (postMessage)\n * and re-dispatch as a CustomEvent so hooks like useAgentChatGenerating() work.\n */\nif (typeof window !== \"undefined\") {\n window.addEventListener(\"message\", (event) => {\n if (!isTrustedFrameMessage(event) && !isTrustedBuilderMessage(event)) {\n return;\n }\n if (\n event.data?.type === \"agentNative.chatRunning\" ||\n event.data?.type === \"builder.chatRunning\"\n ) {\n window.dispatchEvent(\n new CustomEvent(\"agentNative.chatRunning\", {\n detail: event.data.detail ?? event.data.data,\n }),\n );\n }\n });\n}\n\n/** Generate a unique tab ID */\nexport function generateTabId(): string {\n return `chat-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction isMcpAppChatBridgeEnabled(): boolean {\n if (typeof window === \"undefined\" || window.parent === window) return false;\n if (readEmbedMcpChatBridgeFlagFromUrl()) markEmbedMcpChatBridgeActive();\n return isEmbedMcpChatBridgeActive() && isEmbedAuthActive();\n}\n\nfunction isDirectMcpAppEmbedSession(): boolean {\n if (typeof window === \"undefined\" || window.parent === window) return false;\n if (readEmbedMcpChatBridgeFlagFromUrl()) markEmbedMcpChatBridgeActive();\n return isEmbedAuthActive() && !isEmbedMcpChatBridgeActive();\n}\n\nfunction dispatchAgentChatRunning(isRunning: boolean): void {\n if (typeof window === \"undefined\") return;\n window.dispatchEvent(\n new CustomEvent(\"agentNative.chatRunning\", {\n detail: { isRunning },\n }),\n );\n}\n\n/**\n * Send a message to the agent chat via postMessage.\n * Returns the stable tabId for tracking this chat run.\n */\nexport function sendToAgentChat(opts: AgentChatMessage): string {\n const tabId = opts.tabId ?? generateTabId();\n const isCodeRequest = opts.type === \"code\" || opts.requiresCode === true;\n if (isCodeRequest && isInBuilderFrame()) {\n sendToBuilderChat({\n message: opts.message,\n context: opts.context,\n submit: opts.submit,\n });\n return tabId;\n }\n\n const payload = {\n type: AGENT_CHAT_MESSAGE_TYPE,\n data: { ...opts, tabId },\n };\n\n if (opts.submit !== false && isMcpAppChatBridgeEnabled()) {\n const directHostMessage = sendMcpAppHostMessage({\n message: opts.message,\n context: opts.context,\n });\n if (directHostMessage) {\n void Promise.resolve(directHostMessage)\n .then((ok) => {\n if (!ok) {\n window.parent.postMessage(\n payload,\n getFramePostMessageTargetOrigin() || \"*\",\n );\n }\n })\n .finally(() => {\n dispatchAgentChatRunning(false);\n });\n return tabId;\n }\n window.parent.postMessage(\n payload,\n getFramePostMessageTargetOrigin() || \"*\",\n );\n return tabId;\n }\n\n const shouldOpenSidebar = opts.openSidebar !== false && !opts.background;\n\n const targetSelf =\n !isCodeRequest && (isInBuilderFrame() || isDirectMcpAppEmbedSession());\n const target = targetSelf\n ? window\n : window.parent !== window\n ? window.parent\n : window;\n const targetOrigin = targetSelf\n ? window.location.origin\n : getFramePostMessageTargetOrigin() || window.location.origin;\n if (shouldOpenSidebar) {\n window.dispatchEvent(\n new CustomEvent(\"agent-panel:set-mode\", {\n detail: { mode: \"chat\" },\n }),\n );\n window.dispatchEvent(new CustomEvent(\"agent-panel:open\"));\n } else if (!isCodeRequest) {\n window.dispatchEvent(new CustomEvent(AGENT_PANEL_PREPARE_EVENT));\n }\n\n const postToTarget = () => target.postMessage(payload, targetOrigin);\n\n // When the local app owns the chat surface, opening/preparing the sidebar\n // may mount the MessageEvent listener that receives this payload. Defer the\n // post one tick so a closed sidebar cannot drop the prompt while mounting.\n if (!isCodeRequest && target === window) {\n setTimeout(postToTarget, 0);\n } else {\n postToTarget();\n }\n return tabId;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-chat.js","sourceRoot":"","sources":["../../src/client/agent-chat.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,+BAA+B,EAC/B,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,4BAA4B,EAC5B,iCAAiC,GAClC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AA4E5B,MAAM,uBAAuB,GAAG,wBAAwB,CAAC;AACzD,MAAM,+BAA+B,GAAG,4BAA4B,CAAC;AACrE,MAAM,yBAAyB,GAAG,qBAAqB,CAAC;AAExD;;;GAGG;AACH,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;IAClC,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;QAC3C,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,EAAE,CAAC;YACrE,OAAO;QACT,CAAC;QACD,IACE,KAAK,CAAC,IAAI,EAAE,IAAI,KAAK,yBAAyB;YAC9C,KAAK,CAAC,IAAI,EAAE,IAAI,KAAK,qBAAqB,EAC1C,CAAC;YACD,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAC,yBAAyB,EAAE;gBACzC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI;aAC7C,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,+BAA+B;AAC/B,MAAM,UAAU,aAAa;IAC3B,OAAO,QAAQ,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC3C,IAAa;IAEb,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC3D,MAAM,SAAS,GAAG,IAAqC,CAAC;IACxD,IACE,OAAO,SAAS,CAAC,GAAG,KAAK,QAAQ;QACjC,OAAO,SAAS,CAAC,OAAO,KAAK,QAAQ;QACrC,OAAO,SAAS,CAAC,KAAK,KAAK,QAAQ,EACnC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IACjC,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACzC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO;QACL,GAAG;QACH,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG;QACpC,OAAO;KACR,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oCAAoC,CAClD,KAAsC;IAEtC,OAAO,KAAK;SACT,GAAG,CAAC,6BAA6B,CAAC;SAClC,MAAM,CAAC,CAAC,IAAI,EAAgC,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC;SAC7D,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAC5D,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC7C,OAAe,EACf,OAAe;IAEf,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IACtC,IAAI,CAAC,cAAc;QAAE,OAAO,OAAO,CAAC;IACpC,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,kBAAkB,cAAc,cAAc,CAAC;AACzE,CAAC;AAED,SAAS,yBAAyB;IAChC,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IAC5E,IAAI,iCAAiC,EAAE;QAAE,4BAA4B,EAAE,CAAC;IACxE,OAAO,0BAA0B,EAAE,IAAI,iBAAiB,EAAE,CAAC;AAC7D,CAAC;AAED,SAAS,0BAA0B;IACjC,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IAC5E,IAAI,iCAAiC,EAAE;QAAE,4BAA4B,EAAE,CAAC;IACxE,OAAO,iBAAiB,EAAE,IAAI,CAAC,0BAA0B,EAAE,CAAC;AAC9D,CAAC;AAED,SAAS,wBAAwB,CAAC,SAAkB;IAClD,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO;IAC1C,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAC,yBAAyB,EAAE;QACzC,MAAM,EAAE,EAAE,SAAS,EAAE;KACtB,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAAsB;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,aAAa,EAAE,CAAC;IAC5C,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC;IACzE,IAAI,aAAa,IAAI,gBAAgB,EAAE,EAAE,CAAC;QACxC,iBAAiB,CAAC;YAChB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,OAAO,GAAG;QACd,IAAI,EAAE,uBAAuB;QAC7B,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE;KACzB,CAAC;IAEF,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,IAAI,yBAAyB,EAAE,EAAE,CAAC;QACzD,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;YAC9C,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAC;QACH,IAAI,iBAAiB,EAAE,CAAC;YACtB,KAAK,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC;iBACpC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE;gBACX,IAAI,CAAC,EAAE,EAAE,CAAC;oBACR,MAAM,CAAC,MAAM,CAAC,WAAW,CACvB,OAAO,EACP,+BAA+B,EAAE,IAAI,GAAG,CACzC,CAAC;gBACJ,CAAC;YACH,CAAC,CAAC;iBACD,OAAO,CAAC,GAAG,EAAE;gBACZ,wBAAwB,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;YACL,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,CAAC,MAAM,CAAC,WAAW,CACvB,OAAO,EACP,+BAA+B,EAAE,IAAI,GAAG,CACzC,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,iBAAiB,GAAG,IAAI,CAAC,WAAW,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;IAEzE,MAAM,UAAU,GACd,CAAC,aAAa,IAAI,CAAC,gBAAgB,EAAE,IAAI,0BAA0B,EAAE,CAAC,CAAC;IACzE,MAAM,MAAM,GAAG,UAAU;QACvB,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM;YACxB,CAAC,CAAC,MAAM,CAAC,MAAM;YACf,CAAC,CAAC,MAAM,CAAC;IACb,MAAM,YAAY,GAAG,UAAU;QAC7B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM;QACxB,CAAC,CAAC,+BAA+B,EAAE,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;IAChE,IAAI,iBAAiB,EAAE,CAAC;QACtB,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAC,sBAAsB,EAAE;YACtC,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;SACzB,CAAC,CACH,CAAC;QACF,MAAM,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC5D,CAAC;SAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC1B,MAAM,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAErE,0EAA0E;IAC1E,4EAA4E;IAC5E,2EAA2E;IAC3E,IAAI,CAAC,aAAa,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACxC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC;SAAM,CAAC;QACN,YAAY,EAAE,CAAC;IACjB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAA6B;IACjE,MAAM,IAAI,GAAG,6BAA6B,CAAC,IAAI,CAAC,CAAC;IACjD,IAAI,CAAC,IAAI,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO;IAEnD,MAAM,OAAO,GAAG;QACd,IAAI,EAAE,+BAA+B;QACrC,IAAI,EAAE,IAAI;KACX,CAAC;IACF,MAAM,iBAAiB,GAAG,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC;IACrD,MAAM,UAAU,GAAG,gBAAgB,EAAE,IAAI,0BAA0B,EAAE,CAAC;IACtE,MAAM,MAAM,GAAG,UAAU;QACvB,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM;YACxB,CAAC,CAAC,MAAM,CAAC,MAAM;YACf,CAAC,CAAC,MAAM,CAAC;IACb,MAAM,YAAY,GAAG,UAAU;QAC7B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM;QACxB,CAAC,CAAC,+BAA+B,EAAE,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;IAEhE,IAAI,iBAAiB,EAAE,CAAC;QACtB,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAC,sBAAsB,EAAE;YACtC,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;SACzB,CAAC,CACH,CAAC;QACF,MAAM,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC5D,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACrE,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC;SAAM,CAAC;QACN,YAAY,EAAE,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,qBAAqB,CAAC","sourcesContent":["/**\n * Agent Chat Bridge (browser)\n *\n * Sends structured messages to the agent chat from UI interactions.\n * Messages are sent via postMessage to the parent window (or self if top-level).\n * Builder frames are special: code requests go to Builder, but content prompts\n * stay inside the embedded app so its own AgentSidebar can receive them.\n */\n\nimport {\n getFramePostMessageTargetOrigin,\n isTrustedFrameMessage,\n} from \"./frame.js\";\nimport type { ReasoningEffort } from \"../shared/reasoning-effort.js\";\nimport {\n isEmbedAuthActive,\n isEmbedMcpChatBridgeActive,\n markEmbedMcpChatBridgeActive,\n readEmbedMcpChatBridgeFlagFromUrl,\n} from \"./embed-auth.js\";\nimport { sendMcpAppHostMessage } from \"./mcp-app-host.js\";\nimport {\n isInBuilderFrame,\n isTrustedBuilderMessage,\n sendToBuilderChat,\n} from \"./builder-frame.js\";\n\nexport interface AgentChatMessage {\n /** The visible prompt message sent to the chat */\n message: string;\n /** Hidden context appended to the message (not shown in chat UI) */\n context?: string;\n /** true = auto-submit, false = prefill only, omit = use project setting */\n submit?: boolean;\n /** Optional project slug for structured context */\n projectSlug?: string;\n /** Optional preset name for downstream consumers */\n preset?: string;\n /** Optional reference image paths */\n referenceImagePaths?: string[];\n /** Optional uploaded reference images */\n uploadedReferenceImages?: string[];\n /** Optional image data URLs to include in the submitted chat message */\n images?: string[];\n /** Stable tab identifier — auto-generated if omitted */\n tabId?: string;\n /**\n * Message routing type:\n * - \"content\" (default): stays in the embedded app agent for content/data operations\n * - \"code\": routes to the code editing frame (Agent Native Desktop or Builder.io)\n *\n * When type is \"code\" and no frame is connected, a dialog is shown.\n * `requiresCode: true` is treated as `type: \"code\"` for backward compatibility.\n */\n type?: \"content\" | \"code\";\n /** @deprecated Use `type: \"code\"` instead. If true, treated as `type: \"code\"`. */\n requiresCode?: boolean;\n /** Model preference for this sub-agent (e.g. \"claude-haiku-4-5\"). Uses default if omitted */\n model?: string;\n /** Engine preference paired with model for cross-provider switches. */\n engine?: string;\n /** Reasoning effort preference paired with model. */\n effort?: ReasoningEffort;\n /** Scoped system prompt additions for this sub-agent */\n instructions?: string;\n /**\n * Whether to open the agent sidebar if it's currently hidden.\n * Defaults to true — submitting a chat should make the response visible.\n * Pass `false` for background/silent sends that shouldn't pop the UI open.\n */\n openSidebar?: boolean;\n /**\n * When true, opens a new chat tab before sending the message.\n * Use for creation requests (create tool, dashboard, etc.) that deserve\n * their own isolated thread rather than cluttering an existing conversation.\n */\n newTab?: boolean;\n /**\n * When true with newTab, creates the tab in the background without\n * focusing it or opening the sidebar. The message runs silently.\n */\n background?: boolean;\n}\n\nexport interface AgentChatContextItem {\n /** Stable key used to replace an existing context nugget. */\n key: string;\n /** Short label shown in the composer context chip. */\n title: string;\n /** Hidden context included with the next submitted prompt. */\n context: string;\n}\n\nexport interface AgentChatContextMessage extends AgentChatContextItem {\n /**\n * Whether to open the agent sidebar if it's currently hidden.\n * Defaults to true so the user can see the staged context.\n */\n openSidebar?: boolean;\n}\n\nconst AGENT_CHAT_MESSAGE_TYPE = \"agentNative.submitChat\";\nconst AGENT_CHAT_CONTEXT_MESSAGE_TYPE = \"agentNative.setChatContext\";\nconst AGENT_PANEL_PREPARE_EVENT = \"agent-panel:prepare\";\n\n/**\n * Listen for chatRunning messages from the frame (postMessage)\n * and re-dispatch as a CustomEvent so hooks like useAgentChatGenerating() work.\n */\nif (typeof window !== \"undefined\") {\n window.addEventListener(\"message\", (event) => {\n if (!isTrustedFrameMessage(event) && !isTrustedBuilderMessage(event)) {\n return;\n }\n if (\n event.data?.type === \"agentNative.chatRunning\" ||\n event.data?.type === \"builder.chatRunning\"\n ) {\n window.dispatchEvent(\n new CustomEvent(\"agentNative.chatRunning\", {\n detail: event.data.detail ?? event.data.data,\n }),\n );\n }\n });\n}\n\n/** Generate a unique tab ID */\nexport function generateTabId(): string {\n return `chat-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\nexport function normalizeAgentChatContextItem(\n item: unknown,\n): AgentChatContextItem | null {\n if (typeof item !== \"object\" || item === null) return null;\n const candidate = item as Partial<AgentChatContextItem>;\n if (\n typeof candidate.key !== \"string\" ||\n typeof candidate.context !== \"string\" ||\n typeof candidate.title !== \"string\"\n ) {\n return null;\n }\n const key = candidate.key.trim();\n const context = candidate.context.trim();\n if (!key || !context) return null;\n return {\n key,\n title: candidate.title.trim() || key,\n context,\n };\n}\n\nexport function formatAgentChatContextItemsForPrompt(\n items: readonly AgentChatContextItem[],\n): string {\n return items\n .map(normalizeAgentChatContextItem)\n .filter((item): item is AgentChatContextItem => item !== null)\n .map((item) => [`## ${item.title}`, item.context].join(\"\\n\"))\n .join(\"\\n\\n\");\n}\n\nexport function appendAgentChatContextToMessage(\n message: string,\n context: string,\n): string {\n const trimmedContext = context.trim();\n if (!trimmedContext) return message;\n return `${message.trim()}\\n\\n<context>\\n${trimmedContext}\\n</context>`;\n}\n\nfunction isMcpAppChatBridgeEnabled(): boolean {\n if (typeof window === \"undefined\" || window.parent === window) return false;\n if (readEmbedMcpChatBridgeFlagFromUrl()) markEmbedMcpChatBridgeActive();\n return isEmbedMcpChatBridgeActive() && isEmbedAuthActive();\n}\n\nfunction isDirectMcpAppEmbedSession(): boolean {\n if (typeof window === \"undefined\" || window.parent === window) return false;\n if (readEmbedMcpChatBridgeFlagFromUrl()) markEmbedMcpChatBridgeActive();\n return isEmbedAuthActive() && !isEmbedMcpChatBridgeActive();\n}\n\nfunction dispatchAgentChatRunning(isRunning: boolean): void {\n if (typeof window === \"undefined\") return;\n window.dispatchEvent(\n new CustomEvent(\"agentNative.chatRunning\", {\n detail: { isRunning },\n }),\n );\n}\n\n/**\n * Send a message to the agent chat via postMessage.\n * Returns the stable tabId for tracking this chat run.\n */\nexport function sendToAgentChat(opts: AgentChatMessage): string {\n const tabId = opts.tabId ?? generateTabId();\n const isCodeRequest = opts.type === \"code\" || opts.requiresCode === true;\n if (isCodeRequest && isInBuilderFrame()) {\n sendToBuilderChat({\n message: opts.message,\n context: opts.context,\n submit: opts.submit,\n });\n return tabId;\n }\n\n const payload = {\n type: AGENT_CHAT_MESSAGE_TYPE,\n data: { ...opts, tabId },\n };\n\n if (opts.submit !== false && isMcpAppChatBridgeEnabled()) {\n const directHostMessage = sendMcpAppHostMessage({\n message: opts.message,\n context: opts.context,\n });\n if (directHostMessage) {\n void Promise.resolve(directHostMessage)\n .then((ok) => {\n if (!ok) {\n window.parent.postMessage(\n payload,\n getFramePostMessageTargetOrigin() || \"*\",\n );\n }\n })\n .finally(() => {\n dispatchAgentChatRunning(false);\n });\n return tabId;\n }\n window.parent.postMessage(\n payload,\n getFramePostMessageTargetOrigin() || \"*\",\n );\n return tabId;\n }\n\n const shouldOpenSidebar = opts.openSidebar !== false && !opts.background;\n\n const targetSelf =\n !isCodeRequest && (isInBuilderFrame() || isDirectMcpAppEmbedSession());\n const target = targetSelf\n ? window\n : window.parent !== window\n ? window.parent\n : window;\n const targetOrigin = targetSelf\n ? window.location.origin\n : getFramePostMessageTargetOrigin() || window.location.origin;\n if (shouldOpenSidebar) {\n window.dispatchEvent(\n new CustomEvent(\"agent-panel:set-mode\", {\n detail: { mode: \"chat\" },\n }),\n );\n window.dispatchEvent(new CustomEvent(\"agent-panel:open\"));\n } else if (!isCodeRequest) {\n window.dispatchEvent(new CustomEvent(AGENT_PANEL_PREPARE_EVENT));\n }\n\n const postToTarget = () => target.postMessage(payload, targetOrigin);\n\n // When the local app owns the chat surface, opening/preparing the sidebar\n // may mount the MessageEvent listener that receives this payload. Defer the\n // post one tick so a closed sidebar cannot drop the prompt while mounting.\n if (!isCodeRequest && target === window) {\n setTimeout(postToTarget, 0);\n } else {\n postToTarget();\n }\n return tabId;\n}\n\n/**\n * Add or replace a keyed context nugget in the active agent chat composer.\n * The context is not submitted until the user sends the prompt.\n */\nexport function setContextToAgentChat(opts: AgentChatContextMessage): void {\n const item = normalizeAgentChatContextItem(opts);\n if (!item || typeof window === \"undefined\") return;\n\n const payload = {\n type: AGENT_CHAT_CONTEXT_MESSAGE_TYPE,\n data: item,\n };\n const shouldOpenSidebar = opts.openSidebar !== false;\n const targetSelf = isInBuilderFrame() || isDirectMcpAppEmbedSession();\n const target = targetSelf\n ? window\n : window.parent !== window\n ? window.parent\n : window;\n const targetOrigin = targetSelf\n ? window.location.origin\n : getFramePostMessageTargetOrigin() || window.location.origin;\n\n if (shouldOpenSidebar) {\n window.dispatchEvent(\n new CustomEvent(\"agent-panel:set-mode\", {\n detail: { mode: \"chat\" },\n }),\n );\n window.dispatchEvent(new CustomEvent(\"agent-panel:open\"));\n } else {\n window.dispatchEvent(new CustomEvent(AGENT_PANEL_PREPARE_EVENT));\n }\n\n const postToTarget = () => target.postMessage(payload, targetOrigin);\n if (target === window) {\n setTimeout(postToTarget, 0);\n } else {\n postToTarget();\n }\n}\n\nexport const addContextToAgentChat = setContextToAgentChat;\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
type AssistantUiRecoverableErrorKind = "assistant-ui-stale-message-index" | "assistant-ui-duplicate-resource-key" | "assistant-ui-react-fiber-unmount";
|
|
3
|
+
export declare function assistantUiRecoverableRenderErrorKind(error: unknown): AssistantUiRecoverableErrorKind | null;
|
|
4
|
+
export declare function isAssistantUiStaleIndexError(error: unknown): boolean;
|
|
5
|
+
export declare function isAssistantUiRecoverableRenderError(error: unknown): boolean;
|
|
6
|
+
type AssistantUiStaleIndexErrorBoundaryProps = {
|
|
7
|
+
resetKey: string;
|
|
8
|
+
componentName?: string;
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
};
|
|
11
|
+
type AssistantUiStaleIndexErrorBoundaryState = {
|
|
12
|
+
error: Error | null;
|
|
13
|
+
retryToken: number;
|
|
14
|
+
recovery: {
|
|
15
|
+
signature: string;
|
|
16
|
+
retryCount: number;
|
|
17
|
+
} | null;
|
|
18
|
+
};
|
|
19
|
+
export declare class AssistantUiStaleIndexErrorBoundary extends React.Component<AssistantUiStaleIndexErrorBoundaryProps, AssistantUiStaleIndexErrorBoundaryState> {
|
|
20
|
+
state: AssistantUiStaleIndexErrorBoundaryState;
|
|
21
|
+
private retryTimer;
|
|
22
|
+
private recoverySignature;
|
|
23
|
+
static getDerivedStateFromError(error: unknown): Partial<AssistantUiStaleIndexErrorBoundaryState>;
|
|
24
|
+
componentDidCatch(error: unknown, info: React.ErrorInfo): void;
|
|
25
|
+
componentDidUpdate(prevProps: AssistantUiStaleIndexErrorBoundaryProps, prevState: AssistantUiStaleIndexErrorBoundaryState): void;
|
|
26
|
+
componentWillUnmount(): void;
|
|
27
|
+
render(): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
}
|
|
29
|
+
export declare function AssistantMessageListErrorBoundary({ resetKey, children, }: {
|
|
30
|
+
resetKey: string;
|
|
31
|
+
children: React.ReactNode;
|
|
32
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=assistant-ui-recovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assistant-ui-recovery.d.ts","sourceRoot":"","sources":["../../src/client/assistant-ui-recovery.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,KAAK,+BAA+B,GAChC,kCAAkC,GAClC,qCAAqC,GACrC,kCAAkC,CAAC;AAEvC,wBAAgB,qCAAqC,CACnD,KAAK,EAAE,OAAO,GACb,+BAA+B,GAAG,IAAI,CAcxC;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAKpE;AAED,wBAAgB,mCAAmC,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE3E;AAED,KAAK,uCAAuC,GAAG;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,KAAK,uCAAuC,GAAG;IAC7C,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE;QACR,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI,CAAC;CACV,CAAC;AAIF,qBAAa,kCAAmC,SAAQ,KAAK,CAAC,SAAS,CACrE,uCAAuC,EACvC,uCAAuC,CACxC;IACC,KAAK,EAAE,uCAAuC,CAI5C;IAEF,OAAO,CAAC,UAAU,CAA8C;IAEhE,OAAO,CAAC,iBAAiB;IASzB,MAAM,CAAC,wBAAwB,CAC7B,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,uCAAuC,CAAC;IAMnD,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS;IAsCvD,kBAAkB,CAChB,SAAS,EAAE,uCAAuC,EAClD,SAAS,EAAE,uCAAuC;IA2BpD,oBAAoB;IAMpB,MAAM;CAoBP;AAED,wBAAgB,iCAAiC,CAAC,EAChD,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CASA"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { captureError } from "./analytics.js";
|
|
4
|
+
export function assistantUiRecoverableRenderErrorKind(error) {
|
|
5
|
+
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
6
|
+
if (/^tapClientLookup: Index \d+ out of bounds \(length: \d+\)$/.test(message)) {
|
|
7
|
+
return "assistant-ui-stale-message-index";
|
|
8
|
+
}
|
|
9
|
+
if (/^Duplicate key .+ in tapResources$/.test(message)) {
|
|
10
|
+
return "assistant-ui-duplicate-resource-key";
|
|
11
|
+
}
|
|
12
|
+
if (/^Tried to unmount a fiber that is already unmounted\b/.test(message)) {
|
|
13
|
+
return "assistant-ui-react-fiber-unmount";
|
|
14
|
+
}
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
export function isAssistantUiStaleIndexError(error) {
|
|
18
|
+
return (assistantUiRecoverableRenderErrorKind(error) ===
|
|
19
|
+
"assistant-ui-stale-message-index");
|
|
20
|
+
}
|
|
21
|
+
export function isAssistantUiRecoverableRenderError(error) {
|
|
22
|
+
return assistantUiRecoverableRenderErrorKind(error) !== null;
|
|
23
|
+
}
|
|
24
|
+
const MAX_ASSISTANT_UI_RECOVERABLE_RETRIES = 2;
|
|
25
|
+
export class AssistantUiStaleIndexErrorBoundary extends React.Component {
|
|
26
|
+
state = {
|
|
27
|
+
error: null,
|
|
28
|
+
retryToken: 0,
|
|
29
|
+
recovery: null,
|
|
30
|
+
};
|
|
31
|
+
retryTimer = null;
|
|
32
|
+
recoverySignature(kind, error) {
|
|
33
|
+
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
34
|
+
return `${this.props.resetKey}:${kind}:${message}`;
|
|
35
|
+
}
|
|
36
|
+
static getDerivedStateFromError(error) {
|
|
37
|
+
return {
|
|
38
|
+
error: error instanceof Error ? error : new Error(String(error ?? "")),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
componentDidCatch(error, info) {
|
|
42
|
+
const recoverable = assistantUiRecoverableRenderErrorKind(error);
|
|
43
|
+
if (!recoverable)
|
|
44
|
+
return;
|
|
45
|
+
const signature = this.recoverySignature(recoverable, error);
|
|
46
|
+
const retryCount = this.state.recovery?.signature === signature
|
|
47
|
+
? this.state.recovery.retryCount + 1
|
|
48
|
+
: 1;
|
|
49
|
+
captureError(error, {
|
|
50
|
+
tags: {
|
|
51
|
+
component: this.props.componentName ?? "AssistantChat",
|
|
52
|
+
recoverable,
|
|
53
|
+
},
|
|
54
|
+
extra: {
|
|
55
|
+
resetKey: this.props.resetKey,
|
|
56
|
+
retryCount,
|
|
57
|
+
componentStack: info.componentStack,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
this.setState({
|
|
61
|
+
recovery: { signature, retryCount },
|
|
62
|
+
});
|
|
63
|
+
if (retryCount > MAX_ASSISTANT_UI_RECOVERABLE_RETRIES)
|
|
64
|
+
return;
|
|
65
|
+
if (this.retryTimer)
|
|
66
|
+
return;
|
|
67
|
+
this.retryTimer = setTimeout(() => {
|
|
68
|
+
this.retryTimer = null;
|
|
69
|
+
this.setState((state) => {
|
|
70
|
+
if (!state.error || !isAssistantUiRecoverableRenderError(state.error)) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
return { error: null, retryToken: state.retryToken + 1 };
|
|
74
|
+
});
|
|
75
|
+
}, 0);
|
|
76
|
+
}
|
|
77
|
+
componentDidUpdate(prevProps, prevState) {
|
|
78
|
+
if (prevProps.resetKey !== this.props.resetKey) {
|
|
79
|
+
if (this.retryTimer) {
|
|
80
|
+
clearTimeout(this.retryTimer);
|
|
81
|
+
this.retryTimer = null;
|
|
82
|
+
}
|
|
83
|
+
if (this.state.error &&
|
|
84
|
+
isAssistantUiRecoverableRenderError(this.state.error)) {
|
|
85
|
+
this.setState((state) => ({
|
|
86
|
+
error: null,
|
|
87
|
+
retryToken: state.retryToken + 1,
|
|
88
|
+
recovery: null,
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
else if (this.state.recovery) {
|
|
92
|
+
this.setState({ recovery: null });
|
|
93
|
+
}
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (prevState.error && !this.state.error && this.state.recovery) {
|
|
97
|
+
this.setState({ recovery: null });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
componentWillUnmount() {
|
|
101
|
+
if (this.retryTimer) {
|
|
102
|
+
clearTimeout(this.retryTimer);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
render() {
|
|
106
|
+
if (this.state.error) {
|
|
107
|
+
if (!isAssistantUiRecoverableRenderError(this.state.error)) {
|
|
108
|
+
throw this.state.error;
|
|
109
|
+
}
|
|
110
|
+
if (this.state.recovery &&
|
|
111
|
+
this.state.recovery.retryCount > MAX_ASSISTANT_UI_RECOVERABLE_RETRIES) {
|
|
112
|
+
throw this.state.error;
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
return (_jsx(React.Fragment, { children: this.props.children }, `${this.props.resetKey}:${this.state.retryToken}`));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export function AssistantMessageListErrorBoundary({ resetKey, children, }) {
|
|
120
|
+
return (_jsx(AssistantUiStaleIndexErrorBoundary, { resetKey: resetKey, componentName: "AssistantMessageList", children: children }));
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=assistant-ui-recovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assistant-ui-recovery.js","sourceRoot":"","sources":["../../src/client/assistant-ui-recovery.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from \"react\";\n\nimport { captureError } from \"./analytics.js\";\n\ntype AssistantUiRecoverableErrorKind =\n | \"assistant-ui-stale-message-index\"\n | \"assistant-ui-duplicate-resource-key\"\n | \"assistant-ui-react-fiber-unmount\";\n\nexport function assistantUiRecoverableRenderErrorKind(\n error: unknown,\n): AssistantUiRecoverableErrorKind | null {\n const message = error instanceof Error ? error.message : String(error ?? \"\");\n if (\n /^tapClientLookup: Index \\d+ out of bounds \\(length: \\d+\\)$/.test(message)\n ) {\n return \"assistant-ui-stale-message-index\";\n }\n if (/^Duplicate key .+ in tapResources$/.test(message)) {\n return \"assistant-ui-duplicate-resource-key\";\n }\n if (/^Tried to unmount a fiber that is already unmounted\\b/.test(message)) {\n return \"assistant-ui-react-fiber-unmount\";\n }\n return null;\n}\n\nexport function isAssistantUiStaleIndexError(error: unknown): boolean {\n return (\n assistantUiRecoverableRenderErrorKind(error) ===\n \"assistant-ui-stale-message-index\"\n );\n}\n\nexport function isAssistantUiRecoverableRenderError(error: unknown): boolean {\n return assistantUiRecoverableRenderErrorKind(error) !== null;\n}\n\ntype AssistantUiStaleIndexErrorBoundaryProps = {\n resetKey: string;\n componentName?: string;\n children: React.ReactNode;\n};\n\ntype AssistantUiStaleIndexErrorBoundaryState = {\n error: Error | null;\n retryToken: number;\n recovery: {\n signature: string;\n retryCount: number;\n } | null;\n};\n\nconst MAX_ASSISTANT_UI_RECOVERABLE_RETRIES = 2;\n\nexport class AssistantUiStaleIndexErrorBoundary extends React.Component<\n AssistantUiStaleIndexErrorBoundaryProps,\n AssistantUiStaleIndexErrorBoundaryState\n> {\n state: AssistantUiStaleIndexErrorBoundaryState = {\n error: null,\n retryToken: 0,\n recovery: null,\n };\n\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n\n private recoverySignature(\n kind: AssistantUiRecoverableErrorKind,\n error: unknown,\n ): string {\n const message =\n error instanceof Error ? error.message : String(error ?? \"\");\n return `${this.props.resetKey}:${kind}:${message}`;\n }\n\n static getDerivedStateFromError(\n error: unknown,\n ): Partial<AssistantUiStaleIndexErrorBoundaryState> {\n return {\n error: error instanceof Error ? error : new Error(String(error ?? \"\")),\n };\n }\n\n componentDidCatch(error: unknown, info: React.ErrorInfo) {\n const recoverable = assistantUiRecoverableRenderErrorKind(error);\n if (!recoverable) return;\n const signature = this.recoverySignature(recoverable, error);\n const retryCount =\n this.state.recovery?.signature === signature\n ? this.state.recovery.retryCount + 1\n : 1;\n\n captureError(error, {\n tags: {\n component: this.props.componentName ?? \"AssistantChat\",\n recoverable,\n },\n extra: {\n resetKey: this.props.resetKey,\n retryCount,\n componentStack: info.componentStack,\n },\n });\n\n this.setState({\n recovery: { signature, retryCount },\n });\n if (retryCount > MAX_ASSISTANT_UI_RECOVERABLE_RETRIES) return;\n\n if (this.retryTimer) return;\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n this.setState((state) => {\n if (!state.error || !isAssistantUiRecoverableRenderError(state.error)) {\n return null;\n }\n return { error: null, retryToken: state.retryToken + 1 };\n });\n }, 0);\n }\n\n componentDidUpdate(\n prevProps: AssistantUiStaleIndexErrorBoundaryProps,\n prevState: AssistantUiStaleIndexErrorBoundaryState,\n ) {\n if (prevProps.resetKey !== this.props.resetKey) {\n if (this.retryTimer) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n if (\n this.state.error &&\n isAssistantUiRecoverableRenderError(this.state.error)\n ) {\n this.setState((state) => ({\n error: null,\n retryToken: state.retryToken + 1,\n recovery: null,\n }));\n } else if (this.state.recovery) {\n this.setState({ recovery: null });\n }\n return;\n }\n\n if (prevState.error && !this.state.error && this.state.recovery) {\n this.setState({ recovery: null });\n }\n }\n\n componentWillUnmount() {\n if (this.retryTimer) {\n clearTimeout(this.retryTimer);\n }\n }\n\n render() {\n if (this.state.error) {\n if (!isAssistantUiRecoverableRenderError(this.state.error)) {\n throw this.state.error;\n }\n if (\n this.state.recovery &&\n this.state.recovery.retryCount > MAX_ASSISTANT_UI_RECOVERABLE_RETRIES\n ) {\n throw this.state.error;\n }\n return null;\n }\n\n return (\n <React.Fragment key={`${this.props.resetKey}:${this.state.retryToken}`}>\n {this.props.children}\n </React.Fragment>\n );\n }\n}\n\nexport function AssistantMessageListErrorBoundary({\n resetKey,\n children,\n}: {\n resetKey: string;\n children: React.ReactNode;\n}) {\n return (\n <AssistantUiStaleIndexErrorBoundary\n resetKey={resetKey}\n componentName=\"AssistantMessageList\"\n >\n {children}\n </AssistantUiStaleIndexErrorBoundary>\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PromptComposer.d.ts","sourceRoot":"","sources":["../../../src/client/composer/PromptComposer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,aAAa,EAClB,KAAK,GAAG,EACR,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAsBf,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EAE1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EACV,0BAA0B,EAC1B,SAAS,EACT,WAAW,EACX,YAAY,EACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAiB,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"PromptComposer.d.ts","sourceRoot":"","sources":["../../../src/client/composer/PromptComposer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,aAAa,EAClB,KAAK,GAAG,EACR,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAsBf,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EAE1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EACV,0BAA0B,EAC1B,SAAS,EACT,WAAW,EACX,YAAY,EACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAiB,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAcxE;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEtC,MAAM,WAAW,2BAA2B;IAC1C,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,QAAQ,EAAE,CACR,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,kBAAkB,EAAE,EAC3B,UAAU,EAAE,SAAS,EAAE,EACvB,OAAO,EAAE,2BAA2B,KACjC,IAAI,CAAC;IACV,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,+CAA+C;IAC/C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,uDAAuD;IACvD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,sFAAsF;IACtF,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,QAAQ,CAAC;IACjD,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,0EAA0E;IAC1E,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,yEAAyE;IACzE,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,+DAA+D;IAC/D,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,sFAAsF;IACtF,aAAa,CAAC,EAAE,0BAA0B,CAAC;IAC3C,+DAA+D;IAC/D,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,6DAA6D;IAC7D,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;IAC5B,mFAAmF;IACnF,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,mFAAmF;IACnF,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,sEAAsE;IACtE,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,iFAAiF;IACjF,eAAe,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD;;;OAGG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,qDAAqD;IACrD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,mDAAmD;IACnD,WAAW,CAAC,EAAE,GAAG,CAAC,oBAAoB,CAAC,CAAC;CACzC;AA0FD,wBAAsB,6BAA6B,CAAC,OAAO,EAAE;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CACtC,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CAoD3C;AA4TD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,2CAoCxD"}
|
|
@@ -8,6 +8,7 @@ import { AgentComposerFrame } from "./AgentComposerFrame.js";
|
|
|
8
8
|
import { TiptapComposer, } from "./TiptapComposer.js";
|
|
9
9
|
import { useChatModels } from "../use-chat-models.js";
|
|
10
10
|
import { TooltipProvider } from "../components/ui/tooltip.js";
|
|
11
|
+
import { AssistantUiStaleIndexErrorBoundary } from "../assistant-ui-recovery.js";
|
|
11
12
|
import { isPastedTextAttachmentName } from "./pasted-text.js";
|
|
12
13
|
import { PastedTextChip } from "./PastedTextChip.js";
|
|
13
14
|
import { PROMPT_DOCUMENT_ATTACHMENT_ACCEPT, TextAttachmentAdapter, } from "./attachment-accept.js";
|
|
@@ -266,6 +267,11 @@ export function PromptComposer(props) {
|
|
|
266
267
|
const runtime = useLocalRuntime(NOOP_ADAPTER, {
|
|
267
268
|
adapters: { attachments: attachmentAdapter },
|
|
268
269
|
});
|
|
269
|
-
|
|
270
|
+
const resetKey = [
|
|
271
|
+
props.draftScope ?? "",
|
|
272
|
+
props.initialTextKey ?? "",
|
|
273
|
+
props.initialText ?? "",
|
|
274
|
+
].join(":");
|
|
275
|
+
return (_jsx(TooltipProvider, { delayDuration: 200, children: _jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx(ThreadPrimitive.Root, { className: "contents", style: { display: "contents" }, children: _jsx(AssistantUiStaleIndexErrorBoundary, { resetKey: resetKey, componentName: "PromptComposer", children: _jsx(PromptComposerInner, { ...props }) }) }) }) }));
|
|
270
276
|
}
|
|
271
277
|
//# sourceMappingURL=PromptComposer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PromptComposer.js","sourceRoot":"","sources":["../../../src/client/composer/PromptComposer.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type Ref,\n type ReactNode,\n} from \"react\";\nimport {\n AssistantRuntimeProvider,\n ThreadPrimitive,\n useAui,\n useComposer,\n useLocalRuntime,\n} from \"@assistant-ui/react\";\nimport type {\n Attachment,\n AttachmentAdapter,\n ChatModelAdapter,\n CompleteAttachment,\n PendingAttachment,\n} from \"@assistant-ui/react\";\nimport {\n CompositeAttachmentAdapter,\n SimpleImageAttachmentAdapter,\n} from \"@assistant-ui/react\";\nimport { IconX } from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport { AgentComposerFrame } from \"./AgentComposerFrame.js\";\nimport {\n TiptapComposer,\n type ComposerSubmitIntent,\n type TiptapComposerHandle,\n type TiptapComposerSubmitOptions,\n} from \"./TiptapComposer.js\";\nimport type {\n AgentComposerLayoutVariant,\n Reference,\n SkillResult,\n SlashCommand,\n} from \"./types.js\";\nimport { useChatModels, type EngineModelGroup } from \"../use-chat-models.js\";\nimport { TooltipProvider } from \"../components/ui/tooltip.js\";\nimport type { ReasoningEffort } from \"../../shared/reasoning-effort.js\";\nimport { isPastedTextAttachmentName } from \"./pasted-text.js\";\nimport { PastedTextChip } from \"./PastedTextChip.js\";\nimport {\n PROMPT_DOCUMENT_ATTACHMENT_ACCEPT,\n TextAttachmentAdapter,\n} from \"./attachment-accept.js\";\nimport {\n AGENT_PROMPT_MAX_INLINE_IMAGE_BYTES,\n escapePromptAttachmentAttribute,\n} from \"./prompt-attachments.js\";\n\nconst MAX_INLINE_TEXT_FILE_CHARS = 60_000;\n\n/**\n * Files the user attached via the \"+\" button in PromptComposer. The host owns\n * what to do with them — typically POST to a per-app upload endpoint and pass\n * the resulting URLs/paths into the prompt that gets sent to the agent.\n */\nexport type PromptComposerFile = File;\n\nexport interface PromptComposerSubmitOptions {\n intent?: ComposerSubmitIntent;\n model?: string;\n engine?: string;\n effort?: ReasoningEffort;\n}\n\nexport interface PromptComposerProps {\n /** Called when the user submits the composer. */\n onSubmit: (\n text: string,\n files: PromptComposerFile[],\n references: Reference[],\n options: PromptComposerSubmitOptions,\n ) => void;\n placeholder?: string;\n disabled?: boolean;\n autoFocus?: boolean;\n className?: string;\n style?: CSSProperties;\n rootClassName?: string;\n rootStyle?: CSSProperties;\n /** Forwarded to TiptapComposer for draft persistence. */\n draftScope?: string;\n /** Keep the submitted prompt in the editor. Default: false. */\n preserveDraftOnSubmit?: boolean;\n /** Show the model selector (default: true). */\n showModelSelector?: boolean;\n /** Show the voice dictation button (default: true). */\n voiceEnabled?: boolean;\n /** Show file upload controls and pass submitted files to onSubmit (default: true). */\n attachmentsEnabled?: boolean;\n /**\n * Controls the shared \"+\" affordance. Defaults to upload-only for standalone\n * prompt forms; chat surfaces can opt into the full sidebar menu.\n */\n plusMenuMode?: \"full\" | \"upload-only\" | \"hidden\";\n /** Programmatically seed the composer with plain text. */\n initialText?: string;\n /** Stable key used to re-apply `initialText` when the host picks a preset. */\n initialTextKey?: string | number;\n /** Optional host-owned control rendered directly after the \"+\" button. */\n modeControl?: ReactNode;\n /** Explicit host-owned toolbar slot rendered directly after the \"+\" button. */\n toolbarSlot?: ReactNode;\n /** Custom action button to render instead of the default send button. */\n actionButton?: ReactNode;\n /** Extra button rendered alongside the default send button. */\n extraActionButton?: ReactNode;\n /** Shared sizing/layout variant for host surfaces. Default keeps sidebar behavior. */\n layoutVariant?: AgentComposerLayoutVariant;\n /** Additional slash commands surfaced in the shared / menu. */\n slashCommands?: SlashCommand[];\n /** Additional slash skills surfaced in the shared / menu. */\n slashSkills?: SkillResult[];\n /** Include built-in sidebar slash commands like /clear and /help. Default true. */\n includeDefaultSlashCommands?: boolean;\n /** Include app-discovered skills from the default agent endpoint. Default true. */\n includeDefaultSlashSkills?: boolean;\n /** Called when a slash command from the shared / menu is executed. */\n onSlashCommand?: (command: string) => void;\n /** External model list for hosts that already resolve models outside the app. */\n availableModels?: EngineModelGroup[];\n selectedModel?: string;\n selectedEngine?: string;\n selectedEffort?: ReasoningEffort;\n onModelChange?: (model: string, engine: string) => void;\n onEffortChange?: (effort: ReasoningEffort) => void;\n /**\n * Enable server-backed model/provider status checks. Defaults off when the\n * host supplies model state and callbacks, otherwise on.\n */\n modelStatusChecksEnabled?: boolean;\n /** Called whenever the plain editor text changes. */\n onTextChange?: (text: string) => void;\n /**\n * Override the Builder.io connect action in the model picker. When provided,\n * clicking \"Connect Builder.io\" calls this instead of opening a browser popup.\n * Used by the Electron desktop app to route through the native IPC handler.\n */\n onConnectProvider?: () => void;\n /** Imperative handle for focusing the composer. */\n composerRef?: Ref<TiptapComposerHandle>;\n}\n\n// Minimal pass-through adapter. PromptComposer always submits through\n// onSubmitOverride, so the runtime never actually calls this — but\n// `useLocalRuntime` needs *something* shaped like a ChatModelAdapter.\nconst NOOP_ADAPTER: ChatModelAdapter = {\n async *run() {\n return;\n },\n};\n\n/**\n * Local binary document adapter so reference PDFs, decks, and docs can be\n * attached without dragging the whole assistant chat module into bundles that\n * just want a prompt popover.\n */\nclass BinaryDocumentAttachmentAdapter implements AttachmentAdapter {\n public accept = PROMPT_DOCUMENT_ATTACHMENT_ACCEPT;\n\n public async add(state: { file: File }): Promise<PendingAttachment> {\n return {\n id: state.file.name,\n type: \"document\",\n name: state.file.name,\n contentType: state.file.type || \"application/octet-stream\",\n file: state.file,\n status: { type: \"requires-action\", reason: \"composer-send\" },\n };\n }\n\n public async send(\n attachment: PendingAttachment,\n ): Promise<CompleteAttachment> {\n return {\n ...attachment,\n status: { type: \"complete\" },\n content: [],\n };\n }\n\n public async remove() {\n /* noop */\n }\n}\n\nfunction isInlineableTextFile(file: File): boolean {\n if (file.type.startsWith(\"text/\")) return true;\n if (file.type === \"application/json\") return true;\n return /\\.(txt|md|markdown|csv|json|yaml|yml|html?|css|xml)$/i.test(\n file.name,\n );\n}\n\nfunction formatInlineTextFile(name: string, text: string): string {\n const truncated = text.length > MAX_INLINE_TEXT_FILE_CHARS;\n const body = truncated ? text.slice(0, MAX_INLINE_TEXT_FILE_CHARS) : text;\n return [\n `<uploaded-text-file name=\"${escapePromptAttachmentAttribute(name)}\">`,\n body,\n truncated\n ? `[Truncated after ${MAX_INLINE_TEXT_FILE_CHARS} characters.]`\n : \"\",\n \"</uploaded-text-file>\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n}\n\nfunction readFileDataUrl(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\nfunction formatInlineImageFile(\n name: string,\n contentType: string,\n dataUrl: string,\n): string {\n return [\n `<uploaded-image name=\"${escapePromptAttachmentAttribute(name)}\" contentType=\"${escapePromptAttachmentAttribute(contentType)}\">`,\n dataUrl,\n \"</uploaded-image>\",\n ].join(\"\\n\");\n}\n\nexport async function buildPromptComposerSubmission(options: {\n text: string;\n attachments?: ReadonlyArray<unknown>;\n}): Promise<{ text: string; files: File[] }> {\n const files: File[] = [];\n const pastedTextBlocks: string[] = [];\n const rawText = options.text;\n\n for (const att of options.attachments ?? []) {\n const a = att as Attachment;\n if (\"file\" in a && a.file instanceof File) {\n const file = a.file;\n if (isPastedTextAttachmentName(file.name)) {\n try {\n pastedTextBlocks.push(await file.text());\n } catch {\n files.push(file);\n }\n } else {\n if (isInlineableTextFile(file)) {\n try {\n pastedTextBlocks.push(\n formatInlineTextFile(file.name, await file.text()),\n );\n } catch {\n // Keep the upload path fallback below.\n }\n } else if (\n file.type.startsWith(\"image/\") &&\n file.size <= AGENT_PROMPT_MAX_INLINE_IMAGE_BYTES &&\n !rawText.trim()\n ) {\n try {\n pastedTextBlocks.push(\n formatInlineImageFile(\n file.name,\n file.type,\n await readFileDataUrl(file),\n ),\n );\n } catch {\n // Keep the upload path fallback below.\n }\n }\n files.push(file);\n }\n }\n }\n\n return {\n text: pastedTextBlocks.length\n ? [rawText.trim(), ...pastedTextBlocks].filter(Boolean).join(\"\\n\\n\")\n : rawText,\n files,\n };\n}\n\nfunction getImageSrc(attachment: Attachment): string | null {\n if (attachment.type !== \"image\") return null;\n if (\"file\" in attachment && attachment.file) {\n return URL.createObjectURL(attachment.file);\n }\n const imagePart = attachment.content?.find((part) => part.type === \"image\");\n return imagePart && \"image\" in imagePart ? imagePart.image : null;\n}\n\nfunction ImagePreviewLightbox({\n src,\n alt,\n onClose,\n}: {\n src: string;\n alt: string;\n onClose: () => void;\n}) {\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handler);\n document.body.style.overflow = \"hidden\";\n return () => {\n document.removeEventListener(\"keydown\", handler);\n document.body.style.overflow = \"\";\n };\n }, [onClose]);\n\n return (\n <div\n role=\"dialog\"\n aria-label=\"Image preview\"\n onClick={onClose}\n className=\"fixed inset-0 z-[300] flex items-center justify-center bg-black/80 p-6 cursor-zoom-out\"\n >\n <img\n src={src}\n alt={alt}\n onClick={(e) => e.stopPropagation()}\n className=\"max-h-full max-w-full object-contain rounded-md shadow-2xl cursor-default\"\n />\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close preview\"\n className=\"absolute right-4 top-4 flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border border-white/30 bg-black/40 text-white hover:bg-black/60\"\n >\n <IconX className=\"h-4 w-4\" />\n </button>\n </div>\n );\n}\n\nfunction AttachmentChip({\n attachment,\n onRemove,\n}: {\n attachment: Attachment;\n onRemove: (id: string) => void;\n}) {\n const src = useMemo(() => getImageSrc(attachment), [attachment]);\n const [previewOpen, setPreviewOpen] = useState(false);\n useEffect(\n () => () => {\n if (src?.startsWith(\"blob:\")) URL.revokeObjectURL(src);\n },\n [src],\n );\n\n if (isPastedTextAttachmentName(attachment.name)) {\n return <PastedTextChip attachment={attachment} onRemove={onRemove} />;\n }\n\n if (src) {\n return (\n <>\n <button\n type=\"button\"\n onClick={() => setPreviewOpen(true)}\n aria-label={`Preview ${attachment.name}`}\n className=\"agent-composer-attachment-image group relative flex h-16 min-w-16 max-w-28 cursor-zoom-in items-center justify-center overflow-hidden rounded-lg border border-border/70 bg-muted/50\"\n >\n <img\n src={src}\n alt={attachment.name}\n className=\"max-h-full max-w-full object-contain p-1\"\n />\n <span\n role=\"button\"\n tabIndex={0}\n onClick={(e) => {\n e.stopPropagation();\n onRemove(attachment.id);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n e.stopPropagation();\n onRemove(attachment.id);\n }\n }}\n aria-label={`Remove ${attachment.name}`}\n className=\"absolute right-1 top-1 flex h-5 w-5 cursor-pointer items-center justify-center rounded-full border border-border/60 bg-background/90 text-muted-foreground hover:text-foreground\"\n >\n <IconX className=\"h-3 w-3\" />\n </span>\n </button>\n {previewOpen ? (\n <ImagePreviewLightbox\n src={src}\n alt={attachment.name}\n onClose={() => setPreviewOpen(false)}\n />\n ) : null}\n </>\n );\n }\n\n return (\n <div className=\"agent-composer-attachment-chip group relative inline-flex max-w-[200px] items-center gap-2 rounded-md border border-border/70 bg-muted/50 px-2 py-1.5 text-xs\">\n <div className=\"flex h-6 w-6 shrink-0 items-center justify-center rounded bg-background text-[9px] font-semibold uppercase text-muted-foreground\">\n {attachment.name.split(\".\").pop() || \"file\"}\n </div>\n <span className=\"min-w-0 truncate font-medium\">{attachment.name}</span>\n <button\n type=\"button\"\n onClick={() => onRemove(attachment.id)}\n aria-label={`Remove ${attachment.name}`}\n className=\"flex h-5 w-5 shrink-0 cursor-pointer items-center justify-center rounded text-muted-foreground hover:text-foreground\"\n >\n <IconX className=\"h-3 w-3\" />\n </button>\n </div>\n );\n}\n\nfunction PromptAttachmentStrip() {\n const attachments = useComposer((state) => state.attachments);\n const aui = useAui();\n\n const handleRemove = useCallback(\n (id: string) => {\n void aui.composer().attachment({ id }).remove();\n },\n [aui],\n );\n\n if (attachments.length === 0) return null;\n return (\n <div className=\"agent-composer-attachment-strip flex flex-wrap gap-2 px-2 pt-2\">\n {attachments.map((attachment) => (\n <AttachmentChip\n key={attachment.id}\n attachment={attachment}\n onRemove={handleRemove}\n />\n ))}\n </div>\n );\n}\n\nfunction PromptComposerInner({\n onSubmit,\n placeholder,\n disabled,\n autoFocus,\n className,\n style,\n rootClassName,\n rootStyle,\n draftScope,\n preserveDraftOnSubmit = false,\n showModelSelector = true,\n voiceEnabled = true,\n attachmentsEnabled = true,\n plusMenuMode,\n initialText,\n initialTextKey,\n modeControl,\n toolbarSlot,\n actionButton,\n extraActionButton,\n layoutVariant,\n slashCommands,\n slashSkills,\n includeDefaultSlashCommands,\n includeDefaultSlashSkills,\n onSlashCommand,\n availableModels,\n selectedModel,\n selectedEngine,\n selectedEffort,\n onModelChange,\n onEffortChange,\n modelStatusChecksEnabled,\n onTextChange,\n onConnectProvider,\n composerRef,\n}: PromptComposerProps) {\n const localRef = useRef<TiptapComposerHandle>(null);\n const handleRef = composerRef ?? localRef;\n const hostManagedModels = Boolean(\n availableModels && selectedModel && onModelChange,\n );\n const resolvedModelStatusChecksEnabled =\n modelStatusChecksEnabled ?? !hostManagedModels;\n const models = useChatModels({\n enabled: showModelSelector && resolvedModelStatusChecksEnabled,\n });\n const composerModel = showModelSelector\n ? (selectedModel ?? models.selectedModel)\n : undefined;\n const composerEngine = showModelSelector\n ? (selectedEngine ?? models.selectedEngine)\n : undefined;\n const composerEffort = showModelSelector\n ? (selectedEffort ?? models.selectedEffort)\n : undefined;\n const composerModelGroups = showModelSelector\n ? (availableModels ?? models.availableModels)\n : undefined;\n const handleModelChange = showModelSelector\n ? (onModelChange ?? models.onModelChange)\n : undefined;\n const handleEffortChange = showModelSelector\n ? (onEffortChange ?? models.onEffortChange)\n : undefined;\n\n useEffect(() => {\n if (!autoFocus) return;\n const id = window.setTimeout(() => {\n const target =\n typeof handleRef === \"object\" && handleRef && \"current\" in handleRef\n ? handleRef.current\n : null;\n target?.focus();\n }, 50);\n return () => window.clearTimeout(id);\n }, [autoFocus, handleRef]);\n\n const handleSubmit = useCallback(\n async (\n text: string,\n references: Reference[],\n attachments?: ReadonlyArray<unknown>,\n submitOptions?: TiptapComposerSubmitOptions,\n ) => {\n // PromptComposer hosts (NewWorkspaceAppFlow, create-extension, create-deck,\n // …) submit a single string prompt — they don't run the assistant-ui\n // attachment send pipeline. TiptapComposer auto-converts large pastes\n // into a \"Pasted text\" chip, which would otherwise disappear into an\n // unprocessed File. Inline the chip body back into the prompt text so\n // newlines and full content survive the round-trip.\n const { text: finalText, files } = await buildPromptComposerSubmission({\n text,\n attachments,\n });\n onSubmit(finalText, files, references, {\n intent: submitOptions?.intent ?? \"immediate\",\n model: composerModel,\n engine: composerEngine,\n effort: composerEffort,\n });\n },\n [composerEffort, composerEngine, composerModel, onSubmit],\n );\n\n return (\n <AgentComposerFrame\n className={cn(\"text-left\", className)}\n rootClassName={rootClassName}\n style={style}\n rootStyle={rootStyle}\n layoutVariant={layoutVariant}\n >\n <PromptAttachmentStrip />\n <TiptapComposer\n focusRef={handleRef}\n disabled={disabled}\n placeholder={placeholder}\n initialText={initialText}\n initialTextKey={initialTextKey}\n onSubmit={handleSubmit}\n clearOnSubmit={!preserveDraftOnSubmit}\n plusMenuMode={\n plusMenuMode ?? (attachmentsEnabled ? \"upload-only\" : \"hidden\")\n }\n modeControl={modeControl}\n toolbarSlot={toolbarSlot}\n actionButton={actionButton}\n extraActionButton={extraActionButton}\n layoutVariant={layoutVariant}\n slashCommands={slashCommands}\n slashSkills={slashSkills}\n includeDefaultSlashCommands={includeDefaultSlashCommands}\n includeDefaultSlashSkills={includeDefaultSlashSkills}\n onSlashCommand={onSlashCommand}\n voiceEnabled={voiceEnabled}\n onTextChange={onTextChange}\n draftScope={draftScope}\n selectedModel={composerModel}\n selectedEffort={composerEffort}\n availableModels={composerModelGroups}\n onModelChange={handleModelChange}\n onEffortChange={handleEffortChange}\n providerConnectStatusEnabled={resolvedModelStatusChecksEnabled}\n onConnectProvider={onConnectProvider}\n />\n </AgentComposerFrame>\n );\n}\n\n/**\n * Standalone composer that mirrors the agent sidebar's input experience —\n * voice dictation, file upload, model selector, submit-on-Enter — for use in\n * popovers and inline prompt forms (create tool, create deck, create dashboard,\n * the Dispatch new-app flow, etc.).\n *\n * The host owns submission: when the user presses Enter or clicks submit,\n * `onSubmit(text, files, references, options)` is called. PromptComposer runs\n * its own minimal assistant-ui runtime so it can be dropped into any subtree\n * without needing the outer chat to be mounted.\n */\nexport function PromptComposer(props: PromptComposerProps) {\n const attachmentAdapter = useMemo(\n () =>\n new CompositeAttachmentAdapter([\n new SimpleImageAttachmentAdapter(),\n new BinaryDocumentAttachmentAdapter(),\n new TextAttachmentAdapter(),\n ]),\n [],\n );\n const runtime = useLocalRuntime(NOOP_ADAPTER, {\n adapters: { attachments: attachmentAdapter },\n });\n\n return (\n <TooltipProvider delayDuration={200}>\n <AssistantRuntimeProvider runtime={runtime}>\n <ThreadPrimitive.Root\n className=\"contents\"\n style={{ display: \"contents\" }}\n >\n <PromptComposerInner {...props} />\n </ThreadPrimitive.Root>\n </AssistantRuntimeProvider>\n </TooltipProvider>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"PromptComposer.js","sourceRoot":"","sources":["../../../src/client/composer/PromptComposer.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type Ref,\n type ReactNode,\n} from \"react\";\nimport {\n AssistantRuntimeProvider,\n ThreadPrimitive,\n useAui,\n useComposer,\n useLocalRuntime,\n} from \"@assistant-ui/react\";\nimport type {\n Attachment,\n AttachmentAdapter,\n ChatModelAdapter,\n CompleteAttachment,\n PendingAttachment,\n} from \"@assistant-ui/react\";\nimport {\n CompositeAttachmentAdapter,\n SimpleImageAttachmentAdapter,\n} from \"@assistant-ui/react\";\nimport { IconX } from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport { AgentComposerFrame } from \"./AgentComposerFrame.js\";\nimport {\n TiptapComposer,\n type ComposerSubmitIntent,\n type TiptapComposerHandle,\n type TiptapComposerSubmitOptions,\n} from \"./TiptapComposer.js\";\nimport type {\n AgentComposerLayoutVariant,\n Reference,\n SkillResult,\n SlashCommand,\n} from \"./types.js\";\nimport { useChatModels, type EngineModelGroup } from \"../use-chat-models.js\";\nimport { TooltipProvider } from \"../components/ui/tooltip.js\";\nimport { AssistantUiStaleIndexErrorBoundary } from \"../assistant-ui-recovery.js\";\nimport type { ReasoningEffort } from \"../../shared/reasoning-effort.js\";\nimport { isPastedTextAttachmentName } from \"./pasted-text.js\";\nimport { PastedTextChip } from \"./PastedTextChip.js\";\nimport {\n PROMPT_DOCUMENT_ATTACHMENT_ACCEPT,\n TextAttachmentAdapter,\n} from \"./attachment-accept.js\";\nimport {\n AGENT_PROMPT_MAX_INLINE_IMAGE_BYTES,\n escapePromptAttachmentAttribute,\n} from \"./prompt-attachments.js\";\n\nconst MAX_INLINE_TEXT_FILE_CHARS = 60_000;\n\n/**\n * Files the user attached via the \"+\" button in PromptComposer. The host owns\n * what to do with them — typically POST to a per-app upload endpoint and pass\n * the resulting URLs/paths into the prompt that gets sent to the agent.\n */\nexport type PromptComposerFile = File;\n\nexport interface PromptComposerSubmitOptions {\n intent?: ComposerSubmitIntent;\n model?: string;\n engine?: string;\n effort?: ReasoningEffort;\n}\n\nexport interface PromptComposerProps {\n /** Called when the user submits the composer. */\n onSubmit: (\n text: string,\n files: PromptComposerFile[],\n references: Reference[],\n options: PromptComposerSubmitOptions,\n ) => void;\n placeholder?: string;\n disabled?: boolean;\n autoFocus?: boolean;\n className?: string;\n style?: CSSProperties;\n rootClassName?: string;\n rootStyle?: CSSProperties;\n /** Forwarded to TiptapComposer for draft persistence. */\n draftScope?: string;\n /** Keep the submitted prompt in the editor. Default: false. */\n preserveDraftOnSubmit?: boolean;\n /** Show the model selector (default: true). */\n showModelSelector?: boolean;\n /** Show the voice dictation button (default: true). */\n voiceEnabled?: boolean;\n /** Show file upload controls and pass submitted files to onSubmit (default: true). */\n attachmentsEnabled?: boolean;\n /**\n * Controls the shared \"+\" affordance. Defaults to upload-only for standalone\n * prompt forms; chat surfaces can opt into the full sidebar menu.\n */\n plusMenuMode?: \"full\" | \"upload-only\" | \"hidden\";\n /** Programmatically seed the composer with plain text. */\n initialText?: string;\n /** Stable key used to re-apply `initialText` when the host picks a preset. */\n initialTextKey?: string | number;\n /** Optional host-owned control rendered directly after the \"+\" button. */\n modeControl?: ReactNode;\n /** Explicit host-owned toolbar slot rendered directly after the \"+\" button. */\n toolbarSlot?: ReactNode;\n /** Custom action button to render instead of the default send button. */\n actionButton?: ReactNode;\n /** Extra button rendered alongside the default send button. */\n extraActionButton?: ReactNode;\n /** Shared sizing/layout variant for host surfaces. Default keeps sidebar behavior. */\n layoutVariant?: AgentComposerLayoutVariant;\n /** Additional slash commands surfaced in the shared / menu. */\n slashCommands?: SlashCommand[];\n /** Additional slash skills surfaced in the shared / menu. */\n slashSkills?: SkillResult[];\n /** Include built-in sidebar slash commands like /clear and /help. Default true. */\n includeDefaultSlashCommands?: boolean;\n /** Include app-discovered skills from the default agent endpoint. Default true. */\n includeDefaultSlashSkills?: boolean;\n /** Called when a slash command from the shared / menu is executed. */\n onSlashCommand?: (command: string) => void;\n /** External model list for hosts that already resolve models outside the app. */\n availableModels?: EngineModelGroup[];\n selectedModel?: string;\n selectedEngine?: string;\n selectedEffort?: ReasoningEffort;\n onModelChange?: (model: string, engine: string) => void;\n onEffortChange?: (effort: ReasoningEffort) => void;\n /**\n * Enable server-backed model/provider status checks. Defaults off when the\n * host supplies model state and callbacks, otherwise on.\n */\n modelStatusChecksEnabled?: boolean;\n /** Called whenever the plain editor text changes. */\n onTextChange?: (text: string) => void;\n /**\n * Override the Builder.io connect action in the model picker. When provided,\n * clicking \"Connect Builder.io\" calls this instead of opening a browser popup.\n * Used by the Electron desktop app to route through the native IPC handler.\n */\n onConnectProvider?: () => void;\n /** Imperative handle for focusing the composer. */\n composerRef?: Ref<TiptapComposerHandle>;\n}\n\n// Minimal pass-through adapter. PromptComposer always submits through\n// onSubmitOverride, so the runtime never actually calls this — but\n// `useLocalRuntime` needs *something* shaped like a ChatModelAdapter.\nconst NOOP_ADAPTER: ChatModelAdapter = {\n async *run() {\n return;\n },\n};\n\n/**\n * Local binary document adapter so reference PDFs, decks, and docs can be\n * attached without dragging the whole assistant chat module into bundles that\n * just want a prompt popover.\n */\nclass BinaryDocumentAttachmentAdapter implements AttachmentAdapter {\n public accept = PROMPT_DOCUMENT_ATTACHMENT_ACCEPT;\n\n public async add(state: { file: File }): Promise<PendingAttachment> {\n return {\n id: state.file.name,\n type: \"document\",\n name: state.file.name,\n contentType: state.file.type || \"application/octet-stream\",\n file: state.file,\n status: { type: \"requires-action\", reason: \"composer-send\" },\n };\n }\n\n public async send(\n attachment: PendingAttachment,\n ): Promise<CompleteAttachment> {\n return {\n ...attachment,\n status: { type: \"complete\" },\n content: [],\n };\n }\n\n public async remove() {\n /* noop */\n }\n}\n\nfunction isInlineableTextFile(file: File): boolean {\n if (file.type.startsWith(\"text/\")) return true;\n if (file.type === \"application/json\") return true;\n return /\\.(txt|md|markdown|csv|json|yaml|yml|html?|css|xml)$/i.test(\n file.name,\n );\n}\n\nfunction formatInlineTextFile(name: string, text: string): string {\n const truncated = text.length > MAX_INLINE_TEXT_FILE_CHARS;\n const body = truncated ? text.slice(0, MAX_INLINE_TEXT_FILE_CHARS) : text;\n return [\n `<uploaded-text-file name=\"${escapePromptAttachmentAttribute(name)}\">`,\n body,\n truncated\n ? `[Truncated after ${MAX_INLINE_TEXT_FILE_CHARS} characters.]`\n : \"\",\n \"</uploaded-text-file>\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n}\n\nfunction readFileDataUrl(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\nfunction formatInlineImageFile(\n name: string,\n contentType: string,\n dataUrl: string,\n): string {\n return [\n `<uploaded-image name=\"${escapePromptAttachmentAttribute(name)}\" contentType=\"${escapePromptAttachmentAttribute(contentType)}\">`,\n dataUrl,\n \"</uploaded-image>\",\n ].join(\"\\n\");\n}\n\nexport async function buildPromptComposerSubmission(options: {\n text: string;\n attachments?: ReadonlyArray<unknown>;\n}): Promise<{ text: string; files: File[] }> {\n const files: File[] = [];\n const pastedTextBlocks: string[] = [];\n const rawText = options.text;\n\n for (const att of options.attachments ?? []) {\n const a = att as Attachment;\n if (\"file\" in a && a.file instanceof File) {\n const file = a.file;\n if (isPastedTextAttachmentName(file.name)) {\n try {\n pastedTextBlocks.push(await file.text());\n } catch {\n files.push(file);\n }\n } else {\n if (isInlineableTextFile(file)) {\n try {\n pastedTextBlocks.push(\n formatInlineTextFile(file.name, await file.text()),\n );\n } catch {\n // Keep the upload path fallback below.\n }\n } else if (\n file.type.startsWith(\"image/\") &&\n file.size <= AGENT_PROMPT_MAX_INLINE_IMAGE_BYTES &&\n !rawText.trim()\n ) {\n try {\n pastedTextBlocks.push(\n formatInlineImageFile(\n file.name,\n file.type,\n await readFileDataUrl(file),\n ),\n );\n } catch {\n // Keep the upload path fallback below.\n }\n }\n files.push(file);\n }\n }\n }\n\n return {\n text: pastedTextBlocks.length\n ? [rawText.trim(), ...pastedTextBlocks].filter(Boolean).join(\"\\n\\n\")\n : rawText,\n files,\n };\n}\n\nfunction getImageSrc(attachment: Attachment): string | null {\n if (attachment.type !== \"image\") return null;\n if (\"file\" in attachment && attachment.file) {\n return URL.createObjectURL(attachment.file);\n }\n const imagePart = attachment.content?.find((part) => part.type === \"image\");\n return imagePart && \"image\" in imagePart ? imagePart.image : null;\n}\n\nfunction ImagePreviewLightbox({\n src,\n alt,\n onClose,\n}: {\n src: string;\n alt: string;\n onClose: () => void;\n}) {\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handler);\n document.body.style.overflow = \"hidden\";\n return () => {\n document.removeEventListener(\"keydown\", handler);\n document.body.style.overflow = \"\";\n };\n }, [onClose]);\n\n return (\n <div\n role=\"dialog\"\n aria-label=\"Image preview\"\n onClick={onClose}\n className=\"fixed inset-0 z-[300] flex items-center justify-center bg-black/80 p-6 cursor-zoom-out\"\n >\n <img\n src={src}\n alt={alt}\n onClick={(e) => e.stopPropagation()}\n className=\"max-h-full max-w-full object-contain rounded-md shadow-2xl cursor-default\"\n />\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close preview\"\n className=\"absolute right-4 top-4 flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border border-white/30 bg-black/40 text-white hover:bg-black/60\"\n >\n <IconX className=\"h-4 w-4\" />\n </button>\n </div>\n );\n}\n\nfunction AttachmentChip({\n attachment,\n onRemove,\n}: {\n attachment: Attachment;\n onRemove: (id: string) => void;\n}) {\n const src = useMemo(() => getImageSrc(attachment), [attachment]);\n const [previewOpen, setPreviewOpen] = useState(false);\n useEffect(\n () => () => {\n if (src?.startsWith(\"blob:\")) URL.revokeObjectURL(src);\n },\n [src],\n );\n\n if (isPastedTextAttachmentName(attachment.name)) {\n return <PastedTextChip attachment={attachment} onRemove={onRemove} />;\n }\n\n if (src) {\n return (\n <>\n <button\n type=\"button\"\n onClick={() => setPreviewOpen(true)}\n aria-label={`Preview ${attachment.name}`}\n className=\"agent-composer-attachment-image group relative flex h-16 min-w-16 max-w-28 cursor-zoom-in items-center justify-center overflow-hidden rounded-lg border border-border/70 bg-muted/50\"\n >\n <img\n src={src}\n alt={attachment.name}\n className=\"max-h-full max-w-full object-contain p-1\"\n />\n <span\n role=\"button\"\n tabIndex={0}\n onClick={(e) => {\n e.stopPropagation();\n onRemove(attachment.id);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n e.stopPropagation();\n onRemove(attachment.id);\n }\n }}\n aria-label={`Remove ${attachment.name}`}\n className=\"absolute right-1 top-1 flex h-5 w-5 cursor-pointer items-center justify-center rounded-full border border-border/60 bg-background/90 text-muted-foreground hover:text-foreground\"\n >\n <IconX className=\"h-3 w-3\" />\n </span>\n </button>\n {previewOpen ? (\n <ImagePreviewLightbox\n src={src}\n alt={attachment.name}\n onClose={() => setPreviewOpen(false)}\n />\n ) : null}\n </>\n );\n }\n\n return (\n <div className=\"agent-composer-attachment-chip group relative inline-flex max-w-[200px] items-center gap-2 rounded-md border border-border/70 bg-muted/50 px-2 py-1.5 text-xs\">\n <div className=\"flex h-6 w-6 shrink-0 items-center justify-center rounded bg-background text-[9px] font-semibold uppercase text-muted-foreground\">\n {attachment.name.split(\".\").pop() || \"file\"}\n </div>\n <span className=\"min-w-0 truncate font-medium\">{attachment.name}</span>\n <button\n type=\"button\"\n onClick={() => onRemove(attachment.id)}\n aria-label={`Remove ${attachment.name}`}\n className=\"flex h-5 w-5 shrink-0 cursor-pointer items-center justify-center rounded text-muted-foreground hover:text-foreground\"\n >\n <IconX className=\"h-3 w-3\" />\n </button>\n </div>\n );\n}\n\nfunction PromptAttachmentStrip() {\n const attachments = useComposer((state) => state.attachments);\n const aui = useAui();\n\n const handleRemove = useCallback(\n (id: string) => {\n void aui.composer().attachment({ id }).remove();\n },\n [aui],\n );\n\n if (attachments.length === 0) return null;\n return (\n <div className=\"agent-composer-attachment-strip flex flex-wrap gap-2 px-2 pt-2\">\n {attachments.map((attachment) => (\n <AttachmentChip\n key={attachment.id}\n attachment={attachment}\n onRemove={handleRemove}\n />\n ))}\n </div>\n );\n}\n\nfunction PromptComposerInner({\n onSubmit,\n placeholder,\n disabled,\n autoFocus,\n className,\n style,\n rootClassName,\n rootStyle,\n draftScope,\n preserveDraftOnSubmit = false,\n showModelSelector = true,\n voiceEnabled = true,\n attachmentsEnabled = true,\n plusMenuMode,\n initialText,\n initialTextKey,\n modeControl,\n toolbarSlot,\n actionButton,\n extraActionButton,\n layoutVariant,\n slashCommands,\n slashSkills,\n includeDefaultSlashCommands,\n includeDefaultSlashSkills,\n onSlashCommand,\n availableModels,\n selectedModel,\n selectedEngine,\n selectedEffort,\n onModelChange,\n onEffortChange,\n modelStatusChecksEnabled,\n onTextChange,\n onConnectProvider,\n composerRef,\n}: PromptComposerProps) {\n const localRef = useRef<TiptapComposerHandle>(null);\n const handleRef = composerRef ?? localRef;\n const hostManagedModels = Boolean(\n availableModels && selectedModel && onModelChange,\n );\n const resolvedModelStatusChecksEnabled =\n modelStatusChecksEnabled ?? !hostManagedModels;\n const models = useChatModels({\n enabled: showModelSelector && resolvedModelStatusChecksEnabled,\n });\n const composerModel = showModelSelector\n ? (selectedModel ?? models.selectedModel)\n : undefined;\n const composerEngine = showModelSelector\n ? (selectedEngine ?? models.selectedEngine)\n : undefined;\n const composerEffort = showModelSelector\n ? (selectedEffort ?? models.selectedEffort)\n : undefined;\n const composerModelGroups = showModelSelector\n ? (availableModels ?? models.availableModels)\n : undefined;\n const handleModelChange = showModelSelector\n ? (onModelChange ?? models.onModelChange)\n : undefined;\n const handleEffortChange = showModelSelector\n ? (onEffortChange ?? models.onEffortChange)\n : undefined;\n\n useEffect(() => {\n if (!autoFocus) return;\n const id = window.setTimeout(() => {\n const target =\n typeof handleRef === \"object\" && handleRef && \"current\" in handleRef\n ? handleRef.current\n : null;\n target?.focus();\n }, 50);\n return () => window.clearTimeout(id);\n }, [autoFocus, handleRef]);\n\n const handleSubmit = useCallback(\n async (\n text: string,\n references: Reference[],\n attachments?: ReadonlyArray<unknown>,\n submitOptions?: TiptapComposerSubmitOptions,\n ) => {\n // PromptComposer hosts (NewWorkspaceAppFlow, create-extension, create-deck,\n // …) submit a single string prompt — they don't run the assistant-ui\n // attachment send pipeline. TiptapComposer auto-converts large pastes\n // into a \"Pasted text\" chip, which would otherwise disappear into an\n // unprocessed File. Inline the chip body back into the prompt text so\n // newlines and full content survive the round-trip.\n const { text: finalText, files } = await buildPromptComposerSubmission({\n text,\n attachments,\n });\n onSubmit(finalText, files, references, {\n intent: submitOptions?.intent ?? \"immediate\",\n model: composerModel,\n engine: composerEngine,\n effort: composerEffort,\n });\n },\n [composerEffort, composerEngine, composerModel, onSubmit],\n );\n\n return (\n <AgentComposerFrame\n className={cn(\"text-left\", className)}\n rootClassName={rootClassName}\n style={style}\n rootStyle={rootStyle}\n layoutVariant={layoutVariant}\n >\n <PromptAttachmentStrip />\n <TiptapComposer\n focusRef={handleRef}\n disabled={disabled}\n placeholder={placeholder}\n initialText={initialText}\n initialTextKey={initialTextKey}\n onSubmit={handleSubmit}\n clearOnSubmit={!preserveDraftOnSubmit}\n plusMenuMode={\n plusMenuMode ?? (attachmentsEnabled ? \"upload-only\" : \"hidden\")\n }\n modeControl={modeControl}\n toolbarSlot={toolbarSlot}\n actionButton={actionButton}\n extraActionButton={extraActionButton}\n layoutVariant={layoutVariant}\n slashCommands={slashCommands}\n slashSkills={slashSkills}\n includeDefaultSlashCommands={includeDefaultSlashCommands}\n includeDefaultSlashSkills={includeDefaultSlashSkills}\n onSlashCommand={onSlashCommand}\n voiceEnabled={voiceEnabled}\n onTextChange={onTextChange}\n draftScope={draftScope}\n selectedModel={composerModel}\n selectedEffort={composerEffort}\n availableModels={composerModelGroups}\n onModelChange={handleModelChange}\n onEffortChange={handleEffortChange}\n providerConnectStatusEnabled={resolvedModelStatusChecksEnabled}\n onConnectProvider={onConnectProvider}\n />\n </AgentComposerFrame>\n );\n}\n\n/**\n * Standalone composer that mirrors the agent sidebar's input experience —\n * voice dictation, file upload, model selector, submit-on-Enter — for use in\n * popovers and inline prompt forms (create tool, create deck, create dashboard,\n * the Dispatch new-app flow, etc.).\n *\n * The host owns submission: when the user presses Enter or clicks submit,\n * `onSubmit(text, files, references, options)` is called. PromptComposer runs\n * its own minimal assistant-ui runtime so it can be dropped into any subtree\n * without needing the outer chat to be mounted.\n */\nexport function PromptComposer(props: PromptComposerProps) {\n const attachmentAdapter = useMemo(\n () =>\n new CompositeAttachmentAdapter([\n new SimpleImageAttachmentAdapter(),\n new BinaryDocumentAttachmentAdapter(),\n new TextAttachmentAdapter(),\n ]),\n [],\n );\n const runtime = useLocalRuntime(NOOP_ADAPTER, {\n adapters: { attachments: attachmentAdapter },\n });\n const resetKey = [\n props.draftScope ?? \"\",\n props.initialTextKey ?? \"\",\n props.initialText ?? \"\",\n ].join(\":\");\n\n return (\n <TooltipProvider delayDuration={200}>\n <AssistantRuntimeProvider runtime={runtime}>\n <ThreadPrimitive.Root\n className=\"contents\"\n style={{ display: \"contents\" }}\n >\n <AssistantUiStaleIndexErrorBoundary\n resetKey={resetKey}\n componentName=\"PromptComposer\"\n >\n <PromptComposerInner {...props} />\n </AssistantUiStaleIndexErrorBoundary>\n </ThreadPrimitive.Root>\n </AssistantRuntimeProvider>\n </TooltipProvider>\n );\n}\n"]}
|