@vellumai/assistant 0.12.1 → 0.12.2-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/AGENTS.md +4 -0
- package/ARCHITECTURE.md +20 -21
- package/docs/architecture/turn-actor.md +15 -8
- package/docs/guardian-request-flow.md +16 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +13 -8
- package/node_modules/@vellumai/slack-text/src/label-resolution-entities.test.ts +95 -0
- package/openapi.yaml +360 -51
- package/package.json +3 -1
- package/scripts/smoke-desktop-window-theme.ts +186 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +18 -10
- package/src/__tests__/anthropic-provider.test.ts +0 -63
- package/src/__tests__/app-compiler.test.ts +6 -0
- package/src/__tests__/app-control-tool-schemas.test.ts +5 -2
- package/src/__tests__/app-dir-path-guard.test.ts +1 -3
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +6 -7
- package/src/__tests__/assistant-event-hub.test.ts +44 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
- package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +5 -2
- package/src/__tests__/computer-use-tools.test.ts +19 -7
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +28 -29
- package/src/__tests__/config-watcher.test.ts +23 -8
- package/src/__tests__/connection-model-compat.test.ts +2 -2
- package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-pairing.test.ts +26 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -10
- package/src/__tests__/conversation-queue.test.ts +48 -207
- package/src/__tests__/conversation-retry-discard.test.ts +54 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +28 -0
- package/src/__tests__/conversation-skill-tools.test.ts +27 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +8 -3
- package/src/__tests__/conversation-surfaces-point-at-budget.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-point-at-capability.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +67 -0
- package/src/__tests__/conversation-title-service.test.ts +14 -10
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +3 -5
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +51 -0
- package/src/__tests__/credential-record-retire.test.ts +171 -1
- package/src/__tests__/credential-routes.test.ts +250 -3
- package/src/__tests__/credential-security-invariants.test.ts +5 -3
- package/src/__tests__/cu-unified-flow.test.ts +14 -4
- package/src/__tests__/document-sync-tags.test.ts +25 -0
- package/src/__tests__/drain-kick-guard.test.ts +0 -2
- package/src/__tests__/drain-requeue-on-contention.test.ts +0 -6
- package/src/__tests__/evict-conversations-for-reload.test.ts +1 -1
- package/src/__tests__/git-porcelain.test.ts +47 -0
- package/src/__tests__/heartbeat-service.test.ts +56 -40
- package/src/__tests__/helpers/set-workspace-mcp.ts +11 -0
- package/src/__tests__/host-bash-proxy.test.ts +26 -45
- package/src/__tests__/host-browser-proxy.test.ts +6 -17
- package/src/__tests__/host-cu-proxy.test.ts +596 -0
- package/src/__tests__/host-file-proxy-targeted.test.ts +23 -0
- package/src/__tests__/host-file-proxy.test.ts +11 -23
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +30 -9
- package/src/__tests__/list-messages-camera-frame.test.ts +121 -0
- package/src/__tests__/llm-catalog-parity.test.ts +25 -0
- package/src/__tests__/mcp-auth-routes.test.ts +6 -9
- package/src/__tests__/mcp-config-secret-boundary.test.ts +78 -136
- package/src/__tests__/mcp-health-check.test.ts +8 -11
- package/src/__tests__/mcp-list-plugin-servers.test.ts +8 -10
- package/src/__tests__/message-deleted-hook-dispatch.test.ts +119 -0
- package/src/__tests__/messages-after-tiebreaker.test.ts +91 -0
- package/src/__tests__/messages-read-boundary-guard.test.ts +1 -1
- package/src/__tests__/messaging-send-tool.test.ts +355 -548
- package/src/__tests__/model-intents.test.ts +3 -0
- package/src/__tests__/notification-vellum-adapter.test.ts +85 -2
- package/src/__tests__/oauth-commands-routes.test.ts +168 -0
- package/src/__tests__/oauth-provider-profiles.test.ts +18 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +22 -0
- package/src/__tests__/oauth-providers-routes.test.ts +1 -0
- package/src/__tests__/openai-provider.test.ts +1 -0
- package/src/__tests__/outlook-messaging-provider.test.ts +6 -6
- package/src/__tests__/platform-callback-registration.test.ts +8 -16
- package/src/__tests__/platform-client-verify-credential.test.ts +2 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +14 -0
- package/src/__tests__/qdrant-manager.test.ts +132 -0
- package/src/__tests__/resolve-app.test.ts +135 -0
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +229 -6
- package/src/__tests__/script-proxy-certs.test.ts +35 -0
- package/src/__tests__/secret-routes-acp-guard.test.ts +59 -1
- package/src/__tests__/service-account-token.test.ts +247 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +1 -1
- package/src/__tests__/skill-feature-flags.test.ts +2 -2
- package/src/__tests__/skills.test.ts +9 -4
- package/src/__tests__/source-fingerprint.test.ts +184 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +70 -3
- package/src/__tests__/subagent-tools.test.ts +3 -2
- package/src/__tests__/telephony-tts-guard.test.ts +38 -3
- package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
- package/src/__tests__/ui-channel-variants.test.ts +1 -56
- package/src/__tests__/unicode.test.ts +13 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +4 -0
- package/src/__tests__/watch-retro-tool-availability.test.ts +8 -17
- package/src/__tests__/workspace-git-service.test.ts +26 -0
- package/src/__tests__/workspace-migration-154-repair-retired-codex-gpt-5-4-model-ids.test.ts +336 -0
- package/src/acp/__tests__/acp-claude-oauth.test.ts +257 -6
- package/src/acp/__tests__/acp-credentials.test.ts +13 -0
- package/src/acp/__tests__/agent-process.test.ts +258 -4
- package/src/acp/__tests__/auth-required.test.ts +96 -0
- package/src/acp/__tests__/claude-token-refresh.test.ts +257 -0
- package/src/acp/__tests__/client-handler.test.ts +90 -2
- package/src/acp/__tests__/helpers/acp-model-option.ts +51 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +60 -1
- package/src/acp/__tests__/session-manager-persistence.test.ts +5 -1
- package/src/acp/__tests__/session-manager-resume.test.ts +270 -6
- package/src/acp/__tests__/session-manager-usage.test.ts +4 -2
- package/src/acp/__tests__/session-manager.test.ts +895 -4
- package/src/acp/acp-claude-oauth.ts +328 -14
- package/src/acp/acp-credentials.ts +19 -0
- package/src/acp/agent-process.test.ts +4 -1
- package/src/acp/agent-process.ts +96 -10
- package/src/acp/auth-required.ts +50 -1
- package/src/acp/auto-install.test.ts +9 -7
- package/src/acp/claude-token-refresh.ts +150 -0
- package/src/acp/client-handler.ts +16 -3
- package/src/acp/model-config.test.ts +166 -0
- package/src/acp/model-config.ts +138 -0
- package/src/acp/prepare-agent-env.ts +21 -6
- package/src/acp/resolve-agent.test.ts +220 -6
- package/src/acp/resolve-agent.ts +88 -23
- package/src/acp/session-manager.test.ts +196 -3
- package/src/acp/session-manager.ts +441 -18
- package/src/acp/types.ts +50 -5
- package/src/agent/loop.ts +1 -0
- package/src/api/events/acp-session-model-update.test.ts +88 -0
- package/src/api/events/acp-session-model-update.ts +46 -0
- package/src/api/events/app-files-changed.ts +4 -3
- package/src/api/events/notification-intent.ts +2 -0
- package/src/api/events/user-message-echo.ts +7 -1
- package/src/api/index.ts +6 -0
- package/src/api/responses/conversation-message.ts +5 -0
- package/src/apps/app-store.ts +1 -1
- package/src/apps/resolve-app.ts +81 -0
- package/src/apps/source-fingerprint.ts +266 -0
- package/src/avatar/identity-avatar.ts +7 -2
- package/src/bundler/app-compiler.ts +15 -0
- package/src/calls/__tests__/barge-in-guard.test.ts +81 -0
- package/src/{__tests__ → calls/__tests__}/call-controller.test.ts +503 -82
- package/src/{__tests__ → calls/__tests__}/media-stream-audio-transcode.test.ts +1 -1
- package/src/{__tests__ → calls/__tests__}/media-stream-output.test.ts +37 -8
- package/src/{__tests__ → calls/__tests__}/media-stream-parser.test.ts +1 -1
- package/src/{__tests__ → calls/__tests__}/media-stream-server-integration.test.ts +150 -57
- package/src/{__tests__ → calls/__tests__}/media-stream-stt-session.test.ts +5 -5
- package/src/{__tests__ → calls/__tests__}/media-turn-detector.test.ts +1 -1
- package/src/{live-voice → calls}/__tests__/progress-narration.test.ts +4 -4
- package/src/{live-voice → calls}/__tests__/progress-phrases.test.ts +1 -1
- package/src/calls/__tests__/voice-control-protocol.test.ts +120 -25
- package/src/calls/__tests__/voice-leg-coordinator.test.ts +229 -0
- package/src/calls/__tests__/voice-progress-cadence.test.ts +274 -0
- package/src/{__tests__/voice-session-bridge.test.ts → calls/__tests__/voice-session-bridge-turn-flow.test.ts} +20 -12
- package/src/calls/__tests__/voice-session-bridge.test.ts +56 -1
- package/src/calls/__tests__/voice-triage-escalate.test.ts +105 -0
- package/src/calls/barge-in-guard.ts +118 -0
- package/src/calls/call-constants.ts +24 -4
- package/src/calls/call-controller.ts +499 -199
- package/src/calls/call-transport.ts +16 -0
- package/src/calls/media-stream-output.ts +32 -0
- package/src/calls/media-stream-server.ts +82 -30
- package/src/calls/media-stream-stt-session.ts +15 -0
- package/src/{live-voice → calls}/progress-narration.ts +2 -2
- package/src/calls/resolve-call-tts-provider.ts +33 -2
- package/src/calls/tts-call-strategy.ts +9 -5
- package/src/calls/types.ts +2 -0
- package/src/calls/voice-control-protocol.ts +155 -21
- package/src/calls/voice-leg-coordinator.ts +189 -0
- package/src/calls/voice-progress-cadence.ts +423 -0
- package/src/calls/voice-session-bridge.ts +92 -72
- package/src/calls/voice-triage-escalate.ts +178 -59
- package/src/cli/commands/__tests__/apps.test.ts +245 -0
- package/src/cli/commands/__tests__/bash.test.ts +53 -0
- package/src/cli/commands/__tests__/roadmap.help.test.ts +19 -0
- package/src/cli/commands/apps.help.ts +67 -13
- package/src/cli/commands/apps.ts +183 -0
- package/src/cli/commands/bash.help.ts +8 -13
- package/src/cli/commands/bash.ts +7 -25
- package/src/cli/commands/channels/__tests__/send.test.ts +218 -0
- package/src/cli/commands/channels/index.help.ts +70 -2
- package/src/cli/commands/channels/index.ts +16 -3
- package/src/cli/commands/channels/send.ts +128 -0
- package/src/cli/commands/credentials.help.ts +6 -2
- package/src/cli/commands/credentials.ts +2 -2
- package/src/cli/commands/mcp.help.ts +8 -8
- package/src/cli/commands/mcp.ts +1 -1
- package/src/cli/commands/oauth/status.ts +5 -0
- package/src/cli/commands/roadmap.help.ts +5 -1
- package/src/cli/commands/roadmap.ts +1 -1
- package/src/cli/lib/bundled-marketplace.json +103 -90
- package/src/config/__tests__/default-profile-catalog.test.ts +22 -0
- package/src/config/__tests__/memory-retrospective-schema.test.ts +15 -1
- package/src/config/__tests__/platform-identity.test.ts +255 -0
- package/src/config/__tests__/platform-rehydration.test.ts +99 -9
- package/src/config/acp-agent-write.ts +43 -0
- package/src/config/acp-defaults.test.ts +13 -3
- package/src/config/acp-defaults.ts +23 -6
- package/src/config/acp-schema.test.ts +81 -0
- package/src/config/acp-schema.ts +30 -2
- package/src/config/bundled-skills/acp/SKILL.md +22 -14
- package/src/config/bundled-skills/acp/TOOLS.json +5 -1
- package/src/config/bundled-skills/app-builder/SKILL.md +12 -9
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +1 -1
- package/src/config/bundled-skills/computer-use/SKILL.md +29 -2
- package/src/config/bundled-skills/computer-use/TOOLS.json +99 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-sequence.ts +12 -0
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +2 -1
- package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +2 -1
- package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +2 -1
- package/src/config/bundled-skills/messaging/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/TOOLS.json +3 -3
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +67 -139
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +1 -1
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -1
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -1
- package/src/config/bundled-skills/schedule/SKILL.md +3 -4
- package/src/config/bundled-skills/screen-annotation/SKILL.md +8 -1
- package/src/config/bundled-skills/screen-annotation/tools/screen-annotation.test.ts +4 -1
- package/src/config/bundled-skills/skill-management/TOOLS.json +6 -2
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +5 -2
- package/src/config/default-profile-catalog.ts +1 -1
- package/src/config/env.ts +2 -2
- package/src/config/feature-flag-registry.json +33 -13
- package/src/config/loader.ts +2 -0
- package/src/config/memory-v3-gate.test.ts +31 -0
- package/src/config/memory-v3-gate.ts +20 -16
- package/src/config/platform-identity.ts +201 -0
- package/src/config/platform-rehydration.ts +11 -27
- package/src/config/schema.ts +2 -2
- package/src/config/schemas/__tests__/live-voice.test.ts +8 -158
- package/src/config/schemas/__tests__/voice.test.ts +148 -0
- package/src/config/schemas/calls.ts +1 -28
- package/src/config/schemas/live-voice.ts +1 -173
- package/src/config/schemas/mcp.ts +1 -1
- package/src/config/schemas/memory-retrospective.ts +10 -0
- package/src/config/schemas/services.ts +18 -0
- package/src/config/schemas/skills.ts +0 -14
- package/src/config/schemas/voice.ts +150 -0
- package/src/credential-execution/process-manager.test.ts +18 -19
- package/src/credential-health/credential-health-service.ts +11 -17
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -121
- package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +4 -1
- package/src/daemon/__tests__/skill-memory-refresh-mtime.test.ts +133 -0
- package/src/daemon/app-change-notify.ts +45 -0
- package/src/daemon/config-watcher.ts +13 -194
- package/src/daemon/conversation-error.ts +3 -2
- package/src/daemon/conversation-media-retry.ts +2 -1
- package/src/daemon/conversation-process.ts +35 -64
- package/src/daemon/conversation-runtime-assembly.ts +20 -7
- package/src/daemon/conversation-skill-tools.ts +13 -31
- package/src/daemon/conversation-store.ts +1 -1
- package/src/daemon/conversation-surfaces.ts +21 -10
- package/src/daemon/conversation-tool-setup.ts +45 -59
- package/src/daemon/conversation.ts +0 -3
- package/src/daemon/dictation-profile-store.ts +2 -1
- package/src/daemon/handlers/shared.ts +2 -1
- package/src/daemon/handlers/skills.ts +6 -3
- package/src/daemon/host-bash-proxy.ts +8 -12
- package/src/daemon/host-browser-proxy.ts +15 -1
- package/src/daemon/host-cu-proxy.ts +224 -19
- package/src/daemon/host-file-proxy.ts +8 -10
- package/src/daemon/host-proxy-preactivation.ts +2 -1
- package/src/daemon/host-transfer-proxy.ts +14 -18
- package/src/daemon/lifecycle.ts +0 -5
- package/src/daemon/mcp-reload-service.ts +5 -5
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/orphan-reaper.ts +1 -1
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/reaction-history-render.ts +2 -1
- package/src/daemon/shutdown-handlers.ts +1 -9
- package/src/daemon/skill-memory-refresh.ts +64 -0
- package/src/daemon/tool-side-effects.ts +7 -18
- package/src/desktop/__tests__/fake-desktop.ts +122 -0
- package/src/desktop/desktop-chrome-policy.test.ts +79 -0
- package/src/desktop/desktop-chrome-policy.ts +47 -0
- package/src/desktop/desktop-chrome-session.ts +37 -0
- package/src/desktop/desktop-dependencies.test.ts +102 -0
- package/src/desktop/desktop-dependencies.ts +308 -0
- package/src/desktop/desktop-feature.test.ts +18 -0
- package/src/desktop/desktop-feature.ts +19 -0
- package/src/desktop/desktop-panel-config.test.ts +135 -0
- package/src/desktop/desktop-panel-config.ts +149 -0
- package/src/desktop/desktop-session-manager.test.ts +730 -0
- package/src/desktop/desktop-session-manager.ts +850 -0
- package/src/desktop/desktop-stream-bridge.test.ts +395 -0
- package/src/desktop/desktop-stream-bridge.ts +214 -0
- package/src/desktop/desktop-wallpaper.test.ts +191 -0
- package/src/desktop/desktop-wallpaper.ts +113 -0
- package/src/desktop/desktop-window-drag.ts +177 -0
- package/src/desktop/desktop-window-manager-config.test.ts +230 -0
- package/src/desktop/desktop-window-manager-config.ts +238 -0
- package/src/desktop/desktop-window-theme.ts +170 -0
- package/src/heartbeat/heartbeat-service.ts +21 -3
- package/src/home/__tests__/feed-writer.test.ts +22 -0
- package/src/home/feed-writer.ts +11 -2
- package/src/hooks/types.ts +33 -0
- package/src/i18n/AGENTS.md +22 -0
- package/src/i18n/__tests__/i18n.test.ts +108 -0
- package/src/i18n/index.ts +16 -0
- package/src/i18n/locales.ts +93 -0
- package/src/i18n/messages.ts +61 -0
- package/src/i18n/title.ts +25 -0
- package/src/inbound/platform-callback-registration.ts +4 -5
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +121 -0
- package/src/live-voice/__tests__/live-voice-events.test.ts +8 -7
- package/src/live-voice/__tests__/live-voice-metrics.test.ts +0 -3
- package/src/live-voice/__tests__/live-voice-progress.test.ts +94 -15
- package/src/live-voice/__tests__/live-voice-sight-frame-echo.test.ts +238 -0
- package/src/live-voice/__tests__/live-voice-vad.test.ts +2 -2
- package/src/live-voice/__tests__/protocol.test.ts +39 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +13 -69
- package/src/live-voice/__tests__/session-controls.test.ts +79 -0
- package/src/live-voice/live-voice-photo.ts +25 -6
- package/src/live-voice/live-voice-session.ts +297 -699
- package/src/live-voice/protocol.ts +60 -2
- package/src/live-voice/session-controls.ts +111 -0
- package/src/mcp/__tests__/effective-config.test.ts +2 -2
- package/src/mcp/__tests__/workspace-mcp-config.test.ts +135 -0
- package/src/mcp/effective-config.ts +3 -3
- package/src/mcp/mcp-header-store.ts +29 -45
- package/src/mcp/spec-schema.ts +111 -0
- package/src/mcp/startup.ts +8 -4
- package/src/mcp/workspace-mcp-config.ts +188 -0
- package/src/messaging/provider.ts +10 -3
- package/src/messaging/providers/__tests__/proactive-address.test.ts +95 -0
- package/src/messaging/providers/callback-routing.ts +18 -0
- package/src/messaging/providers/channel-transport.ts +56 -0
- package/src/messaging/providers/discord/transport.ts +17 -0
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +6 -17
- package/src/messaging/providers/slack/adapter.ts +7 -44
- package/src/messaging/providers/slack/transport.ts +16 -0
- package/src/messaging/providers/telegram-bot/adapter.ts +1 -48
- package/src/messaging/providers/telegram-bot/client.ts +0 -26
- package/src/messaging/providers/telegram-bot/transport.ts +20 -0
- package/src/messaging/providers/whatsapp/adapter.ts +1 -48
- package/src/messaging/providers/whatsapp/transport.ts +18 -0
- package/src/monitoring/__tests__/workspace-git-heartbeat.test.ts +8 -0
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +55 -0
- package/src/notifications/__tests__/guardian-feed-projection.test.ts +158 -2
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +153 -3
- package/src/notifications/__tests__/schedule-result-producer.test.ts +99 -3
- package/src/notifications/adapters/macos.ts +3 -0
- package/src/notifications/assistant-reply-producer.ts +8 -3
- package/src/notifications/conversation-pairing.ts +36 -16
- package/src/notifications/delivered-post-record.ts +11 -1
- package/src/notifications/guardian-feed-projection.ts +125 -5
- package/src/notifications/home-feed-side-effect.ts +55 -7
- package/src/notifications/schedule-result-producer.ts +66 -22
- package/src/oauth/AGENTS.md +2 -0
- package/src/oauth/__tests__/seed-providers-managed.test.ts +149 -0
- package/src/oauth/byo-connection.test.ts +105 -0
- package/src/oauth/byo-connection.ts +36 -6
- package/src/oauth/connection-resolver.test.ts +100 -0
- package/src/oauth/connection-resolver.ts +120 -3
- package/src/oauth/provider-serializer.ts +9 -0
- package/src/oauth/scope-utils.ts +24 -0
- package/src/oauth/seed-providers.ts +314 -27
- package/src/outbound-proxy/certs.ts +3 -5
- package/src/permissions/checker.test.ts +11 -6
- package/src/persistence/compaction-log-store-clickhouse.ts +3 -3
- package/src/persistence/conversation-crud.ts +71 -63
- package/src/persistence/conversation-lineage.ts +12 -4
- package/src/persistence/conversation-queries.ts +2 -2
- package/src/persistence/conversation-title-placeholders.ts +23 -0
- package/src/persistence/conversation-title-service.ts +9 -26
- package/src/persistence/embeddings/qdrant-manager.ts +163 -18
- package/src/persistence/llm-request-log-sink-clickhouse.ts +3 -3
- package/src/persistence/llm-request-log-source-clickhouse.ts +3 -3
- package/src/persistence/message-cursor.ts +78 -0
- package/src/persistence/message-reads.ts +30 -0
- package/src/persistence/migrations/157-invite-contact-id.ts +18 -6
- package/src/persistence/migrations/__tests__/157-invite-contact-id.test.ts +149 -0
- package/src/persistence/schema/memory-core.ts +5 -0
- package/src/platform/client.test.ts +4 -2
- package/src/platform/client.ts +2 -10
- package/src/plugin-api/constants.ts +2 -0
- package/src/plugin-api/index.ts +1 -0
- package/src/plugin-api/types.ts +2 -0
- package/src/plugins/defaults/index.ts +2 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +46 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-backfill.test.ts +118 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-preserve.test.ts +83 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +9 -5
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +20 -10
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +5 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-state.test.ts +219 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +31 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-trigger-check.test.ts +63 -0
- package/src/plugins/defaults/memory/__tests__/shutdown-hook.test.ts +4 -0
- package/src/plugins/defaults/memory/context-search/agent-runner.ts +3 -2
- package/src/plugins/defaults/memory/context-search/format.ts +3 -2
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +6 -3
- package/src/plugins/defaults/memory/context-search/sources/workspace.ts +3 -2
- package/src/plugins/defaults/memory/graph/capability-seed.ts +6 -7
- package/src/plugins/defaults/memory/hooks/init.ts +10 -0
- package/src/plugins/defaults/memory/hooks/message-deleted.ts +21 -0
- package/src/plugins/defaults/memory/hooks/shutdown.ts +2 -0
- package/src/plugins/defaults/memory/host-utils.ts +10 -0
- package/src/plugins/defaults/memory/jobs-worker.ts +13 -0
- package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +34 -60
- package/src/plugins/defaults/memory/memory-retrospective-cursor-backfill.ts +126 -0
- package/src/plugins/defaults/memory/memory-retrospective-cursor-preserve.ts +79 -0
- package/src/plugins/defaults/memory/memory-retrospective-cursor.ts +28 -0
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +3 -5
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +12 -3
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +1 -1
- package/src/plugins/defaults/memory/memory-retrospective-state.ts +312 -71
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +2 -1
- package/src/plugins/defaults/memory/memory-retrospective-trigger-check.ts +5 -3
- package/src/plugins/defaults/memory/skill-md-mtime-poll.ts +9 -0
- package/src/plugins/defaults/memory/startup.ts +28 -2
- package/src/plugins/defaults/memory/substrate/__tests__/skill-content.test.ts +7 -9
- package/src/plugins/defaults/memory/substrate/page-index.ts +6 -1
- package/src/plugins/defaults/memory/substrate/skill-content.ts +2 -2
- package/src/plugins/defaults/memory/v1/graph/consolidation.ts +4 -2
- package/src/plugins/defaults/memory/v1/graph/extraction.ts +4 -2
- package/src/plugins/defaults/memory/v1/graph/retriever.ts +4 -1
- package/src/plugins/defaults/memory/v2/reranker.ts +6 -1
- package/src/plugins/defaults/memory/v3/__tests__/card.test.ts +24 -0
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +125 -0
- package/src/plugins/defaults/memory/v3/__tests__/sections.test.ts +26 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +30 -0
- package/src/plugins/defaults/memory/v3/card.ts +3 -2
- package/src/plugins/defaults/memory/v3/pool-select.ts +5 -3
- package/src/plugins/defaults/memory/v3/sections.ts +9 -3
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +5 -2
- package/src/plugins/defaults/memory/worker.ts +6 -0
- package/src/plugins/mcp-servers.ts +15 -75
- package/src/providers/__tests__/connection-model-compat.test.ts +3 -3
- package/src/providers/__tests__/retry-callsite.test.ts +41 -0
- package/src/providers/__tests__/retry-outbound-sanitize.test.ts +176 -0
- package/src/providers/anthropic/client.ts +0 -47
- package/src/providers/gemini/client.ts +9 -23
- package/src/providers/gemini-thought-signature.test.ts +63 -0
- package/src/providers/gemini-thought-signature.ts +44 -0
- package/src/providers/inference/__tests__/endpoint-probe.test.ts +42 -3
- package/src/providers/inference/auth.ts +2 -3
- package/src/providers/inference/connection-availability.ts +27 -8
- package/src/providers/inference/endpoint-probe.ts +10 -1
- package/src/providers/inference/resolve-auth.ts +22 -4
- package/src/providers/inference/service-account-token.ts +248 -0
- package/src/providers/model-catalog.ts +34 -0
- package/src/providers/model-intents.ts +10 -5
- package/src/providers/openai/__tests__/chat-completions-output-token-limit.test.ts +141 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +146 -18
- package/src/providers/openai/__tests__/chat-completions-provider-thought-signature.test.ts +613 -0
- package/src/providers/openai/__tests__/google-thought-signature.test.ts +235 -0
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +83 -1
- package/src/providers/openai/chat-completions-provider.ts +212 -79
- package/src/providers/openai/codex-models.ts +0 -4
- package/src/providers/openai/google-thought-signature.ts +320 -0
- package/src/providers/opencode/client.test.ts +73 -4
- package/src/providers/opencode/client.ts +60 -3
- package/src/providers/openrouter/client.ts +20 -0
- package/src/providers/outbound-request-sanitize.ts +96 -0
- package/src/providers/retry.ts +30 -19
- package/src/providers/unparseable-tool-args.ts +5 -1
- package/src/runtime/AGENTS.md +3 -1
- package/src/runtime/__tests__/channel-send.test.ts +443 -0
- package/src/runtime/__tests__/desktop-stream-upgrade.test.ts +89 -0
- package/src/runtime/__tests__/host-observe.test.ts +40 -1
- package/src/runtime/__tests__/live-voice-upgrade.test.ts +58 -0
- package/src/runtime/__tests__/runtime-ws-test-utils.ts +72 -0
- package/src/runtime/__tests__/watch-stream-upgrade.test.ts +59 -0
- package/src/runtime/agent-wake.ts +2 -1
- package/src/runtime/assistant-event-hub.ts +21 -3
- package/src/runtime/auth/same-actor.ts +38 -3
- package/src/runtime/channel-send.ts +316 -0
- package/src/runtime/host-observe.ts +11 -1
- package/src/runtime/http-server.ts +160 -151
- package/src/runtime/routes/__tests__/acp-claude-auth-routes.test.ts +16 -5
- package/src/runtime/routes/__tests__/acp-routes.test.ts +159 -4
- package/src/runtime/routes/__tests__/apps-refresh-route.test.ts +275 -0
- package/src/runtime/routes/__tests__/channel-send-routes.test.ts +127 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +108 -1
- package/src/runtime/routes/__tests__/default-provider-routes.test.ts +2 -2
- package/src/runtime/routes/__tests__/dictation-cleanup-guard.test.ts +107 -0
- package/src/runtime/routes/__tests__/mcp-add-default-risk.test.ts +16 -12
- package/src/runtime/routes/acp-claude-auth-routes.ts +11 -3
- package/src/runtime/routes/acp-routes.test.ts +15 -0
- package/src/runtime/routes/acp-routes.ts +72 -9
- package/src/runtime/routes/app-management-routes.ts +90 -2
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/channel-send-routes.ts +85 -0
- package/src/runtime/routes/conversation-list-routes.ts +14 -3
- package/src/runtime/routes/conversation-query-routes.ts +40 -0
- package/src/runtime/routes/conversation-routes.ts +16 -3
- package/src/runtime/routes/credential-routes.ts +20 -14
- package/src/runtime/routes/desktop-setup-routes.test.ts +74 -0
- package/src/runtime/routes/desktop-setup-routes.ts +35 -0
- package/src/runtime/routes/diagnostics-routes.ts +61 -4
- package/src/runtime/routes/events-routes.ts +4 -0
- package/src/runtime/routes/host-cu-routes.ts +6 -0
- package/src/runtime/routes/index.ts +4 -2
- package/src/runtime/routes/log-export-routes.ts +2 -0
- package/src/runtime/routes/mcp-auth-routes.ts +39 -47
- package/src/runtime/routes/migration-routes.ts +6 -20
- package/src/runtime/routes/oauth-commands-routes.ts +50 -0
- package/src/runtime/routes/oauth-providers.ts +7 -0
- package/src/runtime/routes/platform-routes.ts +18 -15
- package/src/runtime/routes/workspace-routes.test.ts +55 -26
- package/src/runtime/routes/workspace-routes.ts +46 -63
- package/src/runtime/routes/workspace-tree-walk.test.ts +244 -0
- package/src/runtime/routes/workspace-tree-walk.ts +240 -0
- package/src/runtime/routes/workspace-utils.ts +17 -0
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +28 -0
- package/src/runtime/services/conversation-serializer.ts +16 -3
- package/src/runtime/sync/resource-sync-events.ts +2 -1
- package/src/schedule/run-script.ts +2 -1
- package/src/schedule/schedule-store.ts +9 -2
- package/src/schedule/worker.ts +1 -1
- package/src/security/__tests__/ces-http-record-backend.test.ts +137 -0
- package/src/security/ces-http-record-backend.ts +120 -0
- package/src/security/ces-rpc-record-backend.ts +7 -0
- package/src/security/untrusted-content.ts +3 -1
- package/src/skills/__tests__/workspace-skill-md-signature.test.ts +60 -0
- package/src/skills/workspace-skill-md-signature.ts +50 -0
- package/src/subagent/consult-context.ts +12 -25
- package/src/tools/__tests__/side-effect-abort-guard.test.ts +1 -0
- package/src/tools/acp/list-agents.test.ts +3 -1
- package/src/tools/acp/spawn.test.ts +146 -11
- package/src/tools/acp/spawn.ts +21 -3
- package/src/tools/acp/status.test.ts +94 -0
- package/src/tools/acp/status.ts +40 -3
- package/src/tools/app-control/skill-proxy-bridge.ts +2 -1
- package/src/tools/browser/browser-execution.ts +1 -1
- package/src/tools/browser/cdp-client/accessibility-snapshot.ts +9 -3
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +2 -1
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +3 -2
- package/src/tools/browser/network-recorder.ts +2 -1
- package/src/tools/capability-offer.test.ts +22 -2
- package/src/tools/capability-offer.ts +16 -1
- package/src/tools/computer-use/definitions.ts +121 -2
- package/src/tools/computer-use/skill-proxy-bridge.ts +2 -1
- package/src/tools/credentials/metadata-store.ts +100 -0
- package/src/tools/filesystem/search.ts +2 -1
- package/src/tools/host-filesystem/edit.test.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +2 -2
- package/src/tools/host-filesystem/read.test.ts +2 -1
- package/src/tools/host-filesystem/read.ts +2 -2
- package/src/tools/host-filesystem/transfer.test.ts +2 -1
- package/src/tools/host-filesystem/transfer.ts +2 -2
- package/src/tools/host-filesystem/write.test.ts +2 -1
- package/src/tools/host-filesystem/write.ts +2 -2
- package/src/tools/host-terminal/host-shell.test.ts +16 -0
- package/src/tools/host-terminal/host-shell.ts +4 -20
- package/src/tools/network/web-search.ts +6 -1
- package/src/tools/policy-context.ts +6 -7
- package/src/tools/skills/scaffold-managed.ts +61 -3
- package/src/tools/subagent/spawn.ts +5 -8
- package/src/tools/terminal/__tests__/sanitized-bash.test.ts +57 -0
- package/src/tools/terminal/sanitized-bash.ts +105 -0
- package/src/tools/ui-surface/channel-variants.ts +10 -59
- package/src/tools/watch/watch-retro-report.ts +0 -8
- package/src/types/host-capabilities.ts +5 -3
- package/src/util/__tests__/language-subtag.test.ts +23 -1
- package/src/util/ca-bundle.ts +13 -0
- package/src/util/language-subtag.ts +16 -0
- package/src/util/platform.ts +8 -0
- package/src/util/unicode.ts +15 -1
- package/src/watch/watch-retro.ts +6 -8
- package/src/watch/watch-timeline.ts +2 -2
- package/src/workflows/run-manager.ts +2 -1
- package/src/workspace/git-porcelain.ts +66 -0
- package/src/workspace/git-service.ts +6 -55
- package/src/workspace/migrations/154-repair-retired-codex-gpt-5-4-model-ids.ts +258 -0
- package/src/workspace/migrations/155-move-front-model-config-to-voice.ts +78 -0
- package/src/workspace/migrations/156-extract-workspace-mcp-json.ts +214 -0
- package/src/workspace/migrations/__tests__/155-move-front-model-config-to-voice.test.ts +102 -0
- package/src/workspace/migrations/__tests__/156-extract-workspace-mcp-json.test.ts +199 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/__tests__/app-source-watcher.test.ts +0 -218
- package/src/__tests__/config-watcher-skill-reseed.test.ts +0 -359
- package/src/__tests__/speaker-identification.test.ts +0 -56
- package/src/calls/speaker-identification.ts +0 -233
- package/src/daemon/app-source-watcher.ts +0 -218
- package/src/messaging/providers/whatsapp/client.ts +0 -29
- package/src/runtime/routes/debug-bash-routes.ts +0 -173
- package/src/util/fs-watcher-error.ts +0 -36
- /package/src/{live-voice → calls}/progress-phrases.ts +0 -0
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
mediaSourceByteLength,
|
|
18
18
|
resolveMediaReferences,
|
|
19
19
|
} from "../media-resolve.js";
|
|
20
|
+
import { supportsForcedToolChoiceWithThinking } from "../model-catalog.js";
|
|
20
21
|
import { PLACEHOLDER_EMPTY_TURN } from "../placeholder-sentinels.js";
|
|
21
22
|
import { recordProviderRequestDiagnostics } from "../request-diagnostics.js";
|
|
22
23
|
import { createStreamTimeout } from "../stream-timeout.js";
|
|
@@ -27,6 +28,7 @@ import type {
|
|
|
27
28
|
Provider,
|
|
28
29
|
ProviderResponse,
|
|
29
30
|
SendMessageOptions,
|
|
31
|
+
ToolUseContent,
|
|
30
32
|
} from "../types.js";
|
|
31
33
|
import {
|
|
32
34
|
ContextOverflowError,
|
|
@@ -51,6 +53,15 @@ import {
|
|
|
51
53
|
coerceObjectParamsToJsonString,
|
|
52
54
|
decodeCoercedObjectArgs,
|
|
53
55
|
} from "./coerce-object-args.js";
|
|
56
|
+
import {
|
|
57
|
+
applyGemini3UnsignedToolCallFallback,
|
|
58
|
+
attachGoogleThoughtSignatureIfNeeded,
|
|
59
|
+
classifyGoogleThoughtSignatureRetry,
|
|
60
|
+
geminiThoughtSignaturesByToolCallId,
|
|
61
|
+
type GoogleToolCallExtraContent,
|
|
62
|
+
thoughtSignatureFromToolUseMetadata,
|
|
63
|
+
toolUseMetadataFromChatCompletionsDelta,
|
|
64
|
+
} from "./google-thought-signature.js";
|
|
54
65
|
import {
|
|
55
66
|
isOpenAICompatInlineAudio,
|
|
56
67
|
OPENAI_COMPAT_MAX_INLINE_AUDIO_BYTES,
|
|
@@ -197,6 +208,12 @@ export interface OpenAIChatCompletionsProviderOptions {
|
|
|
197
208
|
* (Fireworks, Together) keep sending `none` / forced choices. Enabled for
|
|
198
209
|
* the generic `openai-compatible` adapter, whose upstream is unknown. */
|
|
199
210
|
omitToolChoiceWhenReasoning?: boolean;
|
|
211
|
+
/** Wire field for the output-token limit. OpenAI and OpenAI-compatible
|
|
212
|
+
* backends use `max_completion_tokens`. OpenRouter defaults to
|
|
213
|
+
* `max_tokens` because its parameter router matches that key on
|
|
214
|
+
* `require_parameters` routes; see
|
|
215
|
+
* {@link OpenAIChatCompletionsProvider.resolveOutputTokenLimitField}. */
|
|
216
|
+
outputTokenLimitField?: "max_completion_tokens" | "max_tokens";
|
|
200
217
|
}
|
|
201
218
|
|
|
202
219
|
const log = getLogger("chat-completions");
|
|
@@ -204,7 +221,13 @@ const log = getLogger("chat-completions");
|
|
|
204
221
|
/** Wire-level reasoning_effort values. The OpenAI SDK type doesn't include
|
|
205
222
|
* `"max"`, but Fireworks accepts it for DeepSeek V4; the assignment to
|
|
206
223
|
* `params.reasoning_effort` casts through this union. */
|
|
207
|
-
export type ReasoningEffortWire =
|
|
224
|
+
export type ReasoningEffortWire =
|
|
225
|
+
| "none"
|
|
226
|
+
| "low"
|
|
227
|
+
| "medium"
|
|
228
|
+
| "high"
|
|
229
|
+
| "xhigh"
|
|
230
|
+
| "max";
|
|
208
231
|
|
|
209
232
|
const REASONING_EFFORT_RANK: Record<ReasoningEffortWire, number> = {
|
|
210
233
|
none: 0,
|
|
@@ -388,9 +411,15 @@ export function isThinkingEnabledOnWire(params: unknown): boolean {
|
|
|
388
411
|
* rejected it because thinking/reasoning mode forbids that parameter.
|
|
389
412
|
* DeepSeek thinking mode 400s with `Thinking mode does not support this
|
|
390
413
|
* tool_choice` for any explicit value, including `"auto"` and `"none"`.
|
|
391
|
-
*
|
|
392
|
-
*
|
|
414
|
+
* Kimi 400s with `tool_choice 'specified' is incompatible with thinking
|
|
415
|
+
* enabled`. One retry without `tool_choice` lets the same provider succeed
|
|
416
|
+
* instead of failing over to a different backend.
|
|
393
417
|
*/
|
|
418
|
+
const THINKING_MODE_TOOL_CHOICE_REJECTION_PATTERNS: RegExp[] = [
|
|
419
|
+
/does not support this tool_choice/i,
|
|
420
|
+
/tool_choice\s+'specified'\s+is incompatible with thinking/i,
|
|
421
|
+
];
|
|
422
|
+
|
|
394
423
|
function isThinkingModeToolChoiceRejection(
|
|
395
424
|
error: unknown,
|
|
396
425
|
params: unknown,
|
|
@@ -402,8 +431,9 @@ function isThinkingModeToolChoiceRejection(
|
|
|
402
431
|
if (!isClientErrorStatus(error)) {
|
|
403
432
|
return false;
|
|
404
433
|
}
|
|
405
|
-
|
|
406
|
-
|
|
434
|
+
const haystack = openaiCompatErrorHaystack(error);
|
|
435
|
+
return THINKING_MODE_TOOL_CHOICE_REJECTION_PATTERNS.some((pattern) =>
|
|
436
|
+
pattern.test(haystack),
|
|
407
437
|
);
|
|
408
438
|
}
|
|
409
439
|
|
|
@@ -541,8 +571,10 @@ function isMissingReasoningContentRejection(
|
|
|
541
571
|
|
|
542
572
|
/**
|
|
543
573
|
* True when the request included an assistant `reasoning` / `reasoning_content`
|
|
544
|
-
* extra and the provider rejected it as an unknown
|
|
545
|
-
* without those extras lets a strict Chat Completions
|
|
574
|
+
* extra and the provider rejected it as an unknown or unsupported message
|
|
575
|
+
* property. One retry without those extras lets a strict Chat Completions
|
|
576
|
+
* schema succeed. Groq phrases this as
|
|
577
|
+
* `property 'reasoning_content' is unsupported`.
|
|
546
578
|
*/
|
|
547
579
|
function isUnknownAssistantReasoningFieldRejection(
|
|
548
580
|
error: unknown,
|
|
@@ -561,7 +593,7 @@ function isUnknownAssistantReasoningFieldRejection(
|
|
|
561
593
|
if (!haystackNamesAssistantReasoningField(haystack)) {
|
|
562
594
|
return false;
|
|
563
595
|
}
|
|
564
|
-
return /unknown|unexpected|unrecognized|additional propert|extra (?:field|property)|not (?:a )?valid|invalid (?:argument|parameter|field|property)/i.test(
|
|
596
|
+
return /unknown|unexpected|unrecognized|unsupported|not supported|additional propert|extra (?:field|property)|not (?:a )?valid|invalid (?:argument|parameter|field|property)/i.test(
|
|
565
597
|
haystack,
|
|
566
598
|
);
|
|
567
599
|
}
|
|
@@ -634,6 +666,82 @@ function flattenContentPartsToStrings(params: unknown): boolean {
|
|
|
634
666
|
return flattened;
|
|
635
667
|
}
|
|
636
668
|
|
|
669
|
+
type OpenAICompatRetryKind =
|
|
670
|
+
| "reasoning-opt-out"
|
|
671
|
+
| "thinking-tool-choice"
|
|
672
|
+
| "missing-reasoning-content"
|
|
673
|
+
| "unknown-reasoning-field"
|
|
674
|
+
| "missing-thought-signature"
|
|
675
|
+
| "unknown-extra-content"
|
|
676
|
+
| "chat-template";
|
|
677
|
+
|
|
678
|
+
function classifyOpenAICompatRetry(
|
|
679
|
+
error: unknown,
|
|
680
|
+
params: OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming,
|
|
681
|
+
thoughtSignaturesByCallId: ReadonlyMap<string, string>,
|
|
682
|
+
): { kind: OpenAICompatRetryKind; message: string; apply: () => void } | null {
|
|
683
|
+
if (isReasoningOptOutRejection(error, params)) {
|
|
684
|
+
return {
|
|
685
|
+
kind: "reasoning-opt-out",
|
|
686
|
+
message:
|
|
687
|
+
"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
|
+
},
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
if (isThinkingModeToolChoiceRejection(error, params)) {
|
|
695
|
+
return {
|
|
696
|
+
kind: "thinking-tool-choice",
|
|
697
|
+
message:
|
|
698
|
+
"Upstream rejected tool_choice in thinking mode; retrying without tool_choice",
|
|
699
|
+
apply: () => {
|
|
700
|
+
delete params.tool_choice;
|
|
701
|
+
},
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
if (isMissingReasoningContentRejection(error, params)) {
|
|
705
|
+
return {
|
|
706
|
+
kind: "missing-reasoning-content",
|
|
707
|
+
message:
|
|
708
|
+
"Upstream requires reasoning_content round-trip; retrying with empty field on assistant messages",
|
|
709
|
+
apply: () => {
|
|
710
|
+
backfillEmptyReasoningContent(params);
|
|
711
|
+
},
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
if (isUnknownAssistantReasoningFieldRejection(error, params)) {
|
|
715
|
+
return {
|
|
716
|
+
kind: "unknown-reasoning-field",
|
|
717
|
+
message:
|
|
718
|
+
"Upstream rejected assistant reasoning field; retrying without it",
|
|
719
|
+
apply: () => {
|
|
720
|
+
stripAssistantReasoningFields(params);
|
|
721
|
+
},
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
const thoughtSignatureRetry = classifyGoogleThoughtSignatureRetry(params, {
|
|
725
|
+
isClientError: isClientErrorStatus(error),
|
|
726
|
+
haystack: openaiCompatErrorHaystack(error),
|
|
727
|
+
capturedByCallId: thoughtSignaturesByCallId,
|
|
728
|
+
});
|
|
729
|
+
if (thoughtSignatureRetry) {
|
|
730
|
+
return thoughtSignatureRetry;
|
|
731
|
+
}
|
|
732
|
+
if (isChatTemplateRejection(error, params)) {
|
|
733
|
+
return {
|
|
734
|
+
kind: "chat-template",
|
|
735
|
+
message:
|
|
736
|
+
"Upstream chat template rejected structured message content; retrying with flattened plain-text content",
|
|
737
|
+
apply: () => {
|
|
738
|
+
flattenContentPartsToStrings(params);
|
|
739
|
+
},
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
return null;
|
|
743
|
+
}
|
|
744
|
+
|
|
637
745
|
/**
|
|
638
746
|
* Translate the neutral (Anthropic-shaped) `tool_choice` carried on the call
|
|
639
747
|
* config into the OpenAI chat-completions wire format. Callers express
|
|
@@ -711,6 +819,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
711
819
|
private coerceObjectArgsToJsonString: boolean;
|
|
712
820
|
private salvageXmlToolCalls: boolean;
|
|
713
821
|
private omitToolChoiceWhenReasoning: boolean;
|
|
822
|
+
private outputTokenLimitField: "max_completion_tokens" | "max_tokens";
|
|
714
823
|
|
|
715
824
|
constructor(
|
|
716
825
|
apiKey: string,
|
|
@@ -742,6 +851,8 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
742
851
|
options.salvageXmlToolCalls ?? shouldSalvageXmlToolCalls(model);
|
|
743
852
|
this.omitToolChoiceWhenReasoning =
|
|
744
853
|
options.omitToolChoiceWhenReasoning ?? false;
|
|
854
|
+
this.outputTokenLimitField =
|
|
855
|
+
options.outputTokenLimitField ?? "max_completion_tokens";
|
|
745
856
|
}
|
|
746
857
|
|
|
747
858
|
get defaultModel(): string {
|
|
@@ -774,10 +885,13 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
774
885
|
const coercedObjectKeys = new Map<string, string[]>();
|
|
775
886
|
|
|
776
887
|
try {
|
|
888
|
+
const thoughtSignaturesByCallId =
|
|
889
|
+
geminiThoughtSignaturesByToolCallId(messages);
|
|
777
890
|
const openaiMessages = await this.toOpenAIMessages(
|
|
778
891
|
messages,
|
|
779
892
|
systemPrompt,
|
|
780
893
|
requestSupportsInlineAudio(modelOverride ?? this.model),
|
|
894
|
+
modelOverride ?? this.model,
|
|
781
895
|
);
|
|
782
896
|
|
|
783
897
|
recordProviderRequestDiagnostics({
|
|
@@ -794,7 +908,8 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
794
908
|
};
|
|
795
909
|
|
|
796
910
|
if (maxTokens) {
|
|
797
|
-
params.
|
|
911
|
+
params[this.resolveOutputTokenLimitField(modelOverride ?? this.model)] =
|
|
912
|
+
maxTokens;
|
|
798
913
|
}
|
|
799
914
|
|
|
800
915
|
// Profile-scoped token biasing (e.g. the `suppress-cjk` preset). Resolved
|
|
@@ -874,7 +989,18 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
874
989
|
const thinkingOn = isThinkingEnabledOnWire(params);
|
|
875
990
|
const skipAutoDefault = thinkingOn && toolChoice === "auto";
|
|
876
991
|
const skipAllChoices = thinkingOn && this.omitToolChoiceWhenReasoning;
|
|
877
|
-
|
|
992
|
+
const skipIncompatibleForcedChoice =
|
|
993
|
+
thinkingOn &&
|
|
994
|
+
!supportsForcedToolChoiceWithThinking(
|
|
995
|
+
this.name,
|
|
996
|
+
modelOverride ?? this.model,
|
|
997
|
+
) &&
|
|
998
|
+
(toolChoice === "required" || typeof toolChoice === "object");
|
|
999
|
+
if (
|
|
1000
|
+
!skipAutoDefault &&
|
|
1001
|
+
!skipAllChoices &&
|
|
1002
|
+
!skipIncompatibleForcedChoice
|
|
1003
|
+
) {
|
|
878
1004
|
params.tool_choice = toolChoice;
|
|
879
1005
|
}
|
|
880
1006
|
}
|
|
@@ -973,7 +1099,12 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
973
1099
|
|
|
974
1100
|
const toolCallMap = new Map<
|
|
975
1101
|
number,
|
|
976
|
-
{
|
|
1102
|
+
{
|
|
1103
|
+
id: string;
|
|
1104
|
+
name: string;
|
|
1105
|
+
args: string;
|
|
1106
|
+
providerMetadata?: ToolUseContent["providerMetadata"];
|
|
1107
|
+
}
|
|
977
1108
|
>();
|
|
978
1109
|
const toolProgress = createToolProgressEmitter(onEvent);
|
|
979
1110
|
let finishReason = "unknown";
|
|
@@ -1001,68 +1132,31 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1001
1132
|
? { headers: requestHeaders }
|
|
1002
1133
|
: {}),
|
|
1003
1134
|
});
|
|
1135
|
+
const attemptedCompatRetries = new Set<OpenAICompatRetryKind>();
|
|
1004
1136
|
let stream: Awaited<ReturnType<typeof createStream>>;
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
} catch (error) {
|
|
1008
|
-
if (isReasoningOptOutRejection(error, params)) {
|
|
1009
|
-
log.warn(
|
|
1010
|
-
{
|
|
1011
|
-
provider: this.name,
|
|
1012
|
-
model: modelOverride ?? this.model,
|
|
1013
|
-
error: error instanceof Error ? error.message : String(error),
|
|
1014
|
-
},
|
|
1015
|
-
"Model rejected the explicit reasoning opt-out; retrying without reasoning params",
|
|
1016
|
-
);
|
|
1017
|
-
delete params.reasoning_effort;
|
|
1018
|
-
delete (params as unknown as Record<string, unknown>).reasoning;
|
|
1019
|
-
stream = await createStream();
|
|
1020
|
-
} else if (isThinkingModeToolChoiceRejection(error, params)) {
|
|
1021
|
-
log.warn(
|
|
1022
|
-
{
|
|
1023
|
-
provider: this.name,
|
|
1024
|
-
model: modelOverride ?? this.model,
|
|
1025
|
-
error: error instanceof Error ? error.message : String(error),
|
|
1026
|
-
},
|
|
1027
|
-
"Upstream rejected tool_choice in thinking mode; retrying without tool_choice",
|
|
1028
|
-
);
|
|
1029
|
-
delete params.tool_choice;
|
|
1137
|
+
for (;;) {
|
|
1138
|
+
try {
|
|
1030
1139
|
stream = await createStream();
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
},
|
|
1038
|
-
"Upstream requires reasoning_content round-trip; retrying with empty field on assistant messages",
|
|
1140
|
+
break;
|
|
1141
|
+
} catch (error) {
|
|
1142
|
+
const retry = classifyOpenAICompatRetry(
|
|
1143
|
+
error,
|
|
1144
|
+
params,
|
|
1145
|
+
thoughtSignaturesByCallId,
|
|
1039
1146
|
);
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
{
|
|
1045
|
-
provider: this.name,
|
|
1046
|
-
model: modelOverride ?? this.model,
|
|
1047
|
-
error: error instanceof Error ? error.message : String(error),
|
|
1048
|
-
},
|
|
1049
|
-
"Upstream rejected assistant reasoning field; retrying without it",
|
|
1050
|
-
);
|
|
1051
|
-
stripAssistantReasoningFields(params);
|
|
1052
|
-
stream = await createStream();
|
|
1053
|
-
} else if (isChatTemplateRejection(error, params)) {
|
|
1147
|
+
if (!retry || attemptedCompatRetries.has(retry.kind)) {
|
|
1148
|
+
throw error;
|
|
1149
|
+
}
|
|
1150
|
+
attemptedCompatRetries.add(retry.kind);
|
|
1054
1151
|
log.warn(
|
|
1055
1152
|
{
|
|
1056
1153
|
provider: this.name,
|
|
1057
1154
|
model: modelOverride ?? this.model,
|
|
1058
1155
|
error: error instanceof Error ? error.message : String(error),
|
|
1059
1156
|
},
|
|
1060
|
-
|
|
1157
|
+
retry.message,
|
|
1061
1158
|
);
|
|
1062
|
-
|
|
1063
|
-
stream = await createStream();
|
|
1064
|
-
} else {
|
|
1065
|
-
throw error;
|
|
1159
|
+
retry.apply();
|
|
1066
1160
|
}
|
|
1067
1161
|
}
|
|
1068
1162
|
|
|
@@ -1150,6 +1244,14 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1150
1244
|
entry.args,
|
|
1151
1245
|
);
|
|
1152
1246
|
}
|
|
1247
|
+
const providerMetadata =
|
|
1248
|
+
toolUseMetadataFromChatCompletionsDelta(tc);
|
|
1249
|
+
if (
|
|
1250
|
+
providerMetadata &&
|
|
1251
|
+
!thoughtSignatureFromToolUseMetadata(entry.providerMetadata)
|
|
1252
|
+
) {
|
|
1253
|
+
entry.providerMetadata = providerMetadata;
|
|
1254
|
+
}
|
|
1153
1255
|
}
|
|
1154
1256
|
}
|
|
1155
1257
|
|
|
@@ -1271,6 +1373,9 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1271
1373
|
id: tc.id,
|
|
1272
1374
|
name: tc.name,
|
|
1273
1375
|
input,
|
|
1376
|
+
...(tc.providerMetadata
|
|
1377
|
+
? { providerMetadata: tc.providerMetadata }
|
|
1378
|
+
: {}),
|
|
1274
1379
|
});
|
|
1275
1380
|
}
|
|
1276
1381
|
|
|
@@ -1284,11 +1389,19 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1284
1389
|
content: contentText || null,
|
|
1285
1390
|
tool_calls:
|
|
1286
1391
|
toolCallMap.size > 0
|
|
1287
|
-
? Array.from(toolCallMap.values()).map((tc) =>
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1392
|
+
? Array.from(toolCallMap.values()).map((tc) =>
|
|
1393
|
+
attachGoogleThoughtSignatureIfNeeded(
|
|
1394
|
+
{
|
|
1395
|
+
id: tc.id,
|
|
1396
|
+
type: "function",
|
|
1397
|
+
function: { name: tc.name, arguments: tc.args },
|
|
1398
|
+
},
|
|
1399
|
+
thoughtSignatureFromToolUseMetadata(
|
|
1400
|
+
tc.providerMetadata,
|
|
1401
|
+
),
|
|
1402
|
+
modelOverride ?? this.model,
|
|
1403
|
+
),
|
|
1404
|
+
)
|
|
1292
1405
|
: undefined,
|
|
1293
1406
|
},
|
|
1294
1407
|
finish_reason: finishReason,
|
|
@@ -1474,6 +1587,15 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1474
1587
|
return this.maxReasoningEffort;
|
|
1475
1588
|
}
|
|
1476
1589
|
|
|
1590
|
+
/** Per-request output-token-limit wire key. Defaults to the constructor
|
|
1591
|
+
* `outputTokenLimitField`. Subclasses override when support varies by
|
|
1592
|
+
* model. */
|
|
1593
|
+
protected resolveOutputTokenLimitField(
|
|
1594
|
+
_model: string,
|
|
1595
|
+
): "max_completion_tokens" | "max_tokens" {
|
|
1596
|
+
return this.outputTokenLimitField;
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1477
1599
|
/**
|
|
1478
1600
|
* Per-model sparse `reasoning_effort` support. Subclasses return the
|
|
1479
1601
|
* accepted values for models that 4xx on in-between tiers (e.g. GLM 5.3's
|
|
@@ -1492,6 +1614,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1492
1614
|
messages: Message[],
|
|
1493
1615
|
systemPrompt?: string,
|
|
1494
1616
|
audioInputEnabled = false,
|
|
1617
|
+
model = this.model,
|
|
1495
1618
|
): Promise<OpenAI.Chat.Completions.ChatCompletionMessageParam[]> {
|
|
1496
1619
|
// Swap any persisted attachment references back to inline base64 before
|
|
1497
1620
|
// serializing, so the block transforms below can read `source.data`.
|
|
@@ -1513,7 +1636,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1513
1636
|
const emittedToolCallIds = new Set<string>();
|
|
1514
1637
|
for (const msg of messages) {
|
|
1515
1638
|
if (msg.role === "assistant") {
|
|
1516
|
-
const assistantMessage = this.toOpenAIAssistantMessage(msg);
|
|
1639
|
+
const assistantMessage = this.toOpenAIAssistantMessage(msg, model);
|
|
1517
1640
|
for (const toolCall of assistantMessage.tool_calls ?? []) {
|
|
1518
1641
|
emittedToolCallIds.add(toolCall.id);
|
|
1519
1642
|
}
|
|
@@ -1591,11 +1714,14 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1591
1714
|
/** Convert an assistant message with text + tool_use blocks to OpenAI format. */
|
|
1592
1715
|
private toOpenAIAssistantMessage(
|
|
1593
1716
|
msg: Message,
|
|
1717
|
+
model: string,
|
|
1594
1718
|
): OpenAI.Chat.Completions.ChatCompletionAssistantMessageParam {
|
|
1595
1719
|
const textParts: string[] = [];
|
|
1596
1720
|
const reasoningParts: string[] = [];
|
|
1597
|
-
const toolCalls:
|
|
1598
|
-
|
|
1721
|
+
const toolCalls: Array<
|
|
1722
|
+
OpenAI.Chat.Completions.ChatCompletionMessageToolCall &
|
|
1723
|
+
GoogleToolCallExtraContent
|
|
1724
|
+
> = [];
|
|
1599
1725
|
|
|
1600
1726
|
for (const block of msg.content) {
|
|
1601
1727
|
switch (block.type) {
|
|
@@ -1609,14 +1735,20 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1609
1735
|
}
|
|
1610
1736
|
break;
|
|
1611
1737
|
case "tool_use":
|
|
1612
|
-
toolCalls.push(
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1738
|
+
toolCalls.push(
|
|
1739
|
+
attachGoogleThoughtSignatureIfNeeded(
|
|
1740
|
+
{
|
|
1741
|
+
id: block.id,
|
|
1742
|
+
type: "function",
|
|
1743
|
+
function: {
|
|
1744
|
+
name: block.name,
|
|
1745
|
+
arguments: JSON.stringify(block.input),
|
|
1746
|
+
},
|
|
1747
|
+
},
|
|
1748
|
+
thoughtSignatureFromToolUseMetadata(block.providerMetadata),
|
|
1749
|
+
model,
|
|
1750
|
+
),
|
|
1751
|
+
);
|
|
1620
1752
|
break;
|
|
1621
1753
|
case "server_tool_use":
|
|
1622
1754
|
textParts.push(`[Web search: ${block.name}]`);
|
|
@@ -1635,6 +1767,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
1635
1767
|
};
|
|
1636
1768
|
|
|
1637
1769
|
if (toolCalls.length > 0) {
|
|
1770
|
+
applyGemini3UnsignedToolCallFallback(toolCalls, model);
|
|
1638
1771
|
result.tool_calls = toolCalls;
|
|
1639
1772
|
}
|
|
1640
1773
|
|
|
@@ -14,10 +14,6 @@ export const CODEX_SUBSCRIPTION_MODEL_IDS: ReadonlySet<string> = new Set([
|
|
|
14
14
|
"gpt-5.6-terra",
|
|
15
15
|
"gpt-5.6-luna",
|
|
16
16
|
"gpt-5.5",
|
|
17
|
-
// OpenAI retires these two from ChatGPT sign-in on 2026-08-31; API-key
|
|
18
|
-
// auth is unaffected.
|
|
19
|
-
"gpt-5.4",
|
|
20
|
-
"gpt-5.4-mini",
|
|
21
17
|
]);
|
|
22
18
|
|
|
23
19
|
/** True when `model` is allowlisted for Codex subscription routing. */
|