@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
|
@@ -3,10 +3,12 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
3
3
|
import { parseA2AAgentActivityPart } from "../a2a/activity.js";
|
|
4
4
|
import {
|
|
5
5
|
A2ATaskTimeoutError,
|
|
6
|
+
MAX_A2A_CALLER_RESPONSE_CHARS,
|
|
6
7
|
callAgent,
|
|
7
8
|
shouldPreferGlobalA2ASecret,
|
|
8
9
|
signA2AToken,
|
|
9
10
|
} from "../a2a/client.js";
|
|
11
|
+
import { MAX_A2A_DELEGATION_HOPS } from "../a2a/correlation.js";
|
|
10
12
|
import { invokeAgentAction } from "../a2a/invoke.js";
|
|
11
13
|
import type {
|
|
12
14
|
A2AApprovedAction,
|
|
@@ -22,6 +24,7 @@ import {
|
|
|
22
24
|
import type { ActionRunContext } from "../agent/production-agent.js";
|
|
23
25
|
import type { ActionTool } from "../agent/types.js";
|
|
24
26
|
import { A2A_CONTINUATION_QUEUED_MARKER } from "../integrations/a2a-continuation-marker.js";
|
|
27
|
+
import { trackingIdentityProperties } from "../observability/tracking-identity.js";
|
|
25
28
|
import { getOrgDomain, getOrgA2ASecret } from "../org/context.js";
|
|
26
29
|
import { findAgent, discoverAgents } from "../server/agent-discovery.js";
|
|
27
30
|
import {
|
|
@@ -30,22 +33,106 @@ import {
|
|
|
30
33
|
isIntegrationCallerRequest,
|
|
31
34
|
getIntegrationRequestContext,
|
|
32
35
|
} from "../server/request-context.js";
|
|
36
|
+
import { track } from "../tracking/registry.js";
|
|
33
37
|
|
|
34
38
|
const DEFAULT_SERVERLESS_INTEGRATION_A2A_TIMEOUT_MS = 18_000;
|
|
35
39
|
const NETLIFY_INTEGRATION_A2A_TIMEOUT_MS = 2_000;
|
|
36
40
|
const INTEGRATION_A2A_TOKEN_TTL = "30m";
|
|
41
|
+
const A2A_INVOCATION_EVENT = "$a2a_invocation";
|
|
42
|
+
|
|
43
|
+
type A2AInvocationStatus = "success" | "pending" | "error";
|
|
44
|
+
|
|
45
|
+
function trackA2AInvocation(args: {
|
|
46
|
+
invocationId: string;
|
|
47
|
+
callerApp?: string;
|
|
48
|
+
targetApp: string;
|
|
49
|
+
mode: "message" | "task_poll" | "direct_action";
|
|
50
|
+
status: A2AInvocationStatus;
|
|
51
|
+
startedAt: number;
|
|
52
|
+
taskId?: string;
|
|
53
|
+
terminalCode?: string;
|
|
54
|
+
correlation: A2ACorrelationMetadata;
|
|
55
|
+
}): void {
|
|
56
|
+
try {
|
|
57
|
+
track(
|
|
58
|
+
A2A_INVOCATION_EVENT,
|
|
59
|
+
{
|
|
60
|
+
...trackingIdentityProperties(),
|
|
61
|
+
source: "a2a_delegation",
|
|
62
|
+
invocation_id: args.invocationId,
|
|
63
|
+
caller_app: args.callerApp ?? "unknown",
|
|
64
|
+
target_app: args.targetApp,
|
|
65
|
+
mode: args.mode,
|
|
66
|
+
status: args.status,
|
|
67
|
+
duration_ms: Math.max(0, Date.now() - args.startedAt),
|
|
68
|
+
task_id: args.taskId,
|
|
69
|
+
terminal_code: args.terminalCode,
|
|
70
|
+
delegation_depth: args.correlation.delegationDepth,
|
|
71
|
+
parent_run_id: args.correlation.parentRunId,
|
|
72
|
+
parent_turn_id: args.correlation.parentTurnId,
|
|
73
|
+
},
|
|
74
|
+
{ userId: getRequestUserEmail() },
|
|
75
|
+
);
|
|
76
|
+
} catch {
|
|
77
|
+
// Tracking must never affect delegation.
|
|
78
|
+
}
|
|
79
|
+
}
|
|
37
80
|
|
|
38
81
|
function buildDelegationCorrelation(
|
|
39
82
|
context: ActionRunContext | undefined,
|
|
40
83
|
selfAppId: string | undefined,
|
|
41
84
|
invocationId?: string,
|
|
42
85
|
): A2ACorrelationMetadata {
|
|
86
|
+
const self = normalizeAppHandle(selfAppId);
|
|
87
|
+
const inheritedVisited = Array.isArray(context?.visitedApps)
|
|
88
|
+
? context.visitedApps.map(normalizeAppHandle).filter(Boolean)
|
|
89
|
+
: [];
|
|
90
|
+
const visitedApps = self
|
|
91
|
+
? [...new Set([...inheritedVisited, self])]
|
|
92
|
+
: [...new Set(inheritedVisited)];
|
|
93
|
+
const inheritedDepth = Number.isInteger(context?.delegationDepth)
|
|
94
|
+
? Math.max(0, Number(context?.delegationDepth))
|
|
95
|
+
: 0;
|
|
43
96
|
return {
|
|
44
97
|
...(selfAppId?.trim() ? { callerApp: selfAppId.trim() } : {}),
|
|
45
98
|
...(context?.threadId ? { callerThreadId: context.threadId } : {}),
|
|
46
99
|
...(context?.runId ? { parentRunId: context.runId } : {}),
|
|
47
100
|
...(context?.turnId ? { parentTurnId: context.turnId } : {}),
|
|
48
101
|
...(invocationId ? { invocationId } : {}),
|
|
102
|
+
delegationDepth: Math.min(MAX_A2A_DELEGATION_HOPS, inheritedDepth + 1),
|
|
103
|
+
...(visitedApps.length > 0 ? { visitedApps } : {}),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function normalizeAppHandle(value: unknown): string {
|
|
108
|
+
return typeof value === "string"
|
|
109
|
+
? value
|
|
110
|
+
.trim()
|
|
111
|
+
.toLowerCase()
|
|
112
|
+
.replace(/^agent-native-/, "")
|
|
113
|
+
: "";
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function terminalTaskError(value: unknown): {
|
|
117
|
+
state: string;
|
|
118
|
+
taskId?: string;
|
|
119
|
+
responseText?: string;
|
|
120
|
+
errorCode?: string;
|
|
121
|
+
} | null {
|
|
122
|
+
if (!value || typeof value !== "object") return null;
|
|
123
|
+
const candidate = value as Record<string, unknown>;
|
|
124
|
+
if (candidate.name !== "A2ATaskTerminalError") return null;
|
|
125
|
+
return {
|
|
126
|
+
state: String(candidate.state ?? "failed"),
|
|
127
|
+
...(typeof candidate.taskId === "string"
|
|
128
|
+
? { taskId: candidate.taskId }
|
|
129
|
+
: {}),
|
|
130
|
+
...(typeof candidate.responseText === "string"
|
|
131
|
+
? { responseText: candidate.responseText }
|
|
132
|
+
: {}),
|
|
133
|
+
...(typeof candidate.errorCode === "string"
|
|
134
|
+
? { errorCode: candidate.errorCode }
|
|
135
|
+
: {}),
|
|
49
136
|
};
|
|
50
137
|
}
|
|
51
138
|
|
|
@@ -175,7 +262,7 @@ function formatDownstreamLlmCredentialFailure(
|
|
|
175
262
|
|
|
176
263
|
export const tool: ActionTool = {
|
|
177
264
|
description:
|
|
178
|
-
"
|
|
265
|
+
"Ask a DIFFERENT, separately-deployed app's agent over A2A. Use message by default so the receiving specialist interprets the objective with its own instructions, skills, connected sources, data dictionary, and tools. The receiver owns provider, schema, query, join, and SQL decisions. Use action + input only for an exact, explicitly known, bounded read whose complete input schema is already known; never expose or call a direct action to work around slow or unreliable delegation, and never guess receiver-owned query logic. NEVER use this to call your own app or perform actions you can do with your own tools. Using call-agent on yourself will fail and waste time. " +
|
|
179
266
|
'For brand-consistent generated media, the first-party Assets agent is available as agent="assets"; use it when another app needs generated heroes, diagrams, product shots, thumbnails, videos, or design imagery, unless the current app has its own generation action that already delegates there. ' +
|
|
180
267
|
"IMPORTANT — handling the response: " +
|
|
181
268
|
"(a) If it contains a URL or ID, copy it VERBATIM into your reply. Do not 'correct' or pluralize the path (e.g. /deck/ → /decks/), normalize casing, or change the slug — any edit breaks the link. " +
|
|
@@ -203,7 +290,7 @@ export const tool: ActionTool = {
|
|
|
203
290
|
action: {
|
|
204
291
|
type: "string",
|
|
205
292
|
description:
|
|
206
|
-
"
|
|
293
|
+
"Optional exact read-only action for an explicitly known bounded operation. Prefer message when the target agent must interpret data, choose sources or tools, synthesize, mutate, or do multi-step work. Never guess the action schema or send receiver-owned SQL.",
|
|
207
294
|
},
|
|
208
295
|
input: {
|
|
209
296
|
type: "object",
|
|
@@ -259,6 +346,16 @@ export async function run(
|
|
|
259
346
|
return `Error: You cannot use call-agent to call yourself (${selfAppId}). Use your own registered actions/tools instead. call-agent is only for communicating with OTHER separately-deployed apps.`;
|
|
260
347
|
}
|
|
261
348
|
|
|
349
|
+
const inheritedDepth = Number.isInteger(context?.delegationDepth)
|
|
350
|
+
? Math.max(0, Number(context?.delegationDepth))
|
|
351
|
+
: 0;
|
|
352
|
+
if (!taskId && inheritedDepth >= MAX_A2A_DELEGATION_HOPS) {
|
|
353
|
+
return (
|
|
354
|
+
`Error: Cross-app delegation stopped at the ${MAX_A2A_DELEGATION_HOPS}-hop limit. ` +
|
|
355
|
+
"Finish with the results already collected instead of starting another agent."
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
|
|
262
359
|
const agent = await findAgent(agentIdOrName, selfAppId);
|
|
263
360
|
if (!agent) {
|
|
264
361
|
const available = (await discoverAgents(selfAppId))
|
|
@@ -267,15 +364,42 @@ export async function run(
|
|
|
267
364
|
return `Error: Agent "${agentIdOrName}" not found. Available agents: ${available || "(none)"}`;
|
|
268
365
|
}
|
|
269
366
|
|
|
367
|
+
if (!taskId) {
|
|
368
|
+
const visited = new Set(
|
|
369
|
+
(context?.visitedApps ?? []).map(normalizeAppHandle).filter(Boolean),
|
|
370
|
+
);
|
|
371
|
+
const self = normalizeAppHandle(selfAppId);
|
|
372
|
+
if (self) visited.add(self);
|
|
373
|
+
const targetHandles = [
|
|
374
|
+
normalizeAppHandle((agent as { id?: string }).id),
|
|
375
|
+
normalizeAppHandle(agent.name),
|
|
376
|
+
normalizeAppHandle(agentIdOrName),
|
|
377
|
+
].filter(Boolean);
|
|
378
|
+
const repeated = targetHandles.find((handle) => visited.has(handle));
|
|
379
|
+
if (repeated) {
|
|
380
|
+
return (
|
|
381
|
+
`Error: Cross-app delegation cycle blocked before calling ${agent.name}. ` +
|
|
382
|
+
`The request already visited ${[...visited].join(" -> ")}.`
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
270
387
|
const correlation = buildDelegationCorrelation(context, selfAppId);
|
|
271
388
|
const idempotencyKey =
|
|
272
389
|
message && !taskId
|
|
273
390
|
? buildMessageIdempotencyKey(context?.turnId, agent.url, message)
|
|
274
391
|
: undefined;
|
|
392
|
+
const targetApp =
|
|
393
|
+
normalizeAppHandle((agent as { id?: string }).id) ||
|
|
394
|
+
normalizeAppHandle(agent.name) ||
|
|
395
|
+
normalizeAppHandle(agentIdOrName) ||
|
|
396
|
+
"unknown";
|
|
275
397
|
|
|
276
398
|
if (action) {
|
|
277
399
|
const agentCallId = randomUUID();
|
|
278
400
|
const startedAt = Date.now();
|
|
401
|
+
let terminalStatus: "done" | "error" = "done";
|
|
402
|
+
let terminalCode: string | undefined;
|
|
279
403
|
if (context?.send) {
|
|
280
404
|
context.send({
|
|
281
405
|
type: "agent_call",
|
|
@@ -291,6 +415,10 @@ export async function run(
|
|
|
291
415
|
input as Record<string, unknown>,
|
|
292
416
|
buildDelegationCorrelation(context, selfAppId, randomUUID()),
|
|
293
417
|
);
|
|
418
|
+
if (/^Error\b/i.test(output)) {
|
|
419
|
+
terminalStatus = "error";
|
|
420
|
+
terminalCode = "direct_action_failed";
|
|
421
|
+
}
|
|
294
422
|
if (context?.send && output) {
|
|
295
423
|
context.send({
|
|
296
424
|
type: "agent_call_text",
|
|
@@ -300,12 +428,26 @@ export async function run(
|
|
|
300
428
|
});
|
|
301
429
|
}
|
|
302
430
|
return output;
|
|
431
|
+
} catch (error) {
|
|
432
|
+
terminalStatus = "error";
|
|
433
|
+
terminalCode = "direct_action_failed";
|
|
434
|
+
throw error;
|
|
303
435
|
} finally {
|
|
436
|
+
trackA2AInvocation({
|
|
437
|
+
invocationId: agentCallId,
|
|
438
|
+
callerApp: selfAppId,
|
|
439
|
+
targetApp,
|
|
440
|
+
mode: "direct_action",
|
|
441
|
+
status: terminalStatus === "done" ? "success" : "error",
|
|
442
|
+
startedAt,
|
|
443
|
+
terminalCode,
|
|
444
|
+
correlation,
|
|
445
|
+
});
|
|
304
446
|
if (context?.send) {
|
|
305
447
|
context.send({
|
|
306
448
|
type: "agent_call",
|
|
307
449
|
agent: agent.name,
|
|
308
|
-
status:
|
|
450
|
+
status: terminalStatus,
|
|
309
451
|
agentCallId,
|
|
310
452
|
durationMs: Date.now() - startedAt,
|
|
311
453
|
});
|
|
@@ -322,10 +464,18 @@ export async function run(
|
|
|
322
464
|
const messageWithHint = taskId
|
|
323
465
|
? ""
|
|
324
466
|
: `${message}${integrationSourceContextHint(sourceContext)}\n\n` +
|
|
325
|
-
|
|
467
|
+
`<a2a-caller-hint>\n` +
|
|
468
|
+
`This request comes from another app via A2A. The caller cannot see your local UI, deck list, or navigation — only the literal text you put in your reply. ` +
|
|
326
469
|
`If you create or reference a deck/document/design/dashboard, include its FULLY-QUALIFIED URL (e.g. ${agent.url}/deck/<id>) in your reply, not a relative path. ` +
|
|
327
470
|
`Use only artifact IDs and URL paths returned by successful actions — never invent slugs, IDs, or hosts. ` +
|
|
328
|
-
`Return a concise caller-ready synthesis rather than raw tool output or full transcripts; preserve source counts, IDs, short supporting quotes, and URLs needed to substantiate the answer
|
|
471
|
+
`Return a concise caller-ready synthesis rather than raw tool output or full transcripts; preserve source counts, IDs, short supporting quotes, and URLs needed to substantiate the answer.\n` +
|
|
472
|
+
`</a2a-caller-hint>`;
|
|
473
|
+
|
|
474
|
+
const invocationId = randomUUID();
|
|
475
|
+
const invocationStartedAt = Date.now();
|
|
476
|
+
let invocationStatus: A2AInvocationStatus = "error";
|
|
477
|
+
let invocationTaskId = taskId || undefined;
|
|
478
|
+
let invocationTerminalCode: string | undefined;
|
|
329
479
|
|
|
330
480
|
try {
|
|
331
481
|
// If we have a send context, use streaming so the UI shows progressive text
|
|
@@ -388,10 +538,15 @@ export async function run(
|
|
|
388
538
|
let responseText = "";
|
|
389
539
|
let lastSentLength = 0;
|
|
390
540
|
const agentCallId = randomUUID();
|
|
541
|
+
let terminalStatus: "done" | "pending" | "error" = "done";
|
|
391
542
|
const existingContinuationText = taskId
|
|
392
543
|
? null
|
|
393
544
|
: await formatExistingIntegrationContinuationIfRetry(agent, message);
|
|
394
|
-
if (existingContinuationText)
|
|
545
|
+
if (existingContinuationText) {
|
|
546
|
+
invocationStatus = "pending";
|
|
547
|
+
invocationTerminalCode = "existing_continuation";
|
|
548
|
+
return existingContinuationText;
|
|
549
|
+
}
|
|
395
550
|
|
|
396
551
|
context.send({
|
|
397
552
|
type: "agent_call",
|
|
@@ -547,6 +702,9 @@ export async function run(
|
|
|
547
702
|
} catch (pollErr: any) {
|
|
548
703
|
const timeoutTaskId = getA2ATaskTimeoutTaskId(pollErr);
|
|
549
704
|
if (timeoutTaskId) {
|
|
705
|
+
terminalStatus = "pending";
|
|
706
|
+
invocationTaskId = timeoutTaskId;
|
|
707
|
+
invocationTerminalCode = "timeout_pending";
|
|
550
708
|
const queued = await enqueueIntegrationContinuationIfPossible(
|
|
551
709
|
timeoutTaskId,
|
|
552
710
|
agent,
|
|
@@ -580,23 +738,70 @@ export async function run(
|
|
|
580
738
|
);
|
|
581
739
|
}
|
|
582
740
|
}
|
|
741
|
+
} else if (terminalTaskError(pollErr)?.state === "input-required") {
|
|
742
|
+
terminalStatus = "pending";
|
|
743
|
+
const terminal = terminalTaskError(pollErr)!;
|
|
744
|
+
invocationTaskId = terminal.taskId;
|
|
745
|
+
invocationTerminalCode = terminal.errorCode ?? "input_required";
|
|
746
|
+
responseText = formatInputRequiredWaitInstruction(
|
|
747
|
+
agent.name,
|
|
748
|
+
terminal,
|
|
749
|
+
agentIdOrName,
|
|
750
|
+
);
|
|
751
|
+
} else if (terminalTaskError(pollErr)) {
|
|
752
|
+
terminalStatus = "error";
|
|
753
|
+
const terminal = terminalTaskError(pollErr)!;
|
|
754
|
+
invocationTaskId = terminal.taskId;
|
|
755
|
+
invocationTerminalCode = terminal.errorCode ?? terminal.state;
|
|
756
|
+
const detail = expandRelativeUrls(
|
|
757
|
+
terminal.responseText ?? pollErr?.message ?? "unknown failure",
|
|
758
|
+
agent.url,
|
|
759
|
+
);
|
|
760
|
+
responseText =
|
|
761
|
+
`Error: The ${agent.name} agent ended ${terminal.state}` +
|
|
762
|
+
(terminal.errorCode ? ` (${terminal.errorCode})` : "") +
|
|
763
|
+
(terminal.taskId ? ` [taskId: ${terminal.taskId}]` : "") +
|
|
764
|
+
(detail ? `: ${detail}` : "");
|
|
583
765
|
} else {
|
|
766
|
+
terminalStatus = "error";
|
|
767
|
+
invocationTerminalCode = "call_failed";
|
|
584
768
|
const reason = pollErr?.message ?? "unknown error";
|
|
585
769
|
responseText =
|
|
586
770
|
formatDownstreamLlmCredentialFailure(agent.name, pollErr) ??
|
|
587
|
-
`The ${agent.name} agent
|
|
771
|
+
`Error: The ${agent.name} agent call failed. (${reason})`;
|
|
588
772
|
}
|
|
589
773
|
}
|
|
590
774
|
|
|
775
|
+
if (!responseText && terminalStatus === "done") {
|
|
776
|
+
terminalStatus = "error";
|
|
777
|
+
invocationTerminalCode = "empty_agent_response";
|
|
778
|
+
}
|
|
779
|
+
if (responseText.length > MAX_A2A_CALLER_RESPONSE_CHARS) {
|
|
780
|
+
terminalStatus = "error";
|
|
781
|
+
invocationTerminalCode = "a2a_response_too_large";
|
|
782
|
+
responseText =
|
|
783
|
+
`Error: The ${agent.name} agent returned more data than the caller can safely consume. ` +
|
|
784
|
+
"Ask it for a concise synthesis or a retrievable artifact instead.";
|
|
785
|
+
}
|
|
786
|
+
invocationStatus =
|
|
787
|
+
terminalStatus === "done"
|
|
788
|
+
? "success"
|
|
789
|
+
: terminalStatus === "pending"
|
|
790
|
+
? "pending"
|
|
791
|
+
: "error";
|
|
792
|
+
|
|
591
793
|
context.send({
|
|
592
794
|
type: "agent_call",
|
|
593
795
|
agent: agent.name,
|
|
594
|
-
status:
|
|
796
|
+
status: terminalStatus,
|
|
595
797
|
agentCallId,
|
|
798
|
+
...(invocationTaskId ? { taskId: invocationTaskId } : {}),
|
|
596
799
|
durationMs: Date.now() - callStartedAt,
|
|
597
800
|
});
|
|
598
801
|
|
|
599
|
-
return
|
|
802
|
+
return (
|
|
803
|
+
responseText || `Error: The ${agent.name} agent returned no result.`
|
|
804
|
+
);
|
|
600
805
|
}
|
|
601
806
|
|
|
602
807
|
// No context — use the async + poll call so we don't get cut off at the
|
|
@@ -627,7 +832,22 @@ export async function run(
|
|
|
627
832
|
});
|
|
628
833
|
const sanitized =
|
|
629
834
|
formatDownstreamLlmCredentialFailure(agent.name, response) ?? response;
|
|
630
|
-
|
|
835
|
+
const expanded = expandRelativeUrls(sanitized, agent.url);
|
|
836
|
+
if (!expanded) {
|
|
837
|
+
invocationStatus = "error";
|
|
838
|
+
invocationTerminalCode = "empty_agent_response";
|
|
839
|
+
return "Error: The remote agent returned no result.";
|
|
840
|
+
}
|
|
841
|
+
if (expanded.length > MAX_A2A_CALLER_RESPONSE_CHARS) {
|
|
842
|
+
invocationStatus = "error";
|
|
843
|
+
invocationTerminalCode = "a2a_response_too_large";
|
|
844
|
+
return (
|
|
845
|
+
`Error: The ${agent.name} agent returned more data than the caller can safely consume. ` +
|
|
846
|
+
"Ask it for a concise synthesis or a retrievable artifact instead."
|
|
847
|
+
);
|
|
848
|
+
}
|
|
849
|
+
invocationStatus = "success";
|
|
850
|
+
return expanded;
|
|
631
851
|
} catch (err: any) {
|
|
632
852
|
const msg = err?.message ?? String(err);
|
|
633
853
|
const credentialMessage = formatDownstreamLlmCredentialFailure(
|
|
@@ -635,8 +855,33 @@ export async function run(
|
|
|
635
855
|
err,
|
|
636
856
|
);
|
|
637
857
|
if (credentialMessage) return credentialMessage;
|
|
858
|
+
const terminal = terminalTaskError(err);
|
|
859
|
+
if (terminal?.state === "input-required") {
|
|
860
|
+
invocationStatus = "pending";
|
|
861
|
+
invocationTaskId = terminal.taskId;
|
|
862
|
+
invocationTerminalCode = terminal.errorCode ?? "input_required";
|
|
863
|
+
return formatInputRequiredWaitInstruction(
|
|
864
|
+
agent.name,
|
|
865
|
+
terminal,
|
|
866
|
+
agentIdOrName,
|
|
867
|
+
);
|
|
868
|
+
}
|
|
869
|
+
if (terminal) {
|
|
870
|
+
invocationStatus = "error";
|
|
871
|
+
invocationTaskId = terminal.taskId;
|
|
872
|
+
invocationTerminalCode = terminal.errorCode ?? terminal.state;
|
|
873
|
+
return (
|
|
874
|
+
`Error calling ${agent.name}: remote task ${terminal.state}` +
|
|
875
|
+
(terminal.errorCode ? ` (${terminal.errorCode})` : "") +
|
|
876
|
+
(terminal.taskId ? ` [taskId: ${terminal.taskId}]` : "") +
|
|
877
|
+
(terminal.responseText ? `: ${terminal.responseText}` : "")
|
|
878
|
+
);
|
|
879
|
+
}
|
|
638
880
|
const timeoutTaskId = getA2ATaskTimeoutTaskId(err);
|
|
639
881
|
if (timeoutTaskId) {
|
|
882
|
+
invocationStatus = "pending";
|
|
883
|
+
invocationTaskId = timeoutTaskId;
|
|
884
|
+
invocationTerminalCode = "timeout_pending";
|
|
640
885
|
return formatExistingTaskWaitInstruction(
|
|
641
886
|
agent.name,
|
|
642
887
|
timeoutTaskId,
|
|
@@ -646,9 +891,25 @@ export async function run(
|
|
|
646
891
|
// Friendlier message for the common timeout case so the calling agent can
|
|
647
892
|
// decide whether to give up or retry.
|
|
648
893
|
if (/timeout|did not complete|Inactivity|504/i.test(msg)) {
|
|
649
|
-
|
|
894
|
+
invocationStatus = "error";
|
|
895
|
+
invocationTerminalCode = "timeout_without_task";
|
|
896
|
+
return `Error calling ${agent.name}: the remote request timed out before a task id could be recovered.`;
|
|
650
897
|
}
|
|
898
|
+
invocationStatus = "error";
|
|
899
|
+
invocationTerminalCode = "call_failed";
|
|
651
900
|
return `Error calling ${agent.name}: ${msg}`;
|
|
901
|
+
} finally {
|
|
902
|
+
trackA2AInvocation({
|
|
903
|
+
invocationId,
|
|
904
|
+
callerApp: selfAppId,
|
|
905
|
+
targetApp,
|
|
906
|
+
mode: taskId ? "task_poll" : "message",
|
|
907
|
+
status: invocationStatus,
|
|
908
|
+
startedAt: invocationStartedAt,
|
|
909
|
+
taskId: invocationTaskId,
|
|
910
|
+
terminalCode: invocationTerminalCode,
|
|
911
|
+
correlation,
|
|
912
|
+
});
|
|
652
913
|
}
|
|
653
914
|
}
|
|
654
915
|
|
|
@@ -711,6 +972,28 @@ function formatExistingTaskWaitInstruction(
|
|
|
711
972
|
);
|
|
712
973
|
}
|
|
713
974
|
|
|
975
|
+
function formatInputRequiredWaitInstruction(
|
|
976
|
+
agentName: string,
|
|
977
|
+
terminal: {
|
|
978
|
+
taskId?: string;
|
|
979
|
+
responseText?: string;
|
|
980
|
+
},
|
|
981
|
+
agentIdOrName: string,
|
|
982
|
+
): string {
|
|
983
|
+
const detail = terminal.responseText?.trim();
|
|
984
|
+
if (!terminal.taskId) {
|
|
985
|
+
return (
|
|
986
|
+
(detail ? `${detail}\n\n` : "") +
|
|
987
|
+
`Pending: The ${agentName} agent needs input before it can continue.`
|
|
988
|
+
);
|
|
989
|
+
}
|
|
990
|
+
return (
|
|
991
|
+
(detail ? `${detail}\n\n` : "") +
|
|
992
|
+
`The ${agentName} agent is waiting for input under taskId "${terminal.taskId}". ` +
|
|
993
|
+
`After providing or approving the requested input, call call-agent with agent="${agentIdOrName}" and taskId="${terminal.taskId}" (omit message) to continue this same task. Do not start a new message for this work.`
|
|
994
|
+
);
|
|
995
|
+
}
|
|
996
|
+
|
|
714
997
|
async function enqueueIntegrationContinuationIfPossible(
|
|
715
998
|
taskId: string,
|
|
716
999
|
agent: { name: string; url: string },
|
|
@@ -10,7 +10,7 @@ import { discoverAgents, findAgent } from "../server/agent-discovery.js";
|
|
|
10
10
|
|
|
11
11
|
export const tool: ActionTool = {
|
|
12
12
|
description:
|
|
13
|
-
"Describe what the OTHER apps in this workspace can do for this app, read live from each peer's published A2A agent card. Use this before building a capability locally, before telling the user what is or is not possible across apps, and whenever the user asks which app they should use for something.
|
|
13
|
+
"Describe what the OTHER apps in this workspace can do for this app, read live from each peer's published A2A agent card. Use this before building a capability locally, before telling the user what is or is not possible across apps, and whenever the user asks which app they should use for something. Ask the owning app's agent with a natural-language call-agent message by default; published action contracts are optional details for exact bounded reads, not a substitute for the specialist agent. Pass `app` for one peer's full capability list. This is generated from live deployments - never hand-maintain or cache a list of workspace apps in code, docs, or markdown.",
|
|
14
14
|
parameters: {
|
|
15
15
|
type: "object",
|
|
16
16
|
properties: {
|
|
@@ -41,7 +41,7 @@ export async function run(
|
|
|
41
41
|
return formatCapabilityDetail(
|
|
42
42
|
await loadCapabilities(agent),
|
|
43
43
|
(appId) =>
|
|
44
|
-
`
|
|
44
|
+
`Ask this specialist with call-agent: agent="${appId}", message="<objective>". Use action + input only for an exact bounded read with a fully known schema.`,
|
|
45
45
|
);
|
|
46
46
|
}
|
|
47
47
|
|