mixdog 0.9.4 → 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 +4 -1
- package/scripts/bench/r5-orchestrated-task.json +7 -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-run.mjs +40 -7
- package/scripts/internal-comms-bench.mjs +2 -4
- package/scripts/model-catalog-audit.mjs +209 -0
- package/scripts/model-list-sanitize-test.mjs +37 -0
- package/scripts/recall-bench.mjs +76 -13
- package/scripts/recall-quality-cases.json +12 -0
- package/scripts/tool-smoke.mjs +2 -2
- package/src/agents/heavy-worker/AGENT.md +7 -7
- package/src/agents/scheduler-task/AGENT.md +2 -3
- package/src/agents/webhook-handler/AGENT.md +2 -3
- package/src/agents/worker/AGENT.md +9 -10
- package/src/app.mjs +12 -1
- package/src/headless-role.mjs +7 -1
- package/src/mixdog-session-runtime.mjs +15 -14
- package/src/output-styles/default.md +14 -18
- package/src/output-styles/minimal.md +4 -5
- package/src/output-styles/simple.md +7 -8
- package/src/rules/agent/00-common.md +6 -5
- 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 +6 -3
- package/src/rules/lead/lead-tool.md +6 -4
- 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/providers/model-catalog.mjs +19 -0
- package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +11 -3
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +53 -9
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +23 -10
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +11 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +33 -4
- package/src/runtime/agent/orchestrator/providers/provider-catalog-cache.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +93 -0
- package/src/runtime/agent/orchestrator/session/loop.mjs +27 -5
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +1 -1
- package/src/runtime/agent/orchestrator/stall-policy.mjs +20 -1
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +7 -7
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
- package/src/runtime/channels/backends/discord-gateway.mjs +2 -2
- package/src/runtime/channels/backends/discord.mjs +15 -26
- package/src/runtime/channels/backends/telegram.mjs +8 -12
- package/src/runtime/channels/index.mjs +23 -43
- package/src/runtime/channels/lib/backend-dispatch.mjs +5 -3
- package/src/runtime/channels/lib/config.mjs +37 -149
- package/src/runtime/channels/lib/event-pipeline.mjs +4 -4
- package/src/runtime/channels/lib/event-queue.mjs +15 -9
- package/src/runtime/channels/lib/inbound-routing.mjs +2 -39
- package/src/runtime/channels/lib/interaction-workflows.mjs +5 -113
- package/src/runtime/channels/lib/scheduler.mjs +27 -113
- package/src/runtime/channels/lib/webhook/deliveries.mjs +3 -2
- package/src/runtime/channels/lib/webhook.mjs +8 -47
- package/src/runtime/memory/index.mjs +9 -0
- package/src/runtime/memory/lib/core-memory-store.mjs +5 -1
- package/src/runtime/memory/lib/ko-morph.mjs +195 -0
- package/src/runtime/memory/lib/memory-recall-store.mjs +47 -10
- package/src/runtime/memory/lib/memory-text-utils.mjs +46 -0
- package/src/runtime/memory/lib/query-handlers.mjs +27 -5
- package/src/runtime/memory/tool-defs.mjs +2 -2
- package/src/runtime/shared/config.mjs +14 -4
- 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/session-runtime/config-helpers.mjs +45 -10
- package/src/session-runtime/quick-model-rows.mjs +46 -11
- package/src/session-runtime/quick-search-models.mjs +28 -27
- package/src/session-runtime/settings-api.mjs +34 -1
- package/src/session-runtime/tool-defs.mjs +1 -1
- package/src/session-runtime/workflow.mjs +1 -1
- package/src/standalone/agent-tool/tool-def.mjs +1 -1
- package/src/standalone/agent-tool.mjs +30 -0
- package/src/standalone/channel-admin.mjs +102 -90
- package/src/standalone/explore-tool.mjs +39 -10
- package/src/tui/App.jsx +126 -28
- package/src/tui/app/app-format.mjs +11 -4
- package/src/tui/app/channel-pickers.mjs +2 -4
- package/src/tui/app/maintenance-pickers.mjs +60 -28
- package/src/tui/app/model-options.mjs +5 -1
- package/src/tui/app/settings-picker.mjs +0 -1
- package/src/tui/app/transcript-window.mjs +8 -2
- package/src/tui/app/use-transcript-scroll.mjs +3 -1
- package/src/tui/app/use-transcript-window.mjs +19 -1
- package/src/tui/components/ConfirmBar.jsx +10 -7
- package/src/tui/components/Picker.jsx +32 -11
- package/src/tui/components/PromptInput.jsx +10 -1
- package/src/tui/components/StatusLine.jsx +6 -3
- package/src/tui/dist/index.mjs +440 -293
- package/src/tui/engine.mjs +48 -12
- package/src/tui/index.jsx +11 -52
- package/src/ui/statusline.mjs +10 -0
- package/src/workflows/default/WORKFLOW.md +15 -17
- package/src/workflows/sequential/WORKFLOW.md +15 -17
- package/vendor/ink/build/ink.js +9 -1
- package/scripts/recall-usecase-probe.json +0 -6
- package/src/runtime/channels/lib/holidays.mjs +0 -138
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
{
|
|
2
|
+
"round": "20",
|
|
3
|
+
"runner": "lead",
|
|
4
|
+
"opts": {
|
|
5
|
+
"provider": "openai-oauth",
|
|
6
|
+
"model": "gpt-5.5",
|
|
7
|
+
"effort": null,
|
|
8
|
+
"fast": false,
|
|
9
|
+
"env": {
|
|
10
|
+
"MIXDOG_DATA_DIR": "C:\\Users\\tempe\\.mixdog\\bench-data",
|
|
11
|
+
"MIXDOG_OPENAI_OAUTH_WS_WARMUP": "1"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"tasks": 6,
|
|
15
|
+
"completed": 6,
|
|
16
|
+
"completion_rate": 100,
|
|
17
|
+
"sessions": [
|
|
18
|
+
"sess_24484_1783061209581_1783061209828_780131e53fd6bc2b4d00e76277ef0eac",
|
|
19
|
+
"sess_50164_1783061209590_1783061209828_64514b47078973e8ff313ba80fddc6d6",
|
|
20
|
+
"sess_6636_1783061209603_1783061209840_309bbb037fe8492a38533175c6dec7e7",
|
|
21
|
+
"sess_12456_1783061273178_1783061273417_b75f3cff29775e56257b108f96388d21",
|
|
22
|
+
"sess_34340_1783061299082_1783061299306_c1576ad2a7e9cafad2329f5c0bf5a041",
|
|
23
|
+
"sess_40856_1783061322058_1783061322304_6da5edceb48f481a206a016ccc63c5fc"
|
|
24
|
+
],
|
|
25
|
+
"results": [
|
|
26
|
+
{
|
|
27
|
+
"id": "r4-debug-forwarding-gap#1",
|
|
28
|
+
"agent": "reviewer",
|
|
29
|
+
"ok": true,
|
|
30
|
+
"ms": 112485,
|
|
31
|
+
"sessionId": "sess_24484_1783061209581_1783061209828_780131e53fd6bc2b4d00e76277ef0eac",
|
|
32
|
+
"output": "sessionId: sess_24484_1783061209581_1783061209828_780131e53fd6bc2b4d00e76277ef0eac\n조사 결과, 활성화 직후 출력 유실 가능성은 “바인딩 실패/EOF 바인딩” 쪽에 있고, `fs.watch`/ownership 창은 대부분 지연 후 catch-up됩니다.\n\n- **경로:** `writeBridgeState()`가 `bridge-state.json`을 쓰고(`src/runtime/channels/index.mjs:218`), ownership 갱신이 `startOwnedRuntime()`로 이어져 바인딩/연결/후속 catch-up을 수행합니다(`index.mjs:881`, `index.mjs:710`, `index.mjs:801`).\n\n- **최대 영향 — 바인딩 후보 없음:** 초기 `rebindTranscriptContext()`가 30×150ms 안에 transcript/previous path를 못 찾으면 바인딩 없이 종료됩니다(`index.mjs:431`, `index.mjs:503`, `index.mjs:515`). 이후 이미 존재하는 transcript에 일반 바인딩되면 cursor가 EOF로 잡혀 그 사이 출력은 복구되지 않습니다(`src/runtime/channels/lib/output-forwarder.mjs:125`).\n\n- **기존 transcript + persisted cursor 불일치:** `catchUpFromPersisted`라도 같은 transcript가 아니면 현재 파일 크기부터 시작해 활성화~바인딩 사이에 이미 쓰인 출력은 건너뜁니다(`output-forwarder.mjs:117`, `output-forwarder.mjs:122`). backlog catch-up은 같은 persisted path이거나 `replayFromStart`인 경우에만 복구합니다.\n\n- **미생성 transcript `fs.watch` 실패:** missing file watch는 실패하지만(`output-forwarder.mjs:647`), pending re-arm이 생성 감지 후 watch와 `forwardNewText()`를 실행합니다(`index.mjs:357`, `index.mjs:376`, `index.mjs:486`). 60초 내 생성은 복구되고, timeout 후 추가 rebind가 없으면 지연/미복구입니다.\n\n- **ownership/pre-connect 창:** `_isOwner()`가 `bridgeRuntimeConnected && owned`라 pre-connect flush는 no-op입니다(`index.mjs:316`, `output-forwarder.mjs:351`). cursor를 전진시키지 않고 post-connect catch-up/re-arm이 다시 실행되어 보통 복구됩니다(`index.mjs:801`).\n\n- **watch 설치 race:** `setContext()` stat 이후 watch 설치 전 쓰인 bytes는 `startWatch()`가 즉시 flush를 예약해 복구합니다(`output-forwarder.mjs:665`, `output-forwarder.mjs:703`).\n\n판정: 가장 실제적인 유실 위험은 “초기 discovery miss 후 EOF 바인딩”이며, pending-file watch와 ownership 창은 제한적으로 catch-up됩니다.",
|
|
33
|
+
"card": {
|
|
34
|
+
"session": "sess_24484_1783061209581_1783061209828_780131e53fd6bc2b4d00e76277ef0eac",
|
|
35
|
+
"provider": "openai-oauth",
|
|
36
|
+
"model": "gpt-5.5",
|
|
37
|
+
"wall_ms": 101982,
|
|
38
|
+
"turns": 11,
|
|
39
|
+
"tool_calls": 10,
|
|
40
|
+
"tools_per_turn": 0.9,
|
|
41
|
+
"total_tool_ms": 989,
|
|
42
|
+
"llm_stream_ms": 100233,
|
|
43
|
+
"cache_ratio": 0.793172745612974,
|
|
44
|
+
"cached_tokens": 203264,
|
|
45
|
+
"prompt_tokens": 256267,
|
|
46
|
+
"uncached_tokens": 53003,
|
|
47
|
+
"output_tokens": 8121,
|
|
48
|
+
"cache_weighted_input_10": 73329.4,
|
|
49
|
+
"cache_weighted_input_25": 103819,
|
|
50
|
+
"prompt_growth": 35245,
|
|
51
|
+
"antipatterns": 1,
|
|
52
|
+
"issues": 16,
|
|
53
|
+
"issue_types": [
|
|
54
|
+
"cache",
|
|
55
|
+
"cache_break",
|
|
56
|
+
"cache_miss",
|
|
57
|
+
"readonly_stall",
|
|
58
|
+
"service_tier",
|
|
59
|
+
"missed_parallelism",
|
|
60
|
+
"tool_churn_cluster"
|
|
61
|
+
],
|
|
62
|
+
"read_fragmentation_paths": [],
|
|
63
|
+
"grep_sweep_count": 0
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"id": "r4-impl-usage-summary#1",
|
|
68
|
+
"agent": "worker",
|
|
69
|
+
"ok": true,
|
|
70
|
+
"ms": 89491,
|
|
71
|
+
"sessionId": "sess_50164_1783061209590_1783061209828_64514b47078973e8ff313ba80fddc6d6",
|
|
72
|
+
"output": "sessionId: sess_50164_1783061209590_1783061209828_64514b47078973e8ff313ba80fddc6d6\n요청 범위가 명확해서 바로 구현하고 검증하겠습니다.기능 파일과 스크립트 엔트리는 이미 작업 트리에 반영되어 있어, 관련 diff만 확인하겠습니다.검증은 통과했고, 최종 상태만 확인합니다.재영님, 완료했습니다: `usage:today` 스크립트와 `scripts/usage-today.mjs`가 추가되어 오늘 사용량을 모델별/총합으로 출력합니다.\n\n- **Diff 요약**: `package.json`에 `usage:today` 추가, 새 스크립트는 `MIXDOG_DATA_DIR`/기본 trace 경로를 읽고 local midnight 이후 `usage` 행을 집계합니다.\n- **검증**: `node --check scripts/usage-today.mjs` 통과, `npm run usage:today` 실행 완료.\n- **실행 결과**: GRAND TOTAL 기준 `1629` calls, input `60.99M`, cached `56.76M`, output `1.83M`, costUsd `101.8728`.\n- **참고**: 요청 범위 밖 기존 수정 파일 `src/runtime/channels/lib/*` 2개는 건드리지 않았습니다.",
|
|
73
|
+
"card": {
|
|
74
|
+
"session": "sess_50164_1783061209590_1783061209828_64514b47078973e8ff313ba80fddc6d6",
|
|
75
|
+
"provider": "openai-oauth",
|
|
76
|
+
"model": "gpt-5.5",
|
|
77
|
+
"wall_ms": 79004,
|
|
78
|
+
"turns": 11,
|
|
79
|
+
"tool_calls": 13,
|
|
80
|
+
"tools_per_turn": 1.2,
|
|
81
|
+
"total_tool_ms": 3127,
|
|
82
|
+
"llm_stream_ms": 75555,
|
|
83
|
+
"cache_ratio": 0.8285965759064194,
|
|
84
|
+
"cached_tokens": 145920,
|
|
85
|
+
"prompt_tokens": 176105,
|
|
86
|
+
"uncached_tokens": 30185,
|
|
87
|
+
"output_tokens": 6181,
|
|
88
|
+
"cache_weighted_input_10": 44777,
|
|
89
|
+
"cache_weighted_input_25": 66665,
|
|
90
|
+
"prompt_growth": 16826,
|
|
91
|
+
"antipatterns": 1,
|
|
92
|
+
"issues": 14,
|
|
93
|
+
"issue_types": [
|
|
94
|
+
"cache",
|
|
95
|
+
"cache_break",
|
|
96
|
+
"service_tier",
|
|
97
|
+
"missed_parallelism",
|
|
98
|
+
"tool_churn_cluster"
|
|
99
|
+
],
|
|
100
|
+
"read_fragmentation_paths": [],
|
|
101
|
+
"grep_sweep_count": 0
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "r4-explain-compact-engine#1",
|
|
106
|
+
"agent": "explore",
|
|
107
|
+
"ok": true,
|
|
108
|
+
"ms": 63576,
|
|
109
|
+
"sessionId": "sess_6636_1783061209603_1783061209840_309bbb037fe8492a38533175c6dec7e7",
|
|
110
|
+
"output": "sessionId: sess_6636_1783061209603_1783061209840_309bbb037fe8492a38533175c6dec7e7\nCompaction architecture brief:\n\n- Entry points: `semanticCompactMessages` and `recallFastTrackCompactMessages`; loop pre-send calls recall at `loop.mjs:416` or semantic at `loop.mjs:441`, while manual/clear paths call `runSessionCompaction` at `manager.mjs:1849` and `manager.mjs:1950`.\n\n- Fire decision: auto policy resolves boundary/trigger/reserve/type at `loop/compact-policy.mjs:89`; pre-send compacts when reactive retry is pending or pressure reaches trigger at `loop.mjs:351` and `loop/compact-policy.mjs:170`.\n\n- Manual decision: `runSessionCompaction` forces manual mode, skips small/unforced sessions, requires a boundary, and returns “below threshold” when pressure is under trigger at `manager/compaction-runner.mjs:143`.\n\n- Tail selection: semantic splits protected prefix/live/prior summary at `engine.mjs:100`, keeps recent user turns if any at `engine.mjs:240`, otherwise uses non-tool cut points to preserve assistant/tool-only tails at `engine.mjs:193`.\n\n- Recall tail: recall-fasttrack keeps the newest structured turns, drops oldest turns to fit cap, truncates only if needed, and permits no-user tails at `engine.mjs:593`.\n\n- Redaction: if the transcript already fits, no-op returns sanitized messages before redaction at `engine.mjs:286`; actual compaction redacts tool-call secret values before window selection/output at `engine.mjs:306` and `engine.mjs:644`, implemented shape-preserving in `text-utils.mjs:319`.\n\n- Failure/fallback: semantic throws on missing provider, empty live/no prior head, prompt/summary fit failures, empty provider summary, or final overflow at `engine.mjs:278`, `engine.mjs:315`, `engine.mjs:335`, `engine.mjs:371`, `engine.mjs:384`, and `engine.mjs:395`.\n\n- Degradation: loop fallback prunes old tool outputs only for non-recall failures at `loop.mjs:500`; manager recall-fasttrack can fall back to semantic at `compaction-runner.mjs:237`, then non-recall failures can use unanchored prune at `compaction-runner.mjs:322`, otherwise failure is recorded at `compaction-runner.mjs:348`.",
|
|
111
|
+
"card": {
|
|
112
|
+
"session": "sess_6636_1783061209603_1783061209840_309bbb037fe8492a38533175c6dec7e7",
|
|
113
|
+
"provider": "openai-oauth",
|
|
114
|
+
"model": "gpt-5.5",
|
|
115
|
+
"wall_ms": 53078,
|
|
116
|
+
"turns": 7,
|
|
117
|
+
"tool_calls": 7,
|
|
118
|
+
"tools_per_turn": 1,
|
|
119
|
+
"total_tool_ms": 549,
|
|
120
|
+
"llm_stream_ms": 51861,
|
|
121
|
+
"cache_ratio": 0.47149308599591866,
|
|
122
|
+
"cached_tokens": 64000,
|
|
123
|
+
"prompt_tokens": 135739,
|
|
124
|
+
"uncached_tokens": 71739,
|
|
125
|
+
"output_tokens": 2800,
|
|
126
|
+
"cache_weighted_input_10": 78139,
|
|
127
|
+
"cache_weighted_input_25": 87739,
|
|
128
|
+
"prompt_growth": 41335,
|
|
129
|
+
"antipatterns": 1,
|
|
130
|
+
"issues": 14,
|
|
131
|
+
"issue_types": [
|
|
132
|
+
"cache",
|
|
133
|
+
"cache_break",
|
|
134
|
+
"cache_miss",
|
|
135
|
+
"broad_tool_result",
|
|
136
|
+
"service_tier",
|
|
137
|
+
"missed_parallelism",
|
|
138
|
+
"tool_churn_cluster"
|
|
139
|
+
],
|
|
140
|
+
"read_fragmentation_paths": [],
|
|
141
|
+
"grep_sweep_count": 0
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"id": "r4-debug-forwarding-gap#2",
|
|
146
|
+
"agent": "reviewer",
|
|
147
|
+
"ok": true,
|
|
148
|
+
"ms": 115365,
|
|
149
|
+
"sessionId": "sess_12456_1783061273178_1783061273417_b75f3cff29775e56257b108f96388d21",
|
|
150
|
+
"output": "sessionId: sess_12456_1783061273178_1783061273417_b75f3cff29775e56257b108f96388d21\n조사 결과, 활성화 직후 출력은 일부 경로에서 지연 복구되지만, “기존 파일을 EOF로 바인딩”하거나 “잘못된 transcript에 붙는” 경우는 영구 유실될 수 있습니다.\n\n**경로 요약**\n- `activate_channel_bridge`/`start()`가 `channelBridgeActive=true`와 `bridge-state.json`을 먼저 기록합니다 (`src/runtime/channels/lib/tool-dispatch.mjs:46`, `src/runtime/channels/index.mjs:1735`).\n- 이후 ownership claim → `refreshBridgeOwnership()` → `startOwnedRuntime()` → `bindPersistedTranscriptIfAny()` → `rebindTranscriptContext()` → `applyTranscriptBinding()` → `OutputForwarder.startWatch()` → `forwardNewText()` 순서로 첫 전달이 열립니다 (`src/runtime/channels/index.mjs:710`, `src/runtime/channels/index.mjs:577`, `src/runtime/channels/index.mjs:394`, `src/runtime/channels/index.mjs:317`, `src/runtime/channels/lib/output-forwarder.mjs:647`).\n\n**영구 유실: 기존 transcript를 persisted cursor 없이 EOF로 바인딩**\n- `setContext()`는 `catchUpFromPersisted`라도 같은 persisted transcript가 아니면 `currentSize`로 커서를 둡니다 (`src/runtime/channels/lib/output-forwarder.mjs:117`). 활성화와 바인딩 사이에 이미 쓰인 assistant 출력은 이후 `forwardNewText()`가 읽지 않습니다.\n- **backlog catch-up:** 복구 안 됨. 같은 persisted path의 `lastFileSize`가 있거나 `replayFromStart`일 때만 복구됩니다.\n\n**영구 유실 가능: 활성화 직후 self transcript 발견 전 stale/wrong transcript에 바인딩**\n- 첫 inbound에서 기존 binding을 재사용하거나 500ms steal poll이 실패하면 stale path를 `exists:true`로 취급해 바인딩할 수 있습니다 (`src/runtime/channels/index.mjs:1506`, `src/runtime/channels/index.mjs:1571`, `src/runtime/channels/index.mjs:1597`).\n- **backlog catch-up:** 실제 self transcript가 나중에 “이미 존재” 상태로 재바인딩되면 EOF 바인딩이라 복구 안 됨. “pending/not-yet-created”로 잡힌 경우만 `replayFromStart`/rearm으로 복구됩니다 (`src/runtime/channels/index.mjs:486`).\n\n**지연 복구: transcript 파일이 아직 없어서 `fs.watch` 설치 실패**\n- `startWatch()`는 없는 파일에서 `watch()` 실패 후 watcher를 닫습니다 (`src/runtime/channels/lib/output-forwarder.mjs:657`, `src/runtime/channels/lib/output-forwarder.mjs:667`). 이를 `schedulePendingTranscriptRearm()`가 250ms 폴링으로 다시 설치하고 즉시 `forwardNewText()`를 호출합니다 (`src/runtime/channels/index.mjs:357`, `src/runtime/channels/index.mjs:376`).\n- **backlog catch-up:** 60초 안에 파일이 생기면 복구됨. 60초 timeout 이후 생성되면 복구 안 됨 (`src/runtime/channels/index.mjs:384`).\n\n**지연 복구: ownership/backend 연결 전 forwarder가 fail-closed**\n- owner probe는 `bridgeRuntimeConnected && currentOwnerState().owned`가 아니면 false이고, `forwardNewText()`는 읽기 전에 반환합니다 (`src/runtime/channels/index.mjs:316`, `src/runtime/channels/lib/output-forwarder.mjs:36`, `src/runtime/channels/lib/output-forwarder.mjs:351`).\n- **backlog catch-up:** 커서를 전진시키지 않으므로 보통 복구됨. 연결 후 `post-connect forwardNewText()` 또는 rearm이 다시 읽습니다 (`src/runtime/channels/index.mjs:776`, `src/runtime/channels/index.mjs:803`).\n\n**지연 복구: `setContext()` stat과 `fs.watch` 설치 사이의 write**\n- `startWatch()`가 watch 설치 직후 `scheduleWatchFlush()`를 호출해 그 사이 쓰인 bytes를 읽도록 되어 있습니다 (`src/runtime/channels/lib/output-forwarder.mjs:665`, `src/runtime/channels/lib/output-forwarder.mjs:703`).\n- **backlog catch-up:** 복구됨. 다만 이 flush가 owner false로 빠지면 post-connect forward가 맡습니다.\n\n평결: 활성화 창의 missing-file/ownership 지연은 대부분 catch-up되지만, 기존 transcript를 EOF로 잡는 바인딩과 wrong-transcript 바인딩은 첫 assistant 출력 영구 유실 위험이 남아 있습니다.",
|
|
151
|
+
"card": {
|
|
152
|
+
"session": "sess_12456_1783061273178_1783061273417_b75f3cff29775e56257b108f96388d21",
|
|
153
|
+
"provider": "openai-oauth",
|
|
154
|
+
"model": "gpt-5.5",
|
|
155
|
+
"wall_ms": 104870,
|
|
156
|
+
"turns": 10,
|
|
157
|
+
"tool_calls": 12,
|
|
158
|
+
"tools_per_turn": 1.2,
|
|
159
|
+
"total_tool_ms": 866,
|
|
160
|
+
"llm_stream_ms": 103586,
|
|
161
|
+
"cache_ratio": 0.8181367561503744,
|
|
162
|
+
"cached_tokens": 250880,
|
|
163
|
+
"prompt_tokens": 306648,
|
|
164
|
+
"uncached_tokens": 55768,
|
|
165
|
+
"output_tokens": 10163,
|
|
166
|
+
"cache_weighted_input_10": 80856,
|
|
167
|
+
"cache_weighted_input_25": 118488,
|
|
168
|
+
"prompt_growth": 44684,
|
|
169
|
+
"antipatterns": 1,
|
|
170
|
+
"issues": 15,
|
|
171
|
+
"issue_types": [
|
|
172
|
+
"cache",
|
|
173
|
+
"cache_break",
|
|
174
|
+
"readonly_stall",
|
|
175
|
+
"service_tier",
|
|
176
|
+
"missed_parallelism",
|
|
177
|
+
"tool_churn_cluster"
|
|
178
|
+
],
|
|
179
|
+
"read_fragmentation_paths": [],
|
|
180
|
+
"grep_sweep_count": 0
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"id": "r4-impl-usage-summary#2",
|
|
185
|
+
"agent": "worker",
|
|
186
|
+
"ok": true,
|
|
187
|
+
"ms": 68832,
|
|
188
|
+
"sessionId": "sess_34340_1783061299082_1783061299306_c1576ad2a7e9cafad2329f5c0bf5a041",
|
|
189
|
+
"output": "sessionId: sess_34340_1783061299082_1783061299306_c1576ad2a7e9cafad2329f5c0bf5a041\n작업 범위가 작고 실행 요청까지 포함되어 있어 바로 반영하고 검증하겠습니다.구현 파일과 npm script가 이미 작업트리에 있어 검증과 diff 확인을 진행합니다.완료했습니다. `usage:today` 스크립트와 `scripts/usage-today.mjs`가 작업트리에 반영되어 있습니다.\n\n- **Diff 요약**: `package.json`에 `\"usage:today\": \"node scripts/usage-today.mjs\"` 추가, 새 스크립트가 오늘 자정 이후 usage를 모델별/총합으로 집계합니다.\n- **검증**: `node --check scripts/usage-today.mjs` 통과, `npm run usage:today` 실행 성공.\n- **참고**: 기존 작업트리에 `src/runtime/channels/lib/event-queue.mjs`, `src/runtime/channels/lib/output-forwarder.mjs` 수정도 남아 있으며 이번 변경 범위와 별개입니다.",
|
|
190
|
+
"card": {
|
|
191
|
+
"session": "sess_34340_1783061299082_1783061299306_c1576ad2a7e9cafad2329f5c0bf5a041",
|
|
192
|
+
"provider": "openai-oauth",
|
|
193
|
+
"model": "gpt-5.5",
|
|
194
|
+
"wall_ms": 58353,
|
|
195
|
+
"turns": 9,
|
|
196
|
+
"tool_calls": 14,
|
|
197
|
+
"tools_per_turn": 1.6,
|
|
198
|
+
"total_tool_ms": 2016,
|
|
199
|
+
"llm_stream_ms": 55759,
|
|
200
|
+
"cache_ratio": 0.6363588621444202,
|
|
201
|
+
"cached_tokens": 72704,
|
|
202
|
+
"prompt_tokens": 114250,
|
|
203
|
+
"uncached_tokens": 41546,
|
|
204
|
+
"output_tokens": 3718,
|
|
205
|
+
"cache_weighted_input_10": 48816.4,
|
|
206
|
+
"cache_weighted_input_25": 59722,
|
|
207
|
+
"prompt_growth": 11717,
|
|
208
|
+
"antipatterns": 0,
|
|
209
|
+
"issues": 12,
|
|
210
|
+
"issue_types": [
|
|
211
|
+
"cache",
|
|
212
|
+
"cache_break",
|
|
213
|
+
"cache_miss",
|
|
214
|
+
"service_tier"
|
|
215
|
+
],
|
|
216
|
+
"read_fragmentation_paths": [],
|
|
217
|
+
"grep_sweep_count": 0
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"id": "r4-explain-compact-engine#2",
|
|
222
|
+
"agent": "explore",
|
|
223
|
+
"ok": true,
|
|
224
|
+
"ms": 98300,
|
|
225
|
+
"sessionId": "sess_40856_1783061322058_1783061322304_6da5edceb48f481a206a016ccc63c5fc",
|
|
226
|
+
"output": "sessionId: sess_40856_1783061322058_1783061322304_6da5edceb48f481a206a016ccc63c5fc\n- **Entry points**: `semanticCompactMessages` and `recallFastTrackCompactMessages` live in `engine.mjs` and are re-exported by `compact.mjs` for loop/manager callers (`engine.mjs:278`, `engine.mjs:445`, `compact.mjs:52-55`).\n\n- **Callers**: auto pre-send compaction runs inside `agentLoop`; manual/auto-clear uses `runSessionCompaction`; recall-fasttrack has a loop pipeline wrapper before calling the engine (`loop.mjs:329-365`, `manager.mjs:1849-1957`, `loop/recall-fasttrack.mjs:161-172`).\n\n- **Fire decision**: policy resolves `auto`, boundary, trigger, reserve, type, tail budget; trigger is explicit sub-boundary limit or `boundary - buffer`, with default buffer from shared context utils (`compact-policy.mjs:89-148`, `context-utils.mjs:221-227`).\n\n- **Auto threshold**: compaction fires when forced reactive, token estimate is unavailable, or `messageTokens + reserve >= trigger`; loop drains queued steering before checking (`compact-policy.mjs:170-175`, `loop.mjs:324-354`).\n\n- **Reactive path**: provider context-overflow sets `reactiveOverflowRetryPending`, loops back, and forces the next pre-send compact once; second failure surfaces overflow (`loop.mjs:981-1026`).\n\n- **Semantic flow**: sanitize/dedup first, no-op if already under budget and not forced, otherwise redact, select window, summarize head, then emit `system + summary + tail` (`engine.mjs:284-314`, `engine.mjs:367-397`).\n\n- **Tail selection**: protected system/reminder prefix is separated, old summaries are excluded from live history, and previous summary is captured for merge (`engine.mjs:100-111`, `messages.mjs:56-82`).\n\n- **User-tail path**: with real user turns, keep up to `tailTurns` recent turns within `preserveRecentBudget`, splitting the newest turn suffix if needed (`engine.mjs:134-185`, `engine.mjs:235-245`).\n\n- **No-user tail path**: without user turns, tail boundaries are any non-tool message so assistant/tool pairs stay valid; it grows newest-to-oldest until budget overflow (`engine.mjs:121-128`, `engine.mjs:193-232`).\n\n- **Recall tail**: recall-fasttrack preserves newest structured turns, drops whole oldest turns over cap, then truncates oldest surviving content; no-user recent structure is valid (`engine.mjs:593-619`, `engine.mjs:601-610`).\n\n- **Redaction hook**: compaction redacts sensitive tool-call args before window selection, so preserved system/tail are measured and emitted redacted; no-op fast path intentionally skips redaction (`engine.mjs:286-312`, `engine.mjs:389-392`, `engine.mjs:644-651`).\n\n- **Redaction mechanics**: sensitive keys/raw `key:value` secrets become `[redacted]`; verbatim redaction preserves object shape/order and only changes secret values (`text-utils.mjs:12-17`, `text-utils.mjs:46-80`, `text-utils.mjs:217-230`).\n\n- **Semantic failures**: provider missing, empty live/no compactable head, prompt fit failure, empty provider summary, summary fit failure, or final over-budget all throw (`engine.mjs:279-280`, `engine.mjs:254-256`, `engine.mjs:315-337`, `engine.mjs:371-397`).\n\n- **Budget fallback**: if mandatory `system + tail` plus summary room exceeds target, engine raises the working budget instead of refusing (`engine.mjs:319-331`, `constants.mjs:33-40`).\n\n- **Runtime fallback**: recall-fasttrack failure may fall back to semantic in manager; semantic/non-recall failure may fall back to non-LLM prune; unrecovered failures record `*_failed` telemetry (`compaction-runner.mjs:231-279`, `compaction-runner.mjs:327-374`, `loop.mjs:500-627`).",
|
|
227
|
+
"card": {
|
|
228
|
+
"session": "sess_40856_1783061322058_1783061322304_6da5edceb48f481a206a016ccc63c5fc",
|
|
229
|
+
"provider": "openai-oauth",
|
|
230
|
+
"model": "gpt-5.5",
|
|
231
|
+
"wall_ms": 87800,
|
|
232
|
+
"turns": 10,
|
|
233
|
+
"tool_calls": 13,
|
|
234
|
+
"tools_per_turn": 1.3,
|
|
235
|
+
"total_tool_ms": 816,
|
|
236
|
+
"llm_stream_ms": 86336,
|
|
237
|
+
"cache_ratio": 0.6981522354599766,
|
|
238
|
+
"cached_tokens": 181248,
|
|
239
|
+
"prompt_tokens": 259611,
|
|
240
|
+
"uncached_tokens": 78363,
|
|
241
|
+
"output_tokens": 4217,
|
|
242
|
+
"cache_weighted_input_10": 96487.8,
|
|
243
|
+
"cache_weighted_input_25": 123675,
|
|
244
|
+
"prompt_growth": 60577,
|
|
245
|
+
"antipatterns": 1,
|
|
246
|
+
"issues": 18,
|
|
247
|
+
"issue_types": [
|
|
248
|
+
"cache",
|
|
249
|
+
"cache_break",
|
|
250
|
+
"cache_miss",
|
|
251
|
+
"readonly_stall",
|
|
252
|
+
"broad_tool_result",
|
|
253
|
+
"service_tier",
|
|
254
|
+
"missed_parallelism",
|
|
255
|
+
"tool_churn_cluster"
|
|
256
|
+
],
|
|
257
|
+
"read_fragmentation_paths": [],
|
|
258
|
+
"grep_sweep_count": 0
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
],
|
|
262
|
+
"task_complete": true,
|
|
263
|
+
"task_errors": [],
|
|
264
|
+
"score_complete": true,
|
|
265
|
+
"score_errors": [],
|
|
266
|
+
"group": {
|
|
267
|
+
"n": 6,
|
|
268
|
+
"wall_ms": 80847.8,
|
|
269
|
+
"turns": 9.7,
|
|
270
|
+
"tool_calls": 11.5,
|
|
271
|
+
"tools_per_turn": 1.2,
|
|
272
|
+
"total_tool_ms": 1393.8,
|
|
273
|
+
"llm_stream_ms": 78888.3,
|
|
274
|
+
"cache_ratio": 0.7,
|
|
275
|
+
"cached_tokens": 153002.7,
|
|
276
|
+
"prompt_tokens": 208103.3,
|
|
277
|
+
"uncached_tokens": 55100.7,
|
|
278
|
+
"output_tokens": 5866.7,
|
|
279
|
+
"cache_weighted_input_10": 70400.9,
|
|
280
|
+
"cache_weighted_input_25": 93351.3,
|
|
281
|
+
"prompt_growth": 35064,
|
|
282
|
+
"antipatterns": 0.8,
|
|
283
|
+
"issues": 14.8,
|
|
284
|
+
"grep_sweep_count": 0
|
|
285
|
+
},
|
|
286
|
+
"cards": [
|
|
287
|
+
{
|
|
288
|
+
"session": "sess_24484_1783061209581_1783061209828_780131e53fd6bc2b4d00e76277ef0eac",
|
|
289
|
+
"provider": "openai-oauth",
|
|
290
|
+
"model": "gpt-5.5",
|
|
291
|
+
"wall_ms": 101982,
|
|
292
|
+
"turns": 11,
|
|
293
|
+
"tool_calls": 10,
|
|
294
|
+
"tools_per_turn": 0.9,
|
|
295
|
+
"total_tool_ms": 989,
|
|
296
|
+
"llm_stream_ms": 100233,
|
|
297
|
+
"cache_ratio": 0.793172745612974,
|
|
298
|
+
"cached_tokens": 203264,
|
|
299
|
+
"prompt_tokens": 256267,
|
|
300
|
+
"uncached_tokens": 53003,
|
|
301
|
+
"output_tokens": 8121,
|
|
302
|
+
"cache_weighted_input_10": 73329.4,
|
|
303
|
+
"cache_weighted_input_25": 103819,
|
|
304
|
+
"prompt_growth": 35245,
|
|
305
|
+
"antipatterns": 1,
|
|
306
|
+
"issues": 16,
|
|
307
|
+
"issue_types": [
|
|
308
|
+
"cache",
|
|
309
|
+
"cache_break",
|
|
310
|
+
"cache_miss",
|
|
311
|
+
"readonly_stall",
|
|
312
|
+
"service_tier",
|
|
313
|
+
"missed_parallelism",
|
|
314
|
+
"tool_churn_cluster"
|
|
315
|
+
],
|
|
316
|
+
"read_fragmentation_paths": [],
|
|
317
|
+
"grep_sweep_count": 0
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
"session": "sess_50164_1783061209590_1783061209828_64514b47078973e8ff313ba80fddc6d6",
|
|
321
|
+
"provider": "openai-oauth",
|
|
322
|
+
"model": "gpt-5.5",
|
|
323
|
+
"wall_ms": 79004,
|
|
324
|
+
"turns": 11,
|
|
325
|
+
"tool_calls": 13,
|
|
326
|
+
"tools_per_turn": 1.2,
|
|
327
|
+
"total_tool_ms": 3127,
|
|
328
|
+
"llm_stream_ms": 75555,
|
|
329
|
+
"cache_ratio": 0.8285965759064194,
|
|
330
|
+
"cached_tokens": 145920,
|
|
331
|
+
"prompt_tokens": 176105,
|
|
332
|
+
"uncached_tokens": 30185,
|
|
333
|
+
"output_tokens": 6181,
|
|
334
|
+
"cache_weighted_input_10": 44777,
|
|
335
|
+
"cache_weighted_input_25": 66665,
|
|
336
|
+
"prompt_growth": 16826,
|
|
337
|
+
"antipatterns": 1,
|
|
338
|
+
"issues": 14,
|
|
339
|
+
"issue_types": [
|
|
340
|
+
"cache",
|
|
341
|
+
"cache_break",
|
|
342
|
+
"service_tier",
|
|
343
|
+
"missed_parallelism",
|
|
344
|
+
"tool_churn_cluster"
|
|
345
|
+
],
|
|
346
|
+
"read_fragmentation_paths": [],
|
|
347
|
+
"grep_sweep_count": 0
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
"session": "sess_6636_1783061209603_1783061209840_309bbb037fe8492a38533175c6dec7e7",
|
|
351
|
+
"provider": "openai-oauth",
|
|
352
|
+
"model": "gpt-5.5",
|
|
353
|
+
"wall_ms": 53078,
|
|
354
|
+
"turns": 7,
|
|
355
|
+
"tool_calls": 7,
|
|
356
|
+
"tools_per_turn": 1,
|
|
357
|
+
"total_tool_ms": 549,
|
|
358
|
+
"llm_stream_ms": 51861,
|
|
359
|
+
"cache_ratio": 0.47149308599591866,
|
|
360
|
+
"cached_tokens": 64000,
|
|
361
|
+
"prompt_tokens": 135739,
|
|
362
|
+
"uncached_tokens": 71739,
|
|
363
|
+
"output_tokens": 2800,
|
|
364
|
+
"cache_weighted_input_10": 78139,
|
|
365
|
+
"cache_weighted_input_25": 87739,
|
|
366
|
+
"prompt_growth": 41335,
|
|
367
|
+
"antipatterns": 1,
|
|
368
|
+
"issues": 14,
|
|
369
|
+
"issue_types": [
|
|
370
|
+
"cache",
|
|
371
|
+
"cache_break",
|
|
372
|
+
"cache_miss",
|
|
373
|
+
"broad_tool_result",
|
|
374
|
+
"service_tier",
|
|
375
|
+
"missed_parallelism",
|
|
376
|
+
"tool_churn_cluster"
|
|
377
|
+
],
|
|
378
|
+
"read_fragmentation_paths": [],
|
|
379
|
+
"grep_sweep_count": 0
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
"session": "sess_12456_1783061273178_1783061273417_b75f3cff29775e56257b108f96388d21",
|
|
383
|
+
"provider": "openai-oauth",
|
|
384
|
+
"model": "gpt-5.5",
|
|
385
|
+
"wall_ms": 104870,
|
|
386
|
+
"turns": 10,
|
|
387
|
+
"tool_calls": 12,
|
|
388
|
+
"tools_per_turn": 1.2,
|
|
389
|
+
"total_tool_ms": 866,
|
|
390
|
+
"llm_stream_ms": 103586,
|
|
391
|
+
"cache_ratio": 0.8181367561503744,
|
|
392
|
+
"cached_tokens": 250880,
|
|
393
|
+
"prompt_tokens": 306648,
|
|
394
|
+
"uncached_tokens": 55768,
|
|
395
|
+
"output_tokens": 10163,
|
|
396
|
+
"cache_weighted_input_10": 80856,
|
|
397
|
+
"cache_weighted_input_25": 118488,
|
|
398
|
+
"prompt_growth": 44684,
|
|
399
|
+
"antipatterns": 1,
|
|
400
|
+
"issues": 15,
|
|
401
|
+
"issue_types": [
|
|
402
|
+
"cache",
|
|
403
|
+
"cache_break",
|
|
404
|
+
"readonly_stall",
|
|
405
|
+
"service_tier",
|
|
406
|
+
"missed_parallelism",
|
|
407
|
+
"tool_churn_cluster"
|
|
408
|
+
],
|
|
409
|
+
"read_fragmentation_paths": [],
|
|
410
|
+
"grep_sweep_count": 0
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
"session": "sess_34340_1783061299082_1783061299306_c1576ad2a7e9cafad2329f5c0bf5a041",
|
|
414
|
+
"provider": "openai-oauth",
|
|
415
|
+
"model": "gpt-5.5",
|
|
416
|
+
"wall_ms": 58353,
|
|
417
|
+
"turns": 9,
|
|
418
|
+
"tool_calls": 14,
|
|
419
|
+
"tools_per_turn": 1.6,
|
|
420
|
+
"total_tool_ms": 2016,
|
|
421
|
+
"llm_stream_ms": 55759,
|
|
422
|
+
"cache_ratio": 0.6363588621444202,
|
|
423
|
+
"cached_tokens": 72704,
|
|
424
|
+
"prompt_tokens": 114250,
|
|
425
|
+
"uncached_tokens": 41546,
|
|
426
|
+
"output_tokens": 3718,
|
|
427
|
+
"cache_weighted_input_10": 48816.4,
|
|
428
|
+
"cache_weighted_input_25": 59722,
|
|
429
|
+
"prompt_growth": 11717,
|
|
430
|
+
"antipatterns": 0,
|
|
431
|
+
"issues": 12,
|
|
432
|
+
"issue_types": [
|
|
433
|
+
"cache",
|
|
434
|
+
"cache_break",
|
|
435
|
+
"cache_miss",
|
|
436
|
+
"service_tier"
|
|
437
|
+
],
|
|
438
|
+
"read_fragmentation_paths": [],
|
|
439
|
+
"grep_sweep_count": 0
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
"session": "sess_40856_1783061322058_1783061322304_6da5edceb48f481a206a016ccc63c5fc",
|
|
443
|
+
"provider": "openai-oauth",
|
|
444
|
+
"model": "gpt-5.5",
|
|
445
|
+
"wall_ms": 87800,
|
|
446
|
+
"turns": 10,
|
|
447
|
+
"tool_calls": 13,
|
|
448
|
+
"tools_per_turn": 1.3,
|
|
449
|
+
"total_tool_ms": 816,
|
|
450
|
+
"llm_stream_ms": 86336,
|
|
451
|
+
"cache_ratio": 0.6981522354599766,
|
|
452
|
+
"cached_tokens": 181248,
|
|
453
|
+
"prompt_tokens": 259611,
|
|
454
|
+
"uncached_tokens": 78363,
|
|
455
|
+
"output_tokens": 4217,
|
|
456
|
+
"cache_weighted_input_10": 96487.8,
|
|
457
|
+
"cache_weighted_input_25": 123675,
|
|
458
|
+
"prompt_growth": 60577,
|
|
459
|
+
"antipatterns": 1,
|
|
460
|
+
"issues": 18,
|
|
461
|
+
"issue_types": [
|
|
462
|
+
"cache",
|
|
463
|
+
"cache_break",
|
|
464
|
+
"cache_miss",
|
|
465
|
+
"readonly_stall",
|
|
466
|
+
"broad_tool_result",
|
|
467
|
+
"service_tier",
|
|
468
|
+
"missed_parallelism",
|
|
469
|
+
"tool_churn_cluster"
|
|
470
|
+
],
|
|
471
|
+
"read_fragmentation_paths": [],
|
|
472
|
+
"grep_sweep_count": 0
|
|
473
|
+
}
|
|
474
|
+
]
|
|
475
|
+
}
|