@vellumai/assistant 0.6.4 → 0.6.6
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/.prettierignore +5 -0
- package/AGENTS.md +9 -1
- package/ARCHITECTURE.md +43 -49
- package/Dockerfile +17 -3
- package/README.md +3 -4
- package/__tests__/permissions/gateway-threshold-reader.test.ts +283 -0
- package/bun.lock +8 -3
- package/docs/architecture/integrations.md +33 -59
- package/docs/architecture/memory.md +25 -30
- package/docs/architecture/security.md +19 -18
- package/docs/browser-use-architecture-phase2.md +63 -20
- package/docs/error-handling.md +111 -0
- package/docs/plugins.md +761 -0
- package/docs/skills.md +10 -10
- package/docs/stt-provider-onboarding.md +2 -1
- package/examples/plugins/echo/README.md +132 -0
- package/examples/plugins/echo/package.json +17 -0
- package/examples/plugins/echo/register.ts +187 -0
- package/knip.json +9 -2
- package/node_modules/@vellumai/ces-contracts/package.json +2 -1
- package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +471 -0
- package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +398 -4
- package/node_modules/@vellumai/credential-storage/bun.lock +2 -2
- package/node_modules/@vellumai/credential-storage/package.json +2 -2
- package/node_modules/@vellumai/credential-storage/src/oauth-runtime.ts +20 -2
- package/node_modules/@vellumai/egress-proxy/bun.lock +2 -2
- package/node_modules/@vellumai/egress-proxy/package.json +2 -2
- package/node_modules/@vellumai/egress-proxy/src/types.ts +19 -0
- package/openapi.yaml +334 -78
- package/package.json +6 -3
- package/scripts/generate-openapi.ts +50 -11
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +318 -0
- package/src/__tests__/agent-loop-sentry-hygiene.test.ts +137 -0
- package/src/__tests__/agent-loop.test.ts +112 -1
- package/src/__tests__/anthropic-error-formatting.test.ts +98 -0
- package/src/__tests__/anthropic-provider.test.ts +171 -2
- package/src/__tests__/app-compiler.test.ts +57 -0
- package/src/__tests__/approval-cascade.test.ts +36 -10
- package/src/__tests__/approval-routes-http.test.ts +134 -10
- package/src/__tests__/assistant-attachments.test.ts +44 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -0
- package/src/__tests__/auto-analysis-end-to-end.test.ts +1 -0
- package/src/__tests__/avatar-generator.test.ts +4 -2
- package/src/__tests__/browser-fill-credential.test.ts +1 -1
- package/src/__tests__/browser-identifier-parity-guard.test.ts +53 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +23 -33
- package/src/__tests__/browser-skill-endstate.test.ts +51 -182
- package/src/__tests__/btw-routes.test.ts +47 -1
- package/src/__tests__/bundled-asset.test.ts +6 -6
- package/src/__tests__/call-controller.test.ts +1 -2
- package/src/__tests__/call-site-routing-provider.test.ts +214 -0
- package/src/__tests__/catalog-cache.test.ts +96 -4
- package/src/__tests__/channel-approval-routes.test.ts +4 -4
- package/src/__tests__/channel-reply-delivery.test.ts +300 -2
- package/src/__tests__/checker.test.ts +870 -655
- package/src/__tests__/circuit-breaker-pipeline.test.ts +406 -0
- package/src/__tests__/cli-command-risk-guard.test.ts +30 -33
- package/src/__tests__/compaction-events.test.ts +501 -0
- package/src/__tests__/compaction-pipeline.test.ts +210 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +181 -0
- package/src/__tests__/compaction-timeout-recovery.test.ts +262 -0
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/config-analysis.test.ts +11 -28
- package/src/__tests__/config-loader-backfill.test.ts +174 -0
- package/src/__tests__/config-loader-corrupt.test.ts +183 -0
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +202 -0
- package/src/__tests__/config-model-image-provider.test.ts +110 -0
- package/src/__tests__/config-schema-cmd.test.ts +11 -5
- package/src/__tests__/config-schema.test.ts +440 -114
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +0 -4
- package/src/__tests__/config-watcher.test.ts +2 -2
- package/src/__tests__/contact-store-user-file.test.ts +72 -73
- package/src/__tests__/contacts-tools.test.ts +26 -0
- package/src/__tests__/contacts-write.test.ts +4 -4
- package/src/__tests__/context-overflow-policy.test.ts +7 -7
- package/src/__tests__/context-token-estimator.test.ts +191 -1
- package/src/__tests__/context-window-manager.test.ts +883 -4
- package/src/__tests__/conversation-abort-tool-results.test.ts +32 -15
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +86 -46
- package/src/__tests__/conversation-agent-loop.test.ts +435 -216
- package/src/__tests__/conversation-attachments.test.ts +1 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +36 -10
- package/src/__tests__/conversation-error.test.ts +37 -6
- package/src/__tests__/conversation-history-web-search.test.ts +7 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +34 -12
- package/src/__tests__/conversation-lifecycle.test.ts +336 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +27 -10
- package/src/__tests__/conversation-pairing.test.ts +174 -10
- package/src/__tests__/conversation-pre-run-repair.test.ts +32 -15
- package/src/__tests__/conversation-process-callsite.test.ts +309 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +44 -21
- package/src/__tests__/conversation-queue.test.ts +68 -38
- package/src/__tests__/conversation-routes-disk-view.test.ts +36 -7
- package/src/__tests__/conversation-routes-slash-commands.test.ts +31 -3
- package/src/__tests__/conversation-runtime-assembly.test.ts +2877 -152
- package/src/__tests__/conversation-runtime-workspace.test.ts +35 -50
- package/src/__tests__/conversation-seed-composer.test.ts +2 -2
- package/src/__tests__/conversation-skill-tools.test.ts +12 -146
- package/src/__tests__/conversation-slash-queue.test.ts +39 -19
- package/src/__tests__/conversation-slash-unknown.test.ts +53 -16
- package/src/__tests__/conversation-speed-override.test.ts +36 -12
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1035 -0
- package/src/__tests__/conversation-surfaces-standalone.test.ts +630 -0
- package/src/__tests__/conversation-title-service.test.ts +118 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +41 -2
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +1 -1
- package/src/__tests__/conversation-unread-route.test.ts +2 -2
- package/src/__tests__/conversation-usage.test.ts +4 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +33 -9
- package/src/__tests__/conversation-workspace-injection.test.ts +46 -15
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +46 -15
- package/src/__tests__/credential-broker-browser-fill.test.ts +110 -0
- package/src/__tests__/credential-health-service.test.ts +78 -9
- package/src/__tests__/credential-security-invariants.test.ts +5 -2
- package/src/__tests__/credential-storage-oauth-compat.test.ts +18 -0
- package/src/__tests__/credential-storage-static-compat.test.ts +28 -0
- package/src/__tests__/credential-vault-unit.test.ts +135 -19
- package/src/__tests__/credentials-cli.test.ts +1 -9
- package/src/__tests__/cross-provider-web-search.test.ts +84 -0
- package/src/__tests__/daemon-server-persist-and-process-callsite.test.ts +92 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
- package/src/__tests__/delete-propagation.test.ts +437 -0
- package/src/__tests__/dm-backfill.test.ts +417 -0
- package/src/__tests__/dm-persistence.test.ts +227 -0
- package/src/__tests__/edit-propagation.test.ts +280 -0
- package/src/__tests__/empty-response-pipeline.test.ts +305 -0
- package/src/__tests__/ephemeral-permissions.test.ts +93 -3
- package/src/__tests__/estimator-calibration-integration.test.ts +208 -0
- package/src/__tests__/estimator-calibration.test.ts +213 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +29 -10
- package/src/__tests__/file-write-tool.test.ts +151 -1
- package/src/__tests__/filing-service.test.ts +255 -0
- package/src/__tests__/first-greeting.test.ts +247 -5
- package/src/__tests__/gemini-provider.test.ts +0 -3
- package/src/__tests__/guardian-grant-minting.test.ts +8 -0
- package/src/__tests__/headless-browser-interactions.test.ts +1 -1
- package/src/__tests__/headless-browser-mode.test.ts +57 -0
- package/src/__tests__/heartbeat-service.test.ts +96 -15
- package/src/__tests__/history-repair-pipeline.test.ts +399 -0
- package/src/__tests__/host-browser-e2e-cloud.test.ts +307 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +3 -3
- package/src/__tests__/host-proxy-interface.test.ts +36 -2
- package/src/__tests__/host-shell-tool.test.ts +124 -18
- package/src/__tests__/http-user-message-parity.test.ts +29 -1
- package/src/__tests__/image-credentials.test.ts +137 -0
- package/src/__tests__/image-service-dispatcher.test.ts +186 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +340 -0
- package/src/__tests__/injector-chain.test.ts +526 -0
- package/src/__tests__/intent-routing.test.ts +1 -66
- package/src/__tests__/llm-call-pipeline.test.ts +285 -0
- package/src/__tests__/llm-catalog-parity.test.ts +174 -0
- package/src/__tests__/llm-context-normalization.test.ts +121 -0
- package/src/__tests__/llm-resolver.test.ts +214 -0
- package/src/__tests__/llm-schema.test.ts +223 -0
- package/src/__tests__/managed-proxy-context.test.ts +6 -2
- package/src/__tests__/media-generate-image.test.ts +119 -13
- package/src/__tests__/memory-retrieval-pipeline.test.ts +401 -0
- package/src/__tests__/memory-upsert-concurrency.test.ts +1 -0
- package/src/__tests__/messaging-skill-split.test.ts +3 -34
- package/src/__tests__/migration-import-from-url.test.ts +621 -0
- package/src/__tests__/model-intents.test.ts +11 -83
- package/src/__tests__/notification-broadcaster.test.ts +3 -3
- package/src/__tests__/notification-decision-fallback.test.ts +0 -10
- package/src/__tests__/notification-decision-identity.test.ts +0 -9
- package/src/__tests__/notification-decision-recipient-context.test.ts +0 -9
- package/src/__tests__/notification-decision-strategy.test.ts +0 -11
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +108 -0
- package/src/__tests__/oauth-apps-routes.test.ts +1 -1
- package/src/__tests__/oauth-cli.test.ts +14 -12
- package/src/__tests__/oauth-connect-orchestrator.test.ts +4 -13
- package/src/__tests__/oauth-provider-serializer.test.ts +6 -4
- package/src/__tests__/oauth-provider-visibility.test.ts +3 -5
- package/src/__tests__/oauth-providers-routes.test.ts +3 -2
- package/src/__tests__/oauth-store.test.ts +46 -78
- package/src/__tests__/oauth2-gateway-transport.test.ts +8 -3
- package/src/__tests__/oauth2-refresh-retry.test.ts +279 -0
- package/src/__tests__/onboarding-template-contract.test.ts +16 -64
- package/src/__tests__/openai-image-service.test.ts +368 -0
- package/src/__tests__/openai-provider.test.ts +7 -0
- package/src/__tests__/openai-responses-provider.test.ts +396 -0
- package/src/__tests__/openrouter-provider-only.test.ts +135 -0
- package/src/__tests__/outbound-slack-persistence.test.ts +293 -0
- package/src/__tests__/overflow-reduce-pipeline.test.ts +676 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +1 -25
- package/src/__tests__/permission-mode.test.ts +16 -0
- package/src/__tests__/permission-types.test.ts +0 -1
- package/src/__tests__/persist-onboarding-artifacts.test.ts +266 -0
- package/src/__tests__/persistence-pipeline.test.ts +377 -0
- package/src/__tests__/persona-resolver.test.ts +13 -13
- package/src/__tests__/pipeline-runner.test.ts +565 -0
- package/src/__tests__/pkb-autoinject.test.ts +37 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -1
- package/src/__tests__/platform.test.ts +5 -2
- package/src/__tests__/plugin-bootstrap.test.ts +483 -0
- package/src/__tests__/plugin-registry.test.ts +273 -0
- package/src/__tests__/plugin-route-contribution.test.ts +288 -0
- package/src/__tests__/plugin-skill-contribution.test.ts +367 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +286 -0
- package/src/__tests__/plugin-types.test.ts +320 -0
- package/src/__tests__/pricing.test.ts +93 -14
- package/src/__tests__/profiler-routes.test.ts +1 -1
- package/src/__tests__/provider-commit-message-generator.test.ts +14 -84
- package/src/__tests__/provider-env-vars-scope.test.ts +52 -0
- package/src/__tests__/provider-error-scenarios.test.ts +135 -6
- package/src/__tests__/provider-managed-proxy-integration.test.ts +42 -11
- package/src/__tests__/provider-registry-ollama.test.ts +1 -2
- package/src/__tests__/proxy-approval-callback.test.ts +69 -9
- package/src/__tests__/reaction-persistence.test.ts +561 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +0 -2
- package/src/__tests__/relay-server.test.ts +1 -1
- package/src/__tests__/require-fresh-approval.test.ts +1 -1
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +136 -0
- package/src/__tests__/retry-thinking-tool-choice.test.ts +226 -0
- package/src/__tests__/risk-classifier-parity.test.ts +230 -0
- package/src/__tests__/sanitize-config-for-transfer.test.ts +78 -1
- package/src/__tests__/schedule-routes.test.ts +131 -1
- package/src/__tests__/scheduler-recurrence.test.ts +14 -70
- package/src/__tests__/scheduler-reuse-conversation.test.ts +10 -50
- package/src/__tests__/secret-detection-handler.test.ts +0 -10
- package/src/__tests__/secret-ingress-http.test.ts +28 -0
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +125 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +2 -3
- package/src/__tests__/secret-scanner-executor.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +29 -1
- package/src/__tests__/server-history-render.test.ts +31 -0
- package/src/__tests__/shell-identity.test.ts +0 -134
- package/src/__tests__/shell-parser-property.test.ts +13 -13
- package/src/__tests__/skill-cache-store.test.ts +182 -0
- package/src/__tests__/skills.test.ts +19 -33
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
- package/src/__tests__/slack-skill.test.ts +3 -8
- package/src/__tests__/starter-bundle.test.ts +35 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +280 -0
- package/src/__tests__/suggestion-routes.test.ts +259 -3
- package/src/__tests__/system-prompt.test.ts +22 -35
- package/src/__tests__/task-memory-cleanup.test.ts +1 -0
- package/src/__tests__/task-runner.test.ts +3 -1
- package/src/__tests__/task-scheduler.test.ts +3 -15
- package/src/__tests__/tcc-sandbox-deny.test.ts +198 -0
- package/src/__tests__/terminal-tools.test.ts +8 -0
- package/src/__tests__/test-preload.ts +11 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +2 -52
- package/src/__tests__/thread-backfill.test.ts +941 -0
- package/src/__tests__/title-generate-pipeline.test.ts +224 -0
- package/src/__tests__/token-estimate-pipeline.test.ts +431 -0
- package/src/__tests__/tool-error-pipeline.test.ts +244 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +431 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -8
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -2
- package/src/__tests__/tool-executor-shell-integration.test.ts +7 -10
- package/src/__tests__/tool-executor.test.ts +201 -94
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +356 -0
- package/src/__tests__/tool-result-truncation.test.ts +0 -110
- package/src/__tests__/trust-store.test.ts +442 -109
- package/src/__tests__/update-bulletin-job.test.ts +389 -0
- package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -1
- package/src/__tests__/user-plugin-loader.test.ts +191 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +1 -22
- package/src/__tests__/voice-session-bridge.test.ts +39 -0
- package/src/__tests__/volume-security-guard.test.ts +3 -2
- package/src/__tests__/web-search-history.test.ts +337 -0
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +343 -0
- package/src/__tests__/workspace-migration-043-release-notes-latex-rendering.test.ts +202 -0
- package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +210 -0
- package/src/__tests__/workspace-migration-046-seed-conversation-starters-callsite.test.ts +185 -0
- package/src/__tests__/workspace-migration-049-release-notes-default-sonnet.test.ts +100 -0
- package/src/__tests__/workspace-migration-050-seed-main-agent-opus-callsite.test.ts +171 -0
- package/src/__tests__/workspace-migration-051-seed-conversation-summarization-callsite.test.ts +252 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +11 -11
- package/src/__tests__/workspace-migration-remove-hooks.test.ts +99 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +841 -0
- package/src/__tests__/workspace-policy.test.ts +22 -16
- package/src/acp/client-handler.ts +1 -2
- package/src/agent/loop.ts +545 -115
- package/src/approvals/__tests__/guardian-feed-event.test.ts +304 -0
- package/src/approvals/guardian-request-resolvers.ts +80 -0
- package/src/avatar/resvg-lazy.test.ts +136 -0
- package/src/avatar/resvg-lazy.ts +82 -9
- package/src/avatar/traits-png-sync.ts +21 -1
- package/src/backup/__tests__/backup-worker.test.ts +2 -13
- package/src/backup/backup-worker.ts +3 -15
- package/src/browser/__tests__/operations.test.ts +163 -0
- package/src/browser/identifiers.ts +51 -0
- package/src/browser/operations.ts +660 -0
- package/src/browser/types.ts +81 -0
- package/src/bundler/app-compiler.ts +84 -1
- package/src/calls/call-state.ts +2 -2
- package/src/calls/guardian-question-copy.ts +2 -2
- package/src/calls/telephony-stt-routing.ts +1 -1
- package/src/calls/voice-session-bridge.ts +1 -0
- package/src/channels/__tests__/types.test.ts +3 -3
- package/src/channels/types.ts +6 -4
- package/src/cli/AGENTS.md +1 -1
- package/src/cli/__tests__/notifications.test.ts +87 -211
- package/src/cli/commands/__tests__/attachment.test.ts +438 -0
- package/src/cli/commands/__tests__/backup.test.ts +1 -1
- package/src/cli/commands/__tests__/browser.test.ts +554 -0
- package/src/cli/commands/__tests__/cache.test.ts +623 -0
- package/src/cli/commands/__tests__/email-list.test.ts +6 -0
- package/src/cli/commands/__tests__/email-send.test.ts +93 -1
- package/src/cli/commands/__tests__/image-generation.test.ts +886 -0
- package/src/cli/commands/__tests__/inference-send.test.ts +463 -0
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +454 -0
- package/src/cli/commands/__tests__/task.test.ts +913 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +606 -0
- package/src/cli/commands/__tests__/ui-confirm.test.ts +650 -0
- package/src/cli/commands/__tests__/ui.test.ts +1215 -0
- package/src/cli/commands/__tests__/watchers.test.ts +716 -0
- package/src/cli/commands/attachment.ts +182 -0
- package/src/cli/commands/backup.ts +2 -2
- package/src/cli/commands/browser.ts +350 -0
- package/src/cli/commands/cache.ts +341 -0
- package/src/cli/commands/clients.ts +138 -0
- package/src/cli/commands/completions.ts +2 -12
- package/src/cli/commands/config.ts +6 -6
- package/src/cli/commands/conversations-import.ts +347 -0
- package/src/cli/commands/conversations.ts +69 -8
- package/src/cli/commands/email.ts +234 -194
- package/src/cli/commands/image-generation.ts +299 -0
- package/src/cli/commands/inference.ts +200 -0
- package/src/cli/commands/memory.ts +127 -17
- package/src/cli/commands/notifications.ts +68 -103
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -1
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
- package/src/cli/commands/oauth/connect.ts +2 -2
- package/src/cli/commands/oauth/providers.ts +176 -8
- package/src/cli/commands/oauth/status.ts +46 -36
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/connect.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +0 -1
- package/src/cli/commands/skills.ts +3 -4
- package/src/cli/commands/stt.ts +339 -0
- package/src/cli/commands/task.ts +795 -0
- package/src/cli/commands/trust.ts +50 -19
- package/src/cli/commands/tts.ts +273 -0
- package/src/cli/commands/ui.ts +670 -0
- package/src/cli/commands/watchers.ts +509 -0
- package/src/cli/lib/daemon-credential-client.ts +0 -19
- package/src/cli/program.ts +39 -24
- package/src/cli.ts +0 -37
- package/src/config/__tests__/backup-schema.test.ts +7 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +10 -10
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +66 -87
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +28 -51
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +22 -40
- package/src/config/bundled-skills/image-studio/SKILL.md +2 -1
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -1
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +23 -39
- package/src/config/bundled-skills/media-processing/services/reduce.ts +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +5 -5
- package/src/config/bundled-skills/messaging/TOOLS.json +4 -0
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +207 -0
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +20 -1
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +15 -1
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +21 -1
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +69 -12
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -8
- package/src/config/bundled-skills/schedule/SKILL.md +8 -3
- package/src/config/bundled-skills/schedule/TOOLS.json +15 -7
- package/src/config/bundled-skills/schedule/references/SCRIPT_MODE_PATTERNS.md +59 -0
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-tool-registry.ts +0 -190
- package/src/config/env.ts +7 -2
- package/src/config/feature-flag-registry.json +42 -10
- package/src/config/llm-resolver.ts +128 -0
- package/src/config/loader.ts +194 -10
- package/src/config/raw-config-utils.ts +30 -2
- package/src/config/sanitize-for-transfer.ts +35 -0
- package/src/config/schema.ts +49 -41
- package/src/config/schemas/analysis.ts +3 -22
- package/src/config/schemas/backup.ts +1 -1
- package/src/config/schemas/calls.ts +0 -4
- package/src/config/schemas/conversations.ts +16 -0
- package/src/config/schemas/filing.ts +2 -7
- package/src/config/schemas/heartbeat.ts +0 -5
- package/src/config/schemas/inference.ts +3 -23
- package/src/config/schemas/llm.ts +317 -0
- package/src/config/schemas/memory-processing.ts +1 -9
- package/src/config/schemas/notifications.ts +4 -11
- package/src/config/schemas/platform.ts +3 -9
- package/src/config/schemas/security.ts +33 -0
- package/src/config/schemas/services.ts +9 -4
- package/src/config/schemas/stt.ts +1 -0
- package/src/config/schemas/tts.ts +64 -0
- package/src/config/schemas/updates.ts +1 -1
- package/src/config/schemas/workspace-git.ts +3 -40
- package/src/config/skill-state.ts +6 -2
- package/src/config/skills.ts +96 -7
- package/src/context/__tests__/compact-prompt.test.ts +63 -0
- package/src/context/__tests__/microcompact.test.ts +805 -0
- package/src/context/estimator-calibration.ts +136 -0
- package/src/context/microcompact.ts +443 -0
- package/src/context/prompts/compact.md +26 -0
- package/src/context/token-estimator.ts +61 -3
- package/src/context/tool-result-truncation.ts +3 -63
- package/src/context/window-manager.ts +417 -39
- package/src/credential-execution/approval-bridge.ts +0 -1
- package/src/credential-execution/executable-discovery.ts +19 -8
- package/src/credential-execution/process-manager.test.ts +109 -0
- package/src/credential-execution/process-manager.ts +65 -2
- package/src/credential-health/credential-health-service.ts +19 -6
- package/src/daemon/__tests__/conversation-feed-event.test.ts +317 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +4 -12
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +14 -15
- package/src/daemon/approval-generators.ts +29 -4
- package/src/daemon/assistant-attachments.ts +24 -13
- package/src/daemon/classifier.ts +2 -2
- package/src/daemon/config-watcher.ts +0 -3
- package/src/daemon/context-overflow-policy.ts +4 -13
- package/src/daemon/context-overflow-reducer.ts +4 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +162 -34
- package/src/daemon/conversation-agent-loop.ts +1282 -599
- package/src/daemon/conversation-attachments.ts +2 -6
- package/src/daemon/conversation-error.ts +36 -1
- package/src/daemon/conversation-history.ts +10 -19
- package/src/daemon/conversation-lifecycle.ts +59 -17
- package/src/daemon/conversation-messaging.ts +73 -4
- package/src/daemon/conversation-notifiers.ts +2 -110
- package/src/daemon/conversation-process.ts +24 -11
- package/src/daemon/conversation-queue-manager.ts +3 -0
- package/src/daemon/conversation-runtime-assembly.ts +1063 -211
- package/src/daemon/conversation-slash.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +389 -1
- package/src/daemon/conversation-tool-setup.ts +51 -9
- package/src/daemon/conversation-usage.ts +1 -1
- package/src/daemon/conversation.ts +197 -64
- package/src/daemon/external-plugins-bootstrap.ts +478 -0
- package/src/daemon/external-skills-bootstrap.ts +41 -0
- package/src/daemon/first-greeting.ts +191 -14
- package/src/daemon/guardian-action-generators.ts +34 -14
- package/src/daemon/handlers/config-model.test.ts +86 -0
- package/src/daemon/handlers/config-model.ts +65 -12
- package/src/daemon/handlers/conversations.ts +9 -2
- package/src/daemon/handlers/shared.ts +39 -11
- package/src/daemon/handlers/skills.ts +7 -3
- package/src/daemon/handlers/slack-channel-oauth-install.ts +197 -0
- package/src/daemon/lifecycle.ts +109 -82
- package/src/daemon/message-types/computer-use.ts +2 -34
- package/src/daemon/message-types/conversations.ts +63 -0
- package/src/daemon/message-types/messages.ts +21 -1
- package/src/daemon/message-types/trust.ts +0 -2
- package/src/daemon/parse-actual-tokens-from-error.test.ts +57 -1
- package/src/daemon/parse-actual-tokens-from-error.ts +66 -0
- package/src/daemon/pkb-context-tracker.test.ts +169 -0
- package/src/daemon/pkb-context-tracker.ts +125 -0
- package/src/daemon/pkb-reminder-builder.test.ts +70 -0
- package/src/daemon/pkb-reminder-builder.ts +31 -0
- package/src/daemon/providers-setup.ts +6 -0
- package/src/daemon/server.ts +122 -12
- package/src/daemon/shutdown-handlers.ts +2 -12
- package/src/daemon/tool-side-effects.ts +14 -65
- package/src/daemon/web-search-history.ts +126 -0
- package/src/events/domain-events.ts +0 -1
- package/src/filing/filing-service.ts +9 -10
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +160 -0
- package/src/heartbeat/heartbeat-service.ts +99 -28
- package/src/home/__tests__/feed-population-integration.test.ts +312 -0
- package/src/home/__tests__/feed-scheduler.test.ts +39 -11
- package/src/home/__tests__/rollup-producer.test.ts +44 -0
- package/src/home/assistant-feed-authoring.ts +4 -0
- package/src/home/emit-feed-event.ts +11 -0
- package/src/home/feed-scheduler.ts +20 -4
- package/src/home/feed-types.ts +97 -4
- package/src/home/relationship-state-writer.ts +2 -2
- package/src/home/rewrite-command-preview.ts +66 -0
- package/src/home/rollup-producer.ts +34 -5
- package/src/home/suggested-prompts.ts +101 -0
- package/src/ipc/__tests__/attachment-ipc.test.ts +213 -0
- package/src/ipc/__tests__/browser-ipc.test.ts +339 -0
- package/src/ipc/__tests__/cache-ipc.test.ts +266 -0
- package/src/ipc/__tests__/socket-path.test.ts +34 -0
- package/src/ipc/__tests__/task-ipc.test.ts +577 -0
- package/src/ipc/__tests__/ui-request-route.test.ts +495 -0
- package/src/ipc/__tests__/watcher-ipc.test.ts +295 -0
- package/src/ipc/cli-client.ts +2 -1
- package/src/ipc/cli-server.ts +26 -8
- package/src/ipc/gateway-client.ts +6 -3
- package/src/ipc/routes/attachment.ts +114 -0
- package/src/ipc/routes/browser-context.ts +63 -0
- package/src/ipc/routes/browser.ts +97 -0
- package/src/ipc/routes/cache.ts +96 -0
- package/src/ipc/routes/get-contact.ts +16 -0
- package/src/ipc/routes/index.ts +31 -1
- package/src/ipc/routes/list-clients.ts +31 -0
- package/src/ipc/routes/merge-contacts.ts +17 -0
- package/src/ipc/routes/notification.ts +133 -0
- package/src/ipc/routes/rename-conversation.ts +59 -0
- package/src/ipc/routes/search-contacts.ts +19 -0
- package/src/ipc/routes/task-queue.ts +226 -0
- package/src/ipc/routes/task.ts +173 -0
- package/src/ipc/routes/ui-request.ts +50 -0
- package/src/ipc/routes/upsert-contact.ts +25 -0
- package/src/ipc/routes/watcher.ts +203 -0
- package/src/ipc/socket-path.ts +76 -0
- package/src/media/app-icon-generator.ts +23 -46
- package/src/media/avatar-router.ts +26 -41
- package/src/media/gemini-image-service.ts +8 -41
- package/src/media/image-credentials.ts +73 -0
- package/src/media/image-service.ts +85 -0
- package/src/media/openai-image-service.ts +131 -0
- package/src/media/types.ts +46 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +9 -8
- package/src/memory/__tests__/conversation-group-migration.test.ts +99 -0
- package/src/memory/admin.ts +18 -0
- package/src/memory/conversation-analyze-job.ts +14 -13
- package/src/memory/conversation-attention-store.ts +13 -6
- package/src/memory/conversation-crud.ts +133 -3
- package/src/memory/conversation-group-migration.ts +38 -6
- package/src/memory/conversation-queries.ts +57 -4
- package/src/memory/conversation-title-service.ts +32 -4
- package/src/memory/db-init.ts +10 -0
- package/src/memory/embedding-backend.ts +1 -1
- package/src/memory/embedding-gemini.test.ts +41 -2
- package/src/memory/embedding-gemini.ts +6 -1
- package/src/memory/graph/bootstrap.test.ts +282 -0
- package/src/memory/graph/bootstrap.ts +8 -5
- package/src/memory/graph/compaction.ts +299 -0
- package/src/memory/graph/consolidation.ts +4 -4
- package/src/memory/graph/conversation-graph-memory.ts +89 -29
- package/src/memory/graph/extraction.test.ts +272 -2
- package/src/memory/graph/extraction.ts +183 -53
- package/src/memory/graph/graph-search.test.ts +93 -0
- package/src/memory/graph/graph-search.ts +4 -1
- package/src/memory/graph/inspect.ts +2 -2
- package/src/memory/graph/narrative.ts +2 -2
- package/src/memory/graph/pattern-scan.ts +2 -2
- package/src/memory/graph/retriever.test.ts +459 -0
- package/src/memory/graph/retriever.ts +237 -48
- package/src/memory/graph/store.ts +41 -0
- package/src/memory/graph/tool-handlers.ts +27 -0
- package/src/memory/graph/tools.ts +6 -1
- package/src/memory/indexer.ts +5 -5
- package/src/memory/job-handlers/conversation-starters.ts +23 -20
- package/src/memory/job-handlers/summarization.ts +2 -2
- package/src/memory/job-utils.ts +7 -1
- package/src/memory/jobs/embed-pkb-file.test.ts +168 -0
- package/src/memory/jobs/embed-pkb-file.ts +54 -0
- package/src/memory/jobs-store.ts +44 -3
- package/src/memory/jobs-worker.ts +4 -0
- package/src/memory/migrations/041-approval-prompt-ts-tracker.ts +26 -0
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +1 -1
- package/src/memory/migrations/149-oauth-tables.ts +1 -0
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +2 -2
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +82 -0
- package/src/memory/migrations/223-schedule-script-column.ts +11 -0
- package/src/memory/migrations/224-oauth-providers-managed-service-is-paid.ts +24 -0
- package/src/memory/migrations/225-oauth-providers-available-scopes.ts +13 -0
- package/src/memory/migrations/index.ts +5 -0
- package/src/memory/pkb/pkb-index.test.ts +369 -0
- package/src/memory/pkb/pkb-index.ts +255 -0
- package/src/memory/pkb/pkb-reconcile.test.ts +252 -0
- package/src/memory/pkb/pkb-reconcile.ts +148 -0
- package/src/memory/pkb/pkb-search.test.ts +499 -0
- package/src/memory/pkb/pkb-search.ts +159 -0
- package/src/memory/pkb/types.ts +53 -0
- package/src/memory/qdrant-client.test.ts +60 -0
- package/src/memory/qdrant-client.ts +147 -1
- package/src/memory/schema/infrastructure.ts +1 -0
- package/src/memory/schema/oauth.ts +4 -1
- package/src/memory/slack-thread-store.ts +37 -0
- package/src/messaging/providers/gmail/adapter.ts +6 -16
- package/src/messaging/providers/gmail/client.ts +22 -0
- package/src/messaging/providers/gmail/types.ts +7 -0
- package/src/messaging/providers/slack/adapter.ts +14 -2
- package/src/messaging/providers/slack/backfill.test.ts +257 -0
- package/src/messaging/providers/slack/backfill.ts +101 -0
- package/src/messaging/providers/slack/message-metadata.test.ts +316 -0
- package/src/messaging/providers/slack/message-metadata.ts +123 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +1421 -0
- package/src/messaging/providers/slack/render-transcript.ts +501 -0
- package/src/messaging/style-analyzer.ts +5 -2
- package/src/notifications/README.md +9 -5
- package/src/notifications/conversation-pairing.ts +78 -19
- package/src/notifications/copy-composer.ts +0 -5
- package/src/notifications/decision-engine.ts +3 -9
- package/src/notifications/emit-signal.ts +1 -1
- package/src/notifications/preference-extractor.ts +2 -6
- package/src/notifications/signal.ts +1 -2
- package/src/oauth/AGENTS.md +1 -1
- package/src/oauth/__tests__/identity-verifier.test.ts +2 -1
- package/src/oauth/connect-orchestrator.ts +8 -34
- package/src/oauth/connect-types.ts +6 -10
- package/src/oauth/manual-token-connection.ts +23 -0
- package/src/oauth/oauth-store.ts +31 -14
- package/src/oauth/platform-connection.test.ts +47 -0
- package/src/oauth/platform-connection.ts +15 -5
- package/src/oauth/provider-serializer.ts +6 -1
- package/src/oauth/seed-providers.ts +56 -106
- package/src/outbound-proxy/http-forwarder.ts +9 -0
- package/src/permissions/approval-policy.test.ts +1223 -0
- package/src/permissions/approval-policy.ts +309 -0
- package/src/permissions/arg-parser.test.ts +161 -0
- package/src/permissions/arg-parser.ts +141 -0
- package/src/permissions/bash-risk-classifier.test.ts +1620 -0
- package/src/permissions/bash-risk-classifier.ts +950 -0
- package/src/permissions/checker.ts +348 -711
- package/src/permissions/command-registry.test.ts +774 -0
- package/src/permissions/command-registry.ts +1005 -0
- package/src/permissions/defaults.ts +28 -79
- package/src/permissions/file-risk-classifier.test.ts +535 -0
- package/src/permissions/file-risk-classifier.ts +274 -0
- package/src/permissions/gateway-threshold-reader.ts +196 -0
- package/src/permissions/prompter.ts +4 -0
- package/src/permissions/risk-types.ts +262 -0
- package/src/permissions/schedule-risk-classifier.test.ts +129 -0
- package/src/permissions/schedule-risk-classifier.ts +85 -0
- package/src/permissions/secret-prompter.ts +53 -2
- package/src/permissions/shell-identity.ts +2 -42
- package/src/permissions/skill-risk-classifier.test.ts +311 -0
- package/src/permissions/skill-risk-classifier.ts +214 -0
- package/src/permissions/trust-client.ts +52 -25
- package/src/permissions/trust-store-interface.ts +1 -6
- package/src/permissions/trust-store.ts +161 -62
- package/src/permissions/types.ts +25 -14
- package/src/permissions/web-risk-classifier.test.ts +170 -0
- package/src/permissions/web-risk-classifier.ts +89 -0
- package/src/permissions/workspace-policy.ts +9 -19
- package/src/platform/client.ts +19 -1
- package/src/plugins/defaults/circuit-breaker.ts +146 -0
- package/src/plugins/defaults/compaction.ts +145 -0
- package/src/plugins/defaults/empty-response.ts +126 -0
- package/src/plugins/defaults/history-repair.ts +85 -0
- package/src/plugins/defaults/index.ts +116 -0
- package/src/plugins/defaults/injectors.ts +491 -0
- package/src/plugins/defaults/llm-call.ts +82 -0
- package/src/plugins/defaults/memory-retrieval.ts +226 -0
- package/src/plugins/defaults/overflow-reduce.ts +181 -0
- package/src/plugins/defaults/persistence.ts +129 -0
- package/src/plugins/defaults/title-generate.ts +95 -0
- package/src/plugins/defaults/token-estimate.ts +104 -0
- package/src/plugins/defaults/tool-error.ts +126 -0
- package/src/plugins/defaults/tool-execute.ts +89 -0
- package/src/plugins/defaults/tool-result-truncate.ts +88 -0
- package/src/plugins/pipeline.ts +316 -0
- package/src/plugins/plugin-skill-contributions.ts +292 -0
- package/src/plugins/registry.ts +241 -0
- package/src/plugins/types.ts +1134 -0
- package/src/plugins/user-loader.ts +177 -0
- package/src/prompts/persona-resolver.ts +3 -3
- package/src/prompts/system-prompt.ts +19 -20
- package/src/prompts/templates/BOOTSTRAP.md +27 -77
- package/src/prompts/templates/SOUL.md +2 -2
- package/src/prompts/update-bulletin-job.ts +190 -0
- package/src/providers/__tests__/context-overflow-error.test.ts +328 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +102 -0
- package/src/providers/__tests__/retry-callsite.test.ts +424 -0
- package/src/providers/anthropic/client.ts +183 -14
- package/src/providers/call-site-routing.ts +71 -0
- package/src/providers/gemini/client.ts +65 -2
- package/src/providers/managed-proxy/constants.ts +2 -1
- package/src/providers/model-catalog.ts +524 -33
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/openai/chat-completions-provider.ts +57 -1
- package/src/providers/openai/responses-provider.ts +86 -9
- package/src/providers/openrouter/client.ts +80 -9
- package/src/providers/provider-env-vars.ts +56 -0
- package/src/providers/provider-send-message.ts +22 -5
- package/src/providers/ratelimit.ts +4 -0
- package/src/providers/registry.ts +19 -8
- package/src/providers/retry.ts +174 -39
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +55 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +61 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +57 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +4 -4
- package/src/providers/speech-to-text/provider-catalog.ts +17 -0
- package/src/providers/speech-to-text/resolve.ts +7 -0
- package/src/providers/speech-to-text/xai-realtime.test.ts +646 -0
- package/src/providers/speech-to-text/xai-realtime.ts +821 -0
- package/src/providers/speech-to-text/xai.test.ts +155 -0
- package/src/providers/speech-to-text/xai.ts +97 -0
- package/src/providers/types.ts +93 -3
- package/src/runtime/AGENTS.md +27 -18
- package/src/runtime/__tests__/agent-wake.test.ts +43 -2
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +3 -3
- package/src/runtime/__tests__/client-registry.test.ts +293 -0
- package/src/runtime/__tests__/interactive-ui.test.ts +673 -0
- package/src/runtime/agent-wake.ts +63 -22
- package/src/runtime/auth/route-policy.ts +4 -0
- package/src/runtime/btw-sidechain.ts +13 -3
- package/src/runtime/channel-reply-delivery.ts +106 -2
- package/src/runtime/client-registry.ts +261 -0
- package/src/runtime/decision-token.ts +116 -0
- package/src/runtime/gateway-client.ts +2 -2
- package/src/runtime/http-router.ts +32 -0
- package/src/runtime/http-server.ts +129 -9
- package/src/runtime/http-types.ts +23 -3
- package/src/runtime/interactive-ui.ts +362 -0
- package/src/runtime/invite-instruction-generator.ts +2 -2
- package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +176 -0
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +390 -0
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge.test.ts +221 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +1540 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +453 -0
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +222 -0
- package/src/runtime/migrations/gcs-signed-url.ts +162 -0
- package/src/runtime/migrations/vbundle-builder.ts +1 -22
- package/src/runtime/migrations/vbundle-importer.ts +154 -9
- package/src/runtime/migrations/vbundle-metadata-merge.ts +124 -0
- package/src/runtime/migrations/vbundle-streaming-importer.ts +2522 -0
- package/src/runtime/migrations/vbundle-streaming-validator.ts +244 -0
- package/src/runtime/migrations/vbundle-tar-stream.ts +217 -0
- package/src/runtime/migrations/vbundle-validator.ts +15 -6
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +111 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +114 -75
- package/src/runtime/routes/__tests__/migration-vellum-metadata-reconcile.test.ts +246 -0
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +78 -0
- package/src/runtime/routes/approval-routes.ts +29 -17
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +9 -0
- package/src/runtime/routes/avatar-routes.ts +20 -4
- package/src/runtime/routes/browser-extension-pair-routes.ts +27 -8
- package/src/runtime/routes/btw-routes.ts +1 -4
- package/src/runtime/routes/conversation-management-routes.ts +20 -2
- package/src/runtime/routes/conversation-routes.ts +351 -138
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/diagnostics-routes.ts +6 -4
- package/src/runtime/routes/events-routes.ts +16 -0
- package/src/runtime/routes/guardian-approval-interception.ts +33 -3
- package/src/runtime/routes/guardian-approval-prompt.ts +13 -3
- package/src/runtime/routes/home-feed-routes.ts +120 -2
- package/src/runtime/routes/inbound-message-handler.ts +987 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +113 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +61 -3
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +129 -6
- package/src/runtime/routes/integrations/slack/channel.ts +25 -3
- package/src/runtime/routes/llm-context-normalization.ts +23 -1
- package/src/runtime/routes/memory-item-routes.test.ts +1 -0
- package/src/runtime/routes/migration-routes.ts +720 -127
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +284 -0
- package/src/runtime/routes/playground/__tests__/guard.test.ts +80 -0
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +294 -0
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +271 -0
- package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +202 -0
- package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +309 -0
- package/src/runtime/routes/playground/__tests__/state.test.ts +224 -0
- package/src/runtime/routes/playground/conversation-not-found.ts +29 -0
- package/src/runtime/routes/playground/deps.ts +56 -0
- package/src/runtime/routes/playground/force-compact.ts +73 -0
- package/src/runtime/routes/playground/guard.ts +37 -0
- package/src/runtime/routes/playground/index.ts +28 -0
- package/src/runtime/routes/playground/inject-failures.ts +159 -0
- package/src/runtime/routes/playground/reset-circuit.ts +115 -0
- package/src/runtime/routes/playground/seed-conversation.ts +139 -0
- package/src/runtime/routes/playground/seeded-conversations.ts +78 -0
- package/src/runtime/routes/playground/state.ts +78 -0
- package/src/runtime/routes/schedule-routes.ts +89 -8
- package/src/runtime/routes/settings-routes.ts +4 -2
- package/src/runtime/routes/trust-rules-routes.ts +30 -14
- package/src/runtime/routes/work-items-routes.test.ts +1 -1
- package/src/runtime/routes/work-items-routes.ts +3 -2
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +25 -43
- package/src/runtime/services/analyze-conversation.ts +12 -16
- package/src/runtime/skill-route-registry.ts +97 -15
- package/src/schedule/run-script.ts +68 -0
- package/src/schedule/schedule-store.ts +7 -1
- package/src/schedule/scheduler.ts +56 -8
- package/src/security/__tests__/provider-key-env-fallback.test.ts +119 -0
- package/src/security/__tests__/untrusted-content.test.ts +109 -0
- package/src/security/oauth2.ts +98 -35
- package/src/security/secure-keys.ts +7 -8
- package/src/security/token-manager.ts +27 -13
- package/src/security/untrusted-content.ts +102 -0
- package/src/skills/catalog-cache.ts +35 -9
- package/src/skills/catalog-install.ts +31 -3
- package/src/skills/skill-cache-store.ts +97 -0
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +76 -0
- package/src/stt/daemon-batch-transcriber.ts +33 -0
- package/src/stt/stt-stream-session.ts +8 -1
- package/src/stt/types.ts +5 -1
- package/src/subagent/manager.ts +41 -13
- package/src/tasks/ephemeral-permissions.ts +9 -4
- package/src/telemetry/usage-telemetry-reporter.ts +27 -5
- package/src/tools/browser/__tests__/browser-status.test.ts +234 -2
- package/src/tools/browser/browser-execution.ts +150 -54
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +230 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +146 -3
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +22 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +54 -3
- package/src/tools/browser/cdp-client/factory.ts +15 -4
- package/src/tools/credentials/tool-policy.ts +39 -5
- package/src/tools/credentials/vault.ts +9 -4
- package/src/tools/executor.ts +129 -73
- package/src/tools/filesystem/write.ts +52 -0
- package/src/tools/host-terminal/host-shell.ts +45 -5
- package/src/tools/memory/register.test.ts +185 -0
- package/src/tools/memory/register.ts +3 -1
- package/src/tools/network/script-proxy/session-manager.ts +37 -1
- package/src/tools/network/web-fetch.ts +20 -10
- package/src/tools/network/web-search.ts +19 -4
- package/src/tools/permission-checker.ts +116 -46
- package/src/tools/policy-context.ts +29 -8
- package/src/tools/registry.ts +195 -6
- package/src/tools/schedule/create.ts +23 -8
- package/src/tools/schedule/update.ts +3 -1
- package/src/tools/secret-detection-handler.ts +0 -51
- package/src/tools/side-effects.ts +0 -11
- package/src/tools/skills/execute.ts +2 -2
- package/src/tools/skills/sandbox-runner.ts +5 -2
- package/src/tools/system/avatar-generator.ts +6 -2
- package/src/tools/terminal/backends/native.ts +51 -2
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/terminal/shell.ts +1 -0
- package/src/tools/tool-manifest.ts +6 -21
- package/src/tools/types.ts +40 -5
- package/src/tools/verification-control-plane-policy.ts +1 -1
- package/src/tts/__tests__/provider-adapters.test.ts +240 -13
- package/src/tts/provider-catalog.ts +18 -0
- package/src/tts/providers/index.ts +2 -0
- package/src/tts/providers/xai-provider.ts +224 -0
- package/src/tts/types.ts +46 -0
- package/src/types/tar-stream.d.ts +66 -0
- package/src/util/json.ts +17 -0
- package/src/util/platform.ts +9 -4
- package/src/util/pricing.ts +41 -8
- package/src/watcher/engine.ts +1 -1
- package/src/watcher/providers/google-calendar.ts +134 -8
- package/src/watcher/providers/outlook-calendar.ts +42 -2
- package/src/workspace/git-service.ts +23 -4
- package/src/workspace/migrations/006-services-config.ts +2 -4
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +2 -3
- package/src/workspace/migrations/038-unify-llm-callsite-configs.ts +516 -0
- package/src/workspace/migrations/039-drop-legacy-llm-keys.ts +171 -0
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +154 -0
- package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +56 -0
- package/src/workspace/migrations/042-fix-backfill-google-gmail-settings-scope.ts +70 -0
- package/src/workspace/migrations/043-release-notes-latex-rendering.ts +75 -0
- package/src/workspace/migrations/044-bump-stale-provider-stream-timeout.ts +51 -0
- package/src/workspace/migrations/045-release-notes-meet-avatar.ts +130 -0
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +108 -0
- package/src/workspace/migrations/047-remove-watch-callsites.ts +54 -0
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +81 -0
- package/src/workspace/migrations/049-release-notes-default-sonnet.ts +80 -0
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +86 -0
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +128 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/registry.ts +28 -0
- package/src/workspace/provider-commit-message-generator.ts +19 -38
- package/tsconfig.json +1 -1
- package/hook-templates/debug-prompt-logger/hook.json +0 -7
- package/hook-templates/debug-prompt-logger/run.sh +0 -66
- package/src/__tests__/context-overflow-approval.test.ts +0 -156
- package/src/__tests__/gmail-archive-fallback.test.ts +0 -193
- package/src/__tests__/gmail-archive-gate.test.ts +0 -246
- package/src/__tests__/gmail-preferences.test.ts +0 -117
- package/src/__tests__/hooks-blocking.test.ts +0 -178
- package/src/__tests__/hooks-cli.test.ts +0 -182
- package/src/__tests__/hooks-config.test.ts +0 -108
- package/src/__tests__/hooks-discovery.test.ts +0 -211
- package/src/__tests__/hooks-integration.test.ts +0 -196
- package/src/__tests__/hooks-manager.test.ts +0 -226
- package/src/__tests__/hooks-runner.test.ts +0 -175
- package/src/__tests__/hooks-settings.test.ts +0 -160
- package/src/__tests__/hooks-templates.test.ts +0 -169
- package/src/__tests__/hooks-ts-runner.test.ts +0 -170
- package/src/__tests__/hooks-watch.test.ts +0 -112
- package/src/__tests__/notification-schedule-dedup.test.ts +0 -213
- package/src/__tests__/oauth-scope-policy.test.ts +0 -180
- package/src/__tests__/outlook-attachments.test.ts +0 -301
- package/src/__tests__/outlook-automation-tools.test.ts +0 -425
- package/src/__tests__/outlook-categories.test.ts +0 -212
- package/src/__tests__/outlook-compose-tools.test.ts +0 -325
- package/src/__tests__/outlook-declutter-tools.test.ts +0 -585
- package/src/__tests__/outlook-follow-up.test.ts +0 -196
- package/src/__tests__/outlook-trash.test.ts +0 -77
- package/src/__tests__/outlook-unsubscribe.test.ts +0 -279
- package/src/__tests__/send-notification-tool.test.ts +0 -83
- package/src/__tests__/update-bulletin-format.test.ts +0 -181
- package/src/__tests__/update-bulletin-state.test.ts +0 -135
- package/src/__tests__/update-bulletin.test.ts +0 -478
- package/src/__tests__/update-template-contract.test.ts +0 -29
- package/src/cli/commands/doctor.ts +0 -341
- package/src/cli/commands/shotgun.ts +0 -266
- package/src/config/bundled-skills/browser/SKILL.md +0 -88
- package/src/config/bundled-skills/browser/TOOLS.json +0 -516
- package/src/config/bundled-skills/browser/tools/browser-attach.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-click.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-close.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-detach.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-extract.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-hover.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-navigate.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-press-key.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-scroll.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-select-option.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-status.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-type.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +0 -49
- package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +0 -12
- package/src/config/bundled-skills/chatgpt-import/SKILL.md +0 -27
- package/src/config/bundled-skills/chatgpt-import/TOOLS.json +0 -27
- package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +0 -378
- package/src/config/bundled-skills/conversations/SKILL.md +0 -20
- package/src/config/bundled-skills/conversations/TOOLS.json +0 -23
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +0 -66
- package/src/config/bundled-skills/gmail/SKILL.md +0 -221
- package/src/config/bundled-skills/gmail/TOOLS.json +0 -588
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +0 -256
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +0 -112
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +0 -44
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +0 -81
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +0 -108
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +0 -146
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +0 -53
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +0 -347
- package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +0 -59
- package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +0 -82
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +0 -26
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +0 -347
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +0 -29
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +0 -122
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +0 -67
- package/src/config/bundled-skills/gmail/tools/scan-result-store.ts +0 -100
- package/src/config/bundled-skills/gmail/tools/shared.ts +0 -47
- package/src/config/bundled-skills/google-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/google-calendar/TOOLS.json +0 -226
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +0 -223
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +0 -27
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +0 -48
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +0 -19
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +0 -36
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +0 -58
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/google-calendar/types.ts +0 -97
- package/src/config/bundled-skills/heartbeat/SKILL.md +0 -43
- package/src/config/bundled-skills/notifications/SKILL.md +0 -40
- package/src/config/bundled-skills/notifications/TOOLS.json +0 -80
- package/src/config/bundled-skills/notifications/tools/send-notification.ts +0 -152
- package/src/config/bundled-skills/notifications/tools/shared.ts +0 -13
- package/src/config/bundled-skills/outlook/SKILL.md +0 -196
- package/src/config/bundled-skills/outlook/TOOLS.json +0 -530
- package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +0 -85
- package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +0 -77
- package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +0 -84
- package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +0 -94
- package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +0 -49
- package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +0 -237
- package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +0 -161
- package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +0 -32
- package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +0 -272
- package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +0 -29
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +0 -129
- package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +0 -87
- package/src/config/bundled-skills/outlook/tools/shared.ts +0 -20
- package/src/config/bundled-skills/outlook-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/outlook-calendar/TOOLS.json +0 -221
- package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +0 -252
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +0 -53
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +0 -74
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +0 -18
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +0 -46
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +0 -36
- package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/outlook-calendar/types.ts +0 -120
- package/src/config/bundled-skills/screen-watch/SKILL.md +0 -27
- package/src/config/bundled-skills/screen-watch/TOOLS.json +0 -35
- package/src/config/bundled-skills/screen-watch/tools/start-screen-watch.ts +0 -12
- package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -84
- package/src/config/bundled-skills/slack/SKILL.md +0 -108
- package/src/config/bundled-skills/tasks/SKILL.md +0 -37
- package/src/config/bundled-skills/tasks/TOOLS.json +0 -353
- package/src/config/bundled-skills/tasks/icon.svg +0 -34
- package/src/config/bundled-skills/tasks/tools/task-delete.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-add.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-show.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-update.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-save.ts +0 -12
- package/src/config/bundled-skills/watcher/SKILL.md +0 -31
- package/src/config/bundled-skills/watcher/TOOLS.json +0 -167
- package/src/config/bundled-skills/watcher/tools/watcher-create.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-list.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-update.ts +0 -12
- package/src/daemon/context-overflow-approval.ts +0 -52
- package/src/daemon/watch-handler.ts +0 -399
- package/src/hooks/cli.ts +0 -253
- package/src/hooks/config.ts +0 -100
- package/src/hooks/discovery.ts +0 -135
- package/src/hooks/manager.ts +0 -179
- package/src/hooks/runner.ts +0 -117
- package/src/hooks/templates.ts +0 -77
- package/src/hooks/types.ts +0 -75
- package/src/oauth/scope-policy.ts +0 -89
- package/src/prompts/templates/UPDATES.md +0 -50
- package/src/prompts/update-bulletin-format.ts +0 -85
- package/src/prompts/update-bulletin-state.ts +0 -58
- package/src/prompts/update-bulletin-template-path.ts +0 -13
- package/src/prompts/update-bulletin.ts +0 -139
- package/src/runtime/gateway-internal-client.ts +0 -94
- package/src/runtime/routes/watch-routes.ts +0 -156
- package/src/shared/provider-env-vars.ts +0 -19
- package/src/signals/shotgun.ts +0 -203
- package/src/tools/watch/screen-watch.ts +0 -144
- package/src/tools/watch/watch-state.ts +0 -142
- package/src/tools/watcher/create.ts +0 -86
- package/src/tools/watcher/delete.ts +0 -36
- package/src/tools/watcher/digest.ts +0 -54
- package/src/tools/watcher/list.ts +0 -83
- package/src/tools/watcher/update.ts +0 -71
package/src/providers/retry.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { resolveCallSiteConfig } from "../config/llm-resolver.js";
|
|
2
|
+
import { getConfig } from "../config/loader.js";
|
|
1
3
|
import { ProviderError } from "../util/errors.js";
|
|
2
4
|
import { getLogger } from "../util/logger.js";
|
|
3
5
|
import {
|
|
@@ -7,13 +9,13 @@ import {
|
|
|
7
9
|
isRetryableNetworkError,
|
|
8
10
|
sleep,
|
|
9
11
|
} from "../util/retry.js";
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
Message,
|
|
13
|
-
Provider,
|
|
14
|
-
ProviderResponse,
|
|
15
|
-
SendMessageOptions,
|
|
16
|
-
ToolDefinition,
|
|
12
|
+
import {
|
|
13
|
+
isContextOverflowError,
|
|
14
|
+
type Message,
|
|
15
|
+
type Provider,
|
|
16
|
+
type ProviderResponse,
|
|
17
|
+
type SendMessageOptions,
|
|
18
|
+
type ToolDefinition,
|
|
17
19
|
} from "./types.js";
|
|
18
20
|
|
|
19
21
|
const log = getLogger("retry");
|
|
@@ -61,6 +63,19 @@ function isRetryableProviderMessage(error: unknown): boolean {
|
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
function isRetryableError(error: unknown): boolean {
|
|
66
|
+
// Context overflow is deterministic — retrying the same oversized prompt
|
|
67
|
+
// will never succeed. Short-circuit before the generic 429/5xx check so
|
|
68
|
+
// ContextOverflowError (which extends ProviderError and may carry a 429
|
|
69
|
+
// statusCode on Gemini/Vertex) never triggers exponential backoff.
|
|
70
|
+
if (isContextOverflowError(error)) return false;
|
|
71
|
+
// Daemon/user-initiated aborts are never retryable. The catch-site tags
|
|
72
|
+
// these with `abortReason` exactly when `signal.aborted` was true at the
|
|
73
|
+
// time of failure, so this short-circuits before any message-based pattern
|
|
74
|
+
// matches — which matters because transport-level aborts (retryable) and
|
|
75
|
+
// caller-cancels both surface as "Request was aborted" from the SDK.
|
|
76
|
+
if (error instanceof ProviderError && error.abortReason !== undefined) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
64
79
|
if (error instanceof ProviderError && error.statusCode !== undefined) {
|
|
65
80
|
if (error.statusCode === 429 || error.statusCode >= 500) return true;
|
|
66
81
|
}
|
|
@@ -69,6 +84,27 @@ function isRetryableError(error: unknown): boolean {
|
|
|
69
84
|
return isRetryableNetworkError(error);
|
|
70
85
|
}
|
|
71
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Normalize per-call options before handing them to the wrapped provider.
|
|
89
|
+
*
|
|
90
|
+
* When `config.callSite` is set, resolves model/maxTokens/effort/speed/
|
|
91
|
+
* temperature/thinking via `resolveCallSiteConfig` and writes them into
|
|
92
|
+
* `nextConfig` using the wire-format names that downstream provider clients
|
|
93
|
+
* consume (`max_tokens` snake-case for the token cap; camelCase for the rest,
|
|
94
|
+
* which matches the resolver's shape). Per-call explicit overrides on the
|
|
95
|
+
* original `config` object win over the resolved values, so callers can pin
|
|
96
|
+
* a model or other parameter for a single request. `contextWindow` and
|
|
97
|
+
* `provider` are intentionally excluded from the written fields — they are
|
|
98
|
+
* server-side routing/overflow concerns, not provider request parameters,
|
|
99
|
+
* and forwarding them would leak unknown fields into provider request bodies
|
|
100
|
+
* (strict-schema clients like Anthropic reject the request).
|
|
101
|
+
*
|
|
102
|
+
* Whether or not `callSite` is set, this function applies per-provider
|
|
103
|
+
* stripping (`thinking`/`effort`/`speed`) based on the wrapped provider's
|
|
104
|
+
* name — agent-loop callers that pre-resolve provider/model still need this
|
|
105
|
+
* stripping so they don't accidentally send Anthropic-only knobs to OpenAI
|
|
106
|
+
* etc.
|
|
107
|
+
*/
|
|
72
108
|
function normalizeSendMessageOptions(
|
|
73
109
|
providerName: string,
|
|
74
110
|
options?: SendMessageOptions,
|
|
@@ -76,34 +112,77 @@ function normalizeSendMessageOptions(
|
|
|
76
112
|
const config = options?.config;
|
|
77
113
|
if (!config) return options;
|
|
78
114
|
|
|
79
|
-
const
|
|
80
|
-
typeof config.model === "string" && config.model.trim().length > 0
|
|
81
|
-
? config.model.trim()
|
|
82
|
-
: undefined;
|
|
83
|
-
const intent = isModelIntent(config.modelIntent)
|
|
84
|
-
? config.modelIntent
|
|
85
|
-
: undefined;
|
|
86
|
-
const hasIntent = config.modelIntent !== undefined;
|
|
87
|
-
|
|
88
|
-
const needsThinkingStrip =
|
|
89
|
-
!THINKING_AWARE_PROVIDERS.has(providerName) && config.thinking !== undefined;
|
|
90
|
-
const needsEffortStrip =
|
|
91
|
-
!EFFORT_SUPPORTED_PROVIDERS.has(providerName) && config.effort !== undefined;
|
|
92
|
-
const needsSpeedStrip =
|
|
93
|
-
providerName !== "anthropic" && config.speed !== undefined;
|
|
115
|
+
const nextConfig: Record<string, unknown> = { ...config };
|
|
94
116
|
|
|
95
|
-
if (
|
|
96
|
-
|
|
97
|
-
explicitModel === config.model &&
|
|
98
|
-
!needsThinkingStrip &&
|
|
99
|
-
!needsEffortStrip &&
|
|
100
|
-
!needsSpeedStrip
|
|
101
|
-
) {
|
|
102
|
-
return options;
|
|
103
|
-
}
|
|
117
|
+
if (config.callSite !== undefined) {
|
|
118
|
+
const resolved = resolveCallSiteConfig(config.callSite, getConfig().llm);
|
|
104
119
|
|
|
105
|
-
|
|
106
|
-
|
|
120
|
+
const explicitModel =
|
|
121
|
+
typeof config.model === "string" && config.model.trim().length > 0
|
|
122
|
+
? config.model.trim()
|
|
123
|
+
: undefined;
|
|
124
|
+
|
|
125
|
+
// Routing key is consumed by the RetryProvider layer and must not leak
|
|
126
|
+
// downstream.
|
|
127
|
+
delete nextConfig.callSite;
|
|
128
|
+
|
|
129
|
+
// Apply resolved values, letting per-call explicit fields win where set.
|
|
130
|
+
nextConfig.model = explicitModel ?? resolved.model;
|
|
131
|
+
if (nextConfig.max_tokens === undefined) {
|
|
132
|
+
nextConfig.max_tokens = resolved.maxTokens;
|
|
133
|
+
}
|
|
134
|
+
if (nextConfig.effort === undefined) {
|
|
135
|
+
nextConfig.effort = resolved.effort;
|
|
136
|
+
}
|
|
137
|
+
if (nextConfig.speed === undefined) {
|
|
138
|
+
nextConfig.speed = resolved.speed;
|
|
139
|
+
}
|
|
140
|
+
// `temperature` defaults to `null` in the LLM schema (meaning "no opinion
|
|
141
|
+
// — let the provider pick its own default"). Only forward when the
|
|
142
|
+
// resolved value is an actual number; passing `temperature: null` to
|
|
143
|
+
// provider clients would either be a wire error or silently override
|
|
144
|
+
// sensible provider defaults. Mirrors the legacy non-callSite path which
|
|
145
|
+
// never set `temperature` on `providerConfig`.
|
|
146
|
+
if (
|
|
147
|
+
nextConfig.temperature === undefined &&
|
|
148
|
+
resolved.temperature !== null &&
|
|
149
|
+
resolved.temperature !== undefined
|
|
150
|
+
) {
|
|
151
|
+
nextConfig.temperature = resolved.temperature;
|
|
152
|
+
}
|
|
153
|
+
if (nextConfig.thinking === undefined) {
|
|
154
|
+
// Convert the schema-shape `{ enabled, streamThinking }` into the
|
|
155
|
+
// Anthropic wire-format `{ type: "adaptive" }` (or omit when disabled).
|
|
156
|
+
// Mirrors the non-callSite path in `agent/loop.ts` which sets
|
|
157
|
+
// `providerConfig.thinking = { type: "adaptive" }` only when enabled.
|
|
158
|
+
// Without this conversion, `thinking` arrives at `AnthropicProvider`
|
|
159
|
+
// with a shape the SDK doesn't accept (`ThinkingConfigParam` requires
|
|
160
|
+
// a `type` discriminator), and OpenRouter's truthy check would treat
|
|
161
|
+
// a disabled config as enabled.
|
|
162
|
+
if (resolved.thinking?.enabled === true) {
|
|
163
|
+
nextConfig.thinking = { type: "adaptive" };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// Forward OpenRouter-only routing preferences so `OpenRouterProvider` can
|
|
167
|
+
// translate `openrouter.only` into the wire-format `provider: { only: [...] }`
|
|
168
|
+
// body field on both the OpenAI-compat and Anthropic-compat endpoints.
|
|
169
|
+
if (
|
|
170
|
+
providerName === "openrouter" &&
|
|
171
|
+
nextConfig.openrouter === undefined &&
|
|
172
|
+
Array.isArray(resolved.openrouter?.only) &&
|
|
173
|
+
resolved.openrouter.only.length > 0
|
|
174
|
+
) {
|
|
175
|
+
nextConfig.openrouter = { only: resolved.openrouter.only };
|
|
176
|
+
}
|
|
177
|
+
// `contextWindow` and `provider` are server-side concerns, not provider
|
|
178
|
+
// request parameters: `contextWindow` is consumed by the agent loop's
|
|
179
|
+
// overflow recovery and the conversation manager directly from
|
|
180
|
+
// `config.llm.default.contextWindow.*`; `provider` selection is handled
|
|
181
|
+
// by `CallSiteRoutingProvider` upstream. Forwarding them as per-call
|
|
182
|
+
// config leaks unknown fields into provider request bodies — Anthropic
|
|
183
|
+
// (and other strict-schema clients) reject the request with
|
|
184
|
+
// "Extra inputs are not permitted".
|
|
185
|
+
}
|
|
107
186
|
|
|
108
187
|
// thinking is Anthropic-specific on the wire; OpenRouter reads it as a
|
|
109
188
|
// signal for its unified reasoning parameter. Strip it for other providers.
|
|
@@ -114,6 +193,33 @@ function normalizeSendMessageOptions(
|
|
|
114
193
|
delete nextConfig.thinking;
|
|
115
194
|
}
|
|
116
195
|
|
|
196
|
+
// Anthropic (and OpenRouter fronting Anthropic) rejects requests that
|
|
197
|
+
// combine extended thinking with forced tool use (`tool_choice.type` of
|
|
198
|
+
// `"tool"` or `"any"`). Strip thinking when both are present so the
|
|
199
|
+
// request doesn't fail with a 400 "Thinking may not be enabled when
|
|
200
|
+
// tool_choice forces tool use." `tool_choice: { type: "auto" }` is
|
|
201
|
+
// compatible with thinking and left untouched.
|
|
202
|
+
//
|
|
203
|
+
// For OpenRouter, only strip when routing to an `anthropic/*` model —
|
|
204
|
+
// non-Anthropic reasoning models (e.g. xAI Grok) translate `thinking`
|
|
205
|
+
// into OpenRouter's `reasoning` parameter via `buildExtraCreateParams`
|
|
206
|
+
// and may support reasoning with forced tool_choice.
|
|
207
|
+
const isThinkingForcedToolConflict = (() => {
|
|
208
|
+
if (nextConfig.thinking == null) return false;
|
|
209
|
+
const tc = nextConfig.tool_choice as Record<string, unknown> | undefined;
|
|
210
|
+
if (tc == null || (tc.type !== "tool" && tc.type !== "any")) return false;
|
|
211
|
+
if (providerName === "anthropic") return true;
|
|
212
|
+
if (providerName === "openrouter") {
|
|
213
|
+
const model =
|
|
214
|
+
typeof nextConfig.model === "string" ? nextConfig.model : "";
|
|
215
|
+
return model.startsWith("anthropic/");
|
|
216
|
+
}
|
|
217
|
+
return false;
|
|
218
|
+
})();
|
|
219
|
+
if (isThinkingForcedToolConflict) {
|
|
220
|
+
delete nextConfig.thinking;
|
|
221
|
+
}
|
|
222
|
+
|
|
117
223
|
// effort is supported by Anthropic, OpenAI, and OpenAI-compatible providers; strip for others
|
|
118
224
|
if (
|
|
119
225
|
!EFFORT_SUPPORTED_PROVIDERS.has(providerName) &&
|
|
@@ -127,12 +233,10 @@ function normalizeSendMessageOptions(
|
|
|
127
233
|
delete nextConfig.speed;
|
|
128
234
|
}
|
|
129
235
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
nextConfig.
|
|
134
|
-
} else {
|
|
135
|
-
delete nextConfig.model;
|
|
236
|
+
// `openrouter.only` is OpenRouter-specific routing; strip for other
|
|
237
|
+
// providers so strict-schema clients don't see an unknown field.
|
|
238
|
+
if (providerName !== "openrouter" && nextConfig.openrouter !== undefined) {
|
|
239
|
+
delete nextConfig.openrouter;
|
|
136
240
|
}
|
|
137
241
|
|
|
138
242
|
return {
|
|
@@ -141,9 +245,21 @@ function normalizeSendMessageOptions(
|
|
|
141
245
|
};
|
|
142
246
|
}
|
|
143
247
|
|
|
248
|
+
/**
|
|
249
|
+
* `RetryProvider` sets `retriesExhausted = true` on the final thrown error
|
|
250
|
+
* when the retry loop burned through all attempts against a retryable error
|
|
251
|
+
* (transient network, 5xx, provider-overloaded, mid-stream corruption).
|
|
252
|
+
* Consumers can read it via `(err as { retriesExhausted?: boolean })` to
|
|
253
|
+
* suppress Sentry captures for user-network-flap noise — the retry loop
|
|
254
|
+
* already did its job, and no engineering action would change the outcome.
|
|
255
|
+
*/
|
|
144
256
|
export class RetryProvider implements Provider {
|
|
145
257
|
public readonly name: string;
|
|
146
258
|
|
|
259
|
+
get tokenEstimationProvider(): string | undefined {
|
|
260
|
+
return this.inner.tokenEstimationProvider;
|
|
261
|
+
}
|
|
262
|
+
|
|
147
263
|
constructor(private readonly inner: Provider) {
|
|
148
264
|
this.name = inner.name;
|
|
149
265
|
}
|
|
@@ -155,6 +271,7 @@ export class RetryProvider implements Provider {
|
|
|
155
271
|
options?: SendMessageOptions,
|
|
156
272
|
): Promise<ProviderResponse> {
|
|
157
273
|
let lastError: unknown;
|
|
274
|
+
let didRetry = false;
|
|
158
275
|
|
|
159
276
|
const normalizedOptions = normalizeSendMessageOptions(this.name, options);
|
|
160
277
|
|
|
@@ -202,14 +319,32 @@ export class RetryProvider implements Provider {
|
|
|
202
319
|
},
|
|
203
320
|
"Retrying after transient error",
|
|
204
321
|
);
|
|
322
|
+
didRetry = true;
|
|
205
323
|
await sleep(delay);
|
|
206
324
|
continue;
|
|
207
325
|
}
|
|
208
326
|
|
|
327
|
+
// If we exhausted retries on a retryable error, tag the error so
|
|
328
|
+
// downstream consumers (Sentry capture, etc.) can recognize that the
|
|
329
|
+
// retry loop already tried its best. The catch-site logic above only
|
|
330
|
+
// stops retrying when either (a) retries are exhausted, or (b) the
|
|
331
|
+
// error isn't retryable — so we check the retryable predicate here to
|
|
332
|
+
// distinguish the two cases.
|
|
333
|
+
if (didRetry && isRetryableError(error) && error instanceof Error) {
|
|
334
|
+
(error as Error & { retriesExhausted?: boolean }).retriesExhausted =
|
|
335
|
+
true;
|
|
336
|
+
}
|
|
337
|
+
|
|
209
338
|
throw error;
|
|
210
339
|
}
|
|
211
340
|
}
|
|
212
341
|
|
|
342
|
+
// Unreachable in practice — the loop body always either returns or throws —
|
|
343
|
+
// but mark the last error in case execution somehow falls through.
|
|
344
|
+
if (lastError instanceof Error && isRetryableError(lastError)) {
|
|
345
|
+
(lastError as Error & { retriesExhausted?: boolean }).retriesExhausted =
|
|
346
|
+
true;
|
|
347
|
+
}
|
|
213
348
|
throw lastError;
|
|
214
349
|
}
|
|
215
350
|
}
|
|
@@ -70,6 +70,7 @@ mock.module("../../../security/credential-key.js", () => ({
|
|
|
70
70
|
const deepgramCtorCalls: Array<{ apiKey: string; options: unknown }> = [];
|
|
71
71
|
const geminiCtorCalls: Array<{ apiKey: string; options: unknown }> = [];
|
|
72
72
|
const whisperCtorCalls: Array<{ apiKey: string; options: unknown }> = [];
|
|
73
|
+
const xaiCtorCalls: Array<{ apiKey: string; options: unknown }> = [];
|
|
73
74
|
|
|
74
75
|
mock.module("../deepgram-realtime.js", () => ({
|
|
75
76
|
DeepgramRealtimeTranscriber: class {
|
|
@@ -101,6 +102,16 @@ mock.module("../openai-whisper-stream.js", () => ({
|
|
|
101
102
|
},
|
|
102
103
|
}));
|
|
103
104
|
|
|
105
|
+
mock.module("../xai-realtime.js", () => ({
|
|
106
|
+
XAIRealtimeTranscriber: class {
|
|
107
|
+
readonly providerId = "xai" as const;
|
|
108
|
+
readonly boundaryId = "daemon-streaming" as const;
|
|
109
|
+
constructor(apiKey: string, options: unknown) {
|
|
110
|
+
xaiCtorCalls.push({ apiKey, options });
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
}));
|
|
114
|
+
|
|
104
115
|
// ---------------------------------------------------------------------------
|
|
105
116
|
// Subject import (after mocks)
|
|
106
117
|
//
|
|
@@ -541,6 +552,7 @@ describe("telephony routing catalog alignment", () => {
|
|
|
541
552
|
"openai-whisper": "openai",
|
|
542
553
|
deepgram: "deepgram",
|
|
543
554
|
"google-gemini": "gemini",
|
|
555
|
+
xai: "xai",
|
|
544
556
|
};
|
|
545
557
|
|
|
546
558
|
for (const id of listProviderIds()) {
|
|
@@ -714,6 +726,7 @@ describe("resolveStreamingTranscriber diarize preference", () => {
|
|
|
714
726
|
deepgramCtorCalls.length = 0;
|
|
715
727
|
geminiCtorCalls.length = 0;
|
|
716
728
|
whisperCtorCalls.length = 0;
|
|
729
|
+
xaiCtorCalls.length = 0;
|
|
717
730
|
loggerWarnings.length = 0;
|
|
718
731
|
});
|
|
719
732
|
|
|
@@ -825,4 +838,46 @@ describe("resolveStreamingTranscriber diarize preference", () => {
|
|
|
825
838
|
expect(options.sampleRate).toBe(48000);
|
|
826
839
|
expect(options.diarize).toBe(true);
|
|
827
840
|
});
|
|
841
|
+
|
|
842
|
+
// -------------------------------------------------------------------------
|
|
843
|
+
// xAI realtime streaming
|
|
844
|
+
// -------------------------------------------------------------------------
|
|
845
|
+
|
|
846
|
+
test("resolves a non-null xai transcriber when xai is configured and credentials are available", async () => {
|
|
847
|
+
mockProviderKeys["xai"] = "xai-key";
|
|
848
|
+
mockConfig = buildConfig({ provider: "xai" });
|
|
849
|
+
|
|
850
|
+
const transcriber = await resolveStreamingTranscriber();
|
|
851
|
+
|
|
852
|
+
expect(transcriber).not.toBeNull();
|
|
853
|
+
expect(transcriber!.providerId).toBe("xai");
|
|
854
|
+
expect(transcriber!.boundaryId).toBe("daemon-streaming");
|
|
855
|
+
expect(xaiCtorCalls).toHaveLength(1);
|
|
856
|
+
});
|
|
857
|
+
|
|
858
|
+
test("diarize: 'required' with xai constructs the transcriber (does not reject)", async () => {
|
|
859
|
+
mockProviderKeys["xai"] = "xai-key";
|
|
860
|
+
mockConfig = buildConfig({ provider: "xai" });
|
|
861
|
+
|
|
862
|
+
const transcriber = await resolveStreamingTranscriber({
|
|
863
|
+
diarize: "required",
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
expect(transcriber).not.toBeNull();
|
|
867
|
+
expect(xaiCtorCalls).toHaveLength(1);
|
|
868
|
+
const options = xaiCtorCalls[0]!.options as Record<string, unknown>;
|
|
869
|
+
expect(options.diarize).toBe(true);
|
|
870
|
+
// No warning logged — xai supports diarization per the catalog.
|
|
871
|
+
expect(loggerWarnings).toHaveLength(0);
|
|
872
|
+
});
|
|
873
|
+
|
|
874
|
+
test("returns null for xai when no credential is set", async () => {
|
|
875
|
+
mockProviderKeys = {};
|
|
876
|
+
mockConfig = buildConfig({ provider: "xai" });
|
|
877
|
+
|
|
878
|
+
const transcriber = await resolveStreamingTranscriber();
|
|
879
|
+
|
|
880
|
+
expect(transcriber).toBeNull();
|
|
881
|
+
expect(xaiCtorCalls).toHaveLength(0);
|
|
882
|
+
});
|
|
828
883
|
});
|
|
@@ -805,6 +805,67 @@ describe("DeepgramRealtimeTranscriber", () => {
|
|
|
805
805
|
expect(errorEvents).toHaveLength(0);
|
|
806
806
|
});
|
|
807
807
|
|
|
808
|
+
// ─────────────────────────────────────────────────────────────────
|
|
809
|
+
// KeepAlive
|
|
810
|
+
// ─────────────────────────────────────────────────────────────────
|
|
811
|
+
|
|
812
|
+
test("sends KeepAlive frames at the configured interval while open", async () => {
|
|
813
|
+
const { transcriber } = await startSession({
|
|
814
|
+
keepaliveIntervalMs: 30,
|
|
815
|
+
});
|
|
816
|
+
|
|
817
|
+
// Wait long enough that at least two KeepAlives fire even on a loaded
|
|
818
|
+
// CI runner with event-loop jitter.
|
|
819
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
820
|
+
|
|
821
|
+
const keepalives = mockWs.sentData.filter(
|
|
822
|
+
(d) => typeof d === "string" && d === '{"type":"KeepAlive"}',
|
|
823
|
+
);
|
|
824
|
+
expect(keepalives.length).toBeGreaterThanOrEqual(2);
|
|
825
|
+
|
|
826
|
+
transcriber.stop();
|
|
827
|
+
});
|
|
828
|
+
|
|
829
|
+
test("KeepAlive timer stops firing after stop()", async () => {
|
|
830
|
+
const { transcriber } = await startSession({
|
|
831
|
+
keepaliveIntervalMs: 30,
|
|
832
|
+
});
|
|
833
|
+
|
|
834
|
+
// Let one KeepAlive fire so we know the interval is running.
|
|
835
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
836
|
+
const beforeStop = mockWs.sentData.filter(
|
|
837
|
+
(d) => typeof d === "string" && d === '{"type":"KeepAlive"}',
|
|
838
|
+
).length;
|
|
839
|
+
expect(beforeStop).toBeGreaterThanOrEqual(1);
|
|
840
|
+
|
|
841
|
+
transcriber.stop();
|
|
842
|
+
|
|
843
|
+
// Drain the close grace flow.
|
|
844
|
+
await new Promise((resolve) => setTimeout(resolve, 80));
|
|
845
|
+
|
|
846
|
+
// The interval should be cleared — count must not have grown beyond
|
|
847
|
+
// what was already buffered before stop(). Tolerate one extra fire
|
|
848
|
+
// racing with stop()'s synchronous clear path, but no more.
|
|
849
|
+
const afterStop = mockWs.sentData.filter(
|
|
850
|
+
(d) => typeof d === "string" && d === '{"type":"KeepAlive"}',
|
|
851
|
+
).length;
|
|
852
|
+
expect(afterStop).toBeLessThanOrEqual(beforeStop + 1);
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
test("keepaliveIntervalMs=0 disables the timer entirely", async () => {
|
|
856
|
+
const { transcriber } = await startSession({
|
|
857
|
+
keepaliveIntervalMs: 0,
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
await new Promise((resolve) => setTimeout(resolve, 80));
|
|
861
|
+
const keepalives = mockWs.sentData.filter(
|
|
862
|
+
(d) => typeof d === "string" && d === '{"type":"KeepAlive"}',
|
|
863
|
+
);
|
|
864
|
+
expect(keepalives).toHaveLength(0);
|
|
865
|
+
|
|
866
|
+
transcriber.stop();
|
|
867
|
+
});
|
|
868
|
+
|
|
808
869
|
// ─────────────────────────────────────────────────────────────────
|
|
809
870
|
// WebSocket URL construction
|
|
810
871
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -53,6 +53,17 @@ const DEFAULT_CONNECT_TIMEOUT_MS = 10_000;
|
|
|
53
53
|
*/
|
|
54
54
|
const DEFAULT_INACTIVITY_TIMEOUT_MS = 30_000;
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Default interval (ms) for emitting Deepgram `KeepAlive` control frames
|
|
58
|
+
* during silent stretches. Deepgram's server-side timeout closes the
|
|
59
|
+
* socket if no real audio content arrives for ~10s; raw silence PCM does
|
|
60
|
+
* not reset that timer, only an explicit `{"type":"KeepAlive"}` message
|
|
61
|
+
* does. Sending one every 5s keeps the socket alive through arbitrary
|
|
62
|
+
* pauses (think: 1:1 voice mode while the user is thinking) without any
|
|
63
|
+
* meaningful bandwidth cost.
|
|
64
|
+
*/
|
|
65
|
+
const DEFAULT_KEEPALIVE_INTERVAL_MS = 5_000;
|
|
66
|
+
|
|
56
67
|
/**
|
|
57
68
|
* Maximum WebSocket bufferedAmount (bytes) before sendAudio applies
|
|
58
69
|
* backpressure by dropping frames. This prevents unbounded memory growth
|
|
@@ -87,6 +98,13 @@ export interface DeepgramRealtimeOptions {
|
|
|
87
98
|
connectTimeoutMs?: number;
|
|
88
99
|
/** Inactivity timeout in milliseconds. Default: 30_000. */
|
|
89
100
|
inactivityTimeoutMs?: number;
|
|
101
|
+
/**
|
|
102
|
+
* Interval (ms) between Deepgram `KeepAlive` control frames sent during
|
|
103
|
+
* silent stretches. Default: 5_000. Set to 0 to disable (not recommended
|
|
104
|
+
* outside tests — the server-side socket will close after ~10s of
|
|
105
|
+
* silence).
|
|
106
|
+
*/
|
|
107
|
+
keepaliveIntervalMs?: number;
|
|
90
108
|
/** Audio sample rate in Hz (default: 16000). Passed through from the client WebSocket connection. */
|
|
91
109
|
sampleRate?: number;
|
|
92
110
|
/**
|
|
@@ -222,6 +240,7 @@ export class DeepgramRealtimeTranscriber implements StreamingTranscriber {
|
|
|
222
240
|
private readonly baseUrl: string;
|
|
223
241
|
private readonly connectTimeoutMs: number;
|
|
224
242
|
private readonly inactivityTimeoutMs: number;
|
|
243
|
+
private readonly keepaliveIntervalMs: number;
|
|
225
244
|
private readonly sampleRate: number;
|
|
226
245
|
/**
|
|
227
246
|
* Whether speaker diarization is requested. Forwarded to the Deepgram
|
|
@@ -248,6 +267,13 @@ export class DeepgramRealtimeTranscriber implements StreamingTranscriber {
|
|
|
248
267
|
/** Close grace timer handle. */
|
|
249
268
|
private closeGraceTimer: ReturnType<typeof setTimeout> | null = null;
|
|
250
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Periodic keepalive timer. Fires every {@link keepaliveIntervalMs} while
|
|
272
|
+
* the socket is open and emits a Deepgram `KeepAlive` control frame so
|
|
273
|
+
* silent stretches do not trip Deepgram's server-side inactivity close.
|
|
274
|
+
*/
|
|
275
|
+
private keepaliveTimer: ReturnType<typeof setInterval> | null = null;
|
|
276
|
+
|
|
251
277
|
constructor(apiKey: string, options: DeepgramRealtimeOptions = {}) {
|
|
252
278
|
this.apiKey = apiKey;
|
|
253
279
|
this.model = options.model ?? DEFAULT_MODEL;
|
|
@@ -260,6 +286,8 @@ export class DeepgramRealtimeTranscriber implements StreamingTranscriber {
|
|
|
260
286
|
options.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
|
|
261
287
|
this.inactivityTimeoutMs =
|
|
262
288
|
options.inactivityTimeoutMs ?? DEFAULT_INACTIVITY_TIMEOUT_MS;
|
|
289
|
+
this.keepaliveIntervalMs =
|
|
290
|
+
options.keepaliveIntervalMs ?? DEFAULT_KEEPALIVE_INTERVAL_MS;
|
|
263
291
|
this.sampleRate = options.sampleRate ?? 16_000;
|
|
264
292
|
this.diarize = options.diarize ?? false;
|
|
265
293
|
}
|
|
@@ -329,6 +357,7 @@ export class DeepgramRealtimeTranscriber implements StreamingTranscriber {
|
|
|
329
357
|
// the active session lifetime.
|
|
330
358
|
this.attachSessionHandlers(ws);
|
|
331
359
|
this.resetInactivityTimer();
|
|
360
|
+
this.startKeepaliveTimer();
|
|
332
361
|
|
|
333
362
|
log.info("Deepgram realtime session opened");
|
|
334
363
|
}
|
|
@@ -644,6 +673,34 @@ export class DeepgramRealtimeTranscriber implements StreamingTranscriber {
|
|
|
644
673
|
clearTimeout(this.closeGraceTimer);
|
|
645
674
|
this.closeGraceTimer = null;
|
|
646
675
|
}
|
|
676
|
+
if (this.keepaliveTimer !== null) {
|
|
677
|
+
clearInterval(this.keepaliveTimer);
|
|
678
|
+
this.keepaliveTimer = null;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* Start the periodic keepalive timer. Sends a Deepgram `KeepAlive`
|
|
684
|
+
* control frame every {@link keepaliveIntervalMs}; this is the only
|
|
685
|
+
* thing that resets Deepgram's server-side inactivity timer when the
|
|
686
|
+
* stream is carrying silence (raw silence PCM frames do not count).
|
|
687
|
+
*
|
|
688
|
+
* Skipped when {@link keepaliveIntervalMs} is 0 (test override) or the
|
|
689
|
+
* adapter is already closed/stopping.
|
|
690
|
+
*/
|
|
691
|
+
private startKeepaliveTimer(): void {
|
|
692
|
+
if (this.closed || this.stopping) return;
|
|
693
|
+
if (this.keepaliveIntervalMs <= 0) return;
|
|
694
|
+
this.keepaliveTimer = setInterval(() => {
|
|
695
|
+
if (this.closed || this.stopping) return;
|
|
696
|
+
const ws = this.ws;
|
|
697
|
+
if (!ws || ws.readyState !== WS_OPEN) return;
|
|
698
|
+
try {
|
|
699
|
+
ws.send(JSON.stringify({ type: "KeepAlive" }));
|
|
700
|
+
} catch (err) {
|
|
701
|
+
log.warn({ err }, "Deepgram KeepAlive send failed");
|
|
702
|
+
}
|
|
703
|
+
}, this.keepaliveIntervalMs);
|
|
647
704
|
}
|
|
648
705
|
|
|
649
706
|
/**
|
|
@@ -250,10 +250,9 @@ export class GoogleGeminiLiveStreamingTranscriber implements StreamingTranscribe
|
|
|
250
250
|
let timedOut = false;
|
|
251
251
|
connectPromise
|
|
252
252
|
.then((session) => {
|
|
253
|
-
if (timedOut) {
|
|
254
|
-
// Never assign a session after
|
|
255
|
-
// `this.session` would persist
|
|
256
|
-
// retry would incorrectly trip the "start() called twice" guard.
|
|
253
|
+
if (timedOut || this.closed || this.stopping) {
|
|
254
|
+
// Never assign a session after shutdown or timeout: if we did,
|
|
255
|
+
// `this.session` would persist as an orphaned live WebSocket.
|
|
257
256
|
try {
|
|
258
257
|
session.close();
|
|
259
258
|
} catch {
|
|
@@ -398,6 +397,7 @@ export class GoogleGeminiLiveStreamingTranscriber implements StreamingTranscribe
|
|
|
398
397
|
serverContent.turnComplete === true;
|
|
399
398
|
|
|
400
399
|
if (isComplete) {
|
|
400
|
+
if (this.finalEmittedForCurrentTurn) return;
|
|
401
401
|
const finalText = this.currentTurnText;
|
|
402
402
|
this.currentTurnText = "";
|
|
403
403
|
this.lastEmittedPartial = "";
|
|
@@ -219,6 +219,23 @@ const CATALOG: ReadonlyMap<SttProviderId, SttProviderEntry> = new Map<
|
|
|
219
219
|
},
|
|
220
220
|
},
|
|
221
221
|
],
|
|
222
|
+
[
|
|
223
|
+
"xai",
|
|
224
|
+
{
|
|
225
|
+
id: "xai",
|
|
226
|
+
credentialProvider: "xai",
|
|
227
|
+
supportedBoundaries: new Set<SttBoundaryId>([
|
|
228
|
+
"daemon-batch",
|
|
229
|
+
"daemon-streaming",
|
|
230
|
+
]),
|
|
231
|
+
telephonyMode: "batch-only",
|
|
232
|
+
conversationStreamingMode: "realtime-ws",
|
|
233
|
+
supportsDiarization: true,
|
|
234
|
+
telephonyRouting: {
|
|
235
|
+
strategyKind: "media-stream-custom",
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
],
|
|
222
239
|
]);
|
|
223
240
|
|
|
224
241
|
// ---------------------------------------------------------------------------
|
|
@@ -381,6 +381,13 @@ async function createStreamingTranscriber(
|
|
|
381
381
|
pcmSampleRate: options.sampleRate,
|
|
382
382
|
});
|
|
383
383
|
}
|
|
384
|
+
case "xai": {
|
|
385
|
+
const { XAIRealtimeTranscriber } = await import("./xai-realtime.js");
|
|
386
|
+
return new XAIRealtimeTranscriber(apiKey, {
|
|
387
|
+
sampleRate: options.sampleRate,
|
|
388
|
+
...(options.diarize ? { diarize: true } : {}),
|
|
389
|
+
});
|
|
390
|
+
}
|
|
384
391
|
default: {
|
|
385
392
|
const _exhaustive: never = providerId;
|
|
386
393
|
return null;
|