@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
|
@@ -63,6 +63,8 @@ interface TurnTailContext {
|
|
|
63
63
|
/** Minimal per-run handler state {@link settleTurnContent} consumes. */
|
|
64
64
|
interface TurnContentState {
|
|
65
65
|
readonly lastAssistantMessageId: string | undefined;
|
|
66
|
+
/** Earlier reply rows that must join the final disk-view export. */
|
|
67
|
+
readonly assistantMessageIdsToSync: ReadonlySet<string>;
|
|
66
68
|
/** In-flight content writers the turn left behind (see EventHandlerState). */
|
|
67
69
|
readonly inflightWriters: Map<string, InflightContentWriter>;
|
|
68
70
|
}
|
|
@@ -224,20 +226,31 @@ export async function settleTurnContent(params: {
|
|
|
224
226
|
);
|
|
225
227
|
}
|
|
226
228
|
|
|
227
|
-
// Mirror
|
|
228
|
-
//
|
|
229
|
-
//
|
|
230
|
-
//
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
229
|
+
// Mirror every assistant row finalized by this turn into the JSONL disk
|
|
230
|
+
// view. Most turns contribute only their last row. A turn that delivered its
|
|
231
|
+
// reply through `send_user_message` can also contribute an earlier row that
|
|
232
|
+
// received the reply attachment. Set insertion order preserves the reply's
|
|
233
|
+
// position, while adding the last row deduplicates the ordinary case where
|
|
234
|
+
// both ids are the same.
|
|
235
|
+
if (liveConversation) {
|
|
236
|
+
const messageIds = new Set(state.assistantMessageIdsToSync);
|
|
237
|
+
if (state.lastAssistantMessageId) {
|
|
238
|
+
messageIds.add(state.lastAssistantMessageId);
|
|
239
|
+
}
|
|
240
|
+
for (const messageId of messageIds) {
|
|
241
|
+
try {
|
|
242
|
+
syncMessageToDisk(
|
|
243
|
+
ctx.conversationId,
|
|
244
|
+
messageId,
|
|
245
|
+
liveConversation.createdAt,
|
|
246
|
+
);
|
|
247
|
+
} catch (err) {
|
|
248
|
+
rlog.warn(
|
|
249
|
+
{ err, messageId },
|
|
250
|
+
"Failed to sync assistant message to disk (non-fatal)",
|
|
251
|
+
);
|
|
252
|
+
}
|
|
238
253
|
}
|
|
239
|
-
} catch (err) {
|
|
240
|
-
rlog.warn({ err }, "Failed to sync assistant message to disk (non-fatal)");
|
|
241
254
|
}
|
|
242
255
|
}
|
|
243
256
|
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import { repairHistory } from "../agent/history-repair/history-repair.js";
|
|
19
|
-
import type { AgentLoopConfig } from "../agent/loop.js";
|
|
19
|
+
import type { AgentLoopConfig, PreparedModelCall } from "../agent/loop.js";
|
|
20
20
|
import { AgentLoop } from "../agent/loop.js";
|
|
21
21
|
import type { AssistantActivityStateEvent } from "../api/events/assistant-activity-state.js";
|
|
22
22
|
import type { ConfirmationStateChangedEvent } from "../api/events/confirmation-state-changed.js";
|
|
@@ -39,6 +39,7 @@ import { resolveCallSiteConfig } from "../config/llm-resolver.js";
|
|
|
39
39
|
import { getConfig } from "../config/loader.js";
|
|
40
40
|
import type { LLMCallSite, Speed } from "../config/schemas/llm.js";
|
|
41
41
|
import { resolveSendUserMessageActive } from "../config/send-user-message-gate.js";
|
|
42
|
+
import { isSessionGroupsEnabled } from "../config/session-groups-gate.js";
|
|
42
43
|
import {
|
|
43
44
|
derefToolResultReReads,
|
|
44
45
|
postTurnTruncateToolResults,
|
|
@@ -92,6 +93,7 @@ import {
|
|
|
92
93
|
markV3LiveBlock,
|
|
93
94
|
MEMORY_V3_POINTER_BLOCK_METADATA_KEY,
|
|
94
95
|
} from "../plugins/defaults/memory/v3/types.js";
|
|
96
|
+
import { resolveDelegateIndependentTasks } from "../prompts/delegation-gate.js";
|
|
95
97
|
import {
|
|
96
98
|
applyBootstrapTemplate,
|
|
97
99
|
buildSystemPrompt,
|
|
@@ -117,6 +119,8 @@ import { withSqliteRetry } from "../util/sqlite-retry.js";
|
|
|
117
119
|
import type { WorkspaceGitService } from "../workspace/git-service.js";
|
|
118
120
|
import type { commitTurnChanges } from "../workspace/turn-commit.js";
|
|
119
121
|
import type { AssistantAttachmentDraft } from "./assistant-attachments.js";
|
|
122
|
+
import { BrowserModeSessionProducer } from "./browser-mode-session.js";
|
|
123
|
+
import { ComputerUseModeSessionProducer } from "./computer-use-mode-session.js";
|
|
120
124
|
import type { AssistantSurface } from "./conversation-agent-loop.js";
|
|
121
125
|
import {
|
|
122
126
|
applyCompactionResult,
|
|
@@ -140,6 +144,7 @@ import {
|
|
|
140
144
|
persistUserMessage as persistUserMessageImpl,
|
|
141
145
|
redirectToSecurePrompt as redirectToSecurePromptImpl,
|
|
142
146
|
} from "./conversation-messaging.js";
|
|
147
|
+
import { ConversationModeSessionCoordinator } from "./conversation-mode-session.js";
|
|
143
148
|
// Extracted modules
|
|
144
149
|
import { registerConversationNotifiers } from "./conversation-notifiers.js";
|
|
145
150
|
import type { ProcessMessageOptions } from "./conversation-process.js";
|
|
@@ -181,6 +186,7 @@ import {
|
|
|
181
186
|
canSpawnSubagentsForTurn,
|
|
182
187
|
createResolveToolsCallback,
|
|
183
188
|
createToolExecutor,
|
|
189
|
+
createWireToolSurfaceRecorder,
|
|
184
190
|
} from "./conversation-tool-setup.js";
|
|
185
191
|
import { canonicalizeTimeZone } from "./date-context.js";
|
|
186
192
|
import { HostAppControlProxy } from "./host-app-control-proxy.js";
|
|
@@ -191,6 +197,7 @@ import { filterMessagesForUntrustedActor } from "./message-provenance.js";
|
|
|
191
197
|
import type { ConversationTransportMetadata } from "./message-types/conversations.js";
|
|
192
198
|
import { isHostProxyTransport } from "./message-types/conversations.js";
|
|
193
199
|
import { conversationMetadataSyncTag } from "./message-types/sync.js";
|
|
200
|
+
import { bestEffortModeSessionTracking } from "./mode-session-tracking.js";
|
|
194
201
|
import { renderReactionHistoryText } from "./reaction-history-render.js";
|
|
195
202
|
import type { QueuedReactionRecord } from "./reaction-record.js";
|
|
196
203
|
import {
|
|
@@ -199,6 +206,7 @@ import {
|
|
|
199
206
|
} from "./summarize-boundary.js";
|
|
200
207
|
|
|
201
208
|
const log = getLogger("conversation");
|
|
209
|
+
const PROMPT_CACHE_WARM_MAX_TOKENS = 16;
|
|
202
210
|
|
|
203
211
|
/**
|
|
204
212
|
* First text block of a persisted message row's content, mirroring
|
|
@@ -452,6 +460,41 @@ export class Conversation {
|
|
|
452
460
|
* @internal
|
|
453
461
|
*/
|
|
454
462
|
toolContextPin?: WakeToolContextPin;
|
|
463
|
+
/**
|
|
464
|
+
* Tool definitions sent verbatim in place of the resolved wire array, for
|
|
465
|
+
* a wake replaying its source conversation's recorded surface
|
|
466
|
+
* (`recordConversationToolSurface`). Set and restored alongside the
|
|
467
|
+
* allowlist by `scopeWakeAllowedTools`; read only where the resolver returns
|
|
468
|
+
* the wire array, so it never widens what may execute.
|
|
469
|
+
* @internal
|
|
470
|
+
*/
|
|
471
|
+
wireToolReplay?: readonly ToolDefinition[];
|
|
472
|
+
/**
|
|
473
|
+
* The delegation section's rendered state a wake replaying its source's
|
|
474
|
+
* recorded surface carries into its system prompt, in place of the answer
|
|
475
|
+
* derived from the wake's own scope (`canSpawnSubagentsForTurn`). Set and
|
|
476
|
+
* restored alongside {@link wireToolReplay} by `scopeWakeAllowedTools`;
|
|
477
|
+
* read only by {@link buildCurrentSystemPrompt}, so it never widens what
|
|
478
|
+
* may execute.
|
|
479
|
+
* @internal
|
|
480
|
+
*/
|
|
481
|
+
delegateIndependentTasksReplay?: boolean;
|
|
482
|
+
/**
|
|
483
|
+
* The delegation-section state the system prompt most recently built by
|
|
484
|
+
* {@link buildCurrentSystemPrompt} rendered: the value the loop's prompt
|
|
485
|
+
* carries until the next build. `null` when that prompt is a verbatim
|
|
486
|
+
* override, unset before the first build. Read by the wire-surface recorder
|
|
487
|
+
* so the recorded state is the one the provider received, not a
|
|
488
|
+
* re-derivation that a config change mid-turn could flip.
|
|
489
|
+
* @internal
|
|
490
|
+
*/
|
|
491
|
+
renderedDelegateIndependentTasks?: boolean | null;
|
|
492
|
+
/**
|
|
493
|
+
* Hash of the wire surface last recorded for this conversation in this
|
|
494
|
+
* process, so an unchanged surface is not rewritten on every provider call.
|
|
495
|
+
* @internal
|
|
496
|
+
*/
|
|
497
|
+
recordedToolSurfaceHash?: string;
|
|
455
498
|
/** @internal */ readonly skillProjectionState = new Map<string, string>();
|
|
456
499
|
/** @internal */ readonly skillProjectionCache: SkillProjectionCache = {};
|
|
457
500
|
/** @internal */ usageStats: UsageStats = {
|
|
@@ -488,6 +531,13 @@ export class Conversation {
|
|
|
488
531
|
*/
|
|
489
532
|
enabledPlugins: string[] | null = null;
|
|
490
533
|
/** @internal */ currentRequestId?: string;
|
|
534
|
+
/** Canonical recorded-session ownership for this conversation. */
|
|
535
|
+
readonly modeSessions: ConversationModeSessionCoordinator;
|
|
536
|
+
/** Computer-use producer mapped onto the canonical session coordinator. */
|
|
537
|
+
readonly computerUseModeSessions: ComputerUseModeSessionProducer;
|
|
538
|
+
/** Browser producer mapped onto the canonical session coordinator. */
|
|
539
|
+
readonly browserModeSessions: BrowserModeSessionProducer;
|
|
540
|
+
private liveVoiceResidencyLeases = 0;
|
|
491
541
|
/**
|
|
492
542
|
* The `clientMessageId` the running turn was started by, recorded in the same
|
|
493
543
|
* synchronous step that takes the processing lock.
|
|
@@ -746,17 +796,22 @@ export class Conversation {
|
|
|
746
796
|
*/
|
|
747
797
|
pendingInterruptActivityBridge = false;
|
|
748
798
|
/**
|
|
749
|
-
* Set by `interruptRunningTurn`
|
|
750
|
-
*
|
|
751
|
-
* interrupting user message, which appends
|
|
799
|
+
* Set by `interruptRunningTurn` on every handover it completes, and consumed
|
|
800
|
+
* exactly once by the first user message persisted after it, which appends
|
|
752
801
|
* {@link INTERRUPTED_TURN_NOTE_TEXT} to that message's LLM-facing content
|
|
753
802
|
* and stamps `interruptedPriorTurn` on the row.
|
|
754
803
|
*
|
|
755
|
-
*
|
|
756
|
-
* `tool_result`
|
|
757
|
-
*
|
|
758
|
-
*
|
|
759
|
-
*
|
|
804
|
+
* The note is the only place the behavior after an interrupt is spelled out.
|
|
805
|
+
* A synthetic `tool_result` states what happened to the one call it answers
|
|
806
|
+
* and nothing more, so an interrupt caught mid-tool arms this too.
|
|
807
|
+
*
|
|
808
|
+
* It belongs to the history position, not to the send that armed it. That
|
|
809
|
+
* first row is the one sitting directly under the work the handover stopped,
|
|
810
|
+
* so it is the row whose note the model reads in the right place. Normally it
|
|
811
|
+
* is the interrupting message itself. When that send loses the lock race and
|
|
812
|
+
* queues, the message that persists first was also sent while the assistant
|
|
813
|
+
* was working, and the note is true of it; the queued one drains after a
|
|
814
|
+
* completed turn, where the same note would be stale.
|
|
760
815
|
* @internal
|
|
761
816
|
*/
|
|
762
817
|
pendingInterruptNote = false;
|
|
@@ -938,6 +993,16 @@ export class Conversation {
|
|
|
938
993
|
const { maxTokens, speedOverride, cacheTtl, modelOverride } = options ?? {};
|
|
939
994
|
const enableNativeWebSearch = options?.enableNativeWebSearch ?? false;
|
|
940
995
|
this.conversationId = conversationId;
|
|
996
|
+
this.modeSessions = new ConversationModeSessionCoordinator(conversationId);
|
|
997
|
+
this.computerUseModeSessions = new ComputerUseModeSessionProducer(
|
|
998
|
+
this.modeSessions,
|
|
999
|
+
isSessionGroupsEnabled,
|
|
1000
|
+
);
|
|
1001
|
+
this.browserModeSessions = new BrowserModeSessionProducer(
|
|
1002
|
+
this.modeSessions,
|
|
1003
|
+
1,
|
|
1004
|
+
isSessionGroupsEnabled,
|
|
1005
|
+
);
|
|
941
1006
|
this.parentConversationId = options?.parentConversationId;
|
|
942
1007
|
this.systemPrompt = systemPrompt;
|
|
943
1008
|
this.provider = provider;
|
|
@@ -1038,6 +1103,7 @@ export class Conversation {
|
|
|
1038
1103
|
tools: toolDefs.length > 0 ? toolDefs : undefined,
|
|
1039
1104
|
toolExecutor: toolDefs.length > 0 ? toolExecutor : undefined,
|
|
1040
1105
|
resolveTools,
|
|
1106
|
+
onToolsSent: createWireToolSurfaceRecorder(this),
|
|
1041
1107
|
resolveConversationDir: () => {
|
|
1042
1108
|
const conv = getConversation(this.conversationId);
|
|
1043
1109
|
if (!conv) {
|
|
@@ -1132,23 +1198,40 @@ export class Conversation {
|
|
|
1132
1198
|
* the provider's prefix cache).
|
|
1133
1199
|
*/
|
|
1134
1200
|
buildCurrentSystemPrompt(): string {
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1201
|
+
if (this.hasSystemPromptOverride) {
|
|
1202
|
+
this.renderedDelegateIndependentTasks = null;
|
|
1203
|
+
return this.systemPrompt;
|
|
1204
|
+
}
|
|
1205
|
+
// Resolved once here, handed to the builder, and kept for the
|
|
1206
|
+
// wire-surface recorder, so the prompt the provider receives and the state
|
|
1207
|
+
// a fork replays are the same value by construction. A wake replaying its
|
|
1208
|
+
// source's recorded surface renders the section the source's live turn
|
|
1209
|
+
// rendered; otherwise the answer is read off this turn's resolved tool
|
|
1210
|
+
// surface: a workspace `tools.exclude` entry, a background run's
|
|
1211
|
+
// `allowedTools` scope, a read-only subagent pass, or tools disabled all
|
|
1212
|
+
// answer no, and the section renders off rather than pointing at a tool
|
|
1213
|
+
// the turn cannot call.
|
|
1214
|
+
const delegateIndependentTasks =
|
|
1215
|
+
this.delegateIndependentTasksReplay ??
|
|
1216
|
+
resolveDelegateIndependentTasks({
|
|
1217
|
+
canSpawnSubagents: canSpawnSubagentsForTurn(this),
|
|
1218
|
+
channelCapabilities: this.currentTurnChannelCapabilities,
|
|
1219
|
+
});
|
|
1220
|
+
const prompt = buildSystemPrompt({
|
|
1221
|
+
hasNoClient: this.hasNoClient,
|
|
1222
|
+
trustContext: this.currentTurnTrustContext,
|
|
1223
|
+
channelCapabilities: this.currentTurnChannelCapabilities,
|
|
1224
|
+
personaOverride: this.wakePersonaOverride,
|
|
1225
|
+
onboardingContext: this.getOnboardingContext(),
|
|
1226
|
+
conversationId: this.conversationId,
|
|
1227
|
+
sendUserMessageTool: resolveSendUserMessageActive(this),
|
|
1228
|
+
delegateIndependentTasks,
|
|
1229
|
+
});
|
|
1230
|
+
// Recorded only once the build succeeds: a wake's prompt sync swallows a
|
|
1231
|
+
// failed rebuild and runs on the previous prompt, whose state must stay
|
|
1232
|
+
// the recorded one.
|
|
1233
|
+
this.renderedDelegateIndependentTasks = delegateIndependentTasks;
|
|
1234
|
+
return prompt;
|
|
1152
1235
|
}
|
|
1153
1236
|
|
|
1154
1237
|
/**
|
|
@@ -1182,48 +1265,91 @@ export class Conversation {
|
|
|
1182
1265
|
// ── Prompt Cache Warming ─────────────────────────────────────────
|
|
1183
1266
|
|
|
1184
1267
|
/**
|
|
1185
|
-
*
|
|
1186
|
-
* prompt cache (system prompt + tools).
|
|
1187
|
-
* greeting so the user's next real message gets a cache hit.
|
|
1268
|
+
* Non-rejecting LLM call with a minimal output budget to populate the selected
|
|
1269
|
+
* provider's prompt cache (system prompt + tools).
|
|
1188
1270
|
*/
|
|
1189
|
-
warmPromptCache(
|
|
1271
|
+
async warmPromptCache(options?: {
|
|
1272
|
+
callSite?: LLMCallSite;
|
|
1273
|
+
overrideProfile?: string;
|
|
1274
|
+
forceOverrideProfile?: boolean;
|
|
1275
|
+
signal?: AbortSignal;
|
|
1276
|
+
systemPrompt?: string | null;
|
|
1277
|
+
tools?: ToolDefinition[];
|
|
1278
|
+
}): Promise<void> {
|
|
1190
1279
|
this.cacheWarmAbort?.abort();
|
|
1191
1280
|
const abort = new AbortController();
|
|
1192
1281
|
this.cacheWarmAbort = abort;
|
|
1193
1282
|
|
|
1194
|
-
const
|
|
1195
|
-
const
|
|
1196
|
-
|
|
1283
|
+
const externalSignal = options?.signal;
|
|
1284
|
+
const relayAbort = (): void => abort.abort(externalSignal?.reason);
|
|
1285
|
+
if (externalSignal?.aborted) {
|
|
1286
|
+
relayAbort();
|
|
1287
|
+
} else {
|
|
1288
|
+
externalSignal?.addEventListener("abort", relayAbort, { once: true });
|
|
1289
|
+
}
|
|
1197
1290
|
|
|
1198
|
-
const
|
|
1199
|
-
role: "user",
|
|
1200
|
-
content: [{ type: "text", text: "hi" }],
|
|
1201
|
-
};
|
|
1291
|
+
const callSite = options?.callSite ?? "mainAgent";
|
|
1202
1292
|
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
systemPrompt
|
|
1293
|
+
try {
|
|
1294
|
+
const hasSystemPrompt =
|
|
1295
|
+
options !== undefined &&
|
|
1296
|
+
Object.prototype.hasOwnProperty.call(options, "systemPrompt");
|
|
1297
|
+
const systemPrompt = hasSystemPrompt
|
|
1298
|
+
? (options.systemPrompt ?? undefined)
|
|
1299
|
+
: this.buildCurrentSystemPrompt();
|
|
1300
|
+
const tools =
|
|
1301
|
+
options?.tools ?? this.agentLoop.getResolvedTools(this.messages);
|
|
1302
|
+
const providerConfig = {
|
|
1303
|
+
...(options?.overrideProfile !== undefined
|
|
1304
|
+
? { overrideProfile: options.overrideProfile }
|
|
1305
|
+
: {}),
|
|
1306
|
+
...(options?.forceOverrideProfile !== undefined
|
|
1307
|
+
? { forceOverrideProfile: options.forceOverrideProfile }
|
|
1308
|
+
: {}),
|
|
1309
|
+
selectionSeed: this.conversationId,
|
|
1310
|
+
};
|
|
1311
|
+
const warmMessage: Message = {
|
|
1312
|
+
role: "user",
|
|
1313
|
+
content: [{ type: "text", text: "hi" }],
|
|
1314
|
+
};
|
|
1315
|
+
|
|
1316
|
+
await this.provider.sendMessage([warmMessage], {
|
|
1317
|
+
tools: tools.length > 0 ? tools : undefined,
|
|
1318
|
+
...(systemPrompt !== undefined ? { systemPrompt } : {}),
|
|
1207
1319
|
config: {
|
|
1208
|
-
max_tokens:
|
|
1209
|
-
callSite
|
|
1210
|
-
|
|
1320
|
+
max_tokens: PROMPT_CACHE_WARM_MAX_TOKENS,
|
|
1321
|
+
callSite,
|
|
1322
|
+
...providerConfig,
|
|
1323
|
+
conversationId: this.conversationId,
|
|
1211
1324
|
},
|
|
1212
1325
|
signal: abort.signal,
|
|
1213
|
-
})
|
|
1214
|
-
.then(() => {
|
|
1215
|
-
log.info("Prompt cache warmed successfully");
|
|
1216
|
-
})
|
|
1217
|
-
.catch((err) => {
|
|
1218
|
-
if (!abort.signal.aborted) {
|
|
1219
|
-
log.warn({ err }, "Prompt cache warming failed (non-fatal)");
|
|
1220
|
-
}
|
|
1221
|
-
})
|
|
1222
|
-
.finally(() => {
|
|
1223
|
-
if (this.cacheWarmAbort === abort) {
|
|
1224
|
-
this.cacheWarmAbort = undefined;
|
|
1225
|
-
}
|
|
1226
1326
|
});
|
|
1327
|
+
if (!abort.signal.aborted) {
|
|
1328
|
+
log.info(
|
|
1329
|
+
{
|
|
1330
|
+
callSite,
|
|
1331
|
+
profile: options?.overrideProfile ?? null,
|
|
1332
|
+
},
|
|
1333
|
+
"Prompt cache warmed successfully",
|
|
1334
|
+
);
|
|
1335
|
+
}
|
|
1336
|
+
} catch (err) {
|
|
1337
|
+
if (!abort.signal.aborted) {
|
|
1338
|
+
log.warn(
|
|
1339
|
+
{
|
|
1340
|
+
err,
|
|
1341
|
+
callSite,
|
|
1342
|
+
profile: options?.overrideProfile ?? null,
|
|
1343
|
+
},
|
|
1344
|
+
"Prompt cache warming failed (non-fatal)",
|
|
1345
|
+
);
|
|
1346
|
+
}
|
|
1347
|
+
} finally {
|
|
1348
|
+
externalSignal?.removeEventListener("abort", relayAbort);
|
|
1349
|
+
if (this.cacheWarmAbort === abort) {
|
|
1350
|
+
this.cacheWarmAbort = undefined;
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1227
1353
|
}
|
|
1228
1354
|
|
|
1229
1355
|
// ── Lifecycle ────────────────────────────────────────────────────
|
|
@@ -2454,14 +2580,31 @@ export class Conversation {
|
|
|
2454
2580
|
return !this.queue.isEmpty;
|
|
2455
2581
|
}
|
|
2456
2582
|
|
|
2583
|
+
acquireLiveVoiceResidency(): () => void {
|
|
2584
|
+
this.liveVoiceResidencyLeases += 1;
|
|
2585
|
+
let released = false;
|
|
2586
|
+
return () => {
|
|
2587
|
+
if (released) {
|
|
2588
|
+
return;
|
|
2589
|
+
}
|
|
2590
|
+
released = true;
|
|
2591
|
+
this.liveVoiceResidencyLeases = Math.max(
|
|
2592
|
+
0,
|
|
2593
|
+
this.liveVoiceResidencyLeases - 1,
|
|
2594
|
+
);
|
|
2595
|
+
};
|
|
2596
|
+
}
|
|
2597
|
+
|
|
2457
2598
|
/**
|
|
2458
2599
|
* True when dropping this instance would lose work that is still in flight:
|
|
2459
|
-
* a live turn,
|
|
2600
|
+
* a live turn, queued successor, child subagent, or mode-session lifecycle.
|
|
2460
2601
|
*/
|
|
2461
2602
|
hasInFlightWork(): boolean {
|
|
2462
2603
|
return (
|
|
2463
2604
|
this.isProcessing() ||
|
|
2464
2605
|
this.hasQueuedMessages() ||
|
|
2606
|
+
this.liveVoiceResidencyLeases > 0 ||
|
|
2607
|
+
this.modeSessions.hasResidentWork() ||
|
|
2465
2608
|
getSubagentManager().hasActiveChildren(this.conversationId)
|
|
2466
2609
|
);
|
|
2467
2610
|
}
|
|
@@ -2588,6 +2731,16 @@ export class Conversation {
|
|
|
2588
2731
|
|
|
2589
2732
|
setHostCuProxy(proxy: HostCuProxy | undefined): void {
|
|
2590
2733
|
if (this.hostCuProxy && this.hostCuProxy !== proxy) {
|
|
2734
|
+
const previousProxy = this.hostCuProxy;
|
|
2735
|
+
bestEffortModeSessionTracking("computer use proxy replacement", () => {
|
|
2736
|
+
this.computerUseModeSessions.endTask({
|
|
2737
|
+
turnId: this.currentRequestId,
|
|
2738
|
+
source: {
|
|
2739
|
+
sourceId: previousProxy.sourceId,
|
|
2740
|
+
generation: previousProxy.resetGeneration,
|
|
2741
|
+
},
|
|
2742
|
+
});
|
|
2743
|
+
});
|
|
2591
2744
|
this.hostCuProxy.dispose();
|
|
2592
2745
|
}
|
|
2593
2746
|
this.hostCuProxy = proxy;
|
|
@@ -3362,6 +3515,8 @@ export class Conversation {
|
|
|
3362
3515
|
*/
|
|
3363
3516
|
replyDeliveredInAppOnly?: boolean;
|
|
3364
3517
|
callSite?: LLMCallSite;
|
|
3518
|
+
/** Provider configuration source when distinct from turn semantics. */
|
|
3519
|
+
inferenceCallSite?: LLMCallSite;
|
|
3365
3520
|
/**
|
|
3366
3521
|
* Optional ad-hoc inference-profile override applied to every LLM call
|
|
3367
3522
|
* the loop issues for this turn. Forwarded into
|
|
@@ -3373,6 +3528,8 @@ export class Conversation {
|
|
|
3373
3528
|
overrideProfile?: string;
|
|
3374
3529
|
/** Float `overrideProfile` above call-site layers for this run. */
|
|
3375
3530
|
forceOverrideProfile?: boolean;
|
|
3531
|
+
/** Observe the first finalized model request without delaying it. */
|
|
3532
|
+
onFirstModelCallPrepared?: (prepared: PreparedModelCall) => void;
|
|
3376
3533
|
/**
|
|
3377
3534
|
* Firing's `cron_runs.id` stamped onto this turn's usage rows. Per-turn:
|
|
3378
3535
|
* forwarded into {@link runAgentLoopImpl} and threaded to `recordUsage`.
|
|
@@ -43,7 +43,7 @@ function isPositiveInteger(v: unknown): v is number {
|
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* Read daemon timeout values directly from the config JSON file, bypassing
|
|
46
|
-
* loadConfig() and its
|
|
46
|
+
* loadConfig() and its ensureDataDir() side effects.
|
|
47
47
|
* Falls back to hardcoded defaults on any error (missing file, malformed JSON,
|
|
48
48
|
* unexpected shape) so daemon stop/start never fails due to config issues.
|
|
49
49
|
*/
|
|
@@ -258,15 +258,11 @@ async function getDaemonStatus(): Promise<{
|
|
|
258
258
|
return { running: true, pid };
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
function getStartupLockPath(): string {
|
|
262
|
-
return getDaemonStartupLockPath();
|
|
263
|
-
}
|
|
264
|
-
|
|
265
261
|
/** Attempt to acquire a startup lock. Returns true on success. Stale locks
|
|
266
262
|
* (older than STARTUP_LOCK_STALE_MS) are forcibly removed to prevent
|
|
267
263
|
* permanent deadlocks from a crashed caller. */
|
|
268
264
|
function acquireStartupLock(): boolean {
|
|
269
|
-
const lockPath =
|
|
265
|
+
const lockPath = getDaemonStartupLockPath();
|
|
270
266
|
try {
|
|
271
267
|
// Ensure the root directory exists before attempting the lock file write.
|
|
272
268
|
// On a first-time run, getRootDir() may not exist yet, and writeFileSync
|
|
@@ -293,7 +289,7 @@ function acquireStartupLock(): boolean {
|
|
|
293
289
|
|
|
294
290
|
function releaseStartupLock(): void {
|
|
295
291
|
try {
|
|
296
|
-
unlinkSync(
|
|
292
|
+
unlinkSync(getDaemonStartupLockPath());
|
|
297
293
|
} catch {
|
|
298
294
|
/* already removed */
|
|
299
295
|
}
|
|
@@ -98,14 +98,16 @@ export function setImageGenModel(modelId: string, ctx: ModelSetContext): void {
|
|
|
98
98
|
// Keep the derived provider in sync with the selected model so downstream
|
|
99
99
|
// routing never sends a Gemini request to an OpenAI model (or vice versa).
|
|
100
100
|
// The prefix logic is shared with workspace migration 006-services-config
|
|
101
|
-
// via providerForImageModelPrefix().
|
|
102
|
-
// managed for every model
|
|
103
|
-
//
|
|
104
|
-
// BYOK provider they may hold no key
|
|
101
|
+
// via providerForImageModelPrefix(). Providers "vellum" and "openrouter"
|
|
102
|
+
// are exempt: vellum is managed for every model, and openrouter owns every
|
|
103
|
+
// selected slug (including google/ and openai/ prefixes). Rewriting either
|
|
104
|
+
// would silently move the user onto a BYOK provider they may hold no key
|
|
105
|
+
// for.
|
|
105
106
|
const services = raw.services as
|
|
106
107
|
| Record<string, { provider?: string }>
|
|
107
108
|
| undefined;
|
|
108
|
-
|
|
109
|
+
const currentProvider = services?.["image-generation"]?.provider;
|
|
110
|
+
if (currentProvider !== "vellum" && currentProvider !== "openrouter") {
|
|
109
111
|
setServiceField(
|
|
110
112
|
raw,
|
|
111
113
|
"image-generation",
|
|
@@ -3,8 +3,13 @@ import {
|
|
|
3
3
|
SENTINEL_REDACTION_VERSION,
|
|
4
4
|
} from "@vellumai/service-contracts/redacted-credential";
|
|
5
5
|
import { v4 as uuid } from "uuid";
|
|
6
|
+
import { z } from "zod";
|
|
6
7
|
|
|
7
8
|
import { AnsweredQuestionSchema } from "../../api/events/question-answered.js";
|
|
9
|
+
import {
|
|
10
|
+
type ToolActivityMetadata,
|
|
11
|
+
ToolActivityMetadataSchema,
|
|
12
|
+
} from "../../api/events/tool-result.js";
|
|
8
13
|
import type {
|
|
9
14
|
ConversationContentBlock,
|
|
10
15
|
ConversationMessageAttachment,
|
|
@@ -246,6 +251,33 @@ export interface ConversationCreateOptions {
|
|
|
246
251
|
conversationType?: ConversationCreateType;
|
|
247
252
|
}
|
|
248
253
|
|
|
254
|
+
/** One schema per activity entry, so each entry validates on its own. */
|
|
255
|
+
const ACTIVITY_ENTRY_SCHEMAS = Object.entries(
|
|
256
|
+
ToolActivityMetadataSchema.shape,
|
|
257
|
+
).map(([key, schema]) => z.object({ [key]: schema }));
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Validates a persisted `_activityMetadata` rider one tool's entry at a time.
|
|
261
|
+
* Cards render these fields directly, so an entry that no longer matches its
|
|
262
|
+
* schema is dropped (its card degrades to the result text) without taking a
|
|
263
|
+
* valid sibling entry with it.
|
|
264
|
+
*/
|
|
265
|
+
function readPersistedActivityMetadata(
|
|
266
|
+
value: unknown,
|
|
267
|
+
): ToolActivityMetadata | undefined {
|
|
268
|
+
if (!isRecord(value)) {
|
|
269
|
+
return undefined;
|
|
270
|
+
}
|
|
271
|
+
const activity: ToolActivityMetadata = {};
|
|
272
|
+
for (const schema of ACTIVITY_ENTRY_SCHEMAS) {
|
|
273
|
+
const parsed = schema.safeParse(value);
|
|
274
|
+
if (parsed.success) {
|
|
275
|
+
Object.assign(activity, parsed.data);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return Object.keys(activity).length > 0 ? activity : undefined;
|
|
279
|
+
}
|
|
280
|
+
|
|
249
281
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
250
282
|
return typeof value === "object" && value != null;
|
|
251
283
|
}
|
|
@@ -661,12 +693,12 @@ export function renderHistoryContent(
|
|
|
661
693
|
entry.riskDirectoryScopeOptions =
|
|
662
694
|
block._riskDirectoryScopeOptions as HistoryToolCall["riskDirectoryScopeOptions"];
|
|
663
695
|
}
|
|
664
|
-
// Read back tool activity
|
|
665
|
-
//
|
|
666
|
-
//
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
696
|
+
// Read back tool activity persisted by `annotatePersistedAssistantMessage`
|
|
697
|
+
// so the activity card survives a history reopen instead of degrading to
|
|
698
|
+
// the plain result text.
|
|
699
|
+
const activity = readPersistedActivityMetadata(block._activityMetadata);
|
|
700
|
+
if (activity) {
|
|
701
|
+
entry.activityMetadata = activity;
|
|
670
702
|
}
|
|
671
703
|
// Read back the answered `ask_question` record so the answered card
|
|
672
704
|
// rehydrates from history. Validated (rather than trusted like the
|
|
@@ -708,9 +740,9 @@ export function renderHistoryContent(
|
|
|
708
740
|
}
|
|
709
741
|
// Native server tools (Anthropic web_search) persist their activity on
|
|
710
742
|
// the server_tool_use block, so read it back here too.
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
743
|
+
const activity = readPersistedActivityMetadata(block._activityMetadata);
|
|
744
|
+
if (activity) {
|
|
745
|
+
entry.activityMetadata = activity;
|
|
714
746
|
}
|
|
715
747
|
toolCalls.push(entry);
|
|
716
748
|
if (id) {
|
|
@@ -936,17 +968,24 @@ async function mintCollectionLinkFallback(
|
|
|
936
968
|
*
|
|
937
969
|
* Lifecycle state (resolver, timer) is registered in pendingInteractions — the
|
|
938
970
|
* same tracker the in-conversation SecretPrompter uses — so `POST /v1/secret`
|
|
939
|
-
* resolves the prompt generically.
|
|
940
|
-
* `credentials prompt` command forwards
|
|
941
|
-
*
|
|
942
|
-
*
|
|
943
|
-
*
|
|
944
|
-
*
|
|
945
|
-
*
|
|
971
|
+
* resolves the prompt generically. The broadcast is scoped to the supplied
|
|
972
|
+
* `conversationId` (the CLI `credentials prompt` command forwards
|
|
973
|
+
* `__CONVERSATION_ID`) so clients deliver it. Two cases have no surface that
|
|
974
|
+
* can render the card and resolve immediately with `unsupported_channel`,
|
|
975
|
+
* carrying a one-time collection link when the gateway can mint one, instead
|
|
976
|
+
* of broadcasting a request that can only time out:
|
|
977
|
+
* - the conversation's channel cannot render dynamic UI (slack, telegram);
|
|
978
|
+
* - there is no conversation at all (a headless exec such as Doctor's
|
|
979
|
+
* `run_assistant_cli`). Clients drop conversation-scoped events without a
|
|
980
|
+
* conversationId and `/v1/pending-interactions` is keyed by conversation,
|
|
981
|
+
* so a conversation-less `secret_request` is invisible everywhere.
|
|
946
982
|
*/
|
|
947
983
|
export function requestSecretStandalone(
|
|
948
984
|
params: StandaloneSecretParams,
|
|
949
985
|
): Promise<SecretPromptResult> {
|
|
986
|
+
if (!params.conversationId) {
|
|
987
|
+
return mintCollectionLinkFallback(params);
|
|
988
|
+
}
|
|
950
989
|
const conversation = findConversation(params.conversationId);
|
|
951
990
|
if (conversation && !conversationSupportsDynamicUi(conversation)) {
|
|
952
991
|
return mintCollectionLinkFallback(params);
|