@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
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
type H3Event,
|
|
9
9
|
} from "h3";
|
|
10
10
|
|
|
11
|
+
import { getBuilderGatewayRequestHeaders } from "../agent/engine/builder-gateway-headers.js";
|
|
11
12
|
import {
|
|
12
13
|
actionsToEngineTools,
|
|
13
14
|
type ActionEntry,
|
|
@@ -18,7 +19,11 @@ import {
|
|
|
18
19
|
sanitizeToolErrorValue,
|
|
19
20
|
} from "../agent/tool-error-redaction.js";
|
|
20
21
|
import { getSession } from "./auth.js";
|
|
21
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
getBuilderGatewayBaseUrl,
|
|
24
|
+
resolveBuilderCredentials,
|
|
25
|
+
resolveSecret,
|
|
26
|
+
} from "./credential-provider.js";
|
|
22
27
|
import { getH3App } from "./framework-request-handler.js";
|
|
23
28
|
import { runWithRequestContext } from "./request-context.js";
|
|
24
29
|
|
|
@@ -336,12 +341,20 @@ function createSessionHandler(
|
|
|
336
341
|
: undefined,
|
|
337
342
|
},
|
|
338
343
|
async () => {
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
|
|
344
|
+
const builderCredentials = await resolveBuilderCredentials();
|
|
345
|
+
const builderConfigured = Boolean(
|
|
346
|
+
builderCredentials.privateKey?.trim() &&
|
|
347
|
+
builderCredentials.publicKey?.trim(),
|
|
348
|
+
);
|
|
349
|
+
const apiKey = builderConfigured
|
|
350
|
+
? null
|
|
351
|
+
: (await resolveSecret("OPENAI_API_KEY"))?.trim();
|
|
352
|
+
if (!builderConfigured && !apiKey) {
|
|
353
|
+
setResponseStatus(event, 409);
|
|
342
354
|
return {
|
|
343
355
|
error:
|
|
344
|
-
"
|
|
356
|
+
"Connect Builder or configure an OpenAI API key to use realtime voice.",
|
|
357
|
+
code: "realtime_voice_setup_required",
|
|
345
358
|
};
|
|
346
359
|
}
|
|
347
360
|
|
|
@@ -369,39 +382,73 @@ function createSessionHandler(
|
|
|
369
382
|
tool_choice: "auto",
|
|
370
383
|
};
|
|
371
384
|
|
|
372
|
-
const form = new FormData();
|
|
373
|
-
form.set("sdp", sdp);
|
|
374
|
-
form.set("session", JSON.stringify(session));
|
|
375
|
-
|
|
376
385
|
let upstream: Response;
|
|
377
386
|
try {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
387
|
+
if (builderConfigured) {
|
|
388
|
+
const gatewayUrl = new URL(
|
|
389
|
+
"realtime/calls",
|
|
390
|
+
getBuilderGatewayBaseUrl().endsWith("/")
|
|
391
|
+
? getBuilderGatewayBaseUrl()
|
|
392
|
+
: `${getBuilderGatewayBaseUrl()}/`,
|
|
393
|
+
);
|
|
394
|
+
gatewayUrl.searchParams.set(
|
|
395
|
+
"apiKey",
|
|
396
|
+
builderCredentials.publicKey!.trim(),
|
|
397
|
+
);
|
|
398
|
+
upstream = await fetch(gatewayUrl.toString(), {
|
|
399
|
+
method: "POST",
|
|
400
|
+
headers: {
|
|
401
|
+
"Content-Type": "application/json",
|
|
402
|
+
Authorization: `Bearer ${builderCredentials.privateKey!.trim()}`,
|
|
403
|
+
"x-builder-api-key": builderCredentials.publicKey!.trim(),
|
|
404
|
+
...getBuilderGatewayRequestHeaders(),
|
|
405
|
+
...(builderCredentials.userId
|
|
406
|
+
? { "x-builder-user-id": builderCredentials.userId }
|
|
407
|
+
: {}),
|
|
408
|
+
},
|
|
409
|
+
body: JSON.stringify({ sdp, session }),
|
|
410
|
+
});
|
|
411
|
+
} else {
|
|
412
|
+
const form = new FormData();
|
|
413
|
+
form.set("sdp", sdp);
|
|
414
|
+
form.set("session", JSON.stringify(session));
|
|
415
|
+
upstream = await fetch(OPENAI_REALTIME_CALLS_URL, {
|
|
416
|
+
method: "POST",
|
|
417
|
+
headers: {
|
|
418
|
+
Authorization: `Bearer ${apiKey}`,
|
|
419
|
+
"OpenAI-Safety-Identifier": await realtimeVoiceSafetyIdentifier(
|
|
420
|
+
auth.userEmail,
|
|
421
|
+
),
|
|
422
|
+
},
|
|
423
|
+
body: form,
|
|
424
|
+
});
|
|
425
|
+
}
|
|
388
426
|
} catch {
|
|
389
427
|
setResponseStatus(event, 502);
|
|
390
|
-
return {
|
|
428
|
+
return {
|
|
429
|
+
error: builderConfigured
|
|
430
|
+
? "Could not reach the Builder realtime voice gateway"
|
|
431
|
+
: "Could not reach the OpenAI Realtime API",
|
|
432
|
+
};
|
|
391
433
|
}
|
|
392
434
|
|
|
393
435
|
if (!upstream.ok) {
|
|
394
|
-
const detail = await safeOpenAiErrorDetail(
|
|
395
|
-
|
|
436
|
+
const detail = await safeOpenAiErrorDetail(
|
|
437
|
+
upstream,
|
|
438
|
+
builderConfigured ? builderCredentials.privateKey! : apiKey!,
|
|
439
|
+
);
|
|
440
|
+
setResponseStatus(event, builderConfigured ? upstream.status : 502);
|
|
396
441
|
return {
|
|
397
|
-
error:
|
|
442
|
+
error: `${builderConfigured ? "Builder" : "OpenAI"} rejected the realtime session (${upstream.status})${detail ? `: ${detail}` : ""}`,
|
|
398
443
|
};
|
|
399
444
|
}
|
|
400
445
|
|
|
401
446
|
const answerSdp = await upstream.text().catch(() => "");
|
|
402
447
|
if (!answerSdp.trim()) {
|
|
403
448
|
setResponseStatus(event, 502);
|
|
404
|
-
return {
|
|
449
|
+
return {
|
|
450
|
+
error: `${builderConfigured ? "Builder" : "OpenAI"} returned an empty realtime session answer`,
|
|
451
|
+
};
|
|
405
452
|
}
|
|
406
453
|
|
|
407
454
|
setResponseStatus(event, upstream.status);
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
import { getOrgContext } from "../org/context.js";
|
|
23
23
|
import { getSession } from "./auth.js";
|
|
24
24
|
import {
|
|
25
|
-
|
|
25
|
+
resolveHasCompleteBuilderConnection,
|
|
26
26
|
resolveSecret,
|
|
27
27
|
} from "./credential-provider.js";
|
|
28
28
|
import { resolveGoogleRealtimeCredentials } from "./google-realtime-session.js";
|
|
@@ -90,8 +90,9 @@ export function createVoiceProvidersStatusHandler() {
|
|
|
90
90
|
let builder = false;
|
|
91
91
|
try {
|
|
92
92
|
builder =
|
|
93
|
-
(await withRequestContext(() =>
|
|
94
|
-
|
|
93
|
+
(await withRequestContext(() =>
|
|
94
|
+
resolveHasCompleteBuilderConnection(),
|
|
95
|
+
)) === true;
|
|
95
96
|
} catch {
|
|
96
97
|
builder = false;
|
|
97
98
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export const DEFAULT_SSR_CACHE_CONTROL =
|
|
2
|
-
"public, max-age=5, stale-while-revalidate=604800, stale-if-error=3600";
|
|
1
|
+
export const DEFAULT_SSR_CACHE_CONTROL = "public, max-age=0, must-revalidate";
|
|
3
2
|
|
|
4
|
-
export const DEFAULT_SSR_CDN_CACHE_CONTROL =
|
|
3
|
+
export const DEFAULT_SSR_CDN_CACHE_CONTROL =
|
|
4
|
+
"public, s-maxage=600, stale-while-revalidate=604800, stale-if-error=3600";
|
|
5
5
|
|
|
6
6
|
export const DEFAULT_SSR_NETLIFY_CDN_CACHE_CONTROL =
|
|
7
|
-
"public, durable,
|
|
7
|
+
"public, durable, s-maxage=600, stale-while-revalidate=604800, stale-if-error=3600";
|
|
8
8
|
|
|
9
9
|
export const DEFAULT_SSR_CACHE_HEADERS = {
|
|
10
10
|
"cache-control": DEFAULT_SSR_CACHE_CONTROL,
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
@import "./agent-conversation.css";
|
|
26
26
|
@import "./rich-markdown-editor.css";
|
|
27
27
|
@import "./blocks.css";
|
|
28
|
+
@import "./chat-history-list.css";
|
|
28
29
|
|
|
29
30
|
/* Scan @agent-native/core's compiled client output for Tailwind classes.
|
|
30
31
|
Path is resolved relative to THIS file. After build, this CSS lives at
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Shared chat history list — used by core's `HistoryPopover`
|
|
3
|
+
* (MultiTabAssistantChat.tsx) and by Agent-Native Code's run rail
|
|
4
|
+
* (code-agents-ui CodeAgentsApp.tsx). Stable, prefixed class names (not
|
|
5
|
+
* Tailwind utilities) so the same visual language works in both a Tailwind
|
|
6
|
+
* host (core/templates) and a plain-CSS host (code-agents-ui), matching the
|
|
7
|
+
* approach used by agent-conversation.css. All colors resolve through the
|
|
8
|
+
* shared `hsl(var(--token))` variables so light/dark both work in either
|
|
9
|
+
* host's theme.
|
|
10
|
+
*
|
|
11
|
+
* Two density variants:
|
|
12
|
+
* .an-chat-history default — compact popover list (core)
|
|
13
|
+
* .an-chat-history--rail denser rail list with solid active state
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
.an-chat-history {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
min-height: 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.an-chat-history__search {
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
gap: 8px;
|
|
26
|
+
padding: 8px 12px;
|
|
27
|
+
border-bottom: 1px solid hsl(var(--border));
|
|
28
|
+
color: hsl(var(--muted-foreground));
|
|
29
|
+
flex-shrink: 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.an-chat-history__search-icon {
|
|
33
|
+
flex-shrink: 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.an-chat-history__search-input {
|
|
37
|
+
flex: 1;
|
|
38
|
+
min-width: 0;
|
|
39
|
+
background: transparent;
|
|
40
|
+
border: 0;
|
|
41
|
+
outline: none;
|
|
42
|
+
font-size: 12px;
|
|
43
|
+
color: hsl(var(--foreground));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.an-chat-history__search-input::placeholder {
|
|
47
|
+
color: hsl(var(--muted-foreground));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.an-chat-history__list {
|
|
51
|
+
overflow-y: auto;
|
|
52
|
+
padding: 4px 0;
|
|
53
|
+
max-height: 16rem;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.an-chat-history--rail .an-chat-history__list {
|
|
57
|
+
max-height: none;
|
|
58
|
+
flex: 1;
|
|
59
|
+
min-height: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.an-chat-history__state {
|
|
63
|
+
padding: 16px 12px;
|
|
64
|
+
text-align: center;
|
|
65
|
+
font-size: 12px;
|
|
66
|
+
color: hsl(var(--muted-foreground));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.an-chat-history__state--error {
|
|
70
|
+
/* Matches the amber-500 warning tone historically used for the
|
|
71
|
+
HistoryPopover load-error state (Tailwind's `text-amber-500`). */
|
|
72
|
+
color: hsl(38 92% 50%);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.an-chat-history__section-label {
|
|
76
|
+
padding: 6px 12px 4px;
|
|
77
|
+
font-size: 10px;
|
|
78
|
+
text-transform: uppercase;
|
|
79
|
+
letter-spacing: 0.04em;
|
|
80
|
+
color: hsl(var(--muted-foreground) / 0.7);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.an-chat-history--rail .an-chat-history__section {
|
|
84
|
+
display: grid;
|
|
85
|
+
gap: 1px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* ── Row ──────────────────────────────────────────────────────────────── */
|
|
89
|
+
|
|
90
|
+
.an-chat-history-row {
|
|
91
|
+
position: relative;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.an-chat-history--rail .an-chat-history-row {
|
|
95
|
+
border-radius: calc(var(--radius) - 2px);
|
|
96
|
+
margin: 0 4px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.an-chat-history-row__button {
|
|
100
|
+
display: block;
|
|
101
|
+
width: 100%;
|
|
102
|
+
padding: 8px 12px;
|
|
103
|
+
border: 0;
|
|
104
|
+
background: transparent;
|
|
105
|
+
color: inherit;
|
|
106
|
+
text-align: start;
|
|
107
|
+
cursor: pointer;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.an-chat-history-row--disabled .an-chat-history-row__button {
|
|
111
|
+
cursor: default;
|
|
112
|
+
opacity: 0.6;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.an-chat-history-row:hover .an-chat-history-row__button {
|
|
116
|
+
background: hsl(var(--accent) / 0.5);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.an-chat-history-row--active .an-chat-history-row__button {
|
|
120
|
+
background: hsl(var(--accent) / 0.3);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.an-chat-history--rail .an-chat-history-row__button {
|
|
124
|
+
min-height: 32px;
|
|
125
|
+
padding: 6px 36px 6px 10px;
|
|
126
|
+
border-radius: inherit;
|
|
127
|
+
color: hsl(var(--muted-foreground));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.an-chat-history--rail
|
|
131
|
+
.an-chat-history-row--active
|
|
132
|
+
.an-chat-history-row__button {
|
|
133
|
+
background: hsl(var(--accent));
|
|
134
|
+
color: hsl(var(--accent-foreground));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.an-chat-history-row__topline {
|
|
138
|
+
display: flex;
|
|
139
|
+
align-items: baseline;
|
|
140
|
+
justify-content: space-between;
|
|
141
|
+
gap: 8px;
|
|
142
|
+
min-width: 0;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.an-chat-history-row__title {
|
|
146
|
+
min-width: 0;
|
|
147
|
+
overflow: hidden;
|
|
148
|
+
text-overflow: ellipsis;
|
|
149
|
+
white-space: nowrap;
|
|
150
|
+
font-size: 12px;
|
|
151
|
+
font-weight: 500;
|
|
152
|
+
color: hsl(var(--foreground));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.an-chat-history-row--active .an-chat-history-row__title {
|
|
156
|
+
color: hsl(var(--foreground));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.an-chat-history--rail
|
|
160
|
+
.an-chat-history-row--active
|
|
161
|
+
.an-chat-history-row__title {
|
|
162
|
+
color: hsl(var(--accent-foreground));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.an-chat-history--rail
|
|
166
|
+
.an-chat-history-row--pinned:not(.an-chat-history-row--active)
|
|
167
|
+
.an-chat-history-row__title {
|
|
168
|
+
color: hsl(var(--foreground));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.an-chat-history-row__timestamp {
|
|
172
|
+
flex-shrink: 0;
|
|
173
|
+
font-size: 10px;
|
|
174
|
+
color: hsl(var(--muted-foreground));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.an-chat-history--rail .an-chat-history-row__timestamp {
|
|
178
|
+
font-size: 11px;
|
|
179
|
+
color: hsl(var(--muted-foreground) / 0.62);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.an-chat-history--rail
|
|
183
|
+
.an-chat-history-row--active
|
|
184
|
+
.an-chat-history-row__timestamp {
|
|
185
|
+
color: hsl(var(--accent-foreground));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.an-chat-history-row__subtitle {
|
|
189
|
+
margin-top: 2px;
|
|
190
|
+
overflow: hidden;
|
|
191
|
+
text-overflow: ellipsis;
|
|
192
|
+
white-space: nowrap;
|
|
193
|
+
font-size: 11px;
|
|
194
|
+
color: hsl(var(--muted-foreground));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.an-chat-history-row__detail {
|
|
198
|
+
margin-top: 2px;
|
|
199
|
+
overflow: hidden;
|
|
200
|
+
text-overflow: ellipsis;
|
|
201
|
+
white-space: nowrap;
|
|
202
|
+
font-size: 10px;
|
|
203
|
+
color: hsl(var(--muted-foreground) / 0.7);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/* ── Inline rename ────────────────────────────────────────────────────── */
|
|
207
|
+
|
|
208
|
+
.an-chat-history-row__rename {
|
|
209
|
+
display: flex;
|
|
210
|
+
align-items: center;
|
|
211
|
+
padding: 6px 12px;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.an-chat-history-row__rename-input {
|
|
215
|
+
width: 100%;
|
|
216
|
+
min-width: 0;
|
|
217
|
+
padding: 2px 6px;
|
|
218
|
+
border: 1px solid hsl(var(--ring));
|
|
219
|
+
border-radius: calc(var(--radius) - 3px);
|
|
220
|
+
background: hsl(var(--background));
|
|
221
|
+
color: hsl(var(--foreground));
|
|
222
|
+
font-size: 12px;
|
|
223
|
+
font-weight: 500;
|
|
224
|
+
line-height: 1.4;
|
|
225
|
+
outline: none;
|
|
226
|
+
box-shadow: 0 0 0 2px hsl(var(--ring) / 0.25);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.an-chat-history-row__rename-input:focus {
|
|
230
|
+
box-shadow: 0 0 0 2px hsl(var(--ring) / 0.35);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/* ── Row action menu ──────────────────────────────────────────────────── */
|
|
234
|
+
|
|
235
|
+
.an-chat-history-row__menu {
|
|
236
|
+
position: absolute;
|
|
237
|
+
top: 4px;
|
|
238
|
+
inset-inline-end: 4px;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.an-chat-history-row__menu-trigger {
|
|
242
|
+
display: inline-flex;
|
|
243
|
+
align-items: center;
|
|
244
|
+
justify-content: center;
|
|
245
|
+
width: 24px;
|
|
246
|
+
height: 24px;
|
|
247
|
+
border: 0;
|
|
248
|
+
border-radius: calc(var(--radius) - 3px);
|
|
249
|
+
background: transparent;
|
|
250
|
+
color: hsl(var(--muted-foreground) / 0.72);
|
|
251
|
+
opacity: 0;
|
|
252
|
+
cursor: pointer;
|
|
253
|
+
transition:
|
|
254
|
+
background 100ms ease,
|
|
255
|
+
color 100ms ease,
|
|
256
|
+
opacity 100ms ease;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.an-chat-history-row:hover .an-chat-history-row__menu-trigger,
|
|
260
|
+
.an-chat-history-row:focus-within .an-chat-history-row__menu-trigger,
|
|
261
|
+
.an-chat-history-row__menu-trigger[aria-expanded="true"],
|
|
262
|
+
.an-chat-history-row__menu-trigger--pinned {
|
|
263
|
+
opacity: 1;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.an-chat-history-row__menu-trigger:hover,
|
|
267
|
+
.an-chat-history-row__menu-trigger[aria-expanded="true"] {
|
|
268
|
+
background: hsl(var(--accent));
|
|
269
|
+
color: hsl(var(--foreground));
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.an-chat-history-row__menu-content {
|
|
273
|
+
position: absolute;
|
|
274
|
+
top: calc(100% + 4px);
|
|
275
|
+
inset-inline-end: 0;
|
|
276
|
+
z-index: 30;
|
|
277
|
+
min-width: 160px;
|
|
278
|
+
padding: 4px;
|
|
279
|
+
border: 1px solid hsl(var(--border));
|
|
280
|
+
border-radius: var(--radius);
|
|
281
|
+
background: hsl(var(--popover));
|
|
282
|
+
color: hsl(var(--popover-foreground));
|
|
283
|
+
box-shadow: 0 10px 30px hsl(var(--background) / 0.28);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.an-chat-history-row__menu-item {
|
|
287
|
+
display: flex;
|
|
288
|
+
align-items: center;
|
|
289
|
+
gap: 8px;
|
|
290
|
+
width: 100%;
|
|
291
|
+
padding: 6px 8px;
|
|
292
|
+
border: 0;
|
|
293
|
+
border-radius: calc(var(--radius) - 4px);
|
|
294
|
+
background: transparent;
|
|
295
|
+
color: inherit;
|
|
296
|
+
font-size: 12px;
|
|
297
|
+
text-align: start;
|
|
298
|
+
cursor: pointer;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.an-chat-history-row__menu-item:hover {
|
|
302
|
+
background: hsl(var(--accent));
|
|
303
|
+
color: hsl(var(--accent-foreground));
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.an-chat-history-row__menu-item--danger {
|
|
307
|
+
color: hsl(var(--destructive));
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.an-chat-history-row__menu-item--danger:hover {
|
|
311
|
+
background: hsl(var(--destructive) / 0.12);
|
|
312
|
+
color: hsl(var(--destructive));
|
|
313
|
+
}
|
|
@@ -126,6 +126,26 @@ The agent loop reads active experiments via `resolveActiveExperimentConfig()` an
|
|
|
126
126
|
|
|
127
127
|
Compute results with `POST /_agent-native/observability/experiments/:id/results`.
|
|
128
128
|
|
|
129
|
+
#### First-party hosted default-model rollout
|
|
130
|
+
|
|
131
|
+
First-party apps on `agent-native.com` automatically run the July 2026
|
|
132
|
+
default-model experiment for authenticated users on the Builder engine:
|
|
133
|
+
|
|
134
|
+
- 80% `claude-sonnet-5`
|
|
135
|
+
- 20% `gpt-5-6-luna`
|
|
136
|
+
- Assignment is sticky by normalized user email and shared across templates.
|
|
137
|
+
- The rollout applies only when the user, app, and deployment have not selected
|
|
138
|
+
a model. Explicit model choices and BYO provider engines always win.
|
|
139
|
+
- Set `AGENT_NATIVE_HOSTED_MODEL_EXPERIMENT=off` for an emergency rollback, or
|
|
140
|
+
`true` to exercise the rollout on a non-first-party preview.
|
|
141
|
+
- `$ai_generation` tracking includes `experiment_id`,
|
|
142
|
+
`experiment_variant`, and `model_selection_source` for central analysis.
|
|
143
|
+
|
|
144
|
+
In production, experiment management routes require the caller's email in the
|
|
145
|
+
comma-separated `AGENT_NATIVE_EXPERIMENT_ADMIN_EMAILS` allowlist. This gate is
|
|
146
|
+
separate from normal app/org admin roles because an experiment affects every
|
|
147
|
+
user in that deployment.
|
|
148
|
+
|
|
129
149
|
### 5. Dashboard
|
|
130
150
|
|
|
131
151
|
`ObservabilityDashboard` is a React component with 5 tabs:
|
package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md
CHANGED
|
@@ -41,9 +41,13 @@ shared agent sidebar.
|
|
|
41
41
|
## Realtime speech mode
|
|
42
42
|
|
|
43
43
|
Realtime speech mode is a full-duplex OpenAI Realtime WebRTC session, separate
|
|
44
|
-
from the dictation providers below. It
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
from the dictation providers below. It prefers the authenticated user's
|
|
45
|
+
complete Builder connection and the Builder-managed metered gateway. A scoped
|
|
46
|
+
`OPENAI_API_KEY` is the fallback when Builder is not connected. The server owns
|
|
47
|
+
the `gpt-realtime-2.1` session configuration and keeps credentials out of
|
|
48
|
+
browser code. If neither provider is configured, show **Connect Builder** as
|
|
49
|
+
the primary microphone-popover action and OpenAI key setup as the secondary
|
|
50
|
+
action before requesting microphone permission.
|
|
47
51
|
|
|
48
52
|
- Starting voice mode collapses the chat into a persistent bottom-end speech
|
|
49
53
|
orb. The orb stays visible above the chat even when the chat opens
|
|
@@ -169,7 +173,7 @@ client.
|
|
|
169
173
|
|
|
170
174
|
Templates can:
|
|
171
175
|
- **Disable the mic**: pass `voiceEnabled={false}` to `TiptapComposer`.
|
|
172
|
-
- **Replace the button**: wrap `TiptapComposer` and render your own `extraActionButton
|
|
176
|
+
- **Replace the button**: wrap `TiptapComposer` and render your own `extraActionButton`; the framework mic stays immediately before the primary send/stop control. Use `stopButton` for an active-run control so the disabled send button becomes stop when the draft is empty and returns when the user types.
|
|
173
177
|
- **Pre-register provider keys as `required: true`**: call `registerRequiredSecret(...)` from your own server plugin when a template needs a specific BYOK provider in onboarding.
|
|
174
178
|
|
|
175
179
|
## Don'ts
|
|
@@ -20,6 +20,13 @@ details live in `.agents/skills/`.
|
|
|
20
20
|
status) and the injected `<data-dictionary>` to learn what exists and which
|
|
21
21
|
table/columns/join paths to use. Don't fan out blind queries when the catalog
|
|
22
22
|
already answers where a fact lives.
|
|
23
|
+
- Simple time-bounded metric fast path: when the data dictionary or a known
|
|
24
|
+
canonical source already identifies the metric, run one bounded aggregate.
|
|
25
|
+
Once that query returns a valid result, answer immediately with the source,
|
|
26
|
+
time window, row count, and only necessary caveats. Do not schema-discover,
|
|
27
|
+
retry, enrich, or add breakdowns unless the query fails or its result
|
|
28
|
+
conflicts with the known metric definition. This never waives the real-data
|
|
29
|
+
requirement: do not answer from a guess, stale value, or unverified result.
|
|
23
30
|
- Clarify-first for ambiguous ad-hoc work: when the metric definition, date
|
|
24
31
|
range, or grain is ambiguous and a wrong guess would change the numbers, use
|
|
25
32
|
the `ask-question` clarifying tool (multiple-choice) before computing. Ask at
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AgentActionStopError, defineAction } from "@agent-native/core";
|
|
2
|
+
import type { ActionRunContext } from "@agent-native/core/action";
|
|
2
3
|
import { z } from "zod";
|
|
3
4
|
|
|
4
5
|
import { runQuery } from "../server/lib/bigquery";
|
|
@@ -49,6 +50,23 @@ function stopForBigQueryNotConfigured(message: string): never {
|
|
|
49
50
|
});
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
function stopForBigQueryCancellation(): never {
|
|
54
|
+
const message =
|
|
55
|
+
"The BigQuery query was cancelled because the agent run ended before it could finish.";
|
|
56
|
+
throw new AgentActionStopError(message, {
|
|
57
|
+
errorCode: "run_cancelled",
|
|
58
|
+
toolResult: JSON.stringify(
|
|
59
|
+
{
|
|
60
|
+
error: "run_cancelled",
|
|
61
|
+
message,
|
|
62
|
+
recoverable: false,
|
|
63
|
+
},
|
|
64
|
+
null,
|
|
65
|
+
2,
|
|
66
|
+
),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
52
70
|
export default defineAction({
|
|
53
71
|
description:
|
|
54
72
|
"Query the user-configured BigQuery data warehouse. Use this when the user asks for warehouse SQL, BigQuery, or a data-dictionary metric/table that lives in BigQuery. If the user names a provider action such as Jira or Pylon, use that provider action first and do not use BigQuery unless the user explicitly asks for a warehouse copy. Pass standard SQL via the `sql` arg. Do NOT use `db-query` for warehouse data (it only reaches the app's own SQL database). If a query fails with a schema or SQL error (unknown dataset/table/column, syntax), treat it as a normal debugging signal: inspect the real schema with `search-bigquery-schema` (or query INFORMATION_SCHEMA), correct the query based on the error, and run it again — a few corrective attempts are expected. Surface the error to the user only if it still fails after a few attempts or is non-recoverable (missing credentials, permission, quota). Never rerun identical failing SQL, and never substitute made-up numbers for data you could not query.",
|
|
@@ -57,10 +75,16 @@ export default defineAction({
|
|
|
57
75
|
}),
|
|
58
76
|
readOnly: true,
|
|
59
77
|
toolCallable: true,
|
|
60
|
-
run: async (args) => {
|
|
78
|
+
run: async (args, context?: ActionRunContext) => {
|
|
61
79
|
try {
|
|
62
|
-
return await runQuery(args.sql);
|
|
80
|
+
return await runQuery(args.sql, { signal: context?.signal });
|
|
63
81
|
} catch (err) {
|
|
82
|
+
// A run cancellation is terminal for this invocation. Returning it as a
|
|
83
|
+
// recoverable SQL error would invite the agent to retry work after the
|
|
84
|
+
// parent run has already ended. Normalize the provider's AbortError so
|
|
85
|
+
// the generic tool-error path cannot record it as a warehouse failure.
|
|
86
|
+
if (context?.signal?.aborted) stopForBigQueryCancellation();
|
|
87
|
+
|
|
64
88
|
const msg = err instanceof Error ? err.message : String(err);
|
|
65
89
|
if (
|
|
66
90
|
/GOOGLE_APPLICATION_CREDENTIALS_JSON not configured/i.test(msg) ||
|
|
@@ -190,7 +190,25 @@ export default defineAction({
|
|
|
190
190
|
workspaceConnection,
|
|
191
191
|
};
|
|
192
192
|
});
|
|
193
|
+
const configuredDataSources = providers
|
|
194
|
+
.filter((provider) => provider.configured)
|
|
195
|
+
.map((provider) => ({
|
|
196
|
+
provider: provider.provider,
|
|
197
|
+
label: provider.label,
|
|
198
|
+
via:
|
|
199
|
+
provider.configuredKeys.length > 0 &&
|
|
200
|
+
provider.workspaceConnection.grantState === "connected"
|
|
201
|
+
? "credentials-and-workspace"
|
|
202
|
+
: provider.workspaceConnection.grantState === "connected"
|
|
203
|
+
? "workspace"
|
|
204
|
+
: "credentials",
|
|
205
|
+
}));
|
|
193
206
|
return {
|
|
207
|
+
// Keep a compact, explicit summary first so models do not infer source
|
|
208
|
+
// availability from the much larger per-credential list below.
|
|
209
|
+
hasConfiguredDataSources: configuredDataSources.length > 0,
|
|
210
|
+
configuredDataSourceCount: configuredDataSources.length,
|
|
211
|
+
configuredDataSources,
|
|
194
212
|
credentials: results,
|
|
195
213
|
providers,
|
|
196
214
|
total: results.length,
|
|
@@ -1295,7 +1295,7 @@ function persistedAnalyticsThreadId() {
|
|
|
1295
1295
|
}
|
|
1296
1296
|
}
|
|
1297
1297
|
|
|
1298
|
-
function AnalyticsChatsSection() {
|
|
1298
|
+
function AnalyticsChatsSection({ isAskRoute }: { isAskRoute: boolean }) {
|
|
1299
1299
|
const navigate = useNavigate();
|
|
1300
1300
|
const t = useT();
|
|
1301
1301
|
const {
|
|
@@ -1439,8 +1439,9 @@ function AnalyticsChatsSection() {
|
|
|
1439
1439
|
{visibleThreads.map((thread) => {
|
|
1440
1440
|
const title = threadTitle(thread, t("chat.untitledChat"));
|
|
1441
1441
|
const isActive =
|
|
1442
|
-
|
|
1443
|
-
thread.id ===
|
|
1442
|
+
isAskRoute &&
|
|
1443
|
+
(thread.id === activeThreadId ||
|
|
1444
|
+
thread.id === persistedAnalyticsThreadId());
|
|
1444
1445
|
const isRenaming = thread.id === renamingThreadId;
|
|
1445
1446
|
return (
|
|
1446
1447
|
<div
|
|
@@ -2592,7 +2593,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2592
2593
|
/>
|
|
2593
2594
|
</button>
|
|
2594
2595
|
</div>
|
|
2595
|
-
{askOpen && <AnalyticsChatsSection />}
|
|
2596
|
+
{askOpen && <AnalyticsChatsSection isAskRoute={isAskRoute} />}
|
|
2596
2597
|
</div>
|
|
2597
2598
|
|
|
2598
2599
|
{/* Sessions link */}
|