@agent-native/core 0.92.11 → 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 +45 -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 +48 -5
- package/corpus/core/src/agent/run-manager.ts +171 -20
- package/corpus/core/src/agent/run-store.ts +297 -42
- 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 +110 -17
- 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/components/player/transcript-panel.tsx +27 -5
- 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/hooks/use-player-shortcuts.ts +1 -0
- 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-fixed-copying-agent-responses-and-transcript-text-from-recor.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 +92 -23
- package/corpus/templates/content/actions/_database-source-utils.ts +207 -41
- package/corpus/templates/content/actions/_property-utils.ts +30 -2
- package/corpus/templates/content/actions/add-content-database-source-field-property.ts +316 -121
- package/corpus/templates/content/actions/attach-content-database-source.ts +41 -17
- package/corpus/templates/content/actions/change-content-database-source-role.ts +46 -8
- package/corpus/templates/content/actions/submit-content-database-form.ts +497 -0
- package/corpus/templates/content/actions/suggest-source-join-key.ts +8 -1
- 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-09-builder-source-refreshes-now-keep-mapped-fields-such-as-topi.md +6 -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 +28 -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 +5 -3
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +34 -8
- 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 +124 -18
- 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 +274 -37
- 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 +97 -16
- 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/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +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/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.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
|
@@ -29,6 +29,19 @@ export interface RunStuckBannerProps {
|
|
|
29
29
|
* itself only handles aborting the prior run.
|
|
30
30
|
*/
|
|
31
31
|
onRetry?: (runId: string) => void;
|
|
32
|
+
/**
|
|
33
|
+
* Returns true when the run has a tool call or sub-agent (A2A) call that
|
|
34
|
+
* hasn't returned a result yet — typically backed by
|
|
35
|
+
* `chatHandle.hasInFlightWork()`. "No progress" for a stretch of time does
|
|
36
|
+
* not mean the run is dead: a long provider query or a cross-app `call
|
|
37
|
+
* agent` can legitimately emit nothing for minutes. When this returns
|
|
38
|
+
* true, Retry (which aborts the run) is hidden — aborting would destroy
|
|
39
|
+
* real in-flight work and re-execute the same long call from scratch.
|
|
40
|
+
* Only Cancel, an explicit destructive choice, remains available. Checked
|
|
41
|
+
* fresh on every render; omit to keep the unconditional Retry/Cancel
|
|
42
|
+
* behavior.
|
|
43
|
+
*/
|
|
44
|
+
hasInFlightWork?: () => boolean;
|
|
32
45
|
/**
|
|
33
46
|
* Called whenever the stuck state transitions. Useful for surfacing
|
|
34
47
|
* observability events (Sentry, PostHog) at the call site.
|
|
@@ -49,5 +62,5 @@ export interface RunStuckBannerProps {
|
|
|
49
62
|
/** Extra class on the outer container. */
|
|
50
63
|
className?: string;
|
|
51
64
|
}
|
|
52
|
-
export declare function RunStuckBanner({ threadId, enabled, apiUrl, stuckThresholdMs, onRetry, onStuckStateChange, autoRetry, autoRetryOwnerId, className, }: RunStuckBannerProps): import("react").JSX.Element | null;
|
|
65
|
+
export declare function RunStuckBanner({ threadId, enabled, apiUrl, stuckThresholdMs, onRetry, onStuckStateChange, autoRetry, autoRetryOwnerId, hasInFlightWork, className, }: RunStuckBannerProps): import("react").JSX.Element | null;
|
|
53
66
|
//# sourceMappingURL=RunStuckBanner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RunStuckBanner.d.ts","sourceRoot":"","sources":["../../src/client/RunStuckBanner.tsx"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,8BAA8B,CAAC;AAGtC;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACpD;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2FD,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,OAAc,EACd,MAAM,EACN,gBAAgB,EAChB,OAAO,EACP,kBAAkB,EAClB,SAAiB,EACjB,gBAAgB,EAChB,SAAS,GACV,EAAE,mBAAmB,
|
|
1
|
+
{"version":3,"file":"RunStuckBanner.d.ts","sourceRoot":"","sources":["../../src/client/RunStuckBanner.tsx"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,8BAA8B,CAAC;AAGtC;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC;IAChC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACpD;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2FD,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,OAAc,EACd,MAAM,EACN,gBAAgB,EAChB,OAAO,EACP,kBAAkB,EAClB,SAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,SAAS,GACV,EAAE,mBAAmB,sCAwPrB"}
|
|
@@ -61,7 +61,7 @@ async function claimAutoRetryAttempt(threadId, runId, ownerId) {
|
|
|
61
61
|
}
|
|
62
62
|
return markAutoRetryClaim(key, ownerId);
|
|
63
63
|
}
|
|
64
|
-
export function RunStuckBanner({ threadId, enabled = true, apiUrl, stuckThresholdMs, onRetry, onStuckStateChange, autoRetry = false, autoRetryOwnerId, className, }) {
|
|
64
|
+
export function RunStuckBanner({ threadId, enabled = true, apiUrl, stuckThresholdMs, onRetry, onStuckStateChange, autoRetry = false, autoRetryOwnerId, hasInFlightWork, className, }) {
|
|
65
65
|
const state = useRunStuckDetection({
|
|
66
66
|
threadId,
|
|
67
67
|
enabled,
|
|
@@ -77,6 +77,22 @@ export function RunStuckBanner({ threadId, enabled = true, apiUrl, stuckThreshol
|
|
|
77
77
|
}
|
|
78
78
|
const ownerId = autoRetryOwnerId ?? generatedOwnerIdRef.current;
|
|
79
79
|
const backgroundWorkerStillAlive = isFreshBackgroundWorker(state);
|
|
80
|
+
// A live tool call or sub-agent (A2A) call means "no progress" is not the
|
|
81
|
+
// same as "dead" — the process is genuinely still doing the user's work.
|
|
82
|
+
// Retry aborts the run, so it must not be offered as the (implicitly
|
|
83
|
+
// safe-looking) primary action while real work is in flight; see the
|
|
84
|
+
// `hasInFlightWork` prop doc comment. Re-checked on every render (the
|
|
85
|
+
// underlying source mutates in place as tool/agent-call events stream in),
|
|
86
|
+
// which is why this is a function prop rather than a plain boolean.
|
|
87
|
+
//
|
|
88
|
+
// Two sources, combined disjunctively (either knowing = in flight): the
|
|
89
|
+
// SERVER-authoritative `state.hasInFlightWork` from /runs/active (the
|
|
90
|
+
// `in_flight_since` marker, correct even when the client's message list is
|
|
91
|
+
// stale after a reconnect/reader-mode replay) and the client-side proxy
|
|
92
|
+
// prop (unresolved tool-call parts in the local messages). Destroying live
|
|
93
|
+
// work is the failure we guard against, so we err toward "in flight" if
|
|
94
|
+
// either signal says so.
|
|
95
|
+
const inFlightWork = state.hasInFlightWork === true || (hasInFlightWork?.() ?? false);
|
|
80
96
|
// Server-continued runs are recovered by the SERVER (chained continuation
|
|
81
97
|
// chunks + lost-handoff sweep); an automatic client abort would kill a live
|
|
82
98
|
// server-chained run. Auto-retry is therefore disabled unconditionally for
|
|
@@ -126,6 +142,9 @@ export function RunStuckBanner({ threadId, enabled = true, apiUrl, stuckThreshol
|
|
|
126
142
|
// comment on isServerContinuedDispatch above).
|
|
127
143
|
isServerContinuedDispatch ||
|
|
128
144
|
backgroundWorkerStillAlive ||
|
|
145
|
+
// A live tool/A2A call in flight — never auto-abort real work (see
|
|
146
|
+
// `inFlightWork` comment above).
|
|
147
|
+
inFlightWork ||
|
|
129
148
|
!state.isStuck ||
|
|
130
149
|
!state.runId ||
|
|
131
150
|
busy.type !== "none" ||
|
|
@@ -158,6 +177,7 @@ export function RunStuckBanner({ threadId, enabled = true, apiUrl, stuckThreshol
|
|
|
158
177
|
autoRetry,
|
|
159
178
|
backgroundWorkerStillAlive,
|
|
160
179
|
busy,
|
|
180
|
+
inFlightWork,
|
|
161
181
|
isServerContinuedDispatch,
|
|
162
182
|
onRetry,
|
|
163
183
|
ownerId,
|
|
@@ -181,7 +201,10 @@ export function RunStuckBanner({ threadId, enabled = true, apiUrl, stuckThreshol
|
|
|
181
201
|
await abortRun(runId, "user_stuck_cancel");
|
|
182
202
|
};
|
|
183
203
|
const handleRetry = async () => {
|
|
184
|
-
|
|
204
|
+
// Defense in depth: the button is hidden while `inFlightWork` is true
|
|
205
|
+
// (see render below), but guard the handler itself too so an abort can
|
|
206
|
+
// never be triggered against live work through this path.
|
|
207
|
+
if (!state.runId || busy.type !== "none" || inFlightWork)
|
|
185
208
|
return;
|
|
186
209
|
const runId = state.runId;
|
|
187
210
|
setBusy({ type: "retry", runId });
|
|
@@ -196,12 +219,17 @@ export function RunStuckBanner({ threadId, enabled = true, apiUrl, stuckThreshol
|
|
|
196
219
|
};
|
|
197
220
|
const busyType = busy.type;
|
|
198
221
|
const stuckSeconds = state.stuckSinceMs != null ? Math.floor(state.stuckSinceMs / 1000) : null;
|
|
199
|
-
|
|
222
|
+
const stillWorking = backgroundWorkerStillAlive || inFlightWork;
|
|
223
|
+
return (_jsxs("div", { role: "status", "aria-live": "polite", className: cn("mx-3 mt-2 flex items-start gap-2.5 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-2.5 text-xs text-foreground", className), children: [_jsx(IconAlertTriangle, { size: 16, className: "mt-0.5 shrink-0 text-amber-500", "aria-hidden": "true" }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [_jsxs("div", { className: "leading-snug", children: [_jsx("span", { className: "font-medium", children: stillWorking
|
|
200
224
|
? "The agent is still working."
|
|
201
|
-
: "This chat looks stuck." }), " ", _jsxs("span", { className: "text-muted-foreground", children: ["No progress", stuckSeconds != null ? ` for ${stuckSeconds}s` : "", ".", " ",
|
|
202
|
-
? "
|
|
203
|
-
:
|
|
225
|
+
: "This chat looks stuck." }), " ", _jsxs("span", { className: "text-muted-foreground", children: ["No progress", stuckSeconds != null ? ` for ${stuckSeconds}s` : "", ".", " ", inFlightWork
|
|
226
|
+
? "It's waiting on a call to another app or a long tool — canceling will stop that work."
|
|
227
|
+
: backgroundWorkerStillAlive
|
|
228
|
+
? "The background worker is still alive; large updates can take a few minutes."
|
|
229
|
+
: "The agent may have hit a server timeout or lost its connection.", autoRetry && busyType === "retry"
|
|
204
230
|
? " Retrying automatically now."
|
|
205
|
-
: ""] })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("button", { type: "button", onClick: handleRetry, disabled: busyType !== "none", className: "inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md bg-foreground px-2.5 text-[11px] font-medium text-background transition-colors hover:bg-foreground/90 disabled:cursor-not-allowed disabled:opacity-60", children: [busyType === "retry" ? (_jsx(IconLoader2, { size: 12, className: "animate-spin", "aria-hidden": "true" })) : null, "Retry"] }), _jsxs("button", { type: "button", onClick: handleCancel, disabled: busyType !== "none",
|
|
231
|
+
: ""] })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [inFlightWork ? null : (_jsxs("button", { type: "button", onClick: handleRetry, disabled: busyType !== "none", className: "inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md bg-foreground px-2.5 text-[11px] font-medium text-background transition-colors hover:bg-foreground/90 disabled:cursor-not-allowed disabled:opacity-60", children: [busyType === "retry" ? (_jsx(IconLoader2, { size: 12, className: "animate-spin", "aria-hidden": "true" })) : null, "Retry"] })), _jsxs("button", { type: "button", onClick: handleCancel, disabled: busyType !== "none", title: inFlightWork
|
|
232
|
+
? "Stop the in-progress run. Work that hasn't finished will be lost."
|
|
233
|
+
: undefined, className: "inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md border border-border bg-background px-2.5 text-[11px] font-medium text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-60", children: [busyType === "cancel" ? (_jsx(IconLoader2, { size: 12, className: "animate-spin", "aria-hidden": "true" })) : null, "Cancel"] })] })] })] }));
|
|
206
234
|
}
|
|
207
235
|
//# sourceMappingURL=RunStuckBanner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RunStuckBanner.js","sourceRoot":"","sources":["../../src/client/RunStuckBanner.tsx"],"names":[],"mappings":"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","sourcesContent":["import { IconAlertTriangle, IconLoader2 } from \"@tabler/icons-react\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { trackEvent } from \"./analytics.js\";\nimport {\n useRunStuckDetection,\n useAbortRun,\n type RunStuckState,\n} from \"./use-run-stuck-detection.js\";\nimport { cn } from \"./utils.js\";\n\n/**\n * Surface a user-visible affordance when a chat run hasn't emitted any\n * events for an unusually long time. The adapter's silent reconnect logic\n * keeps trying in the background; this banner is the fallback when those\n * attempts haven't restored progress and the user is staring at a frozen\n * spinner.\n */\nexport interface RunStuckBannerProps {\n /** The thread to monitor. Pass null/undefined to disable. */\n threadId: string | null | undefined;\n /**\n * Set false to skip polling entirely — used when this banner is mounted\n * for a background tab kept alive via display:none. Only the active tab\n * should poll `/runs/active`. Defaults to true.\n */\n enabled?: boolean;\n /** API base path. Default `/_agent-native/agent-chat`. */\n apiUrl?: string;\n /**\n * Threshold above which an in-flight run is considered stuck.\n * Defaults to 90s (after the adapter's 75s no-progress reconnect\n * has had a chance to recover).\n */\n stuckThresholdMs?: number;\n /**\n * Called when the user clicks Retry. Implementations should re-prompt\n * the agent (typically via `chatHandle.sendMessage(...)`) — the banner\n * itself only handles aborting the prior run.\n */\n onRetry?: (runId: string) => void;\n /**\n * Called whenever the stuck state transitions. Useful for surfacing\n * observability events (Sentry, PostHog) at the call site.\n */\n onStuckStateChange?: (state: RunStuckState) => void;\n /**\n * Automatically abort and retry once when the server reports a run is\n * alive but has stopped making real progress. Manual controls remain visible\n * as the fallback if the automatic recovery cannot clear the run.\n */\n autoRetry?: boolean;\n /**\n * Stable browser-tab/window id used to coordinate automatic retries across\n * multiple mounted chat views for the same thread. A local id is generated\n * when omitted.\n */\n autoRetryOwnerId?: string;\n /** Extra class on the outer container. */\n className?: string;\n}\n\nconst AUTO_RETRY_CLAIM_TTL_MS = 5 * 60 * 1000;\nconst BACKGROUND_WORKER_FRESH_HEARTBEAT_MS = 30_000;\n\ntype BusyState = { type: \"none\" } | { type: \"cancel\" | \"retry\"; runId: string };\n\ntype MaybeLockManager = {\n request<T>(\n name: string,\n options: { mode?: \"exclusive\" | \"shared\"; ifAvailable?: boolean },\n callback: (lock: unknown) => T | Promise<T>,\n ): Promise<T>;\n};\n\nfunction createAutoRetryOwnerId() {\n const cryptoApi =\n typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\"\n ? crypto\n : null;\n return cryptoApi?.randomUUID() ?? `owner-${Math.random().toString(36)}`;\n}\n\nfunction autoRetryClaimKey(threadId: string, runId: string) {\n return `agent-native:stuck-auto-retry:${threadId}:${runId}`;\n}\n\nfunction isFreshBackgroundWorker(state: RunStuckState): boolean {\n return Boolean(\n state.status === \"running\" &&\n state.dispatchMode === \"background-processing\" &&\n state.heartbeatSinceMs != null &&\n state.heartbeatSinceMs >= 0 &&\n state.heartbeatSinceMs < BACKGROUND_WORKER_FRESH_HEARTBEAT_MS,\n );\n}\n\nfunction markAutoRetryClaim(key: string, ownerId: string) {\n if (typeof window === \"undefined\") return true;\n const now = Date.now();\n try {\n const raw = window.localStorage.getItem(key);\n if (raw) {\n const existing = JSON.parse(raw) as {\n ownerId?: unknown;\n expiresAt?: unknown;\n };\n const expiresAt =\n typeof existing.expiresAt === \"number\" ? existing.expiresAt : 0;\n if (expiresAt > now && existing.ownerId !== ownerId) return false;\n }\n window.localStorage.setItem(\n key,\n JSON.stringify({ ownerId, expiresAt: now + AUTO_RETRY_CLAIM_TTL_MS }),\n );\n const confirmed = JSON.parse(window.localStorage.getItem(key) ?? \"{}\") as {\n ownerId?: unknown;\n };\n return confirmed.ownerId === ownerId;\n } catch {\n // Private browsing or disabled storage: fall back to in-tab retry. The\n // server abort is idempotent, and manual controls remain available.\n return true;\n }\n}\n\nasync function claimAutoRetryAttempt(\n threadId: string | null | undefined,\n runId: string,\n ownerId: string,\n) {\n if (!threadId) return true;\n const key = autoRetryClaimKey(threadId, runId);\n const locks =\n typeof navigator !== \"undefined\"\n ? (navigator as Navigator & { locks?: MaybeLockManager }).locks\n : undefined;\n if (locks?.request) {\n try {\n return await locks.request(\n key,\n { mode: \"exclusive\", ifAvailable: true },\n (lock) => (lock ? markAutoRetryClaim(key, ownerId) : false),\n );\n } catch {\n return markAutoRetryClaim(key, ownerId);\n }\n }\n return markAutoRetryClaim(key, ownerId);\n}\n\nexport function RunStuckBanner({\n threadId,\n enabled = true,\n apiUrl,\n stuckThresholdMs,\n onRetry,\n onStuckStateChange,\n autoRetry = false,\n autoRetryOwnerId,\n className,\n}: RunStuckBannerProps) {\n const state = useRunStuckDetection({\n threadId,\n enabled,\n stuckThresholdMs,\n apiUrl,\n });\n const abortRun = useAbortRun(apiUrl);\n const [busy, setBusy] = useState<BusyState>({ type: \"none\" });\n const autoRetriedRunIdsRef = useRef<Set<string>>(new Set());\n const generatedOwnerIdRef = useRef<string | null>(null);\n if (!generatedOwnerIdRef.current) {\n generatedOwnerIdRef.current = createAutoRetryOwnerId();\n }\n const ownerId = autoRetryOwnerId ?? generatedOwnerIdRef.current;\n const backgroundWorkerStillAlive = isFreshBackgroundWorker(state);\n // Server-continued runs are recovered by the SERVER (chained continuation\n // chunks + lost-handoff sweep); an automatic client abort would kill a live\n // server-chained run. Auto-retry is therefore disabled unconditionally for\n // these modes — not just a fresh-heartbeat worker — and the\n // localStorage/Web-Locks auto-retry claim below is never taken for them (the\n // adapter's follow loop is read-only, so multiple tabs need no retry dedup).\n // Only the manual banner remains, on the wider server-owned threshold from\n // useRunStuckDetection.\n const isServerContinuedDispatch =\n state.dispatchMode === \"foreground-self-chain\" ||\n state.dispatchMode?.startsWith(\"background\") === true;\n\n const lastReportedRef = useRef<{\n isStuck: boolean;\n runId: string | null;\n }>({ isStuck: false, runId: null });\n useEffect(() => {\n const last = lastReportedRef.current;\n if (last.isStuck === state.isStuck && last.runId === state.runId) return;\n lastReportedRef.current = { isStuck: state.isStuck, runId: state.runId };\n onStuckStateChange?.(state);\n if (state.isStuck && state.runId) {\n trackEvent(\"agent_chat_stuck_detected\", {\n runId: state.runId,\n threadId: threadId ?? null,\n stuckSinceMs: state.stuckSinceMs ?? null,\n stuckSinceSec:\n state.stuckSinceMs != null\n ? Math.floor(state.stuckSinceMs / 1000)\n : null,\n runStatus: state.status,\n });\n }\n }, [state, onStuckStateChange, threadId]);\n\n // Reset the busy spinner once the underlying run is no longer the one we\n // acted on. A recovery continuation can start quickly enough that polling\n // never observes an idle state between run ids.\n useEffect(() => {\n setBusy((current) => {\n if (current.type === \"none\") return current;\n if (state.status !== \"running\") return { type: \"none\" };\n if (state.runId && state.runId !== current.runId) return { type: \"none\" };\n return current;\n });\n }, [state.runId, state.status]);\n\n useEffect(() => {\n if (\n !autoRetry ||\n // Server owns recovery for these dispatch modes — never auto-abort (see\n // comment on isServerContinuedDispatch above).\n isServerContinuedDispatch ||\n backgroundWorkerStillAlive ||\n !state.isStuck ||\n !state.runId ||\n busy.type !== \"none\" ||\n autoRetriedRunIdsRef.current.has(state.runId)\n ) {\n return;\n }\n\n const runId = state.runId;\n void claimAutoRetryAttempt(threadId, runId, ownerId).then((claimed) => {\n autoRetriedRunIdsRef.current.add(runId);\n if (!claimed) return;\n setBusy({ type: \"retry\", runId });\n trackEvent(\"agent_chat_stuck_auto_retry\", {\n runId,\n threadId: threadId ?? null,\n stuckSinceMs: state.stuckSinceMs ?? null,\n });\n void abortRun(runId, \"auto_stuck_retry\").then((aborted) => {\n if (aborted) {\n onRetry?.(aborted);\n return;\n }\n setBusy((current) =>\n current.type !== \"none\" && current.runId === runId\n ? { type: \"none\" }\n : current,\n );\n });\n });\n }, [\n abortRun,\n autoRetry,\n backgroundWorkerStillAlive,\n busy,\n isServerContinuedDispatch,\n onRetry,\n ownerId,\n state.isStuck,\n state.runId,\n state.stuckSinceMs,\n threadId,\n ]);\n\n if (!state.isStuck || !state.runId) return null;\n\n const handleCancel = async () => {\n if (!state.runId || busy.type !== \"none\") return;\n const runId = state.runId;\n setBusy({ type: \"cancel\", runId });\n trackEvent(\"agent_chat_stuck_cancel\", {\n runId,\n threadId: threadId ?? null,\n stuckSinceMs: state.stuckSinceMs ?? null,\n });\n await abortRun(runId, \"user_stuck_cancel\");\n };\n\n const handleRetry = async () => {\n if (!state.runId || busy.type !== \"none\") return;\n const runId = state.runId;\n setBusy({ type: \"retry\", runId });\n trackEvent(\"agent_chat_stuck_retry\", {\n runId,\n threadId: threadId ?? null,\n stuckSinceMs: state.stuckSinceMs ?? null,\n });\n const aborted = await abortRun(runId, \"user_stuck_retry\");\n if (aborted) onRetry?.(aborted);\n };\n\n const busyType = busy.type;\n\n const stuckSeconds =\n state.stuckSinceMs != null ? Math.floor(state.stuckSinceMs / 1000) : null;\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={cn(\n \"mx-3 mt-2 flex items-start gap-2.5 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-2.5 text-xs text-foreground\",\n className,\n )}\n >\n <IconAlertTriangle\n size={16}\n className=\"mt-0.5 shrink-0 text-amber-500\"\n aria-hidden=\"true\"\n />\n <div className=\"flex min-w-0 flex-1 flex-col gap-1.5\">\n <div className=\"leading-snug\">\n <span className=\"font-medium\">\n {backgroundWorkerStillAlive\n ? \"The agent is still working.\"\n : \"This chat looks stuck.\"}\n </span>{\" \"}\n <span className=\"text-muted-foreground\">\n No progress\n {stuckSeconds != null ? ` for ${stuckSeconds}s` : \"\"}.{\" \"}\n {backgroundWorkerStillAlive\n ? \"The background worker is still alive; large updates can take a few minutes.\"\n : \"The agent may have hit a server timeout or lost its connection.\"}\n {autoRetry && busyType === \"retry\"\n ? \" Retrying automatically now.\"\n : \"\"}\n </span>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n onClick={handleRetry}\n disabled={busyType !== \"none\"}\n className=\"inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md bg-foreground px-2.5 text-[11px] font-medium text-background transition-colors hover:bg-foreground/90 disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {busyType === \"retry\" ? (\n <IconLoader2\n size={12}\n className=\"animate-spin\"\n aria-hidden=\"true\"\n />\n ) : null}\n Retry\n </button>\n <button\n type=\"button\"\n onClick={handleCancel}\n disabled={busyType !== \"none\"}\n className=\"inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md border border-border bg-background px-2.5 text-[11px] font-medium text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {busyType === \"cancel\" ? (\n <IconLoader2\n size={12}\n className=\"animate-spin\"\n aria-hidden=\"true\"\n />\n ) : null}\n Cancel\n </button>\n </div>\n </div>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"RunStuckBanner.js","sourceRoot":"","sources":["../../src/client/RunStuckBanner.tsx"],"names":[],"mappings":"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","sourcesContent":["import { IconAlertTriangle, IconLoader2 } from \"@tabler/icons-react\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { trackEvent } from \"./analytics.js\";\nimport {\n useRunStuckDetection,\n useAbortRun,\n type RunStuckState,\n} from \"./use-run-stuck-detection.js\";\nimport { cn } from \"./utils.js\";\n\n/**\n * Surface a user-visible affordance when a chat run hasn't emitted any\n * events for an unusually long time. The adapter's silent reconnect logic\n * keeps trying in the background; this banner is the fallback when those\n * attempts haven't restored progress and the user is staring at a frozen\n * spinner.\n */\nexport interface RunStuckBannerProps {\n /** The thread to monitor. Pass null/undefined to disable. */\n threadId: string | null | undefined;\n /**\n * Set false to skip polling entirely — used when this banner is mounted\n * for a background tab kept alive via display:none. Only the active tab\n * should poll `/runs/active`. Defaults to true.\n */\n enabled?: boolean;\n /** API base path. Default `/_agent-native/agent-chat`. */\n apiUrl?: string;\n /**\n * Threshold above which an in-flight run is considered stuck.\n * Defaults to 90s (after the adapter's 75s no-progress reconnect\n * has had a chance to recover).\n */\n stuckThresholdMs?: number;\n /**\n * Called when the user clicks Retry. Implementations should re-prompt\n * the agent (typically via `chatHandle.sendMessage(...)`) — the banner\n * itself only handles aborting the prior run.\n */\n onRetry?: (runId: string) => void;\n /**\n * Returns true when the run has a tool call or sub-agent (A2A) call that\n * hasn't returned a result yet — typically backed by\n * `chatHandle.hasInFlightWork()`. \"No progress\" for a stretch of time does\n * not mean the run is dead: a long provider query or a cross-app `call\n * agent` can legitimately emit nothing for minutes. When this returns\n * true, Retry (which aborts the run) is hidden — aborting would destroy\n * real in-flight work and re-execute the same long call from scratch.\n * Only Cancel, an explicit destructive choice, remains available. Checked\n * fresh on every render; omit to keep the unconditional Retry/Cancel\n * behavior.\n */\n hasInFlightWork?: () => boolean;\n /**\n * Called whenever the stuck state transitions. Useful for surfacing\n * observability events (Sentry, PostHog) at the call site.\n */\n onStuckStateChange?: (state: RunStuckState) => void;\n /**\n * Automatically abort and retry once when the server reports a run is\n * alive but has stopped making real progress. Manual controls remain visible\n * as the fallback if the automatic recovery cannot clear the run.\n */\n autoRetry?: boolean;\n /**\n * Stable browser-tab/window id used to coordinate automatic retries across\n * multiple mounted chat views for the same thread. A local id is generated\n * when omitted.\n */\n autoRetryOwnerId?: string;\n /** Extra class on the outer container. */\n className?: string;\n}\n\nconst AUTO_RETRY_CLAIM_TTL_MS = 5 * 60 * 1000;\nconst BACKGROUND_WORKER_FRESH_HEARTBEAT_MS = 30_000;\n\ntype BusyState = { type: \"none\" } | { type: \"cancel\" | \"retry\"; runId: string };\n\ntype MaybeLockManager = {\n request<T>(\n name: string,\n options: { mode?: \"exclusive\" | \"shared\"; ifAvailable?: boolean },\n callback: (lock: unknown) => T | Promise<T>,\n ): Promise<T>;\n};\n\nfunction createAutoRetryOwnerId() {\n const cryptoApi =\n typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\"\n ? crypto\n : null;\n return cryptoApi?.randomUUID() ?? `owner-${Math.random().toString(36)}`;\n}\n\nfunction autoRetryClaimKey(threadId: string, runId: string) {\n return `agent-native:stuck-auto-retry:${threadId}:${runId}`;\n}\n\nfunction isFreshBackgroundWorker(state: RunStuckState): boolean {\n return Boolean(\n state.status === \"running\" &&\n state.dispatchMode === \"background-processing\" &&\n state.heartbeatSinceMs != null &&\n state.heartbeatSinceMs >= 0 &&\n state.heartbeatSinceMs < BACKGROUND_WORKER_FRESH_HEARTBEAT_MS,\n );\n}\n\nfunction markAutoRetryClaim(key: string, ownerId: string) {\n if (typeof window === \"undefined\") return true;\n const now = Date.now();\n try {\n const raw = window.localStorage.getItem(key);\n if (raw) {\n const existing = JSON.parse(raw) as {\n ownerId?: unknown;\n expiresAt?: unknown;\n };\n const expiresAt =\n typeof existing.expiresAt === \"number\" ? existing.expiresAt : 0;\n if (expiresAt > now && existing.ownerId !== ownerId) return false;\n }\n window.localStorage.setItem(\n key,\n JSON.stringify({ ownerId, expiresAt: now + AUTO_RETRY_CLAIM_TTL_MS }),\n );\n const confirmed = JSON.parse(window.localStorage.getItem(key) ?? \"{}\") as {\n ownerId?: unknown;\n };\n return confirmed.ownerId === ownerId;\n } catch {\n // Private browsing or disabled storage: fall back to in-tab retry. The\n // server abort is idempotent, and manual controls remain available.\n return true;\n }\n}\n\nasync function claimAutoRetryAttempt(\n threadId: string | null | undefined,\n runId: string,\n ownerId: string,\n) {\n if (!threadId) return true;\n const key = autoRetryClaimKey(threadId, runId);\n const locks =\n typeof navigator !== \"undefined\"\n ? (navigator as Navigator & { locks?: MaybeLockManager }).locks\n : undefined;\n if (locks?.request) {\n try {\n return await locks.request(\n key,\n { mode: \"exclusive\", ifAvailable: true },\n (lock) => (lock ? markAutoRetryClaim(key, ownerId) : false),\n );\n } catch {\n return markAutoRetryClaim(key, ownerId);\n }\n }\n return markAutoRetryClaim(key, ownerId);\n}\n\nexport function RunStuckBanner({\n threadId,\n enabled = true,\n apiUrl,\n stuckThresholdMs,\n onRetry,\n onStuckStateChange,\n autoRetry = false,\n autoRetryOwnerId,\n hasInFlightWork,\n className,\n}: RunStuckBannerProps) {\n const state = useRunStuckDetection({\n threadId,\n enabled,\n stuckThresholdMs,\n apiUrl,\n });\n const abortRun = useAbortRun(apiUrl);\n const [busy, setBusy] = useState<BusyState>({ type: \"none\" });\n const autoRetriedRunIdsRef = useRef<Set<string>>(new Set());\n const generatedOwnerIdRef = useRef<string | null>(null);\n if (!generatedOwnerIdRef.current) {\n generatedOwnerIdRef.current = createAutoRetryOwnerId();\n }\n const ownerId = autoRetryOwnerId ?? generatedOwnerIdRef.current;\n const backgroundWorkerStillAlive = isFreshBackgroundWorker(state);\n // A live tool call or sub-agent (A2A) call means \"no progress\" is not the\n // same as \"dead\" — the process is genuinely still doing the user's work.\n // Retry aborts the run, so it must not be offered as the (implicitly\n // safe-looking) primary action while real work is in flight; see the\n // `hasInFlightWork` prop doc comment. Re-checked on every render (the\n // underlying source mutates in place as tool/agent-call events stream in),\n // which is why this is a function prop rather than a plain boolean.\n //\n // Two sources, combined disjunctively (either knowing = in flight): the\n // SERVER-authoritative `state.hasInFlightWork` from /runs/active (the\n // `in_flight_since` marker, correct even when the client's message list is\n // stale after a reconnect/reader-mode replay) and the client-side proxy\n // prop (unresolved tool-call parts in the local messages). Destroying live\n // work is the failure we guard against, so we err toward \"in flight\" if\n // either signal says so.\n const inFlightWork =\n state.hasInFlightWork === true || (hasInFlightWork?.() ?? false);\n // Server-continued runs are recovered by the SERVER (chained continuation\n // chunks + lost-handoff sweep); an automatic client abort would kill a live\n // server-chained run. Auto-retry is therefore disabled unconditionally for\n // these modes — not just a fresh-heartbeat worker — and the\n // localStorage/Web-Locks auto-retry claim below is never taken for them (the\n // adapter's follow loop is read-only, so multiple tabs need no retry dedup).\n // Only the manual banner remains, on the wider server-owned threshold from\n // useRunStuckDetection.\n const isServerContinuedDispatch =\n state.dispatchMode === \"foreground-self-chain\" ||\n state.dispatchMode?.startsWith(\"background\") === true;\n\n const lastReportedRef = useRef<{\n isStuck: boolean;\n runId: string | null;\n }>({ isStuck: false, runId: null });\n useEffect(() => {\n const last = lastReportedRef.current;\n if (last.isStuck === state.isStuck && last.runId === state.runId) return;\n lastReportedRef.current = { isStuck: state.isStuck, runId: state.runId };\n onStuckStateChange?.(state);\n if (state.isStuck && state.runId) {\n trackEvent(\"agent_chat_stuck_detected\", {\n runId: state.runId,\n threadId: threadId ?? null,\n stuckSinceMs: state.stuckSinceMs ?? null,\n stuckSinceSec:\n state.stuckSinceMs != null\n ? Math.floor(state.stuckSinceMs / 1000)\n : null,\n runStatus: state.status,\n });\n }\n }, [state, onStuckStateChange, threadId]);\n\n // Reset the busy spinner once the underlying run is no longer the one we\n // acted on. A recovery continuation can start quickly enough that polling\n // never observes an idle state between run ids.\n useEffect(() => {\n setBusy((current) => {\n if (current.type === \"none\") return current;\n if (state.status !== \"running\") return { type: \"none\" };\n if (state.runId && state.runId !== current.runId) return { type: \"none\" };\n return current;\n });\n }, [state.runId, state.status]);\n\n useEffect(() => {\n if (\n !autoRetry ||\n // Server owns recovery for these dispatch modes — never auto-abort (see\n // comment on isServerContinuedDispatch above).\n isServerContinuedDispatch ||\n backgroundWorkerStillAlive ||\n // A live tool/A2A call in flight — never auto-abort real work (see\n // `inFlightWork` comment above).\n inFlightWork ||\n !state.isStuck ||\n !state.runId ||\n busy.type !== \"none\" ||\n autoRetriedRunIdsRef.current.has(state.runId)\n ) {\n return;\n }\n\n const runId = state.runId;\n void claimAutoRetryAttempt(threadId, runId, ownerId).then((claimed) => {\n autoRetriedRunIdsRef.current.add(runId);\n if (!claimed) return;\n setBusy({ type: \"retry\", runId });\n trackEvent(\"agent_chat_stuck_auto_retry\", {\n runId,\n threadId: threadId ?? null,\n stuckSinceMs: state.stuckSinceMs ?? null,\n });\n void abortRun(runId, \"auto_stuck_retry\").then((aborted) => {\n if (aborted) {\n onRetry?.(aborted);\n return;\n }\n setBusy((current) =>\n current.type !== \"none\" && current.runId === runId\n ? { type: \"none\" }\n : current,\n );\n });\n });\n }, [\n abortRun,\n autoRetry,\n backgroundWorkerStillAlive,\n busy,\n inFlightWork,\n isServerContinuedDispatch,\n onRetry,\n ownerId,\n state.isStuck,\n state.runId,\n state.stuckSinceMs,\n threadId,\n ]);\n\n if (!state.isStuck || !state.runId) return null;\n\n const handleCancel = async () => {\n if (!state.runId || busy.type !== \"none\") return;\n const runId = state.runId;\n setBusy({ type: \"cancel\", runId });\n trackEvent(\"agent_chat_stuck_cancel\", {\n runId,\n threadId: threadId ?? null,\n stuckSinceMs: state.stuckSinceMs ?? null,\n });\n await abortRun(runId, \"user_stuck_cancel\");\n };\n\n const handleRetry = async () => {\n // Defense in depth: the button is hidden while `inFlightWork` is true\n // (see render below), but guard the handler itself too so an abort can\n // never be triggered against live work through this path.\n if (!state.runId || busy.type !== \"none\" || inFlightWork) return;\n const runId = state.runId;\n setBusy({ type: \"retry\", runId });\n trackEvent(\"agent_chat_stuck_retry\", {\n runId,\n threadId: threadId ?? null,\n stuckSinceMs: state.stuckSinceMs ?? null,\n });\n const aborted = await abortRun(runId, \"user_stuck_retry\");\n if (aborted) onRetry?.(aborted);\n };\n\n const busyType = busy.type;\n\n const stuckSeconds =\n state.stuckSinceMs != null ? Math.floor(state.stuckSinceMs / 1000) : null;\n\n const stillWorking = backgroundWorkerStillAlive || inFlightWork;\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={cn(\n \"mx-3 mt-2 flex items-start gap-2.5 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-2.5 text-xs text-foreground\",\n className,\n )}\n >\n <IconAlertTriangle\n size={16}\n className=\"mt-0.5 shrink-0 text-amber-500\"\n aria-hidden=\"true\"\n />\n <div className=\"flex min-w-0 flex-1 flex-col gap-1.5\">\n <div className=\"leading-snug\">\n <span className=\"font-medium\">\n {stillWorking\n ? \"The agent is still working.\"\n : \"This chat looks stuck.\"}\n </span>{\" \"}\n <span className=\"text-muted-foreground\">\n No progress\n {stuckSeconds != null ? ` for ${stuckSeconds}s` : \"\"}.{\" \"}\n {inFlightWork\n ? \"It's waiting on a call to another app or a long tool — canceling will stop that work.\"\n : backgroundWorkerStillAlive\n ? \"The background worker is still alive; large updates can take a few minutes.\"\n : \"The agent may have hit a server timeout or lost its connection.\"}\n {autoRetry && busyType === \"retry\"\n ? \" Retrying automatically now.\"\n : \"\"}\n </span>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n {inFlightWork ? null : (\n <button\n type=\"button\"\n onClick={handleRetry}\n disabled={busyType !== \"none\"}\n className=\"inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md bg-foreground px-2.5 text-[11px] font-medium text-background transition-colors hover:bg-foreground/90 disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {busyType === \"retry\" ? (\n <IconLoader2\n size={12}\n className=\"animate-spin\"\n aria-hidden=\"true\"\n />\n ) : null}\n Retry\n </button>\n )}\n <button\n type=\"button\"\n onClick={handleCancel}\n disabled={busyType !== \"none\"}\n title={\n inFlightWork\n ? \"Stop the in-progress run. Work that hasn't finished will be lost.\"\n : undefined\n }\n className=\"inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md border border-border bg-background px-2.5 text-[11px] font-medium text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {busyType === \"cancel\" ? (\n <IconLoader2\n size={12}\n className=\"animate-spin\"\n aria-hidden=\"true\"\n />\n ) : null}\n Cancel\n </button>\n </div>\n </div>\n </div>\n );\n}\n"]}
|
|
@@ -9,7 +9,10 @@ export type AgentChatSurfaceKind =
|
|
|
9
9
|
*/
|
|
10
10
|
"app"
|
|
11
11
|
/** Chat rendered by the outer local dev frame, outside the app iframe. */
|
|
12
|
-
| "dev-frame"
|
|
12
|
+
| "dev-frame"
|
|
13
|
+
/** Chat hosted by Desktop for a local app with explicit code access. */
|
|
14
|
+
| "desktop";
|
|
15
|
+
export declare const BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS = 150000;
|
|
13
16
|
/**
|
|
14
17
|
* The composer's exec mode is sent as explicit request metadata. The server
|
|
15
18
|
* owns the plan-mode prompt and read-only tool filtering so the chat history
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-chat-adapter.d.ts","sourceRoot":"","sources":["../../src/client/agent-chat-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-chat-adapter.d.ts","sourceRoot":"","sources":["../../src/client/agent-chat-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,qBAAqB,CAAC;AAWhF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAmBrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,MAAM,oBAAoB;AAC9B;;;;GAIG;AACD,KAAK;AACP,0EAA0E;GACxE,WAAW;AACb,wEAAwE;GACtE,SAAS,CAAC;AAwId,eAAO,MAAM,iCAAiC,SAAU,CAAC;AA6nCzD;;;;GAIG;AACH;;;GAGG;AACH,MAAM,WAAW,6BAA6B;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IAC3C,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IAC5C,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,eAAe,GAAG,SAAS,CAAA;KAAE,CAAC;IACrD,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,CAAA;KAAE,CAAC;IAC3D,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC;AAyED,wBAAgB,sBAAsB,CACpC,OAAO,CAAC,EAAE,6BAA6B,GACtC,gBAAgB,CA6iElB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { actionPreparationContinuationNote } from "../agent/action-continuation-guidance.js";
|
|
2
|
+
import { LLM_MISSING_CREDENTIALS_ERROR_CODE, LLM_MISSING_CREDENTIALS_MESSAGE, } from "../agent/engine/credential-errors.js";
|
|
2
3
|
import { setActiveRun, updateActiveRunSeq, clearActiveRun, } from "./active-run-state.js";
|
|
3
4
|
import { captureError } from "./analytics.js";
|
|
4
5
|
import { agentNativePath } from "./api-path.js";
|
|
@@ -96,18 +97,42 @@ const BACKGROUND_FOLLOW_POLL_INTERVAL_MS = 1_000;
|
|
|
96
97
|
// the 25s grace plus sweep/DB latency. This stays below the background
|
|
97
98
|
// reconnect stuck threshold, but gives the server-owned recovery brain time to
|
|
98
99
|
// surface the successor or terminal errored run before the client reports idle.
|
|
99
|
-
|
|
100
|
+
//
|
|
101
|
+
// THREE-SITE INVARIANT (keep in lockstep with run-store.ts and
|
|
102
|
+
// agent-chat-plugin.ts — see `UNCLAIMED_BACKGROUND_RUN_FAST_SWEEP_MS`'s doc
|
|
103
|
+
// comment in run-store.ts for the full derivation): a `chainServerDrivenContinuation`
|
|
104
|
+
// deferral (server/production-agent.ts) leaves a successor row `running` with
|
|
105
|
+
// no live worker until a sweep redispatches it. The budget is a derived
|
|
106
|
+
// chain, each bound comfortably inside the next:
|
|
107
|
+
// UNCLAIMED_BACKGROUND_RUN_GRACE_MS (25s)
|
|
108
|
+
// + UNCLAIMED_BACKGROUND_RUN_FAST_SWEEP_MS (20s)
|
|
109
|
+
// = ~45-65s worst-case time-to-first-redispatch-attempt
|
|
110
|
+
// < BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS (150s, this constant)
|
|
111
|
+
// < UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS (300s, run-store.ts)
|
|
112
|
+
// On top of that margin, the follow loop below never counts a tick against
|
|
113
|
+
// this timeout at all while `/runs/active` reports `awaitingRedispatch:
|
|
114
|
+
// true` — a server-authoritative "known deferred, recovery in progress"
|
|
115
|
+
// signal, not a guess — so this timeout is a backstop for a genuinely lost
|
|
116
|
+
// run, not the primary mechanism racing the sweep. Do NOT raise this value to
|
|
117
|
+
// paper over a slow sweep; fix the sweep timing (run-store.ts /
|
|
118
|
+
// agent-chat-plugin.ts) instead, and keep this comment's inequality chain
|
|
119
|
+
// accurate if any of the four numbers change.
|
|
120
|
+
export const BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS = 150_000;
|
|
100
121
|
/**
|
|
101
122
|
* User-facing copy for the server's background terminal reasons
|
|
102
123
|
* (`agent_runs.terminal_reason`, surfaced by /runs/active). These runs died in
|
|
103
124
|
* server-side handoff machinery where no richer error event may exist, so the
|
|
104
125
|
* client owns the message. Keys are matched after stripping an optional
|
|
105
|
-
* `error:` prefix (`terminalReasonForEvent` records `error:<code>`).
|
|
126
|
+
* `error:` prefix (`terminalReasonForEvent` records `error:<code>`). Keep this
|
|
127
|
+
* map scoped to terminal failures, including reasons that must override a
|
|
128
|
+
* mistakenly completed row.
|
|
106
129
|
*/
|
|
107
130
|
const BACKGROUND_TERMINAL_REASON_MESSAGES = {
|
|
108
131
|
background_worker_never_started: "The agent run was handed off to a background worker that never started. It was recovered so you can try again.",
|
|
109
132
|
background_continuation_dispatch_failed: "The agent's background worker could not hand off the next step of this run. Retry to continue from the preserved context.",
|
|
110
133
|
dispatch_payload_missing: "The agent's background run lost its saved request data and could not continue. Retry to start a fresh run.",
|
|
134
|
+
missing_api_key: LLM_MISSING_CREDENTIALS_MESSAGE,
|
|
135
|
+
missing_credentials: LLM_MISSING_CREDENTIALS_MESSAGE,
|
|
111
136
|
turn_continuation_budget_exhausted: "This request needed more automatic continuations than allowed and was stopped. Try breaking it into smaller steps.",
|
|
112
137
|
};
|
|
113
138
|
function normalizeMentions(text) {
|
|
@@ -1399,6 +1424,11 @@ export function createAgentChatAdapter(options) {
|
|
|
1399
1424
|
}
|
|
1400
1425
|
};
|
|
1401
1426
|
const reconnectCursorForRun = (nextRunId, previousRunId) => {
|
|
1427
|
+
if (previousRunId !== nextRunId) {
|
|
1428
|
+
lastAutoContinueReason = null;
|
|
1429
|
+
lastRecoverableRunError = null;
|
|
1430
|
+
lastActivityTrail = [];
|
|
1431
|
+
}
|
|
1402
1432
|
const rememberedSeq = seenRunSeqs.get(nextRunId);
|
|
1403
1433
|
if (rememberedSeq !== undefined) {
|
|
1404
1434
|
lastSeq = rememberedSeq;
|
|
@@ -1705,6 +1735,9 @@ export function createAgentChatAdapter(options) {
|
|
|
1705
1735
|
...(runId ? { runId } : {}),
|
|
1706
1736
|
};
|
|
1707
1737
|
if (typeof window !== "undefined") {
|
|
1738
|
+
if (args.errorCode === LLM_MISSING_CREDENTIALS_ERROR_CODE) {
|
|
1739
|
+
dispatchMissingApiKey();
|
|
1740
|
+
}
|
|
1708
1741
|
window.dispatchEvent(new CustomEvent("agent-chat:run-error", {
|
|
1709
1742
|
detail: { ...runError, tabId },
|
|
1710
1743
|
}));
|
|
@@ -1735,7 +1768,41 @@ export function createAgentChatAdapter(options) {
|
|
|
1735
1768
|
: "";
|
|
1736
1769
|
// terminal_reason is either a bare reason ("dispatch_payload_missing")
|
|
1737
1770
|
// or "error:<errorCode>" when derived from a terminal error event.
|
|
1771
|
+
const hasErrorTerminalReason = rawTerminalReason.startsWith("error:");
|
|
1738
1772
|
const terminalReason = rawTerminalReason.replace(/^error:/, "");
|
|
1773
|
+
const mappedMessage = terminalReason
|
|
1774
|
+
? BACKGROUND_TERMINAL_REASON_MESSAGES[terminalReason]
|
|
1775
|
+
: undefined;
|
|
1776
|
+
const mappedErrorCode = terminalReason === "missing_api_key" ||
|
|
1777
|
+
terminalReason === LLM_MISSING_CREDENTIALS_ERROR_CODE
|
|
1778
|
+
? LLM_MISSING_CREDENTIALS_ERROR_CODE
|
|
1779
|
+
: terminalReason;
|
|
1780
|
+
if (mappedMessage) {
|
|
1781
|
+
yield* emitBackgroundTerminalError({
|
|
1782
|
+
message: mappedMessage,
|
|
1783
|
+
errorCode: mappedErrorCode,
|
|
1784
|
+
details: `terminal_reason: ${rawTerminalReason}`,
|
|
1785
|
+
});
|
|
1786
|
+
return;
|
|
1787
|
+
}
|
|
1788
|
+
if (hasErrorTerminalReason) {
|
|
1789
|
+
if (lastRecoverableRunError) {
|
|
1790
|
+
yield* emitBackgroundTerminalError({
|
|
1791
|
+
message: lastRecoverableRunError.message,
|
|
1792
|
+
errorCode: lastRecoverableRunError.errorCode ||
|
|
1793
|
+
mappedErrorCode ||
|
|
1794
|
+
"background_run_failed",
|
|
1795
|
+
details: lastRecoverableRunError.details,
|
|
1796
|
+
});
|
|
1797
|
+
return;
|
|
1798
|
+
}
|
|
1799
|
+
yield* emitBackgroundTerminalError({
|
|
1800
|
+
message: "The agent's background run failed before its final response could be recovered. You can retry from the preserved chat context.",
|
|
1801
|
+
errorCode: mappedErrorCode || "background_run_failed",
|
|
1802
|
+
details: `terminal_reason: ${rawTerminalReason}`,
|
|
1803
|
+
});
|
|
1804
|
+
return;
|
|
1805
|
+
}
|
|
1739
1806
|
if (status === "completed") {
|
|
1740
1807
|
// The turn finished server-side; the events we managed to fold are
|
|
1741
1808
|
// the durable transcript. Finalize with them.
|
|
@@ -1750,17 +1817,6 @@ export function createAgentChatAdapter(options) {
|
|
|
1750
1817
|
clearActiveRun();
|
|
1751
1818
|
return;
|
|
1752
1819
|
}
|
|
1753
|
-
const mappedMessage = terminalReason
|
|
1754
|
-
? BACKGROUND_TERMINAL_REASON_MESSAGES[terminalReason]
|
|
1755
|
-
: undefined;
|
|
1756
|
-
if (mappedMessage) {
|
|
1757
|
-
yield* emitBackgroundTerminalError({
|
|
1758
|
-
message: mappedMessage,
|
|
1759
|
-
errorCode: terminalReason,
|
|
1760
|
-
details: `terminal_reason: ${rawTerminalReason}`,
|
|
1761
|
-
});
|
|
1762
|
-
return;
|
|
1763
|
-
}
|
|
1764
1820
|
if (lastRecoverableRunError) {
|
|
1765
1821
|
// A replayed terminal error event already carried the real
|
|
1766
1822
|
// message (recoverable errors replay as auto-continue signals
|
|
@@ -1934,10 +1990,24 @@ export function createAgentChatAdapter(options) {
|
|
|
1934
1990
|
if (isTerminal) {
|
|
1935
1991
|
replayedTerminalRunIds.add(activeRunId);
|
|
1936
1992
|
}
|
|
1937
|
-
|
|
1993
|
+
// Server-authoritative "silently deferred, recovery in
|
|
1994
|
+
// progress" signal (see `awaitingRedispatch` on
|
|
1995
|
+
// `getActiveRunForThreadAsync`, run-manager.ts): a
|
|
1996
|
+
// `chainServerDrivenContinuation` successor still inside
|
|
1997
|
+
// `UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS`, being
|
|
1998
|
+
// redispatched by the server's fast/slow sweeps. This is known
|
|
1999
|
+
// to demonstrably exist — same as a "detached" attach — so
|
|
2000
|
+
// treat it identically and never accumulate idle time against
|
|
2001
|
+
// it. Once the server's own bound is exceeded (or the row is
|
|
2002
|
+
// claimed/terminal) this flips false and normal idle accounting
|
|
2003
|
+
// resumes, so a truly stuck deferral still fails loud via the
|
|
2004
|
+
// existing timeout below.
|
|
2005
|
+
const awaitingRedispatch = active?.awaitingRedispatch === true;
|
|
2006
|
+
if (attach === "detached" || awaitingRedispatch) {
|
|
1938
2007
|
// We really attached to a live stream (chunk boundary or
|
|
1939
|
-
// transport blip)
|
|
1940
|
-
//
|
|
2008
|
+
// transport blip), or the server told us recovery is
|
|
2009
|
+
// in-flight — the run demonstrably exists; keep following
|
|
2010
|
+
// with a fresh idle window.
|
|
1941
2011
|
idleSince = null;
|
|
1942
2012
|
}
|
|
1943
2013
|
else {
|
|
@@ -2320,7 +2390,18 @@ export function createAgentChatAdapter(options) {
|
|
|
2320
2390
|
recoverable: true,
|
|
2321
2391
|
runId: activeRunId,
|
|
2322
2392
|
};
|
|
2393
|
+
// This is a terminal outcome for the attempted turn. Settle
|
|
2394
|
+
// both real in-flight calls and activity-only placeholders
|
|
2395
|
+
// before yielding the error; otherwise a prior "Preparing
|
|
2396
|
+
// run-code" event remains an unresolved tool card and the UI
|
|
2397
|
+
// keeps showing a spinner beside an already-terminal error.
|
|
2398
|
+
settleInterruptedToolCalls(content, undefined, {
|
|
2399
|
+
includeActivity: true,
|
|
2400
|
+
});
|
|
2323
2401
|
if (typeof window !== "undefined") {
|
|
2402
|
+
window.dispatchEvent(new CustomEvent("agent-chat:activity-clear", {
|
|
2403
|
+
detail: { tabId },
|
|
2404
|
+
}));
|
|
2324
2405
|
window.dispatchEvent(new CustomEvent("agent-chat:run-error", {
|
|
2325
2406
|
detail: { ...runError, tabId },
|
|
2326
2407
|
}));
|