@agent-native/core 0.12.23 → 0.12.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/production-agent.d.ts +9 -2
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +36 -35
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +26 -1
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +212 -0
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/agent/types.d.ts +7 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +3 -3
- package/dist/cli/create.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +9 -1
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +49 -10
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/ErrorBoundary.d.ts.map +1 -1
- package/dist/client/ErrorBoundary.js +3 -2
- package/dist/client/ErrorBoundary.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +105 -45
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/composer/PromptComposer.js +1 -1
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +5 -0
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +10 -1
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.js +2 -1
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/client/progress/RunsTray.d.ts.map +1 -1
- package/dist/client/progress/RunsTray.js +20 -3
- package/dist/client/progress/RunsTray.js.map +1 -1
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +5 -4
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +5 -3
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +4 -1
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/collab/client.d.ts +9 -0
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +36 -10
- package/dist/collab/client.js.map +1 -1
- package/dist/onboarding/default-steps.d.ts.map +1 -1
- package/dist/onboarding/default-steps.js +9 -2
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/progress/store.d.ts.map +1 -1
- package/dist/progress/store.js +1 -1
- package/dist/progress/store.js.map +1 -1
- package/dist/server/action-routes.d.ts +2 -0
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +4 -1
- 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 +79 -16
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +2 -2
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +22 -1
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/google-oauth.js +1 -1
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/request-context.d.ts +9 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +13 -0
- package/dist/server/request-context.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorBoundary.d.ts","sourceRoot":"","sources":["../../src/client/ErrorBoundary.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ErrorBoundary.d.ts","sourceRoot":"","sources":["../../src/client/ErrorBoundary.tsx"],"names":[],"mappings":"AAoHA,wBAAgB,aAAa,4CAS5B"}
|
|
@@ -31,7 +31,8 @@ function ErrorScreen({ error, canUseRouterLink, }) {
|
|
|
31
31
|
status = error.status;
|
|
32
32
|
if (error.status === 404) {
|
|
33
33
|
title = "Page not found";
|
|
34
|
-
|
|
34
|
+
const path = typeof window !== "undefined" ? window.location.pathname : "this path";
|
|
35
|
+
details = `The app does not define a route for ${path}. If this should be a workspace app, make sure it is added and enabled in Dispatch; if it is a new screen, it may need to be shipped first.`;
|
|
35
36
|
}
|
|
36
37
|
else {
|
|
37
38
|
title = `${error.status} Error`;
|
|
@@ -59,7 +60,7 @@ function ErrorScreen({ error, canUseRouterLink, }) {
|
|
|
59
60
|
if (typeof console !== "undefined" && error) {
|
|
60
61
|
console.error("[ErrorBoundary]", error);
|
|
61
62
|
}
|
|
62
|
-
return (_jsx("main", { className: "flex items-center justify-center min-h-screen p-4 bg-background text-foreground", children: _jsxs("div", { className: "flex flex-col items-center text-center max-w-md", children: [status && (_jsx("span", { className: "text-7xl font-bold tracking-tight text-muted-foreground/40", children: status })), _jsx("h1", { className: "mt-3 text-2xl font-semibold", children: title }), _jsx("p", { className: "mt-2 text-muted-foreground text-sm", children: details }), canUseRouterLink ? (_jsx(Link, { to: "/", className: homeLinkClassName, children: "Go home" })) : (_jsx("a", { href: "/", className: homeLinkClassName, children: "Go home" })), stack && (_jsx("pre", { className: "mt-6 w-full text-left text-xs overflow-auto p-4 bg-muted rounded", children: _jsx("code", { children: stack }) }))] }) }));
|
|
63
|
+
return (_jsx("main", { className: "flex items-center justify-center min-h-screen p-4 bg-background text-foreground", children: _jsxs("div", { className: "flex flex-col items-center text-center max-w-md", children: [status && (_jsx("span", { className: "text-7xl font-bold tracking-tight text-muted-foreground/40", children: status })), _jsx("h1", { className: "mt-3 text-2xl font-semibold", children: title }), _jsx("p", { className: "mt-2 text-muted-foreground text-sm", children: details }), canUseRouterLink ? (_jsx(Link, { to: "/", className: homeLinkClassName, children: "Go home" })) : (_jsx("a", { href: "/", className: homeLinkClassName, children: "Go home" })), _jsx("button", { type: "button", onClick: () => window.location.reload(), className: "mt-3 inline-flex cursor-pointer items-center gap-1.5 rounded-md border border-border bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm hover:bg-accent", children: "Reload" }), stack && (_jsx("pre", { className: "mt-6 w-full text-left text-xs overflow-auto p-4 bg-muted rounded", children: _jsx("code", { children: stack }) }))] }) }));
|
|
63
64
|
}
|
|
64
65
|
function RoutedErrorScreen() {
|
|
65
66
|
return _jsx(ErrorScreen, { error: useRouteError(), canUseRouterLink: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorBoundary.js","sourceRoot":"","sources":["../../src/client/ErrorBoundary.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EACL,oBAAoB,EACpB,IAAI,EACJ,kBAAkB,EAClB,aAAa,GACd,MAAM,cAAc,CAAC;AAEtB,MAAM,iBAAiB,GACrB,gKAAgK,CAAC;AAEnK,SAAS,kBAAkB;IACzB,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,IAAI,GAAG,QAAQ,CAAC,eAAe,CAAC;QACtC,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;YACrE,OAAO;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBACtB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC7B,CAAC;iBAAM,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC9B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC9B,CAAC;iBAAM,IAAI,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,OAAO,EAAE,CAAC;gBACrE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AAED,SAAS,WAAW,CAAC,EACnB,KAAK,EACL,gBAAgB,GAIjB;IACC,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,KAAK,GAAG,sBAAsB,CAAC;IACnC,IAAI,OAAO,GAAG,+BAA+B,CAAC;IAC9C,IAAI,KAAyB,CAAC;IAE9B,IAAI,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QACtB,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACzB,KAAK,GAAG,gBAAgB,CAAC;YACzB,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"ErrorBoundary.js","sourceRoot":"","sources":["../../src/client/ErrorBoundary.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect } from \"react\";\nimport {\n isRouteErrorResponse,\n Link,\n useInRouterContext,\n useRouteError,\n} from \"react-router\";\n\nconst homeLinkClassName =\n \"mt-6 inline-flex items-center gap-1.5 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm hover:bg-primary/90 cursor-pointer\";\n\nfunction useApplyThemeClass() {\n useEffect(() => {\n const root = document.documentElement;\n if (root.classList.contains(\"dark\") || root.classList.contains(\"light\"))\n return;\n try {\n const stored = localStorage.getItem(\"theme\");\n if (stored === \"dark\") {\n root.classList.add(\"dark\");\n } else if (stored === \"light\") {\n root.classList.add(\"light\");\n } else if (window.matchMedia(\"(prefers-color-scheme: dark)\").matches) {\n root.classList.add(\"dark\");\n }\n } catch {}\n }, []);\n}\n\nfunction ErrorScreen({\n error,\n canUseRouterLink,\n}: {\n error: unknown;\n canUseRouterLink: boolean;\n}) {\n let status: number | null = null;\n let title = \"Something went wrong\";\n let details = \"An unexpected error occurred.\";\n let stack: string | undefined;\n\n if (isRouteErrorResponse(error)) {\n status = error.status;\n if (error.status === 404) {\n title = \"Page not found\";\n const path =\n typeof window !== \"undefined\" ? window.location.pathname : \"this path\";\n details = `The app does not define a route for ${path}. If this should be a workspace app, make sure it is added and enabled in Dispatch; if it is a new screen, it may need to be shipped first.`;\n } else {\n title = `${error.status} Error`;\n details = error.statusText || details;\n }\n } else if (error instanceof Error) {\n // Always surface the underlying error message — a generic\n // \"An unexpected error occurred.\" in production tells users (and us)\n // nothing. The stack trace is still gated to dev so we don't leak\n // internals to end users.\n if (error.message) {\n details = error.message;\n }\n if (\n typeof process !== \"undefined\" &&\n process.env.NODE_ENV !== \"production\"\n ) {\n stack = error.stack;\n }\n } else if (typeof error === \"string\" && error) {\n details = error;\n }\n\n // Log to the console so the underlying failure is recoverable from\n // browser devtools / Sentry even when the UI hides the stack.\n if (typeof console !== \"undefined\" && error) {\n console.error(\"[ErrorBoundary]\", error);\n }\n\n return (\n <main className=\"flex items-center justify-center min-h-screen p-4 bg-background text-foreground\">\n <div className=\"flex flex-col items-center text-center max-w-md\">\n {status && (\n <span className=\"text-7xl font-bold tracking-tight text-muted-foreground/40\">\n {status}\n </span>\n )}\n <h1 className=\"mt-3 text-2xl font-semibold\">{title}</h1>\n <p className=\"mt-2 text-muted-foreground text-sm\">{details}</p>\n {canUseRouterLink ? (\n <Link to=\"/\" className={homeLinkClassName}>\n Go home\n </Link>\n ) : (\n <a href=\"/\" className={homeLinkClassName}>\n Go home\n </a>\n )}\n <button\n type=\"button\"\n onClick={() => window.location.reload()}\n className=\"mt-3 inline-flex cursor-pointer items-center gap-1.5 rounded-md border border-border bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm hover:bg-accent\"\n >\n Reload\n </button>\n {stack && (\n <pre className=\"mt-6 w-full text-left text-xs overflow-auto p-4 bg-muted rounded\">\n <code>{stack}</code>\n </pre>\n )}\n </div>\n </main>\n );\n}\n\nfunction RoutedErrorScreen() {\n return <ErrorScreen error={useRouteError()} canUseRouterLink />;\n}\n\nexport function ErrorBoundary() {\n useApplyThemeClass();\n const inRouterContext = useInRouterContext();\n\n if (!inRouterContext) {\n return <ErrorScreen error={undefined} canUseRouterLink={false} />;\n }\n\n return <RoutedErrorScreen />;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-chat-adapter.d.ts","sourceRoot":"","sources":["../../src/client/agent-chat-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,qBAAqB,CAAC;AAehF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-chat-adapter.d.ts","sourceRoot":"","sources":["../../src/client/agent-chat-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,qBAAqB,CAAC;AAehF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAsgBrE;;;;GAIG;AACH;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IAC3C,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IAC5C,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,eAAe,GAAG,SAAS,CAAA;KAAE,CAAC;IACrD,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;CACzD,GAAG,gBAAgB,CA80BnB"}
|
|
@@ -23,6 +23,7 @@ const MAX_STALLED_TRANSIENT_CONTINUATIONS = 8;
|
|
|
23
23
|
const MAX_TOTAL_TRANSIENT_CONTINUATIONS = 32;
|
|
24
24
|
const RETRY_BASE_DELAY_MS = 500;
|
|
25
25
|
const RETRY_MAX_DELAY_MS = 8_000;
|
|
26
|
+
const MAX_HISTORY_ATTACHMENT_CHARS = 60_000;
|
|
26
27
|
function normalizeMentions(text) {
|
|
27
28
|
return text.replace(/@\[([^\]|]+)\|[^\]]+\]/g, "@$1");
|
|
28
29
|
}
|
|
@@ -58,6 +59,13 @@ function messageTextFromContent(content) {
|
|
|
58
59
|
.map((p) => normalizeMentions(p.text))
|
|
59
60
|
.join("\n");
|
|
60
61
|
}
|
|
62
|
+
function escapeAttachmentAttribute(value) {
|
|
63
|
+
return value
|
|
64
|
+
.replace(/&/g, "&")
|
|
65
|
+
.replace(/"/g, """)
|
|
66
|
+
.replace(/</g, "<")
|
|
67
|
+
.replace(/>/g, ">");
|
|
68
|
+
}
|
|
61
69
|
function isTextAttachmentContentType(value) {
|
|
62
70
|
if (!value)
|
|
63
71
|
return false;
|
|
@@ -84,6 +92,84 @@ function decodeTextDataUrl(dataUrl) {
|
|
|
84
92
|
return null;
|
|
85
93
|
}
|
|
86
94
|
}
|
|
95
|
+
function extractAttachmentsFromMessage(message) {
|
|
96
|
+
const attachments = [];
|
|
97
|
+
for (const att of message.attachments ?? []) {
|
|
98
|
+
for (const part of att.content) {
|
|
99
|
+
if (part.type === "image" && typeof part.image === "string") {
|
|
100
|
+
attachments.push({
|
|
101
|
+
type: "image",
|
|
102
|
+
name: att.name,
|
|
103
|
+
contentType: att.contentType,
|
|
104
|
+
data: part.image,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
else if (part.type === "file" && typeof part.data === "string") {
|
|
108
|
+
const contentType = att.contentType ??
|
|
109
|
+
(typeof part.mimeType === "string" ? part.mimeType : undefined);
|
|
110
|
+
const decodedText = part.data.startsWith("data:")
|
|
111
|
+
? decodeTextDataUrl(part.data)
|
|
112
|
+
: null;
|
|
113
|
+
attachments.push({
|
|
114
|
+
type: "file",
|
|
115
|
+
name: att.name,
|
|
116
|
+
contentType,
|
|
117
|
+
...(decodedText !== null
|
|
118
|
+
? { text: truncateOutboundAttachment(decodedText) }
|
|
119
|
+
: part.data.startsWith("data:")
|
|
120
|
+
? { data: part.data }
|
|
121
|
+
: { text: truncateOutboundAttachment(part.data) }),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
else if (part.type === "text" && typeof part.text === "string") {
|
|
125
|
+
attachments.push({
|
|
126
|
+
type: "file",
|
|
127
|
+
name: att.name,
|
|
128
|
+
contentType: att.contentType,
|
|
129
|
+
text: truncateOutboundAttachment(unwrapAttachmentEnvelope(part.text)),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return attachments;
|
|
135
|
+
}
|
|
136
|
+
function truncateHistoryAttachment(text) {
|
|
137
|
+
if (text.length <= MAX_HISTORY_ATTACHMENT_CHARS)
|
|
138
|
+
return text;
|
|
139
|
+
const omitted = text.length - MAX_HISTORY_ATTACHMENT_CHARS;
|
|
140
|
+
return `${text.slice(0, MAX_HISTORY_ATTACHMENT_CHARS)}\n\n[Attachment truncated after ${MAX_HISTORY_ATTACHMENT_CHARS.toLocaleString()} characters; ${omitted.toLocaleString()} characters omitted from prior chat history.]`;
|
|
141
|
+
}
|
|
142
|
+
function truncateOutboundAttachment(text) {
|
|
143
|
+
if (text.length <= MAX_HISTORY_ATTACHMENT_CHARS)
|
|
144
|
+
return text;
|
|
145
|
+
const omitted = text.length - MAX_HISTORY_ATTACHMENT_CHARS;
|
|
146
|
+
return `${text.slice(0, MAX_HISTORY_ATTACHMENT_CHARS)}\n\n[Attachment truncated after ${MAX_HISTORY_ATTACHMENT_CHARS.toLocaleString()} characters; ${omitted.toLocaleString()} characters omitted from the submitted attachment.]`;
|
|
147
|
+
}
|
|
148
|
+
function attachmentHistoryText(attachment) {
|
|
149
|
+
if (typeof attachment.text === "string" && attachment.text.length > 0) {
|
|
150
|
+
const attrs = [
|
|
151
|
+
`name="${escapeAttachmentAttribute(attachment.name || "attachment")}"`,
|
|
152
|
+
attachment.contentType
|
|
153
|
+
? `contentType="${escapeAttachmentAttribute(attachment.contentType)}"`
|
|
154
|
+
: null,
|
|
155
|
+
attachment.type
|
|
156
|
+
? `type="${escapeAttachmentAttribute(attachment.type)}"`
|
|
157
|
+
: null,
|
|
158
|
+
].filter(Boolean);
|
|
159
|
+
return `<attachment ${attrs.join(" ")}>\n${truncateHistoryAttachment(attachment.text)}\n</attachment>`;
|
|
160
|
+
}
|
|
161
|
+
if (attachment.name) {
|
|
162
|
+
return `[Attached ${attachment.type || "file"}: ${attachment.name}${attachment.contentType ? ` (${attachment.contentType})` : ""}]`;
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
function messageTextForHistory(message) {
|
|
167
|
+
const text = messageTextFromContent(message.content);
|
|
168
|
+
const attachments = extractAttachmentsFromMessage(message)
|
|
169
|
+
.map(attachmentHistoryText)
|
|
170
|
+
.filter((part) => !!part && part.trim().length > 0);
|
|
171
|
+
return [text, ...attachments].filter((part) => part.trim()).join("\n\n");
|
|
172
|
+
}
|
|
87
173
|
function isToolCallContentPart(part) {
|
|
88
174
|
return Boolean(part && typeof part === "object" && part.type === "tool-call");
|
|
89
175
|
}
|
|
@@ -150,7 +236,7 @@ function assistantUiMessagesToStructuredHistory(messages) {
|
|
|
150
236
|
const structured = [];
|
|
151
237
|
for (const message of messages) {
|
|
152
238
|
if (message.role === "user") {
|
|
153
|
-
const text =
|
|
239
|
+
const text = messageTextForHistory(message);
|
|
154
240
|
if (text.trim()) {
|
|
155
241
|
structured.push({
|
|
156
242
|
role: "user",
|
|
@@ -361,47 +447,9 @@ export function createAgentChatAdapter(options) {
|
|
|
361
447
|
// Extract attachments (images as base64, text as content).
|
|
362
448
|
// assistant-ui puts user attachments on msg.attachments (not on content);
|
|
363
449
|
// each attachment carries its own content parts from the adapter.
|
|
364
|
-
const attachments =
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
for (const att of msgAttachments ?? []) {
|
|
368
|
-
for (const part of att.content) {
|
|
369
|
-
if (part.type === "image" && typeof part.image === "string") {
|
|
370
|
-
attachments.push({
|
|
371
|
-
type: "image",
|
|
372
|
-
name: att.name,
|
|
373
|
-
contentType: att.contentType,
|
|
374
|
-
data: part.image,
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
else if (part.type === "file" && typeof part.data === "string") {
|
|
378
|
-
const contentType = att.contentType ??
|
|
379
|
-
(typeof part.mimeType === "string" ? part.mimeType : undefined);
|
|
380
|
-
const decodedText = part.data.startsWith("data:")
|
|
381
|
-
? decodeTextDataUrl(part.data)
|
|
382
|
-
: null;
|
|
383
|
-
attachments.push({
|
|
384
|
-
type: "file",
|
|
385
|
-
name: att.name,
|
|
386
|
-
contentType,
|
|
387
|
-
...(decodedText !== null
|
|
388
|
-
? { text: decodedText }
|
|
389
|
-
: part.data.startsWith("data:")
|
|
390
|
-
? { data: part.data }
|
|
391
|
-
: { text: part.data }),
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
else if (part.type === "text" && typeof part.text === "string") {
|
|
395
|
-
attachments.push({
|
|
396
|
-
type: "file",
|
|
397
|
-
name: att.name,
|
|
398
|
-
contentType: att.contentType,
|
|
399
|
-
text: unwrapAttachmentEnvelope(part.text),
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
}
|
|
450
|
+
const attachments = lastUserMsg
|
|
451
|
+
? extractAttachmentsFromMessage(lastUserMsg)
|
|
452
|
+
: [];
|
|
405
453
|
const userMessageText = rawMessageText.trim() || attachments.length === 0
|
|
406
454
|
? rawMessageText
|
|
407
455
|
: "Use the attached context.";
|
|
@@ -410,7 +458,9 @@ export function createAgentChatAdapter(options) {
|
|
|
410
458
|
.filter((m) => m.role === "user" || m.role === "assistant")
|
|
411
459
|
.map((m) => ({
|
|
412
460
|
role: m.role,
|
|
413
|
-
content:
|
|
461
|
+
content: m.role === "user"
|
|
462
|
+
? messageTextForHistory(m)
|
|
463
|
+
: messageTextFromContent(m.content),
|
|
414
464
|
}))
|
|
415
465
|
.filter((m) => m.content.trim());
|
|
416
466
|
const structuredHistory = assistantUiMessagesToStructuredHistory(priorMessages);
|
|
@@ -429,6 +479,7 @@ export function createAgentChatAdapter(options) {
|
|
|
429
479
|
let currentStructuredHistory = structuredHistory;
|
|
430
480
|
let includeAttachments = attachments.length > 0;
|
|
431
481
|
let includeReferences = Boolean(runConfig?.custom?.references);
|
|
482
|
+
let internalContinuationRequest = false;
|
|
432
483
|
let startupRecoveryAttempts = 0;
|
|
433
484
|
let staleRunContinuationAttempts = 0;
|
|
434
485
|
let stalledTransientContinuationAttempts = 0;
|
|
@@ -711,8 +762,13 @@ export function createAgentChatAdapter(options) {
|
|
|
711
762
|
...structuredCombinedHistory,
|
|
712
763
|
];
|
|
713
764
|
currentMessageText = autoContinueMessage(signal);
|
|
714
|
-
|
|
715
|
-
|
|
765
|
+
// Continuation requests are stateless new POSTs. If the interrupted
|
|
766
|
+
// turn depended on uploaded context, re-send that context; otherwise
|
|
767
|
+
// an attachment-only prompt degrades to "Use the attached context."
|
|
768
|
+
// with nothing attached after a stale run or reconnect recovery.
|
|
769
|
+
includeAttachments = attachments.length > 0;
|
|
770
|
+
includeReferences = Boolean(runConfig?.custom?.references);
|
|
771
|
+
internalContinuationRequest = true;
|
|
716
772
|
startupRecoveryAttempts = 0;
|
|
717
773
|
clearActiveRun();
|
|
718
774
|
if (!isTransient) {
|
|
@@ -732,9 +788,13 @@ export function createAgentChatAdapter(options) {
|
|
|
732
788
|
headers,
|
|
733
789
|
body: JSON.stringify({
|
|
734
790
|
message: currentMessageText,
|
|
791
|
+
displayMessage: userMessageText,
|
|
735
792
|
history: currentHistory,
|
|
736
793
|
structuredHistory: currentStructuredHistory,
|
|
737
794
|
...(threadId ? { threadId } : {}),
|
|
795
|
+
...(internalContinuationRequest
|
|
796
|
+
? { internalContinuation: true }
|
|
797
|
+
: {}),
|
|
738
798
|
...(requestMode ? { mode: requestMode } : {}),
|
|
739
799
|
...(modelRef?.current ? { model: modelRef.current } : {}),
|
|
740
800
|
...(engineRef?.current ? { engine: engineRef.current } : {}),
|