@agent-native/core 0.19.1 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +12 -1
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +5 -0
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +17 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +210 -0
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/cli/code-agent-executor.d.ts +2 -0
- package/dist/cli/code-agent-executor.d.ts.map +1 -1
- package/dist/cli/code-agent-executor.js +39 -1
- package/dist/cli/code-agent-executor.js.map +1 -1
- package/dist/cli/code-agent-runs.d.ts +3 -0
- package/dist/cli/code-agent-runs.d.ts.map +1 -1
- package/dist/cli/code-agent-runs.js +3 -0
- package/dist/cli/code-agent-runs.js.map +1 -1
- package/dist/cli/connect.d.ts +3 -2
- package/dist/cli/connect.d.ts.map +1 -1
- package/dist/cli/connect.js +12 -8
- package/dist/cli/connect.js.map +1 -1
- package/dist/cli/mcp-config-writers.d.ts +3 -3
- package/dist/cli/mcp-config-writers.d.ts.map +1 -1
- package/dist/cli/mcp-config-writers.js +19 -8
- package/dist/cli/mcp-config-writers.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +8 -3
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +58 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +122 -50
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +172 -13
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-sidebar-state.d.ts +2 -0
- package/dist/client/agent-sidebar-state.d.ts.map +1 -1
- package/dist/client/agent-sidebar-state.js +32 -0
- package/dist/client/agent-sidebar-state.js.map +1 -1
- package/dist/client/code-agent-chat-adapter.d.ts +81 -0
- package/dist/client/code-agent-chat-adapter.d.ts.map +1 -0
- package/dist/client/code-agent-chat-adapter.js +297 -0
- package/dist/client/code-agent-chat-adapter.js.map +1 -0
- package/dist/client/composer/PromptComposer.d.ts +11 -0
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +7 -3
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +12 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +16 -7
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/index.d.ts +1 -0
- package/dist/client/composer/index.d.ts.map +1 -1
- package/dist/client/composer/index.js +1 -0
- package/dist/client/composer/index.js.map +1 -1
- package/dist/client/composer/prompt-attachments.d.ts +11 -0
- package/dist/client/composer/prompt-attachments.d.ts.map +1 -0
- package/dist/client/composer/prompt-attachments.js +45 -0
- package/dist/client/composer/prompt-attachments.js.map +1 -0
- package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
- package/dist/client/conversation/AgentConversation.js +124 -1
- package/dist/client/conversation/AgentConversation.js.map +1 -1
- package/dist/client/conversation/code-agent-transcript.d.ts +25 -0
- package/dist/client/conversation/code-agent-transcript.d.ts.map +1 -0
- package/dist/client/conversation/code-agent-transcript.js +200 -0
- package/dist/client/conversation/code-agent-transcript.js.map +1 -0
- package/dist/client/conversation/index.d.ts +2 -1
- package/dist/client/conversation/index.d.ts.map +1 -1
- package/dist/client/conversation/index.js +1 -0
- package/dist/client/conversation/index.js.map +1 -1
- package/dist/client/conversation/types.d.ts +8 -0
- package/dist/client/conversation/types.d.ts.map +1 -1
- package/dist/client/conversation/types.js.map +1 -1
- package/dist/client/conversation/use-near-bottom-autoscroll.d.ts.map +1 -1
- package/dist/client/conversation/use-near-bottom-autoscroll.js +26 -9
- package/dist/client/conversation/use-near-bottom-autoscroll.js.map +1 -1
- package/dist/client/index.d.ts +5 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +5 -2
- package/dist/client/index.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +2 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +21 -3
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.spec.js +16 -2
- package/dist/client/settings/useBuilderStatus.spec.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +3 -0
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/use-chat-models.d.ts +6 -1
- package/dist/client/use-chat-models.d.ts.map +1 -1
- package/dist/client/use-chat-models.js +7 -3
- package/dist/client/use-chat-models.js.map +1 -1
- package/dist/client/use-chat-models.spec.d.ts +2 -0
- package/dist/client/use-chat-models.spec.d.ts.map +1 -0
- package/dist/client/use-chat-models.spec.js +39 -0
- package/dist/client/use-chat-models.spec.js.map +1 -0
- package/dist/code-agents/background-controller.d.ts.map +1 -1
- package/dist/code-agents/background-controller.js +16 -0
- package/dist/code-agents/background-controller.js.map +1 -1
- package/dist/code-agents/index.d.ts +2 -0
- package/dist/code-agents/index.d.ts.map +1 -1
- package/dist/code-agents/index.js +2 -0
- package/dist/code-agents/index.js.map +1 -1
- package/dist/code-agents/prompt-attachments.d.ts +11 -0
- package/dist/code-agents/prompt-attachments.d.ts.map +1 -0
- package/dist/code-agents/prompt-attachments.js +23 -0
- package/dist/code-agents/prompt-attachments.js.map +1 -0
- package/dist/code-agents/transcript-normalizer.js +14 -5
- package/dist/code-agents/transcript-normalizer.js.map +1 -1
- package/dist/code-agents/transcript-order.d.ts +16 -0
- package/dist/code-agents/transcript-order.d.ts.map +1 -0
- package/dist/code-agents/transcript-order.js +47 -0
- package/dist/code-agents/transcript-order.js.map +1 -0
- package/dist/extensions/routes.d.ts.map +1 -1
- package/dist/extensions/routes.js +18 -14
- package/dist/extensions/routes.js.map +1 -1
- package/dist/mcp/build-server.d.ts +33 -1
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +39 -12
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/builtin-tools.d.ts +3 -1
- package/dist/mcp/builtin-tools.d.ts.map +1 -1
- package/dist/mcp/builtin-tools.js +40 -10
- package/dist/mcp/builtin-tools.js.map +1 -1
- package/dist/mcp/connect-route.d.ts.map +1 -1
- package/dist/mcp/connect-route.js +299 -97
- package/dist/mcp/connect-route.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +17 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/secrets/substitution.d.ts +18 -0
- package/dist/secrets/substitution.d.ts.map +1 -1
- package/dist/secrets/substitution.js +74 -0
- package/dist/secrets/substitution.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +33 -0
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/auth.d.ts +8 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +8 -1
- package/dist/server/auth.js.map +1 -1
- package/dist/server/deep-link.d.ts +0 -18
- package/dist/server/deep-link.d.ts.map +1 -1
- package/dist/server/deep-link.js +2 -1
- package/dist/server/deep-link.js.map +1 -1
- package/dist/server/open-route.d.ts.map +1 -1
- package/dist/server/open-route.js +23 -4
- package/dist/server/open-route.js.map +1 -1
- package/dist/shared/agent-sidebar-url.d.ts +6 -0
- package/dist/shared/agent-sidebar-url.d.ts.map +1 -0
- package/dist/shared/agent-sidebar-url.js +37 -0
- package/dist/shared/agent-sidebar-url.js.map +1 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +1 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/styles/agent-conversation.css +403 -0
- package/dist/styles/agent-native.css +2 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +1 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/external-agents.md +27 -6
- package/docs/content/mcp-clients.md +2 -0
- package/docs/content/mcp-protocol.md +4 -2
- package/package.json +1 -1
|
@@ -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;AAKrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,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;AAKrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAutB7D;;;;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;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,CAAA;KAAE,CAAC;CAC5D,GAAG,gBAAgB,CAu9BnB"}
|
|
@@ -21,9 +21,16 @@ const MAX_STARTUP_RECOVERY_ATTEMPTS = 8;
|
|
|
21
21
|
const MAX_STALE_RUN_CONTINUATIONS = 3;
|
|
22
22
|
const MAX_STALLED_TRANSIENT_CONTINUATIONS = 8;
|
|
23
23
|
const MAX_TOTAL_TRANSIENT_CONTINUATIONS = 32;
|
|
24
|
+
const MAX_EMPTY_TRANSIENT_CONTINUATIONS = 1;
|
|
24
25
|
const RETRY_BASE_DELAY_MS = 500;
|
|
25
26
|
const RETRY_MAX_DELAY_MS = 8_000;
|
|
26
27
|
const MAX_HISTORY_ATTACHMENT_CHARS = 60_000;
|
|
28
|
+
const MAX_HISTORY_MESSAGES = 24;
|
|
29
|
+
const MAX_HISTORY_TOTAL_CHARS = 64_000;
|
|
30
|
+
const MAX_HISTORY_MESSAGE_CHARS = 12_000;
|
|
31
|
+
const MAX_HISTORY_TOOL_ARGS_CHARS = 8_000;
|
|
32
|
+
const MAX_HISTORY_TOOL_RESULT_CHARS = 12_000;
|
|
33
|
+
const STARTUP_RESPONSE_TIMEOUT_MS = 45_000;
|
|
27
34
|
function normalizeMentions(text) {
|
|
28
35
|
return text.replace(/@\[([^\]|]+)\|[^\]]+\]/g, "@$1");
|
|
29
36
|
}
|
|
@@ -32,6 +39,12 @@ function truncateForContinuation(value, maxChars) {
|
|
|
32
39
|
return value;
|
|
33
40
|
return `${value.slice(0, maxChars)}\n\n...[truncated ${value.length - maxChars} chars from prior partial output]`;
|
|
34
41
|
}
|
|
42
|
+
function truncateForHistory(value, maxChars, label) {
|
|
43
|
+
if (value.length <= maxChars)
|
|
44
|
+
return value;
|
|
45
|
+
const omitted = value.length - maxChars;
|
|
46
|
+
return `${value.slice(0, maxChars)}\n\n[${label} truncated after ${maxChars.toLocaleString()} characters; ${omitted.toLocaleString()} characters omitted from prior chat history. Read the current app/resource state with tools if exact content is needed.]`;
|
|
47
|
+
}
|
|
35
48
|
function contentToContinuationHistory(content) {
|
|
36
49
|
const chunks = [];
|
|
37
50
|
for (const part of content) {
|
|
@@ -54,6 +67,33 @@ function contentToContinuationHistory(content) {
|
|
|
54
67
|
return truncateForContinuation(chunks.join("\n\n"), 40_000).trim();
|
|
55
68
|
}
|
|
56
69
|
function messageTextFromContent(content) {
|
|
70
|
+
return truncateForHistory(content
|
|
71
|
+
.filter((p) => p.type === "text")
|
|
72
|
+
.map((p) => normalizeMentions(p.text))
|
|
73
|
+
.join("\n"), MAX_HISTORY_MESSAGE_CHARS, "Message");
|
|
74
|
+
}
|
|
75
|
+
function truncateToolArgsForHistory(args) {
|
|
76
|
+
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
77
|
+
return {};
|
|
78
|
+
try {
|
|
79
|
+
const json = JSON.stringify(args);
|
|
80
|
+
if (json.length <= MAX_HISTORY_TOOL_ARGS_CHARS) {
|
|
81
|
+
return args;
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
__agentNativeTruncated: true,
|
|
85
|
+
note: "Tool input was too large to resend in chat history. Use the current app/resource state as the source of truth if exact content is needed.",
|
|
86
|
+
preview: truncateForHistory(json, MAX_HISTORY_TOOL_ARGS_CHARS, "Tool input"),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return {
|
|
91
|
+
__agentNativeTruncated: true,
|
|
92
|
+
note: "Tool input could not be serialized for prior chat history.",
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function messageTextFromContentRaw(content) {
|
|
57
97
|
return content
|
|
58
98
|
.filter((p) => p.type === "text")
|
|
59
99
|
.map((p) => normalizeMentions(p.text))
|
|
@@ -164,11 +204,11 @@ function attachmentHistoryText(attachment) {
|
|
|
164
204
|
return null;
|
|
165
205
|
}
|
|
166
206
|
function messageTextForHistory(message) {
|
|
167
|
-
const text =
|
|
207
|
+
const text = messageTextFromContentRaw(message.content);
|
|
168
208
|
const attachments = extractAttachmentsFromMessage(message)
|
|
169
209
|
.map(attachmentHistoryText)
|
|
170
210
|
.filter((part) => !!part && part.trim().length > 0);
|
|
171
|
-
return [text, ...attachments].filter((part) => part.trim()).join("\n\n");
|
|
211
|
+
return truncateForHistory([text, ...attachments].filter((part) => part.trim()).join("\n\n"), MAX_HISTORY_MESSAGE_CHARS, "Message");
|
|
172
212
|
}
|
|
173
213
|
function isToolCallContentPart(part) {
|
|
174
214
|
return Boolean(part && typeof part === "object" && part.type === "tool-call");
|
|
@@ -183,10 +223,11 @@ function toolResultContent(result) {
|
|
|
183
223
|
return String(result ?? "");
|
|
184
224
|
}
|
|
185
225
|
}
|
|
186
|
-
function contentToStructuredMessages(content, nextToolCallId) {
|
|
226
|
+
function contentToStructuredMessages(content, nextToolCallId, options) {
|
|
187
227
|
const messages = [];
|
|
188
228
|
let assistantParts = [];
|
|
189
229
|
let pendingToolResults = [];
|
|
230
|
+
const truncate = options?.truncateForHistory === true;
|
|
190
231
|
const flushToolTurn = () => {
|
|
191
232
|
if (pendingToolResults.length === 0)
|
|
192
233
|
return;
|
|
@@ -202,7 +243,12 @@ function contentToStructuredMessages(content, nextToolCallId) {
|
|
|
202
243
|
if (pendingToolResults.length > 0)
|
|
203
244
|
flushToolTurn();
|
|
204
245
|
if (part.text.trim()) {
|
|
205
|
-
assistantParts.push({
|
|
246
|
+
assistantParts.push({
|
|
247
|
+
type: "text",
|
|
248
|
+
text: truncate
|
|
249
|
+
? truncateForHistory(part.text, MAX_HISTORY_MESSAGE_CHARS, "Assistant text")
|
|
250
|
+
: part.text,
|
|
251
|
+
});
|
|
206
252
|
}
|
|
207
253
|
continue;
|
|
208
254
|
}
|
|
@@ -212,14 +258,18 @@ function contentToStructuredMessages(content, nextToolCallId) {
|
|
|
212
258
|
type: "tool-call",
|
|
213
259
|
toolCallId,
|
|
214
260
|
toolName: part.toolName,
|
|
215
|
-
args:
|
|
261
|
+
args: truncate
|
|
262
|
+
? truncateToolArgsForHistory(part.args ?? {})
|
|
263
|
+
: (part.args ?? {}),
|
|
216
264
|
});
|
|
217
265
|
if (part.result !== undefined) {
|
|
218
266
|
pendingToolResults.push({
|
|
219
267
|
type: "tool-result",
|
|
220
268
|
toolCallId,
|
|
221
269
|
toolName: part.toolName,
|
|
222
|
-
content:
|
|
270
|
+
content: truncate
|
|
271
|
+
? truncateForHistory(toolResultContent(part.result), MAX_HISTORY_TOOL_RESULT_CHARS, "Tool result")
|
|
272
|
+
: toolResultContent(part.result),
|
|
223
273
|
});
|
|
224
274
|
}
|
|
225
275
|
}
|
|
@@ -276,10 +326,36 @@ function assistantUiMessagesToStructuredHistory(messages) {
|
|
|
276
326
|
});
|
|
277
327
|
}
|
|
278
328
|
}
|
|
279
|
-
structured.push(...contentToStructuredMessages(content, nextToolCallId
|
|
329
|
+
structured.push(...contentToStructuredMessages(content, nextToolCallId, {
|
|
330
|
+
truncateForHistory: true,
|
|
331
|
+
}));
|
|
280
332
|
}
|
|
281
333
|
return structured;
|
|
282
334
|
}
|
|
335
|
+
function estimateHistoryMessageCost(message) {
|
|
336
|
+
return Math.max(1, messageTextForHistory(message).length);
|
|
337
|
+
}
|
|
338
|
+
function limitPriorMessagesForRequest(messages) {
|
|
339
|
+
const recent = messages.slice(-MAX_HISTORY_MESSAGES);
|
|
340
|
+
const kept = [];
|
|
341
|
+
let totalChars = 0;
|
|
342
|
+
for (let i = recent.length - 1; i >= 0; i--) {
|
|
343
|
+
const message = recent[i];
|
|
344
|
+
if (message.role !== "user" && message.role !== "assistant")
|
|
345
|
+
continue;
|
|
346
|
+
const cost = estimateHistoryMessageCost(message);
|
|
347
|
+
if (kept.length > 0 && totalChars + cost > MAX_HISTORY_TOTAL_CHARS) {
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
kept.push(message);
|
|
351
|
+
totalChars += cost;
|
|
352
|
+
}
|
|
353
|
+
kept.reverse();
|
|
354
|
+
while (kept.length > 0 && kept[0].role !== "user") {
|
|
355
|
+
kept.shift();
|
|
356
|
+
}
|
|
357
|
+
return kept;
|
|
358
|
+
}
|
|
283
359
|
function combineContinuationHistory(fragments) {
|
|
284
360
|
return truncateForContinuation(fragments.filter(Boolean).join("\n\n"), 40_000).trim();
|
|
285
361
|
}
|
|
@@ -317,6 +393,40 @@ function delay(ms, abortSignal) {
|
|
|
317
393
|
}, { once: true });
|
|
318
394
|
});
|
|
319
395
|
}
|
|
396
|
+
class AgentStartupTimeoutError extends Error {
|
|
397
|
+
timeoutMs;
|
|
398
|
+
constructor(timeoutMs) {
|
|
399
|
+
super(`Agent chat did not start streaming within ${Math.round(timeoutMs / 1000)}s.`);
|
|
400
|
+
this.name = "AgentStartupTimeoutError";
|
|
401
|
+
this.timeoutMs = timeoutMs;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
async function fetchWithStartupTimeout(input, init, timeoutMs, abortSignal) {
|
|
405
|
+
if (abortSignal.aborted) {
|
|
406
|
+
throw new DOMException("The operation was aborted.", "AbortError");
|
|
407
|
+
}
|
|
408
|
+
const controller = new AbortController();
|
|
409
|
+
let timedOut = false;
|
|
410
|
+
const timeout = setTimeout(() => {
|
|
411
|
+
timedOut = true;
|
|
412
|
+
controller.abort();
|
|
413
|
+
}, timeoutMs);
|
|
414
|
+
const abort = () => controller.abort();
|
|
415
|
+
abortSignal.addEventListener("abort", abort, { once: true });
|
|
416
|
+
try {
|
|
417
|
+
return await fetch(input, { ...init, signal: controller.signal });
|
|
418
|
+
}
|
|
419
|
+
catch (error) {
|
|
420
|
+
if (timedOut) {
|
|
421
|
+
throw new AgentStartupTimeoutError(timeoutMs);
|
|
422
|
+
}
|
|
423
|
+
throw error;
|
|
424
|
+
}
|
|
425
|
+
finally {
|
|
426
|
+
clearTimeout(timeout);
|
|
427
|
+
abortSignal.removeEventListener("abort", abort);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
320
430
|
function retryDelay(attempt, abortSignal) {
|
|
321
431
|
const base = Math.min(RETRY_MAX_DELAY_MS, RETRY_BASE_DELAY_MS * Math.pow(2, attempt));
|
|
322
432
|
const jitter = base * 0.2;
|
|
@@ -510,7 +620,7 @@ export function createAgentChatAdapter(options) {
|
|
|
510
620
|
const userMessageText = rawMessageText.trim() || attachments.length === 0
|
|
511
621
|
? rawMessageText
|
|
512
622
|
: "Use the attached context.";
|
|
513
|
-
const priorMessages = messages.slice(0, -1); // exclude latest user message
|
|
623
|
+
const priorMessages = limitPriorMessagesForRequest(messages.slice(0, -1)); // exclude latest user message and cap resend size
|
|
514
624
|
const history = priorMessages
|
|
515
625
|
.filter((m) => m.role === "user" || m.role === "assistant")
|
|
516
626
|
.map((m) => ({
|
|
@@ -564,6 +674,15 @@ export function createAgentChatAdapter(options) {
|
|
|
564
674
|
.filter(Boolean)
|
|
565
675
|
.join("\n");
|
|
566
676
|
};
|
|
677
|
+
const exhaustedRecoveryMessage = (reason) => {
|
|
678
|
+
if (content.length === 0 &&
|
|
679
|
+
(reason === "run_timeout" ||
|
|
680
|
+
reason === "no_progress" ||
|
|
681
|
+
reason === "stream_ended")) {
|
|
682
|
+
return "The agent request started but did not produce any visible progress before timing out. I stopped the automatic retries so this chat would not stay stuck on Thinking.";
|
|
683
|
+
}
|
|
684
|
+
return "The agent connection kept failing after several automatic recovery attempts.";
|
|
685
|
+
};
|
|
567
686
|
const dispatchAuthError = (reason) => {
|
|
568
687
|
if (typeof window === "undefined")
|
|
569
688
|
return;
|
|
@@ -788,11 +907,20 @@ export function createAgentChatAdapter(options) {
|
|
|
788
907
|
const visibleContent = visibleContentForContinuation();
|
|
789
908
|
const currentPartialHistory = contentToContinuationHistory(visibleContent);
|
|
790
909
|
const madeProgress = hasContinuationProgress(visibleContent);
|
|
910
|
+
const madeVisibleProgress = visibleContent.length > 0;
|
|
791
911
|
if (signal.reason === "loop_limit") {
|
|
792
912
|
stalledTransientContinuationAttempts = 0;
|
|
793
913
|
}
|
|
794
914
|
else {
|
|
795
915
|
totalTransientContinuationAttempts += 1;
|
|
916
|
+
if (!madeVisibleProgress && signal.reason === "run_timeout") {
|
|
917
|
+
return { ok: false, resetVisibleContent: false };
|
|
918
|
+
}
|
|
919
|
+
if (!madeVisibleProgress &&
|
|
920
|
+
totalTransientContinuationAttempts >
|
|
921
|
+
MAX_EMPTY_TRANSIENT_CONTINUATIONS) {
|
|
922
|
+
return { ok: false, resetVisibleContent: false };
|
|
923
|
+
}
|
|
796
924
|
if (signal.reason === "stale_run") {
|
|
797
925
|
staleRunContinuationAttempts += 1;
|
|
798
926
|
if (staleRunContinuationAttempts > MAX_STALE_RUN_CONTINUATIONS) {
|
|
@@ -861,7 +989,7 @@ export function createAgentChatAdapter(options) {
|
|
|
861
989
|
try {
|
|
862
990
|
runId = null;
|
|
863
991
|
lastSeq = -1;
|
|
864
|
-
const res = await
|
|
992
|
+
const res = await fetchWithStartupTimeout(apiUrl, {
|
|
865
993
|
method: "POST",
|
|
866
994
|
headers,
|
|
867
995
|
body: JSON.stringify({
|
|
@@ -884,8 +1012,7 @@ export function createAgentChatAdapter(options) {
|
|
|
884
1012
|
? { references: runConfig.custom.references }
|
|
885
1013
|
: {}),
|
|
886
1014
|
}),
|
|
887
|
-
|
|
888
|
-
});
|
|
1015
|
+
}, STARTUP_RESPONSE_TIMEOUT_MS, abortSignal);
|
|
889
1016
|
// Check for auth errors returned as 200 with JSON (common with middleware issues)
|
|
890
1017
|
const contentType = res.headers.get("content-type") || "";
|
|
891
1018
|
if (res.ok &&
|
|
@@ -1067,7 +1194,7 @@ export function createAgentChatAdapter(options) {
|
|
|
1067
1194
|
}
|
|
1068
1195
|
const continuation = prepareAutoContinuation(err);
|
|
1069
1196
|
if (!continuation.ok) {
|
|
1070
|
-
const message =
|
|
1197
|
+
const message = exhaustedRecoveryMessage(err.reason);
|
|
1071
1198
|
captureChatClientError(err, "auto-continuation-exhausted", {
|
|
1072
1199
|
autoContinueReason: err.reason,
|
|
1073
1200
|
});
|
|
@@ -1158,12 +1285,44 @@ export function createAgentChatAdapter(options) {
|
|
|
1158
1285
|
const activeReconnected = yield* reconnectActiveRunForThread();
|
|
1159
1286
|
if (activeReconnected)
|
|
1160
1287
|
return;
|
|
1288
|
+
if (err instanceof AgentStartupTimeoutError) {
|
|
1289
|
+
const message = "The agent chat endpoint accepted the request but did not start streaming in time. This usually means prompt setup, the LLM gateway, or the provider is stalled.";
|
|
1290
|
+
captureChatClientError(err, "startup-timeout", {
|
|
1291
|
+
timeoutMs: err.timeoutMs,
|
|
1292
|
+
});
|
|
1293
|
+
const runError = {
|
|
1294
|
+
message,
|
|
1295
|
+
details: connectionRecoveryDetails(),
|
|
1296
|
+
errorCode: "startup_timeout",
|
|
1297
|
+
recoverable: true,
|
|
1298
|
+
...(runId ? { runId } : {}),
|
|
1299
|
+
};
|
|
1300
|
+
if (typeof window !== "undefined") {
|
|
1301
|
+
window.dispatchEvent(new CustomEvent("agent-chat:run-error", {
|
|
1302
|
+
detail: { ...runError, tabId },
|
|
1303
|
+
}));
|
|
1304
|
+
}
|
|
1305
|
+
content.push({
|
|
1306
|
+
type: "text",
|
|
1307
|
+
text: `Something went wrong: ${message}`,
|
|
1308
|
+
});
|
|
1309
|
+
yield {
|
|
1310
|
+
content: [...content],
|
|
1311
|
+
status: {
|
|
1312
|
+
type: "incomplete",
|
|
1313
|
+
reason: "error",
|
|
1314
|
+
},
|
|
1315
|
+
metadata: { custom: { ...(runId ? { runId } : {}), runError } },
|
|
1316
|
+
};
|
|
1317
|
+
clearActiveRun();
|
|
1318
|
+
return;
|
|
1319
|
+
}
|
|
1161
1320
|
// Reconnect failed or not possible — keep going from the partial
|
|
1162
1321
|
// streamed content instead of surfacing a transient transport error.
|
|
1163
1322
|
if (content.length > 0) {
|
|
1164
1323
|
const continuation = prepareAutoContinuation(new AgentAutoContinueSignal({ reason: "stream_ended" }));
|
|
1165
1324
|
if (!continuation.ok) {
|
|
1166
|
-
const message = "
|
|
1325
|
+
const message = exhaustedRecoveryMessage("stream_ended");
|
|
1167
1326
|
captureChatClientError(err, "recovery-exhausted");
|
|
1168
1327
|
const runError = {
|
|
1169
1328
|
message,
|