@agent-native/core 0.132.2 → 0.133.1
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 +181 -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 +61 -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 +49 -7
- 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 +51 -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 +38 -6
- 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/struct-routes.d.ts +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/file-upload/actions/upload-image.d.ts +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 +1 -1
- package/dist/observability/routes.d.ts +1 -1
- 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/resources/handlers.d.ts +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/agent-engine-api-key-route.d.ts +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/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 +61 -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 +49 -7
- 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
|
@@ -675,3 +675,33 @@ export async function getActiveIntegrationInstallationForTenant(
|
|
|
675
675
|
? toSafeInstallation(rowToRaw(rows[0] as Record<string, unknown>))
|
|
676
676
|
: null;
|
|
677
677
|
}
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Every connected installation for a tenant, newest first.
|
|
681
|
+
*
|
|
682
|
+
* A workspace can legitimately have several apps of the same platform
|
|
683
|
+
* connected at once (e.g. a product-specific Slack app alongside a generic
|
|
684
|
+
* one). Callers that cannot name an app id must see that ambiguity rather
|
|
685
|
+
* than receive an arbitrary winner — picking the most recently updated row
|
|
686
|
+
* silently sends as whichever app happened to reconnect last.
|
|
687
|
+
*/
|
|
688
|
+
export async function listActiveIntegrationInstallationsForTenant(
|
|
689
|
+
platform: string,
|
|
690
|
+
tenantId: string,
|
|
691
|
+
): Promise<IntegrationInstallation[]> {
|
|
692
|
+
await ensureTable();
|
|
693
|
+
const { rows } = await getDbExec().execute({
|
|
694
|
+
sql: `SELECT * FROM ${TABLE}
|
|
695
|
+
WHERE platform = ? AND (team_id = ? OR enterprise_id = ?)
|
|
696
|
+
AND status = 'connected'
|
|
697
|
+
ORDER BY updated_at DESC`,
|
|
698
|
+
args: [
|
|
699
|
+
normalizePlatform(platform),
|
|
700
|
+
required(tenantId, "tenantId"),
|
|
701
|
+
required(tenantId, "tenantId"),
|
|
702
|
+
],
|
|
703
|
+
});
|
|
704
|
+
return rows.map((row) =>
|
|
705
|
+
toSafeInstallation(rowToRaw(row as Record<string, unknown>)),
|
|
706
|
+
);
|
|
707
|
+
}
|
|
@@ -93,7 +93,6 @@ import {
|
|
|
93
93
|
INTEGRATION_RETRY_SWEEP_TOKEN_SUBJECT,
|
|
94
94
|
integrationDispatchScopeValue,
|
|
95
95
|
isInIntegrationRecoveryRuntime,
|
|
96
|
-
isIntegrationDurableDispatchConfigured,
|
|
97
96
|
isIntegrationDurableDispatchEnabledForTask,
|
|
98
97
|
} from "./integration-durable-dispatch.js";
|
|
99
98
|
import {
|
|
@@ -1787,15 +1786,16 @@ export function createIntegrationsPlugin(
|
|
|
1787
1786
|
setResponseStatus(event, 401);
|
|
1788
1787
|
return { error: "Invalid or expired internal token" };
|
|
1789
1788
|
}
|
|
1790
|
-
if (!isIntegrationDurableDispatchConfigured()) {
|
|
1791
|
-
return { ok: true, disabled: true };
|
|
1792
|
-
}
|
|
1793
1789
|
const webhookBaseUrl = getBaseUrl(event);
|
|
1794
1790
|
const [pendingTasks, campaigns, a2aContinuations] = await Promise.all([
|
|
1791
|
+
// Portable (fire-and-forget) dispatch loses tasks whenever the
|
|
1792
|
+
// self-dispatch POST dies with the container, and the in-process
|
|
1793
|
+
// retry interval does not survive a serverless freeze. Sweeping only
|
|
1794
|
+
// durable scopes left those deployments with no recovery at all, so
|
|
1795
|
+
// the queue is swept regardless of dispatch mode.
|
|
1795
1796
|
retryStuckPendingTasks({
|
|
1796
1797
|
webhookBaseUrl,
|
|
1797
1798
|
limit: 20,
|
|
1798
|
-
durableOnly: true,
|
|
1799
1799
|
}).catch((error) => {
|
|
1800
1800
|
console.error(
|
|
1801
1801
|
"[integrations] Pending-task recovery failed:",
|
|
@@ -163,6 +163,13 @@ export interface OutboundTarget {
|
|
|
163
163
|
tenantId?: string;
|
|
164
164
|
/** Managed installation id when the caller already resolved it. */
|
|
165
165
|
installationId?: string;
|
|
166
|
+
/**
|
|
167
|
+
* Provider installation key identifying which connected app to send as.
|
|
168
|
+
* Required when a tenant has more than one app of the same platform
|
|
169
|
+
* connected — without it the adapter cannot tell them apart and refuses to
|
|
170
|
+
* guess rather than posting under the wrong bot identity.
|
|
171
|
+
*/
|
|
172
|
+
installationKey?: string;
|
|
166
173
|
}
|
|
167
174
|
|
|
168
175
|
/**
|
|
@@ -606,7 +606,7 @@ async function enqueueAndDispatch(
|
|
|
606
606
|
),
|
|
607
607
|
)
|
|
608
608
|
: PROCESSOR_DISPATCH_SETTLE_WAIT_MS;
|
|
609
|
-
await dispatchPendingIntegrationTask({
|
|
609
|
+
const outcome = await dispatchPendingIntegrationTask({
|
|
610
610
|
taskId,
|
|
611
611
|
task: {
|
|
612
612
|
platform: incoming.platform,
|
|
@@ -617,6 +617,29 @@ async function enqueueAndDispatch(
|
|
|
617
617
|
baseUrl,
|
|
618
618
|
portableSettleMs: settleWaitMs,
|
|
619
619
|
});
|
|
620
|
+
|
|
621
|
+
// A definitive dispatch failure leaves a queued task nobody is running while
|
|
622
|
+
// the placeholder above already told the user work had started. Say so
|
|
623
|
+
// instead of leaving that indicator spinning until the sweep — if it runs.
|
|
624
|
+
if (outcome === "failed") {
|
|
625
|
+
console.error(
|
|
626
|
+
`[integrations] dispatch failed for task ${taskId} (${incoming.platform}/${incoming.externalThreadId})`,
|
|
627
|
+
);
|
|
628
|
+
try {
|
|
629
|
+
await options.adapter.sendResponse(
|
|
630
|
+
{
|
|
631
|
+
text: "I couldn't start working on that — the request was accepted but never handed off. Please try again.",
|
|
632
|
+
platformContext: incoming.platformContext,
|
|
633
|
+
},
|
|
634
|
+
incoming,
|
|
635
|
+
);
|
|
636
|
+
} catch (err) {
|
|
637
|
+
console.error(
|
|
638
|
+
"[integrations] failed to report dispatch failure to user:",
|
|
639
|
+
err,
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
620
643
|
}
|
|
621
644
|
|
|
622
645
|
/**
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from "../agent/production-agent.js";
|
|
16
16
|
import { runAgentLoopDirectWithSoftTimeout } from "../agent/run-loop-with-resume.js";
|
|
17
17
|
import { resolveRunSoftTimeoutMs, startRun } from "../agent/run-manager.js";
|
|
18
|
+
import { claimBackgroundRun, insertRun } from "../agent/run-store.js";
|
|
18
19
|
import { attachToolSearch } from "../agent/tool-search.js";
|
|
19
20
|
import {
|
|
20
21
|
resolveAutomationExecutionIdentity,
|
|
@@ -290,8 +291,23 @@ export async function runBackgroundAutomation(
|
|
|
290
291
|
const systemPrompt = await deps.getSystemPrompt(ownerEmail);
|
|
291
292
|
const thread = await createThread(ownerEmail, { title: threadTitle });
|
|
292
293
|
const runId = createRunId(options.runIdPrefix);
|
|
294
|
+
// Scheduled work is background work: it has no synchronous serverless
|
|
295
|
+
// caller waiting on it, so it must not inherit the interactive clamp
|
|
296
|
+
// (40s soft timeout, a 30s no-progress backstop at 0.75x that, and 6
|
|
297
|
+
// continuations). A dashboard render or digest legitimately spends
|
|
298
|
+
// minutes across many tool calls, and dies the first time any gap
|
|
299
|
+
// between two of them exceeds 30s — recorded as `no_progress` after
|
|
300
|
+
// several minutes of real work, because the backstop is suspended
|
|
301
|
+
// while a tool is in flight but not between tools.
|
|
302
|
+
//
|
|
303
|
+
// Hardcoded rather than `isInBackgroundFunctionRuntime()` (what
|
|
304
|
+
// webhook-handler.ts uses): a webhook can arrive on either runtime, but
|
|
305
|
+
// a scheduler tick never serves a synchronous request, so the
|
|
306
|
+
// interactive clamp never applies to it. The wider soft ceiling stays
|
|
307
|
+
// bounded by this runner's own BACKGROUND_RUN_HARD_TIMEOUT_MS abort.
|
|
293
308
|
const softTimeoutMs = resolveRunSoftTimeoutMs(undefined, {
|
|
294
309
|
useHostedDefault: true,
|
|
310
|
+
backgroundFunction: true,
|
|
295
311
|
});
|
|
296
312
|
|
|
297
313
|
const usageRef: {
|
|
@@ -300,6 +316,26 @@ export async function runBackgroundAutomation(
|
|
|
300
316
|
let responseText = "";
|
|
301
317
|
let hardAbortTimer: ReturnType<typeof setTimeout> | null = null;
|
|
302
318
|
|
|
319
|
+
// This runner executes in-process, synchronously — there is no HTTP
|
|
320
|
+
// self-dispatch to a separate worker. Self-claim the row into
|
|
321
|
+
// 'background-processing' right away, exactly like a genuine HTTP
|
|
322
|
+
// background worker does immediately after its own insert (see
|
|
323
|
+
// production-agent.ts's `claimBackgroundWorkerRunEarly`). Without this,
|
|
324
|
+
// the row sits at dispatch_mode='background' for its whole life with no
|
|
325
|
+
// worker ever claiming it, which is indistinguishable from a lost HTTP
|
|
326
|
+
// handoff to the unclaimed-background-run sweep — it gets reaped as
|
|
327
|
+
// "background_worker_never_started" out from under a still-executing
|
|
328
|
+
// job the moment any single tool call runs past the 25s grace window.
|
|
329
|
+
await insertRun(runId, thread.id, undefined, {
|
|
330
|
+
dispatchMode: "background",
|
|
331
|
+
});
|
|
332
|
+
const claimedOwnRun = await claimBackgroundRun(runId);
|
|
333
|
+
if (!claimedOwnRun) {
|
|
334
|
+
throw new Error(
|
|
335
|
+
`Background automation "${automation.name}" (run "${runId}") could not claim its own freshly-inserted run row`,
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
|
|
303
339
|
await new Promise<void>((resolve, reject) => {
|
|
304
340
|
const activeRun = startRun(
|
|
305
341
|
runId,
|
|
@@ -329,6 +365,7 @@ export async function runBackgroundAutomation(
|
|
|
329
365
|
runId,
|
|
330
366
|
},
|
|
331
367
|
softTimeoutMs,
|
|
368
|
+
{ backgroundFunction: true },
|
|
332
369
|
);
|
|
333
370
|
},
|
|
334
371
|
async (run) => {
|
|
@@ -360,7 +397,7 @@ export async function runBackgroundAutomation(
|
|
|
360
397
|
},
|
|
361
398
|
{
|
|
362
399
|
softTimeoutMs,
|
|
363
|
-
|
|
400
|
+
backgroundFunction: true,
|
|
364
401
|
model,
|
|
365
402
|
engineName: engine.name,
|
|
366
403
|
},
|
|
@@ -3997,8 +3997,14 @@ async function resolveRequiredCredential(options: {
|
|
|
3997
3997
|
connectionId?: string | null;
|
|
3998
3998
|
}): Promise<ProviderApiResolvedCredential> {
|
|
3999
3999
|
const credential = await resolveOptionalCredential(options);
|
|
4000
|
-
if (
|
|
4001
|
-
|
|
4000
|
+
if (credential?.value) return credential;
|
|
4001
|
+
const scopeGap = await describeCredentialScopeGap([options.key], options.ctx)
|
|
4002
|
+
// coercion-ok: only enriches an error we throw either way — losing the scope
|
|
4003
|
+
// hint still surfaces the real "not configured" failure, never a success.
|
|
4004
|
+
.catch(() => null);
|
|
4005
|
+
throw new Error(
|
|
4006
|
+
`${options.key} not configured${scopeGap ? `. ${scopeGap}` : ""}`,
|
|
4007
|
+
);
|
|
4002
4008
|
}
|
|
4003
4009
|
|
|
4004
4010
|
async function resolveOptionalCredential(options: {
|
|
@@ -30,6 +30,7 @@ import { findAgent, discoverAgents } from "../server/agent-discovery.js";
|
|
|
30
30
|
import {
|
|
31
31
|
getRequestUserEmail,
|
|
32
32
|
getRequestOrgId,
|
|
33
|
+
getRequestRunContext,
|
|
33
34
|
isIntegrationCallerRequest,
|
|
34
35
|
getIntegrationRequestContext,
|
|
35
36
|
} from "../server/request-context.js";
|
|
@@ -93,8 +94,13 @@ function buildDelegationCorrelation(
|
|
|
93
94
|
const inheritedDepth = Number.isInteger(context?.delegationDepth)
|
|
94
95
|
? Math.max(0, Number(context?.delegationDepth))
|
|
95
96
|
: 0;
|
|
97
|
+
// The model this turn is actually running on, so a receiver with no model of
|
|
98
|
+
// its own can match the user's selection instead of its own default. A
|
|
99
|
+
// preference only — the receiver bounds it to its own engine's catalog.
|
|
100
|
+
const callerModel = getRequestRunContext()?.model?.trim();
|
|
96
101
|
return {
|
|
97
102
|
...(selfAppId?.trim() ? { callerApp: selfAppId.trim() } : {}),
|
|
103
|
+
...(callerModel ? { callerModel } : {}),
|
|
98
104
|
...(context?.threadId ? { callerThreadId: context.threadId } : {}),
|
|
99
105
|
...(context?.runId ? { parentRunId: context.runId } : {}),
|
|
100
106
|
...(context?.turnId ? { parentTurnId: context.turnId } : {}),
|
|
@@ -58,6 +58,7 @@ import {
|
|
|
58
58
|
createAnthropicEngine,
|
|
59
59
|
getStoredModelForEngine,
|
|
60
60
|
normalizeModelForEngine,
|
|
61
|
+
resolveDelegatedRunModel,
|
|
61
62
|
getAgentEngineEntry,
|
|
62
63
|
isAgentEnginePackageInstalled,
|
|
63
64
|
isStoredEngineUsableForRequest,
|
|
@@ -83,6 +84,7 @@ import {
|
|
|
83
84
|
callerHasThreadAccess,
|
|
84
85
|
} from "../agent/run-ownership.js";
|
|
85
86
|
import { markTurnAborted, readBackgroundRunClaim } from "../agent/run-store.js";
|
|
87
|
+
import type { UnclaimedBackgroundRunRow } from "../agent/run-store.js";
|
|
86
88
|
import {
|
|
87
89
|
buildCurrentTimeUserContext,
|
|
88
90
|
buildRuntimeContextPrompt,
|
|
@@ -1616,13 +1618,17 @@ export function createAgentChatPlugin(
|
|
|
1616
1618
|
: await buildSchemaBlock(owner, databaseToolsMode);
|
|
1617
1619
|
const extra = await resolveExtraContext(context.event, owner);
|
|
1618
1620
|
|
|
1619
|
-
const
|
|
1620
|
-
options?.model
|
|
1621
|
-
|
|
1621
|
+
const model = resolveDelegatedRunModel(a2aEngine, {
|
|
1622
|
+
explicitModel: options?.model,
|
|
1623
|
+
storedModel: await getStoredModelForEngine(a2aEngine, {
|
|
1622
1624
|
appId: options?.appId,
|
|
1623
|
-
})
|
|
1624
|
-
|
|
1625
|
-
|
|
1625
|
+
}),
|
|
1626
|
+
// Preference only, and last before the default: an app that pinned
|
|
1627
|
+
// a model keeps it. Read separately from the correlation sanitizer
|
|
1628
|
+
// below so it stays out of every identity/access path.
|
|
1629
|
+
callerModelHint: sanitizeA2ACorrelationMetadata(context.metadata)
|
|
1630
|
+
.callerModel,
|
|
1631
|
+
});
|
|
1626
1632
|
if (a2aRunContext) {
|
|
1627
1633
|
a2aRunContext.engine = a2aEngine;
|
|
1628
1634
|
a2aRunContext.model = model;
|
|
@@ -5893,7 +5899,15 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5893
5899
|
const attemptUnclaimedBackgroundRunRedispatch = async (row: {
|
|
5894
5900
|
id: string;
|
|
5895
5901
|
startedAt: number;
|
|
5902
|
+
hasDispatchPayload: boolean;
|
|
5896
5903
|
}): Promise<void> => {
|
|
5904
|
+
// Eligibility for this sweep does not mean the row is redispatchable.
|
|
5905
|
+
// The marker below asserts `payloadRef: true`, and a worker that then
|
|
5906
|
+
// finds no payload fails the run as `dispatch_payload_missing` — so
|
|
5907
|
+
// redispatching a payload-less row does not recover it, it destroys it.
|
|
5908
|
+
// Leave it for the slow sweep's reap, which reports the true cause
|
|
5909
|
+
// (`background_worker_never_started`) and is client-recoverable.
|
|
5910
|
+
if (!row.hasDispatchPayload) return;
|
|
5897
5911
|
const { updateRunHeartbeat } = await import("../agent/run-store.js");
|
|
5898
5912
|
const { resolveAgentChatProcessRunDispatchPath } =
|
|
5899
5913
|
await import("../agent/durable-background.js");
|
|
@@ -5974,7 +5988,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5974
5988
|
// idempotent, re-checks staleness at UPDATE time and honours
|
|
5975
5989
|
// the in-flight grace, so it is safe on this cadence.
|
|
5976
5990
|
await reapAllStaleRuns().catch(() => {});
|
|
5977
|
-
let rows:
|
|
5991
|
+
let rows: UnclaimedBackgroundRunRow[];
|
|
5978
5992
|
try {
|
|
5979
5993
|
rows = await listUnclaimedBackgroundRunRows();
|
|
5980
5994
|
} catch {
|
|
@@ -6019,7 +6033,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
6019
6033
|
reapUnclaimedBackgroundRun,
|
|
6020
6034
|
shouldRedispatchUnclaimedBackgroundRun,
|
|
6021
6035
|
} = await import("../agent/run-store.js");
|
|
6022
|
-
let rows:
|
|
6036
|
+
let rows: UnclaimedBackgroundRunRow[];
|
|
6023
6037
|
try {
|
|
6024
6038
|
rows = await listUnclaimedBackgroundRunRows();
|
|
6025
6039
|
} catch {
|
|
@@ -6027,7 +6041,14 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
6027
6041
|
}
|
|
6028
6042
|
for (const row of rows) {
|
|
6029
6043
|
try {
|
|
6030
|
-
|
|
6044
|
+
// A row with no `dispatch_payload` can never be rehydrated by
|
|
6045
|
+
// a redispatched worker, so waiting out the redispatch bound
|
|
6046
|
+
// buys nothing — fall straight through to the reap below and
|
|
6047
|
+
// fail it loudly with its real cause.
|
|
6048
|
+
if (
|
|
6049
|
+
row.hasDispatchPayload &&
|
|
6050
|
+
shouldRedispatchUnclaimedBackgroundRun(row)
|
|
6051
|
+
) {
|
|
6031
6052
|
await attemptUnclaimedBackgroundRunRedispatch(row);
|
|
6032
6053
|
continue;
|
|
6033
6054
|
}
|
|
@@ -101,6 +101,8 @@ export interface WorkspaceAppManifestEntry {
|
|
|
101
101
|
description: string;
|
|
102
102
|
path: string;
|
|
103
103
|
url?: string | null;
|
|
104
|
+
/** Local-only child port used to authorize loopback A2A calls. */
|
|
105
|
+
port?: number;
|
|
104
106
|
isDispatch?: boolean;
|
|
105
107
|
audience?: WorkspaceAppAudience;
|
|
106
108
|
publicPaths?: string[];
|
|
@@ -57,8 +57,15 @@ export interface BuilderDesignSystemProxyFieldsOptions {
|
|
|
57
57
|
projectName?: string;
|
|
58
58
|
description?: string;
|
|
59
59
|
surface: "design" | "slides";
|
|
60
|
+
sourceKind?: BuilderDesignSystemSourceKind;
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
export type BuilderDesignSystemSourceKind =
|
|
64
|
+
| "figma"
|
|
65
|
+
| "code"
|
|
66
|
+
| "github"
|
|
67
|
+
| "mixed";
|
|
68
|
+
|
|
62
69
|
export interface BuilderDesignSystemProxyFields {
|
|
63
70
|
title: string;
|
|
64
71
|
description: string;
|
|
@@ -68,6 +75,7 @@ export interface BuilderDesignSystemProxyFields {
|
|
|
68
75
|
|
|
69
76
|
export interface BuilderDesignSystemProxyReference {
|
|
70
77
|
source: "builder";
|
|
78
|
+
sourceKind?: BuilderDesignSystemSourceKind;
|
|
71
79
|
builderDesignSystemId: string;
|
|
72
80
|
builderJobId: string;
|
|
73
81
|
builderProjectId?: string;
|
|
@@ -532,6 +540,7 @@ export function createBuilderDesignSystemProxyFields({
|
|
|
532
540
|
projectName,
|
|
533
541
|
description,
|
|
534
542
|
surface,
|
|
543
|
+
sourceKind,
|
|
535
544
|
}: BuilderDesignSystemProxyFieldsOptions): BuilderDesignSystemProxyFields {
|
|
536
545
|
const title = projectName?.trim() || "Builder indexed design system";
|
|
537
546
|
const fallbackDescription =
|
|
@@ -540,6 +549,7 @@ export function createBuilderDesignSystemProxyFields({
|
|
|
540
549
|
const spacingKey = surface === "slides" ? "slidePadding" : "pagePadding";
|
|
541
550
|
const data = JSON.stringify({
|
|
542
551
|
source: "builder",
|
|
552
|
+
...(sourceKind ? { sourceKind } : {}),
|
|
543
553
|
builderDesignSystemId: result.designSystemId,
|
|
544
554
|
builderJobId: result.jobId,
|
|
545
555
|
builderProjectId: result.projectId,
|
|
@@ -611,8 +621,19 @@ export function parseBuilderDesignSystemProxyReference(
|
|
|
611
621
|
if (value.source !== "builder") return null;
|
|
612
622
|
if (typeof value.builderDesignSystemId !== "string") return null;
|
|
613
623
|
if (typeof value.builderJobId !== "string") return null;
|
|
624
|
+
const sourceKind = value.sourceKind;
|
|
625
|
+
if (
|
|
626
|
+
sourceKind !== undefined &&
|
|
627
|
+
sourceKind !== "figma" &&
|
|
628
|
+
sourceKind !== "code" &&
|
|
629
|
+
sourceKind !== "github" &&
|
|
630
|
+
sourceKind !== "mixed"
|
|
631
|
+
) {
|
|
632
|
+
return null;
|
|
633
|
+
}
|
|
614
634
|
return {
|
|
615
635
|
source: "builder",
|
|
636
|
+
...(sourceKind ? { sourceKind } : {}),
|
|
616
637
|
builderDesignSystemId: value.builderDesignSystemId,
|
|
617
638
|
builderJobId: value.builderJobId,
|
|
618
639
|
builderProjectId:
|
|
@@ -280,8 +280,23 @@ interface BuilderResolvedCredentials {
|
|
|
280
280
|
source: Exclude<BuilderCredentialSource, "env">;
|
|
281
281
|
}
|
|
282
282
|
|
|
283
|
-
|
|
284
|
-
|
|
283
|
+
/**
|
|
284
|
+
* A complete key pair is not necessarily a usable one: the gateway may have
|
|
285
|
+
* already rejected this exact private+public pair (see
|
|
286
|
+
* `recordBuilderCredentialAuthFailure`). Treating a marked-bad pair as
|
|
287
|
+
* "complete" is how a rejected credential got resent on every subsequent
|
|
288
|
+
* turn forever — this is the read side of that write, symmetric with
|
|
289
|
+
* `resolveUsableProviderSecret` for every non-Builder provider.
|
|
290
|
+
*/
|
|
291
|
+
async function isCompleteBuilderConnection(
|
|
292
|
+
creds: BuilderResolvedCredentials,
|
|
293
|
+
): Promise<boolean> {
|
|
294
|
+
if (!creds.privateKey || !creds.publicKey) return false;
|
|
295
|
+
const failure = await getBuilderCredentialAuthFailure({
|
|
296
|
+
privateKey: creds.privateKey,
|
|
297
|
+
publicKey: creds.publicKey,
|
|
298
|
+
});
|
|
299
|
+
return !failure;
|
|
285
300
|
}
|
|
286
301
|
|
|
287
302
|
function readOptionalBuilderBoolean(
|
|
@@ -524,14 +539,14 @@ async function resolveScopedBuilderCredentials(): Promise<ScopedBuilderCredentia
|
|
|
524
539
|
let orgLookupCause: unknown;
|
|
525
540
|
try {
|
|
526
541
|
const { readAppSecrets } = await import("../secrets/storage.js");
|
|
527
|
-
const traceScope = (
|
|
542
|
+
const traceScope = async (
|
|
528
543
|
creds: BuilderResolvedCredentials,
|
|
529
544
|
scopeId: string,
|
|
530
545
|
extra = "",
|
|
531
546
|
) => {
|
|
532
547
|
if (!traceLookup) return;
|
|
533
548
|
console.log(
|
|
534
|
-
`[builder-credential] scope=${creds.source} scopeId=${scopeId} email=${email}${extra} complete=${isCompleteBuilderConnection(creds)} private=${Boolean(creds.privateKey)} public=${Boolean(creds.publicKey)}`,
|
|
549
|
+
`[builder-credential] scope=${creds.source} scopeId=${scopeId} email=${email}${extra} complete=${await isCompleteBuilderConnection(creds)} private=${Boolean(creds.privateKey)} public=${Boolean(creds.publicKey)}`,
|
|
535
550
|
);
|
|
536
551
|
};
|
|
537
552
|
|
|
@@ -540,8 +555,8 @@ async function resolveScopedBuilderCredentials(): Promise<ScopedBuilderCredentia
|
|
|
540
555
|
"user",
|
|
541
556
|
email,
|
|
542
557
|
);
|
|
543
|
-
traceScope(userCreds, email);
|
|
544
|
-
if (isCompleteBuilderConnection(userCreds)) {
|
|
558
|
+
await traceScope(userCreds, email);
|
|
559
|
+
if (await isCompleteBuilderConnection(userCreds)) {
|
|
545
560
|
return { creds: userCreds, lookupFailed: false };
|
|
546
561
|
}
|
|
547
562
|
|
|
@@ -563,8 +578,8 @@ async function resolveScopedBuilderCredentials(): Promise<ScopedBuilderCredentia
|
|
|
563
578
|
"org",
|
|
564
579
|
orgId,
|
|
565
580
|
);
|
|
566
|
-
traceScope(orgCreds, orgId, ` orgSource=${orgSource}`);
|
|
567
|
-
if (isCompleteBuilderConnection(orgCreds)) {
|
|
581
|
+
await traceScope(orgCreds, orgId, ` orgSource=${orgSource}`);
|
|
582
|
+
if (await isCompleteBuilderConnection(orgCreds)) {
|
|
568
583
|
return { creds: orgCreds, lookupFailed: false };
|
|
569
584
|
}
|
|
570
585
|
|
|
@@ -574,8 +589,8 @@ async function resolveScopedBuilderCredentials(): Promise<ScopedBuilderCredentia
|
|
|
574
589
|
"workspace",
|
|
575
590
|
orgId,
|
|
576
591
|
);
|
|
577
|
-
traceScope(workspaceCreds, orgId, ` orgSource=${orgSource}`);
|
|
578
|
-
if (isCompleteBuilderConnection(workspaceCreds)) {
|
|
592
|
+
await traceScope(workspaceCreds, orgId, ` orgSource=${orgSource}`);
|
|
593
|
+
if (await isCompleteBuilderConnection(workspaceCreds)) {
|
|
579
594
|
return { creds: workspaceCreds, lookupFailed: false };
|
|
580
595
|
}
|
|
581
596
|
}
|
|
@@ -594,12 +609,12 @@ async function resolveScopedBuilderCredentials(): Promise<ScopedBuilderCredentia
|
|
|
594
609
|
"workspace",
|
|
595
610
|
soloScopeId,
|
|
596
611
|
);
|
|
597
|
-
traceScope(
|
|
612
|
+
await traceScope(
|
|
598
613
|
soloCreds,
|
|
599
614
|
soloScopeId,
|
|
600
615
|
` orgId=${orgId ?? "(none)"} orgSource=${orgSource}`,
|
|
601
616
|
);
|
|
602
|
-
if (isCompleteBuilderConnection(soloCreds)) {
|
|
617
|
+
if (await isCompleteBuilderConnection(soloCreds)) {
|
|
603
618
|
return { creds: soloCreds, lookupFailed: false };
|
|
604
619
|
}
|
|
605
620
|
} catch (err) {
|
|
@@ -791,6 +806,30 @@ export async function resolveBuilderCredentialsDetailed(): Promise<BuilderCreden
|
|
|
791
806
|
readDeployCredentialEnv("BUILDER_IS_FREE_ACCOUNT"),
|
|
792
807
|
)
|
|
793
808
|
: null;
|
|
809
|
+
// The deploy-level fallback is a candidate scope like any other: a pair the
|
|
810
|
+
// gateway already rejected must not be handed back as the "configured"
|
|
811
|
+
// credential just because no per-user/org row exists to shadow it.
|
|
812
|
+
const envFailure =
|
|
813
|
+
privateKey && publicKey
|
|
814
|
+
? await getBuilderCredentialAuthFailure({ privateKey, publicKey })
|
|
815
|
+
: null;
|
|
816
|
+
if (envFailure) {
|
|
817
|
+
return {
|
|
818
|
+
privateKey: null,
|
|
819
|
+
publicKey: null,
|
|
820
|
+
userId: null,
|
|
821
|
+
orgName: null,
|
|
822
|
+
orgKind: null,
|
|
823
|
+
subscription: null,
|
|
824
|
+
subscriptionLevel: null,
|
|
825
|
+
subscriptionName: null,
|
|
826
|
+
isEnterprise: null,
|
|
827
|
+
isFreeAccount: null,
|
|
828
|
+
source: null,
|
|
829
|
+
lookupFailed,
|
|
830
|
+
cause,
|
|
831
|
+
};
|
|
832
|
+
}
|
|
794
833
|
return {
|
|
795
834
|
privateKey,
|
|
796
835
|
publicKey,
|
|
@@ -514,6 +514,7 @@ export {
|
|
|
514
514
|
type BuilderDesignSystemProxyFields,
|
|
515
515
|
type BuilderDesignSystemProxyFieldsOptions,
|
|
516
516
|
type BuilderDesignSystemProxyReference,
|
|
517
|
+
type BuilderDesignSystemSourceKind,
|
|
517
518
|
} from "./builder-design-systems.js";
|
|
518
519
|
export {
|
|
519
520
|
getBuilderBranchProjectId,
|
|
@@ -3264,6 +3264,32 @@ ${
|
|
|
3264
3264
|
var RESEND_VERIFICATION_COOLDOWN_SECONDS = 60;
|
|
3265
3265
|
var resendVerificationCooldownUntil = 0;
|
|
3266
3266
|
var resendVerificationCooldownTimer = null;
|
|
3267
|
+
var PENDING_SIGNUP_EMAIL_STORAGE_KEY = 'an.onboarding.pendingSignupEmail';
|
|
3268
|
+
// The verification link can open in a new tab, so in-memory pending state
|
|
3269
|
+
// cannot be the only source of the account email. Keep only the address,
|
|
3270
|
+
// never the password, for the manual-login fallback.
|
|
3271
|
+
function pendingSignupEmailStorageKey() {
|
|
3272
|
+
return PENDING_SIGNUP_EMAIL_STORAGE_KEY + ':' + (__anBasePath() || '/');
|
|
3273
|
+
}
|
|
3274
|
+
function rememberPendingSignupEmail(email) {
|
|
3275
|
+
try {
|
|
3276
|
+
if (email) localStorage.setItem(pendingSignupEmailStorageKey(), email);
|
|
3277
|
+
else localStorage.removeItem(pendingSignupEmailStorageKey());
|
|
3278
|
+
// coercion-ok: localStorage is optional; the in-memory and form fallbacks remain available.
|
|
3279
|
+
} catch (e) {}
|
|
3280
|
+
}
|
|
3281
|
+
function readRememberedPendingSignupEmail() {
|
|
3282
|
+
try {
|
|
3283
|
+
var email = localStorage.getItem(pendingSignupEmailStorageKey()) || '';
|
|
3284
|
+
return __anIsValidAuthEmail(email) ? __anNormalizeAuthEmail(email) : '';
|
|
3285
|
+
// coercion-ok: localStorage is optional; callers fall back to the in-memory or form value.
|
|
3286
|
+
} catch (e) {
|
|
3287
|
+
return '';
|
|
3288
|
+
}
|
|
3289
|
+
}
|
|
3290
|
+
function clearRememberedPendingSignupEmail() {
|
|
3291
|
+
rememberPendingSignupEmail('');
|
|
3292
|
+
}
|
|
3267
3293
|
function setActiveTab(name, opts) {
|
|
3268
3294
|
if (name !== 'signup' && name !== 'login') return;
|
|
3269
3295
|
var form = document.getElementById(name + '-form');
|
|
@@ -3283,6 +3309,7 @@ ${
|
|
|
3283
3309
|
function showVerificationStep(email, password) {
|
|
3284
3310
|
pendingSignupEmail = email || '';
|
|
3285
3311
|
pendingSignupPassword = password || '';
|
|
3312
|
+
rememberPendingSignupEmail(pendingSignupEmail);
|
|
3286
3313
|
tabs.forEach(function(x) { x.classList.remove('active'); });
|
|
3287
3314
|
forms.forEach(function(x) { x.classList.remove('active'); });
|
|
3288
3315
|
var card = document.querySelector('.card');
|
|
@@ -3313,7 +3340,7 @@ ${
|
|
|
3313
3340
|
function getPendingSignupEmail() {
|
|
3314
3341
|
var signupEmail = document.getElementById('s-email');
|
|
3315
3342
|
var loginEmail = document.getElementById('l-email');
|
|
3316
|
-
return (pendingSignupEmail || (signupEmail && signupEmail.value) || (loginEmail && loginEmail.value) || '').trim();
|
|
3343
|
+
return (pendingSignupEmail || readRememberedPendingSignupEmail() || (signupEmail && signupEmail.value) || (loginEmail && loginEmail.value) || '').trim();
|
|
3317
3344
|
}
|
|
3318
3345
|
function getPendingSignupPassword() {
|
|
3319
3346
|
var signupPassword = document.getElementById('s-pass');
|
|
@@ -3366,6 +3393,7 @@ ${
|
|
|
3366
3393
|
body: JSON.stringify({ email: email, password: password }),
|
|
3367
3394
|
});
|
|
3368
3395
|
if (res.ok) {
|
|
3396
|
+
clearRememberedPendingSignupEmail();
|
|
3369
3397
|
__anRedirectToSignedInApp();
|
|
3370
3398
|
return { ok: true };
|
|
3371
3399
|
}
|
|
@@ -3398,6 +3426,7 @@ ${
|
|
|
3398
3426
|
});
|
|
3399
3427
|
var data = await res.json().catch(function() { return {}; });
|
|
3400
3428
|
if (res.ok && data && data.email && !data.error) {
|
|
3429
|
+
clearRememberedPendingSignupEmail();
|
|
3401
3430
|
__anRedirectToSignedInApp();
|
|
3402
3431
|
return;
|
|
3403
3432
|
}
|
|
@@ -3464,7 +3493,7 @@ ${
|
|
|
3464
3493
|
async function resendVerificationEmail() {
|
|
3465
3494
|
var btn = document.getElementById('resend-verification');
|
|
3466
3495
|
var msg = document.getElementById('verify-msg');
|
|
3467
|
-
var email =
|
|
3496
|
+
var email = getPendingSignupEmail();
|
|
3468
3497
|
if (!email) return;
|
|
3469
3498
|
if (resendVerificationCooldownUntil > Date.now()) {
|
|
3470
3499
|
updateResendVerificationCooldown();
|
|
@@ -3533,6 +3562,9 @@ ${
|
|
|
3533
3562
|
setActiveTab(initial, { persist: false });
|
|
3534
3563
|
try {
|
|
3535
3564
|
if (__anIsVerifiedRedirectSuccess()) {
|
|
3565
|
+
var rememberedEmail = readRememberedPendingSignupEmail();
|
|
3566
|
+
var loginEmail = document.getElementById('l-email');
|
|
3567
|
+
if (loginEmail && rememberedEmail) loginEmail.value = rememberedEmail;
|
|
3536
3568
|
var msg = document.getElementById('l-msg');
|
|
3537
3569
|
if (msg) {
|
|
3538
3570
|
msg.textContent = __anT('emailVerifiedFinishing');
|
|
@@ -3591,6 +3623,7 @@ ${
|
|
|
3591
3623
|
body: JSON.stringify({ email: email, password: pass }),
|
|
3592
3624
|
});
|
|
3593
3625
|
if (loginRes.ok) {
|
|
3626
|
+
clearRememberedPendingSignupEmail();
|
|
3594
3627
|
msg.textContent = __anT('accountCreatedSigningIn');
|
|
3595
3628
|
msg.classList.add('show', 'success');
|
|
3596
3629
|
__anRedirectToSignedInApp();
|
|
@@ -3630,6 +3663,7 @@ ${
|
|
|
3630
3663
|
var backToSignup = document.getElementById('back-to-signup');
|
|
3631
3664
|
if (backToSignup) backToSignup.addEventListener('click', function(e) {
|
|
3632
3665
|
e.preventDefault();
|
|
3666
|
+
clearRememberedPendingSignupEmail();
|
|
3633
3667
|
setActiveTab('signup', { persist: true });
|
|
3634
3668
|
var email = document.getElementById('s-email');
|
|
3635
3669
|
setTimeout(function() { if (email) email.focus(); }, 0);
|
|
@@ -3724,6 +3758,7 @@ ${
|
|
|
3724
3758
|
}),
|
|
3725
3759
|
});
|
|
3726
3760
|
if (res.ok) {
|
|
3761
|
+
clearRememberedPendingSignupEmail();
|
|
3727
3762
|
__anRedirectToSignedInApp();
|
|
3728
3763
|
return;
|
|
3729
3764
|
}
|
|
@@ -156,7 +156,7 @@ export function stepDownReasoningEffort(
|
|
|
156
156
|
return REASONING_EFFORT_STEP_DOWN[effort] ?? effort;
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
function isGPTReasoningModel(model: string) {
|
|
159
|
+
export function isGPTReasoningModel(model: string) {
|
|
160
160
|
const id = model.toLowerCase().replace(/^openai\//, "");
|
|
161
161
|
return /^gpt-5/.test(id) || /^o\d/.test(id);
|
|
162
162
|
}
|
|
@@ -17,6 +17,17 @@ Agents call other agents over A2A, a JSON-RPC protocol for discovery and
|
|
|
17
17
|
delegation. Use it when work belongs to a different agent entirely — not the
|
|
18
18
|
local agent chat.
|
|
19
19
|
|
|
20
|
+
**No workarounds when A2A feels flaky.** The strong default is `ask_app` (or
|
|
21
|
+
`call-agent`) working reliably, full stop — not apps reaching around it. Do
|
|
22
|
+
not have app A generate and execute raw SQL against app B's database, and do
|
|
23
|
+
not expose B's internal tools directly to A as a substitute for delegation.
|
|
24
|
+
The receiving agent has context, skills, and guardrails the caller doesn't;
|
|
25
|
+
bypassing it to work around a flaky A2A call reintroduces exactly the bugs A2A
|
|
26
|
+
exists to prevent, and makes the real reliability problem invisible instead of
|
|
27
|
+
fixing it. If A2A delegation is unreliable, fix A2A — file it as a bug in the
|
|
28
|
+
delegation path (timeout handling, retries, typed terminal states), don't
|
|
29
|
+
route around it app by app.
|
|
30
|
+
|
|
20
31
|
Connecting app A to app B is two independent things, and both must be true:
|
|
21
32
|
|
|
22
33
|
1. **B is registered on A** as a `remote-agents/<id>.json` resource.
|