@agent-native/core 0.131.4 → 0.131.6
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 +69 -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 +14 -10
- package/corpus/core/docs/content/docs-components.mdx +491 -0
- 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/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/types.ts +4 -0
- package/corpus/core/src/action.ts +3 -0
- package/corpus/core/src/agent/engine/registry.ts +45 -5
- 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/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 +290 -9
- package/corpus/core/src/scripts/describe-workspace-apps.ts +2 -2
- package/corpus/core/src/secrets/crypto.ts +126 -34
- package/corpus/core/src/secrets/storage.ts +61 -25
- package/corpus/core/src/server/agent-capabilities.ts +1 -1
- package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +111 -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 +14 -7
- package/corpus/core/src/templates/headless/.agents/skills/secrets/SKILL.md +14 -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 +14 -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 +6 -4
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +4 -3
- 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/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/.agents/skills/content-product-development/SKILL.md +47 -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/slides/.agents/skills/analytics-data-for-decks/SKILL.md +8 -12
- package/corpus/templates/slides/AGENTS.md +4 -4
- 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-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/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/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +34 -7
- 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/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +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/file-upload/actions/upload-image.d.ts +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/notifications/routes.d.ts +2 -2
- 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/resources/handlers.d.ts +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +233 -10
- 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 +31 -21
- package/dist/secrets/crypto.d.ts.map +1 -1
- package/dist/secrets/crypto.js +108 -33
- package/dist/secrets/crypto.js.map +1 -1
- package/dist/secrets/storage.d.ts +3 -5
- package/dist/secrets/storage.d.ts.map +1 -1
- package/dist/secrets/storage.js +40 -25
- 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 +92 -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/agent-engine-api-key-route.d.ts +1 -1
- package/dist/templates/default/.agents/skills/secrets/SKILL.md +14 -7
- package/dist/templates/headless/.agents/skills/secrets/SKILL.md +14 -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 +14 -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 +14 -10
- package/docs/content/docs-components.mdx +491 -0
- 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/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 +2 -2
- package/src/a2a/client.ts +449 -66
- package/src/a2a/correlation.ts +31 -0
- package/src/a2a/types.ts +4 -0
- package/src/action.ts +3 -0
- package/src/agent/engine/registry.ts +45 -5
- 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/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 +290 -9
- package/src/scripts/describe-workspace-apps.ts +2 -2
- package/src/secrets/crypto.ts +126 -34
- package/src/secrets/storage.ts +61 -25
- package/src/server/agent-capabilities.ts +1 -1
- package/src/server/agent-chat/action-filters-a2a.ts +111 -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 +14 -7
- package/src/templates/headless/.agents/skills/secrets/SKILL.md +14 -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 +14 -7
- package/src/vite/client.ts +1 -0
package/src/a2a/correlation.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { A2ACorrelationMetadata } from "./types.js";
|
|
2
2
|
|
|
3
3
|
export const MAX_A2A_CORRELATION_VALUE_CHARS = 200;
|
|
4
|
+
export const MAX_A2A_DELEGATION_HOPS = 3;
|
|
4
5
|
|
|
5
6
|
const APP_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
6
7
|
const CORRELATION_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]*$/;
|
|
@@ -40,11 +41,41 @@ export function sanitizeA2ACorrelationMetadata(
|
|
|
40
41
|
const parentRunId = sanitizeA2ACorrelationId(metadata.parentRunId);
|
|
41
42
|
const parentTurnId = sanitizeA2ACorrelationId(metadata.parentTurnId);
|
|
42
43
|
const invocationId = sanitizeA2ACorrelationId(metadata.invocationId);
|
|
44
|
+
const providedDelegationDepth =
|
|
45
|
+
typeof metadata.delegationDepth === "number" &&
|
|
46
|
+
Number.isInteger(metadata.delegationDepth) &&
|
|
47
|
+
metadata.delegationDepth >= 0 &&
|
|
48
|
+
metadata.delegationDepth <= MAX_A2A_DELEGATION_HOPS
|
|
49
|
+
? metadata.delegationDepth
|
|
50
|
+
: undefined;
|
|
51
|
+
const visitedApps = Array.isArray(metadata.visitedApps)
|
|
52
|
+
? [
|
|
53
|
+
...new Set(
|
|
54
|
+
metadata.visitedApps
|
|
55
|
+
.map((value) => boundedIdentifier(value, APP_ID_PATTERN))
|
|
56
|
+
.filter((value): value is string => !!value),
|
|
57
|
+
),
|
|
58
|
+
].slice(0, MAX_A2A_DELEGATION_HOPS + 1)
|
|
59
|
+
: [];
|
|
60
|
+
const pathDepth = Math.min(MAX_A2A_DELEGATION_HOPS, visitedApps.length);
|
|
61
|
+
// Damaged lineage must never reset a nested call to depth zero. Derive at
|
|
62
|
+
// least the valid path length, and fail closed at the hop limit when a peer
|
|
63
|
+
// supplied an explicit but invalid depth.
|
|
64
|
+
const delegationDepth =
|
|
65
|
+
providedDelegationDepth !== undefined
|
|
66
|
+
? Math.max(providedDelegationDepth, pathDepth)
|
|
67
|
+
: metadata.delegationDepth !== undefined
|
|
68
|
+
? MAX_A2A_DELEGATION_HOPS
|
|
69
|
+
: visitedApps.length > 0
|
|
70
|
+
? pathDepth
|
|
71
|
+
: undefined;
|
|
43
72
|
return {
|
|
44
73
|
...(callerApp ? { callerApp } : {}),
|
|
45
74
|
...(callerThreadId ? { callerThreadId } : {}),
|
|
46
75
|
...(parentRunId ? { parentRunId } : {}),
|
|
47
76
|
...(parentTurnId ? { parentTurnId } : {}),
|
|
48
77
|
...(invocationId ? { invocationId } : {}),
|
|
78
|
+
...(delegationDepth !== undefined ? { delegationDepth } : {}),
|
|
79
|
+
...(visitedApps.length > 0 ? { visitedApps } : {}),
|
|
49
80
|
};
|
|
50
81
|
}
|
package/src/a2a/types.ts
CHANGED
|
@@ -170,6 +170,10 @@ export interface A2ACorrelationMetadata {
|
|
|
170
170
|
parentRunId?: string;
|
|
171
171
|
parentTurnId?: string;
|
|
172
172
|
invocationId?: string;
|
|
173
|
+
/** Number of cross-app edges already traversed by this logical request. */
|
|
174
|
+
delegationDepth?: number;
|
|
175
|
+
/** Bounded app ids already visited, used only for cycle prevention. */
|
|
176
|
+
visitedApps?: string[];
|
|
173
177
|
}
|
|
174
178
|
|
|
175
179
|
// --- Framework config ---
|
package/src/action.ts
CHANGED
|
@@ -81,6 +81,9 @@ export interface ActionRunContext {
|
|
|
81
81
|
networkProtocol?: "a2a" | "mcp" | "provider-api";
|
|
82
82
|
networkId?: string;
|
|
83
83
|
networkPeer?: string;
|
|
84
|
+
/** Bounded cross-app lineage used to prevent recursive delegation cycles. */
|
|
85
|
+
delegationDepth?: number;
|
|
86
|
+
visitedApps?: string[];
|
|
84
87
|
/**
|
|
85
88
|
* Attachments submitted with the current agent turn (pasted text blocks,
|
|
86
89
|
* uploaded files, images), exactly as the server received them — with full,
|
|
@@ -604,8 +604,36 @@ async function engineCreateConfigForEntry(
|
|
|
604
604
|
entry: AgentEngineEntry,
|
|
605
605
|
apiKey: string | undefined,
|
|
606
606
|
extra?: Record<string, unknown>,
|
|
607
|
+
preferResolvedCredential = false,
|
|
607
608
|
): Promise<Record<string, unknown>> {
|
|
608
609
|
const safeExtra = { ...(extra ?? {}) };
|
|
610
|
+
let matchingApiKey = apiKey;
|
|
611
|
+
// Automatic engine selection must also select that engine's credential.
|
|
612
|
+
// Callers historically passed one untagged "active" key before the registry
|
|
613
|
+
// chose an engine, which could hand an Anthropic key to an app-default
|
|
614
|
+
// OpenAI engine (or vice versa). Explicit engineOption branches retain their
|
|
615
|
+
// paired key; automatic branches opt into matching the chosen provider here.
|
|
616
|
+
if (
|
|
617
|
+
preferResolvedCredential &&
|
|
618
|
+
entry.name !== "builder" &&
|
|
619
|
+
entry.requiredEnvVars.length > 0
|
|
620
|
+
) {
|
|
621
|
+
let foundMatchingCredential = false;
|
|
622
|
+
for (const key of entry.requiredEnvVars) {
|
|
623
|
+
const resolved = (await resolveUsableProviderSecret(key)) ?? undefined;
|
|
624
|
+
if (!resolved) continue;
|
|
625
|
+
foundMatchingCredential = true;
|
|
626
|
+
const deployFallback =
|
|
627
|
+
canUseDeployCredentialFallbackForRequest(key) &&
|
|
628
|
+
readDeployCredentialEnv(key) === resolved;
|
|
629
|
+
// Keep deploy-only credentials implicit so provider SDKs retain their
|
|
630
|
+
// established env-fallback behavior. Scoped credentials must be passed
|
|
631
|
+
// explicitly, and replace an unrelated preselected provider key.
|
|
632
|
+
if (matchingApiKey || !deployFallback) matchingApiKey = resolved;
|
|
633
|
+
break;
|
|
634
|
+
}
|
|
635
|
+
if (!foundMatchingCredential) matchingApiKey = undefined;
|
|
636
|
+
}
|
|
609
637
|
if (entry.name === "ai-sdk:openai") {
|
|
610
638
|
if (typeof safeExtra.baseURL === "string" && safeExtra.baseUrl == null) {
|
|
611
639
|
safeExtra.baseUrl = normalizeOpenAiBaseUrl(safeExtra.baseURL);
|
|
@@ -615,7 +643,7 @@ async function engineCreateConfigForEntry(
|
|
|
615
643
|
if (baseUrl) safeExtra.baseUrl = baseUrl;
|
|
616
644
|
}
|
|
617
645
|
}
|
|
618
|
-
return engineCreateConfig(entry,
|
|
646
|
+
return engineCreateConfig(entry, matchingApiKey, safeExtra);
|
|
619
647
|
}
|
|
620
648
|
|
|
621
649
|
/**
|
|
@@ -816,7 +844,9 @@ export async function resolveEngine(
|
|
|
816
844
|
const entry = _registry.get(envEngine);
|
|
817
845
|
if (entry) {
|
|
818
846
|
assertAgentEnginePackageInstalled(entry);
|
|
819
|
-
return entry.create(
|
|
847
|
+
return entry.create(
|
|
848
|
+
await engineCreateConfigForEntry(entry, apiKey, undefined, true),
|
|
849
|
+
);
|
|
820
850
|
}
|
|
821
851
|
}
|
|
822
852
|
|
|
@@ -824,7 +854,9 @@ export async function resolveEngine(
|
|
|
824
854
|
if (appDefault?.engine) {
|
|
825
855
|
const entry = _registry.get(appDefault.engine);
|
|
826
856
|
if (entry && (await isStoredEngineUsableForRequest(appDefault, entry))) {
|
|
827
|
-
return entry.create(
|
|
857
|
+
return entry.create(
|
|
858
|
+
await engineCreateConfigForEntry(entry, apiKey, undefined, true),
|
|
859
|
+
);
|
|
828
860
|
}
|
|
829
861
|
}
|
|
830
862
|
|
|
@@ -857,6 +889,7 @@ export async function resolveEngine(
|
|
|
857
889
|
stripInlineApiKeyConfig(
|
|
858
890
|
storedConfig as Record<string, unknown> | undefined,
|
|
859
891
|
),
|
|
892
|
+
true,
|
|
860
893
|
),
|
|
861
894
|
);
|
|
862
895
|
}
|
|
@@ -864,7 +897,12 @@ export async function resolveEngine(
|
|
|
864
897
|
|
|
865
898
|
if (detectedFromUser) {
|
|
866
899
|
return detectedFromUser.create(
|
|
867
|
-
await engineCreateConfigForEntry(
|
|
900
|
+
await engineCreateConfigForEntry(
|
|
901
|
+
detectedFromUser,
|
|
902
|
+
apiKey,
|
|
903
|
+
undefined,
|
|
904
|
+
true,
|
|
905
|
+
),
|
|
868
906
|
);
|
|
869
907
|
}
|
|
870
908
|
|
|
@@ -873,7 +911,9 @@ export async function resolveEngine(
|
|
|
873
911
|
// auth-failure markers so a rejected deploy key cannot permanently win.
|
|
874
912
|
const detected = await detectEngineFromEnvForRequest();
|
|
875
913
|
if (detected) {
|
|
876
|
-
return detected.create(
|
|
914
|
+
return detected.create(
|
|
915
|
+
await engineCreateConfigForEntry(detected, apiKey, undefined, true),
|
|
916
|
+
);
|
|
877
917
|
}
|
|
878
918
|
|
|
879
919
|
// 9. Default: anthropic
|
|
@@ -1068,7 +1068,12 @@ export interface ProductionAgentOptions {
|
|
|
1068
1068
|
* `maxResultChars` takes precedence; this sets the fallback for actions
|
|
1069
1069
|
* that don't declare their own limits.
|
|
1070
1070
|
*/
|
|
1071
|
-
toolLimits?: {
|
|
1071
|
+
toolLimits?: {
|
|
1072
|
+
timeoutMs?: number;
|
|
1073
|
+
maxResultChars?: number;
|
|
1074
|
+
/** Absolute cap applied after action-level overrides. */
|
|
1075
|
+
hardMaxResultChars?: number;
|
|
1076
|
+
};
|
|
1072
1077
|
}
|
|
1073
1078
|
|
|
1074
1079
|
export async function resolveAgentOwnerEmail(
|
|
@@ -1307,11 +1312,7 @@ export function isRetryableError(err: unknown): boolean {
|
|
|
1307
1312
|
msg.includes("gateway error") ||
|
|
1308
1313
|
msg.includes("socket hang up") ||
|
|
1309
1314
|
msg.includes("connection reset") ||
|
|
1310
|
-
|
|
1311
|
-
// "Connection error." — Builder gateway often forwards it as a stop
|
|
1312
|
-
// event with no structured code. Without this match the run fails in
|
|
1313
|
-
// ~3s and the client recovery loop storms POSTs.
|
|
1314
|
-
msg.includes("connection error") ||
|
|
1315
|
+
hasProviderConnectionErrorMessage(msg) ||
|
|
1315
1316
|
msg.includes("too many requests") ||
|
|
1316
1317
|
msg.includes("timeout") ||
|
|
1317
1318
|
msg.includes("gateway timeout") ||
|
|
@@ -1320,6 +1321,17 @@ export function isRetryableError(err: unknown): boolean {
|
|
|
1320
1321
|
);
|
|
1321
1322
|
}
|
|
1322
1323
|
|
|
1324
|
+
function hasProviderConnectionErrorMessage(message: string): boolean {
|
|
1325
|
+
const normalized = message.toLowerCase();
|
|
1326
|
+
// Anthropic's APIConnectionError uses "Connection error."; AI SDK wraps
|
|
1327
|
+
// OpenAI TLS failures as "Cannot connect to API". Both can cross a worker
|
|
1328
|
+
// boundary without their structured EngineError metadata.
|
|
1329
|
+
return (
|
|
1330
|
+
normalized.includes("connection error") ||
|
|
1331
|
+
normalized.includes("cannot connect to api")
|
|
1332
|
+
);
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1323
1335
|
// ---------------------------------------------------------------------------
|
|
1324
1336
|
// Context-window overflow recovery
|
|
1325
1337
|
// ---------------------------------------------------------------------------
|
|
@@ -2064,6 +2076,18 @@ export interface AgentLoopUsage {
|
|
|
2064
2076
|
firstEngineEventAtMs?: number;
|
|
2065
2077
|
}
|
|
2066
2078
|
|
|
2079
|
+
/** Machine-readable terminal state for one agent-loop attempt. */
|
|
2080
|
+
export type AgentLoopOutcome =
|
|
2081
|
+
| { state: "completed" }
|
|
2082
|
+
| { state: "input_required"; code: string; message: string }
|
|
2083
|
+
| {
|
|
2084
|
+
state: "failed";
|
|
2085
|
+
code: string;
|
|
2086
|
+
retryable: boolean;
|
|
2087
|
+
message: string;
|
|
2088
|
+
}
|
|
2089
|
+
| { state: "canceled"; message?: string };
|
|
2090
|
+
|
|
2067
2091
|
export interface AgentLoopToolCallSummary {
|
|
2068
2092
|
name: string;
|
|
2069
2093
|
input: unknown;
|
|
@@ -2152,7 +2176,7 @@ export type AgentLoopContinuationReason =
|
|
|
2152
2176
|
|
|
2153
2177
|
export function appendAgentLoopContinuation(
|
|
2154
2178
|
messages: EngineMessage[],
|
|
2155
|
-
reason: AgentLoopContinuationReason,
|
|
2179
|
+
reason: AgentLoopContinuationReason | "rate_limited",
|
|
2156
2180
|
options: { actionPreparationTool?: string } = {},
|
|
2157
2181
|
) {
|
|
2158
2182
|
const note =
|
|
@@ -2164,11 +2188,13 @@ export function appendAgentLoopContinuation(
|
|
|
2164
2188
|
? "The previous stream ended before the agent sent a final completion signal."
|
|
2165
2189
|
: reason === "gateway_timeout"
|
|
2166
2190
|
? "The previous LLM call hit an upstream gateway timeout before the response finished streaming."
|
|
2167
|
-
: reason === "
|
|
2168
|
-
? "The previous LLM call was
|
|
2169
|
-
: reason === "
|
|
2170
|
-
? "The previous
|
|
2171
|
-
:
|
|
2191
|
+
: reason === "rate_limited"
|
|
2192
|
+
? "The previous LLM call was temporarily rate limited after exhausting its short provider retry budget."
|
|
2193
|
+
: reason === "network_interrupted"
|
|
2194
|
+
? "The previous LLM call was cut off by a transport-level interruption (socket dropped, connection reset, or stream closed unexpectedly)."
|
|
2195
|
+
: reason === "no_progress"
|
|
2196
|
+
? "The previous run stopped producing progress events while the connection stayed open."
|
|
2197
|
+
: "The previous run reached an internal execution budget.";
|
|
2172
2198
|
const actionInputNote = options.actionPreparationTool
|
|
2173
2199
|
? actionPreparationContinuationNote(options.actionPreparationTool)
|
|
2174
2200
|
: "";
|
|
@@ -2238,7 +2264,7 @@ export function isResumableEngineError(err: unknown): boolean {
|
|
|
2238
2264
|
text.includes("econnaborted") ||
|
|
2239
2265
|
text.includes("fetch failed") ||
|
|
2240
2266
|
text.includes("network error") ||
|
|
2241
|
-
text
|
|
2267
|
+
hasProviderConnectionErrorMessage(text) ||
|
|
2242
2268
|
text.includes("connection reset") ||
|
|
2243
2269
|
text.includes("connection closed") ||
|
|
2244
2270
|
text.includes("stream closed") ||
|
|
@@ -2251,6 +2277,34 @@ export function isResumableEngineError(err: unknown): boolean {
|
|
|
2251
2277
|
);
|
|
2252
2278
|
}
|
|
2253
2279
|
|
|
2280
|
+
/**
|
|
2281
|
+
* True only for transient provider throttling that may recover after one
|
|
2282
|
+
* cooled-down background continuation. This is deliberately narrower than
|
|
2283
|
+
* `isRetryableError`: daily/account caps are terminal, and generic retryable
|
|
2284
|
+
* transport errors keep using the normal resumable-error path.
|
|
2285
|
+
*
|
|
2286
|
+
* The engine has already spent its short in-call retry budget before this
|
|
2287
|
+
* helper is consulted. Callers must add their own small continuation cap so a
|
|
2288
|
+
* sustained provider limit cannot turn into an unbounded request storm.
|
|
2289
|
+
*/
|
|
2290
|
+
export function isTransientProviderRateLimitError(err: unknown): boolean {
|
|
2291
|
+
if (!(err instanceof EngineError)) return false;
|
|
2292
|
+
const code = (err.errorCode ?? "").toLowerCase();
|
|
2293
|
+
const text = errorSearchText(err);
|
|
2294
|
+
|
|
2295
|
+
if (
|
|
2296
|
+
code === "rate_limit_exceeded" ||
|
|
2297
|
+
text.includes("daily gateway request cap")
|
|
2298
|
+
) {
|
|
2299
|
+
return false;
|
|
2300
|
+
}
|
|
2301
|
+
if (err.statusCode === 429 || err.statusCode === 529) {
|
|
2302
|
+
return true;
|
|
2303
|
+
}
|
|
2304
|
+
if (code === "http_429" || code === "http_529") return true;
|
|
2305
|
+
return false;
|
|
2306
|
+
}
|
|
2307
|
+
|
|
2254
2308
|
/**
|
|
2255
2309
|
* Map a resumable error to the most descriptive continuation reason. Used
|
|
2256
2310
|
* when surfacing the resume to the agent and to clients via the
|
|
@@ -2825,6 +2879,9 @@ export interface ExecuteAgentToolCallOptions {
|
|
|
2825
2879
|
networkProtocol?: "a2a" | "mcp" | "provider-api";
|
|
2826
2880
|
networkId?: string;
|
|
2827
2881
|
networkPeer?: string;
|
|
2882
|
+
/** Bounded cross-app lineage used to prevent recursive delegation cycles. */
|
|
2883
|
+
delegationDepth?: number;
|
|
2884
|
+
visitedApps?: string[];
|
|
2828
2885
|
threadId?: string;
|
|
2829
2886
|
turnId?: string;
|
|
2830
2887
|
approvedToolCalls?: string[];
|
|
@@ -3735,6 +3792,8 @@ export async function runAgentLoop(opts: {
|
|
|
3735
3792
|
signal: AbortSignal;
|
|
3736
3793
|
/** Observe usage as each model response reports it, including aborted loops. */
|
|
3737
3794
|
onUsage?: (usage: AgentLoopUsage) => void;
|
|
3795
|
+
/** Observe the attempt's typed terminal state separately from chat events. */
|
|
3796
|
+
onOutcome?: (outcome: AgentLoopOutcome) => void;
|
|
3738
3797
|
ownerEmail?: string | null;
|
|
3739
3798
|
orgId?: string | null;
|
|
3740
3799
|
/** Action invocation attribution. Defaults to the normal agent tool loop. */
|
|
@@ -3753,6 +3812,9 @@ export async function runAgentLoop(opts: {
|
|
|
3753
3812
|
networkProtocol?: "a2a" | "mcp" | "provider-api";
|
|
3754
3813
|
networkId?: string;
|
|
3755
3814
|
networkPeer?: string;
|
|
3815
|
+
/** Bounded cross-app lineage used to prevent recursive delegation cycles. */
|
|
3816
|
+
delegationDepth?: number;
|
|
3817
|
+
visitedApps?: string[];
|
|
3756
3818
|
/**
|
|
3757
3819
|
* Attachments submitted with this turn (pasted text, files, images), passed
|
|
3758
3820
|
* through to each tool's `ActionRunContext.attachments` so actions can
|
|
@@ -3792,7 +3854,12 @@ export async function runAgentLoop(opts: {
|
|
|
3792
3854
|
* App-level default limits applied to every tool call unless the individual
|
|
3793
3855
|
* ActionEntry overrides them with its own timeoutMs / maxResultChars.
|
|
3794
3856
|
*/
|
|
3795
|
-
toolLimits?: {
|
|
3857
|
+
toolLimits?: {
|
|
3858
|
+
timeoutMs?: number;
|
|
3859
|
+
maxResultChars?: number;
|
|
3860
|
+
/** Absolute cap applied after action-level overrides. */
|
|
3861
|
+
hardMaxResultChars?: number;
|
|
3862
|
+
};
|
|
3796
3863
|
/**
|
|
3797
3864
|
* Stable approval keys granted by a human for actions declared
|
|
3798
3865
|
* `needsApproval`. A call whose key is present here runs even though the
|
|
@@ -3821,6 +3888,16 @@ export async function runAgentLoop(opts: {
|
|
|
3821
3888
|
send,
|
|
3822
3889
|
signal,
|
|
3823
3890
|
} = opts;
|
|
3891
|
+
let outcomeReported = false;
|
|
3892
|
+
const reportOutcome = (outcome: AgentLoopOutcome) => {
|
|
3893
|
+
if (outcomeReported) return;
|
|
3894
|
+
outcomeReported = true;
|
|
3895
|
+
try {
|
|
3896
|
+
opts.onOutcome?.(outcome);
|
|
3897
|
+
} catch {
|
|
3898
|
+
// Outcome observers are telemetry/protocol adapters and cannot alter the run.
|
|
3899
|
+
}
|
|
3900
|
+
};
|
|
3824
3901
|
const budgetStartedAt = opts.budgetStartedAt ?? Date.now();
|
|
3825
3902
|
const finalResponseGuardRequestText =
|
|
3826
3903
|
opts.finalResponseGuardRequestText ??
|
|
@@ -3951,6 +4028,7 @@ export async function runAgentLoop(opts: {
|
|
|
3951
4028
|
// `loop_limit` and `done` share one terminal-event slot in run-manager, so a
|
|
3952
4029
|
// trailing `done` would overwrite the boundary the continuation logic reads.
|
|
3953
4030
|
let endedAtLoopLimit = false;
|
|
4031
|
+
let terminalActionStop: { message: string; errorCode?: string } | null = null;
|
|
3954
4032
|
// Overridden (raised tokens, lowered effort) only after an empty-final-
|
|
3955
4033
|
// response retry below — kept separate from `opts.maxOutputTokens`/
|
|
3956
4034
|
// `opts.reasoningEffort` so the very first attempt is unaffected and later
|
|
@@ -5044,10 +5122,17 @@ export async function runAgentLoop(opts: {
|
|
|
5044
5122
|
runToolTimeoutCeilingMs > 0
|
|
5045
5123
|
? Math.min(requestedToolTimeoutMs, runToolTimeoutCeilingMs)
|
|
5046
5124
|
: requestedToolTimeoutMs;
|
|
5047
|
-
const
|
|
5125
|
+
const configuredToolMaxResultChars =
|
|
5048
5126
|
actionEntry.maxResultChars ??
|
|
5049
5127
|
opts.toolLimits?.maxResultChars ??
|
|
5050
5128
|
DEFAULT_TOOL_RESULT_CHARS;
|
|
5129
|
+
const toolMaxResultChars =
|
|
5130
|
+
typeof opts.toolLimits?.hardMaxResultChars === "number"
|
|
5131
|
+
? Math.min(
|
|
5132
|
+
configuredToolMaxResultChars,
|
|
5133
|
+
opts.toolLimits.hardMaxResultChars,
|
|
5134
|
+
)
|
|
5135
|
+
: configuredToolMaxResultChars;
|
|
5051
5136
|
|
|
5052
5137
|
// TOOL-CALL JOURNAL HARD-BLOCK (resume safety, tool-layer enforcement).
|
|
5053
5138
|
// The prompt-level resume journal already TELLS a resuming model not to
|
|
@@ -5406,6 +5491,8 @@ export async function runAgentLoop(opts: {
|
|
|
5406
5491
|
networkProtocol: opts.networkProtocol,
|
|
5407
5492
|
networkId: opts.networkId,
|
|
5408
5493
|
networkPeer: opts.networkPeer,
|
|
5494
|
+
delegationDepth: opts.delegationDepth,
|
|
5495
|
+
visitedApps: opts.visitedApps,
|
|
5409
5496
|
attachments: opts.attachments,
|
|
5410
5497
|
signal,
|
|
5411
5498
|
// Audit attribution: the action name + the agent thread/turn that
|
|
@@ -5702,6 +5789,7 @@ export async function runAgentLoop(opts: {
|
|
|
5702
5789
|
message: string;
|
|
5703
5790
|
errorCode?: string;
|
|
5704
5791
|
};
|
|
5792
|
+
terminalActionStop = stop;
|
|
5705
5793
|
send({ type: "text", text: stop.message });
|
|
5706
5794
|
break;
|
|
5707
5795
|
}
|
|
@@ -5712,6 +5800,9 @@ export async function runAgentLoop(opts: {
|
|
|
5712
5800
|
// ended on a guardrail, not a clean turn. The result hook still fires below
|
|
5713
5801
|
// so processors can observe the (halted) final text.
|
|
5714
5802
|
if (tripwire) {
|
|
5803
|
+
// TypeScript cannot see assignments performed by the processor callback
|
|
5804
|
+
// inside the loop, so preserve the runtime narrowing explicitly here.
|
|
5805
|
+
const terminalTripwire = tripwire as TripWire;
|
|
5715
5806
|
if (processorChain) {
|
|
5716
5807
|
try {
|
|
5717
5808
|
await processorChain.runResult(
|
|
@@ -5724,10 +5815,24 @@ export async function runAgentLoop(opts: {
|
|
|
5724
5815
|
// A result-hook abort is a no-op: the run is already halting.
|
|
5725
5816
|
}
|
|
5726
5817
|
}
|
|
5818
|
+
reportOutcome({
|
|
5819
|
+
state: "failed",
|
|
5820
|
+
code:
|
|
5821
|
+
terminalTripwire.processor === "run-input-token-budget"
|
|
5822
|
+
? "budget_exhausted"
|
|
5823
|
+
: terminalTripwire.processor
|
|
5824
|
+
? `guardrail:${terminalTripwire.processor}`
|
|
5825
|
+
: "guardrail",
|
|
5826
|
+
// Re-running the same request with the same deterministic guardrail
|
|
5827
|
+
// would reproduce the stop. A caller can issue a smaller follow-up, but
|
|
5828
|
+
// must not automatically replay this turn.
|
|
5829
|
+
retryable: false,
|
|
5830
|
+
message: terminalTripwire.message,
|
|
5831
|
+
});
|
|
5727
5832
|
return usage;
|
|
5728
5833
|
}
|
|
5729
5834
|
|
|
5730
|
-
if (!signal.aborted && !endedAtLoopLimit) {
|
|
5835
|
+
if (!signal.aborted && !endedAtLoopLimit && !terminalActionStop) {
|
|
5731
5836
|
// In-loop processor seam (result hook). Fires once at clean run end with the
|
|
5732
5837
|
// final assistant text so processors (e.g. a proof-of-done gate) can record
|
|
5733
5838
|
// a verdict. A result-hook abort cannot un-finish a completed run, so a
|
|
@@ -5772,6 +5877,32 @@ export async function runAgentLoop(opts: {
|
|
|
5772
5877
|
}
|
|
5773
5878
|
}
|
|
5774
5879
|
}
|
|
5880
|
+
|
|
5881
|
+
if (signal.aborted) {
|
|
5882
|
+
reportOutcome({ state: "canceled", message: "Agent run was aborted." });
|
|
5883
|
+
} else if (endedAtLoopLimit) {
|
|
5884
|
+
reportOutcome({
|
|
5885
|
+
state: "failed",
|
|
5886
|
+
code: "loop_limit",
|
|
5887
|
+
retryable: false,
|
|
5888
|
+
message: `Agent stopped after ${maxIterations} iterations.`,
|
|
5889
|
+
});
|
|
5890
|
+
} else if (terminalActionStop?.errorCode === "needs-approval") {
|
|
5891
|
+
reportOutcome({
|
|
5892
|
+
state: "input_required",
|
|
5893
|
+
code: "needs_approval",
|
|
5894
|
+
message: terminalActionStop.message,
|
|
5895
|
+
});
|
|
5896
|
+
} else if (terminalActionStop) {
|
|
5897
|
+
reportOutcome({
|
|
5898
|
+
state: "failed",
|
|
5899
|
+
code: terminalActionStop.errorCode ?? "tool_failed",
|
|
5900
|
+
retryable: false,
|
|
5901
|
+
message: terminalActionStop.message,
|
|
5902
|
+
});
|
|
5903
|
+
} else {
|
|
5904
|
+
reportOutcome({ state: "completed" });
|
|
5905
|
+
}
|
|
5775
5906
|
return usage;
|
|
5776
5907
|
}
|
|
5777
5908
|
|
|
@@ -5806,7 +5937,7 @@ function isRecoverableContinuationError(event: {
|
|
|
5806
5937
|
code === "http_529" ||
|
|
5807
5938
|
code === "run_timeout" ||
|
|
5808
5939
|
message.includes("timeout") ||
|
|
5809
|
-
message
|
|
5940
|
+
hasProviderConnectionErrorMessage(message) ||
|
|
5810
5941
|
message.includes("temporarily unavailable")
|
|
5811
5942
|
);
|
|
5812
5943
|
}
|
|
@@ -7103,7 +7234,9 @@ function progressStepFromAgentChatEvent(event: AgentChatEvent): string | null {
|
|
|
7103
7234
|
? `Calling ${event.agent}.`
|
|
7104
7235
|
: event.status === "done"
|
|
7105
7236
|
? `Finished ${event.agent}.`
|
|
7106
|
-
:
|
|
7237
|
+
: event.status === "pending"
|
|
7238
|
+
? `${event.agent} is still working.`
|
|
7239
|
+
: `${event.agent} failed.`;
|
|
7107
7240
|
case "agent_task":
|
|
7108
7241
|
return event.status === "running"
|
|
7109
7242
|
? "Started background task."
|