@agent-native/core 0.164.4 → 0.164.12
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/corpus/README.md +1 -1
- package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +84 -0
- package/corpus/templates/calendar/AGENTS.md +5 -0
- package/corpus/templates/calendar/actions/delete-event.ts +1 -1
- package/corpus/templates/calendar/actions/delete-events.ts +508 -0
- package/corpus/templates/calendar/actions/event-action-helpers.ts +1 -1
- package/corpus/templates/calendar/actions/list-events.ts +53 -0
- package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +36 -47
- package/corpus/templates/calendar/app/components/calendar/DayView.tsx +3 -0
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +18 -1
- package/corpus/templates/calendar/app/components/calendar/InlineEventPickers.tsx +256 -38
- package/corpus/templates/calendar/app/hooks/use-google-auth.ts +43 -3
- package/corpus/templates/calendar/app/i18n-data.ts +120 -0
- package/corpus/templates/calendar/app/lib/event-form-utils.ts +113 -0
- package/corpus/templates/calendar/changelog/2026-08-18-the-agent-can-now-remove-many-meetings-at-once-such-as-every.md +6 -0
- package/corpus/templates/calendar/server/handlers/google-auth.ts +119 -3
- package/corpus/templates/calendar/server/lib/event-weekday.ts +112 -0
- package/corpus/templates/calendar/server/routes/[base]/_agent-native/google/add-account/auth-url.post.ts +1 -0
- package/corpus/templates/calendar/server/routes/[base]/_agent-native/google/auth-url.post.ts +1 -0
- package/corpus/templates/calendar/server/routes/_agent-native/google/add-account/auth-url.post.ts +1 -0
- package/corpus/templates/calendar/server/routes/_agent-native/google/auth-url.post.ts +1 -0
- package/corpus/templates/clips/app/components/player/video-player.tsx +12 -0
- package/corpus/templates/clips/app/routes/_app.dictate.tsx +18 -4
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +114 -20
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +83 -78
- package/corpus/templates/clips/changelog/2026-08-19-clips-nightly-builds-are-available-for-trying-the-latest-upd.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-19-social-preview-video-frames.md +1 -0
- package/corpus/templates/clips/desktop/README.md +19 -4
- package/corpus/templates/clips/desktop/src/app.tsx +78 -16
- package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +3 -2
- package/corpus/templates/clips/desktop/src-tauri/tauri.conf.json +1 -0
- package/corpus/templates/clips/server/routes/[base]/_agent-native/google/auth-url.post.ts +1 -0
- package/corpus/templates/clips/server/routes/_agent-native/google/auth-url.get.ts +41 -3
- package/corpus/templates/clips/server/routes/_agent-native/google/auth-url.post.ts +1 -0
- package/corpus/templates/clips/server/routes/_agent-native/google/callback.get.ts +22 -1
- package/corpus/templates/clips/server/routes/api/clips-updater.json.get.ts +41 -22
- package/corpus/templates/factory/AGENTS.md +3 -2
- package/corpus/templates/factory/actions/get-factory-graph-version.ts +69 -0
- package/corpus/templates/factory/actions/list-factory-automations.ts +4 -0
- package/corpus/templates/factory/actions/list-factory-graph-versions.ts +82 -0
- package/corpus/templates/factory/actions/restore-factory-graph-version.ts +163 -0
- package/corpus/templates/factory/actions/save-factory-graph.ts +93 -60
- package/corpus/templates/factory/actions/start-builder-for-item.ts +19 -17
- package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +100 -36
- package/corpus/templates/factory/app/components/factory/FactoryHistoryView.tsx +709 -0
- package/corpus/templates/factory/app/components/factory/FactoryInspector.tsx +62 -2
- package/corpus/templates/factory/app/components/ui/alert-dialog.tsx +1 -0
- package/corpus/templates/factory/app/i18n/en-US.ts +47 -0
- package/corpus/templates/factory/app/routes/factory.tsx +324 -61
- package/corpus/templates/factory/server/connectors/slack.ts +44 -2
- package/corpus/templates/factory/server/plugins/agent-chat.ts +12 -8
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +13 -0
- package/corpus/templates/factory/server/triage/slack-client.ts +5 -0
- package/corpus/templates/factory/server/triage/slack-poller.ts +72 -4
- package/corpus/templates/mail/actions/view-screen.ts +1 -1
- package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +100 -18
- package/corpus/templates/mail/server/handlers/google-auth.ts +125 -24
- package/corpus/templates/mail/server/lib/gmail-query.ts +5 -2
- package/corpus/templates/mail/server/routes/[base]/_agent-native/google/add-account/auth-url.post.ts +1 -0
- package/corpus/templates/mail/server/routes/[base]/_agent-native/google/auth-url.post.ts +1 -0
- package/corpus/templates/mail/server/routes/_agent-native/google/add-account/auth-url.post.ts +1 -0
- package/corpus/templates/mail/server/routes/_agent-native/google/auth-url.post.ts +1 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +0 -12
- package/corpus/templates/plan/changelog/2026-08-19-plan-prompts-now-guide-you-to-connect-ai-before-sending-and-.md +6 -0
- package/corpus/templates/slides/actions/approve-deck-access-request.ts +234 -0
- package/corpus/templates/slides/actions/get-deck-access-status.ts +35 -2
- package/corpus/templates/slides/actions/request-deck-access.ts +263 -64
- package/corpus/templates/slides/app/components/editor/MissingDeckAccessPane.tsx +196 -0
- package/corpus/templates/slides/app/components/editor/RequestDeckAccessDialog.tsx +101 -0
- package/corpus/templates/slides/app/hooks/use-deck-access.ts +7 -4
- package/corpus/templates/slides/app/i18n/en-US.ts +29 -6
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +147 -169
- package/corpus/templates/slides/app/routes/access-request.approve.tsx +250 -0
- package/corpus/templates/slides/server/db/schema.ts +8 -0
- package/corpus/templates/slides/server/lib/access-request-email.ts +36 -0
- package/corpus/templates/slides/server/lib/emails.ts +26 -0
- package/corpus/templates/slides/server/plugins/agent-chat.ts +7 -0
- package/corpus/templates/slides/server/plugins/db.ts +50 -0
- package/corpus/templates/slides/shared/deck-access.ts +31 -0
- package/dist/a2a/task-store.d.ts +1 -0
- package/dist/a2a/task-store.js +1 -1
- package/dist/agent/observational-memory/store.d.ts +1 -0
- package/dist/agent/observational-memory/store.js +1 -1
- package/dist/agent/run-store.d.ts +1 -0
- package/dist/agent/run-store.js +1 -1
- package/dist/agent/tool-approval-store.d.ts +1 -0
- package/dist/agent/tool-approval-store.js +1 -1
- package/dist/application-state/store.d.ts +1 -0
- package/dist/application-state/store.js +1 -1
- package/dist/browser-sessions/store.d.ts +1 -0
- package/dist/browser-sessions/store.js +1 -1
- package/dist/checkpoints/store.d.ts +1 -0
- package/dist/checkpoints/store.js +1 -1
- package/dist/cli/code-agent-schedules.d.ts +11 -0
- package/dist/cli/code-agent-schedules.js +44 -5
- package/dist/client/AgentPanel.d.ts +5 -1
- package/dist/client/AgentPanel.js +2 -2
- package/dist/client/AssistantChat.d.ts +5 -1
- package/dist/client/AssistantChat.js +40 -6
- package/dist/client/EnvironmentBadge.d.ts +7 -13
- package/dist/client/EnvironmentBadge.js +43 -92
- package/dist/client/agent-chat/index.d.ts +1 -0
- package/dist/client/agent-chat/index.js +1 -0
- package/dist/client/agent-chat-adapter.js +76 -50
- package/dist/client/app-providers.js +4 -4
- package/dist/client/chat/message-components.d.ts +4 -0
- package/dist/client/chat/message-components.js +28 -1
- package/dist/client/chat/run-recovery.js +26 -0
- package/dist/client/chat-first/apps-rail.d.ts +1 -0
- package/dist/client/chat-first/apps-rail.js +28 -2
- package/dist/client/sse-event-processor.js +13 -8
- package/dist/client/use-active-agent-chat-run.d.ts +2 -0
- package/dist/client/use-active-agent-chat-run.js +22 -0
- package/dist/coding-tools/sandbox/executions-store.d.ts +1 -0
- package/dist/coding-tools/sandbox/executions-store.js +1 -1
- package/dist/collab/awareness-store.d.ts +1 -0
- package/dist/collab/awareness-store.js +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/storage.d.ts +1 -0
- package/dist/collab/storage.js +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/db/client.js +3 -3
- package/dist/db/ddl-guard.js +8 -0
- package/dist/db/migration-runtime.d.ts +23 -0
- package/dist/db/migration-runtime.js +41 -0
- package/dist/db/migrations.d.ts +1 -2
- package/dist/db/migrations.js +2 -24
- package/dist/email-catalog/log.d.ts +1 -0
- package/dist/email-catalog/log.js +1 -1
- package/dist/guards/index.d.ts +1 -0
- package/dist/guards/index.js +1 -0
- package/dist/guards/release-schema-complete.d.ts +22 -0
- package/dist/guards/release-schema-complete.js +144 -0
- package/dist/integrations/a2a-continuations-store.d.ts +1 -0
- package/dist/integrations/a2a-continuations-store.js +1 -1
- package/dist/integrations/awaiting-input-store.d.ts +1 -0
- package/dist/integrations/awaiting-input-store.js +1 -1
- package/dist/integrations/config-store.d.ts +1 -0
- package/dist/integrations/config-store.js +1 -1
- package/dist/integrations/controls-store.d.ts +1 -0
- package/dist/integrations/controls-store.js +1 -1
- package/dist/integrations/identity-links-store.d.ts +1 -0
- package/dist/integrations/identity-links-store.js +1 -1
- package/dist/integrations/installations-store.d.ts +1 -0
- package/dist/integrations/installations-store.js +1 -1
- package/dist/integrations/remote-commands-store.d.ts +1 -0
- package/dist/integrations/remote-commands-store.js +1 -1
- package/dist/integrations/remote-devices-store.d.ts +1 -0
- package/dist/integrations/remote-devices-store.js +1 -1
- package/dist/integrations/remote-push-store.d.ts +1 -0
- package/dist/integrations/remote-push-store.js +1 -1
- package/dist/integrations/remote-run-events-store.d.ts +1 -0
- package/dist/integrations/remote-run-events-store.js +1 -1
- package/dist/integrations/scope-store.d.ts +1 -0
- package/dist/integrations/scope-store.js +1 -1
- package/dist/integrations/thread-mapping-store.d.ts +1 -0
- package/dist/integrations/thread-mapping-store.js +1 -1
- package/dist/integrations/usage-budget-store.d.ts +1 -0
- package/dist/integrations/usage-budget-store.js +1 -1
- package/dist/jobs/background-automation-runner.js +111 -9
- package/dist/jobs/run-history.d.ts +1 -0
- package/dist/jobs/run-history.js +1 -1
- package/dist/jobs/scheduler-health.d.ts +1 -0
- package/dist/jobs/scheduler-health.js +1 -1
- package/dist/mcp/approval-store.d.ts +1 -0
- package/dist/mcp/approval-store.js +1 -1
- package/dist/mcp/connect-store.d.ts +1 -0
- package/dist/mcp/connect-store.js +1 -1
- package/dist/mcp/oauth-store.d.ts +1 -0
- package/dist/mcp/oauth-store.js +1 -1
- package/dist/notifications/store.d.ts +1 -0
- package/dist/notifications/store.js +1 -1
- package/dist/oauth-tokens/store.d.ts +1 -0
- package/dist/oauth-tokens/store.js +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/progress/store.d.ts +1 -0
- package/dist/progress/store.js +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +5 -5
- package/dist/provider-api/actions/provider-api.d.ts +4 -4
- package/dist/provider-api/corpus-jobs-store.d.ts +1 -0
- package/dist/provider-api/corpus-jobs-store.js +1 -1
- package/dist/provider-api/custom-registry.d.ts +1 -0
- package/dist/provider-api/custom-registry.js +1 -1
- package/dist/provider-api/quota-governor.d.ts +1 -0
- package/dist/provider-api/quota-governor.js +1 -1
- package/dist/provider-api/staged-datasets-store.d.ts +1 -0
- package/dist/provider-api/staged-datasets-store.js +1 -1
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/resources/store.d.ts +1 -0
- package/dist/resources/store.js +1 -1
- package/dist/scripts/dev/index.js +15 -1
- package/dist/search/index.js +3 -0
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/secrets/storage.d.ts +1 -0
- package/dist/secrets/storage.js +1 -1
- package/dist/server/agent-chat-plugin.js +38 -9
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-teams-run-queue.d.ts +1 -0
- package/dist/server/agent-teams-run-queue.js +1 -1
- package/dist/server/auth-marketing.js +3 -1
- package/dist/server/auth.d.ts +18 -1
- package/dist/server/auth.js +370 -154
- package/dist/server/embed-session.d.ts +1 -0
- package/dist/server/embed-session.js +1 -1
- package/dist/server/google-auth-plugin.js +3 -1
- package/dist/server/google-oauth.d.ts +10 -0
- package/dist/server/google-oauth.js +25 -1
- package/dist/server/identity-sso-store.d.ts +1 -0
- package/dist/server/identity-sso-store.js +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/onboarding-html.js +200 -31
- package/dist/server/poll.d.ts +2 -0
- package/dist/server/poll.js +19 -1
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/release-migrations.js +5 -0
- package/dist/server/release-schema.d.ts +46 -0
- package/dist/server/release-schema.js +307 -0
- package/dist/settings/store.d.ts +1 -0
- package/dist/settings/store.js +1 -1
- package/dist/shared/environment-lanes.d.ts +28 -0
- package/dist/shared/environment-lanes.js +61 -0
- package/dist/sharing/actions/share-resource.js +22 -2
- package/dist/styles/agent-native.css +17 -15
- package/dist/triggers/routes.d.ts +11 -0
- package/dist/triggers/routes.js +10 -0
- package/dist/usage/alerts-store.d.ts +1 -0
- package/dist/usage/alerts-store.js +1 -1
- package/dist/usage/store.d.ts +1 -0
- package/dist/usage/store.js +1 -1
- package/docs/content/actions-access-control.mdx +136 -2
- package/docs/content/actions-agent-tools.mdx +101 -0
- package/docs/content/actions-defining.mdx +2 -2
- package/docs/content/audit-log.mdx +1 -1
- package/docs/content/authentication.mdx +1 -1
- package/docs/content/cloudflare.mdx +43 -0
- package/docs/content/creating-templates.mdx +1 -1
- package/docs/content/deploy-an-app.mdx +109 -0
- package/docs/content/deployment-environment-variables.mdx +101 -0
- package/docs/content/deployment.mdx +125 -792
- package/docs/content/docs-components.mdx +2 -2
- package/docs/content/environment-variables.mdx +41 -41
- package/docs/content/file-uploads.mdx +74 -40
- package/docs/content/harness-agents.mdx +2 -2
- package/docs/content/internationalization.mdx +61 -65
- package/docs/content/key-concepts.mdx +3 -3
- package/docs/content/multi-app-workspace.mdx +2 -2
- package/docs/content/netlify.mdx +47 -0
- package/docs/content/node-docker.mdx +138 -0
- package/docs/content/organizations-teams-permissions.mdx +5 -5
- package/docs/content/other-platforms.mdx +27 -0
- package/docs/content/ssr-caching.mdx +45 -0
- package/docs/content/template-assets-developers.mdx +2 -2
- package/docs/content/template-chat-developers.mdx +2 -2
- package/docs/content/template-content-developers.mdx +2 -2
- package/docs/content/{local-file-mode.mdx → template-content-local-files.mdx} +2 -1
- package/docs/content/template-content-sync.mdx +2 -2
- package/docs/content/toolkit-agent-ux.mdx +1 -1
- package/docs/content/toolkit-resources.mdx +2 -2
- package/docs/content/updating-ui-in-production.mdx +35 -0
- package/docs/content/vercel.mdx +38 -0
- package/docs/content/what-is-agent-native.mdx +1 -1
- package/docs/content/workspace-deployment.mdx +350 -0
- package/package.json +2 -2
- package/docs/content/agents.mdx +0 -9
- package/docs/content/database.mdx +0 -317
- package/docs/content/human-approval.mdx +0 -156
|
@@ -1429,6 +1429,16 @@ function isMissingCredentialMessage(message) {
|
|
|
1429
1429
|
msg.includes("no llm provider") ||
|
|
1430
1430
|
msg.includes("llm provider is connected"));
|
|
1431
1431
|
}
|
|
1432
|
+
function isMissingProviderErrorMessage(message, errorCode) {
|
|
1433
|
+
const text = message.toLowerCase();
|
|
1434
|
+
const code = (errorCode ?? "").toLowerCase();
|
|
1435
|
+
return (text.includes("no llm provider") ||
|
|
1436
|
+
text.includes("missing credentials") ||
|
|
1437
|
+
text.includes("missing api key") ||
|
|
1438
|
+
text.includes("missing_api_key") ||
|
|
1439
|
+
((code === "missing_credentials" || code === "missing_api_key") &&
|
|
1440
|
+
text.includes("llm provider")));
|
|
1441
|
+
}
|
|
1432
1442
|
function missingCredentialFailure(message) {
|
|
1433
1443
|
try {
|
|
1434
1444
|
const parsed = JSON.parse(message);
|
|
@@ -1439,9 +1449,10 @@ function missingCredentialFailure(message) {
|
|
|
1439
1449
|
: message;
|
|
1440
1450
|
const errorCode = typeof parsed.errorCode === "string"
|
|
1441
1451
|
? parsed.errorCode
|
|
1442
|
-
:
|
|
1452
|
+
: isMissingCredentialMessage(raw)
|
|
1453
|
+
? "missing_credentials"
|
|
1454
|
+
: "authentication_error";
|
|
1443
1455
|
return {
|
|
1444
|
-
text: formatChatErrorText(raw, typeof parsed.upgradeUrl === "string" ? parsed.upgradeUrl : undefined, errorCode),
|
|
1445
1456
|
runError: {
|
|
1446
1457
|
message: normalizeChatError(raw).message,
|
|
1447
1458
|
errorCode,
|
|
@@ -1450,10 +1461,11 @@ function missingCredentialFailure(message) {
|
|
|
1450
1461
|
}
|
|
1451
1462
|
catch {
|
|
1452
1463
|
return {
|
|
1453
|
-
text: formatChatErrorText(message, undefined, "missing_credentials"),
|
|
1454
1464
|
runError: {
|
|
1455
1465
|
message: normalizeChatError(message).message,
|
|
1456
|
-
errorCode:
|
|
1466
|
+
errorCode: isMissingCredentialMessage(message)
|
|
1467
|
+
? "missing_credentials"
|
|
1468
|
+
: "authentication_error",
|
|
1457
1469
|
},
|
|
1458
1470
|
};
|
|
1459
1471
|
}
|
|
@@ -1707,6 +1719,16 @@ export function createAgentChatAdapter(options) {
|
|
|
1707
1719
|
activeRun.threadId === threadId &&
|
|
1708
1720
|
activeRun.runId === runId));
|
|
1709
1721
|
};
|
|
1722
|
+
const clearOwnedActiveRun = () => {
|
|
1723
|
+
if (!ownsActiveRunState())
|
|
1724
|
+
return;
|
|
1725
|
+
if (threadId && runId) {
|
|
1726
|
+
clearActiveRunIfMatches(threadId, runId);
|
|
1727
|
+
}
|
|
1728
|
+
else {
|
|
1729
|
+
clearActiveRun();
|
|
1730
|
+
}
|
|
1731
|
+
};
|
|
1710
1732
|
// The adapter's own stream outranks AssistantChat's reconnect fallback:
|
|
1711
1733
|
// when it attaches to a run, any reconnect reader folding the same run
|
|
1712
1734
|
// must stop writing UI state or both folds render at once.
|
|
@@ -1716,6 +1738,18 @@ export function createAgentChatAdapter(options) {
|
|
|
1716
1738
|
preemptRunStream(threadId, runId, streamOwnershipToken);
|
|
1717
1739
|
}
|
|
1718
1740
|
};
|
|
1741
|
+
let terminalChatUiStopped = false;
|
|
1742
|
+
const publishTerminalChatUiStopped = () => {
|
|
1743
|
+
if (terminalChatUiStopped)
|
|
1744
|
+
return;
|
|
1745
|
+
terminalChatUiStopped = true;
|
|
1746
|
+
if (typeof window === "undefined")
|
|
1747
|
+
return;
|
|
1748
|
+
dispatchTerminalChatUiCleanup(tabId);
|
|
1749
|
+
window.dispatchEvent(new CustomEvent("agentNative.chatRunning", {
|
|
1750
|
+
detail: { isRunning: false, tabId },
|
|
1751
|
+
}));
|
|
1752
|
+
};
|
|
1719
1753
|
const settleTerminalChatRun = () => {
|
|
1720
1754
|
if (threadId && runId) {
|
|
1721
1755
|
releaseRunStream(threadId, runId, streamOwnershipToken);
|
|
@@ -1728,12 +1762,7 @@ export function createAgentChatAdapter(options) {
|
|
|
1728
1762
|
else {
|
|
1729
1763
|
clearActiveRun();
|
|
1730
1764
|
}
|
|
1731
|
-
|
|
1732
|
-
return;
|
|
1733
|
-
dispatchTerminalChatUiCleanup(tabId);
|
|
1734
|
-
window.dispatchEvent(new CustomEvent("agentNative.chatRunning", {
|
|
1735
|
-
detail: { isRunning: false, tabId },
|
|
1736
|
-
}));
|
|
1765
|
+
publishTerminalChatUiStopped();
|
|
1737
1766
|
};
|
|
1738
1767
|
const seenRunSeqs = new Map();
|
|
1739
1768
|
const preparingActionStatesByRun = new Map();
|
|
@@ -2062,7 +2091,7 @@ export function createAgentChatAdapter(options) {
|
|
|
2062
2091
|
const reconnectRes = await fetch(`${apiUrl}/runs/${encodeURIComponent(runId)}/events?after=${lastSeq + 1}`, { signal: abortSignal });
|
|
2063
2092
|
if (!reconnectRes.ok || !reconnectRes.body) {
|
|
2064
2093
|
if (reconnectRes.status === 404) {
|
|
2065
|
-
|
|
2094
|
+
clearOwnedActiveRun();
|
|
2066
2095
|
return false;
|
|
2067
2096
|
}
|
|
2068
2097
|
lastReconnectError = new Error(`Reconnect failed: ${reconnectRes.status}`);
|
|
@@ -2091,14 +2120,14 @@ export function createAgentChatAdapter(options) {
|
|
|
2091
2120
|
yield nextResult;
|
|
2092
2121
|
}
|
|
2093
2122
|
if (ownsActiveRunState()) {
|
|
2094
|
-
|
|
2123
|
+
clearOwnedActiveRun();
|
|
2095
2124
|
}
|
|
2096
2125
|
return true;
|
|
2097
2126
|
}
|
|
2098
2127
|
catch (reconnectErr) {
|
|
2099
2128
|
if (reconnectErr instanceof Error &&
|
|
2100
2129
|
reconnectErr.name === "AbortError") {
|
|
2101
|
-
|
|
2130
|
+
clearOwnedActiveRun();
|
|
2102
2131
|
return true;
|
|
2103
2132
|
}
|
|
2104
2133
|
if (reconnectErr instanceof AgentAutoContinueSignal) {
|
|
@@ -2162,7 +2191,7 @@ export function createAgentChatAdapter(options) {
|
|
|
2162
2191
|
catch (activeErr) {
|
|
2163
2192
|
if (activeErr instanceof Error &&
|
|
2164
2193
|
activeErr.name === "AbortError") {
|
|
2165
|
-
|
|
2194
|
+
clearOwnedActiveRun();
|
|
2166
2195
|
return true;
|
|
2167
2196
|
}
|
|
2168
2197
|
lastActiveRunError = activeErr;
|
|
@@ -2235,7 +2264,7 @@ export function createAgentChatAdapter(options) {
|
|
|
2235
2264
|
catch (activeErr) {
|
|
2236
2265
|
if (activeErr instanceof Error &&
|
|
2237
2266
|
activeErr.name === "AbortError") {
|
|
2238
|
-
|
|
2267
|
+
clearOwnedActiveRun();
|
|
2239
2268
|
return true;
|
|
2240
2269
|
}
|
|
2241
2270
|
lastActiveRunError = activeErr;
|
|
@@ -2273,17 +2302,19 @@ export function createAgentChatAdapter(options) {
|
|
|
2273
2302
|
settleInterruptedToolCalls(content, undefined, {
|
|
2274
2303
|
includeActivity: true,
|
|
2275
2304
|
});
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2305
|
+
if (!isMissingProviderErrorMessage(args.message, args.errorCode)) {
|
|
2306
|
+
content.push({
|
|
2307
|
+
type: "text",
|
|
2308
|
+
text: formatChatErrorText(args.message, undefined, args.errorCode),
|
|
2309
|
+
});
|
|
2310
|
+
}
|
|
2280
2311
|
settleTerminalChatRun();
|
|
2281
2312
|
yield {
|
|
2282
2313
|
content: [...content],
|
|
2283
2314
|
status: { type: "incomplete", reason: "error" },
|
|
2284
2315
|
metadata: { custom: { ...(runId ? { runId } : {}), runError } },
|
|
2285
2316
|
};
|
|
2286
|
-
|
|
2317
|
+
clearOwnedActiveRun();
|
|
2287
2318
|
};
|
|
2288
2319
|
// Final outcome for a background turn the follow loop can no longer
|
|
2289
2320
|
// follow: either the run went terminal server-side (surface its
|
|
@@ -2313,7 +2344,7 @@ export function createAgentChatAdapter(options) {
|
|
|
2313
2344
|
},
|
|
2314
2345
|
},
|
|
2315
2346
|
};
|
|
2316
|
-
|
|
2347
|
+
clearOwnedActiveRun();
|
|
2317
2348
|
return;
|
|
2318
2349
|
}
|
|
2319
2350
|
// terminal_reason is either a bare reason ("dispatch_payload_missing")
|
|
@@ -2385,7 +2416,7 @@ export function createAgentChatAdapter(options) {
|
|
|
2385
2416
|
},
|
|
2386
2417
|
},
|
|
2387
2418
|
};
|
|
2388
|
-
|
|
2419
|
+
clearOwnedActiveRun();
|
|
2389
2420
|
return;
|
|
2390
2421
|
}
|
|
2391
2422
|
if (lastRecoverableRunError) {
|
|
@@ -2466,17 +2497,17 @@ export function createAgentChatAdapter(options) {
|
|
|
2466
2497
|
}
|
|
2467
2498
|
settleTerminalChatRun();
|
|
2468
2499
|
yield missingFinalResponseResult;
|
|
2469
|
-
|
|
2500
|
+
clearOwnedActiveRun();
|
|
2470
2501
|
return "completed";
|
|
2471
2502
|
}
|
|
2472
2503
|
// readSSEStream returned normally: a terminal done/error was
|
|
2473
2504
|
// consumed and rendered — the turn is over.
|
|
2474
|
-
|
|
2505
|
+
clearOwnedActiveRun();
|
|
2475
2506
|
return "completed";
|
|
2476
2507
|
}
|
|
2477
2508
|
catch (attachErr) {
|
|
2478
2509
|
if (attachErr instanceof Error && attachErr.name === "AbortError") {
|
|
2479
|
-
|
|
2510
|
+
clearOwnedActiveRun();
|
|
2480
2511
|
return "aborted";
|
|
2481
2512
|
}
|
|
2482
2513
|
if (attachErr instanceof AgentAutoContinueSignal) {
|
|
@@ -2624,7 +2655,7 @@ export function createAgentChatAdapter(options) {
|
|
|
2624
2655
|
const replayedTerminalRunIds = new Set();
|
|
2625
2656
|
while (true) {
|
|
2626
2657
|
if (abortSignal.aborted) {
|
|
2627
|
-
|
|
2658
|
+
clearOwnedActiveRun();
|
|
2628
2659
|
return "completed";
|
|
2629
2660
|
}
|
|
2630
2661
|
if (Date.now() - followStartedAt >=
|
|
@@ -2663,7 +2694,7 @@ export function createAgentChatAdapter(options) {
|
|
|
2663
2694
|
}
|
|
2664
2695
|
catch (pollErr) {
|
|
2665
2696
|
if (pollErr instanceof Error && pollErr.name === "AbortError") {
|
|
2666
|
-
|
|
2697
|
+
clearOwnedActiveRun();
|
|
2667
2698
|
return "completed";
|
|
2668
2699
|
}
|
|
2669
2700
|
activeUnreadable = true;
|
|
@@ -2672,7 +2703,7 @@ export function createAgentChatAdapter(options) {
|
|
|
2672
2703
|
// Unreadable: learn nothing, decide nothing, wait and re-ask.
|
|
2673
2704
|
await delay(BACKGROUND_FOLLOW_POLL_INTERVAL_MS, abortSignal);
|
|
2674
2705
|
if (abortSignal.aborted) {
|
|
2675
|
-
|
|
2706
|
+
clearOwnedActiveRun();
|
|
2676
2707
|
return "completed";
|
|
2677
2708
|
}
|
|
2678
2709
|
continue;
|
|
@@ -2747,7 +2778,7 @@ export function createAgentChatAdapter(options) {
|
|
|
2747
2778
|
if (isBackgroundTerminalErrorOutcome(active)) {
|
|
2748
2779
|
const graceOutcome = await awaitBackgroundErrorRecoverySuccessor(activeRunId);
|
|
2749
2780
|
if (graceOutcome === "aborted") {
|
|
2750
|
-
|
|
2781
|
+
clearOwnedActiveRun();
|
|
2751
2782
|
return "completed";
|
|
2752
2783
|
}
|
|
2753
2784
|
if (graceOutcome === "successor") {
|
|
@@ -2866,7 +2897,7 @@ export function createAgentChatAdapter(options) {
|
|
|
2866
2897
|
catch (refetchErr) {
|
|
2867
2898
|
if (refetchErr instanceof Error &&
|
|
2868
2899
|
refetchErr.name === "AbortError") {
|
|
2869
|
-
|
|
2900
|
+
clearOwnedActiveRun();
|
|
2870
2901
|
return "completed";
|
|
2871
2902
|
}
|
|
2872
2903
|
secondOpinionUnreadable = true;
|
|
@@ -2966,7 +2997,7 @@ export function createAgentChatAdapter(options) {
|
|
|
2966
2997
|
const nextPollDelayMs = Math.min(backedOffPollDelayMs, idleRemainingMs);
|
|
2967
2998
|
await delay(nextPollDelayMs, abortSignal);
|
|
2968
2999
|
if (abortSignal.aborted) {
|
|
2969
|
-
|
|
3000
|
+
clearOwnedActiveRun();
|
|
2970
3001
|
return "completed";
|
|
2971
3002
|
}
|
|
2972
3003
|
}
|
|
@@ -3098,7 +3129,7 @@ export function createAgentChatAdapter(options) {
|
|
|
3098
3129
|
includeReferences = Boolean(runConfig?.custom?.references);
|
|
3099
3130
|
internalContinuationRequest = true;
|
|
3100
3131
|
startupRecoveryAttempts = 0;
|
|
3101
|
-
|
|
3132
|
+
clearOwnedActiveRun();
|
|
3102
3133
|
if (!isTransient) {
|
|
3103
3134
|
return {
|
|
3104
3135
|
ok: true,
|
|
@@ -3334,7 +3365,6 @@ export function createAgentChatAdapter(options) {
|
|
|
3334
3365
|
detail: { ...failure.runError, tabId },
|
|
3335
3366
|
}));
|
|
3336
3367
|
}
|
|
3337
|
-
content.push({ type: "text", text: failure.text });
|
|
3338
3368
|
settleTerminalChatRun();
|
|
3339
3369
|
yield {
|
|
3340
3370
|
content: [...content],
|
|
@@ -3417,17 +3447,17 @@ export function createAgentChatAdapter(options) {
|
|
|
3417
3447
|
}
|
|
3418
3448
|
settleTerminalChatRun();
|
|
3419
3449
|
yield missingFinalResponseResult;
|
|
3420
|
-
|
|
3450
|
+
clearOwnedActiveRun();
|
|
3421
3451
|
return;
|
|
3422
3452
|
}
|
|
3423
3453
|
// Run completed normally — clear active run state
|
|
3424
|
-
|
|
3454
|
+
clearOwnedActiveRun();
|
|
3425
3455
|
return;
|
|
3426
3456
|
}
|
|
3427
3457
|
catch (err) {
|
|
3428
3458
|
if (err instanceof Error && err.name === "AbortError") {
|
|
3429
3459
|
// User-initiated abort (Stop button) — clear active run
|
|
3430
|
-
|
|
3460
|
+
clearOwnedActiveRun();
|
|
3431
3461
|
return;
|
|
3432
3462
|
}
|
|
3433
3463
|
if (err instanceof AgentAutoContinueSignal) {
|
|
@@ -3487,7 +3517,7 @@ export function createAgentChatAdapter(options) {
|
|
|
3487
3517
|
},
|
|
3488
3518
|
},
|
|
3489
3519
|
};
|
|
3490
|
-
|
|
3520
|
+
clearOwnedActiveRun();
|
|
3491
3521
|
return;
|
|
3492
3522
|
}
|
|
3493
3523
|
const preservedError = err.errorInfo ?? lastRecoverableRunError ?? null;
|
|
@@ -3541,7 +3571,7 @@ export function createAgentChatAdapter(options) {
|
|
|
3541
3571
|
custom: { ...(runId ? { runId } : {}), runError },
|
|
3542
3572
|
},
|
|
3543
3573
|
};
|
|
3544
|
-
|
|
3574
|
+
clearOwnedActiveRun();
|
|
3545
3575
|
return;
|
|
3546
3576
|
}
|
|
3547
3577
|
if (continuation.resetVisibleContent) {
|
|
@@ -3612,7 +3642,7 @@ export function createAgentChatAdapter(options) {
|
|
|
3612
3642
|
custom: { ...(runId ? { runId } : {}), runError },
|
|
3613
3643
|
},
|
|
3614
3644
|
};
|
|
3615
|
-
|
|
3645
|
+
clearOwnedActiveRun();
|
|
3616
3646
|
return;
|
|
3617
3647
|
}
|
|
3618
3648
|
const errMsg = err instanceof Error ? err.message : "Something went wrong.";
|
|
@@ -3636,7 +3666,7 @@ export function createAgentChatAdapter(options) {
|
|
|
3636
3666
|
reason: "error",
|
|
3637
3667
|
},
|
|
3638
3668
|
};
|
|
3639
|
-
|
|
3669
|
+
clearOwnedActiveRun();
|
|
3640
3670
|
return;
|
|
3641
3671
|
}
|
|
3642
3672
|
if (isMissingCredentialMessage(errMsg)) {
|
|
@@ -3647,7 +3677,6 @@ export function createAgentChatAdapter(options) {
|
|
|
3647
3677
|
detail: { ...failure.runError, tabId },
|
|
3648
3678
|
}));
|
|
3649
3679
|
}
|
|
3650
|
-
content.push({ type: "text", text: failure.text });
|
|
3651
3680
|
settleTerminalChatRun();
|
|
3652
3681
|
yield {
|
|
3653
3682
|
content: [...content],
|
|
@@ -3657,7 +3686,7 @@ export function createAgentChatAdapter(options) {
|
|
|
3657
3686
|
},
|
|
3658
3687
|
metadata: { custom: { runError: failure.runError } },
|
|
3659
3688
|
};
|
|
3660
|
-
|
|
3689
|
+
clearOwnedActiveRun();
|
|
3661
3690
|
return;
|
|
3662
3691
|
}
|
|
3663
3692
|
// Connection lost — try to reconnect to the run
|
|
@@ -3716,7 +3745,7 @@ export function createAgentChatAdapter(options) {
|
|
|
3716
3745
|
},
|
|
3717
3746
|
metadata: { custom: { ...(runId ? { runId } : {}), runError } },
|
|
3718
3747
|
};
|
|
3719
|
-
|
|
3748
|
+
clearOwnedActiveRun();
|
|
3720
3749
|
return;
|
|
3721
3750
|
}
|
|
3722
3751
|
// Reconnect failed or not possible — keep going from the partial
|
|
@@ -3745,7 +3774,7 @@ export function createAgentChatAdapter(options) {
|
|
|
3745
3774
|
},
|
|
3746
3775
|
},
|
|
3747
3776
|
};
|
|
3748
|
-
|
|
3777
|
+
clearOwnedActiveRun();
|
|
3749
3778
|
return;
|
|
3750
3779
|
}
|
|
3751
3780
|
const message = exhaustedRecoveryMessage("stream_ended");
|
|
@@ -3780,7 +3809,7 @@ export function createAgentChatAdapter(options) {
|
|
|
3780
3809
|
custom: { ...(runId ? { runId } : {}), runError },
|
|
3781
3810
|
},
|
|
3782
3811
|
};
|
|
3783
|
-
|
|
3812
|
+
clearOwnedActiveRun();
|
|
3784
3813
|
return;
|
|
3785
3814
|
}
|
|
3786
3815
|
if (continuation.resetVisibleContent) {
|
|
@@ -3843,11 +3872,8 @@ export function createAgentChatAdapter(options) {
|
|
|
3843
3872
|
}
|
|
3844
3873
|
}
|
|
3845
3874
|
finally {
|
|
3846
|
-
if (
|
|
3847
|
-
|
|
3848
|
-
window.dispatchEvent(new CustomEvent("agentNative.chatRunning", {
|
|
3849
|
-
detail: { isRunning: false, tabId },
|
|
3850
|
-
}));
|
|
3875
|
+
if (ownsActiveRunState()) {
|
|
3876
|
+
publishTerminalChatUiStopped();
|
|
3851
3877
|
}
|
|
3852
3878
|
}
|
|
3853
3879
|
},
|
|
@@ -143,14 +143,14 @@ function DocumentTitleGuard({ fallbackTitle }) {
|
|
|
143
143
|
}, [fallbackTitle]);
|
|
144
144
|
return null;
|
|
145
145
|
}
|
|
146
|
-
function ProvidersInner({ queryClient, defaultTheme = "system", themeAttribute = "class", tooltipDelayDuration, toaster = DEFAULT_TOASTER, disableThemeTransitions = true, i18n, documentTitleFallback, children, }) {
|
|
146
|
+
function ProvidersInner({ queryClient, defaultTheme = "system", themeAttribute = "class", tooltipDelayDuration, toaster = DEFAULT_TOASTER, disableThemeTransitions = true, i18n, documentTitleFallback, showProductionEnvironmentBadge, children, }) {
|
|
147
147
|
const localizedChildren = i18n === false ? (children) : (_jsx(AgentNativeI18nProvider, { ...(i18n ?? {}), children: children }));
|
|
148
|
-
return (_jsx(QueryClientProvider, { client: queryClient, children: _jsxs(ThemeProvider, { attribute: themeAttribute, defaultTheme: defaultTheme, enableSystem: true, disableTransitionOnChange: disableThemeTransitions, children: [_jsx(EmbeddedThemeSync, {}), _jsxs(TooltipProvider, { delayDuration: tooltipDelayDuration, children: [localizedChildren, _jsx(DocumentTitleGuard, { fallbackTitle: documentTitleFallback }), _jsx(RuntimeConfigNotice, {}), _jsx(RoutedAppEnhancements, {}), toaster] })] }) }));
|
|
148
|
+
return (_jsx(QueryClientProvider, { client: queryClient, children: _jsxs(ThemeProvider, { attribute: themeAttribute, defaultTheme: defaultTheme, enableSystem: true, disableTransitionOnChange: disableThemeTransitions, children: [_jsx(EmbeddedThemeSync, {}), _jsxs(TooltipProvider, { delayDuration: tooltipDelayDuration, children: [localizedChildren, _jsx(DocumentTitleGuard, { fallbackTitle: documentTitleFallback }), _jsx(RuntimeConfigNotice, {}), _jsx(RoutedAppEnhancements, {}), _jsx(EnvironmentBadge, { showProduction: showProductionEnvironmentBadge }), toaster] })] }) }));
|
|
149
149
|
}
|
|
150
150
|
export function AppProviders({ queryClient, isPublicPath = false, clientOnlyFallback, sessionBypass = false, defaultTheme, themeAttribute, tooltipDelayDuration, toaster, disableThemeTransitions, i18n, documentTitleFallback, children, }) {
|
|
151
151
|
const fallback = clientOnlyFallback ?? _jsx(DefaultSpinner, {});
|
|
152
152
|
if (isPublicPath) {
|
|
153
|
-
return (_jsx(ProvidersInner, { queryClient: queryClient, defaultTheme: defaultTheme, themeAttribute: themeAttribute, tooltipDelayDuration: tooltipDelayDuration, toaster: toaster, disableThemeTransitions: disableThemeTransitions, i18n: i18n, documentTitleFallback: documentTitleFallback, children: children }));
|
|
153
|
+
return (_jsx(ProvidersInner, { queryClient: queryClient, defaultTheme: defaultTheme, themeAttribute: themeAttribute, tooltipDelayDuration: tooltipDelayDuration, toaster: toaster, disableThemeTransitions: disableThemeTransitions, i18n: i18n, documentTitleFallback: documentTitleFallback, showProductionEnvironmentBadge: false, children: children }));
|
|
154
154
|
}
|
|
155
|
-
return (_jsx(ClientOnly, { fallback: fallback, children: _jsx(ProvidersInner, { queryClient: queryClient, defaultTheme: defaultTheme, themeAttribute: themeAttribute, tooltipDelayDuration: tooltipDelayDuration, toaster: toaster, disableThemeTransitions: disableThemeTransitions, i18n: i18n, documentTitleFallback: documentTitleFallback, children: _jsx(RequireSession, { bypass: sessionBypass, fallback: fallback, children: sessionBypass ? (children) : (
|
|
155
|
+
return (_jsx(ClientOnly, { fallback: fallback, children: _jsx(ProvidersInner, { queryClient: queryClient, defaultTheme: defaultTheme, themeAttribute: themeAttribute, tooltipDelayDuration: tooltipDelayDuration, toaster: toaster, disableThemeTransitions: disableThemeTransitions, i18n: i18n, documentTitleFallback: documentTitleFallback, showProductionEnvironmentBadge: !sessionBypass, children: _jsx(RequireSession, { bypass: sessionBypass, fallback: fallback, children: sessionBypass ? (children) : (_jsx(FirstRunOnboardingStartupGate, { children: children })) }) }) }));
|
|
156
156
|
}
|
|
@@ -71,6 +71,10 @@ export declare function MessageActionsMenu({ showRevert, onRevert, threadId, }?:
|
|
|
71
71
|
export declare function UserMessage(): React.JSX.Element | null;
|
|
72
72
|
export declare function messageTextFromContent(content: unknown): string;
|
|
73
73
|
export declare function isMissingFinalResponseWarningText(text: string): boolean;
|
|
74
|
+
export declare function isMissingCredentialAssistantMessage(message: {
|
|
75
|
+
content?: unknown;
|
|
76
|
+
metadata?: unknown;
|
|
77
|
+
}): boolean;
|
|
74
78
|
export declare function latestUserMessageText(messages: readonly unknown[]): string;
|
|
75
79
|
export declare function userMessageTextBeforeAssistant(messages: readonly unknown[], assistantMessageId: string): string;
|
|
76
80
|
export declare function assistantMessageHasUnresolvedTool(content: unknown): boolean;
|
|
@@ -539,6 +539,32 @@ function missingFinalResponseWarningText(content) {
|
|
|
539
539
|
}
|
|
540
540
|
return null;
|
|
541
541
|
}
|
|
542
|
+
export function isMissingCredentialAssistantMessage(message) {
|
|
543
|
+
const metadata = message.metadata;
|
|
544
|
+
const runError = metadata?.custom?.runError ?? metadata?.runError;
|
|
545
|
+
const errorCode = typeof runError?.errorCode === "string"
|
|
546
|
+
? runError.errorCode.toLowerCase()
|
|
547
|
+
: "";
|
|
548
|
+
const errorMessage = typeof runError?.message === "string" ? runError.message : "";
|
|
549
|
+
if (/no llm provider(?: key)? (?:is connected|was found)|missing credentials|missing api key|missing_api_key/i.test(errorMessage) ||
|
|
550
|
+
((errorCode === "missing_credentials" || errorCode === "missing_api_key") &&
|
|
551
|
+
!errorMessage &&
|
|
552
|
+
!message.content)) {
|
|
553
|
+
return true;
|
|
554
|
+
}
|
|
555
|
+
const text = Array.isArray(message.content)
|
|
556
|
+
? message.content
|
|
557
|
+
.filter((part) => Boolean(part) &&
|
|
558
|
+
typeof part === "object" &&
|
|
559
|
+
part.type === "text" &&
|
|
560
|
+
typeof part.text === "string")
|
|
561
|
+
.map((part) => part.text)
|
|
562
|
+
.join("\n")
|
|
563
|
+
: typeof message.content === "string"
|
|
564
|
+
? message.content
|
|
565
|
+
: "";
|
|
566
|
+
return /^Error:\s*(?:No LLM provider(?: key)? (?:is connected|was found))/i.test(text.trim());
|
|
567
|
+
}
|
|
542
568
|
export function latestUserMessageText(messages) {
|
|
543
569
|
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
544
570
|
const message = messages[index];
|
|
@@ -847,6 +873,7 @@ export function AssistantMessage() {
|
|
|
847
873
|
const activeTurnId = React.useContext(ChatRunningTurnIdContext);
|
|
848
874
|
const lastRunDurationMs = React.useContext(ChatRunDurationContext);
|
|
849
875
|
const msg = messageRuntime.getState();
|
|
876
|
+
const isMissingCredential = isMissingCredentialAssistantMessage(msg);
|
|
850
877
|
const persistedDurationMs = getAssistantRunDurationMs(msg);
|
|
851
878
|
const timestamp = formatMessageTimestamp(msg.createdAt, locale, t("agentChat.history.yesterday"));
|
|
852
879
|
const isLast = msg.isLast;
|
|
@@ -1052,7 +1079,7 @@ export function AssistantMessage() {
|
|
|
1052
1079
|
chatRunning,
|
|
1053
1080
|
isLast,
|
|
1054
1081
|
});
|
|
1055
|
-
if (!hasRenderableContent)
|
|
1082
|
+
if (!hasRenderableContent || isMissingCredential)
|
|
1056
1083
|
return null;
|
|
1057
1084
|
return (_jsxs("div", { className: "group relative", style: { contentVisibility: isComplete ? "auto" : "visible" }, children: [_jsxs("div", { className: "w-full max-w-[95%] text-sm leading-relaxed text-foreground", children: [isComplete && (_jsx(McpConnectionSuggestion, { text: responseConnectionText, contextText: responseConnectionContext, variant: "response" })), _jsx(ToolCallStackMotion, { children: _jsx(MessagePrimitive.GroupedParts, { groupBy: groupAssistantWorkParts, children: ({ part, children }) => {
|
|
1058
1085
|
switch (part.type) {
|
|
@@ -112,6 +112,14 @@ function isConnectionRecoveryRunError(info) {
|
|
|
112
112
|
message.includes("connection kept failing") ||
|
|
113
113
|
message.includes("automatic recovery attempts"));
|
|
114
114
|
}
|
|
115
|
+
function isMissingLlmProviderRunError(info) {
|
|
116
|
+
const code = (info.errorCode ?? "").toLowerCase();
|
|
117
|
+
const text = [info.message, info.details].filter(Boolean).join("\n");
|
|
118
|
+
const hasCredentialSetupText = /no llm provider(?: key)? (?:is connected|was found)|missing credentials|missing api key|missing_api_key|(?:api[_ -]?key|auth[_ -]?token)\s*(?:(?:is|was)\s+)?(?:not\s+(?:set|configured|available|present|provided|found)|missing|unavailable|empty|unset|unconfigured)/i.test(text);
|
|
119
|
+
return (hasCredentialSetupText ||
|
|
120
|
+
((code === "missing_credentials" || code === "missing_api_key") &&
|
|
121
|
+
!text.trim()));
|
|
122
|
+
}
|
|
115
123
|
// ─── BuilderConnectCta ────────────────────────────────────────────────────────
|
|
116
124
|
// Renders a single row with left-aligned copy and a right-aligned action.
|
|
117
125
|
// Click opens the Builder OAuth popup via the shared
|
|
@@ -194,11 +202,15 @@ export function RunErrorRecoveryCard({ info, onContinue, onRetry, onFork, onDism
|
|
|
194
202
|
const [copyState, setCopyState] = useState("idle");
|
|
195
203
|
const [forking, setForking] = useState(false);
|
|
196
204
|
const [forkError, setForkError] = useState(null);
|
|
205
|
+
const [providerConnected, setProviderConnected] = useState(false);
|
|
206
|
+
const retryRequestedRef = useRef(false);
|
|
207
|
+
const [retryRequested, setRetryRequested] = useState(false);
|
|
197
208
|
const builderReconnect = useBuilderConnectFlow({
|
|
198
209
|
trackingSource: "assistant_chat_reconnect_error",
|
|
199
210
|
});
|
|
200
211
|
const canRecover = info.recoverable === true;
|
|
201
212
|
const shouldShowBuilderReconnect = isBuilderReconnectRunError(info);
|
|
213
|
+
const shouldShowMissingProviderSetup = isMissingLlmProviderRunError(info);
|
|
202
214
|
const isProviderAuthError = isProviderAuthenticationError([info.message, info.details].filter(Boolean).join("\n"), info.errorCode);
|
|
203
215
|
// Blocked on something the reader goes and fixes elsewhere, then comes back
|
|
204
216
|
// to. Without a retry the card is a dead end and its own copy ("then retry")
|
|
@@ -241,6 +253,17 @@ export function RunErrorRecoveryCard({ info, onContinue, onRetry, onFork, onDism
|
|
|
241
253
|
onRetry();
|
|
242
254
|
onDismiss();
|
|
243
255
|
}, [onDismiss, onProviderConnected, onRetry]);
|
|
256
|
+
const handleMissingProviderConnected = useCallback(() => {
|
|
257
|
+
setProviderConnected(true);
|
|
258
|
+
onProviderConnected?.();
|
|
259
|
+
}, [onProviderConnected]);
|
|
260
|
+
const handleMissingProviderRetry = useCallback(() => {
|
|
261
|
+
if (retryRequestedRef.current)
|
|
262
|
+
return;
|
|
263
|
+
retryRequestedRef.current = true;
|
|
264
|
+
setRetryRequested(true);
|
|
265
|
+
onRetry();
|
|
266
|
+
}, [onRetry]);
|
|
244
267
|
const handleFork = useCallback(async () => {
|
|
245
268
|
if (!onFork || forking)
|
|
246
269
|
return;
|
|
@@ -264,6 +287,9 @@ export function RunErrorRecoveryCard({ info, onContinue, onRetry, onFork, onDism
|
|
|
264
287
|
onDismiss();
|
|
265
288
|
}
|
|
266
289
|
}, [builderReconnectResolved, onDismiss]);
|
|
290
|
+
if (shouldShowMissingProviderSetup) {
|
|
291
|
+
return (_jsxs("div", { className: "w-full", children: [_jsx(BuilderSetupCard, { fullWidth: true, layout: "sidebar", onConnected: handleMissingProviderConnected }), providerConnected ? (_jsx("div", { className: "flex justify-center px-3 pt-1", children: _jsxs("button", { type: "button", onClick: handleMissingProviderRetry, disabled: retryRequested, className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90 disabled:cursor-wait disabled:opacity-60", children: [_jsx(IconRefresh, { size: 13 }), t("agentChat.common.retry")] }) })) : null] }));
|
|
292
|
+
}
|
|
267
293
|
return (_jsxs("div", { className: "rounded-lg border border-amber-500/25 bg-amber-500/[0.06] p-3 text-sm", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-amber-500/10 text-amber-700 dark:text-amber-300", children: _jsx(IconAlertTriangle, { size: 14 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "font-medium text-foreground", children: runErrorHeadline(info, {
|
|
268
294
|
recoverable: t("agentChat.error.stopped"),
|
|
269
295
|
terminal: t("agentChat.error.failed"),
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import type { ChatFirstAppRailProps } from "./types.js";
|
|
2
|
+
export declare const CHAT_FIRST_APP_RAIL_SHOW_ALL_STORAGE_KEY = "agent-native:chat-first-app-rail-show-all:v1";
|
|
2
3
|
export declare const ChatFirstAppsRail: import("react").MemoExoticComponent<({ apps, defaultAppIds, activeAppId, loading, error, collapsed, layout: controlledLayout, onLayoutChange, onLayoutError, onRetry, onOpenApp, onRemoveApp, onOpenAllApps, onCreateApp, createAppTrigger, renderIcon, copy, }: ChatFirstAppRailProps) => import("react").JSX.Element>;
|
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ContextMenuTrigger, Skeleton, Tooltip, TooltipContent, TooltipTrigger, } from "@agent-native/toolkit/ui";
|
|
3
3
|
import { IconApps, IconChevronDown, IconChevronUp, IconPin, IconPlus, IconTrash, } from "@tabler/icons-react";
|
|
4
|
-
import { memo, useMemo, useState } from "react";
|
|
4
|
+
import { memo, useEffect, useMemo, useState } from "react";
|
|
5
5
|
import { CHAT_FIRST_DEFAULT_APP_IDS, orderChatFirstAppIds, readChatFirstAppLayout, writeChatFirstAppLayout, } from "../chat-first.js";
|
|
6
6
|
import { cn } from "../utils.js";
|
|
7
7
|
import { defaultChatFirstCopy } from "./copy.js";
|
|
8
|
+
export const CHAT_FIRST_APP_RAIL_SHOW_ALL_STORAGE_KEY = "agent-native:chat-first-app-rail-show-all:v1";
|
|
9
|
+
function readChatFirstAppRailShowAll() {
|
|
10
|
+
if (typeof window === "undefined")
|
|
11
|
+
return false;
|
|
12
|
+
try {
|
|
13
|
+
return (window.localStorage.getItem(CHAT_FIRST_APP_RAIL_SHOW_ALL_STORAGE_KEY) ===
|
|
14
|
+
"true");
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// coercion-ok: localStorage is optional; false keeps the rail usable in-memory.
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function writeChatFirstAppRailShowAll(showAllApps) {
|
|
22
|
+
if (typeof window === "undefined")
|
|
23
|
+
return;
|
|
24
|
+
try {
|
|
25
|
+
window.localStorage.setItem(CHAT_FIRST_APP_RAIL_SHOW_ALL_STORAGE_KEY, String(showAllApps));
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// coercion-ok: localStorage is optional; the in-memory toggle remains usable.
|
|
29
|
+
}
|
|
30
|
+
}
|
|
8
31
|
function ChatFirstRailAppIcon({ app, activeAppId, renderIcon, }) {
|
|
9
32
|
const isActive = activeAppId !== undefined && activeAppId === app.id;
|
|
10
33
|
const isInactive = activeAppId !== undefined && !isActive;
|
|
@@ -45,7 +68,10 @@ export const ChatFirstAppsRail = memo(function ChatFirstAppsRail({ apps, default
|
|
|
45
68
|
const [localLayout, setLocalLayout] = useState(() => readChatFirstAppLayout());
|
|
46
69
|
const layout = controlledLayout ?? localLayout;
|
|
47
70
|
const [draggedAppId, setDraggedAppId] = useState(null);
|
|
48
|
-
const [showAllApps, setShowAllApps] = useState(
|
|
71
|
+
const [showAllApps, setShowAllApps] = useState(() => readChatFirstAppRailShowAll());
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
writeChatFirstAppRailShowAll(showAllApps);
|
|
74
|
+
}, [showAllApps]);
|
|
49
75
|
const orderedApps = useMemo(() => {
|
|
50
76
|
const orderedIds = orderChatFirstAppIds(apps.map((app) => app.id), layout, defaultAppIds);
|
|
51
77
|
const appsById = new Map(apps.map((app) => [app.id, app]));
|
|
@@ -605,6 +605,12 @@ function isMissingCredentialText(message, errorCode) {
|
|
|
605
605
|
msg.includes("no llm provider") ||
|
|
606
606
|
msg.includes("llm provider is connected"));
|
|
607
607
|
}
|
|
608
|
+
function isMissingProviderErrorText(message, errorCode) {
|
|
609
|
+
const code = String(errorCode ?? "").toLowerCase();
|
|
610
|
+
return (code === "missing_api_key" ||
|
|
611
|
+
code === "missing_credentials" ||
|
|
612
|
+
/no llm provider(?: key)? (?:is connected|was found)/i.test(message));
|
|
613
|
+
}
|
|
608
614
|
function dispatchActivityClear(tabId) {
|
|
609
615
|
if (typeof window === "undefined")
|
|
610
616
|
return;
|
|
@@ -1389,10 +1395,6 @@ export function processEvent(ev, content, toolCallCounter, tabId, state) {
|
|
|
1389
1395
|
// the last preparation activity, so do not leave its label mounted.
|
|
1390
1396
|
dispatchActivityClear(tabId);
|
|
1391
1397
|
settleInterruptedToolCalls(content, undefined, { includeActivity: true });
|
|
1392
|
-
content.push({
|
|
1393
|
-
type: "text",
|
|
1394
|
-
text: formatChatErrorText(errMsg, undefined, errorCode),
|
|
1395
|
-
});
|
|
1396
1398
|
return {
|
|
1397
1399
|
action: "missing_api_key",
|
|
1398
1400
|
result: {
|
|
@@ -1472,6 +1474,7 @@ export function processEvent(ev, content, toolCallCounter, tabId, state) {
|
|
|
1472
1474
|
};
|
|
1473
1475
|
}
|
|
1474
1476
|
const normalized = normalizeChatError(errMsg, ev.errorCode);
|
|
1477
|
+
const missingProviderError = isMissingProviderErrorText(errMsg, ev.errorCode);
|
|
1475
1478
|
if (isMissingCredentialText(errMsg, ev.errorCode)) {
|
|
1476
1479
|
dispatchMissingApiKey(tabId);
|
|
1477
1480
|
}
|
|
@@ -1492,10 +1495,12 @@ export function processEvent(ev, content, toolCallCounter, tabId, state) {
|
|
|
1492
1495
|
}));
|
|
1493
1496
|
}
|
|
1494
1497
|
settleInterruptedToolCalls(content, undefined, { includeActivity: true });
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1498
|
+
if (!missingProviderError) {
|
|
1499
|
+
content.push({
|
|
1500
|
+
type: "text",
|
|
1501
|
+
text: formatChatErrorText(errMsg, ev.upgradeUrl, ev.errorCode),
|
|
1502
|
+
});
|
|
1503
|
+
}
|
|
1499
1504
|
return {
|
|
1500
1505
|
action: "error",
|
|
1501
1506
|
result: {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { ACTIVE_RUN_STATE_EVENT, getActiveRun, } from "./active-run-state.js";
|
|
3
|
+
/** Return the focused run for a thread and keep it current as the stream moves. */
|
|
4
|
+
export function useActiveAgentChatRunId(threadId) {
|
|
5
|
+
const [activeRun, setActiveRun] = useState(() => getActiveRun());
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const syncFromStorage = () => setActiveRun(getActiveRun());
|
|
8
|
+
const handleActiveRunChange = (event) => {
|
|
9
|
+
const state = event
|
|
10
|
+
.detail?.state;
|
|
11
|
+
setActiveRun(state ?? null);
|
|
12
|
+
};
|
|
13
|
+
syncFromStorage();
|
|
14
|
+
window.addEventListener(ACTIVE_RUN_STATE_EVENT, handleActiveRunChange);
|
|
15
|
+
window.addEventListener("storage", syncFromStorage);
|
|
16
|
+
return () => {
|
|
17
|
+
window.removeEventListener(ACTIVE_RUN_STATE_EVENT, handleActiveRunChange);
|
|
18
|
+
window.removeEventListener("storage", syncFromStorage);
|
|
19
|
+
};
|
|
20
|
+
}, []);
|
|
21
|
+
return activeRun && activeRun.threadId === threadId ? activeRun.runId : null;
|
|
22
|
+
}
|