@agent-native/core 0.12.23 → 0.12.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/agent/thread-data-builder.d.ts +10 -0
  2. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  3. package/dist/agent/thread-data-builder.js +80 -0
  4. package/dist/agent/thread-data-builder.js.map +1 -1
  5. package/dist/agent/types.d.ts +7 -0
  6. package/dist/agent/types.d.ts.map +1 -1
  7. package/dist/agent/types.js.map +1 -1
  8. package/dist/cli/create.d.ts.map +1 -1
  9. package/dist/cli/create.js +3 -3
  10. package/dist/cli/create.js.map +1 -1
  11. package/dist/client/AgentPanel.d.ts.map +1 -1
  12. package/dist/client/AgentPanel.js +9 -1
  13. package/dist/client/AgentPanel.js.map +1 -1
  14. package/dist/client/AssistantChat.d.ts.map +1 -1
  15. package/dist/client/AssistantChat.js +49 -10
  16. package/dist/client/AssistantChat.js.map +1 -1
  17. package/dist/client/ErrorBoundary.d.ts.map +1 -1
  18. package/dist/client/ErrorBoundary.js +3 -2
  19. package/dist/client/ErrorBoundary.js.map +1 -1
  20. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  21. package/dist/client/agent-chat-adapter.js +93 -45
  22. package/dist/client/agent-chat-adapter.js.map +1 -1
  23. package/dist/client/composer/PromptComposer.js +1 -1
  24. package/dist/client/composer/PromptComposer.js.map +1 -1
  25. package/dist/client/composer/TiptapComposer.d.ts +5 -0
  26. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  27. package/dist/client/composer/TiptapComposer.js +10 -1
  28. package/dist/client/composer/TiptapComposer.js.map +1 -1
  29. package/dist/client/onboarding/OnboardingPanel.js +2 -1
  30. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  31. package/dist/client/progress/RunsTray.d.ts.map +1 -1
  32. package/dist/client/progress/RunsTray.js +18 -3
  33. package/dist/client/progress/RunsTray.js.map +1 -1
  34. package/dist/client/resources/ResourceTree.d.ts.map +1 -1
  35. package/dist/client/resources/ResourceTree.js +5 -4
  36. package/dist/client/resources/ResourceTree.js.map +1 -1
  37. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  38. package/dist/client/settings/useBuilderStatus.js +5 -3
  39. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  40. package/dist/collab/client.d.ts +9 -0
  41. package/dist/collab/client.d.ts.map +1 -1
  42. package/dist/collab/client.js +36 -10
  43. package/dist/collab/client.js.map +1 -1
  44. package/dist/onboarding/default-steps.js +1 -1
  45. package/dist/onboarding/default-steps.js.map +1 -1
  46. package/dist/progress/store.d.ts.map +1 -1
  47. package/dist/progress/store.js +1 -1
  48. package/dist/progress/store.js.map +1 -1
  49. package/dist/server/action-routes.d.ts +2 -0
  50. package/dist/server/action-routes.d.ts.map +1 -1
  51. package/dist/server/action-routes.js +4 -1
  52. package/dist/server/action-routes.js.map +1 -1
  53. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  54. package/dist/server/agent-chat-plugin.js +27 -15
  55. package/dist/server/agent-chat-plugin.js.map +1 -1
  56. package/dist/server/index.d.ts +1 -1
  57. package/dist/server/index.d.ts.map +1 -1
  58. package/dist/server/index.js +1 -1
  59. package/dist/server/index.js.map +1 -1
  60. package/dist/server/request-context.d.ts +9 -0
  61. package/dist/server/request-context.d.ts.map +1 -1
  62. package/dist/server/request-context.js +13 -0
  63. package/dist/server/request-context.js.map +1 -1
  64. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ErrorBoundary.d.ts","sourceRoot":"","sources":["../../src/client/ErrorBoundary.tsx"],"names":[],"mappings":"AA2GA,wBAAgB,aAAa,4CAS5B"}
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
- details = "This page doesn’t exist. It may have been moved or deleted.";
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":"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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 details = \"This page doesn’t exist. It may have been moved or deleted.\";\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 {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
+ {"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;AAsZrE;;;;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,CAo3BnB"}
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;AAggBrE;;;;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,CAw0BnB"}
@@ -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, "&amp;")
65
+ .replace(/"/g, "&quot;")
66
+ .replace(/</g, "&lt;")
67
+ .replace(/>/g, "&gt;");
68
+ }
61
69
  function isTextAttachmentContentType(value) {
62
70
  if (!value)
63
71
  return false;
@@ -84,6 +92,78 @@ 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: decodedText }
119
+ : part.data.startsWith("data:")
120
+ ? { data: part.data }
121
+ : { text: 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: 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 attachmentHistoryText(attachment) {
143
+ if (typeof attachment.text === "string" && attachment.text.length > 0) {
144
+ const attrs = [
145
+ `name="${escapeAttachmentAttribute(attachment.name || "attachment")}"`,
146
+ attachment.contentType
147
+ ? `contentType="${escapeAttachmentAttribute(attachment.contentType)}"`
148
+ : null,
149
+ attachment.type
150
+ ? `type="${escapeAttachmentAttribute(attachment.type)}"`
151
+ : null,
152
+ ].filter(Boolean);
153
+ return `<attachment ${attrs.join(" ")}>\n${truncateHistoryAttachment(attachment.text)}\n</attachment>`;
154
+ }
155
+ if (attachment.name) {
156
+ return `[Attached ${attachment.type || "file"}: ${attachment.name}${attachment.contentType ? ` (${attachment.contentType})` : ""}]`;
157
+ }
158
+ return null;
159
+ }
160
+ function messageTextForHistory(message) {
161
+ const text = messageTextFromContent(message.content);
162
+ const attachments = extractAttachmentsFromMessage(message)
163
+ .map(attachmentHistoryText)
164
+ .filter((part) => !!part && part.trim().length > 0);
165
+ return [text, ...attachments].filter((part) => part.trim()).join("\n\n");
166
+ }
87
167
  function isToolCallContentPart(part) {
88
168
  return Boolean(part && typeof part === "object" && part.type === "tool-call");
89
169
  }
@@ -150,7 +230,7 @@ function assistantUiMessagesToStructuredHistory(messages) {
150
230
  const structured = [];
151
231
  for (const message of messages) {
152
232
  if (message.role === "user") {
153
- const text = messageTextFromContent(message.content);
233
+ const text = messageTextForHistory(message);
154
234
  if (text.trim()) {
155
235
  structured.push({
156
236
  role: "user",
@@ -361,47 +441,9 @@ export function createAgentChatAdapter(options) {
361
441
  // Extract attachments (images as base64, text as content).
362
442
  // assistant-ui puts user attachments on msg.attachments (not on content);
363
443
  // each attachment carries its own content parts from the adapter.
364
- const attachments = [];
365
- if (lastUserMsg && "attachments" in lastUserMsg) {
366
- const msgAttachments = lastUserMsg.attachments;
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
- }
444
+ const attachments = lastUserMsg
445
+ ? extractAttachmentsFromMessage(lastUserMsg)
446
+ : [];
405
447
  const userMessageText = rawMessageText.trim() || attachments.length === 0
406
448
  ? rawMessageText
407
449
  : "Use the attached context.";
@@ -410,7 +452,9 @@ export function createAgentChatAdapter(options) {
410
452
  .filter((m) => m.role === "user" || m.role === "assistant")
411
453
  .map((m) => ({
412
454
  role: m.role,
413
- content: messageTextFromContent(m.content),
455
+ content: m.role === "user"
456
+ ? messageTextForHistory(m)
457
+ : messageTextFromContent(m.content),
414
458
  }))
415
459
  .filter((m) => m.content.trim());
416
460
  const structuredHistory = assistantUiMessagesToStructuredHistory(priorMessages);
@@ -711,8 +755,12 @@ export function createAgentChatAdapter(options) {
711
755
  ...structuredCombinedHistory,
712
756
  ];
713
757
  currentMessageText = autoContinueMessage(signal);
714
- includeAttachments = false;
715
- includeReferences = false;
758
+ // Continuation requests are stateless new POSTs. If the interrupted
759
+ // turn depended on uploaded context, re-send that context; otherwise
760
+ // an attachment-only prompt degrades to "Use the attached context."
761
+ // with nothing attached after a stale run or reconnect recovery.
762
+ includeAttachments = attachments.length > 0;
763
+ includeReferences = Boolean(runConfig?.custom?.references);
716
764
  startupRecoveryAttempts = 0;
717
765
  clearActiveRun();
718
766
  if (!isTransient) {