@vellumai/assistant 0.12.2 → 0.12.3-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/.env.example +2 -0
- package/AGENTS.md +1 -1
- package/ARCHITECTURE.md +43 -29
- package/Dockerfile +63 -0
- package/docs/architecture/integrations.md +7 -0
- package/docs/architecture/memory.md +17 -2
- package/docs/architecture/security.md +10 -5
- package/docs/architecture/turn-actor.md +2 -0
- package/docs/credential-execution-service.md +1 -1
- package/docs/desktop-browser-cli.md +50 -5
- package/docs/live-voice-task-outcomes.md +100 -0
- package/docs/mode-sessions.md +183 -0
- package/docs/voice-input-diagnostics.md +58 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +2 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/integration-categories.ts +36 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +4 -1
- package/node_modules/@vellumai/environments/src/shell.test.ts +21 -0
- package/node_modules/@vellumai/environments/src/shell.ts +24 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +2 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/integration-categories.ts +36 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +4 -1
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +20 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +8 -2
- package/node_modules/@vellumai/gateway-client/src/index.ts +4 -1
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +38 -7
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +5 -6
- package/node_modules/@vellumai/service-contracts/package.json +2 -1
- package/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/integration-categories.ts +36 -0
- package/node_modules/@vellumai/service-contracts/src/secret-detection.ts +4 -1
- package/node_modules/@vellumai/slack-text/src/index.ts +4 -8
- package/openapi.yaml +716 -16
- package/package.json +1 -1
- package/scripts/smoke-desktop-browser-cli.ts +11 -26
- package/scripts/smoke-desktop-window-theme.ts +2 -3
- package/scripts/sync-llm-catalog.ts +3 -0
- package/scripts/voice-ttft-spike.ts +2 -2
- package/src/__tests__/agent-loop-output-hooks.test.ts +150 -1
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +87 -19
- package/src/__tests__/agent-loop.test.ts +259 -0
- package/src/__tests__/agent-wake-delegation-prompt.test.ts +64 -2
- package/src/__tests__/annotate-activity-metadata.test.ts +3 -1
- package/src/__tests__/annotate-risk-options.test.ts +2 -0
- package/src/__tests__/answered-question-persistence.test.ts +2 -0
- package/src/__tests__/anthropic-gateway-shared.test.ts +22 -0
- package/src/__tests__/anthropic-provider.test.ts +55 -0
- package/src/__tests__/approval-interception-trust-gates.test.ts +40 -0
- package/src/__tests__/approval-message-composer.test.ts +1 -118
- package/src/__tests__/approval-routes-http.test.ts +3 -0
- package/src/__tests__/assistant-event-hub-connection-history.test.ts +111 -0
- package/src/__tests__/assistant-event-hub-targeted.test.ts +50 -0
- package/src/__tests__/assistant-event-targeting.test.ts +186 -0
- package/src/__tests__/assistant-stream-state.test.ts +29 -9
- package/src/__tests__/attachments-store.test.ts +22 -3
- package/src/__tests__/browser-fill-credential.test.ts +11 -22
- package/src/__tests__/btw-routes.test.ts +4 -1
- package/src/__tests__/build-persisted-content.test.ts +1 -1
- package/src/__tests__/call-conversation-messages.test.ts +5 -0
- package/src/__tests__/call-recovery.test.ts +7 -2
- package/src/__tests__/call-routes-http.test.ts +12 -0
- package/src/__tests__/call-store.test.ts +7 -2
- package/src/__tests__/channel-approval.test.ts +9 -14
- package/src/__tests__/channel-reply-delivery.test.ts +56 -0
- package/src/__tests__/channel-retry-sweep.test.ts +9 -0
- package/src/__tests__/chat-credential-redaction.test.ts +23 -0
- package/src/__tests__/chat-reveal-guard-priming.test.ts +2 -0
- package/src/__tests__/checker.test.ts +11 -3
- package/src/__tests__/client-os-metadata-persistence.test.ts +35 -1
- package/src/__tests__/computer-use-screenshot-attachments.test.ts +411 -0
- package/src/__tests__/computer-use-screenshot-selection.test.ts +50 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +0 -25
- package/src/__tests__/computer-use-tools.test.ts +1 -233
- package/src/__tests__/config-model-image-provider.test.ts +39 -0
- package/src/__tests__/config-schema.test.ts +16 -0
- package/src/__tests__/config-watcher.test.ts +24 -0
- package/src/__tests__/context-search-agent-runner.test.ts +260 -1
- package/src/__tests__/context-search-fanout.test.ts +1 -1
- package/src/__tests__/context-search-types.test.ts +7 -7
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +8 -2
- package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop.test.ts +797 -16
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +53 -1
- package/src/__tests__/conversation-attachments.test.ts +106 -0
- package/src/__tests__/conversation-evictor.test.ts +62 -37
- package/src/__tests__/conversation-fork-crud.test.ts +191 -0
- package/src/__tests__/conversation-history-boundary-repair-failure.test.ts +174 -0
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +2 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +2 -0
- package/src/__tests__/conversation-rendered-delegation-state.test.ts +276 -0
- package/src/__tests__/conversation-retry-route.test.ts +22 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +2 -0
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +2 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +10 -0
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +2 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +29 -0
- package/src/__tests__/conversation-surface-snapshots.test.ts +543 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +151 -0
- package/src/__tests__/conversation-surfaces-point-at-budget.test.ts +63 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +23 -0
- package/src/__tests__/conversation-undo.test.ts +61 -0
- package/src/__tests__/credential-execution-client.test.ts +72 -55
- package/src/__tests__/credential-prompt-route.test.ts +35 -3
- package/src/__tests__/cu-unified-flow.test.ts +82 -1
- package/src/__tests__/db-conversation-tool-surface.test.ts +221 -0
- package/src/__tests__/db-mode-sessions-migration.test.ts +175 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -0
- package/src/__tests__/dm-backfill.test.ts +91 -1
- package/src/__tests__/document-create-route.test.ts +88 -0
- package/src/__tests__/document-sync-tags.test.ts +27 -0
- package/src/__tests__/emit-signal-routing-intent.test.ts +142 -2
- package/src/__tests__/events-tail-route.test.ts +58 -0
- package/src/__tests__/evict-conversations-for-reload.test.ts +57 -8
- package/src/__tests__/guardian-action-sweep.test.ts +16 -0
- package/src/__tests__/guardian-dispatch.test.ts +13 -0
- package/src/__tests__/headless-browser-interactions.test.ts +64 -20
- package/src/__tests__/heartbeat-service.test.ts +2 -59
- package/src/__tests__/helpers/mock-conversation.ts +21 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +2 -0
- package/src/__tests__/helpers/verification-sessions-ipc-sim.ts +5 -0
- package/src/__tests__/history-repair.test.ts +53 -0
- package/src/__tests__/host-cu-proxy.test.ts +46 -2
- package/src/__tests__/http-user-message-parity.test.ts +2 -0
- package/src/__tests__/image-credentials.test.ts +49 -0
- package/src/__tests__/image-service-dispatcher.test.ts +45 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +26 -0
- package/src/__tests__/interrupt-on-send.test.ts +57 -43
- package/src/__tests__/interrupt-turn-note.test.ts +5 -6
- package/src/__tests__/list-messages-tool-merge.test.ts +85 -1
- package/src/__tests__/llm-catalog-parity.test.ts +27 -4
- package/src/__tests__/media-generate-image.test.ts +49 -1
- package/src/__tests__/message-provenance-contact-id.test.ts +69 -0
- package/src/__tests__/migration-export-to-gcs.test.ts +142 -0
- package/src/__tests__/mode-session-history.test.ts +245 -0
- package/src/__tests__/mode-session-recovery.test.ts +222 -0
- package/src/__tests__/mode-session-wire.test.ts +141 -0
- package/src/__tests__/notification-guardian-path.test.ts +7 -0
- package/src/__tests__/notification-telegram-adapter.test.ts +2 -2
- package/src/__tests__/notification-vellum-adapter.test.ts +34 -0
- package/src/__tests__/oauth-apps-routes.test.ts +1 -0
- package/src/__tests__/oauth-commands-routes.test.ts +114 -101
- package/src/__tests__/oauth-connect-orchestrator.test.ts +2 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +13 -0
- package/src/__tests__/oauth-providers-routes.test.ts +3 -0
- package/src/__tests__/outbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/persist-media-references.test.ts +50 -0
- package/src/__tests__/persistence-secret-redaction.test.ts +2 -0
- package/src/__tests__/plugin-api-provider.test.ts +5 -0
- package/src/__tests__/plugin-api-resolve-credential.test.ts +97 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +9 -1
- package/src/__tests__/process-message-display-content.test.ts +56 -0
- package/src/__tests__/reaction-persistence.test.ts +5 -0
- package/src/__tests__/request-secret-standalone-channel-gate.test.ts +25 -9
- package/src/__tests__/run-conversation-turn-persistence.test.ts +138 -1
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +1 -1
- package/src/__tests__/schedule-routes.test.ts +20 -0
- package/src/__tests__/scheduler-result-notification.test.ts +23 -4
- package/src/__tests__/script-proxy-certs.test.ts +1 -1
- package/src/__tests__/scripted-turn-metadata-persistence.test.ts +73 -0
- package/src/__tests__/secret-ingress-http.test.ts +2 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +86 -31
- package/src/__tests__/secret-routes-scrub.test.ts +22 -27
- package/src/__tests__/secret-scanner.test.ts +20 -0
- package/src/__tests__/secure-keys-managed-failover.test.ts +8 -0
- package/src/__tests__/secure-keys.test.ts +50 -4
- package/src/__tests__/send-endpoint-busy.test.ts +163 -1
- package/src/__tests__/server-history-render.test.ts +91 -1
- package/src/__tests__/server-tool-pairing.test.ts +107 -0
- package/src/__tests__/settings-routes.test.ts +50 -1
- package/src/__tests__/skill-script-runner-sandbox.test.ts +32 -0
- package/src/__tests__/skills.test.ts +5 -4
- package/src/__tests__/subagent-fork-notifications.test.ts +1 -2
- package/src/__tests__/subagent-manager-notify.test.ts +1 -2
- package/src/__tests__/subagent-notify-parent.test.ts +146 -39
- package/src/__tests__/subagent-notify-stale-rebuild.test.ts +2 -4
- package/src/__tests__/subagent-tool-gate-mode.test.ts +226 -0
- package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +2 -0
- package/src/__tests__/terminal-tools.test.ts +8 -0
- package/src/__tests__/thread-backfill.test.ts +53 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +2 -0
- package/src/__tests__/tool-result-follow-up.test.ts +99 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +66 -1
- package/src/__tests__/tool-start-timestamp.test.ts +2 -0
- package/src/__tests__/twilio-routes.test.ts +1 -0
- package/src/__tests__/unicode.test.ts +36 -0
- package/src/__tests__/web-search-backend-failure.test.ts +1 -1
- package/src/activation/progress-store.test.ts +12 -7
- package/src/agent/loop.ts +136 -53
- package/src/agent/tool-result-follow-up.ts +70 -0
- package/src/api/attachment-provenance.test.ts +68 -0
- package/src/api/computer-use-tool.test.ts +55 -0
- package/src/api/computer-use-tool.ts +27 -0
- package/src/api/events/assistant-outbound-attachment.ts +3 -0
- package/src/api/events/assistant-turn-start.ts +3 -0
- package/src/api/events/desktop-activity-changed.ts +10 -0
- package/src/api/events/generation-handoff.ts +2 -0
- package/src/api/events/message-complete.ts +2 -0
- package/src/api/events/notification-conversation-created.ts +14 -16
- package/src/api/events/notification-intent.ts +4 -2
- package/src/api/events/question-request.ts +1 -0
- package/src/api/events/tool-result.ts +85 -0
- package/src/api/events/tool-use-start.ts +3 -0
- package/src/api/events/user-message-echo.ts +3 -0
- package/src/api/index.ts +42 -6
- package/src/api/mode-session.test.ts +131 -0
- package/src/api/mode-session.ts +148 -0
- package/src/api/remember-tool.ts +15 -0
- package/src/api/responses/conversation-message.ts +9 -0
- package/src/approvals/AGENTS.md +4 -2
- package/src/approvals/approval-primitive.ts +5 -2
- package/src/approvals/scoped-approval-grants.ts +6 -2
- package/src/browser/__tests__/operations.test.ts +29 -0
- package/src/browser/operation-meta.ts +2 -1
- package/src/browser/operations.ts +29 -0
- package/src/browser/virtual-desktop-target.ts +2 -9
- package/src/bundler/bundle-signer.ts +1 -3
- package/src/calls/__tests__/barge-in-guard.test.ts +3 -0
- package/src/calls/__tests__/call-controller.test.ts +94 -0
- package/src/calls/__tests__/call-funnel-telemetry.test.ts +204 -0
- package/src/calls/__tests__/voice-control-protocol.test.ts +15 -0
- package/src/calls/__tests__/voice-escalation-judge.test.ts +209 -0
- package/src/calls/__tests__/voice-leg-coordinator.test.ts +168 -0
- package/src/{live-voice/__tests__/live-voice-metrics.test.ts → calls/__tests__/voice-metrics.test.ts} +32 -38
- package/src/calls/__tests__/voice-session-bridge.test.ts +576 -122
- package/src/calls/barge-in-guard.ts +5 -0
- package/src/calls/call-controller.ts +196 -1
- package/src/calls/call-domain.ts +4 -0
- package/src/calls/call-store.ts +87 -2
- package/src/calls/guardian-action-sweep.ts +22 -8
- package/src/calls/media-stream-audio-transcode.ts +1 -3
- package/src/calls/typesafe-noul.ts +156 -0
- package/src/calls/voice-control-protocol.ts +6 -0
- package/src/calls/voice-escalation-judge.ts +145 -0
- package/src/calls/voice-escalation-target.ts +10 -0
- package/src/calls/voice-leg-coordinator.ts +121 -3
- package/src/{live-voice/live-voice-metrics.ts → calls/voice-metrics.ts} +94 -87
- package/src/calls/voice-session-bridge.ts +256 -112
- package/src/calls/voice-triage-escalate.ts +7 -0
- package/src/cli/__tests__/roadmap-cli.test.ts +4 -41
- package/src/cli/commands/__tests__/cli-test-harness.ts +21 -3
- package/src/cli/commands/__tests__/notifications.test.ts +35 -10
- package/src/cli/commands/__tests__/plugins.test.ts +20 -1
- package/src/cli/commands/__tests__/schedules.test.ts +14 -0
- package/src/cli/commands/bash.help.ts +4 -3
- package/src/cli/commands/browser.help.ts +9 -6
- package/src/cli/commands/browser.ts +0 -1
- package/src/cli/commands/clients.help.ts +46 -0
- package/src/cli/commands/clients.ts +116 -0
- package/src/cli/commands/credentials.help.ts +9 -4
- package/src/cli/commands/notifications.help.ts +16 -2
- package/src/cli/commands/notifications.ts +30 -8
- package/src/cli/commands/oauth/index.help.ts +10 -0
- package/src/cli/commands/oauth/providers.ts +12 -0
- package/src/cli/commands/oauth/request.test.ts +179 -2
- package/src/cli/commands/oauth/request.ts +41 -10
- package/src/cli/commands/plugins.ts +12 -5
- package/src/cli/commands/roadmap.help.ts +18 -21
- package/src/cli/commands/roadmap.ts +4 -21
- package/src/cli/commands/schedules.ts +2 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +41 -0
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +5 -2
- package/src/cli/lib/__tests__/local-plugin-upgrade.test.ts +133 -51
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +8 -2
- package/src/cli/lib/bundled-marketplace.json +906 -1
- package/src/cli/lib/bundled-plugin-packages.json +783 -1
- package/src/cli/lib/inspect-plugin.ts +11 -4
- package/src/cli/lib/plugin-marketplace.ts +8 -0
- package/src/cli/lib/publish-plugin.ts +1 -2
- package/src/cli/lib/upgrade-plugin.ts +19 -11
- package/src/cli/output.ts +18 -4
- package/src/config/__tests__/default-provider.test.ts +6 -0
- package/src/config/__tests__/memory-retrospective-schema.test.ts +14 -1
- package/src/config/bundled-skills/computer-use/SKILL.md +1 -1
- package/src/config/bundled-skills/computer-use/TOOLS.json +89 -1
- package/src/config/bundled-skills/image-studio/SKILL.md +17 -2
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +7 -11
- package/src/config/bundled-skills/schedule/SKILL.md +6 -6
- package/src/config/bundled-skills/sequences/TOOLS.json +1 -5
- package/src/config/call-site-defaults.ts +9 -0
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/loader.ts +9 -17
- package/src/config/platform-identity.ts +8 -8
- package/src/config/profile-text-generation.test.ts +51 -0
- package/src/config/profile-text-generation.ts +51 -0
- package/src/config/schemas/__tests__/memory-v3.test.ts +12 -0
- package/src/config/schemas/__tests__/tools.test.ts +31 -0
- package/src/config/schemas/call-site-catalog.ts +14 -0
- package/src/config/schemas/channels.ts +0 -18
- package/src/config/schemas/llm.ts +9 -2
- package/src/config/schemas/mcp.ts +6 -1
- package/src/config/schemas/memory-retrospective.ts +11 -2
- package/src/config/schemas/memory-v3.ts +12 -0
- package/src/config/schemas/services.ts +15 -6
- package/src/config/schemas/tools.ts +10 -0
- package/src/config/session-groups-gate.ts +21 -0
- package/src/config/skills.ts +2 -6
- package/src/conversations/__tests__/message-consolidation.test.ts +149 -0
- package/src/conversations/message-consolidation.ts +102 -5
- package/src/credential-execution/ces-connect.test.ts +69 -0
- package/src/credential-execution/ces-connect.ts +115 -0
- package/src/credential-execution/ces-runtime.ts +55 -93
- package/src/credential-execution/executable-discovery.ts +34 -142
- package/src/credential-execution/process-manager.test.ts +20 -24
- package/src/credential-execution/process-manager.ts +24 -19
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +10 -1
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +43 -0
- package/src/daemon/__tests__/inference-profile-notification.test.ts +2 -0
- package/src/daemon/__tests__/turn-tail-deleted-conversation.test.ts +36 -0
- package/src/daemon/assistant-attachments.ts +20 -12
- package/src/daemon/browser-mode-session.test.ts +402 -0
- package/src/daemon/browser-mode-session.ts +186 -0
- package/src/daemon/chat-credential-redaction.ts +16 -1
- package/src/daemon/computer-use-mode-session.test.ts +210 -0
- package/src/daemon/computer-use-mode-session.ts +105 -0
- package/src/daemon/config-watcher.ts +10 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +132 -13
- package/src/daemon/conversation-agent-loop.ts +231 -25
- package/src/daemon/conversation-attachments.ts +93 -12
- package/src/daemon/conversation-evictor.ts +5 -24
- package/src/daemon/conversation-history.ts +10 -0
- package/src/daemon/conversation-interrupt-repair.ts +4 -43
- package/src/daemon/conversation-interrupt.ts +7 -11
- package/src/daemon/conversation-messaging.ts +58 -5
- package/src/daemon/conversation-mode-session.test.ts +1667 -0
- package/src/daemon/conversation-mode-session.ts +1008 -0
- package/src/daemon/conversation-process.ts +5 -0
- package/src/daemon/conversation-runtime-assembly.ts +10 -20
- package/src/daemon/conversation-skill-tools.ts +1 -0
- package/src/daemon/conversation-store.ts +4 -4
- package/src/daemon/conversation-surface-snapshots.ts +135 -0
- package/src/daemon/conversation-surfaces.ts +113 -5
- package/src/daemon/conversation-tool-setup.ts +79 -6
- package/src/daemon/conversation-turn-finalize.ts +26 -13
- package/src/daemon/conversation.ts +215 -58
- package/src/daemon/daemon-control.ts +3 -7
- package/src/daemon/handlers/config-model.ts +7 -5
- package/src/daemon/handlers/shared.ts +55 -16
- package/src/daemon/host-cu-proxy.ts +51 -22
- package/src/daemon/lifecycle.ts +30 -13
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/message-protocol.ts +0 -1
- package/src/daemon/message-provenance.ts +28 -4
- package/src/daemon/message-types/shared.ts +1 -0
- package/src/daemon/mode-session-startup-recovery.ts +23 -0
- package/src/daemon/mode-session-tracking.ts +54 -0
- package/src/daemon/orphan-reaper.ts +4 -3
- package/src/daemon/persist-media-references.ts +20 -3
- package/src/daemon/process-message.ts +13 -4
- package/src/daemon/tool-setup-types.ts +6 -0
- package/src/daemon/virtual-desktop-context.ts +21 -0
- package/src/daemon/wake-conversation-ops.ts +50 -15
- package/src/desktop/__tests__/fake-desktop.ts +1 -0
- package/src/desktop/desktop-accessibility-script.ts +88 -0
- package/src/desktop/desktop-accessibility.test.ts +160 -0
- package/src/desktop/desktop-accessibility.ts +169 -0
- package/src/desktop/desktop-automation-lease.test.ts +302 -64
- package/src/desktop/desktop-automation-lease.ts +129 -54
- package/src/desktop/desktop-browser-endpoint.ts +4 -0
- package/src/desktop/desktop-computer-use-routing.test.ts +330 -0
- package/src/desktop/desktop-computer-use.test.ts +449 -0
- package/src/desktop/desktop-computer-use.ts +502 -0
- package/src/desktop/desktop-dependencies.ts +47 -293
- package/src/desktop/desktop-display.ts +2 -2
- package/src/desktop/desktop-help.ts +15 -0
- package/src/desktop/desktop-panel-config.test.ts +13 -3
- package/src/desktop/desktop-panel-config.ts +109 -15
- package/src/desktop/desktop-session-manager.test.ts +69 -21
- package/src/desktop/desktop-session-manager.ts +76 -22
- package/src/desktop/desktop-stream-bridge.test.ts +76 -132
- package/src/desktop/desktop-stream-bridge.ts +9 -11
- package/src/desktop/desktop-wallpaper-renderer.ts +132 -0
- package/src/desktop/desktop-wallpaper-worker.ts +17 -0
- package/src/desktop/desktop-wallpaper.test.ts +48 -7
- package/src/desktop/desktop-wallpaper.ts +34 -102
- package/src/desktop/desktop-window-theme.ts +5 -25
- package/src/desktop/virtual-desktop-feature.ts +53 -3
- package/src/desktop/virtual-desktop-platform.test.ts +5 -9
- package/src/documents/document-store.ts +23 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +22 -26
- package/src/heartbeat/heartbeat-service.ts +5 -33
- package/src/ipc/__tests__/browser-ipc.test.ts +215 -6
- package/src/ipc/assistant-server.ts +2 -0
- package/src/ipc/routes/__tests__/channel-reply-ipc-routes.test.ts +111 -0
- package/src/ipc/routes/channel-reply-ipc-routes.ts +73 -0
- package/src/live-voice/__tests__/continuation-judge.test.ts +151 -0
- package/src/live-voice/__tests__/live-activity-reporter.test.ts +154 -15
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +743 -31
- package/src/live-voice/__tests__/live-voice-look-follow-up.test.ts +191 -10
- package/src/live-voice/__tests__/live-voice-session-groups-gate.test.ts +87 -0
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +5 -1
- package/src/live-voice/__tests__/live-voice-sight-frame-echo.test.ts +41 -0
- package/src/live-voice/__tests__/live-voice-sight-frame.test.ts +1017 -9
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +224 -1
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +101 -0
- package/src/live-voice/__tests__/live-voice-tts.test.ts +44 -0
- package/src/live-voice/__tests__/live-voice-vad.test.ts +939 -75
- package/src/live-voice/__tests__/microphone-idle-gate.test.ts +87 -0
- package/src/live-voice/__tests__/session-controls.test.ts +23 -0
- package/src/live-voice/__tests__/task-outcomes.test.ts +117 -0
- package/src/live-voice/__tests__/voice-input-diagnostics.test.ts +117 -0
- package/src/live-voice/camera-mode-session.test.ts +265 -0
- package/src/live-voice/camera-mode-session.ts +277 -0
- package/src/live-voice/continuation-judge.ts +123 -0
- package/src/live-voice/live-activity-reporter.ts +115 -6
- package/src/live-voice/live-voice-manager.ts +36 -1
- package/src/live-voice/live-voice-photo.ts +88 -7
- package/src/live-voice/live-voice-session-manager.ts +15 -0
- package/src/live-voice/live-voice-session.ts +1443 -747
- package/src/live-voice/live-voice-tts.ts +22 -4
- package/src/live-voice/microphone-idle-gate.ts +56 -0
- package/src/live-voice/protocol.ts +171 -4
- package/src/live-voice/session-controls.ts +11 -3
- package/src/live-voice/task-outcomes.ts +131 -0
- package/src/live-voice/voice-input-diagnostics.ts +117 -0
- package/src/mcp/__tests__/manager-tool-caps.test.ts +156 -0
- package/src/mcp/__tests__/startup.test.ts +30 -7
- package/src/mcp/__tests__/tool-caps.test.ts +134 -0
- package/src/mcp/manager.ts +171 -101
- package/src/mcp/startup.ts +33 -13
- package/src/mcp/tool-caps.ts +184 -0
- package/src/media/__tests__/image-models.test.ts +58 -0
- package/src/media/image-credentials.ts +5 -0
- package/src/media/image-models.ts +52 -0
- package/src/media/image-service.ts +8 -0
- package/src/media/openrouter-image-service.test.ts +133 -0
- package/src/media/openrouter-image-service.ts +153 -0
- package/src/media/types.ts +1 -1
- package/src/messaging/provider-message-metadata.ts +3 -3
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +65 -11
- package/src/messaging/providers/discord/send.ts +4 -17
- package/src/messaging/providers/discord/transport.ts +2 -2
- package/src/messaging/providers/outlook/client.ts +16 -22
- package/src/messaging/providers/telegram-bot/send.test.ts +236 -1
- package/src/messaging/providers/telegram-bot/send.ts +10 -7
- package/src/messaging/providers/telegram-bot/transport.ts +3 -10
- package/src/messaging/providers/whatsapp/send.test.ts +169 -4
- package/src/monitoring/__tests__/control.test.ts +17 -5
- package/src/monitoring/control.ts +15 -5
- package/src/notifications/AGENTS.md +1 -1
- package/src/notifications/README.md +83 -99
- package/src/notifications/__tests__/broadcaster.test.ts +1 -1
- package/src/notifications/__tests__/channel-allowlist.test.ts +39 -0
- package/src/notifications/__tests__/copy-composer.test.ts +71 -1
- package/src/notifications/__tests__/decision-engine.test.ts +79 -2
- package/src/notifications/__tests__/deterministic-checks.test.ts +10 -10
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +93 -4
- package/src/notifications/__tests__/notification-utils.test.ts +18 -0
- package/src/notifications/adapters/macos.ts +37 -46
- package/src/notifications/broadcaster.ts +5 -6
- package/src/notifications/channel-allowlist.ts +44 -0
- package/src/notifications/copy-composer.ts +11 -26
- package/src/notifications/decision-engine.ts +24 -14
- package/src/notifications/deterministic-checks.ts +1 -1
- package/src/notifications/emit-signal.ts +123 -37
- package/src/notifications/home-feed-side-effect.ts +9 -7
- package/src/notifications/notification-utils.ts +19 -0
- package/src/notifications/schedule-result-producer.ts +4 -6
- package/src/notifications/signal.ts +4 -19
- package/src/notifications/types.ts +15 -0
- package/src/oauth/AGENTS.md +2 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +36 -1
- package/src/oauth/connection-resolver.ts +1 -2
- package/src/oauth/identity-verifier.ts +24 -0
- package/src/oauth/oauth-store.ts +12 -4
- package/src/oauth/provider-serializer.ts +8 -0
- package/src/oauth/seed-providers.ts +42 -0
- package/src/onboarding/onboarding-events-store.ts +99 -12
- package/src/permissions/confirmation-guardian-request.test.ts +16 -0
- package/src/permissions/confirmation-guardian-request.ts +2 -3
- package/src/permissions/question-prompter.test.ts +31 -0
- package/src/permissions/question-prompter.ts +2 -0
- package/src/persistence/__tests__/client-connection-events-store.test.ts +322 -0
- package/src/persistence/attachments-store.ts +84 -44
- package/src/persistence/client-connection-events-store.ts +377 -0
- package/src/persistence/conversation-crud.ts +166 -26
- package/src/persistence/conversation-mode-sessions.test.ts +424 -0
- package/src/persistence/conversation-mode-sessions.ts +460 -0
- package/src/persistence/conversation-plugin-facade.ts +30 -0
- package/src/persistence/conversation-queries.ts +6 -19
- package/src/persistence/conversation-tool-surface.ts +135 -0
- package/src/persistence/conversation-types.test.ts +32 -0
- package/src/persistence/conversation-types.ts +26 -4
- package/src/persistence/llm-usage-store.ts +3 -9
- package/src/persistence/message-metadata.ts +25 -0
- package/src/persistence/migrations/378-create-conversation-tool-surfaces.test.ts +78 -0
- package/src/persistence/migrations/378-create-conversation-tool-surfaces.ts +29 -0
- package/src/persistence/migrations/379-oauth-providers-response-ok-field.test.ts +92 -0
- package/src/persistence/migrations/379-oauth-providers-response-ok-field.ts +32 -0
- package/src/persistence/migrations/380-conversation-tool-surfaces-delegate-independent-tasks.test.ts +90 -0
- package/src/persistence/migrations/380-conversation-tool-surfaces-delegate-independent-tasks.ts +34 -0
- package/src/persistence/migrations/381-create-conversation-mode-sessions.ts +41 -0
- package/src/persistence/migrations/382-create-client-connection-events.ts +40 -0
- package/src/persistence/migrations/__tests__/382-create-client-connection-events.test.ts +56 -0
- package/src/persistence/schema/conversation-tool-surfaces.ts +32 -0
- package/src/persistence/schema/conversations.ts +67 -0
- package/src/persistence/schema/index.ts +1 -0
- package/src/persistence/schema/infrastructure.ts +29 -0
- package/src/persistence/schema/oauth.ts +1 -0
- package/src/persistence/steps.ts +41 -3
- package/src/plugin-api/__tests__/plugin-name-env.test.ts +249 -0
- package/src/plugin-api/conversation-turn.ts +31 -7
- package/src/plugin-api/effective-context-window.ts +33 -0
- package/src/plugin-api/index.ts +35 -6
- package/src/plugin-api/plugin-channel-turn-trust.test.ts +133 -0
- package/src/plugin-api/plugin-channel-turn-trust.ts +71 -0
- package/src/plugin-api/plugin-name-env.ts +125 -0
- package/src/plugin-api/resolve-credential.ts +79 -20
- package/src/plugin-api/vision-support.test.ts +22 -0
- package/src/plugin-api/vision-support.ts +17 -5
- package/src/plugins/__tests__/active-plugin-env.test.ts +136 -0
- package/src/plugins/active-plugin-env.ts +51 -0
- package/src/plugins/defaults/index.ts +24 -0
- package/src/plugins/defaults/memory/AGENTS.md +39 -5
- package/src/plugins/defaults/memory/__tests__/archive-removal-framing.test.ts +64 -0
- package/src/plugins/defaults/memory/__tests__/buffer-file.test.ts +365 -0
- package/src/plugins/defaults/memory/__tests__/buffer-format.test.ts +43 -0
- package/src/plugins/defaults/memory/__tests__/conversation-memory-purge.test.ts +1 -0
- package/src/plugins/defaults/memory/__tests__/db-memory-attach.test.ts +2 -0
- package/src/plugins/defaults/memory/__tests__/fixtures/buffer-appender.ts +17 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +74 -0
- package/src/plugins/defaults/memory/__tests__/memory-run-evidence.test.ts +161 -0
- package/src/plugins/defaults/memory/__tests__/relocated-memory-test-rows.ts +10 -0
- package/src/plugins/defaults/memory/__tests__/worker-control.test.ts +19 -6
- package/src/plugins/defaults/memory/buffer-file.ts +354 -0
- package/src/plugins/defaults/memory/buffer-format.ts +40 -0
- package/src/plugins/defaults/memory/context-search/agent-protocol.ts +9 -12
- package/src/plugins/defaults/memory/context-search/agent-runner.ts +77 -22
- package/src/plugins/defaults/memory/context-search/format.ts +53 -8
- package/src/plugins/defaults/memory/context-search/limits.ts +10 -12
- package/src/plugins/defaults/memory/context-search/recall-input.ts +38 -0
- package/src/plugins/defaults/memory/context-search/search.ts +8 -14
- package/src/plugins/defaults/memory/context-search/sources/conversations.ts +1 -0
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +2 -1
- package/src/plugins/defaults/memory/context-search/sources/workspace.ts +2 -1
- package/src/plugins/defaults/memory/context-search/types.ts +1 -11
- package/src/plugins/defaults/memory/conversation-memory-purge.ts +4 -0
- package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +11 -4
- package/src/plugins/defaults/memory/graph/capability-seed.ts +1 -2
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +13 -63
- package/src/plugins/defaults/memory/graph/tools.ts +35 -64
- package/src/plugins/defaults/memory/host-utils.ts +0 -10
- package/src/plugins/defaults/memory/injectors.ts +4 -3
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +72 -183
- package/src/plugins/defaults/memory/memory-run-evidence.ts +213 -0
- package/src/plugins/defaults/memory/src/memory-eval-routes.ts +2 -3
- package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +6 -1
- package/src/plugins/defaults/memory/src/memory-item-routes.ts +2 -1
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +407 -99
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-prompt-flag-gating-guard.test.ts +10 -0
- package/src/plugins/defaults/memory/substrate/__tests__/prompts-consolidation.test.ts +107 -7
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +307 -86
- package/src/plugins/defaults/memory/substrate/consolidation-tool-surface.ts +34 -0
- package/src/plugins/defaults/memory/substrate/page-index.ts +2 -1
- package/src/plugins/defaults/memory/substrate/prompts/consolidation.ts +91 -51
- package/src/plugins/defaults/memory/substrate/sweep-job.ts +1 -1
- package/src/plugins/defaults/memory/tools.test.ts +124 -9
- package/src/plugins/defaults/memory/tools.ts +38 -11
- package/src/plugins/defaults/memory/v1/graph/consolidation.ts +2 -2
- package/src/plugins/defaults/memory/v1/graph/extraction.ts +2 -1
- package/src/plugins/defaults/memory/v1/graph/retriever.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/migration.test.ts +5 -0
- package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +5 -2
- package/src/plugins/defaults/memory/v2/reranker.ts +2 -1
- package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +81 -1
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +87 -0
- package/src/plugins/defaults/memory/v3/__tests__/plugin-schema.test.ts +12 -0
- package/src/plugins/defaults/memory/v3/__tests__/pool-log-store.test.ts +332 -15
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +626 -27
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +148 -28
- package/src/plugins/defaults/memory/v3/card.ts +2 -1
- package/src/plugins/defaults/memory/v3/injector.ts +212 -178
- package/src/plugins/defaults/memory/v3/orchestrate.ts +159 -32
- package/src/plugins/defaults/memory/v3/plugin-schema.ts +54 -4
- package/src/plugins/defaults/memory/v3/pool-log-store.ts +275 -37
- package/src/plugins/defaults/memory/v3/pool-select.test.ts +47 -5
- package/src/plugins/defaults/memory/v3/pool-select.ts +710 -59
- package/src/plugins/defaults/memory/v3/sections.ts +2 -1
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +41 -14
- package/src/plugins/defaults/memory/worker-control.ts +15 -5
- package/src/plugins/defaults/task-progress/__tests__/registration.test.ts +70 -0
- package/src/plugins/defaults/task-progress/__tests__/task-progress-context.test.ts +380 -0
- package/src/plugins/defaults/task-progress/hooks/post-compact.ts +19 -0
- package/src/plugins/defaults/task-progress/hooks/user-prompt-submit.ts +24 -0
- package/src/plugins/defaults/task-progress/package.json +14 -0
- package/src/plugins/defaults/task-progress/src/apply-task-progress-context.ts +93 -0
- package/src/plugins/defaults/task-progress/src/format-task-progress-context.ts +67 -0
- package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +4 -1
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +1 -46
- package/src/prompts/__tests__/parallel-tasks-section.test.ts +25 -0
- package/src/prompts/delegation-gate.ts +57 -0
- package/src/prompts/system-prompt.ts +14 -32
- package/src/providers/__tests__/context-overflow-error.test.ts +10 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +18 -0
- package/src/providers/anthropic/client.ts +10 -1
- package/src/providers/anthropic-gateway-shared.ts +6 -0
- package/src/providers/fetch-provider-catalog.ts +11 -0
- package/src/providers/gemini/client.ts +25 -8
- package/src/providers/inference/adapter-factory.ts +6 -0
- package/src/providers/jev/client.test.ts +270 -0
- package/src/providers/jev/client.ts +534 -0
- package/src/providers/model-catalog.ts +59 -3
- package/src/providers/openai/__tests__/chat-completions-extra-body.test.ts +94 -1
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +106 -1
- package/src/providers/openai/__tests__/chat-template-flatten.test.ts +24 -0
- package/src/providers/openai/__tests__/google-thought-signature.test.ts +1 -2
- package/src/providers/openai/chat-completions-provider.ts +100 -29
- package/src/providers/openai/google-thought-signature.ts +0 -6
- package/src/providers/openai/responses-provider.ts +23 -1
- package/src/providers/ratelimit.ts +1 -3
- package/src/providers/search-provider-catalog.ts +24 -0
- package/src/providers/server-tool-pairing.ts +16 -7
- package/src/providers/speech-to-text/__tests__/deepgram-flux-frames.test.ts +24 -0
- package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +7 -1
- package/src/providers/speech-to-text/__tests__/vellum-managed-realtime.test.ts +50 -1
- package/src/providers/speech-to-text/deepgram-flux-frames.ts +11 -0
- package/src/providers/speech-to-text/vellum-managed-flux-realtime.ts +13 -0
- package/src/providers/types.ts +5 -0
- package/src/routes/control.ts +7 -5
- package/src/runtime/AGENTS.md +6 -4
- package/src/runtime/__tests__/agent-wake.test.ts +94 -1
- package/src/runtime/actor-trust-resolver.ts +3 -3
- package/src/runtime/agent-wake.ts +32 -5
- package/src/runtime/approval-message-composer.ts +3 -69
- package/src/runtime/assistant-event-hub.ts +73 -75
- package/src/runtime/assistant-event-publish-options.ts +7 -0
- package/src/runtime/assistant-event-targeting.ts +79 -0
- package/src/runtime/assistant-stream-state.ts +13 -100
- package/src/runtime/background-job-runner.ts +5 -5
- package/src/runtime/channel-retry-sweep.ts +1 -0
- package/src/runtime/guardian-action-message-composer.ts +8 -161
- package/src/runtime/guardian-action-service.ts +2 -17
- package/src/runtime/guardian-reply-router.ts +29 -40
- package/src/runtime/http-server.ts +2 -2
- package/src/runtime/http-types.ts +6 -0
- package/src/runtime/message-composer-types.ts +3 -61
- package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +67 -1
- package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +89 -0
- package/src/runtime/migrations/vbundle-builder.ts +24 -1
- package/src/runtime/migrations/vbundle-import-analyzer.ts +13 -4
- package/src/runtime/migrations/vbundle-import-policy.ts +43 -11
- package/src/runtime/migrations/vbundle-importer.ts +4 -1
- package/src/runtime/migrations/vbundle-streaming-importer.ts +4 -1
- package/src/runtime/migrations/vbundle-validator.ts +1 -0
- package/src/runtime/pending-interactions-mode-session.test.ts +62 -0
- package/src/runtime/pending-interactions.ts +29 -0
- package/src/runtime/routes/__tests__/client-history-routes.test.ts +104 -0
- package/src/runtime/routes/__tests__/image-generation-routes.test.ts +97 -0
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +24 -2
- package/src/runtime/routes/__tests__/roadmap-routes.test.ts +29 -6
- package/src/runtime/routes/browser-context.ts +31 -11
- package/src/runtime/routes/browser-routes.ts +43 -4
- package/src/runtime/routes/btw-routes.ts +9 -4
- package/src/runtime/routes/channel-route-shared.ts +1 -9
- package/src/runtime/routes/client-routes.ts +108 -0
- package/src/runtime/routes/conversation-management-routes.ts +4 -1
- package/src/runtime/routes/conversation-routes.ts +125 -14
- package/src/runtime/routes/credential-prompt-routes.ts +4 -3
- package/src/runtime/routes/credential-routes.ts +1 -2
- package/src/runtime/routes/desktop-setup-routes.test.ts +9 -18
- package/src/runtime/routes/desktop-setup-routes.ts +8 -7
- package/src/runtime/routes/documents-routes.ts +51 -0
- package/src/runtime/routes/email-routes.ts +3 -7
- package/src/runtime/routes/events-routes.ts +75 -54
- package/src/runtime/routes/guardian-approval-interception.ts +24 -0
- package/src/runtime/routes/identity-routes.ts +1 -5
- package/src/runtime/routes/image-generation-routes.ts +8 -14
- package/src/runtime/routes/inbound-message-handler.ts +37 -41
- package/src/runtime/routes/inbound-stages/backfill-sender-provenance.test.ts +168 -0
- package/src/runtime/routes/inbound-stages/backfill-sender-provenance.ts +96 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +39 -10
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +9 -9
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +2 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +11 -1
- package/src/runtime/routes/inference-profiles-routes.ts +9 -0
- package/src/runtime/routes/llm-context-normalization.ts +1 -7
- package/src/runtime/routes/migration-routes.ts +73 -2
- package/src/runtime/routes/notification-routes.ts +10 -0
- package/src/runtime/routes/oauth-commands-routes.ts +57 -54
- package/src/runtime/routes/oauth-providers.ts +11 -0
- package/src/runtime/routes/oauth-request-hints.test.ts +246 -0
- package/src/runtime/routes/oauth-request-hints.ts +149 -0
- package/src/runtime/routes/plugins-routes.ts +6 -0
- package/src/runtime/routes/roadmap-routes.ts +47 -8
- package/src/runtime/routes/schedule-routes.ts +2 -0
- package/src/runtime/routes/secret-routes.ts +99 -119
- package/src/runtime/routes/settings-routes.ts +10 -4
- package/src/runtime/routes/watcher-routes.ts +1 -3
- package/src/runtime/trust-class.test.ts +7 -6
- package/src/runtime/trust-class.ts +9 -17
- package/src/schedule/__tests__/worker-control.test.ts +36 -5
- package/src/schedule/__tests__/worker-mcp-bootstrap.test.ts +107 -0
- package/src/schedule/__tests__/worker-mcp-readiness.test.ts +173 -0
- package/src/schedule/__tests__/worker-mcp-tools.test.ts +13 -47
- package/src/schedule/run-script.ts +2 -2
- package/src/schedule/scheduler.ts +47 -11
- package/src/schedule/tool-surface-readiness.ts +65 -0
- package/src/schedule/worker-control.ts +15 -5
- package/src/schedule/worker-mcp.ts +85 -0
- package/src/schedule/worker.ts +9 -31
- package/src/security/secure-keys.ts +74 -112
- package/src/skills/clawhub.ts +3 -8
- package/src/skills/managed-store.ts +1 -5
- package/src/stt/types.ts +4 -0
- package/src/subagent/notify.ts +54 -34
- package/src/subagent/parent-notification.ts +6 -0
- package/src/telemetry/__tests__/phone-call-funnel.test.ts +72 -0
- package/src/telemetry/phone-call-funnel.ts +144 -0
- package/src/tools/__tests__/tool-schema-root-combinator-guard.test.ts +81 -0
- package/src/tools/ask-question/ask-question-tool.test.ts +167 -5
- package/src/tools/ask-question/ask-question-tool.ts +120 -22
- package/src/tools/browser/browser-execution.ts +29 -60
- package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +561 -39
- package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +435 -39
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +1 -8
- package/src/tools/client-os.ts +15 -0
- package/src/tools/computer-use/skill-proxy-bridge.ts +1 -1
- package/src/tools/computer-use/target.ts +42 -0
- package/src/tools/document/document-tool.ts +13 -18
- package/src/tools/execution-target.ts +14 -16
- package/src/tools/host-terminal/host-shell.ts +16 -7
- package/src/tools/network/__tests__/web-fetch-tinyfish.test.ts +250 -0
- package/src/tools/network/__tests__/web-search.test.ts +203 -0
- package/src/tools/network/web-fetch.ts +274 -7
- package/src/tools/network/web-search.ts +468 -6
- package/src/tools/permission-checker.ts +3 -3
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/shared/filesystem/file-ops-service.ts +1 -31
- package/src/tools/shared/shell-output.test.ts +10 -0
- package/src/tools/shared/shell-output.ts +14 -2
- package/src/tools/skills/load.ts +2 -1
- package/src/tools/skills/sandbox-runner.ts +24 -4
- package/src/tools/skills/scaffold-managed.ts +2 -1
- package/src/tools/skills/skill-script-runner.ts +7 -0
- package/src/tools/skills/skill-tool-factory.ts +15 -1
- package/src/tools/terminal/__tests__/safe-env.test.ts +44 -4
- package/src/tools/terminal/__tests__/sanitized-bash.test.ts +0 -14
- package/src/tools/terminal/safe-env.ts +39 -24
- package/src/tools/terminal/sanitized-bash.ts +15 -2
- package/src/tools/terminal/shell-launch.test.ts +162 -0
- package/src/tools/terminal/shell.test.ts +29 -0
- package/src/tools/terminal/shell.ts +15 -7
- package/src/tools/tool-approval-handler.ts +5 -1
- package/src/tools/tool-types.ts +3 -3
- package/src/tools/types.ts +8 -2
- package/src/util/__tests__/worker-process-command.test.ts +5 -4
- package/src/util/abort-reasons.ts +18 -26
- package/src/util/browser-human-verification.ts +14 -0
- package/src/util/canonicalize-identity.test.ts +21 -0
- package/src/util/canonicalize-identity.ts +16 -0
- package/src/util/errors.ts +13 -3
- package/src/util/host-process.test.ts +17 -1
- package/src/util/host-process.ts +24 -0
- package/src/util/provider-error-patterns.ts +3 -0
- package/src/util/unicode.ts +29 -0
- package/src/util/worker-process.ts +77 -35
- package/src/workspace/migrations/157-add-desktop-files-launcher.ts +94 -0
- package/src/workspace/migrations/__tests__/156-extract-workspace-mcp-json.test.ts +4 -10
- package/src/workspace/migrations/__tests__/157-add-desktop-files-launcher.test.ts +113 -0
- package/src/workspace/migrations/registry.ts +2 -0
- package/src/__tests__/computer-use-window-schema.test.ts +0 -24
- package/src/api/events/heartbeat-alert.ts +0 -20
- package/src/daemon/message-types/web-activity.ts +0 -65
- package/src/desktop/desktop-dependencies.test.ts +0 -131
- package/src/tools/computer-use/definitions.ts +0 -607
|
@@ -1,10 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-turn voice latency marks, shared by both voice transports.
|
|
3
|
+
*
|
|
4
|
+
* The collector times a turn's journey from the caller's speech to the first
|
|
5
|
+
* audio the assistant speaks back, and summarises the retained window. It
|
|
6
|
+
* knows nothing about the transport that feeds it: live voice marks a
|
|
7
|
+
* WebSocket session's turns and emits a snapshot to the client on every mark,
|
|
8
|
+
* while a phone call marks the same points from `call-controller.ts` and logs
|
|
9
|
+
* the aggregate once per turn (Twilio has no client to send frames to).
|
|
10
|
+
*
|
|
11
|
+
* Marks are all first-wins per turn and every one is optional, so a transport
|
|
12
|
+
* that cannot observe a point (a phone turn has no partial transcript, and no
|
|
13
|
+
* push-to-talk release) simply never stamps it and the durations that depend
|
|
14
|
+
* on it come back null.
|
|
15
|
+
*/
|
|
1
16
|
import { getLogger } from "../util/logger.js";
|
|
2
17
|
|
|
3
|
-
const log = getLogger("
|
|
18
|
+
const log = getLogger("voice-metrics");
|
|
4
19
|
|
|
5
|
-
export type
|
|
20
|
+
export type VoiceMetricsClock = () => number;
|
|
6
21
|
|
|
7
|
-
export type
|
|
22
|
+
export type VoiceMetricsEvent =
|
|
8
23
|
| "session_started"
|
|
9
24
|
| "session_ready"
|
|
10
25
|
| "turn_started"
|
|
@@ -36,23 +51,23 @@ export type VoiceEndpointSource = "front-door" | "provider";
|
|
|
36
51
|
const DEFAULT_ENDPOINT_SOURCE: VoiceEndpointSource = "front-door";
|
|
37
52
|
|
|
38
53
|
// Semantic-endpointing decision on a silence boundary.
|
|
39
|
-
interface
|
|
54
|
+
interface VoiceEndpointDecisionMark {
|
|
40
55
|
action: VoiceEndpointAction;
|
|
41
56
|
latencyMs: number;
|
|
42
57
|
source?: VoiceEndpointSource;
|
|
43
58
|
}
|
|
44
59
|
|
|
45
|
-
type
|
|
60
|
+
type VoiceTurnStatus = "active" | "completed" | "cancelled";
|
|
46
61
|
|
|
47
|
-
interface
|
|
62
|
+
interface VoiceMetricsCollectorOptions {
|
|
48
63
|
sessionId: string;
|
|
49
64
|
conversationId?: string;
|
|
50
|
-
clock?:
|
|
51
|
-
emit?: (frame:
|
|
65
|
+
clock?: VoiceMetricsClock;
|
|
66
|
+
emit?: (frame: VoiceMetricsFrame) => void;
|
|
52
67
|
recentTurnLimit?: number;
|
|
53
68
|
}
|
|
54
69
|
|
|
55
|
-
interface
|
|
70
|
+
interface VoiceSessionMetrics {
|
|
56
71
|
sessionId: string;
|
|
57
72
|
conversationId?: string;
|
|
58
73
|
startedAtMs: number;
|
|
@@ -62,7 +77,7 @@ interface LiveVoiceSessionMetrics {
|
|
|
62
77
|
|
|
63
78
|
// Marks captured before a turn opened in the collector (server-VAD overlap);
|
|
64
79
|
// passed to startTurn to backfill the new turn's timestamps.
|
|
65
|
-
export interface
|
|
80
|
+
export interface VoiceTurnSeedMarks {
|
|
66
81
|
firstAudioAtMs?: number;
|
|
67
82
|
firstPartialAtMs?: number;
|
|
68
83
|
speechStartAtMs?: number;
|
|
@@ -76,9 +91,9 @@ const SEEDABLE_MARK_FIELDS = [
|
|
|
76
91
|
"speechStartAtMs",
|
|
77
92
|
"utteranceEndAtMs",
|
|
78
93
|
"finalTranscriptAtMs",
|
|
79
|
-
] as const satisfies ReadonlyArray<keyof
|
|
94
|
+
] as const satisfies ReadonlyArray<keyof VoiceTurnSeedMarks>;
|
|
80
95
|
|
|
81
|
-
interface
|
|
96
|
+
interface VoiceTurnTimestamps {
|
|
82
97
|
startedAtMs: number;
|
|
83
98
|
firstAudioAtMs: number | null;
|
|
84
99
|
firstPartialAtMs: number | null;
|
|
@@ -98,7 +113,7 @@ interface LiveVoiceTurnTimestamps {
|
|
|
98
113
|
cancelledAtMs: number | null;
|
|
99
114
|
}
|
|
100
115
|
|
|
101
|
-
interface
|
|
116
|
+
interface VoiceTurnDurations {
|
|
102
117
|
firstAudioToFirstPartialMs: number | null;
|
|
103
118
|
pttReleaseToFinalTranscriptMs: number | null;
|
|
104
119
|
utteranceEndToFinalTranscriptMs: number | null;
|
|
@@ -115,12 +130,12 @@ interface LiveVoiceTurnDurations {
|
|
|
115
130
|
totalTurnDurationMs: number | null;
|
|
116
131
|
}
|
|
117
132
|
|
|
118
|
-
interface
|
|
133
|
+
interface VoiceTurnMetrics {
|
|
119
134
|
turnId: string;
|
|
120
|
-
status:
|
|
135
|
+
status: VoiceTurnStatus;
|
|
121
136
|
cancellationReason: string | null;
|
|
122
|
-
timestamps:
|
|
123
|
-
durations:
|
|
137
|
+
timestamps: VoiceTurnTimestamps;
|
|
138
|
+
durations: VoiceTurnDurations;
|
|
124
139
|
// End of turn measured from the local VAD speech-stop mark to the commit,
|
|
125
140
|
// recorded on every committed turn whichever decider owned the boundary.
|
|
126
141
|
// Absent on a turn that never committed, and in push-to-talk mode, where
|
|
@@ -134,35 +149,35 @@ interface LiveVoiceTurnMetrics {
|
|
|
134
149
|
progressUpdatesSpoken?: number;
|
|
135
150
|
}
|
|
136
151
|
|
|
137
|
-
interface
|
|
152
|
+
interface VoiceDurationSummary {
|
|
138
153
|
count: number;
|
|
139
154
|
p50Ms: number | null;
|
|
140
155
|
p95Ms: number | null;
|
|
141
156
|
}
|
|
142
157
|
|
|
143
|
-
interface
|
|
158
|
+
interface VoiceMetricsSummary {
|
|
144
159
|
retainedTurnCount: number;
|
|
145
160
|
completedTurnCount: number;
|
|
146
161
|
cancelledTurnCount: number;
|
|
147
162
|
durations: {
|
|
148
|
-
firstAudioToFirstPartialMs:
|
|
149
|
-
pttReleaseToFinalTranscriptMs:
|
|
150
|
-
utteranceEndToFinalTranscriptMs:
|
|
151
|
-
finalTranscriptToFirstAssistantDeltaMs:
|
|
152
|
-
firstAssistantDeltaToFirstTtsAudioMs:
|
|
153
|
-
roundTripMs:
|
|
154
|
-
totalTurnDurationMs:
|
|
163
|
+
firstAudioToFirstPartialMs: VoiceDurationSummary;
|
|
164
|
+
pttReleaseToFinalTranscriptMs: VoiceDurationSummary;
|
|
165
|
+
utteranceEndToFinalTranscriptMs: VoiceDurationSummary;
|
|
166
|
+
finalTranscriptToFirstAssistantDeltaMs: VoiceDurationSummary;
|
|
167
|
+
firstAssistantDeltaToFirstTtsAudioMs: VoiceDurationSummary;
|
|
168
|
+
roundTripMs: VoiceDurationSummary;
|
|
169
|
+
totalTurnDurationMs: VoiceDurationSummary;
|
|
155
170
|
};
|
|
156
171
|
}
|
|
157
172
|
|
|
158
|
-
interface
|
|
159
|
-
session:
|
|
160
|
-
activeTurn:
|
|
161
|
-
recentTurns:
|
|
162
|
-
summary:
|
|
173
|
+
export interface VoiceMetricsSnapshot {
|
|
174
|
+
session: VoiceSessionMetrics;
|
|
175
|
+
activeTurn: VoiceTurnMetrics | null;
|
|
176
|
+
recentTurns: VoiceTurnMetrics[];
|
|
177
|
+
summary: VoiceMetricsSummary;
|
|
163
178
|
}
|
|
164
179
|
|
|
165
|
-
interface
|
|
180
|
+
interface VoiceMetricsAggregateFields {
|
|
166
181
|
sttMs: number | null;
|
|
167
182
|
llmFirstDeltaMs: number | null;
|
|
168
183
|
// Dispatch-anchored felt latency: leg dispatch to first delta / first TTS
|
|
@@ -175,7 +190,7 @@ interface LiveVoiceMetricsAggregateFields {
|
|
|
175
190
|
totalMs: number | null;
|
|
176
191
|
// Optional so metrics frames stay byte-identical when the turn never
|
|
177
192
|
// committed and when the front-model features never engaged (see the
|
|
178
|
-
// matching fields on
|
|
193
|
+
// matching fields on VoiceTurnMetrics).
|
|
179
194
|
endpointCommitLatencyMs?: number;
|
|
180
195
|
endpointHoldCount?: number;
|
|
181
196
|
endpointDecisionMaxLatencyMs?: number;
|
|
@@ -183,21 +198,21 @@ interface LiveVoiceMetricsAggregateFields {
|
|
|
183
198
|
progressUpdatesSpoken?: number;
|
|
184
199
|
}
|
|
185
200
|
|
|
186
|
-
export interface
|
|
201
|
+
export interface VoiceMetricsFrame {
|
|
187
202
|
type: "metrics";
|
|
188
|
-
event:
|
|
203
|
+
event: VoiceMetricsEvent;
|
|
189
204
|
sessionId: string;
|
|
190
205
|
conversationId?: string;
|
|
191
206
|
turnId?: string;
|
|
192
|
-
metrics:
|
|
207
|
+
metrics: VoiceMetricsSnapshot;
|
|
193
208
|
}
|
|
194
209
|
|
|
195
210
|
interface MutableTurn {
|
|
196
211
|
turnId: string;
|
|
197
|
-
status:
|
|
212
|
+
status: VoiceTurnStatus;
|
|
198
213
|
cancellationReason: string | null;
|
|
199
|
-
timestamps:
|
|
200
|
-
// Null means the turn never committed (see
|
|
214
|
+
timestamps: VoiceTurnTimestamps;
|
|
215
|
+
// Null means the turn never committed (see VoiceTurnMetrics).
|
|
201
216
|
endpointCommitLatencyMs: number | null;
|
|
202
217
|
endpointHoldCount: number;
|
|
203
218
|
// Doubles as the "decider was consulted" latch: null means no endpoint
|
|
@@ -210,11 +225,11 @@ interface MutableTurn {
|
|
|
210
225
|
|
|
211
226
|
const DEFAULT_RECENT_TURN_LIMIT = 50;
|
|
212
227
|
|
|
213
|
-
export class
|
|
228
|
+
export class VoiceMetricsCollector {
|
|
214
229
|
private readonly sessionId: string;
|
|
215
230
|
private readonly conversationId?: string;
|
|
216
|
-
private readonly clock:
|
|
217
|
-
private readonly emitFrame?: (frame:
|
|
231
|
+
private readonly clock: VoiceMetricsClock;
|
|
232
|
+
private readonly emitFrame?: (frame: VoiceMetricsFrame) => void;
|
|
218
233
|
private readonly recentTurnLimit: number;
|
|
219
234
|
private readonly sessionStartedAtMs: number;
|
|
220
235
|
|
|
@@ -224,7 +239,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
224
239
|
private activeTurn: MutableTurn | null = null;
|
|
225
240
|
private readonly recentTurns: MutableTurn[] = [];
|
|
226
241
|
|
|
227
|
-
constructor(options:
|
|
242
|
+
constructor(options: VoiceMetricsCollectorOptions) {
|
|
228
243
|
this.sessionId = options.sessionId;
|
|
229
244
|
this.conversationId = options.conversationId;
|
|
230
245
|
this.clock = options.clock ?? Date.now;
|
|
@@ -234,7 +249,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
234
249
|
this.emit("session_started");
|
|
235
250
|
}
|
|
236
251
|
|
|
237
|
-
markReady():
|
|
252
|
+
markReady(): VoiceMetricsFrame {
|
|
238
253
|
if (this.readyAtMs === null) {
|
|
239
254
|
this.readyAtMs = this.timestamp();
|
|
240
255
|
}
|
|
@@ -243,8 +258,8 @@ export class LiveVoiceMetricsCollector {
|
|
|
243
258
|
|
|
244
259
|
startTurn(
|
|
245
260
|
turnId = this.createTurnId(),
|
|
246
|
-
seedMarks:
|
|
247
|
-
):
|
|
261
|
+
seedMarks: VoiceTurnSeedMarks = {},
|
|
262
|
+
): VoiceTurnMetrics {
|
|
248
263
|
if (this.activeTurn !== null) {
|
|
249
264
|
this.cancelTurn("superseded");
|
|
250
265
|
}
|
|
@@ -283,10 +298,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
283
298
|
// an existing mark (first timestamp wins) and are clamped to the turn's
|
|
284
299
|
// start timestamp; the earliest seed becomes the turn start so total
|
|
285
300
|
// durations cover the stashed span.
|
|
286
|
-
private applySeedMarks(
|
|
287
|
-
turn: MutableTurn,
|
|
288
|
-
seeds: LiveVoiceTurnSeedMarks,
|
|
289
|
-
): void {
|
|
301
|
+
private applySeedMarks(turn: MutableTurn, seeds: VoiceTurnSeedMarks): void {
|
|
290
302
|
const startedAtMs = turn.timestamps.startedAtMs;
|
|
291
303
|
let earliestMs = startedAtMs;
|
|
292
304
|
for (const field of SEEDABLE_MARK_FIELDS) {
|
|
@@ -304,7 +316,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
304
316
|
turn.timestamps.startedAtMs = earliestMs;
|
|
305
317
|
}
|
|
306
318
|
|
|
307
|
-
markFirstAudio(turnId?: string):
|
|
319
|
+
markFirstAudio(turnId?: string): VoiceMetricsFrame {
|
|
308
320
|
const turn = this.ensureActiveTurn(turnId);
|
|
309
321
|
if (turn.timestamps.firstAudioAtMs === null) {
|
|
310
322
|
turn.timestamps.firstAudioAtMs = this.timestamp();
|
|
@@ -312,7 +324,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
312
324
|
return this.emit("first_audio", turn.turnId);
|
|
313
325
|
}
|
|
314
326
|
|
|
315
|
-
markFirstPartial(turnId?: string):
|
|
327
|
+
markFirstPartial(turnId?: string): VoiceMetricsFrame {
|
|
316
328
|
const turn = this.ensureActiveTurn(turnId);
|
|
317
329
|
if (turn.timestamps.firstPartialAtMs === null) {
|
|
318
330
|
turn.timestamps.firstPartialAtMs = this.timestamp();
|
|
@@ -320,7 +332,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
320
332
|
return this.emit("first_partial", turn.turnId);
|
|
321
333
|
}
|
|
322
334
|
|
|
323
|
-
markSpeechStart(turnId?: string):
|
|
335
|
+
markSpeechStart(turnId?: string): VoiceMetricsFrame {
|
|
324
336
|
const turn = this.ensureActiveTurn(turnId);
|
|
325
337
|
if (turn.timestamps.speechStartAtMs === null) {
|
|
326
338
|
turn.timestamps.speechStartAtMs = this.timestamp();
|
|
@@ -328,7 +340,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
328
340
|
return this.emit("vad_speech_start", turn.turnId);
|
|
329
341
|
}
|
|
330
342
|
|
|
331
|
-
markPushToTalkRelease(turnId?: string):
|
|
343
|
+
markPushToTalkRelease(turnId?: string): VoiceMetricsFrame {
|
|
332
344
|
const turn = this.ensureActiveTurn(turnId);
|
|
333
345
|
if (turn.timestamps.pttReleaseAtMs === null) {
|
|
334
346
|
turn.timestamps.pttReleaseAtMs = this.timestamp();
|
|
@@ -336,7 +348,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
336
348
|
return this.emit("ptt_release", turn.turnId);
|
|
337
349
|
}
|
|
338
350
|
|
|
339
|
-
markUtteranceEnd(turnId?: string):
|
|
351
|
+
markUtteranceEnd(turnId?: string): VoiceMetricsFrame {
|
|
340
352
|
const turn = this.ensureActiveTurn(turnId);
|
|
341
353
|
if (turn.timestamps.utteranceEndAtMs === null) {
|
|
342
354
|
turn.timestamps.utteranceEndAtMs = this.timestamp();
|
|
@@ -348,8 +360,8 @@ export class LiveVoiceMetricsCollector {
|
|
|
348
360
|
// bump the per-turn count and both outcomes feed the worst-latency figure.
|
|
349
361
|
markEndpointDecision(
|
|
350
362
|
turnId: string | undefined,
|
|
351
|
-
decision:
|
|
352
|
-
):
|
|
363
|
+
decision: VoiceEndpointDecisionMark,
|
|
364
|
+
): VoiceMetricsFrame {
|
|
353
365
|
const turn = this.ensureActiveTurn(turnId);
|
|
354
366
|
if (decision.action === "hold") {
|
|
355
367
|
turn.endpointHoldCount += 1;
|
|
@@ -366,7 +378,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
366
378
|
markEndpointCommit(
|
|
367
379
|
turnId: string | undefined,
|
|
368
380
|
latencyMs: number,
|
|
369
|
-
):
|
|
381
|
+
): VoiceMetricsFrame {
|
|
370
382
|
const turn = this.ensureActiveTurn(turnId);
|
|
371
383
|
if (turn.endpointCommitLatencyMs === null) {
|
|
372
384
|
turn.endpointCommitLatencyMs = normalizeLatencyMs(latencyMs);
|
|
@@ -376,13 +388,13 @@ export class LiveVoiceMetricsCollector {
|
|
|
376
388
|
|
|
377
389
|
// A counter, not a first-wins mark: every spoken progress narration bumps
|
|
378
390
|
// the per-turn count.
|
|
379
|
-
markProgressSpoken(turnId?: string):
|
|
391
|
+
markProgressSpoken(turnId?: string): VoiceMetricsFrame {
|
|
380
392
|
const turn = this.ensureActiveTurn(turnId);
|
|
381
393
|
turn.progressUpdatesSpoken += 1;
|
|
382
394
|
return this.emit("progress_spoken", turn.turnId);
|
|
383
395
|
}
|
|
384
396
|
|
|
385
|
-
markBargeIn(turnId?: string):
|
|
397
|
+
markBargeIn(turnId?: string): VoiceMetricsFrame {
|
|
386
398
|
const turn = this.ensureActiveTurn(turnId);
|
|
387
399
|
if (turn.timestamps.bargeInAtMs === null) {
|
|
388
400
|
turn.timestamps.bargeInAtMs = this.timestamp();
|
|
@@ -390,7 +402,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
390
402
|
return this.emit("barge_in", turn.turnId);
|
|
391
403
|
}
|
|
392
404
|
|
|
393
|
-
markFinalTranscript(turnId?: string):
|
|
405
|
+
markFinalTranscript(turnId?: string): VoiceMetricsFrame {
|
|
394
406
|
const turn = this.ensureActiveTurn(turnId);
|
|
395
407
|
if (turn.timestamps.finalTranscriptAtMs === null) {
|
|
396
408
|
turn.timestamps.finalTranscriptAtMs = this.timestamp();
|
|
@@ -398,7 +410,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
398
410
|
return this.emit("final_transcript", turn.turnId);
|
|
399
411
|
}
|
|
400
412
|
|
|
401
|
-
markAssistantDispatch(turnId?: string):
|
|
413
|
+
markAssistantDispatch(turnId?: string): VoiceMetricsFrame {
|
|
402
414
|
const turn = this.ensureActiveTurn(turnId);
|
|
403
415
|
if (turn.timestamps.assistantDispatchAtMs === null) {
|
|
404
416
|
turn.timestamps.assistantDispatchAtMs = this.timestamp();
|
|
@@ -406,7 +418,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
406
418
|
return this.emit("assistant_dispatch", turn.turnId);
|
|
407
419
|
}
|
|
408
420
|
|
|
409
|
-
markFirstAssistantDelta(turnId?: string):
|
|
421
|
+
markFirstAssistantDelta(turnId?: string): VoiceMetricsFrame {
|
|
410
422
|
const turn = this.ensureActiveTurn(turnId);
|
|
411
423
|
if (turn.timestamps.firstAssistantDeltaAtMs === null) {
|
|
412
424
|
turn.timestamps.firstAssistantDeltaAtMs = this.timestamp();
|
|
@@ -414,7 +426,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
414
426
|
return this.emit("first_assistant_delta", turn.turnId);
|
|
415
427
|
}
|
|
416
428
|
|
|
417
|
-
markFirstTtsAudio(turnId?: string):
|
|
429
|
+
markFirstTtsAudio(turnId?: string): VoiceMetricsFrame {
|
|
418
430
|
const turn = this.ensureActiveTurn(turnId);
|
|
419
431
|
if (turn.timestamps.firstTtsAudioAtMs === null) {
|
|
420
432
|
turn.timestamps.firstTtsAudioAtMs = this.timestamp();
|
|
@@ -422,7 +434,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
422
434
|
return this.emit("first_tts_audio", turn.turnId);
|
|
423
435
|
}
|
|
424
436
|
|
|
425
|
-
completeTurn(turnId?: string):
|
|
437
|
+
completeTurn(turnId?: string): VoiceTurnMetrics {
|
|
426
438
|
const turn = this.ensureActiveTurn(turnId);
|
|
427
439
|
if (turn.status === "active") {
|
|
428
440
|
turn.status = "completed";
|
|
@@ -433,7 +445,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
433
445
|
return snapshotTurn(turn);
|
|
434
446
|
}
|
|
435
447
|
|
|
436
|
-
cancelTurn(reason = "cancelled", turnId?: string):
|
|
448
|
+
cancelTurn(reason = "cancelled", turnId?: string): VoiceTurnMetrics {
|
|
437
449
|
const turn = this.ensureActiveTurn(turnId);
|
|
438
450
|
if (turn.status === "active") {
|
|
439
451
|
turn.status = "cancelled";
|
|
@@ -445,7 +457,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
445
457
|
return snapshotTurn(turn);
|
|
446
458
|
}
|
|
447
459
|
|
|
448
|
-
getSnapshot():
|
|
460
|
+
getSnapshot(): VoiceMetricsSnapshot {
|
|
449
461
|
return {
|
|
450
462
|
session: this.getSessionMetrics(),
|
|
451
463
|
activeTurn: this.activeTurn ? snapshotTurn(this.activeTurn) : null,
|
|
@@ -454,7 +466,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
454
466
|
};
|
|
455
467
|
}
|
|
456
468
|
|
|
457
|
-
private getSessionMetrics():
|
|
469
|
+
private getSessionMetrics(): VoiceSessionMetrics {
|
|
458
470
|
return {
|
|
459
471
|
sessionId: this.sessionId,
|
|
460
472
|
conversationId: this.conversationId,
|
|
@@ -480,7 +492,7 @@ export class LiveVoiceMetricsCollector {
|
|
|
480
492
|
private mutableStartTurn(turnId: string): MutableTurn {
|
|
481
493
|
this.startTurn(turnId);
|
|
482
494
|
if (this.activeTurn === null) {
|
|
483
|
-
throw new Error("
|
|
495
|
+
throw new Error("Voice metrics failed to start a turn.");
|
|
484
496
|
}
|
|
485
497
|
return this.activeTurn;
|
|
486
498
|
}
|
|
@@ -538,11 +550,8 @@ export class LiveVoiceMetricsCollector {
|
|
|
538
550
|
return normalized;
|
|
539
551
|
}
|
|
540
552
|
|
|
541
|
-
private emit(
|
|
542
|
-
|
|
543
|
-
turnId?: string,
|
|
544
|
-
): LiveVoiceMetricsFrame {
|
|
545
|
-
const frame: LiveVoiceMetricsFrame = {
|
|
553
|
+
private emit(event: VoiceMetricsEvent, turnId?: string): VoiceMetricsFrame {
|
|
554
|
+
const frame: VoiceMetricsFrame = {
|
|
546
555
|
type: "metrics",
|
|
547
556
|
event,
|
|
548
557
|
sessionId: this.sessionId,
|
|
@@ -561,10 +570,10 @@ export class LiveVoiceMetricsCollector {
|
|
|
561
570
|
}
|
|
562
571
|
}
|
|
563
572
|
|
|
564
|
-
export function
|
|
565
|
-
snapshot:
|
|
573
|
+
export function getVoiceMetricsAggregateFields(
|
|
574
|
+
snapshot: VoiceMetricsSnapshot,
|
|
566
575
|
turnId?: string,
|
|
567
|
-
):
|
|
576
|
+
): VoiceMetricsAggregateFields {
|
|
568
577
|
const turn = selectTurnForAggregate(snapshot, turnId);
|
|
569
578
|
if (!turn) {
|
|
570
579
|
return {
|
|
@@ -582,8 +591,8 @@ export function getLiveVoiceMetricsAggregateFields(
|
|
|
582
591
|
}
|
|
583
592
|
|
|
584
593
|
function aggregateFieldsForTurn(
|
|
585
|
-
turn:
|
|
586
|
-
):
|
|
594
|
+
turn: VoiceTurnMetrics,
|
|
595
|
+
): VoiceMetricsAggregateFields {
|
|
587
596
|
return {
|
|
588
597
|
// Manual mode stamps ptt_release; server-VAD sessions stamp utterance_end
|
|
589
598
|
// instead, so the VAD boundary plays the sttMs role there.
|
|
@@ -615,7 +624,7 @@ function optionalTurnFields(
|
|
|
615
624
|
progressUpdatesSpoken?: number | null;
|
|
616
625
|
},
|
|
617
626
|
): Pick<
|
|
618
|
-
|
|
627
|
+
VoiceTurnMetrics,
|
|
619
628
|
| "endpointCommitLatencyMs"
|
|
620
629
|
| "endpointHoldCount"
|
|
621
630
|
| "endpointDecisionMaxLatencyMs"
|
|
@@ -650,9 +659,9 @@ function normalizeRecentTurnLimit(limit: number | undefined): number {
|
|
|
650
659
|
}
|
|
651
660
|
|
|
652
661
|
function selectTurnForAggregate(
|
|
653
|
-
snapshot:
|
|
662
|
+
snapshot: VoiceMetricsSnapshot,
|
|
654
663
|
turnId: string | undefined,
|
|
655
|
-
):
|
|
664
|
+
): VoiceTurnMetrics | null {
|
|
656
665
|
if (turnId !== undefined) {
|
|
657
666
|
if (snapshot.activeTurn?.turnId === turnId) {
|
|
658
667
|
return snapshot.activeTurn;
|
|
@@ -686,7 +695,7 @@ function cloneMutableTurn(turn: MutableTurn): MutableTurn {
|
|
|
686
695
|
};
|
|
687
696
|
}
|
|
688
697
|
|
|
689
|
-
function snapshotTurn(turn: MutableTurn):
|
|
698
|
+
function snapshotTurn(turn: MutableTurn): VoiceTurnMetrics {
|
|
690
699
|
const timestamps = { ...turn.timestamps };
|
|
691
700
|
return {
|
|
692
701
|
turnId: turn.turnId,
|
|
@@ -735,7 +744,7 @@ function snapshotTurn(turn: MutableTurn): LiveVoiceTurnMetrics {
|
|
|
735
744
|
};
|
|
736
745
|
}
|
|
737
746
|
|
|
738
|
-
function summarizeTurns(turns: MutableTurn[]):
|
|
747
|
+
function summarizeTurns(turns: MutableTurn[]): VoiceMetricsSummary {
|
|
739
748
|
const snapshots = turns.map(snapshotTurn);
|
|
740
749
|
const durations = snapshots.map((turn) => turn.durations);
|
|
741
750
|
|
|
@@ -771,9 +780,7 @@ function summarizeTurns(turns: MutableTurn[]): LiveVoiceMetricsSummary {
|
|
|
771
780
|
};
|
|
772
781
|
}
|
|
773
782
|
|
|
774
|
-
function summarizeDuration(
|
|
775
|
-
values: Array<number | null>,
|
|
776
|
-
): LiveVoiceDurationSummary {
|
|
783
|
+
function summarizeDuration(values: Array<number | null>): VoiceDurationSummary {
|
|
777
784
|
const sorted = values
|
|
778
785
|
.filter((value): value is number => value !== null)
|
|
779
786
|
.sort((left, right) => left - right);
|