mixdog 0.9.3 → 0.9.5
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 +112 -38
- package/package.json +10 -3
- package/scripts/bench/lead-review-tasks-r3.json +20 -0
- package/scripts/bench/lead-review-tasks.json +20 -0
- package/scripts/bench/r4-mixed-tasks.json +20 -0
- package/scripts/bench/r5-orchestrated-task.json +7 -0
- package/scripts/bench/review-tasks.json +20 -0
- package/scripts/bench/round-codex.json +114 -0
- package/scripts/bench/round-mixdog-lead-r3.json +269 -0
- package/scripts/bench/round-mixdog-lead.json +269 -0
- package/scripts/bench/round-mixdog.json +126 -0
- package/scripts/bench/round-r10-bigsample.json +679 -0
- package/scripts/bench/round-r11-codexalign.json +257 -0
- package/scripts/bench/round-r13-clientmeta.json +464 -0
- package/scripts/bench/round-r14-betafeatures.json +466 -0
- package/scripts/bench/round-r15-fulldefault.json +462 -0
- package/scripts/bench/round-r16-sessionid.json +466 -0
- package/scripts/bench/round-r17-wirebytes.json +456 -0
- package/scripts/bench/round-r18-prewarm.json +468 -0
- package/scripts/bench/round-r19-clean.json +472 -0
- package/scripts/bench/round-r20-prewarm-clean.json +475 -0
- package/scripts/bench/round-r21-delta-retry.json +473 -0
- package/scripts/bench/round-r22-full-probe.json +693 -0
- package/scripts/bench/round-r23-itemprobe.json +701 -0
- package/scripts/bench/round-r24-shapefix.json +677 -0
- package/scripts/bench/round-r25-serial.json +464 -0
- package/scripts/bench/round-r26-parallel3.json +671 -0
- package/scripts/bench/round-r27-parallel10.json +894 -0
- package/scripts/bench/round-r28-parallel10-stagger.json +882 -0
- package/scripts/bench/round-r29-parallel10-stagger166.json +886 -0
- package/scripts/bench/round-r30-instid.json +253 -0
- package/scripts/bench/round-r31-upgradeprobe.json +256 -0
- package/scripts/bench/round-r32-vs-codex-lead.json +254 -0
- package/scripts/bench/round-r33-vs-codex-codex.json +115 -0
- package/scripts/bench/round-r34-orchestrated.json +120 -0
- package/scripts/bench/round-r35-orchestrated-codex.json +61 -0
- package/scripts/bench/round-r36-orchestrated-capped.json +128 -0
- package/scripts/bench/round-r4-codex.json +114 -0
- package/scripts/bench/round-r4-mixed.json +225 -0
- package/scripts/bench/round-r5-gpt-lead.json +259 -0
- package/scripts/bench/round-r6-codex.json +114 -0
- package/scripts/bench/round-r6-solo.json +257 -0
- package/scripts/bench/round-r7-full.json +254 -0
- package/scripts/bench/round-r8-fulldefault.json +255 -0
- package/scripts/bench-run.mjs +251 -32
- package/scripts/freevar-smoke.mjs +95 -0
- package/scripts/internal-comms-bench.mjs +3 -4
- package/scripts/internal-comms-smoke.mjs +10 -9
- package/scripts/model-catalog-audit.mjs +209 -0
- package/scripts/model-list-sanitize-test.mjs +37 -0
- package/scripts/mouse-probe.mjs +45 -0
- package/scripts/output-style-bench.mjs +13 -6
- package/scripts/output-style-smoke.mjs +4 -4
- package/scripts/provider-toolcall-test.mjs +7 -3
- package/scripts/recall-bench.mjs +76 -13
- package/scripts/recall-quality-cases.json +12 -0
- package/scripts/recall-usecase-cases.json +18 -0
- package/scripts/session-bench.mjs +152 -6
- package/scripts/tool-smoke.mjs +25 -65
- package/scripts/tui-render-smoke.mjs +90 -0
- package/scripts/webhook-smoke.mjs +208 -0
- package/src/agents/debugger/AGENT.md +4 -1
- package/src/agents/heavy-worker/AGENT.md +9 -8
- package/src/agents/maintainer/AGENT.md +4 -0
- package/src/agents/reviewer/AGENT.md +2 -1
- package/src/agents/scheduler-task/AGENT.md +2 -3
- package/src/agents/webhook-handler/AGENT.md +2 -3
- package/src/agents/worker/AGENT.md +10 -7
- package/src/app.mjs +12 -1
- package/src/headless-role.mjs +7 -1
- package/src/lib/rules-builder.cjs +4 -0
- package/src/mixdog-session-runtime.mjs +647 -2056
- package/src/output-styles/default.md +30 -9
- package/src/output-styles/{oneline.md → extreme-minimal.md} +5 -4
- package/src/output-styles/minimal.md +8 -6
- package/src/output-styles/simple.md +21 -7
- package/src/rules/agent/00-common.md +6 -3
- package/src/rules/agent/30-explorer.md +16 -5
- package/src/rules/lead/01-general.md +5 -5
- package/src/rules/lead/lead-brief.md +15 -0
- package/src/rules/lead/lead-tool.md +6 -15
- package/src/rules/shared/01-tool.md +17 -21
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +8 -3
- package/src/runtime/agent/orchestrator/agent-runtime/agent-loop-policy.mjs +25 -0
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +100 -23
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +6 -15
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +362 -0
- package/src/runtime/agent/orchestrator/agent-trace-io.mjs +410 -0
- package/src/runtime/agent/orchestrator/agent-trace.mjs +16 -735
- package/src/runtime/agent/orchestrator/config.mjs +69 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +62 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +209 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +489 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +81 -1281
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +607 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +32 -3
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +81 -0
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +248 -0
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +303 -0
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +505 -0
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +43 -1013
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +105 -11
- package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +356 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-model.mjs +108 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +58 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +368 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +760 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +40 -1143
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +740 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +193 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +349 -2131
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +143 -1002
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +229 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-events.mjs +67 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +465 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +1105 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/provider-catalog-cache.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/compact/budget.mjs +288 -0
- package/src/runtime/agent/orchestrator/session/compact/constants.mjs +85 -0
- package/src/runtime/agent/orchestrator/session/compact/engine.mjs +749 -0
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +82 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-schema.mjs +315 -0
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +643 -0
- package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +326 -0
- package/src/runtime/agent/orchestrator/session/compact.mjs +40 -2282
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +14 -2
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +61 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +275 -0
- package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +173 -0
- package/src/runtime/agent/orchestrator/session/loop/termination.mjs +58 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +239 -0
- package/src/runtime/agent/orchestrator/session/loop.mjs +278 -402
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +471 -0
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +7 -4
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +406 -0
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +210 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +166 -1087
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +189 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +74 -179
- package/src/runtime/agent/orchestrator/stall-policy.mjs +20 -1
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +70 -20
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +22 -2
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +35 -44
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +40 -0
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +29 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +126 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +81 -92
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +161 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +108 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +28 -265
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +0 -6
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +57 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/keyword-match.mjs +82 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +10 -122
- package/src/runtime/agent/orchestrator/tools/code-graph/text-columns.mjs +45 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/patch/constants.mjs +9 -0
- package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +171 -0
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +471 -0
- package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +436 -0
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +342 -0
- package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +359 -0
- package/src/runtime/agent/orchestrator/tools/patch/paths.mjs +340 -0
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +643 -0
- package/src/runtime/agent/orchestrator/tools/patch.mjs +36 -2959
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +0 -21
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +9 -72
- package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/shell-state.mjs +154 -0
- package/src/runtime/channels/backends/discord-access.mjs +32 -0
- package/src/runtime/channels/backends/discord-attachments.mjs +65 -0
- package/src/runtime/channels/backends/discord-gateway.mjs +233 -0
- package/src/runtime/channels/backends/discord.mjs +27 -318
- package/src/runtime/channels/backends/telegram.mjs +8 -12
- package/src/runtime/channels/index.mjs +247 -701
- package/src/runtime/channels/lib/backend-dispatch.mjs +46 -0
- package/src/runtime/channels/lib/config.mjs +37 -149
- package/src/runtime/channels/lib/event-pipeline.mjs +22 -5
- package/src/runtime/channels/lib/event-queue.mjs +78 -13
- package/src/runtime/channels/lib/inbound-routing.mjs +74 -0
- package/src/runtime/channels/lib/interaction-workflows.mjs +5 -113
- package/src/runtime/channels/lib/output-forwarder.mjs +1 -1
- package/src/runtime/channels/lib/owner-heartbeat.mjs +75 -0
- package/src/runtime/channels/lib/parent-bridge.mjs +88 -0
- package/src/runtime/channels/lib/runtime-paths.mjs +14 -4
- package/src/runtime/channels/lib/scheduler.mjs +27 -113
- package/src/runtime/channels/lib/session-discovery.mjs +56 -4
- package/src/runtime/channels/lib/tool-dispatch.mjs +158 -0
- package/src/runtime/channels/lib/tool-format.mjs +1 -1
- package/src/runtime/channels/lib/transcript-discovery.mjs +4 -4
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +6 -3
- package/src/runtime/channels/lib/voice-transcription.mjs +179 -0
- package/src/runtime/channels/lib/webhook/deliveries.mjs +313 -0
- package/src/runtime/channels/lib/webhook/log.mjs +42 -0
- package/src/runtime/channels/lib/webhook/ngrok.mjs +181 -0
- package/src/runtime/channels/lib/webhook/signature.mjs +60 -0
- package/src/runtime/channels/lib/webhook.mjs +43 -616
- package/src/runtime/channels/tool-defs.mjs +11 -130
- package/src/runtime/memory/index.mjs +210 -1948
- package/src/runtime/memory/lib/core-memory-store.mjs +5 -1
- package/src/runtime/memory/lib/cycle-llm-adapters.mjs +58 -0
- package/src/runtime/memory/lib/cycle-scheduler.mjs +497 -0
- package/src/runtime/memory/lib/embedding-warmup.mjs +58 -0
- package/src/runtime/memory/lib/ko-morph.mjs +195 -0
- package/src/runtime/memory/lib/memory-config-flags.mjs +91 -0
- package/src/runtime/memory/lib/memory-cycle.mjs +1 -1
- package/src/runtime/memory/lib/memory-cycle2-gate.mjs +515 -0
- package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +324 -0
- package/src/runtime/memory/lib/memory-cycle2-shared.mjs +18 -0
- package/src/runtime/memory/lib/memory-cycle2.mjs +24 -842
- package/src/runtime/memory/lib/memory-embed.mjs +149 -0
- package/src/runtime/memory/lib/memory-process-lock.mjs +162 -0
- package/src/runtime/memory/lib/memory-recall-store.mjs +69 -12
- package/src/runtime/memory/lib/memory-text-utils.mjs +46 -0
- package/src/runtime/memory/lib/pg/supervisor.mjs +1 -1
- package/src/runtime/memory/lib/query-handlers.mjs +802 -0
- package/src/runtime/memory/lib/recall-format.mjs +55 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +8 -3
- package/src/runtime/memory/lib/transcript-ingest.mjs +425 -0
- package/src/runtime/memory/tool-defs.mjs +5 -13
- package/src/runtime/search/lib/http-fetch.mjs +274 -0
- package/src/runtime/search/lib/ssrf-guard.mjs +333 -0
- package/src/runtime/search/lib/web-tools.mjs +24 -602
- package/src/runtime/shared/atomic-file.mjs +26 -1
- package/src/runtime/shared/config.mjs +14 -4
- package/src/runtime/shared/launcher-control.mjs +2 -2
- package/src/runtime/shared/markdown-frontmatter.mjs +19 -0
- package/src/runtime/shared/schedules-store.mjs +13 -3
- package/src/runtime/shared/tool-execution-contract.mjs +2 -2
- package/src/runtime/shared/tool-primitives.mjs +308 -0
- package/src/runtime/shared/tool-result-summary.mjs +515 -0
- package/src/runtime/shared/tool-surface.mjs +80 -898
- package/src/runtime/shared/transcript-writer.mjs +23 -0
- package/src/runtime/shared/update-checker.mjs +7 -4
- package/src/session-runtime/config-helpers.mjs +119 -2
- package/src/session-runtime/config-lifecycle.mjs +232 -0
- package/src/session-runtime/cwd-plugins.mjs +226 -0
- package/src/session-runtime/mcp-glue.mjs +177 -0
- package/src/session-runtime/model-recency.mjs +111 -0
- package/src/session-runtime/native-search.mjs +247 -0
- package/src/session-runtime/output-styles.mjs +11 -9
- package/src/session-runtime/prewarm.mjs +142 -0
- package/src/session-runtime/provider-models.mjs +278 -0
- package/src/session-runtime/provider-usage.mjs +120 -0
- package/src/session-runtime/quick-model-rows.mjs +205 -0
- package/src/session-runtime/quick-search-models.mjs +47 -0
- package/src/session-runtime/session-hooks.mjs +93 -0
- package/src/session-runtime/settings-api.mjs +352 -0
- package/src/session-runtime/tool-catalog.mjs +29 -29
- package/src/session-runtime/tool-defs.mjs +84 -0
- package/src/session-runtime/warmup-schedulers.mjs +201 -0
- package/src/session-runtime/workflow.mjs +1 -1
- package/src/standalone/agent-tool/helpers.mjs +237 -0
- package/src/standalone/agent-tool/notify.mjs +107 -0
- package/src/standalone/agent-tool/provider-init.mjs +143 -0
- package/src/standalone/agent-tool/render.mjs +152 -0
- package/src/standalone/agent-tool/tool-def.mjs +55 -0
- package/src/standalone/agent-tool.mjs +138 -669
- package/src/standalone/channel-admin.mjs +102 -90
- package/src/standalone/channel-worker.mjs +4 -7
- package/src/standalone/explore-tool.mjs +64 -14
- package/src/standalone/hook-bus/config.mjs +207 -0
- package/src/standalone/hook-bus/constants.mjs +90 -0
- package/src/standalone/hook-bus/handlers.mjs +481 -0
- package/src/standalone/hook-bus/payload.mjs +31 -0
- package/src/standalone/hook-bus/rules.mjs +77 -0
- package/src/standalone/hook-bus.mjs +77 -870
- package/src/standalone/memory-runtime-proxy.mjs +7 -0
- package/src/standalone/opencode-go-login.mjs +5 -1
- package/src/standalone/provider-admin.mjs +1 -16
- package/src/standalone/usage-dashboard.mjs +3 -1
- package/src/tui/App.jsx +1059 -8110
- package/src/tui/app/app-format.mjs +213 -0
- package/src/tui/app/channel-pickers.mjs +508 -0
- package/src/tui/app/clipboard.mjs +67 -0
- package/src/tui/app/core-memory-picker.mjs +210 -0
- package/src/tui/app/extension-pickers.mjs +506 -0
- package/src/tui/app/input-parsers.mjs +193 -0
- package/src/tui/app/maintenance-pickers.mjs +356 -0
- package/src/tui/app/model-options.mjs +334 -0
- package/src/tui/app/model-picker.mjs +365 -0
- package/src/tui/app/onboarding-steps.mjs +400 -0
- package/src/tui/app/project-picker.mjs +247 -0
- package/src/tui/app/provider-setup-picker.mjs +580 -0
- package/src/tui/app/resume-picker.mjs +55 -0
- package/src/tui/app/route-pickers.mjs +419 -0
- package/src/tui/app/settings-picker.mjs +489 -0
- package/src/tui/app/slash-commands.mjs +101 -0
- package/src/tui/app/slash-dispatch.mjs +427 -0
- package/src/tui/app/text-layout.mjs +46 -0
- package/src/tui/app/theme-effort-pickers.mjs +154 -0
- package/src/tui/app/transcript-window.mjs +677 -0
- package/src/tui/app/use-mouse-input.mjs +460 -0
- package/src/tui/app/use-prompt-handlers.mjs +310 -0
- package/src/tui/app/use-transcript-scroll.mjs +512 -0
- package/src/tui/app/use-transcript-window.mjs +607 -0
- package/src/tui/components/ConfirmBar.jsx +10 -7
- package/src/tui/components/Picker.jsx +64 -15
- package/src/tui/components/PromptInput.jsx +33 -102
- package/src/tui/components/SlashCommandPalette.jsx +8 -1
- package/src/tui/components/StatusLine.jsx +69 -15
- package/src/tui/components/TextEntryPanel.jsx +11 -0
- package/src/tui/components/ToolExecution.jsx +52 -594
- package/src/tui/components/TranscriptItem.jsx +105 -0
- package/src/tui/components/UsagePanel.jsx +18 -4
- package/src/tui/components/prompt-input/edit-helpers.mjs +72 -0
- package/src/tui/components/prompt-input/voice-indicator.mjs +39 -0
- package/src/tui/components/tool-execution/ResultBody.jsx +56 -0
- package/src/tui/components/tool-execution/surface-detail.mjs +405 -0
- package/src/tui/components/tool-execution/text-format.mjs +161 -0
- package/src/tui/display-width.mjs +20 -3
- package/src/tui/dist/index.mjs +13553 -12384
- package/src/tui/engine/agent-job-feed.mjs +133 -0
- package/src/tui/engine/notification-plan.mjs +76 -0
- package/src/tui/engine/render-timing.mjs +17 -0
- package/src/tui/engine/tool-approval.mjs +94 -0
- package/src/tui/engine/tool-card-results.mjs +234 -0
- package/src/tui/engine/tool-result-status.mjs +135 -0
- package/src/tui/engine.mjs +170 -574
- package/src/tui/figures.mjs +5 -0
- package/src/tui/index.jsx +65 -1
- package/src/tui/input-editing.mjs +2 -2
- package/src/tui/markdown/format-token.mjs +4 -1
- package/src/tui/statusline-ansi-bridge.mjs +11 -3
- package/src/tui/theme.mjs +6 -0
- package/src/ui/statusline-agents.mjs +213 -0
- package/src/ui/statusline-format.mjs +146 -0
- package/src/ui/statusline-segments.mjs +148 -0
- package/src/ui/statusline.mjs +77 -501
- package/src/ui/tool-card.mjs +0 -1
- package/src/vendor/statusline/bin/statusline-route.mjs +15 -2
- package/src/workflows/default/WORKFLOW.md +16 -18
- package/src/workflows/sequential/WORKFLOW.md +16 -18
- package/vendor/ink/build/display-width.js +19 -3
- package/vendor/ink/build/ink.js +112 -7
- package/vendor/ink/build/log-update.js +17 -3
- package/vendor/ink/build/wrap-text.js +125 -0
- package/scripts/_test-folder-dialog.mjs +0 -30
- package/scripts/fix-brief-fn.mjs +0 -35
- package/scripts/fix-format-tool-surface.mjs +0 -24
- package/scripts/fix-tool-exec-visible.mjs +0 -42
- package/scripts/patch-agent-brief.mjs +0 -48
- package/scripts/patch-app.mjs +0 -21
- package/scripts/patch-app2.mjs +0 -18
- package/scripts/patch-dist-brief.mjs +0 -96
- package/scripts/patch-tool-exec.mjs +0 -70
- package/src/examples/schedules/SCHEDULE.example.md +0 -32
- package/src/examples/webhooks/WEBHOOK.example.md +0 -40
- package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +0 -107
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.test.mjs +0 -143
- package/src/runtime/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -285
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.test.mjs +0 -162
- package/src/runtime/agent/orchestrator/tools/builtin/open-config-tool.mjs +0 -26
- package/src/runtime/channels/lib/holidays.mjs +0 -138
- package/src/runtime/shared/channel-notification-routing.test.mjs +0 -45
- package/src/runtime/shared/task-notification-envelope.test.mjs +0 -107
- package/src/runtime/shared/tool-execution-contract.test.mjs +0 -183
- package/src/standalone/agent-task-status.test.mjs +0 -76
- package/src/tui/components/tool-output-format.test.mjs +0 -399
- package/src/tui/display-width.test.mjs +0 -35
- package/src/tui/engine-runtime-notification.test.mjs +0 -115
- package/src/tui/engine-tool-result-text.test.mjs +0 -75
- package/src/tui/input-editing.selection.test.mjs +0 -75
- package/src/tui/markdown/format-token.test.mjs +0 -354
- package/src/tui/markdown/render-ansi.test.mjs +0 -108
- package/src/tui/markdown/stream-fence.test.mjs +0 -26
- package/src/tui/markdown/streaming-markdown.test.mjs +0 -70
- package/src/tui/paste-fix.test.mjs +0 -119
- package/src/tui/prompt-history-store.test.mjs +0 -52
- package/src/tui/statusline-ansi-bridge.test.mjs +0 -159
- package/src/tui/transcript-tool-failures.test.mjs +0 -111
- package/src/ui/markdown.test.mjs +0 -70
- package/src/ui/statusline-context-label.test.mjs +0 -15
- package/src/vendor/statusline/bin/statusline-lib.mjs +0 -186
- package/src/vendor/statusline/bin/statusline-route.test.mjs +0 -80
|
@@ -1,320 +1,19 @@
|
|
|
1
|
-
import { readFileSync, existsSync, mkdirSync, appendFileSync, statSync, renameSync } from 'fs';
|
|
2
|
-
import { appendFile } from 'fs/promises';
|
|
3
|
-
import { dirname, join } from 'path';
|
|
4
1
|
import { createHash } from 'crypto';
|
|
5
|
-
import os from 'os';
|
|
6
|
-
import { getPluginData } from './config.mjs';
|
|
7
2
|
import { isInclusiveProvider } from '../../shared/llm/cost.mjs';
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
let _localTracePath = null;
|
|
23
|
-
let _localTraceBuffer = [];
|
|
24
|
-
let _localTraceTimer = null;
|
|
25
|
-
let _localTraceFlushInFlight = false;
|
|
26
|
-
let _toolFailurePath = null;
|
|
27
|
-
let _toolFailureBuffer = [];
|
|
28
|
-
let _toolFailureTimer = null;
|
|
29
|
-
let _toolFailureFlushInFlight = false;
|
|
30
|
-
const _LOCAL_TRACE_FLUSH_LINES = 100;
|
|
31
|
-
const _LOCAL_TRACE_FLUSH_MS = 1000;
|
|
32
|
-
const _LOCAL_TRACE_MAX_BYTES = 10 * 1024 * 1024; // 10 MB — rotate to .1/.2/.3 above this.
|
|
33
|
-
// Rotation generations kept on disk (.1 newest … .N oldest). A single .1
|
|
34
|
-
// generation proved too short a window — bench rounds (session-bench /
|
|
35
|
-
// task-bench re-scoring) were losing their raw turn rows to a second rotation
|
|
36
|
-
// within hours. 3 generations ≈ 40 MB worst case per log. Env-overridable via
|
|
37
|
-
// MIXDOG_AGENT_TRACE_ROTATE_KEEP (positive integer).
|
|
38
|
-
const _LOCAL_TRACE_ROTATE_KEEP = (() => {
|
|
39
|
-
const v = parseInt(process.env.MIXDOG_AGENT_TRACE_ROTATE_KEEP, 10);
|
|
40
|
-
return Number.isFinite(v) && v > 0 ? v : 3;
|
|
41
|
-
})();
|
|
42
|
-
const _TOOL_FAILURE_FLUSH_LINES = 50;
|
|
43
|
-
const _TOOL_FAILURE_FLUSH_MS = 1000;
|
|
44
|
-
const MIXDOG_SLOW_TOOL_TRACE_MS = (() => {
|
|
45
|
-
const v = parseInt(process.env.MIXDOG_SLOW_TOOL_TRACE_MS, 10);
|
|
46
|
-
return Number.isFinite(v) && v > 0 ? v : 3000;
|
|
47
|
-
})();
|
|
48
|
-
const MIXDOG_SLOW_TOOL_TRACE_NAMES_RAW = String(process.env.MIXDOG_SLOW_TOOL_TRACE_NAMES || 'recall,grep,code_graph');
|
|
49
|
-
const MIXDOG_SLOW_TOOL_TRACE_ALL = MIXDOG_SLOW_TOOL_TRACE_NAMES_RAW.trim() === '*';
|
|
50
|
-
const MIXDOG_SLOW_TOOL_TRACE_NAMES = new Set(
|
|
51
|
-
MIXDOG_SLOW_TOOL_TRACE_NAMES_RAW
|
|
52
|
-
.split(',')
|
|
53
|
-
.map((name) => name.trim())
|
|
54
|
-
.filter(Boolean)
|
|
55
|
-
);
|
|
56
|
-
// Throttle interval for local rotation stat checks. statSync on every flush
|
|
57
|
-
// is unnecessary — rotation is a best-effort size guard. First flush always
|
|
58
|
-
// checks; subsequent checks wait at least this many ms. Tune via env
|
|
59
|
-
// MIXDOG_AGENT_TRACE_ROTATE_CHECK_MS (default 60000 ms, positive integer).
|
|
60
|
-
const MIXDOG_AGENT_TRACE_ROTATE_CHECK_MS = (() => {
|
|
61
|
-
const v = parseInt(process.env.MIXDOG_AGENT_TRACE_ROTATE_CHECK_MS, 10);
|
|
62
|
-
return Number.isFinite(v) && v > 0 ? v : 60000;
|
|
63
|
-
})();
|
|
64
|
-
let _lastRotateCheckMs = 0;
|
|
65
|
-
let _lastToolFailureRotateCheckMs = 0;
|
|
66
|
-
|
|
67
|
-
function _rotateLocalTraceIfNeeded(path) {
|
|
68
|
-
try {
|
|
69
|
-
const stat = statSync(path);
|
|
70
|
-
if (stat && stat.size > _LOCAL_TRACE_MAX_BYTES) {
|
|
71
|
-
try {
|
|
72
|
-
// Shift generations oldest-first: .2 → .3, .1 → .2, live → .1.
|
|
73
|
-
// The oldest (.KEEP) is overwritten by the rename below it.
|
|
74
|
-
for (let gen = _LOCAL_TRACE_ROTATE_KEEP - 1; gen >= 1; gen -= 1) {
|
|
75
|
-
const src = `${path}.${gen}`;
|
|
76
|
-
if (existsSync(src)) renameSync(src, `${path}.${gen + 1}`);
|
|
77
|
-
}
|
|
78
|
-
renameSync(path, `${path}.1`);
|
|
79
|
-
}
|
|
80
|
-
catch (err) {
|
|
81
|
-
warnAgentOnce('agent-trace:local-rotate', `[agent-trace] local rotate failed (${err?.message})`);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
} catch {
|
|
85
|
-
// File missing or unstattable — nothing to rotate.
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function _resolveLocalTracePath() {
|
|
90
|
-
if (process.env.MIXDOG_AGENT_TRACE_LOCAL_DISABLE === '1') return null;
|
|
91
|
-
if (_localTracePath) return _localTracePath;
|
|
92
|
-
try {
|
|
93
|
-
_localTracePath = process.env.MIXDOG_AGENT_TRACE_PATH
|
|
94
|
-
|| join(getPluginData(), 'history', 'agent-trace.jsonl');
|
|
95
|
-
// R4 data-at-rest: trace rows may carry tool payloads / prompts;
|
|
96
|
-
// clamp dir to owner-only on POSIX (advisory on Windows).
|
|
97
|
-
mkdirSync(dirname(_localTracePath), { recursive: true, mode: 0o700 });
|
|
98
|
-
return _localTracePath;
|
|
99
|
-
} catch {
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function _appendLocalTrace(row) {
|
|
105
|
-
if (!_resolveLocalTracePath()) return;
|
|
106
|
-
try {
|
|
107
|
-
_localTraceBuffer.push(`${JSON.stringify(row)}\n`);
|
|
108
|
-
if (_localTraceBuffer.length >= _LOCAL_TRACE_FLUSH_LINES) {
|
|
109
|
-
_flushLocalTrace();
|
|
110
|
-
} else if (!_localTraceTimer) {
|
|
111
|
-
_localTraceTimer = setTimeout(_flushLocalTrace, _LOCAL_TRACE_FLUSH_MS);
|
|
112
|
-
_localTraceTimer.unref?.();
|
|
113
|
-
}
|
|
114
|
-
} catch (err) {
|
|
115
|
-
warnAgentOnce('agent-trace:local-spool', `[agent-trace] local spool failed (${err?.message})`);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function _flushLocalTrace() {
|
|
120
|
-
if (_localTraceTimer) {
|
|
121
|
-
clearTimeout(_localTraceTimer);
|
|
122
|
-
_localTraceTimer = null;
|
|
123
|
-
}
|
|
124
|
-
if (_localTraceBuffer.length === 0) return;
|
|
125
|
-
if (_localTraceFlushInFlight) {
|
|
126
|
-
_localTraceTimer = setTimeout(_flushLocalTrace, 25);
|
|
127
|
-
_localTraceTimer.unref?.();
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
const path = _resolveLocalTracePath();
|
|
131
|
-
if (!path) return;
|
|
132
|
-
const chunk = _localTraceBuffer.join('');
|
|
133
|
-
_localTraceBuffer = [];
|
|
134
|
-
try {
|
|
135
|
-
// Throttle rotation stat checks to avoid unnecessary statSync calls
|
|
136
|
-
// on every flush. First flush (_lastRotateCheckMs === 0) always checks.
|
|
137
|
-
const now = Date.now();
|
|
138
|
-
if (_lastRotateCheckMs === 0 || now - _lastRotateCheckMs >= MIXDOG_AGENT_TRACE_ROTATE_CHECK_MS) {
|
|
139
|
-
_rotateLocalTraceIfNeeded(path);
|
|
140
|
-
_lastRotateCheckMs = now;
|
|
141
|
-
}
|
|
142
|
-
} catch (err) {
|
|
143
|
-
warnAgentOnce('agent-trace:local-spool', `[agent-trace] local spool failed (${err?.message})`);
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
// mode only applies on file creation; existing files keep their mode.
|
|
147
|
-
// Windows ignores POSIX bits — ACL governs there.
|
|
148
|
-
_localTraceFlushInFlight = true;
|
|
149
|
-
appendFile(path, chunk, { encoding: 'utf8', mode: 0o600 })
|
|
150
|
-
.catch((err) => {
|
|
151
|
-
warnAgentOnce('agent-trace:local-spool', `[agent-trace] local spool failed (${err?.message})`);
|
|
152
|
-
})
|
|
153
|
-
.finally(() => {
|
|
154
|
-
_localTraceFlushInFlight = false;
|
|
155
|
-
if (_localTraceBuffer.length > 0) {
|
|
156
|
-
_localTraceTimer = setTimeout(_flushLocalTrace, 0);
|
|
157
|
-
_localTraceTimer.unref?.();
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function _flushLocalTraceSync() {
|
|
163
|
-
if (_localTraceTimer) {
|
|
164
|
-
clearTimeout(_localTraceTimer);
|
|
165
|
-
_localTraceTimer = null;
|
|
166
|
-
}
|
|
167
|
-
if (_localTraceBuffer.length === 0) return;
|
|
168
|
-
const path = _resolveLocalTracePath();
|
|
169
|
-
if (!path) return;
|
|
170
|
-
const chunk = _localTraceBuffer.join('');
|
|
171
|
-
_localTraceBuffer = [];
|
|
172
|
-
try {
|
|
173
|
-
const now = Date.now();
|
|
174
|
-
if (_lastRotateCheckMs === 0 || now - _lastRotateCheckMs >= MIXDOG_AGENT_TRACE_ROTATE_CHECK_MS) {
|
|
175
|
-
_rotateLocalTraceIfNeeded(path);
|
|
176
|
-
_lastRotateCheckMs = now;
|
|
177
|
-
}
|
|
178
|
-
appendFileSync(path, chunk, { encoding: 'utf8', mode: 0o600 });
|
|
179
|
-
} catch (err) {
|
|
180
|
-
warnAgentOnce('agent-trace:local-spool', `[agent-trace] local spool failed (${err?.message})`);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
try {
|
|
185
|
-
process.on('beforeExit', () => {
|
|
186
|
-
_flushLocalTraceSync();
|
|
187
|
-
_flushToolFailuresSync();
|
|
188
|
-
});
|
|
189
|
-
process.on('exit', () => {
|
|
190
|
-
_flushLocalTraceSync();
|
|
191
|
-
_flushToolFailuresSync();
|
|
192
|
-
});
|
|
193
|
-
} catch {
|
|
194
|
-
// Ignore lifecycle hook failures in embedded runtimes.
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function _resolveServiceUrl() {
|
|
198
|
-
if (_serviceUrl) return _serviceUrl;
|
|
199
|
-
try {
|
|
200
|
-
const runtimeRoot = process.env.MIXDOG_RUNTIME_ROOT
|
|
201
|
-
? join(process.env.MIXDOG_RUNTIME_ROOT)
|
|
202
|
-
: join(os.tmpdir(), 'mixdog');
|
|
203
|
-
const activeFile = join(runtimeRoot, 'active-instance.json');
|
|
204
|
-
if (!existsSync(activeFile)) return null;
|
|
205
|
-
const active = JSON.parse(readFileSync(activeFile, 'utf-8'));
|
|
206
|
-
const port = Number(active && active.memory_port);
|
|
207
|
-
if (!Number.isFinite(port) || port <= 0) return null;
|
|
208
|
-
_serviceUrl = `http://127.0.0.1:${port}`;
|
|
209
|
-
return _serviceUrl;
|
|
210
|
-
} catch {
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
async function _flush() {
|
|
216
|
-
_flushTimer = null;
|
|
217
|
-
if (_buffer.length === 0) return;
|
|
218
|
-
if (_flushInFlight) {
|
|
219
|
-
if (!_flushTimer) { _flushTimer = setTimeout(_flush, _FLUSH_INTERVAL_MS); _flushTimer.unref?.(); }
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
_flushInFlight = true;
|
|
223
|
-
try {
|
|
224
|
-
const url = _resolveServiceUrl();
|
|
225
|
-
if (!url) {
|
|
226
|
-
// Service not up yet — keep buffer, retry next timer tick
|
|
227
|
-
if (!_flushTimer) { _flushTimer = setTimeout(_flush, _FLUSH_INTERVAL_MS); _flushTimer.unref?.(); }
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
const batch = _buffer.splice(0, _FLUSH_BATCH_SIZE);
|
|
231
|
-
try {
|
|
232
|
-
const resp = await fetch(`${url}/admin/trace-record`, {
|
|
233
|
-
method: 'POST',
|
|
234
|
-
headers: { 'Content-Type': 'application/json' },
|
|
235
|
-
body: JSON.stringify({ events: batch }),
|
|
236
|
-
signal: AbortSignal.timeout(5000),
|
|
237
|
-
});
|
|
238
|
-
// Always drain the body. An undrained response body keeps the
|
|
239
|
-
// underlying keep-alive socket referenced, which can hold the event
|
|
240
|
-
// loop open and make a short-lived process (smoke scripts / one-shot
|
|
241
|
-
// agent tasks) appear to hang for seconds after its work is done.
|
|
242
|
-
try { await resp.arrayBuffer(); } catch { /* body already gone */ }
|
|
243
|
-
if (!resp.ok) {
|
|
244
|
-
warnAgentOnce('agent-trace:flush-error', `[agent-trace] /admin/trace-record returned ${resp.status} — dropping batch`);
|
|
245
|
-
}
|
|
246
|
-
} catch (err) {
|
|
247
|
-
_serviceUrl = null;
|
|
248
|
-
warnAgentOnce('agent-trace:flush-fetch', `[agent-trace] flush fetch failed (${err?.message}) — dropping batch`);
|
|
249
|
-
}
|
|
250
|
-
if (_buffer.length >= _FLUSH_BATCH_SIZE) {
|
|
251
|
-
// More pending — schedule another flush immediately
|
|
252
|
-
setImmediate(_flush);
|
|
253
|
-
}
|
|
254
|
-
} finally {
|
|
255
|
-
_flushInFlight = false;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
function _scheduleFlush(immediate = false) {
|
|
260
|
-
if (immediate) {
|
|
261
|
-
if (_flushTimer) { clearTimeout(_flushTimer); _flushTimer = null; }
|
|
262
|
-
setImmediate(_flush);
|
|
263
|
-
} else if (!_flushTimer) {
|
|
264
|
-
_flushTimer = setTimeout(_flush, _FLUSH_INTERVAL_MS);
|
|
265
|
-
// Never let the periodic trace flush keep the event loop alive: a
|
|
266
|
-
// ref'd 5s timer prevented short-lived processes (smoke scripts, agent
|
|
267
|
-
// tasks) from exiting naturally after their work was done — they hung
|
|
268
|
-
// until an external timeout/kill. exit/beforeExit drains still flush
|
|
269
|
-
// the buffer, so unref loses no data.
|
|
270
|
-
_flushTimer.unref?.();
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
async function drainAgentTrace() {
|
|
275
|
-
if (!_resolveServiceUrl()) return;
|
|
276
|
-
if (_flushTimer) { clearTimeout(_flushTimer); _flushTimer = null; }
|
|
277
|
-
for (let i = 0; i < 10 && _buffer.length > 0; i++) {
|
|
278
|
-
await _flush();
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
process.on('exit', drainAgentTrace);
|
|
282
|
-
|
|
283
|
-
function normalizeSessionId(sessionId) {
|
|
284
|
-
return sessionId ? String(sessionId) : 'no-session';
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
function appendAgentTrace(record = {}) {
|
|
288
|
-
// Test isolation — when run-all-tests.mjs sets this env, skip entirely.
|
|
289
|
-
if (process.env.MIXDOG_AGENT_TRACE_DISABLE === '1') return;
|
|
290
|
-
try {
|
|
291
|
-
// Coerce ts to epoch ms integer at enqueue time
|
|
292
|
-
let ts = record.ts || Date.now();
|
|
293
|
-
if (typeof ts === 'string') ts = Date.parse(ts);
|
|
294
|
-
ts = Number(ts);
|
|
295
|
-
if (!Number.isFinite(ts)) ts = Date.now();
|
|
296
|
-
|
|
297
|
-
const row = {
|
|
298
|
-
...record,
|
|
299
|
-
ts,
|
|
300
|
-
session_id: record.session_id ?? normalizeSessionId(record.sessionId),
|
|
301
|
-
payload: record.payload ?? {},
|
|
302
|
-
};
|
|
303
|
-
// Drop actor-facing alias to keep schema tidy
|
|
304
|
-
delete row.sessionId;
|
|
305
|
-
|
|
306
|
-
if (_buffer.length >= _BUFFER_MAX) {
|
|
307
|
-
_buffer.shift(); // drop oldest
|
|
308
|
-
warnAgentOnce('agent-trace:buffer-full', '[agent-trace] buffer full (2000) — dropping oldest event');
|
|
309
|
-
}
|
|
310
|
-
_appendLocalTrace(row);
|
|
311
|
-
_buffer.push(row);
|
|
312
|
-
_scheduleFlush(_buffer.length >= _FLUSH_BATCH_SIZE);
|
|
313
|
-
}
|
|
314
|
-
catch {
|
|
315
|
-
// Never break agent execution for telemetry
|
|
316
|
-
}
|
|
317
|
-
}
|
|
3
|
+
import {
|
|
4
|
+
appendAgentTrace,
|
|
5
|
+
drainAgentTrace,
|
|
6
|
+
normalizeSessionId,
|
|
7
|
+
warnAgentOnce,
|
|
8
|
+
} from './agent-trace-io.mjs';
|
|
9
|
+
import {
|
|
10
|
+
traceAgentLoop,
|
|
11
|
+
traceAgentCompact,
|
|
12
|
+
traceAgentTool,
|
|
13
|
+
traceAgentToolFailure,
|
|
14
|
+
traceAgentCompress,
|
|
15
|
+
traceAgentBatch,
|
|
16
|
+
} from './agent-trace-format.mjs';
|
|
318
17
|
|
|
319
18
|
function estimateProviderPayloadBytes(messages, model, tools) {
|
|
320
19
|
try {
|
|
@@ -339,29 +38,6 @@ function extractCachedTokens(usage) {
|
|
|
339
38
|
return 0;
|
|
340
39
|
}
|
|
341
40
|
|
|
342
|
-
function warnAgentOnce(key, message) {
|
|
343
|
-
if (!key || WARNED_KEYS.has(key)) return;
|
|
344
|
-
WARNED_KEYS.add(key);
|
|
345
|
-
try {
|
|
346
|
-
process.stderr.write(`${message}\n`);
|
|
347
|
-
}
|
|
348
|
-
catch {
|
|
349
|
-
// Ignore logging failures.
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
function traceAgentLoop({ sessionId, iteration, sendMs, messageCount, bodyBytesEst }) {
|
|
354
|
-
if (process.env.MIXDOG_AGENT_TRACE_VERBOSE !== '1') return;
|
|
355
|
-
appendAgentTrace({
|
|
356
|
-
sessionId,
|
|
357
|
-
iteration,
|
|
358
|
-
kind: 'loop',
|
|
359
|
-
send_ms: sendMs,
|
|
360
|
-
message_count: messageCount,
|
|
361
|
-
body_bytes_est: bodyBytesEst,
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
|
|
365
41
|
// Lightweight fingerprint of the conversation prefix. Hashes the first 4096
|
|
366
42
|
// characters of JSON.stringify(messages) — enough to detect prefix mutation
|
|
367
43
|
// across iterations (which invalidates the provider prompt cache) without
|
|
@@ -375,403 +51,6 @@ function messagePrefixHash(messages) {
|
|
|
375
51
|
return null;
|
|
376
52
|
}
|
|
377
53
|
}
|
|
378
|
-
|
|
379
|
-
function traceAgentCompact({
|
|
380
|
-
sessionId,
|
|
381
|
-
iteration,
|
|
382
|
-
stage,
|
|
383
|
-
trigger,
|
|
384
|
-
compact_type,
|
|
385
|
-
prune_count,
|
|
386
|
-
compact_changed,
|
|
387
|
-
input_prefix_hash,
|
|
388
|
-
before_count,
|
|
389
|
-
after_count,
|
|
390
|
-
before_bytes,
|
|
391
|
-
after_bytes,
|
|
392
|
-
context_window,
|
|
393
|
-
budget_tokens,
|
|
394
|
-
boundary_tokens,
|
|
395
|
-
target_budget_tokens,
|
|
396
|
-
reserve_tokens,
|
|
397
|
-
pressure_tokens,
|
|
398
|
-
trigger_tokens,
|
|
399
|
-
message_tokens_est,
|
|
400
|
-
duration_ms,
|
|
401
|
-
provider,
|
|
402
|
-
model,
|
|
403
|
-
error,
|
|
404
|
-
error_code,
|
|
405
|
-
details,
|
|
406
|
-
}) {
|
|
407
|
-
appendAgentTrace({
|
|
408
|
-
sessionId,
|
|
409
|
-
iteration,
|
|
410
|
-
kind: 'compact_meta',
|
|
411
|
-
stage: stage || null,
|
|
412
|
-
trigger: trigger || null,
|
|
413
|
-
compact_type: compact_type || null,
|
|
414
|
-
prune_count: prune_count ?? 0,
|
|
415
|
-
compact_changed: !!compact_changed,
|
|
416
|
-
input_prefix_hash: input_prefix_hash || null,
|
|
417
|
-
before_count: before_count ?? null,
|
|
418
|
-
after_count: after_count ?? null,
|
|
419
|
-
before_bytes: before_bytes ?? null,
|
|
420
|
-
after_bytes: after_bytes ?? null,
|
|
421
|
-
context_window: context_window ?? null,
|
|
422
|
-
budget_tokens: budget_tokens ?? null,
|
|
423
|
-
boundary_tokens: boundary_tokens ?? null,
|
|
424
|
-
target_budget_tokens: target_budget_tokens ?? null,
|
|
425
|
-
reserve_tokens: reserve_tokens ?? null,
|
|
426
|
-
pressure_tokens: pressure_tokens ?? null,
|
|
427
|
-
trigger_tokens: trigger_tokens ?? null,
|
|
428
|
-
message_tokens_est: message_tokens_est ?? null,
|
|
429
|
-
duration_ms: duration_ms ?? null,
|
|
430
|
-
provider: provider || null,
|
|
431
|
-
model: model || null,
|
|
432
|
-
error: error || null,
|
|
433
|
-
error_code: error_code || null,
|
|
434
|
-
details: details && typeof details === 'object' ? details : null,
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
const TOOL_ARG_KEYS = {
|
|
439
|
-
read: ['path', 'offset', 'limit', 'line', 'context', 'symbol'],
|
|
440
|
-
grep: ['pattern', 'path', 'glob', 'output_mode', 'head_limit', 'offset'],
|
|
441
|
-
glob: ['pattern', 'path', 'head_limit', 'offset', 'sort'],
|
|
442
|
-
find: ['query', 'path', 'head_limit'],
|
|
443
|
-
list: ['path', 'head_limit', 'offset'],
|
|
444
|
-
recall: ['query', 'limit', 'session_id', 'cwd'],
|
|
445
|
-
search: ['query', 'limit', 'cwd'],
|
|
446
|
-
explore: ['query', 'queries', 'limit', 'cwd'],
|
|
447
|
-
code_graph: ['mode', 'file', 'symbol', 'symbols', 'body', 'language', 'limit', 'depth', 'page', 'cwd'],
|
|
448
|
-
shell: ['command', 'cwd', 'timeout', 'mode', 'run_in_background', 'persistent', 'session_id'],
|
|
449
|
-
task: ['task_id', 'action', 'timeout_ms', 'poll_ms'],
|
|
450
|
-
edit: ['path', 'replace_all', 'edits'],
|
|
451
|
-
edit_many: ['edits'],
|
|
452
|
-
write: ['path'],
|
|
453
|
-
apply_patch: ['base_path', 'dry_run'],
|
|
454
|
-
};
|
|
455
|
-
|
|
456
|
-
const REDACT_KEY_RE = /token|secret|password|passwd|credential|authorization|api[_-]?key/i;
|
|
457
|
-
const BODY_KEY_RE = /content|old_string|new_string|patch|rewrite/i;
|
|
458
|
-
// Redact shell `command` values that look like they carry secrets. Covers
|
|
459
|
-
// assignment forms, Authorization headers, --password / -p flags, and
|
|
460
|
-
function _redactShellCommand(cmd) {
|
|
461
|
-
if (typeof cmd !== 'string') return cmd;
|
|
462
|
-
let out = cmd;
|
|
463
|
-
// Assignment RHS: PASSWORD=, SECRET=, TOKEN=, API_KEY=/APIKEY=.
|
|
464
|
-
out = out.replace(/((?:PASSWORD|SECRET|TOKEN|API_KEY|APIKEY)\s*=\s*)\S+/gi, '$1[redacted]');
|
|
465
|
-
// Authorization: Bearer <token>.
|
|
466
|
-
out = out.replace(/(Authorization:\s*Bearer\s+)\S+/gi, '$1[redacted]');
|
|
467
|
-
// Long flags: --password <v> / --password=<v> (also --token, --secret, --api-key).
|
|
468
|
-
out = out.replace(/(--(?:password|token|secret|api[-_]?key)(?:\s+|=))\S+/gi, '$1[redacted]');
|
|
469
|
-
// Short -p <v> flag (mysql/psql/curl style).
|
|
470
|
-
out = out.replace(/((?:^|\s)-p(?:\s+|=))\S+/g, '$1[redacted]');
|
|
471
|
-
// URL userinfo: scheme://user:secret@host -> scheme://user:[redacted]@host.
|
|
472
|
-
out = out.replace(/(:\/\/[^:\/\s@]+:)[^@\s]+(@)/g, '$1[redacted]$2');
|
|
473
|
-
// URL query params carrying tokens/keys.
|
|
474
|
-
out = out.replace(/([?&](?:token|api[-_]?key|access[-_]?token|auth|password|secret)=)[^&\s#]+/gi, '$1[redacted]');
|
|
475
|
-
return out;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
function compactTraceArgValue(value, key = '', depth = 0) {
|
|
479
|
-
if (REDACT_KEY_RE.test(key)) return '[redacted]';
|
|
480
|
-
if (value === null || value === undefined) return value;
|
|
481
|
-
if (typeof value === 'string') {
|
|
482
|
-
// Redact shell commands that embed secrets before length-truncating.
|
|
483
|
-
if (key === 'command') {
|
|
484
|
-
value = _redactShellCommand(value);
|
|
485
|
-
}
|
|
486
|
-
const limit = BODY_KEY_RE.test(key) ? 60 : 180;
|
|
487
|
-
return value.length > limit ? `${value.slice(0, limit)}...` : value;
|
|
488
|
-
}
|
|
489
|
-
if (typeof value === 'number' || typeof value === 'boolean') return value;
|
|
490
|
-
if (Array.isArray(value)) {
|
|
491
|
-
if (depth >= 2) return `[${value.length} items]`;
|
|
492
|
-
return value.slice(0, 6).map((v) => compactTraceArgValue(v, key, depth + 1));
|
|
493
|
-
}
|
|
494
|
-
if (typeof value === 'object') {
|
|
495
|
-
if (depth >= 2) return '{...}';
|
|
496
|
-
const out = {};
|
|
497
|
-
for (const [k, v] of Object.entries(value).slice(0, 12)) {
|
|
498
|
-
out[k] = compactTraceArgValue(v, k, depth + 1);
|
|
499
|
-
}
|
|
500
|
-
return out;
|
|
501
|
-
}
|
|
502
|
-
return String(value);
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
function summarizeToolArgs(toolName, args) {
|
|
506
|
-
if (!args || typeof args !== 'object') return null;
|
|
507
|
-
const keys = TOOL_ARG_KEYS[String(toolName || '')] || Object.keys(args).slice(0, 8);
|
|
508
|
-
const out = {};
|
|
509
|
-
for (const key of keys) {
|
|
510
|
-
if (Object.prototype.hasOwnProperty.call(args, key)) out[key] = compactTraceArgValue(args[key], key);
|
|
511
|
-
}
|
|
512
|
-
for (const countKey of ['edits', 'writes']) {
|
|
513
|
-
if (Array.isArray(args[countKey])) out[`${countKey}_count`] = args[countKey].length;
|
|
514
|
-
}
|
|
515
|
-
if (toolName === 'read' && Array.isArray(args.path)) {
|
|
516
|
-
out.path_count = args.path.length;
|
|
517
|
-
}
|
|
518
|
-
return Object.keys(out).length ? out : null;
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
function stableTraceStringify(value) {
|
|
522
|
-
if (value === null || value === undefined) return JSON.stringify(value);
|
|
523
|
-
if (typeof value !== 'object') return JSON.stringify(value);
|
|
524
|
-
if (Array.isArray(value)) return '[' + value.map(stableTraceStringify).join(',') + ']';
|
|
525
|
-
const keys = Object.keys(value).sort();
|
|
526
|
-
return '{' + keys.map((k) => `${JSON.stringify(k)}:${stableTraceStringify(value[k])}`).join(',') + '}';
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
function hashTraceValue(value) {
|
|
530
|
-
try {
|
|
531
|
-
return createHash('sha256').update(stableTraceStringify(value)).digest('hex').slice(0, 16);
|
|
532
|
-
} catch {
|
|
533
|
-
return null;
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
function _resolveToolFailurePath() {
|
|
538
|
-
if (process.env.MIXDOG_TOOL_FAILURE_LOG_DISABLE === '1') return null;
|
|
539
|
-
if (_toolFailurePath) return _toolFailurePath;
|
|
540
|
-
try {
|
|
541
|
-
_toolFailurePath = process.env.MIXDOG_TOOL_FAILURE_LOG_PATH
|
|
542
|
-
|| join(getPluginData(), 'history', 'tool-failures.jsonl');
|
|
543
|
-
mkdirSync(dirname(_toolFailurePath), { recursive: true, mode: 0o700 });
|
|
544
|
-
return _toolFailurePath;
|
|
545
|
-
} catch {
|
|
546
|
-
return null;
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
function _scheduleToolFailureFlush(delayMs = _TOOL_FAILURE_FLUSH_MS) {
|
|
551
|
-
if (_toolFailureTimer) return;
|
|
552
|
-
_toolFailureTimer = setTimeout(_flushToolFailures, delayMs);
|
|
553
|
-
_toolFailureTimer.unref?.();
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
function _maybeRotateToolFailureLog(path) {
|
|
557
|
-
const now = Date.now();
|
|
558
|
-
if (_lastToolFailureRotateCheckMs !== 0 && now - _lastToolFailureRotateCheckMs < MIXDOG_AGENT_TRACE_ROTATE_CHECK_MS) return;
|
|
559
|
-
_rotateLocalTraceIfNeeded(path);
|
|
560
|
-
_lastToolFailureRotateCheckMs = now;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
function _appendToolFailureRow(row) {
|
|
564
|
-
if (!_resolveToolFailurePath()) return;
|
|
565
|
-
try {
|
|
566
|
-
_toolFailureBuffer.push(`${JSON.stringify(row)}\n`);
|
|
567
|
-
if (_toolFailureBuffer.length >= _TOOL_FAILURE_FLUSH_LINES) {
|
|
568
|
-
_flushToolFailures();
|
|
569
|
-
} else {
|
|
570
|
-
_scheduleToolFailureFlush();
|
|
571
|
-
}
|
|
572
|
-
} catch (err) {
|
|
573
|
-
warnAgentOnce('tool-failure-log:append', `[tool-failure-log] append failed (${err?.message})`);
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
function _flushToolFailures() {
|
|
578
|
-
if (_toolFailureTimer) {
|
|
579
|
-
clearTimeout(_toolFailureTimer);
|
|
580
|
-
_toolFailureTimer = null;
|
|
581
|
-
}
|
|
582
|
-
if (_toolFailureBuffer.length === 0) return;
|
|
583
|
-
if (_toolFailureFlushInFlight) {
|
|
584
|
-
_scheduleToolFailureFlush(25);
|
|
585
|
-
return;
|
|
586
|
-
}
|
|
587
|
-
const path = _resolveToolFailurePath();
|
|
588
|
-
if (!path) return;
|
|
589
|
-
const chunk = _toolFailureBuffer.join('');
|
|
590
|
-
_toolFailureBuffer = [];
|
|
591
|
-
try {
|
|
592
|
-
_maybeRotateToolFailureLog(path);
|
|
593
|
-
} catch (err) {
|
|
594
|
-
warnAgentOnce('tool-failure-log:rotate', `[tool-failure-log] rotate check failed (${err?.message})`);
|
|
595
|
-
}
|
|
596
|
-
_toolFailureFlushInFlight = true;
|
|
597
|
-
appendFile(path, chunk, { encoding: 'utf8', mode: 0o600 })
|
|
598
|
-
.catch((err) => {
|
|
599
|
-
warnAgentOnce('tool-failure-log:append', `[tool-failure-log] append failed (${err?.message})`);
|
|
600
|
-
})
|
|
601
|
-
.finally(() => {
|
|
602
|
-
_toolFailureFlushInFlight = false;
|
|
603
|
-
if (_toolFailureBuffer.length > 0) _scheduleToolFailureFlush(0);
|
|
604
|
-
});
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
function _flushToolFailuresSync() {
|
|
608
|
-
if (_toolFailureTimer) {
|
|
609
|
-
clearTimeout(_toolFailureTimer);
|
|
610
|
-
_toolFailureTimer = null;
|
|
611
|
-
}
|
|
612
|
-
if (_toolFailureBuffer.length === 0) return;
|
|
613
|
-
const path = _resolveToolFailurePath();
|
|
614
|
-
if (!path) return;
|
|
615
|
-
const chunk = _toolFailureBuffer.join('');
|
|
616
|
-
_toolFailureBuffer = [];
|
|
617
|
-
try {
|
|
618
|
-
_maybeRotateToolFailureLog(path);
|
|
619
|
-
appendFileSync(path, chunk, { encoding: 'utf8', mode: 0o600 });
|
|
620
|
-
} catch (err) {
|
|
621
|
-
warnAgentOnce('tool-failure-log:append', `[tool-failure-log] append failed (${err?.message})`);
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
function _firstNonEmptyLine(text) {
|
|
626
|
-
return String(text ?? '').split(/\r?\n/).find((line) => line.trim())?.trim() || '';
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
function _redactLogText(text) {
|
|
630
|
-
if (typeof text !== 'string') return '';
|
|
631
|
-
let out = text;
|
|
632
|
-
out = out.replace(/(Authorization:\s*Bearer\s+)\S+/gi, '$1[redacted]');
|
|
633
|
-
out = out.replace(/([?&](?:token|api[-_]?key|access[-_]?token|auth|password|secret)=)[^&\s#]+/gi, '$1[redacted]');
|
|
634
|
-
out = out.replace(/((?:PASSWORD|SECRET|TOKEN|API_KEY|APIKEY)\s*=\s*)\S+/gi, '$1[redacted]');
|
|
635
|
-
return out;
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
function classifyToolFailure(resultText, toolName) {
|
|
639
|
-
const text = String(resultText ?? '').toLowerCase();
|
|
640
|
-
if (/requires either|invalid arguments|unknown parameter|must be|schema|expected|required|old_string is .*>=/.test(text)) return 'schema/args';
|
|
641
|
-
if (/enoent|cannot find|not found at this path|path does not exist|no such file|file not found in graph|unreadable/.test(text)) return 'path/cwd';
|
|
642
|
-
if (/timed out|timeout|interrupted|aborted/.test(text)) return 'timeout/abort';
|
|
643
|
-
if (/hunk rejected|patch failed|context mismatch|expected first old\/context|context not found/.test(text)) return 'patch/context';
|
|
644
|
-
if (/not in allow-list|permission|denied|forbidden|not allowed/.test(text)) return 'permission';
|
|
645
|
-
if (/unknown tool|tool.*not.*available|missing.*tool/.test(text)) return 'tool-surface';
|
|
646
|
-
if (String(toolName || '') === 'shell' || /^\s*\[exit code:\s*\d+\]/i.test(String(resultText ?? ''))) return 'command-exit';
|
|
647
|
-
return 'runtime/failure';
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
function traceAgentToolFailure({ sessionId, iteration, toolName, toolKind, toolMs, toolArgs, agent, model, cwd, resultText, resultKind = 'error' }) {
|
|
651
|
-
if (process.env.MIXDOG_AGENT_TRACE_DISABLE === '1') return;
|
|
652
|
-
if (!_resolveToolFailurePath()) return;
|
|
653
|
-
try {
|
|
654
|
-
const cleanText = _redactLogText(String(resultText ?? ''));
|
|
655
|
-
const row = {
|
|
656
|
-
ts: Date.now(),
|
|
657
|
-
session_id: normalizeSessionId(sessionId),
|
|
658
|
-
iteration: iteration ?? null,
|
|
659
|
-
tool_name: toolName || null,
|
|
660
|
-
tool_kind: toolKind || null,
|
|
661
|
-
result_kind: resultKind || 'error',
|
|
662
|
-
category: classifyToolFailure(cleanText, toolName),
|
|
663
|
-
agent: agent || null,
|
|
664
|
-
model: model || null,
|
|
665
|
-
cwd: cwd || null,
|
|
666
|
-
tool_ms: Number.isFinite(Number(toolMs)) ? Number(toolMs) : null,
|
|
667
|
-
tool_args: summarizeToolArgs(toolName, toolArgs),
|
|
668
|
-
error_first_line: _firstNonEmptyLine(cleanText).slice(0, 300),
|
|
669
|
-
error_preview: cleanText.slice(0, 1200),
|
|
670
|
-
result_bytes_est: Buffer.byteLength(cleanText, 'utf8'),
|
|
671
|
-
result_lines_est: cleanText.length > 0 ? cleanText.split('\n').length : 0,
|
|
672
|
-
};
|
|
673
|
-
_appendToolFailureRow(row);
|
|
674
|
-
} catch (err) {
|
|
675
|
-
warnAgentOnce('tool-failure-log:append', `[tool-failure-log] append failed (${err?.message})`);
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
function traceAgentTool({ sessionId, iteration, toolName, toolKind, toolMs, toolArgs, agent, resultKind, model, resultText, cwd }) {
|
|
680
|
-
const nextCallCount = countJsonNextCalls(resultText);
|
|
681
|
-
const resultBytesEst = typeof resultText === 'string' ? Buffer.byteLength(resultText, 'utf8') : 0;
|
|
682
|
-
const resultLinesEst = typeof resultText === 'string' && resultText.length > 0 ? resultText.split('\n').length : 0;
|
|
683
|
-
const numericToolMs = Number(toolMs);
|
|
684
|
-
const summarizedArgs = summarizeToolArgs(toolName, toolArgs);
|
|
685
|
-
const toolArgsHash = summarizedArgs ? hashTraceValue(summarizedArgs) : null;
|
|
686
|
-
// Flat shape — fields named exactly as the agent_calls PG columns so
|
|
687
|
-
// insertAgentCalls can pick them up by direct property access without
|
|
688
|
-
// a payload-unwrap step. result_kind has no column and rides as plain
|
|
689
|
-
// sibling metadata for downstream consumers.
|
|
690
|
-
appendAgentTrace({
|
|
691
|
-
sessionId,
|
|
692
|
-
iteration,
|
|
693
|
-
kind: 'tool',
|
|
694
|
-
agent: agent || null,
|
|
695
|
-
model: model || null,
|
|
696
|
-
tool_name: toolName,
|
|
697
|
-
tool_kind: toolKind,
|
|
698
|
-
tool_ms: toolMs,
|
|
699
|
-
tool_args: summarizedArgs,
|
|
700
|
-
tool_args_hash: toolArgsHash,
|
|
701
|
-
tool_args_summary: summarizedArgs,
|
|
702
|
-
result_kind: resultKind || null,
|
|
703
|
-
result_has_next_call: nextCallCount > 0,
|
|
704
|
-
result_next_call_count: nextCallCount,
|
|
705
|
-
result_bytes_est: resultBytesEst,
|
|
706
|
-
result_lines_est: resultLinesEst,
|
|
707
|
-
});
|
|
708
|
-
if (
|
|
709
|
-
Number.isFinite(numericToolMs)
|
|
710
|
-
&& numericToolMs >= MIXDOG_SLOW_TOOL_TRACE_MS
|
|
711
|
-
&& (MIXDOG_SLOW_TOOL_TRACE_ALL || MIXDOG_SLOW_TOOL_TRACE_NAMES.size === 0 || MIXDOG_SLOW_TOOL_TRACE_NAMES.has(String(toolName || '')))
|
|
712
|
-
) {
|
|
713
|
-
appendAgentTrace({
|
|
714
|
-
sessionId,
|
|
715
|
-
iteration,
|
|
716
|
-
kind: 'tool_slow',
|
|
717
|
-
agent: agent || null,
|
|
718
|
-
model: model || null,
|
|
719
|
-
tool_name: toolName,
|
|
720
|
-
tool_kind: toolKind,
|
|
721
|
-
tool_ms: numericToolMs,
|
|
722
|
-
payload: {
|
|
723
|
-
threshold_ms: MIXDOG_SLOW_TOOL_TRACE_MS,
|
|
724
|
-
result_kind: resultKind || null,
|
|
725
|
-
tool_args: summarizedArgs,
|
|
726
|
-
tool_args_hash: toolArgsHash,
|
|
727
|
-
tool_args_summary: summarizedArgs,
|
|
728
|
-
result_has_next_call: nextCallCount > 0,
|
|
729
|
-
result_next_call_count: nextCallCount,
|
|
730
|
-
result_bytes_est: resultBytesEst,
|
|
731
|
-
result_lines_est: resultLinesEst,
|
|
732
|
-
cwd: cwd || null,
|
|
733
|
-
},
|
|
734
|
-
});
|
|
735
|
-
}
|
|
736
|
-
if (resultKind === 'error') {
|
|
737
|
-
traceAgentToolFailure({ sessionId, iteration, toolName, toolKind, toolMs, toolArgs, agent, model, cwd, resultText, resultKind });
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
// Compression layer trace (result-compression.mjs). One row per tool call
|
|
742
|
-
// where compression actually changed the byte count, so `gain` analytics
|
|
743
|
-
// can sum savings_pct over a window (mirrors RTK's `rtk gain` model
|
|
744
|
-
// without an external binary). No-op rows are dropped at the call site.
|
|
745
|
-
export function traceAgentCompress({ sessionId, toolName, before, after }) {
|
|
746
|
-
// bytes_before/after/savings_pct moved into payload because the
|
|
747
|
-
// trace_events table only carries known top-level columns (id, ts,
|
|
748
|
-
// session_id, kind, tool_name, payload, ...) — fields outside that
|
|
749
|
-
// set are silently dropped at insert time. payload is jsonb so any
|
|
750
|
-
// shape survives. Aggregation: SELECT (payload->>'bytes_before')::int.
|
|
751
|
-
appendAgentTrace({
|
|
752
|
-
sessionId,
|
|
753
|
-
kind: 'compress',
|
|
754
|
-
tool_name: toolName,
|
|
755
|
-
payload: {
|
|
756
|
-
bytes_before: before,
|
|
757
|
-
bytes_after: after,
|
|
758
|
-
savings_pct: before > 0 ? Math.round((1 - after / before) * 100) : 0,
|
|
759
|
-
},
|
|
760
|
-
});
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
// Per-turn batch shape — one row per assistant turn with the number of
|
|
764
|
-
// tool calls observed. Lets a consumer compute Lead-side multi-tool
|
|
765
|
-
// adoption ratio (calls > 1 / total turns) directly from trace rows
|
|
766
|
-
// instead of re-parsing every assistant message body.
|
|
767
|
-
export function traceAgentBatch({ sessionId, toolCallCount }) {
|
|
768
|
-
appendAgentTrace({
|
|
769
|
-
sessionId,
|
|
770
|
-
kind: 'batch',
|
|
771
|
-
tool_call_count: toolCallCount,
|
|
772
|
-
});
|
|
773
|
-
}
|
|
774
|
-
|
|
775
54
|
function traceStreamStalled({ sessionId, info }) {
|
|
776
55
|
appendAgentTrace({
|
|
777
56
|
sessionId,
|
|
@@ -934,6 +213,8 @@ export {
|
|
|
934
213
|
traceAgentToolFailure,
|
|
935
214
|
traceAgentCompact,
|
|
936
215
|
traceAgentUsage,
|
|
216
|
+
traceAgentCompress,
|
|
217
|
+
traceAgentBatch,
|
|
937
218
|
traceStreamAborted,
|
|
938
219
|
traceStreamStalled,
|
|
939
220
|
warnAgentOnce,
|