@vellumai/assistant 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +11 -0
- package/Dockerfile +5 -4
- package/README.md +2 -2
- package/docker-entrypoint.sh +16 -0
- package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
- package/eslint-rules/cli-no-daemon-internals.js +283 -0
- package/eslint.config.mjs +12 -0
- package/knip.json +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
- package/openapi.yaml +4847 -1698
- package/package.json +3 -1
- package/scripts/generate-openapi.ts +52 -4
- package/scripts/sync-llm-catalog.ts +165 -0
- package/scripts/sync-web-search-catalog.ts +107 -0
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
- package/src/__tests__/anthropic-provider.test.ts +92 -2
- package/src/__tests__/app-control-flow.test.ts +7 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
- package/src/__tests__/avatar-identity-sync.test.ts +87 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
- package/src/__tests__/btw-routes.test.ts +1 -0
- package/src/__tests__/call-site-routing-provider.test.ts +172 -45
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
- package/src/__tests__/channel-policy.test.ts +12 -0
- package/src/__tests__/checker.test.ts +89 -0
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +35 -7
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
- package/src/__tests__/config-loader-backfill.test.ts +526 -102
- package/src/__tests__/config-loader-corrupt.test.ts +68 -0
- package/src/__tests__/config-loader-platform-defaults.test.ts +77 -23
- package/src/__tests__/config-schema-cmd.test.ts +63 -29
- package/src/__tests__/config-schema.test.ts +14 -3
- package/src/__tests__/config-set-platform-guard.test.ts +75 -152
- package/src/__tests__/config-set-route.test.ts +198 -0
- package/src/__tests__/config-watcher.test.ts +6 -0
- package/src/__tests__/contacts-tools.test.ts +51 -199
- package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
- package/src/__tests__/context-search-agent-runner.test.ts +22 -138
- package/src/__tests__/context-search-conversations-source.test.ts +42 -16
- package/src/__tests__/context-search-fanout.test.ts +20 -157
- package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
- package/src/__tests__/context-search-types.test.ts +7 -2
- package/src/__tests__/context-window-manager.test.ts +389 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
- package/src/__tests__/conversation-error.test.ts +38 -0
- package/src/__tests__/conversation-fork-crud.test.ts +241 -1
- package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
- package/src/__tests__/conversation-init.benchmark.test.ts +1 -0
- package/src/__tests__/conversation-lifecycle.test.ts +124 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
- package/src/__tests__/conversation-process-callsite.test.ts +21 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +4 -4
- package/src/__tests__/conversation-slash-commands.test.ts +194 -2
- package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
- package/src/__tests__/credential-security-invariants.test.ts +5 -6
- package/src/__tests__/daemon-credential-client.test.ts +56 -1
- package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
- package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
- package/src/__tests__/db-proxy-transaction.test.ts +206 -0
- package/src/__tests__/external-plugin-loader.test.ts +458 -0
- package/src/__tests__/filing-service.test.ts +23 -3
- package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -8
- package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
- package/src/__tests__/heartbeat-service.test.ts +50 -233
- package/src/__tests__/history-repair.test.ts +89 -0
- package/src/__tests__/host-app-control-proxy.test.ts +109 -1
- package/src/__tests__/host-app-control-routes.test.ts +247 -1
- package/src/__tests__/host-browser-proxy.test.ts +416 -20
- package/src/__tests__/host-browser-routes.test.ts +325 -33
- package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
- package/src/__tests__/inference-profile-reaper.test.ts +154 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
- package/src/__tests__/install-skill-routing.test.ts +2 -2
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +15 -0
- package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
- package/src/__tests__/llm-catalog-parity.test.ts +146 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
- package/src/__tests__/llm-resolver.test.ts +46 -0
- package/src/__tests__/managed-profile-guard.test.ts +131 -2
- package/src/__tests__/mcp-auth-routes.test.ts +1 -0
- package/src/__tests__/mcp-cli.test.ts +182 -220
- package/src/__tests__/mcp-health-check.test.ts +56 -27
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
- package/src/__tests__/message-complete-display-id.test.ts +175 -0
- package/src/__tests__/notification-platform-adapter.test.ts +229 -0
- package/src/__tests__/oauth-cli.test.ts +38 -2009
- package/src/__tests__/oauth-commands-routes.test.ts +711 -0
- package/src/__tests__/oauth-connect-routes.test.ts +174 -11
- package/src/__tests__/oauth-providers-routes.test.ts +14 -10
- package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
- package/src/__tests__/openai-responses-provider.test.ts +17 -0
- package/src/__tests__/plugin-bootstrap.test.ts +31 -2
- package/src/__tests__/plugin-route-contribution.test.ts +31 -3
- package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
- package/src/__tests__/plugin-types.test.ts +13 -11
- package/src/__tests__/process-message-background-slack.test.ts +46 -0
- package/src/__tests__/profile-entry-status.test.ts +43 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
- package/src/__tests__/provider-registry-ollama.test.ts +12 -4
- package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
- package/src/__tests__/relay-server.test.ts +118 -0
- package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
- package/src/__tests__/schedule-retry.test.ts +56 -4
- package/src/__tests__/schedule-routes.test.ts +104 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
- package/src/__tests__/scheduler-recurrence.test.ts +87 -34
- package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
- package/src/__tests__/scheduler-wake.test.ts +0 -63
- package/src/__tests__/secret-allowlist.test.ts +1 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
- package/src/__tests__/shell-credential-ref.test.ts +95 -3
- package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skill-load-tool.test.ts +2 -4
- package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +63 -0
- package/src/__tests__/task-scheduler.test.ts +88 -23
- package/src/__tests__/update-bulletin-job.test.ts +96 -193
- package/src/__tests__/usage-cli.test.ts +11 -73
- package/src/__tests__/user-plugin-loader.test.ts +145 -0
- package/src/__tests__/vercel-config.test.ts +168 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
- package/src/__tests__/web-search.test.ts +303 -2
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
- package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +53 -20
- package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
- package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
- package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
- package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
- package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
- package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
- package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
- package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
- package/src/acp/__tests__/helpers/which-stub.ts +4 -2
- package/src/acp/resolve-agent.test.ts +25 -0
- package/src/acp/resolve-agent.ts +13 -2
- package/src/acp/session-manager.ts +14 -0
- package/src/approvals/guardian-request-resolvers.ts +32 -87
- package/src/calls/relay-server.ts +35 -0
- package/src/calls/relay-setup-router.ts +36 -0
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-session-bridge.ts +23 -4
- package/src/channels/config.ts +14 -1
- package/src/channels/types.ts +1 -0
- package/src/cli/AGENTS.md +164 -4
- package/src/cli/__tests__/notifications.test.ts +54 -0
- package/src/cli/commands/__tests__/avatar.test.ts +540 -0
- package/src/cli/commands/__tests__/backup.test.ts +236 -776
- package/src/cli/commands/__tests__/cache.test.ts +1 -1
- package/src/cli/commands/__tests__/changelog.test.ts +593 -0
- package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
- package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
- package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
- package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
- package/src/cli/commands/__tests__/email-core.test.ts +579 -0
- package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
- package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
- package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
- package/src/cli/commands/__tests__/skills.test.ts +563 -0
- package/src/cli/commands/__tests__/status.test.ts +249 -0
- package/src/cli/commands/__tests__/stt.test.ts +320 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
- package/src/cli/commands/__tests__/tts.test.ts +321 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
- package/src/cli/commands/attachment.ts +8 -3
- package/src/cli/commands/audit.ts +95 -64
- package/src/cli/commands/auth.ts +61 -58
- package/src/cli/commands/avatar.ts +276 -390
- package/src/cli/commands/backup.ts +409 -505
- package/src/cli/commands/bash.ts +9 -5
- package/src/cli/commands/browser.ts +28 -9
- package/src/cli/commands/cache.ts +9 -4
- package/src/cli/commands/changelog.ts +414 -0
- package/src/cli/commands/channel-verification-sessions.ts +238 -317
- package/src/cli/commands/clients.ts +8 -3
- package/src/cli/commands/completions.ts +9 -9
- package/src/cli/commands/config.ts +102 -72
- package/src/cli/commands/contacts.ts +575 -696
- package/src/cli/commands/conversations-defer.ts +17 -69
- package/src/cli/commands/conversations-import.ts +90 -253
- package/src/cli/commands/conversations.ts +346 -436
- package/src/cli/commands/credential-execution.ts +9 -6
- package/src/cli/commands/credentials.ts +456 -736
- package/src/cli/commands/domain.ts +128 -206
- package/src/cli/commands/email.ts +606 -794
- package/src/cli/commands/gateway.ts +8 -1
- package/src/cli/commands/image-generation.ts +157 -205
- package/src/cli/commands/inference-providers.ts +352 -0
- package/src/cli/commands/inference-session.ts +415 -0
- package/src/cli/commands/inference.ts +87 -65
- package/src/cli/commands/keys.ts +8 -3
- package/src/cli/commands/mcp.ts +103 -287
- package/src/cli/commands/memory-v2.ts +162 -516
- package/src/cli/commands/notifications.ts +33 -7
- package/src/cli/commands/oauth/apps.ts +292 -261
- package/src/cli/commands/oauth/connect.ts +176 -297
- package/src/cli/commands/oauth/disconnect.ts +16 -215
- package/src/cli/commands/oauth/index.ts +49 -45
- package/src/cli/commands/oauth/mode.ts +43 -199
- package/src/cli/commands/oauth/ping.ts +17 -125
- package/src/cli/commands/oauth/providers.ts +732 -921
- package/src/cli/commands/oauth/request.ts +60 -350
- package/src/cli/commands/oauth/shared.ts +11 -121
- package/src/cli/commands/oauth/status.ts +31 -121
- package/src/cli/commands/oauth/token.ts +13 -55
- package/src/cli/commands/pending.ts +19 -10
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
- package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
- package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
- package/src/cli/commands/platform/connect.ts +16 -80
- package/src/cli/commands/platform/disconnect.ts +14 -112
- package/src/cli/commands/platform/index.ts +177 -246
- package/src/cli/commands/routes.ts +153 -336
- package/src/cli/commands/sequence.ts +316 -360
- package/src/cli/commands/skills.ts +449 -671
- package/src/cli/commands/status.ts +58 -37
- package/src/cli/commands/stt.ts +94 -262
- package/src/cli/commands/task.ts +14 -40
- package/src/cli/commands/trust.ts +8 -3
- package/src/cli/commands/tts.ts +162 -167
- package/src/cli/commands/ui.ts +35 -42
- package/src/cli/commands/usage.ts +188 -126
- package/src/cli/commands/watchers.ts +8 -3
- package/src/cli/commands/webhooks.ts +99 -193
- package/src/cli/lib/__tests__/register-command.test.ts +85 -0
- package/src/cli/lib/daemon-credential-client.ts +4 -5
- package/src/cli/lib/nested-value.ts +44 -0
- package/src/cli/lib/open-browser.ts +36 -0
- package/src/cli/lib/register-command.ts +19 -0
- package/src/cli/lib/time-ago.ts +34 -0
- package/src/cli/program.ts +2 -4
- package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
- package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
- package/src/cli/utils/conversation-id.ts +30 -0
- package/src/cli/utils/parse-duration.ts +41 -0
- package/src/config/acp-defaults.test.ts +5 -1
- package/src/config/acp-defaults.ts +11 -4
- package/src/config/bundled-skills/acp/TOOLS.json +2 -2
- package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
- package/src/config/bundled-skills/contacts/SKILL.md +12 -45
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
- package/src/config/bundled-tool-registry.ts +0 -2
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/llm-resolver.ts +16 -1
- package/src/config/loader.ts +76 -14
- package/src/config/raw-config-utils.ts +2 -30
- package/src/config/schema.ts +4 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
- package/src/config/schemas/call-site-catalog.ts +29 -7
- package/src/config/schemas/llm-request-logs.ts +57 -0
- package/src/config/schemas/llm.ts +52 -2
- package/src/config/schemas/memory-retrospective.ts +48 -0
- package/src/config/schemas/memory-v2.ts +32 -1
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/services.ts +15 -12
- package/src/config/seed-inference-profiles.ts +195 -134
- package/src/contacts/contact-store.ts +0 -61
- package/src/context/window-manager.ts +191 -5
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +79 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
- package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
- package/src/daemon/approval-generators.ts +23 -29
- package/src/daemon/config-watcher.ts +2 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +24 -0
- package/src/daemon/conversation-agent-loop.ts +127 -97
- package/src/daemon/conversation-error.ts +21 -0
- package/src/daemon/conversation-lifecycle.ts +46 -5
- package/src/daemon/conversation-process.ts +36 -19
- package/src/daemon/conversation-runtime-assembly.ts +14 -5
- package/src/daemon/conversation-slash.ts +175 -23
- package/src/daemon/conversation-store.ts +17 -10
- package/src/daemon/conversation-surfaces.ts +76 -12
- package/src/daemon/conversation-tool-setup.ts +24 -14
- package/src/daemon/conversation.ts +48 -9
- package/src/daemon/external-plugins-bootstrap.ts +18 -8
- package/src/daemon/guardian-action-generators.ts +7 -22
- package/src/daemon/handlers/config-model.ts +8 -126
- package/src/daemon/handlers/config-slack-channel.ts +10 -7
- package/src/daemon/handlers/config-vercel.ts +3 -1
- package/src/daemon/handlers/skills.ts +84 -5
- package/src/daemon/history-repair.ts +33 -6
- package/src/daemon/host-app-control-proxy.ts +44 -19
- package/src/daemon/host-bash-proxy.ts +85 -158
- package/src/daemon/host-browser-proxy.ts +96 -35
- package/src/daemon/host-proxy-base.ts +13 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -1
- package/src/daemon/identity-helpers.ts +19 -0
- package/src/daemon/lifecycle.ts +42 -43
- package/src/daemon/meet-host-supervisor.ts +15 -15
- package/src/daemon/memory-v2-startup.ts +9 -2
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/bookmarks.ts +18 -0
- package/src/daemon/message-types/conversations.ts +12 -9
- package/src/daemon/message-types/messages.ts +9 -1
- package/src/daemon/message-types/sync.ts +60 -0
- package/src/daemon/pkb-reminder-builder.test.ts +54 -13
- package/src/daemon/pkb-reminder-builder.ts +21 -7
- package/src/daemon/process-message.ts +56 -23
- package/src/daemon/server.ts +23 -18
- package/src/daemon/shutdown-handlers.ts +0 -2
- package/src/daemon/tool-setup-types.ts +9 -0
- package/src/daemon/tool-side-effects.ts +6 -4
- package/src/daemon/wake-target-adapter.ts +11 -0
- package/src/export/transcript-formatter.ts +61 -2
- package/src/filing/filing-service.ts +40 -53
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
- package/src/heartbeat/heartbeat-run-store.ts +2 -1
- package/src/heartbeat/heartbeat-service.ts +148 -127
- package/src/home/__tests__/feed-types.test.ts +63 -131
- package/src/home/__tests__/feed-writer.test.ts +77 -278
- package/src/home/__tests__/post-connect-feed.test.ts +9 -12
- package/src/home/feed-types.ts +19 -73
- package/src/home/feed-writer.ts +25 -156
- package/src/home/post-connect-feed.ts +1 -3
- package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
- package/src/ipc/__tests__/email-ipc.test.ts +506 -0
- package/src/ipc/__tests__/exit-helper.test.ts +104 -0
- package/src/ipc/__tests__/streaming-client.test.ts +237 -0
- package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
- package/src/ipc/assistant-server.ts +55 -6
- package/src/ipc/cli-client.ts +370 -50
- package/src/ipc/routes/db-proxy-transaction.ts +151 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
- package/src/ipc/skill-routes/events.ts +30 -3
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
- package/src/live-voice/live-voice-session-manager.ts +11 -4
- package/src/live-voice/live-voice-session.ts +14 -6
- package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
- package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
- package/src/memory/__tests__/conversation-types.test.ts +36 -0
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
- package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
- package/src/memory/bookmark-crud.ts +179 -0
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
- package/src/memory/context-search/agent-protocol.ts +5 -1
- package/src/memory/context-search/agent-runner.ts +60 -85
- package/src/memory/context-search/limits.ts +1 -4
- package/src/memory/context-search/search.ts +23 -113
- package/src/memory/context-search/sources/conversations.ts +18 -6
- package/src/memory/context-search/sources/memory-v2.ts +39 -14
- package/src/memory/context-search/sources/memory.ts +7 -0
- package/src/memory/context-search/sources/workspace.ts +13 -10
- package/src/memory/context-search/types.ts +1 -1
- package/src/memory/conversation-bootstrap.ts +11 -0
- package/src/memory/conversation-crud.ts +312 -10
- package/src/memory/conversation-queries.ts +9 -5
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/conversation-types.ts +16 -0
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.ts +2 -1
- package/src/memory/embedding-runtime-manager.ts +1 -2
- package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
- package/src/memory/graph/conversation-graph-memory.ts +76 -5
- package/src/memory/graph/extraction.ts +4 -0
- package/src/memory/graph/graph-memory-state-store.ts +16 -3
- package/src/memory/graph/tool-handlers.ts +17 -7
- package/src/memory/graph/tools.ts +44 -5
- package/src/memory/indexer.ts +17 -0
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +13 -15
- package/src/memory/jobs/embed-concept-page.ts +45 -9
- package/src/memory/jobs-store.ts +51 -1
- package/src/memory/jobs-worker.ts +52 -3
- package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
- package/src/memory/llm-request-log-source-local.ts +26 -0
- package/src/memory/llm-request-log-source.ts +97 -0
- package/src/memory/llm-request-log-store.ts +1 -1
- package/src/memory/memory-retrospective-constants.ts +13 -0
- package/src/memory/memory-retrospective-enqueue.ts +114 -0
- package/src/memory/memory-retrospective-job.ts +351 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
- package/src/memory/memory-retrospective-state.ts +162 -0
- package/src/memory/memory-retrospective-trigger-check.ts +91 -0
- package/src/memory/memory-v2-activation-log-store.ts +49 -5
- package/src/memory/memory-v2-concept-frequency.ts +4 -0
- package/src/memory/message-content.ts +38 -1
- package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
- package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
- package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
- package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
- package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
- package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
- package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
- package/src/memory/migrations/242-message-bookmarks.ts +38 -0
- package/src/memory/migrations/243-provider-connections.ts +68 -0
- package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
- package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
- package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
- package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
- package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
- package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/published-pages-store.ts +16 -0
- package/src/memory/schema/bookmarks.ts +38 -0
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/index.ts +2 -0
- package/src/memory/schema/inference.ts +29 -0
- package/src/memory/schema/memory-core.ts +9 -0
- package/src/memory/search/semantic.ts +1 -4
- package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
- package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
- package/src/memory/v2/__tests__/activation.test.ts +11 -4
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
- package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
- package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
- package/src/memory/v2/__tests__/injection.test.ts +628 -10
- package/src/memory/v2/__tests__/migration.test.ts +7 -3
- package/src/memory/v2/__tests__/page-index.test.ts +277 -0
- package/src/memory/v2/__tests__/page-store.test.ts +14 -1
- package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
- package/src/memory/v2/__tests__/qdrant.test.ts +72 -0
- package/src/memory/v2/__tests__/reranker.test.ts +4 -4
- package/src/memory/v2/__tests__/router.test.ts +516 -0
- package/src/memory/v2/__tests__/sim.test.ts +45 -1
- package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
- package/src/memory/v2/__tests__/static-context.test.ts +7 -22
- package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
- package/src/memory/v2/activation-store.ts +34 -5
- package/src/memory/v2/activation.ts +40 -27
- package/src/memory/v2/backfill-jobs.ts +17 -84
- package/src/memory/v2/consolidation-job.ts +85 -78
- package/src/memory/v2/frontmatter-sweep.ts +91 -0
- package/src/memory/v2/injection.ts +440 -109
- package/src/memory/v2/migration.ts +117 -20
- package/src/memory/v2/page-index.ts +191 -0
- package/src/memory/v2/page-store.ts +3 -0
- package/src/memory/v2/prompts/consolidation.ts +9 -7
- package/src/memory/v2/prompts/router.ts +192 -0
- package/src/memory/v2/qdrant.ts +100 -87
- package/src/memory/v2/reranker.ts +14 -7
- package/src/memory/v2/router.ts +322 -0
- package/src/memory/v2/sim.ts +25 -12
- package/src/memory/v2/skill-store.ts +118 -29
- package/src/memory/v2/static-context.ts +16 -9
- package/src/memory/v2/sweep-job.ts +122 -96
- package/src/memory/v2/types.ts +10 -6
- package/src/memory/validation.ts +13 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
- package/src/notifications/__tests__/signal-registry.test.ts +17 -0
- package/src/notifications/adapters/platform.ts +171 -0
- package/src/notifications/conversation-pairing.ts +2 -2
- package/src/notifications/copy-composer.ts +15 -0
- package/src/notifications/destination-resolver.ts +21 -0
- package/src/notifications/emit-signal.ts +28 -1
- package/src/notifications/home-feed-side-effect.ts +111 -0
- package/src/notifications/signal.ts +5 -0
- package/src/permissions/checker.ts +12 -0
- package/src/permissions/ipc-risk-types.ts +2 -0
- package/src/plugin-api/index.ts +13 -0
- package/src/plugin-api/package.json +12 -0
- package/src/plugin-api/types.ts +62 -0
- package/src/plugins/defaults/injectors.ts +19 -3
- package/src/plugins/external-plugin-loader.ts +294 -0
- package/src/plugins/types.ts +46 -30
- package/src/plugins/user-loader.ts +64 -41
- package/src/proactive-artifact/job.test.ts +12 -4
- package/src/proactive-artifact/job.ts +4 -0
- package/src/proactive-artifact/trigger-state.test.ts +9 -0
- package/src/proactive-artifact/trigger-state.ts +4 -0
- package/src/prompts/__tests__/system-prompt.test.ts +105 -0
- package/src/prompts/system-prompt.ts +22 -1
- package/src/prompts/update-bulletin-job.ts +61 -73
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
- package/src/providers/__tests__/inference.test.ts +288 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
- package/src/providers/__tests__/retry-callsite.test.ts +14 -32
- package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
- package/src/providers/anthropic/client.ts +95 -26
- package/src/providers/call-site-routing.ts +94 -16
- package/src/providers/connection-resolution.ts +163 -0
- package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
- package/src/providers/inference/adapter-factory.ts +173 -0
- package/src/providers/inference/auth.ts +112 -0
- package/src/providers/inference/backfill.ts +196 -0
- package/src/providers/inference/connections.ts +356 -0
- package/src/providers/inference/resolve-auth.ts +65 -0
- package/src/providers/model-catalog.ts +104 -6
- package/src/providers/openai/responses-provider.ts +4 -2
- package/src/providers/provider-env-vars.ts +17 -7
- package/src/providers/provider-secret-catalog.ts +49 -30
- package/src/providers/provider-send-message.ts +41 -20
- package/src/providers/registry.ts +143 -159
- package/src/providers/retry.ts +18 -10
- package/src/providers/search-provider-catalog.ts +121 -0
- package/src/runtime/AGENTS.md +18 -5
- package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
- package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
- package/src/runtime/actor-trust-resolver.ts +32 -10
- package/src/runtime/agent-wake.ts +35 -6
- package/src/runtime/assistant-event-hub.ts +3 -85
- package/src/runtime/auth/route-policy.ts +303 -8
- package/src/runtime/auth/same-actor.ts +2 -0
- package/src/runtime/background-job-runner.ts +339 -0
- package/src/runtime/btw-sidechain.ts +1 -0
- package/src/runtime/http-router.ts +36 -1
- package/src/runtime/http-server.ts +31 -5
- package/src/runtime/http-types.ts +2 -0
- package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
- package/src/runtime/middleware/request-logger.ts +62 -1
- package/src/runtime/pre-first-message-gate.ts +83 -0
- package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +4 -4
- package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
- package/src/runtime/routes/acp-routes.ts +10 -8
- package/src/runtime/routes/app-management-routes.ts +228 -3
- package/src/runtime/routes/approval-routes.ts +0 -18
- package/src/runtime/routes/audit-routes.ts +43 -0
- package/src/runtime/routes/auth-routes.ts +72 -0
- package/src/runtime/routes/avatar-routes.ts +273 -20
- package/src/runtime/routes/backup-routes.ts +406 -2
- package/src/runtime/routes/bookmark-routes.ts +154 -0
- package/src/runtime/routes/channel-verification-routes.ts +2 -1
- package/src/runtime/routes/contact-routes.ts +0 -160
- package/src/runtime/routes/conversation-cli-routes.ts +192 -0
- package/src/runtime/routes/conversation-management-routes.ts +30 -43
- package/src/runtime/routes/conversation-query-routes.ts +334 -86
- package/src/runtime/routes/conversation-routes.ts +31 -10
- package/src/runtime/routes/conversations-import-routes.ts +229 -0
- package/src/runtime/routes/credential-routes.ts +540 -0
- package/src/runtime/routes/debug-routes.ts +2 -2
- package/src/runtime/routes/document-pdf-renderer.ts +5 -1
- package/src/runtime/routes/domain-routes.ts +167 -0
- package/src/runtime/routes/email-routes.ts +603 -0
- package/src/runtime/routes/errors.ts +2 -2
- package/src/runtime/routes/events-routes.ts +192 -0
- package/src/runtime/routes/home-feed-routes.ts +6 -78
- package/src/runtime/routes/host-app-control-routes.ts +44 -2
- package/src/runtime/routes/host-browser-routes.ts +103 -22
- package/src/runtime/routes/http-adapter.ts +2 -0
- package/src/runtime/routes/identity-routes.ts +5 -0
- package/src/runtime/routes/image-generation-routes.ts +99 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -4
- package/src/runtime/routes/index.ts +36 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
- package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
- package/src/runtime/routes/inference-send-routes.ts +115 -0
- package/src/runtime/routes/integrations/twilio.ts +1 -0
- package/src/runtime/routes/mcp-auth-routes.ts +283 -9
- package/src/runtime/routes/memory-v2-routes.ts +13 -398
- package/src/runtime/routes/notification-routes.ts +2 -0
- package/src/runtime/routes/oauth-apps.ts +112 -7
- package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
- package/src/runtime/routes/oauth-connect-routes.ts +67 -5
- package/src/runtime/routes/oauth-providers.ts +298 -8
- package/src/runtime/routes/platform-routes.ts +336 -0
- package/src/runtime/routes/playground/inject-failures.ts +2 -1
- package/src/runtime/routes/playground/reset-circuit.ts +2 -1
- package/src/runtime/routes/playground/state.ts +2 -1
- package/src/runtime/routes/publish-routes.ts +221 -0
- package/src/runtime/routes/schedule-routes.ts +82 -0
- package/src/runtime/routes/sequence-routes.ts +291 -0
- package/src/runtime/routes/settings-routes.ts +2 -10
- package/src/runtime/routes/skills-routes.ts +31 -1
- package/src/runtime/routes/stt-routes.ts +240 -3
- package/src/runtime/routes/surface-action-routes.ts +43 -7
- package/src/runtime/routes/tts-routes.ts +67 -0
- package/src/runtime/routes/types.ts +32 -0
- package/src/runtime/routes/user-routes-cli.ts +243 -0
- package/src/runtime/routes/webhook-routes.ts +165 -0
- package/src/runtime/sync/resource-sync-events.ts +25 -0
- package/src/runtime/sync/sync-publisher.test.ts +105 -0
- package/src/runtime/sync/sync-publisher.ts +21 -0
- package/src/schedule/scheduler.ts +200 -123
- package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
- package/src/security/secret-patterns.ts +3 -0
- package/src/sequence/engine.ts +38 -40
- package/src/subagent/manager.ts +20 -15
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
- package/src/tools/browser/browser-execution.ts +15 -4
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
- package/src/tools/browser/cdp-client/factory.ts +66 -5
- package/src/tools/browser/runtime-check.ts +77 -0
- package/src/tools/memory/register.test.ts +3 -3
- package/src/tools/memory/register.ts +9 -1
- package/src/tools/network/__tests__/web-search.test.ts +156 -0
- package/src/tools/network/web-search.ts +280 -37
- package/src/tools/permission-checker.ts +13 -5
- package/src/tools/subagent/spawn.ts +3 -3
- package/src/tools/terminal/shell.ts +44 -0
- package/src/usage/attribution.ts +3 -2
- package/src/util/pricing.ts +86 -160
- package/src/watcher/__tests__/engine.test.ts +301 -0
- package/src/watcher/constants.ts +7 -0
- package/src/watcher/engine.ts +90 -90
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
- package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
- package/src/workspace/migrations/069-seed-onboarding-threads.ts +8 -2
- package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
- package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
- package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
- package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
- package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
- package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
- package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
- package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
- package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
- package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
- package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
- package/src/workspace/migrations/registry.ts +22 -0
- package/src/workspace/migrations/runner.ts +13 -2
- package/src/workspace/migrations/types.ts +13 -3
- package/src/workspace/provider-commit-message-generator.ts +3 -2
- package/src/__tests__/context-search-pkb-source.test.ts +0 -498
- package/src/__tests__/credentials-cli.test.ts +0 -1225
- package/src/__tests__/memory-admin-recall.test.ts +0 -213
- package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
- package/src/cli/commands/__tests__/email-download.test.ts +0 -260
- package/src/cli/commands/__tests__/email-list.test.ts +0 -216
- package/src/cli/commands/__tests__/email-register.test.ts +0 -186
- package/src/cli/commands/__tests__/email-send.test.ts +0 -416
- package/src/cli/commands/__tests__/email-status.test.ts +0 -185
- package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
- package/src/cli/commands/__tests__/routes.test.ts +0 -562
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
- package/src/cli/commands/autonomy.ts +0 -365
- package/src/cli/commands/memory.ts +0 -424
- package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -947
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
- package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
- package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
- package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
- package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
- package/src/cli/lib/daemon-avatar-client.ts +0 -37
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
- package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
- package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
- package/src/home/__tests__/emit-feed-event.test.ts +0 -169
- package/src/home/__tests__/feed-population-integration.test.ts +0 -312
- package/src/home/__tests__/feed-scheduler.test.ts +0 -222
- package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
- package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
- package/src/home/__tests__/rollup-producer.test.ts +0 -507
- package/src/home/assistant-feed-authoring.ts +0 -135
- package/src/home/emit-feed-event.ts +0 -169
- package/src/home/feed-scheduler.ts +0 -281
- package/src/home/platform-gmail-digest.ts +0 -163
- package/src/home/rewrite-command-preview.ts +0 -66
- package/src/home/rewrite-feed-title.ts +0 -58
- package/src/home/rollup-producer.ts +0 -426
- package/src/memory/admin.ts +0 -326
- package/src/memory/context-search/sources/pkb.ts +0 -476
- package/src/memory/graph/compaction.ts +0 -299
- /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Transport-agnostic route definitions for speech-to-text.
|
|
3
3
|
*
|
|
4
|
-
* GET /v1/stt/providers
|
|
5
|
-
* POST /v1/stt/transcribe
|
|
4
|
+
* GET /v1/stt/providers — list available STT providers and their metadata
|
|
5
|
+
* POST /v1/stt/transcribe — transcribe base64-encoded audio to text
|
|
6
|
+
* POST /v1/stt/transcribe-file — transcribe audio/video file to text (full ffmpeg + chunking flow)
|
|
6
7
|
*/
|
|
7
8
|
|
|
9
|
+
import { randomUUID } from "node:crypto";
|
|
10
|
+
import { access, mkdir, readdir, readFile, rm, unlink } from "node:fs/promises";
|
|
11
|
+
import { tmpdir } from "node:os";
|
|
12
|
+
import { extname, join } from "node:path";
|
|
13
|
+
|
|
8
14
|
import { z } from "zod";
|
|
9
15
|
|
|
10
16
|
import { listProviderEntries } from "../../providers/speech-to-text/provider-catalog.js";
|
|
11
17
|
import { resolveBatchTranscriber } from "../../providers/speech-to-text/resolve.js";
|
|
12
18
|
import { normalizeSttError } from "../../stt/daemon-batch-transcriber.js";
|
|
13
|
-
import type { SttErrorCategory } from "../../stt/types.js";
|
|
19
|
+
import type { BatchTranscriber, SttErrorCategory } from "../../stt/types.js";
|
|
14
20
|
import { getLogger } from "../../util/logger.js";
|
|
21
|
+
import {
|
|
22
|
+
FFMPEG_TRANSCODE_TIMEOUT_MS,
|
|
23
|
+
FFPROBE_TIMEOUT_MS,
|
|
24
|
+
spawnWithTimeout,
|
|
25
|
+
} from "../../util/spawn.js";
|
|
15
26
|
import {
|
|
16
27
|
BadGatewayError,
|
|
17
28
|
BadRequestError,
|
|
@@ -28,6 +39,155 @@ const log = getLogger("stt-routes");
|
|
|
28
39
|
/** Timeout for a single transcription request. */
|
|
29
40
|
const TRANSCRIPTION_TIMEOUT_MS = 30_000;
|
|
30
41
|
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// File-transcription constants and helpers (used by stt_transcribe_file)
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
const VIDEO_EXTENSIONS = new Set([
|
|
47
|
+
".mp4",
|
|
48
|
+
".mov",
|
|
49
|
+
".avi",
|
|
50
|
+
".mkv",
|
|
51
|
+
".webm",
|
|
52
|
+
".m4v",
|
|
53
|
+
".mpeg",
|
|
54
|
+
".mpg",
|
|
55
|
+
]);
|
|
56
|
+
const AUDIO_EXTENSIONS = new Set([
|
|
57
|
+
".mp3",
|
|
58
|
+
".wav",
|
|
59
|
+
".m4a",
|
|
60
|
+
".aac",
|
|
61
|
+
".ogg",
|
|
62
|
+
".flac",
|
|
63
|
+
".aiff",
|
|
64
|
+
".wma",
|
|
65
|
+
]);
|
|
66
|
+
|
|
67
|
+
/** Max file size for a single STT chunk request (25MB). */
|
|
68
|
+
const STT_CHUNK_MAX_BYTES = 25 * 1024 * 1024;
|
|
69
|
+
|
|
70
|
+
/** Duration per chunk when splitting for large files (10 minutes). */
|
|
71
|
+
const CHUNK_DURATION_SECS = 600;
|
|
72
|
+
|
|
73
|
+
/** Timeout for a single STT transcription request. */
|
|
74
|
+
const STT_REQUEST_TIMEOUT_MS = 300_000;
|
|
75
|
+
|
|
76
|
+
async function getAudioDuration(audioPath: string): Promise<number> {
|
|
77
|
+
const result = await spawnWithTimeout(
|
|
78
|
+
[
|
|
79
|
+
"ffprobe",
|
|
80
|
+
"-v",
|
|
81
|
+
"error",
|
|
82
|
+
"-show_entries",
|
|
83
|
+
"format=duration",
|
|
84
|
+
"-of",
|
|
85
|
+
"csv=p=0",
|
|
86
|
+
audioPath,
|
|
87
|
+
],
|
|
88
|
+
FFPROBE_TIMEOUT_MS,
|
|
89
|
+
);
|
|
90
|
+
if (result.exitCode !== 0) return 0;
|
|
91
|
+
return parseFloat(result.stdout.trim()) || 0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function splitAudio(
|
|
95
|
+
audioPath: string,
|
|
96
|
+
chunkDir: string,
|
|
97
|
+
chunkDurationSecs: number,
|
|
98
|
+
): Promise<string[]> {
|
|
99
|
+
const chunkPattern = join(chunkDir, "chunk-%03d.wav");
|
|
100
|
+
const result = await spawnWithTimeout(
|
|
101
|
+
[
|
|
102
|
+
"ffmpeg",
|
|
103
|
+
"-y",
|
|
104
|
+
"-i",
|
|
105
|
+
audioPath,
|
|
106
|
+
"-f",
|
|
107
|
+
"segment",
|
|
108
|
+
"-segment_time",
|
|
109
|
+
String(chunkDurationSecs),
|
|
110
|
+
"-acodec",
|
|
111
|
+
"pcm_s16le",
|
|
112
|
+
"-ar",
|
|
113
|
+
"16000",
|
|
114
|
+
"-ac",
|
|
115
|
+
"1",
|
|
116
|
+
chunkPattern,
|
|
117
|
+
],
|
|
118
|
+
FFMPEG_TRANSCODE_TIMEOUT_MS,
|
|
119
|
+
);
|
|
120
|
+
if (result.exitCode !== 0) {
|
|
121
|
+
throw new Error(`Failed to split audio: ${result.stderr.slice(0, 300)}`);
|
|
122
|
+
}
|
|
123
|
+
const files = await readdir(chunkDir);
|
|
124
|
+
return files
|
|
125
|
+
.filter((f) => f.startsWith("chunk-") && f.endsWith(".wav"))
|
|
126
|
+
.sort()
|
|
127
|
+
.map((f) => join(chunkDir, f));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Convert source to 16kHz mono WAV for consistent processing. */
|
|
131
|
+
async function toWav(inputPath: string, isVideo: boolean): Promise<string> {
|
|
132
|
+
const wavPath = join(tmpdir(), `vellum-transcribe-${randomUUID()}.wav`);
|
|
133
|
+
const args = ["ffmpeg", "-y", "-i", inputPath];
|
|
134
|
+
if (isVideo) args.push("-vn");
|
|
135
|
+
args.push("-acodec", "pcm_s16le", "-ar", "16000", "-ac", "1", wavPath);
|
|
136
|
+
const result = await spawnWithTimeout(args, FFMPEG_TRANSCODE_TIMEOUT_MS);
|
|
137
|
+
if (result.exitCode !== 0) {
|
|
138
|
+
throw new Error(`ffmpeg failed: ${result.stderr.slice(0, 500)}`);
|
|
139
|
+
}
|
|
140
|
+
return wavPath;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function transcribeWithProvider(
|
|
144
|
+
audioPath: string,
|
|
145
|
+
transcriber: BatchTranscriber,
|
|
146
|
+
): Promise<string> {
|
|
147
|
+
const duration = await getAudioDuration(audioPath);
|
|
148
|
+
const fileSize = Bun.file(audioPath).size;
|
|
149
|
+
|
|
150
|
+
// If small enough, send directly
|
|
151
|
+
if (fileSize <= STT_CHUNK_MAX_BYTES) {
|
|
152
|
+
const audioBuffer = await readFile(audioPath);
|
|
153
|
+
const result = await transcriber.transcribe({
|
|
154
|
+
audio: audioBuffer,
|
|
155
|
+
mimeType: "audio/wav",
|
|
156
|
+
signal: AbortSignal.timeout(STT_REQUEST_TIMEOUT_MS),
|
|
157
|
+
});
|
|
158
|
+
return result.text;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Split into chunks for large files
|
|
162
|
+
const chunkDir = join(tmpdir(), `vellum-transcribe-chunks-${randomUUID()}`);
|
|
163
|
+
await mkdir(chunkDir, { recursive: true });
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
process.stderr.write(
|
|
167
|
+
`Large file (${Math.round(duration / 60)}min) - splitting into chunks...\n`,
|
|
168
|
+
);
|
|
169
|
+
const chunks = await splitAudio(audioPath, chunkDir, CHUNK_DURATION_SECS);
|
|
170
|
+
const parts: string[] = [];
|
|
171
|
+
|
|
172
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
173
|
+
process.stderr.write(
|
|
174
|
+
` Transcribing chunk ${i + 1}/${chunks.length}...\n`,
|
|
175
|
+
);
|
|
176
|
+
const audioBuffer = await readFile(chunks[i]);
|
|
177
|
+
const result = await transcriber.transcribe({
|
|
178
|
+
audio: audioBuffer,
|
|
179
|
+
mimeType: "audio/wav",
|
|
180
|
+
signal: AbortSignal.timeout(STT_REQUEST_TIMEOUT_MS),
|
|
181
|
+
});
|
|
182
|
+
if (result.text) parts.push(result.text);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return parts.join(" ");
|
|
186
|
+
} finally {
|
|
187
|
+
await rm(chunkDir, { recursive: true, force: true }).catch(() => {});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
31
191
|
// ---------------------------------------------------------------------------
|
|
32
192
|
// Error category → RouteError mapping
|
|
33
193
|
// ---------------------------------------------------------------------------
|
|
@@ -156,6 +316,63 @@ async function handleTranscribe({ body }: RouteHandlerArgs) {
|
|
|
156
316
|
}
|
|
157
317
|
}
|
|
158
318
|
|
|
319
|
+
async function handleTranscribeFile({ body }: RouteHandlerArgs) {
|
|
320
|
+
const filePath = body?.filePath;
|
|
321
|
+
if (typeof filePath !== "string" || !filePath) {
|
|
322
|
+
throw new BadRequestError("filePath is required");
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
try {
|
|
326
|
+
await access(filePath);
|
|
327
|
+
} catch {
|
|
328
|
+
throw new BadRequestError(`File not found: ${filePath}`);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const ext = extname(filePath).toLowerCase();
|
|
332
|
+
const isVideo = VIDEO_EXTENSIONS.has(ext);
|
|
333
|
+
const isAudio = AUDIO_EXTENSIONS.has(ext);
|
|
334
|
+
if (!isVideo && !isAudio) {
|
|
335
|
+
throw new BadRequestError(
|
|
336
|
+
`Unsupported file type: ${ext}. Only audio and video files can be transcribed.`,
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
let transcriber;
|
|
341
|
+
try {
|
|
342
|
+
transcriber = await resolveBatchTranscriber();
|
|
343
|
+
} catch (err) {
|
|
344
|
+
log.error({ err }, "Failed to resolve STT transcriber");
|
|
345
|
+
throw new ServiceUnavailableError("STT provider is not available");
|
|
346
|
+
}
|
|
347
|
+
if (!transcriber) {
|
|
348
|
+
throw new ServiceUnavailableError(
|
|
349
|
+
"No speech-to-text provider is configured",
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const startTime = Date.now();
|
|
354
|
+
let wavPath: string | null = null;
|
|
355
|
+
try {
|
|
356
|
+
wavPath = await toWav(filePath, isVideo);
|
|
357
|
+
const text = await transcribeWithProvider(wavPath, transcriber);
|
|
358
|
+
const durationSeconds = (Date.now() - startTime) / 1000;
|
|
359
|
+
return {
|
|
360
|
+
transcript: text,
|
|
361
|
+
provider: transcriber.providerId,
|
|
362
|
+
durationSeconds,
|
|
363
|
+
};
|
|
364
|
+
} catch (err) {
|
|
365
|
+
log.error({ err, filePath }, "File transcription failed");
|
|
366
|
+
throw new BadGatewayError(
|
|
367
|
+
err instanceof Error ? err.message : "Transcription failed",
|
|
368
|
+
);
|
|
369
|
+
} finally {
|
|
370
|
+
if (wavPath) {
|
|
371
|
+
await unlink(wavPath).catch(() => {});
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
159
376
|
// ---------------------------------------------------------------------------
|
|
160
377
|
// Route definitions
|
|
161
378
|
// ---------------------------------------------------------------------------
|
|
@@ -220,4 +437,24 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
220
437
|
}),
|
|
221
438
|
handler: handleTranscribe,
|
|
222
439
|
},
|
|
440
|
+
{
|
|
441
|
+
operationId: "stt_transcribe_file",
|
|
442
|
+
endpoint: "stt/transcribe-file",
|
|
443
|
+
method: "POST",
|
|
444
|
+
policyKey: "stt/transcribe-file",
|
|
445
|
+
requirePolicyEnforcement: true,
|
|
446
|
+
summary: "Transcribe audio/video file to text",
|
|
447
|
+
description:
|
|
448
|
+
"Transcribe an audio or video file to text using the configured STT provider. Handles ffmpeg conversion, large-file chunking, and sequential chunk transcription.",
|
|
449
|
+
tags: ["stt"],
|
|
450
|
+
requestBody: z.object({
|
|
451
|
+
filePath: z.string().describe("Absolute path to the audio or video file"),
|
|
452
|
+
}),
|
|
453
|
+
responseBody: z.object({
|
|
454
|
+
transcript: z.string(),
|
|
455
|
+
provider: z.string(),
|
|
456
|
+
durationSeconds: z.number(),
|
|
457
|
+
}),
|
|
458
|
+
handler: handleTranscribeFile,
|
|
459
|
+
},
|
|
223
460
|
];
|
|
@@ -11,10 +11,13 @@ import { z } from "zod";
|
|
|
11
11
|
|
|
12
12
|
import type { ChannelId } from "../../channels/types.js";
|
|
13
13
|
import { isHttpAuthDisabled } from "../../config/env.js";
|
|
14
|
+
import type { Conversation } from "../../daemon/conversation.js";
|
|
14
15
|
import {
|
|
15
16
|
findConversation,
|
|
16
17
|
findConversationBySurfaceId,
|
|
18
|
+
getOrCreateConversation,
|
|
17
19
|
} from "../../daemon/conversation-store.js";
|
|
20
|
+
import { rawGet } from "../../memory/raw-query.js";
|
|
18
21
|
import { getLogger } from "../../util/logger.js";
|
|
19
22
|
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../assistant-scope.js";
|
|
20
23
|
import { healGuardianBindingDrift } from "../guardian-vellum-migration.js";
|
|
@@ -87,6 +90,37 @@ function applyTrustContext(
|
|
|
87
90
|
}
|
|
88
91
|
}
|
|
89
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Resolve the conversation owning a surface, rehydrating from the DB when
|
|
95
|
+
* the in-memory lookup misses (daemon restart or LRU eviction). The DB scan
|
|
96
|
+
* is also the source of truth that the surface exists — without it,
|
|
97
|
+
* `getOrCreateConversation` would silently create a phantom conversation
|
|
98
|
+
* for any caller-supplied id.
|
|
99
|
+
*/
|
|
100
|
+
async function resolveSurfaceConversation(
|
|
101
|
+
conversationId: string | null | undefined,
|
|
102
|
+
surfaceId: string,
|
|
103
|
+
): Promise<Conversation | undefined> {
|
|
104
|
+
const found = conversationId
|
|
105
|
+
? findConversation(conversationId)
|
|
106
|
+
: findConversationBySurfaceId(surfaceId);
|
|
107
|
+
if (found) return found;
|
|
108
|
+
|
|
109
|
+
// Escape LIKE wildcards so a `surfaceId` like "%" or "_" can't match
|
|
110
|
+
// unrelated rows.
|
|
111
|
+
const escaped = surfaceId.replace(/[\\%_]/g, "\\$&");
|
|
112
|
+
const row = rawGet<{ conversation_id: string }>(
|
|
113
|
+
`SELECT conversation_id FROM messages
|
|
114
|
+
WHERE content LIKE ? ESCAPE '\\'
|
|
115
|
+
ORDER BY created_at DESC
|
|
116
|
+
LIMIT 1`,
|
|
117
|
+
`%"surfaceId":"${escaped}"%`,
|
|
118
|
+
);
|
|
119
|
+
if (!row) return undefined;
|
|
120
|
+
if (conversationId && conversationId !== row.conversation_id) return undefined;
|
|
121
|
+
return await getOrCreateConversation(row.conversation_id);
|
|
122
|
+
}
|
|
123
|
+
|
|
90
124
|
// ---------------------------------------------------------------------------
|
|
91
125
|
// Handlers
|
|
92
126
|
// ---------------------------------------------------------------------------
|
|
@@ -113,9 +147,10 @@ async function handleSurfaceAction({
|
|
|
113
147
|
throw new BadRequestError("conversationId must be a string");
|
|
114
148
|
}
|
|
115
149
|
|
|
116
|
-
const conversation =
|
|
117
|
-
|
|
118
|
-
|
|
150
|
+
const conversation = await resolveSurfaceConversation(
|
|
151
|
+
conversationId,
|
|
152
|
+
surfaceId,
|
|
153
|
+
);
|
|
119
154
|
|
|
120
155
|
if (!conversation) {
|
|
121
156
|
throw new NotFoundError("No active conversation found");
|
|
@@ -175,7 +210,7 @@ async function handleSurfaceAction({
|
|
|
175
210
|
}
|
|
176
211
|
}
|
|
177
212
|
|
|
178
|
-
function handleSurfaceUndo({ body, pathParams }: RouteHandlerArgs) {
|
|
213
|
+
async function handleSurfaceUndo({ body, pathParams }: RouteHandlerArgs) {
|
|
179
214
|
const surfaceId = pathParams?.id;
|
|
180
215
|
if (!surfaceId) {
|
|
181
216
|
throw new BadRequestError("surfaceId path parameter is required");
|
|
@@ -186,9 +221,10 @@ function handleSurfaceUndo({ body, pathParams }: RouteHandlerArgs) {
|
|
|
186
221
|
throw new BadRequestError("conversationId must be a string");
|
|
187
222
|
}
|
|
188
223
|
|
|
189
|
-
const conversation =
|
|
190
|
-
|
|
191
|
-
|
|
224
|
+
const conversation = await resolveSurfaceConversation(
|
|
225
|
+
conversationId,
|
|
226
|
+
surfaceId,
|
|
227
|
+
);
|
|
192
228
|
|
|
193
229
|
if (!conversation) {
|
|
194
230
|
throw new NotFoundError("No active conversation found");
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
TtsSynthesisError,
|
|
21
21
|
} from "../../tts/synthesize-text.js";
|
|
22
22
|
import { resolveTtsConfig } from "../../tts/tts-config-resolver.js";
|
|
23
|
+
import type { TtsUseCase } from "../../tts/types.js";
|
|
23
24
|
import { getLogger } from "../../util/logger.js";
|
|
24
25
|
import {
|
|
25
26
|
BadGatewayError,
|
|
@@ -155,6 +156,45 @@ async function handleSynthesizeTts({ body }: RouteHandlerArgs) {
|
|
|
155
156
|
return doSynthesize(sanitizedText, { context: body.context });
|
|
156
157
|
}
|
|
157
158
|
|
|
159
|
+
async function handleSynthesizeCliTts({ body }: RouteHandlerArgs) {
|
|
160
|
+
if (!body?.text || typeof body.text !== "string") {
|
|
161
|
+
throw new BadRequestError("text is required");
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const sanitizedText = sanitizeForTts(body.text).trim();
|
|
165
|
+
if (!sanitizedText) {
|
|
166
|
+
throw new BadRequestError(
|
|
167
|
+
"Text has no speakable content after sanitization",
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const useCase: TtsUseCase =
|
|
172
|
+
(body.useCase as TtsUseCase | undefined) ?? "message-playback";
|
|
173
|
+
const voiceId =
|
|
174
|
+
body.voiceId && typeof body.voiceId === "string"
|
|
175
|
+
? body.voiceId
|
|
176
|
+
: undefined;
|
|
177
|
+
|
|
178
|
+
try {
|
|
179
|
+
const result = await synthesizeText({ text: sanitizedText, useCase, voiceId });
|
|
180
|
+
return {
|
|
181
|
+
audioBase64: Buffer.from(result.audio).toString("base64"),
|
|
182
|
+
contentType: result.contentType,
|
|
183
|
+
};
|
|
184
|
+
} catch (err) {
|
|
185
|
+
log.error({ err }, "TTS CLI synthesis failed");
|
|
186
|
+
|
|
187
|
+
if (
|
|
188
|
+
err instanceof TtsSynthesisError &&
|
|
189
|
+
err.code === "TTS_PROVIDER_NOT_CONFIGURED"
|
|
190
|
+
) {
|
|
191
|
+
throw new ServiceUnavailableError("TTS provider is not configured");
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
throw new BadGatewayError("TTS synthesis failed");
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
158
198
|
// ---------------------------------------------------------------------------
|
|
159
199
|
// Route definitions
|
|
160
200
|
// ---------------------------------------------------------------------------
|
|
@@ -206,4 +246,31 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
206
246
|
responseHeaders: ttsResponseHeaders,
|
|
207
247
|
handler: handleSynthesizeTts,
|
|
208
248
|
},
|
|
249
|
+
{
|
|
250
|
+
operationId: "tts_synthesize_cli",
|
|
251
|
+
endpoint: "tts/synthesize-cli",
|
|
252
|
+
method: "POST",
|
|
253
|
+
policyKey: "tts/synthesize-cli",
|
|
254
|
+
requirePolicyEnforcement: true,
|
|
255
|
+
summary: "Synthesize text to speech (CLI)",
|
|
256
|
+
description:
|
|
257
|
+
"Synthesize arbitrary text to audio. Returns base64-encoded audio + content type for CLI consumption.",
|
|
258
|
+
tags: ["tts"],
|
|
259
|
+
requestBody: z.object({
|
|
260
|
+
text: z.string().describe("Text to synthesize into speech"),
|
|
261
|
+
useCase: z
|
|
262
|
+
.enum(["message-playback", "phone-call"])
|
|
263
|
+
.optional()
|
|
264
|
+
.default("message-playback"),
|
|
265
|
+
voiceId: z
|
|
266
|
+
.string()
|
|
267
|
+
.optional()
|
|
268
|
+
.describe("Provider-specific voice identifier override"),
|
|
269
|
+
}),
|
|
270
|
+
responseBody: z.object({
|
|
271
|
+
audioBase64: z.string().describe("Base64-encoded audio bytes"),
|
|
272
|
+
contentType: z.string().describe("MIME type of the audio (e.g. audio/mpeg)"),
|
|
273
|
+
}),
|
|
274
|
+
handler: handleSynthesizeCliTts,
|
|
275
|
+
},
|
|
209
276
|
];
|
|
@@ -136,4 +136,36 @@ export interface RouteDefinition {
|
|
|
136
136
|
* RouteError subclasses rather than explicit Response objects.
|
|
137
137
|
*/
|
|
138
138
|
additionalResponses?: Record<string, { description: string }>;
|
|
139
|
+
/**
|
|
140
|
+
* When true, the route expects a raw binary body (e.g. file uploads).
|
|
141
|
+
* The HTTP adapter already reads `rawBody` for non-JSON content types;
|
|
142
|
+
* this flag is a declarative signal for documentation and tooling.
|
|
143
|
+
*/
|
|
144
|
+
rawBody?: boolean;
|
|
145
|
+
/**
|
|
146
|
+
* Per-route request-log control. Routes that opt in can suppress the
|
|
147
|
+
* per-request INFO log line after a confirmed run of successful
|
|
148
|
+
* responses — useful for high-frequency probes like `/v1/health` where
|
|
149
|
+
* the first few responses confirm the route works and every line after
|
|
150
|
+
* that is just noise. Non-success responses (status >= 400) always log.
|
|
151
|
+
*/
|
|
152
|
+
logging?: RouteLoggingConfig;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Logging behavior for a single route. Currently only the success-suppression
|
|
157
|
+
* counter is supported; new knobs (sampling, periodic summary lines) can be
|
|
158
|
+
* added here as separate fields without changing call sites.
|
|
159
|
+
*/
|
|
160
|
+
export interface RouteLoggingConfig {
|
|
161
|
+
/**
|
|
162
|
+
* After this many successful (status < 400) responses, suppress the
|
|
163
|
+
* per-request INFO log line for further successful responses on the
|
|
164
|
+
* same route (keyed by `operationId`, so all path-param variants
|
|
165
|
+
* share a single counter).
|
|
166
|
+
*
|
|
167
|
+
* Counters are process-local and reset on restart. Warning (4xx) and
|
|
168
|
+
* error (5xx) log lines are always emitted regardless of this setting.
|
|
169
|
+
*/
|
|
170
|
+
silenceSuccessAfter?: number;
|
|
139
171
|
}
|