@agent-native/core 0.98.4 → 0.98.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +28 -0
- package/corpus/core/docs/content/durable-background-runs.mdx +37 -0
- package/corpus/core/docs/content/external-agents.mdx +62 -7
- package/corpus/core/docs/content/locales/ar-SA/external-agents.mdx +38 -7
- package/corpus/core/docs/content/locales/ar-SA/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/de-DE/external-agents.mdx +39 -7
- package/corpus/core/docs/content/locales/de-DE/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/es-ES/external-agents.mdx +39 -7
- package/corpus/core/docs/content/locales/es-ES/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/fr-FR/external-agents.mdx +39 -7
- package/corpus/core/docs/content/locales/fr-FR/tracking.mdx +4 -2
- package/corpus/core/docs/content/locales/hi-IN/external-agents.mdx +38 -7
- package/corpus/core/docs/content/locales/hi-IN/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/ja-JP/external-agents.mdx +38 -7
- package/corpus/core/docs/content/locales/ja-JP/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/ko-KR/external-agents.mdx +38 -7
- package/corpus/core/docs/content/locales/ko-KR/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/pt-BR/external-agents.mdx +39 -7
- package/corpus/core/docs/content/locales/pt-BR/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/zh-CN/external-agents.mdx +37 -7
- package/corpus/core/docs/content/locales/zh-CN/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/zh-TW/durable-background-runs.mdx +14 -0
- package/corpus/core/docs/content/locales/zh-TW/external-agents.mdx +37 -7
- package/corpus/core/docs/content/locales/zh-TW/tracking.mdx +2 -0
- package/corpus/core/docs/content/tracking.mdx +2 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/handlers.ts +95 -21
- package/corpus/core/src/a2a/task-store.ts +65 -3
- package/corpus/core/src/agent/durable-background.ts +16 -16
- package/corpus/core/src/agent/engine/ai-sdk-engine.ts +25 -8
- package/corpus/core/src/agent/engine/anthropic-engine.ts +17 -3
- package/corpus/core/src/agent/engine/output-tokens.ts +6 -6
- package/corpus/core/src/agent/production-agent.ts +200 -27
- package/corpus/core/src/agent/run-manager.ts +81 -1
- package/corpus/core/src/agent/run-store.ts +301 -41
- package/corpus/core/src/client/AgentPanel.tsx +6 -2
- package/corpus/core/src/client/AssistantChat.tsx +364 -69
- package/corpus/core/src/client/agent-chat-adapter.ts +169 -1
- package/corpus/core/src/client/chat/message-components.tsx +3 -0
- package/corpus/core/src/client/chat/tool-call-display.tsx +20 -36
- package/corpus/core/src/client/conversation/use-near-bottom-autoscroll.ts +7 -0
- package/corpus/core/src/client/extensions/AgentNativeExtensionFrame.tsx +2 -0
- package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +2 -0
- package/corpus/core/src/client/extensions/ExtensionEditor.tsx +9 -2
- package/corpus/core/src/client/extensions/ExtensionViewer.tsx +2 -0
- package/corpus/core/src/client/extensions/InlineExtensionFrame.tsx +2 -0
- package/corpus/core/src/client/extensions/portable-extension.ts +2 -0
- package/corpus/core/src/client/session-replay.ts +361 -29
- package/corpus/core/src/client/sse-event-processor.ts +43 -1
- package/corpus/core/src/demo/actions/toggle-demo-mode.ts +1 -1
- package/corpus/core/src/demo/config.ts +6 -6
- package/corpus/core/src/demo/fetch-interceptor.ts +13 -4
- package/corpus/core/src/demo/redact.ts +13 -149
- package/corpus/core/src/extensions/html-shell.ts +3 -0
- package/corpus/core/src/extensions/session-replay-iframe.ts +131 -0
- package/corpus/core/src/integrations/adapters/slack.ts +123 -13
- package/corpus/core/src/integrations/identity-links-store.ts +210 -0
- package/corpus/core/src/integrations/identity.ts +132 -0
- package/corpus/core/src/integrations/index.ts +6 -0
- package/corpus/core/src/integrations/plugin.ts +58 -1
- package/corpus/core/src/integrations/types.ts +7 -0
- package/corpus/core/src/mcp/build-server.ts +127 -22
- package/corpus/core/src/mcp/external-agent-policy.ts +18 -0
- package/corpus/core/src/mcp/index.ts +1 -0
- package/corpus/core/src/scripts/agent-engines/list-agent-engines.ts +1 -20
- package/corpus/core/src/server/agent-chat/plugin-options.ts +12 -1
- package/corpus/core/src/server/agent-chat/script-entries.ts +20 -3
- package/corpus/core/src/server/agent-chat-plugin.ts +3 -0
- package/corpus/core/src/session-replay-iframe-protocol.ts +58 -0
- package/corpus/core/src/shared/reasoning-effort.ts +35 -0
- package/corpus/core/src/styles/agent-conversation.css +26 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +34 -5
- package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +0 -15
- package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +30 -21
- package/corpus/templates/analytics/AGENTS.md +27 -0
- package/corpus/templates/analytics/actions/create-session-replay-agent-link.ts +0 -1
- package/corpus/templates/analytics/actions/get-error-issue.ts +1 -0
- package/corpus/templates/analytics/actions/get-session-replay-summary.ts +1 -0
- package/corpus/templates/analytics/actions/get-session-replay-timeline.ts +40 -0
- package/corpus/templates/analytics/actions/list-error-issues.ts +13 -0
- package/corpus/templates/analytics/actions/list-session-recordings.ts +1 -0
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +4 -0
- package/corpus/templates/analytics/app/global.css +2 -2
- package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +41 -4
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +52 -203
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +69 -16
- package/corpus/templates/analytics/changelog/2026-07-12-analytics-chat-retries-before-showing-a-generic-no-data-mess.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-analytics-sessions-search-no-longer-loses-fast-keystrokes-an.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-chart-selection-respects-chat-state.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-connected-external-agents-can-now-look-up-sessions-error-iss.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-demo-mode-anonymizes-error-reporting-emails.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-session-identities-stay-visible-when-demo-mode-is-off.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-session-replays-show-iframe-content.md +6 -0
- package/corpus/templates/analytics/netlify.toml +0 -3
- package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +14 -0
- package/corpus/templates/analytics/server/lib/error-capture.ts +101 -2
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +24 -0
- package/corpus/templates/analytics/server/lib/session-replay-agent-context.ts +49 -17
- package/corpus/templates/analytics/server/lib/session-replay.ts +18 -16
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +43 -6
- package/corpus/templates/analytics/server/plugins/db.ts +15 -0
- package/corpus/templates/assets/app/global.css +1 -1
- package/corpus/templates/brain/app/global.css +2 -2
- package/corpus/templates/brain/changelog/2026-07-12-fix-long-response-progress.md +6 -0
- package/corpus/templates/forms/app/components/CloudUpgrade.tsx +1 -1
- package/corpus/templates/forms/app/components/ThemeToggle.tsx +22 -6
- package/corpus/templates/forms/app/components/builder/FieldPropertiesPanel.tsx +5 -5
- package/corpus/templates/forms/app/components/builder/FieldRenderer.tsx +3 -3
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +16 -16
- package/corpus/templates/forms/app/global.css +164 -13
- package/corpus/templates/forms/app/pages/AskPage.tsx +35 -13
- package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +143 -67
- package/corpus/templates/forms/app/pages/FormFillPage.tsx +44 -11
- package/corpus/templates/forms/app/pages/FormsListPage.tsx +42 -24
- package/corpus/templates/forms/app/pages/ResponseInsightsPage.tsx +28 -15
- package/corpus/templates/forms/app/pages/ResponsesPage.tsx +46 -20
- package/corpus/templates/forms/app/routes/_app.settings.tsx +1 -1
- package/corpus/templates/forms/changelog/2026-07-12-ask-forms-suggestions-now-sit-beneath-the-composer-for-a-tig.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-12-builder-response-tables-now-fill-the-view-without-a-redundan.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-12-form-builder-surfaces-are-calmer-fields-stay-stable-on-hover.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-12-response-tables-now-fill-the-available-pane-with-a-flexible-.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-12-smoother-more-tactile-controls-throughout-animated-icon-and-.md +6 -0
- package/corpus/templates/mail/AGENTS.md +3 -1
- package/corpus/templates/mail/app/components/email/EmailThread.tsx +21 -13
- package/corpus/templates/mail/app/components/email/email-iframe-document.ts +18 -0
- package/corpus/templates/mail/server/lib/mail-integrations.ts +3 -0
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +84 -15
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/task-store.d.ts +20 -1
- package/dist/a2a/task-store.d.ts.map +1 -1
- package/dist/a2a/task-store.js +57 -4
- package/dist/a2a/task-store.js.map +1 -1
- package/dist/agent/durable-background.d.ts +10 -10
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +16 -16
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +19 -8
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +11 -3
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/engine/output-tokens.js +6 -6
- package/dist/agent/engine/output-tokens.js.map +1 -1
- package/dist/agent/production-agent.d.ts +52 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +154 -26
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +9 -0
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +71 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +9 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +243 -48
- package/dist/agent/run-store.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +6 -2
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +21 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +298 -67
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +146 -1
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +2 -1
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +3 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +13 -37
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/conversation/use-near-bottom-autoscroll.d.ts +1 -0
- package/dist/client/conversation/use-near-bottom-autoscroll.d.ts.map +1 -1
- package/dist/client/conversation/use-near-bottom-autoscroll.js +6 -0
- package/dist/client/conversation/use-near-bottom-autoscroll.js.map +1 -1
- package/dist/client/extensions/AgentNativeExtensionFrame.d.ts.map +1 -1
- package/dist/client/extensions/AgentNativeExtensionFrame.js +2 -1
- package/dist/client/extensions/AgentNativeExtensionFrame.js.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.js +2 -1
- package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
- package/dist/client/extensions/ExtensionEditor.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionEditor.js +5 -2
- package/dist/client/extensions/ExtensionEditor.js.map +1 -1
- package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionViewer.js +2 -1
- package/dist/client/extensions/ExtensionViewer.js.map +1 -1
- package/dist/client/extensions/InlineExtensionFrame.d.ts.map +1 -1
- package/dist/client/extensions/InlineExtensionFrame.js +2 -1
- package/dist/client/extensions/InlineExtensionFrame.js.map +1 -1
- package/dist/client/extensions/portable-extension.d.ts.map +1 -1
- package/dist/client/extensions/portable-extension.js +2 -0
- package/dist/client/extensions/portable-extension.js.map +1 -1
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +308 -29
- package/dist/client/session-replay.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +5 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +37 -1
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/demo/actions/toggle-demo-mode.js +1 -1
- package/dist/demo/actions/toggle-demo-mode.js.map +1 -1
- package/dist/demo/config.js +6 -6
- package/dist/demo/config.js.map +1 -1
- package/dist/demo/fetch-interceptor.d.ts.map +1 -1
- package/dist/demo/fetch-interceptor.js +13 -4
- package/dist/demo/fetch-interceptor.js.map +1 -1
- package/dist/demo/redact.d.ts +7 -7
- package/dist/demo/redact.d.ts.map +1 -1
- package/dist/demo/redact.js +8 -145
- package/dist/demo/redact.js.map +1 -1
- package/dist/extensions/html-shell.d.ts.map +1 -1
- package/dist/extensions/html-shell.js +2 -0
- package/dist/extensions/html-shell.js.map +1 -1
- package/dist/extensions/session-replay-iframe.d.ts +10 -0
- package/dist/extensions/session-replay-iframe.d.ts.map +1 -0
- package/dist/extensions/session-replay-iframe.js +121 -0
- package/dist/extensions/session-replay-iframe.js.map +1 -0
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +98 -13
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/identity-links-store.d.ts +23 -0
- package/dist/integrations/identity-links-store.d.ts.map +1 -0
- package/dist/integrations/identity-links-store.js +158 -0
- package/dist/integrations/identity-links-store.js.map +1 -0
- package/dist/integrations/identity.d.ts +11 -0
- package/dist/integrations/identity.d.ts.map +1 -0
- package/dist/integrations/identity.js +100 -0
- package/dist/integrations/identity.js.map +1 -0
- package/dist/integrations/index.d.ts +2 -0
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +2 -0
- package/dist/integrations/index.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +43 -1
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/types.d.ts +6 -0
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/types.js.map +1 -1
- package/dist/mcp/build-server.d.ts +9 -2
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +97 -20
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/external-agent-policy.d.ts +19 -0
- package/dist/mcp/external-agent-policy.d.ts.map +1 -0
- package/dist/mcp/external-agent-policy.js +2 -0
- package/dist/mcp/external-agent-policy.js.map +1 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.js +1 -19
- package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
- package/dist/server/agent-chat/plugin-options.d.ts +11 -1
- package/dist/server/agent-chat/plugin-options.d.ts.map +1 -1
- package/dist/server/agent-chat/plugin-options.js.map +1 -1
- package/dist/server/agent-chat/script-entries.d.ts.map +1 -1
- package/dist/server/agent-chat/script-entries.js +16 -2
- package/dist/server/agent-chat/script-entries.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +3 -0
- 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/session-replay-iframe-protocol.d.ts +36 -0
- package/dist/session-replay-iframe-protocol.d.ts.map +1 -0
- package/dist/session-replay-iframe-protocol.js +24 -0
- package/dist/session-replay-iframe-protocol.js.map +1 -0
- package/dist/shared/reasoning-effort.d.ts +11 -0
- package/dist/shared/reasoning-effort.d.ts.map +1 -1
- package/dist/shared/reasoning-effort.js +36 -0
- package/dist/shared/reasoning-effort.js.map +1 -1
- package/dist/styles/agent-conversation.css +26 -0
- package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +34 -5
- package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +0 -15
- package/docs/content/durable-background-runs.mdx +37 -0
- package/docs/content/external-agents.mdx +62 -7
- package/docs/content/locales/ar-SA/external-agents.mdx +38 -7
- package/docs/content/locales/ar-SA/tracking.mdx +2 -0
- package/docs/content/locales/de-DE/external-agents.mdx +39 -7
- package/docs/content/locales/de-DE/tracking.mdx +2 -0
- package/docs/content/locales/es-ES/external-agents.mdx +39 -7
- package/docs/content/locales/es-ES/tracking.mdx +2 -0
- package/docs/content/locales/fr-FR/external-agents.mdx +39 -7
- package/docs/content/locales/fr-FR/tracking.mdx +4 -2
- package/docs/content/locales/hi-IN/external-agents.mdx +38 -7
- package/docs/content/locales/hi-IN/tracking.mdx +2 -0
- package/docs/content/locales/ja-JP/external-agents.mdx +38 -7
- package/docs/content/locales/ja-JP/tracking.mdx +2 -0
- package/docs/content/locales/ko-KR/external-agents.mdx +38 -7
- package/docs/content/locales/ko-KR/tracking.mdx +2 -0
- package/docs/content/locales/pt-BR/external-agents.mdx +39 -7
- package/docs/content/locales/pt-BR/tracking.mdx +2 -0
- package/docs/content/locales/zh-CN/external-agents.mdx +37 -7
- package/docs/content/locales/zh-CN/tracking.mdx +2 -0
- package/docs/content/locales/zh-TW/durable-background-runs.mdx +14 -0
- package/docs/content/locales/zh-TW/external-agents.mdx +37 -7
- package/docs/content/locales/zh-TW/tracking.mdx +2 -0
- package/docs/content/tracking.mdx +2 -0
- package/package.json +2 -2
- package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +34 -5
- package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +0 -15
- package/corpus/core/src/observability/hosted-model-experiment.ts +0 -118
- package/dist/observability/hosted-model-experiment.d.ts +0 -39
- package/dist/observability/hosted-model-experiment.d.ts.map +0 -1
- package/dist/observability/hosted-model-experiment.js +0 -90
- package/dist/observability/hosted-model-experiment.js.map +0 -1
|
@@ -178,6 +178,16 @@ const BACKGROUND_FOLLOW_POLL_INTERVAL_MS = 1_000;
|
|
|
178
178
|
// accurate if any of the four numbers change.
|
|
179
179
|
export const BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS = 150_000;
|
|
180
180
|
|
|
181
|
+
// A re-observed terminal run whose outcome would be an ERROR (never a
|
|
182
|
+
// genuine "done" success) gets a short extra grace window before the follow
|
|
183
|
+
// loop surfaces it: the server's dead-run recovery can reap a lost
|
|
184
|
+
// background run and insert a claimable successor a beat after the client
|
|
185
|
+
// first sees the stale terminal row. Deliberately much shorter than
|
|
186
|
+
// BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS — this exists to absorb that narrow
|
|
187
|
+
// insert-latency race, not to mask a genuinely lost run behind a long hang
|
|
188
|
+
// before the user sees an error.
|
|
189
|
+
const BACKGROUND_TERMINAL_ERROR_GRACE_POLLS = 5;
|
|
190
|
+
|
|
181
191
|
/**
|
|
182
192
|
* User-facing copy for the server's background terminal reasons
|
|
183
193
|
* (`agent_runs.terminal_reason`, surfaced by /runs/active). These runs died in
|
|
@@ -200,6 +210,50 @@ const BACKGROUND_TERMINAL_REASON_MESSAGES: Record<string, string> = {
|
|
|
200
210
|
"This request needed more automatic continuations than allowed and was stopped. Try breaking it into smaller steps.",
|
|
201
211
|
};
|
|
202
212
|
|
|
213
|
+
/**
|
|
214
|
+
* `agent_runs.terminal_reason` values that mark a CHUNK boundary, not the end
|
|
215
|
+
* of the turn — `markBackgroundContinuationChunkTerminal` (production-agent.ts)
|
|
216
|
+
* writes status "completed" with one of these bare reasons whenever a
|
|
217
|
+
* background chunk ends at a continuation boundary (mirrors
|
|
218
|
+
* `AgentLoopContinuationReason` there). A run in this state is expected to be
|
|
219
|
+
* replaced by a server-chained successor row; it must never be read as "the
|
|
220
|
+
* turn is done" just because its own row says `status: "completed"`.
|
|
221
|
+
*/
|
|
222
|
+
const BACKGROUND_CONTINUATION_TERMINAL_REASONS = new Set<string>([
|
|
223
|
+
"run_timeout",
|
|
224
|
+
"loop_limit",
|
|
225
|
+
"max_tokens",
|
|
226
|
+
"stream_ended",
|
|
227
|
+
"gateway_timeout",
|
|
228
|
+
"network_interrupted",
|
|
229
|
+
"no_progress",
|
|
230
|
+
]);
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* True when the given `/runs/active` snapshot, if surfaced as a background
|
|
234
|
+
* terminal outcome right now, would render as an error rather than a
|
|
235
|
+
* successful completion. Mirrors `emitBackgroundTerminalOutcome`'s own
|
|
236
|
+
* mappedMessage/hasErrorTerminalReason/status branching (kept in sync with
|
|
237
|
+
* it) so callers can decide whether an error-surfacing grace window applies
|
|
238
|
+
* BEFORE actually emitting anything.
|
|
239
|
+
*/
|
|
240
|
+
function isBackgroundTerminalErrorOutcome(
|
|
241
|
+
lastKnown: Record<string, unknown> | null,
|
|
242
|
+
): boolean {
|
|
243
|
+
const status = typeof lastKnown?.status === "string" ? lastKnown.status : "";
|
|
244
|
+
const rawTerminalReason =
|
|
245
|
+
typeof lastKnown?.terminalReason === "string"
|
|
246
|
+
? lastKnown.terminalReason
|
|
247
|
+
: "";
|
|
248
|
+
const hasErrorTerminalReason = rawTerminalReason.startsWith("error:");
|
|
249
|
+
const terminalReason = rawTerminalReason.replace(/^error:/, "");
|
|
250
|
+
const mappedMessage = terminalReason
|
|
251
|
+
? BACKGROUND_TERMINAL_REASON_MESSAGES[terminalReason]
|
|
252
|
+
: undefined;
|
|
253
|
+
if (mappedMessage || hasErrorTerminalReason) return true;
|
|
254
|
+
return status !== "completed";
|
|
255
|
+
}
|
|
256
|
+
|
|
203
257
|
function normalizeMentions(text: string): string {
|
|
204
258
|
return text.replace(/@\[([^\]|]+)\|[^\]]+\]/g, "@$1");
|
|
205
259
|
}
|
|
@@ -2387,6 +2441,52 @@ export function createAgentChatAdapter(
|
|
|
2387
2441
|
};
|
|
2388
2442
|
dispatchResumingUiEvent();
|
|
2389
2443
|
|
|
2444
|
+
// Before surfacing a background terminal ERROR (never called for a
|
|
2445
|
+
// genuine "done" success — see call site), give the server's
|
|
2446
|
+
// reap-and-recover path a short extra window to insert a claimable
|
|
2447
|
+
// successor row for this turn. Returns as soon as `/runs/active`
|
|
2448
|
+
// reports a DIFFERENT runId than the stale one, so the caller can
|
|
2449
|
+
// hand back to the main loop and follow it seamlessly instead of
|
|
2450
|
+
// erroring out from under it.
|
|
2451
|
+
const awaitBackgroundErrorRecoverySuccessor = async (
|
|
2452
|
+
staleRunId: string,
|
|
2453
|
+
): Promise<"successor" | "timeout" | "aborted"> => {
|
|
2454
|
+
for (
|
|
2455
|
+
let attempt = 0;
|
|
2456
|
+
attempt < BACKGROUND_TERMINAL_ERROR_GRACE_POLLS;
|
|
2457
|
+
attempt++
|
|
2458
|
+
) {
|
|
2459
|
+
if (abortSignal.aborted) return "aborted";
|
|
2460
|
+
dispatchResumingUiEvent();
|
|
2461
|
+
await delay(BACKGROUND_FOLLOW_POLL_INTERVAL_MS, abortSignal);
|
|
2462
|
+
if (abortSignal.aborted) return "aborted";
|
|
2463
|
+
let recheck: Record<string, unknown> | null = null;
|
|
2464
|
+
try {
|
|
2465
|
+
const activeRes = await fetch(
|
|
2466
|
+
`${apiUrl}/runs/active?threadId=${encodeURIComponent(threadId!)}`,
|
|
2467
|
+
{ signal: abortSignal },
|
|
2468
|
+
);
|
|
2469
|
+
if (activeRes.ok) {
|
|
2470
|
+
recheck = await activeRes.json().catch(() => null);
|
|
2471
|
+
}
|
|
2472
|
+
} catch (pollErr: unknown) {
|
|
2473
|
+
if (pollErr instanceof Error && pollErr.name === "AbortError") {
|
|
2474
|
+
return "aborted";
|
|
2475
|
+
}
|
|
2476
|
+
// Transient poll failure — this attempt counts as "no
|
|
2477
|
+
// successor yet", not a hard failure of the grace window.
|
|
2478
|
+
}
|
|
2479
|
+
const recheckRunId =
|
|
2480
|
+
recheck?.active === true && recheck.runId
|
|
2481
|
+
? String(recheck.runId)
|
|
2482
|
+
: null;
|
|
2483
|
+
if (recheckRunId && recheckRunId !== staleRunId) {
|
|
2484
|
+
return "successor";
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
return "timeout";
|
|
2488
|
+
};
|
|
2489
|
+
|
|
2390
2490
|
let idleSince: number | null = null;
|
|
2391
2491
|
let lastSeenActive: Record<string, unknown> | null = null;
|
|
2392
2492
|
// Terminal runs already replayed once. A recoverable terminal error
|
|
@@ -2394,7 +2494,10 @@ export function createAgentChatAdapter(
|
|
|
2394
2494
|
// which used to re-drive a POST in foreground mode. In follow mode
|
|
2395
2495
|
// the server owns recovery, so a SECOND visit to the same terminal
|
|
2396
2496
|
// run means the turn is over — surface the outcome instead of
|
|
2397
|
-
// re-replaying it every poll for the whole reconnect window.
|
|
2497
|
+
// re-replaying it every poll for the whole reconnect window. (A
|
|
2498
|
+
// CONTINUATION-class terminal_reason is the one exception: see the
|
|
2499
|
+
// isContinuationChunkBoundary check below, which keeps polling
|
|
2500
|
+
// instead of surfacing anything.)
|
|
2398
2501
|
const replayedTerminalRunIds = new Set<string>();
|
|
2399
2502
|
|
|
2400
2503
|
while (true) {
|
|
@@ -2458,6 +2561,64 @@ export function createAgentChatAdapter(
|
|
|
2458
2561
|
return "client_continue";
|
|
2459
2562
|
}
|
|
2460
2563
|
}
|
|
2564
|
+
const rawTerminalReason =
|
|
2565
|
+
typeof active?.terminalReason === "string"
|
|
2566
|
+
? active.terminalReason
|
|
2567
|
+
: "";
|
|
2568
|
+
const bareTerminalReason = rawTerminalReason.replace(
|
|
2569
|
+
/^error:/,
|
|
2570
|
+
"",
|
|
2571
|
+
);
|
|
2572
|
+
// A re-observed "completed" row with a CONTINUATION-class
|
|
2573
|
+
// reason (run_timeout/no_progress/loop_limit/…) is a MID-TURN
|
|
2574
|
+
// chunk boundary, not the end of the turn — a warm instance
|
|
2575
|
+
// can keep serving this stale row for a beat before the
|
|
2576
|
+
// pre-inserted successor becomes visible. Emitting a terminal
|
|
2577
|
+
// outcome here is exactly the bug this branch exists to
|
|
2578
|
+
// avoid: it would flip the message to "done" while the
|
|
2579
|
+
// successor's content is still coming. Keep polling on the
|
|
2580
|
+
// shared idle budget instead; a truly stuck handoff still
|
|
2581
|
+
// fails loud (never a silent stop) once it expires.
|
|
2582
|
+
const isContinuationChunkBoundary =
|
|
2583
|
+
activeStatus === "completed" &&
|
|
2584
|
+
!rawTerminalReason.startsWith("error:") &&
|
|
2585
|
+
!BACKGROUND_TERMINAL_REASON_MESSAGES[bareTerminalReason] &&
|
|
2586
|
+
BACKGROUND_CONTINUATION_TERMINAL_REASONS.has(
|
|
2587
|
+
bareTerminalReason,
|
|
2588
|
+
);
|
|
2589
|
+
if (isContinuationChunkBoundary) {
|
|
2590
|
+
if (idleSince === null) idleSince = Date.now();
|
|
2591
|
+
if (
|
|
2592
|
+
Date.now() - idleSince >=
|
|
2593
|
+
BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS
|
|
2594
|
+
) {
|
|
2595
|
+
yield* emitBackgroundTerminalError({
|
|
2596
|
+
message:
|
|
2597
|
+
"The agent's background run stopped between chunks and no continuation appeared. You can retry from the preserved chat context.",
|
|
2598
|
+
errorCode: "background_run_lost",
|
|
2599
|
+
details: `terminal_reason: ${rawTerminalReason}`,
|
|
2600
|
+
});
|
|
2601
|
+
return "completed";
|
|
2602
|
+
}
|
|
2603
|
+
dispatchResumingUiEvent();
|
|
2604
|
+
await delay(BACKGROUND_FOLLOW_POLL_INTERVAL_MS, abortSignal);
|
|
2605
|
+
continue;
|
|
2606
|
+
}
|
|
2607
|
+
if (isBackgroundTerminalErrorOutcome(active)) {
|
|
2608
|
+
const graceOutcome =
|
|
2609
|
+
await awaitBackgroundErrorRecoverySuccessor(activeRunId);
|
|
2610
|
+
if (graceOutcome === "aborted") {
|
|
2611
|
+
clearActiveRun();
|
|
2612
|
+
return "completed";
|
|
2613
|
+
}
|
|
2614
|
+
if (graceOutcome === "successor") {
|
|
2615
|
+
// A successor claimed the turn while we waited — hand
|
|
2616
|
+
// back to the top of the loop so it attaches and follows
|
|
2617
|
+
// it exactly like any other newly-discovered run instead
|
|
2618
|
+
// of duplicating that bookkeeping here.
|
|
2619
|
+
continue;
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2461
2622
|
yield* emitBackgroundTerminalOutcome(active);
|
|
2462
2623
|
return "completed";
|
|
2463
2624
|
}
|
|
@@ -2513,6 +2674,13 @@ export function createAgentChatAdapter(
|
|
|
2513
2674
|
}
|
|
2514
2675
|
dispatchResumingUiEvent();
|
|
2515
2676
|
} else {
|
|
2677
|
+
// No active run visible for this turn yet (the gap between a
|
|
2678
|
+
// chunk ending and the successor becoming pollable). Refresh
|
|
2679
|
+
// the "Resuming…" bridge on every tick here too — not just
|
|
2680
|
+
// when an active run IS visible — so the client's own
|
|
2681
|
+
// isAutoResuming window can't lapse into a false-idle UI while
|
|
2682
|
+
// this loop is still confidently waiting out its own budget.
|
|
2683
|
+
dispatchResumingUiEvent();
|
|
2516
2684
|
if (idleSince === null) idleSince = Date.now();
|
|
2517
2685
|
if (Date.now() - idleSince >= BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS) {
|
|
2518
2686
|
captureChatClientError(
|
|
@@ -842,6 +842,7 @@ export function shouldShowAssistantMessageFooter({
|
|
|
842
842
|
|
|
843
843
|
function ReasoningMessagePart() {
|
|
844
844
|
const part = useMessagePartReasoning();
|
|
845
|
+
const chatRunning = React.useContext(ChatRunningContext);
|
|
845
846
|
const isStreaming = part.status?.type === "running";
|
|
846
847
|
// Time thinking client-side: record the moment streaming first starts and
|
|
847
848
|
// the moment it stops so the cell can show "Thought for Xs". Historical
|
|
@@ -864,6 +865,8 @@ function ReasoningMessagePart() {
|
|
|
864
865
|
text={part.text}
|
|
865
866
|
isStreaming={isStreaming}
|
|
866
867
|
durationMs={durationMs}
|
|
868
|
+
defaultOpen={isStreaming || !chatRunning}
|
|
869
|
+
autoCollapse={chatRunning}
|
|
867
870
|
/>
|
|
868
871
|
);
|
|
869
872
|
}
|
|
@@ -404,45 +404,16 @@ export function AnimatedCollapse({
|
|
|
404
404
|
open: boolean;
|
|
405
405
|
children: React.ReactNode;
|
|
406
406
|
}) {
|
|
407
|
-
const ref = useRef<HTMLDivElement>(null);
|
|
408
|
-
const [height, setHeight] = useState<number | "auto">(open ? "auto" : 0);
|
|
409
407
|
const [mounted, setMounted] = useState(open);
|
|
410
|
-
const reduceMotionRef = useRef(false);
|
|
411
|
-
|
|
412
|
-
useEffect(() => {
|
|
413
|
-
reduceMotionRef.current =
|
|
414
|
-
typeof window !== "undefined" &&
|
|
415
|
-
!!window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
|
|
416
|
-
}, []);
|
|
417
408
|
|
|
418
409
|
useLayoutEffect(() => {
|
|
419
410
|
if (open) setMounted(true);
|
|
420
411
|
}, [open]);
|
|
421
412
|
|
|
422
|
-
useLayoutEffect(() => {
|
|
423
|
-
const el = ref.current;
|
|
424
|
-
if (!el || !mounted) return;
|
|
425
|
-
if (reduceMotionRef.current) {
|
|
426
|
-
setHeight(open ? "auto" : 0);
|
|
427
|
-
if (!open) setMounted(false);
|
|
428
|
-
return;
|
|
429
|
-
}
|
|
430
|
-
if (open) {
|
|
431
|
-
const full = el.scrollHeight;
|
|
432
|
-
setHeight(0);
|
|
433
|
-
const frame = requestAnimationFrame(() => setHeight(full));
|
|
434
|
-
return () => cancelAnimationFrame(frame);
|
|
435
|
-
}
|
|
436
|
-
setHeight(el.scrollHeight);
|
|
437
|
-
const frame = requestAnimationFrame(() => setHeight(0));
|
|
438
|
-
return () => cancelAnimationFrame(frame);
|
|
439
|
-
}, [open, mounted]);
|
|
440
|
-
|
|
441
413
|
const onTransitionEnd = useCallback(
|
|
442
414
|
(event: React.TransitionEvent<HTMLDivElement>) => {
|
|
443
|
-
if (event.propertyName !== "
|
|
444
|
-
|
|
445
|
-
else setMounted(false);
|
|
415
|
+
if (event.propertyName !== "grid-template-rows" || open) return;
|
|
416
|
+
setMounted(false);
|
|
446
417
|
},
|
|
447
418
|
[open],
|
|
448
419
|
);
|
|
@@ -451,12 +422,12 @@ export function AnimatedCollapse({
|
|
|
451
422
|
|
|
452
423
|
return (
|
|
453
424
|
<div
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
425
|
+
className="agent-chat-collapse"
|
|
426
|
+
data-state={open ? "open" : "closed"}
|
|
427
|
+
aria-hidden={!open}
|
|
457
428
|
onTransitionEnd={onTransitionEnd}
|
|
458
429
|
>
|
|
459
|
-
{children}
|
|
430
|
+
<div className="agent-chat-collapse__content">{children}</div>
|
|
460
431
|
</div>
|
|
461
432
|
);
|
|
462
433
|
}
|
|
@@ -953,6 +924,7 @@ export function ReconnectStreamMessage({
|
|
|
953
924
|
key={`reconnect-reasoning-${i}`}
|
|
954
925
|
text={part.text}
|
|
955
926
|
isStreaming={chatRunning && i === streamingReasoningPartIndex}
|
|
927
|
+
defaultOpen={chatRunning && i === streamingReasoningPartIndex}
|
|
956
928
|
/>
|
|
957
929
|
);
|
|
958
930
|
}
|
|
@@ -996,11 +968,14 @@ export function ReasoningCell({
|
|
|
996
968
|
text,
|
|
997
969
|
isStreaming = false,
|
|
998
970
|
defaultOpen,
|
|
971
|
+
autoCollapse = false,
|
|
999
972
|
durationMs,
|
|
1000
973
|
}: {
|
|
1001
974
|
text: string;
|
|
1002
975
|
isStreaming?: boolean;
|
|
1003
976
|
defaultOpen?: boolean;
|
|
977
|
+
/** Animate closed when a live reasoning segment finishes during a run. */
|
|
978
|
+
autoCollapse?: boolean;
|
|
1004
979
|
/**
|
|
1005
980
|
* Elapsed thinking time in ms, once known. Only meaningful once streaming
|
|
1006
981
|
* has finished — callers that track live timing (see ReasoningMessagePart)
|
|
@@ -1011,7 +986,16 @@ export function ReasoningCell({
|
|
|
1011
986
|
}) {
|
|
1012
987
|
const embeddedInWorkSummary = React.useContext(WorkSummaryContentContext);
|
|
1013
988
|
const [open, setOpen] = useState(defaultOpen ?? true);
|
|
989
|
+
const wasStreamingRef = useRef(isStreaming);
|
|
1014
990
|
const trimmed = text.trim();
|
|
991
|
+
|
|
992
|
+
useEffect(() => {
|
|
993
|
+
if (autoCollapse && wasStreamingRef.current && !isStreaming) {
|
|
994
|
+
setOpen(false);
|
|
995
|
+
}
|
|
996
|
+
wasStreamingRef.current = isStreaming;
|
|
997
|
+
}, [autoCollapse, isStreaming]);
|
|
998
|
+
|
|
1015
999
|
if (!trimmed && !isStreaming) return null;
|
|
1016
1000
|
|
|
1017
1001
|
if (embeddedInWorkSummary) {
|
|
@@ -1024,7 +1008,7 @@ export function ReasoningCell({
|
|
|
1024
1008
|
|
|
1025
1009
|
const label = isStreaming
|
|
1026
1010
|
? "Thinking"
|
|
1027
|
-
: durationMs != null
|
|
1011
|
+
: durationMs != null
|
|
1028
1012
|
? `Thought for ${formatWorkedDuration(durationMs)}`
|
|
1029
1013
|
: "Thought";
|
|
1030
1014
|
// Only clamp to a scroll-free "tail" view while actively streaming and
|
|
@@ -243,6 +243,12 @@ export function useNearBottomAutoscroll<TElement extends HTMLElement>({
|
|
|
243
243
|
window.setTimeout(() => scrollToBottomIfFollowing(generation), 80);
|
|
244
244
|
}, [scrollToBottomIfFollowing]);
|
|
245
245
|
|
|
246
|
+
const resumeFollowing = useCallback(() => {
|
|
247
|
+
const el = scrollRef.current;
|
|
248
|
+
setFollowingBottom(true, true, el ?? undefined);
|
|
249
|
+
scrollToBottomAfterPaint();
|
|
250
|
+
}, [scrollToBottomAfterPaint, setFollowingBottom]);
|
|
251
|
+
|
|
246
252
|
const markNearBottom = useCallback(() => {
|
|
247
253
|
setFollowingBottom(true, true, scrollRef.current ?? undefined);
|
|
248
254
|
}, [setFollowingBottom]);
|
|
@@ -267,5 +273,6 @@ export function useNearBottomAutoscroll<TElement extends HTMLElement>({
|
|
|
267
273
|
markNearBottom,
|
|
268
274
|
scrollToBottom,
|
|
269
275
|
scrollToBottomAfterPaint,
|
|
276
|
+
resumeFollowing,
|
|
270
277
|
};
|
|
271
278
|
}
|
|
@@ -9,6 +9,7 @@ import React, {
|
|
|
9
9
|
type IframeHTMLAttributes,
|
|
10
10
|
} from "react";
|
|
11
11
|
|
|
12
|
+
import { SESSION_REPLAY_IFRAME_ATTRIBUTE } from "../../session-replay-iframe-protocol.js";
|
|
12
13
|
import {
|
|
13
14
|
createAgentNativeHostBridge,
|
|
14
15
|
type AgentNativeClientAction,
|
|
@@ -604,6 +605,7 @@ export const AgentNativeExtensionFrame = forwardRef<
|
|
|
604
605
|
return (
|
|
605
606
|
<iframe
|
|
606
607
|
{...iframeProps}
|
|
608
|
+
{...{ [SESSION_REPLAY_IFRAME_ATTRIBUTE]: "" }}
|
|
607
609
|
key={`${extension.id}:${extension.updatedAt ?? ""}`}
|
|
608
610
|
ref={(node) => {
|
|
609
611
|
iframeRef.current = node;
|
|
@@ -10,6 +10,7 @@ import { useNavigate } from "react-router";
|
|
|
10
10
|
|
|
11
11
|
import { extensionPath } from "../../extensions/path.js";
|
|
12
12
|
import { THEME_VAR_NAMES } from "../../extensions/theme.js";
|
|
13
|
+
import { SESSION_REPLAY_IFRAME_ATTRIBUTE } from "../../session-replay-iframe-protocol.js";
|
|
13
14
|
import { sendToAgentChat } from "../agent-chat.js";
|
|
14
15
|
import { agentNativePath } from "../api-path.js";
|
|
15
16
|
import { useAppearance } from "../appearance.js";
|
|
@@ -425,6 +426,7 @@ export function EmbeddedExtension({
|
|
|
425
426
|
return (
|
|
426
427
|
<div className={`relative group/embedded-extension ${className ?? ""}`}>
|
|
427
428
|
<iframe
|
|
429
|
+
{...{ [SESSION_REPLAY_IFRAME_ATTRIBUTE]: "" }}
|
|
428
430
|
ref={iframeRef}
|
|
429
431
|
key={`${extensionId}-${extension.updatedAt ?? ""}`}
|
|
430
432
|
src={iframeSrc}
|
|
@@ -6,10 +6,12 @@ import {
|
|
|
6
6
|
IconX,
|
|
7
7
|
} from "@tabler/icons-react";
|
|
8
8
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
9
|
-
import {
|
|
9
|
+
import { useEffect, useMemo, useState } from "react";
|
|
10
10
|
import { Link, useNavigate } from "react-router";
|
|
11
11
|
|
|
12
12
|
import { extensionPath } from "../../extensions/path.js";
|
|
13
|
+
import { injectSessionReplayIframeBootstrap } from "../../extensions/session-replay-iframe.js";
|
|
14
|
+
import { SESSION_REPLAY_IFRAME_ATTRIBUTE } from "../../session-replay-iframe-protocol.js";
|
|
13
15
|
import { agentNativePath } from "../api-path.js";
|
|
14
16
|
import {
|
|
15
17
|
Popover,
|
|
@@ -61,6 +63,10 @@ export function ExtensionEditor({ extensionId }: ExtensionEditorProps) {
|
|
|
61
63
|
const [deleting, setDeleting] = useState(false);
|
|
62
64
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
63
65
|
const [confirmingDelete, setConfirmingDelete] = useState(false);
|
|
66
|
+
const previewHtml = useMemo(
|
|
67
|
+
() => injectSessionReplayIframeBootstrap(content),
|
|
68
|
+
[content],
|
|
69
|
+
);
|
|
64
70
|
|
|
65
71
|
const slotsQuery = useQuery<SlotDeclaration[]>({
|
|
66
72
|
queryKey: ["extension-slots", extensionId],
|
|
@@ -425,7 +431,8 @@ export function ExtensionEditor({ extensionId }: ExtensionEditorProps) {
|
|
|
425
431
|
<div className="w-1/2">
|
|
426
432
|
{content ? (
|
|
427
433
|
<iframe
|
|
428
|
-
|
|
434
|
+
{...{ [SESSION_REPLAY_IFRAME_ATTRIBUTE]: "" }}
|
|
435
|
+
srcDoc={previewHtml}
|
|
429
436
|
className="h-full w-full border-0"
|
|
430
437
|
sandbox="allow-scripts allow-forms"
|
|
431
438
|
title={t("extensions.previewTitle")}
|
|
@@ -17,6 +17,7 @@ import { Link, useLocation, useNavigate } from "react-router";
|
|
|
17
17
|
import { buildExtensionHtml } from "../../extensions/html-shell.js";
|
|
18
18
|
import { extensionPath, isExtensionPathname } from "../../extensions/path.js";
|
|
19
19
|
import { getThemeVars } from "../../extensions/theme.js";
|
|
20
|
+
import { SESSION_REPLAY_IFRAME_ATTRIBUTE } from "../../session-replay-iframe-protocol.js";
|
|
20
21
|
import { sendToAgentChat } from "../agent-chat.js";
|
|
21
22
|
import { AgentToggleButton } from "../AgentPanel.js";
|
|
22
23
|
import { agentNativePath, appPath } from "../api-path.js";
|
|
@@ -1400,6 +1401,7 @@ export function ExtensionViewer({ extensionId }: ExtensionViewerProps) {
|
|
|
1400
1401
|
</div>
|
|
1401
1402
|
)}
|
|
1402
1403
|
<iframe
|
|
1404
|
+
{...{ [SESSION_REPLAY_IFRAME_ATTRIBUTE]: "" }}
|
|
1403
1405
|
ref={iframeRef}
|
|
1404
1406
|
key={`${extension.updatedAt}-${refreshKey}`}
|
|
1405
1407
|
src={iframeSrcDoc ? undefined : iframeSrc}
|
|
@@ -2,6 +2,7 @@ import { useEffect, useMemo, useRef, useState } from "react";
|
|
|
2
2
|
|
|
3
3
|
import { buildExtensionHtml } from "../../extensions/html-shell.js";
|
|
4
4
|
import { getThemeVars } from "../../extensions/theme.js";
|
|
5
|
+
import { SESSION_REPLAY_IFRAME_ATTRIBUTE } from "../../session-replay-iframe-protocol.js";
|
|
5
6
|
import { sendToAgentChat } from "../agent-chat.js";
|
|
6
7
|
import { agentNativePath } from "../api-path.js";
|
|
7
8
|
import {
|
|
@@ -641,6 +642,7 @@ export function InlineExtensionFrame({
|
|
|
641
642
|
return (
|
|
642
643
|
<div className={`relative ${className ?? ""}`}>
|
|
643
644
|
<iframe
|
|
645
|
+
{...{ [SESSION_REPLAY_IFRAME_ATTRIBUTE]: "" }}
|
|
644
646
|
ref={iframeRef}
|
|
645
647
|
key={`${resolvedId}-${extension.updatedAt ?? "inline"}-${isTransient ? "transient" : "persisted"}`}
|
|
646
648
|
src={iframeSrc}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { EXTENSION_IFRAME_META_CSP } from "../../extensions/html-shell.js";
|
|
2
|
+
import { buildSessionReplayIframeBootstrap } from "../../extensions/session-replay-iframe.js";
|
|
2
3
|
import { AGENT_NATIVE_HOST_MESSAGE_TYPES } from "../host-bridge.js";
|
|
3
4
|
|
|
4
5
|
export const AGENT_NATIVE_EXTENSION_MESSAGE_TYPES = {
|
|
@@ -702,6 +703,7 @@ export function buildAgentNativeExtensionHtml({
|
|
|
702
703
|
}, '*');
|
|
703
704
|
})();
|
|
704
705
|
</script>
|
|
706
|
+
${buildSessionReplayIframeBootstrap()}
|
|
705
707
|
</head>
|
|
706
708
|
<body>
|
|
707
709
|
${content}
|