@agent-native/core 0.95.0 → 0.96.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 +35 -0
- package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +13 -0
- package/corpus/core/docs/content/locales/de-DE/template-design.mdx +18 -0
- package/corpus/core/docs/content/locales/es-ES/template-design.mdx +16 -0
- package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +17 -0
- package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +16 -0
- package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +17 -0
- package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +15 -0
- package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +16 -0
- package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +11 -0
- package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +12 -0
- package/corpus/core/docs/content/template-design.mdx +16 -0
- package/corpus/core/package.json +4 -2
- package/corpus/core/src/a2a/client.ts +11 -1
- package/corpus/core/src/agent/production-agent.ts +107 -27
- package/corpus/core/src/agent/thread-data-builder.ts +48 -22
- package/corpus/core/src/chat-threads/store.ts +20 -1
- package/corpus/core/src/cli/code-agent-executor.ts +1 -0
- package/corpus/core/src/cli/code-agent-runs.ts +14 -0
- package/corpus/core/src/client/AgentPanel.tsx +32 -25
- package/corpus/core/src/client/AssistantChat.tsx +286 -45
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +141 -90
- package/corpus/core/src/client/chat/ChatHistoryList.tsx +404 -0
- package/corpus/core/src/client/chat/index.ts +6 -0
- package/corpus/core/src/client/chat/tool-call-display.tsx +38 -4
- package/corpus/core/src/client/chat/use-reconnect-reader-owner.ts +28 -0
- package/corpus/core/src/client/code-agent-chat-adapter.ts +72 -4
- package/corpus/core/src/client/composer/RealtimeVoiceMode.tsx +52 -11
- package/corpus/core/src/client/composer/TiptapComposer.tsx +157 -20
- package/corpus/core/src/client/composer/VoiceButton.tsx +28 -0
- package/corpus/core/src/client/composer/useRealtimeVoiceMode.tsx +5 -0
- package/corpus/core/src/client/conversation/code-agent-transcript.ts +4 -5
- package/corpus/core/src/client/guided-questions.tsx +11 -2
- package/corpus/core/src/client/index.ts +11 -0
- package/corpus/core/src/client/integrations/IntegrationsPanel.tsx +6 -7
- package/corpus/core/src/client/sse-event-processor.ts +90 -21
- package/corpus/core/src/client/use-chat-threads.ts +10 -1
- package/corpus/core/src/client/voice-provider-status.ts +44 -0
- package/corpus/core/src/code-agents/transcript-normalizer.ts +76 -0
- package/corpus/core/src/connections/catalog.ts +2 -2
- package/corpus/core/src/deploy/build.ts +12 -8
- package/corpus/core/src/integrations/a2a-continuation-processor.ts +35 -5
- package/corpus/core/src/integrations/adapters/slack.ts +74 -21
- package/corpus/core/src/integrations/catalog.ts +2 -2
- package/corpus/core/src/integrations/webhook-handler.ts +14 -0
- package/corpus/core/src/localization/default-messages.ts +6 -0
- package/corpus/core/src/observability/hosted-model-experiment.ts +118 -0
- package/corpus/core/src/observability/routes.ts +17 -0
- package/corpus/core/src/observability/store.ts +4 -1
- package/corpus/core/src/observability/traces.ts +41 -2
- package/corpus/core/src/scripts/agent-engines/list-agent-engines.ts +19 -1
- package/corpus/core/src/scripts/call-agent.ts +53 -3
- package/corpus/core/src/scripts/chat/search-chats.ts +11 -8
- package/corpus/core/src/secrets/register-framework-secrets.ts +1 -1
- package/corpus/core/src/server/agent-chat-plugin.ts +41 -6
- package/corpus/core/src/server/auth.ts +1 -1
- package/corpus/core/src/server/core-routes-plugin.ts +15 -0
- package/corpus/core/src/server/credential-provider.ts +7 -3
- package/corpus/core/src/server/realtime-voice.ts +71 -24
- package/corpus/core/src/server/voice-providers-status.ts +4 -3
- package/corpus/core/src/shared/cache-control.ts +4 -4
- package/corpus/core/src/styles/agent-native.css +1 -0
- package/corpus/core/src/styles/chat-history-list.css +313 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +20 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +8 -4
- package/corpus/core/src/vite/client.ts +1 -0
- package/corpus/templates/analytics/AGENTS.md +7 -0
- package/corpus/templates/analytics/actions/bigquery.ts +26 -2
- package/corpus/templates/analytics/actions/data-source-status.ts +18 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +5 -4
- package/corpus/templates/analytics/app/global.css +10 -0
- package/corpus/templates/analytics/app/lib/data-sources.ts +5 -4
- package/corpus/templates/analytics/app/pages/Ask.tsx +25 -2
- package/corpus/templates/analytics/changelog/2026-07-10-analytics-answers-simple-time-bounded-metrics-without-unnece.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-analytics-chat-reliably-uses-connected-data-sources-across-s.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-chat-threads-now-stay-clear-of-top-actions-and-fade-smoothly.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-context-chips-can-now-be-selected-and-removed-one-at-a-time-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-slack-token-setup-marked-legacy.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-the-ask-composer-no-longer-carries-dashboard-or-panel-contex.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-the-ask-section-stays-highlighted-while-its-chat-history-is-.md +6 -0
- package/corpus/templates/analytics/server/lib/bigquery.ts +90 -14
- package/corpus/templates/analytics/server/lib/credential-keys.ts +6 -2
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +82 -7
- package/corpus/templates/brain/changelog/2026-07-10-slack-backfill-token-marked-legacy.md +6 -0
- package/corpus/templates/brain/server/register-secrets.ts +2 -2
- package/corpus/templates/clips/app/components/library/library-layout.tsx +7 -1
- package/corpus/templates/clips/app/components/library/page-header.tsx +19 -3
- package/corpus/templates/clips/app/routes/_app.library._index.tsx +16 -12
- package/corpus/templates/clips/changelog/2026-07-10-new-recording-appears-once-when-the-library-sidebar-is-open.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-slack-token-fallback-guidance.md +6 -0
- package/corpus/templates/clips/server/register-secrets.ts +1 -1
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +0 -66
- package/corpus/templates/content/app/routes/_app.local-files.tsx +7 -47
- package/corpus/templates/content/changelog/2026-07-10-local-folders-now-wait-for-an-explicit-pull-before-content-r.md +6 -0
- package/corpus/templates/content/package.json +1 -1
- package/corpus/templates/design/actions/generate-design.ts +128 -31
- package/corpus/templates/design/actions/present-design-variants.ts +37 -9
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +9 -3
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +32 -10
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +2 -2
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +9 -1
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +7 -5
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +3 -0
- package/corpus/templates/design/app/global.css +10 -0
- package/corpus/templates/design/app/hooks/use-question-flow.ts +9 -2
- package/corpus/templates/design/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/design/app/i18n-data.ts +21 -11
- package/corpus/templates/design/changelog/2026-07-10-editor-panels-are-easier-to-distinguish-and-design-intake-qu.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-interact-mode-now-stays-on-the-full-canvas-matches-edit-visu.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-new-web-designs-open-at-desktop-size-and-adapt-across-mobile.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-tweaks-now-link-to-full-documentation.md +6 -0
- package/corpus/templates/design/server/plugins/agent-chat.ts +2 -0
- package/corpus/templates/mail/app/i18n/ar-SA.ts +3 -3
- package/corpus/templates/mail/app/i18n/de-DE.ts +3 -3
- package/corpus/templates/mail/app/i18n/en-US.ts +4 -3
- package/corpus/templates/mail/app/i18n/es-ES.ts +3 -3
- package/corpus/templates/mail/app/i18n/fr-FR.ts +3 -3
- package/corpus/templates/mail/app/i18n/hi-IN.ts +3 -3
- package/corpus/templates/mail/app/i18n/ja-JP.ts +3 -3
- package/corpus/templates/mail/app/i18n/ko-KR.ts +3 -3
- package/corpus/templates/mail/app/i18n/pt-BR.ts +3 -3
- package/corpus/templates/mail/app/i18n/zh-CN.ts +3 -3
- package/corpus/templates/mail/app/i18n/zh-TW.ts +3 -3
- package/corpus/templates/mail/changelog/2026-07-10-slack-intake-marked-legacy.md +6 -0
- package/corpus/templates/mail/server/lib/env-config.ts +5 -4
- package/corpus/templates/plan/package.json +1 -1
- package/dist/a2a/client.d.ts +7 -0
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +2 -1
- package/dist/a2a/client.js.map +1 -1
- package/dist/agent/production-agent.d.ts +6 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +83 -26
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +1 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +42 -23
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/chat-threads/store.d.ts +10 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +6 -0
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/code-agent-executor.d.ts.map +1 -1
- package/dist/cli/code-agent-executor.js +1 -0
- package/dist/cli/code-agent-executor.js.map +1 -1
- package/dist/cli/code-agent-runs.d.ts +12 -0
- package/dist/cli/code-agent-runs.d.ts.map +1 -1
- package/dist/cli/code-agent-runs.js +1 -0
- package/dist/cli/code-agent-runs.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +3 -3
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +14 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +207 -32
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +83 -10
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/chat/ChatHistoryList.d.ts +88 -0
- package/dist/client/chat/ChatHistoryList.d.ts.map +1 -0
- package/dist/client/chat/ChatHistoryList.js +83 -0
- package/dist/client/chat/ChatHistoryList.js.map +1 -0
- package/dist/client/chat/index.d.ts +1 -0
- package/dist/client/chat/index.d.ts.map +1 -1
- package/dist/client/chat/index.js +1 -0
- package/dist/client/chat/index.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +13 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +11 -3
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/chat/use-reconnect-reader-owner.d.ts +11 -0
- package/dist/client/chat/use-reconnect-reader-owner.d.ts.map +1 -0
- package/dist/client/chat/use-reconnect-reader-owner.js +21 -0
- package/dist/client/chat/use-reconnect-reader-owner.js.map +1 -0
- package/dist/client/code-agent-chat-adapter.d.ts +17 -1
- package/dist/client/code-agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/code-agent-chat-adapter.js +47 -3
- package/dist/client/code-agent-chat-adapter.js.map +1 -1
- package/dist/client/composer/RealtimeVoiceMode.d.ts +11 -1
- package/dist/client/composer/RealtimeVoiceMode.d.ts.map +1 -1
- package/dist/client/composer/RealtimeVoiceMode.js +5 -3
- package/dist/client/composer/RealtimeVoiceMode.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +25 -2
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +96 -5
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/VoiceButton.d.ts.map +1 -1
- package/dist/client/composer/VoiceButton.js +21 -1
- package/dist/client/composer/VoiceButton.js.map +1 -1
- package/dist/client/composer/useRealtimeVoiceMode.d.ts.map +1 -1
- package/dist/client/composer/useRealtimeVoiceMode.js +5 -0
- package/dist/client/composer/useRealtimeVoiceMode.js.map +1 -1
- package/dist/client/conversation/code-agent-transcript.d.ts +2 -0
- package/dist/client/conversation/code-agent-transcript.d.ts.map +1 -1
- package/dist/client/conversation/code-agent-transcript.js +3 -5
- package/dist/client/conversation/code-agent-transcript.js.map +1 -1
- package/dist/client/guided-questions.d.ts.map +1 -1
- package/dist/client/guided-questions.js +7 -2
- package/dist/client/guided-questions.js.map +1 -1
- package/dist/client/index.d.ts +3 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js +5 -7
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +67 -20
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +9 -1
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/client/voice-provider-status.d.ts +10 -0
- package/dist/client/voice-provider-status.d.ts.map +1 -0
- package/dist/client/voice-provider-status.js +32 -0
- package/dist/client/voice-provider-status.js.map +1 -0
- package/dist/code-agents/transcript-normalizer.d.ts +29 -0
- package/dist/code-agents/transcript-normalizer.d.ts.map +1 -1
- package/dist/code-agents/transcript-normalizer.js +55 -0
- package/dist/code-agents/transcript-normalizer.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/connections/catalog.d.ts +2 -2
- package/dist/connections/catalog.js +2 -2
- package/dist/connections/catalog.js.map +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +12 -8
- package/dist/deploy/build.js.map +1 -1
- package/dist/integrations/a2a-continuation-processor.d.ts.map +1 -1
- package/dist/integrations/a2a-continuation-processor.js +25 -5
- package/dist/integrations/a2a-continuation-processor.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +55 -21
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/catalog.js +2 -2
- package/dist/integrations/catalog.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +11 -0
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/localization/default-messages.d.ts +5 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +5 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/observability/hosted-model-experiment.d.ts +39 -0
- package/dist/observability/hosted-model-experiment.d.ts.map +1 -0
- package/dist/observability/hosted-model-experiment.js +90 -0
- package/dist/observability/hosted-model-experiment.js.map +1 -0
- package/dist/observability/routes.d.ts.map +1 -1
- package/dist/observability/routes.js +16 -0
- package/dist/observability/routes.js.map +1 -1
- package/dist/observability/store.d.ts.map +1 -1
- package/dist/observability/store.js +4 -1
- package/dist/observability/store.js.map +1 -1
- package/dist/observability/traces.d.ts +6 -0
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +28 -2
- package/dist/observability/traces.js.map +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.js +19 -1
- 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 +43 -3
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/scripts/chat/search-chats.d.ts +1 -1
- package/dist/scripts/chat/search-chats.d.ts.map +1 -1
- package/dist/scripts/chat/search-chats.js +11 -8
- package/dist/scripts/chat/search-chats.js.map +1 -1
- package/dist/secrets/register-framework-secrets.js +1 -1
- package/dist/secrets/register-framework-secrets.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +11 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +27 -6
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/auth.js +1 -1
- package/dist/server/auth.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts +3 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +13 -0
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +5 -3
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +7 -3
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/realtime-voice.d.ts.map +1 -1
- package/dist/server/realtime-voice.js +55 -21
- package/dist/server/realtime-voice.js.map +1 -1
- package/dist/server/voice-providers-status.d.ts.map +1 -1
- package/dist/server/voice-providers-status.js +2 -3
- package/dist/server/voice-providers-status.js.map +1 -1
- package/dist/shared/cache-control.d.ts +6 -6
- package/dist/shared/cache-control.d.ts.map +1 -1
- package/dist/shared/cache-control.js +3 -3
- package/dist/shared/cache-control.js.map +1 -1
- package/dist/styles/agent-native.css +1 -0
- package/dist/styles/chat-history-list.css +313 -0
- package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +20 -0
- package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +8 -4
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +1 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/locales/ar-SA/template-design.mdx +13 -0
- package/docs/content/locales/de-DE/template-design.mdx +18 -0
- package/docs/content/locales/es-ES/template-design.mdx +16 -0
- package/docs/content/locales/fr-FR/template-design.mdx +17 -0
- package/docs/content/locales/hi-IN/template-design.mdx +16 -0
- package/docs/content/locales/ja-JP/template-design.mdx +17 -0
- package/docs/content/locales/ko-KR/template-design.mdx +15 -0
- package/docs/content/locales/pt-BR/template-design.mdx +16 -0
- package/docs/content/locales/zh-CN/template-design.mdx +11 -0
- package/docs/content/locales/zh-TW/template-design.mdx +12 -0
- package/docs/content/template-design.mdx +16 -0
- package/package.json +4 -2
- package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +20 -0
- package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +8 -4
|
@@ -40,6 +40,11 @@ export interface RealtimeVoiceModeCopy {
|
|
|
40
40
|
entryButtonLabel: string;
|
|
41
41
|
promptTitle: string;
|
|
42
42
|
promptDescription: string;
|
|
43
|
+
setupTitle: string;
|
|
44
|
+
setupDescription: string;
|
|
45
|
+
connectBuilder: string;
|
|
46
|
+
useOpenAiKey: string;
|
|
47
|
+
startWithOpenAiKey: string;
|
|
43
48
|
startVoiceMode: string;
|
|
44
49
|
keepDictating: string;
|
|
45
50
|
showChat: string;
|
|
@@ -63,6 +68,11 @@ export interface RealtimeVoiceModeEntryProps {
|
|
|
63
68
|
onOpenChange?: (open: boolean) => void;
|
|
64
69
|
onStartVoiceMode: () => void;
|
|
65
70
|
onKeepDictating: () => void;
|
|
71
|
+
setupRequired?: boolean;
|
|
72
|
+
openAiConfigured?: boolean;
|
|
73
|
+
connectingBuilder?: boolean;
|
|
74
|
+
onConnectBuilder?: () => void;
|
|
75
|
+
onUseOpenAiKey?: () => void;
|
|
66
76
|
className?: string;
|
|
67
77
|
}
|
|
68
78
|
|
|
@@ -78,6 +88,11 @@ export function RealtimeVoiceModeEntry({
|
|
|
78
88
|
onOpenChange,
|
|
79
89
|
onStartVoiceMode,
|
|
80
90
|
onKeepDictating,
|
|
91
|
+
setupRequired = false,
|
|
92
|
+
openAiConfigured = false,
|
|
93
|
+
connectingBuilder = false,
|
|
94
|
+
onConnectBuilder,
|
|
95
|
+
onUseOpenAiKey,
|
|
81
96
|
className,
|
|
82
97
|
}: RealtimeVoiceModeEntryProps) {
|
|
83
98
|
const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
|
|
@@ -130,17 +145,17 @@ export function RealtimeVoiceModeEntry({
|
|
|
130
145
|
<div className="grid gap-3">
|
|
131
146
|
<div className="grid gap-1">
|
|
132
147
|
<h2 id={titleId} className="text-sm font-semibold text-foreground">
|
|
133
|
-
{copy.promptTitle}
|
|
148
|
+
{setupRequired ? copy.setupTitle : copy.promptTitle}
|
|
134
149
|
</h2>
|
|
135
150
|
<p
|
|
136
151
|
id={descriptionId}
|
|
137
152
|
className="text-sm leading-relaxed text-muted-foreground"
|
|
138
153
|
>
|
|
139
|
-
{copy.promptDescription}
|
|
154
|
+
{setupRequired ? copy.setupDescription : copy.promptDescription}
|
|
140
155
|
</p>
|
|
141
156
|
</div>
|
|
142
157
|
|
|
143
|
-
<div className="flex flex-col-reverse gap-2 sm:flex-row sm:justify-end">
|
|
158
|
+
<div className="flex flex-col-reverse gap-2 sm:flex-row sm:flex-wrap sm:justify-end">
|
|
144
159
|
<Button
|
|
145
160
|
type="button"
|
|
146
161
|
variant="ghost"
|
|
@@ -149,14 +164,40 @@ export function RealtimeVoiceModeEntry({
|
|
|
149
164
|
>
|
|
150
165
|
{copy.keepDictating}
|
|
151
166
|
</Button>
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
167
|
+
{setupRequired ? (
|
|
168
|
+
<>
|
|
169
|
+
<Button
|
|
170
|
+
type="button"
|
|
171
|
+
variant="outline"
|
|
172
|
+
size="sm"
|
|
173
|
+
onClick={() => choose(onUseOpenAiKey ?? onStartVoiceMode)}
|
|
174
|
+
>
|
|
175
|
+
{openAiConfigured
|
|
176
|
+
? copy.startWithOpenAiKey
|
|
177
|
+
: copy.useOpenAiKey}
|
|
178
|
+
</Button>
|
|
179
|
+
<Button
|
|
180
|
+
type="button"
|
|
181
|
+
size="sm"
|
|
182
|
+
disabled={connectingBuilder}
|
|
183
|
+
onClick={() => choose(onConnectBuilder ?? onStartVoiceMode)}
|
|
184
|
+
>
|
|
185
|
+
{connectingBuilder ? (
|
|
186
|
+
<IconLoader2 className="animate-spin" />
|
|
187
|
+
) : null}
|
|
188
|
+
{copy.connectBuilder}
|
|
189
|
+
</Button>
|
|
190
|
+
</>
|
|
191
|
+
) : (
|
|
192
|
+
<Button
|
|
193
|
+
type="button"
|
|
194
|
+
size="sm"
|
|
195
|
+
onClick={() => choose(onStartVoiceMode)}
|
|
196
|
+
>
|
|
197
|
+
<IconMicrophone />
|
|
198
|
+
{copy.startVoiceMode}
|
|
199
|
+
</Button>
|
|
200
|
+
)}
|
|
160
201
|
</div>
|
|
161
202
|
</div>
|
|
162
203
|
</PopoverContent>
|
|
@@ -107,6 +107,38 @@ export function canSubmitComposerContent(options: {
|
|
|
107
107
|
);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
export function resolveComposerPrimaryAction(options: {
|
|
111
|
+
canSubmit: boolean;
|
|
112
|
+
hasStopButton: boolean;
|
|
113
|
+
}): "send" | "stop" {
|
|
114
|
+
return !options.canSubmit && options.hasStopButton ? "stop" : "send";
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export type ContextChipBackspaceAction =
|
|
118
|
+
| { type: "select"; key: string }
|
|
119
|
+
| { type: "remove"; key: string }
|
|
120
|
+
| null;
|
|
121
|
+
|
|
122
|
+
export function resolveContextChipBackspaceAction(options: {
|
|
123
|
+
contextItemKeys: string[];
|
|
124
|
+
selectedKey: string | null;
|
|
125
|
+
cursorAtStart: boolean;
|
|
126
|
+
}): ContextChipBackspaceAction {
|
|
127
|
+
if (!options.cursorAtStart || options.contextItemKeys.length === 0) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
if (
|
|
131
|
+
options.selectedKey &&
|
|
132
|
+
options.contextItemKeys.includes(options.selectedKey)
|
|
133
|
+
) {
|
|
134
|
+
return { type: "remove", key: options.selectedKey };
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
type: "select",
|
|
138
|
+
key: options.contextItemKeys[options.contextItemKeys.length - 1],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
110
142
|
const MAX_DOCUMENT_ATTACHMENT_BYTES = 4 * 1024 * 1024;
|
|
111
143
|
|
|
112
144
|
function composerReferenceFromMentionItem(
|
|
@@ -535,8 +567,13 @@ export interface TiptapComposerProps {
|
|
|
535
567
|
onTextChange?: (text: string) => void;
|
|
536
568
|
/** Custom action button (e.g. stop button) to render instead of the default send button. */
|
|
537
569
|
actionButton?: React.ReactNode;
|
|
538
|
-
/** Extra button to render alongside the
|
|
570
|
+
/** Extra button to render alongside the primary action. */
|
|
539
571
|
extraActionButton?: React.ReactNode;
|
|
572
|
+
/**
|
|
573
|
+
* Stop control shown instead of the disabled send button while the composer
|
|
574
|
+
* has no sendable content. Typing or attaching content restores send.
|
|
575
|
+
*/
|
|
576
|
+
stopButton?: React.ReactNode;
|
|
540
577
|
/** Custom attachment button to render instead of ComposerPrimitive.AddAttachment. */
|
|
541
578
|
attachButton?: React.ReactNode;
|
|
542
579
|
/** Custom host-owned control rendered next to the attachment affordance. */
|
|
@@ -824,6 +861,25 @@ function friendlyModelName(model: string): string {
|
|
|
824
861
|
return model;
|
|
825
862
|
}
|
|
826
863
|
|
|
864
|
+
export function compactComposerModelName(model: string): string {
|
|
865
|
+
const gpt56Variant = model.match(
|
|
866
|
+
/^(?:openai\/)?gpt-5[.-]6[.-](sol|terra|luna)$/i,
|
|
867
|
+
)?.[1];
|
|
868
|
+
if (gpt56Variant) {
|
|
869
|
+
return gpt56Variant[0].toUpperCase() + gpt56Variant.slice(1).toLowerCase();
|
|
870
|
+
}
|
|
871
|
+
return friendlyModelName(model);
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
export function compactComposerReasoningEffortLabel(
|
|
875
|
+
effort: ReasoningEffort,
|
|
876
|
+
): string {
|
|
877
|
+
if (effort === "medium" || effort === "auto") return "Med";
|
|
878
|
+
if (effort === "minimal") return "Min";
|
|
879
|
+
if (effort === "xhigh") return "XHigh";
|
|
880
|
+
return reasoningEffortLabel(effort);
|
|
881
|
+
}
|
|
882
|
+
|
|
827
883
|
/**
|
|
828
884
|
* Deduplicate models to only the latest version per family.
|
|
829
885
|
* e.g. [opus-4-7, opus-4-6, opus-4-5] → [opus-4-7]
|
|
@@ -994,12 +1050,19 @@ function ModelSelector({
|
|
|
994
1050
|
<button
|
|
995
1051
|
type="button"
|
|
996
1052
|
data-agent-composer-slot="model-button"
|
|
1053
|
+
aria-label={`Model: ${friendlyModelName(model)}${
|
|
1054
|
+
effortOptions.length > 0
|
|
1055
|
+
? `. Reasoning: ${reasoningEffortLabel(selectedEffort)}`
|
|
1056
|
+
: ""
|
|
1057
|
+
}`}
|
|
997
1058
|
className="agent-composer-model-button flex min-w-0 max-w-[10.5rem] shrink items-center gap-1 rounded-md px-2 py-1 text-[12px] font-medium text-muted-foreground hover:bg-accent/50 hover:text-foreground"
|
|
998
1059
|
>
|
|
999
|
-
<span className="min-w-0 truncate">
|
|
1060
|
+
<span className="min-w-0 truncate">
|
|
1061
|
+
{compactComposerModelName(model)}
|
|
1062
|
+
</span>
|
|
1000
1063
|
{effortOptions.length > 0 && (
|
|
1001
1064
|
<span className="agent-composer-model-effort min-w-0 shrink truncate text-muted-foreground/70">
|
|
1002
|
-
· {
|
|
1065
|
+
· {compactComposerReasoningEffortLabel(selectedEffort)}
|
|
1003
1066
|
</span>
|
|
1004
1067
|
)}
|
|
1005
1068
|
<IconChevronDown className="h-3 w-3 shrink-0 opacity-60" />
|
|
@@ -1247,6 +1310,7 @@ export function TiptapComposer({
|
|
|
1247
1310
|
onTextChange,
|
|
1248
1311
|
actionButton,
|
|
1249
1312
|
extraActionButton,
|
|
1313
|
+
stopButton,
|
|
1250
1314
|
attachButton,
|
|
1251
1315
|
modeControl,
|
|
1252
1316
|
toolbarSlot,
|
|
@@ -1288,6 +1352,9 @@ export function TiptapComposer({
|
|
|
1288
1352
|
const [slotReferences, setSlotReferences] = useState<
|
|
1289
1353
|
AgentComposerReference[]
|
|
1290
1354
|
>([]);
|
|
1355
|
+
const [selectedContextItemKey, setSelectedContextItemKey] = useState<
|
|
1356
|
+
string | null
|
|
1357
|
+
>(null);
|
|
1291
1358
|
const composerText = useComposer((state) => state.text);
|
|
1292
1359
|
const composerAttachments = useComposer((state) => state.attachments);
|
|
1293
1360
|
const canSend = canSubmitComposerContent({
|
|
@@ -1295,6 +1362,10 @@ export function TiptapComposer({
|
|
|
1295
1362
|
attachmentCount: composerAttachments.length,
|
|
1296
1363
|
disabled,
|
|
1297
1364
|
});
|
|
1365
|
+
const primaryAction = resolveComposerPrimaryAction({
|
|
1366
|
+
canSubmit: canSend,
|
|
1367
|
+
hasStopButton: Boolean(stopButton),
|
|
1368
|
+
});
|
|
1298
1369
|
const hasContextRows = contextItems.length > 0 || slotReferences.length > 0;
|
|
1299
1370
|
const [composerMode, setComposerMode] = useState<ComposerMode | null>(null);
|
|
1300
1371
|
const composerModeRef = useRef<ComposerMode | null>(null);
|
|
@@ -1379,9 +1450,25 @@ export function TiptapComposer({
|
|
|
1379
1450
|
onSlashCommandRef.current = onSlashCommand;
|
|
1380
1451
|
const onTextChangeRef = useRef(onTextChange);
|
|
1381
1452
|
onTextChangeRef.current = onTextChange;
|
|
1453
|
+
const contextItemsRef = useRef(contextItems);
|
|
1454
|
+
contextItemsRef.current = contextItems;
|
|
1455
|
+
const onRemoveContextItemRef = useRef(onRemoveContextItem);
|
|
1456
|
+
onRemoveContextItemRef.current = onRemoveContextItem;
|
|
1457
|
+
const selectedContextItemKeyRef = useRef<string | null>(null);
|
|
1458
|
+
selectedContextItemKeyRef.current = selectedContextItemKey;
|
|
1382
1459
|
const initialTextKeyRef = useRef<string | number | undefined>(undefined);
|
|
1383
1460
|
const seenReferenceInsertIdsRef = useRef<Set<string>>(new Set());
|
|
1384
1461
|
|
|
1462
|
+
useEffect(() => {
|
|
1463
|
+
if (
|
|
1464
|
+
selectedContextItemKey &&
|
|
1465
|
+
!contextItems.some((item) => item.key === selectedContextItemKey)
|
|
1466
|
+
) {
|
|
1467
|
+
selectedContextItemKeyRef.current = null;
|
|
1468
|
+
setSelectedContextItemKey(null);
|
|
1469
|
+
}
|
|
1470
|
+
}, [contextItems, selectedContextItemKey]);
|
|
1471
|
+
|
|
1385
1472
|
const closePopover = useCallback(() => {
|
|
1386
1473
|
setPopover(null);
|
|
1387
1474
|
popoverStateRef.current = null;
|
|
@@ -1449,6 +1536,13 @@ export function TiptapComposer({
|
|
|
1449
1536
|
} catch {}
|
|
1450
1537
|
}, 300);
|
|
1451
1538
|
},
|
|
1539
|
+
onSelectionUpdate: ({ editor: ed }) => {
|
|
1540
|
+
const { from, to } = ed.state.selection;
|
|
1541
|
+
if (selectedContextItemKeyRef.current && (from !== to || from > 1)) {
|
|
1542
|
+
selectedContextItemKeyRef.current = null;
|
|
1543
|
+
setSelectedContextItemKey(null);
|
|
1544
|
+
}
|
|
1545
|
+
},
|
|
1452
1546
|
editorProps: {
|
|
1453
1547
|
attributes: {
|
|
1454
1548
|
"data-agent-composer-variant": layoutVariant,
|
|
@@ -1581,9 +1675,37 @@ export function TiptapComposer({
|
|
|
1581
1675
|
}
|
|
1582
1676
|
}
|
|
1583
1677
|
|
|
1678
|
+
const { from, to } = view.state.selection;
|
|
1679
|
+
const cursorAtStart = from === to && from <= 1;
|
|
1680
|
+
if (event.key === "Backspace" && onRemoveContextItemRef.current) {
|
|
1681
|
+
const chipAction = resolveContextChipBackspaceAction({
|
|
1682
|
+
contextItemKeys: contextItemsRef.current.map((item) => item.key),
|
|
1683
|
+
selectedKey: selectedContextItemKeyRef.current,
|
|
1684
|
+
cursorAtStart,
|
|
1685
|
+
});
|
|
1686
|
+
if (chipAction) {
|
|
1687
|
+
event.preventDefault();
|
|
1688
|
+
if (chipAction.type === "select") {
|
|
1689
|
+
selectedContextItemKeyRef.current = chipAction.key;
|
|
1690
|
+
setSelectedContextItemKey(chipAction.key);
|
|
1691
|
+
} else {
|
|
1692
|
+
selectedContextItemKeyRef.current = null;
|
|
1693
|
+
setSelectedContextItemKey(null);
|
|
1694
|
+
contextItemsRef.current = contextItemsRef.current.filter(
|
|
1695
|
+
(item) => item.key !== chipAction.key,
|
|
1696
|
+
);
|
|
1697
|
+
onRemoveContextItemRef.current?.(chipAction.key);
|
|
1698
|
+
}
|
|
1699
|
+
return true;
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
if (selectedContextItemKeyRef.current) {
|
|
1703
|
+
selectedContextItemKeyRef.current = null;
|
|
1704
|
+
setSelectedContextItemKey(null);
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1584
1707
|
// Backspace removes composer mode chip when editor is empty
|
|
1585
1708
|
if (event.key === "Backspace" && composerModeRef.current) {
|
|
1586
|
-
const { from, to } = view.state.selection;
|
|
1587
1709
|
if (
|
|
1588
1710
|
view.state.doc.textContent.trim() === "" &&
|
|
1589
1711
|
from === to &&
|
|
@@ -2535,13 +2657,24 @@ export function TiptapComposer({
|
|
|
2535
2657
|
{contextItems.map((item) => (
|
|
2536
2658
|
<span
|
|
2537
2659
|
key={item.key}
|
|
2538
|
-
|
|
2660
|
+
data-state={
|
|
2661
|
+
selectedContextItemKey === item.key ? "selected" : undefined
|
|
2662
|
+
}
|
|
2663
|
+
className={`inline-flex max-w-full items-center gap-1.5 rounded-md border px-2 py-1 text-[11px] font-medium text-foreground ${
|
|
2664
|
+
selectedContextItemKey === item.key
|
|
2665
|
+
? "border-ring bg-accent ring-2 ring-ring/40"
|
|
2666
|
+
: "border-border bg-muted/50"
|
|
2667
|
+
}`}
|
|
2539
2668
|
>
|
|
2540
2669
|
<IconClipboardList className="h-3 w-3 shrink-0 text-muted-foreground" />
|
|
2541
2670
|
<span className="min-w-0 truncate">{item.title}</span>
|
|
2542
2671
|
<button
|
|
2543
2672
|
type="button"
|
|
2544
|
-
onClick={() =>
|
|
2673
|
+
onClick={() => {
|
|
2674
|
+
selectedContextItemKeyRef.current = null;
|
|
2675
|
+
setSelectedContextItemKey(null);
|
|
2676
|
+
onRemoveContextItem?.(item.key);
|
|
2677
|
+
}}
|
|
2545
2678
|
aria-label={`Remove ${item.title} context`}
|
|
2546
2679
|
className="ms-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground"
|
|
2547
2680
|
>
|
|
@@ -2607,20 +2740,24 @@ export function TiptapComposer({
|
|
|
2607
2740
|
{voiceEnabled && (
|
|
2608
2741
|
<VoiceButton voice={voice} isMac={isMac} disabled={disabled} />
|
|
2609
2742
|
)}
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2743
|
+
{primaryAction === "stop" ? (
|
|
2744
|
+
stopButton
|
|
2745
|
+
) : (
|
|
2746
|
+
<Tooltip>
|
|
2747
|
+
<TooltipTrigger asChild>
|
|
2748
|
+
<button
|
|
2749
|
+
type="button"
|
|
2750
|
+
onClick={() => void submitComposer("immediate")}
|
|
2751
|
+
disabled={!canSend}
|
|
2752
|
+
data-agent-composer-slot="send-button"
|
|
2753
|
+
className="agent-composer-send-button shrink-0 flex h-7 w-7 items-center justify-center rounded-md bg-primary text-primary-foreground hover:opacity-90 disabled:opacity-30 disabled:cursor-not-allowed"
|
|
2754
|
+
>
|
|
2755
|
+
<IconArrowUp className="h-3.5 w-3.5" />
|
|
2756
|
+
</button>
|
|
2757
|
+
</TooltipTrigger>
|
|
2758
|
+
<TooltipContent>Send message</TooltipContent>
|
|
2759
|
+
</Tooltip>
|
|
2760
|
+
)}
|
|
2624
2761
|
</>
|
|
2625
2762
|
)}
|
|
2626
2763
|
</div>
|
|
@@ -20,6 +20,8 @@ import {
|
|
|
20
20
|
TooltipContent,
|
|
21
21
|
TooltipTrigger,
|
|
22
22
|
} from "../components/ui/tooltip.js";
|
|
23
|
+
import { useBuilderConnectFlow } from "../settings/useBuilderStatus.js";
|
|
24
|
+
import { useVoiceProviderStatus } from "../voice-provider-status.js";
|
|
23
25
|
import { RealtimeVoiceModeEntry } from "./RealtimeVoiceMode.js";
|
|
24
26
|
import {
|
|
25
27
|
useRealtimeVoiceModeCopy,
|
|
@@ -27,6 +29,16 @@ import {
|
|
|
27
29
|
} from "./useRealtimeVoiceMode.js";
|
|
28
30
|
import type { VoiceDictationApi } from "./useVoiceDictation.js";
|
|
29
31
|
|
|
32
|
+
function openOpenAiKeySettings(): void {
|
|
33
|
+
window.location.hash = "#secrets:OPENAI_API_KEY";
|
|
34
|
+
window.dispatchEvent(new Event("agent-panel:open"));
|
|
35
|
+
window.dispatchEvent(
|
|
36
|
+
new CustomEvent("agent-panel:open-settings", {
|
|
37
|
+
detail: { section: "secrets" },
|
|
38
|
+
}),
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
30
42
|
export interface VoiceButtonProps {
|
|
31
43
|
voice: VoiceDictationApi;
|
|
32
44
|
isMac: boolean;
|
|
@@ -37,6 +49,12 @@ export function VoiceButton({ voice, isMac, disabled }: VoiceButtonProps) {
|
|
|
37
49
|
const { state, start, stop, supported } = voice;
|
|
38
50
|
const realtimeVoice = useRealtimeVoiceModeOptional();
|
|
39
51
|
const realtimeCopy = useRealtimeVoiceModeCopy();
|
|
52
|
+
const voiceProviders = useVoiceProviderStatus();
|
|
53
|
+
const builderConnect = useBuilderConnectFlow({
|
|
54
|
+
trackingSource: "realtime_voice",
|
|
55
|
+
trackingFlow: "voice_transcription",
|
|
56
|
+
onConnected: () => voiceProviders.refresh(),
|
|
57
|
+
});
|
|
40
58
|
|
|
41
59
|
if (!supported) return null;
|
|
42
60
|
|
|
@@ -50,6 +68,16 @@ export function VoiceButton({ voice, isMac, disabled }: VoiceButtonProps) {
|
|
|
50
68
|
<RealtimeVoiceModeEntry
|
|
51
69
|
copy={realtimeCopy}
|
|
52
70
|
disabled={disabled}
|
|
71
|
+
setupRequired={
|
|
72
|
+
builderConnect.hasFetchedStatus && !builderConnect.configured
|
|
73
|
+
}
|
|
74
|
+
openAiConfigured={voiceProviders.status?.openai === true}
|
|
75
|
+
connectingBuilder={builderConnect.connecting}
|
|
76
|
+
onConnectBuilder={builderConnect.start}
|
|
77
|
+
onUseOpenAiKey={() => {
|
|
78
|
+
if (voiceProviders.status?.openai) void realtimeVoice.start();
|
|
79
|
+
else openOpenAiKeySettings();
|
|
80
|
+
}}
|
|
53
81
|
onStartVoiceMode={() => void realtimeVoice.start()}
|
|
54
82
|
onKeepDictating={() => void start()}
|
|
55
83
|
/>
|
|
@@ -247,6 +247,11 @@ function voiceCopy(t: ReturnType<typeof useT>): RealtimeVoiceModeCopy {
|
|
|
247
247
|
entryButtonLabel: t("agentPanel.voiceMode.entryButtonLabel"),
|
|
248
248
|
promptTitle: t("agentPanel.voiceMode.promptTitle"),
|
|
249
249
|
promptDescription: t("agentPanel.voiceMode.promptDescription"),
|
|
250
|
+
setupTitle: t("agentPanel.voiceMode.setupTitle"),
|
|
251
|
+
setupDescription: t("agentPanel.voiceMode.setupDescription"),
|
|
252
|
+
connectBuilder: t("agentPanel.voiceMode.connectBuilder"),
|
|
253
|
+
useOpenAiKey: t("agentPanel.voiceMode.useOpenAiKey"),
|
|
254
|
+
startWithOpenAiKey: t("agentPanel.voiceMode.startWithOpenAiKey"),
|
|
250
255
|
startVoiceMode: t("agentPanel.voiceMode.start"),
|
|
251
256
|
keepDictating: t("agentPanel.voiceMode.keepDictating"),
|
|
252
257
|
showChat: t("agentPanel.voiceMode.showChat"),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
isCredentialGapCodeAgentEvent,
|
|
2
3
|
normalizeCodeAgentTranscript,
|
|
3
4
|
type CodeAgentTranscriptEvent as CoreCodeAgentTranscriptEvent,
|
|
4
5
|
type NormalizedCodeAgentStatusEvent,
|
|
@@ -38,6 +39,7 @@ export interface CodeAgentConversationTranscriptEvent {
|
|
|
38
39
|
artifactPath?: string;
|
|
39
40
|
artifactUrl?: string;
|
|
40
41
|
metadata?: Record<string, unknown>;
|
|
42
|
+
signal?: CoreCodeAgentTranscriptEvent["signal"];
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
export interface NormalizeCodeAgentTranscriptOptions {
|
|
@@ -160,6 +162,7 @@ function toCoreTranscriptEvent(
|
|
|
160
162
|
...(event.artifactPath ? { artifactPath: event.artifactPath } : {}),
|
|
161
163
|
...(event.artifactUrl ? { artifactUrl: event.artifactUrl } : {}),
|
|
162
164
|
},
|
|
165
|
+
...(event.signal ? { signal: event.signal } : {}),
|
|
163
166
|
};
|
|
164
167
|
}
|
|
165
168
|
|
|
@@ -194,7 +197,7 @@ function toConversationNotice(
|
|
|
194
197
|
item: NormalizedCodeAgentStatusEvent,
|
|
195
198
|
options: NormalizeCodeAgentTranscriptOptions,
|
|
196
199
|
): AgentConversationNotice | null {
|
|
197
|
-
if (options.hideCredentialMessages &&
|
|
200
|
+
if (options.hideCredentialMessages && isCredentialGapCodeAgentEvent(item))
|
|
198
201
|
return null;
|
|
199
202
|
if (item.level === "info" && item.statusKind !== "note") return null;
|
|
200
203
|
return {
|
|
@@ -255,10 +258,6 @@ function stringMetadata(
|
|
|
255
258
|
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
256
259
|
}
|
|
257
260
|
|
|
258
|
-
function isCredentialText(value: string): boolean {
|
|
259
|
-
return /No LLM provider key was found|Missing credentials/i.test(value);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
261
|
function extractAttachments(
|
|
263
262
|
events: CoreCodeAgentTranscriptEvent[],
|
|
264
263
|
): AgentConversationAttachment[] {
|
|
@@ -4,7 +4,11 @@ import {
|
|
|
4
4
|
IconUpload,
|
|
5
5
|
IconX,
|
|
6
6
|
} from "@tabler/icons-react";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
keepPreviousData,
|
|
9
|
+
useQuery,
|
|
10
|
+
useQueryClient,
|
|
11
|
+
} from "@tanstack/react-query";
|
|
8
12
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
9
13
|
|
|
10
14
|
import { sendToAgentChat } from "./agent-chat.js";
|
|
@@ -1051,6 +1055,10 @@ export function useGuidedQuestionFlow({
|
|
|
1051
1055
|
},
|
|
1052
1056
|
refetchInterval: resolvedRefetchInterval,
|
|
1053
1057
|
structuralSharing: false,
|
|
1058
|
+
// A matching app-state event changes the query key. Preserve the existing
|
|
1059
|
+
// payload while the replacement read is in flight so full-canvas question
|
|
1060
|
+
// forms do not unmount and flash during routine sync updates.
|
|
1061
|
+
placeholderData: keepPreviousData,
|
|
1054
1062
|
});
|
|
1055
1063
|
|
|
1056
1064
|
useEffect(() => {
|
|
@@ -1059,7 +1067,8 @@ export function useGuidedQuestionFlow({
|
|
|
1059
1067
|
if (
|
|
1060
1068
|
prev &&
|
|
1061
1069
|
guidedQuestionsFingerprint(prev.questions) ===
|
|
1062
|
-
guidedQuestionsFingerprint(data.questions)
|
|
1070
|
+
guidedQuestionsFingerprint(data.questions) &&
|
|
1071
|
+
prev.clientResolveId === data.clientResolveId
|
|
1063
1072
|
) {
|
|
1064
1073
|
return prev;
|
|
1065
1074
|
}
|
|
@@ -87,6 +87,7 @@ export {
|
|
|
87
87
|
} from "./embed-auth.js";
|
|
88
88
|
export {
|
|
89
89
|
codeAgentTranscriptEventsToContent,
|
|
90
|
+
codeAgentTranscriptHasPendingApproval,
|
|
90
91
|
createCodeAgentChatAdapter,
|
|
91
92
|
type CodeAgentChatController,
|
|
92
93
|
type CodeAgentChatControlResult,
|
|
@@ -107,6 +108,10 @@ export {
|
|
|
107
108
|
type CodeAgentRunStateLike,
|
|
108
109
|
type CodeAgentTranscriptOrderEvent,
|
|
109
110
|
} from "../code-agents/transcript-order.js";
|
|
111
|
+
export {
|
|
112
|
+
CREDENTIAL_GAP_SIGNAL,
|
|
113
|
+
isCredentialGapCodeAgentEvent,
|
|
114
|
+
} from "../code-agents/transcript-normalizer.js";
|
|
110
115
|
export { useSendToAgentChat } from "./use-send-to-agent-chat.js";
|
|
111
116
|
export {
|
|
112
117
|
useChatModels,
|
|
@@ -557,6 +562,12 @@ export {
|
|
|
557
562
|
type ChatThreadShareState,
|
|
558
563
|
type UseChatThreadsOptions,
|
|
559
564
|
} from "./use-chat-threads.js";
|
|
565
|
+
export {
|
|
566
|
+
ChatHistoryList,
|
|
567
|
+
type ChatHistoryItem,
|
|
568
|
+
type ChatHistorySection,
|
|
569
|
+
type ChatHistoryListProps,
|
|
570
|
+
} from "./chat/ChatHistoryList.js";
|
|
560
571
|
export { AgentChatHome, type AgentChatHomeProps } from "./AgentChatHome.js";
|
|
561
572
|
export {
|
|
562
573
|
AgentChatSurface,
|
|
@@ -43,16 +43,15 @@ interface PlatformInfo {
|
|
|
43
43
|
const PLATFORMS: PlatformInfo[] = [
|
|
44
44
|
{
|
|
45
45
|
id: "slack",
|
|
46
|
-
label: "Slack",
|
|
46
|
+
label: "Slack (legacy)",
|
|
47
47
|
icon: IconBrandSlack,
|
|
48
|
-
description:
|
|
48
|
+
description:
|
|
49
|
+
"Legacy single-workspace setup. Use Settings → Messaging for new Slack connections.",
|
|
49
50
|
envVars: ["SLACK_BOT_TOKEN", "SLACK_SIGNING_SECRET"],
|
|
50
51
|
setupSteps: [
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
"Install the app to your workspace",
|
|
55
|
-
"Copy the Bot Token and Signing Secret into your environment",
|
|
52
|
+
"Open Settings → Messaging for the supported managed Slack setup",
|
|
53
|
+
"Use this legacy setup only for an existing single-workspace installation",
|
|
54
|
+
"Managed OAuth stores workspace bot tokens automatically; do not add SLACK_BOT_TOKEN for new connections",
|
|
56
55
|
],
|
|
57
56
|
docsUrl: "https://api.slack.com/apps",
|
|
58
57
|
},
|