@agent-native/core 0.118.0 → 0.119.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +32 -0
- package/corpus/core/docs/content/a2a-protocol.mdx +15 -0
- package/corpus/core/docs/content/template-chat.mdx +1 -1
- package/corpus/core/docs/content/template-plan.mdx +3 -3
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/activity.ts +371 -0
- package/corpus/core/src/a2a/client.ts +35 -11
- package/corpus/core/src/a2a/index.ts +21 -0
- package/corpus/core/src/a2a/types.ts +8 -0
- package/corpus/core/src/agent/model-config.ts +19 -23
- package/corpus/core/src/agent/production-agent.ts +167 -100
- package/corpus/core/src/agent/types.ts +16 -1
- package/corpus/core/src/cli/index.ts +18 -10
- package/corpus/core/src/cli/multi-frontier-runs.ts +5 -3
- package/corpus/core/src/cli/templates-meta.ts +0 -12
- package/corpus/core/src/cli/workspace-dev.ts +1 -1
- package/corpus/core/src/client/AgentPanel.tsx +9 -1
- package/corpus/core/src/client/RunStuckBanner.tsx +39 -47
- package/corpus/core/src/client/chat/action-chat-ui-surface.tsx +32 -0
- package/corpus/core/src/client/chat/message-components.tsx +53 -8
- package/corpus/core/src/client/chat/tool-call-display.tsx +214 -44
- package/corpus/core/src/client/chat/widgets/InlineExtensionWidget.tsx +0 -1
- package/corpus/core/src/client/chat/widgets/builtin-tool-renderers.tsx +7 -3
- package/corpus/core/src/client/chat-model-groups.ts +67 -27
- package/corpus/core/src/client/conversation/AgentConversation.tsx +12 -1
- package/corpus/core/src/client/error-capture.ts +2 -6
- package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +20 -14
- package/corpus/core/src/client/resources/ResourcesPanel.tsx +5 -1
- package/corpus/core/src/client/resources/mcp-integration-catalog.ts +7 -17
- package/corpus/core/src/client/resources/mcp-integration-logos.ts +2 -2
- package/corpus/core/src/client/route-chunk-recovery.ts +5 -3
- package/corpus/core/src/client/session-replay.ts +3 -3
- package/corpus/core/src/client/settings/SettingsPanel.tsx +15 -6
- package/corpus/core/src/client/sharing/ShareButton.tsx +1 -27
- package/corpus/core/src/client/sharing/ShareDialog.tsx +0 -16
- package/corpus/core/src/client/sharing/useShareButtonController.ts +0 -7
- package/corpus/core/src/client/sharing/useShareDialogController.ts +0 -2
- package/corpus/core/src/client/sse-event-processor.ts +85 -1
- package/corpus/core/src/client/transcription/use-live-transcription.ts +64 -45
- package/corpus/core/src/deploy/build.ts +2 -1
- package/corpus/core/src/guards/db-tool-scoping.ts +1 -1
- package/corpus/core/src/integrations/adapters/slack.ts +84 -5
- package/corpus/core/src/integrations/index.ts +5 -1
- package/corpus/core/src/localization/default-messages.ts +7 -1
- package/corpus/core/src/mcp-client/oauth-routes.ts +45 -12
- package/corpus/core/src/scripts/agent-engines/list-agent-engines.ts +1 -18
- package/corpus/core/src/scripts/call-agent.ts +49 -6
- package/corpus/core/src/server/agent-chat-plugin.ts +50 -10
- package/corpus/core/src/server/realtime-voice.ts +4 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +16 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +7 -5
- package/corpus/core/src/terminal/cli-registry.ts +1 -1
- package/corpus/core/src/vite/client.ts +166 -1
- package/corpus/templates/analytics/app/hooks/use-dashboard-views.ts +13 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/ViewsMenu.tsx +10 -0
- package/corpus/templates/analytics/changelog/2026-07-22-show-a-useful-error-when-saving-a-dashboard-view-fails.md +6 -0
- package/corpus/templates/brain/app/routes/sources.tsx +181 -114
- package/corpus/templates/clips/AGENTS.md +8 -6
- package/corpus/templates/clips/actions/request-transcript.ts +90 -420
- package/corpus/templates/clips/actions/save-browser-transcript.ts +11 -28
- package/corpus/templates/clips/app/components/capture-install-options.tsx +5 -3
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +3 -136
- package/corpus/templates/clips/app/lib/capture-install-options.ts +15 -4
- package/corpus/templates/clips/app/routes/download.tsx +3 -2
- package/corpus/templates/clips/changelog/2026-07-22-fixed-an-intermittent-hydration-error-on-the-download-page.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-22-fixed-transcript-generation-when-native-speech-capture-retur.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-22-transcript-generation-now-retries-with-backup-speech-recogni.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-23-fixed-recordings-failing-to-save-with-a-cancelled-or-cleanup.md +6 -0
- package/corpus/templates/clips/server/lib/public-agent-context.ts +2 -2
- package/corpus/templates/clips/server/plugins/db.ts +9 -1
- package/corpus/templates/clips/server/register-secrets.ts +7 -6
- package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +16 -84
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +13 -7
- package/corpus/templates/content/app/components/editor/extensions/ImageBlock.tsx +2 -2
- package/corpus/templates/content/app/i18n-data.ts +10 -0
- package/corpus/templates/design/server/lib/fig-file-decoder.ts +1 -0
- package/corpus/templates/plan/app/entry.client.tsx +3 -0
- package/corpus/templates/plan/changelog/2026-07-22-recover-stale-pages-after-a-deployment-refresh-automatically.md +6 -0
- package/corpus/templates/slides/app/hooks/use-agent-generating.ts +10 -3
- package/corpus/templates/slides/app/pages/Index.tsx +1 -0
- package/corpus/templates/slides/changelog/2026-07-22-new-deck-prompts-now-open-in-their-own-visible-chat-thread.md +6 -0
- package/corpus/toolkit/CHANGELOG.md +9 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/composer/PromptComposer.tsx +5 -1
- package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +119 -31
- package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +30 -0
- package/corpus/toolkit/src/conformance/runner.tsx +153 -1
- package/corpus/toolkit/src/editor/SharedRichEditor.tsx +13 -2
- package/corpus/toolkit/src/editor/SlashCommandMenu.tsx +20 -0
- package/corpus/toolkit/src/editor/index.ts +2 -0
- package/corpus/toolkit/src/styles.css +52 -23
- package/dist/a2a/activity.d.ts +50 -0
- package/dist/a2a/activity.d.ts.map +1 -0
- package/dist/a2a/activity.js +236 -0
- package/dist/a2a/activity.js.map +1 -0
- package/dist/a2a/client.d.ts +5 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +18 -13
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/index.d.ts +2 -1
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +1 -0
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/types.d.ts +1 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts +1 -1
- package/dist/agent/engine/builder-engine.d.ts +2 -2
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/model-config.d.ts +16 -16
- package/dist/agent/model-config.d.ts.map +1 -1
- package/dist/agent/model-config.js +19 -23
- package/dist/agent/model-config.js.map +1 -1
- package/dist/agent/production-agent.d.ts +26 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +137 -80
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/types.d.ts +10 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/cli/index.js +18 -8
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/multi-frontier-runs.js +3 -3
- package/dist/cli/multi-frontier-runs.js.map +1 -1
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +0 -12
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/cli/workspace-dev.js +1 -1
- package/dist/cli/workspace-dev.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +4 -1
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/RunStuckBanner.d.ts +3 -5
- package/dist/client/RunStuckBanner.d.ts.map +1 -1
- package/dist/client/RunStuckBanner.js +17 -18
- package/dist/client/RunStuckBanner.js.map +1 -1
- package/dist/client/chat/action-chat-ui-surface.d.ts +8 -0
- package/dist/client/chat/action-chat-ui-surface.d.ts.map +1 -0
- package/dist/client/chat/action-chat-ui-surface.js +10 -0
- package/dist/client/chat/action-chat-ui-surface.js.map +1 -0
- package/dist/client/chat/message-components.d.ts +3 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +40 -7
- 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 +76 -23
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/chat/widgets/InlineExtensionWidget.d.ts.map +1 -1
- package/dist/client/chat/widgets/InlineExtensionWidget.js +1 -1
- package/dist/client/chat/widgets/InlineExtensionWidget.js.map +1 -1
- package/dist/client/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
- package/dist/client/chat/widgets/builtin-tool-renderers.js +5 -3
- package/dist/client/chat/widgets/builtin-tool-renderers.js.map +1 -1
- package/dist/client/chat-model-groups.d.ts.map +1 -1
- package/dist/client/chat-model-groups.js +44 -21
- package/dist/client/chat-model-groups.js.map +1 -1
- package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
- package/dist/client/conversation/AgentConversation.js +3 -2
- package/dist/client/conversation/AgentConversation.js.map +1 -1
- package/dist/client/error-capture.d.ts.map +1 -1
- package/dist/client/error-capture.js +2 -2
- package/dist/client/error-capture.js.map +1 -1
- package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
- package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
- package/dist/client/resources/McpConnectionSuggestion.js +9 -8
- package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +3 -1
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
- package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.js +4 -17
- package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
- package/dist/client/resources/mcp-integration-logos.js +2 -2
- package/dist/client/resources/mcp-integration-logos.js.map +1 -1
- package/dist/client/route-chunk-recovery.d.ts.map +1 -1
- package/dist/client/route-chunk-recovery.js +5 -3
- package/dist/client/route-chunk-recovery.js.map +1 -1
- package/dist/client/session-replay.js +3 -3
- package/dist/client/session-replay.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +2 -2
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts +1 -1
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +3 -4
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
- package/dist/client/sharing/ShareDialog.js +1 -2
- package/dist/client/sharing/ShareDialog.js.map +1 -1
- package/dist/client/sharing/useShareButtonController.d.ts +0 -1
- package/dist/client/sharing/useShareButtonController.d.ts.map +1 -1
- package/dist/client/sharing/useShareButtonController.js +0 -6
- package/dist/client/sharing/useShareButtonController.js.map +1 -1
- package/dist/client/sharing/useShareDialogController.d.ts +0 -1
- package/dist/client/sharing/useShareDialogController.d.ts.map +1 -1
- package/dist/client/sharing/useShareDialogController.js +0 -1
- package/dist/client/sharing/useShareDialogController.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +12 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +63 -1
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/transcription/use-live-transcription.d.ts +3 -3
- package/dist/client/transcription/use-live-transcription.d.ts.map +1 -1
- package/dist/client/transcription/use-live-transcription.js +22 -11
- package/dist/client/transcription/use-live-transcription.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +1 -1
- package/dist/deploy/build.js.map +1 -1
- package/dist/guards/db-tool-scoping.js +1 -1
- package/dist/guards/db-tool-scoping.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts +1 -0
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +61 -5
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/index.d.ts +1 -1
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +1 -1
- package/dist/integrations/index.js.map +1 -1
- package/dist/localization/default-messages.d.ts +6 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +7 -1
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp-client/oauth-routes.d.ts +3 -0
- package/dist/mcp-client/oauth-routes.d.ts.map +1 -1
- package/dist/mcp-client/oauth-routes.js +41 -12
- package/dist/mcp-client/oauth-routes.js.map +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.js +1 -18
- package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +49 -6
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +38 -10
- 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/realtime-voice.d.ts.map +1 -1
- package/dist/server/realtime-voice.js +1 -1
- package/dist/server/realtime-voice.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +16 -0
- package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +7 -5
- package/dist/terminal/cli-registry.js +1 -1
- package/dist/terminal/cli-registry.js.map +1 -1
- package/dist/vite/client.d.ts +8 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +113 -2
- package/dist/vite/client.js.map +1 -1
- package/docs/content/a2a-protocol.mdx +15 -0
- package/docs/content/template-chat.mdx +1 -1
- package/docs/content/template-plan.mdx +3 -3
- package/package.json +2 -2
- package/src/a2a/activity.ts +371 -0
- package/src/a2a/client.ts +35 -11
- package/src/a2a/index.ts +21 -0
- package/src/a2a/types.ts +8 -0
- package/src/agent/model-config.ts +19 -23
- package/src/agent/production-agent.ts +167 -100
- package/src/agent/types.ts +16 -1
- package/src/cli/index.ts +18 -10
- package/src/cli/multi-frontier-runs.ts +5 -3
- package/src/cli/templates-meta.ts +0 -12
- package/src/cli/workspace-dev.ts +1 -1
- package/src/client/AgentPanel.tsx +9 -1
- package/src/client/RunStuckBanner.tsx +39 -47
- package/src/client/chat/action-chat-ui-surface.tsx +32 -0
- package/src/client/chat/message-components.tsx +53 -8
- package/src/client/chat/tool-call-display.tsx +214 -44
- package/src/client/chat/widgets/InlineExtensionWidget.tsx +0 -1
- package/src/client/chat/widgets/builtin-tool-renderers.tsx +7 -3
- package/src/client/chat-model-groups.ts +67 -27
- package/src/client/conversation/AgentConversation.tsx +12 -1
- package/src/client/error-capture.ts +2 -6
- package/src/client/resources/McpConnectionSuggestion.tsx +20 -14
- package/src/client/resources/ResourcesPanel.tsx +5 -1
- package/src/client/resources/mcp-integration-catalog.ts +7 -17
- package/src/client/resources/mcp-integration-logos.ts +2 -2
- package/src/client/route-chunk-recovery.ts +5 -3
- package/src/client/session-replay.ts +3 -3
- package/src/client/settings/SettingsPanel.tsx +15 -6
- package/src/client/sharing/ShareButton.tsx +1 -27
- package/src/client/sharing/ShareDialog.tsx +0 -16
- package/src/client/sharing/useShareButtonController.ts +0 -7
- package/src/client/sharing/useShareDialogController.ts +0 -2
- package/src/client/sse-event-processor.ts +85 -1
- package/src/client/transcription/use-live-transcription.ts +64 -45
- package/src/deploy/build.ts +2 -1
- package/src/guards/db-tool-scoping.ts +1 -1
- package/src/integrations/adapters/slack.ts +84 -5
- package/src/integrations/index.ts +5 -1
- package/src/localization/default-messages.ts +7 -1
- package/src/mcp-client/oauth-routes.ts +45 -12
- package/src/scripts/agent-engines/list-agent-engines.ts +1 -18
- package/src/scripts/call-agent.ts +49 -6
- package/src/server/agent-chat-plugin.ts +50 -10
- package/src/server/realtime-voice.ts +4 -1
- package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +16 -0
- package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +7 -5
- package/src/terminal/cli-registry.ts +1 -1
- package/src/vite/client.ts +166 -1
- package/corpus/core/src/observability/hosted-model-experiment.ts +0 -118
- package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +0 -115
- package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +0 -177
- package/corpus/templates/crm/.agents/skills/crm/SKILL.md +0 -128
- package/corpus/templates/crm/.agents/skills/customizing-agent-native/SKILL.md +0 -220
- package/corpus/templates/crm/.agents/skills/feature-flags/SKILL.md +0 -169
- package/corpus/templates/crm/.agents/skills/upgrade-agent-native/SKILL.md +0 -100
- package/corpus/templates/crm/.env.example +0 -5
- package/corpus/templates/crm/AGENTS.md +0 -120
- package/corpus/templates/crm/CHANGELOG.md +0 -1
- package/corpus/templates/crm/DEVELOPING.md +0 -66
- package/corpus/templates/crm/README.md +0 -106
- package/corpus/templates/crm/_gitignore +0 -12
- package/corpus/templates/crm/actions/_crm-action-utils.ts +0 -87
- package/corpus/templates/crm/actions/_crm-dashboard.ts +0 -69
- package/corpus/templates/crm/actions/_crm-data-program-actions.ts +0 -15
- package/corpus/templates/crm/actions/_crm-signal-utils.ts +0 -79
- package/corpus/templates/crm/actions/apply-crm-proposals.ts +0 -203
- package/corpus/templates/crm/actions/attach-call-evidence.ts +0 -170
- package/corpus/templates/crm/actions/configure-crm-connection.ts +0 -126
- package/corpus/templates/crm/actions/configure-native-crm.ts +0 -44
- package/corpus/templates/crm/actions/create-crm-record.ts +0 -148
- package/corpus/templates/crm/actions/create-crm-signal-tracker.ts +0 -58
- package/corpus/templates/crm/actions/delete-staged-dataset.ts +0 -14
- package/corpus/templates/crm/actions/get-crm-automation-recipe.ts +0 -36
- package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +0 -35
- package/corpus/templates/crm/actions/get-crm-dashboard.ts +0 -14
- package/corpus/templates/crm/actions/get-crm-overview.ts +0 -13
- package/corpus/templates/crm/actions/get-crm-pipeline-data.ts +0 -61
- package/corpus/templates/crm/actions/get-crm-record.ts +0 -75
- package/corpus/templates/crm/actions/install-crm-pipeline-dashboard.ts +0 -81
- package/corpus/templates/crm/actions/list-crm-dashboard-revisions.ts +0 -15
- package/corpus/templates/crm/actions/list-crm-dashboards.ts +0 -15
- package/corpus/templates/crm/actions/list-crm-proposals.ts +0 -31
- package/corpus/templates/crm/actions/list-crm-records.ts +0 -79
- package/corpus/templates/crm/actions/list-crm-saved-views.ts +0 -15
- package/corpus/templates/crm/actions/list-crm-signal-hits.ts +0 -43
- package/corpus/templates/crm/actions/list-crm-signal-trackers.ts +0 -32
- package/corpus/templates/crm/actions/list-crm-tasks.ts +0 -22
- package/corpus/templates/crm/actions/list-staged-datasets.ts +0 -14
- package/corpus/templates/crm/actions/list-workspace-connections.ts +0 -47
- package/corpus/templates/crm/actions/manage-crm-signal-tracker.ts +0 -87
- package/corpus/templates/crm/actions/manage-crm-task.ts +0 -132
- package/corpus/templates/crm/actions/navigate.ts +0 -63
- package/corpus/templates/crm/actions/provider-api-catalog.ts +0 -22
- package/corpus/templates/crm/actions/provider-api-docs.ts +0 -54
- package/corpus/templates/crm/actions/provider-api-request.ts +0 -92
- package/corpus/templates/crm/actions/query-staged-dataset.ts +0 -44
- package/corpus/templates/crm/actions/record-crm-call-insight.ts +0 -160
- package/corpus/templates/crm/actions/record-crm-smart-signal.ts +0 -150
- package/corpus/templates/crm/actions/restore-crm-dashboard-revision.ts +0 -23
- package/corpus/templates/crm/actions/review-crm-signal.ts +0 -31
- package/corpus/templates/crm/actions/run-crm-saved-view-program.ts +0 -103
- package/corpus/templates/crm/actions/run-crm-signal-trackers.ts +0 -275
- package/corpus/templates/crm/actions/run.ts +0 -7
- package/corpus/templates/crm/actions/save-crm-dashboard.ts +0 -51
- package/corpus/templates/crm/actions/save-crm-saved-view.ts +0 -119
- package/corpus/templates/crm/actions/sync-crm.ts +0 -146
- package/corpus/templates/crm/actions/update-crm-record.ts +0 -510
- package/corpus/templates/crm/actions/view-screen.ts +0 -218
- package/corpus/templates/crm/agent-native.app-skill.json +0 -58
- package/corpus/templates/crm/app/components/crm/CreateCrmRecordDialog.tsx +0 -158
- package/corpus/templates/crm/app/components/crm/CrmDashboardPanel.tsx +0 -78
- package/corpus/templates/crm/app/components/crm/CrmSignalsPanel.tsx +0 -226
- package/corpus/templates/crm/app/components/crm/IntelligenceSettings.tsx +0 -414
- package/corpus/templates/crm/app/components/crm/RecordActions.tsx +0 -510
- package/corpus/templates/crm/app/components/crm/RecordGrid.tsx +0 -134
- package/corpus/templates/crm/app/components/crm/RecordWorkspace.tsx +0 -362
- package/corpus/templates/crm/app/components/crm/SavedViewDataProgram.tsx +0 -93
- package/corpus/templates/crm/app/components/crm/Surface.tsx +0 -97
- package/corpus/templates/crm/app/components/crm/WorkOverview.tsx +0 -180
- package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +0 -112
- package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +0 -84
- package/corpus/templates/crm/app/components/ui/alert-dialog.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/badge.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/button.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/card.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/dialog.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/input.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/label.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/select.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/sheet.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/skeleton.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/switch.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/table.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/tabs.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/textarea.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/toolkit-provider.tsx +0 -17
- package/corpus/templates/crm/app/design-system.ts +0 -3
- package/corpus/templates/crm/app/entry.client.tsx +0 -16
- package/corpus/templates/crm/app/entry.server.tsx +0 -10
- package/corpus/templates/crm/app/global.css +0 -167
- package/corpus/templates/crm/app/hooks/use-navigation-state.ts +0 -60
- package/corpus/templates/crm/app/i18n/en-US.ts +0 -89
- package/corpus/templates/crm/app/i18n/index.ts +0 -34
- package/corpus/templates/crm/app/lib/dashboard.ts +0 -13
- package/corpus/templates/crm/app/lib/navigation.ts +0 -54
- package/corpus/templates/crm/app/lib/tab-id.ts +0 -1
- package/corpus/templates/crm/app/lib/types.ts +0 -172
- package/corpus/templates/crm/app/lib/utils.ts +0 -1
- package/corpus/templates/crm/app/root.tsx +0 -91
- package/corpus/templates/crm/app/routes/_index.tsx +0 -26
- package/corpus/templates/crm/app/routes/accounts.tsx +0 -41
- package/corpus/templates/crm/app/routes/agent.tsx +0 -5
- package/corpus/templates/crm/app/routes/ask.tsx +0 -53
- package/corpus/templates/crm/app/routes/dashboard.tsx +0 -118
- package/corpus/templates/crm/app/routes/opportunities.tsx +0 -41
- package/corpus/templates/crm/app/routes/people.tsx +0 -41
- package/corpus/templates/crm/app/routes/proposals.tsx +0 -266
- package/corpus/templates/crm/app/routes/records.$recordId.tsx +0 -35
- package/corpus/templates/crm/app/routes/settings.tsx +0 -63
- package/corpus/templates/crm/app/routes/setup.tsx +0 -308
- package/corpus/templates/crm/app/routes/tasks.tsx +0 -252
- package/corpus/templates/crm/app/routes/views.tsx +0 -333
- package/corpus/templates/crm/app/routes.ts +0 -17
- package/corpus/templates/crm/app/vite-env.d.ts +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-agent-native-crm.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-clips-call-evidence-review-recipe.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-find-and-review-evidence-grounded-call-signals-w.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-manage-keyword-and-smart-call-signal-trackers-fr.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-delegated-local-crm-automation.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-native-sql.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboard.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboards-now-install-correctly-from-the-crm-actio.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-salesforce-connection.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-22-crm-field-validation-now-explains-which-fields-cannot-be-edi.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-22-fixed-hubspot-contact-syncs-missing-records-updated-after-th.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-22-fixed-pipeline-dashboard-panels-so-their-opportunity-data-lo.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +0 -6
- package/corpus/templates/crm/components.json +0 -20
- package/corpus/templates/crm/docs/architecture/crm-contract.md +0 -180
- package/corpus/templates/crm/learnings.defaults.md +0 -5
- package/corpus/templates/crm/package.json +0 -59
- package/corpus/templates/crm/public/favicon.svg +0 -1
- package/corpus/templates/crm/public/icon-180.svg +0 -1
- package/corpus/templates/crm/public/manifest.json +0 -11
- package/corpus/templates/crm/react-router.config.ts +0 -7
- package/corpus/templates/crm/server/crm/adapter.ts +0 -32
- package/corpus/templates/crm/server/crm/crm-field-firewall.ts +0 -64
- package/corpus/templates/crm/server/crm/crm-mirror.ts +0 -711
- package/corpus/templates/crm/server/crm/hubspot-adapter.ts +0 -1146
- package/corpus/templates/crm/server/crm/native-adapter.ts +0 -1715
- package/corpus/templates/crm/server/crm/read-through.ts +0 -207
- package/corpus/templates/crm/server/crm/salesforce-adapter.ts +0 -1255
- package/corpus/templates/crm/server/db/crm-store.ts +0 -1170
- package/corpus/templates/crm/server/db/index.ts +0 -169
- package/corpus/templates/crm/server/db/schema.ts +0 -441
- package/corpus/templates/crm/server/lib/intelligence/default-detectors.ts +0 -65
- package/corpus/templates/crm/server/lib/intelligence/evidence.ts +0 -105
- package/corpus/templates/crm/server/lib/intelligence/keyword-detector.ts +0 -100
- package/corpus/templates/crm/server/lib/intelligence/smart-detector.ts +0 -144
- package/corpus/templates/crm/server/lib/intelligence/summary.ts +0 -141
- package/corpus/templates/crm/server/lib/provider-api.ts +0 -64
- package/corpus/templates/crm/server/middleware/auth.ts +0 -4
- package/corpus/templates/crm/server/plugins/agent-chat.ts +0 -68
- package/corpus/templates/crm/server/plugins/auth.ts +0 -14
- package/corpus/templates/crm/server/plugins/core-routes.ts +0 -17
- package/corpus/templates/crm/server/plugins/db.ts +0 -454
- package/corpus/templates/crm/server/routes/[...page].get.ts +0 -5
- package/corpus/templates/crm/shared/crm-automation-recipes.ts +0 -132
- package/corpus/templates/crm/shared/crm-contract.ts +0 -254
- package/corpus/templates/crm/shared/crm-sales-config.ts +0 -63
- package/corpus/templates/crm/ssr-entry.ts +0 -11
- package/corpus/templates/crm/tsconfig.json +0 -24
- package/corpus/templates/crm/vite.config.ts +0 -15
- package/corpus/templates/crm/vitest.config.ts +0 -5
- 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
- package/src/observability/hosted-model-experiment.ts +0 -118
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* stop when the user hits stop. The accumulated transcript is available
|
|
7
7
|
* immediately — no round-trip to Whisper needed.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* Builder can transcribe the original recording afterward if native capture
|
|
10
|
+
* produces no text, but this gives users something useful from second zero
|
|
11
|
+
* without a cloud transcription request.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
@@ -58,12 +58,21 @@ export function useLiveTranscription(
|
|
|
58
58
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
59
59
|
const recognitionRef = useRef<any>(null);
|
|
60
60
|
const transcriptRef = useRef("");
|
|
61
|
+
const interimRef = useRef("");
|
|
61
62
|
const stoppedManuallyRef = useRef(false);
|
|
62
63
|
const stopWaiterRef = useRef<((text: string) => void) | null>(null);
|
|
63
64
|
const restartTimerRef = useRef<number | null>(null);
|
|
64
65
|
const networkErrorCountRef = useRef(0);
|
|
65
66
|
const restartDelayRef = useRef(0);
|
|
66
67
|
|
|
68
|
+
const currentTranscript = useCallback(
|
|
69
|
+
() =>
|
|
70
|
+
[transcriptRef.current.trim(), interimRef.current.trim()]
|
|
71
|
+
.filter(Boolean)
|
|
72
|
+
.join(" "),
|
|
73
|
+
[],
|
|
74
|
+
);
|
|
75
|
+
|
|
67
76
|
const supported = !!getSpeechRecognitionCtor();
|
|
68
77
|
|
|
69
78
|
const start = useCallback(() => {
|
|
@@ -89,6 +98,7 @@ export function useLiveTranscription(
|
|
|
89
98
|
recognition.lang = lang;
|
|
90
99
|
recognitionRef.current = recognition;
|
|
91
100
|
transcriptRef.current = "";
|
|
101
|
+
interimRef.current = "";
|
|
92
102
|
stoppedManuallyRef.current = false;
|
|
93
103
|
networkErrorCountRef.current = 0;
|
|
94
104
|
restartDelayRef.current = 0;
|
|
@@ -107,6 +117,7 @@ export function useLiveTranscription(
|
|
|
107
117
|
interim += text;
|
|
108
118
|
}
|
|
109
119
|
}
|
|
120
|
+
interimRef.current = interim;
|
|
110
121
|
setInterimText(interim);
|
|
111
122
|
if (event.results.length > 0) {
|
|
112
123
|
networkErrorCountRef.current = 0;
|
|
@@ -167,7 +178,7 @@ export function useLiveTranscription(
|
|
|
167
178
|
}
|
|
168
179
|
setIsActive(false);
|
|
169
180
|
if (stopWaiterRef.current) {
|
|
170
|
-
stopWaiterRef.current(
|
|
181
|
+
stopWaiterRef.current(currentTranscript());
|
|
171
182
|
}
|
|
172
183
|
};
|
|
173
184
|
|
|
@@ -177,14 +188,16 @@ export function useLiveTranscription(
|
|
|
177
188
|
} catch {
|
|
178
189
|
/* browser may block without user gesture */
|
|
179
190
|
}
|
|
180
|
-
}, [lang]);
|
|
191
|
+
}, [currentTranscript, lang]);
|
|
181
192
|
|
|
182
193
|
const stop = useCallback((): string => {
|
|
194
|
+
const text = currentTranscript();
|
|
183
195
|
stoppedManuallyRef.current = true;
|
|
184
196
|
if (restartTimerRef.current !== null) {
|
|
185
197
|
window.clearTimeout(restartTimerRef.current);
|
|
186
198
|
restartTimerRef.current = null;
|
|
187
199
|
}
|
|
200
|
+
interimRef.current = "";
|
|
188
201
|
setInterimText("");
|
|
189
202
|
if (recognitionRef.current) {
|
|
190
203
|
try {
|
|
@@ -195,51 +208,57 @@ export function useLiveTranscription(
|
|
|
195
208
|
recognitionRef.current = null;
|
|
196
209
|
}
|
|
197
210
|
setIsActive(false);
|
|
198
|
-
return
|
|
199
|
-
}, []);
|
|
211
|
+
return text;
|
|
212
|
+
}, [currentTranscript]);
|
|
200
213
|
|
|
201
|
-
const stopAndWait = useCallback(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const recognition = recognitionRef.current;
|
|
210
|
-
if (!recognition) {
|
|
211
|
-
setIsActive(false);
|
|
212
|
-
return Promise.resolve(transcriptRef.current);
|
|
213
|
-
}
|
|
214
|
+
const stopAndWait = useCallback(
|
|
215
|
+
(timeoutMs = 1200): Promise<string> => {
|
|
216
|
+
stoppedManuallyRef.current = true;
|
|
217
|
+
if (restartTimerRef.current !== null) {
|
|
218
|
+
window.clearTimeout(restartTimerRef.current);
|
|
219
|
+
restartTimerRef.current = null;
|
|
220
|
+
}
|
|
221
|
+
setInterimText("");
|
|
214
222
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
settled = true;
|
|
220
|
-
window.clearTimeout(timeout);
|
|
221
|
-
if (stopWaiterRef.current === finish) {
|
|
222
|
-
stopWaiterRef.current = null;
|
|
223
|
-
}
|
|
224
|
-
if (recognitionRef.current === recognition) {
|
|
225
|
-
recognitionRef.current = null;
|
|
226
|
-
}
|
|
223
|
+
const recognition = recognitionRef.current;
|
|
224
|
+
if (!recognition) {
|
|
225
|
+
const text = currentTranscript();
|
|
226
|
+
interimRef.current = "";
|
|
227
227
|
setIsActive(false);
|
|
228
|
-
resolve(text);
|
|
229
|
-
}
|
|
228
|
+
return Promise.resolve(text);
|
|
229
|
+
}
|
|
230
230
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
231
|
+
return new Promise((resolve) => {
|
|
232
|
+
let settled = false;
|
|
233
|
+
const finish = (text: string) => {
|
|
234
|
+
if (settled) return;
|
|
235
|
+
settled = true;
|
|
236
|
+
window.clearTimeout(timeout);
|
|
237
|
+
if (stopWaiterRef.current === finish) {
|
|
238
|
+
stopWaiterRef.current = null;
|
|
239
|
+
}
|
|
240
|
+
if (recognitionRef.current === recognition) {
|
|
241
|
+
recognitionRef.current = null;
|
|
242
|
+
}
|
|
243
|
+
interimRef.current = "";
|
|
244
|
+
setIsActive(false);
|
|
245
|
+
resolve(text);
|
|
246
|
+
};
|
|
234
247
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
248
|
+
const timeout = window.setTimeout(() => {
|
|
249
|
+
finish(currentTranscript());
|
|
250
|
+
}, timeoutMs);
|
|
251
|
+
|
|
252
|
+
stopWaiterRef.current = finish;
|
|
253
|
+
try {
|
|
254
|
+
recognition.stop();
|
|
255
|
+
} catch {
|
|
256
|
+
finish(currentTranscript());
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
},
|
|
260
|
+
[currentTranscript],
|
|
261
|
+
);
|
|
243
262
|
|
|
244
263
|
const pause = useCallback(() => {
|
|
245
264
|
if (!recognitionRef.current) return;
|
package/src/deploy/build.ts
CHANGED
|
@@ -1805,7 +1805,8 @@ async function buildCloudflarePages() {
|
|
|
1805
1805
|
// fails: context-xray token counts fall back to char/4 estimates and the
|
|
1806
1806
|
// OG image route falls back to SVG.
|
|
1807
1807
|
const heavyClientExternals = CLOUDFLARE_WORKER_ESBUILD_EXTERNALS.filter(
|
|
1808
|
-
(p) =>
|
|
1808
|
+
(p) =>
|
|
1809
|
+
!Object.prototype.hasOwnProperty.call(CLOUDFLARE_WORKER_STUB_MODULES, p),
|
|
1809
1810
|
).map((p) => `--external:${p}`);
|
|
1810
1811
|
|
|
1811
1812
|
execFileSync(
|
|
@@ -103,7 +103,7 @@ export function scanDbToolScoping(options: DbToolScopingOptions): GuardResult {
|
|
|
103
103
|
const tables = extractTableCalls(contents);
|
|
104
104
|
for (const table of tables) {
|
|
105
105
|
if (hasRawDbScope(table.body)) continue;
|
|
106
|
-
if (Object.
|
|
106
|
+
if (Object.prototype.hasOwnProperty.call(denylist, table.sqlName)) {
|
|
107
107
|
seenAllowed.add(table.sqlName);
|
|
108
108
|
continue;
|
|
109
109
|
}
|
|
@@ -45,6 +45,17 @@ const SLACK_IDENTITY_CACHE_TTL_MS = 10 * 60 * 1_000;
|
|
|
45
45
|
// API blip must not fail-close a sender's identity (and DMs) for 10 minutes.
|
|
46
46
|
const SLACK_IDENTITY_NEGATIVE_CACHE_TTL_MS = 30 * 1_000;
|
|
47
47
|
const SLACK_IDENTITY_CACHE_MAX_ENTRIES = 1_000;
|
|
48
|
+
const SLACK_TOKEN_IDENTITY_CACHE_TTL_MS = 10 * 60 * 1_000;
|
|
49
|
+
const SLACK_TOKEN_IDENTITY_NEGATIVE_CACHE_TTL_MS = 30 * 1_000;
|
|
50
|
+
|
|
51
|
+
type SlackTokenIdentity = {
|
|
52
|
+
teamId: string | null;
|
|
53
|
+
appId: string | null;
|
|
54
|
+
valid: boolean;
|
|
55
|
+
expiresAt: number;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const slackTokenIdentityCache = new Map<string, SlackTokenIdentity>();
|
|
48
59
|
|
|
49
60
|
interface SlackUserIdentity {
|
|
50
61
|
email: string | null;
|
|
@@ -116,8 +127,7 @@ export function slackAdapter(
|
|
|
116
127
|
): PlatformAdapter {
|
|
117
128
|
const resolveBotToken = async (incoming: IncomingMessage) =>
|
|
118
129
|
(await options.resolveBotToken?.(incoming)) ??
|
|
119
|
-
(await
|
|
120
|
-
(await resolveSecret("SLACK_BOT_TOKEN")) ??
|
|
130
|
+
(await resolveSlackBotTokenForIncoming(incoming)) ??
|
|
121
131
|
undefined;
|
|
122
132
|
|
|
123
133
|
return {
|
|
@@ -713,6 +723,19 @@ function parseAllowlistEnv(name: string): Set<string> | null {
|
|
|
713
723
|
return new Set(values);
|
|
714
724
|
}
|
|
715
725
|
|
|
726
|
+
export async function resolveSlackBotTokenForIncoming(
|
|
727
|
+
incoming: IncomingMessage,
|
|
728
|
+
): Promise<string | undefined> {
|
|
729
|
+
const managedToken = await resolveManagedSlackBotToken(incoming);
|
|
730
|
+
if (managedToken) return managedToken;
|
|
731
|
+
|
|
732
|
+
const legacyToken = await resolveSecret("SLACK_BOT_TOKEN");
|
|
733
|
+
if (!legacyToken) return undefined;
|
|
734
|
+
return (await isSlackTokenForIncoming(legacyToken, incoming))
|
|
735
|
+
? legacyToken
|
|
736
|
+
: undefined;
|
|
737
|
+
}
|
|
738
|
+
|
|
716
739
|
async function resolveManagedSlackBotToken(
|
|
717
740
|
incoming: IncomingMessage,
|
|
718
741
|
): Promise<string | undefined> {
|
|
@@ -736,13 +759,13 @@ async function resolveManagedSlackBotToken(
|
|
|
736
759
|
slackInstallationKey({ teamId, enterpriseId, apiAppId }),
|
|
737
760
|
)
|
|
738
761
|
: null;
|
|
739
|
-
if (!installation && teamId) {
|
|
762
|
+
if (!installation && !apiAppId && teamId) {
|
|
740
763
|
installation = await getActiveIntegrationInstallationForTenant(
|
|
741
764
|
"slack",
|
|
742
765
|
teamId,
|
|
743
766
|
);
|
|
744
767
|
}
|
|
745
|
-
if (!installation && enterpriseId) {
|
|
768
|
+
if (!installation && !apiAppId && enterpriseId) {
|
|
746
769
|
installation = await getActiveIntegrationInstallationForTenant(
|
|
747
770
|
"slack",
|
|
748
771
|
enterpriseId,
|
|
@@ -757,6 +780,62 @@ async function resolveManagedSlackBotToken(
|
|
|
757
780
|
}
|
|
758
781
|
}
|
|
759
782
|
|
|
783
|
+
async function isSlackTokenForIncoming(
|
|
784
|
+
token: string,
|
|
785
|
+
incoming: IncomingMessage,
|
|
786
|
+
): Promise<boolean> {
|
|
787
|
+
const teamId = slackIdentityValue(incoming.platformContext.teamId);
|
|
788
|
+
const apiAppId = slackIdentityValue(incoming.platformContext.apiAppId);
|
|
789
|
+
if (!teamId && !apiAppId) return true;
|
|
790
|
+
|
|
791
|
+
const cached = slackTokenIdentityCache.get(token);
|
|
792
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
793
|
+
return (
|
|
794
|
+
cached.valid &&
|
|
795
|
+
(!teamId || cached.teamId === teamId) &&
|
|
796
|
+
(!apiAppId || cached.appId === apiAppId)
|
|
797
|
+
);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
const auth = await slackJson(token, "auth.test", {});
|
|
801
|
+
const authTeamId = slackIdentityValue(auth?.team_id);
|
|
802
|
+
const botId = slackIdentityValue(auth?.bot_id);
|
|
803
|
+
let appId: string | null = null;
|
|
804
|
+
let valid = !!auth;
|
|
805
|
+
|
|
806
|
+
if (valid && apiAppId) {
|
|
807
|
+
const bot = botId
|
|
808
|
+
? await slackJson(token, "bots.info", { bot: botId })
|
|
809
|
+
: null;
|
|
810
|
+
appId = slackIdentityValue(bot?.bot?.app_id);
|
|
811
|
+
valid = !!appId;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
const identity: SlackTokenIdentity = {
|
|
815
|
+
teamId: authTeamId,
|
|
816
|
+
appId,
|
|
817
|
+
valid,
|
|
818
|
+
expiresAt:
|
|
819
|
+
Date.now() +
|
|
820
|
+
(valid
|
|
821
|
+
? SLACK_TOKEN_IDENTITY_CACHE_TTL_MS
|
|
822
|
+
: SLACK_TOKEN_IDENTITY_NEGATIVE_CACHE_TTL_MS),
|
|
823
|
+
};
|
|
824
|
+
slackTokenIdentityCache.set(token, identity);
|
|
825
|
+
|
|
826
|
+
return (
|
|
827
|
+
valid &&
|
|
828
|
+
(!teamId || identity.teamId === teamId) &&
|
|
829
|
+
(!apiAppId || identity.appId === apiAppId)
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
function slackIdentityValue(value: unknown): string | null {
|
|
834
|
+
if (typeof value !== "string") return null;
|
|
835
|
+
const normalized = value.trim();
|
|
836
|
+
return normalized && normalized !== "unknown" ? normalized : null;
|
|
837
|
+
}
|
|
838
|
+
|
|
760
839
|
let _missingAllowlistWarned = false;
|
|
761
840
|
|
|
762
841
|
/**
|
|
@@ -1079,7 +1158,7 @@ async function resolveSlackThreadPermalink(
|
|
|
1079
1158
|
if (typeof channelId !== "string" || typeof threadTs !== "string") {
|
|
1080
1159
|
return undefined;
|
|
1081
1160
|
}
|
|
1082
|
-
const token = resolvedToken
|
|
1161
|
+
const token = resolvedToken;
|
|
1083
1162
|
if (!token) return undefined;
|
|
1084
1163
|
|
|
1085
1164
|
try {
|
|
@@ -114,7 +114,11 @@ export type {
|
|
|
114
114
|
} from "./remote-types.js";
|
|
115
115
|
|
|
116
116
|
// Adapters
|
|
117
|
-
export {
|
|
117
|
+
export {
|
|
118
|
+
resolveSlackBotTokenForIncoming,
|
|
119
|
+
slackAdapter,
|
|
120
|
+
type SlackAdapterOptions,
|
|
121
|
+
} from "./adapters/slack.js";
|
|
118
122
|
export { telegramAdapter } from "./adapters/telegram.js";
|
|
119
123
|
export { whatsappAdapter } from "./adapters/whatsapp.js";
|
|
120
124
|
export { discordAdapter } from "./adapters/discord.js";
|
|
@@ -337,6 +337,12 @@ const messages = {
|
|
|
337
337
|
configureProviderKeys: "Configure Anthropic, OpenAI, or another provider",
|
|
338
338
|
checkingAiConnection: "Checking AI connection...",
|
|
339
339
|
connectionUnavailable: "Unable to check AI connection. Click to retry.",
|
|
340
|
+
delegatedAgent: {
|
|
341
|
+
asking: "Asking {{name}}...",
|
|
342
|
+
asked: "Asked {{name}}",
|
|
343
|
+
error: "Error asking {{name}}",
|
|
344
|
+
elapsed: "{{duration}} elapsed",
|
|
345
|
+
},
|
|
340
346
|
voiceMode: {
|
|
341
347
|
entryButtonLabel: "Use microphone",
|
|
342
348
|
promptTitle: "Use your voice",
|
|
@@ -806,7 +812,7 @@ const messages = {
|
|
|
806
812
|
connected: "Connected",
|
|
807
813
|
configure: "Configure",
|
|
808
814
|
connect: "Connect",
|
|
809
|
-
connectWithOAuth: "Connect
|
|
815
|
+
connectWithOAuth: "Connect",
|
|
810
816
|
useApiToken: "Use API token",
|
|
811
817
|
connectSuggestion: "Connect {{name}} to use it in chat",
|
|
812
818
|
connectSuggestionWithApiToken:
|
|
@@ -4,10 +4,11 @@ import type { OAuthClientInformationMixed } from "@modelcontextprotocol/sdk/shar
|
|
|
4
4
|
import {
|
|
5
5
|
deleteCookie,
|
|
6
6
|
defineEventHandler,
|
|
7
|
+
getChunkedCookie,
|
|
7
8
|
getCookie,
|
|
8
9
|
getMethod,
|
|
9
10
|
getQuery,
|
|
10
|
-
|
|
11
|
+
setChunkedCookie,
|
|
11
12
|
setResponseStatus,
|
|
12
13
|
type H3Event,
|
|
13
14
|
} from "h3";
|
|
@@ -32,6 +33,9 @@ import {
|
|
|
32
33
|
|
|
33
34
|
const FLOW_COOKIE = "an_mcp_oauth_flow";
|
|
34
35
|
const FLOW_TTL_SECONDS = 10 * 60;
|
|
36
|
+
const FLOW_COOKIE_CHUNK_SIZE = 2_800;
|
|
37
|
+
const FLOW_COOKIE_MAX_CHUNKS = 8;
|
|
38
|
+
const CHUNKED_COOKIE_PREFIX = "__chunked__";
|
|
35
39
|
|
|
36
40
|
export interface McpOAuthFlow {
|
|
37
41
|
name: string;
|
|
@@ -189,13 +193,7 @@ async function handleMcpOAuthStart(
|
|
|
189
193
|
...(safeReturnUrl ? { returnUrl: safeReturnUrl } : {}),
|
|
190
194
|
expiresAt: Date.now() + FLOW_TTL_SECONDS * 1_000,
|
|
191
195
|
};
|
|
192
|
-
|
|
193
|
-
httpOnly: true,
|
|
194
|
-
secure: redirectUri.startsWith("https://"),
|
|
195
|
-
sameSite: "lax",
|
|
196
|
-
path: "/",
|
|
197
|
-
maxAge: FLOW_TTL_SECONDS,
|
|
198
|
-
});
|
|
196
|
+
setMcpOAuthFlowCookie(event, flow, redirectUri.startsWith("https://"));
|
|
199
197
|
return redirectWithStagedCookies(event, started.authorizationUrl.href);
|
|
200
198
|
} catch {
|
|
201
199
|
setResponseStatus(event, 400);
|
|
@@ -217,8 +215,8 @@ async function handleMcpOAuthCallback(
|
|
|
217
215
|
const code = text(query.code);
|
|
218
216
|
const state = text(query.state);
|
|
219
217
|
const providerError = text(query.error);
|
|
220
|
-
const flow =
|
|
221
|
-
|
|
218
|
+
const flow = readMcpOAuthFlowCookie(event);
|
|
219
|
+
clearMcpOAuthFlowCookies(event);
|
|
222
220
|
if (providerError || !code || !state) {
|
|
223
221
|
setResponseStatus(event, 400);
|
|
224
222
|
return { error: "MCP OAuth authorization was not completed." };
|
|
@@ -275,8 +273,36 @@ async function handleMcpOAuthCallback(
|
|
|
275
273
|
}
|
|
276
274
|
}
|
|
277
275
|
|
|
278
|
-
function
|
|
279
|
-
|
|
276
|
+
export function setMcpOAuthFlowCookie(
|
|
277
|
+
event: H3Event,
|
|
278
|
+
flow: McpOAuthFlow,
|
|
279
|
+
secure: boolean,
|
|
280
|
+
): void {
|
|
281
|
+
const encrypted = encryptSecretValue(JSON.stringify(flow));
|
|
282
|
+
const chunkCount = Math.ceil(encrypted.length / FLOW_COOKIE_CHUNK_SIZE);
|
|
283
|
+
if (chunkCount > FLOW_COOKIE_MAX_CHUNKS) {
|
|
284
|
+
throw new Error("MCP OAuth flow state exceeds the cookie size limit.");
|
|
285
|
+
}
|
|
286
|
+
setChunkedCookie(event, FLOW_COOKIE, encrypted, {
|
|
287
|
+
httpOnly: true,
|
|
288
|
+
secure,
|
|
289
|
+
sameSite: "lax",
|
|
290
|
+
path: "/",
|
|
291
|
+
maxAge: FLOW_TTL_SECONDS,
|
|
292
|
+
chunkMaxLength: FLOW_COOKIE_CHUNK_SIZE,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export function readMcpOAuthFlowCookie(event: H3Event): McpOAuthFlow | null {
|
|
297
|
+
const primaryCookie = getCookie(event, FLOW_COOKIE);
|
|
298
|
+
if (!primaryCookie) return null;
|
|
299
|
+
if (primaryCookie.startsWith(CHUNKED_COOKIE_PREFIX)) {
|
|
300
|
+
const rawCount = primaryCookie.slice(CHUNKED_COOKIE_PREFIX.length);
|
|
301
|
+
if (!/^\d+$/.test(rawCount)) return null;
|
|
302
|
+
const chunkCount = Number(rawCount);
|
|
303
|
+
if (chunkCount < 2 || chunkCount > FLOW_COOKIE_MAX_CHUNKS) return null;
|
|
304
|
+
}
|
|
305
|
+
const encrypted = getChunkedCookie(event, FLOW_COOKIE);
|
|
280
306
|
if (!encrypted) return null;
|
|
281
307
|
try {
|
|
282
308
|
const parsed = JSON.parse(decryptSecretValue(encrypted)) as McpOAuthFlow;
|
|
@@ -286,6 +312,13 @@ function readFlow(event: H3Event): McpOAuthFlow | null {
|
|
|
286
312
|
}
|
|
287
313
|
}
|
|
288
314
|
|
|
315
|
+
export function clearMcpOAuthFlowCookies(event: H3Event): void {
|
|
316
|
+
deleteCookie(event, FLOW_COOKIE, { path: "/" });
|
|
317
|
+
for (let index = 1; index <= FLOW_COOKIE_MAX_CHUNKS; index += 1) {
|
|
318
|
+
deleteCookie(event, `${FLOW_COOKIE}.${index}`, { path: "/" });
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
289
322
|
export function isValidMcpOAuthFlow(
|
|
290
323
|
flow: McpOAuthFlow,
|
|
291
324
|
email: string,
|
|
@@ -15,8 +15,6 @@ import {
|
|
|
15
15
|
normalizeModelForEngine,
|
|
16
16
|
} from "../../agent/engine/index.js";
|
|
17
17
|
import type { ActionTool } from "../../agent/types.js";
|
|
18
|
-
import { resolveHostedDefaultModelExperiment } from "../../observability/hosted-model-experiment.js";
|
|
19
|
-
import { getRequestUserEmail } from "../../server/request-context.js";
|
|
20
18
|
import { getSetting } from "../../settings/index.js";
|
|
21
19
|
|
|
22
20
|
export const tool: ActionTool = {
|
|
@@ -91,15 +89,6 @@ export async function run(args: Record<string, string> = {}): Promise<string> {
|
|
|
91
89
|
currentModelCandidate ?? currentEntry.defaultModel,
|
|
92
90
|
)
|
|
93
91
|
: (currentModelCandidate ?? DEFAULT_MODEL);
|
|
94
|
-
const hostedExperiment = currentEntry
|
|
95
|
-
? resolveHostedDefaultModelExperiment({
|
|
96
|
-
userId: getRequestUserEmail(),
|
|
97
|
-
engineName: currentEntry.name,
|
|
98
|
-
isDefaultModelSelection: currentModelCandidate == null,
|
|
99
|
-
supportedModels: currentEntry.supportedModels,
|
|
100
|
-
})
|
|
101
|
-
: null;
|
|
102
|
-
const effectiveCurrentModel = hostedExperiment?.model ?? currentModel;
|
|
103
92
|
const result = {
|
|
104
93
|
engines: engines.map((e) => ({
|
|
105
94
|
name: e.name,
|
|
@@ -116,13 +105,7 @@ export async function run(args: Record<string, string> = {}): Promise<string> {
|
|
|
116
105
|
? null
|
|
117
106
|
: {
|
|
118
107
|
engine: currentEngineName,
|
|
119
|
-
model:
|
|
120
|
-
...(hostedExperiment
|
|
121
|
-
? {
|
|
122
|
-
modelSelectionSource: "experiment",
|
|
123
|
-
experimentAssignments: [hostedExperiment.assignment],
|
|
124
|
-
}
|
|
125
|
-
: {}),
|
|
108
|
+
model: currentModel,
|
|
126
109
|
},
|
|
127
110
|
};
|
|
128
111
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
|
|
3
|
+
import { parseA2AAgentActivityPart } from "../a2a/activity.js";
|
|
3
4
|
import {
|
|
4
5
|
A2ATaskTimeoutError,
|
|
5
6
|
callAgent,
|
|
@@ -271,8 +272,15 @@ export async function run(
|
|
|
271
272
|
: undefined;
|
|
272
273
|
|
|
273
274
|
if (action) {
|
|
275
|
+
const agentCallId = randomUUID();
|
|
276
|
+
const startedAt = Date.now();
|
|
274
277
|
if (context?.send) {
|
|
275
|
-
context.send({
|
|
278
|
+
context.send({
|
|
279
|
+
type: "agent_call",
|
|
280
|
+
agent: agent.name,
|
|
281
|
+
status: "start",
|
|
282
|
+
agentCallId,
|
|
283
|
+
});
|
|
276
284
|
}
|
|
277
285
|
try {
|
|
278
286
|
const output = await invokeReadOnlyAppAction(
|
|
@@ -281,10 +289,24 @@ export async function run(
|
|
|
281
289
|
input as Record<string, unknown>,
|
|
282
290
|
buildDelegationCorrelation(context, selfAppId, randomUUID()),
|
|
283
291
|
);
|
|
292
|
+
if (context?.send && output) {
|
|
293
|
+
context.send({
|
|
294
|
+
type: "agent_call_text",
|
|
295
|
+
agent: agent.name,
|
|
296
|
+
text: output,
|
|
297
|
+
agentCallId,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
284
300
|
return output;
|
|
285
301
|
} finally {
|
|
286
302
|
if (context?.send) {
|
|
287
|
-
context.send({
|
|
303
|
+
context.send({
|
|
304
|
+
type: "agent_call",
|
|
305
|
+
agent: agent.name,
|
|
306
|
+
status: "done",
|
|
307
|
+
agentCallId,
|
|
308
|
+
durationMs: Date.now() - startedAt,
|
|
309
|
+
});
|
|
288
310
|
}
|
|
289
311
|
}
|
|
290
312
|
}
|
|
@@ -363,6 +385,7 @@ export async function run(
|
|
|
363
385
|
|
|
364
386
|
let responseText = "";
|
|
365
387
|
let lastSentLength = 0;
|
|
388
|
+
const agentCallId = randomUUID();
|
|
366
389
|
const existingContinuationText = taskId
|
|
367
390
|
? null
|
|
368
391
|
: await formatExistingIntegrationContinuationIfRetry(agent, message);
|
|
@@ -372,6 +395,7 @@ export async function run(
|
|
|
372
395
|
type: "agent_call",
|
|
373
396
|
agent: agent.name,
|
|
374
397
|
status: "start",
|
|
398
|
+
agentCallId,
|
|
375
399
|
});
|
|
376
400
|
|
|
377
401
|
const emitNewText = (newText: string) => {
|
|
@@ -380,6 +404,7 @@ export async function run(
|
|
|
380
404
|
type: "agent_call_text",
|
|
381
405
|
agent: agent.name,
|
|
382
406
|
text: newText.slice(lastSentLength),
|
|
407
|
+
agentCallId,
|
|
383
408
|
});
|
|
384
409
|
lastSentLength = newText.length;
|
|
385
410
|
}
|
|
@@ -395,9 +420,10 @@ export async function run(
|
|
|
395
420
|
// time we get to the sync fallback, Lambda is dead and the second fetch
|
|
396
421
|
// errors out as "fetch failed". Async+poll has its own short fetches
|
|
397
422
|
// with their own budgets, so it works reliably across hosts. The
|
|
398
|
-
// trade-off is
|
|
399
|
-
//
|
|
400
|
-
//
|
|
423
|
+
// trade-off is that cross-app activity arrives at the poll cadence rather
|
|
424
|
+
// than token-by-token. Agent Native peers attach their current reasoning,
|
|
425
|
+
// tool status, and response preview to each task checkpoint, and the
|
|
426
|
+
// receiver's full response still surfaces below.
|
|
401
427
|
//
|
|
402
428
|
// That trade-off has a second-order cost: callAgent()'s poll (see
|
|
403
429
|
// A2AClient.sendAndWait in a2a/client.ts) can legitimately run for
|
|
@@ -450,8 +476,22 @@ export async function run(
|
|
|
450
476
|
]);
|
|
451
477
|
const callStartedAt = Date.now();
|
|
452
478
|
let lastProgressEmitAt = callStartedAt;
|
|
479
|
+
let lastActivitySequence = -1;
|
|
453
480
|
const onRemotePollUpdate = (task: Task) => {
|
|
454
481
|
const state = task?.status?.state;
|
|
482
|
+
const parts = task.status?.message?.parts;
|
|
483
|
+
const snapshot = Array.isArray(parts)
|
|
484
|
+
? parts.map(parseA2AAgentActivityPart).find((value) => value !== null)
|
|
485
|
+
: undefined;
|
|
486
|
+
if (snapshot && snapshot.sequence > lastActivitySequence) {
|
|
487
|
+
lastActivitySequence = snapshot.sequence;
|
|
488
|
+
context.send!({
|
|
489
|
+
type: "agent_call_activity",
|
|
490
|
+
agent: agent.name,
|
|
491
|
+
agentCallId,
|
|
492
|
+
snapshot,
|
|
493
|
+
});
|
|
494
|
+
}
|
|
455
495
|
if (!state || !ACTIVELY_WORKING_STATES.has(state)) return;
|
|
456
496
|
const now = Date.now();
|
|
457
497
|
if (now - lastProgressEmitAt < PROGRESS_MIN_INTERVAL_MS) return;
|
|
@@ -462,6 +502,7 @@ export async function run(
|
|
|
462
502
|
agent: agent.name,
|
|
463
503
|
state,
|
|
464
504
|
elapsedSeconds: Math.round((now - callStartedAt) / 1000),
|
|
505
|
+
agentCallId,
|
|
465
506
|
...(detail ? { detail } : {}),
|
|
466
507
|
});
|
|
467
508
|
};
|
|
@@ -549,6 +590,8 @@ export async function run(
|
|
|
549
590
|
type: "agent_call",
|
|
550
591
|
agent: agent.name,
|
|
551
592
|
status: "done",
|
|
593
|
+
agentCallId,
|
|
594
|
+
durationMs: Date.now() - callStartedAt,
|
|
552
595
|
});
|
|
553
596
|
|
|
554
597
|
return responseText || "(empty response)";
|
|
@@ -718,7 +761,7 @@ async function enqueueIntegrationContinuationIfPossible(
|
|
|
718
761
|
const MAX_PROGRESS_DETAIL_CHARS = 200;
|
|
719
762
|
function extractRemoteProgressDetail(task: Task): string | undefined {
|
|
720
763
|
const parts = task.status?.message?.parts;
|
|
721
|
-
if (!parts) return undefined;
|
|
764
|
+
if (!Array.isArray(parts)) return undefined;
|
|
722
765
|
const text = parts
|
|
723
766
|
.filter((p): p is { type: "text"; text: string } => p.type === "text")
|
|
724
767
|
.map((p) => p.text)
|