@agent-native/core 0.108.0 → 0.109.1
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 +25 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/client.ts +162 -17
- package/corpus/core/src/a2a/correlation.ts +50 -0
- package/corpus/core/src/a2a/handlers.ts +200 -14
- package/corpus/core/src/a2a/index.ts +7 -1
- package/corpus/core/src/a2a/invoke.ts +77 -1
- package/corpus/core/src/a2a/server.ts +13 -1
- package/corpus/core/src/a2a/task-store.ts +146 -6
- package/corpus/core/src/a2a/types.ts +32 -0
- package/corpus/core/src/action.ts +5 -2
- package/corpus/core/src/agent/production-agent.ts +33 -4
- package/corpus/core/src/client/AssistantChat.tsx +648 -603
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +31 -4
- package/corpus/core/src/client/agent-chat-adapter.ts +23 -37
- package/corpus/core/src/client/agent-sidebar-state.ts +4 -0
- package/corpus/core/src/client/analytics.ts +84 -0
- package/corpus/core/src/client/chat/message-components.tsx +94 -22
- package/corpus/core/src/client/chat/tool-call-display.tsx +170 -47
- package/corpus/core/src/client/chat/use-agent-chat-lifecycle-tracking.ts +74 -0
- package/corpus/core/src/client/chat-thread-url.ts +11 -0
- package/corpus/core/src/client/error-capture.ts +12 -0
- package/corpus/core/src/client/extensions/ExtensionSlot.tsx +37 -1
- package/corpus/core/src/client/index.ts +2 -0
- package/corpus/core/src/client/route-chunk-recovery.ts +20 -8
- package/corpus/core/src/client/session-replay.ts +31 -0
- package/corpus/core/src/client/use-run-stuck-detection.ts +27 -1
- package/corpus/core/src/db/client.ts +55 -0
- package/corpus/core/src/extensions/actions.ts +2 -14
- package/corpus/core/src/extensions/store.ts +1 -1
- package/corpus/core/src/localization/default-messages.ts +3 -0
- package/corpus/core/src/mcp/build-server.ts +2 -2
- package/corpus/core/src/observability/traces.ts +172 -19
- package/corpus/core/src/progress/actions.ts +4 -2
- package/corpus/core/src/provider-api/index.ts +205 -105
- package/corpus/core/src/scripts/call-agent.ts +190 -19
- package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +112 -25
- package/corpus/core/src/server/agent-chat-plugin.ts +136 -4
- package/corpus/core/src/styles/agent-conversation.css +7 -0
- package/corpus/core/src/templates/default/app/i18n/ar-SA.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/de-DE.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/en-US.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/es-ES.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/fr-FR.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/hi-IN.ts +19 -0
- package/corpus/core/src/templates/default/app/i18n/ja-JP.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/ko-KR.ts +19 -0
- package/corpus/core/src/templates/default/app/i18n/pt-BR.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/zh-CN.ts +19 -0
- package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +19 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +49 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +29 -10
- package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +54 -23
- package/corpus/templates/analytics/.builder/skills/apollo/SKILL.md +19 -41
- package/corpus/templates/analytics/.builder/skills/commonroom/SKILL.md +20 -35
- package/corpus/templates/analytics/.builder/skills/github/SKILL.md +23 -67
- package/corpus/templates/analytics/.builder/skills/pylon/SKILL.md +25 -43
- package/corpus/templates/analytics/AGENTS.md +22 -13
- package/corpus/templates/analytics/actions/account-deep-dive.ts +1 -0
- package/corpus/templates/analytics/actions/configure-gong-native-insights.ts +29 -0
- package/corpus/templates/analytics/actions/content-calendar-schema.ts +8 -4
- package/corpus/templates/analytics/actions/content-calendar.ts +12 -4
- package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +2 -1
- package/corpus/templates/analytics/actions/gong-calls.ts +113 -22
- package/corpus/templates/analytics/actions/gong-native-insights.ts +166 -0
- package/corpus/templates/analytics/actions/hubspot-deals.ts +190 -46
- package/corpus/templates/analytics/actions/pylon-issues.ts +123 -0
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
- package/corpus/templates/analytics/actions/slack-messages.ts +179 -27
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +48 -152
- package/corpus/templates/analytics/app/components/ui/chart.tsx +1 -1
- package/corpus/templates/analytics/app/hooks/use-chart-tooltip-flip.ts +21 -6
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +13 -0
- package/corpus/templates/analytics/app/i18n-data.ts +134 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +181 -30
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +6 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +4 -3
- package/corpus/templates/analytics/changelog/2026-07-17-analytics-now-includes-a-default-alert-for-spikes-in-stuck-agent-chats.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-dashboard-editors-can-add-shared-extensions-or-opt-into-per-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-dashboard-extensions-show-a-loading-skeleton.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-errors-now-group-repeat-failures-consistently-and-keep-priva.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-gong-transcript-reviews-now-batch-bounded-call-windows-for-f.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-hubspot-deal-filters-now-run-in-hubspot-before-paging-result.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-notion-content-calendars-now-discover-the-matching-database-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-pylon-dashboard-reads-now-use-the-paginated-issue-search-api.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-slack-reads-no-longer-join-channels-and-report-pagination-coverage.md +6 -0
- package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +23 -14
- package/corpus/templates/analytics/docs/schemas/tracked-events.md +5 -1
- package/corpus/templates/analytics/server/handlers/notion.ts +14 -3
- package/corpus/templates/analytics/server/handlers/slack.ts +182 -29
- package/corpus/templates/analytics/server/jobs/analytics-alerts.ts +3 -3
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +2 -6
- package/corpus/templates/analytics/server/lib/analytics-alerts.ts +209 -87
- package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +6 -2
- package/corpus/templates/analytics/server/lib/error-capture.ts +75 -8
- package/corpus/templates/analytics/server/lib/gong-native-policy.ts +72 -0
- package/corpus/templates/analytics/server/lib/gong.ts +54 -66
- package/corpus/templates/analytics/server/lib/hubspot.ts +40 -3
- package/corpus/templates/analytics/server/lib/notion.ts +83 -8
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +4 -0
- package/corpus/templates/analytics/server/lib/slack.ts +242 -90
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +3 -3
- package/corpus/templates/analytics/server/routes/api/pylon/accounts.get.ts +42 -1
- package/corpus/templates/analytics/server/routes/api/pylon/issues.get.ts +71 -1
- package/corpus/templates/analytics/server/routes/api/test-connection.post.ts +44 -4
- package/corpus/templates/clips/actions/finalize-recording.ts +541 -62
- package/corpus/templates/clips/app/components/library/bulk-action-toolbar.tsx +19 -1
- package/corpus/templates/clips/app/components/library/create-folder-dialog.tsx +123 -0
- package/corpus/templates/clips/app/components/library/library-grid.tsx +42 -4
- package/corpus/templates/clips/app/components/library/recording-card.tsx +30 -0
- package/corpus/templates/clips/app/components/player/playback-comment-overlay.tsx +17 -2
- package/corpus/templates/clips/app/components/player/video-player.tsx +14 -2
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +2 -2
- package/corpus/templates/clips/app/entry.client.tsx +6 -1
- package/corpus/templates/clips/app/i18n/ar-SA.ts +12 -1
- package/corpus/templates/clips/app/i18n/de-DE.ts +12 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +12 -1
- package/corpus/templates/clips/app/i18n/es-ES.ts +11 -1
- package/corpus/templates/clips/app/i18n/fr-FR.ts +11 -1
- package/corpus/templates/clips/app/i18n/hi-IN.ts +10 -1
- package/corpus/templates/clips/app/i18n/ja-JP.ts +12 -1
- package/corpus/templates/clips/app/i18n/ko-KR.ts +11 -1
- package/corpus/templates/clips/app/i18n/pt-BR.ts +11 -1
- package/corpus/templates/clips/app/i18n/zh-CN.ts +11 -1
- package/corpus/templates/clips/app/i18n/zh-TW.ts +11 -1
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +72 -1
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -1
- package/corpus/templates/clips/app/routes/record.tsx +3 -3
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +6 -3
- package/corpus/templates/clips/changelog/2026-07-17-choose-which-workspace-receives-new-clips-recordings-and-des.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-clips-now-retries-storage-verification-in-the-background-ins.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-create-folders-directly-from-the-move-menu.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-failed-desktop-uploads-now-offer-a-direct-way-to-reopen-clip.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-fixed-broken-thumbnail-icons-appearing-over-playable-clip-em.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-playback-comments-stay-readable-at-faster-playback-speeds.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/finalize-recovery.ts +3 -0
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +3 -3
- package/corpus/templates/clips/desktop/src/app.tsx +19 -7
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +111 -13
- package/corpus/templates/clips/desktop/src/lib/upload-verification.ts +16 -7
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -4
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +32 -15
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +45 -18
- package/corpus/templates/clips/server/jobs/media-verification.ts +130 -0
- package/corpus/templates/clips/server/lib/builder-media-compression.ts +15 -0
- package/corpus/templates/clips/server/lib/media-verification-state.ts +38 -0
- package/corpus/templates/clips/server/lib/player-thumbnail-url.ts +31 -0
- package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +10 -3
- package/corpus/templates/clips/server/plugins/auth.ts +5 -5
- package/corpus/templates/clips/server/plugins/calendar-jobs.ts +2 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +12 -2
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +6 -1
- package/corpus/templates/clips/server/routes/api/thumbnail/[recordingId].get.ts +340 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +24 -7
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +91 -7
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/status.get.ts +14 -0
- package/corpus/templates/clips/shared/finalize-recovery.ts +61 -2
- package/corpus/templates/clips/shared/share-meta.ts +1 -1
- package/corpus/templates/content/app/entry.client.tsx +6 -1
- package/corpus/templates/dispatch/AGENTS.md +5 -0
- package/corpus/templates/dispatch/changelog/2026-07-17-apps-page-links-to-other-available-apps.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-17-curated-template-remixes.md +6 -0
- package/corpus/templates/mail/app/entry.client.tsx +6 -1
- package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +11 -7
- package/corpus/templates/slides/.env.example +0 -1
- package/corpus/templates/slides/AGENTS.md +4 -0
- package/corpus/templates/slides/DEVELOPING.md +2 -2
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +1 -1
- package/corpus/templates/slides/actions/logo-config.ts +6 -7
- package/corpus/templates/slides/actions/search-images.ts +11 -39
- package/corpus/templates/slides/actions/search-logos.ts +5 -52
- package/corpus/templates/slides/app/components/editor/ImageSearchPanel.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/LogoSearchPanel.tsx +16 -26
- package/corpus/templates/slides/app/entry.client.tsx +6 -1
- package/corpus/templates/slides/server/lib/media-search-providers.ts +216 -0
- package/corpus/templates/slides/server/register-secrets.ts +30 -0
- package/dist/a2a/client.d.ts +47 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +94 -12
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/correlation.d.ts +10 -0
- package/dist/a2a/correlation.d.ts.map +1 -0
- package/dist/a2a/correlation.js +40 -0
- package/dist/a2a/correlation.js.map +1 -0
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +147 -15
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/index.d.ts +4 -4
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +2 -2
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/invoke.d.ts +29 -2
- package/dist/a2a/invoke.d.ts.map +1 -1
- package/dist/a2a/invoke.js +33 -1
- package/dist/a2a/invoke.js.map +1 -1
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +14 -1
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/task-store.d.ts +12 -1
- package/dist/a2a/task-store.d.ts.map +1 -1
- package/dist/a2a/task-store.js +96 -6
- package/dist/a2a/task-store.js.map +1 -1
- package/dist/a2a/types.d.ts +27 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/action.d.ts +5 -2
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js.map +1 -1
- package/dist/agent/production-agent.d.ts +14 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +19 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +14 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +158 -136
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +27 -4
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +21 -39
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-sidebar-state.d.ts +1 -0
- package/dist/client/agent-sidebar-state.d.ts.map +1 -1
- package/dist/client/agent-sidebar-state.js +4 -0
- package/dist/client/agent-sidebar-state.js.map +1 -1
- package/dist/client/analytics.d.ts +14 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +67 -0
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +8 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +62 -19
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +6 -0
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +83 -14
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts +8 -0
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts.map +1 -0
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.js +51 -0
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.js.map +1 -0
- package/dist/client/chat-thread-url.d.ts +2 -0
- package/dist/client/chat-thread-url.d.ts.map +1 -0
- package/dist/client/chat-thread-url.js +12 -0
- package/dist/client/chat-thread-url.js.map +1 -0
- package/dist/client/error-capture.d.ts.map +1 -1
- package/dist/client/error-capture.js +7 -0
- package/dist/client/error-capture.js.map +1 -1
- package/dist/client/extensions/ExtensionSlot.d.ts +3 -1
- package/dist/client/extensions/ExtensionSlot.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionSlot.js +28 -3
- package/dist/client/extensions/ExtensionSlot.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/route-chunk-recovery.d.ts.map +1 -1
- package/dist/client/route-chunk-recovery.js +14 -9
- package/dist/client/route-chunk-recovery.js.map +1 -1
- package/dist/client/session-replay.d.ts +15 -0
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +20 -0
- package/dist/client/session-replay.js.map +1 -1
- package/dist/client/use-run-stuck-detection.d.ts.map +1 -1
- package/dist/client/use-run-stuck-detection.js +25 -1
- package/dist/client/use-run-stuck-detection.js.map +1 -1
- package/dist/db/client.d.ts +7 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +33 -0
- package/dist/db/client.js.map +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +2 -10
- package/dist/extensions/actions.js.map +1 -1
- package/dist/extensions/store.js +1 -1
- package/dist/extensions/store.js.map +1 -1
- package/dist/localization/default-messages.d.ts +3 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +3 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp/build-server.d.ts +2 -0
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +2 -2
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +5 -5
- package/dist/observability/traces.d.ts +9 -0
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +137 -19
- package/dist/observability/traces.js.map +1 -1
- package/dist/progress/actions.d.ts.map +1 -1
- package/dist/progress/actions.js +3 -2
- package/dist/progress/actions.js.map +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +91 -8
- package/dist/provider-api/index.js.map +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +140 -17
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat/action-filters-a2a.d.ts +24 -2
- package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +62 -7
- package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +118 -5
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/styles/agent-conversation.css +7 -0
- package/dist/templates/default/app/i18n/ar-SA.ts +20 -0
- package/dist/templates/default/app/i18n/de-DE.ts +20 -0
- package/dist/templates/default/app/i18n/en-US.ts +20 -0
- package/dist/templates/default/app/i18n/es-ES.ts +20 -0
- package/dist/templates/default/app/i18n/fr-FR.ts +21 -0
- package/dist/templates/default/app/i18n/hi-IN.ts +19 -0
- package/dist/templates/default/app/i18n/ja-JP.ts +20 -0
- package/dist/templates/default/app/i18n/ko-KR.ts +19 -0
- package/dist/templates/default/app/i18n/pt-BR.ts +20 -0
- package/dist/templates/default/app/i18n/zh-CN.ts +19 -0
- package/dist/templates/default/app/i18n/zh-TW.ts +19 -0
- package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +49 -0
- package/dist/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
- package/package.json +1 -1
- package/src/templates/default/app/i18n/ar-SA.ts +20 -0
- package/src/templates/default/app/i18n/de-DE.ts +20 -0
- package/src/templates/default/app/i18n/en-US.ts +20 -0
- package/src/templates/default/app/i18n/es-ES.ts +20 -0
- package/src/templates/default/app/i18n/fr-FR.ts +21 -0
- package/src/templates/default/app/i18n/hi-IN.ts +19 -0
- package/src/templates/default/app/i18n/ja-JP.ts +20 -0
- package/src/templates/default/app/i18n/ko-KR.ts +19 -0
- package/src/templates/default/app/i18n/pt-BR.ts +20 -0
- package/src/templates/default/app/i18n/zh-CN.ts +19 -0
- package/src/templates/default/app/i18n/zh-TW.ts +19 -0
- package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +49 -0
- package/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
- package/corpus/templates/analytics/server/handlers/github.ts +0 -200
- package/corpus/templates/analytics/server/handlers/pylon.ts +0 -43
- package/corpus/templates/analytics/server/lib/apollo.ts +0 -167
- package/corpus/templates/analytics/server/lib/commonroom.ts +0 -149
- package/corpus/templates/analytics/server/lib/github.ts +0 -660
- package/corpus/templates/analytics/server/lib/mixpanel.ts +0 -156
- package/corpus/templates/analytics/server/lib/posthog.ts +0 -194
- package/corpus/templates/analytics/server/lib/pylon.ts +0 -109
- package/corpus/templates/analytics/server/routes/api/github/graphql.post.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/issue.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/org-prs.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/pr.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/prs.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/search.get.ts +0 -1
- package/corpus/templates/slides/actions/fetch-logos.ts +0 -90
- package/corpus/templates/slides/actions/image-search.ts +0 -64
- package/corpus/templates/slides/actions/import-github.ts +0 -182
- package/corpus/templates/slides/actions/logo-lookup.ts +0 -113
|
@@ -63,6 +63,8 @@ import {
|
|
|
63
63
|
|
|
64
64
|
// Exported so AssistantChatInner can provide a context value.
|
|
65
65
|
export const ChatRunningContext = React.createContext(false);
|
|
66
|
+
export const ChatRunDurationContext = React.createContext<number | null>(null);
|
|
67
|
+
export const ASSISTANT_VISIBLE_TOOL_CALL_LIMIT = 3;
|
|
66
68
|
|
|
67
69
|
/**
|
|
68
70
|
* Human-in-the-loop approval bridge. `AssistantChatInner` provides a value that
|
|
@@ -898,6 +900,7 @@ export function ReconnectStreamMessage({
|
|
|
898
900
|
content: ContentPart[];
|
|
899
901
|
}) {
|
|
900
902
|
const chatRunning = React.useContext(ChatRunningContext);
|
|
903
|
+
const toolSummary = getReconnectToolSummaryInfo(content);
|
|
901
904
|
const latestReasoningPartIndex = content.reduce(
|
|
902
905
|
(latestIndex, part, index) =>
|
|
903
906
|
part.type === "reasoning" ? index : latestIndex,
|
|
@@ -908,61 +911,148 @@ export function ReconnectStreamMessage({
|
|
|
908
911
|
const streamingReasoningPartIndex =
|
|
909
912
|
content.at(-1)?.type === "reasoning" ? content.length - 1 : -1;
|
|
910
913
|
|
|
914
|
+
const renderPart = (part: ContentPart, i: number) => {
|
|
915
|
+
if (part.type === "text") {
|
|
916
|
+
const partStreaming = chatRunning && i === streamingTextPartIndex;
|
|
917
|
+
return (
|
|
918
|
+
<SmoothMarkdownText
|
|
919
|
+
key={`reconnect-text-${i}`}
|
|
920
|
+
text={part.text}
|
|
921
|
+
streaming={partStreaming}
|
|
922
|
+
resetKey={`reconnect-text-${i}`}
|
|
923
|
+
statusType={partStreaming ? "running" : "complete"}
|
|
924
|
+
/>
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
if (part.type === "reasoning") {
|
|
928
|
+
return (
|
|
929
|
+
<ReasoningCell
|
|
930
|
+
key={`reconnect-reasoning-${i}`}
|
|
931
|
+
text={part.text}
|
|
932
|
+
isStreaming={chatRunning && i === streamingReasoningPartIndex}
|
|
933
|
+
resetKey={`reconnect-reasoning-${i}`}
|
|
934
|
+
defaultOpen={i === latestReasoningPartIndex}
|
|
935
|
+
collapseWhenReplaced={i < latestReasoningPartIndex}
|
|
936
|
+
/>
|
|
937
|
+
);
|
|
938
|
+
}
|
|
939
|
+
return (
|
|
940
|
+
<ToolCallDisplay
|
|
941
|
+
key={`reconnect-tool-${i}`}
|
|
942
|
+
toolName={part.toolName}
|
|
943
|
+
argsText={part.argsText}
|
|
944
|
+
args={part.args}
|
|
945
|
+
result={part.result}
|
|
946
|
+
mcpApp={part.mcpApp}
|
|
947
|
+
chatUI={part.chatUI}
|
|
948
|
+
structuredMeta={part.structuredMeta}
|
|
949
|
+
isRunning={
|
|
950
|
+
part.result === undefined && (chatRunning || part.activity === true)
|
|
951
|
+
}
|
|
952
|
+
approval={part.approval}
|
|
953
|
+
repeatCount={part.repeatCount}
|
|
954
|
+
/>
|
|
955
|
+
);
|
|
956
|
+
};
|
|
957
|
+
|
|
958
|
+
const renderedParts: React.ReactNode[] = [];
|
|
959
|
+
let summaryStartIndex = -1;
|
|
960
|
+
let summaryToolCount = 0;
|
|
961
|
+
const flushSummary = (endIndex: number) => {
|
|
962
|
+
if (summaryStartIndex < 0) return;
|
|
963
|
+
renderedParts.push(
|
|
964
|
+
<RanToolsSummary
|
|
965
|
+
key={`reconnect-tool-summary-${summaryStartIndex}`}
|
|
966
|
+
toolCount={summaryToolCount}
|
|
967
|
+
>
|
|
968
|
+
{content
|
|
969
|
+
.slice(summaryStartIndex, endIndex)
|
|
970
|
+
.map((part, offset) => renderPart(part, summaryStartIndex + offset))}
|
|
971
|
+
</RanToolsSummary>,
|
|
972
|
+
);
|
|
973
|
+
summaryStartIndex = -1;
|
|
974
|
+
summaryToolCount = 0;
|
|
975
|
+
};
|
|
976
|
+
|
|
977
|
+
for (let i = 0; i < content.length; i++) {
|
|
978
|
+
const part = content[i]!;
|
|
979
|
+
const isOlderToolWork =
|
|
980
|
+
toolSummary.startIndex >= 0 &&
|
|
981
|
+
i < toolSummary.startIndex &&
|
|
982
|
+
isReconnectToolSummaryPart(content, i, toolSummary.startIndex);
|
|
983
|
+
if (isOlderToolWork) {
|
|
984
|
+
summaryStartIndex = summaryStartIndex < 0 ? i : summaryStartIndex;
|
|
985
|
+
if (part.type === "tool-call") summaryToolCount++;
|
|
986
|
+
continue;
|
|
987
|
+
}
|
|
988
|
+
flushSummary(i);
|
|
989
|
+
renderedParts.push(renderPart(part, i));
|
|
990
|
+
}
|
|
991
|
+
flushSummary(content.length);
|
|
992
|
+
|
|
911
993
|
return (
|
|
912
994
|
<div className="flex justify-start">
|
|
913
995
|
<div className="w-full max-w-[95%] text-sm leading-relaxed text-foreground space-y-1">
|
|
914
|
-
{
|
|
915
|
-
if (part.type === "text") {
|
|
916
|
-
const partStreaming = chatRunning && i === streamingTextPartIndex;
|
|
917
|
-
return (
|
|
918
|
-
<SmoothMarkdownText
|
|
919
|
-
key={`reconnect-text-${i}`}
|
|
920
|
-
text={part.text}
|
|
921
|
-
streaming={partStreaming}
|
|
922
|
-
resetKey={`reconnect-text-${i}`}
|
|
923
|
-
statusType={partStreaming ? "running" : "complete"}
|
|
924
|
-
/>
|
|
925
|
-
);
|
|
926
|
-
}
|
|
927
|
-
if (part.type === "reasoning") {
|
|
928
|
-
return (
|
|
929
|
-
<ReasoningCell
|
|
930
|
-
key={`reconnect-reasoning-${i}`}
|
|
931
|
-
text={part.text}
|
|
932
|
-
isStreaming={chatRunning && i === streamingReasoningPartIndex}
|
|
933
|
-
resetKey={`reconnect-reasoning-${i}`}
|
|
934
|
-
defaultOpen={i === latestReasoningPartIndex}
|
|
935
|
-
collapseWhenReplaced={i < latestReasoningPartIndex}
|
|
936
|
-
/>
|
|
937
|
-
);
|
|
938
|
-
}
|
|
939
|
-
if (part.type === "tool-call") {
|
|
940
|
-
return (
|
|
941
|
-
<ToolCallDisplay
|
|
942
|
-
key={`reconnect-tool-${i}`}
|
|
943
|
-
toolName={part.toolName}
|
|
944
|
-
argsText={part.argsText}
|
|
945
|
-
args={part.args}
|
|
946
|
-
result={part.result}
|
|
947
|
-
mcpApp={part.mcpApp}
|
|
948
|
-
chatUI={part.chatUI}
|
|
949
|
-
structuredMeta={part.structuredMeta}
|
|
950
|
-
isRunning={
|
|
951
|
-
part.result === undefined &&
|
|
952
|
-
(chatRunning || part.activity === true)
|
|
953
|
-
}
|
|
954
|
-
approval={part.approval}
|
|
955
|
-
repeatCount={part.repeatCount}
|
|
956
|
-
/>
|
|
957
|
-
);
|
|
958
|
-
}
|
|
959
|
-
return null;
|
|
960
|
-
})}
|
|
996
|
+
{renderedParts}
|
|
961
997
|
</div>
|
|
962
998
|
</div>
|
|
963
999
|
);
|
|
964
1000
|
}
|
|
965
1001
|
|
|
1002
|
+
function getReconnectToolSummaryInfo(content: readonly ContentPart[]) {
|
|
1003
|
+
const toolCallIndices = content.reduce<number[]>((indices, part, index) => {
|
|
1004
|
+
if (part.type === "tool-call" && isReconnectSummarizablePart(part)) {
|
|
1005
|
+
indices.push(index);
|
|
1006
|
+
}
|
|
1007
|
+
return indices;
|
|
1008
|
+
}, []);
|
|
1009
|
+
if (toolCallIndices.length <= ASSISTANT_VISIBLE_TOOL_CALL_LIMIT) {
|
|
1010
|
+
return { startIndex: -1 };
|
|
1011
|
+
}
|
|
1012
|
+
return {
|
|
1013
|
+
startIndex:
|
|
1014
|
+
toolCallIndices[
|
|
1015
|
+
toolCallIndices.length - ASSISTANT_VISIBLE_TOOL_CALL_LIMIT
|
|
1016
|
+
]!,
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
function isReconnectSummarizablePart(part: ContentPart): boolean {
|
|
1021
|
+
return (
|
|
1022
|
+
part.type === "reasoning" ||
|
|
1023
|
+
(part.type === "tool-call" && part.toolName !== "connect-builder")
|
|
1024
|
+
);
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
function isReconnectToolSummaryPart(
|
|
1028
|
+
content: readonly ContentPart[],
|
|
1029
|
+
index: number,
|
|
1030
|
+
startIndex: number,
|
|
1031
|
+
): boolean {
|
|
1032
|
+
if (startIndex < 0 || index >= startIndex) return false;
|
|
1033
|
+
if (!isReconnectSummarizablePart(content[index]!)) return false;
|
|
1034
|
+
|
|
1035
|
+
let segmentStart = index;
|
|
1036
|
+
while (
|
|
1037
|
+
segmentStart > 0 &&
|
|
1038
|
+
isReconnectSummarizablePart(content[segmentStart - 1]!)
|
|
1039
|
+
) {
|
|
1040
|
+
segmentStart--;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
let segmentEnd = index + 1;
|
|
1044
|
+
while (
|
|
1045
|
+
segmentEnd < startIndex &&
|
|
1046
|
+
isReconnectSummarizablePart(content[segmentEnd]!)
|
|
1047
|
+
) {
|
|
1048
|
+
segmentEnd++;
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
return content
|
|
1052
|
+
.slice(segmentStart, segmentEnd)
|
|
1053
|
+
.some((candidate) => candidate.type === "tool-call");
|
|
1054
|
+
}
|
|
1055
|
+
|
|
966
1056
|
// ─── Reasoning / Thinking cell ────────────────────────────────────────────────
|
|
967
1057
|
|
|
968
1058
|
/**
|
|
@@ -1141,6 +1231,39 @@ export function WorkedForSummary({
|
|
|
1141
1231
|
);
|
|
1142
1232
|
}
|
|
1143
1233
|
|
|
1234
|
+
export function RanToolsSummary({
|
|
1235
|
+
toolCount,
|
|
1236
|
+
children,
|
|
1237
|
+
}: {
|
|
1238
|
+
toolCount: number;
|
|
1239
|
+
children: React.ReactNode;
|
|
1240
|
+
}) {
|
|
1241
|
+
const [open, setOpen] = useState(false);
|
|
1242
|
+
const label = `Ran ${toolCount} ${toolCount === 1 ? "tool" : "tools"}`;
|
|
1243
|
+
|
|
1244
|
+
return (
|
|
1245
|
+
<div className="my-1 w-full">
|
|
1246
|
+
<button
|
|
1247
|
+
type="button"
|
|
1248
|
+
onClick={() => setOpen((v) => !v)}
|
|
1249
|
+
aria-expanded={open}
|
|
1250
|
+
className="flex items-center gap-1.5 py-0.5 text-[13px] text-muted-foreground transition-colors hover:text-foreground"
|
|
1251
|
+
>
|
|
1252
|
+
<span>{label}</span>
|
|
1253
|
+
<IconChevronRight
|
|
1254
|
+
className={cn(
|
|
1255
|
+
"size-3.5 shrink-0 transition-transform",
|
|
1256
|
+
open && "rotate-90",
|
|
1257
|
+
)}
|
|
1258
|
+
/>
|
|
1259
|
+
</button>
|
|
1260
|
+
<AnimatedCollapse open={open}>
|
|
1261
|
+
<div className="pt-1">{children}</div>
|
|
1262
|
+
</AnimatedCollapse>
|
|
1263
|
+
</div>
|
|
1264
|
+
);
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1144
1267
|
// ─── Re-export for AssistantMessage ───────────────────────────────────────────
|
|
1145
1268
|
// AssistantMessage in AssistantChat.tsx uses FilesChangedSummary directly, so
|
|
1146
1269
|
// re-export it so AssistantChat.tsx can import from one place.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { useCallback, useEffect } from "react";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
ACTIVE_RUN_STATE_EVENT,
|
|
5
|
+
getActiveRun,
|
|
6
|
+
type ActiveRunState,
|
|
7
|
+
} from "../active-run-state.js";
|
|
8
|
+
import { trackAgentChatLifecycle } from "../analytics.js";
|
|
9
|
+
|
|
10
|
+
export interface AgentChatLifecycleTrackingOptions {
|
|
11
|
+
surface: string;
|
|
12
|
+
threadId?: string;
|
|
13
|
+
tabId?: string;
|
|
14
|
+
onActiveRunChange?: (active: boolean) => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function useAgentChatLifecycleTracking({
|
|
18
|
+
surface,
|
|
19
|
+
threadId,
|
|
20
|
+
tabId,
|
|
21
|
+
onActiveRunChange,
|
|
22
|
+
}: AgentChatLifecycleTrackingOptions): (runId?: string) => void {
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
trackAgentChatLifecycle({
|
|
25
|
+
phase: "surface-mounted",
|
|
26
|
+
surface,
|
|
27
|
+
...(threadId ? { threadId } : {}),
|
|
28
|
+
...(tabId ? { tabId } : {}),
|
|
29
|
+
});
|
|
30
|
+
}, [surface, tabId, threadId]);
|
|
31
|
+
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
const sync = (state = getActiveRun()) => {
|
|
34
|
+
const active = Boolean(
|
|
35
|
+
threadId && state?.threadId === threadId && state.runId,
|
|
36
|
+
);
|
|
37
|
+
onActiveRunChange?.(active);
|
|
38
|
+
if (!active || !state) return;
|
|
39
|
+
trackAgentChatLifecycle({
|
|
40
|
+
phase: "run-observed",
|
|
41
|
+
surface,
|
|
42
|
+
threadId: state.threadId,
|
|
43
|
+
runId: state.runId,
|
|
44
|
+
...(tabId ? { tabId } : {}),
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
sync();
|
|
48
|
+
const activeRunHandler = (event: Event) => {
|
|
49
|
+
const state = (event as CustomEvent<{ state?: ActiveRunState | null }>)
|
|
50
|
+
.detail?.state;
|
|
51
|
+
sync(state ?? null);
|
|
52
|
+
};
|
|
53
|
+
const storageHandler = () => sync();
|
|
54
|
+
window.addEventListener(ACTIVE_RUN_STATE_EVENT, activeRunHandler);
|
|
55
|
+
window.addEventListener("storage", storageHandler);
|
|
56
|
+
return () => {
|
|
57
|
+
window.removeEventListener(ACTIVE_RUN_STATE_EVENT, activeRunHandler);
|
|
58
|
+
window.removeEventListener("storage", storageHandler);
|
|
59
|
+
};
|
|
60
|
+
}, [onActiveRunChange, surface, tabId, threadId]);
|
|
61
|
+
|
|
62
|
+
return useCallback(
|
|
63
|
+
(runId?: string) => {
|
|
64
|
+
trackAgentChatLifecycle({
|
|
65
|
+
phase: "run-stopped",
|
|
66
|
+
surface,
|
|
67
|
+
...(threadId ? { threadId } : {}),
|
|
68
|
+
...(runId ? { runId } : {}),
|
|
69
|
+
...(tabId ? { tabId } : {}),
|
|
70
|
+
});
|
|
71
|
+
},
|
|
72
|
+
[surface, tabId, threadId],
|
|
73
|
+
);
|
|
74
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function hasChatThreadDeepLink(): boolean {
|
|
2
|
+
if (typeof window === "undefined") return false;
|
|
3
|
+
try {
|
|
4
|
+
const params = new URLSearchParams(window.location.search);
|
|
5
|
+
return Boolean(
|
|
6
|
+
params.get("thread")?.trim() || params.get("threadId")?.trim(),
|
|
7
|
+
);
|
|
8
|
+
} catch {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -355,6 +355,18 @@ function shouldIgnoreAutoCapturedError(normalized: {
|
|
|
355
355
|
return true;
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
+
// Route-chunk recovery reloads the current page after stale lazy chunks or
|
|
359
|
+
// module scripts fail. Browser-level failures have no useful stack, so do
|
|
360
|
+
// not retain the transient loader noise as an application issue.
|
|
361
|
+
if (
|
|
362
|
+
!stack &&
|
|
363
|
+
/^(?:Importing a module script failed\.?|(?:Failed to fetch|error loading) dynamically imported module(?::.*)?)$/i.test(
|
|
364
|
+
message,
|
|
365
|
+
)
|
|
366
|
+
) {
|
|
367
|
+
return true;
|
|
368
|
+
}
|
|
369
|
+
|
|
358
370
|
if (
|
|
359
371
|
normalized.type === "InvalidStateError" &&
|
|
360
372
|
/^Transition was aborted because of invalid state$/i.test(message)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IconPlus } from "@tabler/icons-react";
|
|
2
2
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
3
|
-
import { useState } from "react";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
4
|
|
|
5
5
|
import { sendToAgentChat } from "../agent-chat.js";
|
|
6
6
|
import { agentNativePath } from "../api-path.js";
|
|
@@ -49,6 +49,8 @@ export interface ExtensionSlotProps {
|
|
|
49
49
|
className?: string;
|
|
50
50
|
/** Optional className applied to each EmbeddedExtension. */
|
|
51
51
|
toolClassName?: string;
|
|
52
|
+
/** Fires once when the slot query and all installed extensions are ready. */
|
|
53
|
+
onReady?: () => void;
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
/**
|
|
@@ -70,8 +72,11 @@ export function ExtensionSlot({
|
|
|
70
72
|
showEmptyAffordance,
|
|
71
73
|
className,
|
|
72
74
|
toolClassName,
|
|
75
|
+
onReady,
|
|
73
76
|
}: ExtensionSlotProps) {
|
|
74
77
|
const t = useT();
|
|
78
|
+
const readyInstallIds = useRef(new Set<string>());
|
|
79
|
+
const readyNotified = useRef(false);
|
|
75
80
|
const installsQuery = useQuery<SlotInstall[]>({
|
|
76
81
|
queryKey: ["slot-installs", id],
|
|
77
82
|
queryFn: async () => {
|
|
@@ -87,6 +92,35 @@ export function ExtensionSlot({
|
|
|
87
92
|
});
|
|
88
93
|
const installs = installsQuery.data ?? [];
|
|
89
94
|
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
readyInstallIds.current.clear();
|
|
97
|
+
readyNotified.current = false;
|
|
98
|
+
}, [id]);
|
|
99
|
+
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
if (readyNotified.current || installsQuery.isLoading) return;
|
|
102
|
+
if (
|
|
103
|
+
installsQuery.isError ||
|
|
104
|
+
installs.length === 0 ||
|
|
105
|
+
readyInstallIds.current.size >= installs.length
|
|
106
|
+
) {
|
|
107
|
+
readyNotified.current = true;
|
|
108
|
+
onReady?.();
|
|
109
|
+
}
|
|
110
|
+
}, [installs, installsQuery.isError, installsQuery.isLoading, onReady]);
|
|
111
|
+
|
|
112
|
+
const markInstallReady = (installId: string) => {
|
|
113
|
+
readyInstallIds.current.add(installId);
|
|
114
|
+
if (
|
|
115
|
+
!readyNotified.current &&
|
|
116
|
+
!installsQuery.isLoading &&
|
|
117
|
+
readyInstallIds.current.size >= installs.length
|
|
118
|
+
) {
|
|
119
|
+
readyNotified.current = true;
|
|
120
|
+
onReady?.();
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
90
124
|
if (installsQuery.isLoading) {
|
|
91
125
|
return null;
|
|
92
126
|
}
|
|
@@ -121,6 +155,8 @@ export function ExtensionSlot({
|
|
|
121
155
|
slotId={id}
|
|
122
156
|
context={context}
|
|
123
157
|
className={toolClassName}
|
|
158
|
+
onReady={() => markInstallReady(install.installId)}
|
|
159
|
+
onUnavailable={() => markInstallReady(install.installId)}
|
|
124
160
|
/>
|
|
125
161
|
))}
|
|
126
162
|
</div>
|
|
@@ -787,6 +787,7 @@ export {
|
|
|
787
787
|
export { AgentTerminal, type AgentTerminalProps } from "./terminal/index.js";
|
|
788
788
|
export {
|
|
789
789
|
trackEvent,
|
|
790
|
+
trackAgentChatLifecycle,
|
|
790
791
|
trackSessionStatus,
|
|
791
792
|
configureTracking,
|
|
792
793
|
setTrackingContentCaptureEnabled,
|
|
@@ -811,6 +812,7 @@ export {
|
|
|
811
812
|
type CaptureExceptionContext,
|
|
812
813
|
type CapturedExceptionEvent,
|
|
813
814
|
type ClientCaptureContext,
|
|
815
|
+
type AgentChatLifecycleEvent,
|
|
814
816
|
type ConfigureTrackingOptions,
|
|
815
817
|
type ErrorCaptureConfigOptions,
|
|
816
818
|
type ExceptionBreadcrumb,
|
|
@@ -201,6 +201,17 @@ function recoverToIntendedNavigation(
|
|
|
201
201
|
return true;
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
+
function recoverFromDynamicImportFailure(
|
|
205
|
+
win: Window,
|
|
206
|
+
state: RouteChunkRecoveryState,
|
|
207
|
+
message: string,
|
|
208
|
+
): boolean {
|
|
209
|
+
if (!isDynamicImportFailureMessage(message)) return false;
|
|
210
|
+
state.routeModuleFailureAt = Date.now();
|
|
211
|
+
if (recoverToIntendedNavigation(win, state)) return true;
|
|
212
|
+
return reloadForStaleChunk(win);
|
|
213
|
+
}
|
|
214
|
+
|
|
204
215
|
function patchHistoryMethod(
|
|
205
216
|
win: Window,
|
|
206
217
|
state: RouteChunkRecoveryState,
|
|
@@ -290,16 +301,17 @@ export function installRouteChunkRecovery(
|
|
|
290
301
|
win.addEventListener("unhandledrejection", (event) => {
|
|
291
302
|
const reason = (event as PromiseRejectionEvent).reason;
|
|
292
303
|
const message = String(reason?.message || reason || "");
|
|
293
|
-
if (
|
|
294
|
-
state.routeModuleFailureAt = Date.now();
|
|
295
|
-
if (recoverToIntendedNavigation(win, state)) {
|
|
304
|
+
if (recoverFromDynamicImportFailure(win, state, message)) {
|
|
296
305
|
event.preventDefault();
|
|
297
|
-
return;
|
|
298
306
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
win.addEventListener("error", (event) => {
|
|
310
|
+
const errorEvent = event as ErrorEvent;
|
|
311
|
+
const message = String(
|
|
312
|
+
errorEvent.error?.message || errorEvent.message || "",
|
|
313
|
+
);
|
|
314
|
+
if (recoverFromDynamicImportFailure(win, state, message)) {
|
|
303
315
|
event.preventDefault();
|
|
304
316
|
}
|
|
305
317
|
});
|
|
@@ -390,6 +390,8 @@ const SESSION_REPLAY_CLAIM_TIMEOUT_MS = 150;
|
|
|
390
390
|
export const SESSION_REPLAY_CONSOLE_EVENT_TAG = "agent-native.console";
|
|
391
391
|
/** rrweb custom-event tag for captured fetch/XHR request summaries. */
|
|
392
392
|
export const SESSION_REPLAY_NETWORK_EVENT_TAG = "agent-native.network";
|
|
393
|
+
/** Content-free agent-chat lifecycle markers for replay incident forensics. */
|
|
394
|
+
export const SESSION_REPLAY_AGENT_CHAT_EVENT_TAG = "agent-native.chat";
|
|
393
395
|
|
|
394
396
|
const DEFAULT_MAX_CONSOLE_EVENTS = 1000;
|
|
395
397
|
const DEFAULT_MAX_NETWORK_EVENTS = 2000;
|
|
@@ -3384,3 +3386,32 @@ export function emitSessionReplayException(input: {
|
|
|
3384
3386
|
...(input.url ? { url: input.url } : {}),
|
|
3385
3387
|
});
|
|
3386
3388
|
}
|
|
3389
|
+
|
|
3390
|
+
export type SessionReplayAgentChatEvent = {
|
|
3391
|
+
phase: "surface-mounted" | "run-observed" | "run-stopped";
|
|
3392
|
+
surface: string;
|
|
3393
|
+
threadId?: string;
|
|
3394
|
+
runId?: string;
|
|
3395
|
+
tabId?: string;
|
|
3396
|
+
};
|
|
3397
|
+
|
|
3398
|
+
/**
|
|
3399
|
+
* Add a content-free chat lifecycle marker to the active replay. The payload
|
|
3400
|
+
* deliberately accepts only ids and low-cardinality state; prompt/response
|
|
3401
|
+
* content must never enter replay diagnostics through this path.
|
|
3402
|
+
*/
|
|
3403
|
+
export function emitSessionReplayAgentChatEvent(
|
|
3404
|
+
input: SessionReplayAgentChatEvent,
|
|
3405
|
+
): void {
|
|
3406
|
+
const state = getState();
|
|
3407
|
+
if (!state.active || !state.addCustomEvent) return;
|
|
3408
|
+
const bounded = (value: string | undefined, max = 160) =>
|
|
3409
|
+
value?.trim().slice(0, max) || undefined;
|
|
3410
|
+
emitReplayCustomEvent(state, SESSION_REPLAY_AGENT_CHAT_EVENT_TAG, {
|
|
3411
|
+
phase: input.phase,
|
|
3412
|
+
surface: bounded(input.surface, 80) ?? "app",
|
|
3413
|
+
...(bounded(input.threadId) ? { threadId: bounded(input.threadId) } : {}),
|
|
3414
|
+
...(bounded(input.runId) ? { runId: bounded(input.runId) } : {}),
|
|
3415
|
+
...(bounded(input.tabId) ? { tabId: bounded(input.tabId) } : {}),
|
|
3416
|
+
});
|
|
3417
|
+
}
|
|
@@ -80,6 +80,7 @@ export const DEFAULT_BACKGROUND_STUCK_THRESHOLD_MS = 180_000;
|
|
|
80
80
|
export const DEFAULT_LIVE_BACKGROUND_STUCK_THRESHOLD_MS = 13 * 60_000;
|
|
81
81
|
const DEFAULT_POLL_INTERVAL_MS = 5_000;
|
|
82
82
|
const IDLE_BACKOFF_INTERVAL_MS = 15_000;
|
|
83
|
+
const MAX_POLL_ERROR_BACKOFF_MS = 30_000;
|
|
83
84
|
const FRESH_BACKGROUND_HEARTBEAT_MS = 30_000;
|
|
84
85
|
|
|
85
86
|
interface ActiveRunResponse {
|
|
@@ -129,6 +130,22 @@ export function useRunStuckDetection({
|
|
|
129
130
|
let timer: ReturnType<typeof setTimeout> | null = null;
|
|
130
131
|
let snapshotTransitionTimer: ReturnType<typeof setTimeout> | null = null;
|
|
131
132
|
let snapshotVersion = 0;
|
|
133
|
+
let consecutivePollFailures = 0;
|
|
134
|
+
|
|
135
|
+
const pollFailureDelay = () => {
|
|
136
|
+
consecutivePollFailures += 1;
|
|
137
|
+
return Math.min(
|
|
138
|
+
Math.max(pollIntervalMs, 1) * 2 ** consecutivePollFailures,
|
|
139
|
+
MAX_POLL_ERROR_BACKOFF_MS,
|
|
140
|
+
);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const clearObservedRun = () => {
|
|
144
|
+
snapshotVersion += 1;
|
|
145
|
+
if (snapshotTransitionTimer) clearTimeout(snapshotTransitionTimer);
|
|
146
|
+
snapshotTransitionTimer = null;
|
|
147
|
+
setState(EMPTY_STATE);
|
|
148
|
+
};
|
|
132
149
|
|
|
133
150
|
type RunHealthSnapshot = {
|
|
134
151
|
active: boolean;
|
|
@@ -269,6 +286,7 @@ export function useRunStuckDetection({
|
|
|
269
286
|
);
|
|
270
287
|
if (cancelled) return;
|
|
271
288
|
if (res.ok) {
|
|
289
|
+
consecutivePollFailures = 0;
|
|
272
290
|
const data = (await res.json()) as ActiveRunResponse;
|
|
273
291
|
const lastProgressAt = data.lastProgressAt ?? null;
|
|
274
292
|
// Measure elapsed against the SERVER clock (serverNow) rather than the
|
|
@@ -336,9 +354,17 @@ export function useRunStuckDetection({
|
|
|
336
354
|
if (!data.active || data.status !== "running") {
|
|
337
355
|
nextDelay = IDLE_BACKOFF_INTERVAL_MS;
|
|
338
356
|
}
|
|
357
|
+
} else if (res.status === 429 || res.status >= 500) {
|
|
358
|
+
nextDelay = pollFailureDelay();
|
|
359
|
+
} else {
|
|
360
|
+
consecutivePollFailures = 0;
|
|
361
|
+
clearObservedRun();
|
|
362
|
+
nextDelay = MAX_POLL_ERROR_BACKOFF_MS;
|
|
339
363
|
}
|
|
340
364
|
} catch {
|
|
341
|
-
// Network blip — leave previous state
|
|
365
|
+
// Network/503 blip — leave previous state and ease polling pressure
|
|
366
|
+
// while the server or database recovers.
|
|
367
|
+
nextDelay = pollFailureDelay();
|
|
342
368
|
}
|
|
343
369
|
if (!cancelled) {
|
|
344
370
|
timer = setTimeout(poll, nextDelay);
|
|
@@ -669,6 +669,61 @@ export function isConnectionError(err: any): boolean {
|
|
|
669
669
|
);
|
|
670
670
|
}
|
|
671
671
|
|
|
672
|
+
/**
|
|
673
|
+
* Classify database failures that should temporarily shed request load.
|
|
674
|
+
* Statement timeouts are not included in isConnectionError() because retrying
|
|
675
|
+
* every timed-out mutation would not be safe, but request handlers can still
|
|
676
|
+
* return a retryable service-unavailable response for them.
|
|
677
|
+
*/
|
|
678
|
+
export function isTransientDatabaseError(err: unknown): boolean {
|
|
679
|
+
const error = err as {
|
|
680
|
+
code?: unknown;
|
|
681
|
+
name?: unknown;
|
|
682
|
+
message?: unknown;
|
|
683
|
+
stack?: unknown;
|
|
684
|
+
cause?: {
|
|
685
|
+
code?: unknown;
|
|
686
|
+
name?: unknown;
|
|
687
|
+
message?: unknown;
|
|
688
|
+
stack?: unknown;
|
|
689
|
+
};
|
|
690
|
+
};
|
|
691
|
+
const code = String(error?.code ?? error?.cause?.code ?? "");
|
|
692
|
+
if (
|
|
693
|
+
code === "ECHECKOUTTIMEOUT" ||
|
|
694
|
+
code === "53300" ||
|
|
695
|
+
code === "57014" ||
|
|
696
|
+
/^08/.test(code) ||
|
|
697
|
+
/^57P0[123]$/.test(code)
|
|
698
|
+
) {
|
|
699
|
+
return true;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
const message = [error?.message, error?.cause?.message]
|
|
703
|
+
.filter((value): value is string => typeof value === "string")
|
|
704
|
+
.join(" ");
|
|
705
|
+
if (
|
|
706
|
+
/\bstatement timeout\b|\bdb (?:query|connect) timed out\b/i.test(message)
|
|
707
|
+
) {
|
|
708
|
+
return true;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
const databaseSurface = [
|
|
712
|
+
error?.name,
|
|
713
|
+
error?.cause?.name,
|
|
714
|
+
error?.stack,
|
|
715
|
+
error?.cause?.stack,
|
|
716
|
+
]
|
|
717
|
+
.filter((value): value is string => typeof value === "string")
|
|
718
|
+
.join(" ");
|
|
719
|
+
return (
|
|
720
|
+
isConnectionError(error) &&
|
|
721
|
+
/@neondatabase|@libsql|\bpostgres(?:ql)?\b|\bpg-pool\b|drizzle-orm|\/db\/client\.[cm]?[jt]s/i.test(
|
|
722
|
+
databaseSurface,
|
|
723
|
+
)
|
|
724
|
+
);
|
|
725
|
+
}
|
|
726
|
+
|
|
672
727
|
export async function retryOnConnectionError<T>(
|
|
673
728
|
fn: () => Promise<T>,
|
|
674
729
|
maxAttempts = 3,
|
|
@@ -727,20 +727,8 @@ export function createExtensionActionEntries(): Record<string, ActionEntry> {
|
|
|
727
727
|
!coerceBoolean(args?.allowFullReplacement)
|
|
728
728
|
) {
|
|
729
729
|
const message =
|
|
730
|
-
"Full extension-body replacement
|
|
731
|
-
throw new
|
|
732
|
-
errorCode: "extension_full_replacement_requires_explicit_intent",
|
|
733
|
-
toolResult: JSON.stringify(
|
|
734
|
-
{
|
|
735
|
-
error: "extension_full_replacement_requires_explicit_intent",
|
|
736
|
-
message,
|
|
737
|
-
recoverable: false,
|
|
738
|
-
next: "Call get-extension once, then update-extension with patches or edits that change only the data-loading code. Use allowFullReplacement=true only for an explicitly requested visual rewrite.",
|
|
739
|
-
},
|
|
740
|
-
null,
|
|
741
|
-
2,
|
|
742
|
-
),
|
|
743
|
-
});
|
|
730
|
+
"Full extension-body replacement requires allowFullReplacement=true. No changes were applied. If the user's request includes a broad visual rewrite such as changing layout, compactness, visible sections, naming, or padding, retry once with allowFullReplacement=true; otherwise read the current extension and use focused patches/edits for a data-only repair. Do not retry unchanged arguments.";
|
|
731
|
+
throw new ExtensionContentEditError(message);
|
|
744
732
|
}
|
|
745
733
|
|
|
746
734
|
// Full-replacement content can come inline (`content`) or by reference
|
|
@@ -1192,7 +1192,7 @@ export async function updateExtensionContent(
|
|
|
1192
1192
|
|
|
1193
1193
|
if (opts.content !== undefined && opts.allowFullReplacement !== true) {
|
|
1194
1194
|
throw new ExtensionContentEditError(
|
|
1195
|
-
"Full extension-body replacement requires
|
|
1195
|
+
"Full extension-body replacement requires allowFullReplacement=true. No changes were applied. Use patches or edits for a targeted data-only repair, or set allowFullReplacement=true for a user-requested broad visual rewrite.",
|
|
1196
1196
|
);
|
|
1197
1197
|
}
|
|
1198
1198
|
|