mixdog 0.9.63 → 0.9.65
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/README.md +3 -0
- package/package.json +9 -2
- package/scripts/code-graph-description-contract.mjs +3 -3
- package/scripts/verify-release-assets.mjs +2 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +11 -14
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +6 -6
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -2
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
- package/src/runtime/agent/orchestrator/config.mjs +19 -124
- package/src/runtime/agent/orchestrator/context/collect.mjs +6 -6
- package/src/runtime/agent/orchestrator/dispatch-persist.mjs +2 -2
- package/src/runtime/agent/orchestrator/internal-agents.mjs +2 -2
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +1 -1
- package/src/runtime/agent/orchestrator/mcp/client.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-betas.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +333 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +3 -277
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +6 -6
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +196 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +460 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +14 -593
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +5 -280
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +357 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-headers.mjs +216 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +2 -188
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/provider-catalog-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/registry.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/compact/budget.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/compact/file-reattach.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/compact/summary-schema.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +4 -4
- package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +17 -0
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +18 -26
- package/src/runtime/agent/orchestrator/session/loop/termination.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/delivered-completions.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +49 -0
- package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +49 -0
- package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +260 -0
- package/src/runtime/agent/orchestrator/session/store/serialize.mjs +72 -0
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +163 -0
- package/src/runtime/agent/orchestrator/session/store/write-guards.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/store.mjs +9 -561
- package/src/runtime/agent/orchestrator/session/tool-envelope.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +2 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +11 -11
- package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/bash-session.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +2 -154
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/cwd-utils.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/fs-reachability.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/glob-walk.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/path-locks.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/path-utils.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-args.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +2 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-image-resize.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-open.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-spawn.mjs +519 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +5 -449
- package/src/runtime/agent/orchestrator/tools/builtin/snapshot-helpers.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +212 -0
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +1 -7
- package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +9 -36
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +15 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/search-references.mjs +429 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +2 -395
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/text-mask.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/trusted-roots.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph-state.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/mutation-planner.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/next-call-utils.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +7 -7
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +72 -9
- package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/patch/paths.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/patch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/result-compression.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +2 -444
- package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +505 -0
- package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +1 -1
- package/src/runtime/channels/lib/backend-dispatch.mjs +20 -5
- package/src/runtime/channels/lib/scheduler.mjs +1 -1
- package/src/runtime/channels/lib/telegram-format.mjs +1 -1
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +4 -4
- package/src/runtime/channels/tool-defs.mjs +2 -3
- package/src/runtime/memory/index.mjs +1 -5
- package/src/runtime/memory/lib/core-memory-candidates.mjs +357 -0
- package/src/runtime/memory/lib/core-memory-store.mjs +7 -357
- package/src/runtime/memory/lib/cycle-signatures.mjs +1 -1
- package/src/runtime/memory/lib/embedding-model-config.mjs +1 -1
- package/src/runtime/memory/lib/embedding-provider.mjs +1 -5
- package/src/runtime/memory/lib/embedding-worker.mjs +1 -5
- package/src/runtime/memory/lib/ko-morph.mjs +2 -2
- package/src/runtime/memory/lib/memory-config-flags.mjs +2 -5
- package/src/runtime/memory/lib/memory-cycle-requests.mjs +3 -7
- package/src/runtime/memory/lib/memory-cycle1.mjs +4 -8
- package/src/runtime/memory/lib/memory-cycle2-gate.mjs +1 -1
- package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +1 -1
- package/src/runtime/memory/lib/memory-cycle2-shared.mjs +2 -5
- package/src/runtime/memory/lib/memory-cycle3.mjs +1 -5
- package/src/runtime/memory/lib/memory-embed.mjs +2 -6
- package/src/runtime/memory/lib/memory-log.mjs +8 -0
- package/src/runtime/memory/lib/memory-ops-policy.mjs +4 -8
- package/src/runtime/memory/lib/memory-recall-scope-filter.mjs +1 -1
- package/src/runtime/memory/lib/memory-recall-store.mjs +2 -193
- package/src/runtime/memory/lib/memory-score.mjs +1 -1
- package/src/runtime/memory/lib/memory-text-utils.mjs +2 -2
- package/src/runtime/memory/lib/memory.mjs +2 -6
- package/src/runtime/memory/lib/pg/adapter.mjs +2 -6
- package/src/runtime/memory/lib/pg/process.mjs +1 -5
- package/src/runtime/memory/lib/pg/supervisor.mjs +1 -5
- package/src/runtime/memory/lib/recall-format.mjs +2 -2
- package/src/runtime/memory/lib/recall-scoring.mjs +195 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +1 -5
- package/src/runtime/memory/lib/trace-store.mjs +2 -6
- package/src/runtime/search/lib/http-fetch.mjs +6 -6
- package/src/runtime/search/lib/web-tools.mjs +2 -2
- package/src/runtime/shared/buffered-appender.mjs +1 -1
- package/src/runtime/shared/child-guardian.mjs +1 -1
- package/src/runtime/shared/child-spawn-gate.mjs +1 -1
- package/src/runtime/shared/config.mjs +4 -4
- package/src/runtime/shared/launcher-control.mjs +9 -10
- package/src/runtime/shared/llm/index.mjs +5 -20
- package/src/runtime/shared/markdown-frontmatter.mjs +1 -1
- package/src/runtime/shared/memory-snapshot.mjs +4 -4
- package/src/runtime/shared/pristine-execution.mjs +1 -1
- package/src/runtime/shared/process-lifecycle.mjs +0 -1
- package/src/runtime/shared/process-shutdown.mjs +1 -1
- package/src/runtime/shared/resource-admission.mjs +2 -2
- package/src/runtime/shared/schedule-session-run.mjs +1 -1
- package/src/runtime/shared/schedules-db.mjs +1 -1
- package/src/runtime/shared/service-discovery.mjs +2 -2
- package/src/runtime/shared/staged-update.mjs +6 -6
- package/src/runtime/shared/tool-execution-contract.mjs +1 -1
- package/src/runtime/shared/tool-primitives.mjs +1 -1
- package/src/runtime/shared/tool-surface.mjs +2 -2
- package/src/runtime/shared/turn-snapshot.mjs +184 -0
- package/src/runtime/shared/update-checker.mjs +1 -1
- package/src/runtime/shared/user-cwd.mjs +3 -3
- package/src/runtime/shared/user-data-guard.mjs +4 -4
- package/src/runtime/shared/workspace-router.mjs +5 -5
- package/src/session-runtime/config-helpers.mjs +2 -3
- package/src/session-runtime/config-lifecycle.mjs +1 -1
- package/src/session-runtime/hitch-profile.mjs +1 -1
- package/src/session-runtime/lifecycle-api.mjs +6 -4
- package/src/session-runtime/model-recency.mjs +5 -5
- package/src/session-runtime/plugin-mcp.mjs +1 -1
- package/src/session-runtime/provider-request-snapshot.mjs +338 -0
- package/src/session-runtime/runtime-core.mjs +4 -0
- package/src/session-runtime/session-text.mjs +4 -4
- package/src/session-runtime/session-turn-api.mjs +7 -0
- package/src/session-runtime/tool-catalog-schema.mjs +197 -0
- package/src/session-runtime/tool-catalog.mjs +6 -483
- package/src/session-runtime/tool-defs.mjs +1 -1
- package/src/standalone/agent-task-status.mjs +1 -1
- package/src/standalone/agent-tool/helpers.mjs +2 -2
- package/src/standalone/channel-admin.mjs +4 -4
- package/src/standalone/explore-tool.mjs +3 -3
- package/src/standalone/hook-bus/config.mjs +1 -1
- package/src/standalone/hook-bus/constants.mjs +1 -1
- package/src/standalone/hook-bus/rules.mjs +1 -1
- package/src/standalone/projects.mjs +1 -1
- package/src/standalone/provider-admin.mjs +2 -2
- package/src/tui/App.jsx +1 -1
- package/src/tui/app/app-format.mjs +2 -2
- package/src/tui/app/clipboard.mjs +3 -3
- package/src/tui/app/input-parsers.mjs +1 -1
- package/src/tui/app/text-layout.mjs +1 -1
- package/src/tui/app/transcript-row-estimate.mjs +360 -0
- package/src/tui/app/transcript-window.mjs +5 -347
- package/src/tui/app/use-mouse-input.mjs +1 -1
- package/src/tui/app/use-prompt-handlers.mjs +1 -1
- package/src/tui/components/tool-execution/surface-detail.mjs +9 -9
- package/src/tui/components/tool-execution/text-format.mjs +2 -2
- package/src/tui/components/tool-output-format.mjs +7 -7
- package/src/tui/display-width.mjs +4 -4
- package/src/tui/dist/index.mjs +187 -99
- package/src/tui/engine/agent-envelope.mjs +5 -5
- package/src/tui/engine/live-share.mjs +100 -0
- package/src/tui/engine/notification-plan.mjs +1 -1
- package/src/tui/engine/queue-helpers.mjs +3 -3
- package/src/tui/engine/render-timing.mjs +4 -5
- package/src/tui/engine/session-api-ext.mjs +6 -3
- package/src/tui/engine/tool-result-status.mjs +5 -5
- package/src/tui/engine/tool-result-text.mjs +1 -1
- package/src/tui/engine/transcript-spill.mjs +585 -0
- package/src/tui/engine/tui-steering-persist.mjs +1 -1
- package/src/tui/engine.mjs +29 -474
- package/src/tui/lib/voice-setup.mjs +1 -1
- package/src/tui/markdown/format-token.mjs +1 -1
- package/src/tui/markdown/render-ansi.mjs +1 -1
- package/src/tui/markdown/table-layout.mjs +4 -4
- package/src/tui/paste-attachments.mjs +1 -1
- package/src/tui/prompt-history-store.mjs +3 -3
- package/src/tui/statusline-ansi-bridge.mjs +2 -2
- package/src/tui/theme.mjs +1 -1
- package/src/tui/transcript-tool-failures.mjs +2 -2
- package/src/ui/ansi.mjs +0 -9
- package/src/ui/statusline-format.mjs +2 -4
- package/scripts/_bench-cwc.json +0 -20
- package/scripts/_jitter-fuzz.jsx +0 -42
- package/scripts/_jitter-fuzz2.jsx +0 -30
- package/scripts/_jitter-probe.jsx +0 -35
- package/scripts/_jp2.jsx +0 -16
- package/scripts/_smoke_wd.mjs +0 -7
- package/scripts/abort-recovery-test.mjs +0 -175
- package/scripts/agent-dispatch-abort-compose-test.mjs +0 -31
- package/scripts/agent-live-arg-guard-smoke.mjs +0 -20
- package/scripts/agent-live-path-suffix-smoke.mjs +0 -34
- package/scripts/agent-live-toolcall-args-smoke.mjs +0 -45
- package/scripts/agent-loop-policy-test.mjs +0 -37
- package/scripts/agent-model-liveness-test.mjs +0 -763
- package/scripts/agent-parallel-smoke.mjs +0 -435
- package/scripts/agent-route-batch-test.mjs +0 -40
- package/scripts/agent-tag-reuse-smoke.mjs +0 -441
- package/scripts/agent-terminal-reap-test.mjs +0 -252
- package/scripts/agent-trace-io-test.mjs +0 -133
- package/scripts/ansi-color-capability-test.mjs +0 -90
- package/scripts/anthropic-admission-retry-integration-test.mjs +0 -119
- package/scripts/anthropic-maxtokens-test.mjs +0 -119
- package/scripts/anthropic-oauth-refresh-race-test.mjs +0 -397
- package/scripts/anthropic-transport-policy-test.mjs +0 -726
- package/scripts/apply-patch-edit-smoke.mjs +0 -71
- package/scripts/arg-guard-test.mjs +0 -93
- package/scripts/async-notify-settlement-test.mjs +0 -99
- package/scripts/atomic-lock-tryonce-test.mjs +0 -125
- package/scripts/background-task-meta-smoke.mjs +0 -38
- package/scripts/bench-run.mjs +0 -508
- package/scripts/boot-smoke.mjs +0 -137
- package/scripts/build-runtime-windows.ps1 +0 -242
- package/scripts/channel-daemon-smoke.mjs +0 -1103
- package/scripts/code-graph-aggregate-cwd-test.mjs +0 -158
- package/scripts/code-graph-disk-hit-test.mjs +0 -290
- package/scripts/code-graph-dispatch-test.mjs +0 -96
- package/scripts/code-graph-root-federation-test.mjs +0 -273
- package/scripts/compact-active-turn-test.mjs +0 -68
- package/scripts/compact-file-reattach-test.mjs +0 -88
- package/scripts/compact-pressure-test.mjs +0 -788
- package/scripts/compact-prior-context-flatten-test.mjs +0 -252
- package/scripts/compact-recall-digest-test.mjs +0 -57
- package/scripts/compact-smoke.mjs +0 -1017
- package/scripts/compact-trigger-migration-smoke.mjs +0 -261
- package/scripts/compacted-placeholder-scrub-test.mjs +0 -63
- package/scripts/context-mcp-metering-test.mjs +0 -1406
- package/scripts/debounced-skills-async-save-test.mjs +0 -57
- package/scripts/deferred-tool-loading-test.mjs +0 -250
- package/scripts/desktop-session-bridge-test.mjs +0 -1013
- package/scripts/dispatch-persist-recovery-test.mjs +0 -141
- package/scripts/embedding-worker-exit-test.mjs +0 -76
- package/scripts/execution-completion-dedup-test.mjs +0 -205
- package/scripts/execution-pending-resume-kick-test.mjs +0 -151
- package/scripts/execution-resume-esc-integration-test.mjs +0 -176
- package/scripts/explore-bench-tmp.mjs +0 -36
- package/scripts/explore-bench.mjs +0 -248
- package/scripts/explore-prompt-policy-test.mjs +0 -256
- package/scripts/explore-timeout-cancel-test.mjs +0 -345
- package/scripts/find-fuzzy-hidden-test.mjs +0 -267
- package/scripts/forwarder-rebind-tail-test.mjs +0 -67
- package/scripts/freevar-smoke.mjs +0 -98
- package/scripts/gemini-provider-test.mjs +0 -1448
- package/scripts/generate-oc-icons.mjs +0 -11
- package/scripts/grok-oauth-refresh-race-test.mjs +0 -273
- package/scripts/headless-pristine-execution-test.mjs +0 -614
- package/scripts/hook-bus-test.mjs +0 -552
- package/scripts/ingest-pure-conversation-smoke.mjs +0 -175
- package/scripts/internal-comms-bench-test.mjs +0 -226
- package/scripts/internal-comms-bench.mjs +0 -853
- package/scripts/internal-comms-smoke.mjs +0 -277
- package/scripts/internal-tools-normalization-test.mjs +0 -62
- package/scripts/interrupted-turn-history-test.mjs +0 -399
- package/scripts/lead-workflow-smoke.mjs +0 -592
- package/scripts/lifecycle-api-test.mjs +0 -137
- package/scripts/live-share-test.mjs +0 -148
- package/scripts/live-worker-smoke.mjs +0 -333
- package/scripts/log-writer-guard-smoke.mjs +0 -131
- package/scripts/maintenance-default-routes-test.mjs +0 -164
- package/scripts/max-output-recovery-persist-test.mjs +0 -81
- package/scripts/max-output-recovery-test.mjs +0 -368
- package/scripts/mcp-client-normalization-test.mjs +0 -45
- package/scripts/mcp-grace-deferred-test.mjs +0 -225
- package/scripts/memory-core-input-test.mjs +0 -167
- package/scripts/memory-cycle-routing-test.mjs +0 -111
- package/scripts/memory-meta-concurrency-test.mjs +0 -20
- package/scripts/memory-pg-recovery-test.mjs +0 -59
- package/scripts/memory-rule-contract-test.mjs +0 -93
- package/scripts/model-list-sanitize-test.mjs +0 -37
- package/scripts/mouse-tracking-restore-smoke.mjs +0 -107
- package/scripts/native-edit-wire-test.mjs +0 -152
- package/scripts/notify-completion-mirror-test.mjs +0 -73
- package/scripts/openai-oauth-refresh-race-test.mjs +0 -120
- package/scripts/openai-oauth-ws-1006-retry-test.mjs +0 -954
- package/scripts/openai-ws-early-settle-test.mjs +0 -216
- package/scripts/output-style-bench.mjs +0 -292
- package/scripts/output-style-smoke.mjs +0 -145
- package/scripts/parent-abort-link-test.mjs +0 -90
- package/scripts/patch-binary-cache-test.mjs +0 -181
- package/scripts/path-suffix-test.mjs +0 -57
- package/scripts/pending-completion-drop-test.mjs +0 -239
- package/scripts/pending-messages-lock-nonblocking-test.mjs +0 -62
- package/scripts/pretool-ask-runtime-test.mjs +0 -54
- package/scripts/process-lifecycle-test.mjs +0 -461
- package/scripts/prompt-immediate-render-test.mjs +0 -89
- package/scripts/prompt-input-parity-test.mjs +0 -145
- package/scripts/provider-admission-scheduler-test.mjs +0 -681
- package/scripts/provider-contract-test.mjs +0 -632
- package/scripts/provider-stream-stall-test.mjs +0 -276
- package/scripts/provider-toolcall-test.mjs +0 -3063
- package/scripts/reactive-compact-persist-smoke.mjs +0 -203
- package/scripts/recall-bench.mjs +0 -359
- package/scripts/resource-admission-test.mjs +0 -792
- package/scripts/result-classification-test.mjs +0 -75
- package/scripts/rg-runner-test.mjs +0 -240
- package/scripts/routing-corpus-test.mjs +0 -349
- package/scripts/sanitize-tool-pairs-test.mjs +0 -260
- package/scripts/session-bench-cache-break-test.mjs +0 -102
- package/scripts/session-bench.mjs +0 -1708
- package/scripts/session-context-bench.mjs +0 -344
- package/scripts/session-heartbeat-lifecycle-test.mjs +0 -68
- package/scripts/session-ingest-compaction-smoke.mjs +0 -279
- package/scripts/session-ingest-smoke.mjs +0 -177
- package/scripts/session-orphan-sweep-test.mjs +0 -109
- package/scripts/set-effort-config-test.mjs +0 -41
- package/scripts/shell-failure-diagnostics-test.mjs +0 -280
- package/scripts/shell-hardening-test.mjs +0 -209
- package/scripts/shell-jobs-windows-hide-test.mjs +0 -164
- package/scripts/ship-mode-test.mjs +0 -98
- package/scripts/smoke-loop-failure-summary-test.mjs +0 -38
- package/scripts/smoke-loop-failure-summary.mjs +0 -16
- package/scripts/smoke-loop-report.mjs +0 -221
- package/scripts/smoke-loop.mjs +0 -202
- package/scripts/smoke-runtime-negative.ps1 +0 -106
- package/scripts/statusline-quota-hysteresis-test.mjs +0 -62
- package/scripts/steering-drain-buckets-test.mjs +0 -467
- package/scripts/steering-fold-provenance-test.mjs +0 -71
- package/scripts/streaming-tail-window-test.mjs +0 -175
- package/scripts/submit-commandbusy-race-test.mjs +0 -257
- package/scripts/task-bench.mjs +0 -205
- package/scripts/terminal-bench-isolation-guards-test.mjs +0 -102
- package/scripts/termio-input-smoke.mjs +0 -199
- package/scripts/tool-result-hook-test.mjs +0 -48
- package/scripts/tool-smoke.mjs +0 -2453
- package/scripts/tool-tui-presentation-test.mjs +0 -286
- package/scripts/toolcall-args-test.mjs +0 -239
- package/scripts/tui-ambiguous-width-test.mjs +0 -113
- package/scripts/tui-background-failure-smoke.mjs +0 -73
- package/scripts/tui-perf-run.ps1 +0 -26
- package/scripts/tui-render-smoke.mjs +0 -90
- package/scripts/tui-runtime-load-bench-entry.jsx +0 -608
- package/scripts/tui-runtime-load-bench.mjs +0 -50
- package/scripts/tui-store-frame-batch-test.mjs +0 -99
- package/scripts/tui-transcript-jitter-harness-entry.jsx +0 -383
- package/scripts/tui-transcript-perf-test.mjs +0 -934
- package/scripts/usage-metrics-epoch-smoke.mjs +0 -114
- package/scripts/verify-release-assets-test.mjs +0 -281
- package/scripts/web-fetch-routing-test.mjs +0 -158
- package/scripts/webhook-smoke.mjs +0 -201
- package/scripts/windows-hide-spawn-options-test.mjs +0 -19
- package/scripts/worker-notify-rejection-test.mjs +0 -51
- package/scripts/write-backpressure-test.mjs +0 -147
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
|
|
26
26
|
// Human-readable transport label for handshake/acquire error messages. Shared
|
|
27
27
|
// with openai-oauth-ws.mjs (stream-side errors use the same labels).
|
|
28
|
+
import { _envOn, _codexUuidIdParity, _codexDashedId, _codexTurnStateGate, _codexDashedIdV7, _codexBetaFeatures, _dumpHandshakeHeaders, _dumpFrame, _cfCookieHeader, _cfCookieCapture } from './openai-ws-headers.mjs';
|
|
28
29
|
export function _wsErrLabel(p) {
|
|
29
30
|
if (p === 'xai') return 'xAI WS';
|
|
30
31
|
if (p === 'openai-direct' || p === 'openai') return 'OpenAI WS';
|
|
@@ -68,7 +69,7 @@ const MAX_POOLED_SOCKETS_PER_KEY = 8;
|
|
|
68
69
|
// Entry: { socket, busy, idleTimer, lastResponseId, lastRequestSansInput,
|
|
69
70
|
// lastRequestInput, lastResponseItems, lastInputLen, turnState,
|
|
70
71
|
// closing, ephemeral }
|
|
71
|
-
const _wsPool = new Map();
|
|
72
|
+
export const _wsPool = new Map();
|
|
72
73
|
let _releaseSequence = 0;
|
|
73
74
|
|
|
74
75
|
function _poolCompatibility(auth, cacheKey) {
|
|
@@ -119,193 +120,6 @@ function _selectIdleEntry(entries, compatibility) {
|
|
|
119
120
|
// (opencode request.ts:187, ws-pool.ts:66)
|
|
120
121
|
// MIXDOG_OAI_WS_URL_SESSION=0 drop the ?session_id= URL query (codex/pi/
|
|
121
122
|
// opencode all use the bare WS URL)
|
|
122
|
-
const _cfCookieJar = new Map(); // accountKey -> { name -> value }
|
|
123
|
-
const _CF_COOKIE_ALLOWLIST = new Set(['__cf_bm', '_cfuvid']);
|
|
124
|
-
|
|
125
|
-
function _envOn(name) {
|
|
126
|
-
const v = String(process.env[name] || '').trim().toLowerCase();
|
|
127
|
-
return ['1', 'true', 'yes', 'on'].includes(v);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// --- Opt-in Codex fingerprint/id parity knobs ------------------------------
|
|
131
|
-
// All default OFF; unset envs leave the winning combo
|
|
132
|
-
// (MIXDOG_OAI_CODEX_WIRE_PARITY=1 + ws-delta + underscore session_id) exactly
|
|
133
|
-
// as-is. These add EXTRA parity dimensions for backend fingerprint probes.
|
|
134
|
-
|
|
135
|
-
// codex sends dashed RFC-4122 UUIDs as session-id/thread-id (client.rs:1033-
|
|
136
|
-
// 1057); we key those dashed handshake headers off the underscore cacheKey by
|
|
137
|
-
// default. Opt in with MIXDOG_OAI_CODEX_WIRE_PARITY_UUID_IDS to reshape ONLY
|
|
138
|
-
// the dashed pair (session-id/thread-id/x-client-request-id) into codex's UUID
|
|
139
|
-
// format. The value is derived deterministically from the id so it stays
|
|
140
|
-
// stable per cache key (prefix-cache continuity preserved), and the underscore
|
|
141
|
-
// `session_id` header (the backend prefix-dedupe key) is left untouched.
|
|
142
|
-
function _codexUuidIdParity() {
|
|
143
|
-
const v = String(process.env.MIXDOG_OAI_CODEX_WIRE_PARITY_UUID_IDS || '').trim().toLowerCase();
|
|
144
|
-
return ['1', 'true', 'yes', 'on', 'uuid', 'dashed'].includes(v);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function _codexDashedId(value) {
|
|
148
|
-
const h = createHash('sha256').update(String(value)).digest();
|
|
149
|
-
const b = Buffer.from(h.subarray(0, 16));
|
|
150
|
-
b[6] = (b[6] & 0x0f) | 0x50; // version 5 nibble
|
|
151
|
-
b[8] = (b[8] & 0x3f) | 0x80; // RFC-4122 variant
|
|
152
|
-
const hex = b.toString('hex');
|
|
153
|
-
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Opt-in turn-state gate experiment bundle (MIXDOG_OAI_CODEX_TURN_STATE_GATE).
|
|
157
|
-
// The debugger's working hypothesis for what gates x-codex-turn-state issuance
|
|
158
|
-
// is a specific wire shape: Codex-shaped UUIDv7 session/thread ids + dashed-only
|
|
159
|
-
// handshake headers (drop the underscore session_id) + NO duplicated
|
|
160
|
-
// x-client-request-id + a parent-thread header (added in openai-oauth-ws.mjs).
|
|
161
|
-
// This env ties those dimensions together as ONE experiment so operators can
|
|
162
|
-
// A/B the whole gate shape without hand-composing four flags. Default OFF; it
|
|
163
|
-
// leaves MIXDOG_OAI_CODEX_WIRE_PARITY_UUID_IDS / _SESSION_ID and every existing
|
|
164
|
-
// flag intact and only reshapes the wire when explicitly enabled.
|
|
165
|
-
function _codexTurnStateGate() {
|
|
166
|
-
const v = String(process.env.MIXDOG_OAI_CODEX_TURN_STATE_GATE || '').trim().toLowerCase();
|
|
167
|
-
return ['1', 'true', 'yes', 'on'].includes(v);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Same derivation as _codexDashedId but stamps the version-7 nibble so the
|
|
171
|
-
// dashed pair reads as a Codex-shaped UUIDv7. Deterministic per id (prefix
|
|
172
|
-
// cache continuity preserved); only used under the turn-state gate bundle.
|
|
173
|
-
function _codexDashedIdV7(value) {
|
|
174
|
-
const h = createHash('sha256').update(String(value)).digest();
|
|
175
|
-
const b = Buffer.from(h.subarray(0, 16));
|
|
176
|
-
b[6] = (b[6] & 0x0f) | 0x70; // version 7 nibble
|
|
177
|
-
b[8] = (b[8] & 0x3f) | 0x80; // RFC-4122 variant
|
|
178
|
-
const hex = b.toString('hex');
|
|
179
|
-
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// codex advertises enabled beta features on the WS handshake; the backend
|
|
183
|
-
// plausibly gates x-codex-turn-state issuance on that list (see the
|
|
184
|
-
// x-codex-beta-features comment below). MIXDOG_CODEX_BETA_FEATURES replaces the
|
|
185
|
-
// whole list; MIXDOG_OAI_CODEX_TURN_STATE_FEATURES is a safe ADD-ONLY opt-in
|
|
186
|
-
// that appends turn-state-gating feature token(s) (comma-separated, de-duped)
|
|
187
|
-
// without dropping the default `remote_compaction_v2`. Unset = default list.
|
|
188
|
-
function _codexBetaFeatures() {
|
|
189
|
-
const base = process.env.MIXDOG_CODEX_BETA_FEATURES || 'remote_compaction_v2';
|
|
190
|
-
const extra = String(process.env.MIXDOG_OAI_CODEX_TURN_STATE_FEATURES || '').trim();
|
|
191
|
-
if (!extra) return base;
|
|
192
|
-
const seen = new Set();
|
|
193
|
-
const out = [];
|
|
194
|
-
for (const tok of `${base},${extra}`.split(',').map((s) => s.trim()).filter(Boolean)) {
|
|
195
|
-
if (seen.has(tok)) continue;
|
|
196
|
-
seen.add(tok);
|
|
197
|
-
out.push(tok);
|
|
198
|
-
}
|
|
199
|
-
return out.join(',');
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// --- Opt-in raw WS capture for byte-diff against codex-rs -------------------
|
|
203
|
-
// Enabled ONLY when MIXDOG_OAI_WS_DUMP_DIR names a directory. Persists the
|
|
204
|
-
// (redacted) handshake header metadata and the exact serialized
|
|
205
|
-
// response.create frame bytes so our wire format can be byte-diffed against
|
|
206
|
-
// codex. Secrets (Authorization / Cookie / account-id / routing tokens) are
|
|
207
|
-
// hashed, never written in clear. When the env is unset both helpers are
|
|
208
|
-
// no-ops, so there is no default behavior change.
|
|
209
|
-
const _WS_DUMP_SECRET_RE = /^(authorization|proxy-authorization|cookie|set-cookie|chatgpt-account-id|x-codex-turn-state|session_id|session-id|thread-id|x-codex-parent-thread-id|x-client-request-id|x-session-affinity)$/i;
|
|
210
|
-
|
|
211
|
-
function _wsDumpDir() {
|
|
212
|
-
const dir = String(process.env.MIXDOG_OAI_WS_DUMP_DIR || '').trim();
|
|
213
|
-
return dir || null;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
function _redactHeaderValue(key, value) {
|
|
217
|
-
const v = String(value ?? '');
|
|
218
|
-
if (_WS_DUMP_SECRET_RE.test(String(key))) {
|
|
219
|
-
if (!v) return '';
|
|
220
|
-
return `<redacted:sha256:${createHash('sha256').update(v).digest('hex').slice(0, 12)}:len${v.length}>`;
|
|
221
|
-
}
|
|
222
|
-
return v;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
function _redactDumpUrl(url) {
|
|
226
|
-
try {
|
|
227
|
-
const parsed = new URL(String(url));
|
|
228
|
-
for (const [key, value] of parsed.searchParams.entries()) {
|
|
229
|
-
if (_WS_DUMP_SECRET_RE.test(String(key))) {
|
|
230
|
-
parsed.searchParams.set(key, _redactHeaderValue(key, value));
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
return parsed.toString();
|
|
234
|
-
} catch {
|
|
235
|
-
return String(url || '');
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
function _dumpHandshakeHeaders(url, headers) {
|
|
240
|
-
const dir = _wsDumpDir();
|
|
241
|
-
if (!dir) return;
|
|
242
|
-
try {
|
|
243
|
-
mkdirSync(dir, { recursive: true });
|
|
244
|
-
const redacted = {};
|
|
245
|
-
for (const [k, v] of Object.entries(headers || {})) redacted[k] = _redactHeaderValue(k, v);
|
|
246
|
-
const rec = {
|
|
247
|
-
ts: new Date().toISOString(),
|
|
248
|
-
kind: 'ws_handshake',
|
|
249
|
-
url: _redactDumpUrl(url),
|
|
250
|
-
// Header order matters for the codex byte-diff; keep it explicit.
|
|
251
|
-
headerOrder: Object.keys(headers || {}),
|
|
252
|
-
headers: redacted,
|
|
253
|
-
};
|
|
254
|
-
const stamp = `${Date.now()}-${randomBytes(4).toString('hex')}`;
|
|
255
|
-
writeFileSync(join(dir, `handshake-${stamp}.json`), JSON.stringify(rec, null, 2));
|
|
256
|
-
} catch {}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
function _dumpFrame(payload) {
|
|
260
|
-
const dir = _wsDumpDir();
|
|
261
|
-
if (!dir) return;
|
|
262
|
-
try {
|
|
263
|
-
mkdirSync(dir, { recursive: true });
|
|
264
|
-
const stamp = `${Date.now()}-${randomBytes(4).toString('hex')}`;
|
|
265
|
-
// Persist the serialized response.create bytes for codex byte-diff,
|
|
266
|
-
// but never dump x-codex-turn-state in clear. That token is a
|
|
267
|
-
// per-turn credential-like routing secret; header dumps already hash
|
|
268
|
-
// it, so frame dumps must do the same when client_metadata carries it.
|
|
269
|
-
let out = payload;
|
|
270
|
-
try {
|
|
271
|
-
const frame = JSON.parse(String(payload));
|
|
272
|
-
const meta = frame?.client_metadata;
|
|
273
|
-
if (meta && typeof meta === 'object' && typeof meta['x-codex-turn-state'] === 'string') {
|
|
274
|
-
meta['x-codex-turn-state'] = _redactHeaderValue('x-codex-turn-state', meta['x-codex-turn-state']);
|
|
275
|
-
out = JSON.stringify(frame);
|
|
276
|
-
}
|
|
277
|
-
} catch {}
|
|
278
|
-
writeFileSync(join(dir, `frame-${stamp}.json`), out);
|
|
279
|
-
} catch {}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
function _cfCookieAccountKey(auth) {
|
|
283
|
-
return String(auth?.account_id || auth?.apiKey || 'default');
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
function _cfCookieHeader(auth) {
|
|
287
|
-
if (!_envOn('MIXDOG_OAI_CF_COOKIES')) return null;
|
|
288
|
-
const jar = _cfCookieJar.get(_cfCookieAccountKey(auth));
|
|
289
|
-
if (!jar || !jar.size) return null;
|
|
290
|
-
return [...jar.entries()].map(([k, v]) => `${k}=${v}`).join('; ');
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
function _cfCookieCapture(auth, setCookieHeaders) {
|
|
294
|
-
if (!_envOn('MIXDOG_OAI_CF_COOKIES')) return;
|
|
295
|
-
const list = Array.isArray(setCookieHeaders) ? setCookieHeaders : (setCookieHeaders ? [setCookieHeaders] : []);
|
|
296
|
-
if (!list.length) return;
|
|
297
|
-
const key = _cfCookieAccountKey(auth);
|
|
298
|
-
let jar = _cfCookieJar.get(key);
|
|
299
|
-
if (!jar) { jar = new Map(); _cfCookieJar.set(key, jar); }
|
|
300
|
-
for (const raw of list) {
|
|
301
|
-
const pair = String(raw || '').split(';', 1)[0];
|
|
302
|
-
const eq = pair.indexOf('=');
|
|
303
|
-
if (eq <= 0) continue;
|
|
304
|
-
const name = pair.slice(0, eq).trim();
|
|
305
|
-
if (_CF_COOKIE_ALLOWLIST.has(name)) jar.set(name, pair.slice(eq + 1).trim());
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
123
|
function _getPoolArr(poolKey) {
|
|
310
124
|
if (!poolKey) return null;
|
|
311
125
|
let arr = _wsPool.get(poolKey);
|
|
@@ -85,7 +85,7 @@ export {
|
|
|
85
85
|
// inter-chunk / reasoning span keeps the longer deadlines below.
|
|
86
86
|
// Positive-int coercion for per-call timeout overrides: finite > 0 → floor,
|
|
87
87
|
// else fallback.
|
|
88
|
-
|
|
88
|
+
function _positiveInt(value, fallback = 0) {
|
|
89
89
|
const n = Number(value);
|
|
90
90
|
return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;
|
|
91
91
|
}
|
|
@@ -102,7 +102,7 @@ export const WS_INTER_CHUNK_MS = PROVIDER_WS_INTER_CHUNK_TIMEOUT_MS;
|
|
|
102
102
|
// The ws library has already assembled the Buffer by this point, so this check
|
|
103
103
|
// must stay before data.toString() below. xAI shares this stream implementation
|
|
104
104
|
// but retains its existing unbounded behavior.
|
|
105
|
-
|
|
105
|
+
const OPENAI_WS_MAX_INCOMING_FRAME_BYTES = 16 * 1024 * 1024;
|
|
106
106
|
const X_CODEX_TURN_STATE_HEADER = 'x-codex-turn-state';
|
|
107
107
|
const WS_TRACE_ENABLED = process.env.MIXDOG_WS_TRACE === '1';
|
|
108
108
|
|
|
@@ -31,12 +31,12 @@ const OPENAI_DIRECT_PRIORITY_MODEL_PATTERNS = Object.freeze([
|
|
|
31
31
|
/^gpt-5\.4-mini(?:-\d{4}|$)/,
|
|
32
32
|
]);
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
function openAiDirectSupportsPriority(model) {
|
|
35
35
|
const id = String(model || '').trim();
|
|
36
36
|
return OPENAI_DIRECT_PRIORITY_MODEL_PATTERNS.some(re => re.test(id));
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
function applyOpenAIDirectFastTier(body, model, opts) {
|
|
40
40
|
if (opts?.fast === true && openAiDirectSupportsPriority(model)) {
|
|
41
41
|
body.service_tier = 'priority';
|
|
42
42
|
}
|
|
@@ -41,7 +41,7 @@ export function openCodeGoEndpointForModel(model, configuredBaseURL) {
|
|
|
41
41
|
: `${bases.openai}/chat/completions`;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
function normalizeOpenCodeGoResultUsage(result, anthropicRoute) {
|
|
45
45
|
if (!anthropicRoute || !result?.usage) return result;
|
|
46
46
|
const usage = result.usage;
|
|
47
47
|
const input = Number(usage.inputTokens) || 0;
|
|
@@ -44,7 +44,7 @@ function rowId(row) {
|
|
|
44
44
|
return String(row?.id || row?.name || row?.slug || '').trim();
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
function getProviderCachedModelSync(provider, model) {
|
|
48
48
|
const p = String(provider || '').toLowerCase();
|
|
49
49
|
const files = PROVIDER_CACHE_FILES[p] || [];
|
|
50
50
|
if (!files.length || !model) return null;
|
|
@@ -316,7 +316,7 @@ export function _withLoadedProviderCtorForTest(name, Ctor, fn) {
|
|
|
316
316
|
// agent.init() after providers are registered so the first agent dispatch call
|
|
317
317
|
// (e.g. cycle1 on session start) does not pay the catalog refresh latency
|
|
318
318
|
// inline. Fire-and-forget: failures are logged inside each provider.
|
|
319
|
-
|
|
319
|
+
function warmupCatalogs() {
|
|
320
320
|
const metadataReady = Promise.resolve()
|
|
321
321
|
.then(() => warmModelMetadataCatalogs())
|
|
322
322
|
.catch((err) => {
|
|
@@ -274,7 +274,7 @@ function isPermanentQuotaError(err) {
|
|
|
274
274
|
* oauth's MAX_ATTEMPTS, openai-oauth-ws's mid-stream classifier) still gate
|
|
275
275
|
* on attempt count separately; this helper only answers the kind question.
|
|
276
276
|
*/
|
|
277
|
-
|
|
277
|
+
function isRetryable(err) {
|
|
278
278
|
return classifyError(err) === 'transient'
|
|
279
279
|
}
|
|
280
280
|
|
|
@@ -304,7 +304,7 @@ export function anthropicRequestTimeoutMs() {
|
|
|
304
304
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : 600_000
|
|
305
305
|
}
|
|
306
306
|
|
|
307
|
-
|
|
307
|
+
const ANTHROPIC_MAX_CONSECUTIVE_529 = 3
|
|
308
308
|
|
|
309
309
|
export class AnthropicFallbackTriggeredError extends Error {
|
|
310
310
|
constructor(originalModel, fallbackModel, cause) {
|
|
@@ -19,7 +19,7 @@ async function loadRouteMetaModule() {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/** Await before calling the sync exports when route-meta may not be ready yet. */
|
|
22
|
-
|
|
22
|
+
async function ensureStatuslineRouteMetaLoaded() {
|
|
23
23
|
return loadRouteMetaModule();
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -131,7 +131,7 @@ export function invalidatePrefetchCache(path, cwd) {
|
|
|
131
131
|
_deleteDiskEntry(abs);
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
function drainPrefetchDiskWrites() {
|
|
135
135
|
if (_diskWriteTimer !== null) {
|
|
136
136
|
clearTimeout(_diskWriteTimer);
|
|
137
137
|
_diskWriteTimer = null;
|
|
@@ -326,7 +326,7 @@ export function clearScopedCounters(sessionId) {
|
|
|
326
326
|
* Configure the data directory for snapshot writes. Must be called once at
|
|
327
327
|
* startup. Safe to call repeatedly.
|
|
328
328
|
*/
|
|
329
|
-
|
|
329
|
+
function configureCacheStatsSnapshot(dataDir) {
|
|
330
330
|
_snapshotDataDir = typeof dataDir === 'string' && dataDir.length > 0 ? dataDir : null;
|
|
331
331
|
}
|
|
332
332
|
|
|
@@ -334,7 +334,7 @@ export function configureCacheStatsSnapshot(dataDir) {
|
|
|
334
334
|
* Aggregate all live session counters into totals + per-session breakdown.
|
|
335
335
|
* Pure computation — no I/O. Exported for tests.
|
|
336
336
|
*/
|
|
337
|
-
|
|
337
|
+
function aggregateCacheStats() {
|
|
338
338
|
const totals = { sets: 0, hits: 0, misses: 0, clears: 0 };
|
|
339
339
|
const perSession = [];
|
|
340
340
|
for (const [sessionId, c] of _scopedCounters) {
|
|
@@ -379,7 +379,7 @@ function _scheduleCacheStatsFlush() {
|
|
|
379
379
|
}
|
|
380
380
|
|
|
381
381
|
/** Sync-flush pending cache-stats snapshot on exit. */
|
|
382
|
-
|
|
382
|
+
function drainCacheStats() {
|
|
383
383
|
if (_snapshotTimer === null) return;
|
|
384
384
|
clearTimeout(_snapshotTimer);
|
|
385
385
|
_snapshotTimer = null;
|
|
@@ -36,8 +36,8 @@ const PRUNE_TOOL_OUTPUT_MAX_CHARS = 2_000;
|
|
|
36
36
|
const PRUNE_TOOL_OUTPUT_HEAD_CHARS = 1_000;
|
|
37
37
|
const PRUNE_TOOL_OUTPUT_TAIL_CHARS = 600;
|
|
38
38
|
const PRUNE_TAIL_TURNS = 2;
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
const MIN_PRESERVE_RECENT_TOKENS = 2_000;
|
|
40
|
+
const PRESERVED_FACTS_MAX_CHARS = 600;
|
|
41
41
|
|
|
42
42
|
function preservedFactHints() {
|
|
43
43
|
return String(process.env.MIXDOG_COMPACT_FACT_HINTS || '')
|
|
@@ -13,7 +13,7 @@ import { isAbsolute, resolve as resolvePath } from 'node:path';
|
|
|
13
13
|
import { estimateTokens } from '../context-utils.mjs';
|
|
14
14
|
|
|
15
15
|
export const MAX_REATTACH_FILES = 3;
|
|
16
|
-
|
|
16
|
+
const REATTACH_MAX_TOKENS_PER_FILE = 5_000;
|
|
17
17
|
export const REATTACH_MAX_TOTAL_TOKENS = 8_000;
|
|
18
18
|
const REATTACH_MIN_ROOM_TOKENS = 1_024;
|
|
19
19
|
const REATTACH_MAX_FILE_BYTES = 512 * 1024;
|
|
@@ -41,7 +41,7 @@ function pathsFromReadArgs(rawArgs) {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
// Ordered (oldest -> newest) file paths read via the `read` tool in `messages`.
|
|
44
|
-
|
|
44
|
+
function collectReadToolPaths(messages) {
|
|
45
45
|
const out = [];
|
|
46
46
|
for (const m of Array.isArray(messages) ? messages : []) {
|
|
47
47
|
if (m?.role !== 'assistant' || !Array.isArray(m.toolCalls)) continue;
|
|
@@ -45,7 +45,7 @@ function summaryHeadingLines(summary) {
|
|
|
45
45
|
// Preferences` satisfy the `## Constraints` anchor while NOT letting an
|
|
46
46
|
// unrelated `## Goalkeeper` heading satisfy `## Goal`. Requires a real `## `
|
|
47
47
|
// heading line (not a substring buried in prose).
|
|
48
|
-
|
|
48
|
+
function headingMatchesAnchor(heading, anchor) {
|
|
49
49
|
const anchorTitle = anchor.replace(/^##\s+/, '').trim().toLowerCase();
|
|
50
50
|
const headingTitle = heading.replace(/^##\s+/, '').trim().toLowerCase();
|
|
51
51
|
if (headingTitle === anchorTitle) return true;
|
|
@@ -90,7 +90,7 @@ function transcriptLineForCompaction(m, index, perMessageChars) {
|
|
|
90
90
|
return `${index + 1}. ${role}${meta}:\n${text}`;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
function buildCompactionPrompt({ head, previousSummary, preservedFacts }, perMessageChars) {
|
|
94
94
|
const lines = [
|
|
95
95
|
previousSummary
|
|
96
96
|
? 'Update the anchored summary below using the conversation history that follows. Preserve still-true details, remove stale details, and merge in the new facts.'
|
|
@@ -6,9 +6,9 @@ import { estimateMessagesTokens } from '../context-utils.mjs';
|
|
|
6
6
|
const TOOL_ARG_STRING_MAX_CHARS = 360;
|
|
7
7
|
const TOOL_ARG_ARRAY_MAX_ITEMS = 8;
|
|
8
8
|
const TOOL_ARG_MAX_DEPTH = 4;
|
|
9
|
-
|
|
9
|
+
const TOOL_CALL_ARGS_MAX_CHARS = 260;
|
|
10
10
|
export const TOOL_CALL_FACT_ARGS_MAX_CHARS = 140;
|
|
11
|
-
|
|
11
|
+
const TOOL_CALLS_MAX = 4;
|
|
12
12
|
const SENSITIVE_TOOL_ARG_KEY_RE = /(?:^|[_-])(?:api[_-]?key|authorization|auth|cookie|credential|passwd|password|refresh[_-]?token|secret|token)(?:$|[_-])/i;
|
|
13
13
|
// Word alternation for raw-string (non-JSON) secret redaction. Mirrors the
|
|
14
14
|
// keys in SENSITIVE_TOOL_ARG_KEY_RE and the session-ingest redactor so a raw
|
|
@@ -28,7 +28,7 @@ export {
|
|
|
28
28
|
// Token estimation: real o200k_base BPE (tiktoken) + per-provider calibration.
|
|
29
29
|
//
|
|
30
30
|
// estimateTokens() encodes the provider-visible text projection with the real
|
|
31
|
-
// o200k_base BPE (tiktoken, same approach as
|
|
31
|
+
// o200k_base BPE (tiktoken, same approach as mainstream agent UIs), so
|
|
32
32
|
// estimates track actual billing instead of a weighted-chars heuristic that
|
|
33
33
|
// diverged -25%..+60% depending on script and provider. The residual
|
|
34
34
|
// provider-specific gap between an o200k count and billed prompt tokens is
|
|
@@ -71,7 +71,7 @@ function bpeEncoder() {
|
|
|
71
71
|
|
|
72
72
|
// Compaction budget loops re-estimate overlapping transcript slices; identical
|
|
73
73
|
// large strings (tool results, system blocks) would re-encode every pass.
|
|
74
|
-
// Hash-keyed LRU
|
|
74
|
+
// Hash-keyed LRU absorbs the repeats.
|
|
75
75
|
const TOKEN_COUNT_CACHE_MIN_CHARS = 512;
|
|
76
76
|
const TOKEN_COUNT_CACHE_MAX_ENTRIES = 1_024;
|
|
77
77
|
const tokenCountCache = new Map();
|
|
@@ -283,7 +283,7 @@ function nativeBlocksEstimateText(value) {
|
|
|
283
283
|
catch { return String(block ?? ''); }
|
|
284
284
|
}).join('\n');
|
|
285
285
|
}
|
|
286
|
-
|
|
286
|
+
function messageEstimateText(m) {
|
|
287
287
|
if (!m || typeof m !== 'object') return '';
|
|
288
288
|
// Multimodal image payloads remain on the live message for provider sends,
|
|
289
289
|
// but their base64/data-url JSON is not text and must not dominate local
|
|
@@ -361,7 +361,7 @@ function messageFileAllowance(m) {
|
|
|
361
361
|
Math.max(FILE_TOKEN_ALLOWANCE_FLOOR, Math.ceil((descriptor.sizeBytes || 0) / 16)),
|
|
362
362
|
), 0);
|
|
363
363
|
}
|
|
364
|
-
|
|
364
|
+
function estimateMessageTokens(m) {
|
|
365
365
|
return estimateTokens(messageEstimateText(m)) + messageImageAllowance(m) + messageFileAllowance(m) + 4;
|
|
366
366
|
}
|
|
367
367
|
export function estimateMessagesTokens(messages) {
|
|
@@ -31,7 +31,7 @@ export function isOnDeferredToolSurface(session, name) {
|
|
|
31
31
|
return isActiveSessionTool(session, name) || lookupDeferredCatalogTool(session, name) !== null;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
function toolExecutesWhenInactive(name) {
|
|
35
35
|
return INACTIVE_INFRA_BYPASS.has(name);
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -27,6 +27,20 @@ const WORKER_DENIED_TOOLS = new Set([
|
|
|
27
27
|
]);
|
|
28
28
|
|
|
29
29
|
const IMAGE_PATH_RE = /\.(?:png|jpe?g|gif|webp)(?:$|[?#])/i;
|
|
30
|
+
const COMPACTED_PATCH_LINE_RE = /^\s*\[mixdog compacted\b[^\]\n]*\]/;
|
|
31
|
+
|
|
32
|
+
function hasCompactedPatchPlaceholder(call) {
|
|
33
|
+
if (call?.name !== 'apply_patch') return false;
|
|
34
|
+
const value = typeof call?.arguments === 'string'
|
|
35
|
+
? call.arguments
|
|
36
|
+
: call?.arguments?.patch;
|
|
37
|
+
if (typeof value !== 'string') return false;
|
|
38
|
+
for (const line of value.split(/\r?\n/)) {
|
|
39
|
+
if (line.startsWith('+') || line.startsWith('-') || line.startsWith(' ')) continue;
|
|
40
|
+
if (COMPACTED_PATCH_LINE_RE.test(line)) return true;
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
30
44
|
|
|
31
45
|
function callUrls(call) {
|
|
32
46
|
const value = call?.arguments?.url;
|
|
@@ -67,6 +81,9 @@ export function routeWebFetchCall(call) {
|
|
|
67
81
|
function _preDispatchDeny(call, toolKind, sessionRef) {
|
|
68
82
|
const name = call?.name;
|
|
69
83
|
if (typeof name !== 'string' || !name) return null;
|
|
84
|
+
if (hasCompactedPatchPlaceholder(call)) {
|
|
85
|
+
return 'Error: [tool-input-validation] apply_patch received a compacted-history placeholder, not executable patch content. Re-read the current target files and submit a fresh full patch; do not replay or reconstruct the stored marker.';
|
|
86
|
+
}
|
|
70
87
|
const _agentOwned = sessionRef?.scope?.startsWith?.('agent:')
|
|
71
88
|
|| isAgentOwner(sessionRef);
|
|
72
89
|
const _controlPlaneTool = WORKER_DENIED_TOOLS.has(name);
|
|
@@ -14,7 +14,7 @@ export function steeringContentText(content) {
|
|
|
14
14
|
return String(content ?? '');
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
function normalizeSteeringEntry(entry) {
|
|
18
18
|
if (typeof entry === 'string') {
|
|
19
19
|
const text = entry.trim();
|
|
20
20
|
return text ? { content: text, text } : null;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Stored tool-call argument compaction/restoration, extracted from loop.mjs.
|
|
2
2
|
// Long body/command args are truncated with a sha256-tagged head/tail preview
|
|
3
|
-
// when persisted into assistant history
|
|
4
|
-
//
|
|
3
|
+
// when persisted into assistant history. Failed command/script calls may
|
|
4
|
+
// restore their full text, but mutation bodies stay compacted so stale patches
|
|
5
|
+
// cannot be replayed from history.
|
|
5
6
|
import { createHash } from 'crypto';
|
|
6
7
|
|
|
7
8
|
const STORED_TOOL_ARG_BODY_KEY_RE = /^(?:content|old_string|new_string|patch|rewrite)$/i;
|
|
@@ -23,8 +24,8 @@ function compactStoredToolArgString(value, key = '') {
|
|
|
23
24
|
// apply_patch / edit inputs. Keeping a head/tail preview leaves real patch
|
|
24
25
|
// fragments (a "*** Begin Patch" opening, diff lines) inside a SUCCESSFUL
|
|
25
26
|
// history entry that the model can copy back verbatim as new tool input.
|
|
26
|
-
// Emit the marker ALONE for these keys so nothing copyable survives
|
|
27
|
-
//
|
|
27
|
+
// Emit the marker ALONE for these keys so nothing copyable survives,
|
|
28
|
+
// including after a failed call.
|
|
28
29
|
if (isBody) return marker;
|
|
29
30
|
const head = value.slice(0, STORED_TOOL_ARG_PREVIEW_HEAD).replace(/\r\n/g, '\n');
|
|
30
31
|
const tail = value.slice(-STORED_TOOL_ARG_PREVIEW_TAIL).replace(/\r\n/g, '\n');
|
|
@@ -57,21 +58,15 @@ export function compactToolCallsForHistory(calls) {
|
|
|
57
58
|
});
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
// Restore
|
|
61
|
-
// whose toolCalls were compacted at push time.
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
//
|
|
61
|
+
// Restore retry-safe long command/script text for ONE failed tool call inside a
|
|
62
|
+
// history assistant message whose toolCalls were compacted at push time.
|
|
63
|
+
// Mutation bodies (patch, old_string, new_string, content, rewrite) deliberately
|
|
64
|
+
// remain compacted: replaying their stale pre-failure text can repeat partial
|
|
65
|
+
// writes or overwrite newer state. Must run BEFORE the message is first
|
|
66
|
+
// transmitted so it never mutates an already-cached prefix.
|
|
66
67
|
//
|
|
67
|
-
// Only
|
|
68
|
-
//
|
|
69
|
-
// recursive (compactStoredToolArgValue), so batch shapes like edits[].old_string
|
|
70
|
-
// or writes[].content carry nested compacted bodies too. Every other field
|
|
71
|
-
// (e.g. `path`, which a tool may mutate in place during execution) is taken from
|
|
72
|
-
// the compacted snapshot captured at push time, before any mutation. The
|
|
73
|
-
// compacted args tree is built fresh by compactToolCallsForHistory and is not
|
|
74
|
-
// shared with originalCalls, so rebuilding it here is safe.
|
|
68
|
+
// Only command/script keys are restored, at ANY depth. Every body key and every
|
|
69
|
+
// other field is taken from the compacted snapshot captured at push time.
|
|
75
70
|
export function restoreToolCallBodyForId(assistantMsg, originalCalls, callId) {
|
|
76
71
|
if (!assistantMsg || !Array.isArray(assistantMsg.toolCalls) || !callId) return;
|
|
77
72
|
if (!Array.isArray(originalCalls)) return;
|
|
@@ -83,15 +78,12 @@ export function restoreToolCallBodyForId(assistantMsg, originalCalls, callId) {
|
|
|
83
78
|
tc.arguments = _restoreCompactedBodies(tc.arguments, orig.arguments, '');
|
|
84
79
|
}
|
|
85
80
|
|
|
86
|
-
// Recursively rebuild a compacted args tree: replace ONLY
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
// the same structure (compaction only shortens body strings), so the walk
|
|
90
|
-
// descends them in parallel; a missing or non-object origVal falls back to the
|
|
91
|
-
// compacted value rather than throwing.
|
|
81
|
+
// Recursively rebuild a compacted args tree: replace ONLY retry-safe long
|
|
82
|
+
// command/script fields with their full originals and keep mutation bodies plus
|
|
83
|
+
// every other field from the compacted snapshot.
|
|
92
84
|
function _restoreCompactedBodies(tcVal, origVal, key) {
|
|
93
|
-
if (
|
|
94
|
-
|
|
85
|
+
if (STORED_TOOL_ARG_BODY_KEY_RE.test(key)) return tcVal;
|
|
86
|
+
if (STORED_TOOL_ARG_LONG_KEY_RE.test(key) && typeof origVal === 'string') {
|
|
95
87
|
return origVal;
|
|
96
88
|
}
|
|
97
89
|
if (Array.isArray(tcVal) && Array.isArray(origVal)) {
|
|
@@ -15,7 +15,7 @@ export const INCOMPLETE_STOP_REASONS = new Set([
|
|
|
15
15
|
// Gemini OTHER is intentionally opaque; neither is safe to treat as a token-cap
|
|
16
16
|
// continuation. Compare case-insensitively so provider spelling variants do not
|
|
17
17
|
// create a second policy.
|
|
18
|
-
|
|
18
|
+
const OUTPUT_LIMIT_STOP_REASONS = new Set([
|
|
19
19
|
'length', 'max_tokens', 'max_output_tokens',
|
|
20
20
|
]);
|
|
21
21
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// loop.mjs. These drive cross-turn read dedup, scoped caching, shell routing,
|
|
3
3
|
// and duplicate-call detection. Strips the MCP prefix so direct calls and
|
|
4
4
|
// MCP-wrapped calls share the same cache.
|
|
5
|
-
|
|
5
|
+
const MCP_TOOL_PREFIX = 'mcp__plugin_mixdog_mixdog__';
|
|
6
6
|
|
|
7
7
|
export function _stripMcpPrefix(name) {
|
|
8
8
|
return typeof name === 'string' && name.startsWith(MCP_TOOL_PREFIX)
|
|
@@ -21,7 +21,7 @@ export function _isMutationTool(name) {
|
|
|
21
21
|
// shell/bash_session, write/edit-style tools, and any (non-mixdog) MCP tool
|
|
22
22
|
// whose effects are unknown. Kept separate from _isMutationTool, which stays
|
|
23
23
|
// apply_patch-only for epoch-mutation counting and eager-dispatch gating.
|
|
24
|
-
|
|
24
|
+
const ORDERED_GATE_SAFE_READONLY_TOOLS = new Set([
|
|
25
25
|
'read',
|
|
26
26
|
'find',
|
|
27
27
|
'glob',
|
|
@@ -40,7 +40,7 @@ export const ORDERED_GATE_SAFE_READONLY_TOOLS = new Set([
|
|
|
40
40
|
export function _isOrderedGateSkippable(name) {
|
|
41
41
|
return !ORDERED_GATE_SAFE_READONLY_TOOLS.has(_stripMcpPrefix(name));
|
|
42
42
|
}
|
|
43
|
-
|
|
43
|
+
const SCOPED_CACHEABLE_TOOLS = new Set([
|
|
44
44
|
'code_graph',
|
|
45
45
|
'grep',
|
|
46
46
|
'list',
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
semanticCompactionEnabledForSession,
|
|
25
25
|
compactTypeForSession,
|
|
26
26
|
} from './context-meta.mjs';
|
|
27
|
+
import { resolveSemanticSummaryModel } from '../loop/compact-policy.mjs';
|
|
27
28
|
import { uncachedInputTokensForProvider } from './usage-metrics.mjs';
|
|
28
29
|
import { pruneOffloadSession } from '../tool-result-offload.mjs';
|
|
29
30
|
import { _getPendingMessagesForSession } from './pending-messages.mjs';
|
|
@@ -42,7 +42,7 @@ const CONTEXT_WINDOWS = {
|
|
|
42
42
|
// (llama/mistral/phi/qwen/gemma) stay small so an unknown local id never claims
|
|
43
43
|
// a giant window.
|
|
44
44
|
const LOCAL_PROVIDERS = new Set(['ollama', 'lmstudio', 'llamacpp', 'llama.cpp', 'local', '']);
|
|
45
|
-
|
|
45
|
+
function guessContextWindow(model, provider = null) {
|
|
46
46
|
if (CONTEXT_WINDOWS[model])
|
|
47
47
|
return CONTEXT_WINDOWS[model];
|
|
48
48
|
const m = String(model || '').toLowerCase();
|
|
@@ -31,7 +31,7 @@ const DELIVERED_MAX_ENTRIES = 512;
|
|
|
31
31
|
// oldest key is always the first — used for bounded-size eviction.
|
|
32
32
|
const _delivered = new Map();
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
function hashCompletionText(text) {
|
|
35
35
|
const value = String(text ?? '').trim();
|
|
36
36
|
if (!value) return null;
|
|
37
37
|
return createHash('sha1').update(value).digest('hex');
|