@agent-native/core 0.113.0 → 0.114.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/agent-native.eject.json +164 -0
- package/corpus/README.md +3 -3
- package/corpus/core/CHANGELOG.md +20 -0
- package/corpus/core/README.md +61 -174
- package/corpus/core/agent-native.eject.json +164 -0
- package/corpus/core/docs/content/agent-native-toolkit.mdx +38 -0
- package/corpus/core/docs/content/package-lifecycle.mdx +54 -4
- package/corpus/core/package.json +15 -2
- package/corpus/core/src/cli/eject.ts +1594 -0
- package/corpus/core/src/cli/index.ts +16 -0
- package/corpus/core/src/client/build-compatibility.ts +77 -0
- package/corpus/core/src/client/index.ts +4 -0
- package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +8 -2
- package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +7 -2
- package/corpus/core/src/client/resources/ResourcesPanel.tsx +17 -3
- package/corpus/core/src/client/resources/index.ts +19 -0
- package/corpus/core/src/client/resources/mcp-integration-catalog.ts +9 -1
- package/corpus/core/src/client/resources/runtime.ts +1 -0
- package/corpus/core/src/client/route-chunk-recovery/index.ts +1 -0
- package/corpus/core/src/client/setup-connections/catalog.ts +6 -0
- package/corpus/core/src/client/setup-connections/index.ts +1 -0
- package/corpus/core/src/client/setup-connections/runtime.ts +1 -0
- package/corpus/core/src/client/use-action.ts +32 -1
- package/corpus/core/src/connections/catalog.ts +41 -24
- package/corpus/core/src/connections/index.ts +1 -0
- package/corpus/core/src/connections/runtime.ts +1 -0
- package/corpus/core/src/deploy/build.ts +4 -1
- package/corpus/core/src/eject/provider-api-definitions.ts +193 -0
- package/corpus/core/src/eject/remote-mcp-presets.ts +137 -0
- package/corpus/core/src/eject/setup-readiness-ui.tsx +29 -0
- package/corpus/core/src/eject/workspace-connections.ts +92 -0
- package/corpus/core/src/index.ts +1 -0
- package/corpus/core/src/integrations/adapter-overrides.ts +12 -0
- package/corpus/core/src/integrations/eject/messaging-adapters.ts +85 -0
- package/corpus/core/src/integrations/index.ts +5 -1
- package/corpus/core/src/integrations/plugin.ts +34 -12
- package/corpus/core/src/integrations/runtime.ts +1 -0
- package/corpus/core/src/integrations/types.ts +3 -1
- package/corpus/core/src/org/context.ts +56 -30
- package/corpus/core/src/package-lifecycle/eject-manifest.ts +345 -0
- package/corpus/core/src/package-lifecycle/index.ts +1 -0
- package/corpus/core/src/provider-api/index.ts +46 -12
- package/corpus/core/src/provider-api/runtime.ts +1 -0
- package/corpus/core/src/server/action-routes.ts +52 -2
- package/corpus/core/src/server/auth-plugin.ts +9 -4
- package/corpus/core/src/server/better-auth-instance.ts +5 -1
- package/corpus/core/src/setup-connections/index.ts +1 -0
- package/corpus/core/src/shared/mcp-embed-headers.ts +1 -1
- package/corpus/core/src/shared/merge-by-id.ts +14 -0
- package/corpus/core/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +15 -13
- package/corpus/core/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/core/src/templates/default/AGENTS.md +6 -5
- package/corpus/core/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +15 -13
- package/corpus/core/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/core/src/templates/headless/AGENTS.md +5 -4
- package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +15 -13
- package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +3 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/core/src/templates/workspace-core/AGENTS.md +4 -4
- package/corpus/core/src/templates/workspace-root/AGENTS.md +4 -4
- package/corpus/core/src/vite/client.ts +42 -2
- package/corpus/templates/analytics/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/templates/assets/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/templates/brain/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/templates/brain/actions/remediate-legacy-capture-audiences.ts +167 -0
- package/corpus/templates/brain/app/lib/brain-chat-readiness.ts +6 -0
- package/corpus/templates/brain/app/routes/_index.tsx +8 -0
- package/corpus/templates/brain/app/routes.ts +1 -0
- package/corpus/templates/brain/changelog/2026-07-19-ask-starts-immediately-when-builder-s-managed-ai-connection-.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-19-slack-and-granola-backfills-now-process-captures-concurrentl.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-19-source-review-settings-now-control-knowledge-approval.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-19-the-manage-agent-page-now-opens-correctly-from-brain-navigat.md +6 -0
- package/corpus/templates/brain/server/db/schema.ts +3 -0
- package/corpus/templates/brain/server/lib/brain.ts +41 -2
- package/corpus/templates/brain/server/lib/connectors.ts +379 -113
- package/corpus/templates/brain/server/lib/meeting-audience.ts +38 -0
- package/corpus/templates/brain/server/plugins/db.ts +10 -0
- package/corpus/templates/brain/server/routes/api/_agent-native/brain/ingest.post.ts +6 -4
- package/corpus/templates/calendar/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +15 -13
- package/corpus/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/templates/chat/AGENTS.md +3 -2
- package/corpus/templates/clips/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/templates/content/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/templates/content/AGENTS.md +2 -0
- package/corpus/templates/content/actions/_content-database-personal-view.ts +49 -5
- package/corpus/templates/content/actions/_content-document-access.ts +21 -0
- package/corpus/templates/content/actions/_content-favorites.ts +91 -0
- package/corpus/templates/content/actions/_content-files.ts +79 -23
- package/corpus/templates/content/actions/_content-sidebar-state.ts +24 -0
- package/corpus/templates/content/actions/_content-space-access.ts +15 -17
- package/corpus/templates/content/actions/_content-space-catalog-guards.ts +20 -0
- package/corpus/templates/content/actions/_content-spaces.ts +364 -167
- package/corpus/templates/content/actions/_database-source-utils.ts +8 -0
- package/corpus/templates/content/actions/_database-utils.ts +249 -15
- package/corpus/templates/content/actions/_delete-content-space.ts +84 -0
- package/corpus/templates/content/actions/_files-system-properties.ts +499 -0
- package/corpus/templates/content/actions/_local-file-documents.ts +0 -1
- package/corpus/templates/content/actions/_property-utils.ts +18 -9
- package/corpus/templates/content/actions/bind-content-database-source-field.ts +3 -0
- package/corpus/templates/content/actions/configure-document-property.ts +3 -0
- package/corpus/templates/content/actions/create-content-database.ts +2 -2
- package/corpus/templates/content/actions/create-content-space.ts +34 -0
- package/corpus/templates/content/actions/create-document.ts +4 -1
- package/corpus/templates/content/actions/delete-content-space.ts +19 -0
- package/corpus/templates/content/actions/delete-database-items.ts +28 -1
- package/corpus/templates/content/actions/delete-document-property.ts +3 -0
- package/corpus/templates/content/actions/delete-document.ts +39 -2
- package/corpus/templates/content/actions/duplicate-database-item.ts +6 -0
- package/corpus/templates/content/actions/duplicate-database-items.ts +6 -0
- package/corpus/templates/content/actions/duplicate-document-property.ts +3 -0
- package/corpus/templates/content/actions/get-content-database.ts +11 -2
- package/corpus/templates/content/actions/get-content-sidebar-state.ts +23 -0
- package/corpus/templates/content/actions/get-document.ts +32 -7
- package/corpus/templates/content/actions/import-content-source.ts +33 -1
- package/corpus/templates/content/actions/list-content-spaces.ts +34 -2
- package/corpus/templates/content/actions/list-documents.ts +39 -7
- package/corpus/templates/content/actions/reorder-document-property.ts +9 -0
- package/corpus/templates/content/actions/set-document-property.ts +41 -23
- package/corpus/templates/content/actions/share-local-file-document.ts +15 -0
- package/corpus/templates/content/actions/submit-content-database-form.ts +7 -0
- package/corpus/templates/content/actions/sync-local-folder-source.ts +14 -0
- package/corpus/templates/content/actions/update-content-database-view.ts +1 -0
- package/corpus/templates/content/actions/update-content-sidebar-state.ts +27 -0
- package/corpus/templates/content/actions/update-document.ts +158 -66
- package/corpus/templates/content/app/components/EmptyState.tsx +4 -57
- package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +8 -1
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +519 -178
- package/corpus/templates/content/app/components/editor/DocumentInfoPanel.tsx +39 -0
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +1 -1
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +266 -7
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +430 -152
- package/corpus/templates/content/app/components/editor/database/sidebar.tsx +467 -66
- package/corpus/templates/content/app/components/editor/database/view-config.ts +9 -3
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +720 -196
- package/corpus/templates/content/app/components/sidebar/DocumentTreeItem.tsx +173 -1
- package/corpus/templates/content/app/components/sidebar/document-sidebar-sections.ts +1 -1
- package/corpus/templates/content/app/components/sidebar/select-content-space.ts +91 -16
- package/corpus/templates/content/app/entry.client.tsx +5 -1
- package/corpus/templates/content/app/hooks/use-content-database.ts +84 -3
- package/corpus/templates/content/app/hooks/use-content-spaces.ts +60 -2
- package/corpus/templates/content/app/hooks/use-create-page.ts +30 -0
- package/corpus/templates/content/app/hooks/use-documents.ts +270 -19
- package/corpus/templates/content/app/i18n-data.ts +243 -20
- package/corpus/templates/content/app/lib/local-folder-picker-safety.ts +54 -0
- package/corpus/templates/content/app/lib/local-folder-picker-support.ts +18 -0
- package/corpus/templates/content/app/routes/_app.favorites.tsx +30 -0
- package/corpus/templates/content/app/routes/_app.local-files.tsx +18 -6
- package/corpus/templates/content/changelog/2026-07-17-workspace-files-now-stay-in-a-loading-state-until-automatic-.md +6 -0
- package/corpus/templates/content/changelog/2026-07-17-workspace-switching-now-opens-the-selected-files-database-pr.md +6 -0
- package/corpus/templates/content/changelog/2026-07-17-workspaces-now-expand-above-their-own-files-list-without-dup.md +6 -0
- package/corpus/templates/content/changelog/2026-07-18-create-named-workspaces-each-with-its-own-private-files-data.md +6 -0
- package/corpus/templates/content/changelog/2026-07-18-favorites-align-with-workspace-and-file-rows-in-the-sidebar.md +6 -0
- package/corpus/templates/content/changelog/2026-07-18-local-folder-selection-no-longer-invokes-the-unsafe-native-p.md +6 -0
- package/corpus/templates/content/changelog/2026-07-18-made-content-workspaces-independently-expandable-restored-or.md +6 -0
- package/corpus/templates/content/changelog/2026-07-18-page-details-now-live-in-a-shared-info-and-comments-rail-dat.md +6 -0
- package/corpus/templates/content/changelog/2026-07-18-workspace-database-views-now-control-sidebar-workspace-navig.md +6 -0
- package/corpus/templates/content/changelog/2026-07-18-workspace-navigation-now-aligns-favorites-with-workspace-pag.md +6 -0
- package/corpus/templates/content/changelog/2026-07-19-favorites-now-open-as-a-table-and-compact-breadcrumbs-make-w.md +6 -0
- package/corpus/templates/content/changelog/2026-07-19-files-databases-now-start-unfiltered-sidebar-rows-exactly-fo.md +6 -0
- package/corpus/templates/content/changelog/2026-07-19-sidebar-page-trees-now-open-only-when-expanded-remember-thei.md +6 -0
- package/corpus/templates/content/changelog/2026-07-19-workspace-file-databases-now-use-the-workspace-name-open-as-.md +6 -0
- package/corpus/templates/content/changelog/2026-07-19-workspace-navigation-now-stays-stable-on-hover-uses-folder-i.md +6 -0
- package/corpus/templates/content/changelog/2026-07-19-workspace-rows-now-use-folder-icons-and-deleting-a-user-crea.md +6 -0
- package/corpus/templates/content/changelog/2026-07-19-workspaces-can-be-created-without-leaving-the-workspaces-dat.md +6 -0
- package/corpus/templates/content/e2e/global-setup.ts +3 -2
- package/corpus/templates/content/parity/matrix.md +28 -28
- package/corpus/templates/content/parity/matrix.ts +8 -2
- package/corpus/templates/content/server/db/index.ts +1 -0
- package/corpus/templates/content/server/db/schema.ts +10 -0
- package/corpus/templates/content/server/lib/documents.ts +12 -7
- package/corpus/templates/content/server/plugins/db.ts +17 -0
- package/corpus/templates/content/shared/api.ts +9 -0
- package/corpus/templates/content/shared/database-form.ts +11 -2
- package/corpus/templates/content/vite.config.ts +1 -0
- package/corpus/templates/design/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/templates/dispatch/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/templates/forms/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/templates/macros/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/templates/mail/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/templates/plan/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/templates/slides/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +15 -13
- package/corpus/templates/tasks/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/corpus/templates/tasks/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/corpus/toolkit/CHANGELOG.md +6 -0
- package/corpus/toolkit/agent-native.eject.json +411 -0
- package/corpus/toolkit/package.json +5 -2
- package/dist/cli/eject.d.ts +21 -0
- package/dist/cli/eject.d.ts.map +1 -0
- package/dist/cli/eject.js +1145 -0
- package/dist/cli/eject.js.map +1 -0
- package/dist/cli/index.js +15 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/client/build-compatibility.d.ts +11 -0
- package/dist/client/build-compatibility.d.ts.map +1 -0
- package/dist/client/build-compatibility.js +56 -0
- package/dist/client/build-compatibility.js.map +1 -0
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/resources/McpConnectionSuggestion.d.ts +4 -3
- package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
- package/dist/client/resources/McpConnectionSuggestion.js +3 -3
- package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.d.ts +4 -3
- package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.js +2 -2
- package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts +4 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +9 -7
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/index.d.ts +3 -0
- package/dist/client/resources/index.d.ts.map +1 -1
- package/dist/client/resources/index.js +3 -0
- package/dist/client/resources/index.js.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.d.ts +2 -1
- package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.js +6 -2
- package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
- package/dist/client/resources/runtime.d.ts +2 -0
- package/dist/client/resources/runtime.d.ts.map +1 -0
- package/dist/client/resources/runtime.js +2 -0
- package/dist/client/resources/runtime.js.map +1 -0
- package/dist/client/route-chunk-recovery/index.d.ts +1 -0
- package/dist/client/route-chunk-recovery/index.d.ts.map +1 -1
- package/dist/client/route-chunk-recovery/index.js +1 -0
- package/dist/client/route-chunk-recovery/index.js.map +1 -1
- package/dist/client/setup-connections/catalog.d.ts +2 -0
- package/dist/client/setup-connections/catalog.d.ts.map +1 -0
- package/dist/client/setup-connections/catalog.js +7 -0
- package/dist/client/setup-connections/catalog.js.map +1 -0
- package/dist/client/setup-connections/index.d.ts +1 -0
- package/dist/client/setup-connections/index.d.ts.map +1 -1
- package/dist/client/setup-connections/index.js +1 -0
- package/dist/client/setup-connections/index.js.map +1 -1
- package/dist/client/setup-connections/runtime.d.ts +2 -0
- package/dist/client/setup-connections/runtime.d.ts.map +1 -0
- package/dist/client/setup-connections/runtime.js +2 -0
- package/dist/client/setup-connections/runtime.js.map +1 -0
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +19 -1
- package/dist/client/use-action.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/connections/catalog.d.ts +5 -3
- package/dist/connections/catalog.d.ts.map +1 -1
- package/dist/connections/catalog.js +16 -8
- package/dist/connections/catalog.js.map +1 -1
- package/dist/connections/index.d.ts +1 -1
- package/dist/connections/index.d.ts.map +1 -1
- package/dist/connections/index.js +1 -1
- package/dist/connections/index.js.map +1 -1
- package/dist/connections/runtime.d.ts +2 -0
- package/dist/connections/runtime.d.ts.map +1 -0
- package/dist/connections/runtime.js +2 -0
- package/dist/connections/runtime.js.map +1 -0
- package/dist/deploy/build.js +2 -1
- package/dist/deploy/build.js.map +1 -1
- package/dist/eject/provider-api-definitions.d.ts +34 -0
- package/dist/eject/provider-api-definitions.d.ts.map +1 -0
- package/dist/eject/provider-api-definitions.js +88 -0
- package/dist/eject/provider-api-definitions.js.map +1 -0
- package/dist/eject/remote-mcp-presets.d.ts +17 -0
- package/dist/eject/remote-mcp-presets.d.ts.map +1 -0
- package/dist/eject/remote-mcp-presets.js +81 -0
- package/dist/eject/remote-mcp-presets.js.map +1 -0
- package/dist/eject/setup-readiness-ui.d.ts +7 -0
- package/dist/eject/setup-readiness-ui.d.ts.map +1 -0
- package/dist/eject/setup-readiness-ui.js +13 -0
- package/dist/eject/setup-readiness-ui.js.map +1 -0
- package/dist/eject/workspace-connections.d.ts +11 -0
- package/dist/eject/workspace-connections.d.ts.map +1 -0
- package/dist/eject/workspace-connections.js +47 -0
- package/dist/eject/workspace-connections.js.map +1 -0
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/adapter-overrides.d.ts +3 -0
- package/dist/integrations/adapter-overrides.d.ts.map +1 -0
- package/dist/integrations/adapter-overrides.js +7 -0
- package/dist/integrations/adapter-overrides.js.map +1 -0
- package/dist/integrations/eject/messaging-adapters.d.ts +12 -0
- package/dist/integrations/eject/messaging-adapters.d.ts.map +1 -0
- package/dist/integrations/eject/messaging-adapters.js +49 -0
- package/dist/integrations/eject/messaging-adapters.js.map +1 -0
- package/dist/integrations/index.d.ts +3 -2
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +2 -1
- package/dist/integrations/index.js.map +1 -1
- package/dist/integrations/plugin.d.ts +32 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +19 -12
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/runtime.d.ts +2 -0
- package/dist/integrations/runtime.d.ts.map +1 -0
- package/dist/integrations/runtime.js +2 -0
- package/dist/integrations/runtime.js.map +1 -0
- package/dist/integrations/types.d.ts +3 -1
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/types.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +5 -5
- package/dist/org/context.d.ts +4 -2
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/context.js +44 -22
- package/dist/org/context.js.map +1 -1
- package/dist/package-lifecycle/eject-manifest.d.ts +43 -0
- package/dist/package-lifecycle/eject-manifest.d.ts.map +1 -0
- package/dist/package-lifecycle/eject-manifest.js +219 -0
- package/dist/package-lifecycle/eject-manifest.js.map +1 -0
- package/dist/package-lifecycle/index.d.ts +1 -0
- package/dist/package-lifecycle/index.d.ts.map +1 -1
- package/dist/package-lifecycle/index.js +1 -0
- package/dist/package-lifecycle/index.js.map +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/provider-api/index.d.ts +6 -2
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +25 -12
- package/dist/provider-api/index.js.map +1 -1
- package/dist/provider-api/runtime.d.ts +2 -0
- package/dist/provider-api/runtime.d.ts.map +1 -0
- package/dist/provider-api/runtime.js +2 -0
- package/dist/provider-api/runtime.js.map +1 -0
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +32 -2
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/auth-plugin.d.ts.map +1 -1
- package/dist/server/auth-plugin.js +9 -5
- package/dist/server/auth-plugin.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +4 -1
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/setup-connections/index.d.ts +1 -1
- package/dist/setup-connections/index.d.ts.map +1 -1
- package/dist/setup-connections/index.js +1 -1
- package/dist/setup-connections/index.js.map +1 -1
- package/dist/shared/mcp-embed-headers.d.ts +1 -1
- package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
- package/dist/shared/mcp-embed-headers.js +1 -1
- package/dist/shared/mcp-embed-headers.js.map +1 -1
- package/dist/shared/merge-by-id.d.ts +5 -0
- package/dist/shared/merge-by-id.d.ts.map +1 -0
- package/dist/shared/merge-by-id.js +7 -0
- package/dist/shared/merge-by-id.js.map +1 -0
- package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +15 -13
- package/dist/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/dist/templates/chat/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/dist/templates/chat/AGENTS.md +3 -2
- package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +15 -13
- package/dist/templates/default/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/dist/templates/default/AGENTS.md +6 -5
- package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +15 -13
- package/dist/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/dist/templates/headless/AGENTS.md +5 -4
- package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +15 -13
- package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +3 -2
- package/dist/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/dist/templates/workspace-core/AGENTS.md +4 -4
- package/dist/templates/workspace-root/AGENTS.md +4 -4
- package/dist/vite/client.d.ts +6 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +30 -2
- package/dist/vite/client.js.map +1 -1
- package/docs/content/agent-native-toolkit.mdx +38 -0
- package/docs/content/package-lifecycle.mdx +54 -4
- package/package.json +15 -2
- package/src/a2a/agent-card.ts +83 -0
- package/src/a2a/artifact-response.ts +1648 -0
- package/src/a2a/auth-policy.ts +66 -0
- package/src/a2a/caller-auth.ts +102 -0
- package/src/a2a/client.ts +876 -0
- package/src/a2a/correlation.ts +50 -0
- package/src/a2a/handlers.ts +1285 -0
- package/src/a2a/index.ts +50 -0
- package/src/a2a/invoke.ts +348 -0
- package/src/a2a/response-text.ts +53 -0
- package/src/a2a/server.ts +586 -0
- package/src/a2a/task-store.ts +917 -0
- package/src/a2a/types.ts +221 -0
- package/src/a2a-claims.ts +52 -0
- package/src/action-change-marker.ts +74 -0
- package/src/action-ui.ts +38 -0
- package/src/action.ts +1406 -0
- package/src/adapters/cli/index.ts +6 -0
- package/src/adapters/cli/registry.ts +73 -0
- package/src/adapters/cli/shell-adapter.ts +92 -0
- package/src/adapters/cli/types.ts +27 -0
- package/src/agent/action-continuation-guidance.ts +38 -0
- package/src/agent/app-model-defaults.ts +201 -0
- package/src/agent/context-xray/actions/context-evict.ts +56 -0
- package/src/agent/context-xray/actions/context-manifest-get.ts +75 -0
- package/src/agent/context-xray/actions/context-pin.ts +56 -0
- package/src/agent/context-xray/actions/context-preview-get.ts +134 -0
- package/src/agent/context-xray/actions/context-report.ts +75 -0
- package/src/agent/context-xray/actions/context-restore.ts +51 -0
- package/src/agent/context-xray/actions/errors.ts +40 -0
- package/src/agent/context-xray/apply-directives.ts +137 -0
- package/src/agent/context-xray/directives-store.ts +178 -0
- package/src/agent/context-xray/identity.ts +37 -0
- package/src/agent/context-xray/manifest.ts +284 -0
- package/src/agent/context-xray/migrations.ts +32 -0
- package/src/agent/context-xray/plugin.ts +23 -0
- package/src/agent/context-xray/schema.ts +17 -0
- package/src/agent/context-xray/segments.ts +194 -0
- package/src/agent/context-xray/tokenize.ts +93 -0
- package/src/agent/default-model.ts +5 -0
- package/src/agent/durable-background.ts +547 -0
- package/src/agent/engine/ai-sdk-engine.ts +565 -0
- package/src/agent/engine/anthropic-engine.ts +320 -0
- package/src/agent/engine/builder-engine.ts +1110 -0
- package/src/agent/engine/builder-gateway-headers.ts +44 -0
- package/src/agent/engine/builtin.ts +122 -0
- package/src/agent/engine/context-directives-transform.ts +73 -0
- package/src/agent/engine/continuation-dispatch-retry.ts +168 -0
- package/src/agent/engine/credential-errors.ts +69 -0
- package/src/agent/engine/index.ts +54 -0
- package/src/agent/engine/openai-compatible-endpoint.ts +25 -0
- package/src/agent/engine/output-tokens.ts +181 -0
- package/src/agent/engine/provider-env-vars.ts +69 -0
- package/src/agent/engine/registry.ts +853 -0
- package/src/agent/engine/tool-call-journal-seed.ts +85 -0
- package/src/agent/engine/translate-ai-sdk.ts +407 -0
- package/src/agent/engine/translate-anthropic.ts +611 -0
- package/src/agent/engine/types.ts +310 -0
- package/src/agent/harness/acp-adapter.ts +893 -0
- package/src/agent/harness/acp-builtin.ts +70 -0
- package/src/agent/harness/ai-sdk-adapter.ts +509 -0
- package/src/agent/harness/background.ts +365 -0
- package/src/agent/harness/builtin.ts +50 -0
- package/src/agent/harness/index.ts +86 -0
- package/src/agent/harness/lifecycle.ts +498 -0
- package/src/agent/harness/registry.ts +97 -0
- package/src/agent/harness/runner.ts +182 -0
- package/src/agent/harness/store.ts +466 -0
- package/src/agent/harness/translate.ts +130 -0
- package/src/agent/harness/types.ts +129 -0
- package/src/agent/index.ts +32 -0
- package/src/agent/loop-settings.ts +186 -0
- package/src/agent/model-config.ts +363 -0
- package/src/agent/observational-memory/compactor.ts +78 -0
- package/src/agent/observational-memory/config.ts +78 -0
- package/src/agent/observational-memory/index.ts +79 -0
- package/src/agent/observational-memory/internal-run.ts +89 -0
- package/src/agent/observational-memory/message-text.ts +49 -0
- package/src/agent/observational-memory/migrations.ts +44 -0
- package/src/agent/observational-memory/observer.ts +128 -0
- package/src/agent/observational-memory/plugin.ts +35 -0
- package/src/agent/observational-memory/prompts.ts +53 -0
- package/src/agent/observational-memory/read.ts +131 -0
- package/src/agent/observational-memory/reflector.ts +119 -0
- package/src/agent/observational-memory/schema.ts +48 -0
- package/src/agent/observational-memory/store.ts +275 -0
- package/src/agent/observational-memory/types.ts +65 -0
- package/src/agent/processors.ts +209 -0
- package/src/agent/production-agent.ts +8254 -0
- package/src/agent/run-loop-with-resume.ts +394 -0
- package/src/agent/run-manager.ts +1825 -0
- package/src/agent/run-ownership.ts +75 -0
- package/src/agent/run-store.ts +2601 -0
- package/src/agent/runtime-context.ts +169 -0
- package/src/agent/thread-data-builder.ts +1584 -0
- package/src/agent/tool-call-journal.ts +368 -0
- package/src/agent/tool-error-redaction.ts +52 -0
- package/src/agent/tool-result-images.ts +178 -0
- package/src/agent/tool-search.ts +376 -0
- package/src/agent/types.ts +372 -0
- package/src/agent-native/index.ts +198 -0
- package/src/agent-web/config.ts +253 -0
- package/src/agent-web/generator.ts +382 -0
- package/src/agent-web/index.ts +36 -0
- package/src/appearance/actions/change-appearance.ts +35 -0
- package/src/application-state/emitter.ts +81 -0
- package/src/application-state/handlers.ts +121 -0
- package/src/application-state/index.ts +44 -0
- package/src/application-state/script-helpers.ts +155 -0
- package/src/application-state/store.ts +274 -0
- package/src/assets/branding/agent-native.icon/Assets/background.svg +3 -0
- package/src/assets/branding/agent-native.icon/Assets/foreground.svg +12 -0
- package/src/assets/branding/agent-native.icon/icon.json +49 -0
- package/src/assets/branding/favicon.png +0 -0
- package/src/assets/branding/favicon.svg +1 -0
- package/src/assets/branding/icon-on-dark.svg +10 -0
- package/src/assets/branding/icon-on-light.svg +10 -0
- package/src/assets/branding/mac-app-icon.svg +1 -0
- package/src/assets/branding/slack-bot/agent-native-1024.png +0 -0
- package/src/assets/branding/slack-bot/agent-native-512.png +0 -0
- package/src/assets/branding/tray-icon.svg +6 -0
- package/src/assets/branding/wordmark-on-dark.svg +21 -0
- package/src/assets/branding/wordmark-on-light.svg +21 -0
- package/src/assets/fonts/LICENSE_LIBERATION +96 -0
- package/src/assets/fonts/LICENSE_NOTO_NASKH_ARABIC +93 -0
- package/src/assets/fonts/LiberationSans-Bold.ttf +0 -0
- package/src/assets/fonts/LiberationSans-Regular.ttf +0 -0
- package/src/assets/fonts/NotoNaskhArabic-Variable.ttf +0 -0
- package/src/audit/actions/export-audit-events.ts +162 -0
- package/src/audit/actions/get-audit-event.ts +24 -0
- package/src/audit/actions/list-audit-events.ts +66 -0
- package/src/audit/cleanup-job.ts +100 -0
- package/src/audit/config.ts +90 -0
- package/src/audit/index.ts +43 -0
- package/src/audit/record.ts +180 -0
- package/src/audit/redact.ts +109 -0
- package/src/audit/store.ts +346 -0
- package/src/audit/types.ts +141 -0
- package/src/automation/index.ts +802 -0
- package/src/brand-kit/brand-signals.ts +124 -0
- package/src/brand-kit/fig/index.ts +64 -0
- package/src/brand-kit/index.ts +72 -0
- package/src/brand-kit/types.ts +113 -0
- package/src/browser-sessions/actions.ts +302 -0
- package/src/browser-sessions/routes.ts +234 -0
- package/src/browser-sessions/store.ts +679 -0
- package/src/browser-sessions/types.ts +84 -0
- package/src/changelog/parse.ts +328 -0
- package/src/chat-threads/emitter.ts +22 -0
- package/src/chat-threads/schema.ts +43 -0
- package/src/chat-threads/store.ts +1311 -0
- package/src/checkpoints/index.ts +15 -0
- package/src/checkpoints/service.ts +142 -0
- package/src/checkpoints/store.ts +153 -0
- package/src/cli/add.ts +425 -0
- package/src/cli/agent.ts +424 -0
- package/src/cli/agents.ts +122 -0
- package/src/cli/app-skill.ts +1455 -0
- package/src/cli/atomic-json-file.ts +324 -0
- package/src/cli/audit-agent-web.ts +324 -0
- package/src/cli/changelog.ts +199 -0
- package/src/cli/claude-code-participant.ts +515 -0
- package/src/cli/code-agent-commands.ts +270 -0
- package/src/cli/code-agent-connector.ts +1109 -0
- package/src/cli/code-agent-executor.ts +1970 -0
- package/src/cli/code-agent-output-smoother.ts +140 -0
- package/src/cli/code-agent-runs.concurrent-worker.ts +33 -0
- package/src/cli/code-agent-runs.ts +548 -0
- package/src/cli/code.ts +1805 -0
- package/src/cli/codex-cli-participant.ts +496 -0
- package/src/cli/connect.ts +2714 -0
- package/src/cli/content-local.ts +442 -0
- package/src/cli/context-xray-local.ts +2193 -0
- package/src/cli/create-workspace.ts +30 -0
- package/src/cli/create.ts +2247 -0
- package/src/cli/deploy-build.ts +50 -0
- package/src/cli/design-connect.ts +3187 -0
- package/src/cli/doctor.ts +472 -0
- package/src/cli/eject.ts +1594 -0
- package/src/cli/eval.ts +134 -0
- package/src/cli/gateway-helpers.ts +70 -0
- package/src/cli/index.ts +1217 -0
- package/src/cli/info.ts +105 -0
- package/src/cli/invoke.ts +288 -0
- package/src/cli/mcp-config-writers.ts +857 -0
- package/src/cli/mcp.ts +594 -0
- package/src/cli/migrate.ts +1813 -0
- package/src/cli/migration-codemod.ts +646 -0
- package/src/cli/multi-frontier-runs.ts +1952 -0
- package/src/cli/package-lifecycle.ts +823 -0
- package/src/cli/plan-blocks.ts +143 -0
- package/src/cli/plan-local.ts +3189 -0
- package/src/cli/plan-publish-store.ts +138 -0
- package/src/cli/pr-visual-recap-workflow.ts +2 -0
- package/src/cli/recap.ts +5 -0
- package/src/cli/setup-agents.ts +120 -0
- package/src/cli/skills-content/assets-skill.ts +83 -0
- package/src/cli/skills-content/canvas.ts +153 -0
- package/src/cli/skills-content/connection.ts +52 -0
- package/src/cli/skills-content/content-skill.ts +120 -0
- package/src/cli/skills-content/design-exploration-skill.ts +118 -0
- package/src/cli/skills-content/design-visual-edit-skill.ts +228 -0
- package/src/cli/skills-content/document-quality.ts +196 -0
- package/src/cli/skills-content/exemplar.ts +69 -0
- package/src/cli/skills-content/help.ts +77 -0
- package/src/cli/skills-content/index.ts +22 -0
- package/src/cli/skills-content/local-files.ts +100 -0
- package/src/cli/skills-content/plan-setup-auth.ts +80 -0
- package/src/cli/skills-content/visual-plan-skill.ts +493 -0
- package/src/cli/skills-content/visual-recap-skill.ts +553 -0
- package/src/cli/skills-content/visualize-repo-skill.ts +93 -0
- package/src/cli/skills-content/wireframe.ts +349 -0
- package/src/cli/skills.ts +4340 -0
- package/src/cli/sync-builder-starter-manifest.ts +631 -0
- package/src/cli/telemetry.ts +136 -0
- package/src/cli/templates-meta.ts +269 -0
- package/src/cli/upgrade.ts +956 -0
- package/src/cli/visualize-repo.ts +715 -0
- package/src/cli/workspace-dev.ts +1486 -0
- package/src/cli/workspacify.ts +258 -0
- package/src/client/AgentAskPopover.tsx +89 -0
- package/src/client/AgentChatHome.tsx +66 -0
- package/src/client/AgentNative.tsx +161 -0
- package/src/client/AgentNativeEmbedded.tsx +288 -0
- package/src/client/AgentNativeFrame.tsx +151 -0
- package/src/client/AgentPanel.tsx +3437 -0
- package/src/client/AgentTaskCard.tsx +273 -0
- package/src/client/AppearancePicker.tsx +79 -0
- package/src/client/AssistantChat.tsx +5793 -0
- package/src/client/ClientOnly.tsx +22 -0
- package/src/client/CommandMenu.tsx +726 -0
- package/src/client/ConnectBuilderCard.tsx +390 -0
- package/src/client/DefaultSpinner.tsx +47 -0
- package/src/client/ErrorBoundary.tsx +359 -0
- package/src/client/ErrorReportActions.tsx +69 -0
- package/src/client/FeedbackButton.tsx +553 -0
- package/src/client/HighlightedCodeBlock.tsx +173 -0
- package/src/client/IframeEmbed.tsx +151 -0
- package/src/client/KeepTabOpenNotice.tsx +181 -0
- package/src/client/MultiTabAssistantChat.tsx +2576 -0
- package/src/client/NewWorkspaceAppFlow.tsx +525 -0
- package/src/client/PoweredByBadge.tsx +284 -0
- package/src/client/RunStuckBanner.tsx +431 -0
- package/src/client/StarfieldBackground.tsx +466 -0
- package/src/client/Turnstile.tsx +125 -0
- package/src/client/active-run-state.ts +139 -0
- package/src/client/agent-chat/index.ts +279 -0
- package/src/client/agent-chat-adapter.ts +3692 -0
- package/src/client/agent-chat.ts +1233 -0
- package/src/client/agent-engine-key.ts +122 -0
- package/src/client/agent-page/AgentContextTab.tsx +487 -0
- package/src/client/agent-page/AgentEmptyState.tsx +44 -0
- package/src/client/agent-page/AgentJobsTab.tsx +441 -0
- package/src/client/agent-page/AgentTabFrame.tsx +39 -0
- package/src/client/agent-page/AgentTabsPage.tsx +1096 -0
- package/src/client/agent-page/types.ts +18 -0
- package/src/client/agent-page/use-jobs.ts +150 -0
- package/src/client/agent-sidebar-state.ts +166 -0
- package/src/client/analytics/index.ts +40 -0
- package/src/client/analytics-session.ts +70 -0
- package/src/client/analytics.ts +1757 -0
- package/src/client/api-path.ts +124 -0
- package/src/client/app-providers.tsx +230 -0
- package/src/client/appearance.ts +130 -0
- package/src/client/application-state.ts +154 -0
- package/src/client/assistant-ui-recovery.tsx +205 -0
- package/src/client/automation/index.ts +4 -0
- package/src/client/automation.ts +22 -0
- package/src/client/blocks/AiEditableField.tsx +30 -0
- package/src/client/blocks/BlockView.tsx +145 -0
- package/src/client/blocks/RegistryBlockDataProvider.tsx +121 -0
- package/src/client/blocks/SchemaBlockEditor.tsx +457 -0
- package/src/client/blocks/agent.ts +95 -0
- package/src/client/blocks/code-block-direction.ts +21 -0
- package/src/client/blocks/index.ts +308 -0
- package/src/client/blocks/library/AnnotatedCodeBlock.tsx +710 -0
- package/src/client/blocks/library/ApiEndpointBlock.tsx +1120 -0
- package/src/client/blocks/library/DataModelBlock.tsx +775 -0
- package/src/client/blocks/library/DiffBlock.tsx +1854 -0
- package/src/client/blocks/library/FileTreeBlock.tsx +868 -0
- package/src/client/blocks/library/HighlightedCode.tsx +260 -0
- package/src/client/blocks/library/JsonExplorerBlock.tsx +608 -0
- package/src/client/blocks/library/MermaidBlock.tsx +362 -0
- package/src/client/blocks/library/OpenApiSpecBlock.tsx +998 -0
- package/src/client/blocks/library/annotated-code.config.ts +101 -0
- package/src/client/blocks/library/annotation-rail.tsx +1020 -0
- package/src/client/blocks/library/api-endpoint.config.ts +207 -0
- package/src/client/blocks/library/block-copy.ts +399 -0
- package/src/client/blocks/library/callout.config.ts +57 -0
- package/src/client/blocks/library/callout.tsx +149 -0
- package/src/client/blocks/library/checklist.config.ts +56 -0
- package/src/client/blocks/library/checklist.tsx +208 -0
- package/src/client/blocks/library/code-filename-label.tsx +59 -0
- package/src/client/blocks/library/code-highlight.tsx +178 -0
- package/src/client/blocks/library/code-tabs.config.ts +70 -0
- package/src/client/blocks/library/code-tabs.tsx +606 -0
- package/src/client/blocks/library/code.config.ts +69 -0
- package/src/client/blocks/library/code.tsx +440 -0
- package/src/client/blocks/library/columns.config.ts +85 -0
- package/src/client/blocks/library/columns.tsx +334 -0
- package/src/client/blocks/library/data-model.config.ts +152 -0
- package/src/client/blocks/library/dev-doc-ui.tsx +191 -0
- package/src/client/blocks/library/diagram.config.ts +222 -0
- package/src/client/blocks/library/diagram.tsx +958 -0
- package/src/client/blocks/library/diff.config.ts +115 -0
- package/src/client/blocks/library/file-tree.config.ts +92 -0
- package/src/client/blocks/library/html.config.ts +79 -0
- package/src/client/blocks/library/html.tsx +258 -0
- package/src/client/blocks/library/json-explorer.config.ts +74 -0
- package/src/client/blocks/library/mermaid.config.ts +49 -0
- package/src/client/blocks/library/narrow-container.tsx +37 -0
- package/src/client/blocks/library/openapi-spec.config.ts +66 -0
- package/src/client/blocks/library/question-form.config.ts +127 -0
- package/src/client/blocks/library/question-form.tsx +944 -0
- package/src/client/blocks/library/sanitize-html.ts +343 -0
- package/src/client/blocks/library/server-specs.ts +338 -0
- package/src/client/blocks/library/specs.tsx +308 -0
- package/src/client/blocks/library/table.config.ts +61 -0
- package/src/client/blocks/library/table.tsx +449 -0
- package/src/client/blocks/library/tabs.config.ts +96 -0
- package/src/client/blocks/library/tabs.tsx +665 -0
- package/src/client/blocks/library/wireframe-icons.ts +210 -0
- package/src/client/blocks/library/wireframe-kit.tsx +1850 -0
- package/src/client/blocks/library/wireframe.config.ts +539 -0
- package/src/client/blocks/library/wireframe.tsx +535 -0
- package/src/client/blocks/mdx.ts +364 -0
- package/src/client/blocks/provider.tsx +51 -0
- package/src/client/blocks/registry.ts +83 -0
- package/src/client/blocks/schema-form/introspect.ts +201 -0
- package/src/client/blocks/server.ts +170 -0
- package/src/client/blocks/types.ts +415 -0
- package/src/client/browser-session-bridge.ts +548 -0
- package/src/client/browser-tab-id.ts +36 -0
- package/src/client/build-compatibility.ts +77 -0
- package/src/client/builder-frame.ts +194 -0
- package/src/client/builder-mark.tsx +21 -0
- package/src/client/changelog/Changelog.tsx +333 -0
- package/src/client/changelog/index.ts +1 -0
- package/src/client/chat/ChatHistoryList.tsx +7 -0
- package/src/client/chat/attachment-adapters.ts +426 -0
- package/src/client/chat/connectors.ts +1579 -0
- package/src/client/chat/index.ts +160 -0
- package/src/client/chat/markdown-renderer.tsx +693 -0
- package/src/client/chat/message-components.tsx +1326 -0
- package/src/client/chat/repo-helpers.ts +281 -0
- package/src/client/chat/run-recovery.tsx +994 -0
- package/src/client/chat/runtime.ts +1810 -0
- package/src/client/chat/tool-call-display.tsx +1270 -0
- package/src/client/chat/tool-render-registry.tsx +144 -0
- package/src/client/chat/use-agent-chat-lifecycle-tracking.ts +74 -0
- package/src/client/chat/use-reconnect-reader-owner.ts +28 -0
- package/src/client/chat/widgets/DataChartRenderer.tsx +242 -0
- package/src/client/chat/widgets/DataChartWidget.tsx +51 -0
- package/src/client/chat/widgets/DataInsightsWidget.tsx +59 -0
- package/src/client/chat/widgets/DataTableWidget.tsx +240 -0
- package/src/client/chat/widgets/InlineExtensionWidget.tsx +60 -0
- package/src/client/chat/widgets/builtin-tool-renderers.tsx +213 -0
- package/src/client/chat/widgets/data-widget-types.ts +1 -0
- package/src/client/chat/widgets/inline-extension-result.ts +86 -0
- package/src/client/chat-model-groups.ts +171 -0
- package/src/client/chat-thread-url.ts +11 -0
- package/src/client/chat-view-transition.ts +213 -0
- package/src/client/client-action.ts +21 -0
- package/src/client/client-bootstrap.ts +7 -0
- package/src/client/client-surface.ts +41 -0
- package/src/client/clipboard.ts +89 -0
- package/src/client/code-agent-chat-adapter.ts +537 -0
- package/src/client/collab/index.ts +60 -0
- package/src/client/command-navigation/index.ts +15 -0
- package/src/client/comments-review/index.ts +1 -0
- package/src/client/components/AgentPresenceChip.tsx +4 -0
- package/src/client/components/ApiKeySettings.tsx +309 -0
- package/src/client/components/CodeAgentIndicator.tsx +59 -0
- package/src/client/components/CodeRequiredDialog.tsx +470 -0
- package/src/client/components/LiveCursorOverlay.tsx +5 -0
- package/src/client/components/MissingKeyCard.tsx +61 -0
- package/src/client/components/PresenceBar.tsx +4 -0
- package/src/client/components/RecentEditHighlights.tsx +4 -0
- package/src/client/components/RemoteSelectionRings.tsx +5 -0
- package/src/client/components/icons/AgentNativeIcon.tsx +46 -0
- package/src/client/components/ui/dialog.tsx +1 -0
- package/src/client/components/ui/dropdown-menu.tsx +1 -0
- package/src/client/components/ui/hover-card.tsx +1 -0
- package/src/client/components/ui/message-scroller.tsx +131 -0
- package/src/client/components/ui/popover.tsx +1 -0
- package/src/client/components/ui/sheet.tsx +1 -0
- package/src/client/components/ui/tooltip.tsx +1 -0
- package/src/client/composer/index.ts +11 -0
- package/src/client/composer/runtime-adapters.tsx +123 -0
- package/src/client/composer/use-mention-search.ts +7 -0
- package/src/client/composer/wired-components.tsx +53 -0
- package/src/client/context-xray/ContextMeter.tsx +124 -0
- package/src/client/context-xray/ContextSegmentRow.tsx +27 -0
- package/src/client/context-xray/ContextTreemap.tsx +24 -0
- package/src/client/context-xray/ContextXRayPanel.tsx +59 -0
- package/src/client/context-xray/SegmentProvenancePopover.tsx +18 -0
- package/src/client/context-xray/format.ts +27 -0
- package/src/client/conversation/AgentConversation.tsx +555 -0
- package/src/client/conversation/code-agent-transcript.ts +283 -0
- package/src/client/conversation/index.ts +22 -0
- package/src/client/conversation/types.ts +85 -0
- package/src/client/conversation/use-near-bottom-autoscroll.ts +278 -0
- package/src/client/create-query-client.ts +86 -0
- package/src/client/db-admin/DataGrid.tsx +551 -0
- package/src/client/db-admin/DbAdminPage.tsx +218 -0
- package/src/client/db-admin/DevDatabaseLink.tsx +16 -0
- package/src/client/db-admin/EditableCell.tsx +451 -0
- package/src/client/db-admin/FilterBar.tsx +203 -0
- package/src/client/db-admin/ResultsGrid.tsx +114 -0
- package/src/client/db-admin/RowSidePanel.tsx +337 -0
- package/src/client/db-admin/SqlEditor.tsx +840 -0
- package/src/client/db-admin/TableBrowser.tsx +212 -0
- package/src/client/db-admin/TableEditor.tsx +760 -0
- package/src/client/db-admin/cell-format.ts +246 -0
- package/src/client/db-admin/changeset.ts +296 -0
- package/src/client/db-admin/export-utils.ts +78 -0
- package/src/client/db-admin/index.ts +33 -0
- package/src/client/db-admin/sql-storage.ts +134 -0
- package/src/client/db-admin/storage.ts +68 -0
- package/src/client/db-admin/useAgentSync.ts +226 -0
- package/src/client/db-admin/useDbAdmin.ts +294 -0
- package/src/client/dev-overlay/DevOverlay.tsx +576 -0
- package/src/client/dev-overlay/builtins.ts +40 -0
- package/src/client/dev-overlay/index.ts +23 -0
- package/src/client/dev-overlay/registry.ts +67 -0
- package/src/client/dev-overlay/types.ts +64 -0
- package/src/client/dev-overlay/use-dev-option.ts +78 -0
- package/src/client/dev-overlay/use-dev-overlay-shortcut.ts +31 -0
- package/src/client/dynamic-suggestions.ts +455 -0
- package/src/client/embed-auth.ts +544 -0
- package/src/client/embed.ts +54 -0
- package/src/client/error-capture.ts +690 -0
- package/src/client/error-format.ts +211 -0
- package/src/client/error-reporting.ts +100 -0
- package/src/client/extensions/AgentNativeExtensionFrame.e2e-host.tsx +136 -0
- package/src/client/extensions/AgentNativeExtensionFrame.tsx +708 -0
- package/src/client/extensions/EmbeddedExtension.tsx +604 -0
- package/src/client/extensions/ExtensionEditor.tsx +450 -0
- package/src/client/extensions/ExtensionQueryErrorState.tsx +47 -0
- package/src/client/extensions/ExtensionSlot.tsx +345 -0
- package/src/client/extensions/ExtensionViewer.tsx +1502 -0
- package/src/client/extensions/ExtensionViewerPage.tsx +32 -0
- package/src/client/extensions/ExtensionsListPage.tsx +432 -0
- package/src/client/extensions/ExtensionsSidebarSection.tsx +1259 -0
- package/src/client/extensions/InlineExtensionFrame.tsx +660 -0
- package/src/client/extensions/agent-native-extension-runtime.ts +495 -0
- package/src/client/extensions/delete-extension.ts +76 -0
- package/src/client/extensions/extension-load-error.ts +26 -0
- package/src/client/extensions/extension-order.ts +49 -0
- package/src/client/extensions/extension-popularity.ts +61 -0
- package/src/client/extensions/iframe-bridge.ts +377 -0
- package/src/client/extensions/index.ts +84 -0
- package/src/client/extensions/portable-extension.ts +712 -0
- package/src/client/feature-flags/FeatureFlagsPanel.tsx +519 -0
- package/src/client/feature-flags/helpers.ts +77 -0
- package/src/client/feature-flags/index.ts +13 -0
- package/src/client/feature-flags/types.ts +29 -0
- package/src/client/feature-flags/use-feature-flag.ts +26 -0
- package/src/client/feedback-context.ts +90 -0
- package/src/client/frame-protocol.ts +168 -0
- package/src/client/frame.ts +329 -0
- package/src/client/guided-questions.tsx +1152 -0
- package/src/client/history/VersionHistoryPanel.tsx +175 -0
- package/src/client/history/index.ts +21 -0
- package/src/client/history/use-history.ts +114 -0
- package/src/client/hooks/index.ts +46 -0
- package/src/client/host/index.ts +170 -0
- package/src/client/host-bridge.ts +1272 -0
- package/src/client/host-tools.ts +190 -0
- package/src/client/i18n.tsx +798 -0
- package/src/client/index.ts +370 -0
- package/src/client/integrations/IntegrationCard.tsx +186 -0
- package/src/client/integrations/IntegrationsPanel.tsx +633 -0
- package/src/client/integrations/api.ts +295 -0
- package/src/client/integrations/index.ts +29 -0
- package/src/client/integrations/useIntegrationStatus.ts +52 -0
- package/src/client/mcp-app-host.ts +720 -0
- package/src/client/mcp-apps/McpAppRenderer.tsx +760 -0
- package/src/client/navigation/index.ts +54 -0
- package/src/client/notifications/NotificationsBell.tsx +383 -0
- package/src/client/notifications/index.ts +1 -0
- package/src/client/observability/ObservabilityDashboard.tsx +890 -0
- package/src/client/observability/ThumbsFeedback.tsx +160 -0
- package/src/client/observability/index.ts +20 -0
- package/src/client/observability/useObservability.ts +266 -0
- package/src/client/onboarding/OnboardingBanner.tsx +73 -0
- package/src/client/onboarding/OnboardingPanel.tsx +1036 -0
- package/src/client/onboarding/SetupButton.tsx +64 -0
- package/src/client/onboarding/index.ts +25 -0
- package/src/client/onboarding/use-onboarding.ts +164 -0
- package/src/client/onboarding/use-preview-mode.ts +40 -0
- package/src/client/org/InvitationBanner.tsx +148 -0
- package/src/client/org/OrgSwitcher.tsx +754 -0
- package/src/client/org/RequireActiveOrg.tsx +337 -0
- package/src/client/org/TeamPage.tsx +1432 -0
- package/src/client/org/hooks.ts +359 -0
- package/src/client/org/index.ts +70 -0
- package/src/client/org/workspace-app-links.ts +367 -0
- package/src/client/org-team/index.ts +1 -0
- package/src/client/progress/RunsTray.tsx +680 -0
- package/src/client/progress/index.ts +1 -0
- package/src/client/require-session.tsx +142 -0
- package/src/client/resources/BuiltinCapabilityDetail.tsx +258 -0
- package/src/client/resources/McpConnectionSuggestion.tsx +276 -0
- package/src/client/resources/McpIntegrationDialog.tsx +808 -0
- package/src/client/resources/McpServerDetail.tsx +230 -0
- package/src/client/resources/ResourceEditor.tsx +872 -0
- package/src/client/resources/ResourceTree.tsx +860 -0
- package/src/client/resources/ResourcesPanel.tsx +1960 -0
- package/src/client/resources/index.ts +25 -0
- package/src/client/resources/mcp-integration-catalog.ts +771 -0
- package/src/client/resources/mcp-integration-logos.ts +108 -0
- package/src/client/resources/runtime.ts +1 -0
- package/src/client/resources/use-builtin-capabilities.ts +113 -0
- package/src/client/resources/use-mcp-servers.ts +217 -0
- package/src/client/resources/use-resources.ts +402 -0
- package/src/client/review/ReviewCommentComposer.tsx +123 -0
- package/src/client/review/ReviewStatusBadge.tsx +39 -0
- package/src/client/review/ReviewThreadPanel.tsx +625 -0
- package/src/client/review/index.ts +38 -0
- package/src/client/review/use-review.ts +186 -0
- package/src/client/route-chunk-recovery/index.ts +2 -0
- package/src/client/route-chunk-recovery.ts +331 -0
- package/src/client/route-state.ts +455 -0
- package/src/client/route-warmup.tsx +543 -0
- package/src/client/session-replay-iframe.e2e-host.tsx +100 -0
- package/src/client/session-replay.ts +3417 -0
- package/src/client/settings/AgentsSection.tsx +441 -0
- package/src/client/settings/AutomationsSection.tsx +516 -0
- package/src/client/settings/BackgroundAgentSection.tsx +189 -0
- package/src/client/settings/BrowserSection.tsx +110 -0
- package/src/client/settings/DemoModeSection.tsx +48 -0
- package/src/client/settings/SecretsSection.tsx +875 -0
- package/src/client/settings/SettingsPanel.tsx +3162 -0
- package/src/client/settings/SettingsSection.tsx +283 -0
- package/src/client/settings/SettingsTabsPage.tsx +592 -0
- package/src/client/settings/UsageSection.tsx +401 -0
- package/src/client/settings/VoiceTranscriptionSection.tsx +960 -0
- package/src/client/settings/agent-settings-search.ts +220 -0
- package/src/client/settings/index.ts +27 -0
- package/src/client/settings/useBuilderStatus.ts +1055 -0
- package/src/client/setup-connections/BuilderConnectCard.tsx +89 -0
- package/src/client/setup-connections/ProviderReadinessBadge.tsx +73 -0
- package/src/client/setup-connections/SetupConnectionsPage.tsx +94 -0
- package/src/client/setup-connections/catalog.ts +6 -0
- package/src/client/setup-connections/index.ts +47 -0
- package/src/client/setup-connections/runtime.ts +1 -0
- package/src/client/sharing/ShareButton.tsx +1748 -0
- package/src/client/sharing/ShareDialog.tsx +846 -0
- package/src/client/sharing/VisibilityBadge.tsx +4 -0
- package/src/client/sharing/index.ts +2 -0
- package/src/client/sse-event-processor.ts +2002 -0
- package/src/client/terminal/AgentTerminal.tsx +488 -0
- package/src/client/terminal/index.ts +7 -0
- package/src/client/theme.ts +27 -0
- package/src/client/tombstone/agent-presence-chip.ts +17 -0
- package/src/client/tombstone/editor.ts +265 -0
- package/src/client/tombstone/live-cursor-overlay.ts +21 -0
- package/src/client/tombstone/presence-bar.ts +17 -0
- package/src/client/tombstone/recent-edit-highlights.ts +17 -0
- package/src/client/tombstone/remote-selection-rings.ts +21 -0
- package/src/client/tombstone/rich-markdown-editor.ts +265 -0
- package/src/client/tombstone/ui-dialog.ts +49 -0
- package/src/client/tombstone/ui-dropdown-menu.ts +69 -0
- package/src/client/tombstone/ui-hover-card.ts +21 -0
- package/src/client/tombstone/ui-popover.ts +25 -0
- package/src/client/tombstone/ui-sheet.ts +49 -0
- package/src/client/tombstone/ui-tooltip.ts +29 -0
- package/src/client/tombstone/visual-style-controls.ts +61 -0
- package/src/client/tool-cells/BashCell.tsx +164 -0
- package/src/client/tool-cells/EditCell.tsx +303 -0
- package/src/client/tool-cells/FilesChangedSummary.tsx +208 -0
- package/src/client/tool-cells/WriteCell.tsx +145 -0
- package/src/client/tool-cells/index.ts +7 -0
- package/src/client/tool-display.ts +41 -0
- package/src/client/track.ts +57 -0
- package/src/client/transcription/BuilderTranscriptionCta.tsx +120 -0
- package/src/client/transcription/use-live-transcription.ts +292 -0
- package/src/client/ui/index.ts +55 -0
- package/src/client/uploads/index.ts +6 -0
- package/src/client/uploads/upload-editor-image.ts +79 -0
- package/src/client/uploads/use-upload-resource.ts +24 -0
- package/src/client/url-scrub.ts +51 -0
- package/src/client/use-action.ts +797 -0
- package/src/client/use-agent-chat-context.ts +63 -0
- package/src/client/use-agent-chat-home-handoff.ts +207 -0
- package/src/client/use-agent-chat.ts +53 -0
- package/src/client/use-agent-engine-configured.ts +211 -0
- package/src/client/use-avatar.ts +127 -0
- package/src/client/use-change-version.ts +150 -0
- package/src/client/use-chat-models.ts +252 -0
- package/src/client/use-chat-threads.ts +1262 -0
- package/src/client/use-db-sync.ts +1112 -0
- package/src/client/use-demo-mode-status.ts +30 -0
- package/src/client/use-dev-mode.ts +177 -0
- package/src/client/use-external-value.ts +40 -0
- package/src/client/use-pausing-interval.ts +65 -0
- package/src/client/use-pinch-zoom.ts +202 -0
- package/src/client/use-run-stuck-detection.ts +427 -0
- package/src/client/use-send-to-agent-chat.ts +85 -0
- package/src/client/use-session.ts +114 -0
- package/src/client/utils.ts +7 -0
- package/src/client/visual-style-controls.tsx +1 -0
- package/src/client/vite-dev-recovery-script.ts +226 -0
- package/src/client/voice-provider-status.ts +44 -0
- package/src/client/widgets/index.ts +41 -0
- package/src/code-agents/background-controller.ts +398 -0
- package/src/code-agents/background-run.ts +156 -0
- package/src/code-agents/index.ts +95 -0
- package/src/code-agents/prompt-attachments.ts +39 -0
- package/src/code-agents/transcript-normalizer.ts +750 -0
- package/src/code-agents/transcript-order.ts +73 -0
- package/src/coding-tools/index.ts +742 -0
- package/src/coding-tools/run-code.ts +1662 -0
- package/src/coding-tools/sandbox/adapter.ts +82 -0
- package/src/coding-tools/sandbox/background.ts +406 -0
- package/src/coding-tools/sandbox/executions-store.ts +517 -0
- package/src/coding-tools/sandbox/index.ts +132 -0
- package/src/coding-tools/sandbox/local-child-process-adapter.ts +217 -0
- package/src/collab/agent-identity.ts +5 -0
- package/src/collab/agent-presence.ts +341 -0
- package/src/collab/awareness-store.ts +196 -0
- package/src/collab/awareness.ts +317 -0
- package/src/collab/client-struct.ts +366 -0
- package/src/collab/client.ts +1205 -0
- package/src/collab/emitter.ts +31 -0
- package/src/collab/follow-mode.ts +107 -0
- package/src/collab/index.ts +151 -0
- package/src/collab/json-to-yjs.ts +504 -0
- package/src/collab/presence.ts +207 -0
- package/src/collab/recent-edits.ts +215 -0
- package/src/collab/routes.ts +191 -0
- package/src/collab/storage.ts +228 -0
- package/src/collab/struct-routes.ts +133 -0
- package/src/collab/text-to-yjs.ts +79 -0
- package/src/collab/undo.ts +432 -0
- package/src/collab/xml-ops.ts +68 -0
- package/src/collab/ydoc-manager.ts +544 -0
- package/src/command-navigation/actions.ts +100 -0
- package/src/command-navigation/index.ts +12 -0
- package/src/comments-review/index.ts +1 -0
- package/src/connections/catalog.ts +451 -0
- package/src/connections/index.ts +48 -0
- package/src/connections/reader.ts +911 -0
- package/src/connections/runtime.ts +1 -0
- package/src/credentials/index.ts +187 -0
- package/src/data-programs/actions.ts +335 -0
- package/src/data-programs/contract.ts +284 -0
- package/src/data-programs/execute.ts +693 -0
- package/src/data-programs/index.ts +72 -0
- package/src/data-programs/schema.ts +148 -0
- package/src/data-programs/store.ts +755 -0
- package/src/data-widgets/index.ts +376 -0
- package/src/db/client.ts +1627 -0
- package/src/db/create-get-db.ts +579 -0
- package/src/db/ddl-guard.ts +302 -0
- package/src/db/drizzle-config.ts +190 -0
- package/src/db/ensure-additive-columns.ts +430 -0
- package/src/db/index.ts +57 -0
- package/src/db/migrations.ts +691 -0
- package/src/db/request-telemetry.ts +154 -0
- package/src/db/runtime-diagnostics.ts +331 -0
- package/src/db/schema.ts +121 -0
- package/src/db/widen-columns.ts +75 -0
- package/src/db-admin/agent-tools.ts +202 -0
- package/src/db-admin/index.ts +26 -0
- package/src/db-admin/operations.ts +803 -0
- package/src/db-admin/routes.ts +174 -0
- package/src/db-admin/types.ts +110 -0
- package/src/demo/browser-state.ts +47 -0
- package/src/demo/fetch-interceptor.ts +175 -0
- package/src/demo/redact.ts +575 -0
- package/src/deploy/build.ts +3938 -0
- package/src/deploy/immutable-assets.ts +65 -0
- package/src/deploy/route-discovery.ts +458 -0
- package/src/deploy/workspace-core.ts +282 -0
- package/src/deploy/workspace-deploy.ts +1488 -0
- package/src/eject/provider-api-definitions.ts +193 -0
- package/src/eject/remote-mcp-presets.ts +137 -0
- package/src/eject/setup-readiness-ui.tsx +29 -0
- package/src/eject/workspace-connections.ts +92 -0
- package/src/embedding/agent.ts +159 -0
- package/src/embedding/bridge.ts +297 -0
- package/src/embedding/index.ts +43 -0
- package/src/embedding/protocol.ts +185 -0
- package/src/embedding/react.tsx +319 -0
- package/src/embeddings/index.ts +233 -0
- package/src/eval/agent-runner.ts +210 -0
- package/src/eval/define-eval.ts +55 -0
- package/src/eval/index.ts +49 -0
- package/src/eval/report.ts +75 -0
- package/src/eval/runner.ts +369 -0
- package/src/eval/scorer.ts +244 -0
- package/src/eval/types.ts +188 -0
- package/src/event-bus/bus.ts +140 -0
- package/src/event-bus/index.ts +3 -0
- package/src/event-bus/registry.ts +79 -0
- package/src/event-bus/types.ts +29 -0
- package/src/extensions/actions.ts +1636 -0
- package/src/extensions/change-marker.ts +54 -0
- package/src/extensions/content-patch.ts +468 -0
- package/src/extensions/fetch-tool.ts +461 -0
- package/src/extensions/html-shell.ts +803 -0
- package/src/extensions/local.ts +462 -0
- package/src/extensions/path.ts +40 -0
- package/src/extensions/proxy-security.ts +171 -0
- package/src/extensions/routes.ts +1080 -0
- package/src/extensions/schema.ts +269 -0
- package/src/extensions/session-replay-iframe.ts +131 -0
- package/src/extensions/slots/routes.ts +126 -0
- package/src/extensions/slots/schema.ts +87 -0
- package/src/extensions/slots/store.ts +450 -0
- package/src/extensions/store.ts +1347 -0
- package/src/extensions/theme.ts +114 -0
- package/src/extensions/url-safety.ts +316 -0
- package/src/extensions/web-content.ts +663 -0
- package/src/extensions/web-search-tool.ts +437 -0
- package/src/feature-flags/a2a-action-route.ts +56 -0
- package/src/feature-flags/actions/get-feature-flags.ts +24 -0
- package/src/feature-flags/actions/list-feature-flags.ts +69 -0
- package/src/feature-flags/actions/set-feature-flag.ts +89 -0
- package/src/feature-flags/index.ts +21 -0
- package/src/feature-flags/permissions.ts +53 -0
- package/src/feature-flags/plugin.ts +44 -0
- package/src/feature-flags/registry.ts +96 -0
- package/src/feature-flags/store.ts +176 -0
- package/src/file-upload/actions/upload-image.ts +213 -0
- package/src/file-upload/builder.ts +431 -0
- package/src/file-upload/index.ts +24 -0
- package/src/file-upload/pre-upload-attachments.ts +305 -0
- package/src/file-upload/registry.ts +125 -0
- package/src/file-upload/types.ts +89 -0
- package/src/guards/db-tool-scoping.ts +129 -0
- package/src/guards/index.ts +23 -0
- package/src/guards/no-drizzle-push.ts +116 -0
- package/src/guards/no-env-credentials.ts +229 -0
- package/src/guards/no-env-mutation.ts +114 -0
- package/src/guards/no-localhost-fallback.ts +124 -0
- package/src/guards/no-unscoped-credentials.ts +227 -0
- package/src/guards/no-unscoped-queries.ts +834 -0
- package/src/guards/scan-utils.ts +105 -0
- package/src/guards/types.ts +30 -0
- package/src/history/actions/create-resource-version.ts +92 -0
- package/src/history/actions/get-resource-version.ts +60 -0
- package/src/history/actions/list-resource-history.ts +53 -0
- package/src/history/actions/list-resource-versions.ts +43 -0
- package/src/history/actions/restore-resource-version.ts +96 -0
- package/src/history/index.ts +26 -0
- package/src/history/registry.ts +111 -0
- package/src/history/store.ts +379 -0
- package/src/history/types.ts +69 -0
- package/src/index.browser.ts +155 -0
- package/src/index.ts +408 -0
- package/src/ingestion/docx.ts +158 -0
- package/src/ingestion/figma-node-to-html.ts +1860 -0
- package/src/ingestion/figma.ts +548 -0
- package/src/ingestion/index.ts +107 -0
- package/src/ingestion/media.ts +264 -0
- package/src/ingestion/notion.ts +121 -0
- package/src/ingestion/office.ts +213 -0
- package/src/ingestion/orchestration.ts +160 -0
- package/src/ingestion/pptx.ts +331 -0
- package/src/ingestion/selection.ts +81 -0
- package/src/ingestion/website.ts +151 -0
- package/src/integrations/a2a-continuation-marker.ts +2 -0
- package/src/integrations/a2a-continuation-processor.ts +888 -0
- package/src/integrations/a2a-continuations-store.ts +643 -0
- package/src/integrations/adapter-overrides.ts +12 -0
- package/src/integrations/adapters/discord.ts +364 -0
- package/src/integrations/adapters/email.ts +1164 -0
- package/src/integrations/adapters/google-docs.ts +371 -0
- package/src/integrations/adapters/index.ts +29 -0
- package/src/integrations/adapters/microsoft-teams.ts +413 -0
- package/src/integrations/adapters/slack.ts +1914 -0
- package/src/integrations/adapters/telegram.ts +386 -0
- package/src/integrations/adapters/whatsapp.ts +358 -0
- package/src/integrations/awaiting-input-store.ts +130 -0
- package/src/integrations/catalog.ts +571 -0
- package/src/integrations/computer-supervision-store.ts +423 -0
- package/src/integrations/computer-supervision.ts +213 -0
- package/src/integrations/config-store.ts +131 -0
- package/src/integrations/controls-store.ts +187 -0
- package/src/integrations/eject/messaging-adapters.ts +85 -0
- package/src/integrations/google-docs-poller.ts +671 -0
- package/src/integrations/identity-links-store.ts +210 -0
- package/src/integrations/identity.ts +196 -0
- package/src/integrations/index.ts +220 -0
- package/src/integrations/installations-store.ts +677 -0
- package/src/integrations/integration-memory.ts +187 -0
- package/src/integrations/internal-token.ts +106 -0
- package/src/integrations/pending-tasks-retry-job.ts +286 -0
- package/src/integrations/pending-tasks-store.ts +468 -0
- package/src/integrations/plugin.ts +3048 -0
- package/src/integrations/remote-commands-store.ts +690 -0
- package/src/integrations/remote-devices-store.ts +492 -0
- package/src/integrations/remote-json-safety.ts +127 -0
- package/src/integrations/remote-push-delivery-job.ts +48 -0
- package/src/integrations/remote-push-delivery.ts +370 -0
- package/src/integrations/remote-push-store.ts +664 -0
- package/src/integrations/remote-retry-job.ts +55 -0
- package/src/integrations/remote-run-events-store.ts +222 -0
- package/src/integrations/remote-types.ts +186 -0
- package/src/integrations/runtime.ts +1 -0
- package/src/integrations/scope-store.ts +498 -0
- package/src/integrations/slack-manifest.ts +78 -0
- package/src/integrations/slack-oauth.ts +344 -0
- package/src/integrations/task-queue-stats.ts +144 -0
- package/src/integrations/thread-mapping-store.ts +134 -0
- package/src/integrations/types.ts +485 -0
- package/src/integrations/usage-budget-store.ts +906 -0
- package/src/integrations/webhook-delivery.ts +55 -0
- package/src/integrations/webhook-handler.ts +1939 -0
- package/src/jobs/actions/list-recurring-jobs.ts +105 -0
- package/src/jobs/actions/manage-recurring-job.ts +85 -0
- package/src/jobs/cron.ts +126 -0
- package/src/jobs/index.ts +9 -0
- package/src/jobs/scheduler.ts +703 -0
- package/src/jobs/tools.ts +367 -0
- package/src/local-artifacts/index.ts +1372 -0
- package/src/localization/actions/get-localization-preference.ts +24 -0
- package/src/localization/actions/set-localization-preference.ts +32 -0
- package/src/localization/default-messages.ts +1009 -0
- package/src/localization/index.ts +2 -0
- package/src/localization/server.ts +131 -0
- package/src/localization/shared.ts +208 -0
- package/src/mcp/actions/call-mcp-tool.ts +19 -0
- package/src/mcp/actions/create-org-service-token.ts +87 -0
- package/src/mcp/actions/list-mcp-tools.ts +18 -0
- package/src/mcp/actions/list-org-service-tokens.ts +44 -0
- package/src/mcp/actions/revoke-org-service-token.ts +30 -0
- package/src/mcp/actions/service-token-access.ts +121 -0
- package/src/mcp/ask-app-inline-tasks.ts +125 -0
- package/src/mcp/build-server.ts +2356 -0
- package/src/mcp/builtin-tools.ts +1506 -0
- package/src/mcp/connect-route.ts +1460 -0
- package/src/mcp/connect-store.ts +680 -0
- package/src/mcp/embed-app.ts +2051 -0
- package/src/mcp/embed-route.ts +84 -0
- package/src/mcp/external-agent-policy.ts +18 -0
- package/src/mcp/index.ts +47 -0
- package/src/mcp/oauth-route.ts +1016 -0
- package/src/mcp/oauth-store.ts +581 -0
- package/src/mcp/oauth-token.ts +227 -0
- package/src/mcp/org-directory.ts +343 -0
- package/src/mcp/route-paths.ts +34 -0
- package/src/mcp/screen-memory-stdio.ts +290 -0
- package/src/mcp/server.ts +507 -0
- package/src/mcp/stdio.ts +328 -0
- package/src/mcp/workspace-resolve.ts +261 -0
- package/src/mcp-client/app-api.ts +136 -0
- package/src/mcp-client/app-result.ts +64 -0
- package/src/mcp-client/builtin-capabilities.ts +146 -0
- package/src/mcp-client/builtin-store.ts +93 -0
- package/src/mcp-client/config.ts +281 -0
- package/src/mcp-client/errors.ts +54 -0
- package/src/mcp-client/hub-client.ts +172 -0
- package/src/mcp-client/hub-routes.ts +198 -0
- package/src/mcp-client/index.ts +504 -0
- package/src/mcp-client/manager.ts +968 -0
- package/src/mcp-client/oauth-client.ts +462 -0
- package/src/mcp-client/oauth-routes.ts +307 -0
- package/src/mcp-client/remote-store.ts +674 -0
- package/src/mcp-client/remote-url.ts +97 -0
- package/src/mcp-client/routes.ts +1093 -0
- package/src/mcp-client/screen-memory-local.ts +461 -0
- package/src/mcp-client/tool-policy.ts +182 -0
- package/src/mcp-client/visibility.ts +56 -0
- package/src/mcp-client/workspace-servers.ts +379 -0
- package/src/navigation/index.ts +170 -0
- package/src/notifications/actions.ts +151 -0
- package/src/notifications/channels.ts +410 -0
- package/src/notifications/index.ts +22 -0
- package/src/notifications/registry.ts +216 -0
- package/src/notifications/routes.ts +106 -0
- package/src/notifications/store.ts +236 -0
- package/src/notifications/types.ts +52 -0
- package/src/oauth-tokens/google-refresh.ts +175 -0
- package/src/oauth-tokens/index.ts +15 -0
- package/src/oauth-tokens/store.ts +384 -0
- package/src/observability/cleanup-job.ts +124 -0
- package/src/observability/evals.ts +507 -0
- package/src/observability/experiments.ts +359 -0
- package/src/observability/feedback.ts +332 -0
- package/src/observability/hosted-model-experiment.ts +118 -0
- package/src/observability/index.ts +62 -0
- package/src/observability/plugin.ts +31 -0
- package/src/observability/routes.ts +431 -0
- package/src/observability/sentiment.ts +261 -0
- package/src/observability/store.ts +1347 -0
- package/src/observability/traces.ts +789 -0
- package/src/observability/tracing.ts +157 -0
- package/src/observability/tracking-identity.ts +55 -0
- package/src/observability/types.ts +211 -0
- package/src/onboarding/default-steps.ts +428 -0
- package/src/onboarding/index.ts +22 -0
- package/src/onboarding/plugin.ts +262 -0
- package/src/onboarding/registry.ts +47 -0
- package/src/onboarding/types.ts +96 -0
- package/src/org/accept-pending.ts +98 -0
- package/src/org/auto-join-domain.ts +113 -0
- package/src/org/context.ts +640 -0
- package/src/org/free-email-providers.ts +124 -0
- package/src/org/handlers.ts +1153 -0
- package/src/org/index.ts +63 -0
- package/src/org/migrations.ts +105 -0
- package/src/org/permissions.ts +30 -0
- package/src/org/plugin.ts +255 -0
- package/src/org/schema.ts +28 -0
- package/src/org/types.ts +57 -0
- package/src/org-team/index.ts +1 -0
- package/src/package-lifecycle/deprecated-imports.ts +179 -0
- package/src/package-lifecycle/eject-manifest.ts +345 -0
- package/src/package-lifecycle/index.ts +7 -0
- package/src/package-lifecycle/manifest.ts +120 -0
- package/src/package-lifecycle/migration-manifest.ts +159 -0
- package/src/package-lifecycle/migration-message.ts +6 -0
- package/src/package-lifecycle/tombstone.ts +58 -0
- package/src/package-lifecycle/upgrade-error.ts +37 -0
- package/src/private-blob/index.ts +18 -0
- package/src/private-blob/registry.ts +242 -0
- package/src/private-blob/types.ts +55 -0
- package/src/progress/actions.ts +179 -0
- package/src/progress/index.ts +16 -0
- package/src/progress/registry.ts +127 -0
- package/src/progress/routes.ts +89 -0
- package/src/progress/store.ts +353 -0
- package/src/progress/types.ts +59 -0
- package/src/provider-api/actions/custom-provider-registration.ts +197 -0
- package/src/provider-api/actions/delete-staged-dataset.ts +5 -0
- package/src/provider-api/actions/github-repo-files.ts +266 -0
- package/src/provider-api/actions/list-staged-datasets.ts +5 -0
- package/src/provider-api/actions/provider-api-audit.ts +88 -0
- package/src/provider-api/actions/provider-api.ts +460 -0
- package/src/provider-api/actions/query-staged-dataset.ts +5 -0
- package/src/provider-api/actions/staged-datasets.ts +359 -0
- package/src/provider-api/corpus-jobs-store.ts +522 -0
- package/src/provider-api/corpus-jobs.ts +1817 -0
- package/src/provider-api/custom-registry.ts +456 -0
- package/src/provider-api/github-repo.ts +675 -0
- package/src/provider-api/gong.ts +108 -0
- package/src/provider-api/index.ts +5444 -0
- package/src/provider-api/quota-governor.ts +562 -0
- package/src/provider-api/runtime.ts +1 -0
- package/src/provider-api/staged-datasets-aggregate.ts +304 -0
- package/src/provider-api/staged-datasets-store.ts +441 -0
- package/src/provider-api/staging.ts +483 -0
- package/src/resources/agents.ts +65 -0
- package/src/resources/emitter.ts +54 -0
- package/src/resources/handlers.ts +728 -0
- package/src/resources/index.ts +4 -0
- package/src/resources/metadata.ts +252 -0
- package/src/resources/script-helpers.ts +160 -0
- package/src/resources/store.ts +1618 -0
- package/src/review/actions/consume-review-feedback.ts +48 -0
- package/src/review/actions/create-review-comment.ts +108 -0
- package/src/review/actions/delete-review-comment.ts +67 -0
- package/src/review/actions/get-review-feedback.ts +49 -0
- package/src/review/actions/list-review-comments.ts +87 -0
- package/src/review/actions/reply-review-comment.ts +118 -0
- package/src/review/actions/resolve-review-thread.ts +94 -0
- package/src/review/actions/send-review-thread-to-agent.ts +62 -0
- package/src/review/actions/set-review-status.ts +58 -0
- package/src/review/identity.ts +101 -0
- package/src/review/index.ts +45 -0
- package/src/review/mentions.ts +44 -0
- package/src/review/registry.ts +111 -0
- package/src/review/store.ts +997 -0
- package/src/review/types.ts +101 -0
- package/src/router/index.ts +24 -0
- package/src/scripts/agent-engines/list-agent-engines.ts +130 -0
- package/src/scripts/agent-engines/manage-agent-engine.ts +197 -0
- package/src/scripts/agent-engines/set-agent-engine.ts +84 -0
- package/src/scripts/agent-engines/test-agent-engine.ts +174 -0
- package/src/scripts/call-agent.ts +792 -0
- package/src/scripts/chat/index.ts +8 -0
- package/src/scripts/chat/open-chat.ts +56 -0
- package/src/scripts/chat/search-chats.ts +121 -0
- package/src/scripts/core-scripts.ts +22 -0
- package/src/scripts/db/check-scoping.ts +212 -0
- package/src/scripts/db/exec.ts +791 -0
- package/src/scripts/db/index.ts +19 -0
- package/src/scripts/db/migrate-encrypt-credentials.ts +223 -0
- package/src/scripts/db/migrate-encrypt-oauth-tokens.ts +213 -0
- package/src/scripts/db/migrate-user-api-keys.ts +257 -0
- package/src/scripts/db/patch.ts +820 -0
- package/src/scripts/db/query.ts +299 -0
- package/src/scripts/db/reset-dev-owner.ts +285 -0
- package/src/scripts/db/safety.ts +286 -0
- package/src/scripts/db/schema.ts +364 -0
- package/src/scripts/db/scoping.ts +341 -0
- package/src/scripts/db/sqlite-client.ts +78 -0
- package/src/scripts/db/tool-mode.ts +23 -0
- package/src/scripts/db/tool-schemas.ts +31 -0
- package/src/scripts/db/wipe-leaked-builder-keys.ts +201 -0
- package/src/scripts/dev/index.ts +296 -0
- package/src/scripts/dev/list-files.ts +119 -0
- package/src/scripts/dev/read-file.ts +77 -0
- package/src/scripts/dev/search-files.ts +151 -0
- package/src/scripts/dev/shell.ts +111 -0
- package/src/scripts/dev/write-file.ts +56 -0
- package/src/scripts/dev-session.ts +96 -0
- package/src/scripts/docs/index.ts +8 -0
- package/src/scripts/docs/search.ts +274 -0
- package/src/scripts/docs/source-search.ts +363 -0
- package/src/scripts/index.ts +15 -0
- package/src/scripts/manage-agent-loop-settings.ts +84 -0
- package/src/scripts/parse-args.ts +46 -0
- package/src/scripts/resources/delete-memory.ts +67 -0
- package/src/scripts/resources/delete.ts +69 -0
- package/src/scripts/resources/effective.ts +71 -0
- package/src/scripts/resources/index.ts +18 -0
- package/src/scripts/resources/list.ts +103 -0
- package/src/scripts/resources/migrate-learnings.ts +40 -0
- package/src/scripts/resources/read.ts +107 -0
- package/src/scripts/resources/save-memory.ts +99 -0
- package/src/scripts/resources/write.ts +158 -0
- package/src/scripts/runner.ts +339 -0
- package/src/scripts/utils.ts +130 -0
- package/src/search/index.ts +413 -0
- package/src/search-utils/index.ts +112 -0
- package/src/secrets/crypto.ts +228 -0
- package/src/secrets/index.ts +65 -0
- package/src/secrets/onboarding.ts +101 -0
- package/src/secrets/register-framework-secrets.ts +228 -0
- package/src/secrets/register.ts +129 -0
- package/src/secrets/routes.ts +697 -0
- package/src/secrets/schema.ts +52 -0
- package/src/secrets/storage.ts +561 -0
- package/src/secrets/substitution.ts +305 -0
- package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +150 -0
- package/src/server/action-change.ts +66 -0
- package/src/server/action-discovery.ts +774 -0
- package/src/server/action-routes.ts +658 -0
- package/src/server/agent-access.ts +72 -0
- package/src/server/agent-chat/action-filters-a2a.ts +339 -0
- package/src/server/agent-chat/browser-team-tools.ts +510 -0
- package/src/server/agent-chat/context-tools.ts +599 -0
- package/src/server/agent-chat/framework-prompts.ts +467 -0
- package/src/server/agent-chat/lazy-fs.ts +11 -0
- package/src/server/agent-chat/mcp-glue.ts +91 -0
- package/src/server/agent-chat/plugin-options.ts +379 -0
- package/src/server/agent-chat/process-run-failure.ts +62 -0
- package/src/server/agent-chat/prompt-resources.ts +1004 -0
- package/src/server/agent-chat/recurring-jobs-runtime.ts +80 -0
- package/src/server/agent-chat/request-surface.ts +71 -0
- package/src/server/agent-chat/run-code-tools.ts +67 -0
- package/src/server/agent-chat/script-entries.ts +796 -0
- package/src/server/agent-chat/shared-thread.ts +301 -0
- package/src/server/agent-chat/skill-frontmatter.ts +41 -0
- package/src/server/agent-chat-plugin.ts +5930 -0
- package/src/server/agent-discovery.ts +706 -0
- package/src/server/agent-engine-api-key-route.ts +236 -0
- package/src/server/agent-run-context.ts +204 -0
- package/src/server/agent-teams-run-queue.ts +344 -0
- package/src/server/agent-teams.ts +2257 -0
- package/src/server/agents-bundle.ts +464 -0
- package/src/server/analytics.ts +105 -0
- package/src/server/app-base-path.ts +79 -0
- package/src/server/app-name.ts +53 -0
- package/src/server/app-url.ts +184 -0
- package/src/server/attachment-actions.ts +276 -0
- package/src/server/attribution.ts +214 -0
- package/src/server/auth-marketing.ts +260 -0
- package/src/server/auth-plugin.ts +32 -0
- package/src/server/auth.ts +3803 -0
- package/src/server/better-auth-instance.ts +1201 -0
- package/src/server/builder-browser.ts +1701 -0
- package/src/server/builder-design-systems.ts +668 -0
- package/src/server/builder-space.ts +176 -0
- package/src/server/captcha.ts +63 -0
- package/src/server/capture-error.ts +64 -0
- package/src/server/cli-capture.ts +141 -0
- package/src/server/collab-plugin.ts +391 -0
- package/src/server/complete-text.ts +231 -0
- package/src/server/cookie-namespace.ts +159 -0
- package/src/server/core-routes-plugin.ts +4122 -0
- package/src/server/cors-origins.ts +60 -0
- package/src/server/create-server.ts +268 -0
- package/src/server/credential-provider.ts +1202 -0
- package/src/server/csrf.ts +229 -0
- package/src/server/date-utils.ts +42 -0
- package/src/server/deep-link.ts +119 -0
- package/src/server/derived-secret.ts +32 -0
- package/src/server/design-token-utils.ts +1032 -0
- package/src/server/desktop-sso.ts +83 -0
- package/src/server/edge.ts +69 -0
- package/src/server/email-actions.ts +218 -0
- package/src/server/email-template.ts +192 -0
- package/src/server/email-templates.ts +148 -0
- package/src/server/email.ts +219 -0
- package/src/server/embed-route.ts +283 -0
- package/src/server/embed-session.ts +805 -0
- package/src/server/embedded.ts +252 -0
- package/src/server/entry-server.tsx +154 -0
- package/src/server/framework-request-handler.ts +848 -0
- package/src/server/fusion-app.ts +447 -0
- package/src/server/google-auth-mode.ts +34 -0
- package/src/server/google-auth-plugin.ts +496 -0
- package/src/server/google-oauth-credentials.ts +128 -0
- package/src/server/google-oauth.ts +972 -0
- package/src/server/google-realtime-session.ts +182 -0
- package/src/server/h3-helpers.ts +174 -0
- package/src/server/http-response-telemetry.ts +396 -0
- package/src/server/identity-sso-store.ts +304 -0
- package/src/server/identity-sso.ts +514 -0
- package/src/server/index.ts +593 -0
- package/src/server/missing-key.ts +36 -0
- package/src/server/oauth-helpers.ts +44 -0
- package/src/server/oauth-public-origin.ts +44 -0
- package/src/server/oauth-return-url.ts +120 -0
- package/src/server/og-fonts-data.ts +15 -0
- package/src/server/og-fonts.ts +75 -0
- package/src/server/onboarding-html.ts +4040 -0
- package/src/server/open-route.ts +311 -0
- package/src/server/org-admin.ts +28 -0
- package/src/server/poll-events.ts +88 -0
- package/src/server/poll.ts +1224 -0
- package/src/server/prompts/framework-core-compact.ts +107 -0
- package/src/server/prompts/framework-core.ts +143 -0
- package/src/server/prompts/index.ts +16 -0
- package/src/server/prompts/model-overlays.ts +54 -0
- package/src/server/prompts/shared-rules.ts +104 -0
- package/src/server/realtime-voice.ts +967 -0
- package/src/server/recap-image-route.ts +242 -0
- package/src/server/recap-image-store.ts +185 -0
- package/src/server/request-context.ts +416 -0
- package/src/server/request-origin.ts +67 -0
- package/src/server/resources-plugin.ts +119 -0
- package/src/server/schema-prompt.ts +429 -0
- package/src/server/scoped-key-storage.ts +223 -0
- package/src/server/security-headers.ts +170 -0
- package/src/server/self-dispatch.ts +224 -0
- package/src/server/sentry-config.ts +73 -0
- package/src/server/sentry-plugin.ts +138 -0
- package/src/server/sentry.ts +444 -0
- package/src/server/short-lived-token.ts +170 -0
- package/src/server/social-og-image.ts +454 -0
- package/src/server/sse.ts +102 -0
- package/src/server/ssr-handler.ts +466 -0
- package/src/server/transcribe-voice.ts +1076 -0
- package/src/server/voice-providers-status.ts +118 -0
- package/src/server/workspace-oauth.ts +31 -0
- package/src/server/workspace-provider-oauth.ts +970 -0
- package/src/session-replay-iframe-protocol.ts +58 -0
- package/src/settings/handlers.ts +44 -0
- package/src/settings/index.ts +34 -0
- package/src/settings/org-settings.ts +83 -0
- package/src/settings/script-helpers.ts +24 -0
- package/src/settings/store.ts +247 -0
- package/src/settings/user-settings.ts +47 -0
- package/src/setup-connections/index.ts +90 -0
- package/src/setup-connections/onboarding.ts +47 -0
- package/src/shared/agent-access.ts +112 -0
- package/src/shared/agent-chat.ts +124 -0
- package/src/shared/agent-env.ts +46 -0
- package/src/shared/agent-readable-resource.ts +111 -0
- package/src/shared/agent-sidebar-url.ts +39 -0
- package/src/shared/cache-control.ts +25 -0
- package/src/shared/cloudflare-globals.d.ts +34 -0
- package/src/shared/context-xray.ts +172 -0
- package/src/shared/embed-auth.ts +6 -0
- package/src/shared/index.ts +83 -0
- package/src/shared/llm-connection.ts +42 -0
- package/src/shared/markdown-block-split.ts +129 -0
- package/src/shared/mcp-connect-content.ts +130 -0
- package/src/shared/mcp-embed-headers.ts +175 -0
- package/src/shared/mcp-integration-config.ts +101 -0
- package/src/shared/merge-by-id.ts +14 -0
- package/src/shared/oauth-state.ts +39 -0
- package/src/shared/reasoning-effort.ts +228 -0
- package/src/shared/route-warmup-config.ts +128 -0
- package/src/shared/runtime.ts +31 -0
- package/src/shared/social-meta.ts +82 -0
- package/src/shared/streaming-text-smoothing.ts +184 -0
- package/src/shared/truncate.ts +13 -0
- package/src/shared/workspace-app-audience.ts +177 -0
- package/src/shared/workspace-app-id.ts +54 -0
- package/src/sharing/access.ts +585 -0
- package/src/sharing/actions/create-agent-resource-link.ts +91 -0
- package/src/sharing/actions/extension-change.ts +22 -0
- package/src/sharing/actions/list-resource-shares.ts +93 -0
- package/src/sharing/actions/set-resource-visibility.ts +91 -0
- package/src/sharing/actions/share-resource.ts +322 -0
- package/src/sharing/actions/unshare-resource.ts +72 -0
- package/src/sharing/index.ts +35 -0
- package/src/sharing/registry.ts +201 -0
- package/src/sharing/schema.ts +99 -0
- package/src/styles/agent-conversation.css +766 -0
- package/src/styles/agent-native.css +938 -0
- package/src/styles/blocks.css +1717 -0
- package/src/styles/chat-history-list.css +1 -0
- package/src/styles/rich-markdown-editor.css +1 -0
- package/src/tailwind.preset.ts +140 -0
- package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +15 -13
- package/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/src/templates/chat/AGENTS.md +3 -2
- package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +15 -13
- package/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/src/templates/default/AGENTS.md +6 -5
- package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +15 -13
- package/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/src/templates/headless/AGENTS.md +5 -4
- package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +15 -13
- package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +3 -2
- package/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +63 -20
- package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +9 -6
- package/src/templates/workspace-core/AGENTS.md +4 -4
- package/src/templates/workspace-root/AGENTS.md +4 -4
- package/src/terminal/cli-registry.ts +57 -0
- package/src/terminal/index.ts +22 -0
- package/src/terminal/pty-server.ts +389 -0
- package/src/terminal/terminal-plugin.ts +265 -0
- package/src/testing.ts +23 -0
- package/src/tracking/index.ts +10 -0
- package/src/tracking/providers.ts +422 -0
- package/src/tracking/registry.ts +102 -0
- package/src/tracking/route.ts +108 -0
- package/src/tracking/types.ts +16 -0
- package/src/transcription/builder-transcription.ts +118 -0
- package/src/triggers/actions/list-automations.ts +99 -0
- package/src/triggers/actions/manage-automation.ts +78 -0
- package/src/triggers/actions.ts +333 -0
- package/src/triggers/condition-evaluator.ts +163 -0
- package/src/triggers/dispatcher.ts +536 -0
- package/src/triggers/index.ts +13 -0
- package/src/triggers/routes.ts +322 -0
- package/src/triggers/types.ts +42 -0
- package/src/types/pglite.d.ts +26 -0
- package/src/usage/store.ts +698 -0
- package/src/vite/action-types-plugin.ts +481 -0
- package/src/vite/agent-web-plugin.ts +78 -0
- package/src/vite/agents-bundle-plugin.ts +185 -0
- package/src/vite/client.ts +3056 -0
- package/src/vite/index.ts +21 -0
- package/src/voice/index.ts +18 -0
- package/src/voice/voice-cleanup-prompt.ts +38 -0
- package/src/voice/voice-context.ts +217 -0
- package/src/voice/voice-replacements.ts +75 -0
- package/src/workspace-connections/credentials.ts +603 -0
- package/src/workspace-connections/index.ts +72 -0
- package/src/workspace-connections/lifecycle.ts +43 -0
- package/src/workspace-connections/store.ts +1943 -0
- package/src/workspace-files/index.ts +18 -0
- package/src/workspace-files/store.ts +339 -0
- package/src/workspace-files/tool.ts +266 -0
|
@@ -0,0 +1,2257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Teams — sub-agent orchestration for agent-native.
|
|
3
|
+
*
|
|
4
|
+
* The main agent chat acts as an orchestrator. It spawns sub-agents
|
|
5
|
+
* for individual tasks, which run in their own threads. Sub-agents
|
|
6
|
+
* appear as rich preview cards (chips) inline in the main chat.
|
|
7
|
+
*
|
|
8
|
+
* This module provides the server-side infrastructure:
|
|
9
|
+
* - Creating sub-agent threads and running them in background
|
|
10
|
+
* - Tracking task status and results
|
|
11
|
+
* - Emitting SSE events for live preview cards
|
|
12
|
+
* - Bidirectional messaging between main agent and sub-agents
|
|
13
|
+
*
|
|
14
|
+
* Task state is persisted in application_state (SQL) so it survives
|
|
15
|
+
* serverless cold starts and works across multiple processes.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
19
|
+
|
|
20
|
+
import { applyAgentTextEventToBuffer } from "../a2a/response-text.js";
|
|
21
|
+
import { resolveMainChatMaxOutputTokens } from "../agent/engine/output-tokens.js";
|
|
22
|
+
import type { AgentEngine, EngineMessage } from "../agent/engine/types.js";
|
|
23
|
+
import type {
|
|
24
|
+
ActionEntry,
|
|
25
|
+
AgentLoopFinalResponseGuard,
|
|
26
|
+
} from "../agent/production-agent.js";
|
|
27
|
+
import {
|
|
28
|
+
actionsToEngineTools,
|
|
29
|
+
filterInitialEngineTools,
|
|
30
|
+
resolveAgentRequestReasoningEffort,
|
|
31
|
+
} from "../agent/production-agent.js";
|
|
32
|
+
import {
|
|
33
|
+
runAgentLoop,
|
|
34
|
+
appendAgentLoopContinuation,
|
|
35
|
+
} from "../agent/production-agent.js";
|
|
36
|
+
import {
|
|
37
|
+
abortRun,
|
|
38
|
+
getActiveRunForThreadAsync,
|
|
39
|
+
getRun,
|
|
40
|
+
startRun,
|
|
41
|
+
subscribeToRun,
|
|
42
|
+
type ActiveRun,
|
|
43
|
+
} from "../agent/run-manager.js";
|
|
44
|
+
import { getRunEventsSince } from "../agent/run-store.js";
|
|
45
|
+
import { resolveMaxSubagentDelegationDepth } from "../agent/runtime-context.js";
|
|
46
|
+
import {
|
|
47
|
+
buildAssistantMessage,
|
|
48
|
+
foldAssistantTurn,
|
|
49
|
+
threadDataToEngineMessages,
|
|
50
|
+
} from "../agent/thread-data-builder.js";
|
|
51
|
+
import { attachToolSearch } from "../agent/tool-search.js";
|
|
52
|
+
import type { AgentChatEvent } from "../agent/types.js";
|
|
53
|
+
import type { RunEvent } from "../agent/types.js";
|
|
54
|
+
import {
|
|
55
|
+
readAppState,
|
|
56
|
+
writeAppState,
|
|
57
|
+
listAppState,
|
|
58
|
+
deleteAppState,
|
|
59
|
+
} from "../application-state/script-helpers.js";
|
|
60
|
+
import { createThread } from "../chat-threads/store.js";
|
|
61
|
+
import type {
|
|
62
|
+
BackgroundAgentRun,
|
|
63
|
+
BackgroundAgentRunStatus,
|
|
64
|
+
BackgroundAgentTranscriptEvent,
|
|
65
|
+
} from "../code-agents/background-run.js";
|
|
66
|
+
import type {
|
|
67
|
+
BackgroundAgentController,
|
|
68
|
+
BackgroundAgentControlInput,
|
|
69
|
+
BackgroundAgentControlResult,
|
|
70
|
+
BackgroundAgentFollowUpInput,
|
|
71
|
+
ListBackgroundAgentRunsOptions,
|
|
72
|
+
} from "../code-agents/index.js";
|
|
73
|
+
import { describeDbError } from "../db/client.js";
|
|
74
|
+
import { resolveOrgIdForEmail } from "../org/context.js";
|
|
75
|
+
import {
|
|
76
|
+
completeRun as completeProgressRun,
|
|
77
|
+
startRun as startProgressRun,
|
|
78
|
+
updateRunProgress,
|
|
79
|
+
} from "../progress/registry.js";
|
|
80
|
+
import {
|
|
81
|
+
enqueueAgentTeamRun,
|
|
82
|
+
claimAgentTeamRun,
|
|
83
|
+
touchAgentTeamRun,
|
|
84
|
+
bumpAgentTeamContinuation,
|
|
85
|
+
completeAgentTeamRun,
|
|
86
|
+
getAgentTeamRunDispatchState,
|
|
87
|
+
listActiveAgentTeamTaskIdsForOwner,
|
|
88
|
+
MAX_AGENT_TEAM_CONTINUATIONS,
|
|
89
|
+
MAX_AGENT_TEAM_NO_PROGRESS_CONTINUATIONS,
|
|
90
|
+
RUN_DISPATCH_STUCK_AFTER_MS,
|
|
91
|
+
RUN_PROCESSING_STUCK_AFTER_MS,
|
|
92
|
+
type AgentTeamRunPayload,
|
|
93
|
+
} from "./agent-teams-run-queue.js";
|
|
94
|
+
import {
|
|
95
|
+
getRequestUserEmail,
|
|
96
|
+
runWithRequestContext,
|
|
97
|
+
} from "./request-context.js";
|
|
98
|
+
import { fireInternalDispatch } from "./self-dispatch.js";
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Ambient delegation depth for the agent whose run is currently executing.
|
|
102
|
+
*
|
|
103
|
+
* `processAgentTeamRun` runs each sub-agent inside `runWithDelegationDepth(d)`
|
|
104
|
+
* where `d` is that sub-agent's own depth. So if a sub-agent calls `spawnTask`
|
|
105
|
+
* (e.g. because tool-stripping was bypassed and it was handed the `agent-teams`
|
|
106
|
+
* tool anyway), the spawn path reads its parent's depth from here and refuses
|
|
107
|
+
* once the cap is reached — independent of any tool-level guard. The top-level
|
|
108
|
+
* chat runs outside this storage, so its ambient depth is 0.
|
|
109
|
+
*/
|
|
110
|
+
const delegationDepthStorage = new AsyncLocalStorage<number>();
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Run `fn` with `depth` recorded as the ambient delegation depth so any
|
|
114
|
+
* `spawnTask` call made transitively from `fn` knows the depth of the agent
|
|
115
|
+
* doing the spawning.
|
|
116
|
+
*/
|
|
117
|
+
function runWithDelegationDepth<T>(
|
|
118
|
+
depth: number,
|
|
119
|
+
fn: () => T | Promise<T>,
|
|
120
|
+
): T | Promise<T> {
|
|
121
|
+
return delegationDepthStorage.run(Math.max(0, Math.floor(depth || 0)), fn);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Depth of the agent currently executing (0 = top-level chat). */
|
|
125
|
+
function currentAmbientDelegationDepth(): number {
|
|
126
|
+
return delegationDepthStorage.getStore() ?? 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Public read of the ambient sub-agent delegation depth for the currently
|
|
131
|
+
* executing agent. 0 = the top-level (user-facing) chat; 1+ = a spawned
|
|
132
|
+
* sub-agent. Used by the chat plugin to thread the depth into
|
|
133
|
+
* `buildRuntimeContextPrompt` so a sub-agent at the cap is told it can't
|
|
134
|
+
* delegate further. Mirrors `currentAmbientDelegationDepth`; exported under a
|
|
135
|
+
* descriptive name so callers outside this module don't depend on the private
|
|
136
|
+
* helper or the test-only export object.
|
|
137
|
+
*/
|
|
138
|
+
export function getCurrentDelegationDepth(): number {
|
|
139
|
+
return currentAmbientDelegationDepth();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface SubagentDepthDecision {
|
|
143
|
+
/** Whether the spawn is allowed under the depth cap. */
|
|
144
|
+
allowed: boolean;
|
|
145
|
+
/** Depth of the agent doing the spawning (parent). */
|
|
146
|
+
parentDepth: number;
|
|
147
|
+
/** Depth the spawned sub-agent would have (parentDepth + 1). */
|
|
148
|
+
childDepth: number;
|
|
149
|
+
/** The effective cap (resolved from env, clamped). */
|
|
150
|
+
maxDepth: number;
|
|
151
|
+
/** Human-readable refusal message when `allowed` is false. */
|
|
152
|
+
error?: string;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Decide whether an agent at `parentDepth` may spawn another sub-agent. The
|
|
157
|
+
* child would sit at `parentDepth + 1`; a child deeper than `maxDepth` is
|
|
158
|
+
* refused. Pure + exported so the enforcement is unit-testable and reusable.
|
|
159
|
+
*/
|
|
160
|
+
export function evaluateSubagentDepth(
|
|
161
|
+
parentDepth: number,
|
|
162
|
+
env: Record<string, string | undefined> = process.env,
|
|
163
|
+
): SubagentDepthDecision {
|
|
164
|
+
const safeParentDepth = Number.isFinite(parentDepth)
|
|
165
|
+
? Math.max(0, Math.floor(parentDepth))
|
|
166
|
+
: 0;
|
|
167
|
+
const childDepth = safeParentDepth + 1;
|
|
168
|
+
const maxDepth = resolveMaxSubagentDelegationDepth(env);
|
|
169
|
+
const allowed = childDepth <= maxDepth;
|
|
170
|
+
return {
|
|
171
|
+
allowed,
|
|
172
|
+
parentDepth: safeParentDepth,
|
|
173
|
+
childDepth,
|
|
174
|
+
maxDepth,
|
|
175
|
+
error: allowed
|
|
176
|
+
? undefined
|
|
177
|
+
: `Delegation depth limit reached (max ${maxDepth}); cannot spawn another sub-agent.`,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** Framework route the self-fire dispatch targets to run a queued sub-agent in
|
|
182
|
+
* a fresh function invocation. Mounted inside the agent-chat plugin (where the
|
|
183
|
+
* sub-agent action/prompt/engine closures live). */
|
|
184
|
+
export const AGENT_TEAM_PROCESS_RUN_PATH =
|
|
185
|
+
"/_agent-native/agent-teams/_process-run";
|
|
186
|
+
|
|
187
|
+
/** Heartbeat cadence for the queue row while a chunk is actively processing. */
|
|
188
|
+
const RUN_QUEUE_HEARTBEAT_MS = 5_000;
|
|
189
|
+
|
|
190
|
+
export interface AgentTask {
|
|
191
|
+
taskId: string;
|
|
192
|
+
threadId: string;
|
|
193
|
+
parentThreadId?: string;
|
|
194
|
+
name?: string;
|
|
195
|
+
description: string;
|
|
196
|
+
status: "running" | "completed" | "errored";
|
|
197
|
+
preview: string;
|
|
198
|
+
summary: string;
|
|
199
|
+
currentStep: string;
|
|
200
|
+
createdAt: number;
|
|
201
|
+
updatedAt?: number;
|
|
202
|
+
startedAt?: number;
|
|
203
|
+
completedAt?: number;
|
|
204
|
+
runId?: string;
|
|
205
|
+
error?: string;
|
|
206
|
+
/**
|
|
207
|
+
* Delegation depth of THIS sub-agent: 1 for a sub-agent spawned by the
|
|
208
|
+
* top-level chat, 2 for a sub-agent spawned by a depth-1 sub-agent, etc.
|
|
209
|
+
* Drives the runaway-delegation guardrail (see `evaluateSubagentDepth`).
|
|
210
|
+
*/
|
|
211
|
+
delegationDepth?: number;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export type AgentTeamBackgroundRun = Omit<
|
|
215
|
+
BackgroundAgentRun,
|
|
216
|
+
| "kind"
|
|
217
|
+
| "source"
|
|
218
|
+
| "sourceRecord"
|
|
219
|
+
| "status"
|
|
220
|
+
| "cwd"
|
|
221
|
+
| "goalId"
|
|
222
|
+
| "transcriptPath"
|
|
223
|
+
| "artifactRoot"
|
|
224
|
+
> & {
|
|
225
|
+
kind: "agent-team";
|
|
226
|
+
source: "hosted-agent-team";
|
|
227
|
+
sourceRecord: {
|
|
228
|
+
type: "agent-team-task";
|
|
229
|
+
id: string;
|
|
230
|
+
threadId: string;
|
|
231
|
+
};
|
|
232
|
+
status: BackgroundAgentRunStatus;
|
|
233
|
+
cwd?: string;
|
|
234
|
+
goalId: "agent-team";
|
|
235
|
+
transcriptPath?: string;
|
|
236
|
+
artifactRoot?: string;
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
export type AgentTeamBackgroundTranscriptEvent = Omit<
|
|
240
|
+
BackgroundAgentTranscriptEvent,
|
|
241
|
+
"kind" | "source" | "sourceRecord"
|
|
242
|
+
> & {
|
|
243
|
+
kind: "user" | "system" | "note" | "artifact" | "status";
|
|
244
|
+
source: "hosted-agent-team";
|
|
245
|
+
sourceRecord: {
|
|
246
|
+
type: "agent-team-run-event";
|
|
247
|
+
id: string;
|
|
248
|
+
seq: number;
|
|
249
|
+
};
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
export interface SendToAgentTeamBackgroundRunResult {
|
|
253
|
+
ok: boolean;
|
|
254
|
+
error?: string;
|
|
255
|
+
messageId?: string;
|
|
256
|
+
queuedCount?: number;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export interface ControlAgentTeamBackgroundRunResult {
|
|
260
|
+
ok: boolean;
|
|
261
|
+
error?: string;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export function createAgentTeamBackgroundAgentController(): BackgroundAgentController {
|
|
265
|
+
return {
|
|
266
|
+
async list(options?: ListBackgroundAgentRunsOptions) {
|
|
267
|
+
if (options?.goalId && options.goalId !== "agent-team") return [];
|
|
268
|
+
return listAgentTeamBackgroundRuns();
|
|
269
|
+
},
|
|
270
|
+
get: getAgentTeamBackgroundRun,
|
|
271
|
+
transcript: listAgentTeamBackgroundTranscriptEvents,
|
|
272
|
+
sendFollowUp: sendAgentTeamBackgroundAgentFollowUp,
|
|
273
|
+
control: controlAgentTeamBackgroundAgentRun,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export const agentTeamBackgroundAgentController =
|
|
278
|
+
createAgentTeamBackgroundAgentController();
|
|
279
|
+
|
|
280
|
+
/** Key prefix for task records: agent-task:{taskId} */
|
|
281
|
+
const TASK_PREFIX = "agent-task:";
|
|
282
|
+
|
|
283
|
+
/** Key prefix for thread→task reverse lookup: agent-task-thread:{threadId} */
|
|
284
|
+
const THREAD_PREFIX = "agent-task-thread:";
|
|
285
|
+
|
|
286
|
+
/** Key prefix for queued orchestrator→sub-agent messages. */
|
|
287
|
+
const TASK_MESSAGE_PREFIX = "task-message:";
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Key prefix for durable completion-injection entries that tell the parent
|
|
291
|
+
* thread's next turn about a finished sub-agent. Pattern mirrors
|
|
292
|
+
* `TASK_MESSAGE_PREFIX` (appstate key → JSON payload consumed once).
|
|
293
|
+
*
|
|
294
|
+
* Key: `parent-completion:{parentThreadId}:{injectionId}`
|
|
295
|
+
* Value: `ParentCompletionInjection` JSON.
|
|
296
|
+
*/
|
|
297
|
+
const PARENT_COMPLETION_PREFIX = "parent-completion:";
|
|
298
|
+
|
|
299
|
+
/** Max chars of the sub-agent summary to include inline in the injection.
|
|
300
|
+
* The orchestrator can always call read-result for the full output. */
|
|
301
|
+
const PARENT_COMPLETION_INLINE_MAX = 2_000;
|
|
302
|
+
|
|
303
|
+
export interface ParentCompletionInjection {
|
|
304
|
+
id: string;
|
|
305
|
+
taskId: string;
|
|
306
|
+
taskName?: string;
|
|
307
|
+
status: "completed" | "errored";
|
|
308
|
+
hitContinuationLimit: boolean;
|
|
309
|
+
summaryExcerpt: string;
|
|
310
|
+
fullSummaryAvailable: boolean;
|
|
311
|
+
timestamp: number;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function parentCompletionQueuePrefix(parentThreadId: string): string {
|
|
315
|
+
return `${PARENT_COMPLETION_PREFIX}${parentThreadId}:`;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function generateInjectionId(): string {
|
|
319
|
+
return `inj-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/** Append a completion-injection entry to the parent thread's queue. */
|
|
323
|
+
async function appendParentCompletionInjection(
|
|
324
|
+
parentThreadId: string,
|
|
325
|
+
task: AgentTask,
|
|
326
|
+
terminal: {
|
|
327
|
+
taskStatus: "completed" | "errored";
|
|
328
|
+
summary: string;
|
|
329
|
+
hitContinuationLimit?: boolean;
|
|
330
|
+
},
|
|
331
|
+
): Promise<void> {
|
|
332
|
+
const id = generateInjectionId();
|
|
333
|
+
const summaryExcerpt =
|
|
334
|
+
terminal.summary.length > PARENT_COMPLETION_INLINE_MAX
|
|
335
|
+
? terminal.summary.slice(0, PARENT_COMPLETION_INLINE_MAX)
|
|
336
|
+
: terminal.summary;
|
|
337
|
+
const injection: ParentCompletionInjection = {
|
|
338
|
+
id,
|
|
339
|
+
taskId: task.taskId,
|
|
340
|
+
taskName: task.name,
|
|
341
|
+
status: terminal.taskStatus,
|
|
342
|
+
hitContinuationLimit: terminal.hitContinuationLimit ?? false,
|
|
343
|
+
summaryExcerpt,
|
|
344
|
+
fullSummaryAvailable:
|
|
345
|
+
terminal.summary.length > PARENT_COMPLETION_INLINE_MAX,
|
|
346
|
+
timestamp: Date.now(),
|
|
347
|
+
};
|
|
348
|
+
await writeAppState(
|
|
349
|
+
`${parentCompletionQueuePrefix(parentThreadId)}${id}`,
|
|
350
|
+
injection as any,
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/** Format a parent-completion injection as a human-readable orchestrator
|
|
355
|
+
* message. Mirrors `formatQueuedTaskMessages`. */
|
|
356
|
+
function formatParentCompletionInjection(
|
|
357
|
+
inj: ParentCompletionInjection,
|
|
358
|
+
): string {
|
|
359
|
+
const name = inj.taskName ? `"${inj.taskName}"` : `task ${inj.taskId}`;
|
|
360
|
+
const statusLine =
|
|
361
|
+
inj.status === "completed"
|
|
362
|
+
? inj.hitContinuationLimit
|
|
363
|
+
? `completed (reached continuation limit — partial result)`
|
|
364
|
+
: `completed`
|
|
365
|
+
: `failed`;
|
|
366
|
+
const tail = inj.fullSummaryAvailable
|
|
367
|
+
? `\n\n(Full output truncated — call \`agent-teams\` action "read-result" with taskId "${inj.taskId}" to retrieve the complete result.)`
|
|
368
|
+
: "";
|
|
369
|
+
return `Sub-agent ${name} ${statusLine}:\n\n${inj.summaryExcerpt}${tail}`;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Drain the parent-completion injection queue for a thread. Returns all
|
|
374
|
+
* pending injections and deletes them atomically. Exported so the agent-chat
|
|
375
|
+
* plugin can drain these into the orchestrator's next user-turn.
|
|
376
|
+
*/
|
|
377
|
+
export async function drainParentCompletionInjections(
|
|
378
|
+
parentThreadId: string,
|
|
379
|
+
): Promise<ParentCompletionInjection[]> {
|
|
380
|
+
const prefix = parentCompletionQueuePrefix(parentThreadId);
|
|
381
|
+
const entries = await listAppState(prefix);
|
|
382
|
+
if (entries.length === 0) return [];
|
|
383
|
+
const injections: ParentCompletionInjection[] = [];
|
|
384
|
+
for (const entry of entries) {
|
|
385
|
+
const v = entry.value as Record<string, unknown>;
|
|
386
|
+
if (
|
|
387
|
+
typeof v.id === "string" &&
|
|
388
|
+
typeof v.taskId === "string" &&
|
|
389
|
+
typeof v.status === "string"
|
|
390
|
+
) {
|
|
391
|
+
injections.push(v as unknown as ParentCompletionInjection);
|
|
392
|
+
await deleteAppState(entry.key);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return injections.sort((a, b) => a.timestamp - b.timestamp);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Format all drained parent-completion injections as a single user-turn
|
|
400
|
+
* message to inject into the orchestrator thread.
|
|
401
|
+
*/
|
|
402
|
+
export function formatParentCompletionInjections(
|
|
403
|
+
injections: ParentCompletionInjection[],
|
|
404
|
+
): string {
|
|
405
|
+
return injections.map(formatParentCompletionInjection).join("\n\n---\n\n");
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
const TASK_RUN_MISSING_GRACE_MS = 60_000;
|
|
409
|
+
|
|
410
|
+
export interface QueuedTaskMessage {
|
|
411
|
+
id: string;
|
|
412
|
+
from: "orchestrator";
|
|
413
|
+
message: string;
|
|
414
|
+
timestamp: number;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function taskMessageQueuePrefix(taskId: string): string {
|
|
418
|
+
return `${TASK_MESSAGE_PREFIX}${taskId}:`;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function generateTaskMessageId(): string {
|
|
422
|
+
return `msg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function normalizeQueuedTaskMessage(
|
|
426
|
+
value: Record<string, unknown>,
|
|
427
|
+
fallbackId: string,
|
|
428
|
+
): QueuedTaskMessage | null {
|
|
429
|
+
if (typeof value.message !== "string" || value.message.trim().length === 0) {
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
const timestamp =
|
|
433
|
+
typeof value.timestamp === "number" && Number.isFinite(value.timestamp)
|
|
434
|
+
? value.timestamp
|
|
435
|
+
: Date.now();
|
|
436
|
+
return {
|
|
437
|
+
id: typeof value.id === "string" ? value.id : fallbackId,
|
|
438
|
+
from: "orchestrator",
|
|
439
|
+
message: value.message,
|
|
440
|
+
timestamp,
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function formatQueuedTaskMessages(messages: QueuedTaskMessage[]): string {
|
|
445
|
+
const label =
|
|
446
|
+
messages.length === 1
|
|
447
|
+
? "Orchestrator message received while you were working"
|
|
448
|
+
: "Orchestrator messages received while you were working";
|
|
449
|
+
const body = messages
|
|
450
|
+
.map((message) => {
|
|
451
|
+
const sentAt = new Date(message.timestamp).toISOString();
|
|
452
|
+
return `[${sentAt}] ${message.message}`;
|
|
453
|
+
})
|
|
454
|
+
.join("\n\n");
|
|
455
|
+
return `${label}:\n\n${body}\n\nAdjust your next steps to account for this update.`;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const taskMessageDrainLocks = new Map<string, Promise<unknown>>();
|
|
459
|
+
|
|
460
|
+
async function withTaskMessageDrainLock<T>(
|
|
461
|
+
taskId: string,
|
|
462
|
+
fn: () => Promise<T>,
|
|
463
|
+
): Promise<T> {
|
|
464
|
+
const previous = taskMessageDrainLocks.get(taskId) ?? Promise.resolve();
|
|
465
|
+
let release!: () => void;
|
|
466
|
+
const current = new Promise<void>((resolve) => (release = resolve));
|
|
467
|
+
taskMessageDrainLocks.set(taskId, current);
|
|
468
|
+
await previous.catch(() => {});
|
|
469
|
+
try {
|
|
470
|
+
return await fn();
|
|
471
|
+
} finally {
|
|
472
|
+
release();
|
|
473
|
+
if (taskMessageDrainLocks.get(taskId) === current) {
|
|
474
|
+
taskMessageDrainLocks.delete(taskId);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
async function listQueuedTaskMessages(
|
|
480
|
+
taskId: string,
|
|
481
|
+
): Promise<Array<{ key: string; message: QueuedTaskMessage }>> {
|
|
482
|
+
const queuePrefix = taskMessageQueuePrefix(taskId);
|
|
483
|
+
const entries = await listAppState(queuePrefix);
|
|
484
|
+
const messages = entries
|
|
485
|
+
.map((entry) => {
|
|
486
|
+
const id = entry.key.slice(queuePrefix.length);
|
|
487
|
+
const message = normalizeQueuedTaskMessage(entry.value, id);
|
|
488
|
+
return message ? { key: entry.key, message } : null;
|
|
489
|
+
})
|
|
490
|
+
.filter(
|
|
491
|
+
(
|
|
492
|
+
entry,
|
|
493
|
+
): entry is {
|
|
494
|
+
key: string;
|
|
495
|
+
message: QueuedTaskMessage;
|
|
496
|
+
} => Boolean(entry),
|
|
497
|
+
);
|
|
498
|
+
|
|
499
|
+
// Backward compatibility for messages queued by the old implementation.
|
|
500
|
+
const legacyKey = `${TASK_MESSAGE_PREFIX}${taskId}`;
|
|
501
|
+
const legacy = await readAppState(legacyKey);
|
|
502
|
+
const legacyMessage = legacy
|
|
503
|
+
? normalizeQueuedTaskMessage(legacy, "legacy")
|
|
504
|
+
: null;
|
|
505
|
+
if (legacyMessage) {
|
|
506
|
+
messages.push({ key: legacyKey, message: legacyMessage });
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
return messages.sort((a, b) => {
|
|
510
|
+
const byTimestamp = a.message.timestamp - b.message.timestamp;
|
|
511
|
+
return byTimestamp || a.message.id.localeCompare(b.message.id);
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
async function drainQueuedTaskMessages(
|
|
516
|
+
taskId: string,
|
|
517
|
+
): Promise<QueuedTaskMessage[]> {
|
|
518
|
+
return withTaskMessageDrainLock(taskId, async () => {
|
|
519
|
+
const entries = await listQueuedTaskMessages(taskId);
|
|
520
|
+
if (entries.length === 0) return [];
|
|
521
|
+
for (const entry of entries) {
|
|
522
|
+
await deleteAppState(entry.key);
|
|
523
|
+
}
|
|
524
|
+
return entries.map((entry) => entry.message);
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
async function appendQueuedTaskMessage(
|
|
529
|
+
taskId: string,
|
|
530
|
+
message: string,
|
|
531
|
+
): Promise<{ messageId: string; queuedCount: number }> {
|
|
532
|
+
const messageId = generateTaskMessageId();
|
|
533
|
+
await writeAppState(`${taskMessageQueuePrefix(taskId)}${messageId}`, {
|
|
534
|
+
id: messageId,
|
|
535
|
+
from: "orchestrator",
|
|
536
|
+
message,
|
|
537
|
+
timestamp: Date.now(),
|
|
538
|
+
});
|
|
539
|
+
const queuedCount = (await listQueuedTaskMessages(taskId)).length;
|
|
540
|
+
return { messageId, queuedCount };
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
function createMessageAwareActions(
|
|
544
|
+
taskId: string,
|
|
545
|
+
actions: Record<string, ActionEntry>,
|
|
546
|
+
): Record<string, ActionEntry> {
|
|
547
|
+
return Object.fromEntries(
|
|
548
|
+
Object.entries(actions).map(([name, entry]) => [
|
|
549
|
+
name,
|
|
550
|
+
{
|
|
551
|
+
...entry,
|
|
552
|
+
run: async (args, context) => {
|
|
553
|
+
// Sub-agents / agent-teams run through the production-agent loop, so
|
|
554
|
+
// the loop already passes a full ctx with caller "tool". Forward it,
|
|
555
|
+
// defaulting caller to "tool" if a caller invokes this wrapper without
|
|
556
|
+
// a context object.
|
|
557
|
+
const result = await entry.run(args, {
|
|
558
|
+
...context,
|
|
559
|
+
caller: context?.caller ?? "tool",
|
|
560
|
+
});
|
|
561
|
+
const queuedMessages = await drainQueuedTaskMessages(taskId);
|
|
562
|
+
if (queuedMessages.length === 0) return result;
|
|
563
|
+
|
|
564
|
+
// Tool results are already the next safe model-visible boundary:
|
|
565
|
+
// the loop records all tool output, then asks the model to continue.
|
|
566
|
+
// Attaching queued updates here avoids mutating message history while
|
|
567
|
+
// an assistant tool-call turn is still being resolved.
|
|
568
|
+
const formatted = formatQueuedTaskMessages(queuedMessages);
|
|
569
|
+
const resultText =
|
|
570
|
+
typeof result === "string"
|
|
571
|
+
? result
|
|
572
|
+
: JSON.stringify(result, null, 2);
|
|
573
|
+
return `${resultText}\n\n${formatted}`;
|
|
574
|
+
},
|
|
575
|
+
},
|
|
576
|
+
]),
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
function createTaskMessageFinalGuard(
|
|
581
|
+
taskId: string,
|
|
582
|
+
): AgentLoopFinalResponseGuard {
|
|
583
|
+
return async () => {
|
|
584
|
+
const queuedMessages = await drainQueuedTaskMessages(taskId);
|
|
585
|
+
if (queuedMessages.length === 0) return null;
|
|
586
|
+
|
|
587
|
+
// This is queued delivery, not a live interrupt: if the sub-agent is
|
|
588
|
+
// already producing a final answer, the guard asks the loop for one more
|
|
589
|
+
// continuation that includes the orchestrator update as a fresh user turn.
|
|
590
|
+
return {
|
|
591
|
+
retryMessage: formatQueuedTaskMessages(queuedMessages),
|
|
592
|
+
fallbackMessage:
|
|
593
|
+
"I received an orchestrator update while finishing, but could not continue from it. Please check the task status and send the update again if needed.",
|
|
594
|
+
// A queued update can introduce a request for an action that was
|
|
595
|
+
// deferred behind tool-search. The retry is already a corrective turn,
|
|
596
|
+
// so expose the full authorized registry rather than making the
|
|
597
|
+
// sub-agent spend that turn rediscovering the same tool.
|
|
598
|
+
expandToolSurface: true,
|
|
599
|
+
};
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
async function saveTask(task: AgentTask): Promise<void> {
|
|
604
|
+
task.updatedAt = Date.now();
|
|
605
|
+
await writeAppState(`${TASK_PREFIX}${task.taskId}`, task as any);
|
|
606
|
+
await writeAppState(`${THREAD_PREFIX}${task.threadId}`, {
|
|
607
|
+
taskId: task.taskId,
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
async function loadTask(taskId: string): Promise<AgentTask | null> {
|
|
612
|
+
const data = await readAppState(`${TASK_PREFIX}${taskId}`);
|
|
613
|
+
return data ? (data as unknown as AgentTask) : null;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
async function loadTaskByThread(threadId: string): Promise<AgentTask | null> {
|
|
617
|
+
const ref = await readAppState(`${THREAD_PREFIX}${threadId}`);
|
|
618
|
+
if (!ref || !ref.taskId) return null;
|
|
619
|
+
return loadTask(ref.taskId as string);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
function applyDispatchMetadataToTask(
|
|
623
|
+
task: AgentTask,
|
|
624
|
+
dispatch: Awaited<ReturnType<typeof getAgentTeamRunDispatchState>> | null,
|
|
625
|
+
): AgentTask {
|
|
626
|
+
if (!dispatch) return task;
|
|
627
|
+
const parentThreadId = dispatch.payload.parentThreadId?.trim();
|
|
628
|
+
const name = dispatch.payload.name?.trim();
|
|
629
|
+
if (parentThreadId && !task.parentThreadId) {
|
|
630
|
+
task.parentThreadId = parentThreadId;
|
|
631
|
+
}
|
|
632
|
+
if (name && !task.name) {
|
|
633
|
+
task.name = name;
|
|
634
|
+
}
|
|
635
|
+
return task;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
async function completeReconciledTask(
|
|
639
|
+
task: AgentTask,
|
|
640
|
+
ownerEmail: string | null,
|
|
641
|
+
): Promise<AgentTask> {
|
|
642
|
+
task.status = "completed";
|
|
643
|
+
task.summary = task.summary || task.preview || "Task completed.";
|
|
644
|
+
task.currentStep = "";
|
|
645
|
+
task.completedAt = Date.now();
|
|
646
|
+
await saveTask(task);
|
|
647
|
+
if (ownerEmail) {
|
|
648
|
+
await completeTaskProgressRun(
|
|
649
|
+
task,
|
|
650
|
+
ownerEmail,
|
|
651
|
+
"succeeded",
|
|
652
|
+
"Task completed.",
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
return task;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
async function failReconciledTask(
|
|
659
|
+
task: AgentTask,
|
|
660
|
+
ownerEmail: string | null,
|
|
661
|
+
message: string,
|
|
662
|
+
progressStatus: TerminalProgressStatus = "failed",
|
|
663
|
+
): Promise<AgentTask> {
|
|
664
|
+
task.status = "errored";
|
|
665
|
+
task.summary = task.summary || task.preview || message;
|
|
666
|
+
task.error = task.error || message;
|
|
667
|
+
task.currentStep = "";
|
|
668
|
+
task.completedAt = Date.now();
|
|
669
|
+
await saveTask(task);
|
|
670
|
+
if (ownerEmail) {
|
|
671
|
+
await completeTaskProgressRun(task, ownerEmail, progressStatus, message);
|
|
672
|
+
}
|
|
673
|
+
// Make the dispatch row terminal too so it isn't re-fired.
|
|
674
|
+
await completeAgentTeamRun(task.taskId, "failed").catch(() => {});
|
|
675
|
+
return task;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
function subAgentDispatchFailureMessage(err: unknown): string {
|
|
679
|
+
return err instanceof Error
|
|
680
|
+
? `Failed to start sub-agent: ${err.message}`
|
|
681
|
+
: "Failed to start sub-agent.";
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Re-fire a dropped self-dispatch. When the queue row is still queued/running
|
|
686
|
+
* but its heartbeat has gone stale (the self-fire never landed, or the
|
|
687
|
+
* processing invocation died), kick the processor again before the hard
|
|
688
|
+
* stuck-cutoff fail path gives up. Best-effort — the fail path is the backstop.
|
|
689
|
+
*/
|
|
690
|
+
async function refireStuckAgentTeamRunIfNeeded(
|
|
691
|
+
task: AgentTask,
|
|
692
|
+
dispatch: NonNullable<
|
|
693
|
+
Awaited<ReturnType<typeof getAgentTeamRunDispatchState>>
|
|
694
|
+
>,
|
|
695
|
+
event?: any,
|
|
696
|
+
): Promise<void> {
|
|
697
|
+
if (dispatch.status !== "queued" && dispatch.status !== "running") return;
|
|
698
|
+
const idleFor = Date.now() - dispatch.updatedAt;
|
|
699
|
+
if (idleFor < RUN_DISPATCH_STUCK_AFTER_MS) return; // still fresh — leave it
|
|
700
|
+
if (idleFor >= RUN_PROCESSING_STUCK_AFTER_MS) return; // fail path owns this
|
|
701
|
+
try {
|
|
702
|
+
await fireInternalDispatch({
|
|
703
|
+
event,
|
|
704
|
+
path: AGENT_TEAM_PROCESS_RUN_PATH,
|
|
705
|
+
taskId: task.taskId,
|
|
706
|
+
body: { mode: dispatch.continuationCount > 0 ? "continue" : "start" },
|
|
707
|
+
});
|
|
708
|
+
} catch (err) {
|
|
709
|
+
await failReconciledTask(
|
|
710
|
+
task,
|
|
711
|
+
dispatch.ownerEmail,
|
|
712
|
+
subAgentDispatchFailureMessage(err),
|
|
713
|
+
);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Reconcile a task that still reads "running" against the actual run state.
|
|
719
|
+
*
|
|
720
|
+
* Durable-dispatch path (the normal case): the `agent_team_run_queue` row is
|
|
721
|
+
* the authority. While it's queued/running the task stays running (a single
|
|
722
|
+
* completed agent_runs chunk at a soft-timeout boundary does NOT mean the task
|
|
723
|
+
* finished — a continuation may be queued/in-flight). A dropped dispatch is
|
|
724
|
+
* re-fired; a genuinely stalled one (past the hard cutoff) is failed.
|
|
725
|
+
*
|
|
726
|
+
* Legacy fallback (no queue row — pre-upgrade tasks, or the in-process
|
|
727
|
+
* Cloudflare path): fall back to the in-memory/SQL run state via
|
|
728
|
+
* `getActiveRunForThreadAsync`, with the original missing-run grace.
|
|
729
|
+
*/
|
|
730
|
+
async function reconcileTaskWithRun(
|
|
731
|
+
task: AgentTask,
|
|
732
|
+
event?: any,
|
|
733
|
+
): Promise<AgentTask> {
|
|
734
|
+
let dispatch: Awaited<ReturnType<typeof getAgentTeamRunDispatchState>> = null;
|
|
735
|
+
try {
|
|
736
|
+
dispatch = await getAgentTeamRunDispatchState(task.taskId);
|
|
737
|
+
} catch {
|
|
738
|
+
dispatch = null;
|
|
739
|
+
}
|
|
740
|
+
applyDispatchMetadataToTask(task, dispatch);
|
|
741
|
+
|
|
742
|
+
if (task.status !== "running") return task;
|
|
743
|
+
|
|
744
|
+
if (dispatch) {
|
|
745
|
+
const ownerEmail = dispatch.ownerEmail ?? getRequestUserEmail() ?? null;
|
|
746
|
+
if (dispatch.status === "queued" || dispatch.status === "running") {
|
|
747
|
+
const stuckFor = Date.now() - dispatch.updatedAt;
|
|
748
|
+
if (stuckFor < RUN_PROCESSING_STUCK_AFTER_MS) {
|
|
749
|
+
await refireStuckAgentTeamRunIfNeeded(task, dispatch, event);
|
|
750
|
+
return task;
|
|
751
|
+
}
|
|
752
|
+
return await failReconciledTask(
|
|
753
|
+
task,
|
|
754
|
+
ownerEmail,
|
|
755
|
+
"Sub-agent run stalled and did not produce a result.",
|
|
756
|
+
);
|
|
757
|
+
}
|
|
758
|
+
if (dispatch.status === "failed") {
|
|
759
|
+
return await failReconciledTask(
|
|
760
|
+
task,
|
|
761
|
+
ownerEmail,
|
|
762
|
+
task.error || task.summary || "Sub-agent run failed.",
|
|
763
|
+
);
|
|
764
|
+
}
|
|
765
|
+
// status === "done" but task still running — safety net (the processor
|
|
766
|
+
// normally sets the task terminal before completing the queue row).
|
|
767
|
+
return await completeReconciledTask(task, ownerEmail);
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
// ── Legacy fallback: no durable queue row ────────────────────────────────
|
|
771
|
+
if (!task.runId) return task;
|
|
772
|
+
let runState:
|
|
773
|
+
| Awaited<ReturnType<typeof getActiveRunForThreadAsync>>
|
|
774
|
+
| undefined;
|
|
775
|
+
try {
|
|
776
|
+
runState = await getActiveRunForThreadAsync(task.threadId);
|
|
777
|
+
} catch {
|
|
778
|
+
return task;
|
|
779
|
+
}
|
|
780
|
+
if (runState?.status === "running") return task;
|
|
781
|
+
|
|
782
|
+
const ownerEmail = getRequestUserEmail() ?? null;
|
|
783
|
+
if (runState?.status === "completed") {
|
|
784
|
+
return await completeReconciledTask(task, ownerEmail);
|
|
785
|
+
}
|
|
786
|
+
if (runState?.status === "errored" || runState?.status === "aborted") {
|
|
787
|
+
return await failReconciledTask(
|
|
788
|
+
task,
|
|
789
|
+
ownerEmail,
|
|
790
|
+
runState.status === "aborted" ? "Task stopped." : "Task failed.",
|
|
791
|
+
runState.status === "aborted" ? "cancelled" : "failed",
|
|
792
|
+
);
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
const referenceAt = task.startedAt ?? task.createdAt;
|
|
796
|
+
if (Date.now() - referenceAt < TASK_RUN_MISSING_GRACE_MS) return task;
|
|
797
|
+
return await failReconciledTask(
|
|
798
|
+
task,
|
|
799
|
+
ownerEmail,
|
|
800
|
+
"Sub-agent run is no longer active and did not produce a result.",
|
|
801
|
+
);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/**
|
|
805
|
+
* Reconcile all of an owner's in-flight sub-agent runs. Wired into the RunsTray
|
|
806
|
+
* data path (`/_agent-native/runs`) so the tray self-heals: dropped dispatches
|
|
807
|
+
* are re-fired and dead runs are marked failed promptly, even when the
|
|
808
|
+
* orchestrator chat never polls `status`/`read-result`.
|
|
809
|
+
*/
|
|
810
|
+
export async function reconcileAgentTeamRunsForOwner(
|
|
811
|
+
owner: string,
|
|
812
|
+
event?: any,
|
|
813
|
+
): Promise<void> {
|
|
814
|
+
let taskIds: string[];
|
|
815
|
+
try {
|
|
816
|
+
taskIds = await listActiveAgentTeamTaskIdsForOwner(owner);
|
|
817
|
+
} catch {
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
for (const taskId of taskIds) {
|
|
821
|
+
try {
|
|
822
|
+
const task = await loadTask(taskId);
|
|
823
|
+
if (task) await reconcileTaskWithRun(task, event);
|
|
824
|
+
} catch {
|
|
825
|
+
// best-effort per task — one bad row shouldn't block the rest
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
function generateTaskId(): string {
|
|
831
|
+
return `task-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
function taskRunId(taskId: string): string {
|
|
835
|
+
return `run-task-${taskId}`;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
function taskRunChunkId(taskId: string, chunk: number): string {
|
|
839
|
+
return `${taskRunId(taskId)}-c${chunk}`;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
function taskIdFromBackgroundRunId(runId: string): string {
|
|
843
|
+
const taskId = runId.startsWith("run-task-")
|
|
844
|
+
? runId.slice("run-task-".length)
|
|
845
|
+
: runId;
|
|
846
|
+
const chunkTaskId = taskId.match(/^(.*)-c\d+$/)?.[1];
|
|
847
|
+
// Public background run ids are stable base ids. Only strip a chunk suffix
|
|
848
|
+
// when the caller passed a live run-manager chunk id.
|
|
849
|
+
return chunkTaskId && getRun(runId)?.status === "running"
|
|
850
|
+
? chunkTaskId
|
|
851
|
+
: taskId;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
function runningInMemoryTaskRunId(taskId: string): string {
|
|
855
|
+
const baseRunId = taskRunId(taskId);
|
|
856
|
+
for (let i = MAX_AGENT_TEAM_CONTINUATIONS; i >= 0; i -= 1) {
|
|
857
|
+
const chunkRunId = taskRunChunkId(taskId, i);
|
|
858
|
+
if (getRun(chunkRunId)?.status === "running") return chunkRunId;
|
|
859
|
+
}
|
|
860
|
+
if (getRun(baseRunId)?.status === "running") return baseRunId;
|
|
861
|
+
return baseRunId;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
async function durableActiveTaskRunId(taskId: string): Promise<string> {
|
|
865
|
+
try {
|
|
866
|
+
const dispatch = await getAgentTeamRunDispatchState(taskId);
|
|
867
|
+
if (dispatch?.status === "queued" || dispatch?.status === "running") {
|
|
868
|
+
return taskRunChunkId(taskId, dispatch.continuationCount);
|
|
869
|
+
}
|
|
870
|
+
} catch {
|
|
871
|
+
// Fall back to in-memory state if queue state is temporarily unavailable.
|
|
872
|
+
}
|
|
873
|
+
return runningInMemoryTaskRunId(taskId);
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
function mapTaskStatusToBackgroundStatus(
|
|
877
|
+
status: AgentTask["status"],
|
|
878
|
+
): BackgroundAgentRunStatus {
|
|
879
|
+
return status;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
function taskTimestampToIso(timestamp: number): string {
|
|
883
|
+
const date = new Date(timestamp);
|
|
884
|
+
return Number.isFinite(date.getTime())
|
|
885
|
+
? date.toISOString()
|
|
886
|
+
: new Date(0).toISOString();
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
function latestTaskText(task: AgentTask): string | undefined {
|
|
890
|
+
return task.summary || task.preview || task.currentStep || undefined;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
function formatTaskPhase(task: AgentTask): string {
|
|
894
|
+
if (task.status === "running") return task.currentStep || "Running";
|
|
895
|
+
if (task.status === "completed") return "Completed";
|
|
896
|
+
const phase = task.error || task.summary || "Task failed.";
|
|
897
|
+
return phase.length > 120 ? `${phase.slice(0, 117)}...` : phase;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
type TerminalProgressStatus = "succeeded" | "failed" | "cancelled";
|
|
901
|
+
|
|
902
|
+
function taskProgressMetadata(task: AgentTask): Record<string, unknown> {
|
|
903
|
+
return {
|
|
904
|
+
kind: "agent-team",
|
|
905
|
+
source: "agent-teams",
|
|
906
|
+
taskId: task.taskId,
|
|
907
|
+
threadId: task.threadId,
|
|
908
|
+
description: task.description,
|
|
909
|
+
preview: task.preview,
|
|
910
|
+
summary: task.summary,
|
|
911
|
+
currentStep: task.currentStep,
|
|
912
|
+
surfaceUrl: `agent-native://threads/${encodeURIComponent(task.threadId)}`,
|
|
913
|
+
...(task.parentThreadId ? { parentThreadId: task.parentThreadId } : {}),
|
|
914
|
+
...(task.name ? { name: task.name } : {}),
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
function currentTaskProgressStep(task: AgentTask): string {
|
|
919
|
+
return (
|
|
920
|
+
task.currentStep ||
|
|
921
|
+
(task.preview ? "Working on response" : "Starting sub-agent")
|
|
922
|
+
);
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
async function startTaskProgressRun(
|
|
926
|
+
task: AgentTask,
|
|
927
|
+
ownerEmail: string,
|
|
928
|
+
): Promise<void> {
|
|
929
|
+
const runId = task.runId ?? taskRunId(task.taskId);
|
|
930
|
+
task.runId = runId;
|
|
931
|
+
try {
|
|
932
|
+
await startProgressRun({
|
|
933
|
+
id: runId,
|
|
934
|
+
owner: ownerEmail,
|
|
935
|
+
title: task.description,
|
|
936
|
+
step: currentTaskProgressStep(task),
|
|
937
|
+
metadata: taskProgressMetadata(task),
|
|
938
|
+
});
|
|
939
|
+
} catch {
|
|
940
|
+
// Progress rows are user-facing visibility. A write failure should not
|
|
941
|
+
// prevent the sub-agent from running or the task card from updating.
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
async function updateTaskProgressRun(
|
|
946
|
+
task: AgentTask,
|
|
947
|
+
ownerEmail: string,
|
|
948
|
+
): Promise<void> {
|
|
949
|
+
const runId = task.runId ?? taskRunId(task.taskId);
|
|
950
|
+
task.runId = runId;
|
|
951
|
+
try {
|
|
952
|
+
await updateRunProgress(runId, ownerEmail, {
|
|
953
|
+
step: currentTaskProgressStep(task),
|
|
954
|
+
metadata: taskProgressMetadata(task),
|
|
955
|
+
});
|
|
956
|
+
} catch {
|
|
957
|
+
// best-effort
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
async function completeTaskProgressRun(
|
|
962
|
+
task: AgentTask,
|
|
963
|
+
ownerEmail: string,
|
|
964
|
+
status: TerminalProgressStatus,
|
|
965
|
+
step: string,
|
|
966
|
+
): Promise<void> {
|
|
967
|
+
const runId = task.runId ?? taskRunId(task.taskId);
|
|
968
|
+
task.runId = runId;
|
|
969
|
+
try {
|
|
970
|
+
await completeProgressRun(runId, ownerEmail, status, {
|
|
971
|
+
step,
|
|
972
|
+
metadata: taskProgressMetadata(task),
|
|
973
|
+
});
|
|
974
|
+
} catch {
|
|
975
|
+
// best-effort
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
/**
|
|
980
|
+
* Maximum characters stored in `task.summary` (the full result surfaced to the
|
|
981
|
+
* orchestrator via `read-result`). Generous enough to avoid destroying long
|
|
982
|
+
* sub-agent output; matches the tool-result truncation cap used in the main
|
|
983
|
+
* production-agent loop.
|
|
984
|
+
*/
|
|
985
|
+
const TASK_SUMMARY_MAX_CHARS = 50_000;
|
|
986
|
+
|
|
987
|
+
function resolveTaskCompletion(
|
|
988
|
+
run: Pick<ActiveRun, "status" | "abortReason">,
|
|
989
|
+
accumulatedText: string,
|
|
990
|
+
options?: { hitContinuationLimit?: boolean },
|
|
991
|
+
): {
|
|
992
|
+
taskStatus: "completed" | "errored";
|
|
993
|
+
summary: string;
|
|
994
|
+
progressStatus: TerminalProgressStatus;
|
|
995
|
+
progressStep: string;
|
|
996
|
+
error?: string;
|
|
997
|
+
} {
|
|
998
|
+
const text = accumulatedText.trim();
|
|
999
|
+
if (run.status === "aborted") {
|
|
1000
|
+
const stopped =
|
|
1001
|
+
run.abortReason && run.abortReason !== "user"
|
|
1002
|
+
? `Task stopped: ${run.abortReason}`
|
|
1003
|
+
: "Task stopped.";
|
|
1004
|
+
return {
|
|
1005
|
+
taskStatus: "errored",
|
|
1006
|
+
summary: stopped,
|
|
1007
|
+
progressStatus: "cancelled",
|
|
1008
|
+
progressStep: stopped,
|
|
1009
|
+
error: stopped,
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
if (run.status === "errored") {
|
|
1013
|
+
// Keep a reasonable tail for error context; errors are rarely huge.
|
|
1014
|
+
const failed = text.slice(-500) || "Task failed.";
|
|
1015
|
+
return {
|
|
1016
|
+
taskStatus: "errored",
|
|
1017
|
+
summary: failed,
|
|
1018
|
+
progressStatus: "failed",
|
|
1019
|
+
progressStep: "Task failed.",
|
|
1020
|
+
error: failed,
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
// Store up to TASK_SUMMARY_MAX_CHARS so the orchestrator's read-result tool
|
|
1024
|
+
// can access the full output without truncation. If the absolute continuation
|
|
1025
|
+
// cap was hit, mark the result so the orchestrator can distinguish it.
|
|
1026
|
+
let summary =
|
|
1027
|
+
text.length > TASK_SUMMARY_MAX_CHARS
|
|
1028
|
+
? text.slice(-TASK_SUMMARY_MAX_CHARS)
|
|
1029
|
+
: text || "Task completed successfully.";
|
|
1030
|
+
if (options?.hitContinuationLimit) {
|
|
1031
|
+
summary = `[hit-continuation-limit]\n\n${summary}`;
|
|
1032
|
+
}
|
|
1033
|
+
return {
|
|
1034
|
+
taskStatus: "completed",
|
|
1035
|
+
summary,
|
|
1036
|
+
progressStatus: "succeeded",
|
|
1037
|
+
progressStep: "Task completed.",
|
|
1038
|
+
};
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
export function toAgentTaskBackgroundRun(
|
|
1042
|
+
task: AgentTask,
|
|
1043
|
+
): AgentTeamBackgroundRun {
|
|
1044
|
+
const createdAt = taskTimestampToIso(task.createdAt);
|
|
1045
|
+
const updatedAt = taskTimestampToIso(
|
|
1046
|
+
task.completedAt ?? task.updatedAt ?? task.createdAt,
|
|
1047
|
+
);
|
|
1048
|
+
const phase = formatTaskPhase(task);
|
|
1049
|
+
return {
|
|
1050
|
+
schemaVersion: 1,
|
|
1051
|
+
id: taskRunId(task.taskId),
|
|
1052
|
+
kind: "agent-team",
|
|
1053
|
+
source: "hosted-agent-team",
|
|
1054
|
+
sourceLabel: "Agent Teams",
|
|
1055
|
+
sourceRecord: {
|
|
1056
|
+
type: "agent-team-task",
|
|
1057
|
+
id: task.taskId,
|
|
1058
|
+
threadId: task.threadId,
|
|
1059
|
+
...(task.parentThreadId ? { parentThreadId: task.parentThreadId } : {}),
|
|
1060
|
+
...(task.name ? { name: task.name } : {}),
|
|
1061
|
+
},
|
|
1062
|
+
title: task.description,
|
|
1063
|
+
subtitle:
|
|
1064
|
+
task.currentStep || (task.status === "errored" ? phase : undefined),
|
|
1065
|
+
status: mapTaskStatusToBackgroundStatus(task.status),
|
|
1066
|
+
phase,
|
|
1067
|
+
createdAt,
|
|
1068
|
+
updatedAt,
|
|
1069
|
+
goalId: "agent-team",
|
|
1070
|
+
needsInput: false,
|
|
1071
|
+
needsApproval: false,
|
|
1072
|
+
details: [
|
|
1073
|
+
{ label: "Task", value: task.taskId },
|
|
1074
|
+
{ label: "Thread", value: task.threadId },
|
|
1075
|
+
...(task.parentThreadId
|
|
1076
|
+
? [{ label: "Parent", value: task.parentThreadId }]
|
|
1077
|
+
: []),
|
|
1078
|
+
],
|
|
1079
|
+
surfaceUrl: `agent-native://threads/${task.threadId}`,
|
|
1080
|
+
metadata: {
|
|
1081
|
+
taskId: task.taskId,
|
|
1082
|
+
threadId: task.threadId,
|
|
1083
|
+
description: task.description,
|
|
1084
|
+
preview: task.preview,
|
|
1085
|
+
summary: task.summary,
|
|
1086
|
+
currentStep: task.currentStep,
|
|
1087
|
+
latestText: latestTaskText(task),
|
|
1088
|
+
completedAt: task.completedAt,
|
|
1089
|
+
error: task.error,
|
|
1090
|
+
...(task.parentThreadId ? { parentThreadId: task.parentThreadId } : {}),
|
|
1091
|
+
...(task.name ? { name: task.name } : {}),
|
|
1092
|
+
},
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
function summarizeAgentChatEvent(event: RunEvent): {
|
|
1097
|
+
kind: AgentTeamBackgroundTranscriptEvent["kind"];
|
|
1098
|
+
message: string;
|
|
1099
|
+
metadata?: Record<string, unknown>;
|
|
1100
|
+
} | null {
|
|
1101
|
+
const payload = event.event;
|
|
1102
|
+
switch (payload.type) {
|
|
1103
|
+
case "text":
|
|
1104
|
+
return { kind: "note", message: payload.text };
|
|
1105
|
+
case "activity":
|
|
1106
|
+
return {
|
|
1107
|
+
kind: "status",
|
|
1108
|
+
message: payload.label,
|
|
1109
|
+
metadata: payload.tool ? { tool: payload.tool } : undefined,
|
|
1110
|
+
};
|
|
1111
|
+
case "tool_start":
|
|
1112
|
+
return {
|
|
1113
|
+
kind: "status",
|
|
1114
|
+
message: `Running ${payload.tool}`,
|
|
1115
|
+
metadata: { tool: payload.tool, input: payload.input },
|
|
1116
|
+
};
|
|
1117
|
+
case "tool_done":
|
|
1118
|
+
return {
|
|
1119
|
+
kind: "artifact",
|
|
1120
|
+
message: payload.result,
|
|
1121
|
+
metadata: { tool: payload.tool },
|
|
1122
|
+
};
|
|
1123
|
+
case "agent_task":
|
|
1124
|
+
return {
|
|
1125
|
+
kind: "status",
|
|
1126
|
+
message: `${payload.description} (${payload.status})`,
|
|
1127
|
+
metadata: {
|
|
1128
|
+
taskId: payload.taskId,
|
|
1129
|
+
threadId: payload.threadId,
|
|
1130
|
+
status: payload.status,
|
|
1131
|
+
},
|
|
1132
|
+
};
|
|
1133
|
+
case "agent_task_update":
|
|
1134
|
+
return {
|
|
1135
|
+
kind: "status",
|
|
1136
|
+
message: payload.preview || payload.currentStep || "Task updated",
|
|
1137
|
+
metadata: {
|
|
1138
|
+
taskId: payload.taskId,
|
|
1139
|
+
currentStep: payload.currentStep,
|
|
1140
|
+
},
|
|
1141
|
+
};
|
|
1142
|
+
case "agent_task_complete":
|
|
1143
|
+
return {
|
|
1144
|
+
kind: "status",
|
|
1145
|
+
message: payload.summary,
|
|
1146
|
+
metadata: { taskId: payload.taskId },
|
|
1147
|
+
};
|
|
1148
|
+
case "error":
|
|
1149
|
+
return {
|
|
1150
|
+
kind: "status",
|
|
1151
|
+
message: payload.error,
|
|
1152
|
+
metadata: {
|
|
1153
|
+
errorCode: payload.errorCode,
|
|
1154
|
+
upgradeUrl: payload.upgradeUrl,
|
|
1155
|
+
},
|
|
1156
|
+
};
|
|
1157
|
+
case "missing_api_key":
|
|
1158
|
+
return {
|
|
1159
|
+
kind: "status",
|
|
1160
|
+
message: "Missing API key",
|
|
1161
|
+
};
|
|
1162
|
+
case "done":
|
|
1163
|
+
return { kind: "status", message: "Run completed" };
|
|
1164
|
+
case "loop_limit":
|
|
1165
|
+
return { kind: "status", message: "Run stopped at the loop limit" };
|
|
1166
|
+
case "auto_continue":
|
|
1167
|
+
return {
|
|
1168
|
+
kind: "status",
|
|
1169
|
+
message: "Run reached its continuation boundary",
|
|
1170
|
+
metadata: { reason: payload.reason },
|
|
1171
|
+
};
|
|
1172
|
+
case "clear":
|
|
1173
|
+
return {
|
|
1174
|
+
kind: "status",
|
|
1175
|
+
message: "",
|
|
1176
|
+
metadata: { agentChatEventType: "clear" },
|
|
1177
|
+
};
|
|
1178
|
+
case "agent_call":
|
|
1179
|
+
return {
|
|
1180
|
+
kind: "status",
|
|
1181
|
+
message: `${payload.agent} ${payload.status}`,
|
|
1182
|
+
metadata: { agent: payload.agent, status: payload.status },
|
|
1183
|
+
};
|
|
1184
|
+
case "agent_call_text":
|
|
1185
|
+
return {
|
|
1186
|
+
kind: "note",
|
|
1187
|
+
message: payload.text,
|
|
1188
|
+
metadata: { agent: payload.agent },
|
|
1189
|
+
};
|
|
1190
|
+
default:
|
|
1191
|
+
return null;
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
export function toAgentTaskBackgroundTranscriptEvent(
|
|
1196
|
+
runId: string,
|
|
1197
|
+
event: RunEvent,
|
|
1198
|
+
options: { seq?: number; sourceRunId?: string } = {},
|
|
1199
|
+
): AgentTeamBackgroundTranscriptEvent | null {
|
|
1200
|
+
const summary = summarizeAgentChatEvent(event);
|
|
1201
|
+
if (!summary) return null;
|
|
1202
|
+
const sourceRunId = options.sourceRunId ?? runId;
|
|
1203
|
+
const eventId = `${sourceRunId}:${event.seq}`;
|
|
1204
|
+
const seq = options.seq ?? event.seq;
|
|
1205
|
+
const metadata = {
|
|
1206
|
+
...(summary.metadata ?? {}),
|
|
1207
|
+
seq,
|
|
1208
|
+
sourceSeq: event.seq,
|
|
1209
|
+
...(sourceRunId === runId ? {} : { sourceRunId }),
|
|
1210
|
+
};
|
|
1211
|
+
return {
|
|
1212
|
+
schemaVersion: 1,
|
|
1213
|
+
id: eventId,
|
|
1214
|
+
runId,
|
|
1215
|
+
kind: summary.kind,
|
|
1216
|
+
source: "hosted-agent-team",
|
|
1217
|
+
sourceRecord: {
|
|
1218
|
+
type: "agent-team-run-event",
|
|
1219
|
+
id: eventId,
|
|
1220
|
+
seq,
|
|
1221
|
+
},
|
|
1222
|
+
message: summary.message,
|
|
1223
|
+
createdAt: new Date().toISOString(),
|
|
1224
|
+
metadata,
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
export interface SpawnTaskOptions {
|
|
1229
|
+
/** Description of what the sub-agent should do */
|
|
1230
|
+
description: string;
|
|
1231
|
+
/** Additional instructions scoped to this sub-agent */
|
|
1232
|
+
instructions?: string;
|
|
1233
|
+
/** Model to use (e.g. "claude-haiku-4-5"). Uses default if omitted */
|
|
1234
|
+
model?: string;
|
|
1235
|
+
/** The owner email for thread creation */
|
|
1236
|
+
ownerEmail: string;
|
|
1237
|
+
/** The system prompt base for the sub-agent */
|
|
1238
|
+
systemPrompt: string;
|
|
1239
|
+
/** Available actions for the sub-agent */
|
|
1240
|
+
actions: Record<string, ActionEntry>;
|
|
1241
|
+
/** Agent engine to use. Falls back to creating an Anthropic engine with apiKey. */
|
|
1242
|
+
engine?: AgentEngine;
|
|
1243
|
+
/** API key for Anthropic (used only if engine is not provided) */
|
|
1244
|
+
apiKey?: string;
|
|
1245
|
+
/** Callback to emit events to the parent chat stream */
|
|
1246
|
+
parentSend: (event: AgentChatEvent) => void;
|
|
1247
|
+
/** Parent thread ID — used to auto-respond when the sub-agent finishes */
|
|
1248
|
+
parentThreadId?: string;
|
|
1249
|
+
/** Display name for the sub-agent tab (carried into the dispatch payload). */
|
|
1250
|
+
name?: string;
|
|
1251
|
+
/**
|
|
1252
|
+
* Delegation depth of the agent doing the spawning (the parent). Top-level
|
|
1253
|
+
* chat is 0. When omitted, the depth is read from the ambient run context
|
|
1254
|
+
* (set by `processAgentTeamRun` when a sub-agent is itself running), so a
|
|
1255
|
+
* sub-agent that reaches `spawnTask` inherits its own depth automatically.
|
|
1256
|
+
* The spawned sub-agent's depth is `parentDelegationDepth + 1`.
|
|
1257
|
+
*/
|
|
1258
|
+
parentDelegationDepth?: number;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
/**
|
|
1262
|
+
* Error thrown when a spawn is refused because it would exceed the delegation
|
|
1263
|
+
* depth cap. Carries the structured decision so callers (and the tool layer)
|
|
1264
|
+
* can surface a precise message to the parent agent.
|
|
1265
|
+
*/
|
|
1266
|
+
export class SubagentDelegationDepthError extends Error {
|
|
1267
|
+
readonly decision: SubagentDepthDecision;
|
|
1268
|
+
constructor(decision: SubagentDepthDecision) {
|
|
1269
|
+
super(
|
|
1270
|
+
decision.error ??
|
|
1271
|
+
`Delegation depth limit reached (max ${decision.maxDepth}); cannot spawn another sub-agent.`,
|
|
1272
|
+
);
|
|
1273
|
+
this.name = "SubagentDelegationDepthError";
|
|
1274
|
+
this.decision = decision;
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
/**
|
|
1279
|
+
* Spawn a sub-agent task. Creates a thread, starts a background agent run,
|
|
1280
|
+
* and emits agent_task events to the parent chat stream.
|
|
1281
|
+
*/
|
|
1282
|
+
export async function spawnTask(opts: SpawnTaskOptions): Promise<AgentTask> {
|
|
1283
|
+
// ── Delegation-depth guardrail ────────────────────────────────────────────
|
|
1284
|
+
// Defensive, server-side enforcement that holds regardless of any tool-level
|
|
1285
|
+
// stripping in the agent-chat plugin: a sub-agent cannot infinitely spawn
|
|
1286
|
+
// sub-agents. The spawning agent's depth comes from the explicit option or,
|
|
1287
|
+
// failing that, the ambient depth recorded while a sub-agent run executes.
|
|
1288
|
+
const parentDepth =
|
|
1289
|
+
typeof opts.parentDelegationDepth === "number"
|
|
1290
|
+
? opts.parentDelegationDepth
|
|
1291
|
+
: currentAmbientDelegationDepth();
|
|
1292
|
+
const decision = evaluateSubagentDepth(parentDepth);
|
|
1293
|
+
if (!decision.allowed) {
|
|
1294
|
+
throw new SubagentDelegationDepthError(decision);
|
|
1295
|
+
}
|
|
1296
|
+
const childDepth = decision.childDepth;
|
|
1297
|
+
|
|
1298
|
+
const taskId = generateTaskId();
|
|
1299
|
+
|
|
1300
|
+
// Create a dedicated thread for the sub-agent with the task as the first message
|
|
1301
|
+
const thread = await createThread(opts.ownerEmail, {
|
|
1302
|
+
title: opts.description.slice(0, 100),
|
|
1303
|
+
});
|
|
1304
|
+
|
|
1305
|
+
// Save the initial user message to thread data so the tab shows content
|
|
1306
|
+
// immediately. Shape must match assistant-ui's ExportedMessageRepository —
|
|
1307
|
+
// each entry carries an explicit `parentId` so the runtime threads messages
|
|
1308
|
+
// into a linked list; without it, later assistant messages render as
|
|
1309
|
+
// orphaned siblings and only the one under `headId` is shown.
|
|
1310
|
+
const userMsgId = `msg-${taskId}-user`;
|
|
1311
|
+
try {
|
|
1312
|
+
const { updateThreadData } = await import("../chat-threads/store.js");
|
|
1313
|
+
const threadData = JSON.stringify({
|
|
1314
|
+
headId: userMsgId,
|
|
1315
|
+
messages: [
|
|
1316
|
+
{
|
|
1317
|
+
message: {
|
|
1318
|
+
id: userMsgId,
|
|
1319
|
+
role: "user",
|
|
1320
|
+
content: [{ type: "text", text: opts.description }],
|
|
1321
|
+
metadata: {},
|
|
1322
|
+
},
|
|
1323
|
+
parentId: null,
|
|
1324
|
+
},
|
|
1325
|
+
],
|
|
1326
|
+
});
|
|
1327
|
+
await updateThreadData(
|
|
1328
|
+
thread.id,
|
|
1329
|
+
threadData,
|
|
1330
|
+
opts.description.slice(0, 100),
|
|
1331
|
+
opts.description.slice(0, 200),
|
|
1332
|
+
1,
|
|
1333
|
+
);
|
|
1334
|
+
} catch {
|
|
1335
|
+
// Best effort — thread will still work without persisted messages
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
const runId = taskRunId(taskId);
|
|
1339
|
+
const createdAt = Date.now();
|
|
1340
|
+
const task: AgentTask = {
|
|
1341
|
+
taskId,
|
|
1342
|
+
threadId: thread.id,
|
|
1343
|
+
...(opts.parentThreadId ? { parentThreadId: opts.parentThreadId } : {}),
|
|
1344
|
+
...(opts.name ? { name: opts.name } : {}),
|
|
1345
|
+
description: opts.description,
|
|
1346
|
+
status: "running",
|
|
1347
|
+
preview: "",
|
|
1348
|
+
summary: "",
|
|
1349
|
+
currentStep: "Starting sub-agent",
|
|
1350
|
+
createdAt,
|
|
1351
|
+
updatedAt: createdAt,
|
|
1352
|
+
startedAt: createdAt,
|
|
1353
|
+
runId,
|
|
1354
|
+
delegationDepth: childDepth,
|
|
1355
|
+
};
|
|
1356
|
+
|
|
1357
|
+
await saveTask(task);
|
|
1358
|
+
await startTaskProgressRun(task, opts.ownerEmail);
|
|
1359
|
+
|
|
1360
|
+
// Notify parent chat that a sub-agent was spawned
|
|
1361
|
+
opts.parentSend({
|
|
1362
|
+
type: "agent_task",
|
|
1363
|
+
taskId,
|
|
1364
|
+
threadId: thread.id,
|
|
1365
|
+
description: opts.description,
|
|
1366
|
+
status: "running",
|
|
1367
|
+
});
|
|
1368
|
+
|
|
1369
|
+
// Hand the run off to the durable dispatch queue and self-fire a fresh
|
|
1370
|
+
// function invocation to execute it. This is what makes background
|
|
1371
|
+
// sub-agents survive serverless: the spawning request returns immediately
|
|
1372
|
+
// while the sub-agent runs in its OWN invocation (with its own timeout
|
|
1373
|
+
// budget) instead of as a detached in-process promise that the host freezes
|
|
1374
|
+
// when this response flushes. Same enqueue-to-SQL + self-fire-HTTP pattern
|
|
1375
|
+
// as A2A async tasks (a2a/handlers.ts) and integration webhooks
|
|
1376
|
+
// (integrations/webhook-handler.ts). Execution happens in `processAgentTeamRun`,
|
|
1377
|
+
// invoked by the `/_agent-native/agent-teams/_process-run` route mounted
|
|
1378
|
+
// inside the agent-chat plugin (where the action/prompt/engine closures live).
|
|
1379
|
+
let orgId: string | null = null;
|
|
1380
|
+
try {
|
|
1381
|
+
orgId = (await resolveOrgIdForEmail(opts.ownerEmail)) ?? null;
|
|
1382
|
+
} catch {
|
|
1383
|
+
orgId = null;
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
const payload: AgentTeamRunPayload = {
|
|
1387
|
+
description: opts.description,
|
|
1388
|
+
instructions: opts.instructions,
|
|
1389
|
+
model: opts.model,
|
|
1390
|
+
...(opts.parentThreadId ? { parentThreadId: opts.parentThreadId } : {}),
|
|
1391
|
+
...(opts.name ? { name: opts.name } : {}),
|
|
1392
|
+
// Stable across continuation chunks so the durable assistant message folds.
|
|
1393
|
+
turnId: runId,
|
|
1394
|
+
};
|
|
1395
|
+
|
|
1396
|
+
try {
|
|
1397
|
+
await enqueueAgentTeamRun({
|
|
1398
|
+
taskId,
|
|
1399
|
+
threadId: thread.id,
|
|
1400
|
+
runId,
|
|
1401
|
+
ownerEmail: opts.ownerEmail,
|
|
1402
|
+
orgId,
|
|
1403
|
+
payload,
|
|
1404
|
+
});
|
|
1405
|
+
await fireInternalDispatch({
|
|
1406
|
+
path: AGENT_TEAM_PROCESS_RUN_PATH,
|
|
1407
|
+
taskId,
|
|
1408
|
+
body: { mode: "start" },
|
|
1409
|
+
});
|
|
1410
|
+
} catch (err) {
|
|
1411
|
+
// Enqueue/dispatch failed outright — surface as an errored task rather
|
|
1412
|
+
// than a ghost "running" one. (A dropped self-fire that still enqueued is
|
|
1413
|
+
// recovered by the reconcile stuck-refire path.)
|
|
1414
|
+
await failReconciledTask(
|
|
1415
|
+
task,
|
|
1416
|
+
opts.ownerEmail,
|
|
1417
|
+
subAgentDispatchFailureMessage(err),
|
|
1418
|
+
);
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
return task;
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
/**
|
|
1425
|
+
* Build the sub-agent system prompt: a "you are a sub-agent" preamble (so it
|
|
1426
|
+
* starts on its task instead of exploring), the base prompt, and any
|
|
1427
|
+
* task-specific instructions.
|
|
1428
|
+
*/
|
|
1429
|
+
function buildSubAgentSystemPrompt(
|
|
1430
|
+
baseSystemPrompt: string,
|
|
1431
|
+
actions: Record<string, ActionEntry>,
|
|
1432
|
+
instructions?: string,
|
|
1433
|
+
): string {
|
|
1434
|
+
const actionNames = Object.keys(actions).join(", ");
|
|
1435
|
+
const preamble = `## You Are a Sub-Agent
|
|
1436
|
+
|
|
1437
|
+
You are a focused sub-agent with a specific task. You have been given a curated set of actions that connect directly to the app's database and services.
|
|
1438
|
+
|
|
1439
|
+
**Start immediately with your task. Do NOT:**
|
|
1440
|
+
- Run \`db-schema\` to explore the database structure
|
|
1441
|
+
- Run \`bash\` just to search/list files
|
|
1442
|
+
- Try to \`curl\` or access external URLs to find the app
|
|
1443
|
+
- Use \`bash\` for exploration — only for running \`pnpm action\` commands when no direct action exists
|
|
1444
|
+
|
|
1445
|
+
**Your available actions (${actionNames}) work directly. Use them.**
|
|
1446
|
+
|
|
1447
|
+
`;
|
|
1448
|
+
let prompt = preamble + baseSystemPrompt;
|
|
1449
|
+
if (instructions) {
|
|
1450
|
+
prompt += `\n\n## Task-Specific Instructions\n\n${instructions}`;
|
|
1451
|
+
}
|
|
1452
|
+
return prompt;
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
/**
|
|
1456
|
+
* Persist the sub-agent conversation to thread_data, folding continuation
|
|
1457
|
+
* chunks of the same turn into one assistant message (same `foldAssistantTurn`
|
|
1458
|
+
* mechanism the main chat uses). Returns the full folded assistant text for use
|
|
1459
|
+
* as the task summary so multi-chunk runs don't lose earlier chunks' output.
|
|
1460
|
+
*/
|
|
1461
|
+
async function persistTaskThreadData(
|
|
1462
|
+
task: AgentTask,
|
|
1463
|
+
description: string,
|
|
1464
|
+
run: ActiveRun,
|
|
1465
|
+
runId: string,
|
|
1466
|
+
turnId: string,
|
|
1467
|
+
): Promise<string> {
|
|
1468
|
+
try {
|
|
1469
|
+
const { getThread, updateThreadData } =
|
|
1470
|
+
await import("../chat-threads/store.js");
|
|
1471
|
+
const thread = await getThread(task.threadId);
|
|
1472
|
+
let repo: any;
|
|
1473
|
+
try {
|
|
1474
|
+
repo = JSON.parse(thread?.threadData || "{}");
|
|
1475
|
+
} catch {
|
|
1476
|
+
repo = {};
|
|
1477
|
+
}
|
|
1478
|
+
if (!Array.isArray(repo.messages)) repo.messages = [];
|
|
1479
|
+
|
|
1480
|
+
// Ensure the seed user message exists (first chunk / fresh thread).
|
|
1481
|
+
const userMsgId = `msg-${task.taskId}-user`;
|
|
1482
|
+
const hasUser = repo.messages.some(
|
|
1483
|
+
(m: any) => (m?.message ?? m)?.id === userMsgId,
|
|
1484
|
+
);
|
|
1485
|
+
if (!hasUser) {
|
|
1486
|
+
repo.messages.unshift({
|
|
1487
|
+
message: {
|
|
1488
|
+
id: userMsgId,
|
|
1489
|
+
role: "user",
|
|
1490
|
+
content: [{ type: "text", text: description }],
|
|
1491
|
+
metadata: {},
|
|
1492
|
+
},
|
|
1493
|
+
parentId: null,
|
|
1494
|
+
});
|
|
1495
|
+
if (!repo.headId) repo.headId = userMsgId;
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
const assistantMsg = buildAssistantMessage(run.events ?? [], runId, {
|
|
1499
|
+
suppressInternalContinuation: true,
|
|
1500
|
+
turnId,
|
|
1501
|
+
});
|
|
1502
|
+
if (assistantMsg) {
|
|
1503
|
+
repo = foldAssistantTurn(repo, assistantMsg, { runId, turnId });
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
// Extract the folded assistant text (full content across chunks).
|
|
1507
|
+
let assistantText = "";
|
|
1508
|
+
const headEntry = Array.isArray(repo.messages)
|
|
1509
|
+
? repo.messages.find((m: any) => (m?.message ?? m)?.id === repo.headId)
|
|
1510
|
+
: undefined;
|
|
1511
|
+
const headMsg = headEntry?.message ?? headEntry;
|
|
1512
|
+
if (headMsg?.role === "assistant" && Array.isArray(headMsg.content)) {
|
|
1513
|
+
assistantText = headMsg.content
|
|
1514
|
+
.filter((c: any) => c?.type === "text" && typeof c.text === "string")
|
|
1515
|
+
.map((c: any) => c.text)
|
|
1516
|
+
.join("\n");
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
await updateThreadData(
|
|
1520
|
+
task.threadId,
|
|
1521
|
+
JSON.stringify(repo),
|
|
1522
|
+
description.slice(0, 100),
|
|
1523
|
+
assistantText.slice(0, 200),
|
|
1524
|
+
Array.isArray(repo.messages) ? repo.messages.length : 1,
|
|
1525
|
+
);
|
|
1526
|
+
return assistantText;
|
|
1527
|
+
} catch {
|
|
1528
|
+
return "";
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
/** Mark a sub-agent task terminal: task record, progress row, and queue row. */
|
|
1533
|
+
async function finalizeAgentTeamRun(
|
|
1534
|
+
task: AgentTask,
|
|
1535
|
+
run: ActiveRun,
|
|
1536
|
+
ownerEmail: string | null,
|
|
1537
|
+
fullText: string,
|
|
1538
|
+
options?: { hitContinuationLimit?: boolean; claimedAttempts?: number },
|
|
1539
|
+
): Promise<void> {
|
|
1540
|
+
const terminal = resolveTaskCompletion(run, fullText, {
|
|
1541
|
+
hitContinuationLimit: options?.hitContinuationLimit,
|
|
1542
|
+
});
|
|
1543
|
+
task.status = terminal.taskStatus;
|
|
1544
|
+
task.summary = terminal.summary;
|
|
1545
|
+
task.error = terminal.error;
|
|
1546
|
+
task.currentStep = "";
|
|
1547
|
+
task.completedAt = Date.now();
|
|
1548
|
+
await saveTask(task);
|
|
1549
|
+
if (ownerEmail) {
|
|
1550
|
+
await completeTaskProgressRun(
|
|
1551
|
+
task,
|
|
1552
|
+
ownerEmail,
|
|
1553
|
+
terminal.progressStatus,
|
|
1554
|
+
terminal.progressStep,
|
|
1555
|
+
);
|
|
1556
|
+
}
|
|
1557
|
+
await completeAgentTeamRun(
|
|
1558
|
+
task.taskId,
|
|
1559
|
+
terminal.taskStatus === "completed" ? "done" : "failed",
|
|
1560
|
+
options?.claimedAttempts,
|
|
1561
|
+
);
|
|
1562
|
+
|
|
1563
|
+
// ── Completion loop: notify the parent thread ─────────────────────────────
|
|
1564
|
+
// Append a durable injection to the parent thread's queue so the
|
|
1565
|
+
// orchestrator automatically sees the result at its next turn start.
|
|
1566
|
+
// Also write a NotificationsBell entry so the user sees a badge.
|
|
1567
|
+
if (task.parentThreadId) {
|
|
1568
|
+
try {
|
|
1569
|
+
await appendParentCompletionInjection(task.parentThreadId, task, {
|
|
1570
|
+
taskStatus: terminal.taskStatus,
|
|
1571
|
+
summary: terminal.summary,
|
|
1572
|
+
hitContinuationLimit: options?.hitContinuationLimit,
|
|
1573
|
+
});
|
|
1574
|
+
} catch {
|
|
1575
|
+
// best-effort — a queue write failure must not break finalization
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
if (ownerEmail) {
|
|
1579
|
+
try {
|
|
1580
|
+
const { insertNotification } = await import("../notifications/store.js");
|
|
1581
|
+
const name = task.name ?? task.description.slice(0, 60);
|
|
1582
|
+
const statusLabel =
|
|
1583
|
+
terminal.taskStatus === "completed"
|
|
1584
|
+
? options?.hitContinuationLimit
|
|
1585
|
+
? "finished (hit limit)"
|
|
1586
|
+
: "finished"
|
|
1587
|
+
: "failed";
|
|
1588
|
+
await insertNotification({
|
|
1589
|
+
owner: ownerEmail,
|
|
1590
|
+
severity: terminal.taskStatus === "completed" ? "info" : "warning",
|
|
1591
|
+
title: `Sub-agent "${name}" ${statusLabel}`,
|
|
1592
|
+
body: terminal.summary.slice(0, 300) || undefined,
|
|
1593
|
+
metadata: {
|
|
1594
|
+
kind: "agent-team-complete",
|
|
1595
|
+
taskId: task.taskId,
|
|
1596
|
+
threadId: task.threadId,
|
|
1597
|
+
...(task.parentThreadId
|
|
1598
|
+
? { parentThreadId: task.parentThreadId }
|
|
1599
|
+
: {}),
|
|
1600
|
+
},
|
|
1601
|
+
});
|
|
1602
|
+
} catch {
|
|
1603
|
+
// best-effort — a notification write failure must not break finalization
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
/** Run config the processor route resolves from plugin-scope closures. */
|
|
1609
|
+
export interface AgentTeamRunConfig {
|
|
1610
|
+
baseSystemPrompt: string;
|
|
1611
|
+
actions: Record<string, ActionEntry>;
|
|
1612
|
+
engine: AgentEngine;
|
|
1613
|
+
model: string;
|
|
1614
|
+
/**
|
|
1615
|
+
* Tool names to expose on the FIRST engine request for this sub-agent
|
|
1616
|
+
* chunk. See `SchedulerDeps.getInitialToolNames` (`jobs/scheduler.ts`) —
|
|
1617
|
+
* same semantics: when provided, every other action in `actions` is
|
|
1618
|
+
* deferred behind an attached `tool-search` entry instead of being
|
|
1619
|
+
* serialized on every chunk; `runAgentLoop`'s mid-run tool expansion still
|
|
1620
|
+
* lets the model discover and call them after a search. Omit to keep the
|
|
1621
|
+
* full `actions` set visible up front (current behavior).
|
|
1622
|
+
*/
|
|
1623
|
+
initialToolNames?: string[];
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1626
|
+
export interface ProcessAgentTeamRunOptions {
|
|
1627
|
+
taskId: string;
|
|
1628
|
+
/** "start" = first chunk; "continue" = resume from thread_data after a
|
|
1629
|
+
* soft-timeout boundary. Defaults from the queue row's continuation count. */
|
|
1630
|
+
mode?: "start" | "continue";
|
|
1631
|
+
/** Inbound request event, used to resolve the self-dispatch base URL for
|
|
1632
|
+
* continuation self-fires. */
|
|
1633
|
+
event?: any;
|
|
1634
|
+
/** Count of consecutive non-progressing chunks carried forward from the
|
|
1635
|
+
* previous invocation. Used by the progress-aware continuation budget. */
|
|
1636
|
+
noProgressCount?: number;
|
|
1637
|
+
/** Builds the sub-agent run config from the queue payload + resolved owner.
|
|
1638
|
+
* The plugin supplies this because the action registry / base prompt /
|
|
1639
|
+
* engine are per-deployment plugin-scope closures, not serializable. */
|
|
1640
|
+
resolveConfig: (ctx: {
|
|
1641
|
+
payload: AgentTeamRunPayload;
|
|
1642
|
+
ownerEmail: string;
|
|
1643
|
+
orgId: string | null;
|
|
1644
|
+
}) => Promise<AgentTeamRunConfig>;
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
/**
|
|
1648
|
+
* Execute one chunk of a queued sub-agent run in a fresh function invocation.
|
|
1649
|
+
* Called by the `/_agent-native/agent-teams/_process-run` route. Atomically
|
|
1650
|
+
* claims the run (idempotent on duplicate self-fires), reconstructs the
|
|
1651
|
+
* messages (start vs continue), runs the agent loop to completion, persists
|
|
1652
|
+
* thread_data, and either self-fires a continuation (soft-timeout boundary,
|
|
1653
|
+
* under the cap) or finalizes the task.
|
|
1654
|
+
*/
|
|
1655
|
+
export async function processAgentTeamRun(
|
|
1656
|
+
opts: ProcessAgentTeamRunOptions,
|
|
1657
|
+
): Promise<{ ok: boolean; skipped?: string }> {
|
|
1658
|
+
const claimed = await claimAgentTeamRun(opts.taskId);
|
|
1659
|
+
if (!claimed) return { ok: true, skipped: "already-claimed-or-missing" };
|
|
1660
|
+
|
|
1661
|
+
return await runWithRequestContext(
|
|
1662
|
+
{
|
|
1663
|
+
userEmail: claimed.ownerEmail ?? undefined,
|
|
1664
|
+
orgId: claimed.orgId ?? undefined,
|
|
1665
|
+
},
|
|
1666
|
+
async () => {
|
|
1667
|
+
const task = await loadTask(opts.taskId);
|
|
1668
|
+
if (!task) {
|
|
1669
|
+
await completeAgentTeamRun(opts.taskId, "failed");
|
|
1670
|
+
return { ok: true, skipped: "task-missing" };
|
|
1671
|
+
}
|
|
1672
|
+
if (task.status !== "running") {
|
|
1673
|
+
await completeAgentTeamRun(
|
|
1674
|
+
opts.taskId,
|
|
1675
|
+
task.status === "completed" ? "done" : "failed",
|
|
1676
|
+
);
|
|
1677
|
+
return { ok: true, skipped: "task-terminal" };
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
const payload = claimed.payload;
|
|
1681
|
+
const ownerEmail = claimed.ownerEmail ?? getRequestUserEmail() ?? "";
|
|
1682
|
+
const orgId = claimed.orgId;
|
|
1683
|
+
const turnId = payload.turnId || taskRunId(opts.taskId);
|
|
1684
|
+
|
|
1685
|
+
let config: AgentTeamRunConfig;
|
|
1686
|
+
try {
|
|
1687
|
+
config = await opts.resolveConfig({ payload, ownerEmail, orgId });
|
|
1688
|
+
} catch (err) {
|
|
1689
|
+
const message =
|
|
1690
|
+
err instanceof Error
|
|
1691
|
+
? `Failed to prepare sub-agent: ${err.message}`
|
|
1692
|
+
: "Failed to prepare sub-agent.";
|
|
1693
|
+
await failReconciledTask(task, ownerEmail || null, message);
|
|
1694
|
+
return { ok: false, skipped: "config-failed" };
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
const mode: "start" | "continue" =
|
|
1698
|
+
opts.mode ?? (claimed.continuationCount > 0 ? "continue" : "start");
|
|
1699
|
+
|
|
1700
|
+
const systemPrompt = buildSubAgentSystemPrompt(
|
|
1701
|
+
config.baseSystemPrompt,
|
|
1702
|
+
config.actions,
|
|
1703
|
+
payload.instructions,
|
|
1704
|
+
);
|
|
1705
|
+
|
|
1706
|
+
let messages: EngineMessage[];
|
|
1707
|
+
if (mode === "continue") {
|
|
1708
|
+
let priorThreadData: string | null | undefined;
|
|
1709
|
+
try {
|
|
1710
|
+
const { getThread } = await import("../chat-threads/store.js");
|
|
1711
|
+
priorThreadData = (await getThread(task.threadId))?.threadData;
|
|
1712
|
+
} catch {
|
|
1713
|
+
priorThreadData = undefined;
|
|
1714
|
+
}
|
|
1715
|
+
messages = threadDataToEngineMessages(priorThreadData);
|
|
1716
|
+
if (messages.length === 0) {
|
|
1717
|
+
messages = [
|
|
1718
|
+
{
|
|
1719
|
+
role: "user",
|
|
1720
|
+
content: [{ type: "text", text: payload.description }],
|
|
1721
|
+
},
|
|
1722
|
+
];
|
|
1723
|
+
}
|
|
1724
|
+
appendAgentLoopContinuation(messages, "run_timeout");
|
|
1725
|
+
} else {
|
|
1726
|
+
messages = [
|
|
1727
|
+
{
|
|
1728
|
+
role: "user",
|
|
1729
|
+
content: [{ type: "text", text: payload.description }],
|
|
1730
|
+
},
|
|
1731
|
+
];
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
const initialToolNames = config.initialToolNames;
|
|
1735
|
+
// Only attach tool-search (and pay its schema cost) when the caller
|
|
1736
|
+
// actually supplied an initial subset to filter down to — otherwise
|
|
1737
|
+
// this is byte-for-byte the prior unfiltered behavior.
|
|
1738
|
+
const baseActions = initialToolNames
|
|
1739
|
+
? attachToolSearch({ ...config.actions })
|
|
1740
|
+
: config.actions;
|
|
1741
|
+
const messageAwareActions = createMessageAwareActions(
|
|
1742
|
+
opts.taskId,
|
|
1743
|
+
baseActions,
|
|
1744
|
+
);
|
|
1745
|
+
const availableTools = actionsToEngineTools(messageAwareActions);
|
|
1746
|
+
const tools = filterInitialEngineTools(availableTools, initialToolNames);
|
|
1747
|
+
|
|
1748
|
+
// Fresh runId per chunk (avoids agent_runs PK collisions); stable turnId so
|
|
1749
|
+
// the durable assistant message folds across chunks.
|
|
1750
|
+
const runId = `${taskRunId(opts.taskId)}-c${claimed.continuationCount}`;
|
|
1751
|
+
|
|
1752
|
+
task.currentStep =
|
|
1753
|
+
mode === "continue" ? "Continuing sub-agent" : "Working on response";
|
|
1754
|
+
task.startedAt = task.startedAt ?? Date.now();
|
|
1755
|
+
await saveTask(task);
|
|
1756
|
+
if (ownerEmail) await updateTaskProgressRun(task, ownerEmail);
|
|
1757
|
+
|
|
1758
|
+
// The attempts value at claim-time is the fencing token. All queue
|
|
1759
|
+
// writes (heartbeat, bump, complete) include AND attempts = claimedAttempts
|
|
1760
|
+
// so a superseded invocation that was re-claimed by a stuck-refire cannot
|
|
1761
|
+
// accidentally touch the new invocation's row.
|
|
1762
|
+
const claimedAttempts = claimed.attempts;
|
|
1763
|
+
|
|
1764
|
+
const heartbeat = setInterval(() => {
|
|
1765
|
+
// Best-effort: a dropped Neon WebSocket (Lambda freeze/thaw) rejects
|
|
1766
|
+
// with a raw ErrorEvent; a floating rejection here surfaces as an
|
|
1767
|
+
// unhandled promise rejection, so it must be caught and logged.
|
|
1768
|
+
touchAgentTeamRun(opts.taskId, claimedAttempts).catch((err) => {
|
|
1769
|
+
console.warn(
|
|
1770
|
+
`[agent-teams] heartbeat update failed for task ${opts.taskId}:`,
|
|
1771
|
+
describeDbError(err),
|
|
1772
|
+
);
|
|
1773
|
+
});
|
|
1774
|
+
}, RUN_QUEUE_HEARTBEAT_MS);
|
|
1775
|
+
(heartbeat as unknown as { unref?: () => void }).unref?.();
|
|
1776
|
+
|
|
1777
|
+
let accumulatedText = "";
|
|
1778
|
+
let lastProgressSent = 0;
|
|
1779
|
+
const PROGRESS_INTERVAL_MS = 2000;
|
|
1780
|
+
// Track no-progress continuation budget (Fix 3).
|
|
1781
|
+
let consecutiveNoProgressChunks = opts.noProgressCount ?? 0;
|
|
1782
|
+
|
|
1783
|
+
// Capture loop usage for token accounting (Fix 4).
|
|
1784
|
+
let chunkUsage:
|
|
1785
|
+
| import("../agent/production-agent.js").AgentLoopUsage
|
|
1786
|
+
| null = null;
|
|
1787
|
+
|
|
1788
|
+
await new Promise<void>((resolve) => {
|
|
1789
|
+
startRun(
|
|
1790
|
+
runId,
|
|
1791
|
+
task.threadId,
|
|
1792
|
+
async (send, signal) => {
|
|
1793
|
+
const wrappedSend = (event: AgentChatEvent) => {
|
|
1794
|
+
send(event);
|
|
1795
|
+
if (event.type === "text") {
|
|
1796
|
+
accumulatedText = applyAgentTextEventToBuffer(
|
|
1797
|
+
accumulatedText,
|
|
1798
|
+
event,
|
|
1799
|
+
);
|
|
1800
|
+
task.preview = accumulatedText.slice(-800);
|
|
1801
|
+
const now = Date.now();
|
|
1802
|
+
if (now - lastProgressSent >= PROGRESS_INTERVAL_MS) {
|
|
1803
|
+
lastProgressSent = now;
|
|
1804
|
+
saveTask(task).catch((err) => {
|
|
1805
|
+
console.warn(
|
|
1806
|
+
`[agent-teams] progress save failed for task ${task.taskId}:`,
|
|
1807
|
+
describeDbError(err),
|
|
1808
|
+
);
|
|
1809
|
+
});
|
|
1810
|
+
if (ownerEmail) void updateTaskProgressRun(task, ownerEmail);
|
|
1811
|
+
}
|
|
1812
|
+
} else if (event.type === "clear") {
|
|
1813
|
+
accumulatedText = applyAgentTextEventToBuffer(
|
|
1814
|
+
accumulatedText,
|
|
1815
|
+
event,
|
|
1816
|
+
);
|
|
1817
|
+
task.preview = "";
|
|
1818
|
+
lastProgressSent = Date.now();
|
|
1819
|
+
saveTask(task).catch((err) => {
|
|
1820
|
+
console.warn(
|
|
1821
|
+
`[agent-teams] clear save failed for task ${task.taskId}:`,
|
|
1822
|
+
describeDbError(err),
|
|
1823
|
+
);
|
|
1824
|
+
});
|
|
1825
|
+
if (ownerEmail) void updateTaskProgressRun(task, ownerEmail);
|
|
1826
|
+
} else if (event.type === "tool_start") {
|
|
1827
|
+
task.currentStep = `Running ${event.tool}...`;
|
|
1828
|
+
} else if (event.type === "tool_done") {
|
|
1829
|
+
task.currentStep = "";
|
|
1830
|
+
}
|
|
1831
|
+
};
|
|
1832
|
+
await runWithRequestContext(
|
|
1833
|
+
{ userEmail: ownerEmail || undefined, orgId: orgId ?? undefined },
|
|
1834
|
+
// Record THIS sub-agent's own delegation depth as the ambient
|
|
1835
|
+
// depth for the duration of its agent loop. If a tool call from
|
|
1836
|
+
// within the loop reaches `spawnTask` (even with the team tool not
|
|
1837
|
+
// stripped), the spawn path reads this depth and refuses once the
|
|
1838
|
+
// cap is hit. Fall back to depth 1 for legacy tasks persisted
|
|
1839
|
+
// before delegationDepth was tracked.
|
|
1840
|
+
() =>
|
|
1841
|
+
runWithDelegationDepth(task.delegationDepth ?? 1, async () => {
|
|
1842
|
+
chunkUsage = await runAgentLoop({
|
|
1843
|
+
engine: config.engine,
|
|
1844
|
+
model: config.model,
|
|
1845
|
+
// Agent-team runs are delegated turns too. Keep their
|
|
1846
|
+
// first attempt on the same model-aware budget as A2A /
|
|
1847
|
+
// MCP so reasoning models do not spend the old 4K
|
|
1848
|
+
// default before emitting a tool call or answer.
|
|
1849
|
+
maxOutputTokens: resolveMainChatMaxOutputTokens(
|
|
1850
|
+
config.model,
|
|
1851
|
+
),
|
|
1852
|
+
reasoningEffort: resolveAgentRequestReasoningEffort({
|
|
1853
|
+
model: config.model,
|
|
1854
|
+
}),
|
|
1855
|
+
systemPrompt,
|
|
1856
|
+
tools,
|
|
1857
|
+
availableTools,
|
|
1858
|
+
messages,
|
|
1859
|
+
actions: messageAwareActions,
|
|
1860
|
+
send: wrappedSend,
|
|
1861
|
+
signal,
|
|
1862
|
+
finalResponseGuard: createTaskMessageFinalGuard(
|
|
1863
|
+
opts.taskId,
|
|
1864
|
+
),
|
|
1865
|
+
});
|
|
1866
|
+
}),
|
|
1867
|
+
);
|
|
1868
|
+
},
|
|
1869
|
+
async (run) => {
|
|
1870
|
+
clearInterval(heartbeat);
|
|
1871
|
+
try {
|
|
1872
|
+
const fullText = await persistTaskThreadData(
|
|
1873
|
+
task,
|
|
1874
|
+
payload.description,
|
|
1875
|
+
run,
|
|
1876
|
+
runId,
|
|
1877
|
+
turnId,
|
|
1878
|
+
);
|
|
1879
|
+
|
|
1880
|
+
// Record token usage for this chunk (Fix 4).
|
|
1881
|
+
if (chunkUsage && ownerEmail) {
|
|
1882
|
+
try {
|
|
1883
|
+
const u = chunkUsage;
|
|
1884
|
+
if (
|
|
1885
|
+
u.inputTokens > 0 ||
|
|
1886
|
+
u.outputTokens > 0 ||
|
|
1887
|
+
u.cacheReadTokens > 0 ||
|
|
1888
|
+
u.cacheWriteTokens > 0
|
|
1889
|
+
) {
|
|
1890
|
+
const { recordUsage } = await import("../usage/store.js");
|
|
1891
|
+
const label = payload.name
|
|
1892
|
+
? `agent-team:${payload.name}`
|
|
1893
|
+
: "agent-team";
|
|
1894
|
+
await recordUsage({
|
|
1895
|
+
ownerEmail,
|
|
1896
|
+
inputTokens: u.inputTokens,
|
|
1897
|
+
outputTokens: u.outputTokens,
|
|
1898
|
+
cacheReadTokens: u.cacheReadTokens,
|
|
1899
|
+
cacheWriteTokens: u.cacheWriteTokens,
|
|
1900
|
+
model: u.model,
|
|
1901
|
+
label,
|
|
1902
|
+
});
|
|
1903
|
+
}
|
|
1904
|
+
} catch {
|
|
1905
|
+
// Usage recording failed — don't break the run
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
|
|
1909
|
+
// A soft-timeout boundary means the host function wall is near and
|
|
1910
|
+
// the partial turn is checkpointed in thread_data — self-fire the
|
|
1911
|
+
// next continuation chunk (server-side analog of the client re-POST
|
|
1912
|
+
// that continues the main chat) instead of finalizing.
|
|
1913
|
+
const reachedBoundary = (run.events ?? []).some(
|
|
1914
|
+
(e) => e.event.type === "auto_continue",
|
|
1915
|
+
);
|
|
1916
|
+
if (reachedBoundary) {
|
|
1917
|
+
// Progress check (Fix 3): count substantive events in this chunk.
|
|
1918
|
+
// Any text or tool activity counts as progress. An empty chunk
|
|
1919
|
+
// (only auto_continue with no actual work) is non-progressing.
|
|
1920
|
+
const substantiveEvents = (run.events ?? []).filter(
|
|
1921
|
+
(e) =>
|
|
1922
|
+
e.event.type === "text" ||
|
|
1923
|
+
e.event.type === "tool_start" ||
|
|
1924
|
+
e.event.type === "tool_done",
|
|
1925
|
+
).length;
|
|
1926
|
+
if (substantiveEvents === 0) {
|
|
1927
|
+
consecutiveNoProgressChunks += 1;
|
|
1928
|
+
} else {
|
|
1929
|
+
consecutiveNoProgressChunks = 0;
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
const hitNoProgressLimit =
|
|
1933
|
+
consecutiveNoProgressChunks >=
|
|
1934
|
+
MAX_AGENT_TEAM_NO_PROGRESS_CONTINUATIONS;
|
|
1935
|
+
const count = await bumpAgentTeamContinuation(
|
|
1936
|
+
opts.taskId,
|
|
1937
|
+
claimedAttempts,
|
|
1938
|
+
);
|
|
1939
|
+
if (
|
|
1940
|
+
count !== null &&
|
|
1941
|
+
count <= MAX_AGENT_TEAM_CONTINUATIONS &&
|
|
1942
|
+
!hitNoProgressLimit
|
|
1943
|
+
) {
|
|
1944
|
+
task.currentStep = "Continuing sub-agent";
|
|
1945
|
+
task.preview = (fullText || accumulatedText).slice(-800);
|
|
1946
|
+
await saveTask(task);
|
|
1947
|
+
if (ownerEmail) await updateTaskProgressRun(task, ownerEmail);
|
|
1948
|
+
try {
|
|
1949
|
+
await fireInternalDispatch({
|
|
1950
|
+
event: opts.event,
|
|
1951
|
+
path: AGENT_TEAM_PROCESS_RUN_PATH,
|
|
1952
|
+
taskId: opts.taskId,
|
|
1953
|
+
body: {
|
|
1954
|
+
mode: "continue",
|
|
1955
|
+
noProgressCount: consecutiveNoProgressChunks,
|
|
1956
|
+
},
|
|
1957
|
+
});
|
|
1958
|
+
} catch (err) {
|
|
1959
|
+
await failReconciledTask(
|
|
1960
|
+
task,
|
|
1961
|
+
ownerEmail || null,
|
|
1962
|
+
subAgentDispatchFailureMessage(err),
|
|
1963
|
+
);
|
|
1964
|
+
}
|
|
1965
|
+
return;
|
|
1966
|
+
}
|
|
1967
|
+
// Hit the absolute cap or no-progress limit — finalize with an
|
|
1968
|
+
// explicit marker so the orchestrator can distinguish this from a
|
|
1969
|
+
// clean completion.
|
|
1970
|
+
await finalizeAgentTeamRun(
|
|
1971
|
+
task,
|
|
1972
|
+
run,
|
|
1973
|
+
ownerEmail || null,
|
|
1974
|
+
fullText || accumulatedText,
|
|
1975
|
+
{ hitContinuationLimit: true, claimedAttempts },
|
|
1976
|
+
);
|
|
1977
|
+
return;
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1980
|
+
await finalizeAgentTeamRun(
|
|
1981
|
+
task,
|
|
1982
|
+
run,
|
|
1983
|
+
ownerEmail || null,
|
|
1984
|
+
fullText || accumulatedText,
|
|
1985
|
+
{ claimedAttempts },
|
|
1986
|
+
);
|
|
1987
|
+
} finally {
|
|
1988
|
+
resolve();
|
|
1989
|
+
}
|
|
1990
|
+
},
|
|
1991
|
+
{ useHostedSoftTimeoutDefault: true, turnId },
|
|
1992
|
+
);
|
|
1993
|
+
});
|
|
1994
|
+
|
|
1995
|
+
return { ok: true };
|
|
1996
|
+
},
|
|
1997
|
+
);
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
/** Get task by ID */
|
|
2001
|
+
export async function getTask(taskId: string): Promise<AgentTask | undefined> {
|
|
2002
|
+
const task = await loadTask(taskId);
|
|
2003
|
+
return task ? await reconcileTaskWithRun(task) : undefined;
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
/** Get task by thread ID */
|
|
2007
|
+
export async function getTaskByThread(
|
|
2008
|
+
threadId: string,
|
|
2009
|
+
): Promise<AgentTask | undefined> {
|
|
2010
|
+
const task = await loadTaskByThread(threadId);
|
|
2011
|
+
return task ? await reconcileTaskWithRun(task) : undefined;
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
/** List all tasks (most recent first) */
|
|
2015
|
+
export async function listTasks(): Promise<AgentTask[]> {
|
|
2016
|
+
const entries = await listAppState(TASK_PREFIX);
|
|
2017
|
+
const tasks = entries.map((e) => e.value as unknown as AgentTask);
|
|
2018
|
+
const reconciled = await Promise.all(tasks.map(reconcileTaskWithRun));
|
|
2019
|
+
return reconciled.sort(
|
|
2020
|
+
(a, b) =>
|
|
2021
|
+
(b.updatedAt ?? b.completedAt ?? b.createdAt) -
|
|
2022
|
+
(a.updatedAt ?? a.completedAt ?? a.createdAt),
|
|
2023
|
+
);
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
export async function listAgentTeamBackgroundRuns(): Promise<
|
|
2027
|
+
AgentTeamBackgroundRun[]
|
|
2028
|
+
> {
|
|
2029
|
+
return (await listTasks()).map(toAgentTaskBackgroundRun);
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
export async function getAgentTeamBackgroundRun(
|
|
2033
|
+
runId: string,
|
|
2034
|
+
): Promise<AgentTeamBackgroundRun | null> {
|
|
2035
|
+
const task = await loadTask(taskIdFromBackgroundRunId(runId));
|
|
2036
|
+
return task
|
|
2037
|
+
? toAgentTaskBackgroundRun(await reconcileTaskWithRun(task))
|
|
2038
|
+
: null;
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
export async function listAgentTeamBackgroundTranscriptEvents(
|
|
2042
|
+
runId: string,
|
|
2043
|
+
): Promise<AgentTeamBackgroundTranscriptEvent[]> {
|
|
2044
|
+
const taskId = taskIdFromBackgroundRunId(runId);
|
|
2045
|
+
const normalizedRunId = taskRunId(taskId);
|
|
2046
|
+
const runIds = await transcriptRunIdsForTask(taskId);
|
|
2047
|
+
const output: AgentTeamBackgroundTranscriptEvent[] = [];
|
|
2048
|
+
let seq = 0;
|
|
2049
|
+
|
|
2050
|
+
for (const sourceRunId of runIds) {
|
|
2051
|
+
const activeRun = getRun(sourceRunId);
|
|
2052
|
+
const events = activeRun
|
|
2053
|
+
? activeRun.events
|
|
2054
|
+
: await getPersistedRunEvents(sourceRunId);
|
|
2055
|
+
for (const event of events) {
|
|
2056
|
+
const transcriptEvent = toAgentTaskBackgroundTranscriptEvent(
|
|
2057
|
+
normalizedRunId,
|
|
2058
|
+
event,
|
|
2059
|
+
{ seq, sourceRunId },
|
|
2060
|
+
);
|
|
2061
|
+
if (transcriptEvent) {
|
|
2062
|
+
output.push(transcriptEvent);
|
|
2063
|
+
seq += 1;
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
return output;
|
|
2069
|
+
}
|
|
2070
|
+
|
|
2071
|
+
export function subscribeToAgentTeamBackgroundRun(
|
|
2072
|
+
runId: string,
|
|
2073
|
+
fromSeq = 0,
|
|
2074
|
+
): ReadableStream<Uint8Array> | null {
|
|
2075
|
+
return subscribeToRun(
|
|
2076
|
+
runningInMemoryTaskRunId(taskIdFromBackgroundRunId(runId)),
|
|
2077
|
+
fromSeq,
|
|
2078
|
+
);
|
|
2079
|
+
}
|
|
2080
|
+
|
|
2081
|
+
async function transcriptRunIdsForTask(taskId: string): Promise<string[]> {
|
|
2082
|
+
const baseRunId = taskRunId(taskId);
|
|
2083
|
+
let continuationCount = 0;
|
|
2084
|
+
try {
|
|
2085
|
+
continuationCount =
|
|
2086
|
+
(await getAgentTeamRunDispatchState(taskId))?.continuationCount ?? 0;
|
|
2087
|
+
} catch {
|
|
2088
|
+
continuationCount = 0;
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2091
|
+
const ids = [baseRunId];
|
|
2092
|
+
for (let i = 0; i <= continuationCount; i += 1) {
|
|
2093
|
+
ids.push(taskRunChunkId(taskId, i));
|
|
2094
|
+
}
|
|
2095
|
+
return ids;
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2098
|
+
async function getPersistedRunEvents(runId: string): Promise<RunEvent[]> {
|
|
2099
|
+
const rows = await getRunEventsSince(runId, 0);
|
|
2100
|
+
return rows
|
|
2101
|
+
.map((row): RunEvent | null => {
|
|
2102
|
+
try {
|
|
2103
|
+
return {
|
|
2104
|
+
seq: row.seq,
|
|
2105
|
+
event: JSON.parse(row.eventData) as RunEvent["event"],
|
|
2106
|
+
};
|
|
2107
|
+
} catch {
|
|
2108
|
+
return null;
|
|
2109
|
+
}
|
|
2110
|
+
})
|
|
2111
|
+
.filter((event): event is RunEvent => Boolean(event));
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
/** Send a message/update to a running sub-agent via application state */
|
|
2115
|
+
export async function sendToTask(
|
|
2116
|
+
taskId: string,
|
|
2117
|
+
message: string,
|
|
2118
|
+
): Promise<{
|
|
2119
|
+
ok: boolean;
|
|
2120
|
+
error?: string;
|
|
2121
|
+
messageId?: string;
|
|
2122
|
+
queuedCount?: number;
|
|
2123
|
+
}> {
|
|
2124
|
+
const task = await loadTask(taskId);
|
|
2125
|
+
if (!task) return { ok: false, error: "Task not found" };
|
|
2126
|
+
if (task.status !== "running")
|
|
2127
|
+
return { ok: false, error: "Task is not running" };
|
|
2128
|
+
if (message.trim().length === 0)
|
|
2129
|
+
return { ok: false, error: "Message is required" };
|
|
2130
|
+
|
|
2131
|
+
// Append to a durable per-task queue. Running sub-agents drain this queue
|
|
2132
|
+
// after tool batches and immediately before a final response. This does not
|
|
2133
|
+
// interrupt an in-flight model stream or tool call; it guarantees the next
|
|
2134
|
+
// safe continuation sees the update.
|
|
2135
|
+
try {
|
|
2136
|
+
const queued = await appendQueuedTaskMessage(taskId, message);
|
|
2137
|
+
return { ok: true, ...queued };
|
|
2138
|
+
} catch {
|
|
2139
|
+
const sessionId = getRequestUserEmail();
|
|
2140
|
+
if (!sessionId) return { ok: false, error: "no authenticated user" };
|
|
2141
|
+
return { ok: false, error: "Unable to queue message" };
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
|
|
2145
|
+
export async function sendToAgentTeamBackgroundRun(
|
|
2146
|
+
runId: string,
|
|
2147
|
+
message: string,
|
|
2148
|
+
): Promise<SendToAgentTeamBackgroundRunResult> {
|
|
2149
|
+
return sendToTask(taskIdFromBackgroundRunId(runId), message);
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2152
|
+
async function sendAgentTeamBackgroundAgentFollowUp(
|
|
2153
|
+
input: BackgroundAgentFollowUpInput,
|
|
2154
|
+
): Promise<BackgroundAgentControlResult> {
|
|
2155
|
+
const prompt = input.prompt.trim();
|
|
2156
|
+
if (!prompt) {
|
|
2157
|
+
return {
|
|
2158
|
+
ok: false,
|
|
2159
|
+
runId: input.runId,
|
|
2160
|
+
run: await getAgentTeamBackgroundRun(input.runId),
|
|
2161
|
+
error: "Follow-up prompt is required.",
|
|
2162
|
+
};
|
|
2163
|
+
}
|
|
2164
|
+
|
|
2165
|
+
const result = await sendToAgentTeamBackgroundRun(input.runId, prompt);
|
|
2166
|
+
return {
|
|
2167
|
+
ok: result.ok,
|
|
2168
|
+
runId: input.runId,
|
|
2169
|
+
run: await getAgentTeamBackgroundRun(input.runId),
|
|
2170
|
+
queued: result.ok,
|
|
2171
|
+
message: result.ok
|
|
2172
|
+
? "Follow-up queued for the Agent Teams background run."
|
|
2173
|
+
: undefined,
|
|
2174
|
+
error: result.error,
|
|
2175
|
+
};
|
|
2176
|
+
}
|
|
2177
|
+
|
|
2178
|
+
async function controlAgentTeamBackgroundAgentRun(
|
|
2179
|
+
input: BackgroundAgentControlInput,
|
|
2180
|
+
): Promise<BackgroundAgentControlResult> {
|
|
2181
|
+
if (input.command !== "stop") {
|
|
2182
|
+
return {
|
|
2183
|
+
ok: false,
|
|
2184
|
+
runId: input.runId,
|
|
2185
|
+
run: await getAgentTeamBackgroundRun(input.runId),
|
|
2186
|
+
error:
|
|
2187
|
+
"Agent Teams background runs currently support stop through the shared controller.",
|
|
2188
|
+
};
|
|
2189
|
+
}
|
|
2190
|
+
|
|
2191
|
+
const result = await stopAgentTeamBackgroundRun(input.runId);
|
|
2192
|
+
return {
|
|
2193
|
+
ok: result.ok,
|
|
2194
|
+
runId: input.runId,
|
|
2195
|
+
run: await getAgentTeamBackgroundRun(input.runId),
|
|
2196
|
+
message: result.ok ? "Agent Teams background run stopped." : undefined,
|
|
2197
|
+
error: result.error,
|
|
2198
|
+
};
|
|
2199
|
+
}
|
|
2200
|
+
|
|
2201
|
+
export async function stopAgentTeamBackgroundRun(
|
|
2202
|
+
runId: string,
|
|
2203
|
+
reason = "user",
|
|
2204
|
+
): Promise<ControlAgentTeamBackgroundRunResult> {
|
|
2205
|
+
const taskId = taskIdFromBackgroundRunId(runId);
|
|
2206
|
+
const task = await loadTask(taskId);
|
|
2207
|
+
if (!task) return { ok: false, error: "Task not found" };
|
|
2208
|
+
if (task.status !== "running") {
|
|
2209
|
+
return { ok: false, error: "Task is not running" };
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2212
|
+
abortRun(await durableActiveTaskRunId(taskId), reason);
|
|
2213
|
+
task.status = "errored";
|
|
2214
|
+
task.summary =
|
|
2215
|
+
reason === "user" ? "Task stopped." : `Task stopped: ${reason}`;
|
|
2216
|
+
task.error = task.summary;
|
|
2217
|
+
task.currentStep = "";
|
|
2218
|
+
task.completedAt = Date.now();
|
|
2219
|
+
await saveTask(task);
|
|
2220
|
+
const ownerEmail = getRequestUserEmail();
|
|
2221
|
+
if (ownerEmail) {
|
|
2222
|
+
await completeTaskProgressRun(task, ownerEmail, "cancelled", task.summary);
|
|
2223
|
+
}
|
|
2224
|
+
await completeAgentTeamRun(task.taskId, "failed");
|
|
2225
|
+
return { ok: true };
|
|
2226
|
+
}
|
|
2227
|
+
|
|
2228
|
+
/** Mark a task as errored */
|
|
2229
|
+
export async function markTaskErrored(
|
|
2230
|
+
taskId: string,
|
|
2231
|
+
error: string,
|
|
2232
|
+
): Promise<void> {
|
|
2233
|
+
const task = await loadTask(taskId);
|
|
2234
|
+
if (task) {
|
|
2235
|
+
task.status = "errored";
|
|
2236
|
+
task.summary = error;
|
|
2237
|
+
task.error = error;
|
|
2238
|
+
task.currentStep = "";
|
|
2239
|
+
task.completedAt = Date.now();
|
|
2240
|
+
await saveTask(task);
|
|
2241
|
+
const ownerEmail = getRequestUserEmail();
|
|
2242
|
+
if (ownerEmail) {
|
|
2243
|
+
await completeTaskProgressRun(task, ownerEmail, "failed", error);
|
|
2244
|
+
}
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
|
|
2248
|
+
export const _agentTeamsQueueForTests = {
|
|
2249
|
+
createMessageAwareActions,
|
|
2250
|
+
createTaskMessageFinalGuard,
|
|
2251
|
+
drainQueuedTaskMessages,
|
|
2252
|
+
formatQueuedTaskMessages,
|
|
2253
|
+
resolveTaskCompletion,
|
|
2254
|
+
evaluateSubagentDepth,
|
|
2255
|
+
runWithDelegationDepth,
|
|
2256
|
+
currentAmbientDelegationDepth,
|
|
2257
|
+
};
|