@agent-native/core 0.132.2 → 0.133.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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +161 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/correlation.ts +11 -1
- package/corpus/core/src/a2a/types.ts +11 -3
- package/corpus/core/src/agent/engine/ai-sdk-engine.ts +33 -46
- package/corpus/core/src/agent/engine/builder-engine.ts +22 -10
- package/corpus/core/src/agent/engine/error-detail.ts +184 -3
- package/corpus/core/src/agent/engine/failure-taxonomy.ts +123 -0
- package/corpus/core/src/agent/engine/index.ts +8 -0
- package/corpus/core/src/agent/engine/registry.ts +92 -8
- package/corpus/core/src/agent/engine/translate-ai-sdk.ts +17 -2
- package/corpus/core/src/agent/production-agent.ts +13 -33
- package/corpus/core/src/agent/run-loop-with-resume.ts +1 -1
- package/corpus/core/src/agent/run-manager.ts +43 -14
- package/corpus/core/src/agent/run-store.ts +30 -3
- package/corpus/core/src/agent/thread-data-builder.ts +36 -4
- package/corpus/core/src/cli/templates-meta.ts +13 -0
- package/corpus/core/src/cli/workspace-dev.ts +1 -0
- package/corpus/core/src/client/error-format.ts +12 -0
- package/corpus/core/src/credentials/index.ts +51 -12
- package/corpus/core/src/extensions/url-safety.ts +46 -12
- package/corpus/core/src/integrations/adapters/slack.ts +32 -10
- package/corpus/core/src/integrations/google-docs-poller.ts +12 -1
- package/corpus/core/src/integrations/installations-store.ts +30 -0
- package/corpus/core/src/integrations/plugin.ts +5 -5
- package/corpus/core/src/integrations/types.ts +7 -0
- package/corpus/core/src/integrations/webhook-handler.ts +24 -1
- package/corpus/core/src/jobs/background-automation-runner.ts +38 -1
- package/corpus/core/src/provider-api/index.ts +8 -2
- package/corpus/core/src/scripts/call-agent.ts +6 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +30 -9
- package/corpus/core/src/server/agent-discovery.ts +2 -0
- package/corpus/core/src/server/builder-design-systems.ts +21 -0
- package/corpus/core/src/server/credential-provider.ts +51 -12
- package/corpus/core/src/server/index.ts +1 -0
- package/corpus/core/src/server/onboarding-html.ts +37 -2
- package/corpus/core/src/shared/reasoning-effort.ts +1 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +11 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +6 -2
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +39 -19
- package/corpus/templates/assets/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
- package/corpus/templates/brain/app/components/layout/Sidebar.tsx +30 -3
- package/corpus/templates/brain/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +1 -1
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +54 -25
- package/corpus/templates/calendar/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +30 -3
- package/corpus/templates/chat/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/corpus/templates/clips/app/components/library/library-layout.tsx +37 -21
- package/corpus/templates/clips/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
- package/corpus/templates/clips/desktop/src/hooks/useMediaDevices.ts +1 -1
- package/corpus/templates/clips/desktop/src/lib/media-capture-constraints.ts +1 -1
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +34 -17
- package/corpus/templates/content/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +6 -2
- package/corpus/templates/design/actions/create-design-system.ts +1 -0
- package/corpus/templates/design/actions/set-default-design-system.ts +34 -26
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +21 -4
- package/corpus/templates/design/app/i18n-data.ts +39 -0
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +229 -12
- package/corpus/templates/design/app/pages/DesignSystems.tsx +10 -4
- package/corpus/templates/design/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/corpus/templates/design/changelog/2026-07-31-design-system-indexing-keeps-your-chosen-name-when-you-uploa.md +6 -0
- package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +19 -4
- package/corpus/templates/dispatch/AGENTS.md +4 -0
- package/corpus/templates/factory/.agents/skills/actions/SKILL.md +562 -0
- package/corpus/templates/factory/.agents/skills/adding-a-feature/SKILL.md +198 -0
- package/corpus/templates/factory/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +182 -0
- package/corpus/templates/factory/.agents/skills/capture-learnings/SKILL.md +89 -0
- package/corpus/templates/factory/.agents/skills/create-skill/SKILL.md +221 -0
- package/corpus/templates/factory/.agents/skills/customizing-agent-native/SKILL.md +220 -0
- package/corpus/templates/factory/.agents/skills/delegate-to-agent/SKILL.md +263 -0
- package/corpus/templates/factory/.agents/skills/factory-graphs/SKILL.md +52 -0
- package/corpus/templates/factory/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +174 -0
- package/corpus/templates/factory/.agents/skills/real-time-sync/SKILL.md +232 -0
- package/corpus/templates/factory/.agents/skills/security/SKILL.md +324 -0
- package/corpus/templates/factory/.agents/skills/self-modifying-code/SKILL.md +119 -0
- package/corpus/templates/factory/.agents/skills/shadcn-ui/SKILL.md +123 -0
- package/corpus/templates/factory/.agents/skills/sharing/SKILL.md +232 -0
- package/corpus/templates/factory/.agents/skills/storing-data/SKILL.md +178 -0
- package/corpus/templates/factory/.agents/skills/upgrade-agent-native/SKILL.md +122 -0
- package/corpus/templates/factory/.env.example +24 -0
- package/corpus/templates/factory/.ignore +0 -0
- package/corpus/templates/factory/.oxfmtrc.json +8 -0
- package/corpus/templates/factory/AGENTS.md +90 -0
- package/corpus/templates/factory/CHANGELOG.md +10 -0
- package/corpus/templates/factory/DEVELOPING.md +185 -0
- package/corpus/templates/factory/README.md +64 -0
- package/corpus/templates/factory/_gitignore +42 -0
- package/corpus/templates/factory/actions/add-factory-comment.ts +55 -0
- package/corpus/templates/factory/actions/approve-factory-item.ts +214 -0
- package/corpus/templates/factory/actions/babysit-pull-request.ts +126 -0
- package/corpus/templates/factory/actions/evaluate-triage-item.ts +172 -0
- package/corpus/templates/factory/actions/get-factory-graph.ts +62 -0
- package/corpus/templates/factory/actions/get-triage-config.ts +42 -0
- package/corpus/templates/factory/actions/get-triage-item.ts +74 -0
- package/corpus/templates/factory/actions/hello.ts +13 -0
- package/corpus/templates/factory/actions/ingest-github-observation.ts +100 -0
- package/corpus/templates/factory/actions/list-factories.ts +40 -0
- package/corpus/templates/factory/actions/list-factory-comments.ts +40 -0
- package/corpus/templates/factory/actions/list-triage-items.ts +85 -0
- package/corpus/templates/factory/actions/list-triage-rules.ts +44 -0
- package/corpus/templates/factory/actions/navigate.ts +41 -0
- package/corpus/templates/factory/actions/poll-slack-channel.ts +118 -0
- package/corpus/templates/factory/actions/reconcile-triage-run.ts +179 -0
- package/corpus/templates/factory/actions/record-triage-feedback.ts +58 -0
- package/corpus/templates/factory/actions/run.ts +2 -0
- package/corpus/templates/factory/actions/save-factory-graph.ts +129 -0
- package/corpus/templates/factory/actions/save-triage-config.ts +67 -0
- package/corpus/templates/factory/actions/save-triage-rule.ts +89 -0
- package/corpus/templates/factory/actions/suggest-factory-rules.ts +70 -0
- package/corpus/templates/factory/actions/view-screen.ts +73 -0
- package/corpus/templates/factory/app/components/factory/FactoryCanvas.tsx +441 -0
- package/corpus/templates/factory/app/components/factory/FactoryInspector.tsx +388 -0
- package/corpus/templates/factory/app/components/layout/Header.tsx +60 -0
- package/corpus/templates/factory/app/components/layout/Layout.tsx +190 -0
- package/corpus/templates/factory/app/components/layout/Sidebar.tsx +538 -0
- package/corpus/templates/factory/app/components/triage/triage-status-pill.tsx +28 -0
- package/corpus/templates/factory/app/components/ui/button.tsx +1 -0
- package/corpus/templates/factory/app/components/ui/card.tsx +1 -0
- package/corpus/templates/factory/app/components/ui/dropdown-menu.tsx +1 -0
- package/corpus/templates/factory/app/components/ui/input.tsx +1 -0
- package/corpus/templates/factory/app/components/ui/label.tsx +1 -0
- package/corpus/templates/factory/app/components/ui/sheet.tsx +1 -0
- package/corpus/templates/factory/app/components/ui/textarea.tsx +1 -0
- package/corpus/templates/factory/app/components/ui/toolkit-provider.tsx +17 -0
- package/corpus/templates/factory/app/components/ui/tooltip.tsx +1 -0
- package/corpus/templates/factory/app/design-system.ts +3 -0
- package/corpus/templates/factory/app/entry.client.tsx +22 -0
- package/corpus/templates/factory/app/entry.server.tsx +10 -0
- package/corpus/templates/factory/app/global.css +93 -0
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +113 -0
- package/corpus/templates/factory/app/i18n/en-US.ts +211 -0
- package/corpus/templates/factory/app/i18n/index.ts +34 -0
- package/corpus/templates/factory/app/i18n-data.ts +556 -0
- package/corpus/templates/factory/app/lib/agent-page.tsx +49 -0
- package/corpus/templates/factory/app/lib/app-config.ts +11 -0
- package/corpus/templates/factory/app/lib/tab-id.ts +1 -0
- package/corpus/templates/factory/app/lib/utils.ts +1 -0
- package/corpus/templates/factory/app/root.tsx +175 -0
- package/corpus/templates/factory/app/routes/_index.tsx +94 -0
- package/corpus/templates/factory/app/routes/agent.tsx +24 -0
- package/corpus/templates/factory/app/routes/chat.$threadId.tsx +1 -0
- package/corpus/templates/factory/app/routes/database.tsx +17 -0
- package/corpus/templates/factory/app/routes/extensions.$id.$slug.tsx +2 -0
- package/corpus/templates/factory/app/routes/extensions.$id.tsx +11 -0
- package/corpus/templates/factory/app/routes/extensions._index.tsx +11 -0
- package/corpus/templates/factory/app/routes/extensions.tsx +5 -0
- package/corpus/templates/factory/app/routes/factory.tsx +1003 -0
- package/corpus/templates/factory/app/routes/observability.tsx +19 -0
- package/corpus/templates/factory/app/routes/settings.tsx +89 -0
- package/corpus/templates/factory/app/routes/team.tsx +11 -0
- package/corpus/templates/factory/app/routes.ts +4 -0
- package/corpus/templates/factory/app/vite-env.d.ts +6 -0
- package/corpus/templates/factory/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
- package/corpus/templates/factory/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/factory/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/factory/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/factory/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/factory/changelog/2026-07-10-chat-now-makes-ai-connection-setup-clear-without-shifting-th.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-14-chat-opens-reliably-on-hosted-deployments-instead-of-failing.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-15-chat-navigation-focuses-on-chat-and-agent.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-29-sidebar-footers-now-keep-feedback-search-and-collapse-togeth.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-31-added-an-inspectable-observe-only-factory-queue-for-slack-.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/corpus/templates/factory/components.json +20 -0
- package/corpus/templates/factory/data/sync-config.json +1 -0
- package/corpus/templates/factory/learnings.defaults.md +5 -0
- package/corpus/templates/factory/netlify.toml +10 -0
- package/corpus/templates/factory/package.json +105 -0
- package/corpus/templates/factory/public/agent-native-icon-dark.svg +10 -0
- package/corpus/templates/factory/public/agent-native-icon-light.svg +10 -0
- package/corpus/templates/factory/public/agent-native-logo-dark.svg +21 -0
- package/corpus/templates/factory/public/agent-native-logo-light.svg +21 -0
- package/corpus/templates/factory/public/favicon.svg +1 -0
- package/corpus/templates/factory/public/icon-180.svg +1 -0
- package/corpus/templates/factory/public/icon-192.svg +1 -0
- package/corpus/templates/factory/public/icon-512.svg +1 -0
- package/corpus/templates/factory/public/manifest.json +21 -0
- package/corpus/templates/factory/react-router.config.ts +7 -0
- package/corpus/templates/factory/server/connectors/credentials.ts +129 -0
- package/corpus/templates/factory/server/connectors/slack.ts +129 -0
- package/corpus/templates/factory/server/db/index.ts +6 -0
- package/corpus/templates/factory/server/db/schema.ts +193 -0
- package/corpus/templates/factory/server/factory-graph/contracts.ts +212 -0
- package/corpus/templates/factory/server/factory-graph/store.ts +121 -0
- package/corpus/templates/factory/server/lib/require-workspace-member.ts +55 -0
- package/corpus/templates/factory/server/middleware/auth.ts +15 -0
- package/corpus/templates/factory/server/plugins/agent-chat.ts +58 -0
- package/corpus/templates/factory/server/plugins/auth.ts +14 -0
- package/corpus/templates/factory/server/plugins/factory-migrations.ts +247 -0
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +116 -0
- package/corpus/templates/factory/server/plugins/integrations.ts +46 -0
- package/corpus/templates/factory/server/routes/[...page].get.ts +5 -0
- package/corpus/templates/factory/server/routes/_agent-native/factory/builder-callback.post.ts +116 -0
- package/corpus/templates/factory/server/triage/ai-services-git.ts +197 -0
- package/corpus/templates/factory/server/triage/builder-executor.ts +118 -0
- package/corpus/templates/factory/server/triage/contracts.ts +164 -0
- package/corpus/templates/factory/server/triage/github-ingestion.ts +35 -0
- package/corpus/templates/factory/server/triage/guards.ts +121 -0
- package/corpus/templates/factory/server/triage/ids.ts +27 -0
- package/corpus/templates/factory/server/triage/pr-babysit.ts +100 -0
- package/corpus/templates/factory/server/triage/pr-monitor.ts +220 -0
- package/corpus/templates/factory/server/triage/slack-client.ts +55 -0
- package/corpus/templates/factory/server/triage/slack-poller.ts +152 -0
- package/corpus/templates/factory/ssr-entry.ts +15 -0
- package/corpus/templates/factory/tsconfig.json +21 -0
- package/corpus/templates/factory/vite.config.ts +19 -0
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +55 -5
- package/corpus/templates/forms/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +6 -2
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +21 -6
- package/corpus/templates/plan/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +12 -0
- package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +9 -0
- package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +11 -0
- package/corpus/templates/slides/AGENTS.md +5 -6
- package/corpus/templates/slides/actions/_await-fit-check.ts +20 -10
- package/corpus/templates/slides/actions/add-slide.ts +17 -4
- package/corpus/templates/slides/actions/create-design-system.ts +16 -4
- package/corpus/templates/slides/actions/delete-design-system.ts +18 -2
- package/corpus/templates/slides/actions/get-layout-overflows.ts +88 -0
- package/corpus/templates/slides/actions/import-file.ts +1 -0
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +8 -0
- package/corpus/templates/slides/actions/patch-deck.ts +48 -16
- package/corpus/templates/slides/actions/set-default-design-system.ts +49 -19
- package/corpus/templates/slides/actions/update-slide.ts +13 -3
- package/corpus/templates/slides/actions/view-screen.ts +87 -10
- package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +155 -28
- package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +21 -17
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +849 -341
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +102 -2
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +13 -16
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +60 -12
- package/corpus/templates/slides/app/components/editor/SlideOverflowWarning.tsx +11 -1
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +66 -19
- package/corpus/templates/slides/app/i18n/en-US.ts +23 -0
- package/corpus/templates/slides/app/lib/normalize-slide-padding.ts +8 -15
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +4 -3
- package/corpus/templates/slides/app/pages/DesignSystems.tsx +4 -3
- package/corpus/templates/slides/app/pages/Index.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-07-31-design-system-details-now-show-their-source-and-indexing-sta.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-31-design-system-indexing-keeps-your-chosen-name-when-you-uploa.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-31-design-system-setup-keeps-focus-rings-visible-and-uses-a-sim.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-31-skip-prompt-is-now-available-in-the-new-deck-prompt-header.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-31-slides-now-detect-real-text-and-box-overflow-across-the-deck.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
- package/corpus/templates/slides/server/handlers/design-systems.ts +1 -0
- package/corpus/templates/slides/server/handlers/index-design-system-sources.ts +1 -0
- package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +23 -4
- package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -0
- package/corpus/templates/slides/server/plugins/creative-context.ts +16 -3
- package/corpus/templates/slides/server/workspace-defaults.ts +5 -1
- package/corpus/templates/slides/shared/slide-fit.ts +26 -0
- package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +30 -3
- package/corpus/templates/tasks/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/dist/a2a/correlation.d.ts +4 -1
- package/dist/a2a/correlation.d.ts.map +1 -1
- package/dist/a2a/correlation.js +8 -1
- package/dist/a2a/correlation.js.map +1 -1
- package/dist/a2a/types.d.ts +11 -3
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +27 -41
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +18 -8
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/engine/error-detail.d.ts +61 -0
- package/dist/agent/engine/error-detail.d.ts.map +1 -1
- package/dist/agent/engine/error-detail.js +145 -3
- package/dist/agent/engine/error-detail.js.map +1 -1
- package/dist/agent/engine/failure-taxonomy.d.ts +24 -0
- package/dist/agent/engine/failure-taxonomy.d.ts.map +1 -0
- package/dist/agent/engine/failure-taxonomy.js +88 -0
- package/dist/agent/engine/failure-taxonomy.js.map +1 -0
- package/dist/agent/engine/index.d.ts +2 -1
- package/dist/agent/engine/index.d.ts.map +1 -1
- package/dist/agent/engine/index.js +2 -1
- package/dist/agent/engine/index.js.map +1 -1
- package/dist/agent/engine/registry.d.ts +16 -0
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +71 -6
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/engine/translate-ai-sdk.d.ts.map +1 -1
- package/dist/agent/engine/translate-ai-sdk.js +14 -2
- package/dist/agent/engine/translate-ai-sdk.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +13 -24
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-loop-with-resume.js +1 -1
- package/dist/agent/run-loop-with-resume.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +39 -10
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +10 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +20 -3
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +28 -4
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +13 -0
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/cli/workspace-dev.d.ts.map +1 -1
- package/dist/cli/workspace-dev.js +1 -0
- package/dist/cli/workspace-dev.js.map +1 -1
- package/dist/client/error-format.d.ts.map +1 -1
- package/dist/client/error-format.js +10 -0
- package/dist/client/error-format.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/credentials/index.d.ts +9 -2
- package/dist/credentials/index.d.ts.map +1 -1
- package/dist/credentials/index.js +50 -8
- package/dist/credentials/index.js.map +1 -1
- package/dist/extensions/url-safety.d.ts.map +1 -1
- package/dist/extensions/url-safety.js +38 -12
- package/dist/extensions/url-safety.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +25 -8
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/google-docs-poller.d.ts.map +1 -1
- package/dist/integrations/google-docs-poller.js +13 -1
- package/dist/integrations/google-docs-poller.js.map +1 -1
- package/dist/integrations/installations-store.d.ts +10 -0
- package/dist/integrations/installations-store.d.ts.map +1 -1
- package/dist/integrations/installations-store.js +24 -0
- package/dist/integrations/installations-store.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +6 -5
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/types.d.ts +7 -0
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/types.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +16 -1
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/jobs/background-automation-runner.d.ts.map +1 -1
- package/dist/jobs/background-automation-runner.js +35 -2
- package/dist/jobs/background-automation-runner.js.map +1 -1
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/mcp/screen-memory-stdio.d.ts.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +3 -3
- package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/provider-api/index.js +7 -3
- package/dist/provider-api/index.js.map +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +6 -1
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +25 -7
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts +2 -0
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/builder-design-systems.d.ts +4 -1
- package/dist/server/builder-design-systems.d.ts.map +1 -1
- package/dist/server/builder-design-systems.js +11 -1
- package/dist/server/builder-design-systems.js.map +1 -1
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +49 -12
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +37 -2
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/shared/reasoning-effort.d.ts +1 -0
- package/dist/shared/reasoning-effort.d.ts.map +1 -1
- package/dist/shared/reasoning-effort.js +1 -1
- package/dist/shared/reasoning-effort.js.map +1 -1
- package/dist/templates/chat/app/components/layout/Sidebar.tsx +30 -3
- package/dist/templates/chat/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +11 -0
- package/package.json +1 -1
- package/src/a2a/correlation.ts +11 -1
- package/src/a2a/types.ts +11 -3
- package/src/agent/engine/ai-sdk-engine.ts +33 -46
- package/src/agent/engine/builder-engine.ts +22 -10
- package/src/agent/engine/error-detail.ts +184 -3
- package/src/agent/engine/failure-taxonomy.ts +123 -0
- package/src/agent/engine/index.ts +8 -0
- package/src/agent/engine/registry.ts +92 -8
- package/src/agent/engine/translate-ai-sdk.ts +17 -2
- package/src/agent/production-agent.ts +13 -33
- package/src/agent/run-loop-with-resume.ts +1 -1
- package/src/agent/run-manager.ts +43 -14
- package/src/agent/run-store.ts +30 -3
- package/src/agent/thread-data-builder.ts +36 -4
- package/src/cli/templates-meta.ts +13 -0
- package/src/cli/workspace-dev.ts +1 -0
- package/src/client/error-format.ts +12 -0
- package/src/credentials/index.ts +51 -12
- package/src/extensions/url-safety.ts +46 -12
- package/src/integrations/adapters/slack.ts +32 -10
- package/src/integrations/google-docs-poller.ts +12 -1
- package/src/integrations/installations-store.ts +30 -0
- package/src/integrations/plugin.ts +5 -5
- package/src/integrations/types.ts +7 -0
- package/src/integrations/webhook-handler.ts +24 -1
- package/src/jobs/background-automation-runner.ts +38 -1
- package/src/provider-api/index.ts +8 -2
- package/src/scripts/call-agent.ts +6 -0
- package/src/server/agent-chat-plugin.ts +30 -9
- package/src/server/agent-discovery.ts +2 -0
- package/src/server/builder-design-systems.ts +21 -0
- package/src/server/credential-provider.ts +51 -12
- package/src/server/index.ts +1 -0
- package/src/server/onboarding-html.ts +37 -2
- package/src/shared/reasoning-effort.ts +1 -1
- package/src/templates/chat/app/components/layout/Sidebar.tsx +30 -3
- package/src/templates/chat/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +11 -0
- package/corpus/templates/clips/desktop/src/lib/media-device-selection.ts +0 -157
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { classifyTerminalErrorCode } from "./error-detail.js";
|
|
2
|
+
|
|
3
|
+
export const AGENT_FAILURE_TAXONOMY_CODES = [
|
|
4
|
+
"provider_network_error",
|
|
5
|
+
"provider_config_error",
|
|
6
|
+
"overloaded_error",
|
|
7
|
+
"authentication_error",
|
|
8
|
+
"unknown",
|
|
9
|
+
] as const;
|
|
10
|
+
|
|
11
|
+
export type AgentFailureTaxonomyCode =
|
|
12
|
+
(typeof AGENT_FAILURE_TAXONOMY_CODES)[number];
|
|
13
|
+
|
|
14
|
+
export type AgentFailureRegime = "interactive" | "scheduled";
|
|
15
|
+
|
|
16
|
+
export interface AgentFailureTaxonomy {
|
|
17
|
+
code: AgentFailureTaxonomyCode;
|
|
18
|
+
label: string;
|
|
19
|
+
regime: AgentFailureRegime;
|
|
20
|
+
source: "error_code" | "error_detail" | "unknown";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const LABELS: Record<AgentFailureTaxonomyCode, string> = {
|
|
24
|
+
provider_network_error: "SSL/TLS provider transport drop",
|
|
25
|
+
provider_config_error: "Model reasoning_effort with tools",
|
|
26
|
+
overloaded_error: "Provider overloaded_error",
|
|
27
|
+
authentication_error: "Missing provider authentication",
|
|
28
|
+
unknown: "Unclassified failure",
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
function knownCode(value: unknown): AgentFailureTaxonomyCode | undefined {
|
|
32
|
+
const normalized =
|
|
33
|
+
typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
34
|
+
if (
|
|
35
|
+
normalized === "provider_network_error" ||
|
|
36
|
+
normalized === "connection_error" ||
|
|
37
|
+
normalized === "network_error" ||
|
|
38
|
+
normalized === "ssl_error" ||
|
|
39
|
+
normalized === "tls_error"
|
|
40
|
+
) {
|
|
41
|
+
return "provider_network_error";
|
|
42
|
+
}
|
|
43
|
+
if (
|
|
44
|
+
normalized === "provider_config_error" ||
|
|
45
|
+
normalized === "reasoning_effort_tools"
|
|
46
|
+
) {
|
|
47
|
+
return "provider_config_error";
|
|
48
|
+
}
|
|
49
|
+
if (
|
|
50
|
+
normalized === "overloaded_error" ||
|
|
51
|
+
normalized === "provider_overloaded"
|
|
52
|
+
) {
|
|
53
|
+
return "overloaded_error";
|
|
54
|
+
}
|
|
55
|
+
if (
|
|
56
|
+
normalized === "authentication_error" ||
|
|
57
|
+
normalized === "missing_authentication_header" ||
|
|
58
|
+
normalized === "http_401" ||
|
|
59
|
+
normalized === "unauthorized"
|
|
60
|
+
) {
|
|
61
|
+
return "authentication_error";
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Classify the production failure families used by the Factory triage queue.
|
|
68
|
+
* The regime is deliberately derived from the durable run id, not inferred
|
|
69
|
+
* from prose: scheduled runs use the `job-` namespace and interactive runs do
|
|
70
|
+
* not. This keeps a healthy chat sample from hiding a scheduled outage.
|
|
71
|
+
*/
|
|
72
|
+
export function classifyAgentFailure(input: {
|
|
73
|
+
runId?: unknown;
|
|
74
|
+
errorCode?: unknown;
|
|
75
|
+
errorDetail?: unknown;
|
|
76
|
+
terminalReason?: unknown;
|
|
77
|
+
terminalEvent?: unknown;
|
|
78
|
+
regime?: AgentFailureRegime;
|
|
79
|
+
}): AgentFailureTaxonomy {
|
|
80
|
+
const regime =
|
|
81
|
+
input.regime ??
|
|
82
|
+
(typeof input.runId === "string" && input.runId.startsWith("job-")
|
|
83
|
+
? "scheduled"
|
|
84
|
+
: "interactive");
|
|
85
|
+
const explicit = knownCode(input.errorCode);
|
|
86
|
+
if (explicit) {
|
|
87
|
+
return {
|
|
88
|
+
code: explicit,
|
|
89
|
+
label: LABELS[explicit],
|
|
90
|
+
regime,
|
|
91
|
+
source: "error_code",
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const evidence = [
|
|
96
|
+
input.errorCode,
|
|
97
|
+
input.errorDetail,
|
|
98
|
+
input.terminalReason,
|
|
99
|
+
input.terminalEvent,
|
|
100
|
+
].filter((value) => value !== undefined && value !== null);
|
|
101
|
+
for (const value of evidence) {
|
|
102
|
+
const text =
|
|
103
|
+
typeof value === "string"
|
|
104
|
+
? value
|
|
105
|
+
: (JSON.stringify(value) ?? String(value));
|
|
106
|
+
const classified = knownCode(classifyTerminalErrorCode(text));
|
|
107
|
+
if (classified) {
|
|
108
|
+
return {
|
|
109
|
+
code: classified,
|
|
110
|
+
label: LABELS[classified],
|
|
111
|
+
regime,
|
|
112
|
+
source: "error_detail",
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
code: "unknown",
|
|
119
|
+
label: LABELS.unknown,
|
|
120
|
+
regime,
|
|
121
|
+
source: "unknown",
|
|
122
|
+
};
|
|
123
|
+
}
|
|
@@ -25,6 +25,7 @@ export {
|
|
|
25
25
|
getConfiguredEngineNameForRequest,
|
|
26
26
|
getStoredModelForEngine,
|
|
27
27
|
normalizeModelForEngine,
|
|
28
|
+
resolveDelegatedRunModel,
|
|
28
29
|
resolveEnginePreservesCustomModels,
|
|
29
30
|
type NormalizeModelOptions,
|
|
30
31
|
detectEngineFromEnv,
|
|
@@ -54,3 +55,10 @@ export {
|
|
|
54
55
|
} from "./anthropic-engine.js";
|
|
55
56
|
export { createAISDKEngine, type AISDKProvider } from "./ai-sdk-engine.js";
|
|
56
57
|
export { registerBuiltinEngines } from "./builtin.js";
|
|
58
|
+
export {
|
|
59
|
+
AGENT_FAILURE_TAXONOMY_CODES,
|
|
60
|
+
classifyAgentFailure,
|
|
61
|
+
type AgentFailureRegime,
|
|
62
|
+
type AgentFailureTaxonomy,
|
|
63
|
+
type AgentFailureTaxonomyCode,
|
|
64
|
+
} from "./failure-taxonomy.js";
|
|
@@ -13,6 +13,7 @@ import { createRequire } from "node:module";
|
|
|
13
13
|
import {
|
|
14
14
|
assertCredentialStoreReadable,
|
|
15
15
|
canUseDeployCredentialFallbackForRequest,
|
|
16
|
+
getBuilderCredentialAuthFailure,
|
|
16
17
|
getProviderCredentialAuthFailure,
|
|
17
18
|
readDeployCredentialEnv,
|
|
18
19
|
resolveBuilderCredentialsDetailed,
|
|
@@ -272,6 +273,70 @@ export function normalizeModelForEngine(
|
|
|
272
273
|
);
|
|
273
274
|
}
|
|
274
275
|
|
|
276
|
+
type ModelResolvableEngine = Pick<
|
|
277
|
+
AgentEngine,
|
|
278
|
+
"name" | "defaultModel" | "supportedModels" | "preserveCustomModels"
|
|
279
|
+
>;
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Bound an untrusted, caller-supplied model preference to this engine's own
|
|
283
|
+
* catalog. Returns `undefined` — never a substitute — when the hint names
|
|
284
|
+
* anything the engine does not already offer, so a peer can never move the run
|
|
285
|
+
* to a different provider, an unknown id, or a capability tier this engine was
|
|
286
|
+
* not going to serve on its own.
|
|
287
|
+
*/
|
|
288
|
+
function resolveModelHintForEngine(
|
|
289
|
+
engine: ModelResolvableEngine,
|
|
290
|
+
hint: string | null | undefined,
|
|
291
|
+
): string | undefined {
|
|
292
|
+
const candidate = typeof hint === "string" ? hint.trim() : "";
|
|
293
|
+
if (!candidate || candidate === "auto") return undefined;
|
|
294
|
+
// An engine with no catalog, or one that passes custom ids through verbatim
|
|
295
|
+
// (an OpenAI-compatible gateway), cannot prove membership — so it takes no
|
|
296
|
+
// hint at all rather than forwarding an unverifiable id to a provider.
|
|
297
|
+
if (engine.preserveCustomModels || engine.supportedModels.length === 0) {
|
|
298
|
+
return undefined;
|
|
299
|
+
}
|
|
300
|
+
const normalized = normalizeModelForEngine(engine, candidate);
|
|
301
|
+
// `normalizeModelForEngine` answers `defaultModel` both for "this IS the
|
|
302
|
+
// default" and for "no idea what this is", so an unmatched hint is only
|
|
303
|
+
// distinguishable by re-checking the raw candidate. Anything else it returns
|
|
304
|
+
// is a real catalog hit.
|
|
305
|
+
const matched =
|
|
306
|
+
normalized === engine.defaultModel
|
|
307
|
+
? engine.supportedModels.includes(candidate)
|
|
308
|
+
: engine.supportedModels.includes(normalized);
|
|
309
|
+
return matched ? normalized : undefined;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Model for a delegated (A2A) run, in strict precedence: the receiving app's
|
|
314
|
+
* explicit configuration, then its own stored setting, then the caller's hint,
|
|
315
|
+
* then the engine default. An app that pins a model keeps it; a hint only fills
|
|
316
|
+
* the gap where the receiver would otherwise take a default it never chose.
|
|
317
|
+
*
|
|
318
|
+
* A rejected hint is logged and dropped — a delegated run must never fail over
|
|
319
|
+
* a preference.
|
|
320
|
+
*/
|
|
321
|
+
export function resolveDelegatedRunModel(
|
|
322
|
+
engine: ModelResolvableEngine,
|
|
323
|
+
options: {
|
|
324
|
+
explicitModel?: string | null;
|
|
325
|
+
storedModel?: string | null;
|
|
326
|
+
callerModelHint?: string | null;
|
|
327
|
+
},
|
|
328
|
+
): string {
|
|
329
|
+
const own = options.explicitModel ?? options.storedModel;
|
|
330
|
+
if (own) return normalizeModelForEngine(engine, own);
|
|
331
|
+
const hinted = resolveModelHintForEngine(engine, options.callerModelHint);
|
|
332
|
+
if (!hinted && options.callerModelHint) {
|
|
333
|
+
console.log(
|
|
334
|
+
`[a2a] Ignoring caller model hint "${options.callerModelHint}" — not offered by engine ${engine.name}`,
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
return normalizeModelForEngine(engine, hinted ?? engine.defaultModel);
|
|
338
|
+
}
|
|
339
|
+
|
|
275
340
|
/**
|
|
276
341
|
* Whether models saved or read for this engine ENTRY should be preserved
|
|
277
342
|
* verbatim instead of normalized against the built-in catalog.
|
|
@@ -360,10 +425,7 @@ export function detectEngineFromEnv(): AgentEngineEntry | null {
|
|
|
360
425
|
return null;
|
|
361
426
|
}
|
|
362
427
|
|
|
363
|
-
async function envKeyUsableForEntry(
|
|
364
|
-
entry: AgentEngineEntry,
|
|
365
|
-
key: string,
|
|
366
|
-
): Promise<boolean> {
|
|
428
|
+
async function envKeyUsableForEntry(key: string): Promise<boolean> {
|
|
367
429
|
if (
|
|
368
430
|
!(
|
|
369
431
|
canUseDeployCredentialFallbackForRequest(key) &&
|
|
@@ -372,19 +434,41 @@ async function envKeyUsableForEntry(
|
|
|
372
434
|
) {
|
|
373
435
|
return false;
|
|
374
436
|
}
|
|
375
|
-
if (entry.name === "builder") {
|
|
376
|
-
return true;
|
|
377
|
-
}
|
|
378
437
|
const value = readDeployCredentialEnv(key);
|
|
379
438
|
if (!value) return false;
|
|
380
439
|
return !(await getProviderCredentialAuthFailure({ key, value }));
|
|
381
440
|
}
|
|
382
441
|
|
|
442
|
+
/**
|
|
443
|
+
* Builder's deploy-env fallback is checked as a pair, not per-key: the
|
|
444
|
+
* auth-failure marker is fingerprinted from privateKey+publicKey together
|
|
445
|
+
* (see `builderCredentialFingerprint`), so a single-key lookup can never
|
|
446
|
+
* match it. Without this, a rejected deploy-level Builder key would keep
|
|
447
|
+
* reporting "usable" through this env-only path forever — the same class of
|
|
448
|
+
* bug as the per-scope check in `credential-provider.ts`'s
|
|
449
|
+
* `isCompleteBuilderConnection`.
|
|
450
|
+
*/
|
|
451
|
+
async function hasUsableBuilderEnvKeys(): Promise<boolean> {
|
|
452
|
+
const privateKey = canUseDeployCredentialFallbackForRequest(
|
|
453
|
+
"BUILDER_PRIVATE_KEY",
|
|
454
|
+
)
|
|
455
|
+
? readDeployCredentialEnv("BUILDER_PRIVATE_KEY")
|
|
456
|
+
: null;
|
|
457
|
+
const publicKey = canUseDeployCredentialFallbackForRequest(
|
|
458
|
+
"BUILDER_PUBLIC_KEY",
|
|
459
|
+
)
|
|
460
|
+
? readDeployCredentialEnv("BUILDER_PUBLIC_KEY")
|
|
461
|
+
: null;
|
|
462
|
+
if (!privateKey || !publicKey) return false;
|
|
463
|
+
return !(await getBuilderCredentialAuthFailure({ privateKey, publicKey }));
|
|
464
|
+
}
|
|
465
|
+
|
|
383
466
|
async function hasUsableEnvKeys(entry: AgentEngineEntry): Promise<boolean> {
|
|
384
467
|
if (!isAgentEnginePackageInstalled(entry)) return false;
|
|
385
468
|
if (entry.requiredEnvVars.length === 0) return false;
|
|
469
|
+
if (entry.name === "builder") return hasUsableBuilderEnvKeys();
|
|
386
470
|
for (const key of entry.requiredEnvVars) {
|
|
387
|
-
if (!(await envKeyUsableForEntry(
|
|
471
|
+
if (!(await envKeyUsableForEntry(key))) return false;
|
|
388
472
|
}
|
|
389
473
|
return true;
|
|
390
474
|
}
|
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
* `ModelMessage` shapes.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import {
|
|
11
|
+
classifyProviderError,
|
|
12
|
+
describeErrorWithCauses,
|
|
13
|
+
} from "./error-detail.js";
|
|
10
14
|
import { backfillEngineMessagesToolResults } from "./translate-anthropic.js";
|
|
11
15
|
import type {
|
|
12
16
|
EngineTool,
|
|
@@ -294,11 +298,22 @@ export function aiSdkPartToEngineEvents(part: any): EngineEvent[] {
|
|
|
294
298
|
case "error": {
|
|
295
299
|
const errMsg =
|
|
296
300
|
part.error instanceof Error
|
|
297
|
-
? part.error
|
|
301
|
+
? describeErrorWithCauses(part.error)
|
|
298
302
|
: typeof part.error === "string"
|
|
299
303
|
? part.error
|
|
300
304
|
: JSON.stringify(part.error);
|
|
301
|
-
|
|
305
|
+
// `streamText` reports a failed provider request as a stream part rather
|
|
306
|
+
// than a throw, so this is the arrival path for most provider HTTP
|
|
307
|
+
// failures. It used to emit the message alone, discarding the
|
|
308
|
+
// APICallError's statusCode/isRetryable — which is why they all landed as
|
|
309
|
+
// `unknown` and were retried only if their prose happened to match a
|
|
310
|
+
// keyword. Same classifier as the thrown path in ai-sdk-engine.ts.
|
|
311
|
+
events.push({
|
|
312
|
+
type: "stop",
|
|
313
|
+
reason: "error",
|
|
314
|
+
error: errMsg,
|
|
315
|
+
...classifyProviderError(part.error),
|
|
316
|
+
});
|
|
302
317
|
break;
|
|
303
318
|
}
|
|
304
319
|
|
|
@@ -84,6 +84,7 @@ import {
|
|
|
84
84
|
LLM_MISSING_CREDENTIALS_MESSAGE,
|
|
85
85
|
userFacingLlmCredentialError,
|
|
86
86
|
} from "./engine/credential-errors.js";
|
|
87
|
+
import { isProviderConnectionErrorMessage } from "./engine/error-detail.js";
|
|
87
88
|
import {
|
|
88
89
|
resolveEngine,
|
|
89
90
|
registerBuiltinEngines,
|
|
@@ -1312,7 +1313,7 @@ export function isRetryableError(err: unknown): boolean {
|
|
|
1312
1313
|
msg.includes("gateway error") ||
|
|
1313
1314
|
msg.includes("socket hang up") ||
|
|
1314
1315
|
msg.includes("connection reset") ||
|
|
1315
|
-
|
|
1316
|
+
isProviderConnectionErrorMessage(msg) ||
|
|
1316
1317
|
msg.includes("too many requests") ||
|
|
1317
1318
|
msg.includes("timeout") ||
|
|
1318
1319
|
msg.includes("gateway timeout") ||
|
|
@@ -1321,17 +1322,6 @@ export function isRetryableError(err: unknown): boolean {
|
|
|
1321
1322
|
);
|
|
1322
1323
|
}
|
|
1323
1324
|
|
|
1324
|
-
function hasProviderConnectionErrorMessage(message: string): boolean {
|
|
1325
|
-
const normalized = message.toLowerCase();
|
|
1326
|
-
// Anthropic's APIConnectionError uses "Connection error."; AI SDK wraps
|
|
1327
|
-
// OpenAI TLS failures as "Cannot connect to API". Both can cross a worker
|
|
1328
|
-
// boundary without their structured EngineError metadata.
|
|
1329
|
-
return (
|
|
1330
|
-
normalized.includes("connection error") ||
|
|
1331
|
-
normalized.includes("cannot connect to api")
|
|
1332
|
-
);
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1335
1325
|
// ---------------------------------------------------------------------------
|
|
1336
1326
|
// Context-window overflow recovery
|
|
1337
1327
|
// ---------------------------------------------------------------------------
|
|
@@ -2264,7 +2254,7 @@ export function isResumableEngineError(err: unknown): boolean {
|
|
|
2264
2254
|
text.includes("econnaborted") ||
|
|
2265
2255
|
text.includes("fetch failed") ||
|
|
2266
2256
|
text.includes("network error") ||
|
|
2267
|
-
|
|
2257
|
+
isProviderConnectionErrorMessage(text) ||
|
|
2268
2258
|
text.includes("connection reset") ||
|
|
2269
2259
|
text.includes("connection closed") ||
|
|
2270
2260
|
text.includes("stream closed") ||
|
|
@@ -6104,7 +6094,7 @@ function isRecoverableContinuationError(event: {
|
|
|
6104
6094
|
code === "http_529" ||
|
|
6105
6095
|
code === "run_timeout" ||
|
|
6106
6096
|
message.includes("timeout") ||
|
|
6107
|
-
|
|
6097
|
+
isProviderConnectionErrorMessage(message) ||
|
|
6108
6098
|
message.includes("temporarily unavailable")
|
|
6109
6099
|
);
|
|
6110
6100
|
}
|
|
@@ -6432,7 +6422,7 @@ export async function runAgentLoopWithMainChatInternalContinuations(
|
|
|
6432
6422
|
type: "error",
|
|
6433
6423
|
error: RUN_BUDGET_EXHAUSTED_MESSAGE,
|
|
6434
6424
|
errorCode: RUN_BUDGET_EXHAUSTED_ERROR_CODE,
|
|
6435
|
-
recoverable:
|
|
6425
|
+
recoverable: false,
|
|
6436
6426
|
});
|
|
6437
6427
|
}
|
|
6438
6428
|
return usage;
|
|
@@ -6661,9 +6651,9 @@ export async function claimBackgroundWorkerRunEarly(opts: {
|
|
|
6661
6651
|
.join(" "),
|
|
6662
6652
|
).catch(() => {});
|
|
6663
6653
|
|
|
6664
|
-
// A failed durable abort read
|
|
6665
|
-
//
|
|
6666
|
-
if (await turnAborted(threadId, turnId)
|
|
6654
|
+
// A failed durable abort read must surface as infrastructure failure. It is
|
|
6655
|
+
// not evidence that the user stopped the turn.
|
|
6656
|
+
if (await turnAborted(threadId, turnId)) {
|
|
6667
6657
|
await abortRun(opts.runId, "user").catch(() => {});
|
|
6668
6658
|
return { claimed: false, skipped: "turn-aborted" };
|
|
6669
6659
|
}
|
|
@@ -6674,7 +6664,7 @@ export async function claimBackgroundWorkerRunEarly(opts: {
|
|
|
6674
6664
|
}).catch(() => {});
|
|
6675
6665
|
}
|
|
6676
6666
|
|
|
6677
|
-
if (await turnAborted(threadId, turnId)
|
|
6667
|
+
if (await turnAborted(threadId, turnId)) {
|
|
6678
6668
|
await abortRun(opts.runId, "user").catch(() => {});
|
|
6679
6669
|
return { claimed: false, skipped: "turn-aborted" };
|
|
6680
6670
|
}
|
|
@@ -6687,7 +6677,7 @@ export async function claimBackgroundWorkerRunEarly(opts: {
|
|
|
6687
6677
|
|
|
6688
6678
|
await record(opts.runId, RUN_DIAG_STAGE.workerClaimed).catch(() => {});
|
|
6689
6679
|
await heartbeat(opts.runId).catch(() => {});
|
|
6690
|
-
if (await turnAborted(threadId, turnId)
|
|
6680
|
+
if (await turnAborted(threadId, turnId)) {
|
|
6691
6681
|
await abortRun(opts.runId, "user").catch(() => {});
|
|
6692
6682
|
return { claimed: false, skipped: "turn-aborted" };
|
|
6693
6683
|
}
|
|
@@ -7143,11 +7133,7 @@ export async function chainServerDrivenContinuation(opts: {
|
|
|
7143
7133
|
};
|
|
7144
7134
|
delete continuationBody[AGENT_CHAT_BACKGROUND_RUN_FIELD];
|
|
7145
7135
|
try {
|
|
7146
|
-
if (
|
|
7147
|
-
await d
|
|
7148
|
-
.isTurnAborted(effectiveThreadId, effectiveTurnId)
|
|
7149
|
-
.catch(() => true)
|
|
7150
|
-
) {
|
|
7136
|
+
if (await d.isTurnAborted(effectiveThreadId, effectiveTurnId)) {
|
|
7151
7137
|
await d.markRunAborted(runId, "user").catch(() => {});
|
|
7152
7138
|
return;
|
|
7153
7139
|
}
|
|
@@ -7196,11 +7182,7 @@ export async function chainServerDrivenContinuation(opts: {
|
|
|
7196
7182
|
insertErr instanceof Error ? insertErr.message : insertErr,
|
|
7197
7183
|
);
|
|
7198
7184
|
}
|
|
7199
|
-
if (
|
|
7200
|
-
await d
|
|
7201
|
-
.isTurnAborted(effectiveThreadId, effectiveTurnId)
|
|
7202
|
-
.catch(() => true)
|
|
7203
|
-
) {
|
|
7185
|
+
if (await d.isTurnAborted(effectiveThreadId, effectiveTurnId)) {
|
|
7204
7186
|
if (nextRowInserted)
|
|
7205
7187
|
await d.markRunAborted(nextRunId, "user").catch(() => {});
|
|
7206
7188
|
await d.markRunAborted(runId, "user").catch(() => {});
|
|
@@ -8376,9 +8358,7 @@ export function createProductionAgentHandler(
|
|
|
8376
8358
|
: runId;
|
|
8377
8359
|
if (
|
|
8378
8360
|
isBackgroundWorker &&
|
|
8379
|
-
(await isTurnAborted(effectiveThreadId, effectiveTurnId)
|
|
8380
|
-
() => true,
|
|
8381
|
-
))
|
|
8361
|
+
(await isTurnAborted(effectiveThreadId, effectiveTurnId))
|
|
8382
8362
|
) {
|
|
8383
8363
|
await markRunAborted(runId, "user").catch(() => {});
|
|
8384
8364
|
return { ok: true, stopped: true };
|
|
@@ -605,7 +605,7 @@ export async function runAgentLoopDirectWithSoftTimeout(
|
|
|
605
605
|
type: "error",
|
|
606
606
|
error: RUN_BUDGET_EXHAUSTED_MESSAGE,
|
|
607
607
|
errorCode: RUN_BUDGET_EXHAUSTED_ERROR_CODE,
|
|
608
|
-
recoverable:
|
|
608
|
+
recoverable: false,
|
|
609
609
|
});
|
|
610
610
|
reportFinalOutcome({
|
|
611
611
|
state: "failed",
|
package/src/agent/run-manager.ts
CHANGED
|
@@ -4,6 +4,11 @@ import {
|
|
|
4
4
|
LLM_MISSING_CREDENTIALS_ERROR_CODE,
|
|
5
5
|
LLM_MISSING_CREDENTIALS_MESSAGE,
|
|
6
6
|
} from "./engine/credential-errors.js";
|
|
7
|
+
import {
|
|
8
|
+
classifyTerminalErrorCode,
|
|
9
|
+
describeErrorWithCauses,
|
|
10
|
+
isProviderConnectionError,
|
|
11
|
+
} from "./engine/error-detail.js";
|
|
7
12
|
import { EngineError } from "./engine/types.js";
|
|
8
13
|
import {
|
|
9
14
|
insertRun,
|
|
@@ -341,23 +346,16 @@ function getRunErrorMessage(err: unknown): string {
|
|
|
341
346
|
return "Unknown error";
|
|
342
347
|
}
|
|
343
348
|
|
|
344
|
-
function isProviderConnectionErrorMessage(message: string): boolean {
|
|
345
|
-
const normalized = message.trim().toLowerCase();
|
|
346
|
-
return (
|
|
347
|
-
normalized === "connection error." ||
|
|
348
|
-
normalized.includes("cannot connect to api:")
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
349
|
function getRunErrorCode(err: unknown): string | undefined {
|
|
353
350
|
if (err instanceof EngineError) {
|
|
354
351
|
if (err.errorCode) return err.errorCode;
|
|
355
352
|
if (err.statusCode === 429) return PROVIDER_RATE_LIMITED_ERROR_CODE;
|
|
356
353
|
}
|
|
357
|
-
if (
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
354
|
+
if (isProviderConnectionError(err)) return PROVIDER_NETWORK_ERROR_CODE;
|
|
355
|
+
// The code rides the error EVENT to the client, which decides recovery from
|
|
356
|
+
// it — so an uncoded transport failure has to be classified here too, not
|
|
357
|
+
// only when the run row is persisted.
|
|
358
|
+
return classifyTerminalErrorCode(describeErrorWithCauses(err));
|
|
361
359
|
}
|
|
362
360
|
|
|
363
361
|
function getEngineRunErrorDetails(err: EngineError): string | undefined {
|
|
@@ -376,7 +374,7 @@ function shouldCaptureRunError(err: unknown): boolean {
|
|
|
376
374
|
}
|
|
377
375
|
if (!(err instanceof Error)) return true;
|
|
378
376
|
if (/^40[13] status code\b/i.test(err.message)) return false;
|
|
379
|
-
if (
|
|
377
|
+
if (isProviderConnectionError(err)) return false;
|
|
380
378
|
if (!errorCode) return true;
|
|
381
379
|
const normalizedCode = errorCode.toLowerCase();
|
|
382
380
|
return (
|
|
@@ -984,6 +982,13 @@ export function startRun(
|
|
|
984
982
|
// false-stale-reap zombie scenario where the reaper flipped the row while
|
|
985
983
|
// this isolate was briefly unable to heartbeat (DB latency / GC pause).
|
|
986
984
|
let lastAbortCheck = Date.now() - 3000;
|
|
985
|
+
// A read failure here used to be indistinguishable from "not aborted" —
|
|
986
|
+
// exactly the coerced-to-false pattern that lets a real Stop go unseen for
|
|
987
|
+
// the rest of the run. Count consecutive failures like the heartbeat-write
|
|
988
|
+
// handler above; past the same threshold, fail closed (self-abort with a
|
|
989
|
+
// reason outside TURN_ENDING_ABORT_REASONS/RECOVERABLE_ABORT_REASONS, so it
|
|
990
|
+
// surfaces as a typed error) instead of silently retrying forever.
|
|
991
|
+
let consecutiveAbortCheckFailures = 0;
|
|
987
992
|
const checkSqlAbort = () => {
|
|
988
993
|
const now = Date.now();
|
|
989
994
|
if (now - lastAbortCheck < 3000) return;
|
|
@@ -1004,7 +1009,26 @@ export function startRun(
|
|
|
1004
1009
|
}
|
|
1005
1010
|
}
|
|
1006
1011
|
})
|
|
1007
|
-
.
|
|
1012
|
+
.then(() => {
|
|
1013
|
+
consecutiveAbortCheckFailures = 0;
|
|
1014
|
+
})
|
|
1015
|
+
.catch((error) => {
|
|
1016
|
+
consecutiveAbortCheckFailures += 1;
|
|
1017
|
+
if (consecutiveAbortCheckFailures >= 3) {
|
|
1018
|
+
captureError(error, {
|
|
1019
|
+
route: "/_agent-native/agent-chat",
|
|
1020
|
+
tags: {
|
|
1021
|
+
source: "agent-run-manager",
|
|
1022
|
+
phase: "abort-check",
|
|
1023
|
+
consecutiveFailures: String(consecutiveAbortCheckFailures),
|
|
1024
|
+
},
|
|
1025
|
+
extra: { runId, threadId },
|
|
1026
|
+
});
|
|
1027
|
+
if (!abort.signal.aborted) {
|
|
1028
|
+
abortInMemoryRun(run, "abort_check_unavailable");
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
});
|
|
1008
1032
|
};
|
|
1009
1033
|
|
|
1010
1034
|
// Heartbeat: bump heartbeat_at every 1.5s so watchers can detect a dead
|
|
@@ -1456,6 +1480,11 @@ export function startRun(
|
|
|
1456
1480
|
? completionError.message
|
|
1457
1481
|
: String(completionError));
|
|
1458
1482
|
}
|
|
1483
|
+
// An engine that emitted an error event without a code has NOT told us
|
|
1484
|
+
// the failure is unclassifiable — it told us nothing. Recover the code
|
|
1485
|
+
// from the message before falling back to "unknown", which the client
|
|
1486
|
+
// reads as "do not attempt recovery".
|
|
1487
|
+
errorCode ??= classifyTerminalErrorCode(errorDetail);
|
|
1459
1488
|
runTerminalErrorCode = errorCode ?? "unknown";
|
|
1460
1489
|
runTerminalErrorDetail = errorDetail;
|
|
1461
1490
|
await setRunError(runId, errorCode ?? "unknown", errorDetail);
|
package/src/agent/run-store.ts
CHANGED
|
@@ -946,6 +946,16 @@ export interface UnclaimedBackgroundRunRow {
|
|
|
946
946
|
* pre-inserted — independent of any liveness bump a redispatch attempt
|
|
947
947
|
* makes along the way. */
|
|
948
948
|
startedAt: number;
|
|
949
|
+
/**
|
|
950
|
+
* Whether the row still carries the `dispatch_payload` a redispatched worker
|
|
951
|
+
* would rehydrate its request body from. Eligibility for this sweep does NOT
|
|
952
|
+
* imply it: a background row can reach the grace window having never had a
|
|
953
|
+
* payload at all. Redispatching one of those asserts `payloadRef: true` to a
|
|
954
|
+
* worker that then cannot rehydrate, so it kills the run as
|
|
955
|
+
* `dispatch_payload_missing` — a reason that reads like data loss for what is
|
|
956
|
+
* really an un-redispatchable handoff.
|
|
957
|
+
*/
|
|
958
|
+
hasDispatchPayload: boolean;
|
|
949
959
|
}
|
|
950
960
|
|
|
951
961
|
/**
|
|
@@ -965,7 +975,10 @@ export async function listUnclaimedBackgroundRunRows(): Promise<
|
|
|
965
975
|
const { rows } = await client.execute({
|
|
966
976
|
// CAST keeps the ms-epoch param 64-bit on Postgres (see
|
|
967
977
|
// backgroundAwareStaleCutoffSql for the int4-inference failure mode).
|
|
968
|
-
|
|
978
|
+
// Report payload presence rather than filtering on it: a payload-less row
|
|
979
|
+
// must still be VISIBLE to the sweep so the slow pass can reap it. Filtering
|
|
980
|
+
// it out here would leave it `running` forever.
|
|
981
|
+
sql: `SELECT id, started_at, (dispatch_payload IS NOT NULL) AS has_dispatch_payload FROM agent_runs
|
|
969
982
|
WHERE status = 'running'
|
|
970
983
|
AND dispatch_mode = 'background'
|
|
971
984
|
AND COALESCE(heartbeat_at, started_at) < (CAST(? AS BIGINT) - ${UNCLAIMED_BACKGROUND_RUN_GRACE_MS})`,
|
|
@@ -975,11 +988,15 @@ export async function listUnclaimedBackgroundRunRows(): Promise<
|
|
|
975
988
|
for (const row of rows ?? []) {
|
|
976
989
|
const id = (row as { id?: unknown }).id;
|
|
977
990
|
const startedAt = (row as { started_at?: unknown }).started_at;
|
|
991
|
+
const hasPayload = (row as { has_dispatch_payload?: unknown })
|
|
992
|
+
.has_dispatch_payload;
|
|
978
993
|
if (typeof id === "string" && id) {
|
|
979
994
|
result.push({
|
|
980
995
|
id,
|
|
981
996
|
startedAt:
|
|
982
997
|
typeof startedAt === "number" ? startedAt : Number(startedAt) || 0,
|
|
998
|
+
// SQLite returns 1/0 where Postgres returns a boolean.
|
|
999
|
+
hasDispatchPayload: hasPayload === true || hasPayload === 1,
|
|
983
1000
|
});
|
|
984
1001
|
}
|
|
985
1002
|
}
|
|
@@ -1147,10 +1164,20 @@ export async function setRunTerminalReason(
|
|
|
1147
1164
|
await ensureRunTables();
|
|
1148
1165
|
const client = getDbExec();
|
|
1149
1166
|
const reason = terminalReason.slice(0, 200);
|
|
1167
|
+
// Write-once for a row that is already terminal. Three writers in three
|
|
1168
|
+
// isolates race on this column — the mid-run checkpoint, the run-manager's
|
|
1169
|
+
// finalization, and the background worker's failure path — with no ordering
|
|
1170
|
+
// between them, and last-writer-wins let a late checkpoint relabel a row
|
|
1171
|
+
// another isolate had already finalized. That produced impossible rows
|
|
1172
|
+
// (status='errored' carrying a continuation reason, no error_code, no
|
|
1173
|
+
// terminal event) and misattributed 130 production runs to a failure mode
|
|
1174
|
+
// they never hit. A row still `running` has no honest reason yet, so it
|
|
1175
|
+
// stays writable; once one is recorded on a terminal row, it stands.
|
|
1176
|
+
const guard = `AND (status = 'running' OR terminal_reason IS NULL OR terminal_reason = '')`;
|
|
1150
1177
|
await client.execute({
|
|
1151
1178
|
sql: isContinuationTerminalReason(reason)
|
|
1152
|
-
? `UPDATE agent_runs SET terminal_reason = ?, status = CASE WHEN status = 'completed' THEN 'truncated' ELSE status END WHERE id =
|
|
1153
|
-
: `UPDATE agent_runs SET terminal_reason = ? WHERE id =
|
|
1179
|
+
? `UPDATE agent_runs SET terminal_reason = ?, status = CASE WHEN status = 'completed' THEN 'truncated' ELSE status END WHERE id = ? ${guard}`
|
|
1180
|
+
: `UPDATE agent_runs SET terminal_reason = ? WHERE id = ? ${guard}`,
|
|
1154
1181
|
args: [reason, runId],
|
|
1155
1182
|
});
|
|
1156
1183
|
} catch {
|