@agent-native/core 0.7.81 → 0.7.83

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 (257) hide show
  1. package/dist/action.d.ts +8 -0
  2. package/dist/action.d.ts.map +1 -1
  3. package/dist/action.js +4 -0
  4. package/dist/action.js.map +1 -1
  5. package/dist/agent/production-agent.d.ts +12 -2
  6. package/dist/agent/production-agent.d.ts.map +1 -1
  7. package/dist/agent/production-agent.js +58 -20
  8. package/dist/agent/production-agent.js.map +1 -1
  9. package/dist/agent/run-manager.d.ts +8 -1
  10. package/dist/agent/run-manager.d.ts.map +1 -1
  11. package/dist/agent/run-manager.js +11 -12
  12. package/dist/agent/run-manager.js.map +1 -1
  13. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  14. package/dist/agent/thread-data-builder.js +13 -17
  15. package/dist/agent/thread-data-builder.js.map +1 -1
  16. package/dist/agent/types.d.ts +4 -0
  17. package/dist/agent/types.d.ts.map +1 -1
  18. package/dist/agent/types.js.map +1 -1
  19. package/dist/application-state/handlers.d.ts.map +1 -1
  20. package/dist/application-state/handlers.js +3 -8
  21. package/dist/application-state/handlers.js.map +1 -1
  22. package/dist/application-state/script-helpers.d.ts +2 -4
  23. package/dist/application-state/script-helpers.d.ts.map +1 -1
  24. package/dist/application-state/script-helpers.js +10 -47
  25. package/dist/application-state/script-helpers.js.map +1 -1
  26. package/dist/cli/create.d.ts +1 -1
  27. package/dist/cli/create.d.ts.map +1 -1
  28. package/dist/cli/create.js +35 -10
  29. package/dist/cli/create.js.map +1 -1
  30. package/dist/cli/workspace-dev.js +78 -15
  31. package/dist/cli/workspace-dev.js.map +1 -1
  32. package/dist/client/AgentPanel.d.ts.map +1 -1
  33. package/dist/client/AgentPanel.js +6 -2
  34. package/dist/client/AgentPanel.js.map +1 -1
  35. package/dist/client/AssistantChat.d.ts +0 -15
  36. package/dist/client/AssistantChat.d.ts.map +1 -1
  37. package/dist/client/AssistantChat.js +69 -57
  38. package/dist/client/AssistantChat.js.map +1 -1
  39. package/dist/client/ConnectBuilderCard.d.ts +7 -1
  40. package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
  41. package/dist/client/ConnectBuilderCard.js +46 -5
  42. package/dist/client/ConnectBuilderCard.js.map +1 -1
  43. package/dist/client/ErrorBoundary.d.ts.map +1 -1
  44. package/dist/client/ErrorBoundary.js +20 -5
  45. package/dist/client/ErrorBoundary.js.map +1 -1
  46. package/dist/client/FeedbackButton.d.ts +3 -2
  47. package/dist/client/FeedbackButton.d.ts.map +1 -1
  48. package/dist/client/FeedbackButton.js +23 -15
  49. package/dist/client/FeedbackButton.js.map +1 -1
  50. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  51. package/dist/client/agent-chat-adapter.js +303 -169
  52. package/dist/client/agent-chat-adapter.js.map +1 -1
  53. package/dist/client/builder-frame.d.ts +36 -0
  54. package/dist/client/builder-frame.d.ts.map +1 -1
  55. package/dist/client/builder-frame.js +80 -9
  56. package/dist/client/builder-frame.js.map +1 -1
  57. package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
  58. package/dist/client/composer/ComposerPlusMenu.js +7 -2
  59. package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
  60. package/dist/client/composer/PastedTextChip.d.ts +9 -0
  61. package/dist/client/composer/PastedTextChip.d.ts.map +1 -0
  62. package/dist/client/composer/PastedTextChip.js +47 -0
  63. package/dist/client/composer/PastedTextChip.js.map +1 -0
  64. package/dist/client/composer/PromptComposer.d.ts +4 -2
  65. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  66. package/dist/client/composer/PromptComposer.js +33 -5
  67. package/dist/client/composer/PromptComposer.js.map +1 -1
  68. package/dist/client/composer/TiptapComposer.d.ts +13 -1
  69. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  70. package/dist/client/composer/TiptapComposer.js +61 -16
  71. package/dist/client/composer/TiptapComposer.js.map +1 -1
  72. package/dist/client/composer/VoiceButton.d.ts.map +1 -1
  73. package/dist/client/composer/VoiceButton.js +5 -1
  74. package/dist/client/composer/VoiceButton.js.map +1 -1
  75. package/dist/client/composer/pasted-text.d.ts +6 -0
  76. package/dist/client/composer/pasted-text.d.ts.map +1 -0
  77. package/dist/client/composer/pasted-text.js +49 -0
  78. package/dist/client/composer/pasted-text.js.map +1 -0
  79. package/dist/client/composer/useVoiceDictation.d.ts +1 -0
  80. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  81. package/dist/client/composer/useVoiceDictation.js +18 -0
  82. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  83. package/dist/client/index.d.ts +0 -1
  84. package/dist/client/index.d.ts.map +1 -1
  85. package/dist/client/index.js +0 -1
  86. package/dist/client/index.js.map +1 -1
  87. package/dist/client/integrations/IntegrationCard.d.ts.map +1 -1
  88. package/dist/client/integrations/IntegrationCard.js +14 -2
  89. package/dist/client/integrations/IntegrationCard.js.map +1 -1
  90. package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
  91. package/dist/client/integrations/IntegrationsPanel.js +23 -4
  92. package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
  93. package/dist/client/notifications/NotificationsBell.d.ts.map +1 -1
  94. package/dist/client/notifications/NotificationsBell.js +4 -42
  95. package/dist/client/notifications/NotificationsBell.js.map +1 -1
  96. package/dist/client/org/OrgSwitcher.d.ts +4 -6
  97. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  98. package/dist/client/org/OrgSwitcher.js +84 -74
  99. package/dist/client/org/OrgSwitcher.js.map +1 -1
  100. package/dist/client/org/TeamPage.d.ts.map +1 -1
  101. package/dist/client/org/TeamPage.js +3 -154
  102. package/dist/client/org/TeamPage.js.map +1 -1
  103. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  104. package/dist/client/resources/ResourcesPanel.js +13 -35
  105. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  106. package/dist/client/settings/SettingsPanel.js +1 -1
  107. package/dist/client/settings/SettingsPanel.js.map +1 -1
  108. package/dist/client/settings/useBuilderStatus.d.ts +6 -0
  109. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  110. package/dist/client/settings/useBuilderStatus.js +3 -0
  111. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  112. package/dist/client/sse-event-processor.d.ts +15 -1
  113. package/dist/client/sse-event-processor.d.ts.map +1 -1
  114. package/dist/client/sse-event-processor.js +58 -54
  115. package/dist/client/sse-event-processor.js.map +1 -1
  116. package/dist/client/tools/ToolEditor.d.ts.map +1 -1
  117. package/dist/client/tools/ToolEditor.js +34 -4
  118. package/dist/client/tools/ToolEditor.js.map +1 -1
  119. package/dist/client/tools/ToolViewer.d.ts.map +1 -1
  120. package/dist/client/tools/ToolViewer.js +20 -1
  121. package/dist/client/tools/ToolViewer.js.map +1 -1
  122. package/dist/client/tools/ToolsListPage.d.ts.map +1 -1
  123. package/dist/client/tools/ToolsListPage.js +2 -1
  124. package/dist/client/tools/ToolsListPage.js.map +1 -1
  125. package/dist/client/tools/ToolsSidebarSection.js +1 -1
  126. package/dist/client/tools/ToolsSidebarSection.js.map +1 -1
  127. package/dist/client/transcription/BuilderTranscriptionCta.js +1 -1
  128. package/dist/client/transcription/BuilderTranscriptionCta.js.map +1 -1
  129. package/dist/client/use-chat-threads.d.ts.map +1 -1
  130. package/dist/client/use-chat-threads.js +7 -2
  131. package/dist/client/use-chat-threads.js.map +1 -1
  132. package/dist/collab/client.d.ts.map +1 -1
  133. package/dist/collab/client.js +26 -7
  134. package/dist/collab/client.js.map +1 -1
  135. package/dist/jobs/scheduler.js +0 -4
  136. package/dist/jobs/scheduler.js.map +1 -1
  137. package/dist/oauth-tokens/store.d.ts +0 -4
  138. package/dist/oauth-tokens/store.d.ts.map +1 -1
  139. package/dist/oauth-tokens/store.js +3 -24
  140. package/dist/oauth-tokens/store.js.map +1 -1
  141. package/dist/observability/routes.d.ts.map +1 -1
  142. package/dist/observability/routes.js +1 -9
  143. package/dist/observability/routes.js.map +1 -1
  144. package/dist/onboarding/default-steps.js +1 -1
  145. package/dist/onboarding/default-steps.js.map +1 -1
  146. package/dist/onboarding/plugin.d.ts.map +1 -1
  147. package/dist/onboarding/plugin.js +1 -8
  148. package/dist/onboarding/plugin.js.map +1 -1
  149. package/dist/org/accept-pending.d.ts.map +1 -1
  150. package/dist/org/accept-pending.js +1 -2
  151. package/dist/org/accept-pending.js.map +1 -1
  152. package/dist/org/context.d.ts +0 -2
  153. package/dist/org/context.d.ts.map +1 -1
  154. package/dist/org/context.js +0 -5
  155. package/dist/org/context.js.map +1 -1
  156. package/dist/resources/script-helpers.d.ts +3 -4
  157. package/dist/resources/script-helpers.d.ts.map +1 -1
  158. package/dist/resources/script-helpers.js +8 -15
  159. package/dist/resources/script-helpers.js.map +1 -1
  160. package/dist/scripts/chat/search-chats.d.ts.map +1 -1
  161. package/dist/scripts/chat/search-chats.js +4 -4
  162. package/dist/scripts/chat/search-chats.js.map +1 -1
  163. package/dist/scripts/manage-agent-loop-settings.js +2 -2
  164. package/dist/scripts/manage-agent-loop-settings.js.map +1 -1
  165. package/dist/scripts/resources/delete-memory.d.ts.map +1 -1
  166. package/dist/scripts/resources/delete-memory.js +4 -2
  167. package/dist/scripts/resources/delete-memory.js.map +1 -1
  168. package/dist/scripts/resources/delete.d.ts.map +1 -1
  169. package/dist/scripts/resources/delete.js +11 -4
  170. package/dist/scripts/resources/delete.js.map +1 -1
  171. package/dist/scripts/resources/list.d.ts.map +1 -1
  172. package/dist/scripts/resources/list.js +5 -3
  173. package/dist/scripts/resources/list.js.map +1 -1
  174. package/dist/scripts/resources/migrate-learnings.d.ts.map +1 -1
  175. package/dist/scripts/resources/migrate-learnings.js +5 -2
  176. package/dist/scripts/resources/migrate-learnings.js.map +1 -1
  177. package/dist/scripts/resources/read.d.ts.map +1 -1
  178. package/dist/scripts/resources/read.js +4 -2
  179. package/dist/scripts/resources/read.js.map +1 -1
  180. package/dist/scripts/resources/save-memory.d.ts.map +1 -1
  181. package/dist/scripts/resources/save-memory.js +4 -2
  182. package/dist/scripts/resources/save-memory.js.map +1 -1
  183. package/dist/scripts/resources/write.d.ts.map +1 -1
  184. package/dist/scripts/resources/write.js +11 -4
  185. package/dist/scripts/resources/write.js.map +1 -1
  186. package/dist/secrets/onboarding.d.ts.map +1 -1
  187. package/dist/secrets/onboarding.js +1 -9
  188. package/dist/secrets/onboarding.js.map +1 -1
  189. package/dist/secrets/routes.d.ts.map +1 -1
  190. package/dist/secrets/routes.js +2 -7
  191. package/dist/secrets/routes.js.map +1 -1
  192. package/dist/server/action-discovery.d.ts +15 -0
  193. package/dist/server/action-discovery.d.ts.map +1 -1
  194. package/dist/server/action-discovery.js +49 -0
  195. package/dist/server/action-discovery.js.map +1 -1
  196. package/dist/server/agent-chat-plugin.d.ts +5 -0
  197. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  198. package/dist/server/agent-chat-plugin.js +81 -20
  199. package/dist/server/agent-chat-plugin.js.map +1 -1
  200. package/dist/server/agent-discovery.d.ts.map +1 -1
  201. package/dist/server/agent-discovery.js +5 -7
  202. package/dist/server/agent-discovery.js.map +1 -1
  203. package/dist/server/auth.d.ts +16 -20
  204. package/dist/server/auth.d.ts.map +1 -1
  205. package/dist/server/auth.js +115 -333
  206. package/dist/server/auth.js.map +1 -1
  207. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  208. package/dist/server/core-routes-plugin.js +23 -16
  209. package/dist/server/core-routes-plugin.js.map +1 -1
  210. package/dist/server/credential-provider.d.ts.map +1 -1
  211. package/dist/server/credential-provider.js +1 -2
  212. package/dist/server/credential-provider.js.map +1 -1
  213. package/dist/server/google-oauth.d.ts +14 -2
  214. package/dist/server/google-oauth.d.ts.map +1 -1
  215. package/dist/server/google-oauth.js +32 -10
  216. package/dist/server/google-oauth.js.map +1 -1
  217. package/dist/server/index.d.ts +3 -3
  218. package/dist/server/index.d.ts.map +1 -1
  219. package/dist/server/index.js +2 -2
  220. package/dist/server/index.js.map +1 -1
  221. package/dist/server/oauth-helpers.d.ts +2 -4
  222. package/dist/server/oauth-helpers.d.ts.map +1 -1
  223. package/dist/server/oauth-helpers.js +2 -4
  224. package/dist/server/oauth-helpers.js.map +1 -1
  225. package/dist/server/transcribe-voice.d.ts.map +1 -1
  226. package/dist/server/transcribe-voice.js +2 -4
  227. package/dist/server/transcribe-voice.js.map +1 -1
  228. package/dist/triggers/dispatcher.d.ts.map +1 -1
  229. package/dist/triggers/dispatcher.js +0 -3
  230. package/dist/triggers/dispatcher.js.map +1 -1
  231. package/dist/vite/client.d.ts.map +1 -1
  232. package/dist/vite/client.js +13 -0
  233. package/dist/vite/client.js.map +1 -1
  234. package/docs/content/actions.md +1 -0
  235. package/docs/content/authentication.md +3 -20
  236. package/docs/content/creating-templates.md +1 -1
  237. package/docs/content/deployment.md +0 -1
  238. package/docs/content/security.md +0 -1
  239. package/docs/content/template-analytics.md +10 -0
  240. package/docs/content/template-calendar.md +10 -0
  241. package/docs/content/template-clips.md +10 -0
  242. package/docs/content/template-content.md +11 -1
  243. package/docs/content/template-dispatch.md +10 -0
  244. package/docs/content/template-forms.md +10 -0
  245. package/docs/content/template-mail.md +10 -0
  246. package/docs/content/template-slides.md +11 -1
  247. package/docs/content/template-starter.md +11 -1
  248. package/docs/content/template-video.md +10 -0
  249. package/package.json +1 -1
  250. package/dist/client/dev-mode.d.ts +0 -14
  251. package/dist/client/dev-mode.d.ts.map +0 -1
  252. package/dist/client/dev-mode.js +0 -14
  253. package/dist/client/dev-mode.js.map +0 -1
  254. package/dist/server/local-migration.d.ts +0 -41
  255. package/dist/server/local-migration.d.ts.map +0 -1
  256. package/dist/server/local-migration.js +0 -235
  257. package/dist/server/local-migration.js.map +0 -1
@@ -1,7 +1,56 @@
1
1
  import { setActiveRun, updateActiveRunSeq, clearActiveRun, } from "./active-run-state.js";
2
- import { readSSEStream } from "./sse-event-processor.js";
2
+ import { AgentAutoContinueSignal, readSSEStream, } from "./sse-event-processor.js";
3
3
  import { agentNativePath } from "./api-path.js";
4
4
  import { normalizeChatError } from "./error-format.js";
5
+ const AUTO_CONTINUE_PROMPT = "Continue from where you left off and finish the user's original request. Do not repeat completed work, do not mention internal reconnects, time limits, or step limits, and continue as if this is the same uninterrupted run.";
6
+ function normalizeMentions(text) {
7
+ return text.replace(/@\[([^\]|]+)\|[^\]]+\]/g, "@$1");
8
+ }
9
+ function truncateForContinuation(value, maxChars) {
10
+ if (value.length <= maxChars)
11
+ return value;
12
+ return `${value.slice(0, maxChars)}\n\n...[truncated ${value.length - maxChars} chars from prior partial output]`;
13
+ }
14
+ function contentToContinuationHistory(content) {
15
+ const chunks = [];
16
+ for (const part of content) {
17
+ if (part.type === "text") {
18
+ if (part.text.trim())
19
+ chunks.push(part.text.trim());
20
+ continue;
21
+ }
22
+ const toolSummary = [
23
+ `Tool: ${part.toolName}`,
24
+ part.argsText ? `Input: ${part.argsText}` : "",
25
+ part.result
26
+ ? `Result:\n${truncateForContinuation(part.result, 8_000)}`
27
+ : "Result: interrupted before this tool returned a result",
28
+ ]
29
+ .filter(Boolean)
30
+ .join("\n");
31
+ chunks.push(toolSummary);
32
+ }
33
+ return truncateForContinuation(chunks.join("\n\n"), 40_000).trim();
34
+ }
35
+ function autoContinueMessage(signal) {
36
+ const reason = signal.reason === "loop_limit"
37
+ ? "The previous run reached an internal step budget."
38
+ : signal.reason === "stream_ended"
39
+ ? "The previous stream ended before the agent sent a final completion signal."
40
+ : "The previous run reached an internal execution budget.";
41
+ return `${AUTO_CONTINUE_PROMPT}\n\nInternal note: ${reason}`;
42
+ }
43
+ function delay(ms, abortSignal) {
44
+ if (abortSignal.aborted)
45
+ return Promise.resolve();
46
+ return new Promise((resolve) => {
47
+ const timer = setTimeout(resolve, ms);
48
+ abortSignal.addEventListener("abort", () => {
49
+ clearTimeout(timer);
50
+ resolve();
51
+ }, { once: true });
52
+ });
53
+ }
5
54
  /**
6
55
  * The composer's exec mode is sent as explicit request metadata. The server
7
56
  * owns the plan-mode prompt and read-only tool filtering so the chat history
@@ -99,6 +148,10 @@ export function createAgentChatAdapter(options) {
99
148
  const toolCallCounter = { value: 0 };
100
149
  let runId = null;
101
150
  let lastSeq = -1;
151
+ let currentMessageText = normalizeMentions(rawMessageText);
152
+ let currentHistory = history;
153
+ let includeAttachments = attachments.length > 0;
154
+ let includeReferences = Boolean(runConfig?.custom?.references);
102
155
  try {
103
156
  const headers = {
104
157
  "Content-Type": "application/json",
@@ -111,71 +164,211 @@ export function createAgentChatAdapter(options) {
111
164
  catch {
112
165
  // Non-browser or Intl unavailable — tool calls will fall back to UTC.
113
166
  }
114
- const res = await fetch(apiUrl, {
115
- method: "POST",
116
- headers,
117
- body: JSON.stringify({
118
- message: rawMessageText.replace(/@\[([^\]|]+)\|[^\]]+\]/g, "@$1"),
119
- history,
120
- ...(threadId ? { threadId } : {}),
121
- ...(requestMode ? { mode: requestMode } : {}),
122
- ...(modelRef?.current ? { model: modelRef.current } : {}),
123
- ...(engineRef?.current ? { engine: engineRef.current } : {}),
124
- ...(effortRef?.current ? { effort: effortRef.current } : {}),
125
- ...(attachments.length > 0 ? { attachments } : {}),
126
- ...(runConfig?.custom?.references
127
- ? { references: runConfig.custom.references }
128
- : {}),
129
- }),
130
- signal: abortSignal,
131
- });
132
- // Check for auth errors returned as 200 with JSON (common with middleware issues)
133
- const contentType = res.headers.get("content-type") || "";
134
- if (res.ok &&
135
- contentType.includes("application/json") &&
136
- !contentType.includes("text/event-stream")) {
137
- try {
138
- const body = await res.text();
139
- const parsed = JSON.parse(body);
140
- if (parsed.error) {
141
- throw new Error(parsed.error);
167
+ const reconnectCurrentRun = async function* () {
168
+ if (!runId)
169
+ return false;
170
+ for (let attempt = 0; attempt < 3; attempt++) {
171
+ try {
172
+ const reconnectRes = await fetch(`${apiUrl}/runs/${encodeURIComponent(runId)}/events?after=${lastSeq + 1}`, { signal: abortSignal });
173
+ if (!reconnectRes.ok || !reconnectRes.body)
174
+ break;
175
+ yield* readSSEStream(reconnectRes.body, content, toolCallCounter, tabId, (seq) => {
176
+ lastSeq = seq;
177
+ if (threadId)
178
+ updateActiveRunSeq(seq);
179
+ }, runId);
180
+ clearActiveRun();
181
+ return true;
142
182
  }
143
- }
144
- catch (e) {
145
- if (e instanceof Error &&
146
- e.message !== "Unexpected end of JSON input") {
147
- throw e;
183
+ catch (reconnectErr) {
184
+ if (reconnectErr instanceof Error &&
185
+ reconnectErr.name === "AbortError") {
186
+ clearActiveRun();
187
+ return true;
188
+ }
189
+ if (reconnectErr instanceof AgentAutoContinueSignal) {
190
+ return false;
191
+ }
192
+ await delay(1000, abortSignal);
148
193
  }
149
194
  }
150
- }
151
- if (!res.ok) {
152
- // 405 Method Not Allowed usually means the session is broken/expired
153
- // (e.g. a redirect to a login page that only accepts GET).
154
- if (res.status === 405) {
155
- if (typeof window !== "undefined") {
156
- window.dispatchEvent(new CustomEvent("agent-chat:auth-error", {
157
- detail: { reason: "session-expired" },
158
- }));
195
+ return false;
196
+ };
197
+ while (true) {
198
+ try {
199
+ runId = null;
200
+ lastSeq = -1;
201
+ const res = await fetch(apiUrl, {
202
+ method: "POST",
203
+ headers,
204
+ body: JSON.stringify({
205
+ message: currentMessageText,
206
+ history: currentHistory,
207
+ ...(threadId ? { threadId } : {}),
208
+ ...(requestMode ? { mode: requestMode } : {}),
209
+ ...(modelRef?.current ? { model: modelRef.current } : {}),
210
+ ...(engineRef?.current ? { engine: engineRef.current } : {}),
211
+ ...(effortRef?.current ? { effort: effortRef.current } : {}),
212
+ ...(includeAttachments ? { attachments } : {}),
213
+ ...(includeReferences && runConfig?.custom?.references
214
+ ? { references: runConfig.custom.references }
215
+ : {}),
216
+ }),
217
+ signal: abortSignal,
218
+ });
219
+ // Check for auth errors returned as 200 with JSON (common with middleware issues)
220
+ const contentType = res.headers.get("content-type") || "";
221
+ if (res.ok &&
222
+ contentType.includes("application/json") &&
223
+ !contentType.includes("text/event-stream")) {
224
+ try {
225
+ const body = await res.text();
226
+ const parsed = JSON.parse(body);
227
+ if (parsed.error) {
228
+ throw new Error(parsed.error);
229
+ }
230
+ }
231
+ catch (e) {
232
+ if (e instanceof Error &&
233
+ e.message !== "Unexpected end of JSON input") {
234
+ throw e;
235
+ }
236
+ }
159
237
  }
160
- content.push({ type: "text", text: "" });
161
- yield {
162
- content: [...content],
163
- status: {
164
- type: "incomplete",
165
- reason: "error",
166
- },
167
- };
238
+ if (!res.ok) {
239
+ if (res.status === 409) {
240
+ let handledConflict = false;
241
+ try {
242
+ const body = await res.json();
243
+ if (body?.activeRunId) {
244
+ handledConflict = true;
245
+ runId = String(body.activeRunId);
246
+ lastSeq = -1;
247
+ if (threadId) {
248
+ setActiveRun({ threadId, runId, lastSeq: -1 });
249
+ }
250
+ const reconnected = yield* reconnectCurrentRun();
251
+ if (reconnected)
252
+ return;
253
+ }
254
+ }
255
+ catch {
256
+ // Fall through to the generic response handling below.
257
+ }
258
+ if (handledConflict) {
259
+ await delay(1000, abortSignal);
260
+ if (abortSignal.aborted)
261
+ return;
262
+ continue;
263
+ }
264
+ }
265
+ // 405 Method Not Allowed usually means the session is broken/expired
266
+ // (e.g. a redirect to a login page that only accepts GET).
267
+ if (res.status === 405) {
268
+ if (typeof window !== "undefined") {
269
+ window.dispatchEvent(new CustomEvent("agent-chat:auth-error", {
270
+ detail: { reason: "session-expired" },
271
+ }));
272
+ }
273
+ content.push({ type: "text", text: "" });
274
+ yield {
275
+ content: [...content],
276
+ status: {
277
+ type: "incomplete",
278
+ reason: "error",
279
+ },
280
+ };
281
+ return;
282
+ }
283
+ let errorText = `Server error: ${res.status}`;
284
+ try {
285
+ const body = await res.text();
286
+ if (body.includes("apiKey") ||
287
+ body.includes("authToken") ||
288
+ body.includes("ANTHROPIC_API_KEY") ||
289
+ body.includes("authentication")) {
290
+ if (typeof window !== "undefined") {
291
+ window.dispatchEvent(new Event("agent-chat:missing-api-key"));
292
+ }
293
+ content.push({ type: "text", text: "" });
294
+ yield {
295
+ content: [...content],
296
+ status: {
297
+ type: "incomplete",
298
+ reason: "error",
299
+ },
300
+ };
301
+ return;
302
+ }
303
+ else if (body.includes("Cannot find any path")) {
304
+ errorText =
305
+ "Agent chat endpoint not found. Make sure the agent-chat plugin is loaded in server/plugins/.";
306
+ }
307
+ else if (body) {
308
+ errorText =
309
+ body.length > 200 ? body.slice(0, 200) + "..." : body;
310
+ }
311
+ }
312
+ catch { }
313
+ throw new Error(errorText);
314
+ }
315
+ if (!res.body) {
316
+ throw new Error("No response body");
317
+ }
318
+ // Track the run ID for reconnection
319
+ runId = res.headers.get("X-Run-Id");
320
+ if (runId && threadId) {
321
+ setActiveRun({ threadId, runId, lastSeq: -1 });
322
+ }
323
+ yield* readSSEStream(res.body, content, toolCallCounter, tabId, (seq) => {
324
+ lastSeq = seq;
325
+ if (runId && threadId) {
326
+ updateActiveRunSeq(seq);
327
+ }
328
+ }, runId);
329
+ // Run completed normally — clear active run state
330
+ clearActiveRun();
168
331
  return;
169
332
  }
170
- let errorText = `Server error: ${res.status}`;
171
- try {
172
- const body = await res.text();
173
- if (body.includes("apiKey") ||
174
- body.includes("authToken") ||
175
- body.includes("ANTHROPIC_API_KEY") ||
176
- body.includes("authentication")) {
333
+ catch (err) {
334
+ if (err instanceof Error && err.name === "AbortError") {
335
+ // User-initiated abort (Stop button) — clear active run
336
+ clearActiveRun();
337
+ return;
338
+ }
339
+ if (err instanceof AgentAutoContinueSignal) {
340
+ if (err.reason === "stream_ended") {
341
+ const reconnected = yield* reconnectCurrentRun();
342
+ if (reconnected)
343
+ return;
344
+ }
345
+ const partialHistory = contentToContinuationHistory(content);
346
+ currentHistory = [
347
+ ...history,
348
+ { role: "user", content: normalizeMentions(rawMessageText) },
349
+ ...(partialHistory
350
+ ? [{ role: "assistant", content: partialHistory }]
351
+ : []),
352
+ ];
353
+ currentMessageText = autoContinueMessage(err);
354
+ includeAttachments = false;
355
+ includeReferences = false;
356
+ clearActiveRun();
357
+ await delay(250, abortSignal);
358
+ if (abortSignal.aborted)
359
+ return;
360
+ continue;
361
+ }
362
+ const errMsg = err instanceof Error ? err.message : "Something went wrong.";
363
+ const isAuthError = errMsg.includes("Unauthorized") ||
364
+ errMsg.includes("Not authenticated") ||
365
+ errMsg.includes("401") ||
366
+ errMsg.includes("403") ||
367
+ errMsg.includes("405");
368
+ // Don't try to reconnect for auth/client errors — show error directly
369
+ if (isAuthError) {
177
370
  if (typeof window !== "undefined") {
178
- window.dispatchEvent(new Event("agent-chat:missing-api-key"));
371
+ window.dispatchEvent(new Event("agent-chat:auth-error"));
179
372
  }
180
373
  content.push({ type: "text", text: "" });
181
374
  yield {
@@ -185,123 +378,64 @@ export function createAgentChatAdapter(options) {
185
378
  reason: "error",
186
379
  },
187
380
  };
381
+ clearActiveRun();
188
382
  return;
189
383
  }
190
- else if (body.includes("Cannot find any path")) {
191
- errorText =
192
- "Agent chat endpoint not found. Make sure the agent-chat plugin is loaded in server/plugins/.";
193
- }
194
- else if (body) {
195
- errorText = body.length > 200 ? body.slice(0, 200) + "..." : body;
196
- }
197
- }
198
- catch { }
199
- throw new Error(errorText);
200
- }
201
- if (!res.body) {
202
- throw new Error("No response body");
203
- }
204
- // Track the run ID for reconnection
205
- runId = res.headers.get("X-Run-Id");
206
- if (runId && threadId) {
207
- setActiveRun({ threadId, runId, lastSeq: -1 });
208
- }
209
- yield* readSSEStream(res.body, content, toolCallCounter, tabId, (seq) => {
210
- lastSeq = seq;
211
- if (runId && threadId) {
212
- updateActiveRunSeq(seq);
213
- }
214
- }, runId);
215
- // Run completed normally — clear active run state
216
- clearActiveRun();
217
- }
218
- catch (err) {
219
- if (err instanceof Error && err.name === "AbortError") {
220
- // User-initiated abort (Stop button) — clear active run
221
- clearActiveRun();
222
- return;
223
- }
224
- const errMsg = err instanceof Error ? err.message : "Something went wrong.";
225
- const isAuthError = errMsg.includes("Unauthorized") ||
226
- errMsg.includes("Not authenticated") ||
227
- errMsg.includes("401") ||
228
- errMsg.includes("403") ||
229
- errMsg.includes("405");
230
- // Don't try to reconnect for auth/client errors — show error directly
231
- if (isAuthError) {
232
- if (typeof window !== "undefined") {
233
- window.dispatchEvent(new Event("agent-chat:auth-error"));
234
- }
235
- content.push({ type: "text", text: "" });
236
- yield {
237
- content: [...content],
238
- status: {
239
- type: "incomplete",
240
- reason: "error",
241
- },
242
- };
243
- clearActiveRun();
244
- return;
245
- }
246
- // Connection lost — try to reconnect to the run
247
- if (runId && lastSeq >= 0) {
248
- let reconnected = false;
249
- for (let attempt = 0; attempt < 3; attempt++) {
250
- try {
251
- const reconnectRes = await fetch(`${apiUrl}/runs/${encodeURIComponent(runId)}/events?after=${lastSeq + 1}`, { signal: abortSignal });
252
- if (!reconnectRes.ok || !reconnectRes.body)
253
- break;
254
- yield* readSSEStream(reconnectRes.body, content, toolCallCounter, tabId, (seq) => {
255
- lastSeq = seq;
256
- if (threadId) {
257
- updateActiveRunSeq(seq);
258
- }
259
- }, runId);
260
- reconnected = true;
384
+ // Connection lost try to reconnect to the run
385
+ const reconnected = yield* reconnectCurrentRun();
386
+ if (reconnected)
387
+ return;
388
+ // Reconnect failed or not possible — keep going from the partial
389
+ // streamed content instead of surfacing a transient transport error.
390
+ if (content.length > 0) {
391
+ const partialHistory = contentToContinuationHistory(content);
392
+ currentHistory = [
393
+ ...history,
394
+ { role: "user", content: normalizeMentions(rawMessageText) },
395
+ ...(partialHistory
396
+ ? [{ role: "assistant", content: partialHistory }]
397
+ : []),
398
+ ];
399
+ currentMessageText = autoContinueMessage(new AgentAutoContinueSignal({ reason: "stream_ended" }));
400
+ includeAttachments = false;
401
+ includeReferences = false;
261
402
  clearActiveRun();
262
- break;
263
- }
264
- catch (reconnectErr) {
265
- if (reconnectErr instanceof Error &&
266
- reconnectErr.name === "AbortError") {
267
- clearActiveRun();
403
+ await delay(250, abortSignal);
404
+ if (abortSignal.aborted)
268
405
  return;
269
- }
270
- // Wait briefly before retrying
271
- await new Promise((r) => setTimeout(r, 1000));
406
+ continue;
272
407
  }
273
- }
274
- if (reconnected)
408
+ // No partial work exists, so this is still a real startup failure.
409
+ const normalized = normalizeChatError(errMsg);
410
+ const runError = {
411
+ message: normalized.message,
412
+ ...(normalized.details ? { details: normalized.details } : {}),
413
+ errorCode: "connection_error",
414
+ recoverable: true,
415
+ ...(runId ? { runId } : {}),
416
+ };
417
+ if (typeof window !== "undefined") {
418
+ window.dispatchEvent(new CustomEvent("agent-chat:run-error", {
419
+ detail: { ...runError, tabId },
420
+ }));
421
+ }
422
+ content.push({
423
+ type: "text",
424
+ text: errMsg.startsWith("Server error:")
425
+ ? errMsg
426
+ : `Something went wrong: ${normalized.message}`,
427
+ });
428
+ yield {
429
+ content: [...content],
430
+ status: {
431
+ type: "incomplete",
432
+ reason: "error",
433
+ },
434
+ metadata: { custom: { ...(runId ? { runId } : {}), runError } },
435
+ };
275
436
  return;
437
+ }
276
438
  }
277
- // Reconnect failed or not possible — show error with details
278
- const normalized = normalizeChatError(errMsg);
279
- const runError = {
280
- message: normalized.message,
281
- ...(normalized.details ? { details: normalized.details } : {}),
282
- errorCode: "connection_error",
283
- recoverable: true,
284
- ...(runId ? { runId } : {}),
285
- };
286
- if (typeof window !== "undefined") {
287
- window.dispatchEvent(new CustomEvent("agent-chat:run-error", {
288
- detail: { ...runError, tabId },
289
- }));
290
- }
291
- content.push({
292
- type: "text",
293
- text: errMsg.startsWith("Server error:")
294
- ? errMsg
295
- : `Something went wrong: ${normalized.message}`,
296
- });
297
- yield {
298
- content: [...content],
299
- status: {
300
- type: "incomplete",
301
- reason: "error",
302
- },
303
- metadata: { custom: { ...(runId ? { runId } : {}), runError } },
304
- };
305
439
  }
306
440
  finally {
307
441
  if (typeof window !== "undefined") {