@agent-native/core 0.132.1 → 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 +198 -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/chat-threads/store.ts +42 -0
- 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/client/use-chat-threads.ts +76 -16
- 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 +46 -10
- 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-30-meeting-microphone-transcription-works-reliably-from-the-fir.md +6 -0
- 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/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +13 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +2 -0
- package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +25 -132
- 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/.generated/bridge/editor-chrome.generated.ts +5 -0
- 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/design/KeyboardShortcutsPanel.tsx +5 -3
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +23 -0
- package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +3 -0
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +21 -4
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +11 -7
- 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-30-fixed-the-keyboard-shortcuts-panel-not-opening-with-ctrl-shi.md +6 -0
- 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/chat-threads/store.d.ts +13 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +35 -0
- package/dist/chat-threads/store.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/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +66 -16
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.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/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/notifications/routes.d.ts +6 -6
- 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 +38 -9
- 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/chat-threads/store.ts +42 -0
- 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/client/use-chat-threads.ts +76 -16
- 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 +46 -10
- 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
|
@@ -167,6 +167,21 @@ function normalizeLookupHostname(hostname: string): string {
|
|
|
167
167
|
return hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
+
function loopbackHostnameVariants(hostname: string): string[] {
|
|
171
|
+
const normalized = normalizeLookupHostname(hostname);
|
|
172
|
+
if (
|
|
173
|
+
normalized !== "localhost" &&
|
|
174
|
+
normalized !== "127.0.0.1" &&
|
|
175
|
+
normalized !== "::1"
|
|
176
|
+
) {
|
|
177
|
+
return [normalized];
|
|
178
|
+
}
|
|
179
|
+
// Local workspace manifests can identify the same child server as
|
|
180
|
+
// localhost, 127.0.0.1, or ::1. They are equivalent only for loopback; do
|
|
181
|
+
// not alias arbitrary private or public hostnames.
|
|
182
|
+
return ["localhost", "127.0.0.1", "::1"];
|
|
183
|
+
}
|
|
184
|
+
|
|
170
185
|
function normalizeAllowedPrivateOriginKeys(
|
|
171
186
|
origins: readonly string[],
|
|
172
187
|
): Set<string> {
|
|
@@ -178,7 +193,30 @@ function normalizeAllowedPrivateOriginKeys(
|
|
|
178
193
|
continue;
|
|
179
194
|
}
|
|
180
195
|
const port = parsed.port || (parsed.protocol === "https:" ? "443" : "80");
|
|
181
|
-
|
|
196
|
+
for (const hostname of loopbackHostnameVariants(parsed.hostname)) {
|
|
197
|
+
keys.add(`${hostname}:${port}`);
|
|
198
|
+
}
|
|
199
|
+
} catch {
|
|
200
|
+
// coercion-ok: malformed deployment configuration is omitted, preserving the fail-closed private-IP guard.
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return keys;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function normalizeAllowedPrivateOriginOriginKeys(
|
|
207
|
+
origins: readonly string[],
|
|
208
|
+
): Set<string> {
|
|
209
|
+
const keys = new Set<string>();
|
|
210
|
+
for (const origin of origins) {
|
|
211
|
+
try {
|
|
212
|
+
const parsed = new URL(origin);
|
|
213
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
const port = parsed.port || (parsed.protocol === "https:" ? "443" : "80");
|
|
217
|
+
for (const hostname of loopbackHostnameVariants(parsed.hostname)) {
|
|
218
|
+
keys.add(`${parsed.protocol}//${hostname}:${port}`);
|
|
219
|
+
}
|
|
182
220
|
} catch {
|
|
183
221
|
// Ignore malformed deployment configuration and retain the private-IP guard.
|
|
184
222
|
}
|
|
@@ -309,21 +347,17 @@ export async function ssrfSafeFetch(
|
|
|
309
347
|
const dispatcher =
|
|
310
348
|
(await createSsrfSafeDispatcher(options.allowedPrivateOrigins)) ??
|
|
311
349
|
undefined;
|
|
312
|
-
const allowedPrivateOrigins =
|
|
313
|
-
|
|
314
|
-
.map((origin) => {
|
|
315
|
-
try {
|
|
316
|
-
return new URL(origin).origin;
|
|
317
|
-
} catch {
|
|
318
|
-
return "";
|
|
319
|
-
}
|
|
320
|
-
})
|
|
321
|
-
.filter(Boolean),
|
|
350
|
+
const allowedPrivateOrigins = normalizeAllowedPrivateOriginOriginKeys(
|
|
351
|
+
options.allowedPrivateOrigins ?? [],
|
|
322
352
|
);
|
|
323
353
|
const isAllowedPrivateOrigin = (candidate: string): boolean => {
|
|
324
354
|
if (allowedPrivateOrigins.size === 0) return false;
|
|
325
355
|
try {
|
|
326
|
-
|
|
356
|
+
const parsed = new URL(candidate);
|
|
357
|
+
const port = parsed.port || (parsed.protocol === "https:" ? "443" : "80");
|
|
358
|
+
return allowedPrivateOrigins.has(
|
|
359
|
+
`${parsed.protocol}//${normalizeLookupHostname(parsed.hostname)}:${port}`,
|
|
360
|
+
);
|
|
327
361
|
} catch {
|
|
328
362
|
return false;
|
|
329
363
|
}
|
|
@@ -11,7 +11,7 @@ import { consumeIntegrationAwaitingInput } from "../awaiting-input-store.js";
|
|
|
11
11
|
import { createIntegrationControl } from "../controls-store.js";
|
|
12
12
|
import {
|
|
13
13
|
getActiveIntegrationInstallationByKey,
|
|
14
|
-
|
|
14
|
+
listActiveIntegrationInstallationsForTenant,
|
|
15
15
|
listIntegrationInstallations,
|
|
16
16
|
resolveIntegrationTokenBundle,
|
|
17
17
|
} from "../installations-store.js";
|
|
@@ -666,13 +666,18 @@ export function slackAdapter(
|
|
|
666
666
|
channelId: target.destination,
|
|
667
667
|
threadTs: target.threadRef,
|
|
668
668
|
teamId: target.tenantId,
|
|
669
|
+
installationKey: target.installationKey,
|
|
669
670
|
},
|
|
670
671
|
tenantId: target.tenantId,
|
|
671
672
|
timestamp: Date.now(),
|
|
672
673
|
};
|
|
673
674
|
const token = await resolveBotToken(targetContext);
|
|
674
675
|
if (!token) {
|
|
675
|
-
console.error(
|
|
676
|
+
console.error(
|
|
677
|
+
"[slack] no bot token for outbound target" +
|
|
678
|
+
(target.tenantId ? ` (tenant ${target.tenantId})` : "") +
|
|
679
|
+
"; set SLACK_BOT_TOKEN or pass installationKey to name the app",
|
|
680
|
+
);
|
|
676
681
|
return;
|
|
677
682
|
}
|
|
678
683
|
|
|
@@ -808,25 +813,42 @@ async function resolveManagedSlackBotToken(
|
|
|
808
813
|
typeof incoming.platformContext.enterpriseId === "string"
|
|
809
814
|
? incoming.platformContext.enterpriseId
|
|
810
815
|
: undefined;
|
|
816
|
+
const installationKeyHint =
|
|
817
|
+
typeof incoming.platformContext.installationKey === "string"
|
|
818
|
+
? incoming.platformContext.installationKey
|
|
819
|
+
: undefined;
|
|
811
820
|
if (!teamId && !enterpriseId) return undefined;
|
|
812
821
|
try {
|
|
813
|
-
let installation =
|
|
822
|
+
let installation = installationKeyHint
|
|
814
823
|
? await getActiveIntegrationInstallationByKey(
|
|
815
824
|
"slack",
|
|
816
|
-
|
|
825
|
+
installationKeyHint,
|
|
817
826
|
)
|
|
818
827
|
: null;
|
|
819
|
-
if (!installation &&
|
|
820
|
-
installation = await
|
|
828
|
+
if (!installation && apiAppId) {
|
|
829
|
+
installation = await getActiveIntegrationInstallationByKey(
|
|
821
830
|
"slack",
|
|
822
|
-
teamId,
|
|
831
|
+
slackInstallationKey({ teamId, enterpriseId, apiAppId }),
|
|
823
832
|
);
|
|
824
833
|
}
|
|
825
|
-
if (!installation && !apiAppId
|
|
826
|
-
|
|
834
|
+
if (!installation && !apiAppId) {
|
|
835
|
+
// Without an app id the tenant can match several connected Slack apps.
|
|
836
|
+
// Sending as an arbitrary one posts under the wrong bot identity, so
|
|
837
|
+
// only proceed when the tenant resolves to exactly one installation.
|
|
838
|
+
const tenant = teamId ?? enterpriseId!;
|
|
839
|
+
const candidates = await listActiveIntegrationInstallationsForTenant(
|
|
827
840
|
"slack",
|
|
828
|
-
|
|
841
|
+
tenant,
|
|
829
842
|
);
|
|
843
|
+
if (candidates.length > 1) {
|
|
844
|
+
console.error(
|
|
845
|
+
`[slack] ${candidates.length} connected Slack apps for tenant ${tenant}; ` +
|
|
846
|
+
`cannot choose one without an app id. Pass installationKey on the outbound target. ` +
|
|
847
|
+
`Candidates: ${candidates.map((c) => c.installationKey).join(", ")}`,
|
|
848
|
+
);
|
|
849
|
+
return undefined;
|
|
850
|
+
}
|
|
851
|
+
installation = candidates[0] ?? null;
|
|
830
852
|
}
|
|
831
853
|
const key =
|
|
832
854
|
installation?.installationKey ??
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isInBackgroundFunctionRuntime } from "../agent/durable-background.js";
|
|
1
2
|
import { createAnthropicEngine } from "../agent/engine/index.js";
|
|
2
3
|
import type { EngineMessage } from "../agent/engine/types.js";
|
|
3
4
|
import {
|
|
@@ -518,7 +519,17 @@ async function processComment(
|
|
|
518
519
|
signal,
|
|
519
520
|
},
|
|
520
521
|
undefined,
|
|
521
|
-
|
|
522
|
+
// Same omission the scheduled-job runner had: without this, a
|
|
523
|
+
// poller-driven reply inherits the interactive clamp (40s soft
|
|
524
|
+
// timeout, a no-progress backstop at 0.75x that, 6 continuations)
|
|
525
|
+
// even though no client is waiting on a response. Uses the runtime
|
|
526
|
+
// check rather than a hardcoded `true` — matching webhook-handler.ts
|
|
527
|
+
// in this same subsystem — because unlike the job runner there is no
|
|
528
|
+
// hard-abort cap here to bound a wider ceiling.
|
|
529
|
+
{
|
|
530
|
+
useHostedDefault: true,
|
|
531
|
+
backgroundFunction: isInBackgroundFunctionRuntime(),
|
|
532
|
+
},
|
|
522
533
|
),
|
|
523
534
|
);
|
|
524
535
|
},
|
|
@@ -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,
|
|
@@ -107,10 +109,12 @@ import type {
|
|
|
107
109
|
import { readAppStateForCurrentTab } from "../application-state/script-helpers.js";
|
|
108
110
|
import { runChatThreadDataMigrations } from "../chat-threads/migrations.js";
|
|
109
111
|
import {
|
|
112
|
+
adoptThreadScopeIfUnscoped,
|
|
110
113
|
createThread,
|
|
111
114
|
forkThread,
|
|
112
115
|
getThread,
|
|
113
116
|
registerChatThreadsShareable,
|
|
117
|
+
resolveRunThreadScope,
|
|
114
118
|
resolveThreadAccess,
|
|
115
119
|
listThreads,
|
|
116
120
|
searchThreads,
|
|
@@ -1614,13 +1618,17 @@ export function createAgentChatPlugin(
|
|
|
1614
1618
|
: await buildSchemaBlock(owner, databaseToolsMode);
|
|
1615
1619
|
const extra = await resolveExtraContext(context.event, owner);
|
|
1616
1620
|
|
|
1617
|
-
const
|
|
1618
|
-
options?.model
|
|
1619
|
-
|
|
1621
|
+
const model = resolveDelegatedRunModel(a2aEngine, {
|
|
1622
|
+
explicitModel: options?.model,
|
|
1623
|
+
storedModel: await getStoredModelForEngine(a2aEngine, {
|
|
1620
1624
|
appId: options?.appId,
|
|
1621
|
-
})
|
|
1622
|
-
|
|
1623
|
-
|
|
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
|
+
});
|
|
1624
1632
|
if (a2aRunContext) {
|
|
1625
1633
|
a2aRunContext.engine = a2aEngine;
|
|
1626
1634
|
a2aRunContext.model = model;
|
|
@@ -2538,11 +2546,16 @@ export function createAgentChatPlugin(
|
|
|
2538
2546
|
getRequestRunContext()?.owner ?? getRequestUserEmail();
|
|
2539
2547
|
if (!ownerEmail) return;
|
|
2540
2548
|
|
|
2549
|
+
const runScope = getRequestRunContext()?.chatScope ?? null;
|
|
2550
|
+
|
|
2541
2551
|
await withThreadDataLock(threadId, async () => {
|
|
2542
2552
|
let thread = await getThread(threadId);
|
|
2543
2553
|
if (!thread) {
|
|
2544
2554
|
try {
|
|
2545
|
-
thread = await createThread(ownerEmail, {
|
|
2555
|
+
thread = await createThread(ownerEmail, {
|
|
2556
|
+
id: threadId,
|
|
2557
|
+
scope: runScope,
|
|
2558
|
+
});
|
|
2546
2559
|
} catch {
|
|
2547
2560
|
thread = await getThread(threadId);
|
|
2548
2561
|
}
|
|
@@ -2566,6 +2579,14 @@ export function createAgentChatPlugin(
|
|
|
2566
2579
|
});
|
|
2567
2580
|
}
|
|
2568
2581
|
|
|
2582
|
+
const nextScope = resolveRunThreadScope(thread.scope, runScope);
|
|
2583
|
+
if (nextScope && nextScope !== thread.scope) {
|
|
2584
|
+
thread = {
|
|
2585
|
+
...thread,
|
|
2586
|
+
scope: await adoptThreadScopeIfUnscoped(threadId, nextScope),
|
|
2587
|
+
};
|
|
2588
|
+
}
|
|
2589
|
+
|
|
2569
2590
|
let repo: any;
|
|
2570
2591
|
try {
|
|
2571
2592
|
repo = JSON.parse(thread.threadData || "{}");
|
|
@@ -5878,7 +5899,15 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5878
5899
|
const attemptUnclaimedBackgroundRunRedispatch = async (row: {
|
|
5879
5900
|
id: string;
|
|
5880
5901
|
startedAt: number;
|
|
5902
|
+
hasDispatchPayload: boolean;
|
|
5881
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;
|
|
5882
5911
|
const { updateRunHeartbeat } = await import("../agent/run-store.js");
|
|
5883
5912
|
const { resolveAgentChatProcessRunDispatchPath } =
|
|
5884
5913
|
await import("../agent/durable-background.js");
|
|
@@ -5959,7 +5988,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5959
5988
|
// idempotent, re-checks staleness at UPDATE time and honours
|
|
5960
5989
|
// the in-flight grace, so it is safe on this cadence.
|
|
5961
5990
|
await reapAllStaleRuns().catch(() => {});
|
|
5962
|
-
let rows:
|
|
5991
|
+
let rows: UnclaimedBackgroundRunRow[];
|
|
5963
5992
|
try {
|
|
5964
5993
|
rows = await listUnclaimedBackgroundRunRows();
|
|
5965
5994
|
} catch {
|
|
@@ -6004,7 +6033,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
6004
6033
|
reapUnclaimedBackgroundRun,
|
|
6005
6034
|
shouldRedispatchUnclaimedBackgroundRun,
|
|
6006
6035
|
} = await import("../agent/run-store.js");
|
|
6007
|
-
let rows:
|
|
6036
|
+
let rows: UnclaimedBackgroundRunRow[];
|
|
6008
6037
|
try {
|
|
6009
6038
|
rows = await listUnclaimedBackgroundRunRows();
|
|
6010
6039
|
} catch {
|
|
@@ -6012,7 +6041,14 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
6012
6041
|
}
|
|
6013
6042
|
for (const row of rows) {
|
|
6014
6043
|
try {
|
|
6015
|
-
|
|
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
|
+
) {
|
|
6016
6052
|
await attemptUnclaimedBackgroundRunRedispatch(row);
|
|
6017
6053
|
continue;
|
|
6018
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:
|