mixdog 0.9.18 → 0.9.20
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/LICENSE +21 -0
- package/README.md +93 -29
- package/package.json +5 -3
- package/scripts/build-runtime-windows.ps1 +242 -242
- package/scripts/build-tui.mjs +6 -0
- package/scripts/hook-bus-test.mjs +8 -0
- package/scripts/log-writer-guard-smoke.mjs +131 -0
- package/scripts/output-style-smoke.mjs +2 -2
- package/scripts/reactive-compact-persist-smoke.mjs +22 -6
- package/scripts/recall-bench-cases.json +10 -0
- package/scripts/recall-bench.mjs +91 -2
- package/scripts/recall-quality-cases.json +1 -2
- package/scripts/recall-usecase-cases.json +1 -1
- package/scripts/session-ingest-compaction-smoke.mjs +241 -0
- package/scripts/smoke-runtime-negative.ps1 +106 -106
- package/scripts/tool-efficiency-diag.mjs +5 -2
- package/scripts/tool-smoke.mjs +251 -72
- package/src/agents/debugger/AGENT.md +3 -3
- package/src/agents/heavy-worker/AGENT.md +7 -10
- package/src/agents/maintainer/AGENT.md +1 -2
- package/src/agents/reviewer/AGENT.md +1 -2
- package/src/agents/worker/AGENT.md +5 -8
- package/src/defaults/agents.json +3 -0
- package/src/help.mjs +2 -5
- package/src/lib/mixdog-debug.cjs +13 -0
- package/src/mixdog-session-runtime.mjs +7 -3311
- package/src/rules/agent/00-core.md +4 -3
- package/src/rules/agent/30-explorer.md +53 -22
- package/src/rules/lead/02-channels.md +3 -3
- package/src/rules/lead/lead-tool.md +3 -2
- package/src/rules/shared/01-tool.md +24 -29
- package/src/runtime/agent/orchestrator/context/collect.mjs +33 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +24 -3
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +663 -0
- package/src/runtime/agent/orchestrator/session/compact/engine.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +153 -0
- package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +49 -0
- package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +250 -35
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +9 -1
- package/src/runtime/agent/orchestrator/session/loop.mjs +8 -1860
- package/src/runtime/agent/orchestrator/session/manager/agent-runtime-singleton.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +686 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +60 -12
- package/src/runtime/agent/orchestrator/session/manager/env-utils.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +159 -0
- package/src/runtime/agent/orchestrator/session/manager/message-sanitize.mjs +143 -0
- package/src/runtime/agent/orchestrator/session/manager/prefetch-bridge.mjs +268 -0
- package/src/runtime/agent/orchestrator/session/manager/provider-cache-key.mjs +22 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-loaders.mjs +26 -0
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +124 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +258 -0
- package/src/runtime/agent/orchestrator/session/manager/session-errors.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/manager/session-id.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +475 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +6 -4
- package/src/runtime/agent/orchestrator/session/manager.mjs +88 -2285
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +440 -0
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +153 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/tool-batch.mjs +642 -0
- package/src/runtime/agent/orchestrator/tools/bash-session.mjs +23 -3
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +198 -6
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +10 -2
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +13 -15
- package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +45 -3
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +5 -2
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +195 -3
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +108 -2
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +15 -3
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +7 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +24 -2
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +17 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +38 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +72 -8
- package/src/runtime/agent/orchestrator/tools/shell-policy-danger-target.mjs +5 -1
- package/src/runtime/agent/orchestrator/tools/shell-state.mjs +1 -1
- package/src/runtime/channels/backends/discord-gateway.mjs +14 -1
- package/src/runtime/channels/backends/discord.mjs +43 -1
- package/src/runtime/channels/index.mjs +6 -2096
- package/src/runtime/channels/lib/inbound-handler.mjs +328 -0
- package/src/runtime/channels/lib/inbound-routing.mjs +19 -12
- package/src/runtime/channels/lib/interaction-handlers.mjs +260 -0
- package/src/runtime/channels/lib/memory-client.mjs +32 -14
- package/src/runtime/channels/lib/network-retry.mjs +23 -0
- package/src/runtime/channels/lib/output-forwarder.mjs +38 -7
- package/src/runtime/channels/lib/owned-runtime.mjs +547 -0
- package/src/runtime/channels/lib/owner-heartbeat.mjs +13 -4
- package/src/runtime/channels/lib/runtime-paths.mjs +35 -1
- package/src/runtime/channels/lib/tool-dispatch.mjs +17 -7
- package/src/runtime/channels/lib/transcript-binding.mjs +336 -0
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +39 -2
- package/src/runtime/channels/lib/worker-bootstrap.mjs +97 -0
- package/src/runtime/channels/lib/worker-ipc.mjs +201 -0
- package/src/runtime/channels/lib/worker-main.mjs +771 -0
- package/src/runtime/memory/index.mjs +73 -1725
- package/src/runtime/memory/lib/embedding-provider.mjs +4 -2
- package/src/runtime/memory/lib/embedding-worker.mjs +47 -6
- package/src/runtime/memory/lib/http-router.mjs +772 -0
- package/src/runtime/memory/lib/memory-action-handlers.mjs +901 -0
- package/src/runtime/memory/lib/memory-embed.mjs +28 -7
- package/src/runtime/memory/lib/memory-recall-scope-filter.mjs +8 -2
- package/src/runtime/memory/lib/memory-recall-store.mjs +182 -9
- package/src/runtime/memory/lib/query-handlers.mjs +38 -6
- package/src/runtime/memory/lib/recall-format.mjs +106 -6
- package/src/runtime/memory/lib/session-ingest-runtime.mjs +401 -0
- package/src/runtime/memory/lib/session-ingest.mjs +1 -1
- package/src/runtime/shared/atomic-file.mjs +10 -4
- package/src/runtime/shared/background-tasks.mjs +4 -2
- package/src/runtime/shared/tool-execution-contract.mjs +1 -1
- package/src/runtime/shared/tool-result-summary.mjs +1 -1
- package/src/runtime/shared/tool-surface.mjs +30 -1
- package/src/session-runtime/boot-profile.mjs +36 -0
- package/src/session-runtime/channel-config-api.mjs +70 -0
- package/src/session-runtime/config-lifecycle.mjs +1 -1
- package/src/session-runtime/context-status.mjs +181 -0
- package/src/session-runtime/cwd-plugins.mjs +46 -3
- package/src/session-runtime/env.mjs +17 -0
- package/src/session-runtime/lifecycle-api.mjs +242 -0
- package/src/session-runtime/mcp-glue.mjs +24 -3
- package/src/session-runtime/model-route-api.mjs +198 -0
- package/src/session-runtime/output-styles.mjs +44 -10
- package/src/session-runtime/provider-auth-api.mjs +135 -0
- package/src/session-runtime/resource-api.mjs +282 -0
- package/src/session-runtime/runtime-core.mjs +2046 -0
- package/src/session-runtime/session-turn-api.mjs +274 -0
- package/src/session-runtime/tool-catalog.mjs +18 -264
- package/src/session-runtime/tool-defs.mjs +2 -2
- package/src/session-runtime/workflow-agents-api.mjs +238 -0
- package/src/session-runtime/workflow.mjs +16 -1
- package/src/standalone/agent-tool.mjs +2 -2
- package/src/standalone/channel-worker.mjs +78 -5
- package/src/standalone/explore-tool.mjs +1 -1
- package/src/standalone/memory-runtime-proxy.mjs +56 -6
- package/src/tui/App.jsx +88 -97
- package/src/tui/app/channel-pickers.mjs +45 -0
- package/src/tui/app/core-memory-picker.mjs +1 -1
- package/src/tui/app/slash-commands.mjs +0 -1
- package/src/tui/app/slash-dispatch.mjs +0 -16
- package/src/tui/app/transcript-window.mjs +44 -1
- package/src/tui/app/use-mouse-input.mjs +15 -2
- package/src/tui/app/use-prompt-handlers.mjs +7 -94
- package/src/tui/app/use-transcript-scroll.mjs +82 -4
- package/src/tui/app/use-transcript-window.mjs +65 -5
- package/src/tui/components/PromptInput.jsx +33 -64
- package/src/tui/components/ToolExecution.jsx +2 -2
- package/src/tui/dist/index.mjs +7908 -7558
- package/src/tui/engine/context-state.mjs +145 -0
- package/src/tui/engine/prompt-history.mjs +27 -0
- package/src/tui/engine/session-api-ext.mjs +478 -0
- package/src/tui/engine/session-api.mjs +545 -0
- package/src/tui/engine/session-flow.mjs +485 -0
- package/src/tui/engine/turn.mjs +1078 -0
- package/src/tui/engine.mjs +69 -2582
- package/src/tui/index.jsx +7 -0
- package/src/tui/lib/voice-setup.mjs +166 -0
- package/src/tui/paste-attachments.mjs +12 -5
- package/src/tui/prompt-history-store.mjs +125 -12
- package/vendor/ink/build/ink.js +16 -1
- package/vendor/ink/build/output.js +30 -4
- package/vendor/ink/build/render.js +5 -0
- package/scripts/bench/cache-probe-tasks.json +0 -8
- package/scripts/bench/lead-review-tasks-r3.json +0 -20
- package/scripts/bench/lead-review-tasks.json +0 -20
- package/scripts/bench/r4-mixed-tasks.json +0 -20
- package/scripts/bench/r5-orchestrated-task.json +0 -7
- package/scripts/bench/review-tasks.json +0 -20
- package/scripts/bench/round-codex.json +0 -114
- package/scripts/bench/round-mixdog-lead-r3.json +0 -269
- package/scripts/bench/round-mixdog-lead.json +0 -269
- package/scripts/bench/round-mixdog.json +0 -126
- package/scripts/bench/round-r10-bigsample.json +0 -679
- package/scripts/bench/round-r11-codexalign.json +0 -257
- package/scripts/bench/round-r13-clientmeta.json +0 -464
- package/scripts/bench/round-r14-betafeatures.json +0 -466
- package/scripts/bench/round-r15-fulldefault.json +0 -462
- package/scripts/bench/round-r16-sessionid.json +0 -466
- package/scripts/bench/round-r17-wirebytes.json +0 -456
- package/scripts/bench/round-r18-prewarm.json +0 -468
- package/scripts/bench/round-r19-clean.json +0 -472
- package/scripts/bench/round-r20-prewarm-clean.json +0 -475
- package/scripts/bench/round-r21-delta-retry.json +0 -473
- package/scripts/bench/round-r22-full-probe.json +0 -693
- package/scripts/bench/round-r23-itemprobe.json +0 -701
- package/scripts/bench/round-r24-shapefix.json +0 -677
- package/scripts/bench/round-r25-serial.json +0 -464
- package/scripts/bench/round-r26-parallel3.json +0 -671
- package/scripts/bench/round-r27-parallel10.json +0 -894
- package/scripts/bench/round-r28-parallel10-stagger.json +0 -882
- package/scripts/bench/round-r29-parallel10-stagger166.json +0 -886
- package/scripts/bench/round-r30-instid.json +0 -253
- package/scripts/bench/round-r31-upgradeprobe.json +0 -256
- package/scripts/bench/round-r32-vs-codex-lead.json +0 -254
- package/scripts/bench/round-r33-vs-codex-codex.json +0 -115
- package/scripts/bench/round-r34-orchestrated.json +0 -120
- package/scripts/bench/round-r35-orchestrated-codex.json +0 -61
- package/scripts/bench/round-r36-orchestrated-capped.json +0 -128
- package/scripts/bench/round-r4-codex.json +0 -114
- package/scripts/bench/round-r4-mixed.json +0 -225
- package/scripts/bench/round-r5-gpt-lead.json +0 -259
- package/scripts/bench/round-r6-codex.json +0 -114
- package/scripts/bench/round-r6-solo.json +0 -257
- package/scripts/bench/round-r7-full.json +0 -254
- package/scripts/bench/round-r8-fulldefault.json +0 -255
- package/src/tui/components/prompt-input/voice-indicator.mjs +0 -39
- package/src/tui/lib/voice-recorder.mjs +0 -469
- package/src/workflows/sequential/WORKFLOW.md +0 -51
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"round": "36",
|
|
3
|
-
"runner": "lead",
|
|
4
|
-
"opts": {
|
|
5
|
-
"provider": "openai-oauth",
|
|
6
|
-
"model": "gpt-5.5",
|
|
7
|
-
"effort": null,
|
|
8
|
-
"fast": false,
|
|
9
|
-
"workflow": "default",
|
|
10
|
-
"env": {
|
|
11
|
-
"MIXDOG_DATA_DIR": "C:\\Users\\tempe\\.mixdog\\bench-data"
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
"tasks": 1,
|
|
15
|
-
"completed": 1,
|
|
16
|
-
"completion_rate": 100,
|
|
17
|
-
"sessions": [
|
|
18
|
-
"sess_54872_1783078178435_1783078178685_d27922b6978571ab4599bcc38f64fa0f"
|
|
19
|
-
],
|
|
20
|
-
"results": [
|
|
21
|
-
{
|
|
22
|
-
"id": "r5-orchestrated-audit",
|
|
23
|
-
"agent": "lead",
|
|
24
|
-
"ok": true,
|
|
25
|
-
"ms": 255448,
|
|
26
|
-
"sessionId": "sess_54872_1783078178435_1783078178685_d27922b6978571ab4599bcc38f64fa0f",
|
|
27
|
-
"output": "sessionId: sess_54872_1783078178435_1783078178685_d27922b6978571ab4599bcc38f64fa0f\n완료했습니다. 분석만 수행했고 파일은 수정하지 않았습니다.\n\n**Scope A — classifier bucket reachability**\n\n- `classifyError()`는 `auth|permanent|transient|unknown`만 반환합니다(`retry-classifier.mjs:100-135`). `openai-oauth-ws.mjs`는 이 함수를 import하지 않으므로 WS 경로에서는 직접 도달하지 않지만(`openai-oauth-ws.mjs:33-40`), 전역적으로는 `withRetry()`가 사용합니다(`retry-classifier.mjs:515-570`).\n\n- `classifyHandshakeError()`는 `timeout|reset|dns|refused|network|acquire_timeout|http_${status}|null`을 반환합니다(`retry-classifier.mjs:471-494`). `openai-oauth-ws`는 `_classifyHandshakeError()`로 래핑해 acquire 실패마다 소비합니다(`openai-oauth-ws.mjs:112-114`, `openai-oauth-ws.mjs:403-430`).\n\n- WS midstream classifier는 `first_byte_timeout|ws_send_failed|agent_stall|stream_stalled|ws_1006|ws_1011|ws_1012|ws_4000|ws_1000|http_${status}|response_failed_disconnected|response_failed_network|response_failed_auth_expired|null`을 반환합니다(`retry-classifier.mjs:286-343`). `openai-oauth-ws`는 항상 `mode:'ws'`로만 호출합니다(`openai-oauth-ws.mjs:87-91`, `openai-oauth-ws.mjs:157-159`).\n\n- SSE midstream bucket `agent_stall|stream_stalled|reset|timeout|dns|sse_idle_timeout|stream_terminated|fetch_failed`는 `retry-classifier.mjs` 안에는 존재하지만(`retry-classifier.mjs:348-381`), `openai-oauth-ws` 경로에서는 `mode:'sse'`를 넘기지 않아 도달 불가입니다.\n\n- “생성 불가”로 볼 수 있는 것은 현재 WS classifier가 반환하지 않는 레거시/문서성 `http_5xx` 문자열입니다. 실제 반환은 `http_500` 같은 `http_${status}`이고(`retry-classifier.mjs:309`, `retry-classifier.mjs:480-482`), fallback 쪽만 `http_5xx`와 regex 둘 다 허용합니다(`retry-classifier.mjs:386-410`).\n\n- `response_failed_auth_expired`는 repo 내부가 문자열을 생성하진 않지만, 서버의 `response.failed`/failed `response.done` payload를 그대로 저장해 classifier가 sniff하므로 런타임상 완전한 dead bucket은 아닙니다(`openai-ws-stream.mjs:887-896`, `openai-ws-stream.mjs:953-963`, `retry-classifier.mjs:332-339`).\n\n**Scope B — retry loop budgets/backoff**\n\n- Handshake retry는 `HANDSHAKE_MAX_ATTEMPTS = PROVIDER_RETRY_MAX_ATTEMPTS = 5`라서 최초 1회 + 최대 4회 재시도입니다(`openai-oauth-ws.mjs:104`, `stall-policy.mjs:200-201`). backoff는 `500ms * 2^(attempt-1)`, cap `5000ms`, `jitterDelayMs()` 적용입니다(`openai-oauth-ws.mjs:175-178`, `stall-policy.mjs:202-206`).\n\n- Midstream retry는 outer loop가 `attemptIndex <= 4`까지 돌 수 있지만(`openai-oauth-ws.mjs:514`, `openai-oauth-ws.mjs:557`), 실제 허용 횟수는 classifier별입니다. `ws_1006|ws_1011`은 4회, 나머지 WS bucket은 2회입니다(`retry-classifier.mjs:245-268`, `openai-oauth-ws.mjs:164-168`, `openai-oauth-ws.mjs:843-860`).\n\n- Midstream backoff는 retry 번호별 `[250,1000,2000,4000]`를 쓰고 jitter를 적용합니다(`retry-classifier.mjs:245-247`, `openai-oauth-ws.mjs:170-173`). 단, 로컬 주석은 “two retries / one retry”라고 되어 있어 실제 4/2 budget과 불일치합니다(`openai-oauth-ws.mjs:503-508`).\n\n- 같은 fault가 두 계층에서 이중 재시도되지는 않습니다. acquire 실패는 midstream classifier로 넘어가지 않고 바로 throw되며(`openai-oauth-ws.mjs:578-601`), midstream 실패만 `_classifyMidstreamError()` 후 재시도되고 다음 시도에서 fresh acquire를 새로 수행합니다(`openai-oauth-ws.mjs:511-513`, `openai-oauth-ws.mjs:564-577`, `openai-oauth-ws.mjs:843-860`).\n\n- 다만 한 사용자 요청 안에서 “midstream fault 재시도 → 새 acquire 중 handshake fault 재시도”는 가능하므로, 두 budget은 같은 error class에 중첩되는 것이 아니라 서로 다른 단계의 fault에 순차적으로 소비됩니다.",
|
|
28
|
-
"card": {
|
|
29
|
-
"session": "sess_54872_1783078178435_1783078178685_d27922b6978571ab4599bcc38f64fa0f",
|
|
30
|
-
"provider": "openai-oauth",
|
|
31
|
-
"model": "gpt-5.5",
|
|
32
|
-
"wall_ms": 244855,
|
|
33
|
-
"turns": 44,
|
|
34
|
-
"tool_calls": 42,
|
|
35
|
-
"tools_per_turn": 1,
|
|
36
|
-
"total_tool_ms": 2277,
|
|
37
|
-
"llm_stream_ms": 305080,
|
|
38
|
-
"cache_ratio": 0.7561787493012467,
|
|
39
|
-
"cached_tokens": 597906,
|
|
40
|
-
"prompt_tokens": 790694,
|
|
41
|
-
"uncached_tokens": 35297,
|
|
42
|
-
"output_tokens": 14439,
|
|
43
|
-
"cache_weighted_input_10": 95087.6,
|
|
44
|
-
"cache_weighted_input_25": 184773.5,
|
|
45
|
-
"prompt_growth": 33692,
|
|
46
|
-
"antipatterns": 4,
|
|
47
|
-
"issues": 22,
|
|
48
|
-
"issue_types": [
|
|
49
|
-
"cache",
|
|
50
|
-
"cache_break",
|
|
51
|
-
"cache_miss",
|
|
52
|
-
"readonly_stall",
|
|
53
|
-
"broad_tool_result",
|
|
54
|
-
"service_tier",
|
|
55
|
-
"read_fragmentation",
|
|
56
|
-
"missed_parallelism",
|
|
57
|
-
"tool_churn_cluster"
|
|
58
|
-
],
|
|
59
|
-
"read_fragmentation_paths": [
|
|
60
|
-
"src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs"
|
|
61
|
-
],
|
|
62
|
-
"grep_sweep_count": 0
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
],
|
|
66
|
-
"task_complete": true,
|
|
67
|
-
"task_errors": [],
|
|
68
|
-
"score_complete": true,
|
|
69
|
-
"score_errors": [],
|
|
70
|
-
"group": {
|
|
71
|
-
"n": 1,
|
|
72
|
-
"wall_ms": 244855,
|
|
73
|
-
"turns": 44,
|
|
74
|
-
"tool_calls": 42,
|
|
75
|
-
"tools_per_turn": 1,
|
|
76
|
-
"total_tool_ms": 2277,
|
|
77
|
-
"llm_stream_ms": 305080,
|
|
78
|
-
"cache_ratio": 0.8,
|
|
79
|
-
"cached_tokens": 597906,
|
|
80
|
-
"prompt_tokens": 790694,
|
|
81
|
-
"uncached_tokens": 35297,
|
|
82
|
-
"output_tokens": 14439,
|
|
83
|
-
"cache_weighted_input_10": 95087.6,
|
|
84
|
-
"cache_weighted_input_25": 184773.5,
|
|
85
|
-
"prompt_growth": 33692,
|
|
86
|
-
"antipatterns": 4,
|
|
87
|
-
"issues": 22,
|
|
88
|
-
"grep_sweep_count": 0
|
|
89
|
-
},
|
|
90
|
-
"cards": [
|
|
91
|
-
{
|
|
92
|
-
"session": "sess_54872_1783078178435_1783078178685_d27922b6978571ab4599bcc38f64fa0f",
|
|
93
|
-
"provider": "openai-oauth",
|
|
94
|
-
"model": "gpt-5.5",
|
|
95
|
-
"wall_ms": 244855,
|
|
96
|
-
"turns": 44,
|
|
97
|
-
"tool_calls": 42,
|
|
98
|
-
"tools_per_turn": 1,
|
|
99
|
-
"total_tool_ms": 2277,
|
|
100
|
-
"llm_stream_ms": 305080,
|
|
101
|
-
"cache_ratio": 0.7561787493012467,
|
|
102
|
-
"cached_tokens": 597906,
|
|
103
|
-
"prompt_tokens": 790694,
|
|
104
|
-
"uncached_tokens": 35297,
|
|
105
|
-
"output_tokens": 14439,
|
|
106
|
-
"cache_weighted_input_10": 95087.6,
|
|
107
|
-
"cache_weighted_input_25": 184773.5,
|
|
108
|
-
"prompt_growth": 33692,
|
|
109
|
-
"antipatterns": 4,
|
|
110
|
-
"issues": 22,
|
|
111
|
-
"issue_types": [
|
|
112
|
-
"cache",
|
|
113
|
-
"cache_break",
|
|
114
|
-
"cache_miss",
|
|
115
|
-
"readonly_stall",
|
|
116
|
-
"broad_tool_result",
|
|
117
|
-
"service_tier",
|
|
118
|
-
"read_fragmentation",
|
|
119
|
-
"missed_parallelism",
|
|
120
|
-
"tool_churn_cluster"
|
|
121
|
-
],
|
|
122
|
-
"read_fragmentation_paths": [
|
|
123
|
-
"src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs"
|
|
124
|
-
],
|
|
125
|
-
"grep_sweep_count": 0
|
|
126
|
-
}
|
|
127
|
-
]
|
|
128
|
-
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"round": "4",
|
|
3
|
-
"runner": "codex",
|
|
4
|
-
"opts": {
|
|
5
|
-
"provider": "openai-oauth",
|
|
6
|
-
"model": "gpt-5.5",
|
|
7
|
-
"effort": "high",
|
|
8
|
-
"fast": false,
|
|
9
|
-
"env": {}
|
|
10
|
-
},
|
|
11
|
-
"tasks": 3,
|
|
12
|
-
"completed": 3,
|
|
13
|
-
"completion_rate": 100,
|
|
14
|
-
"sessions": [
|
|
15
|
-
"019f254d-7eb9-7b61-8033-dac06c077921",
|
|
16
|
-
"019f254d-80cf-7ee2-bc2b-e189fd3466e1",
|
|
17
|
-
"019f254d-7f3e-73d1-89b0-a4bd9928d221"
|
|
18
|
-
],
|
|
19
|
-
"results": [
|
|
20
|
-
{
|
|
21
|
-
"id": "r4-debug-forwarding-gap",
|
|
22
|
-
"agent": "reviewer",
|
|
23
|
-
"ok": true,
|
|
24
|
-
"ms": 113095,
|
|
25
|
-
"sessionId": "019f254d-7eb9-7b61-8033-dac06c077921",
|
|
26
|
-
"card": {
|
|
27
|
-
"session": "019f254d-7eb9-7b61-8033-dac06c077921",
|
|
28
|
-
"wall_ms": 113095,
|
|
29
|
-
"uncached_in": 73170,
|
|
30
|
-
"cached_in": 184192,
|
|
31
|
-
"out_tokens": 6579,
|
|
32
|
-
"cache_ratio": 0.716,
|
|
33
|
-
"completed": 1
|
|
34
|
-
},
|
|
35
|
-
"output": "조사 결과입니다. 코드 변경 없이 `src/runtime/channels/index.mjs`와 `src/runtime/channels/lib/output-forwarder.mjs`만 추적했습니다.\n\n**Activation Path**\n`start()`가 먼저 `channelBridgeActive = true`로 만들고 `bridge-state.json`을 씁니다: [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:1734). 그 뒤에 소유권을 claim하고 `refreshBridgeOwnership({ restoreBinding: true })`를 기다립니다: [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:1741).\n\n소유권이 확인되면 `startOwnedRuntime()`이 `active-instance.json`을 `backendReady:false`로 먼저 publish하고: [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:723), persisted transcript bind를 `backend.connect()`와 병렬로 시작합니다: [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:758). connect가 끝나야 `bridgeRuntimeConnected = true`가 됩니다: [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:769). 이후 binding task를 기다린 다음, transcript가 있으면 `forwarder.forwardNewText()`가 첫 실제 forward를 시도합니다: [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:801).\n\n첫 Discord send는 `forwardNewText()` → `extractNewText()` → `deliverQueueItem()` → `cb.send()` → `backend.sendMessage()` 경로입니다: [output-forwarder.mjs](C:/Project/mixdog-bench/src/runtime/channels/lib/output-forwarder.mjs:351), [output-forwarder.mjs](C:/Project/mixdog-bench/src/runtime/channels/lib/output-forwarder.mjs:316), [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:285).\n\n**Findings By Impact**\n\n1. **Highest: existing transcript can be bound at EOF, making already-written assistant output unrecoverable.** \n `setContext()` defaults to `fileSize = currentSize` unless `replayFromStart` or matching `catchUpFromPersisted` is active: [output-forwarder.mjs](C:/Project/mixdog-bench/src/runtime/channels/lib/output-forwarder.mjs:115). If bridge activation discovers an already-existing transcript whose path does not match persisted status, `catchUpFromPersisted` falls back to EOF: [output-forwarder.mjs](C:/Project/mixdog-bench/src/runtime/channels/lib/output-forwarder.mjs:117). The activation bind passes `catchUpFromPersisted:true`: [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:625), but that only catches up when the persisted path matches. \n Backlog recovery: **No**, not after the cursor is initialized to EOF and persisted through `applyTranscriptBinding()` status update: [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:326).\n\n2. **High: inbound Discord messages arriving before `bridgeRuntimeConnected` are dropped, not queued.** \n `backend.onMessage` calls `refreshBridgeOwnershipSafe()` and immediately returns if runtime is not connected or ownership snapshot is false: [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:1469). If this happens during the activation/connect window, the user message is not delivered to the assistant, so there may be no transcript output to forward. \n Backlog recovery: **No** for the inbound message itself. Transcript catch-up can only forward assistant output that was produced by some other path.\n\n3. **Medium: not-yet-created transcript files are not watchable; forwarding is delayed until re-arm succeeds.** \n `applyTranscriptBinding()` calls `forwarder.startWatch()` immediately: [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:317). If the transcript file does not exist, `fs.watch()` throws and `startWatch()` closes the watcher: [output-forwarder.mjs](C:/Project/mixdog-bench/src/runtime/channels/lib/output-forwarder.mjs:647). The repo has a re-arm poll for this exact gap: [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:357). When the file appears, it installs the watcher and calls `forwardNewText()`: [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:376). \n Backlog recovery: **Yes, if the file appears within 60s and ownership is still active**. After timeout, recovery is only by a later rebind/forward trigger, not automatic: [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:384).\n\n4. **Medium: pre-connect ownership probe suppresses early watch flushes, but usually delays rather than drops.** \n The forwarder owner gate requires both `bridgeRuntimeConnected` and `currentOwnerState().owned`: [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:316). Before connect completes, `forwardNewText()` returns before reading bytes: [output-forwarder.mjs](C:/Project/mixdog-bench/src/runtime/channels/lib/output-forwarder.mjs:351). Since it does not advance the cursor, output is not silently consumed. `startOwnedRuntime()` later compensates with post-connect `forwardNewText()` or re-arm scheduling: [index.mjs](C:/Project/mixdog-bench/src/runtime/channels/index.mjs:803). \n Backlog recovery: **Yes on normal activation with `restoreBinding:true`**, delayed until connect finishes.\n\n5. **Low: bytes written between `setContext()` stat and watch install are covered.** \n `startWatch()` schedules an immediate flush after installing `fs.watch()`: [output-forwarder.mjs](C:/Project/mixdog-bench/src/runtime/channels/lib/output-forwarder.mjs:665). \n Backlog recovery: **Yes**, unless this combines with the EOF binding problem above.\n\nVerdict: **The bridge mostly delays early output until connect/re-arm, but an already-existing transcript without a matching persisted cursor can still be bound at EOF and silently lose pre-bind assistant output.**"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
"id": "r4-impl-usage-summary",
|
|
39
|
-
"agent": "worker",
|
|
40
|
-
"ok": true,
|
|
41
|
-
"ms": 59039,
|
|
42
|
-
"sessionId": "019f254d-80cf-7ee2-bc2b-e189fd3466e1",
|
|
43
|
-
"card": {
|
|
44
|
-
"session": "019f254d-80cf-7ee2-bc2b-e189fd3466e1",
|
|
45
|
-
"wall_ms": 59039,
|
|
46
|
-
"uncached_in": 54732,
|
|
47
|
-
"cached_in": 138496,
|
|
48
|
-
"out_tokens": 2624,
|
|
49
|
-
"cache_ratio": 0.717,
|
|
50
|
-
"completed": 1
|
|
51
|
-
},
|
|
52
|
-
"output": "완료했습니다. 다만 현재 세션은 파일 쓰기 권한이 read-only라 제가 새 패치를 적용하진 못했고, 요청하신 변경이 이미 작업트리에 반영되어 있는 상태를 확인하고 검증했습니다.\n\nDiff summary:\n- [package.json](C:\\Project\\mixdog-bench\\package.json): `usage:today` npm script 추가\n- [scripts/usage-today.mjs](C:\\Project\\mixdog-bench\\scripts\\usage-today.mjs): 신규 스크립트 추가\n - `MIXDOG_DATA_DIR` 우선, 기본 `~/.mixdog/data/history/agent-trace.jsonl`\n - 로컬 자정 이후 `kind: \"usage\"` rows 집계\n - 모델별 calls/input/cached/output/costUsd 및 `TOTAL` 출력\n - `--trace`, `--json` 인자 파싱은 `session-bench.mjs` 스타일 사용\n\n검증:\n- `node --check scripts/usage-today.mjs`: 통과\n- `node scripts/usage-today.mjs`: 정상 출력\n- `npm run usage:today`: 정상 출력, 다만 PowerShell의 `npm.ps1`에서 npm global path 접근 경고가 한 줄 뜬 뒤 스크립트는 exit 0으로 실행됐습니다.\n\n참고로 작업트리에는 제가 건드리지 않은 기존 수정도 있습니다:\n- `src/runtime/channels/lib/event-queue.mjs`\n- `src/runtime/channels/lib/output-forwarder.mjs`"
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
"id": "r4-explain-compact-engine",
|
|
56
|
-
"agent": "explore",
|
|
57
|
-
"ok": true,
|
|
58
|
-
"ms": 97535,
|
|
59
|
-
"sessionId": "019f254d-7f3e-73d1-89b0-a4bd9928d221",
|
|
60
|
-
"card": {
|
|
61
|
-
"session": "019f254d-7f3e-73d1-89b0-a4bd9928d221",
|
|
62
|
-
"wall_ms": 97535,
|
|
63
|
-
"uncached_in": 71445,
|
|
64
|
-
"cached_in": 307328,
|
|
65
|
-
"out_tokens": 5046,
|
|
66
|
-
"cache_ratio": 0.811,
|
|
67
|
-
"completed": 1
|
|
68
|
-
},
|
|
69
|
-
"output": "**Compaction Brief**\n\n- Public surface starts in `src/runtime/agent/orchestrator/session/compact/engine.mjs`: `semanticCompactMessages()` and `recallFastTrackCompactMessages()` are exported by the facade at `src/runtime/agent/orchestrator/session/compact.mjs:52-55`.\n- Automatic pre-send caller is `session/loop.mjs`, importing semantic compact at `src/runtime/agent/orchestrator/session/loop.mjs:10-16` and recall pipeline at `src/runtime/agent/orchestrator/session/loop.mjs:31-33`.\n- Manual/session caller is `runSessionCompaction()`, importing both engine entry points through the facade at `src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs:8-16`.\n- CLI `/compact` calls `runtime.compact()` at `src/repl.mjs:304-307`; runtime compact blocks active turns, fires manual hooks, then calls `mgr.compactSessionMessages()` at `src/mixdog-session-runtime.mjs:2452-2464`.\n- `compactSessionMessages()` loads the session, rejects closed/in-progress sessions, and invokes `runSessionCompaction(... mode:'manual', force:true ...)` at `src/runtime/agent/orchestrator/session/manager.mjs:1943-1957`.\n- Auto policy resolves only when `compaction.auto` and env allow it, then derives boundary/trigger/reserve/type/tail settings at `src/runtime/agent/orchestrator/session/loop/compact-policy.mjs:89-148`.\n- Auto fires when `forceReactive` is true, token estimate is unavailable, or `messageTokens + reserve >= triggerTokens` at `src/runtime/agent/orchestrator/session/loop/compact-policy.mjs:170-174`.\n- Loop computes `messageTokensEst`, `shouldCompact`, pressure, trigger label `auto|reactive`, and target budget before the send at `src/runtime/agent/orchestrator/session/loop.mjs:351-364`.\n- Reactive compaction is armed after a provider context-overflow refusal, then the loop continues back through the same pre-send compact path at `src/runtime/agent/orchestrator/session/loop.mjs:982-1011`.\n- Manual runner skips if auto is disabled only for `mode:'auto'`, forces manual runs, skips tiny histories when not forced, and returns “below threshold” when pressure is below trigger at `src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs:143-195`.\n- Semantic engine first sanitizes/dedups/tool-pair reconciles, no-ops if already within budget and not forced, then redacts and selects the compaction window at `src/runtime/agent/orchestrator/session/compact/engine.mjs:278-314`.\n- Semantic window selection separates protected system prefix, strips prior summary from live messages, and remembers the latest previous summary at `src/runtime/agent/orchestrator/session/compact/engine.mjs:100-111`.\n- Semantic preserved-tail budget is `preserveRecentBudget()`, capped by explicit keep/preserve settings or default/min/25%-of-budget rules at `src/runtime/agent/orchestrator/session/compact/budget.mjs:274-287`.\n- With user turns, semantic keeps up to recent `tailTurns`, splitting the newest turn suffix if needed, and force-compaction can move the cut forward to ensure a compactable head at `src/runtime/agent/orchestrator/session/compact/engine.mjs:130-185`.\n- Without user turns, semantic picks non-tool cut points so tool results do not start the tail, grows newest-to-oldest while fitting budget, and falls back to minimal/empty tail cases at `src/runtime/agent/orchestrator/session/compact/engine.mjs:188-232`.\n- After cutting, semantic sanitizes/dedups/reconciles the tail and throws only for an empty live window or no compactable head without a previous summary at `src/runtime/agent/orchestrator/session/compact/engine.mjs:244-258` and `src/runtime/agent/orchestrator/session/compact/engine.mjs:314-317`.\n- Semantic raises budget to fit mandatory `system + tail + summary room`, builds a fitted prompt, calls `provider.send()`, schema-repairs the summary, then emits `system + summary + tail` at `src/runtime/agent/orchestrator/session/compact/engine.mjs:319-397`.\n- Recall-fasttrack loop hydrates memory, dumps session roots, drains raw cycle1 rows when needed, caps recall injection to 5% of context with a floor, then calls `recallFastTrackCompactMessages()` at `src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs:57-172`.\n- Recall preserved tail keeps newest structured turns, drops oldest kept turns until under cap, or truncates the single newest surviving turn; no-user tails are valid at `src/runtime/agent/orchestrator/session/compact/engine.mjs:593-619`.\n- Recall engine redacts, splits protected context, chooses recall tail/head, rejects empty recall/head cases unless allowed, raises mandatory budget, fits recall summary, and emits `system + recall summary + tail` at `src/runtime/agent/orchestrator/session/compact/engine.mjs:622-699`.\n- Redaction hooks in after the no-op fast path and before semantic window selection at `src/runtime/agent/orchestrator/session/compact/engine.mjs:286-314`, and before recall context split at `src/runtime/agent/orchestrator/session/compact/engine.mjs:644-651`.\n- Preserved-message redaction touches only assistant `toolCalls` argument values, preserving role/content/tool IDs/shape/order at `src/runtime/agent/orchestrator/session/compact/text-utils.mjs:261-266` and `src/runtime/agent/orchestrator/session/compact/text-utils.mjs:291-325`.\n- Prompt-side/preserved-fact redaction also scrubs raw secret strings and sensitive tool args before summaries/facts are built at `src/runtime/agent/orchestrator/session/compact/text-utils.mjs:121-160` and `src/runtime/agent/orchestrator/session/compact/budget.mjs:119-163`.\n- Loop failure path: recall failures are not silently pruned; non-recall failures try `pruneToolOutputsUnanchored()` and accept only if changed and within effective budget at `src/runtime/agent/orchestrator/session/loop.mjs:500-537`.\n- If loop fallback succeeds it continues; otherwise it records `overflow_failed`, traces/emits failed compact, and throws `agentContextOverflowError` at `src/runtime/agent/orchestrator/session/loop.mjs:538-627`.\n- Loop success mutates `messages`, clears provider state, resets iterations/usage epoch, records telemetry, traces, emits compact/no_change, and runs post-compact hook at `src/runtime/agent/orchestrator/session/loop.mjs:629-728`.\n- Manager failure path: recall-fasttrack failure can degrade to semantic fallback if semantic is enabled and provider exists at `src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs:231-278`.\n- Manager semantic failures then try the same non-recall unanchored prune fallback, gated off recall errors, at `src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs:319-347`.\n- If manager still has no compacted output it records `manual_failed|post_turn_failed` and returns an error result; success replaces session messages, clears provider state, records stage `manual|post_turn`, and updates compact timestamps at `src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs:348-447`."
|
|
70
|
-
}
|
|
71
|
-
],
|
|
72
|
-
"task_complete": true,
|
|
73
|
-
"task_errors": [],
|
|
74
|
-
"score_complete": true,
|
|
75
|
-
"score_errors": [],
|
|
76
|
-
"group": {
|
|
77
|
-
"n": 3,
|
|
78
|
-
"wall_ms": 89889.7,
|
|
79
|
-
"uncached_in": 66449,
|
|
80
|
-
"cached_in": 210005.3,
|
|
81
|
-
"out_tokens": 4749.7,
|
|
82
|
-
"cache_ratio": 0.7,
|
|
83
|
-
"completed": 1
|
|
84
|
-
},
|
|
85
|
-
"cards": [
|
|
86
|
-
{
|
|
87
|
-
"session": "019f254d-7eb9-7b61-8033-dac06c077921",
|
|
88
|
-
"wall_ms": 113095,
|
|
89
|
-
"uncached_in": 73170,
|
|
90
|
-
"cached_in": 184192,
|
|
91
|
-
"out_tokens": 6579,
|
|
92
|
-
"cache_ratio": 0.716,
|
|
93
|
-
"completed": 1
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
"session": "019f254d-80cf-7ee2-bc2b-e189fd3466e1",
|
|
97
|
-
"wall_ms": 59039,
|
|
98
|
-
"uncached_in": 54732,
|
|
99
|
-
"cached_in": 138496,
|
|
100
|
-
"out_tokens": 2624,
|
|
101
|
-
"cache_ratio": 0.717,
|
|
102
|
-
"completed": 1
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
"session": "019f254d-7f3e-73d1-89b0-a4bd9928d221",
|
|
106
|
-
"wall_ms": 97535,
|
|
107
|
-
"uncached_in": 71445,
|
|
108
|
-
"cached_in": 307328,
|
|
109
|
-
"out_tokens": 5046,
|
|
110
|
-
"cache_ratio": 0.811,
|
|
111
|
-
"completed": 1
|
|
112
|
-
}
|
|
113
|
-
]
|
|
114
|
-
}
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"round": "4",
|
|
3
|
-
"runner": "lead",
|
|
4
|
-
"opts": {
|
|
5
|
-
"provider": null,
|
|
6
|
-
"model": null,
|
|
7
|
-
"effort": null,
|
|
8
|
-
"fast": false,
|
|
9
|
-
"env": {
|
|
10
|
-
"MIXDOG_DATA_DIR": "C:\\Users\\tempe\\.mixdog\\bench-data"
|
|
11
|
-
}
|
|
12
|
-
},
|
|
13
|
-
"tasks": 3,
|
|
14
|
-
"completed": 3,
|
|
15
|
-
"completion_rate": 100,
|
|
16
|
-
"sessions": [
|
|
17
|
-
"sess_54432_1783037011657_1783037011956_040141751665fcffed70f31af6fed031",
|
|
18
|
-
"sess_56432_1783037011657_1783037011956_67cb279c86f5fc873eeae934c042b296",
|
|
19
|
-
"sess_20684_1783037011676_1783037011957_f3a34ca2114150d22a2f8c6ba82408de"
|
|
20
|
-
],
|
|
21
|
-
"results": [
|
|
22
|
-
{
|
|
23
|
-
"id": "r4-debug-forwarding-gap",
|
|
24
|
-
"agent": "reviewer",
|
|
25
|
-
"ok": true,
|
|
26
|
-
"ms": 246989,
|
|
27
|
-
"sessionId": "sess_54432_1783037011657_1783037011956_040141751665fcffed70f31af6fed031",
|
|
28
|
-
"output": "sessionId: sess_54432_1783037011657_1783037011956_040141751665fcffed70f31af6fed031\n조사 완료했습니다. 활성화 경로는 `activate_channel_bridge`(tool-dispatch.mjs:45) 또는 `start()`(index.mjs:1734)에서 `writeBridgeState(true)`(index.mjs:218)가 **바인딩보다 먼저** 기록되고, 이후 `refreshBridgeOwnership → startOwnedRuntime → bindPersistedTranscriptIfAny → rebindTranscriptContext → applyTranscriptBinding → forwarder.setContext/startWatch` 순으로 진행됩니다. 그 창구간의 갭은 다음과 같습니다.\n\n**갭 목록 (영향 순)**\n\n1. **EOF 바인드로 인한 영구 드롭** — `setContext`의 `catchUpFromPersisted`는 영속 경로와 새 트랜스크립트가 다르면 커서를 `currentSize`(EOF)로 설정합니다(output-forwarder.mjs:117-124). `rebindTranscriptContext`의 exists:true 분기는 루프가 먼저 PENDING 상태를 봤을 때만 `replayFromStart`를 켜므로(index.mjs:438-439), 첫 반복에서 이미 파일이 존재하는 새 세션 트랜스크립트는 EOF에 바인드됩니다. 세션 시작~바인드 사이에 기록된 어시스턴트 출력은 커서가 되감기지 않아 **백로그 캐치업으로 복구 불가(영구 손실)**. pending 분기(index.mjs:485-491)와 steal 경로(index.mjs:1602-1616 주석)만 이 문제를 방어합니다.\n\n2. **channelId 미해결 시 첫 인바운드 이전 출력 영구 드롭** — 영속 status도, `mainChannel` 설정도 없으면 `bindPersistedTranscriptIfAny`가 바인딩 없이 반환하고(index.mjs:624), 첫 인바운드의 `applyTranscriptBinding`(index.mjs:1598)은 replay 플래그 없이 EOF 바인드합니다. 그 이전 출력은 **복구 불가**. main 폴백(index.mjs:610-623)이 설정된 환경에서만 완화됩니다.\n\n3. **pre-connect 소유권 게이트로 인한 tool-log 드롭** — `ownerGetter`는 `bridgeRuntimeConnected && owned`(index.mjs:316)인데, 바인딩 태스크는 `backend.connect()`와 동시 실행됩니다(index.mjs:759 vs 769). 이 창에서 `forwardNewText`는 커서를 안 옮기고 반환하므로 텍스트는 post-connect 재전송(index.mjs:801-812)으로 **복구됨(지연만)**. 반면 `forwardToolLog`(output-forwarder.mjs:414)는 트랜스크립트 기반이 아니라 큐 적재 자체가 스킵되어 해당 진행 로그는 **복구 불가**.\n\n4. **미존재 파일 fs.watch 실패 + 60초 rearm 상한** — `startWatch`는 없는 파일에서 조용히 실패하고(output-forwarder.mjs:667-670), rearm 폴은 `PENDING_REARM_MAX_MS=60_000` 후 무음 타임아웃합니다(index.mjs:349, 384-386). 커서가 0이라 다음 트리거(인바운드 리바인드, 툴콜 250ms 디바운스 forwardNewText tool-dispatch.mjs:125, turn-end)에서 **백로그로 복구되나 무기한 지연 가능** — 특히 worker 모드는 `turnEndWatcher`가 미설치라(index.mjs:251) 인바운드/툴콜이 없으면 트리거가 없습니다.\n\n5. **watch error 후 재설치 부재** — watcher 에러 시 `closeWatcher`만 하고 rearm하지 않습니다(output-forwarder.mjs:658-661). 커서는 보존되어 다음 트리거에서 **복구됨(지연)**.\n\n6. **rearm tick의 `!bridgeRuntimeConnected` 영구 종료** — 재스케줄 없이 종료하지만(index.mjs:372-375), start 경로의 post-connect 재무장(index.mjs:804-812)이 커버해 실질 영향은 낮습니다.\n\n**한 줄 결론**: 창구간의 대부분 갭은 커서 보존 덕에 지연 후 백로그로 복구되지만, 영속 경로와 불일치하는 이미-존재하는 새 트랜스크립트를 EOF에 바인드하는 경우(1번, 2번)와 pre-connect 창의 tool-log(3번)는 어떤 캐치업으로도 복구되지 않는 진짜 무음 손실입니다.",
|
|
29
|
-
"card": {
|
|
30
|
-
"session": "sess_54432_1783037011657_1783037011956_040141751665fcffed70f31af6fed031",
|
|
31
|
-
"provider": "anthropic-oauth",
|
|
32
|
-
"model": "claude-fable-5",
|
|
33
|
-
"wall_ms": 236323,
|
|
34
|
-
"turns": 6,
|
|
35
|
-
"tool_calls": 8,
|
|
36
|
-
"tools_per_turn": 1.3,
|
|
37
|
-
"total_tool_ms": 307,
|
|
38
|
-
"llm_stream_ms": 214082,
|
|
39
|
-
"cache_ratio": 0.8010233375523009,
|
|
40
|
-
"cached_tokens": 252517,
|
|
41
|
-
"prompt_tokens": 315243,
|
|
42
|
-
"uncached_tokens": 62726,
|
|
43
|
-
"output_tokens": 29608,
|
|
44
|
-
"cache_weighted_input_10": 87977.7,
|
|
45
|
-
"cache_weighted_input_25": 125855.25,
|
|
46
|
-
"prompt_growth": 62036,
|
|
47
|
-
"antipatterns": 0,
|
|
48
|
-
"issues": 0,
|
|
49
|
-
"issue_types": [],
|
|
50
|
-
"read_fragmentation_paths": [],
|
|
51
|
-
"grep_sweep_count": 0
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
"id": "r4-impl-usage-summary",
|
|
56
|
-
"agent": "worker",
|
|
57
|
-
"ok": true,
|
|
58
|
-
"ms": 136723,
|
|
59
|
-
"sessionId": "sess_56432_1783037011657_1783037011956_67cb279c86f5fc873eeae934c042b296",
|
|
60
|
-
"output": "sessionId: sess_56432_1783037011657_1783037011956_67cb279c86f5fc873eeae934c042b296\napply_patch 도구가 깨져 있어 파일 생성은 shell로 대신합니다.완료했습니다. `usage:today` 스크립트 추가와 npm script 등록, 검증까지 마쳤습니다.\n\n**바뀐 점**\n- `scripts/usage-today.mjs` 신규 (114줄): session-bench.mjs 스타일의 `argValue`/`hasFlag` 파싱(`--trace`, `--json` 지원), `MIXDOG_DATA_DIR` → `resolvePluginData()` → `~/.mixdog/data` 순으로 trace 경로 해석, 로컬 자정 이후 `kind === 'usage'` 행을 모델별로 집계.\n- `package.json`: `\"usage:today\": \"node scripts/usage-today.mjs\"` 스크립트 1줄 추가.\n\n**확인한 것**\n- `node --check` 통과, `npm run usage:today` 실행 결과 모델별 calls/input/cached/output/costUsd + TOTAL 행 정상 출력 (오늘 89 calls, $55.41).\n\n**참고** — apply_patch 도구가 환경 문제(`native patch binary unavailable`)로 실패해서 파일 쓰기는 PowerShell로 처리했고, 실행 시 trace가 `MIXDOG_DATA_DIR` 환경변수 덕에 `.mixdog\\bench-data`로 해석됐습니다(의도된 우선순위 동작).",
|
|
61
|
-
"card": {
|
|
62
|
-
"session": "sess_56432_1783037011657_1783037011956_67cb279c86f5fc873eeae934c042b296",
|
|
63
|
-
"provider": "anthropic-oauth",
|
|
64
|
-
"model": "claude-fable-5",
|
|
65
|
-
"wall_ms": 126133,
|
|
66
|
-
"turns": 9,
|
|
67
|
-
"tool_calls": 9,
|
|
68
|
-
"tools_per_turn": 1,
|
|
69
|
-
"total_tool_ms": 2867,
|
|
70
|
-
"llm_stream_ms": 88804,
|
|
71
|
-
"cache_ratio": 0.892783231866202,
|
|
72
|
-
"cached_tokens": 296371,
|
|
73
|
-
"prompt_tokens": 331963,
|
|
74
|
-
"uncached_tokens": 35592,
|
|
75
|
-
"output_tokens": 10689,
|
|
76
|
-
"cache_weighted_input_10": 65229.100000000006,
|
|
77
|
-
"cache_weighted_input_25": 109684.75,
|
|
78
|
-
"prompt_growth": 34902,
|
|
79
|
-
"antipatterns": 0,
|
|
80
|
-
"issues": 1,
|
|
81
|
-
"issue_types": [
|
|
82
|
-
"tool_error"
|
|
83
|
-
],
|
|
84
|
-
"read_fragmentation_paths": [],
|
|
85
|
-
"grep_sweep_count": 0
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
"id": "r4-explain-compact-engine",
|
|
90
|
-
"agent": "explore",
|
|
91
|
-
"ok": true,
|
|
92
|
-
"ms": 65718,
|
|
93
|
-
"sessionId": "sess_20684_1783037011676_1783037011957_f3a34ca2114150d22a2f8c6ba82408de",
|
|
94
|
-
"output": "sessionId: sess_20684_1783037011676_1783037011957_f3a34ca2114150d22a2f8c6ba82408de\n컴팩션 서브시스템 아키텍처 브리프입니다.\n\n**진입점과 호출자**\n- 엔진 공개 API 2개: `semanticCompactMessages` (engine.mjs:278, LLM 요약), `recallFastTrackCompactMessages` (engine.mjs:445, 비-LLM recall 주입). `compact.mjs:53-54`가 재수출.\n- 호출자 3곳: 루프 내 자동 컴팩트 `loop.mjs:414-460` (recall은 `loop/recall-fasttrack.mjs:161` 경유), 매니저의 수동/auto-clear 경로 `manager/compaction-runner.mjs:210,245,288`, 스모크/벤치 스크립트(`scripts/compact-smoke.mjs`, `scripts/session-context-bench.mjs:257`).\n\n**발동 결정 흐름**\n- 루프: `shouldCompactForSession(loop.mjs:353)`이 압력 토큰으로 판정, reactive overflow 재시도 플래그가 강제 트리거(loop.mjs:352,361). 타입 분기는 recallFastTrack → semantic → 에러(loop.mjs:414,439,497).\n- 매니저: `pressureTokens < triggerTokens`면 no-op 반환(compaction-runner.mjs:176), 예산은 `compactTargetBudget`(compaction-runner.mjs:197).\n- 엔진 자체 no-op 가드: sanitize 후에도 예산에 맞고 `force !== true`면 원본 그대로 반환(engine.mjs:289, 627).\n\n**보존 tail 선택**\n- 공통: `splitLiveCompactionContext`(engine.mjs:100)가 보호 prefix/이전 summary/live를 분리.\n- semantic 경로 `selectCompactionWindow`(engine.mjs:235): user 턴이 있으면 턴 단위 선택 `selectTailStartByTurns`(engine.mjs:134, 최근 `tailTurns`=2턴을 `preserveRecentBudget` 내로), 없으면 컷포인트 방식 `selectTailStartByCutPoint`(engine.mjs:193, tool result에서 시작 불가 규칙은 engine.mjs:121).\n- recall 경로 `selectRecallPreservedTail`(engine.mjs:593): 최근 2턴(engine.mjs:467)을 8k 캡(engine.mjs:468) 내로, 초과 시 오래된 턴 드롭 → 중간 절단(engine.mjs:473).\n- tail 컷 후 `sanitizeToolPairs`류로 tool 페어링 복구(engine.mjs:250, 608).\n\n**레닥션 훅**\n- 컴팩션 진행이 확정된 직후, 윈도 선택 **전에** `redactToolCallSecretsInMessages` 적용(engine.mjs:312, 644; text-utils.mjs에서 import, engine.mjs:23) — 보존 tail이 레닥션된 형태로 측정·방출됨. no-op 경로에는 미적용(engine.mjs:288 주석).\n\n**실패/폴백 경로**\n- 엔진 하드 실패: 빈 live 윈도(engine.mjs:255), 압축할 head 없음(engine.mjs:316), 프롬프트/summary 예산 미달(engine.mjs:336, 386), 결과 예산 초과(engine.mjs:396). 빈 summary(engine.mjs:372), malformed summary는 스키마 강제 복구(engine.mjs:376).\n- 예산 부족은 거부 대신 mandatory+summary room으로 예산 상향(engine.mjs:328-330).\n- 매니저: recall 실패 → semantic 폴백 1회(compaction-runner.mjs:242-263), semantic 실패 → 비-LLM prune 안전망 `pruneToolOutputsUnanchored`(compaction-runner.mjs:327-345), 전부 실패 시 실패 상태 기록(compaction-runner.mjs:348).\n- 루프: 동일한 prune 안전망이 있으나 recall 실패에는 gated(loop.mjs:517-537), 최종 실패는 `overflow_failed` 텔레메트리로 에스컬레이션(loop.mjs:552).",
|
|
95
|
-
"card": {
|
|
96
|
-
"session": "sess_20684_1783037011676_1783037011957_f3a34ca2114150d22a2f8c6ba82408de",
|
|
97
|
-
"provider": "anthropic-oauth",
|
|
98
|
-
"model": "claude-fable-5",
|
|
99
|
-
"wall_ms": 55137,
|
|
100
|
-
"turns": 5,
|
|
101
|
-
"tool_calls": 5,
|
|
102
|
-
"tools_per_turn": 1,
|
|
103
|
-
"total_tool_ms": 511,
|
|
104
|
-
"llm_stream_ms": 32155,
|
|
105
|
-
"cache_ratio": 0.7874257600674105,
|
|
106
|
-
"cached_tokens": 115876,
|
|
107
|
-
"prompt_tokens": 147158,
|
|
108
|
-
"uncached_tokens": 31282,
|
|
109
|
-
"output_tokens": 2956,
|
|
110
|
-
"cache_weighted_input_10": 42869.6,
|
|
111
|
-
"cache_weighted_input_25": 60251,
|
|
112
|
-
"prompt_growth": 30774,
|
|
113
|
-
"antipatterns": 1,
|
|
114
|
-
"issues": 1,
|
|
115
|
-
"issue_types": [
|
|
116
|
-
"tool_churn_cluster"
|
|
117
|
-
],
|
|
118
|
-
"read_fragmentation_paths": [],
|
|
119
|
-
"grep_sweep_count": 0
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
],
|
|
123
|
-
"task_complete": true,
|
|
124
|
-
"task_errors": [],
|
|
125
|
-
"score_complete": true,
|
|
126
|
-
"score_errors": [],
|
|
127
|
-
"group": {
|
|
128
|
-
"n": 3,
|
|
129
|
-
"wall_ms": 139197.7,
|
|
130
|
-
"turns": 6.7,
|
|
131
|
-
"tool_calls": 7.3,
|
|
132
|
-
"tools_per_turn": 1.1,
|
|
133
|
-
"total_tool_ms": 1228.3,
|
|
134
|
-
"llm_stream_ms": 111680.3,
|
|
135
|
-
"cache_ratio": 0.8,
|
|
136
|
-
"cached_tokens": 221588,
|
|
137
|
-
"prompt_tokens": 264788,
|
|
138
|
-
"uncached_tokens": 43200,
|
|
139
|
-
"output_tokens": 14417.7,
|
|
140
|
-
"cache_weighted_input_10": 65358.8,
|
|
141
|
-
"cache_weighted_input_25": 98597,
|
|
142
|
-
"prompt_growth": 42570.7,
|
|
143
|
-
"antipatterns": 0.3,
|
|
144
|
-
"issues": 0.7,
|
|
145
|
-
"grep_sweep_count": 0
|
|
146
|
-
},
|
|
147
|
-
"cards": [
|
|
148
|
-
{
|
|
149
|
-
"session": "sess_54432_1783037011657_1783037011956_040141751665fcffed70f31af6fed031",
|
|
150
|
-
"provider": "anthropic-oauth",
|
|
151
|
-
"model": "claude-fable-5",
|
|
152
|
-
"wall_ms": 236323,
|
|
153
|
-
"turns": 6,
|
|
154
|
-
"tool_calls": 8,
|
|
155
|
-
"tools_per_turn": 1.3,
|
|
156
|
-
"total_tool_ms": 307,
|
|
157
|
-
"llm_stream_ms": 214082,
|
|
158
|
-
"cache_ratio": 0.8010233375523009,
|
|
159
|
-
"cached_tokens": 252517,
|
|
160
|
-
"prompt_tokens": 315243,
|
|
161
|
-
"uncached_tokens": 62726,
|
|
162
|
-
"output_tokens": 29608,
|
|
163
|
-
"cache_weighted_input_10": 87977.7,
|
|
164
|
-
"cache_weighted_input_25": 125855.25,
|
|
165
|
-
"prompt_growth": 62036,
|
|
166
|
-
"antipatterns": 0,
|
|
167
|
-
"issues": 0,
|
|
168
|
-
"issue_types": [],
|
|
169
|
-
"read_fragmentation_paths": [],
|
|
170
|
-
"grep_sweep_count": 0
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
"session": "sess_56432_1783037011657_1783037011956_67cb279c86f5fc873eeae934c042b296",
|
|
174
|
-
"provider": "anthropic-oauth",
|
|
175
|
-
"model": "claude-fable-5",
|
|
176
|
-
"wall_ms": 126133,
|
|
177
|
-
"turns": 9,
|
|
178
|
-
"tool_calls": 9,
|
|
179
|
-
"tools_per_turn": 1,
|
|
180
|
-
"total_tool_ms": 2867,
|
|
181
|
-
"llm_stream_ms": 88804,
|
|
182
|
-
"cache_ratio": 0.892783231866202,
|
|
183
|
-
"cached_tokens": 296371,
|
|
184
|
-
"prompt_tokens": 331963,
|
|
185
|
-
"uncached_tokens": 35592,
|
|
186
|
-
"output_tokens": 10689,
|
|
187
|
-
"cache_weighted_input_10": 65229.100000000006,
|
|
188
|
-
"cache_weighted_input_25": 109684.75,
|
|
189
|
-
"prompt_growth": 34902,
|
|
190
|
-
"antipatterns": 0,
|
|
191
|
-
"issues": 1,
|
|
192
|
-
"issue_types": [
|
|
193
|
-
"tool_error"
|
|
194
|
-
],
|
|
195
|
-
"read_fragmentation_paths": [],
|
|
196
|
-
"grep_sweep_count": 0
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
"session": "sess_20684_1783037011676_1783037011957_f3a34ca2114150d22a2f8c6ba82408de",
|
|
200
|
-
"provider": "anthropic-oauth",
|
|
201
|
-
"model": "claude-fable-5",
|
|
202
|
-
"wall_ms": 55137,
|
|
203
|
-
"turns": 5,
|
|
204
|
-
"tool_calls": 5,
|
|
205
|
-
"tools_per_turn": 1,
|
|
206
|
-
"total_tool_ms": 511,
|
|
207
|
-
"llm_stream_ms": 32155,
|
|
208
|
-
"cache_ratio": 0.7874257600674105,
|
|
209
|
-
"cached_tokens": 115876,
|
|
210
|
-
"prompt_tokens": 147158,
|
|
211
|
-
"uncached_tokens": 31282,
|
|
212
|
-
"output_tokens": 2956,
|
|
213
|
-
"cache_weighted_input_10": 42869.6,
|
|
214
|
-
"cache_weighted_input_25": 60251,
|
|
215
|
-
"prompt_growth": 30774,
|
|
216
|
-
"antipatterns": 1,
|
|
217
|
-
"issues": 1,
|
|
218
|
-
"issue_types": [
|
|
219
|
-
"tool_churn_cluster"
|
|
220
|
-
],
|
|
221
|
-
"read_fragmentation_paths": [],
|
|
222
|
-
"grep_sweep_count": 0
|
|
223
|
-
}
|
|
224
|
-
]
|
|
225
|
-
}
|