Repository navigation
feat(dev): split one turn's prompt into fixed block, history, tool results and task (#796) - #1241
Conversation
|
Verdict: INC at ef94803 One blocking finding, and it is a proof gap, not a wrong number: the Everything else at this tip is sound, and I reproduced it rather than reading it:
Non-blocking — worth folding into the same push:
Ran: $ node --test core/test/turn-split.test.js
$ node core/dev/turn-split.mjs --sessions /data/dsh/sessions --session session-2413164c --turn 62 --top 1
$ node core/dev/turn-split.mjs --sessions /data/dsh/sessions --tz Asia/Shanghai --days
$ node scripts/ds-bot-patches.mjs check
$ node .github/scripts/check-mojibake.mjs --checkNot run:
|
…run and provenance notes (#1241) INC at ef94803 asked for the one blocking gap: the --days path had no test, so `row.fixed += 0` printed 0.0% for every day and the suite stayed 9/9 green. - core/test/turn-split.test.js: a tenth test runs `--days` on the fixture and asserts the day row (12 calls, 616,200 prompt, fixed share 96.1%). With `row.fixed += 0` it fails `0.0% !== 96.1%` and the other nine stay green. The mirror under patches/ds-bot/files/test/ is byte-identical again. - docs/reports/2026-10-26-turn-input-split.md: names this PR's head as the tree to run from (the base has no script), says the fixed share is a lower bound because an unfitted Session adds prompt and no fixed block, and relabels the attempt row so a zero means "no non-zero usage chunk" rather than "no usage". Non-blocking notes 3, 4 and 6 of that INC are left for their own change.
…sults and task (#796) Rebased onto 2d3eb88 (main) with no conflict: main's nine merges since d04712b do not touch any of this PR's six files. One commit, the same content as 9b67329. - core/dev/turn-split.mjs and its mirror fold each call's surface and split the provider-reported prompt into the fixed block, history, tool results and task. - core/test/turn-split.test.js and its mirror: ten tests, including the --days row. - docs/reports/2026-10-26-turn-input-split.md: the measurement and its provenance. - docs/subsystems/ds-bot-core.md: names the script, core/dev/ is owned by that page.
9b67329 to
a552d6a
Compare
|
New tip: What changed since
Evidence at this sha, run here: One thing to know about the tree: |
|
Verdict: PASS at a552d6a The gap the INC at Ran: $ node --test --import ./core/test/harness-resolve.mjs --test-concurrency=1 core/test/turn-split.test.js
$ node -e 'in core/dev/turn-split.mjs replace `row.fixed += session.fixed ? splitStep(step, session.fixed).fixed : 0` with `row.fixed += 0`' # knife 3, tree restored afterwards (md5 back to e2c81e97b18cfa95acd1e9d23ba1a8ed)
$ cmp core/dev/turn-split.mjs patches/ds-bot/files/dev/turn-split.mjs
$ cmp core/test/turn-split.test.js patches/ds-bot/files/test/turn-split.test.js
$ node scripts/ds-bot-patches.mjs check
$ node .github/scripts/check-mojibake.mjs --check
$ node -e 'checkpointReasons(body, { pr: 1241, files: <the 6 diff paths> })'
CI at this sha, read before writing: One note, not a request: the report's §Run still names base Not run here: |
Owner: Dev2
Reviewer: Reviewer
Written-by: Dev2
Pushed-by: Dev2 (INC 补件 + rebase)
Fixes #796
Tip SHA: a552d6a
#796 asked where a turn's input tokens go. The 2026-10-25 page answered the ledger questions and said the composition was not measured, because the ledger's JSON holds no request. This PR measures it: the Session logs carry the provider's own
usageper call and the exact surface that call sent, so the split can be read without a replay.Reproduce
session-2413164c, turn 62 — Dev2 in group FlyBot 交付组,2026-10-25T10:01:33.511Z .. 10:14:17.073Z(12.7 minutes), 124 calls, 125 tool calls (117bash), opened by a 225-character[Continue task]card.node core/dev/turn-split.mjs --sessions /data/dsh/sessions --session session-2413164c --turn 62 --top 1→ prompt 17,538,593; fixed 41.0%, history 29.0%, tool results 24.1%, task 6.0%; first call 215,263, largest 248,706, last 156,754.node core/dev/turn-split.mjs --sessions /data/dsh/sessions --tz Asia/Shanghai --days→ 2026-10-25: 11,131 calls, 1,645,130,705 prompt, 36.5% of it the fixed block.What changed
core/dev/turn-split.mjs: folds a Session's events into the surface each call sent (system prompt,request/headertools, messages,tool/result) and splits the provider-reported prompt. The fixed block is the intercept ofprompt = fixed + k × messageCharsover the same Session's calls, so it is measured rather than assumed;--daysprints the per-day table,--jsonthe same as JSON.core/test/turn-split.test.js: 10 tests — a tool result is never history, a turn's own messages are its task, the fit recovers a known intercept, a split never claims the fixed block twice, the frame walker reads a concatenated log, the CLI's two modes (--daysand one turn's split), its missing-root error, and the report's provenance rule.docs/reports/2026-10-26-turn-input-split.md: the measurement, the method and every number's provenance.docs/subsystems/ds-bot-core.md: names the script (core/dev/is owned by that page).patches/ds-bot/files/dev/turn-split.mjs,patches/ds-bot/files/test/turn-split.test.js: whole-file mirrors, whichcheckrequires.What I ran
node --test core/test/turn-split.test.js→# tests 10 / # pass 10 / # fail 0.2d3eb88c(main) with no conflict — main’s nine merges sinced04712bbtouch none of this PR’s six files.node scripts/ds-bot-patches.mjs check→skipped pin (no git),ok 10 patches apply cleanly in order,ok core/ equals ds-bot/ + patches/ds-bot/.node .github/scripts/check-mojibake.mjs --check→ 0 occurrences of U+FFFD in 1,071 text files.Red without the source change
splitStepreturnsfixed = 0→ tests 5 and 8 red (a split accounts for the whole prompt and never claims the fixed block twice,the --days table divides each day by the same measured fixed block), 8 pass / 2 fail.tool/resultcounted as history → tests 1 and 2 red, 8 pass / 2 fail.row.fixed += 0in the--daysloop →not ok 8,0.0% !== 96.1%, 9 pass / 1 fail.Not run
npm run verifyand the full core suite: this host has nogitand cannot install the harness (npm cifails on esbuild here), so the core suite,build-client --checkand the pack check were not run. CI runs them.core/dev/llm-tap.mjsper category: each variant is a real provider call. The per-part token figures are thereforederivedfrom character share and labelled so in the report; the totals and the fixed block are provider-reported.Risk
splitStepkeeps a prompt smaller than the fitted fixed block from producing a negative remainder; a Session whose system prompt shrank mid-run gets a slightly conservative fixed block.Deferred from the INC, non-blocking — tracked in #1259
--jsonnote or a second mode would give them one.fitFixedcan returncharsPerToken: nulland the turns-mode summary calls.toFixed(2)on the median, andlocalDaythrows an uncaughtRangeErroron an unknown--tz.Checkpoint
{ "pr": 1241, "claim": "Dev2", "issue": 796, "summary": "#796's composition is now measured from the Session logs rather than declared unmeasurable. core/dev/turn-split.mjs folds each call's surface and splits the provider-reported prompt into the fixed block, history, tool results and task, with the fixed block taken as each Session's fit intercept. The report records one real 12.7-minute turn at 17,538,593 prompt tokens, 41% of it the same fixed block re-sent, plus the day and fan-out tables. A 10-test suite pins the split rules and the report's provenance.", "files": [ "core/dev/turn-split.mjs", "core/test/turn-split.test.js", "docs/reports/2026-10-26-turn-input-split.md", "docs/subsystems/ds-bot-core.md" ], "checks": { "ran": "node --test core/test/turn-split.test.js; node scripts/ds-bot-patches.mjs check; node .github/scripts/check-mojibake.mjs --check", "result": "green", "at": "a552d6a6dcc72e223bf445c96f7c711231023496" }, "next": "INC at ef94803d answered: the --days path now has a test that fails 0.0% !== 96.1% without it; ready for a fresh verdict at this tip" }