@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,3 +1,4 @@
|
|
|
1
|
+
import type { Conversation } from "../../daemon/conversation.js";
|
|
1
2
|
import { resolveTurnClientOs } from "../../daemon/conversation-client-surface.js";
|
|
2
3
|
import { findConversation } from "../../daemon/conversation-registry.js";
|
|
3
4
|
import type { ToolContext } from "../../tools/types.js";
|
|
@@ -13,6 +14,22 @@ export async function resolveBrowserContext(
|
|
|
13
14
|
headers: Record<string, string>,
|
|
14
15
|
abortSignal?: AbortSignal,
|
|
15
16
|
): Promise<ToolContext> {
|
|
17
|
+
return (
|
|
18
|
+
await resolveBrowserExecutionContext(
|
|
19
|
+
conversationId,
|
|
20
|
+
sessionId,
|
|
21
|
+
headers,
|
|
22
|
+
abortSignal,
|
|
23
|
+
)
|
|
24
|
+
).context;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function resolveBrowserExecutionContext(
|
|
28
|
+
conversationId: string | undefined,
|
|
29
|
+
sessionId: string,
|
|
30
|
+
headers: Record<string, string>,
|
|
31
|
+
abortSignal?: AbortSignal,
|
|
32
|
+
): Promise<{ context: ToolContext; conversation?: Conversation }> {
|
|
16
33
|
const conversation = conversationId
|
|
17
34
|
? findConversation(conversationId)
|
|
18
35
|
: undefined;
|
|
@@ -24,16 +41,19 @@ export async function resolveBrowserContext(
|
|
|
24
41
|
(signal): signal is AbortSignal => signal !== undefined,
|
|
25
42
|
);
|
|
26
43
|
return {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
44
|
+
context: {
|
|
45
|
+
workingDir: process.cwd(),
|
|
46
|
+
conversationId: conversation
|
|
47
|
+
? conversationId!
|
|
48
|
+
: browserCliConversationKey(sessionId),
|
|
49
|
+
trustClass: conversation?.trustContext?.trustClass ?? "unknown",
|
|
50
|
+
transportInterface: conversation?.transportInterface,
|
|
51
|
+
clientOs: conversation
|
|
52
|
+
? resolveTurnClientOs(conversation).clientOs
|
|
53
|
+
: undefined,
|
|
54
|
+
sourceActorPrincipalId: actor,
|
|
55
|
+
signal: signals.length ? AbortSignal.any(signals) : undefined,
|
|
56
|
+
},
|
|
57
|
+
...(conversation ? { conversation } : {}),
|
|
38
58
|
};
|
|
39
59
|
}
|
|
@@ -11,16 +11,20 @@
|
|
|
11
11
|
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
browserOperationLifecycle,
|
|
16
|
+
executeBrowserOperation,
|
|
17
|
+
} from "../../browser/operations.js";
|
|
15
18
|
import {
|
|
16
19
|
BROWSER_OPERATIONS,
|
|
17
20
|
type BrowserOperation,
|
|
18
21
|
} from "../../browser/types.js";
|
|
19
22
|
import { shouldUseVirtualDesktopBrowser } from "../../browser/virtual-desktop-target.js";
|
|
23
|
+
import { bestEffortModeSessionTracking } from "../../daemon/mode-session-tracking.js";
|
|
20
24
|
import { executeDesktopBrowserOperation } from "../../desktop/desktop-browser-operations.js";
|
|
21
25
|
import type { ContentBlock } from "../../providers/types.js";
|
|
22
26
|
import { LOCAL_PRINCIPALS } from "../auth/route-policy.js";
|
|
23
|
-
import {
|
|
27
|
+
import { resolveBrowserExecutionContext } from "./browser-context.js";
|
|
24
28
|
export { browserCliConversationKey } from "./browser-context.js";
|
|
25
29
|
import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
26
30
|
|
|
@@ -68,16 +72,51 @@ async function handleBrowserExecute({
|
|
|
68
72
|
const { operation, input, sessionId, conversationId, desktop } =
|
|
69
73
|
BrowserExecuteParams.parse(body);
|
|
70
74
|
|
|
71
|
-
const
|
|
75
|
+
const resolved = await resolveBrowserExecutionContext(
|
|
72
76
|
conversationId,
|
|
73
77
|
sessionId,
|
|
74
78
|
headers,
|
|
75
79
|
abortSignal,
|
|
76
80
|
);
|
|
81
|
+
const { context, conversation } = resolved;
|
|
82
|
+
const typedOperation = operation as BrowserOperation;
|
|
83
|
+
const operationToken = conversation?.currentRequestId
|
|
84
|
+
? bestEffortModeSessionTracking("browser admission", () =>
|
|
85
|
+
conversation.browserModeSessions.beginOperation({
|
|
86
|
+
turnId: conversation.currentRequestId!,
|
|
87
|
+
lifecycle: browserOperationLifecycle(typedOperation),
|
|
88
|
+
at: Date.now(),
|
|
89
|
+
}),
|
|
90
|
+
)
|
|
91
|
+
: undefined;
|
|
77
92
|
const execute = shouldUseVirtualDesktopBrowser(desktop, input, context)
|
|
78
93
|
? executeDesktopBrowserOperation
|
|
79
94
|
: executeBrowserOperation;
|
|
80
|
-
const
|
|
95
|
+
const finishOperationTracking = (isError: boolean) => {
|
|
96
|
+
if (!operationToken) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
bestEffortModeSessionTracking("browser completion", () =>
|
|
100
|
+
conversation?.browserModeSessions.finishOperation(operationToken, {
|
|
101
|
+
at: Date.now(),
|
|
102
|
+
isError,
|
|
103
|
+
cancelled: context.signal?.aborted === true,
|
|
104
|
+
...(typedOperation === "close"
|
|
105
|
+
? { terminalReason: "browser_closed" as const }
|
|
106
|
+
: typedOperation === "detach"
|
|
107
|
+
? { terminalReason: "browser_detached" as const }
|
|
108
|
+
: {}),
|
|
109
|
+
}),
|
|
110
|
+
);
|
|
111
|
+
};
|
|
112
|
+
let result;
|
|
113
|
+
try {
|
|
114
|
+
result = await execute(typedOperation, input, context);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
finishOperationTracking(true);
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
finishOperationTracking(result.isError);
|
|
81
120
|
|
|
82
121
|
const screenshots = extractScreenshots(result.contentBlocks);
|
|
83
122
|
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
* Route handler for the POST /v1/btw SSE-streaming side-chain endpoint.
|
|
3
3
|
*
|
|
4
4
|
* Runs an ephemeral LLM call that reuses the conversation's provider, tool
|
|
5
|
-
* definitions, and message history for prompt-cache efficiency
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* definitions, and message history for prompt-cache efficiency; the
|
|
6
|
+
* empty-state greeting targets no real conversation and sends no tools. Uses
|
|
7
|
+
* the conversation's system prompt when a conversation-specific override is
|
|
8
|
+
* active; otherwise builds a fresh prompt excluding BOOTSTRAP.md so first-run
|
|
8
9
|
* onboarding instructions don't leak into cosmetic UI calls like identity
|
|
9
10
|
* intro generation. The response is streamed as SSE events (`btw_text_delta`,
|
|
10
11
|
* `btw_complete`, `btw_error`).
|
|
@@ -145,7 +146,11 @@ async function handleBtw({
|
|
|
145
146
|
const result = await runBtwSidechain({
|
|
146
147
|
content: effectiveContent,
|
|
147
148
|
conversation,
|
|
148
|
-
|
|
149
|
+
// The side-chain forces `tool_choice: none`, so tool definitions
|
|
150
|
+
// only earn their tokens as a shared cache prefix with a real
|
|
151
|
+
// conversation. The greeting runs against an ephemeral one with its
|
|
152
|
+
// own system prompt, so it shares nothing and sends no tools.
|
|
153
|
+
tools: isGreeting ? [] : getAllToolDefinitions(),
|
|
149
154
|
signal: abortSignal,
|
|
150
155
|
...(isGreeting ? { callSite: "emptyStateGreeting" as const } : {}),
|
|
151
156
|
onEvent: (event) => {
|
|
@@ -29,13 +29,6 @@ export function requiredDecisionKeywords(
|
|
|
29
29
|
// Callback data parser — format: "apr:<requestId>:<action>"
|
|
30
30
|
// ---------------------------------------------------------------------------
|
|
31
31
|
|
|
32
|
-
/** Map legacy callback actions to canonical ones for in-flight buttons. */
|
|
33
|
-
const LEGACY_CALLBACK_MAP: Record<string, string> = {
|
|
34
|
-
approve_10m: "approve_once",
|
|
35
|
-
approve_conversation: "approve_once",
|
|
36
|
-
approve_always: "approve_once",
|
|
37
|
-
};
|
|
38
|
-
|
|
39
32
|
export function parseCallbackData(
|
|
40
33
|
data: string,
|
|
41
34
|
sourceChannel?: string,
|
|
@@ -45,8 +38,7 @@ export function parseCallbackData(
|
|
|
45
38
|
return null;
|
|
46
39
|
}
|
|
47
40
|
const requestId = parts[1];
|
|
48
|
-
const
|
|
49
|
-
const action = LEGACY_CALLBACK_MAP[rawAction] ?? rawAction;
|
|
41
|
+
const action = parts.slice(2).join(":");
|
|
50
42
|
if (!requestId || !isApprovalAction(action)) {
|
|
51
43
|
return null;
|
|
52
44
|
}
|
|
@@ -9,6 +9,7 @@ import { z } from "zod";
|
|
|
9
9
|
|
|
10
10
|
import type { HostProxyCapability } from "../../channels/types.js";
|
|
11
11
|
import { isHttpAuthDisabled } from "../../config/env.js";
|
|
12
|
+
import { listClientConnectionHistory } from "../../persistence/client-connection-events-store.js";
|
|
12
13
|
import { datesToISO } from "../../util/json.js";
|
|
13
14
|
import { getLogger } from "../../util/logger.js";
|
|
14
15
|
import {
|
|
@@ -112,6 +113,8 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
112
113
|
interfaceId: c.interfaceId,
|
|
113
114
|
capabilities: c.capabilities,
|
|
114
115
|
machineName: c.machineName,
|
|
116
|
+
clientVersion: c.clientVersion,
|
|
117
|
+
sseWatchdog: c.sseWatchdog,
|
|
115
118
|
connectedAt: c.connectedAt,
|
|
116
119
|
lastActiveAt: c.lastActiveAt,
|
|
117
120
|
degraded: isClientDegraded(
|
|
@@ -151,6 +154,79 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
151
154
|
return { disconnected: count };
|
|
152
155
|
},
|
|
153
156
|
},
|
|
157
|
+
{
|
|
158
|
+
operationId: "list_client_history",
|
|
159
|
+
endpoint: "clients/history",
|
|
160
|
+
method: "GET",
|
|
161
|
+
policy: {
|
|
162
|
+
requiredScopes: ["settings.read"],
|
|
163
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
164
|
+
},
|
|
165
|
+
summary: "List client connection history",
|
|
166
|
+
description:
|
|
167
|
+
"Return persisted client subscribe/dispose events and coalesced sessions. Reconnects shorter than 60 seconds are flaps, not outages.",
|
|
168
|
+
tags: ["clients"],
|
|
169
|
+
queryParams: [
|
|
170
|
+
{
|
|
171
|
+
name: "clientId",
|
|
172
|
+
type: "string",
|
|
173
|
+
required: false,
|
|
174
|
+
description: "Restrict history to one client UUID.",
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: "interfaceId",
|
|
178
|
+
type: "string",
|
|
179
|
+
required: false,
|
|
180
|
+
description: "Restrict history to one interface (e.g. chrome-extension).",
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: "since",
|
|
184
|
+
type: "string",
|
|
185
|
+
required: false,
|
|
186
|
+
description:
|
|
187
|
+
"ISO-8601 or epoch-ms lower bound. Sessions already open at this time are included.",
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: "limit",
|
|
191
|
+
type: "string",
|
|
192
|
+
required: false,
|
|
193
|
+
description: "Max coalesced sessions to return (1-500, default 50).",
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
responseBody: z.object({
|
|
197
|
+
sessions: z.array(z.object({}).passthrough()),
|
|
198
|
+
events: z.array(z.object({}).passthrough()),
|
|
199
|
+
}),
|
|
200
|
+
handler: ({ queryParams, headers }) => {
|
|
201
|
+
const since = parseHistorySince(queryParams?.since);
|
|
202
|
+
const limit = parseHistoryLimit(queryParams?.limit);
|
|
203
|
+
const callerPrincipalId = headers?.["x-vellum-actor-principal-id"];
|
|
204
|
+
const history = listClientConnectionHistory({
|
|
205
|
+
clientId: queryParams?.clientId?.trim() || undefined,
|
|
206
|
+
interfaceId: queryParams?.interfaceId?.trim() || undefined,
|
|
207
|
+
actorPrincipalId: isHttpAuthDisabled()
|
|
208
|
+
? undefined
|
|
209
|
+
: callerPrincipalId || "__none__",
|
|
210
|
+
since,
|
|
211
|
+
limit,
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
sessions: history.sessions.map((session) => ({
|
|
216
|
+
...session,
|
|
217
|
+
startedAt: new Date(session.startedAt).toISOString(),
|
|
218
|
+
endedAt:
|
|
219
|
+
session.endedAt == null
|
|
220
|
+
? null
|
|
221
|
+
: new Date(session.endedAt).toISOString(),
|
|
222
|
+
})),
|
|
223
|
+
events: history.events.map((event) => ({
|
|
224
|
+
...event,
|
|
225
|
+
occurredAt: new Date(event.occurredAt).toISOString(),
|
|
226
|
+
})),
|
|
227
|
+
};
|
|
228
|
+
},
|
|
229
|
+
},
|
|
154
230
|
{
|
|
155
231
|
operationId: "report_client_presence",
|
|
156
232
|
endpoint: "clients/presence",
|
|
@@ -342,3 +418,35 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
342
418
|
},
|
|
343
419
|
},
|
|
344
420
|
];
|
|
421
|
+
|
|
422
|
+
function parseHistorySince(raw: string | undefined): number | undefined {
|
|
423
|
+
if (!raw?.trim()) {
|
|
424
|
+
return undefined;
|
|
425
|
+
}
|
|
426
|
+
const trimmed = raw.trim();
|
|
427
|
+
if (/^\d+$/.test(trimmed)) {
|
|
428
|
+
const epoch = Number(trimmed);
|
|
429
|
+
if (!Number.isFinite(epoch) || epoch < 0) {
|
|
430
|
+
throw new BadRequestError("since must be a non-negative epoch-ms value");
|
|
431
|
+
}
|
|
432
|
+
return epoch;
|
|
433
|
+
}
|
|
434
|
+
const parsed = Date.parse(trimmed);
|
|
435
|
+
if (Number.isNaN(parsed)) {
|
|
436
|
+
throw new BadRequestError(
|
|
437
|
+
"since must be an ISO-8601 timestamp or epoch milliseconds",
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
return parsed;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
function parseHistoryLimit(raw: string | undefined): number | undefined {
|
|
444
|
+
if (!raw?.trim()) {
|
|
445
|
+
return undefined;
|
|
446
|
+
}
|
|
447
|
+
const parsed = Number(raw.trim());
|
|
448
|
+
if (!Number.isInteger(parsed) || parsed < 1) {
|
|
449
|
+
throw new BadRequestError("limit must be a positive integer");
|
|
450
|
+
}
|
|
451
|
+
return parsed;
|
|
452
|
+
}
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
* POST /v1/conversations/:id/retry — retry the last assistant turn
|
|
20
20
|
* POST /v1/conversations/reorder — reorder / pin conversations
|
|
21
21
|
*/
|
|
22
|
-
|
|
23
22
|
import { v7 as uuidv7 } from "uuid";
|
|
24
23
|
import { z } from "zod";
|
|
25
24
|
|
|
@@ -43,6 +42,7 @@ import {
|
|
|
43
42
|
undoLastMessage,
|
|
44
43
|
} from "../../daemon/handlers/conversations.js";
|
|
45
44
|
import { normalizeConversationType } from "../../daemon/message-types/shared.js";
|
|
45
|
+
import { bestEffortModeSessionTracking } from "../../daemon/mode-session-tracking.js";
|
|
46
46
|
import { stripConversationIds } from "../../home/feed-writer.js";
|
|
47
47
|
import {
|
|
48
48
|
archiveConversation,
|
|
@@ -732,6 +732,9 @@ async function handleRetryLastAssistantTurn({
|
|
|
732
732
|
if (!discarded) {
|
|
733
733
|
throw new UnprocessableEntityError("No user message to retry from");
|
|
734
734
|
}
|
|
735
|
+
bestEffortModeSessionTracking("conversation wait invalidation", () =>
|
|
736
|
+
conversation.modeSessions.invalidateAllStructuralWaits(),
|
|
737
|
+
);
|
|
735
738
|
} catch (err) {
|
|
736
739
|
if (conversation.abortController === abortController) {
|
|
737
740
|
conversation.abortController = null;
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
createUserMessage,
|
|
19
19
|
} from "../../agent/message-types.js";
|
|
20
20
|
import type { AssistantEvent } from "../../api/index.js";
|
|
21
|
+
import { ModeSessionDescriptorSchema } from "../../api/mode-session.js";
|
|
21
22
|
import {
|
|
22
23
|
BackgroundToolCompletionSchema,
|
|
23
24
|
type ConversationContentBlock,
|
|
@@ -44,10 +45,8 @@ import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-fl
|
|
|
44
45
|
import { getUserSelectableProfilesForProvider } from "../../config/default-profile-catalog.js";
|
|
45
46
|
import { isHttpAuthDisabled } from "../../config/env.js";
|
|
46
47
|
import { getConfig } from "../../config/loader.js";
|
|
47
|
-
import {
|
|
48
|
-
|
|
49
|
-
mergeToolResultsIntoAssistantMessages,
|
|
50
|
-
} from "../../conversations/message-consolidation.js";
|
|
48
|
+
import { isModeSessionRecoveryHealthy } from "../../config/session-groups-gate.js";
|
|
49
|
+
import { consolidateMessageRows } from "../../conversations/message-consolidation.js";
|
|
51
50
|
import { resolveTurnCommitWaitMs } from "../../daemon/abort-watchdog.js";
|
|
52
51
|
import { createApprovalConversationGenerator } from "../../daemon/approval-generators.js";
|
|
53
52
|
import type { Conversation } from "../../daemon/conversation.js";
|
|
@@ -113,7 +112,7 @@ import { recordOnboardingEvent } from "../../onboarding/onboarding-events-store.
|
|
|
113
112
|
import {
|
|
114
113
|
classifyKind,
|
|
115
114
|
getAttachmentById,
|
|
116
|
-
|
|
115
|
+
getAttachmentMetadataForMessages,
|
|
117
116
|
getAttachmentsByIds,
|
|
118
117
|
resolveAttachmentsForPersist,
|
|
119
118
|
} from "../../persistence/attachments-store.js";
|
|
@@ -132,6 +131,7 @@ import {
|
|
|
132
131
|
isSuppressedQueuedMessage,
|
|
133
132
|
isSystemCardMetadata,
|
|
134
133
|
type MessageRow,
|
|
134
|
+
parseMessageMetadata,
|
|
135
135
|
recordConversationPersistedSeq,
|
|
136
136
|
setConversationInferenceProfile,
|
|
137
137
|
} from "../../persistence/conversation-crud.js";
|
|
@@ -139,12 +139,18 @@ import {
|
|
|
139
139
|
getConversationByKey,
|
|
140
140
|
getOrCreateConversation,
|
|
141
141
|
} from "../../persistence/conversation-key-store.js";
|
|
142
|
+
import { listConversationModeSessionsByIds } from "../../persistence/conversation-mode-sessions.js";
|
|
142
143
|
import { searchConversations } from "../../persistence/conversation-queries.js";
|
|
143
144
|
import {
|
|
145
|
+
computerUseScreenshotAttachmentIdsFromMetadata,
|
|
144
146
|
isNoResponseMetadata,
|
|
145
147
|
messageMetadataIsAmbientSightKeep,
|
|
146
148
|
} from "../../persistence/conversation-types.js";
|
|
147
149
|
import { linkRequestLogsToMessage } from "../../persistence/llm-request-log-store.js";
|
|
150
|
+
import {
|
|
151
|
+
mergeMessageMetadata,
|
|
152
|
+
readModeSessionMetadata,
|
|
153
|
+
} from "../../persistence/message-metadata.js";
|
|
148
154
|
import { assistantTextVisibilityOf } from "../../persistence/user-facing-content.js";
|
|
149
155
|
import { MEMORY_RETROSPECTIVE_FORK_SOURCE } from "../../plugins/defaults/memory/memory-retrospective-constants.js";
|
|
150
156
|
import { normalizeOnboardingContext } from "../../prompts/normalize-onboarding.js";
|
|
@@ -879,10 +885,31 @@ function displayRowFilter(conversationId: string): (m: MessageRow) => boolean {
|
|
|
879
885
|
function consolidateDisplayTurns(rows: MessageRow[]): {
|
|
880
886
|
messages: MessageRow[];
|
|
881
887
|
mergedIdMap: Map<string, string[]>;
|
|
888
|
+
modeSessionActivityMap: Map<string, { firstAt: number; lastAt: number }>;
|
|
882
889
|
} {
|
|
883
|
-
return
|
|
884
|
-
|
|
885
|
-
|
|
890
|
+
return consolidateMessageRows(rows);
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
const MAX_REQUESTED_MODE_SESSION_IDS = 100;
|
|
894
|
+
const MAX_MODE_SESSION_ID_LENGTH = 200;
|
|
895
|
+
|
|
896
|
+
function parseRequestedModeSessionIds(raw: unknown): string[] {
|
|
897
|
+
if (raw === undefined) {
|
|
898
|
+
return [];
|
|
899
|
+
}
|
|
900
|
+
if (typeof raw !== "string") {
|
|
901
|
+
throw new BadRequestError(
|
|
902
|
+
"modeSessionIds must be a comma-separated string",
|
|
903
|
+
);
|
|
904
|
+
}
|
|
905
|
+
const ids = [...new Set(raw.split(",").map((id) => id.trim()))];
|
|
906
|
+
if (
|
|
907
|
+
ids.length > MAX_REQUESTED_MODE_SESSION_IDS ||
|
|
908
|
+
ids.some((id) => id.length === 0 || id.length > MAX_MODE_SESSION_ID_LENGTH)
|
|
909
|
+
) {
|
|
910
|
+
throw new BadRequestError("modeSessionIds contains an invalid session ID");
|
|
911
|
+
}
|
|
912
|
+
return ids;
|
|
886
913
|
}
|
|
887
914
|
|
|
888
915
|
export async function handleListMessages({
|
|
@@ -918,6 +945,9 @@ export async function handleListMessages({
|
|
|
918
945
|
const beforeTimestampRaw = queryParams?.beforeTimestamp;
|
|
919
946
|
const limitRaw = queryParams?.limit;
|
|
920
947
|
const pageRaw = queryParams?.page;
|
|
948
|
+
const requestedModeSessionIds = parseRequestedModeSessionIds(
|
|
949
|
+
queryParams?.modeSessionIds,
|
|
950
|
+
);
|
|
921
951
|
|
|
922
952
|
// Validate: reject NaN values with 400
|
|
923
953
|
if (beforeTimestampRaw != null && isNaN(Number(beforeTimestampRaw))) {
|
|
@@ -1021,8 +1051,47 @@ export async function handleListMessages({
|
|
|
1021
1051
|
// consolidation is deferred to compaction for prefix-cache stability.
|
|
1022
1052
|
// Merge here at query time so renderHistoryContent produces the same
|
|
1023
1053
|
// contentOrder shape as streaming (consecutive tool refs grouped together).
|
|
1024
|
-
const
|
|
1025
|
-
|
|
1054
|
+
const pageModeSessionIds = rawMessages.flatMap((message) => {
|
|
1055
|
+
const owner = readModeSessionMetadata(message.metadata);
|
|
1056
|
+
return owner ? [owner.id] : [];
|
|
1057
|
+
});
|
|
1058
|
+
const summaries = listConversationModeSessionsByIds(resolvedConversationId, [
|
|
1059
|
+
...new Set([...pageModeSessionIds, ...requestedModeSessionIds]),
|
|
1060
|
+
]);
|
|
1061
|
+
const validOwners = new Map(
|
|
1062
|
+
summaries.map((summary) => [summary.id, summary.mode]),
|
|
1063
|
+
);
|
|
1064
|
+
const projectionMessages = rawMessages.map((message) => {
|
|
1065
|
+
const owner = readModeSessionMetadata(message.metadata);
|
|
1066
|
+
if (!owner || validOwners.get(owner.id) === owner.mode) {
|
|
1067
|
+
return message;
|
|
1068
|
+
}
|
|
1069
|
+
return {
|
|
1070
|
+
...message,
|
|
1071
|
+
metadata: mergeMessageMetadata(message.metadata, {
|
|
1072
|
+
modeSession: undefined,
|
|
1073
|
+
}),
|
|
1074
|
+
};
|
|
1075
|
+
});
|
|
1076
|
+
const {
|
|
1077
|
+
messages: consolidatedMessages,
|
|
1078
|
+
mergedIdMap,
|
|
1079
|
+
modeSessionActivityMap,
|
|
1080
|
+
} = consolidateDisplayTurns(projectionMessages);
|
|
1081
|
+
const liveConversation = findConversation(resolvedConversationId);
|
|
1082
|
+
const modeSessions = summaries
|
|
1083
|
+
.filter(
|
|
1084
|
+
(summary) =>
|
|
1085
|
+
isModeSessionRecoveryHealthy() || summary.status !== "active",
|
|
1086
|
+
)
|
|
1087
|
+
.flatMap((summary) => {
|
|
1088
|
+
const descriptor = liveConversation?.modeSessions
|
|
1089
|
+
? liveConversation.modeSessions.describeSummary(summary)
|
|
1090
|
+
: summary.status !== "active"
|
|
1091
|
+
? { summary }
|
|
1092
|
+
: undefined;
|
|
1093
|
+
return descriptor ? [descriptor] : [];
|
|
1094
|
+
});
|
|
1026
1095
|
const assistantSlackDisplayName = getAssistantName()?.trim() || undefined;
|
|
1027
1096
|
|
|
1028
1097
|
// Parse each row's stored content and per-message metadata. Rendering is
|
|
@@ -1150,6 +1219,7 @@ export async function handleListMessages({
|
|
|
1150
1219
|
deletedAt,
|
|
1151
1220
|
clientMessageId: msg.clientMessageId ?? undefined,
|
|
1152
1221
|
assistantTextVisibility: assistantTextVisibilityOf(msg.metadata),
|
|
1222
|
+
modeSession: readModeSessionMetadata(msg.metadata),
|
|
1153
1223
|
// The row's raw stored envelope, carried to the render pass below so it
|
|
1154
1224
|
// can read the row's own `assistantTextVisibility` marker. Never part of
|
|
1155
1225
|
// the wire payload, which the serializer builds field by field.
|
|
@@ -1170,6 +1240,9 @@ export async function handleListMessages({
|
|
|
1170
1240
|
const messages: RuntimeMessagePayload[] = await Promise.all(
|
|
1171
1241
|
parsed.map(async (m) => {
|
|
1172
1242
|
const mergedMessageIds = m.id ? (mergedIdMap.get(m.id) ?? []) : [];
|
|
1243
|
+
const modeSessionActivity = m.id
|
|
1244
|
+
? modeSessionActivityMap.get(m.id)
|
|
1245
|
+
: undefined;
|
|
1173
1246
|
|
|
1174
1247
|
// Hydrate the row's attachments from the DB. A metadata-only query avoids
|
|
1175
1248
|
// loading large base64 blobs for non-image attachments (documents, audio);
|
|
@@ -1180,9 +1253,21 @@ export async function handleListMessages({
|
|
|
1180
1253
|
let msgAttachments: RuntimeAttachmentMetadata[] = [];
|
|
1181
1254
|
if (m.id) {
|
|
1182
1255
|
const idsToQuery = [m.id, ...mergedMessageIds];
|
|
1183
|
-
const
|
|
1184
|
-
|
|
1256
|
+
const linkedRows = getAttachmentMetadataForMessages(idsToQuery);
|
|
1257
|
+
const computerUseScreenshotIds = new Set(
|
|
1258
|
+
linkedRows.flatMap((row) =>
|
|
1259
|
+
computerUseScreenshotAttachmentIdsFromMetadata(
|
|
1260
|
+
parseMessageMetadata(row.messageMetadata),
|
|
1261
|
+
),
|
|
1262
|
+
),
|
|
1185
1263
|
);
|
|
1264
|
+
const linked = linkedRows.map((row) => {
|
|
1265
|
+
return {
|
|
1266
|
+
...row.attachment,
|
|
1267
|
+
computerUseScreenshot:
|
|
1268
|
+
computerUseScreenshotIds.has(row.attachment.id) || undefined,
|
|
1269
|
+
};
|
|
1270
|
+
});
|
|
1186
1271
|
if (linked.length > 0) {
|
|
1187
1272
|
msgAttachments = await Promise.all(
|
|
1188
1273
|
linked.map(async (a) => {
|
|
@@ -1221,6 +1306,9 @@ export async function handleListMessages({
|
|
|
1221
1306
|
? { thumbnailData: a.thumbnailBase64 }
|
|
1222
1307
|
: {}),
|
|
1223
1308
|
fileBacked: true,
|
|
1309
|
+
...(a.computerUseScreenshot
|
|
1310
|
+
? { computerUseScreenshot: true }
|
|
1311
|
+
: {}),
|
|
1224
1312
|
};
|
|
1225
1313
|
}),
|
|
1226
1314
|
);
|
|
@@ -1333,6 +1421,8 @@ export async function handleListMessages({
|
|
|
1333
1421
|
return {
|
|
1334
1422
|
id: m.id ?? "",
|
|
1335
1423
|
...(mergedMessageIds.length > 0 ? { mergedMessageIds } : {}),
|
|
1424
|
+
...(m.modeSession ? { modeSession: m.modeSession } : {}),
|
|
1425
|
+
...(modeSessionActivity ? { modeSessionActivity } : {}),
|
|
1336
1426
|
...(m.clientMessageId ? { clientMessageId: m.clientMessageId } : {}),
|
|
1337
1427
|
role: m.role,
|
|
1338
1428
|
timestamp: new Date(displayTimestamp).toISOString(),
|
|
@@ -1422,6 +1512,7 @@ export async function handleListMessages({
|
|
|
1422
1512
|
oldestMessageId: oldestMessageId ?? null,
|
|
1423
1513
|
seq: persistedSeq,
|
|
1424
1514
|
processing,
|
|
1515
|
+
...(modeSessions.length > 0 ? { modeSessions } : {}),
|
|
1425
1516
|
};
|
|
1426
1517
|
}
|
|
1427
1518
|
|
|
@@ -1432,10 +1523,16 @@ export async function handleListMessages({
|
|
|
1432
1523
|
...(oldestMessageId != null ? { oldestMessageId } : {}),
|
|
1433
1524
|
seq: persistedSeq,
|
|
1434
1525
|
processing,
|
|
1526
|
+
...(modeSessions.length > 0 ? { modeSessions } : {}),
|
|
1435
1527
|
};
|
|
1436
1528
|
}
|
|
1437
1529
|
|
|
1438
|
-
return {
|
|
1530
|
+
return {
|
|
1531
|
+
messages,
|
|
1532
|
+
seq: persistedSeq,
|
|
1533
|
+
processing,
|
|
1534
|
+
...(modeSessions.length > 0 ? { modeSessions } : {}),
|
|
1535
|
+
};
|
|
1439
1536
|
}
|
|
1440
1537
|
|
|
1441
1538
|
/**
|
|
@@ -2167,7 +2264,7 @@ export async function handleSendMessage(
|
|
|
2167
2264
|
publishConversationMessagesChanged(conversationId, originClientId);
|
|
2168
2265
|
},
|
|
2169
2266
|
afterRelease: () => {
|
|
2170
|
-
conversation.warmPromptCache();
|
|
2267
|
+
void conversation.warmPromptCache();
|
|
2171
2268
|
},
|
|
2172
2269
|
});
|
|
2173
2270
|
|
|
@@ -3027,6 +3124,7 @@ export async function handleSendMessage(
|
|
|
3027
3124
|
messageId,
|
|
3028
3125
|
requestId,
|
|
3029
3126
|
clientMessageId,
|
|
3127
|
+
modeSession: conversation.modeSessions.getTurnOwner(requestId),
|
|
3030
3128
|
});
|
|
3031
3129
|
// The row this echo announces was durably persisted above, so advance
|
|
3032
3130
|
// the snapshot↔stream anchor to the echo's seq (stamped inline by
|
|
@@ -3651,6 +3749,13 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
3651
3749
|
required: false,
|
|
3652
3750
|
description: "Maximum number of messages to return.",
|
|
3653
3751
|
},
|
|
3752
|
+
{
|
|
3753
|
+
name: "modeSessionIds",
|
|
3754
|
+
type: "string",
|
|
3755
|
+
required: false,
|
|
3756
|
+
description:
|
|
3757
|
+
"Comma-separated mode-session IDs to include with summaries for loaded active groups outside this page.",
|
|
3758
|
+
},
|
|
3654
3759
|
],
|
|
3655
3760
|
responseBody: z.object({
|
|
3656
3761
|
messages: z
|
|
@@ -3685,6 +3790,12 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
3685
3790
|
.describe(
|
|
3686
3791
|
"Whether the agent is currently mid-turn for this conversation, sourced authoritatively from the persisted `processing_started_at` column. `true` means a turn is in flight; `false` means the conversation is idle. Clients use this to recover from a dropped SSE stream: if a turn appears to be running locally but the server reports `processing: false`, the turn has ended (or died) and the UI should stop waiting rather than spin indefinitely. Absent on older daemons that predate this field.",
|
|
3687
3792
|
),
|
|
3793
|
+
modeSessions: z
|
|
3794
|
+
.array(ModeSessionDescriptorSchema)
|
|
3795
|
+
.optional()
|
|
3796
|
+
.describe(
|
|
3797
|
+
"Conversation-owned mode-session summaries referenced by this page or explicitly requested by ID.",
|
|
3798
|
+
),
|
|
3688
3799
|
}),
|
|
3689
3800
|
handler: (args) => handleListMessages(args),
|
|
3690
3801
|
},
|
|
@@ -177,13 +177,14 @@ async function handleCredentialPrompt({ body = {} }: RouteHandlerArgs) {
|
|
|
177
177
|
expiresAt: result.collectionExpiresAt,
|
|
178
178
|
service: validated.service,
|
|
179
179
|
field: validated.field,
|
|
180
|
-
message:
|
|
180
|
+
message: `${validated.conversationId ? "This channel does not support secure input." : "No conversation is attached to this invocation, so no secure prompt can be shown."} The credential has NOT been stored yet. Share this one-time link with the user to collect it securely (single-use${expiresInMinutes ? `, expires in ${expiresInMinutes} minutes` : ""}): ${result.collectionUrl}`,
|
|
181
181
|
};
|
|
182
182
|
}
|
|
183
183
|
return {
|
|
184
184
|
ok: false,
|
|
185
|
-
error:
|
|
186
|
-
"This conversation's channel does not support secure credential entry"
|
|
185
|
+
error: validated.conversationId
|
|
186
|
+
? "This conversation's channel does not support secure credential entry"
|
|
187
|
+
: "No conversation is attached to this invocation, so no secure prompt can be shown, and a one-time collection link could not be created. Ask the user to add the credential in the app under Settings > Credentials. Never ask them to paste it into chat.",
|
|
187
188
|
};
|
|
188
189
|
}
|
|
189
190
|
// An explicit user cancel is a valid flow, not a failure. Keep it distinct
|
|
@@ -607,8 +607,7 @@ async function handleCredentialsDelete({ body }: RouteHandlerArgs) {
|
|
|
607
607
|
}
|
|
608
608
|
|
|
609
609
|
async function handleCredentialsStatus() {
|
|
610
|
-
|
|
611
|
-
return info;
|
|
610
|
+
return getActiveBackendInfoAsync();
|
|
612
611
|
}
|
|
613
612
|
|
|
614
613
|
// ---------------------------------------------------------------------------
|