mixdog 1.2.2 → 1.2.3
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 +18 -0
- package/package.json +2 -1
- package/scripts/provider-pingpong-live.mjs +509 -0
- package/src/agents/advisor/AGENT.md +1 -1
- package/src/agents/advisor/agent.json +1 -1
- package/src/defaults/shipped-history.json +5 -0
- package/src/defaults/skills/setup/SKILL.md +6 -1
- package/src/defaults/skills/setup/references/actions.md +44 -22
- package/src/defaults/skills/setup/references/surfaces.md +10 -8
- package/src/headless-exec.mjs +15 -8
- package/src/lib/keychain-cjs.cjs +7 -4
- package/src/output-styles/common.md +11 -10
- package/src/rules/agent/AGENT.md +5 -5
- package/src/rules/lead/LEAD.md +5 -5
- package/src/runtime/agent/orchestrator/agent-trace-io.mjs +92 -61
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
- package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
- package/src/runtime/agent/orchestrator/config.mjs +5 -0
- package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +24 -17
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +7 -6
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +29 -10
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +6 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +58 -7
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +29 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +16 -3
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +10 -61
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +12 -6
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +114 -72
- package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +37 -5
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +43 -2
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +64 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +70 -6
- package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
- package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
- package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +25 -8
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +87 -5
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +13 -13
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +355 -37
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +93 -47
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +55 -10
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +26 -8
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +246 -42
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
- package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +388 -0
- package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
- package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
- package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +48 -22
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +119 -18
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +33 -1
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +121 -61
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +37 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
- package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +47 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +151 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +42 -24
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +63 -25
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +172 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +53 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +103 -26
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +23 -4
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +11 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +6 -1
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +15 -23
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +23 -10
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +25 -4
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +71 -24
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +44 -16
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -16
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -35
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +11 -3
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +170 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +75 -70
- package/src/runtime/agent/orchestrator/providers/openrouter.mjs +75 -0
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +147 -8
- package/src/runtime/agent/orchestrator/providers/registry.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
- package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +157 -0
- package/src/runtime/agent/orchestrator/providers/wire-route.mjs +512 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +183 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +100 -0
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +21 -0
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
- package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
- package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +14 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +176 -71
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +62 -10
- package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +14 -93
- package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +120 -0
- package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
- package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +91 -1
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
- package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +21 -10
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +132 -0
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +30 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +63 -20
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +150 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +208 -14
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +15 -3
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +25 -3
- package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +19 -2
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
- package/src/runtime/agent/orchestrator/session/side-question.mjs +192 -0
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +17 -3
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +58 -2
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +41 -28
- package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +12 -1
- package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +10 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/store.mjs +19 -3
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +14 -10
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +49 -34
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
- package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
- package/src/runtime/computer-bridge/action-schema.mjs +44 -21
- package/src/runtime/github/tool.mjs +92 -2
- package/src/runtime/memory/index.mjs +1 -0
- package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
- package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
- package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
- package/src/runtime/memory/lib/pg/process.mjs +31 -26
- package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
- package/src/runtime/memory/lib/pg/supervisor.mjs +108 -3
- package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
- package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
- package/src/runtime/office/README.md +1 -1
- package/src/runtime/office/authoring/html-document-author.mjs +2 -0
- package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
- package/src/runtime/office/authoring/pptx-html-measure.mjs +2 -0
- package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +2 -0
- package/src/runtime/office/core/office-actions-read.mjs +3 -0
- package/src/runtime/office/core/office-render-preview.mjs +2 -0
- package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
- package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
- package/src/runtime/office/core/office-sessions.mjs +5 -0
- package/src/runtime/office/core/office-transactions.mjs +3 -0
- package/src/runtime/office/core/office-write-ledger.mjs +98 -0
- package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
- package/src/runtime/office/index.mjs +30 -0
- package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
- package/src/runtime/office/pdf/pdf-render.mjs +23 -7
- package/src/runtime/office/pdf/pdf-security.mjs +2 -0
- package/src/runtime/office/portable/portable-opc.mjs +4 -1
- package/src/runtime/office/quality/visual-diff.mjs +2 -0
- package/src/runtime/shared/bounded-file-read.mjs +13 -0
- package/src/runtime/shared/bounded-line-diff.mjs +182 -0
- package/src/runtime/shared/buffered-appender.mjs +18 -0
- package/src/runtime/shared/config.mjs +78 -18
- package/src/runtime/shared/err-text.mjs +6 -0
- package/src/runtime/shared/file-permissions.d.mts +6 -1
- package/src/runtime/shared/file-permissions.mjs +54 -6
- package/src/runtime/shared/llm/anthropic-effort.mjs +6 -0
- package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
- package/src/runtime/shared/loopback-listener.mjs +9 -0
- package/src/runtime/shared/provider-api-key.mjs +2 -0
- package/src/runtime/shared/review-diff.mjs +52 -0
- package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
- package/src/runtime/shared/session-sidebar-host.mjs +38 -0
- package/src/runtime/shared/slow-span.mjs +114 -0
- package/src/runtime/shared/statusline/statusline-segments.mjs +28 -4
- package/src/runtime/shared/tool-card-model/card-header.mjs +6 -1
- package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
- package/src/runtime/shared/tool-card-model.mjs +5 -2
- package/src/runtime/shared/tool-output-limit.mjs +4 -0
- package/src/runtime/shared/tool-primitives.mjs +13 -0
- package/src/runtime/shared/tool-result-summary.mjs +8 -1
- package/src/runtime/shared/tool-surface.mjs +18 -3
- package/src/runtime/shared/tool-work-units.mjs +40 -4
- package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
- package/src/runtime/shared/transcript-writer.mjs +10 -2
- package/src/runtime/shared/turn-changes.mjs +268 -100
- package/src/runtime/shared/turn-review-reply.mjs +8 -39
- package/src/runtime/shared/turn-snapshot-store.mjs +19 -108
- package/src/runtime/shared/turn-snapshot.mjs +857 -683
- package/src/runtime/shared/turn-worktree-snapshot.mjs +183 -255
- package/src/runtime/shared/user-data-guard.mjs +262 -49
- package/src/runtime/shared/worktrees/carry.mjs +531 -0
- package/src/runtime/shared/worktrees/contract.mjs +34 -0
- package/src/runtime/shared/worktrees/file-recovery.mjs +68 -0
- package/src/runtime/shared/worktrees/git-head.mjs +205 -0
- package/src/runtime/shared/worktrees/git.mjs +8 -3
- package/src/runtime/shared/worktrees/maintenance.mjs +1 -1
- package/src/runtime/shared/worktrees/manager.mjs +156 -8
- package/src/runtime/shared/worktrees/merge.mjs +31 -21
- package/src/runtime/shared/worktrees/paths.d.mts +6 -0
- package/src/runtime/terminal-bridge/client.mjs +44 -11
- package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
- package/src/runtime/tidy/apply.mjs +47 -2
- package/src/runtime/tidy/run-engines.mjs +11 -5
- package/src/session-runtime/agent-tool-routing.mjs +19 -13
- package/src/session-runtime/boot/apis.mjs +13 -5
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/infrastructure.mjs +6 -1
- package/src/session-runtime/boot/session.mjs +0 -1
- package/src/session-runtime/boot/tools.mjs +4 -1
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +65 -0
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +11 -4
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +115 -18
- package/src/session-runtime/internal-tool-executor.mjs +6 -2
- package/src/session-runtime/lifecycle/cold-heir.mjs +188 -0
- package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
- package/src/session-runtime/lifecycle/session-catalog.mjs +12 -3
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +29 -6
- package/src/session-runtime/lifecycle/teardown.mjs +72 -7
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/connect.mjs +17 -5
- package/src/session-runtime/model-route/set-route.mjs +2 -2
- package/src/session-runtime/native-web-search-usage.mjs +51 -0
- package/src/session-runtime/native-web-search.mjs +10 -1
- package/src/session-runtime/new-session-config.mjs +4 -2
- package/src/session-runtime/provider-auth/login.mjs +4 -0
- package/src/session-runtime/resource-scope-decorate.mjs +10 -3
- package/src/session-runtime/runtime-review-api.mjs +8 -2
- package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
- package/src/session-runtime/services/agent-tool/lead-worker-index/forgotten-leads.mjs +29 -0
- package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +73 -7
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +15 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +10 -1
- package/src/session-runtime/services/agent-tool/worker-index.mjs +46 -7
- package/src/session-runtime/services/agent-tool.mjs +3 -0
- package/src/session-runtime/services/channel-admin.mjs +19 -3
- package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
- package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
- package/src/session-runtime/services/provider-admin.mjs +81 -15
- package/src/session-runtime/session-transcript-purge.mjs +32 -0
- package/src/session-runtime/session-turn-api.mjs +14 -5
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -0
- package/src/session-runtime/setup-tool/executor.mjs +36 -6
- package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +13 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +13 -4
- package/src/session-runtime/skills-api.mjs +3 -5
- package/src/session-runtime/tool-surface.mjs +5 -1
- package/src/session-runtime/turn/compaction-gate.mjs +25 -0
- package/src/session-runtime/turn/session-ops.mjs +7 -5
- package/src/session-runtime/turn/side-question-ops.mjs +22 -0
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +5 -1
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +8 -3
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +10 -0
- package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
- package/src/session-runtime/turn/turn-run.mjs +25 -9
- package/src/session-runtime/usage-stats-api.mjs +43 -11
- package/src/session-runtime/workspace/project-branches.mjs +7 -5
- package/src/session-runtime/workspace/transition-steps.mjs +129 -31
- package/src/session-runtime/workspace/transitions.mjs +190 -15
- package/src/standalone/daemon-agent-control.mjs +9 -1
- package/src/standalone/daemon-local-session-bridge.mjs +14 -1
- package/src/standalone/daemon-owner.mjs +17 -4
- package/src/standalone/daemon-pg-stop.mjs +51 -0
- package/src/standalone/daemon-stop-budget.d.mts +2 -0
- package/src/standalone/daemon-stop-budget.mjs +18 -0
- package/src/standalone/daemon-stored-session-views.mjs +2 -0
- package/src/standalone/daemon-telemetry.mjs +19 -0
- package/src/standalone/daemon.mjs +61 -1
- package/src/standalone/desktop-service-registry.mjs +5 -0
- package/src/standalone/local-session-runtime.mjs +70 -19
- package/src/standalone/session-client.mjs +42 -0
- package/src/standalone/session-protocol.mjs +7 -0
- package/src/standalone/session-proxy/projection.mjs +41 -4
- package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
- package/src/standalone/session-runtime-inline-host.mjs +1 -0
- package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
- package/src/standalone/session-service-api.mjs +6 -1
- package/src/standalone/session-state-patch.d.mts +2 -1
- package/src/standalone/session-state-patch.mjs +41 -1
- package/src/tui/App.jsx +25 -0
- package/src/tui/app/app-view/floating-panel.jsx +26 -1
- package/src/tui/app/btw-controller.mjs +118 -0
- package/src/tui/app/create-app-pickers.mjs +2 -0
- package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
- package/src/tui/app/shell-layout/surfaces.mjs +3 -1
- package/src/tui/app/slash-commands.mjs +13 -3
- package/src/tui/app/slash-dispatch/session-commands.mjs +19 -6
- package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
- package/src/tui/app/use-global-key-input.mjs +5 -12
- package/src/tui/app/use-prompt-handlers.mjs +11 -0
- package/src/tui/components/BtwPanel.jsx +53 -0
- package/src/tui/components/QuestionPanel.jsx +275 -0
- package/src/tui/components/question-panel-model.mjs +156 -0
- package/src/tui/dist/index.mjs +2413 -1465
- package/src/tui/session/context-state.mjs +4 -2
- package/src/tui/session/session-api/commands.mjs +10 -0
- package/src/tui/session/session-api/controls.mjs +2 -2
- package/src/tui/session/session-api/integrations.mjs +9 -2
- package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
- package/src/tui/session/session-api/lifecycle.mjs +2 -1
- package/src/tui/session/session-api/settings.mjs +6 -0
- package/src/tui/session/session-api.mjs +1 -0
- package/src/tui/session/tool-approval.mjs +10 -7
- package/src/tui/session/transcript-spill.mjs +14 -7
- package/src/tui/session/turn-stream.mjs +174 -31
- package/src/tui/session/turn.mjs +12 -5
- package/src/workflows/default/WORKFLOW.md +3 -1
package/README.md
CHANGED
|
@@ -134,6 +134,24 @@ is published in [`benchmarks/terminal-bench-2.1/`](benchmarks/terminal-bench-2.1
|
|
|
134
134
|
and [Context efficiency](docs/context-efficiency.md) explains where the
|
|
135
135
|
savings come from.
|
|
136
136
|
|
|
137
|
+
<details>
|
|
138
|
+
<summary><b>Benchmark history</b></summary>
|
|
139
|
+
|
|
140
|
+
Newest first. Each run links to its details, records, and caveats.
|
|
141
|
+
|
|
142
|
+
| Run | Model · trials | vs | Score | Cost | Final context | Time / trial |
|
|
143
|
+
|---|---|---|---|---|---|---|
|
|
144
|
+
| [2026-10-15](benchmarks/terminal-bench-2.1/#bench-log) | GPT-6.1 Sol xhigh · `k=1` | Codex CLI | 77 vs 78 /89 | **−55%** | **−68%** (10.8K vs 33.6K) | 344s vs 380s |
|
|
145
|
+
| [2026-08-25](benchmarks/terminal-bench-2.1/#gpt-56-sol-xhigh-vs-codex-cli) | GPT-5.6 Sol xhigh · `k=5` | Codex CLI | 385 vs 383 /445 | **−39%** | **−46%** (18.5K vs 34.3K) | 415s vs 437s |
|
|
146
|
+
| [2026-08-25](benchmarks/terminal-bench-2.1/#claude-opus-5-vs-claude-code) | Claude Opus 5 · `k=1` | Claude Code | 79 vs 77 /89 | **−19%** | **−28%** (27.6K vs 38.2K) | 610s vs 708s |
|
|
147
|
+
|
|
148
|
+
The 2026-10-15 run is the first full run with the
|
|
149
|
+
[effort judge](docs/auto-reasoning-effort.md) active on OpenAI routes, with web
|
|
150
|
+
search on for both sides. It is a single pass, so the `k=5` chart above stays
|
|
151
|
+
the reference.
|
|
152
|
+
|
|
153
|
+
</details>
|
|
154
|
+
|
|
137
155
|
## Documentation
|
|
138
156
|
|
|
139
157
|
- [Context efficiency](docs/context-efficiency.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mixdog",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Open-source coding agent that matches Codex on Terminal-Bench 2.1 with 63% fewer tokens.",
|
|
@@ -161,6 +161,7 @@
|
|
|
161
161
|
"@mozilla/readability": "^0.6.0",
|
|
162
162
|
"@napi-rs/canvas": "^1.0.8",
|
|
163
163
|
"@pdf-lib/fontkit": "^1.1.1",
|
|
164
|
+
"ajv": "^8.20.0",
|
|
164
165
|
"chalk": "^5.6.2",
|
|
165
166
|
"cli-highlight": "^2.1.11",
|
|
166
167
|
"diff": "^9.0.0",
|
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
// Live ping-pong across providers.
|
|
2
|
+
// Basic suite (default): three turns - a forced read, a no-tool replay of that history,
|
|
3
|
+
// and two parallel reads.
|
|
4
|
+
// Extended suite (`--suite extended`): after those, tool error, file write, shell, a
|
|
5
|
+
// 3-step tool chain, image input, mid-stream cancel + follow-up. Per-turn usage is
|
|
6
|
+
// captured to report prompt-cache reads on turns 2+.
|
|
7
|
+
//
|
|
8
|
+
// Isolation (default): the runs use a fresh temp MIXDOG_HOME/MIXDOG_DATA_DIR, never the
|
|
9
|
+
// installed app's ~/.mixdog data, so no session, catalog or worker rows reach the real
|
|
10
|
+
// stores. Only the API-key secrets (`secrets/agent.<provider>.apiKey.dpapi`) and the
|
|
11
|
+
// `agent` section of mixdog-config.json are copied in. OAuth providers (`*-oauth`, whose
|
|
12
|
+
// refresh tokens could be rotated) are skipped unless `--real-data` is passed, which
|
|
13
|
+
// restores the old behaviour of running against the real data dir. The isolated dir is
|
|
14
|
+
// deleted at the end, after stopping only processes whose executable lives inside it.
|
|
15
|
+
// Usage: node scripts/provider-pingpong-live.mjs [--suite extended] [--real-data] [case-name ...]
|
|
16
|
+
import fs from 'node:fs';
|
|
17
|
+
import os from 'node:os';
|
|
18
|
+
import path from 'node:path';
|
|
19
|
+
import zlib from 'node:zlib';
|
|
20
|
+
import { fileURLToPath } from 'node:url';
|
|
21
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
22
|
+
|
|
23
|
+
const self = fileURLToPath(import.meta.url);
|
|
24
|
+
const TURN_TIMEOUT_MS = 150_000;
|
|
25
|
+
|
|
26
|
+
const textOf = (response) => {
|
|
27
|
+
const content = response?.result?.content ?? response?.text ?? '';
|
|
28
|
+
if (Array.isArray(content)) return content.map((p) => (typeof p === 'string' ? p : p?.text || '')).join('');
|
|
29
|
+
return String(content);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Solid-colour PNG (8-bit RGB) built from scratch so no image dependency is needed.
|
|
33
|
+
function solidPng(width, height, [r, g, b]) {
|
|
34
|
+
const crcTable = Array.from({ length: 256 }, (_, n) => {
|
|
35
|
+
let c = n;
|
|
36
|
+
for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
37
|
+
return c >>> 0;
|
|
38
|
+
});
|
|
39
|
+
const crc32 = (buf) => {
|
|
40
|
+
let c = 0xffffffff;
|
|
41
|
+
for (const byte of buf) c = crcTable[(c ^ byte) & 0xff] ^ (c >>> 8);
|
|
42
|
+
return (c ^ 0xffffffff) >>> 0;
|
|
43
|
+
};
|
|
44
|
+
const chunk = (type, data) => {
|
|
45
|
+
const body = Buffer.concat([Buffer.from(type, 'ascii'), data]);
|
|
46
|
+
const out = Buffer.alloc(body.length + 8);
|
|
47
|
+
out.writeUInt32BE(data.length, 0);
|
|
48
|
+
body.copy(out, 4);
|
|
49
|
+
out.writeUInt32BE(crc32(body), body.length + 4);
|
|
50
|
+
return out;
|
|
51
|
+
};
|
|
52
|
+
const ihdr = Buffer.alloc(13);
|
|
53
|
+
ihdr.writeUInt32BE(width, 0);
|
|
54
|
+
ihdr.writeUInt32BE(height, 4);
|
|
55
|
+
ihdr[8] = 8; // bit depth
|
|
56
|
+
ihdr[9] = 2; // RGB
|
|
57
|
+
const row = Buffer.concat([Buffer.from([0]), Buffer.from(Array.from({ length: width }, () => [r, g, b]).flat())]);
|
|
58
|
+
const raw = Buffer.concat(Array.from({ length: height }, () => row));
|
|
59
|
+
return Buffer.concat([
|
|
60
|
+
Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
|
|
61
|
+
chunk('IHDR', ihdr),
|
|
62
|
+
chunk('IDAT', zlib.deflateSync(raw)),
|
|
63
|
+
chunk('IEND', Buffer.alloc(0)),
|
|
64
|
+
]);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const withTimeout = (promise, ms, onTimeout) =>
|
|
68
|
+
new Promise((resolve, reject) => {
|
|
69
|
+
const timer = setTimeout(() => {
|
|
70
|
+
onTimeout?.();
|
|
71
|
+
reject(new Error(`timeout after ${ms}ms`));
|
|
72
|
+
}, ms);
|
|
73
|
+
promise.then(
|
|
74
|
+
(v) => (clearTimeout(timer), resolve(v)),
|
|
75
|
+
(e) => (clearTimeout(timer), reject(e))
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Failures caused by the account (limits, billing, entitlement) rather than the provider code.
|
|
80
|
+
const ACCOUNT_RE =
|
|
81
|
+
/quota|billing|\b(?:402|403|429)\b|rate.?limit|usage limit|insufficient|payment|credit|too many requests|exhaust|subscription|plan limit|not entitled|resource_exhausted/i;
|
|
82
|
+
|
|
83
|
+
if (process.argv[2] === '--child') {
|
|
84
|
+
const spec = JSON.parse(process.argv[3]);
|
|
85
|
+
const extended = spec.suite === 'extended';
|
|
86
|
+
const { resolvePluginData } = await import('../src/runtime/shared/plugin-paths.mjs');
|
|
87
|
+
if (spec.dataDir && path.resolve(resolvePluginData()) !== path.resolve(spec.dataDir)) {
|
|
88
|
+
console.log(`RESULT ${JSON.stringify({ name: spec.name, error: `refusing to run: data dir ${resolvePluginData()} is not the isolated ${spec.dataDir}` })}`);
|
|
89
|
+
process.exit(0);
|
|
90
|
+
}
|
|
91
|
+
const { createMixdogSessionRuntime } = await import('../src/session-runtime/runtime-core.mjs');
|
|
92
|
+
const { materializePromptSubmission } = await import('../src/runtime/attachments/store.mjs');
|
|
93
|
+
const { getModelMetadataSync } = await import('../src/runtime/shared/llm/model-catalog.mjs');
|
|
94
|
+
let runtime;
|
|
95
|
+
const out = { name: spec.name, provider: spec.provider, model: spec.model, effort: spec.effort, turns: {}, order: [] };
|
|
96
|
+
const readDisk = (file) => {
|
|
97
|
+
try {
|
|
98
|
+
return fs.readFileSync(path.join(spec.cwd, file), 'utf8');
|
|
99
|
+
} catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// Runs one ask() and records calls/text/usage under `key`. Errors are recorded, not thrown,
|
|
105
|
+
// so later scenarios still run; an ACCOUNT error stops the case (everything after would fail alike).
|
|
106
|
+
const turn = async (key, prompt, options = {}) => {
|
|
107
|
+
const rec = { calls: [], text: '', usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, events: 0 }, models: [] };
|
|
108
|
+
out.turns[key] = rec;
|
|
109
|
+
out.order.push(key);
|
|
110
|
+
const startedAt = Date.now();
|
|
111
|
+
try {
|
|
112
|
+
const response = await withTimeout(
|
|
113
|
+
runtime.ask(prompt, {
|
|
114
|
+
...options,
|
|
115
|
+
onAssistantToolCallObserved: (call) => rec.calls.push(call.name || call.tool),
|
|
116
|
+
onUsageDelta: (d) => {
|
|
117
|
+
rec.usage.events++;
|
|
118
|
+
rec.usage.input += d.deltaInput || 0;
|
|
119
|
+
rec.usage.output += d.deltaOutput || 0;
|
|
120
|
+
rec.usage.cacheRead += d.deltaCachedRead || 0;
|
|
121
|
+
rec.usage.cacheWrite += d.deltaCacheWrite || 0;
|
|
122
|
+
if (d.model && !rec.models.includes(d.model)) rec.models.push(d.model);
|
|
123
|
+
},
|
|
124
|
+
}),
|
|
125
|
+
TURN_TIMEOUT_MS,
|
|
126
|
+
() => runtime.abort('pingpong-timeout')
|
|
127
|
+
);
|
|
128
|
+
rec.text = textOf(response).trim().slice(0, 300);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
rec.error = String(error?.message || error).slice(0, 400);
|
|
131
|
+
if (ACCOUNT_RE.test(rec.error)) out.stopped = 'account';
|
|
132
|
+
}
|
|
133
|
+
rec.ms = Date.now() - startedAt;
|
|
134
|
+
return rec;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
runtime = await createMixdogSessionRuntime({
|
|
139
|
+
provider: spec.provider,
|
|
140
|
+
model: spec.model,
|
|
141
|
+
...(spec.effort ? { effort: spec.effort } : {}),
|
|
142
|
+
cwd: spec.cwd,
|
|
143
|
+
toolMode: 'full',
|
|
144
|
+
autoWakeCompletions: false,
|
|
145
|
+
});
|
|
146
|
+
const steps = [
|
|
147
|
+
['t1', 'Use the read tool on package.json, then reply with only the value of "name".'],
|
|
148
|
+
['t2', 'Without using tools, reply with only that same name in uppercase.'],
|
|
149
|
+
['t3', 'Read a.txt and b.txt with two read calls issued together in one step, then reply with only their two contents joined by "+".'],
|
|
150
|
+
];
|
|
151
|
+
for (const [key, prompt] of steps) {
|
|
152
|
+
await turn(key, prompt);
|
|
153
|
+
if (out.stopped) break;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (extended && !out.stopped) {
|
|
157
|
+
await turn(
|
|
158
|
+
'er',
|
|
159
|
+
'Use the read tool on does-not-exist.txt. Whatever happens, then tell me in one short sentence whether that file exists.'
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
if (extended && !out.stopped) {
|
|
163
|
+
const rec = await turn(
|
|
164
|
+
'wr',
|
|
165
|
+
'Using the file edit/write tool (not the shell), create a new file c.txt in the working directory containing exactly the text gamma. Reply "done" when finished.'
|
|
166
|
+
);
|
|
167
|
+
rec.disk = readDisk('c.txt');
|
|
168
|
+
}
|
|
169
|
+
if (extended && !out.stopped) {
|
|
170
|
+
await turn('sh', 'Use the shell tool to run exactly: node -e "console.log(6*7)" and reply with only its output.');
|
|
171
|
+
}
|
|
172
|
+
if (extended && !out.stopped) {
|
|
173
|
+
const rec = await turn(
|
|
174
|
+
'ml',
|
|
175
|
+
'Do these in order, each as its own tool call, one after another: (1) read a.txt, (2) create a new file d.txt using the file edit/write tool containing the contents of a.txt with its characters reversed and no trailing newline, (3) read d.txt. Then reply with only the text in d.txt.'
|
|
176
|
+
);
|
|
177
|
+
rec.disk = readDisk('d.txt');
|
|
178
|
+
}
|
|
179
|
+
if (extended && !out.stopped) {
|
|
180
|
+
const vision = getModelMetadataSync(spec.model, spec.provider)?.supportsVision;
|
|
181
|
+
if (vision === false) {
|
|
182
|
+
out.turns.im = { skipped: 'catalog says no vision', calls: [], text: '' };
|
|
183
|
+
out.order.push('im');
|
|
184
|
+
} else {
|
|
185
|
+
const png = solidPng(64, 64, [255, 0, 0]).toString('base64');
|
|
186
|
+
// Same intake the session service applies before runtime.ask: inline image
|
|
187
|
+
// parts become content-addressed attachment references.
|
|
188
|
+
const intake = materializePromptSubmission([
|
|
189
|
+
{ type: 'text', text: 'What single colour fills this image? Reply with only the colour name in English.' },
|
|
190
|
+
{ type: 'image', data: png, mimeType: 'image/png' },
|
|
191
|
+
]);
|
|
192
|
+
const rec = await turn('im', intake.prompt, intake.options);
|
|
193
|
+
rec.visionFlag = vision === undefined ? 'unknown' : 'true';
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (extended && !out.stopped) {
|
|
197
|
+
// Real cancel path: runtime.abort() -> abortRuntime -> turn controller + mgr.abortSessionTurn.
|
|
198
|
+
const rec = { calls: [], text: '', usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, events: 0 }, models: [] };
|
|
199
|
+
out.turns.ca = rec;
|
|
200
|
+
out.order.push('ca');
|
|
201
|
+
let deltas = 0;
|
|
202
|
+
let abortResult;
|
|
203
|
+
let aborted = false;
|
|
204
|
+
const doAbort = () => {
|
|
205
|
+
if (aborted) return;
|
|
206
|
+
aborted = true;
|
|
207
|
+
abortResult = runtime.abort('user-cancel');
|
|
208
|
+
};
|
|
209
|
+
const fallback = setTimeout(doAbort, 30_000);
|
|
210
|
+
const onDelta = () => {
|
|
211
|
+
if (++deltas >= 5) doAbort();
|
|
212
|
+
};
|
|
213
|
+
const startedAt = Date.now();
|
|
214
|
+
const pending = runtime
|
|
215
|
+
.ask('Write a very long numbered list from 1 to 300, one item per line, each item a full sentence about a different animal. Do not use tools.', {
|
|
216
|
+
onTextDelta: onDelta,
|
|
217
|
+
onUsageDelta: (d) => {
|
|
218
|
+
rec.usage.events++;
|
|
219
|
+
rec.usage.input += d.deltaInput || 0;
|
|
220
|
+
rec.usage.output += d.deltaOutput || 0;
|
|
221
|
+
rec.usage.cacheRead += d.deltaCachedRead || 0;
|
|
222
|
+
rec.usage.cacheWrite += d.deltaCacheWrite || 0;
|
|
223
|
+
},
|
|
224
|
+
})
|
|
225
|
+
.then(
|
|
226
|
+
(r) => ({ ok: true, text: textOf(r).trim() }),
|
|
227
|
+
(e) => ({ ok: false, error: String(e?.message || e) })
|
|
228
|
+
);
|
|
229
|
+
const settled = await Promise.race([pending, new Promise((r) => setTimeout(() => r({ hang: true }), 120_000))]);
|
|
230
|
+
clearTimeout(fallback);
|
|
231
|
+
rec.ms = Date.now() - startedAt;
|
|
232
|
+
rec.deltas = deltas;
|
|
233
|
+
rec.abortResult = abortResult;
|
|
234
|
+
rec.abortedAfterMs = rec.ms;
|
|
235
|
+
rec.settle = settled.hang ? 'hang' : settled.ok ? 'resolved' : 'rejected';
|
|
236
|
+
rec.text = String(settled.text || '').slice(0, 120);
|
|
237
|
+
rec.error = settled.error ? settled.error.slice(0, 300) : undefined;
|
|
238
|
+
rec.chars = String(settled.text || '').length;
|
|
239
|
+
if (settled.hang) out.stopped = 'hang';
|
|
240
|
+
else if (rec.error && ACCOUNT_RE.test(rec.error) && !aborted) out.stopped = 'account';
|
|
241
|
+
if (!out.stopped) await turn('fu', 'Reply with only the word READY.');
|
|
242
|
+
}
|
|
243
|
+
} catch (error) {
|
|
244
|
+
out.error = String(error?.message || error).slice(0, 400);
|
|
245
|
+
} finally {
|
|
246
|
+
await runtime?.close('provider-pingpong-live').catch(() => {});
|
|
247
|
+
}
|
|
248
|
+
console.log(`RESULT ${JSON.stringify(out)}`);
|
|
249
|
+
process.exit(0);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// [name, provider, model, effort]; each route runs at a low and a high reasoning setting.
|
|
253
|
+
const routes = [
|
|
254
|
+
['openrouter-claude', 'openrouter', 'anthropic/claude-haiku-5.5', ['low', 'max']],
|
|
255
|
+
['openrouter-gpt', 'openrouter', 'openai/gpt-6-luna', ['none', 'xhigh']],
|
|
256
|
+
['openrouter-gemini', 'openrouter', 'google/gemini-3.5-flash-lite', ['minimal', 'high']],
|
|
257
|
+
['openrouter-deepseek', 'openrouter', 'deepseek/deepseek-v4.1-flash', ['low', 'max']],
|
|
258
|
+
['deepseek', 'deepseek', 'deepseek-flash', ['low', 'max']],
|
|
259
|
+
['deepseek-pro', 'deepseek', 'deepseek-v4-pro', ['high']],
|
|
260
|
+
['opencode-go-gemini', 'opencode-go', 'gemini-4-argon-contributor', ['low', 'high']],
|
|
261
|
+
['opencode-go-deepseek', 'opencode-go', 'deepseek-v4.1-flash', ['low', 'max']],
|
|
262
|
+
['opencode-go-claude', 'opencode-go', 'claude-haiku-5-5', ['low', 'max']],
|
|
263
|
+
['opencode-go-gpt', 'opencode-go', 'gpt-6-luna', ['none', 'xhigh']],
|
|
264
|
+
['opencode-go-glm', 'opencode-go', 'glm-5.3-flash', ['low', 'max']],
|
|
265
|
+
['opencode-go-qwen', 'opencode-go', 'qwen3.8-flash', ['low', 'xhigh']],
|
|
266
|
+
['opencode-go-kimi', 'opencode-go', 'kimi-k3', ['max']],
|
|
267
|
+
['opencode-go-minimax', 'opencode-go', 'minimax-m3', [null]],
|
|
268
|
+
['opencode-go-grok', 'opencode-go', 'grok-4.7', ['low']],
|
|
269
|
+
['anthropic-api', 'anthropic', 'claude-haiku-5-5', ['low', 'max']],
|
|
270
|
+
['gemini-api', 'gemini', 'gemini-3.5-flash-lite', ['minimal', 'high']],
|
|
271
|
+
['grok-oauth', 'grok-oauth', 'grok-4.7', ['low', 'xhigh']],
|
|
272
|
+
['openai-oauth', 'openai-oauth', 'gpt-6-luna', ['none', 'xhigh']],
|
|
273
|
+
['anthropic-oauth', 'anthropic-oauth', 'claude-haiku-5-5', ['low', 'max']],
|
|
274
|
+
['antigravity-oauth', 'antigravity-oauth', 'gemini-3.8-flash', ['low', 'high']],
|
|
275
|
+
['cursor-auto', 'cursor-oauth', 'auto', [null]],
|
|
276
|
+
['cursor-composer', 'cursor-oauth', 'composer-2.5', [null]],
|
|
277
|
+
['cursor-claude', 'cursor-oauth', 'claude-opus-5-5', [null]],
|
|
278
|
+
['cursor-grok', 'cursor-oauth', 'grok-4.7', [null]],
|
|
279
|
+
];
|
|
280
|
+
const cases = routes.flatMap(([name, provider, model, efforts]) =>
|
|
281
|
+
efforts.map((effort) => [`${name}${effort ? `@${effort}` : ''}`, provider, model, effort])
|
|
282
|
+
);
|
|
283
|
+
const args = process.argv.slice(2);
|
|
284
|
+
const suiteAt = args.findIndex((a) => a === '--suite' || a.startsWith('--suite='));
|
|
285
|
+
const suite = suiteAt < 0 ? 'basic' : args[suiteAt].includes('=') ? args[suiteAt].split('=')[1] : args[suiteAt + 1];
|
|
286
|
+
const extended = suite === 'extended';
|
|
287
|
+
const realData = args.includes('--real-data');
|
|
288
|
+
const only = args.filter(
|
|
289
|
+
(a, i) => a !== '--real-data' && !a.startsWith('--suite') && !(suiteAt >= 0 && i === suiteAt + 1 && args[suiteAt] === '--suite')
|
|
290
|
+
);
|
|
291
|
+
const chosen = only.length ? cases.filter(([name]) => only.includes(name)) : cases;
|
|
292
|
+
// Refresh-capable OAuth logins are never exercised from an isolated copy.
|
|
293
|
+
const isOauth = ([, provider]) => /-oauth$/.test(provider);
|
|
294
|
+
const selected = realData ? chosen : chosen.filter((c) => !isOauth(c));
|
|
295
|
+
for (const c of chosen) if (!selected.includes(c)) console.log(`SKIP ${c[0]} (OAuth provider; pass --real-data to run against the real data dir)`);
|
|
296
|
+
if (!selected.length) {
|
|
297
|
+
console.log('nothing to run');
|
|
298
|
+
process.exit(0);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Isolated MIXDOG_HOME for the child runtimes: a fresh temp dir holding only the API-key
|
|
302
|
+
// secrets of the selected providers and the `agent` section of the real config.
|
|
303
|
+
let isolated = null;
|
|
304
|
+
if (!realData) {
|
|
305
|
+
const realDataDir = process.env.MIXDOG_DATA_DIR || path.join(process.env.MIXDOG_HOME || path.join(os.homedir(), '.mixdog'), 'data');
|
|
306
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'mixdog-pp-home-'));
|
|
307
|
+
const dataDir = path.join(home, 'data');
|
|
308
|
+
fs.mkdirSync(path.join(dataDir, 'secrets'), { recursive: true });
|
|
309
|
+
const config = JSON.parse(fs.readFileSync(path.join(realDataDir, 'mixdog-config.json'), 'utf8'));
|
|
310
|
+
fs.writeFileSync(path.join(dataDir, 'mixdog-config.json'), JSON.stringify({ agent: config.agent ?? {} }, null, 2));
|
|
311
|
+
for (const provider of new Set(selected.map(([, p]) => p))) {
|
|
312
|
+
const secret = `agent.${provider}.apiKey.dpapi`;
|
|
313
|
+
const from = path.join(realDataDir, 'secrets', secret);
|
|
314
|
+
if (fs.existsSync(from)) fs.copyFileSync(from, path.join(dataDir, 'secrets', secret));
|
|
315
|
+
else console.log(`WARN no ${secret} in the real data dir; ${provider} cases will fail to authenticate`);
|
|
316
|
+
}
|
|
317
|
+
isolated = {
|
|
318
|
+
home,
|
|
319
|
+
dataDir,
|
|
320
|
+
env: { MIXDOG_HOME: home, MIXDOG_DATA_DIR: dataDir, MIXDOG_RUNTIME_ROOT: path.join(home, 'runtime-root') },
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Stops only processes whose executable path is inside `root` (e.g. the isolated memory
|
|
325
|
+
// postgres), then removes the dir. Windows-only lookup, like the DPAPI secrets.
|
|
326
|
+
const removeIsolated = () => {
|
|
327
|
+
if (!isolated) return;
|
|
328
|
+
const { home } = isolated;
|
|
329
|
+
isolated = null;
|
|
330
|
+
if (process.platform === 'win32') {
|
|
331
|
+
const root = home.replace(/'/g, "''");
|
|
332
|
+
spawnSync(
|
|
333
|
+
'powershell.exe',
|
|
334
|
+
[
|
|
335
|
+
'-NoProfile',
|
|
336
|
+
'-Command',
|
|
337
|
+
`$root='${root}\\'; Get-CimInstance Win32_Process | Where-Object { $_.ExecutablePath -and $_.ExecutablePath.StartsWith($root, [StringComparison]::OrdinalIgnoreCase) } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }`,
|
|
338
|
+
],
|
|
339
|
+
{ stdio: 'ignore' }
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
fs.rmSync(home, { recursive: true, force: true, maxRetries: 10, retryDelay: 500 });
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
// One fixture dir per case: concurrent children write c.txt/d.txt and must not collide.
|
|
346
|
+
const tempDirs = new Set();
|
|
347
|
+
const removeTemp = () => {
|
|
348
|
+
for (const dir of tempDirs) fs.rmSync(dir, { recursive: true, force: true });
|
|
349
|
+
tempDirs.clear();
|
|
350
|
+
removeIsolated();
|
|
351
|
+
};
|
|
352
|
+
process.on('exit', removeTemp);
|
|
353
|
+
const makeCwd = (name) => {
|
|
354
|
+
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), `mixdog-pingpong-${name.replace(/[^a-z0-9]+/gi, '-')}-`));
|
|
355
|
+
tempDirs.add(cwd);
|
|
356
|
+
fs.writeFileSync(path.join(cwd, 'package.json'), JSON.stringify({ name: 'pingpong-probe', version: '1.0.0' }, null, 2));
|
|
357
|
+
fs.writeFileSync(path.join(cwd, 'a.txt'), 'alpha\n');
|
|
358
|
+
fs.writeFileSync(path.join(cwd, 'b.txt'), 'beta\n');
|
|
359
|
+
return cwd;
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
const runOne = ([name, provider, model, effort]) =>
|
|
363
|
+
new Promise((resolve) => {
|
|
364
|
+
const cwd = makeCwd(name);
|
|
365
|
+
const child = spawn(
|
|
366
|
+
process.execPath,
|
|
367
|
+
[self, '--child', JSON.stringify({ name, provider, model, effort, cwd, dataDir: isolated?.dataDir, suite: extended ? 'extended' : 'basic' })],
|
|
368
|
+
{ stdio: ['ignore', 'pipe', 'pipe'], env: { ...process.env, ...isolated?.env } }
|
|
369
|
+
);
|
|
370
|
+
let stdout = '';
|
|
371
|
+
let stderr = '';
|
|
372
|
+
child.stdout.on('data', (d) => (stdout += d));
|
|
373
|
+
child.stderr.on('data', (d) => (stderr += d));
|
|
374
|
+
const timer = setTimeout(() => child.kill(), extended ? 900_000 : 240_000);
|
|
375
|
+
child.on('close', () => {
|
|
376
|
+
clearTimeout(timer);
|
|
377
|
+
fs.rmSync(cwd, { recursive: true, force: true });
|
|
378
|
+
tempDirs.delete(cwd);
|
|
379
|
+
const line = stdout.split('\n').find((l) => l.startsWith('RESULT '));
|
|
380
|
+
resolve(line ? JSON.parse(line.slice(7)) : { name, provider, model, effort, error: `no result: ${stderr.slice(-300)}` });
|
|
381
|
+
});
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
// Bounded concurrency keeps per-provider rate limits from masking real failures.
|
|
385
|
+
const results = [];
|
|
386
|
+
const queue = [...selected];
|
|
387
|
+
await Promise.all(
|
|
388
|
+
Array.from({ length: 8 }, async () => {
|
|
389
|
+
while (queue.length) results.push(await runOne(queue.shift()));
|
|
390
|
+
})
|
|
391
|
+
);
|
|
392
|
+
results.sort((a, b) => a.name.localeCompare(b.name));
|
|
393
|
+
|
|
394
|
+
const has = (t, re) => re.test(t?.text || '');
|
|
395
|
+
const called = (t, name) => (t?.calls || []).includes(name);
|
|
396
|
+
const wroteVia = (t) => (t?.calls || []).some((c) => /edit|write|patch/i.test(c));
|
|
397
|
+
// [key, label, check(turn, result)] ; check returns true/false.
|
|
398
|
+
const scenarios = [
|
|
399
|
+
['t1', 't1', (t) => called(t, 'read') && has(t, /pingpong-probe/i)],
|
|
400
|
+
['t2', 't2', (t) => has(t, /PINGPONG-PROBE/)],
|
|
401
|
+
['t3', 't3', (t) => (t.calls || []).filter((c) => c === 'read').length >= 1 && has(t, /alpha/i) && has(t, /beta/i)],
|
|
402
|
+
// The reply language follows the user's profile (may be Korean), so the wording check is bilingual.
|
|
403
|
+
['er', 'err', (t) => called(t, 'read') && has(t, /missing|not exist|doesn.?t exist|does not|no such|not found|nonexistent|isn.?t|cannot|can.?t|존재하지|없|찾을 수|않/i)],
|
|
404
|
+
['wr', 'wr', (t) => wroteVia(t) && String(t.disk ?? '').trim() === 'gamma'],
|
|
405
|
+
['sh', 'sh', (t) => called(t, 'shell') && has(t, /42/)],
|
|
406
|
+
[
|
|
407
|
+
'ml',
|
|
408
|
+
'ml',
|
|
409
|
+
(t) => {
|
|
410
|
+
const c = t.calls || [];
|
|
411
|
+
const firstRead = c.indexOf('read');
|
|
412
|
+
const write = c.findIndex((n, i) => i > firstRead && /edit|write|patch/i.test(n));
|
|
413
|
+
const lastRead = c.lastIndexOf('read');
|
|
414
|
+
return firstRead >= 0 && write > firstRead && lastRead > write && String(t.disk ?? '').trim() === 'ahpla' && has(t, /ahpla/);
|
|
415
|
+
},
|
|
416
|
+
],
|
|
417
|
+
['im', 'img', (t) => has(t, /red/i)],
|
|
418
|
+
['ca', 'can', (t) => t.settle && t.settle !== 'hang' && t.abortResult === true],
|
|
419
|
+
['fu', 'fu', (t) => has(t, /READY/i)],
|
|
420
|
+
];
|
|
421
|
+
|
|
422
|
+
const short = (s, n = 60) => String(s || '').replace(/\s+/g, ' ').slice(0, n);
|
|
423
|
+
const evidence = (key, t) => {
|
|
424
|
+
if (!t) return 'no turn';
|
|
425
|
+
if (t.error && key !== 'ca') return `error: ${short(t.error, 90)}`;
|
|
426
|
+
const base = `[${(t.calls || []).join(',')}] "${short(t.text)}"`;
|
|
427
|
+
if (key === 'wr' || key === 'ml') return `${base} disk=${JSON.stringify(short(t.disk ?? null, 20))}`;
|
|
428
|
+
if (key === 'ca') return `abort=${t.abortResult} settle=${t.settle} deltas=${t.deltas} chars=${t.chars} ${t.error ? `err="${short(t.error, 70)}"` : ''}`;
|
|
429
|
+
return base;
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
const details = [];
|
|
433
|
+
for (const r of results) {
|
|
434
|
+
const marks = [];
|
|
435
|
+
const evid = [];
|
|
436
|
+
let anyFail = false;
|
|
437
|
+
let anyAccount = false;
|
|
438
|
+
for (const [key, label, check] of scenarios) {
|
|
439
|
+
if (!extended && !['t1', 't2', 't3'].includes(key)) continue;
|
|
440
|
+
const t = r.turns?.[key];
|
|
441
|
+
// A cancelled turn is expected to reject, so only 'ca' tolerates an error.
|
|
442
|
+
const ok = t && (key === 'ca' || !t.error) && check(t, r);
|
|
443
|
+
const accountish = t
|
|
444
|
+
? ACCOUNT_RE.test(t.error || t.text || '')
|
|
445
|
+
: r.stopped === 'account' || ACCOUNT_RE.test(r.error || '');
|
|
446
|
+
let mark;
|
|
447
|
+
if (t?.skipped) mark = '-';
|
|
448
|
+
else if (ok) mark = '✓';
|
|
449
|
+
else if (accountish) mark = 'A';
|
|
450
|
+
// The catalog is silent on vision for this model: a wrong answer may just be a text-only
|
|
451
|
+
// model, so it is flagged for manual review instead of counted as a failure.
|
|
452
|
+
else if (key === 'im' && t?.visionFlag === 'unknown') mark = '?';
|
|
453
|
+
else mark = '✗';
|
|
454
|
+
marks.push(`${label}${mark}`);
|
|
455
|
+
if (mark === '✗') anyFail = true;
|
|
456
|
+
if (mark === 'A') anyAccount = true;
|
|
457
|
+
if (mark !== '✓' && mark !== '-') {
|
|
458
|
+
evid.push(`${label}${mark}: ${evidence(key, t)}`);
|
|
459
|
+
details.push({ r, key, label, mark, t });
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
const turns = Object.entries(r.turns || {});
|
|
463
|
+
const later = (r.order || []).slice(1).map((k) => r.turns[k]).filter((t) => t?.usage);
|
|
464
|
+
const sum = (f) => later.reduce((n, t) => n + f(t.usage), 0);
|
|
465
|
+
const events = (r.order || []).reduce((n, k) => n + (r.turns[k]?.usage?.events || 0), 0);
|
|
466
|
+
const cache = !turns.length || !events
|
|
467
|
+
? 'cache=NO-USAGE'
|
|
468
|
+
: `cache r=${sum((u) => u.cacheRead)} w=${sum((u) => u.cacheWrite)} in=${sum((u) => u.input)} cr/turn=[${later.map((t) => t.usage.cacheRead).join(',')}]`;
|
|
469
|
+
const verdict = r.error && !turns.length ? (ACCOUNT_RE.test(r.error) ? 'ACCOUNT' : 'FAIL') : anyFail ? 'FAIL' : anyAccount ? 'ACCOUNT' : 'PASS';
|
|
470
|
+
if (extended) {
|
|
471
|
+
console.log(`${verdict.padEnd(7)} ${r.name.padEnd(30)} ${marks.join(' ')} ${cache}`);
|
|
472
|
+
if (r.error) console.log(` error=${r.error}`);
|
|
473
|
+
for (const e of evid) console.log(` ${e}`);
|
|
474
|
+
} else {
|
|
475
|
+
const turn = (key, label) => {
|
|
476
|
+
const t = r.turns?.[key];
|
|
477
|
+
const ok = t && !t.error && scenarios.find((s) => s[0] === key)[2](t, r);
|
|
478
|
+
return `${label}${ok ? '✓' : '✗'} ${t?.ms}ms [${t?.calls}] "${short(t?.text)}"`;
|
|
479
|
+
};
|
|
480
|
+
const pass = !r.error && verdict === 'PASS';
|
|
481
|
+
console.log(
|
|
482
|
+
`${pass ? 'PASS' : verdict === 'ACCOUNT' ? 'ACCOUNT' : 'FAIL'} ${r.name.padEnd(30)} ` +
|
|
483
|
+
(r.error ? `error=${r.error}` : `${turn('t1', 't1')} | ${turn('t2', 't2')} | ${turn('t3', 't3')}`)
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (extended) {
|
|
489
|
+
// Oddities worth a manual look: model identity, usage presence, notices mixed into answers.
|
|
490
|
+
console.log('\n--- NON-PASS DETAILS (raw) ---');
|
|
491
|
+
for (const { r, label, mark, t } of details) {
|
|
492
|
+
console.log(
|
|
493
|
+
`[${mark === 'A' ? 'ACCOUNT' : mark === '?' ? 'UNVERIFIED' : 'FAIL'}] ${r.provider}/${r.model} effort=${r.effort ?? '-'} ${label}: ` +
|
|
494
|
+
`error=${JSON.stringify(t?.error ?? null)} text=${JSON.stringify(t?.text ?? null)} calls=${JSON.stringify(t?.calls ?? null)} disk=${JSON.stringify(t?.disk ?? null)}`
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
console.log('\n--- ODDITIES ---');
|
|
498
|
+
for (const r of results) {
|
|
499
|
+
for (const key of r.order || []) {
|
|
500
|
+
const t = r.turns[key];
|
|
501
|
+
if (t?.models?.length && !t.models.some((m) => m === r.model || m.endsWith(`/${r.model}`) || m.includes(r.model) || r.model.includes(m)))
|
|
502
|
+
console.log(`${r.name} ${key}: served model ${JSON.stringify(t.models)} != requested ${r.model}`);
|
|
503
|
+
if (/notice|overloaded|retrying|fallback|server error|temporarily/i.test(t?.text || ''))
|
|
504
|
+
console.log(`${r.name} ${key}: notice-like text ${JSON.stringify(t.text)}`);
|
|
505
|
+
if (t && !t.skipped && !t.error && t.usage && t.usage.events === 0) console.log(`${r.name} ${key}: no usage events`);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
removeTemp();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: Advisor
|
|
3
|
-
description: Use on
|
|
3
|
+
description: "Use by difficulty: on any work beyond a simple one- or two-step change, after orientation and before committing to an approach, when errors recur or results stop converging, before changing approach, and for requested second opinions."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
Independent technical advisor.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "advisor",
|
|
3
3
|
"name": "Advisor",
|
|
4
|
-
"description": "Use on
|
|
4
|
+
"description": "Use by difficulty: on any work beyond a simple one- or two-step change, after orientation and before committing to an approach, when errors recur or results stop converging, before changing approach, and for requested second opinions.",
|
|
5
5
|
"entry": "AGENT.md"
|
|
6
6
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"agents": {
|
|
3
3
|
"advisor": [
|
|
4
|
+
"6bd0318995f70547c162efda92795e79",
|
|
4
5
|
"d3b4a7926c9484833fe8ddba70260f9d"
|
|
5
6
|
],
|
|
6
7
|
"debugger": [
|
|
@@ -62,6 +63,7 @@
|
|
|
62
63
|
"56355187d05762ef50579d6285636c71",
|
|
63
64
|
"599d6b09954a3afb163091878d3b7040",
|
|
64
65
|
"5fa8ddf4731b39cec5fa269d632cfcc4",
|
|
66
|
+
"627f69923f1b895e3ac5f95f9b2d766b",
|
|
65
67
|
"660cc103947dd30b94c70bcd1f22cefe",
|
|
66
68
|
"6bbd8bb9e7657bc642f7be02f36dfc6d",
|
|
67
69
|
"7976531213723a66a7a53b9a1cf0f372",
|
|
@@ -99,6 +101,7 @@
|
|
|
99
101
|
"outputStyles": {
|
|
100
102
|
"common.md": [
|
|
101
103
|
"4e6134d60ee5c54c2888e874653bcdad",
|
|
104
|
+
"4ecd89b0c07ad8a81aa1f84882cf1b00",
|
|
102
105
|
"899529696b7d6d3373ae83a76976ab48",
|
|
103
106
|
"8d343d0a406fd5817b7fd98a3ac47010",
|
|
104
107
|
"a1b73ce404125d3ce0a5762e4a1e1555",
|
|
@@ -336,9 +339,11 @@
|
|
|
336
339
|
"70c54f802c77b630863b9e17a16d8224",
|
|
337
340
|
"81e979463e0066e7a45cf511a31c5d68",
|
|
338
341
|
"8476c811b2f02da3a434bcb23a1c3d12",
|
|
342
|
+
"8af2b614e2a07b58dad6c0f1318d22e2",
|
|
339
343
|
"9f90d3872b1ecd312977ce661b770b31",
|
|
340
344
|
"ade615dd0f6ae6ed1601023e5b9cb692",
|
|
341
345
|
"b4f9c79dcb08151e6275b5ee35c2bca4",
|
|
346
|
+
"c6db973f51166fc42814808ae0001797",
|
|
342
347
|
"c8826387a65631b63e8023f55ef807a3",
|
|
343
348
|
"cb6f66d14ba75b11e7470eb3fd5ec94c",
|
|
344
349
|
"de9727a48e52673258bf5f9670564d56",
|
|
@@ -69,7 +69,8 @@ that a call returned without transport error.
|
|
|
69
69
|
injection stays on regardless. `set_recap_enabled` changes only the
|
|
70
70
|
background cycles. Core Memory entries
|
|
71
71
|
are read and changed with the `memory` tool, not setup.
|
|
72
|
-
- Built-ins have installation state separate from enabled state
|
|
72
|
+
- Built-ins have installation state separate from enabled state; Visualize
|
|
73
|
+
is toggle-only (on by default, no install step). Browser Use,
|
|
73
74
|
Computer Use actions require this conversation open in the local Desktop
|
|
74
75
|
window; voice runs on the runtime and needs no Desktop.
|
|
75
76
|
- Hook rules are before-tool policy, separate from MCP and plugins. Deleting a
|
|
@@ -94,6 +95,10 @@ that a call returned without transport error.
|
|
|
94
95
|
- For an MCP failure, inspect the reported transport error before changing
|
|
95
96
|
command, arguments, directory, environment, URL, headers, or enabled state.
|
|
96
97
|
- MCP reads intentionally omit raw connection values that may contain secrets.
|
|
98
|
+
- An HTTP/SSE MCP server that needs OAuth waits for sign-in instead of
|
|
99
|
+
failing; setup rows then show it enabled, not connected, with no `error`.
|
|
100
|
+
Setup cannot sign in, and `reconnect_mcp` does not log in: hand off to
|
|
101
|
+
`open mcp` (Connect/Reconnect) or the TUI `/mcp login`.
|
|
97
102
|
- For an unavailable built-in, distinguish not installed, installed but
|
|
98
103
|
disabled, and bridge inactive.
|
|
99
104
|
- Desktop requests require a single live claimant and a confirmed receipt.
|