@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,6 +1,9 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import OpenAI from "openai";
|
|
4
|
+
|
|
5
|
+
import { ProviderError } from "../../../util/errors.js";
|
|
6
|
+
import { ContextOverflowError, type SendMessageOptions } from "../../types.js";
|
|
4
7
|
import { OpenAIChatCompletionsProvider } from "../chat-completions-provider.js";
|
|
5
8
|
|
|
6
9
|
class ExtraBodyProvider extends OpenAIChatCompletionsProvider {
|
|
@@ -48,4 +51,94 @@ describe("chat-completions extraBody", () => {
|
|
|
48
51
|
expect(seenParams?.directions).toEqual({ companion: 0.4 });
|
|
49
52
|
expect(seenOptions?.extraBody).toBeUndefined();
|
|
50
53
|
});
|
|
54
|
+
|
|
55
|
+
test("attaches the SDK create params as ProviderError.rawRequest on 4xx", async () => {
|
|
56
|
+
const provider = new ExtraBodyProvider("test-key", "qwen/qwen3-8b", {
|
|
57
|
+
providerName: "vellum",
|
|
58
|
+
providerLabel: "Vellum",
|
|
59
|
+
});
|
|
60
|
+
(
|
|
61
|
+
provider as unknown as {
|
|
62
|
+
client: {
|
|
63
|
+
chat: {
|
|
64
|
+
completions: {
|
|
65
|
+
create: () => Promise<AsyncIterable<unknown>>;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
).client.chat.completions.create = async () => {
|
|
71
|
+
throw new OpenAI.APIError(
|
|
72
|
+
400,
|
|
73
|
+
{ detail: "directions are not loaded" },
|
|
74
|
+
undefined,
|
|
75
|
+
new Headers(),
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
await provider.sendMessage([
|
|
81
|
+
{ role: "user", content: [{ type: "text", text: "hi" }] },
|
|
82
|
+
]);
|
|
83
|
+
throw new Error("expected ProviderError");
|
|
84
|
+
} catch (error) {
|
|
85
|
+
expect(error).toBeInstanceOf(ProviderError);
|
|
86
|
+
const rejected = error as ProviderError;
|
|
87
|
+
expect(rejected.provider).toBe("vellum");
|
|
88
|
+
expect(rejected.statusCode).toBe(400);
|
|
89
|
+
expect(rejected.rawRequest).toEqual(
|
|
90
|
+
expect.objectContaining({
|
|
91
|
+
model: "qwen/qwen3-8b",
|
|
92
|
+
directions: { companion: 0.4 },
|
|
93
|
+
}),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("attaches the SDK create params as ContextOverflowError.rawRequest", async () => {
|
|
99
|
+
const provider = new ExtraBodyProvider("test-key", "qwen/qwen3-8b", {
|
|
100
|
+
providerName: "vellum",
|
|
101
|
+
providerLabel: "Vellum",
|
|
102
|
+
});
|
|
103
|
+
(
|
|
104
|
+
provider as unknown as {
|
|
105
|
+
client: {
|
|
106
|
+
chat: {
|
|
107
|
+
completions: {
|
|
108
|
+
create: () => Promise<AsyncIterable<unknown>>;
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
).client.chat.completions.create = async () => {
|
|
114
|
+
throw new OpenAI.APIError(
|
|
115
|
+
400,
|
|
116
|
+
{
|
|
117
|
+
message:
|
|
118
|
+
"This model's maximum context length is 128000 tokens. However, your messages resulted in 150000 tokens.",
|
|
119
|
+
type: "invalid_request_error",
|
|
120
|
+
code: "context_length_exceeded",
|
|
121
|
+
},
|
|
122
|
+
undefined,
|
|
123
|
+
new Headers(),
|
|
124
|
+
);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
await provider.sendMessage([
|
|
129
|
+
{ role: "user", content: [{ type: "text", text: "hi" }] },
|
|
130
|
+
]);
|
|
131
|
+
throw new Error("expected ContextOverflowError");
|
|
132
|
+
} catch (error) {
|
|
133
|
+
expect(error).toBeInstanceOf(ContextOverflowError);
|
|
134
|
+
const rejected = error as ContextOverflowError;
|
|
135
|
+
expect(rejected.provider).toBe("vellum");
|
|
136
|
+
expect(rejected.rawRequest).toEqual(
|
|
137
|
+
expect.objectContaining({
|
|
138
|
+
model: "qwen/qwen3-8b",
|
|
139
|
+
directions: { companion: 0.4 },
|
|
140
|
+
}),
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
51
144
|
});
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
1
|
+
import { beforeEach, describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
3
|
import OpenAI from "openai";
|
|
4
4
|
|
|
5
|
+
import { ProviderError } from "../../../util/errors.js";
|
|
5
6
|
import { isPlaceholderSentinelText } from "../../placeholder-sentinels.js";
|
|
6
7
|
import {
|
|
7
8
|
EMPTY_ASSISTANT_TURN_PLACEHOLDER,
|
|
8
9
|
OpenAIChatCompletionsProvider,
|
|
9
10
|
type OpenAIChatCompletionsProviderOptions,
|
|
11
|
+
resetReasoningOptOutRejectersForTests,
|
|
10
12
|
} from "../chat-completions-provider.js";
|
|
11
13
|
|
|
12
14
|
type ReasoningDetail = {
|
|
@@ -777,6 +779,65 @@ function rejection(message: string, status = 400): Error {
|
|
|
777
779
|
}
|
|
778
780
|
|
|
779
781
|
describe("reasoning opt-out rejection fallback", () => {
|
|
782
|
+
beforeEach(() => {
|
|
783
|
+
resetReasoningOptOutRejectersForTests();
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
test("remembers a rejecting model and skips the opt-out on later requests", async () => {
|
|
787
|
+
const { provider, requests } = stubProviderWithErrors(
|
|
788
|
+
[rejection("reasoning_effort 'none' is not supported for this model")],
|
|
789
|
+
OK_CHUNKS,
|
|
790
|
+
);
|
|
791
|
+
const send = () =>
|
|
792
|
+
provider.sendMessage(
|
|
793
|
+
[{ role: "user", content: [{ type: "text", text: "hi" }] }],
|
|
794
|
+
{ config: { effort: "none" } },
|
|
795
|
+
);
|
|
796
|
+
|
|
797
|
+
await send();
|
|
798
|
+
await send();
|
|
799
|
+
|
|
800
|
+
expect(requests).toHaveLength(3);
|
|
801
|
+
expect(
|
|
802
|
+
(requests[2] as { reasoning_effort?: string }).reasoning_effort,
|
|
803
|
+
).toBeUndefined();
|
|
804
|
+
});
|
|
805
|
+
|
|
806
|
+
test("does not remember when success needed a further compat retry", async () => {
|
|
807
|
+
// The broad /reasoning/ match misreads the reasoning_content round-trip
|
|
808
|
+
// error as an opt-out rejection; the request only succeeds after the
|
|
809
|
+
// backfill retry, so the opt-out itself was never proven unsupported.
|
|
810
|
+
const { provider, requests } = stubProviderWithErrors(
|
|
811
|
+
[
|
|
812
|
+
rejection("reasoning_content must be passed back to the API"),
|
|
813
|
+
rejection("reasoning_content must be passed back to the API"),
|
|
814
|
+
],
|
|
815
|
+
OK_CHUNKS,
|
|
816
|
+
);
|
|
817
|
+
const messages = [
|
|
818
|
+
{
|
|
819
|
+
role: "user" as const,
|
|
820
|
+
content: [{ type: "text" as const, text: "hi" }],
|
|
821
|
+
},
|
|
822
|
+
{
|
|
823
|
+
role: "assistant" as const,
|
|
824
|
+
content: [{ type: "text" as const, text: "hello" }],
|
|
825
|
+
},
|
|
826
|
+
{
|
|
827
|
+
role: "user" as const,
|
|
828
|
+
content: [{ type: "text" as const, text: "again" }],
|
|
829
|
+
},
|
|
830
|
+
];
|
|
831
|
+
|
|
832
|
+
await provider.sendMessage(messages, { config: { effort: "none" } });
|
|
833
|
+
await provider.sendMessage(messages, { config: { effort: "none" } });
|
|
834
|
+
|
|
835
|
+
expect(requests).toHaveLength(4);
|
|
836
|
+
expect(
|
|
837
|
+
(requests[3] as { reasoning_effort?: string }).reasoning_effort,
|
|
838
|
+
).toBe("none");
|
|
839
|
+
});
|
|
840
|
+
|
|
780
841
|
test("retries once without reasoning params when a model rejects the explicit opt-out", async () => {
|
|
781
842
|
const { provider, requests } = stubProviderWithErrors(
|
|
782
843
|
[rejection("reasoning_effort 'none' is not supported for this model")],
|
|
@@ -928,12 +989,56 @@ describe("thinking-mode tool_choice rejection fallback", () => {
|
|
|
928
989
|
expect(first.reasoning_effort).toBe("high");
|
|
929
990
|
expect(second.tool_choice).toBeUndefined();
|
|
930
991
|
expect(second.reasoning_effort).toBe("high");
|
|
992
|
+
expect(
|
|
993
|
+
(response.rawRequest as { tool_choice?: unknown }).tool_choice,
|
|
994
|
+
).toBeUndefined();
|
|
931
995
|
const text = response.content.find((b) => b.type === "text") as
|
|
932
996
|
| { type: "text"; text: string }
|
|
933
997
|
| undefined;
|
|
934
998
|
expect(text?.text).toBe("ok");
|
|
935
999
|
});
|
|
936
1000
|
|
|
1001
|
+
test("ProviderError.rawRequest is the post-retry params when the retried call fails", async () => {
|
|
1002
|
+
const { provider } = stubProviderWithErrors(
|
|
1003
|
+
[
|
|
1004
|
+
rejection("Thinking mode does not support this tool_choice"),
|
|
1005
|
+
Object.assign(
|
|
1006
|
+
new Error("Thinking mode does not support this tool_choice"),
|
|
1007
|
+
{ status: 400 },
|
|
1008
|
+
),
|
|
1009
|
+
],
|
|
1010
|
+
OK_CHUNKS,
|
|
1011
|
+
);
|
|
1012
|
+
|
|
1013
|
+
try {
|
|
1014
|
+
await provider.sendMessage(
|
|
1015
|
+
[{ role: "user", content: [{ type: "text", text: "hi" }] }],
|
|
1016
|
+
{
|
|
1017
|
+
tools: [
|
|
1018
|
+
{
|
|
1019
|
+
name: "bash",
|
|
1020
|
+
description: "Run a shell command",
|
|
1021
|
+
input_schema: { type: "object", properties: {} },
|
|
1022
|
+
},
|
|
1023
|
+
],
|
|
1024
|
+
config: { tool_choice: { type: "none" }, effort: "high" },
|
|
1025
|
+
},
|
|
1026
|
+
);
|
|
1027
|
+
throw new Error("expected ProviderError");
|
|
1028
|
+
} catch (error) {
|
|
1029
|
+
expect(error).toBeInstanceOf(ProviderError);
|
|
1030
|
+
const rejected = error as ProviderError;
|
|
1031
|
+
expect(
|
|
1032
|
+
(rejected.rawRequest as { tool_choice?: unknown } | undefined)
|
|
1033
|
+
?.tool_choice,
|
|
1034
|
+
).toBeUndefined();
|
|
1035
|
+
expect(
|
|
1036
|
+
(rejected.rawRequest as { reasoning_effort?: string } | undefined)
|
|
1037
|
+
?.reasoning_effort,
|
|
1038
|
+
).toBe("high");
|
|
1039
|
+
}
|
|
1040
|
+
});
|
|
1041
|
+
|
|
937
1042
|
test("retries once when Kimi rejects a specified tool_choice in thinking mode", async () => {
|
|
938
1043
|
const { provider, requests } = stubProviderWithErrors(
|
|
939
1044
|
[
|
|
@@ -57,6 +57,10 @@ function stubProviderWithErrors(errors: unknown[]): {
|
|
|
57
57
|
const CHAT_TEMPLATE_400 =
|
|
58
58
|
"Failed to apply chat template: invalid operation: object is not callable (in chat:22)";
|
|
59
59
|
|
|
60
|
+
// Fireworks' renderer error for DeepSeek, verbatim.
|
|
61
|
+
const FIREWORKS_STR_JOIN_400 =
|
|
62
|
+
"sequence item 0: expected str instance, list found";
|
|
63
|
+
|
|
60
64
|
function rejection(message: string, status = 400): Error {
|
|
61
65
|
return Object.assign(new Error(message), { status });
|
|
62
66
|
}
|
|
@@ -103,6 +107,26 @@ describe("chat-template rejection flatten fallback", () => {
|
|
|
103
107
|
expect(text?.text).toBe("ok");
|
|
104
108
|
});
|
|
105
109
|
|
|
110
|
+
test("retries with flattened content on Fireworks' str-join template error", async () => {
|
|
111
|
+
const { provider, requests } = stubProviderWithErrors([
|
|
112
|
+
rejection(FIREWORKS_STR_JOIN_400),
|
|
113
|
+
]);
|
|
114
|
+
|
|
115
|
+
await provider.sendMessage([
|
|
116
|
+
{
|
|
117
|
+
role: "user",
|
|
118
|
+
content: [
|
|
119
|
+
{ type: "text", text: "[Image: a cat]" },
|
|
120
|
+
{ type: "text", text: "what is this?" },
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
]);
|
|
124
|
+
|
|
125
|
+
expect(requests).toHaveLength(2);
|
|
126
|
+
const retry = requests[1] as { messages: Array<{ content: unknown }> };
|
|
127
|
+
expect(retry.messages[0].content).toBe("[Image: a cat]\n\nwhat is this?");
|
|
128
|
+
});
|
|
129
|
+
|
|
106
130
|
test("does not retry when a content-parts array carries media (never silently drop an image)", async () => {
|
|
107
131
|
// GIVEN an endpoint whose chat template 400s on structured message content
|
|
108
132
|
const { provider, requests } = stubProviderWithErrors([
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
attachGoogleThoughtSignature,
|
|
8
8
|
attachGoogleThoughtSignatureIfNeeded,
|
|
9
9
|
backfillGoogleThoughtSignatures,
|
|
10
|
-
backfillUnsignedGoogleThoughtSignatures,
|
|
11
10
|
geminiThoughtSignaturesByToolCallId,
|
|
12
11
|
googleThoughtSignatureFromUnknown,
|
|
13
12
|
type GoogleToolCallExtraContent,
|
|
@@ -177,7 +176,7 @@ describe("thought signature params helpers", () => {
|
|
|
177
176
|
|
|
178
177
|
test("backfills the dummy signature onto unsigned tool_calls", () => {
|
|
179
178
|
const params = structuredClone(unsignedParams);
|
|
180
|
-
expect(
|
|
179
|
+
expect(backfillGoogleThoughtSignatures(params)).toBe(true);
|
|
181
180
|
expect(messagesCarryGoogleThoughtSignature(params)).toBe(true);
|
|
182
181
|
expect(
|
|
183
182
|
params.messages[0].tool_calls[0].extra_content?.google?.thought_signature,
|
|
@@ -355,6 +355,41 @@ function protectJsonSchemaToolResult(payload: string): string {
|
|
|
355
355
|
: payload;
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
+
function carriesReasoningOptOut(params: unknown): boolean {
|
|
359
|
+
const p = params as {
|
|
360
|
+
reasoning_effort?: unknown;
|
|
361
|
+
reasoning?: { effort?: unknown } | null;
|
|
362
|
+
};
|
|
363
|
+
return (
|
|
364
|
+
p.reasoning_effort === "none" ||
|
|
365
|
+
(typeof p.reasoning === "object" &&
|
|
366
|
+
p.reasoning !== null &&
|
|
367
|
+
p.reasoning.effort === "none")
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function stripReasoningParams(params: unknown): void {
|
|
372
|
+
const p = params as Record<string, unknown>;
|
|
373
|
+
delete p.reasoning_effort;
|
|
374
|
+
delete p.reasoning;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* `baseURL|model|routing` keys whose request succeeded on the attempt directly
|
|
379
|
+
* after the opt-out was stripped. Later requests skip the opt-out up front
|
|
380
|
+
* instead of paying a rejected round-trip on every call. A success that needed
|
|
381
|
+
* a further compat retry proves nothing about the opt-out, so it is not
|
|
382
|
+
* recorded. Routing (OpenRouter's `provider` body field) is part of the key
|
|
383
|
+
* because opt-out support belongs to the upstream backend, not the model slug.
|
|
384
|
+
* Process-lifetime only: a restart re-learns with one rejected request per key.
|
|
385
|
+
*/
|
|
386
|
+
const reasoningOptOutRejecters = new Set<string>();
|
|
387
|
+
|
|
388
|
+
/** Test-only: forget learned reasoning opt-out rejections. */
|
|
389
|
+
export function resetReasoningOptOutRejectersForTests(): void {
|
|
390
|
+
reasoningOptOutRejecters.clear();
|
|
391
|
+
}
|
|
392
|
+
|
|
358
393
|
/**
|
|
359
394
|
* True when the request carried an explicit reasoning opt-out (`"none"` sent
|
|
360
395
|
* as flat `reasoning_effort` or nested `reasoning.effort`) and the provider
|
|
@@ -364,16 +399,7 @@ function protectJsonSchemaToolResult(payload: string): string {
|
|
|
364
399
|
* model-default reasoning beats a hard failure.
|
|
365
400
|
*/
|
|
366
401
|
function isReasoningOptOutRejection(error: unknown, params: unknown): boolean {
|
|
367
|
-
|
|
368
|
-
reasoning_effort?: unknown;
|
|
369
|
-
reasoning?: { effort?: unknown } | null;
|
|
370
|
-
};
|
|
371
|
-
const optedOut =
|
|
372
|
-
p.reasoning_effort === "none" ||
|
|
373
|
-
(typeof p.reasoning === "object" &&
|
|
374
|
-
p.reasoning !== null &&
|
|
375
|
-
p.reasoning.effort === "none");
|
|
376
|
-
if (!optedOut) {
|
|
402
|
+
if (!carriesReasoningOptOut(params)) {
|
|
377
403
|
return false;
|
|
378
404
|
}
|
|
379
405
|
if (!isClientErrorStatus(error)) {
|
|
@@ -685,10 +711,7 @@ function classifyOpenAICompatRetry(
|
|
|
685
711
|
kind: "reasoning-opt-out",
|
|
686
712
|
message:
|
|
687
713
|
"Model rejected the explicit reasoning opt-out; retrying without reasoning params",
|
|
688
|
-
apply: () =>
|
|
689
|
-
delete params.reasoning_effort;
|
|
690
|
-
delete (params as unknown as Record<string, unknown>).reasoning;
|
|
691
|
-
},
|
|
714
|
+
apply: () => stripReasoningParams(params),
|
|
692
715
|
};
|
|
693
716
|
}
|
|
694
717
|
if (isThinkingModeToolChoiceRejection(error, params)) {
|
|
@@ -788,6 +811,24 @@ const OPENAI_SUPPORTED_IMAGE_TYPES = new Set([
|
|
|
788
811
|
"image/webp",
|
|
789
812
|
]);
|
|
790
813
|
|
|
814
|
+
/**
|
|
815
|
+
* Persistable view of the chat.completions create params. A `logit_bias`
|
|
816
|
+
* preset (e.g. `suppress-cjk`) is ~5.3k deterministic entries (~68KB);
|
|
817
|
+
* summarize it so inspector rows don't balloon. The full map still went
|
|
818
|
+
* out on the wire.
|
|
819
|
+
*/
|
|
820
|
+
function inspectableChatCompletionsRequest(
|
|
821
|
+
params: OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming,
|
|
822
|
+
): unknown {
|
|
823
|
+
if (!params.logit_bias) {
|
|
824
|
+
return params;
|
|
825
|
+
}
|
|
826
|
+
return {
|
|
827
|
+
...params,
|
|
828
|
+
logit_bias: `<${Object.keys(params.logit_bias).length} token biases omitted>`,
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
|
|
791
832
|
// Think-tag scanning primitives are shared with the TTS reasoning filter
|
|
792
833
|
// (util/think-tag-stream.ts) so the two stream parsers cannot drift. This
|
|
793
834
|
// provider keeps its exact historical behavior: case-sensitive, <think> only.
|
|
@@ -883,6 +924,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
883
924
|
// wire, to be decoded back on the response. Empty unless
|
|
884
925
|
// `coerceObjectArgsToJsonString` is enabled.
|
|
885
926
|
const coercedObjectKeys = new Map<string, string[]>();
|
|
927
|
+
let inspectableRequest: unknown | undefined;
|
|
886
928
|
|
|
887
929
|
try {
|
|
888
930
|
const thoughtSignaturesByCallId =
|
|
@@ -1125,18 +1167,35 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1125
1167
|
if (extraBody) {
|
|
1126
1168
|
Object.assign(params, extraBody);
|
|
1127
1169
|
}
|
|
1128
|
-
const
|
|
1129
|
-
|
|
1170
|
+
const optOutKey = `${this.client.baseURL}|${params.model}|${JSON.stringify(
|
|
1171
|
+
(params as { provider?: unknown }).provider ?? null,
|
|
1172
|
+
)}`;
|
|
1173
|
+
if (
|
|
1174
|
+
reasoningOptOutRejecters.has(optOutKey) &&
|
|
1175
|
+
carriesReasoningOptOut(params)
|
|
1176
|
+
) {
|
|
1177
|
+
stripReasoningParams(params);
|
|
1178
|
+
}
|
|
1179
|
+
const createStream = () => {
|
|
1180
|
+
// Snapshot after extra-body merge and any in-place compat retries
|
|
1181
|
+
// so inspector rows match the params that actually went on the wire.
|
|
1182
|
+
inspectableRequest = inspectableChatCompletionsRequest(params);
|
|
1183
|
+
return this.client.chat.completions.create(params, {
|
|
1130
1184
|
signal: timeoutSignal,
|
|
1131
1185
|
...(Object.keys(requestHeaders).length > 0
|
|
1132
1186
|
? { headers: requestHeaders }
|
|
1133
1187
|
: {}),
|
|
1134
1188
|
});
|
|
1189
|
+
};
|
|
1135
1190
|
const attemptedCompatRetries = new Set<OpenAICompatRetryKind>();
|
|
1191
|
+
let lastCompatRetry: OpenAICompatRetryKind | undefined;
|
|
1136
1192
|
let stream: Awaited<ReturnType<typeof createStream>>;
|
|
1137
1193
|
for (;;) {
|
|
1138
1194
|
try {
|
|
1139
1195
|
stream = await createStream();
|
|
1196
|
+
if (lastCompatRetry === "reasoning-opt-out") {
|
|
1197
|
+
reasoningOptOutRejecters.add(optOutKey);
|
|
1198
|
+
}
|
|
1140
1199
|
break;
|
|
1141
1200
|
} catch (error) {
|
|
1142
1201
|
const retry = classifyOpenAICompatRetry(
|
|
@@ -1148,6 +1207,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1148
1207
|
throw error;
|
|
1149
1208
|
}
|
|
1150
1209
|
attemptedCompatRetries.add(retry.kind);
|
|
1210
|
+
lastCompatRetry = retry.kind;
|
|
1151
1211
|
log.warn(
|
|
1152
1212
|
{
|
|
1153
1213
|
provider: this.name,
|
|
@@ -1447,15 +1507,9 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1447
1507
|
},
|
|
1448
1508
|
stopReason: finishReason,
|
|
1449
1509
|
// `rawRequest` is persisted to the request-log DB and inspector on every
|
|
1450
|
-
// call. A `logit_bias` preset
|
|
1451
|
-
//
|
|
1452
|
-
|
|
1453
|
-
rawRequest: params.logit_bias
|
|
1454
|
-
? {
|
|
1455
|
-
...params,
|
|
1456
|
-
logit_bias: `<${Object.keys(params.logit_bias).length} token biases omitted>`,
|
|
1457
|
-
}
|
|
1458
|
-
: params,
|
|
1510
|
+
// call, including 4xx throws below. A `logit_bias` preset is summarized
|
|
1511
|
+
// so logs don't balloon. The full map still went out on the wire above.
|
|
1512
|
+
rawRequest: inspectableRequest,
|
|
1459
1513
|
rawResponse,
|
|
1460
1514
|
};
|
|
1461
1515
|
} catch (error) {
|
|
@@ -1482,6 +1536,9 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1482
1536
|
maxTokens: overflow.maxTokens,
|
|
1483
1537
|
statusCode: error.status,
|
|
1484
1538
|
cause: error,
|
|
1539
|
+
...(inspectableRequest !== undefined
|
|
1540
|
+
? { rawRequest: inspectableRequest }
|
|
1541
|
+
: {}),
|
|
1485
1542
|
});
|
|
1486
1543
|
}
|
|
1487
1544
|
if (detectVisionNotSupported(error, normalized.message)) {
|
|
@@ -1492,9 +1549,13 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1492
1549
|
error.status,
|
|
1493
1550
|
// Stamp the reason so classification is status-independent (a vision
|
|
1494
1551
|
// rejection returned as 401/403 must not read as an invalid key).
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1552
|
+
{
|
|
1553
|
+
reason: "vision_unsupported" as const,
|
|
1554
|
+
...(abortReason ? { abortReason } : {}),
|
|
1555
|
+
...(inspectableRequest !== undefined
|
|
1556
|
+
? { rawRequest: inspectableRequest }
|
|
1557
|
+
: {}),
|
|
1558
|
+
},
|
|
1498
1559
|
);
|
|
1499
1560
|
}
|
|
1500
1561
|
const retryAfterMs = extractRetryAfterMs(error.headers);
|
|
@@ -1509,6 +1570,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1509
1570
|
apiErrorParam?: string;
|
|
1510
1571
|
requestId?: string;
|
|
1511
1572
|
rawBody?: string;
|
|
1573
|
+
rawRequest?: unknown;
|
|
1512
1574
|
reason?: ProviderErrorReason;
|
|
1513
1575
|
} = { cause: error };
|
|
1514
1576
|
if (retryAfterMs !== undefined) {
|
|
@@ -1535,6 +1597,9 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1535
1597
|
if (normalized.reason) {
|
|
1536
1598
|
errorOptions.reason = normalized.reason;
|
|
1537
1599
|
}
|
|
1600
|
+
if (inspectableRequest !== undefined) {
|
|
1601
|
+
errorOptions.rawRequest = inspectableRequest;
|
|
1602
|
+
}
|
|
1538
1603
|
throw new ProviderError(
|
|
1539
1604
|
formattedMessage,
|
|
1540
1605
|
this.name,
|
|
@@ -1548,7 +1613,13 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1548
1613
|
}`,
|
|
1549
1614
|
this.name,
|
|
1550
1615
|
undefined,
|
|
1551
|
-
|
|
1616
|
+
{
|
|
1617
|
+
cause: error,
|
|
1618
|
+
...(abortReason ? { abortReason } : {}),
|
|
1619
|
+
...(inspectableRequest !== undefined
|
|
1620
|
+
? { rawRequest: inspectableRequest }
|
|
1621
|
+
: {}),
|
|
1622
|
+
},
|
|
1552
1623
|
);
|
|
1553
1624
|
}
|
|
1554
1625
|
}
|
|
@@ -266,12 +266,6 @@ export function backfillGoogleThoughtSignatures(
|
|
|
266
266
|
return added;
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
-
export function backfillUnsignedGoogleThoughtSignatures(
|
|
270
|
-
params: unknown,
|
|
271
|
-
): boolean {
|
|
272
|
-
return backfillGoogleThoughtSignatures(params);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
269
|
const UNKNOWN_EXTRA_CONTENT_REJECTION =
|
|
276
270
|
/unknown|unexpected|unrecognized|additional propert|extra (?:field|property)|not (?:a )?valid|invalid (?:argument|parameter|field|property)/i;
|
|
277
271
|
|
|
@@ -294,6 +294,7 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
294
294
|
configObj.promptCacheKey.length > 0
|
|
295
295
|
? (configObj.promptCacheKey as string)
|
|
296
296
|
: undefined;
|
|
297
|
+
let inspectableRequest: unknown | undefined;
|
|
297
298
|
|
|
298
299
|
try {
|
|
299
300
|
const effectiveModel = modelOverride ?? this.model;
|
|
@@ -428,6 +429,7 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
428
429
|
}
|
|
429
430
|
|
|
430
431
|
Object.assign(params, this.buildExtraCreateParams(options));
|
|
432
|
+
inspectableRequest = params;
|
|
431
433
|
|
|
432
434
|
const { signal: timeoutSignal, cleanup: cleanupTimeout } =
|
|
433
435
|
createStreamTimeout(this.streamTimeoutMs, signal);
|
|
@@ -736,6 +738,9 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
736
738
|
maxTokens: overflow.maxTokens,
|
|
737
739
|
statusCode: error.status,
|
|
738
740
|
cause: error,
|
|
741
|
+
...(inspectableRequest !== undefined
|
|
742
|
+
? { rawRequest: inspectableRequest }
|
|
743
|
+
: {}),
|
|
739
744
|
});
|
|
740
745
|
}
|
|
741
746
|
const retryAfterMs = extractRetryAfterMs(error.headers);
|
|
@@ -750,6 +755,7 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
750
755
|
apiErrorParam?: string;
|
|
751
756
|
requestId?: string;
|
|
752
757
|
rawBody?: string;
|
|
758
|
+
rawRequest?: unknown;
|
|
753
759
|
reason?: ProviderErrorReason;
|
|
754
760
|
} = { cause: error };
|
|
755
761
|
if (retryAfterMs !== undefined) {
|
|
@@ -776,6 +782,9 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
776
782
|
if (normalized.reason) {
|
|
777
783
|
errorOptions.reason = normalized.reason;
|
|
778
784
|
}
|
|
785
|
+
if (inspectableRequest !== undefined) {
|
|
786
|
+
errorOptions.rawRequest = inspectableRequest;
|
|
787
|
+
}
|
|
779
788
|
throw new ProviderError(
|
|
780
789
|
formattedMessage,
|
|
781
790
|
this.name,
|
|
@@ -789,7 +798,20 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
789
798
|
}`,
|
|
790
799
|
this.name,
|
|
791
800
|
undefined,
|
|
792
|
-
abortReason
|
|
801
|
+
abortReason
|
|
802
|
+
? {
|
|
803
|
+
cause: error,
|
|
804
|
+
abortReason,
|
|
805
|
+
...(inspectableRequest !== undefined
|
|
806
|
+
? { rawRequest: inspectableRequest }
|
|
807
|
+
: {}),
|
|
808
|
+
}
|
|
809
|
+
: {
|
|
810
|
+
cause: error,
|
|
811
|
+
...(inspectableRequest !== undefined
|
|
812
|
+
? { rawRequest: inspectableRequest }
|
|
813
|
+
: {}),
|
|
814
|
+
},
|
|
793
815
|
);
|
|
794
816
|
}
|
|
795
817
|
}
|
|
@@ -62,9 +62,7 @@ export class RateLimitProvider implements Provider {
|
|
|
62
62
|
// calls from bypassing the rate limit during the async gap.
|
|
63
63
|
this.recordRequest();
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return response;
|
|
65
|
+
return this.inner.sendMessage(messages, options);
|
|
68
66
|
}
|
|
69
67
|
|
|
70
68
|
private enforceRequestRate(): void {
|
|
@@ -163,6 +163,30 @@ export const SEARCH_PROVIDER_CATALOG: readonly SearchProviderCatalogEntry[] = [
|
|
|
163
163
|
supportsApiBase: true,
|
|
164
164
|
defaultApiBase: "https://api.fastcrw.com",
|
|
165
165
|
},
|
|
166
|
+
{
|
|
167
|
+
id: "searxng",
|
|
168
|
+
displayName: "SearXNG",
|
|
169
|
+
kind: "byok",
|
|
170
|
+
keyless: true,
|
|
171
|
+
apiKeyPrefix: "token (optional)",
|
|
172
|
+
envVar: "SEARXNG_API_KEY",
|
|
173
|
+
secretKey: "searxng",
|
|
174
|
+
fallbackOrder: 7,
|
|
175
|
+
privacyPolicyUrl: "https://docs.searxng.org/own-instance.html",
|
|
176
|
+
supportsApiBase: true,
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
id: "tinyfish",
|
|
180
|
+
displayName: "TinyFish",
|
|
181
|
+
kind: "byok",
|
|
182
|
+
apiKeyPrefix: "TinyFish API key...",
|
|
183
|
+
envVar: "TINYFISH_API_KEY",
|
|
184
|
+
secretKey: "tinyfish",
|
|
185
|
+
fallbackOrder: 8,
|
|
186
|
+
privacyPolicyUrl: "https://www.tinyfish.ai/privacy-policy",
|
|
187
|
+
supportsApiBase: true,
|
|
188
|
+
defaultApiBase: "https://api.search.tinyfish.ai",
|
|
189
|
+
},
|
|
166
190
|
];
|
|
167
191
|
|
|
168
192
|
/** Provider ids accepted by the web-search config schema. */
|