@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.
- package/dist/action.d.ts +8 -0
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +4 -0
- package/dist/action.js.map +1 -1
- package/dist/agent/production-agent.d.ts +12 -2
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +58 -20
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +8 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +11 -12
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +13 -17
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/agent/types.d.ts +4 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/application-state/handlers.d.ts.map +1 -1
- package/dist/application-state/handlers.js +3 -8
- package/dist/application-state/handlers.js.map +1 -1
- package/dist/application-state/script-helpers.d.ts +2 -4
- package/dist/application-state/script-helpers.d.ts.map +1 -1
- package/dist/application-state/script-helpers.js +10 -47
- package/dist/application-state/script-helpers.js.map +1 -1
- package/dist/cli/create.d.ts +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +35 -10
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/workspace-dev.js +78 -15
- package/dist/cli/workspace-dev.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +6 -2
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +0 -15
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +69 -57
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/ConnectBuilderCard.d.ts +7 -1
- package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
- package/dist/client/ConnectBuilderCard.js +46 -5
- package/dist/client/ConnectBuilderCard.js.map +1 -1
- package/dist/client/ErrorBoundary.d.ts.map +1 -1
- package/dist/client/ErrorBoundary.js +20 -5
- package/dist/client/ErrorBoundary.js.map +1 -1
- package/dist/client/FeedbackButton.d.ts +3 -2
- package/dist/client/FeedbackButton.d.ts.map +1 -1
- package/dist/client/FeedbackButton.js +23 -15
- package/dist/client/FeedbackButton.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +303 -169
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/builder-frame.d.ts +36 -0
- package/dist/client/builder-frame.d.ts.map +1 -1
- package/dist/client/builder-frame.js +80 -9
- package/dist/client/builder-frame.js.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.js +7 -2
- package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/client/composer/PastedTextChip.d.ts +9 -0
- package/dist/client/composer/PastedTextChip.d.ts.map +1 -0
- package/dist/client/composer/PastedTextChip.js +47 -0
- package/dist/client/composer/PastedTextChip.js.map +1 -0
- package/dist/client/composer/PromptComposer.d.ts +4 -2
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +33 -5
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +13 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +61 -16
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/VoiceButton.d.ts.map +1 -1
- package/dist/client/composer/VoiceButton.js +5 -1
- package/dist/client/composer/VoiceButton.js.map +1 -1
- package/dist/client/composer/pasted-text.d.ts +6 -0
- package/dist/client/composer/pasted-text.d.ts.map +1 -0
- package/dist/client/composer/pasted-text.js +49 -0
- package/dist/client/composer/pasted-text.js.map +1 -0
- package/dist/client/composer/useVoiceDictation.d.ts +1 -0
- package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
- package/dist/client/composer/useVoiceDictation.js +18 -0
- package/dist/client/composer/useVoiceDictation.js.map +1 -1
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +0 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/integrations/IntegrationCard.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationCard.js +14 -2
- package/dist/client/integrations/IntegrationCard.js.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js +23 -4
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/notifications/NotificationsBell.d.ts.map +1 -1
- package/dist/client/notifications/NotificationsBell.js +4 -42
- package/dist/client/notifications/NotificationsBell.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +4 -6
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +84 -74
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +3 -154
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +13 -35
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/settings/SettingsPanel.js +1 -1
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +6 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +3 -0
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +15 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +58 -54
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/tools/ToolEditor.d.ts.map +1 -1
- package/dist/client/tools/ToolEditor.js +34 -4
- package/dist/client/tools/ToolEditor.js.map +1 -1
- package/dist/client/tools/ToolViewer.d.ts.map +1 -1
- package/dist/client/tools/ToolViewer.js +20 -1
- package/dist/client/tools/ToolViewer.js.map +1 -1
- package/dist/client/tools/ToolsListPage.d.ts.map +1 -1
- package/dist/client/tools/ToolsListPage.js +2 -1
- package/dist/client/tools/ToolsListPage.js.map +1 -1
- package/dist/client/tools/ToolsSidebarSection.js +1 -1
- package/dist/client/tools/ToolsSidebarSection.js.map +1 -1
- package/dist/client/transcription/BuilderTranscriptionCta.js +1 -1
- package/dist/client/transcription/BuilderTranscriptionCta.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +7 -2
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +26 -7
- package/dist/collab/client.js.map +1 -1
- package/dist/jobs/scheduler.js +0 -4
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/oauth-tokens/store.d.ts +0 -4
- package/dist/oauth-tokens/store.d.ts.map +1 -1
- package/dist/oauth-tokens/store.js +3 -24
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/observability/routes.d.ts.map +1 -1
- package/dist/observability/routes.js +1 -9
- package/dist/observability/routes.js.map +1 -1
- package/dist/onboarding/default-steps.js +1 -1
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/onboarding/plugin.d.ts.map +1 -1
- package/dist/onboarding/plugin.js +1 -8
- package/dist/onboarding/plugin.js.map +1 -1
- package/dist/org/accept-pending.d.ts.map +1 -1
- package/dist/org/accept-pending.js +1 -2
- package/dist/org/accept-pending.js.map +1 -1
- package/dist/org/context.d.ts +0 -2
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/context.js +0 -5
- package/dist/org/context.js.map +1 -1
- package/dist/resources/script-helpers.d.ts +3 -4
- package/dist/resources/script-helpers.d.ts.map +1 -1
- package/dist/resources/script-helpers.js +8 -15
- package/dist/resources/script-helpers.js.map +1 -1
- package/dist/scripts/chat/search-chats.d.ts.map +1 -1
- package/dist/scripts/chat/search-chats.js +4 -4
- package/dist/scripts/chat/search-chats.js.map +1 -1
- package/dist/scripts/manage-agent-loop-settings.js +2 -2
- package/dist/scripts/manage-agent-loop-settings.js.map +1 -1
- package/dist/scripts/resources/delete-memory.d.ts.map +1 -1
- package/dist/scripts/resources/delete-memory.js +4 -2
- package/dist/scripts/resources/delete-memory.js.map +1 -1
- package/dist/scripts/resources/delete.d.ts.map +1 -1
- package/dist/scripts/resources/delete.js +11 -4
- package/dist/scripts/resources/delete.js.map +1 -1
- package/dist/scripts/resources/list.d.ts.map +1 -1
- package/dist/scripts/resources/list.js +5 -3
- package/dist/scripts/resources/list.js.map +1 -1
- package/dist/scripts/resources/migrate-learnings.d.ts.map +1 -1
- package/dist/scripts/resources/migrate-learnings.js +5 -2
- package/dist/scripts/resources/migrate-learnings.js.map +1 -1
- package/dist/scripts/resources/read.d.ts.map +1 -1
- package/dist/scripts/resources/read.js +4 -2
- package/dist/scripts/resources/read.js.map +1 -1
- package/dist/scripts/resources/save-memory.d.ts.map +1 -1
- package/dist/scripts/resources/save-memory.js +4 -2
- package/dist/scripts/resources/save-memory.js.map +1 -1
- package/dist/scripts/resources/write.d.ts.map +1 -1
- package/dist/scripts/resources/write.js +11 -4
- package/dist/scripts/resources/write.js.map +1 -1
- package/dist/secrets/onboarding.d.ts.map +1 -1
- package/dist/secrets/onboarding.js +1 -9
- package/dist/secrets/onboarding.js.map +1 -1
- package/dist/secrets/routes.d.ts.map +1 -1
- package/dist/secrets/routes.js +2 -7
- package/dist/secrets/routes.js.map +1 -1
- package/dist/server/action-discovery.d.ts +15 -0
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +49 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +5 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +81 -20
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +5 -7
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/auth.d.ts +16 -20
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +115 -333
- package/dist/server/auth.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +23 -16
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +1 -2
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/google-oauth.d.ts +14 -2
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +32 -10
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server/oauth-helpers.d.ts +2 -4
- package/dist/server/oauth-helpers.d.ts.map +1 -1
- package/dist/server/oauth-helpers.js +2 -4
- package/dist/server/oauth-helpers.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts.map +1 -1
- package/dist/server/transcribe-voice.js +2 -4
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/triggers/dispatcher.d.ts.map +1 -1
- package/dist/triggers/dispatcher.js +0 -3
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +13 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/actions.md +1 -0
- package/docs/content/authentication.md +3 -20
- package/docs/content/creating-templates.md +1 -1
- package/docs/content/deployment.md +0 -1
- package/docs/content/security.md +0 -1
- package/docs/content/template-analytics.md +10 -0
- package/docs/content/template-calendar.md +10 -0
- package/docs/content/template-clips.md +10 -0
- package/docs/content/template-content.md +11 -1
- package/docs/content/template-dispatch.md +10 -0
- package/docs/content/template-forms.md +10 -0
- package/docs/content/template-mail.md +10 -0
- package/docs/content/template-slides.md +11 -1
- package/docs/content/template-starter.md +11 -1
- package/docs/content/template-video.md +10 -0
- package/package.json +1 -1
- package/dist/client/dev-mode.d.ts +0 -14
- package/dist/client/dev-mode.d.ts.map +0 -1
- package/dist/client/dev-mode.js +0 -14
- package/dist/client/dev-mode.js.map +0 -1
- package/dist/server/local-migration.d.ts +0 -41
- package/dist/server/local-migration.d.ts.map +0 -1
- package/dist/server/local-migration.js +0 -235
- 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
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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:
|
|
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
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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") {
|