@agent-native/core 0.131.5 → 0.131.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +3 -3
- package/corpus/core/CHANGELOG.md +70 -0
- package/corpus/core/docs/content/agent-native-toolkit.mdx +13 -6
- package/corpus/core/docs/content/cloneable-saas.mdx +5 -5
- package/corpus/core/docs/content/creating-templates.mdx +9 -0
- package/corpus/core/docs/content/deployment.mdx +18 -12
- package/corpus/core/docs/content/doctor.mdx +8 -1
- package/corpus/core/docs/content/drop-in-agent.mdx +1 -1
- package/corpus/core/docs/content/extensions.mdx +18 -18
- package/corpus/core/docs/content/faq.mdx +4 -4
- package/corpus/core/docs/content/key-concepts.mdx +30 -21
- package/corpus/core/docs/content/security.mdx +2 -2
- package/corpus/core/docs/content/template-brain-developers.mdx +4 -1
- package/corpus/core/docs/content/template-mail-developers.mdx +4 -1
- package/corpus/core/docs/content/what-is-agent-native.mdx +6 -6
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/client.ts +449 -66
- package/corpus/core/src/a2a/correlation.ts +31 -0
- package/corpus/core/src/a2a/invoke.ts +4 -2
- package/corpus/core/src/a2a/types.ts +4 -0
- package/corpus/core/src/action.ts +3 -0
- package/corpus/core/src/agent/action-continuation-guidance.ts +2 -1
- package/corpus/core/src/agent/engine/registry.ts +98 -6
- package/corpus/core/src/agent/production-agent.ts +151 -18
- package/corpus/core/src/agent/run-loop-with-resume.ts +190 -3
- package/corpus/core/src/agent/run-manager.ts +117 -41
- package/corpus/core/src/agent/thread-debug-history.ts +86 -0
- package/corpus/core/src/agent/types.ts +3 -1
- package/corpus/core/src/cli/create.ts +11 -1
- package/corpus/core/src/cli/templates-meta.ts +2 -2
- package/corpus/core/src/client/agent-chat-adapter.ts +91 -13
- package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +11 -9
- package/corpus/core/src/client/sse-event-processor.ts +17 -3
- package/corpus/core/src/db/client.ts +57 -17
- package/corpus/core/src/guards/no-env-credentials.ts +2 -0
- package/corpus/core/src/integrations/adapters/slack.ts +8 -3
- package/corpus/core/src/localization/default-messages.ts +44 -0
- package/corpus/core/src/observability/traces.ts +78 -5
- package/corpus/core/src/scripts/call-agent.ts +294 -11
- package/corpus/core/src/scripts/describe-workspace-apps.ts +2 -2
- package/corpus/core/src/secrets/crypto.ts +156 -35
- package/corpus/core/src/secrets/storage.ts +64 -26
- package/corpus/core/src/server/agent-capabilities.ts +1 -1
- package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +113 -7
- package/corpus/core/src/server/agent-chat/context-tools.ts +2 -0
- package/corpus/core/src/server/agent-chat/plugin-options.ts +34 -1
- package/corpus/core/src/server/agent-chat/prompt-resources.ts +1 -1
- package/corpus/core/src/server/agent-chat-plugin.ts +91 -59
- package/corpus/core/src/templates/default/.agents/skills/secrets/SKILL.md +19 -7
- package/corpus/core/src/templates/headless/.agents/skills/secrets/SKILL.md +19 -7
- package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +18 -7
- package/corpus/core/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +15 -14
- package/corpus/core/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +19 -7
- package/corpus/core/src/vite/client.ts +1 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-ops/SKILL.md +5 -4
- package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +6 -4
- package/corpus/templates/analytics/AGENTS.md +7 -4
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +4 -3
- package/corpus/templates/analytics/changelog/2026-07-30-delegated-analytics-questions-now-return-a-useful-current-me.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-30-scheduled-dashboard-emails-complete-every-panel-without-pool.md +6 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +28 -1
- package/corpus/templates/analytics/server/jobs/dashboard-report.ts +18 -11
- package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +4 -4
- package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +9 -5
- package/corpus/templates/analytics/server/lib/dashboard-panel-query.ts +6 -2
- package/corpus/templates/analytics/server/lib/dashboard-panel-source-resolver.ts +11 -4
- package/corpus/templates/analytics/server/lib/dashboard-report-render.ts +49 -31
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +16 -8
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +9 -3
- package/corpus/templates/analytics/server/lib/production-serverless-runtime.ts +11 -0
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +10 -0
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +3 -2
- package/corpus/templates/analytics/server/plugins/analytics-alert-jobs.ts +2 -1
- package/corpus/templates/analytics/server/plugins/dashboard-report-jobs.ts +2 -1
- package/corpus/templates/analytics/server/plugins/uptime-monitor-jobs.ts +1 -12
- package/corpus/templates/brain/.agents/skills/brain/RUNBOOK.md +54 -6
- package/corpus/templates/brain/.agents/skills/brain/SKILL.md +20 -9
- package/corpus/templates/brain/.agents/skills/ingestion-and-connectors/SKILL.md +33 -1
- package/corpus/templates/brain/AGENTS.md +3 -1
- package/corpus/templates/brain/README.md +4 -1
- package/corpus/templates/brain/actions/_schemas.ts +30 -8
- package/corpus/templates/brain/actions/ask-brain.ts +124 -14
- package/corpus/templates/brain/actions/create-source.ts +18 -2
- package/corpus/templates/brain/actions/enqueue-captures-distillation.ts +8 -123
- package/corpus/templates/brain/actions/enqueue-distillation.ts +6 -127
- package/corpus/templates/brain/actions/import-capture.ts +17 -5
- package/corpus/templates/brain/actions/import-transcript.ts +17 -5
- package/corpus/templates/brain/actions/update-source.ts +25 -5
- package/corpus/templates/brain/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/brain/changelog/2026-07-30-blessed-resources-can-feed-cited-company-answers.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-30-the-left-sidebar-no-longer-shows-a-blank-organization-placeh.md +6 -0
- package/corpus/templates/brain/server/lib/brain.ts +49 -19
- package/corpus/templates/brain/server/lib/distillation-queue.ts +147 -0
- package/corpus/templates/brain/server/lib/source-policy.ts +264 -0
- package/corpus/templates/brain/server/plugins/agent-chat.ts +3 -2
- package/corpus/templates/brain/server/routes/api/_agent-native/brain/ingest.post.ts +116 -19
- package/corpus/templates/clips/app/components/meetings/google-oauth-identity-notice.tsx +51 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +4 -0
- package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +3 -1
- package/corpus/templates/clips/changelog/2026-07-30-google-calendar-warning.md +6 -0
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +72 -8
- package/corpus/templates/content/changelog/2026-07-30-the-slash-command-hint-now-stays-on-only-the-active-empty-li.md +6 -0
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +506 -11
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +148 -17
- package/corpus/templates/design/app/components/design/canvas-interactions/design-canvas-interactions.ts +357 -0
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +7 -466
- package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +15 -311
- package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +19 -997
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +8 -1216
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +31 -38
- package/corpus/templates/design/package.json +0 -1
- package/corpus/templates/dispatch/AGENTS.md +8 -0
- package/corpus/templates/dispatch/DEVELOPING.md +29 -0
- package/corpus/templates/dispatch/actions/view-screen.ts +34 -2
- package/corpus/templates/dispatch/app/i18n-data.ts +457 -0
- package/corpus/templates/dispatch/changelog/2026-07-30-delegated-dispatch-work-continues-reliably-in-the-background.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-30-find-failed-runs-across-apps.md +6 -0
- package/corpus/templates/dispatch/netlify.toml +3 -0
- package/corpus/templates/plan/actions/get-visual-plan.ts +10 -6
- package/corpus/templates/plan/actions/patch-visual-plan-source.ts +117 -1
- package/corpus/templates/plan/actions/update-visual-plan.ts +56 -14
- package/corpus/templates/plan/app/pages/PlansPage.tsx +1 -1
- package/corpus/templates/plan/changelog/2026-07-30-plan-agents-recover-with-targeted-writes.md +6 -0
- package/corpus/templates/plan/shared/plan-content.ts +35 -0
- package/corpus/templates/slides/.agents/skills/analytics-data-for-decks/SKILL.md +8 -12
- package/corpus/templates/slides/AGENTS.md +4 -4
- package/corpus/templates/slides/actions/create-deck.ts +1 -1
- package/corpus/templates/slides/actions/duplicate-deck.ts +19 -4
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +2 -10
- package/corpus/templates/slides/app/components/deck/MermaidRenderer.tsx +12 -1
- package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +30 -13
- package/corpus/templates/slides/app/components/editor/DeckEditorSkeleton.tsx +35 -0
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +63 -56
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +21 -76
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +1110 -292
- package/corpus/templates/slides/app/components/editor/SlideOverflowWarning.tsx +53 -0
- package/corpus/templates/slides/app/components/editor/SlideStyleInspector.tsx +235 -18
- package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +4 -1
- package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +11 -0
- package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +129 -0
- package/corpus/templates/slides/app/components/editor/selection-overlay-measurement.ts +70 -0
- package/corpus/templates/slides/app/components/editor/slide-object-interactions.ts +519 -65
- package/corpus/templates/slides/app/components/visual-editor/CanvasCommentPins.tsx +36 -426
- package/corpus/templates/slides/app/components/visual-editor/DrawOverlay.tsx +19 -458
- package/corpus/templates/slides/app/context/DeckContext.tsx +179 -72
- package/corpus/templates/slides/app/global.css +105 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +8 -0
- package/corpus/templates/slides/app/lib/deck-editor-loading.ts +26 -0
- package/corpus/templates/slides/app/lib/mermaid-blocks.ts +27 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +71 -38
- package/corpus/templates/slides/app/pages/Index.tsx +98 -41
- package/corpus/templates/slides/changelog/2026-07-30-deck-loading-no-longer-flashes-an-unavailable-message.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-30-duplicating-a-deck-from-the-deck-list-now-opens-the-copy-imm.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-30-layout-overflow-warning-is-readable-and-dismissible.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-30-new-decks-now-start-with-an-empty-slide-list-when-no-slides-.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-30-shared-canvas-annotations.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-30-slide-objects-can-be-moved-as-a-group-copied-and-pasted-with.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-30-slide-text-editing-and-object-controls-now-match-google-slides.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-30-style-panel-now-scrolls-with-speaker-notes-open-shows-the-sl.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-30-top-toolbar-controls-now-use-consistent-sizing-with-undo-and.md +6 -0
- package/corpus/templates/slides/netlify.toml +3 -1
- package/corpus/templates/slides/package.json +0 -1
- package/corpus/templates/slides/server/lib/chat-attachments.ts +18 -0
- package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -0
- package/corpus/templates/slides/vite.config.ts +0 -1
- package/corpus/toolkit/CHANGELOG.md +13 -0
- package/corpus/toolkit/README.md +19 -0
- package/corpus/toolkit/agent-native.eject.json +38 -0
- package/corpus/toolkit/package.json +29 -1
- package/corpus/toolkit/src/canvas-annotations/CanvasCommentPins.tsx +861 -0
- package/corpus/toolkit/src/canvas-annotations/DrawOverlay.tsx +1233 -0
- package/corpus/toolkit/src/canvas-annotations/index.ts +15 -0
- package/corpus/toolkit/src/canvas-annotations/types.ts +14 -0
- package/corpus/toolkit/src/canvas-interactions/canvas-interactions.ts +933 -0
- package/corpus/toolkit/src/canvas-interactions/index.ts +67 -0
- package/corpus/toolkit/src/design-tweaks/scrub-input-utils.ts +311 -0
- package/corpus/toolkit/src/design-tweaks/scrub-input.tsx +491 -0
- package/corpus/toolkit/src/design-tweaks/visual-style-controls.tsx +26 -171
- package/corpus/toolkit/src/index.ts +1 -0
- package/dist/a2a/client.d.ts +23 -0
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +309 -44
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/correlation.d.ts +1 -0
- package/dist/a2a/correlation.d.ts.map +1 -1
- package/dist/a2a/correlation.js +27 -0
- package/dist/a2a/correlation.js.map +1 -1
- package/dist/a2a/invoke.d.ts.map +1 -1
- package/dist/a2a/invoke.js +4 -2
- package/dist/a2a/invoke.js.map +1 -1
- package/dist/a2a/types.d.ts +4 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/action.d.ts +3 -0
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js.map +1 -1
- package/dist/agent/action-continuation-guidance.d.ts.map +1 -1
- package/dist/agent/action-continuation-guidance.js +2 -1
- package/dist/agent/action-continuation-guidance.js.map +1 -1
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +82 -8
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/production-agent.d.ts +40 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +113 -15
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-loop-with-resume.d.ts +21 -0
- package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
- package/dist/agent/run-loop-with-resume.js +163 -4
- package/dist/agent/run-loop-with-resume.js.map +1 -1
- package/dist/agent/run-manager.d.ts +16 -9
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +93 -42
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/thread-debug-history.d.ts +10 -0
- package/dist/agent/thread-debug-history.d.ts.map +1 -0
- package/dist/agent/thread-debug-history.js +68 -0
- package/dist/agent/thread-debug-history.js.map +1 -0
- package/dist/agent/types.d.ts +3 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +6 -1
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/templates-meta.js +2 -2
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +76 -13
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.js +1 -1
- package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +12 -3
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +48 -17
- package/dist/db/client.js.map +1 -1
- package/dist/guards/no-env-credentials.d.ts.map +1 -1
- package/dist/guards/no-env-credentials.js +2 -0
- package/dist/guards/no-env-credentials.js.map +1 -1
- package/dist/integrations/adapters/slack.js +7 -3
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/localization/default-messages.d.ts +43 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +43 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/observability/traces.d.ts +3 -1
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +73 -4
- package/dist/observability/traces.js.map +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +12 -12
- package/dist/provider-api/actions/provider-api.d.ts +13 -13
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +237 -12
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/scripts/describe-workspace-apps.js +2 -2
- package/dist/scripts/describe-workspace-apps.js.map +1 -1
- package/dist/secrets/crypto.d.ts +36 -21
- package/dist/secrets/crypto.d.ts.map +1 -1
- package/dist/secrets/crypto.js +134 -33
- package/dist/secrets/crypto.js.map +1 -1
- package/dist/secrets/storage.d.ts +6 -6
- package/dist/secrets/storage.d.ts.map +1 -1
- package/dist/secrets/storage.js +43 -26
- package/dist/secrets/storage.js.map +1 -1
- package/dist/server/agent-capabilities.js +1 -1
- package/dist/server/agent-capabilities.js.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.d.ts +17 -3
- package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +94 -3
- package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
- package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
- package/dist/server/agent-chat/context-tools.js +2 -0
- package/dist/server/agent-chat/context-tools.js.map +1 -1
- package/dist/server/agent-chat/plugin-options.d.ts +23 -0
- package/dist/server/agent-chat/plugin-options.d.ts.map +1 -1
- package/dist/server/agent-chat/plugin-options.js +4 -1
- package/dist/server/agent-chat/plugin-options.js.map +1 -1
- package/dist/server/agent-chat/prompt-resources.js +1 -1
- package/dist/server/agent-chat/prompt-resources.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +2 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +79 -56
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/templates/default/.agents/skills/secrets/SKILL.md +19 -7
- package/dist/templates/headless/.agents/skills/secrets/SKILL.md +19 -7
- package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +18 -7
- package/dist/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +15 -14
- package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +19 -7
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +1 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/agent-native-toolkit.mdx +13 -6
- package/docs/content/cloneable-saas.mdx +5 -5
- package/docs/content/creating-templates.mdx +9 -0
- package/docs/content/deployment.mdx +18 -12
- package/docs/content/doctor.mdx +8 -1
- package/docs/content/drop-in-agent.mdx +1 -1
- package/docs/content/extensions.mdx +18 -18
- package/docs/content/faq.mdx +4 -4
- package/docs/content/key-concepts.mdx +30 -21
- package/docs/content/security.mdx +2 -2
- package/docs/content/template-brain-developers.mdx +4 -1
- package/docs/content/template-mail-developers.mdx +4 -1
- package/docs/content/what-is-agent-native.mdx +6 -6
- package/package.json +3 -3
- package/src/a2a/client.ts +449 -66
- package/src/a2a/correlation.ts +31 -0
- package/src/a2a/invoke.ts +4 -2
- package/src/a2a/types.ts +4 -0
- package/src/action.ts +3 -0
- package/src/agent/action-continuation-guidance.ts +2 -1
- package/src/agent/engine/registry.ts +98 -6
- package/src/agent/production-agent.ts +151 -18
- package/src/agent/run-loop-with-resume.ts +190 -3
- package/src/agent/run-manager.ts +117 -41
- package/src/agent/thread-debug-history.ts +86 -0
- package/src/agent/types.ts +3 -1
- package/src/cli/create.ts +11 -1
- package/src/cli/templates-meta.ts +2 -2
- package/src/client/agent-chat-adapter.ts +91 -13
- package/src/client/resources/McpIntegrationDialog.tsx +11 -9
- package/src/client/sse-event-processor.ts +17 -3
- package/src/db/client.ts +57 -17
- package/src/guards/no-env-credentials.ts +2 -0
- package/src/integrations/adapters/slack.ts +8 -3
- package/src/localization/default-messages.ts +44 -0
- package/src/observability/traces.ts +78 -5
- package/src/scripts/call-agent.ts +294 -11
- package/src/scripts/describe-workspace-apps.ts +2 -2
- package/src/secrets/crypto.ts +156 -35
- package/src/secrets/storage.ts +64 -26
- package/src/server/agent-capabilities.ts +1 -1
- package/src/server/agent-chat/action-filters-a2a.ts +113 -7
- package/src/server/agent-chat/context-tools.ts +2 -0
- package/src/server/agent-chat/plugin-options.ts +34 -1
- package/src/server/agent-chat/prompt-resources.ts +1 -1
- package/src/server/agent-chat-plugin.ts +91 -59
- package/src/templates/default/.agents/skills/secrets/SKILL.md +19 -7
- package/src/templates/headless/.agents/skills/secrets/SKILL.md +19 -7
- package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +18 -7
- package/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +15 -14
- package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +19 -7
- package/src/vite/client.ts +1 -0
|
@@ -174,7 +174,8 @@ const BACKGROUND_FOLLOW_POLL_INTERVAL_MS = 1_000;
|
|
|
174
174
|
// UNCLAIMED_BACKGROUND_RUN_GRACE_MS (25s)
|
|
175
175
|
// + UNCLAIMED_BACKGROUND_RUN_FAST_SWEEP_MS (20s)
|
|
176
176
|
// = ~45-65s worst-case time-to-first-redispatch-attempt
|
|
177
|
-
// <
|
|
177
|
+
// < RUN_NO_PROGRESS_HARD_TIMEOUT_MS (150s, run-manager.ts)
|
|
178
|
+
// < BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS (210s, this constant)
|
|
178
179
|
// < UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS (300s, run-store.ts)
|
|
179
180
|
// On top of that margin, the follow loop below never counts a tick against
|
|
180
181
|
// this timeout at all while `/runs/active` reports `awaitingRedispatch:
|
|
@@ -184,7 +185,7 @@ const BACKGROUND_FOLLOW_POLL_INTERVAL_MS = 1_000;
|
|
|
184
185
|
// paper over a slow sweep; fix the sweep timing (run-store.ts /
|
|
185
186
|
// agent-chat-plugin.ts) instead, and keep this comment's inequality chain
|
|
186
187
|
// accurate if any of the four numbers change.
|
|
187
|
-
export const BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS =
|
|
188
|
+
export const BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS = 210_000;
|
|
188
189
|
|
|
189
190
|
// Per-TURN follow budgets. BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS above is a
|
|
190
191
|
// per-idle-WINDOW bound and resets every time a successor run appears, so a
|
|
@@ -1773,6 +1774,11 @@ export function createAgentChatAdapter(
|
|
|
1773
1774
|
let lastAutoContinueReason: string | null = null;
|
|
1774
1775
|
let lastRecoverableRunError: AgentAutoContinueErrorInfo | null = null;
|
|
1775
1776
|
let lastActivityTrail: AgentActivityTrailEntry[] = [];
|
|
1777
|
+
let backgroundFollowNoProgressDetaches = 0;
|
|
1778
|
+
let backgroundFollowConsecutiveNoProgressDetaches = 0;
|
|
1779
|
+
let backgroundFollowLastDetachReason: string | null = null;
|
|
1780
|
+
let backgroundFollowLastDetachWasClientWatchdog: boolean | null = null;
|
|
1781
|
+
let backgroundFollowLastServerProgressAt: number | null = null;
|
|
1776
1782
|
const attemptedRunIds: string[] = [];
|
|
1777
1783
|
let authRecoveryAttempted = false;
|
|
1778
1784
|
let continuationToolCallCounter = 0;
|
|
@@ -1828,6 +1834,21 @@ export function createAgentChatAdapter(
|
|
|
1828
1834
|
? `activity_trail: ${formatActivityTrail(lastActivityTrail)}`
|
|
1829
1835
|
: "",
|
|
1830
1836
|
`total_transient_continuations: ${totalTransientContinuationAttempts}`,
|
|
1837
|
+
`background_follow_no_progress_detaches: ${backgroundFollowNoProgressDetaches}`,
|
|
1838
|
+
`background_follow_consecutive_no_progress_detaches: ${backgroundFollowConsecutiveNoProgressDetaches}`,
|
|
1839
|
+
backgroundFollowLastDetachReason
|
|
1840
|
+
? `background_follow_last_detach_reason: ${backgroundFollowLastDetachReason}`
|
|
1841
|
+
: "",
|
|
1842
|
+
backgroundFollowLastDetachWasClientWatchdog !== null
|
|
1843
|
+
? `background_follow_last_detach_source: ${
|
|
1844
|
+
backgroundFollowLastDetachWasClientWatchdog
|
|
1845
|
+
? "client_watchdog"
|
|
1846
|
+
: "server"
|
|
1847
|
+
}`
|
|
1848
|
+
: "",
|
|
1849
|
+
backgroundFollowLastServerProgressAt !== null
|
|
1850
|
+
? `background_follow_last_server_progress_at: ${backgroundFollowLastServerProgressAt}`
|
|
1851
|
+
: "",
|
|
1831
1852
|
]
|
|
1832
1853
|
.filter(Boolean)
|
|
1833
1854
|
.join("\n");
|
|
@@ -2451,6 +2472,8 @@ export function createAgentChatAdapter(
|
|
|
2451
2472
|
> {
|
|
2452
2473
|
if (!runId) return "gone";
|
|
2453
2474
|
let attached = false;
|
|
2475
|
+
backgroundFollowLastDetachReason = null;
|
|
2476
|
+
backgroundFollowLastDetachWasClientWatchdog = null;
|
|
2454
2477
|
try {
|
|
2455
2478
|
const eventsRes = await fetch(
|
|
2456
2479
|
`${apiUrl}/runs/${encodeURIComponent(runId)}/events?after=${lastSeq + 1}`,
|
|
@@ -2488,6 +2511,9 @@ export function createAgentChatAdapter(
|
|
|
2488
2511
|
}
|
|
2489
2512
|
if (attachErr instanceof AgentAutoContinueSignal) {
|
|
2490
2513
|
lastAutoContinueReason = attachErr.reason;
|
|
2514
|
+
backgroundFollowLastDetachReason = attachErr.reason;
|
|
2515
|
+
backgroundFollowLastDetachWasClientWatchdog =
|
|
2516
|
+
attachErr.clientWatchdog;
|
|
2491
2517
|
if (attachErr.activityTrail.length > 0) {
|
|
2492
2518
|
lastActivityTrail = [...attachErr.activityTrail];
|
|
2493
2519
|
}
|
|
@@ -2641,6 +2667,9 @@ export function createAgentChatAdapter(
|
|
|
2641
2667
|
|
|
2642
2668
|
let idleSince: number | null = null;
|
|
2643
2669
|
let lastSeenActive: Record<string, unknown> | null = null;
|
|
2670
|
+
let lastObservedActiveRunId = runId;
|
|
2671
|
+
let lastObservedServerProgressAt: number | null = null;
|
|
2672
|
+
let noProgressPollAttempts = 0;
|
|
2644
2673
|
// Terminal runs already replayed once. A recoverable terminal error
|
|
2645
2674
|
// event replays as an auto-continue signal (isAutoRecoverableError),
|
|
2646
2675
|
// which used to re-drive a POST in foreground mode. In follow mode
|
|
@@ -2826,6 +2855,25 @@ export function createAgentChatAdapter(
|
|
|
2826
2855
|
});
|
|
2827
2856
|
return "completed";
|
|
2828
2857
|
}
|
|
2858
|
+
const activeProgressAt =
|
|
2859
|
+
typeof active?.lastProgressAt === "number" &&
|
|
2860
|
+
Number.isFinite(active.lastProgressAt)
|
|
2861
|
+
? active.lastProgressAt
|
|
2862
|
+
: null;
|
|
2863
|
+
const runChanged = activeRunId !== lastObservedActiveRunId;
|
|
2864
|
+
const serverProgressAdvanced =
|
|
2865
|
+
activeProgressAt !== null &&
|
|
2866
|
+
lastObservedServerProgressAt !== null &&
|
|
2867
|
+
activeProgressAt > lastObservedServerProgressAt;
|
|
2868
|
+
lastObservedActiveRunId = activeRunId;
|
|
2869
|
+
if (activeProgressAt !== null) {
|
|
2870
|
+
lastObservedServerProgressAt =
|
|
2871
|
+
lastObservedServerProgressAt === null || runChanged
|
|
2872
|
+
? activeProgressAt
|
|
2873
|
+
: Math.max(lastObservedServerProgressAt, activeProgressAt);
|
|
2874
|
+
backgroundFollowLastServerProgressAt =
|
|
2875
|
+
lastObservedServerProgressAt;
|
|
2876
|
+
}
|
|
2829
2877
|
// Server-authoritative "silently deferred, recovery in
|
|
2830
2878
|
// progress" signal (see `awaitingRedispatch` on
|
|
2831
2879
|
// `getActiveRunForThreadAsync`, run-manager.ts): a
|
|
@@ -2839,19 +2887,29 @@ export function createAgentChatAdapter(
|
|
|
2839
2887
|
// resumes, so a truly stuck deferral still fails loud via the
|
|
2840
2888
|
// existing timeout below.
|
|
2841
2889
|
const awaitingRedispatch = active?.awaitingRedispatch === true;
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
//
|
|
2845
|
-
//
|
|
2846
|
-
//
|
|
2890
|
+
const madeProgress = runChanged || serverProgressAdvanced;
|
|
2891
|
+
if (madeProgress || awaitingRedispatch) {
|
|
2892
|
+
// Only server-authoritative progress resets the idle window:
|
|
2893
|
+
// a successor run or a newer lastProgressAt timestamp. Raw
|
|
2894
|
+
// sequence advancement is not enough — keepalives and retry
|
|
2895
|
+
// `clear` events are sequenced too, but the run manager
|
|
2896
|
+
// deliberately excludes both from lastProgressAt because they
|
|
2897
|
+
// do not move the user's task forward.
|
|
2847
2898
|
idleSince = null;
|
|
2899
|
+
noProgressPollAttempts = 0;
|
|
2900
|
+
backgroundFollowConsecutiveNoProgressDetaches = 0;
|
|
2848
2901
|
} else {
|
|
2849
|
-
//
|
|
2850
|
-
//
|
|
2851
|
-
//
|
|
2852
|
-
//
|
|
2853
|
-
//
|
|
2902
|
+
// An absent stream and an attached stream with no newer
|
|
2903
|
+
// server-authoritative progress are the same no-progress
|
|
2904
|
+
// observation. Keep accumulating one idle window and back off
|
|
2905
|
+
// repeat attaches so a broken SQL tail cannot become a
|
|
2906
|
+
// reconnect storm.
|
|
2854
2907
|
if (idleSince === null) idleSince = Date.now();
|
|
2908
|
+
noProgressPollAttempts += 1;
|
|
2909
|
+
if (attach === "detached") {
|
|
2910
|
+
backgroundFollowNoProgressDetaches += 1;
|
|
2911
|
+
backgroundFollowConsecutiveNoProgressDetaches += 1;
|
|
2912
|
+
}
|
|
2855
2913
|
if (
|
|
2856
2914
|
Date.now() - idleSince >=
|
|
2857
2915
|
BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS
|
|
@@ -2889,7 +2947,27 @@ export function createAgentChatAdapter(
|
|
|
2889
2947
|
return "completed";
|
|
2890
2948
|
}
|
|
2891
2949
|
}
|
|
2892
|
-
|
|
2950
|
+
const backedOffPollDelayMs =
|
|
2951
|
+
noProgressPollAttempts > 0
|
|
2952
|
+
? Math.min(
|
|
2953
|
+
BACKGROUND_FOLLOW_POLL_INTERVAL_MS *
|
|
2954
|
+
2 ** Math.min(noProgressPollAttempts - 1, 3),
|
|
2955
|
+
5_000,
|
|
2956
|
+
)
|
|
2957
|
+
: BACKGROUND_FOLLOW_POLL_INTERVAL_MS;
|
|
2958
|
+
const idleRemainingMs =
|
|
2959
|
+
idleSince === null
|
|
2960
|
+
? Number.POSITIVE_INFINITY
|
|
2961
|
+
: Math.max(
|
|
2962
|
+
0,
|
|
2963
|
+
BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS -
|
|
2964
|
+
(Date.now() - idleSince),
|
|
2965
|
+
);
|
|
2966
|
+
const nextPollDelayMs = Math.min(
|
|
2967
|
+
backedOffPollDelayMs,
|
|
2968
|
+
idleRemainingMs,
|
|
2969
|
+
);
|
|
2970
|
+
await delay(nextPollDelayMs, abortSignal);
|
|
2893
2971
|
if (abortSignal.aborted) {
|
|
2894
2972
|
clearActiveRun();
|
|
2895
2973
|
return "completed";
|
|
@@ -762,14 +762,16 @@ export function McpIntegrationDialog({
|
|
|
762
762
|
</div>
|
|
763
763
|
</div>
|
|
764
764
|
<div className="flex shrink-0 items-center justify-between gap-2 border-t border-border px-7 py-4">
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
765
|
+
{!selectedRequiresSetup && (
|
|
766
|
+
<button
|
|
767
|
+
type="button"
|
|
768
|
+
onClick={runTest}
|
|
769
|
+
disabled={!url.trim() || busy}
|
|
770
|
+
className="rounded-md border border-border bg-background px-3 py-1.5 text-[12px] font-medium text-foreground hover:bg-accent disabled:pointer-events-none disabled:opacity-40"
|
|
771
|
+
>
|
|
772
|
+
{t("mcpIntegrations.test")}
|
|
773
|
+
</button>
|
|
774
|
+
)}
|
|
773
775
|
{!selected ? (
|
|
774
776
|
<button
|
|
775
777
|
type="button"
|
|
@@ -790,7 +792,7 @@ export function McpIntegrationDialog({
|
|
|
790
792
|
href={selected.docsUrl}
|
|
791
793
|
target="_blank"
|
|
792
794
|
rel="noopener noreferrer"
|
|
793
|
-
className="inline-flex min-w-[92px] items-center justify-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-[12px] font-medium text-primary-foreground hover:bg-primary/90"
|
|
795
|
+
className="ms-auto inline-flex min-w-[92px] items-center justify-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-[12px] font-medium text-primary-foreground hover:bg-primary/90"
|
|
794
796
|
>
|
|
795
797
|
{t("mcpIntegrations.viewSetup")}
|
|
796
798
|
<IconExternalLink className="h-3 w-3" />
|
|
@@ -233,7 +233,12 @@ export function sseInFlightWorkDelta(ev: SSEEvent): number {
|
|
|
233
233
|
if (ev.type === "tool_done") return -1;
|
|
234
234
|
if (ev.type === "agent_call") {
|
|
235
235
|
if (ev.status === "start") return 1;
|
|
236
|
-
if (
|
|
236
|
+
if (
|
|
237
|
+
ev.status === "done" ||
|
|
238
|
+
ev.status === "pending" ||
|
|
239
|
+
ev.status === "error"
|
|
240
|
+
)
|
|
241
|
+
return -1;
|
|
237
242
|
}
|
|
238
243
|
return 0;
|
|
239
244
|
}
|
|
@@ -1455,7 +1460,11 @@ export function processEvent(
|
|
|
1455
1460
|
args: {},
|
|
1456
1461
|
activity: true,
|
|
1457
1462
|
});
|
|
1458
|
-
} else if (
|
|
1463
|
+
} else if (
|
|
1464
|
+
ev.status === "done" ||
|
|
1465
|
+
ev.status === "pending" ||
|
|
1466
|
+
ev.status === "error"
|
|
1467
|
+
) {
|
|
1459
1468
|
for (let i = content.length - 1; i >= 0; i--) {
|
|
1460
1469
|
const part = content[i];
|
|
1461
1470
|
if (
|
|
@@ -1464,7 +1473,12 @@ export function processEvent(
|
|
|
1464
1473
|
(!ev.agentCallId || part.toolCallId === ev.agentCallId) &&
|
|
1465
1474
|
part.result === undefined
|
|
1466
1475
|
) {
|
|
1467
|
-
part.result =
|
|
1476
|
+
part.result =
|
|
1477
|
+
ev.status === "error"
|
|
1478
|
+
? "Error calling agent"
|
|
1479
|
+
: ev.status === "pending"
|
|
1480
|
+
? "Remote agent task is still pending"
|
|
1481
|
+
: "Done";
|
|
1468
1482
|
part.structuredMeta = {
|
|
1469
1483
|
...part.structuredMeta,
|
|
1470
1484
|
...(ev.durationMs != null
|
|
@@ -652,6 +652,7 @@ function sqlAndArgs(sql: DbExecStatement): {
|
|
|
652
652
|
}
|
|
653
653
|
|
|
654
654
|
const POSTGRES_STATEMENT_TIMEOUT_HEADROOM_MS = 250;
|
|
655
|
+
const POSTGRES_STATEMENT_TIMEOUT_RESET_MS = 5_000;
|
|
655
656
|
const POSTGRES_MAX_INT = 2_147_483_647;
|
|
656
657
|
|
|
657
658
|
function hasExplicitDbTimeout(statement: DbExecStatement): boolean {
|
|
@@ -1225,22 +1226,15 @@ async function createDbExecInternal(
|
|
|
1225
1226
|
// with CONNECT_TIMEOUT. The serverless Pool handles wake-up transparently
|
|
1226
1227
|
// and keeps the same `pg`-compatible query(...) interface we need here.
|
|
1227
1228
|
if (isNeonUrl(url)) {
|
|
1228
|
-
const { Pool,
|
|
1229
|
-
//
|
|
1230
|
-
//
|
|
1231
|
-
//
|
|
1232
|
-
// queries after the first burst stall on connect()/query() — observed: the
|
|
1233
|
-
// analytics worker stalls right after model resolution and never claims.
|
|
1234
|
-
// HTTP-per-query (poolQueryViaFetch) has no persistent socket to die; the
|
|
1235
|
-
// foreground keeps the WebSocket pool. See the bg-fn execute branch below.
|
|
1229
|
+
const { Pool, neon } = await import("@neondatabase/serverless");
|
|
1230
|
+
// A frozen/thawed background function can retain half-dead WebSocket
|
|
1231
|
+
// connections, so its direct executions use stateless Neon HTTP instead.
|
|
1232
|
+
// The foreground and transaction surface keep the WebSocket pool.
|
|
1236
1233
|
const bgHttp = isBackgroundFunctionPoolContext();
|
|
1237
|
-
if (bgHttp) {
|
|
1238
|
-
(neonConfig as { poolQueryViaFetch?: boolean }).poolQueryViaFetch =
|
|
1239
|
-
true;
|
|
1240
|
-
}
|
|
1241
1234
|
const pool = new Pool({ connectionString: url, max: neonPoolMax() });
|
|
1242
1235
|
attachNeonPoolErrorLogger(pool);
|
|
1243
1236
|
if (trackSingletonResources) _neonPool = pool;
|
|
1237
|
+
const httpSql = bgHttp ? neon(url, { fullResults: true }) : null;
|
|
1244
1238
|
async function queryNeonClient(
|
|
1245
1239
|
client: any,
|
|
1246
1240
|
sql: Parameters<DbExec["execute"]>[0],
|
|
@@ -1282,7 +1276,7 @@ async function createDbExecInternal(
|
|
|
1282
1276
|
await queryNeonClient(
|
|
1283
1277
|
client,
|
|
1284
1278
|
"RESET statement_timeout",
|
|
1285
|
-
remainingMs(),
|
|
1279
|
+
Math.max(remainingMs(), POSTGRES_STATEMENT_TIMEOUT_RESET_MS),
|
|
1286
1280
|
);
|
|
1287
1281
|
} catch (err) {
|
|
1288
1282
|
markClientForDiscard();
|
|
@@ -1293,17 +1287,63 @@ async function createDbExecInternal(
|
|
|
1293
1287
|
}
|
|
1294
1288
|
}
|
|
1295
1289
|
}
|
|
1290
|
+
async function queryNeonHttp(sql: Parameters<DbExec["execute"]>[0]) {
|
|
1291
|
+
if (!httpSql) {
|
|
1292
|
+
throw new Error("Neon HTTP query used outside a background function");
|
|
1293
|
+
}
|
|
1294
|
+
const { rawSql, args } = sqlAndArgs(sql);
|
|
1295
|
+
const { timeoutMs } = dbExecQueryBudget(sql);
|
|
1296
|
+
const pgSql = sqliteToPostgresParams(rawSql);
|
|
1297
|
+
const controller = new AbortController();
|
|
1298
|
+
const run = async () => {
|
|
1299
|
+
if (!hasExplicitDbTimeout(sql)) {
|
|
1300
|
+
return httpSql.query(pgSql, args as any[], {
|
|
1301
|
+
fetchOptions: { signal: controller.signal },
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
const statementDeadlineMs =
|
|
1305
|
+
Date.now() + postgresStatementTimeoutMs(timeoutMs);
|
|
1306
|
+
const results = await httpSql.transaction(
|
|
1307
|
+
[
|
|
1308
|
+
httpSql.query(
|
|
1309
|
+
`SELECT set_config(
|
|
1310
|
+
'statement_timeout',
|
|
1311
|
+
GREATEST(
|
|
1312
|
+
1,
|
|
1313
|
+
$1::bigint -
|
|
1314
|
+
FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000)::bigint
|
|
1315
|
+
)::text,
|
|
1316
|
+
true
|
|
1317
|
+
)`,
|
|
1318
|
+
[statementDeadlineMs],
|
|
1319
|
+
),
|
|
1320
|
+
httpSql.query(pgSql, args as any[]),
|
|
1321
|
+
],
|
|
1322
|
+
{ fetchOptions: { signal: controller.signal } },
|
|
1323
|
+
);
|
|
1324
|
+
return results[1];
|
|
1325
|
+
};
|
|
1326
|
+
const result = await withDbTimeout("query", run, timeoutMs, () =>
|
|
1327
|
+
controller.abort(),
|
|
1328
|
+
);
|
|
1329
|
+
return {
|
|
1330
|
+
rows: result.rows,
|
|
1331
|
+
rowsAffected: result.rowCount ?? 0,
|
|
1332
|
+
};
|
|
1333
|
+
}
|
|
1296
1334
|
return {
|
|
1297
1335
|
async execute(sql) {
|
|
1298
1336
|
const { timeoutMs, maxAttempts } = dbExecQueryBudget(sql);
|
|
1299
1337
|
if (bgHttp) {
|
|
1300
|
-
// HTTP-per-query path
|
|
1301
|
-
//
|
|
1302
|
-
//
|
|
1338
|
+
// HTTP-per-query path: no pool.connect() and no persistent socket
|
|
1339
|
+
// to survive a background-function freeze. Explicitly budgeted
|
|
1340
|
+
// statements run with SET LOCAL inside the same HTTP transaction,
|
|
1341
|
+
// so the server cancels the SQL before the fetch deadline without
|
|
1342
|
+
// leaking session state into Neon's pooled backends.
|
|
1303
1343
|
return retryOnConnectionError<{
|
|
1304
1344
|
rows: unknown[];
|
|
1305
1345
|
rowsAffected: number;
|
|
1306
|
-
}>(() =>
|
|
1346
|
+
}>(() => queryNeonHttp(sql), maxAttempts);
|
|
1307
1347
|
}
|
|
1308
1348
|
const result = await retryOnConnectionError<{
|
|
1309
1349
|
rows: unknown[];
|
|
@@ -2067,7 +2067,9 @@ function createSlackRunProgress(
|
|
|
2067
2067
|
? "in_progress"
|
|
2068
2068
|
: event.status === "done"
|
|
2069
2069
|
? "complete"
|
|
2070
|
-
: "
|
|
2070
|
+
: event.status === "pending"
|
|
2071
|
+
? "in_progress"
|
|
2072
|
+
: "error";
|
|
2071
2073
|
const title = delegatedTaskTitle(event.agent);
|
|
2072
2074
|
tasks.set(id, { title, status });
|
|
2073
2075
|
await append({
|
|
@@ -2075,9 +2077,12 @@ function createSlackRunProgress(
|
|
|
2075
2077
|
id,
|
|
2076
2078
|
title,
|
|
2077
2079
|
status,
|
|
2078
|
-
...(event.status === "start"
|
|
2080
|
+
...(event.status === "start" || event.status === "pending"
|
|
2079
2081
|
? {
|
|
2080
|
-
details:
|
|
2082
|
+
details:
|
|
2083
|
+
event.status === "pending"
|
|
2084
|
+
? `${shortTaskTitle(event.agent)} is still working and will need another status check.`
|
|
2085
|
+
: `I’m contacting ${shortTaskTitle(event.agent)} for an answer.`,
|
|
2081
2086
|
}
|
|
2082
2087
|
: {}),
|
|
2083
2088
|
});
|
|
@@ -316,6 +316,50 @@ const messages = {
|
|
|
316
316
|
unknownPlatform: "unknown",
|
|
317
317
|
attemptsCount: "{{count}} attempts",
|
|
318
318
|
noErrorMessage: "(no error message)",
|
|
319
|
+
threadDebugInspectFailure: "Inspect failed run",
|
|
320
|
+
threadDebugFailureCode: "Failure code",
|
|
321
|
+
threadDebugTerminalReason: "Terminal reason",
|
|
322
|
+
threadDebugDispatchMode: "Dispatch mode",
|
|
323
|
+
threadDebugLastStage: "Last stage",
|
|
324
|
+
threadDebugDuration: "Duration",
|
|
325
|
+
threadDebugLastProgress: "Last progress",
|
|
326
|
+
threadDebugTitle: "Thread Debug",
|
|
327
|
+
threadDebugDescription:
|
|
328
|
+
"Inspect failed agent runs, persisted threads, run events, and AI internals.",
|
|
329
|
+
threadDebugFailedRuns: "Failed runs",
|
|
330
|
+
threadDebugThreads: "Threads",
|
|
331
|
+
threadDebugSource: "Source",
|
|
332
|
+
threadDebugAllSources: "All sources",
|
|
333
|
+
threadDebugOwner: "Owner email",
|
|
334
|
+
threadDebugStatus: "Status",
|
|
335
|
+
threadDebugAllStatuses: "All statuses",
|
|
336
|
+
threadDebugErrored: "Errored",
|
|
337
|
+
threadDebugAborted: "Aborted",
|
|
338
|
+
threadDebugTruncated: "Truncated",
|
|
339
|
+
threadDebugRange: "Time range",
|
|
340
|
+
threadDebugRange24h: "Last 24 hours",
|
|
341
|
+
threadDebugRange7d: "Last 7 days",
|
|
342
|
+
threadDebugRange30d: "Last 30 days",
|
|
343
|
+
threadDebugFailureResults: "failed runs",
|
|
344
|
+
threadDebugCurrentScope: "current scope",
|
|
345
|
+
threadDebugPartialResults: "Partial results",
|
|
346
|
+
threadDebugUnavailableSources: "Unavailable sources:",
|
|
347
|
+
threadDebugDisconnected: "disconnected",
|
|
348
|
+
threadDebugUnsupported: "unsupported",
|
|
349
|
+
threadDebugUnavailable: "unavailable",
|
|
350
|
+
threadDebugRefreshFailures: "Refresh failed runs",
|
|
351
|
+
threadDebugNoFailures: "No failed runs found.",
|
|
352
|
+
threadDebugCurrentDatabase: "Current Dispatch DB",
|
|
353
|
+
threadDebugSearchPlaceholder: "Search title, preview, messages, tools",
|
|
354
|
+
threadDebugSearch: "Search",
|
|
355
|
+
threadDebugLookupPlaceholder: "Paste thread or request/run ID",
|
|
356
|
+
threadDebugInspect: "Inspect",
|
|
357
|
+
threadDebugAdminScope: "admin scope",
|
|
358
|
+
threadDebugOwnScope: "own scope",
|
|
359
|
+
threadDebugResults: "results",
|
|
360
|
+
threadDebugRefreshThreads: "Refresh threads",
|
|
361
|
+
threadDebugNoThreads: "No threads found.",
|
|
362
|
+
threadDebugSelectPrompt: "Select a failed run or thread to inspect.",
|
|
319
363
|
browserChatUnavailableTitle: "Browser chat session unavailable",
|
|
320
364
|
browserChatUnavailableDescription:
|
|
321
365
|
"Reconnect from the Agent-Native browser extension.",
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
AgentLoopOutcome,
|
|
3
|
+
AgentLoopUsage,
|
|
4
|
+
} from "../agent/production-agent.js";
|
|
2
5
|
import type { AgentChatEvent, AgentToolInput } from "../agent/types.js";
|
|
3
6
|
import { type AgentSpan, endAgentSpan, startAgentSpan } from "./tracing.js";
|
|
4
7
|
import { trackingIdentityProperties } from "./tracking-identity.js";
|
|
@@ -100,6 +103,7 @@ function emitLlmGenerationTrackingEvent(args: {
|
|
|
100
103
|
failedTools: number;
|
|
101
104
|
tools: GenerationToolCall[];
|
|
102
105
|
toolsTruncated: boolean;
|
|
106
|
+
terminalOutcome?: AgentLoopOutcome;
|
|
103
107
|
delegation?: {
|
|
104
108
|
protocol: "a2a" | "mcp";
|
|
105
109
|
callerApp?: string;
|
|
@@ -149,6 +153,16 @@ function emitLlmGenerationTrackingEvent(args: {
|
|
|
149
153
|
failed_tools: args.failedTools,
|
|
150
154
|
tools: args.tools,
|
|
151
155
|
tools_truncated: args.toolsTruncated,
|
|
156
|
+
terminal_state: args.terminalOutcome?.state,
|
|
157
|
+
terminal_code:
|
|
158
|
+
args.terminalOutcome?.state === "failed" ||
|
|
159
|
+
args.terminalOutcome?.state === "input_required"
|
|
160
|
+
? args.terminalOutcome.code
|
|
161
|
+
: undefined,
|
|
162
|
+
terminal_retryable:
|
|
163
|
+
args.terminalOutcome?.state === "failed"
|
|
164
|
+
? args.terminalOutcome.retryable
|
|
165
|
+
: undefined,
|
|
152
166
|
delegated: args.delegation ? true : undefined,
|
|
153
167
|
delegation_protocol: args.delegation?.protocol,
|
|
154
168
|
caller_app: args.delegation?.callerApp,
|
|
@@ -269,6 +283,7 @@ export async function instrumentAgentLoop(opts: {
|
|
|
269
283
|
send: (event: AgentChatEvent) => void;
|
|
270
284
|
signal: AbortSignal;
|
|
271
285
|
onUsage?: (usage: AgentLoopUsage) => void;
|
|
286
|
+
onOutcome?: (outcome: AgentLoopOutcome) => void;
|
|
272
287
|
providerOptions?: any;
|
|
273
288
|
runId?: string;
|
|
274
289
|
}) => Promise<AgentLoopUsage>;
|
|
@@ -282,6 +297,7 @@ export async function instrumentAgentLoop(opts: {
|
|
|
282
297
|
send: (event: AgentChatEvent) => void;
|
|
283
298
|
signal: AbortSignal;
|
|
284
299
|
onUsage?: (usage: AgentLoopUsage) => void;
|
|
300
|
+
onOutcome?: (outcome: AgentLoopOutcome) => void;
|
|
285
301
|
providerOptions?: any;
|
|
286
302
|
runId?: string;
|
|
287
303
|
};
|
|
@@ -381,9 +397,62 @@ export async function instrumentAgentLoop(opts: {
|
|
|
381
397
|
// Track in-flight OTel tool spans so they're all ended even if the loop
|
|
382
398
|
// throws before a matching `tool_done` arrives.
|
|
383
399
|
const openOtelToolSpans = new Set<AgentSpan>();
|
|
400
|
+
let usage: AgentLoopUsage | undefined;
|
|
401
|
+
let runStatus: "success" | "error" = "success";
|
|
402
|
+
let errorMessage: string | null = null;
|
|
403
|
+
let runMetadata: Record<string, unknown> | null = opts.metadata ?? null;
|
|
404
|
+
let terminalOutcome: AgentLoopOutcome | undefined;
|
|
405
|
+
|
|
406
|
+
const instrumentedOutcome = (outcome: AgentLoopOutcome): void => {
|
|
407
|
+
terminalOutcome = outcome;
|
|
408
|
+
if (outcome.state === "completed") {
|
|
409
|
+
runStatus = "success";
|
|
410
|
+
errorMessage = null;
|
|
411
|
+
} else {
|
|
412
|
+
runStatus = "error";
|
|
413
|
+
errorMessage =
|
|
414
|
+
outcome.state === "canceled"
|
|
415
|
+
? (outcome.message ?? "Agent run was canceled.")
|
|
416
|
+
: outcome.message;
|
|
417
|
+
}
|
|
418
|
+
runMetadata = {
|
|
419
|
+
...(runMetadata ?? {}),
|
|
420
|
+
terminal_state: outcome.state,
|
|
421
|
+
...("code" in outcome ? { terminal_code: outcome.code } : {}),
|
|
422
|
+
...(outcome.state === "failed"
|
|
423
|
+
? { terminal_retryable: outcome.retryable }
|
|
424
|
+
: {}),
|
|
425
|
+
};
|
|
426
|
+
try {
|
|
427
|
+
loopOpts.onOutcome?.(outcome);
|
|
428
|
+
} catch {
|
|
429
|
+
// Observability adapters cannot alter the agent run.
|
|
430
|
+
}
|
|
431
|
+
};
|
|
384
432
|
|
|
385
433
|
const instrumentedSend = (event: AgentChatEvent): void => {
|
|
386
434
|
try {
|
|
435
|
+
// Some guardrails intentionally stop the loop by emitting a terminal
|
|
436
|
+
// event and returning usage instead of throwing. Preserve that terminal
|
|
437
|
+
// state in telemetry so a tripwire/loop-limit/provider error cannot be
|
|
438
|
+
// counted as a successful delegated generation. A later clear/done means
|
|
439
|
+
// the wrapper recovered and finished cleanly, so reset in that case.
|
|
440
|
+
if (event.type === "clear" || event.type === "done") {
|
|
441
|
+
runStatus = "success";
|
|
442
|
+
errorMessage = null;
|
|
443
|
+
} else if (event.type === "error") {
|
|
444
|
+
runStatus = "error";
|
|
445
|
+
errorMessage = event.error;
|
|
446
|
+
} else if (event.type === "tripwire") {
|
|
447
|
+
runStatus = "error";
|
|
448
|
+
errorMessage = event.reason;
|
|
449
|
+
} else if (event.type === "loop_limit") {
|
|
450
|
+
runStatus = "error";
|
|
451
|
+
errorMessage = "Agent stopped at the loop limit";
|
|
452
|
+
} else if (event.type === "missing_api_key") {
|
|
453
|
+
runStatus = "error";
|
|
454
|
+
errorMessage = "Missing API key";
|
|
455
|
+
}
|
|
387
456
|
if (event.type === "tool_start") {
|
|
388
457
|
const counter = toolInvocationCounter++;
|
|
389
458
|
const sid = spanId();
|
|
@@ -554,15 +623,12 @@ export async function instrumentAgentLoop(opts: {
|
|
|
554
623
|
loopOpts.send(event);
|
|
555
624
|
};
|
|
556
625
|
|
|
557
|
-
let usage: AgentLoopUsage | undefined;
|
|
558
|
-
let runStatus: "success" | "error" = "success";
|
|
559
|
-
let errorMessage: string | null = null;
|
|
560
|
-
let runMetadata: Record<string, unknown> | null = opts.metadata ?? null;
|
|
561
626
|
try {
|
|
562
627
|
usage = await runAgentLoop({
|
|
563
628
|
...loopOpts,
|
|
564
629
|
runId,
|
|
565
630
|
send: instrumentedSend,
|
|
631
|
+
onOutcome: instrumentedOutcome,
|
|
566
632
|
});
|
|
567
633
|
} catch (err: any) {
|
|
568
634
|
const classification = opts.classifyError?.(err) ?? null;
|
|
@@ -727,6 +793,7 @@ export async function instrumentAgentLoop(opts: {
|
|
|
727
793
|
.map(([, detail]) => detail),
|
|
728
794
|
toolsTruncated:
|
|
729
795
|
toolInvocationCounter > MAX_TRACKED_GENERATION_TOOL_CALLS,
|
|
796
|
+
terminalOutcome,
|
|
730
797
|
delegation: opts.delegation,
|
|
731
798
|
createdAt: runStart,
|
|
732
799
|
experimentAssignments: opts.experimentAssignments,
|
|
@@ -811,6 +878,12 @@ export async function instrumentAgentLoop(opts: {
|
|
|
811
878
|
"agent.input_tokens": usage?.inputTokens ?? 0,
|
|
812
879
|
"agent.output_tokens": usage?.outputTokens ?? 0,
|
|
813
880
|
"agent.cost_cents_x100": costCentsX100,
|
|
881
|
+
"agent.terminal_state": terminalOutcome?.state,
|
|
882
|
+
"agent.terminal_code":
|
|
883
|
+
terminalOutcome?.state === "failed" ||
|
|
884
|
+
terminalOutcome?.state === "input_required"
|
|
885
|
+
? terminalOutcome.code
|
|
886
|
+
: undefined,
|
|
814
887
|
},
|
|
815
888
|
});
|
|
816
889
|
} catch {
|