@agent-native/core 0.92.12 → 0.93.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +39 -0
- package/corpus/core/docs/content/automation-connectors.mdx +80 -0
- package/corpus/core/docs/content/extensions.mdx +8 -0
- package/corpus/core/docs/content/locales/ar-SA/extensions.mdx +8 -0
- package/corpus/core/docs/content/locales/ar-SA/messaging.mdx +84 -15
- package/corpus/core/docs/content/locales/ar-SA/template-clips.mdx +1 -0
- package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +1 -0
- package/corpus/core/docs/content/locales/de-DE/extensions.mdx +10 -0
- package/corpus/core/docs/content/locales/de-DE/messaging.mdx +92 -15
- package/corpus/core/docs/content/locales/de-DE/template-clips.mdx +1 -0
- package/corpus/core/docs/content/locales/de-DE/template-design.mdx +1 -0
- package/corpus/core/docs/content/locales/es-ES/extensions.mdx +10 -0
- package/corpus/core/docs/content/locales/es-ES/messaging.mdx +91 -15
- package/corpus/core/docs/content/locales/es-ES/template-clips.mdx +1 -0
- package/corpus/core/docs/content/locales/es-ES/template-design.mdx +1 -0
- package/corpus/core/docs/content/locales/fr-FR/extensions.mdx +10 -0
- package/corpus/core/docs/content/locales/fr-FR/messaging.mdx +91 -15
- package/corpus/core/docs/content/locales/fr-FR/template-clips.mdx +1 -0
- package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +1 -0
- package/corpus/core/docs/content/locales/hi-IN/extensions.mdx +8 -0
- package/corpus/core/docs/content/locales/hi-IN/messaging.mdx +81 -15
- package/corpus/core/docs/content/locales/hi-IN/template-clips.mdx +1 -0
- package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +1 -0
- package/corpus/core/docs/content/locales/ja-JP/extensions.mdx +9 -0
- package/corpus/core/docs/content/locales/ja-JP/messaging.mdx +81 -15
- package/corpus/core/docs/content/locales/ja-JP/template-clips.mdx +1 -0
- package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +1 -0
- package/corpus/core/docs/content/locales/ko-KR/extensions.mdx +8 -0
- package/corpus/core/docs/content/locales/ko-KR/messaging.mdx +80 -15
- package/corpus/core/docs/content/locales/ko-KR/template-clips.mdx +1 -0
- package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +1 -0
- package/corpus/core/docs/content/locales/pt-BR/extensions.mdx +9 -0
- package/corpus/core/docs/content/locales/pt-BR/messaging.mdx +88 -15
- package/corpus/core/docs/content/locales/pt-BR/template-clips.mdx +1 -0
- package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +1 -0
- package/corpus/core/docs/content/locales/zh-CN/extensions.mdx +6 -0
- package/corpus/core/docs/content/locales/zh-CN/messaging.mdx +78 -15
- package/corpus/core/docs/content/locales/zh-CN/template-clips.mdx +1 -0
- package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +1 -0
- package/corpus/core/docs/content/locales/zh-TW/extensions.mdx +6 -0
- package/corpus/core/docs/content/locales/zh-TW/messaging.mdx +78 -15
- package/corpus/core/docs/content/locales/zh-TW/template-clips.mdx +1 -0
- package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +1 -0
- package/corpus/core/docs/content/messaging.mdx +227 -45
- package/corpus/core/docs/content/template-clips.mdx +3 -0
- package/corpus/core/docs/content/template-design.mdx +4 -0
- package/corpus/core/package.json +5 -1
- package/corpus/core/src/a2a/artifact-response.ts +131 -2
- package/corpus/core/src/a2a/client.ts +10 -0
- package/corpus/core/src/a2a/handlers.ts +40 -76
- package/corpus/core/src/a2a/types.ts +2 -0
- package/corpus/core/src/agent/durable-background.ts +24 -0
- package/corpus/core/src/agent/production-agent.ts +15 -3
- package/corpus/core/src/agent/run-manager.ts +130 -10
- package/corpus/core/src/agent/run-store.ts +225 -15
- package/corpus/core/src/agent/types.ts +23 -0
- package/corpus/core/src/audit/record.ts +31 -0
- package/corpus/core/src/audit/store.ts +69 -3
- package/corpus/core/src/audit/types.ts +13 -0
- package/corpus/core/src/automation/index.ts +802 -0
- package/corpus/core/src/cli/create.ts +12 -5
- package/corpus/core/src/cli/design-connect.ts +596 -36
- package/corpus/core/src/client/AgentPanel.tsx +51 -6
- package/corpus/core/src/client/AssistantChat.tsx +274 -147
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +3 -0
- package/corpus/core/src/client/RunStuckBanner.tsx +69 -20
- package/corpus/core/src/client/agent-chat-adapter.ts +54 -5
- package/corpus/core/src/client/automation.ts +22 -0
- package/corpus/core/src/client/chat/run-recovery.tsx +67 -50
- package/corpus/core/src/client/composer/TiptapComposer.tsx +8 -0
- package/corpus/core/src/client/index.ts +30 -0
- package/corpus/core/src/client/integrations/api.ts +295 -0
- package/corpus/core/src/client/integrations/index.ts +26 -0
- package/corpus/core/src/client/transcription/use-live-transcription.ts +68 -5
- package/corpus/core/src/client/use-run-stuck-detection.ts +41 -3
- package/corpus/core/src/deploy/build.ts +59 -3
- package/corpus/core/src/deploy/workspace-deploy.ts +37 -2
- package/corpus/core/src/file-upload/types.ts +2 -0
- package/corpus/core/src/index.ts +37 -0
- package/corpus/core/src/integrations/a2a-continuations-store.ts +6 -4
- package/corpus/core/src/integrations/adapters/discord.ts +362 -0
- package/corpus/core/src/integrations/adapters/index.ts +29 -0
- package/corpus/core/src/integrations/adapters/microsoft-teams.ts +411 -0
- package/corpus/core/src/integrations/adapters/slack.ts +861 -27
- package/corpus/core/src/integrations/adapters/telegram.ts +54 -15
- package/corpus/core/src/integrations/adapters/whatsapp.ts +41 -17
- package/corpus/core/src/integrations/catalog.ts +571 -0
- package/corpus/core/src/integrations/controls-store.ts +187 -0
- package/corpus/core/src/integrations/index.ts +100 -0
- package/corpus/core/src/integrations/installations-store.ts +677 -0
- package/corpus/core/src/integrations/integration-memory.ts +187 -0
- package/corpus/core/src/integrations/pending-tasks-retry-job.ts +6 -6
- package/corpus/core/src/integrations/pending-tasks-store.ts +83 -5
- package/corpus/core/src/integrations/plugin.ts +685 -47
- package/corpus/core/src/integrations/scope-store.ts +498 -0
- package/corpus/core/src/integrations/slack-manifest.ts +78 -0
- package/corpus/core/src/integrations/slack-oauth.ts +343 -0
- package/corpus/core/src/integrations/types.ts +179 -0
- package/corpus/core/src/integrations/usage-budget-store.ts +906 -0
- package/corpus/core/src/integrations/webhook-handler.ts +562 -51
- package/corpus/core/src/jobs/scheduler.ts +100 -2
- package/corpus/core/src/jobs/tools.ts +45 -9
- package/corpus/core/src/provider-api/index.ts +72 -1
- package/corpus/core/src/resources/handlers.ts +88 -14
- package/corpus/core/src/resources/script-helpers.ts +36 -7
- package/corpus/core/src/resources/store.ts +59 -52
- package/corpus/core/src/scripts/call-agent.ts +107 -1
- package/corpus/core/src/server/agent-chat-plugin.ts +294 -119
- package/corpus/core/src/server/auth.ts +10 -14
- package/corpus/core/src/server/builder-design-systems.ts +16 -1
- package/corpus/core/src/server/edge.ts +18 -0
- package/corpus/core/src/server/index.ts +26 -0
- package/corpus/core/src/server/request-context.ts +18 -0
- package/corpus/core/src/server/social-og-image.ts +3 -2
- package/corpus/core/src/styles/agent-native.css +62 -44
- package/corpus/core/src/templates/default/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/corpus/core/src/templates/default/AGENTS.md +7 -3
- package/corpus/core/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +1 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/corpus/core/src/templates/workspace-core/.agents/skills/extension-points/SKILL.md +6 -3
- package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +25 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +15 -0
- package/corpus/core/src/templates/workspace-core/AGENTS.md +3 -2
- package/corpus/core/src/usage/store.ts +37 -2
- package/corpus/templates/analytics/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/corpus/templates/analytics/.agents/skills/provider-api/SKILL.md +23 -0
- package/corpus/templates/analytics/.builder/skills/provider-api/SKILL.md +15 -0
- package/corpus/templates/analytics/actions/save-monitor.ts +25 -2
- package/corpus/templates/analytics/app/lib/data-sources.ts +28 -0
- package/corpus/templates/analytics/changelog/2026-07-10-agent-created-uptime-monitors-now-return-a-direct-link-to-th.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-dashboard-email-reports-still-arrive-when-screenshot-capture-temporarily-fails.md +6 -0
- package/corpus/templates/analytics/server/jobs/dashboard-report.ts +3 -7
- package/corpus/templates/analytics/server/lib/credential-keys.ts +12 -0
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +5 -1
- package/corpus/templates/analytics/server/lib/provider-credentials.ts +2 -0
- package/corpus/templates/analytics/server/routes/api/test-connection.post.ts +16 -0
- package/corpus/templates/assets/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/corpus/templates/brain/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/corpus/templates/calendar/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/corpus/templates/calendar/app/components/calendar/CommandPalette.tsx +98 -108
- package/corpus/templates/calendar/app/components/calendar/EventAttendeesSection.tsx +97 -90
- package/corpus/templates/calendar/changelog/2026-07-10-event-guest-details-and-option-menus-now-use-valid-accessibl.md +6 -0
- package/corpus/templates/calendar/changelog/2026-07-10-natural-language-event-phrases-stay-available-as-quick-creat.md +6 -0
- package/corpus/templates/chat/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/corpus/templates/chat/changelog/2026-07-10-chat-now-makes-ai-connection-setup-clear-without-shifting-th.md +6 -0
- package/corpus/templates/clips/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/corpus/templates/clips/.agents/skills/recording/SKILL.md +17 -1
- package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +8 -0
- package/corpus/templates/clips/AGENTS.md +8 -3
- package/corpus/templates/clips/actions/finalize-recording.ts +63 -23
- package/corpus/templates/clips/actions/get-recording-player-data.ts +6 -2
- package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +72 -9
- package/corpus/templates/clips/actions/list-recordings.ts +19 -3
- package/corpus/templates/clips/actions/navigate.ts +2 -0
- package/corpus/templates/clips/actions/reprocess-recording.ts +20 -6
- package/corpus/templates/clips/actions/request-transcript.ts +16 -31
- package/corpus/templates/clips/actions/view-screen.ts +57 -5
- package/corpus/templates/clips/app/components/layout/Header.tsx +1 -0
- package/corpus/templates/clips/app/components/library/empty-state.tsx +2 -0
- package/corpus/templates/clips/app/components/library/library-grid.tsx +69 -42
- package/corpus/templates/clips/app/components/library/library-layout.tsx +15 -1
- package/corpus/templates/clips/app/components/library/recording-card.tsx +81 -68
- package/corpus/templates/clips/app/components/library/search-bar.tsx +4 -3
- package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +9 -3
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +1 -1
- package/corpus/templates/clips/app/hooks/use-library.ts +1 -1
- package/corpus/templates/clips/app/hooks/use-navigation-state.ts +10 -2
- package/corpus/templates/clips/app/i18n/ar-SA.ts +7 -1
- package/corpus/templates/clips/app/i18n/de-DE.ts +7 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +7 -1
- package/corpus/templates/clips/app/i18n/es-ES.ts +7 -1
- package/corpus/templates/clips/app/i18n/fr-FR.ts +7 -1
- package/corpus/templates/clips/app/i18n/hi-IN.ts +7 -1
- package/corpus/templates/clips/app/i18n/ja-JP.ts +7 -1
- package/corpus/templates/clips/app/i18n/ko-KR.ts +7 -1
- package/corpus/templates/clips/app/i18n/pt-BR.ts +7 -1
- package/corpus/templates/clips/app/i18n/zh-CN.ts +8 -1
- package/corpus/templates/clips/app/i18n/zh-TW.ts +8 -1
- package/corpus/templates/clips/app/lib/recording-visibility.ts +70 -0
- package/corpus/templates/clips/app/routes/_app.shared.tsx +20 -0
- package/corpus/templates/clips/app/routes/download.tsx +24 -8
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +115 -2
- package/corpus/templates/clips/app/routes/record.tsx +62 -0
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +25 -16
- package/corpus/templates/clips/changelog/2026-07-10-clips-desktop-is-now-available-for-linux-with-appimage-debia.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-clips-downloads-updates-sooner-in-the-background-and-offers-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-clips-shared-with-you-now-appear-in-a-searchable-shared-with.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-clips-with-missing-mobile-video-frames-can-be-repaired-witho.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-mobile-camera-recordings-pause-while-backgrounded.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-mp4-downloads-now-show-progress-immediately-after-the-option.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-recording-pages-now-open-as-soon-as-you-stop-with-a-share-li.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-recordings-now-seek-smoothly-downloads-use-the-correct-file-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-s3-compatible-storage-now-saves-hosted-recordings-without-re.md +6 -0
- package/corpus/templates/clips/desktop/README.md +22 -6
- package/corpus/templates/clips/desktop/package.json +1 -1
- package/corpus/templates/clips/desktop/src/app.tsx +32 -19
- package/corpus/templates/clips/desktop/src/components/ReadinessPanel.tsx +15 -9
- package/corpus/templates/clips/desktop/src/lib/finalization-guard.ts +22 -0
- package/corpus/templates/clips/desktop/src/lib/permissions.ts +3 -1
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +97 -120
- package/corpus/templates/clips/desktop/src/lib/updater.ts +26 -4
- package/corpus/templates/clips/desktop/src/overlays/finalizing.tsx +4 -8
- package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +1 -1
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +2 -2
- package/corpus/templates/clips/desktop/src-tauri/src/permission_status.rs +11 -7
- package/corpus/templates/clips/desktop/src-tauri/tauri.linux.conf.json +11 -0
- package/corpus/templates/clips/netlify.toml +3 -0
- package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +106 -0
- package/corpus/templates/clips/server/lib/public-agent-context.ts +9 -1
- package/corpus/templates/clips/server/lib/resumable-upload-provider.ts +52 -0
- package/corpus/templates/clips/server/lib/s3-upload-provider.ts +433 -85
- package/corpus/templates/clips/server/lib/video-remux.ts +114 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +109 -0
- package/corpus/templates/clips/server/routes/api/clips-updater.json.get.ts +22 -11
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +4 -2
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +47 -5
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +10 -2
- package/corpus/templates/clips/shared/share-loader-response.ts +12 -0
- package/corpus/templates/clips/shared/transcript-status.ts +40 -0
- package/corpus/templates/content/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/corpus/templates/content/.agents/skills/content/SKILL.md +57 -5
- package/corpus/templates/content/AGENTS.md +65 -55
- package/corpus/templates/content/actions/_builder-cms-read-client.ts +10 -16
- package/corpus/templates/content/actions/_database-source-utils.ts +58 -11
- package/corpus/templates/content/actions/_property-utils.ts +30 -2
- package/corpus/templates/content/actions/add-content-database-source-field-property.ts +312 -114
- package/corpus/templates/content/actions/submit-content-database-form.ts +497 -0
- package/corpus/templates/content/actions/update-content-database-view.ts +8 -1
- package/corpus/templates/content/actions/view-screen.ts +4 -1
- package/corpus/templates/content/agent-native.app-skill.json +1 -1
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +250 -64
- package/corpus/templates/content/app/components/editor/database/FormView.tsx +460 -0
- package/corpus/templates/content/app/components/editor/database/navigation-state.ts +3 -0
- package/corpus/templates/content/app/components/editor/database/settings.tsx +30 -37
- package/corpus/templates/content/app/components/editor/database/shared.tsx +2 -0
- package/corpus/templates/content/app/components/editor/database/view-config.ts +29 -1
- package/corpus/templates/content/app/components/ui/textarea.tsx +1 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +22 -0
- package/corpus/templates/content/app/i18n/zh-TW.ts +21 -0
- package/corpus/templates/content/app/i18n-data.ts +225 -0
- package/corpus/templates/content/changelog/2026-07-10-builder-backed-properties-now-load-current-source-values-as-.md +6 -0
- package/corpus/templates/content/changelog/2026-07-10-builder-database-refreshes-now-stay-explicit-and-accurate.md +6 -0
- package/corpus/templates/content/changelog/2026-07-10-database-form-views-now-collect-ordered-required-answers-and.md +6 -0
- package/corpus/templates/content/changelog/2026-07-10-database-tables-now-use-a-quieter-more-compact-layout-with-c.md +6 -0
- package/corpus/templates/content/changelog/2026-07-10-slack-intake-routes-to-content-database-forms.md +6 -0
- package/corpus/templates/content/parity/matrix.md +1 -0
- package/corpus/templates/content/parity/matrix.ts +18 -0
- package/corpus/templates/content/shared/api.ts +27 -1
- package/corpus/templates/content/shared/database-form.ts +53 -0
- package/corpus/templates/design/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +26 -0
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +85 -12
- package/corpus/templates/design/AGENTS.md +72 -18
- package/corpus/templates/design/DESIGN.md +1 -1
- package/corpus/templates/design/DEVELOPING.md +1 -1
- package/corpus/templates/design/FIGMA_INTEROPERABILITY.md +116 -0
- package/corpus/templates/design/actions/create-design-from-template.ts +220 -0
- package/corpus/templates/design/actions/create-design-system.ts +92 -16
- package/corpus/templates/design/actions/delete-design-template.ts +28 -0
- package/corpus/templates/design/actions/delete-file.ts +7 -0
- package/corpus/templates/design/actions/edit-design.ts +3 -0
- package/corpus/templates/design/actions/export-design-as-figma-svg.ts +137 -5
- package/corpus/templates/design/actions/export-pdf.ts +1 -1
- package/corpus/templates/design/actions/generate-design.ts +3 -0
- package/corpus/templates/design/actions/get-design-snapshot.ts +9 -0
- package/corpus/templates/design/actions/get-figma-connection-status.ts +26 -0
- package/corpus/templates/design/actions/get-figma-design-context.ts +138 -0
- package/corpus/templates/design/actions/get-figma-styles.ts +2 -2
- package/corpus/templates/design/actions/import-figma-clipboard.ts +112 -16
- package/corpus/templates/design/actions/import-figma-frame.ts +15 -4
- package/corpus/templates/design/actions/index-design-system-with-builder.ts +4 -0
- package/corpus/templates/design/actions/list-design-templates.ts +118 -0
- package/corpus/templates/design/actions/navigate.ts +16 -2
- package/corpus/templates/design/actions/provider-api-request.ts +11 -1
- package/corpus/templates/design/actions/save-design-as-template.ts +156 -0
- package/corpus/templates/design/actions/set-active-breakpoint.ts +13 -4
- package/corpus/templates/design/actions/take-design-screenshot.ts +73 -3
- package/corpus/templates/design/actions/update-file.ts +39 -22
- package/corpus/templates/design/actions/view-screen.ts +36 -1
- package/corpus/templates/design/actions/write-local-file.ts +50 -38
- package/corpus/templates/design/app/components/design/AutoLayoutSuggestionDialog.tsx +151 -0
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +20 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +251 -22
- package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +3 -3
- package/corpus/templates/design/app/components/design/DesignImportPanel.tsx +384 -9
- package/corpus/templates/design/app/components/design/EditPanel.tsx +105 -32
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +58 -28
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +6 -0
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +539 -53
- package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +40 -0
- package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +1 -0
- package/corpus/templates/design/app/components/design/code-workbench/explorer/ExplorerView.tsx +1 -0
- package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +5 -1
- package/corpus/templates/design/app/components/design/code-workbench/workspace/create-providers.ts +2 -0
- package/corpus/templates/design/app/components/design/code-workbench/workspace/localhost-provider.ts +3 -1
- package/corpus/templates/design/app/components/design/code-workbench/workspace/types.ts +2 -0
- package/corpus/templates/design/app/components/design/edit-panel/element-identity.ts +19 -0
- package/corpus/templates/design/app/components/design/edit-panel/frame-presets-panel.tsx +1 -0
- package/corpus/templates/design/app/components/design/edit-panel/interaction-state-helpers.ts +27 -0
- package/corpus/templates/design/app/components/design/inspector/InteractionStatePanel.tsx +137 -81
- package/corpus/templates/design/app/components/design/inspector/frame-size-presets.ts +25 -5
- package/corpus/templates/design/app/components/design/multi-screen/chrome-transitions.ts +1 -1
- package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +220 -3
- package/corpus/templates/design/app/components/design/multi-screen/overview-layout.ts +13 -0
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +22 -1
- package/corpus/templates/design/app/components/design/types.ts +4 -0
- package/corpus/templates/design/app/components/design-system/ProductionDesignSystemShowcase.tsx +208 -0
- package/corpus/templates/design/app/components/editor/FigmaLinkComposerBubble.tsx +321 -0
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +24 -4
- package/corpus/templates/design/app/components/layout/Layout.tsx +16 -2
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +2 -0
- package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +72 -0
- package/corpus/templates/design/app/global.css +2 -35
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +10 -0
- package/corpus/templates/design/app/i18n/zh-TW.ts +127 -5
- package/corpus/templates/design/app/i18n-breakpoints.ts +209 -0
- package/corpus/templates/design/app/i18n-data.ts +1317 -59
- package/corpus/templates/design/app/i18n-template-feature.ts +458 -0
- package/corpus/templates/design/app/lib/design-clipboard.ts +202 -0
- package/corpus/templates/design/app/lib/design-file-upload.ts +87 -0
- package/corpus/templates/design/app/lib/design-import.ts +168 -11
- package/corpus/templates/design/app/lib/desktop-design-preview.ts +423 -0
- package/corpus/templates/design/app/lib/figma-clipboard.ts +74 -8
- package/corpus/templates/design/app/lib/figma-connection.ts +161 -0
- package/corpus/templates/design/app/lib/figma-svg-copy.ts +814 -22
- package/corpus/templates/design/app/lib/figma-url.ts +77 -0
- package/corpus/templates/design/app/lib/pending-generation.ts +35 -0
- package/corpus/templates/design/app/pages/DesignSystems.tsx +236 -177
- package/corpus/templates/design/app/pages/Index.tsx +38 -0
- package/corpus/templates/design/app/pages/Templates.tsx +498 -0
- package/corpus/templates/design/app/pages/design-editor/auto-layout-suggestion.ts +328 -0
- package/corpus/templates/design/app/pages/design-editor/clone-idrefs.ts +113 -0
- package/corpus/templates/design/app/pages/design-editor/created-screen-navigation.ts +55 -0
- package/corpus/templates/design/app/pages/design-editor/editor-session.ts +32 -0
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +49 -2
- package/corpus/templates/design/app/pages/design-editor/export-capture.ts +296 -0
- package/corpus/templates/design/app/pages/design-editor/history.ts +101 -2
- package/corpus/templates/design/app/pages/design-editor/layout-operations.ts +28 -1
- package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +34 -0
- package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +202 -6
- package/corpus/templates/design/app/pages/design-editor/pending-structure-verification.ts +92 -0
- package/corpus/templates/design/app/pages/design-editor/save-failure.ts +58 -0
- package/corpus/templates/design/app/routes/templates.tsx +4 -6
- package/corpus/templates/design/changelog/2026-07-10-app-workspaces-now-use-clean-borderless-main-surfaces-throug.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-ask-chat-what-s-in-a-figma-file-or-frame-structure-screensho.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-canvas-edits-now-reject-malformed-html-before-it-can-corrupt.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-complex-designs-now-export-as-valid-secure-svgs-and-crisp-ra.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-complex-figma-masks-arcs-rich-text-transformed-images-and-ad.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-copied-layers-paste-across-designs-and-browser-tabs.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-copy-and-download-editable-figma-svg.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-copying-design-text-now-pastes-readable-text-into-other-apps.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-deleted-screens-can-be-restored-with-undo-and-removed-again-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-design-changes-now-save-before-switching-apps-and-retry-when.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-design-stays-usable-on-phones-by-keeping-editor-panels-and-f.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-download-all-screens-as-one-multi-page-pdf-from-the-overview.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-duplicated-layers-now-keep-labels-aria-relationships-fragmen.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-fig-import-results-stay-compact.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-figma-imports-now-load-real-fonts-fix-rotated-gradient-dashe.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-figma-links-in-chat-and-the-import-tab-now-offer-secure-one-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-fixed-cmd-z-not-restoring-content-after-an-agent-driven-desi.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-fixed-download-pdf-being-unreachable-from-the-export-panel-e.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-fixed-dragging-a-layer-out-of-an-auto-layout-row-column-no-l.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-fixed-figma-svg-export-text-wrapping-sizing-and-inner-layer.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-fixed-hiding-or-locking-one-layer-no-longer-hides-or-blocks-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-fixed-png-screenshots-of-tall-screens-being-cropped-to-one-v.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-fixed-png-svg-exports-capturing-broken-layout-when-webfonts-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-frame-tool-now-offers-standard-ad-unit-size-presets-medium-r.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-full-view-controls-stay-within-their-frame-instead-of-coveri.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-hover-focus-focus-visible-pressed-and-disabled-states-now-pr.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-layer-drops-now-land-in-the-intended-grid-row-stay-visually-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-local-code-workspaces-now-keep-unsaved-edits-across-panel-sw.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-local-visual-editing-now-keeps-authenticated-sessions-shared.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-long-running-agent-work-no-longer-shows-a-premature-stuck-wa.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-managed-figma-connections-are-recognized-automatically.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-new-designs-can-open-directly-in-the-editor-without-a-pr.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-new-screens-are-selected-and-revealed-immediately.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-new-text-layers-undo-as-one-safe-creation.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-preview-and-apply-inferred-auto-layout-without-changing-yo.md +5 -0
- package/corpus/templates/design/changelog/2026-07-10-print-pdf-exports-and-paper-size-presets-letter-a4-now-match.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-responsive-frame-editing.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-reusable-design-templates.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-screen-overview-frames-now-use-a-clearer-interact-action-wit.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-start-designs-from-source-linked-material-3-carbon-or-primer.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-tweaks-guidance.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-uploaded-fig-files-can-now-become-editable-design-screens-wi.md +6 -0
- package/corpus/templates/design/e2e/helpers.ts +3 -3
- package/corpus/templates/design/package.json +2 -0
- package/corpus/templates/design/scripts/qa-figma-stress-import.ts +96 -0
- package/corpus/templates/design/server/db/index.ts +10 -0
- package/corpus/templates/design/server/db/schema.ts +44 -0
- package/corpus/templates/design/server/handlers/import-design-file.ts +114 -80
- package/corpus/templates/design/server/handlers/index-design-system-with-builder.ts +19 -6
- package/corpus/templates/design/server/lib/design-export.ts +240 -3
- package/corpus/templates/design/server/lib/design-template-data.ts +89 -0
- package/corpus/templates/design/server/lib/design-to-figma-svg.ts +250 -26
- package/corpus/templates/design/server/lib/fig-file-decoder.ts +839 -0
- package/corpus/templates/design/server/lib/fig-file-import.ts +287 -0
- package/corpus/templates/design/server/lib/fig-file-limits.ts +3 -0
- package/corpus/templates/design/server/lib/fig-file-to-html.ts +2568 -0
- package/corpus/templates/design/server/lib/figma-design-context.ts +359 -0
- package/corpus/templates/design/server/lib/figma-node-import.ts +478 -22
- package/corpus/templates/design/server/lib/figma-node-to-html.ts +554 -29
- package/corpus/templates/design/server/lib/local-figma-qa-upload.ts +112 -0
- package/corpus/templates/design/server/lib/verify-write-grant.ts +16 -2
- package/corpus/templates/design/server/lib/visible-clipboard-html.ts +13 -3
- package/corpus/templates/design/server/plugins/agent-chat.ts +7 -0
- package/corpus/templates/design/server/plugins/db.ts +42 -0
- package/corpus/templates/design/server/plugins/local-figma-qa-upload.ts +7 -0
- package/corpus/templates/design/server/register-secrets.ts +8 -8
- package/corpus/templates/design/server/routes/api/qa-figma-import-assets/[assetId].get.ts +46 -0
- package/corpus/templates/design/server/source-workspace.ts +104 -12
- package/corpus/templates/design/shared/code-layer.ts +105 -28
- package/corpus/templates/design/shared/design-system-templates.ts +301 -0
- package/corpus/templates/design/shared/design-template-presets.ts +195 -0
- package/corpus/templates/design/shared/figma-url.ts +8 -0
- package/corpus/templates/design/shared/html-integrity.ts +306 -0
- package/corpus/templates/design/shared/interaction-states.ts +318 -23
- package/corpus/templates/design/shared/locked-layers.ts +151 -0
- package/corpus/templates/dispatch/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/corpus/templates/dispatch/app/i18n/zh-TW.ts +48 -0
- package/corpus/templates/dispatch/app/i18n-data.ts +536 -1
- package/corpus/templates/dispatch/changelog/2026-07-10-connect-slack-workspaces-with-oauth-and-manage-channel-ident.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-10-microsoft-teams-bots-and-discord-slash-commands-can-now-conn.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-10-slack-and-telegram-now-route-uptime-monitor-requests-to-anal.md +6 -0
- package/corpus/templates/forms/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/corpus/templates/forms/.agents/skills/form-publishing/SKILL.md +7 -0
- package/corpus/templates/forms/AGENTS.md +4 -0
- package/corpus/templates/forms/actions/create-form.ts +44 -7
- package/corpus/templates/forms/actions/lib/assert-publishable-form.ts +38 -0
- package/corpus/templates/forms/actions/patch-form-fields.ts +4 -0
- package/corpus/templates/forms/actions/update-form.ts +2 -36
- package/corpus/templates/forms/app/i18n/ar-SA.ts +3 -0
- package/corpus/templates/forms/app/i18n/de-DE.ts +3 -0
- package/corpus/templates/forms/app/i18n/en-US.ts +3 -0
- package/corpus/templates/forms/app/i18n/es-ES.ts +3 -0
- package/corpus/templates/forms/app/i18n/fr-FR.ts +3 -0
- package/corpus/templates/forms/app/i18n/hi-IN.ts +3 -0
- package/corpus/templates/forms/app/i18n/ja-JP.ts +3 -0
- package/corpus/templates/forms/app/i18n/ko-KR.ts +3 -0
- package/corpus/templates/forms/app/i18n/pt-BR.ts +3 -0
- package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
- package/corpus/templates/forms/app/i18n/zh-TW.ts +3 -0
- package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +17 -0
- package/corpus/templates/forms/changelog/2026-07-10-agent-created-published-forms-now-return-the-anonymous-publi.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-10-published-forms-can-no-longer-be-edited-into-an-unusable-emp.md +6 -0
- package/corpus/templates/forms/server/handlers/submissions.ts +4 -3
- package/corpus/templates/forms/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/forms/shared/types.ts +5 -0
- package/corpus/templates/mail/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +2 -2
- package/corpus/templates/mail/changelog/2026-07-10-mail-navigation-now-uses-a-clean-borderless-drawer.md +6 -0
- package/corpus/templates/plan/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/corpus/templates/plan/app/lib/plan-local-bridge.ts +4 -1
- package/corpus/templates/plan/changelog/2026-07-10-local-plans-now-keep-valid-content-visible-when-one-generate.md +6 -0
- package/corpus/templates/plan/server/lib/local-plan-files.ts +4 -1
- package/corpus/templates/slides/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/dist/a2a/artifact-response.d.ts.map +1 -1
- package/dist/a2a/artifact-response.js +88 -2
- package/dist/a2a/artifact-response.js.map +1 -1
- package/dist/a2a/client.d.ts +9 -0
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +1 -0
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +24 -69
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/types.d.ts +2 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/agent/durable-background.d.ts +11 -0
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +17 -0
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/production-agent.d.ts +2 -2
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +15 -5
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +44 -2
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +90 -9
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +109 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +206 -15
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/types.d.ts +22 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/audit/record.d.ts.map +1 -1
- package/dist/audit/record.js +29 -0
- package/dist/audit/record.js.map +1 -1
- package/dist/audit/store.d.ts.map +1 -1
- package/dist/audit/store.js +62 -3
- package/dist/audit/store.js.map +1 -1
- package/dist/audit/types.d.ts +13 -0
- package/dist/audit/types.d.ts.map +1 -1
- package/dist/audit/types.js.map +1 -1
- package/dist/automation/index.d.ts +193 -0
- package/dist/automation/index.d.ts.map +1 -0
- package/dist/automation/index.js +464 -0
- package/dist/automation/index.js.map +1 -0
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +10 -3
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +492 -35
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/client/AgentPanel.d.ts +7 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +32 -8
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +15 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +115 -47
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +1 -1
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/RunStuckBanner.d.ts +14 -1
- package/dist/client/RunStuckBanner.d.ts.map +1 -1
- package/dist/client/RunStuckBanner.js +35 -7
- package/dist/client/RunStuckBanner.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts +4 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +49 -4
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/automation.d.ts +14 -0
- package/dist/client/automation.d.ts.map +1 -0
- package/dist/client/automation.js +9 -0
- package/dist/client/automation.js.map +1 -0
- package/dist/client/chat/run-recovery.d.ts +4 -0
- package/dist/client/chat/run-recovery.d.ts.map +1 -1
- package/dist/client/chat/run-recovery.js +12 -10
- package/dist/client/chat/run-recovery.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +8 -0
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/integrations/api.d.ts +115 -0
- package/dist/client/integrations/api.d.ts.map +1 -0
- package/dist/client/integrations/api.js +123 -0
- package/dist/client/integrations/api.js.map +1 -0
- package/dist/client/integrations/index.d.ts +1 -0
- package/dist/client/integrations/index.d.ts.map +1 -1
- package/dist/client/integrations/index.js +1 -0
- package/dist/client/integrations/index.js.map +1 -1
- package/dist/client/transcription/use-live-transcription.d.ts.map +1 -1
- package/dist/client/transcription/use-live-transcription.js +59 -5
- package/dist/client/transcription/use-live-transcription.js.map +1 -1
- package/dist/client/use-run-stuck-detection.d.ts +16 -1
- package/dist/client/use-run-stuck-detection.d.ts.map +1 -1
- package/dist/client/use-run-stuck-detection.js +23 -4
- package/dist/client/use-run-stuck-detection.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +49 -4
- package/dist/deploy/build.js.map +1 -1
- package/dist/deploy/workspace-deploy.d.ts.map +1 -1
- package/dist/deploy/workspace-deploy.js +31 -2
- package/dist/deploy/workspace-deploy.js.map +1 -1
- package/dist/file-upload/types.d.ts +2 -0
- package/dist/file-upload/types.d.ts.map +1 -1
- package/dist/file-upload/types.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
- package/dist/integrations/a2a-continuations-store.js +6 -4
- package/dist/integrations/a2a-continuations-store.js.map +1 -1
- package/dist/integrations/adapters/discord.d.ts +3 -0
- package/dist/integrations/adapters/discord.d.ts.map +1 -0
- package/dist/integrations/adapters/discord.js +261 -0
- package/dist/integrations/adapters/discord.js.map +1 -0
- package/dist/integrations/adapters/index.d.ts +4 -0
- package/dist/integrations/adapters/index.d.ts.map +1 -0
- package/dist/integrations/adapters/index.js +26 -0
- package/dist/integrations/adapters/index.js.map +1 -0
- package/dist/integrations/adapters/microsoft-teams.d.ts +5 -0
- package/dist/integrations/adapters/microsoft-teams.d.ts.map +1 -0
- package/dist/integrations/adapters/microsoft-teams.js +295 -0
- package/dist/integrations/adapters/microsoft-teams.js.map +1 -0
- package/dist/integrations/adapters/slack.d.ts +8 -2
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +736 -27
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/adapters/telegram.d.ts +0 -2
- package/dist/integrations/adapters/telegram.d.ts.map +1 -1
- package/dist/integrations/adapters/telegram.js +49 -15
- package/dist/integrations/adapters/telegram.js.map +1 -1
- package/dist/integrations/adapters/whatsapp.d.ts +0 -2
- package/dist/integrations/adapters/whatsapp.d.ts.map +1 -1
- package/dist/integrations/adapters/whatsapp.js +40 -17
- package/dist/integrations/adapters/whatsapp.js.map +1 -1
- package/dist/integrations/catalog.d.ts +75 -0
- package/dist/integrations/catalog.d.ts.map +1 -0
- package/dist/integrations/catalog.js +451 -0
- package/dist/integrations/catalog.js.map +1 -0
- package/dist/integrations/controls-store.d.ts +44 -0
- package/dist/integrations/controls-store.d.ts.map +1 -0
- package/dist/integrations/controls-store.js +129 -0
- package/dist/integrations/controls-store.js.map +1 -0
- package/dist/integrations/index.d.ts +13 -1
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +9 -0
- package/dist/integrations/index.js.map +1 -1
- package/dist/integrations/installations-store.d.ts +112 -0
- package/dist/integrations/installations-store.d.ts.map +1 -0
- package/dist/integrations/installations-store.js +493 -0
- package/dist/integrations/installations-store.js.map +1 -0
- package/dist/integrations/integration-memory.d.ts +24 -0
- package/dist/integrations/integration-memory.d.ts.map +1 -0
- package/dist/integrations/integration-memory.js +136 -0
- package/dist/integrations/integration-memory.js.map +1 -0
- package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -1
- package/dist/integrations/pending-tasks-retry-job.js +6 -5
- package/dist/integrations/pending-tasks-retry-job.js.map +1 -1
- package/dist/integrations/pending-tasks-store.d.ts +17 -0
- package/dist/integrations/pending-tasks-store.d.ts.map +1 -1
- package/dist/integrations/pending-tasks-store.js +71 -5
- package/dist/integrations/pending-tasks-store.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +520 -35
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/scope-store.d.ts +65 -0
- package/dist/integrations/scope-store.d.ts.map +1 -0
- package/dist/integrations/scope-store.js +361 -0
- package/dist/integrations/scope-store.js.map +1 -0
- package/dist/integrations/slack-manifest.d.ts +66 -0
- package/dist/integrations/slack-manifest.d.ts.map +1 -0
- package/dist/integrations/slack-manifest.js +70 -0
- package/dist/integrations/slack-manifest.js.map +1 -0
- package/dist/integrations/slack-oauth.d.ts +99 -0
- package/dist/integrations/slack-oauth.d.ts.map +1 -0
- package/dist/integrations/slack-oauth.js +226 -0
- package/dist/integrations/slack-oauth.js.map +1 -0
- package/dist/integrations/types.d.ts +144 -0
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/types.js +16 -1
- package/dist/integrations/types.js.map +1 -1
- package/dist/integrations/usage-budget-store.d.ts +84 -0
- package/dist/integrations/usage-budget-store.d.ts.map +1 -0
- package/dist/integrations/usage-budget-store.js +650 -0
- package/dist/integrations/usage-budget-store.js.map +1 -0
- package/dist/integrations/webhook-handler.d.ts +4 -0
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +415 -47
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/jobs/scheduler.d.ts +6 -0
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +83 -4
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/jobs/tools.d.ts.map +1 -1
- package/dist/jobs/tools.js +43 -11
- package/dist/jobs/tools.js.map +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/index.d.ts +4 -4
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +72 -1
- package/dist/provider-api/index.js.map +1 -1
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +57 -15
- package/dist/resources/handlers.js.map +1 -1
- package/dist/resources/script-helpers.d.ts.map +1 -1
- package/dist/resources/script-helpers.js +34 -8
- package/dist/resources/script-helpers.js.map +1 -1
- package/dist/resources/store.d.ts +10 -0
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +54 -47
- package/dist/resources/store.js.map +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +106 -1
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +15 -4
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +248 -113
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +10 -14
- package/dist/server/auth.js.map +1 -1
- package/dist/server/builder-design-systems.d.ts +3 -1
- package/dist/server/builder-design-systems.d.ts.map +1 -1
- package/dist/server/builder-design-systems.js +9 -2
- package/dist/server/builder-design-systems.js.map +1 -1
- package/dist/server/edge.d.ts +1 -1
- package/dist/server/edge.d.ts.map +1 -1
- package/dist/server/edge.js +1 -1
- package/dist/server/edge.js.map +1 -1
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/request-context.d.ts +18 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/social-og-image.d.ts.map +1 -1
- package/dist/server/social-og-image.js +3 -2
- package/dist/server/social-og-image.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/styles/agent-native.css +62 -44
- package/dist/templates/default/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/dist/templates/default/AGENTS.md +7 -3
- package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/dist/templates/workspace-core/.agents/skills/extension-points/SKILL.md +6 -3
- package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +25 -0
- package/dist/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +15 -0
- package/dist/templates/workspace-core/AGENTS.md +3 -2
- package/dist/usage/store.d.ts +7 -0
- package/dist/usage/store.d.ts.map +1 -1
- package/dist/usage/store.js +24 -3
- package/dist/usage/store.js.map +1 -1
- package/docs/content/automation-connectors.mdx +80 -0
- package/docs/content/extensions.mdx +8 -0
- package/docs/content/locales/ar-SA/extensions.mdx +8 -0
- package/docs/content/locales/ar-SA/messaging.mdx +84 -15
- package/docs/content/locales/ar-SA/template-clips.mdx +1 -0
- package/docs/content/locales/ar-SA/template-design.mdx +1 -0
- package/docs/content/locales/de-DE/extensions.mdx +10 -0
- package/docs/content/locales/de-DE/messaging.mdx +92 -15
- package/docs/content/locales/de-DE/template-clips.mdx +1 -0
- package/docs/content/locales/de-DE/template-design.mdx +1 -0
- package/docs/content/locales/es-ES/extensions.mdx +10 -0
- package/docs/content/locales/es-ES/messaging.mdx +91 -15
- package/docs/content/locales/es-ES/template-clips.mdx +1 -0
- package/docs/content/locales/es-ES/template-design.mdx +1 -0
- package/docs/content/locales/fr-FR/extensions.mdx +10 -0
- package/docs/content/locales/fr-FR/messaging.mdx +91 -15
- package/docs/content/locales/fr-FR/template-clips.mdx +1 -0
- package/docs/content/locales/fr-FR/template-design.mdx +1 -0
- package/docs/content/locales/hi-IN/extensions.mdx +8 -0
- package/docs/content/locales/hi-IN/messaging.mdx +81 -15
- package/docs/content/locales/hi-IN/template-clips.mdx +1 -0
- package/docs/content/locales/hi-IN/template-design.mdx +1 -0
- package/docs/content/locales/ja-JP/extensions.mdx +9 -0
- package/docs/content/locales/ja-JP/messaging.mdx +81 -15
- package/docs/content/locales/ja-JP/template-clips.mdx +1 -0
- package/docs/content/locales/ja-JP/template-design.mdx +1 -0
- package/docs/content/locales/ko-KR/extensions.mdx +8 -0
- package/docs/content/locales/ko-KR/messaging.mdx +80 -15
- package/docs/content/locales/ko-KR/template-clips.mdx +1 -0
- package/docs/content/locales/ko-KR/template-design.mdx +1 -0
- package/docs/content/locales/pt-BR/extensions.mdx +9 -0
- package/docs/content/locales/pt-BR/messaging.mdx +88 -15
- package/docs/content/locales/pt-BR/template-clips.mdx +1 -0
- package/docs/content/locales/pt-BR/template-design.mdx +1 -0
- package/docs/content/locales/zh-CN/extensions.mdx +6 -0
- package/docs/content/locales/zh-CN/messaging.mdx +78 -15
- package/docs/content/locales/zh-CN/template-clips.mdx +1 -0
- package/docs/content/locales/zh-CN/template-design.mdx +1 -0
- package/docs/content/locales/zh-TW/extensions.mdx +6 -0
- package/docs/content/locales/zh-TW/messaging.mdx +78 -15
- package/docs/content/locales/zh-TW/template-clips.mdx +1 -0
- package/docs/content/locales/zh-TW/template-design.mdx +1 -0
- package/docs/content/messaging.mdx +227 -45
- package/docs/content/template-clips.mdx +3 -0
- package/docs/content/template-design.mdx +4 -0
- package/package.json +5 -1
- package/src/templates/default/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/src/templates/default/AGENTS.md +7 -3
- package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +1 -1
- package/src/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +22 -9
- package/src/templates/workspace-core/.agents/skills/extension-points/SKILL.md +6 -3
- package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +25 -0
- package/src/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +15 -0
- package/src/templates/workspace-core/AGENTS.md +3 -2
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
cleanupOldRuns,
|
|
19
19
|
updateRunHeartbeat,
|
|
20
20
|
bumpRunProgress,
|
|
21
|
+
setRunInFlightMarker,
|
|
21
22
|
reapIfStale,
|
|
22
23
|
reapUnclaimedBackgroundRun,
|
|
23
24
|
shouldRedispatchUnclaimedBackgroundRun,
|
|
@@ -627,6 +628,7 @@ export function startRun(
|
|
|
627
628
|
let lastRealProgressAt = Date.now();
|
|
628
629
|
let inFlightWorkCount = 0;
|
|
629
630
|
const trackInFlightWork = (event: AgentChatEvent) => {
|
|
631
|
+
const wasIdle = inFlightWorkCount === 0;
|
|
630
632
|
if (event.type === "tool_start") {
|
|
631
633
|
inFlightWorkCount += 1;
|
|
632
634
|
} else if (event.type === "tool_done") {
|
|
@@ -637,6 +639,23 @@ export function startRun(
|
|
|
637
639
|
} else {
|
|
638
640
|
inFlightWorkCount = Math.max(0, inFlightWorkCount - 1);
|
|
639
641
|
}
|
|
642
|
+
} else {
|
|
643
|
+
return; // Not a work-tracking event — no transition possible.
|
|
644
|
+
}
|
|
645
|
+
// Mirror the 0<->N transition into SQL so a stale reaper running in a
|
|
646
|
+
// DIFFERENT isolate (a client's SQL-subscription poll, a sibling
|
|
647
|
+
// isolate's opportunistic cleanup, a fresh boot's startup sweep) can
|
|
648
|
+
// grant this demonstrably-alive run a bounded grace even when THIS
|
|
649
|
+
// isolate's own heartbeat write is failing (e.g. Neon pooler saturation)
|
|
650
|
+
// — `inFlightWorkCount` itself is in-memory and invisible to those other
|
|
651
|
+
// isolates. Fire-and-forget: never block event emission on this write,
|
|
652
|
+
// and a write failure here is no worse than today's behavior (the row
|
|
653
|
+
// just gets no grace). See `setRunInFlightMarker` / `IN_FLIGHT_RUN_STALE_GRACE_MS`
|
|
654
|
+
// in run-store.ts for the full reasoning and the bounded-grace derivation.
|
|
655
|
+
if (wasIdle && inFlightWorkCount > 0) {
|
|
656
|
+
setRunInFlightMarker(runId, true).catch(() => {});
|
|
657
|
+
} else if (!wasIdle && inFlightWorkCount === 0) {
|
|
658
|
+
setRunInFlightMarker(runId, false).catch(() => {});
|
|
640
659
|
}
|
|
641
660
|
};
|
|
642
661
|
const checkNoProgressBackstop = () => {
|
|
@@ -1432,7 +1451,11 @@ export function getActiveRunForThread(threadId: string): ActiveRun | null {
|
|
|
1432
1451
|
* dead even before the server-side stale reap has fired. Returns
|
|
1433
1452
|
* `lastProgressAt` so the client-side stuck-detector can show a
|
|
1434
1453
|
* user-visible "this chat looks stuck" affordance when a run is alive
|
|
1435
|
-
* (heartbeating) but not actually emitting events.
|
|
1454
|
+
* (heartbeating) but not actually emitting events. Returns
|
|
1455
|
+
* `awaitingRedispatch` so the client's background follow loop can tell a
|
|
1456
|
+
* legitimately-deferred `chainServerDrivenContinuation` successor (recovery
|
|
1457
|
+
* in progress server-side) apart from a genuinely dead run — see this
|
|
1458
|
+
* field's own doc comment below.
|
|
1436
1459
|
*/
|
|
1437
1460
|
export async function getActiveRunForThreadAsync(threadId: string): Promise<{
|
|
1438
1461
|
runId: string;
|
|
@@ -1451,6 +1474,37 @@ export async function getActiveRunForThreadAsync(threadId: string): Promise<{
|
|
|
1451
1474
|
* diagnosable from the client WITHOUT the unreadable bg-fn logs.
|
|
1452
1475
|
*/
|
|
1453
1476
|
diagStage?: string | null;
|
|
1477
|
+
/**
|
|
1478
|
+
* True exactly when this run is a `chainServerDrivenContinuation` deferral
|
|
1479
|
+
* (dispatch_mode === 'background', never claimed) still inside
|
|
1480
|
+
* `UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS` — the same condition this
|
|
1481
|
+
* function already uses below to skip its own `reapUnclaimedBackgroundRun`.
|
|
1482
|
+
* Surfaced on `/runs/active` (agent-chat-plugin.ts) so
|
|
1483
|
+
* `agent-chat-adapter.ts`'s follow loop can tell "silently deferred,
|
|
1484
|
+
* server-side recovery in progress" apart from "dead" and stop counting the
|
|
1485
|
+
* quiet gap against its idle timeout — see the THREE-SITE INVARIANT comment
|
|
1486
|
+
* below and in agent-chat-plugin.ts / production-agent.ts. Always false for
|
|
1487
|
+
* an in-memory run (that isolate IS the live producer) and for any run that
|
|
1488
|
+
* isn't an unclaimed background dispatch.
|
|
1489
|
+
*/
|
|
1490
|
+
awaitingRedispatch: boolean;
|
|
1491
|
+
/**
|
|
1492
|
+
* True exactly when this run's `in_flight_since` marker is set — a tool
|
|
1493
|
+
* call or A2A `agent_call` delegation is open and has not yet resolved
|
|
1494
|
+
* (see `setRunInFlightMarker` / `IN_FLIGHT_RUN_STALE_GRACE_MS` in
|
|
1495
|
+
* run-store.ts). This is the SAME signal `reapIfStale` reads to grant its
|
|
1496
|
+
* bounded stale-reap grace — computed here from the identical
|
|
1497
|
+
* `in_flight_since` column via `getRunByThread`, never re-derived, so the
|
|
1498
|
+
* client and the reaper cannot disagree about what "in flight" means.
|
|
1499
|
+
*
|
|
1500
|
+
* Surfaced on `/runs/active` (agent-chat-plugin.ts) as the
|
|
1501
|
+
* server-authoritative alternative to the client-side proxy
|
|
1502
|
+
* `RunStuckBanner` currently infers from unresolved `tool-call` content
|
|
1503
|
+
* parts in the local message list — that proxy can go stale after a
|
|
1504
|
+
* reconnect or reader-mode replay; this cannot, because it is read fresh
|
|
1505
|
+
* from SQL on every poll.
|
|
1506
|
+
*/
|
|
1507
|
+
hasInFlightWork: boolean;
|
|
1454
1508
|
} | null> {
|
|
1455
1509
|
// Check memory first — return both running AND recently-completed runs
|
|
1456
1510
|
// that still have events in memory. This allows sub-agent tabs to replay
|
|
@@ -1483,6 +1537,18 @@ export async function getActiveRunForThreadAsync(threadId: string): Promise<{
|
|
|
1483
1537
|
dispatchMode: sqlSnapshot?.dispatchMode ?? null,
|
|
1484
1538
|
terminalReason: sqlSnapshot?.terminalReason ?? null,
|
|
1485
1539
|
diagStage: sqlSnapshot?.diagStage ?? null,
|
|
1540
|
+
// In-memory means this isolate is the live producer — never the
|
|
1541
|
+
// "deferred, nobody producing" state this flag identifies.
|
|
1542
|
+
awaitingRedispatch: false,
|
|
1543
|
+
// Read from the SAME SQL snapshot the other fields above already read
|
|
1544
|
+
// (`fetchRunThreadSnapshot` -> `getRunByThread`) rather than the
|
|
1545
|
+
// producer's own in-memory `inFlightWorkCount` — this isolate IS the
|
|
1546
|
+
// live producer, but there is no separate in-memory channel wired for
|
|
1547
|
+
// that counter today, and the SQL marker is written on every 0<->N
|
|
1548
|
+
// transition (see run-manager's `trackInFlightWork`), so it is at most
|
|
1549
|
+
// one event behind here — the same tolerance `lastProgressAt` above
|
|
1550
|
+
// already accepts.
|
|
1551
|
+
hasInFlightWork: sqlSnapshot?.inFlightSince != null,
|
|
1486
1552
|
};
|
|
1487
1553
|
}
|
|
1488
1554
|
// Fall back to SQL — also surface recently terminated runs so the client
|
|
@@ -1525,12 +1591,17 @@ export async function getActiveRunForThreadAsync(threadId: string): Promise<{
|
|
|
1525
1591
|
// follow loop AUTO-continues — and once the redispatch bound is exceeded
|
|
1526
1592
|
// this reap fires loudly as before. So recovery stays automatic in the
|
|
1527
1593
|
// common case and loud failure is only moved later, never removed.
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1594
|
+
//
|
|
1595
|
+
// `isUnclaimedBackgroundDispatch` also becomes the `awaitingRedispatch`
|
|
1596
|
+
// wire field below once the still-inside-the-bound check passes — see
|
|
1597
|
+
// this function's doc comment and the THREE-SITE INVARIANT comment in
|
|
1598
|
+
// agent-chat-plugin.ts / production-agent.ts.
|
|
1599
|
+
const isUnclaimedBackgroundDispatch =
|
|
1600
|
+
sqlRun.dispatchMode === "background";
|
|
1601
|
+
const stillInsideRedispatchBound = shouldRedispatchUnclaimedBackgroundRun(
|
|
1602
|
+
{ startedAt: sqlRun.startedAt },
|
|
1603
|
+
);
|
|
1604
|
+
if (isUnclaimedBackgroundDispatch && !stillInsideRedispatchBound) {
|
|
1534
1605
|
const recovered = await reapUnclaimedBackgroundRun(sqlRun.id).catch(
|
|
1535
1606
|
() => false,
|
|
1536
1607
|
);
|
|
@@ -1551,6 +1622,12 @@ export async function getActiveRunForThreadAsync(threadId: string): Promise<{
|
|
|
1551
1622
|
dispatchMode: sqlRun.dispatchMode,
|
|
1552
1623
|
terminalReason: sqlRun.terminalReason,
|
|
1553
1624
|
diagStage: sqlRun.diagStage,
|
|
1625
|
+
awaitingRedispatch:
|
|
1626
|
+
isUnclaimedBackgroundDispatch && stillInsideRedispatchBound,
|
|
1627
|
+
// Same `in_flight_since` column `reapIfStale` (just called above,
|
|
1628
|
+
// and it did NOT reap this row) reads for its own grace decision —
|
|
1629
|
+
// one source of truth, not a second re-derived notion of "in flight".
|
|
1630
|
+
hasInFlightWork: sqlRun.inFlightSince != null,
|
|
1554
1631
|
};
|
|
1555
1632
|
}
|
|
1556
1633
|
if (sqlRun.status === "completed" || sqlRun.status === "errored") {
|
|
@@ -1579,6 +1656,10 @@ export async function getActiveRunForThreadAsync(threadId: string): Promise<{
|
|
|
1579
1656
|
dispatchMode: sqlRun.dispatchMode,
|
|
1580
1657
|
terminalReason: sqlRun.terminalReason,
|
|
1581
1658
|
diagStage: sqlRun.diagStage,
|
|
1659
|
+
// Terminal already — never the "still deferred, running" state.
|
|
1660
|
+
awaitingRedispatch: false,
|
|
1661
|
+
// Terminal already — no live work can still be in flight.
|
|
1662
|
+
hasInFlightWork: false,
|
|
1582
1663
|
};
|
|
1583
1664
|
}
|
|
1584
1665
|
} catch {
|
|
@@ -1606,15 +1687,54 @@ export function getRun(runId: string): ActiveRun | null {
|
|
|
1606
1687
|
return activeRuns.get(runId) ?? null;
|
|
1607
1688
|
}
|
|
1608
1689
|
|
|
1609
|
-
|
|
1610
|
-
export function abortRun(runId: string, reason: string = "user"): boolean {
|
|
1690
|
+
function abortRunInMemory(runId: string, reason: string): boolean {
|
|
1611
1691
|
const run = activeRuns.get(runId);
|
|
1612
1692
|
if (run) {
|
|
1613
1693
|
abortInMemoryRun(run, reason);
|
|
1614
1694
|
}
|
|
1695
|
+
return !!run;
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
/** Explicitly abort a run (e.g. Stop button). */
|
|
1699
|
+
export function abortRun(runId: string, reason: string = "user"): boolean {
|
|
1700
|
+
const abortedInMemory = abortRunInMemory(runId, reason);
|
|
1615
1701
|
// Also mark as aborted in SQL (for cross-isolate abort on Workers)
|
|
1616
1702
|
markRunAborted(runId, reason).catch(() => {});
|
|
1617
|
-
return
|
|
1703
|
+
return abortedInMemory;
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
/**
|
|
1707
|
+
* Abort a run and wait until the cross-isolate SQL state and terminal event
|
|
1708
|
+
* are durable. Request handlers that start recovery immediately after aborting
|
|
1709
|
+
* must use this path; otherwise the recovery POST can race the old row while
|
|
1710
|
+
* it is still marked running.
|
|
1711
|
+
*/
|
|
1712
|
+
export async function abortRunDurably(
|
|
1713
|
+
runId: string,
|
|
1714
|
+
reason: string = "user",
|
|
1715
|
+
): Promise<boolean> {
|
|
1716
|
+
const abortedInMemory = abortRunInMemory(runId, reason);
|
|
1717
|
+
try {
|
|
1718
|
+
await markRunAborted(runId, reason);
|
|
1719
|
+
} catch (error) {
|
|
1720
|
+
// The local run is already stopped. A transient durable cleanup failure
|
|
1721
|
+
// must not turn the user's Stop/Retry request into a 500 after that
|
|
1722
|
+
// irreversible in-memory outcome. Capture it for repair/reaping and let
|
|
1723
|
+
// the request report the abort it did complete.
|
|
1724
|
+
captureError(error, {
|
|
1725
|
+
route: "/_agent-native/agent-chat/runs/:id/abort",
|
|
1726
|
+
tags: {
|
|
1727
|
+
source: "agent-run-manager",
|
|
1728
|
+
phase: "abort-run",
|
|
1729
|
+
},
|
|
1730
|
+
extra: { runId, reason, abortedInMemory },
|
|
1731
|
+
});
|
|
1732
|
+
console.error(
|
|
1733
|
+
"[run-manager] durable abort persistence failed:",
|
|
1734
|
+
error instanceof Error ? error.message : error,
|
|
1735
|
+
);
|
|
1736
|
+
}
|
|
1737
|
+
return abortedInMemory;
|
|
1618
1738
|
}
|
|
1619
1739
|
|
|
1620
1740
|
// Re-export so callers can avoid importing from run-store directly.
|
|
@@ -118,6 +118,84 @@ export const UNCLAIMED_BACKGROUND_RUN_GRACE_MS = 25_000;
|
|
|
118
118
|
*/
|
|
119
119
|
export const UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS = 5 * 60_000;
|
|
120
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Tick interval for the DEDICATED fast redispatch sweep in
|
|
123
|
+
* agent-chat-plugin.ts (distinct from that file's general-purpose 2-minute
|
|
124
|
+
* orphan/reap sweep). Only attempts redispatch for rows still inside
|
|
125
|
+
* `UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS` — it never reaps, so it
|
|
126
|
+
* cannot race the loud-failure fallback onto an earlier trigger.
|
|
127
|
+
*
|
|
128
|
+
* This constant exists because the general sweep's 2-minute cadence puts the
|
|
129
|
+
* FIRST redispatch attempt uncomfortably close to (and on a slow tick, past)
|
|
130
|
+
* `BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS` (150s, agent-chat-adapter.ts) — the
|
|
131
|
+
* client following a deferred successor would give up and report a fatal
|
|
132
|
+
* error for a turn the server was silently about to recover. The whole
|
|
133
|
+
* budget is a derived chain, each bound following from the one before it:
|
|
134
|
+
*
|
|
135
|
+
* UNCLAIMED_BACKGROUND_RUN_GRACE_MS (25s) row must look abandoned
|
|
136
|
+
* + UNCLAIMED_BACKGROUND_RUN_FAST_SWEEP_MS (20s) worst-case tick latency
|
|
137
|
+
* = ~45s worst-case time-to-first-redispatch-attempt, ~65s to a second
|
|
138
|
+
* attempt if the first fails — both comfortably under the client's 150s
|
|
139
|
+
* idle timeout, which additionally no longer counts a known-deferred row
|
|
140
|
+
* against its idle window at all (see `awaitingRedispatch` surfaced by
|
|
141
|
+
* `/runs/active` and consumed by the client follow loop).
|
|
142
|
+
* < BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS (150s) client's own backstop
|
|
143
|
+
* < UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS (300s) hard, unresettable
|
|
144
|
+
* ceiling — untouched by this constant — past which the slow sweep's
|
|
145
|
+
* existing loud reap (`background_worker_never_started`) still fires.
|
|
146
|
+
*/
|
|
147
|
+
export const UNCLAIMED_BACKGROUND_RUN_FAST_SWEEP_MS = 20_000;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Maximum time the stale reapers (`reapIfStale`, `reapAllStaleRuns`,
|
|
151
|
+
* `cleanupOldRuns`'s heartbeat-stale pass) will suspend reaping a "running"
|
|
152
|
+
* row that is marked in-flight (`in_flight_since`, see `setRunInFlightMarker`)
|
|
153
|
+
* even though its heartbeat/progress liveness basis
|
|
154
|
+
* (`livenessBasisSql`/`backgroundAwareStaleCutoffSql`) has gone stale.
|
|
155
|
+
*
|
|
156
|
+
* WHY a marker column at all: `inFlightWorkCount` in run-manager.ts (the
|
|
157
|
+
* no-progress backstop's guard) is in-memory, per-isolate — but all three
|
|
158
|
+
* reapers above can run in a DIFFERENT isolate than the one holding the
|
|
159
|
+
* producing run (a client's SQL-subscription poll, a sibling isolate's
|
|
160
|
+
* opportunistic `cleanupOldRuns` after ITS OWN run completes, or a fresh
|
|
161
|
+
* boot's `reapAllStaleRuns`). None of them can read another isolate's
|
|
162
|
+
* in-memory counter, so the counter's 0->1 / 1->0 transitions are mirrored
|
|
163
|
+
* into this column (`setRunInFlightMarker`, called from
|
|
164
|
+
* run-manager.ts's `trackInFlightWork`) so it is observable from SQL. This is
|
|
165
|
+
* exactly the gap that let a demonstrably-alive run holding a long tool call
|
|
166
|
+
* or A2A `call-agent` delegation get reaped: the heartbeat WRITE can fail
|
|
167
|
+
* silently (Neon pooler saturation) for the whole `BACKGROUND_RUN_STALE_MS`
|
|
168
|
+
* window while the run is provably still doing work.
|
|
169
|
+
*
|
|
170
|
+
* BOUNDED, not a silent hang — derived from two independent ceilings already
|
|
171
|
+
* in the codebase, not picked by feel:
|
|
172
|
+
* - `DEFAULT_TOOL_TIMEOUT_MS` (12 min, production-agent.ts) is the longest
|
|
173
|
+
* any SINGLE tool call or `agent_call` (A2A delegation) may legitimately
|
|
174
|
+
* stay in flight — past that its own `AbortSignal.timeout` forces a
|
|
175
|
+
* tool_done/error and clears the marker.
|
|
176
|
+
* - `BACKGROUND_SOFT_TIMEOUT_CEILING_MS` (13 min, run-manager.ts) is the
|
|
177
|
+
* background chunk's OWN soft-timeout ceiling. Unlike the no-progress
|
|
178
|
+
* backstop, this timer is NOT gated on in-flight work (see the "secondary"
|
|
179
|
+
* hazard documented next to the soft-timeout timer in run-manager.ts) —
|
|
180
|
+
* it fires unconditionally and checkpoints/continues the run, so by 13
|
|
181
|
+
* minutes the row leaves status='running' via that path regardless of
|
|
182
|
+
* what the marker says.
|
|
183
|
+
* This grace is the LARGER of the two (13 min) plus one `BACKGROUND_RUN_STALE_MS`
|
|
184
|
+
* (90s) buffer for that checkpoint's own completion write to land under the
|
|
185
|
+
* same DB pressure that could have caused the heartbeat to lapse in the first
|
|
186
|
+
* place: 780_000 + 90_000 = 870_000ms (14.5 min). Past that, a "running" row
|
|
187
|
+
* that still shows in-flight work AND a stale liveness basis is not a slow
|
|
188
|
+
* producer anymore — every backstop that should have ended it has ALSO failed
|
|
189
|
+
* to write, and it is reaped loud like any other stale run.
|
|
190
|
+
*
|
|
191
|
+
* Never applied when a caller passes an explicit `maxStaleMs` override to
|
|
192
|
+
* `reapIfStale` — that escape hatch is an exact, caller-chosen window and
|
|
193
|
+
* stays exact. Never weakens the no-in-flight case: a row with no marker set
|
|
194
|
+
* evaluates this grace clause to a no-op and is reaped at the original
|
|
195
|
+
* `BACKGROUND_RUN_STALE_MS` / `RUN_STALE_MS` exactly as before.
|
|
196
|
+
*/
|
|
197
|
+
export const IN_FLIGHT_RUN_STALE_GRACE_MS = 14.5 * 60_000; // 870_000
|
|
198
|
+
|
|
121
199
|
async function ensureRunTables(): Promise<void> {
|
|
122
200
|
if (!_initPromise) {
|
|
123
201
|
_initPromise = (async () => {
|
|
@@ -225,6 +303,14 @@ async function ensureRunTables(): Promise<void> {
|
|
|
225
303
|
// rehydrates the body from this column via the marker's payloadRef.
|
|
226
304
|
// Cleared on terminal status writes.
|
|
227
305
|
["dispatch_payload", "TEXT"],
|
|
306
|
+
// in_flight_since = ms epoch when run-manager's in-memory
|
|
307
|
+
// `inFlightWorkCount` last transitioned 0->1 (a tool call or nested
|
|
308
|
+
// `agent_call`/A2A delegation started), NULL once it drops back to 0.
|
|
309
|
+
// Lets the cross-isolate stale reapers grant a bounded grace to a
|
|
310
|
+
// demonstrably-alive run even when the SAME-isolate heartbeat write
|
|
311
|
+
// has failed. See `IN_FLIGHT_RUN_STALE_GRACE_MS` and
|
|
312
|
+
// `setRunInFlightMarker`.
|
|
313
|
+
["in_flight_since", intType()],
|
|
228
314
|
] as const) {
|
|
229
315
|
await ensureColumnExists(
|
|
230
316
|
"agent_runs",
|
|
@@ -250,6 +336,7 @@ async function ensureRunTables(): Promise<void> {
|
|
|
250
336
|
"completed_at",
|
|
251
337
|
"heartbeat_at",
|
|
252
338
|
"last_progress_at",
|
|
339
|
+
"in_flight_since",
|
|
253
340
|
]);
|
|
254
341
|
await widenIntColumnsToBigInt("agent_run_events", ["event_at"]);
|
|
255
342
|
await widenIntColumnsToBigInt("agent_tool_ledger", ["completed_at"]);
|
|
@@ -286,6 +373,18 @@ async function ensureRunTables(): Promise<void> {
|
|
|
286
373
|
} catch {
|
|
287
374
|
// Column already exists — ignore
|
|
288
375
|
}
|
|
376
|
+
// Backfill in_flight_since — ms epoch when run-manager's in-memory
|
|
377
|
+
// `inFlightWorkCount` last transitioned 0->1, NULL once back to 0. Lets
|
|
378
|
+
// the cross-isolate stale reapers grant a bounded grace to a
|
|
379
|
+
// demonstrably-alive run even when the heartbeat write itself has
|
|
380
|
+
// failed. See `IN_FLIGHT_RUN_STALE_GRACE_MS` and `setRunInFlightMarker`.
|
|
381
|
+
try {
|
|
382
|
+
await client.execute(
|
|
383
|
+
`ALTER TABLE agent_runs ADD COLUMN in_flight_since ${intType()}`,
|
|
384
|
+
);
|
|
385
|
+
} catch {
|
|
386
|
+
// Column already exists — ignore
|
|
387
|
+
}
|
|
289
388
|
// Backfill turn_id / error_code / error_detail.
|
|
290
389
|
// turn_id = stable identity for one logical assistant turn that may
|
|
291
390
|
// span several continuation runs, so the durable record
|
|
@@ -339,6 +438,7 @@ async function ensureRunTables(): Promise<void> {
|
|
|
339
438
|
"completed_at",
|
|
340
439
|
"heartbeat_at",
|
|
341
440
|
"last_progress_at",
|
|
441
|
+
"in_flight_since",
|
|
342
442
|
]);
|
|
343
443
|
await widenIntColumnsToBigInt("agent_run_events", ["event_at"]);
|
|
344
444
|
await widenIntColumnsToBigInt("agent_tool_ledger", ["completed_at"]);
|
|
@@ -529,6 +629,23 @@ function livenessBasisSql(): string {
|
|
|
529
629
|
return `(CASE WHEN COALESCE(last_progress_at, started_at) > COALESCE(heartbeat_at, started_at) THEN COALESCE(last_progress_at, started_at) ELSE COALESCE(heartbeat_at, started_at) END)`;
|
|
530
630
|
}
|
|
531
631
|
|
|
632
|
+
/**
|
|
633
|
+
* Additive grace clause for the default (no explicit `maxStaleMs` override)
|
|
634
|
+
* heartbeat/liveness-based stale reap conditions — TRUE (row remains eligible
|
|
635
|
+
* for the surrounding staleness check) unless `in_flight_since` is set AND
|
|
636
|
+
* still inside `IN_FLIGHT_RUN_STALE_GRACE_MS`. A row with no marker set
|
|
637
|
+
* (`in_flight_since IS NULL`, the common case and every pre-existing row
|
|
638
|
+
* before this migration) always evaluates TRUE here, so this can only make
|
|
639
|
+
* reaping MORE conservative — the no-in-flight `BACKGROUND_RUN_STALE_MS` /
|
|
640
|
+
* `RUN_STALE_MS` behavior is unchanged. See `IN_FLIGHT_RUN_STALE_GRACE_MS`'s
|
|
641
|
+
* doc comment for why this is sound and bounded.
|
|
642
|
+
*
|
|
643
|
+
* Binds one param: the same `now` value the surrounding cutoff clause binds.
|
|
644
|
+
*/
|
|
645
|
+
function inFlightGraceSql(): string {
|
|
646
|
+
return `(in_flight_since IS NULL OR in_flight_since <= (CAST(? AS BIGINT) - ${IN_FLIGHT_RUN_STALE_GRACE_MS}))`;
|
|
647
|
+
}
|
|
648
|
+
|
|
532
649
|
/**
|
|
533
650
|
* Atomically claim a background-dispatched run for processing. The foreground
|
|
534
651
|
* POST inserts the run row with `dispatch_mode = 'background'`; the FIRST
|
|
@@ -1139,12 +1256,57 @@ export async function updateRunHeartbeat(runId: string): Promise<void> {
|
|
|
1139
1256
|
export async function bumpRunProgress(runId: string): Promise<void> {
|
|
1140
1257
|
await ensureRunTables();
|
|
1141
1258
|
const client = getDbExec();
|
|
1259
|
+
const now = Date.now();
|
|
1142
1260
|
await client.execute({
|
|
1143
|
-
|
|
1144
|
-
|
|
1261
|
+
// Multiple event-persistence paths and serverless isolates can bump the
|
|
1262
|
+
// same run concurrently. A slower, older write must never land after a
|
|
1263
|
+
// newer one and move the user-visible no-progress clock backwards.
|
|
1264
|
+
// CASE keeps this portable across SQLite and Postgres.
|
|
1265
|
+
sql: `UPDATE agent_runs SET last_progress_at = CASE WHEN last_progress_at IS NULL OR last_progress_at < ? THEN ? ELSE last_progress_at END WHERE id = ? AND status = 'running'`,
|
|
1266
|
+
args: [now, now, runId],
|
|
1145
1267
|
});
|
|
1146
1268
|
}
|
|
1147
1269
|
|
|
1270
|
+
/**
|
|
1271
|
+
* Mirror run-manager's in-memory `inFlightWorkCount` 0<->N transitions into
|
|
1272
|
+
* SQL so a stale reaper running in a DIFFERENT isolate can tell a
|
|
1273
|
+
* demonstrably-alive run (holding a tool call or A2A `agent_call` delegation)
|
|
1274
|
+
* apart from a genuinely dead one — see `IN_FLIGHT_RUN_STALE_GRACE_MS`'s doc
|
|
1275
|
+
* comment for the full reasoning.
|
|
1276
|
+
*
|
|
1277
|
+
* `inFlight: true` only writes when the row is still `NULL` — a defense-in-
|
|
1278
|
+
* depth belt-and-suspenders against a nested 1->2 transition clobbering the
|
|
1279
|
+
* ORIGINAL start time with a later one (the caller's own counter already
|
|
1280
|
+
* dedupes 0->1 transitions; this WHERE just makes the write itself
|
|
1281
|
+
* idempotent/order-independent too). `inFlight: false` always clears
|
|
1282
|
+
* unconditionally — if it races a fresh 0->1 write from a *different* tool
|
|
1283
|
+
* finishing/starting back to back, worst case is losing a few seconds of
|
|
1284
|
+
* grace, never gaining an incorrect one.
|
|
1285
|
+
*
|
|
1286
|
+
* Best-effort: callers fire-and-forget (`.catch(() => {})`) so a write
|
|
1287
|
+
* failure here never blocks event emission or aborts the run. If this write
|
|
1288
|
+
* itself fails (the same DB pressure that could be starving the heartbeat),
|
|
1289
|
+
* the row simply gets no grace — never worse than today's behavior.
|
|
1290
|
+
*/
|
|
1291
|
+
export async function setRunInFlightMarker(
|
|
1292
|
+
runId: string,
|
|
1293
|
+
inFlight: boolean,
|
|
1294
|
+
): Promise<void> {
|
|
1295
|
+
await ensureRunTables();
|
|
1296
|
+
const client = getDbExec();
|
|
1297
|
+
if (inFlight) {
|
|
1298
|
+
await client.execute({
|
|
1299
|
+
sql: `UPDATE agent_runs SET in_flight_since = ? WHERE id = ? AND status = 'running' AND in_flight_since IS NULL`,
|
|
1300
|
+
args: [Date.now(), runId],
|
|
1301
|
+
});
|
|
1302
|
+
} else {
|
|
1303
|
+
await client.execute({
|
|
1304
|
+
sql: `UPDATE agent_runs SET in_flight_since = NULL WHERE id = ?`,
|
|
1305
|
+
args: [runId],
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1148
1310
|
/**
|
|
1149
1311
|
* If the given run is marked "running" in SQL but its heartbeat is stale
|
|
1150
1312
|
* (producer likely crashed), flip it to "errored" so watchers stop waiting.
|
|
@@ -1160,13 +1322,20 @@ export async function reapIfStale(
|
|
|
1160
1322
|
const completedAt = Date.now();
|
|
1161
1323
|
// Background-dispatched runs get the wider stale window so a slow cold-start
|
|
1162
1324
|
// isn't reaped; foreground runs keep the tight 15s window. An explicit
|
|
1163
|
-
// override forces a flat window for callers that want one
|
|
1325
|
+
// override forces a flat window for callers that want one — and, like that
|
|
1326
|
+
// override already bypasses the background-aware widening, it also bypasses
|
|
1327
|
+
// the in-flight grace below: an explicit `maxStaleMs` is an exact,
|
|
1328
|
+
// caller-chosen window and stays exact.
|
|
1164
1329
|
const staleClause =
|
|
1165
1330
|
typeof maxStaleMs === "number"
|
|
1166
1331
|
? `${livenessBasisSql()} < ?`
|
|
1167
|
-
: `${livenessBasisSql()} < ${backgroundAwareStaleCutoffSql()}`;
|
|
1332
|
+
: `${livenessBasisSql()} < ${backgroundAwareStaleCutoffSql()} AND ${inFlightGraceSql()}`;
|
|
1168
1333
|
const staleArgs =
|
|
1169
|
-
typeof maxStaleMs === "number"
|
|
1334
|
+
typeof maxStaleMs === "number"
|
|
1335
|
+
? [completedAt - maxStaleMs]
|
|
1336
|
+
: // First `?` is backgroundAwareStaleCutoffSql's CAST param, second is
|
|
1337
|
+
// inFlightGraceSql's — both bound to the same "now".
|
|
1338
|
+
[completedAt, completedAt];
|
|
1170
1339
|
const { rowsAffected } = await client.execute({
|
|
1171
1340
|
sql: `UPDATE agent_runs
|
|
1172
1341
|
SET status = 'errored',
|
|
@@ -1500,12 +1669,23 @@ export async function getRunByThread(
|
|
|
1500
1669
|
dispatchMode: string | null;
|
|
1501
1670
|
terminalReason: string | null;
|
|
1502
1671
|
diagStage: string | null;
|
|
1672
|
+
/**
|
|
1673
|
+
* Raw `in_flight_since` marker (see `setRunInFlightMarker`) — non-null
|
|
1674
|
+
* exactly when run-manager's in-memory `inFlightWorkCount` was last known
|
|
1675
|
+
* (from THIS row's own producer) to be > 0: a tool call or A2A `agent_call`
|
|
1676
|
+
* delegation is open and has not yet resolved. Callers that want the
|
|
1677
|
+
* authoritative "does this run currently hold live work" signal (e.g. the
|
|
1678
|
+
* `hasInFlightWork` wire field on `/runs/active`) should test this for
|
|
1679
|
+
* non-null, not re-derive their own notion of in-flight — see
|
|
1680
|
+
* `getActiveRunForThreadAsync` in run-manager.ts.
|
|
1681
|
+
*/
|
|
1682
|
+
inFlightSince: number | null;
|
|
1503
1683
|
} | null> {
|
|
1504
1684
|
await ensureRunTables();
|
|
1505
1685
|
const client = getDbExec();
|
|
1506
1686
|
const sql = options?.includeTerminal
|
|
1507
|
-
? `SELECT id, thread_id, turn_id, status, started_at, heartbeat_at, completed_at, last_progress_at, dispatch_mode, terminal_reason, diag_stage, error_code FROM agent_runs WHERE thread_id = ? ORDER BY started_at DESC LIMIT 1`
|
|
1508
|
-
: `SELECT id, thread_id, turn_id, status, started_at, heartbeat_at, completed_at, last_progress_at, dispatch_mode, terminal_reason, diag_stage, error_code FROM agent_runs WHERE thread_id = ? AND status = 'running' ORDER BY started_at DESC LIMIT 1`;
|
|
1687
|
+
? `SELECT id, thread_id, turn_id, status, started_at, heartbeat_at, completed_at, last_progress_at, dispatch_mode, terminal_reason, diag_stage, error_code, in_flight_since FROM agent_runs WHERE thread_id = ? ORDER BY started_at DESC LIMIT 1`
|
|
1688
|
+
: `SELECT id, thread_id, turn_id, status, started_at, heartbeat_at, completed_at, last_progress_at, dispatch_mode, terminal_reason, diag_stage, error_code, in_flight_since FROM agent_runs WHERE thread_id = ? AND status = 'running' ORDER BY started_at DESC LIMIT 1`;
|
|
1509
1689
|
const { rows } = await client.execute({ sql, args: [threadId] });
|
|
1510
1690
|
if (rows.length === 0) return null;
|
|
1511
1691
|
const r = rows[0] as {
|
|
@@ -1521,6 +1701,7 @@ export async function getRunByThread(
|
|
|
1521
1701
|
terminal_reason?: string | null;
|
|
1522
1702
|
diag_stage?: string | null;
|
|
1523
1703
|
error_code?: string | null;
|
|
1704
|
+
in_flight_since?: number | string | null;
|
|
1524
1705
|
};
|
|
1525
1706
|
const canReconcileFromEvents =
|
|
1526
1707
|
r.status === "running" ||
|
|
@@ -1542,6 +1723,7 @@ export async function getRunByThread(
|
|
|
1542
1723
|
dispatchMode: r.dispatch_mode ?? null,
|
|
1543
1724
|
terminalReason: r.terminal_reason ?? null,
|
|
1544
1725
|
diagStage: r.diag_stage ?? null,
|
|
1726
|
+
inFlightSince: r.in_flight_since == null ? null : Number(r.in_flight_since),
|
|
1545
1727
|
};
|
|
1546
1728
|
}
|
|
1547
1729
|
|
|
@@ -1706,12 +1888,21 @@ export async function reapAllStaleRuns(): Promise<number> {
|
|
|
1706
1888
|
await ensureRunTables();
|
|
1707
1889
|
const client = getDbExec();
|
|
1708
1890
|
const now = Date.now();
|
|
1709
|
-
// Background-dispatched runs use the wider window; everything else 15s.
|
|
1891
|
+
// Background-dispatched runs use the wider window; everything else 15s. The
|
|
1892
|
+
// in-flight grace clause is applied identically to this SELECT and the
|
|
1893
|
+
// UPDATE below (both derive `stale.rows`/the terminal-event-append loop
|
|
1894
|
+
// from the SAME predicate) so a row the grace clause protects from the
|
|
1895
|
+
// UPDATE is never mistakenly given a terminal event anyway — see
|
|
1896
|
+
// `inFlightGraceSql` and `IN_FLIGHT_RUN_STALE_GRACE_MS`. This runs at
|
|
1897
|
+
// server startup across possibly-multiple isolates, so a sibling isolate's
|
|
1898
|
+
// still-alive, in-flight run must not be reaped just because THIS isolate
|
|
1899
|
+
// just booted and has no heartbeat history for it.
|
|
1710
1900
|
const stale = await client.execute({
|
|
1711
1901
|
sql: `SELECT id FROM agent_runs
|
|
1712
1902
|
WHERE status = 'running'
|
|
1713
|
-
AND ${livenessBasisSql()} < ${backgroundAwareStaleCutoffSql()}
|
|
1714
|
-
|
|
1903
|
+
AND ${livenessBasisSql()} < ${backgroundAwareStaleCutoffSql()}
|
|
1904
|
+
AND ${inFlightGraceSql()}`,
|
|
1905
|
+
args: [now, now],
|
|
1715
1906
|
});
|
|
1716
1907
|
for (const row of stale.rows) {
|
|
1717
1908
|
const id = (row as { id?: unknown }).id;
|
|
@@ -1729,13 +1920,15 @@ export async function reapAllStaleRuns(): Promise<number> {
|
|
|
1729
1920
|
terminal_reason = ?
|
|
1730
1921
|
WHERE status = 'running'
|
|
1731
1922
|
AND ${terminalRunEventExclusionSql()}
|
|
1732
|
-
AND ${livenessBasisSql()} < ${backgroundAwareStaleCutoffSql()}
|
|
1923
|
+
AND ${livenessBasisSql()} < ${backgroundAwareStaleCutoffSql()}
|
|
1924
|
+
AND ${inFlightGraceSql()}`,
|
|
1733
1925
|
args: [
|
|
1734
1926
|
completedAt,
|
|
1735
1927
|
STALE_RUN_ERROR_EVENT.errorCode,
|
|
1736
1928
|
STALE_RUN_ERROR_EVENT.details,
|
|
1737
1929
|
STALE_RUN_ERROR_EVENT.errorCode,
|
|
1738
1930
|
completedAt,
|
|
1931
|
+
completedAt,
|
|
1739
1932
|
],
|
|
1740
1933
|
});
|
|
1741
1934
|
for (const row of stale.rows) {
|
|
@@ -1770,15 +1963,24 @@ export async function cleanupOldRuns(
|
|
|
1770
1963
|
// SELECT covers BOTH UPDATE conditions so the terminal-event-append loop
|
|
1771
1964
|
// below catches every row we're about to flip — a 24h-old row with a
|
|
1772
1965
|
// somehow-fresh heartbeat would slip past a heartbeat-only SELECT.
|
|
1966
|
+
//
|
|
1967
|
+
// The in-flight grace clause is applied ONLY to the heartbeat-based branch
|
|
1968
|
+
// (mirroring the second UPDATE below), never the absolute-age branch:
|
|
1969
|
+
// nothing can legitimately hold in-flight work anywhere near `olderThanMs`
|
|
1970
|
+
// (default on the order of a day) — `IN_FLIGHT_RUN_STALE_GRACE_MS` bounds
|
|
1971
|
+
// any real grace at ~14.5 minutes — so a row that old is dead regardless of
|
|
1972
|
+
// its in-flight marker. This runs opportunistically after EVERY run
|
|
1973
|
+
// completes in ANY isolate, so a different thread's still-in-flight A2A
|
|
1974
|
+
// call must not be reaped as a side effect of an unrelated run finishing.
|
|
1773
1975
|
const now = Date.now();
|
|
1774
1976
|
const stale = await client.execute({
|
|
1775
1977
|
sql: `SELECT id FROM agent_runs
|
|
1776
1978
|
WHERE status = 'running'
|
|
1777
1979
|
AND (
|
|
1778
|
-
${livenessBasisSql()} < ${backgroundAwareStaleCutoffSql()}
|
|
1980
|
+
(${livenessBasisSql()} < ${backgroundAwareStaleCutoffSql()} AND ${inFlightGraceSql()})
|
|
1779
1981
|
OR started_at < ?
|
|
1780
1982
|
)`,
|
|
1781
|
-
args: [now, cutoff],
|
|
1983
|
+
args: [now, now, cutoff],
|
|
1782
1984
|
});
|
|
1783
1985
|
for (const row of stale.rows) {
|
|
1784
1986
|
const id = (row as { id?: unknown }).id;
|
|
@@ -1806,7 +2008,13 @@ export async function cleanupOldRuns(
|
|
|
1806
2008
|
],
|
|
1807
2009
|
});
|
|
1808
2010
|
// Also expire runs whose heartbeat is stale — producer has died. Uses the
|
|
1809
|
-
// background-aware window so a slow background cold-start isn't reaped
|
|
2011
|
+
// background-aware window so a slow background cold-start isn't reaped
|
|
2012
|
+
// early, and the in-flight grace so a demonstrably-alive run holding a tool
|
|
2013
|
+
// call / A2A delegation survives a heartbeat write failure. Must match the
|
|
2014
|
+
// SELECT's heartbeat branch above exactly — the terminal-event-append loop
|
|
2015
|
+
// below fires for every row the SELECT returned, so a mismatch would
|
|
2016
|
+
// silently inject a terminal error event onto a row this UPDATE left
|
|
2017
|
+
// status='running'.
|
|
1810
2018
|
await client.execute({
|
|
1811
2019
|
sql: `UPDATE agent_runs
|
|
1812
2020
|
SET status = 'errored',
|
|
@@ -1816,13 +2024,15 @@ export async function cleanupOldRuns(
|
|
|
1816
2024
|
terminal_reason = ?
|
|
1817
2025
|
WHERE status = 'running'
|
|
1818
2026
|
AND ${terminalRunEventExclusionSql()}
|
|
1819
|
-
AND ${livenessBasisSql()} < ${backgroundAwareStaleCutoffSql()}
|
|
2027
|
+
AND ${livenessBasisSql()} < ${backgroundAwareStaleCutoffSql()}
|
|
2028
|
+
AND ${inFlightGraceSql()}`,
|
|
1820
2029
|
args: [
|
|
1821
2030
|
completedAt,
|
|
1822
2031
|
STALE_RUN_ERROR_EVENT.errorCode,
|
|
1823
2032
|
STALE_RUN_ERROR_EVENT.details,
|
|
1824
2033
|
STALE_RUN_ERROR_EVENT.errorCode,
|
|
1825
2034
|
completedAt,
|
|
2035
|
+
completedAt,
|
|
1826
2036
|
],
|
|
1827
2037
|
});
|
|
1828
2038
|
for (const row of stale.rows) {
|
|
@@ -274,6 +274,29 @@ export type AgentChatEvent =
|
|
|
274
274
|
agent: string;
|
|
275
275
|
status: "start" | "done" | "error";
|
|
276
276
|
}
|
|
277
|
+
| {
|
|
278
|
+
/**
|
|
279
|
+
* Periodic liveness for an in-flight cross-app A2A call. Emitted by the
|
|
280
|
+
* `call-agent` action once per throttle window ONLY when a real poll
|
|
281
|
+
* round-trip to the remote agent succeeds and reports a non-terminal
|
|
282
|
+
* state — never on a timer, so a hung/dead remote emits nothing and the
|
|
283
|
+
* stuck-detector can still fire. Counts as real progress in
|
|
284
|
+
* `run-manager`'s `shouldBumpProgressForEvent` (any non-special event
|
|
285
|
+
* type does), which keeps `last_progress_at` fresh so a slow-but-healthy
|
|
286
|
+
* sub-agent call doesn't trip the client's stuck banner. A distinct
|
|
287
|
+
* event type (not an `agent_call` status) so existing `agent_call`
|
|
288
|
+
* consumers that treat "not start/done" as a failure don't render an
|
|
289
|
+
* in-flight tick as an error.
|
|
290
|
+
*/
|
|
291
|
+
type: "agent_call_progress";
|
|
292
|
+
agent: string;
|
|
293
|
+
/** Remote A2A task state for this poll, e.g. "working" | "submitted". */
|
|
294
|
+
state: string;
|
|
295
|
+
/** Elapsed wall-clock seconds since the cross-app call began. */
|
|
296
|
+
elapsedSeconds: number;
|
|
297
|
+
/** Optional short text surfaced from the remote poll, when present. */
|
|
298
|
+
detail?: string;
|
|
299
|
+
}
|
|
277
300
|
| { type: "agent_call_text"; agent: string; text: string }
|
|
278
301
|
| {
|
|
279
302
|
type: "agent_task";
|