@vellumai/assistant 0.9.0 → 0.10.0-staging.2
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/ARCHITECTURE.md +18 -34
- package/bun.lock +7 -8
- package/docs/activation-funnel-telemetry.md +28 -22
- package/docs/architecture/security.md +29 -28
- package/docs/stt-provider-onboarding.md +3 -5
- package/docs/workflows-testing.md +13 -44
- package/docs/workflows.md +3 -5
- package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +47 -0
- package/node_modules/@vellumai/ces-client/src/rpc-client.ts +28 -5
- package/node_modules/@vellumai/environments/src/seeds.ts +2 -5
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +97 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +32 -6
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +119 -0
- package/node_modules/@vellumai/gateway-client/src/types.ts +15 -84
- package/openapi.yaml +976 -63
- package/package.json +2 -1
- package/scripts/sync-llm-catalog.ts +6 -15
- package/scripts/sync-web-search-catalog.ts +3 -11
- package/src/__tests__/access-request-card-view.test.ts +98 -0
- package/src/__tests__/access-request-seed-content-blocks.test.ts +2 -4
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +72 -32
- package/src/__tests__/agent-loop-compaction-strip.test.ts +241 -0
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +16 -13
- package/src/__tests__/agent-loop-output-hooks.test.ts +69 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +25 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -3
- package/src/__tests__/app-compiler.test.ts +15 -1
- package/src/__tests__/app-dir-path-guard.test.ts +0 -1
- package/src/__tests__/assistant-feature-flag-guard.test.ts +1 -4
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
- package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
- package/src/__tests__/avatar-identity-sync.test.ts +2 -27
- package/src/__tests__/btw-routes.test.ts +6 -8
- package/src/__tests__/call-pointer-messages.test.ts +28 -0
- package/src/__tests__/cancel-clears-processing.test.ts +89 -0
- package/src/__tests__/channel-approval-routes.test.ts +0 -4
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
- package/src/__tests__/checker.test.ts +0 -3
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
- package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
- package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
- package/src/__tests__/config-loader-backfill.test.ts +268 -27
- package/src/__tests__/config-schema.test.ts +35 -0
- package/src/__tests__/config-watcher.test.ts +0 -18
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
- package/src/__tests__/contact-store-user-file.test.ts +0 -6
- package/src/__tests__/contacts-tools.test.ts +29 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop.test.ts +58 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
- package/src/__tests__/conversation-lifecycle.test.ts +7 -9
- package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
- package/src/__tests__/conversation-title-service.test.ts +62 -0
- package/src/__tests__/credential-broker.test.ts +449 -1
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
- package/src/__tests__/credential-execution-tools.test.ts +0 -1
- package/src/__tests__/credential-prompt-route.test.ts +4 -4
- package/src/__tests__/credential-routes.test.ts +360 -0
- package/src/__tests__/credential-security-invariants.test.ts +4 -13
- package/src/__tests__/disk-pressure-policy.test.ts +12 -0
- package/src/__tests__/disk-usage.test.ts +65 -0
- package/src/__tests__/dynamic-page-surface.test.ts +152 -1
- package/src/__tests__/fixtures/credential-security-fixtures.ts +2 -33
- package/src/__tests__/gateway-flag-listener.test.ts +110 -1
- package/src/__tests__/gateway-only-guard.test.ts +3 -7
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
- package/src/__tests__/guardian-grant-minting.test.ts +3 -35
- package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
- package/src/__tests__/guardian-routing-state.test.ts +0 -1
- package/src/__tests__/headless-browser-mode.test.ts +10 -0
- package/src/__tests__/headless-browser-navigate.test.ts +8 -3
- package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
- package/src/__tests__/host-browser-proxy.test.ts +87 -0
- package/src/__tests__/identity-routes.test.ts +0 -189
- package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
- package/src/__tests__/injector-v3-suppression.test.ts +27 -20
- package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
- package/src/__tests__/invite-redemption-service.test.ts +4 -7
- package/src/__tests__/llm-callsite-catalog.test.ts +5 -6
- package/src/__tests__/llm-catalog-parity.test.ts +30 -23
- package/src/__tests__/llm-resolver.test.ts +70 -24
- package/src/__tests__/llm-schema.test.ts +1 -0
- package/src/__tests__/managed-profile-guard.test.ts +163 -4
- package/src/__tests__/mcp-health-check.test.ts +6 -7
- package/src/__tests__/media-stream-server-integration.test.ts +317 -13
- package/src/__tests__/oauth-provider-seed-logos.test.ts +4 -6
- package/src/__tests__/onboarding-persona-write.test.ts +1 -1
- package/src/__tests__/path-policy.test.ts +34 -0
- package/src/__tests__/persona-resolver.test.ts +49 -14
- package/src/__tests__/plugin-api-model-profiles.test.ts +178 -0
- package/src/__tests__/plugin-api-provider.test.ts +24 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
- package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
- package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
- package/src/__tests__/reaction-persistence.test.ts +150 -29
- package/src/__tests__/registry.test.ts +2 -7
- package/src/__tests__/relay-server.test.ts +285 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -10
- package/src/__tests__/schedule-routes.test.ts +0 -30
- package/src/__tests__/schedule-tools.test.ts +2 -18
- package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
- package/src/__tests__/skill-execute-input.test.ts +51 -1
- package/src/__tests__/skill-runtime-path.test.ts +2 -3
- package/src/__tests__/skills.test.ts +51 -0
- package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
- package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
- package/src/__tests__/subagent-tools.test.ts +266 -0
- package/src/__tests__/surface-completion-nudge-hook.test.ts +367 -0
- package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
- package/src/__tests__/title-generate-hook.test.ts +100 -3
- package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +1 -29
- package/src/__tests__/token-manager.test.ts +519 -0
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
- package/src/__tests__/tool-audit-listener.test.ts +7 -7
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
- package/src/__tests__/tool-executor.test.ts +0 -79
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
- package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
- package/src/__tests__/trusted-contact-verification.test.ts +8 -10
- package/src/__tests__/twilio-routes.test.ts +81 -1
- package/src/__tests__/voice-invite-redemption.test.ts +2 -3
- package/src/__tests__/weak-open-model.test.ts +30 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +6 -25
- package/src/__tests__/workspace-greetings.test.ts +152 -0
- package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
- package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
- package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
- package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
- package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
- package/src/agent/loop.ts +49 -29
- package/src/api/README.md +6 -6
- package/src/api/events/tool-result.ts +6 -0
- package/src/api/events/workflow-completed.ts +53 -0
- package/src/api/events/workflow-leaf-finished.ts +38 -0
- package/src/api/events/workflow-leaf-started.ts +35 -0
- package/src/api/events/workflow-progress.ts +32 -0
- package/src/api/events/workflow-started.ts +31 -0
- package/src/api/index.ts +40 -0
- package/src/api/responses/conversation-message.ts +28 -4
- package/src/api/responses/home.ts +26 -4
- package/src/api/responses/workflow-journal.ts +53 -0
- package/src/approvals/guardian-card-withdrawal.ts +145 -0
- package/src/approvals/guardian-decision-primitive.ts +26 -3
- package/src/approvals/guardian-request-resolvers.ts +183 -80
- package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
- package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
- package/src/calls/call-pointer-messages.ts +10 -4
- package/src/calls/channel-admission-reader.ts +104 -0
- package/src/calls/guardian-dispatch.ts +17 -45
- package/src/calls/media-stream-server.ts +84 -2
- package/src/calls/relay-access-wait.ts +1 -1
- package/src/calls/relay-server.ts +66 -0
- package/src/calls/relay-setup-router.ts +82 -1
- package/src/calls/twilio-routes.ts +17 -8
- package/src/calls/voice-session-bridge.ts +2 -2
- package/src/cli/commands/clients.ts +3 -0
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
- package/src/cli/commands/memory/index.ts +30 -0
- package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
- package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
- package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
- package/src/cli/commands/oauth/status.test.ts +36 -0
- package/src/cli/commands/oauth/status.ts +23 -3
- package/src/cli/commands/plugins.ts +197 -4
- package/src/cli/lib/__tests__/diff-plugin.test.ts +443 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
- package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +443 -0
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +295 -2
- package/src/cli/lib/diff-plugin.ts +346 -0
- package/src/cli/lib/inspect-plugin.ts +12 -1
- package/src/cli/lib/install-from-github.ts +105 -17
- package/src/cli/lib/merge-plugin-tree.ts +328 -0
- package/src/cli/lib/plugin-fingerprint.ts +14 -0
- package/src/cli/lib/plugin-surfaces.ts +104 -0
- package/src/cli/lib/upgrade-plugin.ts +298 -10
- package/src/cli/program.ts +2 -6
- package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
- package/src/config/assistant-feature-flags.ts +22 -7
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
- package/src/config/bundled-skills/messaging/SKILL.md +6 -4
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
- package/src/config/bundled-skills/subagent/SKILL.md +4 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +4 -0
- package/src/config/bundled-skills/workflows/SKILL.md +14 -8
- package/src/config/bundled-tool-registry.ts +2 -7
- package/src/config/call-site-defaults.ts +15 -2
- package/src/config/feature-flag-registry.json +46 -31
- package/src/config/inference-profile-validation.ts +26 -0
- package/src/config/llm-resolver.ts +3 -0
- package/src/config/loader.ts +4 -0
- package/src/config/memory-v3-gate.ts +11 -0
- package/src/config/profile-order.ts +28 -0
- package/src/config/schema.ts +8 -6
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +7 -0
- package/src/config/schemas/channels.ts +11 -0
- package/src/config/schemas/elevenlabs.ts +0 -1
- package/src/config/schemas/llm.ts +31 -0
- package/src/config/schemas/memory-lifecycle.ts +3 -7
- package/src/config/schemas/memory-v3.ts +6 -0
- package/src/config/schemas/platform.ts +0 -8
- package/src/config/schemas/services.ts +18 -0
- package/src/config/seed-inference-profiles.ts +109 -44
- package/src/config/skills.ts +21 -0
- package/src/config/sync-gated-profiles.ts +220 -0
- package/src/contacts/contact-store.ts +89 -106
- package/src/contacts/contacts-write.ts +5 -22
- package/src/contacts/types.ts +0 -1
- package/src/context/compactor.ts +88 -54
- package/src/context/strip-injections.ts +58 -10
- package/src/context/token-estimator.ts +1 -1
- package/src/credential-execution/process-manager.ts +55 -14
- package/src/credential-execution/prompted-credential.ts +2 -3
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
- package/src/daemon/config-watcher.ts +0 -4
- package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
- package/src/daemon/conversation-agent-loop.ts +114 -22
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-lifecycle.ts +3 -5
- package/src/daemon/conversation-process.ts +13 -5
- package/src/daemon/conversation-runtime-assembly.ts +13 -15
- package/src/daemon/conversation-slash.ts +2 -23
- package/src/daemon/conversation-surfaces.ts +26 -0
- package/src/daemon/conversation-tool-setup.ts +27 -14
- package/src/daemon/conversation.ts +66 -14
- package/src/daemon/disk-pressure-policy.ts +5 -3
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
- package/src/daemon/handlers/config-a2a.ts +0 -2
- package/src/daemon/handlers/config-channels.ts +15 -16
- package/src/daemon/handlers/config-slack-channel.ts +22 -3
- package/src/daemon/handlers/conversations.ts +107 -0
- package/src/daemon/host-browser-proxy.ts +41 -0
- package/src/daemon/lifecycle.ts +55 -27
- package/src/daemon/message-provenance.ts +2 -0
- package/src/daemon/message-types/contacts.ts +0 -1
- package/src/daemon/message-types/conversations.ts +3 -3
- package/src/daemon/message-types/sync.ts +0 -1
- package/src/daemon/message-types/web-activity.ts +7 -1
- package/src/daemon/message-types/workflows.ts +83 -1
- package/src/daemon/orphan-reaper.test.ts +0 -19
- package/src/daemon/orphan-reaper.ts +2 -24
- package/src/daemon/server.ts +0 -10
- package/src/daemon/tool-setup-types.ts +4 -0
- package/src/daemon/trust-context.ts +1 -1
- package/src/events/tool-audit-listener.ts +2 -2
- package/src/home/feed-source-enrichment.test.ts +151 -0
- package/src/home/feed-source-enrichment.ts +176 -0
- package/src/home/relationship-state.ts +2 -4
- package/src/instrument.ts +18 -6
- package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
- package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
- package/src/ipc/assistant-server.ts +37 -4
- package/src/ipc/gateway-flag-listener.ts +18 -2
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
- package/src/memory/__tests__/memory-retrospective-job.test.ts +229 -401
- package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
- package/src/memory/auth-fallback-events-store.ts +2 -2
- package/src/memory/auto-analysis-enqueue.ts +3 -5
- package/src/memory/bookmark-crud.ts +1 -2
- package/src/memory/canonical-guardian-store.ts +39 -1
- package/src/memory/conversation-crud.ts +9 -4
- package/src/memory/conversation-key-store.ts +17 -2
- package/src/memory/conversation-title-service.ts +64 -7
- package/src/memory/db-init.ts +17 -17
- package/src/memory/embedding-backend.ts +38 -1
- package/src/memory/embedding-billing-breaker.ts +96 -0
- package/src/memory/jobs-store.ts +25 -13
- package/src/memory/jobs-worker.ts +54 -1
- package/src/memory/lifecycle-events-store.ts +2 -2
- package/src/memory/memory-retrospective-constants.ts +4 -4
- package/src/memory/memory-retrospective-enqueue.ts +31 -6
- package/src/memory/memory-retrospective-job.ts +28 -227
- package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
- package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
- package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
- package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +72 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
- package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
- package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
- package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
- package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
- package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
- package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +341 -0
- package/src/memory/migrations/__tests__/run-migrations.test.ts +52 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/run-migrations.ts +41 -0
- package/src/memory/migrations/validate-migration-state.ts +1 -1
- package/src/memory/onboarding-events-store.ts +3 -3
- package/src/memory/schema/contacts.ts +0 -5
- package/src/memory/skill-loaded-events-store.test.ts +7 -15
- package/src/memory/skill-loaded-events-store.ts +2 -2
- package/src/memory/tool-executed-events-store.test.ts +7 -7
- package/src/memory/turn-trace-store.test.ts +736 -0
- package/src/memory/turn-trace-store.ts +364 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
- package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
- package/src/memory/v2/consolidation-job.ts +2 -2
- package/src/memory/v2/skill-content.ts +25 -7
- package/src/memory/v2/skill-store.ts +7 -1
- package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
- package/src/memory/v3-eval/eval-packets.ts +546 -0
- package/src/messaging/providers/slack/adapter.ts +1 -1
- package/src/messaging/providers/slack/api.ts +31 -0
- package/src/messaging/providers/slack/send.test.ts +114 -2
- package/src/messaging/providers/slack/send.ts +30 -7
- package/src/messaging/providers/slack/withdraw.test.ts +200 -0
- package/src/messaging/providers/slack/withdraw.ts +161 -0
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/access-request-copy.ts +72 -59
- package/src/notifications/adapters/shared.ts +29 -0
- package/src/notifications/adapters/slack.ts +58 -103
- package/src/notifications/adapters/telegram.ts +2 -20
- package/src/notifications/approval-card-data.ts +333 -0
- package/src/notifications/broadcaster.ts +16 -3
- package/src/notifications/canonical-delivery-recorder.ts +139 -0
- package/src/notifications/copy-composer.ts +3 -3
- package/src/notifications/decision-engine.ts +4 -2
- package/src/notifications/destination-resolver.ts +4 -6
- package/src/notifications/guardian-question-mode.ts +10 -0
- package/src/notifications/home-feed-side-effect.ts +7 -16
- package/src/notifications/notification-utils.ts +19 -20
- package/src/notifications/signal.ts +79 -43
- package/src/notifications/types.ts +98 -121
- package/src/oauth/AGENTS.md +5 -24
- package/src/permissions/checker.test.ts +51 -0
- package/src/permissions/checker.ts +185 -26
- package/src/permissions/ipc-risk-types.ts +24 -0
- package/src/permissions/question-prompter.test.ts +27 -0
- package/src/permissions/question-prompter.ts +4 -0
- package/src/platform/client.test.ts +119 -0
- package/src/platform/client.ts +66 -0
- package/src/platform/consent-cache.test.ts +267 -0
- package/src/platform/consent-cache.ts +174 -0
- package/src/plugin-api/constants.ts +1 -1
- package/src/plugin-api/index.ts +33 -1
- package/src/plugin-api/model-profiles.ts +33 -0
- package/src/plugin-api/types.ts +50 -2
- package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
- package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
- package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
- package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
- package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
- package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
- package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
- package/src/plugins/defaults/advisor/config.ts +21 -0
- package/src/plugins/defaults/advisor/consult.ts +93 -0
- package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
- package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
- package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/advisor/package.json +14 -0
- package/src/plugins/defaults/advisor/steering.ts +67 -0
- package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
- package/src/plugins/defaults/advisor/transcript.ts +76 -0
- package/src/plugins/defaults/index.ts +60 -0
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
- package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +129 -9
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +144 -11
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
- package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +276 -0
- package/src/plugins/defaults/surface-completion-nudge/hooks/stop.ts +22 -0
- package/src/plugins/defaults/surface-completion-nudge/nudge-state-store.ts +46 -0
- package/src/plugins/defaults/surface-completion-nudge/package.json +14 -0
- package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +3 -13
- package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
- package/src/prompts/persona-resolver.ts +14 -4
- package/src/prompts/templates/system-sections.ts +7 -2
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
- package/src/providers/__tests__/retry-callsite.test.ts +176 -0
- package/src/providers/atlascloud/client.ts +85 -0
- package/src/providers/fetch-provider-catalog.ts +85 -0
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/model-catalog.ts +58 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
- package/src/providers/openai/chat-completions-provider.ts +7 -0
- package/src/providers/openai/responses-provider.ts +10 -0
- package/src/providers/provider-send-message.ts +11 -3
- package/src/providers/retry.ts +53 -12
- package/src/providers/search-provider-catalog.ts +10 -0
- package/src/providers/weak-open-model.ts +22 -0
- package/src/runtime/AGENTS.md +0 -1
- package/src/runtime/__tests__/agent-wake.test.ts +181 -0
- package/src/runtime/__tests__/client-health.test.ts +44 -0
- package/src/runtime/access-request-helper.ts +21 -53
- package/src/runtime/actor-trust-resolver.ts +59 -63
- package/src/runtime/agent-wake.ts +52 -0
- package/src/runtime/assistant-event-hub.ts +18 -4
- package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
- package/src/runtime/auth/require-bound-guardian.ts +1 -4
- package/src/runtime/btw-sidechain.ts +3 -6
- package/src/runtime/capabilities.test.ts +120 -0
- package/src/runtime/capabilities.ts +197 -0
- package/src/runtime/channel-approval-types.ts +22 -45
- package/src/runtime/channel-invite-transports/telegram.ts +4 -4
- package/src/runtime/channel-retry-sweep.ts +1 -0
- package/src/runtime/channel-verification-service.ts +3 -3
- package/src/runtime/client-health.ts +26 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
- package/src/runtime/effective-capabilities.test.ts +128 -0
- package/src/runtime/effective-capabilities.ts +84 -0
- package/src/runtime/guardian-reply-router.ts +106 -21
- package/src/runtime/invite-redemption-service.ts +9 -25
- package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +123 -0
- package/src/runtime/migrations/vbundle-builder.ts +49 -20
- package/src/runtime/pending-interactions.ts +15 -0
- package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +240 -1
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -2
- package/src/runtime/routes/assets/vellum-design-system.css +1959 -0
- package/src/runtime/routes/browser-tabs-routes.ts +9 -0
- package/src/runtime/routes/btw-routes.ts +1 -27
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
- package/src/runtime/routes/client-routes.ts +10 -0
- package/src/runtime/routes/contact-routes.ts +31 -8
- package/src/runtime/routes/conversation-compaction-routes.ts +1 -1
- package/src/runtime/routes/conversation-management-routes.ts +80 -1
- package/src/runtime/routes/conversation-query-routes.ts +68 -22
- package/src/runtime/routes/conversation-routes.ts +39 -14
- package/src/runtime/routes/credential-routes.ts +40 -16
- package/src/runtime/routes/empty-state-greeting-cache.ts +1 -2
- package/src/runtime/routes/events-routes.ts +1 -3
- package/src/runtime/routes/guardian-approval-interception.ts +14 -73
- package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
- package/src/runtime/routes/home-feed-routes.ts +8 -3
- package/src/runtime/routes/identity-routes.ts +1 -296
- package/src/runtime/routes/inbound-message-handler.ts +214 -228
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +89 -7
- package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
- package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
- package/src/runtime/routes/integrations/slack/channel.ts +36 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
- package/src/runtime/routes/mcp-auth-routes.ts +233 -41
- package/src/runtime/routes/memory-eval-routes.ts +87 -0
- package/src/runtime/routes/notification-routes.ts +122 -133
- package/src/runtime/routes/platform-routes.ts +2 -2
- package/src/runtime/routes/plugins-routes.ts +202 -3
- package/src/runtime/routes/schedule-routes.ts +0 -22
- package/src/runtime/routes/secret-routes.ts +10 -0
- package/src/runtime/routes/surface-action-routes.ts +2 -1
- package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
- package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
- package/src/runtime/routes/workflow-routes.test.ts +229 -44
- package/src/runtime/routes/workflow-routes.ts +131 -29
- package/src/runtime/routes/workspace-greetings.ts +55 -0
- package/src/runtime/sync/resource-sync-events.ts +1 -11
- package/src/runtime/tool-grant-request-helper.ts +18 -16
- package/src/runtime/trust-context-resolver.ts +8 -5
- package/src/schedule/inference-profile.ts +2 -14
- package/src/schedule/schedule-store.ts +1 -1
- package/src/schedule/scheduler-types.ts +5 -1
- package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
- package/src/security/secret-patterns.ts +3 -0
- package/src/subagent/manager.ts +17 -4
- package/src/subagent/types.ts +6 -0
- package/src/telemetry/trace-collection-policy.test.ts +28 -0
- package/src/telemetry/trace-collection-policy.ts +30 -0
- package/src/telemetry/types.ts +89 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
- package/src/telemetry/usage-telemetry-reporter.ts +148 -41
- package/src/tools/AGENTS.md +3 -3
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
- package/src/tools/browser/browser-execution.ts +30 -19
- package/src/tools/document/document-tool.ts +2 -3
- package/src/tools/executor.ts +5 -3
- package/src/tools/host-terminal/host-shell.ts +5 -4
- package/src/tools/memory/register.ts +2 -2
- package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
- package/src/tools/network/__tests__/web-search.test.ts +143 -0
- package/src/tools/network/web-fetch.ts +372 -1
- package/src/tools/network/web-search-error.ts +1 -1
- package/src/tools/network/web-search.ts +213 -10
- package/src/tools/permission-checker.ts +4 -3
- package/src/tools/registry.ts +20 -0
- package/src/tools/schedule/create.ts +7 -12
- package/src/tools/schedule/update.ts +4 -11
- package/src/tools/shared/filesystem/path-policy.ts +39 -13
- package/src/tools/side-effects.ts +2 -17
- package/src/tools/skills/execute.ts +33 -0
- package/src/tools/subagent/spawn.ts +61 -12
- package/src/tools/terminal/shell.ts +10 -4
- package/src/tools/tool-approval-handler.ts +18 -13
- package/src/tools/tool-manifest.ts +0 -2
- package/src/tools/types.ts +9 -0
- package/src/tools/ui-surface/definitions.ts +64 -3
- package/src/tools/verification-control-plane-policy.ts +3 -1
- package/src/tools/workflows/run-workflow.test.ts +8 -18
- package/src/tools/workflows/run-workflow.ts +1 -0
- package/src/util/disk-usage.ts +78 -23
- package/src/util/platform.ts +10 -3
- package/src/watcher/telemetry.ts +2 -2
- package/src/workflows/capabilities.ts +2 -3
- package/src/workflows/engine.test.ts +175 -1
- package/src/workflows/engine.ts +82 -0
- package/src/workflows/journal-store.test.ts +70 -0
- package/src/workflows/journal-store.ts +18 -3
- package/src/workflows/run-manager.test.ts +171 -28
- package/src/workflows/run-manager.ts +66 -24
- package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
- package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
- package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
- package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +0 -98
- package/src/__tests__/credential-security-e2e.test.ts +0 -362
- package/src/__tests__/credential-vault-unit.test.ts +0 -1528
- package/src/__tests__/credential-vault.test.ts +0 -1706
- package/src/__tests__/identity-intro-cache.test.ts +0 -315
- package/src/__tests__/secret-onetime-send.test.ts +0 -182
- package/src/cli/commands/__tests__/task.test.ts +0 -914
- package/src/cli/commands/task.ts +0 -771
- package/src/config/bundled-skills/personal-page/SKILL.md +0 -57
- package/src/config/bundled-skills/personal-page/TOOLS.json +0 -27
- package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +0 -17
- package/src/config/preloaded-apps/personal-page/src/components/About.tsx +0 -22
- package/src/config/preloaded-apps/personal-page/src/components/App.tsx +0 -16
- package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +0 -77
- package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +0 -57
- package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +0 -28
- package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +0 -234
- package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +0 -48
- package/src/config/preloaded-apps/personal-page/src/components/media.ts +0 -16
- package/src/config/preloaded-apps/personal-page/src/index.html +0 -20
- package/src/config/preloaded-apps/personal-page/src/main.tsx +0 -7
- package/src/config/preloaded-apps/personal-page/src/profile-data.ts +0 -82
- package/src/config/preloaded-apps/personal-page/src/styles.css +0 -759
- package/src/memory/__tests__/preloaded-apps.test.ts +0 -85
- package/src/memory/preloaded-apps.ts +0 -116
- package/src/notifications/tool-approval-copy.ts +0 -142
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +0 -78
- package/src/runtime/routes/identity-intro-cache.ts +0 -172
- package/src/tools/credentials/vault.ts +0 -712
package/ARCHITECTURE.md
CHANGED
|
@@ -343,11 +343,11 @@ The Slack channel provides text-based messaging via Slack's Socket Mode API. Unl
|
|
|
343
343
|
|
|
344
344
|
**Control-plane endpoints** (`/v1/integrations/slack/channel/config`):
|
|
345
345
|
|
|
346
|
-
| Endpoint | Method | Description
|
|
347
|
-
| --------------------------------------- | ------ |
|
|
348
|
-
| `/v1/integrations/slack/channel/config` | GET | Returns current config status: `hasBotToken`, `hasAppToken`, `hasUserToken`, `connected`, plus workspace metadata (`teamId`, `teamName`, `botUserId`, `botUsername`)
|
|
349
|
-
| `/v1/integrations/slack/channel/config` | POST | Validates and stores credentials. Body: `{ botToken?: string, appToken?: string, userToken?: string }`
|
|
350
|
-
| `/v1/integrations/slack/channel/config` | DELETE | Clears all Slack channel credentials (bot, app, and user tokens) from secure storage and credential metadata.
|
|
346
|
+
| Endpoint | Method | Description |
|
|
347
|
+
| --------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
348
|
+
| `/v1/integrations/slack/channel/config` | GET | Returns current config status: `hasBotToken`, `hasAppToken`, `hasUserToken`, `connected`, plus workspace metadata (`teamId`, `teamName`, `botUserId`, `botUsername`) |
|
|
349
|
+
| `/v1/integrations/slack/channel/config` | POST | Validates and stores credentials. Body: `{ botToken?: string, appToken?: string, userToken?: string }` |
|
|
350
|
+
| `/v1/integrations/slack/channel/config` | DELETE | Clears all Slack channel credentials (bot, app, and user tokens) from secure storage and credential metadata. The `credentials delete` route handles `slack_channel`/`user_token` like any other credential except that it skips the OAuth teardown, so removing just the user token leaves the channel's connection (run on the bot + app tokens) intact. `clearSlackUserToken` is the surgical user-token-only helper used internally by Slack config handling. |
|
|
351
351
|
|
|
352
352
|
All endpoints are JWT-authenticated via `Authorization: Bearer <jwt>`.
|
|
353
353
|
|
|
@@ -609,10 +609,9 @@ Audio-to-text conversion occurs in six distinct runtime boundaries, each with it
|
|
|
609
609
|
| ---------------------------- | ----------------------------------------------------------------------------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
610
610
|
| **Telephony (hybrid)** | Twilio-native ConversationRelay or daemon media-stream (provider-conditional) | Configured STT provider (via `services.stt`) | `src/calls/telephony-stt-routing.ts` | `src/calls/twilio-routes.ts` |
|
|
611
611
|
| **Daemon batch** | Daemon process (REST API to provider) | Configured STT provider (via `services.stt`) | `src/stt/daemon-batch-transcriber.ts` | `src/runtime/routes/inbound-stages/transcribe-audio.ts` |
|
|
612
|
-
| **Conversation streaming** | Daemon process (WebSocket-based) | Configured STT provider (via `services.stt`) | `src/stt/stt-stream-session.ts`, `src/providers/speech-to-text/deepgram-realtime.ts`, `src/providers/speech-to-text/google-gemini-live-stream.ts`, `src/providers/speech-to-text/openai-whisper-stream.ts`, `src/providers/speech-to-text/xai-realtime.ts` |
|
|
613
|
-
| **Live voice channel** | Assistant process (gateway-authenticated WebSocket) | Configured STT provider (via `services.stt`) | `src/runtime/http-server.ts`, `src/live-voice/live-voice-session-manager.ts`, `src/live-voice/live-voice-session.ts`, `src/providers/speech-to-text/resolve.ts`, streaming provider adapters |
|
|
614
|
-
| **Client service-first** |
|
|
615
|
-
| **Client-native (fallback)** | macOS on-device | Apple Speech (`SFSpeechRecognizer`) | `clients/macos/.../SpeechRecognizerAdapter.swift` | Fallback when STT service is unconfigured or fails |
|
|
612
|
+
| **Conversation streaming** | Daemon process (WebSocket-based) | Configured STT provider (via `services.stt`) | `src/stt/stt-stream-session.ts`, `src/providers/speech-to-text/deepgram-realtime.ts`, `src/providers/speech-to-text/google-gemini-live-stream.ts`, `src/providers/speech-to-text/openai-whisper-stream.ts`, `src/providers/speech-to-text/xai-realtime.ts` | Web/Electron dictation client via gateway WS proxy |
|
|
613
|
+
| **Live voice channel** | Assistant process (gateway-authenticated WebSocket) | Configured STT provider (via `services.stt`) | `src/runtime/http-server.ts`, `src/live-voice/live-voice-session-manager.ts`, `src/live-voice/live-voice-session.ts`, `src/providers/speech-to-text/resolve.ts`, streaming provider adapters | Web/Electron live voice client via `/v1/live-voice` |
|
|
614
|
+
| **Client service-first** | Web/Electron via gateway → daemon | Configured STT provider (via `services.stt`) | `src/runtime/routes/stt-routes.ts` | Web/Electron dictation and voice clients |
|
|
616
615
|
|
|
617
616
|
**Telephony boundary (hybrid routing):**
|
|
618
617
|
|
|
@@ -679,16 +678,14 @@ Two provider adapters are supported, each implementing the `StreamingTranscriber
|
|
|
679
678
|
|
|
680
679
|
**Session lifecycle (client side):**
|
|
681
680
|
|
|
682
|
-
|
|
683
|
-
- `STTProviderRegistry` (`clients/shared/Utilities/STTProviderRegistry.swift`) exposes `isStreamingAvailable` (checks the configured provider's `conversationStreamingMode` from the `GET /v1/stt/providers` API) and `isServiceConfigured` (checks whether any STT provider is set).
|
|
684
|
-
- macOS: `VoiceInputManager.startStreamingSession()` creates a fresh `STTStreamingClient` per recording session. Streaming partials take priority over `SFSpeechRecognizer` partials while the stream is active and healthy. When recording stops, if the stream delivered at least one `final` event (`streamingReceivedFinal`) and has not failed (`streamingFailed`), the streaming final text is used directly. Otherwise, the batch STT path (`STTClient.transcribe()`) provides the fallback.
|
|
681
|
+
The web client streaming dictation client lives at `clients/web/src/domains/chat/voice/dictation-stream.ts`; it opens the gateway WebSocket to `/v1/stt/stream`, parses `partial`/`final` frames, and reports failures so the caller can fall back to batch transcription. Before opening a session the client checks the configured provider's `conversationStreamingMode` from the `GET /v1/stt/providers` API. When the stream delivers at least one `final` event and has not failed, the streaming final text is used directly; otherwise the batch STT path (`clients/web/src/domains/chat/voice/stt-api.ts`) provides the fallback.
|
|
685
682
|
|
|
686
683
|
**Fallback semantics:**
|
|
687
684
|
|
|
688
685
|
The conversation streaming path degrades gracefully to the existing batch STT path:
|
|
689
686
|
|
|
690
|
-
1. **Unsupported provider** (a hypothetical provider with `conversationStreamingMode: "none"`): The client checks `
|
|
691
|
-
2. **Connection failure** (network error, gateway down, auth failure): The
|
|
687
|
+
1. **Unsupported provider** (a hypothetical provider with `conversationStreamingMode: "none"`): The client checks streaming availability (the configured provider's `conversationStreamingMode` from `GET /v1/stt/providers`) before attempting a streaming session. When unavailable, recording proceeds with the batch-only flow (no WebSocket is opened). On the daemon side, if a streaming session is somehow opened for an unsupported provider, the session sends an `error` event followed by `closed` and closes the socket with code 1000.
|
|
688
|
+
2. **Connection failure** (network error, gateway down, auth failure): The streaming client reports the failure to its caller, which marks the stream as failed and falls through to batch STT resolution when recording stops.
|
|
692
689
|
3. **Mid-session provider error** (provider WebSocket disconnect, timeout, rate limit): The daemon session emits an `error` event (with a normalized `SttErrorCategory`) followed by `closed`. The client marks the stream as failed and defers to batch STT.
|
|
693
690
|
4. **Missing credentials**: `resolveStreamingTranscriber()` returns `null` when the API key is not configured. The session sends an `error`+`closed` pair and the client falls back to batch.
|
|
694
691
|
|
|
@@ -713,9 +710,8 @@ The conversation streaming path degrades gracefully to the existing batch STT pa
|
|
|
713
710
|
| `src/providers/speech-to-text/resolve.ts` | `resolveStreamingTranscriber()`: credential-aware factory for streaming adapters; `resolveConversationStreamingSttCapability()`: capability validator |
|
|
714
711
|
| `src/runtime/http-server.ts` | Runtime WebSocket upgrade handler for `/v1/stt/stream`, session registry (`activeSttStreamSessions`), graceful shutdown |
|
|
715
712
|
| `gateway/src/http/routes/stt-stream-websocket.ts` | Gateway WebSocket proxy: authenticates client, opens upstream WS to daemon with service token |
|
|
716
|
-
| `clients/
|
|
717
|
-
| `clients/
|
|
718
|
-
| `clients/macos/.../VoiceInputManager.swift` | macOS integration: `startStreamingSession()`, streaming/batch priority, fallback on failure |
|
|
713
|
+
| `clients/web/src/domains/chat/voice/dictation-stream.ts` | Web streaming dictation client: WebSocket session, event parsing, failure reporting |
|
|
714
|
+
| `clients/web/src/domains/chat/voice/voice-recording-store.ts` | Web voice recording state: streaming/batch priority, fallback on failure |
|
|
719
715
|
|
|
720
716
|
**Live voice channel boundary:**
|
|
721
717
|
|
|
@@ -742,37 +738,25 @@ V1 is local/gateway-scoped. Managed/cloud WebSocket proxy support, cross-region
|
|
|
742
738
|
|
|
743
739
|
**Client service-first boundary:**
|
|
744
740
|
|
|
745
|
-
All product-facing dictation and voice-streaming paths
|
|
741
|
+
All product-facing dictation and voice-streaming paths use a service-first STT strategy. Clients record audio, encode it to WAV, and POST it through the gateway to the daemon's `POST /v1/stt/transcribe` endpoint. The daemon resolves the configured STT provider through `resolveBatchTranscriber()` and returns the transcribed text.
|
|
746
742
|
|
|
747
|
-
-
|
|
743
|
+
- The client receives a typed result distinguishing success from `notConfigured`, `serviceUnavailable`, and `error`, so callers can deterministically trigger their fallback path.
|
|
748
744
|
- The gateway proxies the request via assistant-scoped path rewriting: `/v1/assistants/:id/stt/transcribe` is rewritten to `/v1/stt/transcribe` on the daemon.
|
|
749
745
|
- `stt-routes.ts` (`src/runtime/routes/stt-routes.ts`) defines the HTTP endpoint, validates the audio payload, and delegates to `resolveBatchTranscriber()`.
|
|
750
746
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
| Flow | Client | Entry point |
|
|
754
|
-
| ----------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
755
|
-
| **Push-to-talk dictation** | macOS | `VoiceInputManager.resolveTranscription()` — encodes accumulated PCM buffers to WAV, calls `sttClient.transcribe()`, falls back to native text on failure |
|
|
756
|
-
| **Conversation chat capture** | macOS | `VoiceInputManager.handleFinalTranscription()` — prefers streaming final when available; falls back to batch `sttClient.transcribe()` when streaming was not used, failed, or produced no finals |
|
|
757
|
-
| **Voice mode (streaming)** | macOS | `OpenAIVoiceService.stopRecordingAndGetTranscription()` — encodes per-turn PCM to WAV, calls `sttClient.transcribe()` for turn-final transcript resolution, falls back to SFSpeechRecognizer result |
|
|
758
|
-
|
|
759
|
-
**Client-native fallback boundary:**
|
|
760
|
-
|
|
761
|
-
Apple-native on-device recognition via `SFSpeechRecognizer` serves two roles in all three product-facing flows above: (1) it provides low-latency partial transcriptions for real-time display during recording, and (2) it provides the fallback final transcription when the STT service is unconfigured (HTTP 503), temporarily unavailable (HTTP 5xx), or returns an empty result. The `SpeechRecognizerAdapter` protocols on each platform abstract Apple Speech for **testability and dependency injection**.
|
|
762
|
-
|
|
763
|
-
The macOS `SpeechRecognizerAdapter` protocol in `clients/macos/vellum-assistant/Features/Voice/SpeechRecognizerAdapter.swift` abstracts `SFSpeechRecognizer` static APIs and instance creation. `AppleSpeechRecognizerAdapter` is the production implementation. `OpenAIVoiceService` and `VoiceInputManager` consume the adapter via dependency injection. **Note:** The protocol leaks Apple Speech types through its surface — `authorizationStatus()` returns `SFSpeechRecognizerAuthorizationStatus` and `makeRecognizer(locale:)` returns `SFSpeechRecognizer?` directly. This means callers depend on the Speech framework at compile time.
|
|
747
|
+
The web client implements these flows in `clients/web/src/domains/chat/voice/`: `stt-api.ts` (batch transcribe), `dictation-stream.ts` (streaming dictation), and `voice-recording-store.ts` (recording state, streaming/batch priority, fallback). Push-to-talk dictation and conversation chat capture prefer a streaming final when available and fall back to batch transcription when streaming was not used, failed, or produced no finals.
|
|
764
748
|
|
|
765
749
|
**Cross-boundary notes:**
|
|
766
750
|
|
|
767
751
|
- The `services.stt` config block is the single source of truth for STT provider selection across the daemon batch boundary, the conversation streaming boundary, the client service-first boundary, and the telephony boundary. The batch and streaming resolvers (`resolveBatchTranscriber()`, `resolveStreamingTranscriber()`) both read from `services.stt.provider` and resolve credentials through the same catalog; the telephony boundary uses `resolveTelephonySttRouting()` to determine the Twilio integration strategy. The daemon provider catalog (`src/providers/speech-to-text/provider-catalog.ts`) is the authoritative registry of supported providers. Native clients fetch display metadata via `GET /v1/stt/providers`.
|
|
768
752
|
- Conversation streaming does not replace the client service-first batch path. When streaming is available, it runs concurrently during recording and provides real-time partials and finals. The batch path remains the fallback for providers that do not support streaming, when streaming fails mid-session, or when streaming produces no final transcript.
|
|
769
753
|
- Credential mapping is catalog-driven: `provider-secret-catalog.ts` derives STT API-key provider names from the daemon catalog via `listCredentialProviderNames()`, deduplicating against the LLM/search provider list. Adding a provider to the catalog automatically includes its credential name in `API_KEY_PROVIDERS`.
|
|
770
|
-
- Terminology: "STT" and "
|
|
754
|
+
- Terminology: "STT", "transcription", and "speech recognition" all refer to the same operation (converting audio to text).
|
|
771
755
|
- **Onboarding**: For a step-by-step guide to adding a new STT provider, see `docs/stt-provider-onboarding.md`.
|
|
772
756
|
|
|
773
757
|
### On-Demand Home Content Generation
|
|
774
758
|
|
|
775
|
-
LLM-generated content shown by clients (personalized home greeting, suggested prompts, conversation starters
|
|
759
|
+
LLM-generated content shown by clients (personalized home greeting, suggested prompts, conversation starters) is produced on demand, never at daemon startup or on unconditional timers.
|
|
776
760
|
|
|
777
761
|
**Data flow (home greeting + suggested prompts):**
|
|
778
762
|
|
package/bun.lock
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"@vellumai/twilio-client": "file:../packages/twilio-client",
|
|
26
26
|
"commander": "13.1.0",
|
|
27
27
|
"croner": "10.0.1",
|
|
28
|
+
"diff": "8.0.4",
|
|
28
29
|
"dotenv": "17.3.1",
|
|
29
30
|
"drizzle-orm": "0.45.2",
|
|
30
31
|
"jszip": "3.10.1",
|
|
@@ -1244,17 +1245,13 @@
|
|
|
1244
1245
|
|
|
1245
1246
|
"@vellumai/ces-client/@types/bun": ["@types/bun@1.2.4", "", { "dependencies": { "bun-types": "1.2.4" } }, "sha512-QtuV5OMR8/rdKJs213iwXDpfVvnskPXY/S0ZiFbsTjQZycuqPbMW8Gf/XhLfwE5njW8sxI2WjISURXPlHypMFA=="],
|
|
1246
1247
|
|
|
1247
|
-
"@vellumai/ces-client/@vellumai/service-contracts": ["@vellumai/service-contracts@file:../packages/service-contracts", {}],
|
|
1248
|
+
"@vellumai/ces-client/@vellumai/service-contracts": ["@vellumai/service-contracts@file:../packages/service-contracts", { "dependencies": { "zod": "4.3.6" }, "devDependencies": { "@types/bun": "1.2.4", "typescript": "5.7.3" } }],
|
|
1248
1249
|
|
|
1249
1250
|
"@vellumai/ces-client/typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="],
|
|
1250
1251
|
|
|
1251
1252
|
"@vellumai/environments/@types/bun": ["@types/bun@1.3.11", "", { "dependencies": { "bun-types": "1.3.11" } }, "sha512-5vPne5QvtpjGpsGYXiFyycfpDF2ECyPcTSsFBMa0fraoxiQyMJ3SmuQIGhzPg2WJuWxVBoxWJ2kClYTcw/4fAg=="],
|
|
1252
1253
|
|
|
1253
|
-
"@vellumai/gateway-client/@vellumai/service-contracts": ["@vellumai/service-contracts@file:../packages/service-contracts", {}],
|
|
1254
|
-
|
|
1255
|
-
"@vellumai/service-contracts/@types/bun": ["@types/bun@1.2.4", "", { "dependencies": { "bun-types": "1.2.4" } }, "sha512-QtuV5OMR8/rdKJs213iwXDpfVvnskPXY/S0ZiFbsTjQZycuqPbMW8Gf/XhLfwE5njW8sxI2WjISURXPlHypMFA=="],
|
|
1256
|
-
|
|
1257
|
-
"@vellumai/service-contracts/typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="],
|
|
1254
|
+
"@vellumai/gateway-client/@vellumai/service-contracts": ["@vellumai/service-contracts@file:../packages/service-contracts", { "dependencies": { "zod": "4.3.6" }, "devDependencies": { "@types/bun": "1.2.4", "typescript": "5.7.3" } }],
|
|
1258
1255
|
|
|
1259
1256
|
"bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
|
|
1260
1257
|
|
|
@@ -1342,9 +1339,11 @@
|
|
|
1342
1339
|
|
|
1343
1340
|
"@vellumai/ces-client/@types/bun/bun-types": ["bun-types@1.2.4", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-nDPymR207ZZEoWD4AavvEaa/KZe/qlrbMSchqpQwovPZCKc7pwMoENjEtHgMKaAjJhy+x6vfqSBA1QU3bJgs0Q=="],
|
|
1344
1341
|
|
|
1345
|
-
"@vellumai/
|
|
1342
|
+
"@vellumai/ces-client/@vellumai/service-contracts/@types/bun": ["@types/bun@1.3.10", "", { "dependencies": { "bun-types": "1.3.10" } }, "sha512-0+rlrUrOrTSskibryHbvQkDOWRJwJZqZlxrUs1u4oOoTln8+WIXBPmAuCF35SWB2z4Zl3E84Nl/D0P7803nigQ=="],
|
|
1346
1343
|
|
|
1347
|
-
"@vellumai/service-contracts
|
|
1344
|
+
"@vellumai/ces-client/@vellumai/service-contracts/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
1345
|
+
|
|
1346
|
+
"@vellumai/environments/@types/bun/bun-types": ["bun-types@1.3.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-1KGPpoxQWl9f6wcZh57LvrPIInQMn2TQ7jsgxqpRzg+l0QPOFvJVH7HmvHo/AiPgwXy+/Thf6Ov3EdVn1vOabg=="],
|
|
1348
1347
|
|
|
1349
1348
|
"detective-typescript/@typescript-eslint/typescript-estree/@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.61.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.61.0", "@typescript-eslint/types": "^8.61.0", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-DV42F7MLJO6Rax7SK1yg43tcnEfGUrurSpSxKuVX+a3RCTzBlH3fuxprrOJXKCJGAaw82xXocikJ0uQaqwXgGA=="],
|
|
1350
1349
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Activation Funnel Telemetry — Runbook + Analytics Handoff
|
|
2
2
|
|
|
3
|
-
> **Linear:**
|
|
3
|
+
> **Linear:** event emission ticket — gates rollout and dashboard tickets.
|
|
4
4
|
> **Funnel version:** `activation_v1_2026_06`
|
|
5
5
|
> **LD flag:** `experiment-activation-flow-2026-06-03`
|
|
6
6
|
> **Cohort arm tag:** `ab_variant = "variant-a"` (treatment); `control` = the no-rail arm.
|
|
@@ -50,8 +50,9 @@ Flow, end to end:
|
|
|
50
50
|
`assistant/src/telemetry/activation-funnel.ts`;
|
|
51
51
|
- emission is best-effort (wrapped in try/catch) and never blocks or alters
|
|
52
52
|
the surface-action flow;
|
|
53
|
-
- `recordActivationEvent` respects the `
|
|
54
|
-
|
|
53
|
+
- `recordActivationEvent` respects the platform `share_analytics` consent gate
|
|
54
|
+
via `getCachedShareAnalytics()` (returns `null` / no row when the platform
|
|
55
|
+
user has not consented; default-off when there is no platform session).
|
|
55
56
|
2. **Reporter flushes** every ~5 min: `usage-telemetry-reporter.ts`
|
|
56
57
|
(`REPORT_INTERVAL_MS = 5 * 60 * 1000`, with a one-time
|
|
57
58
|
`INITIAL_FLUSH_DELAY_MS = 30_000` after startup) POSTs unreported onboarding
|
|
@@ -172,22 +173,27 @@ When the flag is ON, the web prechat context selects
|
|
|
172
173
|
`BOOTSTRAP-ACTIVATION-RAIL.md` as the bootstrap template, and the daemon marks
|
|
173
174
|
the conversation in `activation_sessions` on first build of the system prompt.
|
|
174
175
|
|
|
175
|
-
### 5.2 Confirm
|
|
176
|
-
|
|
177
|
-
Two
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
`
|
|
190
|
-
|
|
176
|
+
### 5.2 Confirm share_analytics consent is on — and pick the right daemon mode
|
|
177
|
+
|
|
178
|
+
Two distinct concerns: whether record-time rows reach SQLite (consent gate), and
|
|
179
|
+
whether those rows reach BigQuery (flush gate, dev-disabled).
|
|
180
|
+
|
|
181
|
+
1. `recordActivationEvent` no-ops when the platform `share_analytics` consent is
|
|
182
|
+
off (it reads `getCachedShareAnalytics()`), and the consent is **default-off
|
|
183
|
+
when there is no platform session**. So the dev session must be signed in to
|
|
184
|
+
the platform with `share_analytics` consent enabled, or no rows are written to
|
|
185
|
+
SQLite. The consent cache is refreshed by `startConsentRefresh()` in
|
|
186
|
+
`assistant/src/daemon/lifecycle.ts`, which runs **regardless of dev mode** — so
|
|
187
|
+
a dev session signed in with `share_analytics` consent enabled writes
|
|
188
|
+
record-time rows to SQLite, where they can be inspected directly.
|
|
189
|
+
2. **Dev mode disables the flush entirely.** When the daemon runs in dev mode
|
|
190
|
+
(`VELLUM_DEV=1`), `assistant/src/daemon/lifecycle.ts` never starts the
|
|
191
|
+
`UsageTelemetryReporter` — rows accumulate in SQLite (consent permitting) but
|
|
192
|
+
are never POSTed, and the "wait/restart for flush" steps below will never reach
|
|
193
|
+
BigQuery. For an end-to-end smoke test, run the daemon **outside dev mode** (so
|
|
194
|
+
the reporter starts), or explicitly invoke the reporter's `flush()` via a dev
|
|
195
|
+
hook. The SQLite rows can be inspected directly in dev mode, but the BigQuery
|
|
196
|
+
verification (§6) requires a real flush.
|
|
191
197
|
|
|
192
198
|
### 5.3 Start a fresh activation conversation and capture its id
|
|
193
199
|
|
|
@@ -261,9 +267,9 @@ collapses it earliest-wins).
|
|
|
261
267
|
|
|
262
268
|
---
|
|
263
269
|
|
|
264
|
-
## 7. Canonical handoff blurb (paste-ready for the final
|
|
270
|
+
## 7. Canonical handoff blurb (paste-ready for the final PR description)
|
|
265
271
|
|
|
266
|
-
> **Activation funnel telemetry — handoff for
|
|
272
|
+
> **Activation funnel telemetry — handoff for dashboard ticket.** The activation rail
|
|
267
273
|
> now emits five milestone funnel events into the existing onboarding telemetry
|
|
268
274
|
> substrate (`type: "onboarding"` → `/v1/telemetry/ingest/` → GCS NDJSON →
|
|
269
275
|
> `vellum-ai-prod.telemetry.onboarding_raw`), so no new event type, ingest
|
|
@@ -290,7 +296,7 @@ collapses it earliest-wins).
|
|
|
290
296
|
|
|
291
297
|
## 8. Notes
|
|
292
298
|
|
|
293
|
-
- **
|
|
299
|
+
- **"naming check" (resolved).** Events fire **deterministically on
|
|
294
300
|
the real user commit of a `ui_show` surface, not every text turn**. The model
|
|
295
301
|
passively tags the surface for a rail move with `activation_moment`; the daemon
|
|
296
302
|
records the milestone in `handleSurfaceAction` when the user commits that
|
|
@@ -223,35 +223,35 @@ The credential system enforces four security invariants:
|
|
|
223
223
|
|
|
224
224
|
```mermaid
|
|
225
225
|
sequenceDiagram
|
|
226
|
-
participant Model as LLM
|
|
227
|
-
participant
|
|
226
|
+
participant Model as LLM (assistant credentials prompt)
|
|
227
|
+
participant Route as credentials prompt route
|
|
228
228
|
participant Prompter as SecretPrompter
|
|
229
229
|
participant HTTP as HTTP Transport
|
|
230
|
-
participant UI as
|
|
230
|
+
participant UI as Secret prompt UI (client)
|
|
231
231
|
participant Store as Credential Store (CES / encrypted file)
|
|
232
232
|
|
|
233
|
-
Model->>
|
|
234
|
-
|
|
233
|
+
Model->>Route: assistant credentials prompt --service --field --label
|
|
234
|
+
Route->>Prompter: requestSecretStandalone(service, field, label, ...)
|
|
235
235
|
Prompter->>HTTP: secret_request {requestId, service, field, label, allowOneTimeSend}
|
|
236
|
-
HTTP->>UI: Show
|
|
237
|
-
UI->>UI: User enters value in
|
|
236
|
+
HTTP->>UI: Show secret prompt
|
|
237
|
+
UI->>UI: User enters value in a masked field
|
|
238
238
|
alt Store (default)
|
|
239
239
|
UI->>HTTP: secret_response {requestId, value, delivery: "store"}
|
|
240
240
|
HTTP->>Prompter: resolve(value, "store")
|
|
241
|
-
Prompter->>
|
|
242
|
-
|
|
243
|
-
|
|
241
|
+
Prompter->>Route: {value, delivery: "store"}
|
|
242
|
+
Route->>Store: persistPromptedCredential → setSecureKeyAsync("credential/svc/field", value)
|
|
243
|
+
Route->>Model: "Stored credential ..." (no value in output)
|
|
244
244
|
else One-Time Send (if enabled)
|
|
245
245
|
UI->>HTTP: secret_response {requestId, value, delivery: "transient_send"}
|
|
246
246
|
HTTP->>Prompter: resolve(value, "transient_send")
|
|
247
|
-
Prompter->>
|
|
248
|
-
Note over
|
|
249
|
-
|
|
247
|
+
Prompter->>Route: {value, delivery: "transient_send"}
|
|
248
|
+
Note over Route: Hands value to CredentialBroker<br/>for single-use consumption
|
|
249
|
+
Route->>Model: "One-time credential provided" (no value in output)
|
|
250
250
|
else Cancel
|
|
251
251
|
UI->>HTTP: secret_response {requestId, value: null}
|
|
252
252
|
HTTP->>Prompter: resolve(null)
|
|
253
|
-
Prompter->>
|
|
254
|
-
|
|
253
|
+
Prompter->>Route: null
|
|
254
|
+
Route->>Model: "User cancelled"
|
|
255
255
|
end
|
|
256
256
|
```
|
|
257
257
|
|
|
@@ -273,7 +273,7 @@ The `allowOneTimeSend` config gate (default: `false`) enables a secondary "Send
|
|
|
273
273
|
- The secret value is handed to the `CredentialBroker`, which holds it in memory for the next `consume` or `browserFill` call
|
|
274
274
|
- The value is **not** persisted to the credential store
|
|
275
275
|
- The broker discards the value after a single use
|
|
276
|
-
- The
|
|
276
|
+
- The credentials prompt route output confirms delivery without including the secret value — the value is never returned to the model
|
|
277
277
|
- The config gate must be explicitly enabled by the operator
|
|
278
278
|
|
|
279
279
|
### Storage Layout
|
|
@@ -286,18 +286,19 @@ The `allowOneTimeSend` config gate (default: `false`) enables a secondary "Send
|
|
|
286
286
|
|
|
287
287
|
### Key Files
|
|
288
288
|
|
|
289
|
-
| File
|
|
290
|
-
|
|
|
291
|
-
| `assistant/src/
|
|
292
|
-
| `assistant/src/
|
|
293
|
-
| `assistant/src/
|
|
294
|
-
| `assistant/src/tools/credentials/
|
|
295
|
-
| `assistant/src/tools/credentials/
|
|
296
|
-
| `assistant/src/
|
|
297
|
-
| `assistant/src/
|
|
298
|
-
| `assistant/src/security/secret-
|
|
299
|
-
| `assistant/src/
|
|
300
|
-
| `
|
|
289
|
+
| File | Role |
|
|
290
|
+
| ----------------------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
291
|
+
| `assistant/src/runtime/routes/credential-routes.ts` | `assistant credentials` CLI — store, list, delete, inspect, reveal handlers |
|
|
292
|
+
| `assistant/src/credential-execution/prompted-credential.ts` | Persists credentials collected through the secure `credentials prompt` flow |
|
|
293
|
+
| `assistant/src/security/secure-keys.ts` | Async secure key CRUD via CES and encrypted file store |
|
|
294
|
+
| `assistant/src/tools/credentials/metadata-store.ts` | JSON file metadata CRUD for credential records |
|
|
295
|
+
| `assistant/src/tools/credentials/broker.ts` | Brokered credential access with policy enforcement and transient send |
|
|
296
|
+
| `assistant/src/tools/credentials/policy-validate.ts` | Policy input validation (allowedTools, allowedDomains) |
|
|
297
|
+
| `assistant/src/permissions/secret-prompter.ts` | HTTP secret_request/secret_response flow |
|
|
298
|
+
| `assistant/src/security/secret-scanner.ts` | Prefix + shape-based secret regex detection (used by display-time `redactSecrets`) |
|
|
299
|
+
| `assistant/src/security/secret-ingress.ts` | Prefix-only ingress check on user messages |
|
|
300
|
+
| `assistant/src/util/log-redact.ts` | Pino log serializers — prefix-based redaction for logs |
|
|
301
|
+
| `clients/web/src/domains/chat/components/secret-prompt-card.tsx` | UI for secure credential entry |
|
|
301
302
|
|
|
302
303
|
---
|
|
303
304
|
|
|
@@ -72,13 +72,11 @@ Native clients fetch this metadata at launch via `GET /v1/stt/providers`. No sep
|
|
|
72
72
|
| `google-gemini` | `gemini` | shared |
|
|
73
73
|
| `xai` | `xai` | exclusive |
|
|
74
74
|
|
|
75
|
-
When the provider ID differs from the credential provider name (e.g. `google-gemini` maps to `gemini`), the key is **shared** with other services that use the same credential.
|
|
75
|
+
When the provider ID differs from the credential provider name (e.g. `google-gemini` maps to `gemini`), the key is **shared** with other services that use the same credential.
|
|
76
76
|
|
|
77
|
-
###
|
|
77
|
+
### Client settings key behavior
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
The `sttKeyIsExclusive(for:)` / `sttKeyIsShared(for:)` helpers derive shared-vs-exclusive key behavior from the catalog automatically: if `apiKeyProviderName == id`, the key is exclusive; otherwise it is shared. No new conditionals are needed unless the provider has a non-standard key-ownership model.
|
|
79
|
+
Clients derive shared-vs-exclusive key behavior from the catalog automatically: if `apiKeyProviderName == id`, the key is exclusive; otherwise it is shared. No new conditionals are needed unless the provider has a non-standard key-ownership model. The web settings UI lives in `clients/web/src/domains/settings/ai/speech-to-text-card.tsx`.
|
|
82
80
|
|
|
83
81
|
## 7. Verify unified STT architecture
|
|
84
82
|
|
|
@@ -2,14 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
This runbook covers the parts of the workflow engine that automated tests do not:
|
|
4
4
|
real provider calls, real journaled resume across a restart, capability
|
|
5
|
-
containment under a live model,
|
|
5
|
+
containment under a live model, and persona-leaf voice. Unit
|
|
6
6
|
and integration coverage lives under `assistant/src/workflows/*.test.ts` and
|
|
7
7
|
`assistant/src/__tests__/`; this is the human-in-the-loop pass that runs **last**,
|
|
8
8
|
on throwaway instances first, and only touches a real inbox or a production
|
|
9
9
|
instance at the very end.
|
|
10
10
|
|
|
11
|
-
Work through the steps in order
|
|
12
|
-
every step that exercises the engine first enables it on a throwaway instance.
|
|
11
|
+
Work through the steps in order, on throwaway instances first.
|
|
13
12
|
|
|
14
13
|
> **Safety rule:** Nothing in this runbook touches a real inbox, a real workspace,
|
|
15
14
|
> or a production instance until every throwaway-instance step has passed. The
|
|
@@ -17,7 +16,7 @@ every step that exercises the engine first enables it on a throwaway instance.
|
|
|
17
16
|
|
|
18
17
|
---
|
|
19
18
|
|
|
20
|
-
## 1. Hatch a throwaway instance
|
|
19
|
+
## 1. Hatch a throwaway instance
|
|
21
20
|
|
|
22
21
|
Hatch a disposable Docker instance built from local source:
|
|
23
22
|
|
|
@@ -26,25 +25,14 @@ vellum hatch --remote docker --source .
|
|
|
26
25
|
```
|
|
27
26
|
|
|
28
27
|
Note the instance name it prints (e.g. `vellum-<adjective>-<animal>`). Use it as
|
|
29
|
-
`--assistant <name>` for everything below, or set it active.
|
|
30
|
-
|
|
31
|
-
Enable the `workflows` flag via that instance's feature-flag override file. The
|
|
32
|
-
override lives in the instance's `protected/feature-flags.json` (overrides here
|
|
33
|
-
win over the registry default — see the feature-flag-overrides gotcha):
|
|
34
|
-
|
|
35
|
-
```jsonc
|
|
36
|
-
// .../<instance>/protected/feature-flags.json
|
|
37
|
-
{ "workflows": true }
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Restart the instance so it re-reads the override, then confirm it is up:
|
|
28
|
+
`--assistant <name>` for everything below, or set it active. Confirm it is up:
|
|
41
29
|
|
|
42
30
|
```
|
|
43
31
|
vellum ps
|
|
44
32
|
```
|
|
45
33
|
|
|
46
|
-
Sanity-check that the surface is
|
|
47
|
-
should return an (empty) table
|
|
34
|
+
Sanity-check that the workflow surface is live: `vellum workflows runs --assistant <name>`
|
|
35
|
+
should return an (empty) table.
|
|
48
36
|
|
|
49
37
|
---
|
|
50
38
|
|
|
@@ -168,27 +156,9 @@ or a send tool, with `capabilities.tools` left empty). Run it and confirm:
|
|
|
168
156
|
|
|
169
157
|
---
|
|
170
158
|
|
|
171
|
-
## 6.
|
|
172
|
-
|
|
173
|
-
On a **default** instance (no `workflows` override, or set back to `false` and
|
|
174
|
-
restart), confirm the whole surface is gone:
|
|
175
|
-
|
|
176
|
-
- `run_workflow` and `manage_workflows` are **absent** from the tool set (the
|
|
177
|
-
assistant cannot call them).
|
|
178
|
-
- The routes 404:
|
|
179
|
-
|
|
180
|
-
```
|
|
181
|
-
vellum workflows runs --assistant <default-instance> # request fails (404)
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
- A scheduler `workflow`-mode job is **rejected** (the engine gate throws before
|
|
185
|
-
any run is launched).
|
|
186
|
-
|
|
187
|
-
---
|
|
188
|
-
|
|
189
|
-
## 7. Real-data smoke (throwaway TEST account)
|
|
159
|
+
## 6. Real-data smoke (throwaway TEST account)
|
|
190
160
|
|
|
191
|
-
Only after steps 1–
|
|
161
|
+
Only after steps 1–5 pass: run the full path against a **throwaway TEST Google or
|
|
192
162
|
Slack account** with about a dozen messages — never a real account. Drive the
|
|
193
163
|
end-to-end flow:
|
|
194
164
|
|
|
@@ -203,17 +173,16 @@ real content, and every side effect was one the manifest declared.
|
|
|
203
173
|
|
|
204
174
|
---
|
|
205
175
|
|
|
206
|
-
##
|
|
176
|
+
## 7. Production / persona instance — LAST
|
|
207
177
|
|
|
208
|
-
|
|
209
|
-
|
|
178
|
+
Run on a real (e.g. persona) instance **only after** the throwaway instances
|
|
179
|
+
above pass, and only after the instance is on current code:
|
|
210
180
|
|
|
211
181
|
1. `git pull` and **restart** the instance so it runs the merged code (a restart
|
|
212
182
|
alone re-runs stale code — see the deploy gotcha).
|
|
213
|
-
2.
|
|
214
|
-
3. Start with the **smallest real slice** — a few items, dry-run actions where the
|
|
183
|
+
2. Start with the **smallest real slice** — a few items, dry-run actions where the
|
|
215
184
|
tool supports it — before any larger or side-effecting run.
|
|
216
|
-
|
|
185
|
+
3. **Human-eval the persona-leaf voice**: read a persona leaf's output and confirm
|
|
217
186
|
it reads as the assistant, not as a generic worker.
|
|
218
187
|
|
|
219
188
|
Stop and reassess if any run's `agentsSpawned` approaches `maxAgentsPerRun`, if
|
package/docs/workflows.md
CHANGED
|
@@ -8,11 +8,9 @@ from each of a hundred documents, draft-then-verify a batch — and you want the
|
|
|
8
8
|
results orchestrated deterministically and reported back when the whole run
|
|
9
9
|
finishes.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
`run_workflow` / `manage_workflows` tools are served by the flag-gated `workflows`
|
|
11
|
+
The `run_workflow` / `manage_workflows` tools are served by the `workflows`
|
|
13
12
|
bundled skill rather than as always-on tools — load it with `skill_load` and invoke
|
|
14
|
-
its tools via `skill_execute`.
|
|
15
|
-
management routes 404, and the scheduler rejects `workflow`-mode jobs.
|
|
13
|
+
its tools via `skill_execute`.
|
|
16
14
|
|
|
17
15
|
- Engine code: `assistant/src/workflows/`
|
|
18
16
|
- Skill (tool surface): `assistant/src/config/bundled-skills/workflows/`
|
|
@@ -437,7 +435,7 @@ Reached via the skill (`skill_load` then `skill_execute`), not as always-on tool
|
|
|
437
435
|
`list_profiles` returns `{ profiles, activeProfile }` — the defined LLM profile
|
|
438
436
|
names plus the workspace active profile, used to pick a valid leaf `profile`.
|
|
439
437
|
|
|
440
|
-
### Routes (read/abort/resume
|
|
438
|
+
### Routes (read/abort/resume)
|
|
441
439
|
|
|
442
440
|
| Method | Path | Purpose |
|
|
443
441
|
| ------ | ------------------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
@@ -74,7 +74,11 @@ function createMockTransport(): CesTransport & {
|
|
|
74
74
|
messages: string[];
|
|
75
75
|
messageHandler: ((msg: string) => void) | null;
|
|
76
76
|
alive: boolean;
|
|
77
|
+
/** Simulate the transport dying (e.g. a spurious stdout EOF): mark it dead
|
|
78
|
+
* and fire the registered close handlers, as the real transports do. */
|
|
79
|
+
die: () => void;
|
|
77
80
|
} {
|
|
81
|
+
const closeHandlers: Array<() => void> = [];
|
|
78
82
|
const transport = {
|
|
79
83
|
messages: [] as string[],
|
|
80
84
|
messageHandler: null as ((msg: string) => void) | null,
|
|
@@ -88,9 +92,16 @@ function createMockTransport(): CesTransport & {
|
|
|
88
92
|
isAlive() {
|
|
89
93
|
return transport.alive;
|
|
90
94
|
},
|
|
95
|
+
onClose(handler: () => void) {
|
|
96
|
+
closeHandlers.push(handler);
|
|
97
|
+
},
|
|
91
98
|
close() {
|
|
92
99
|
transport.alive = false;
|
|
93
100
|
},
|
|
101
|
+
die() {
|
|
102
|
+
transport.alive = false;
|
|
103
|
+
for (const handler of closeHandlers) handler();
|
|
104
|
+
},
|
|
94
105
|
};
|
|
95
106
|
return transport;
|
|
96
107
|
}
|
|
@@ -605,6 +616,42 @@ describe("CesRpcClient", () => {
|
|
|
605
616
|
expect(client.isReady()).toBe(false);
|
|
606
617
|
});
|
|
607
618
|
|
|
619
|
+
test("a pending request fails fast when the transport dies (no timeout wait)", async () => {
|
|
620
|
+
const transport = createMockTransport();
|
|
621
|
+
const client = createCesRpcClient(transport, {
|
|
622
|
+
handshakeTimeoutMs: 5000,
|
|
623
|
+
// Long timeout on purpose: the call must reject from the transport
|
|
624
|
+
// DEATH, not this timer. Without the fail-fast it would hang 60s.
|
|
625
|
+
requestTimeoutMs: 60_000,
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
// Handshake
|
|
629
|
+
const hPromise = client.handshake();
|
|
630
|
+
const hSent = JSON.parse(transport.messages[0]!);
|
|
631
|
+
transport.messageHandler!(
|
|
632
|
+
JSON.stringify({
|
|
633
|
+
type: "handshake_ack",
|
|
634
|
+
protocolVersion: CES_PROTOCOL_VERSION,
|
|
635
|
+
sessionId: hSent.sessionId,
|
|
636
|
+
accepted: true,
|
|
637
|
+
}),
|
|
638
|
+
);
|
|
639
|
+
await hPromise;
|
|
640
|
+
|
|
641
|
+
const callPromise = client.call("list_credentials", {});
|
|
642
|
+
|
|
643
|
+
// The transport's read side dies (e.g. a spurious stdout EOF on a CES
|
|
644
|
+
// bounce) while the request is in flight — the response can never arrive.
|
|
645
|
+
transport.die();
|
|
646
|
+
|
|
647
|
+
try {
|
|
648
|
+
await callPromise;
|
|
649
|
+
throw new Error("should have thrown");
|
|
650
|
+
} catch (err) {
|
|
651
|
+
expect(err).toBeInstanceOf(CesTransportError);
|
|
652
|
+
}
|
|
653
|
+
});
|
|
654
|
+
|
|
608
655
|
test("subsequent handshake call returns immediately if already ready", async () => {
|
|
609
656
|
const transport = createMockTransport();
|
|
610
657
|
const client = createCesRpcClient(transport, { handshakeTimeoutMs: 5000 });
|