Repository navigation
perf(stop): cost-tracker builds the subagent type map in two jq calls (#379) - #384
Merged
Merged
Conversation
… (GH #379) build_type_map forked jq 2-3 times and basename once per subagent file. One jq now reads every meta (--rawfile each) and prints each agentType; a file whose meta is missing, unreadable or any other shape takes the old per-file path, so every type is the one that path gives. A second jq builds the map from named args. scan_transcript's id loop drops basename for parameter expansion. Whole hook, 20 runs, medians (bash 3.2 / bash 5): 6 subagents 202 -> 144 / 219 -> 158 ms; 37: 890 -> 485 / 846 -> 479 ms; 193: 5992 -> 3692 / 5931 -> 3700 ms. Byte-identical costs.jsonl, marker, stdout, stderr and rc against the develop copy on 316 real sessions (1,531 rows) plus 8 hand-made fixture sessions (61 rows), under both shells. Test phase 5 pins five subagent types (meta, a --help type, toolUseId via the parent, no meta) and their return windows; 8 mutants killed.
This was referenced Oct 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #379 (item 2 of 3: cost-tracker subagent type map).
What
build_type_mapforked jq 2-3 times andbasenameonce per subagent file. It now runs two jq calls in all:agent-<id>.meta.json(--rawfileeach) and prints one line per file: itsagentTypewhen that is a non-empty one-line string, else"";--arg f<i>/i<i>/t<i>, never positional, so a type or idthat starts with
-stays a value).A
""line (no meta, a directory, an unreadable file, a non-string or multi-lineagentType, bad JSON)takes the old per-file code unchanged, so every type is the one that code gives.
scan_transcript's id loop uses parameter expansion instead ofbasename.Proof
Equivalence. The develop copy of the script was frozen and both copies ran on the same inputs. Each run
had a throwaway
HOME, settle 0, and adateshim. Every run comparedcosts.jsonl, the marker file,stdout, stderr and the exit code byte for byte. The one normalization: bash's own
<script path>: line N:prefix on stderr, because the two copies live at different paths.
All 4,003 local metas carry a plain string
agentType, so real data never takes the fallback. Thehand-made sessions cover it: a missing meta, a directory, chmod 000, an
agentTypethat isnull/false/""/number/object/array/NUL/newline/trailing newline/U+2028/invalid UTF-8/BOM, concatenated and
truncated JSON,
toolUseIdwith and without a parent hit,--helpas a type, names with a space and aquote, a non-
agent-file, bothjq_failedsentinel paths, and codex calls in main and subagent files.A positive control (the
agent-strip removed) shows DIFF on 8 of 12 real sessions and 1 fixture session.Tests. Phase 5 of
test-cost-tracker.shadds five subagents under one transcript: two plain types,--help, a meta that holds onlytoolUseId(resolved through the parent's Agent call), and no meta. Italso adds two return windows. It asserts the exact
(agent_type, input, returns, verify_tokens)persubagent row. It passes on the develop copy and on the new code under bash 3.2 and 5. It kills all 8
mutants: types index off by one, f/t keys swapped,
agent-prefix kept, fast path empty with nofallback, rawfile index counting only present metas, ids passed positionally, and two in the scan loop
(
.jsonlkept, directory kept).Timing. Whole hook, 20 interleaved runs, settle 0, medians (p90 of runs):
The hook is async, so this is CPU per Stop, not wait time.
Notes
$ARGS.namedholding--rawfilevalues was checked on jq 1.8.2 (local) and runs in CI on therunner's jq. On a jq where it is missing, the fast path prints
""and every file takes the per-filepath: slower, same output.
ponytail:comment in the code): the map call takes about 400 bytes of args per file, somacOS ARG_MAX is near 2,000 subagents.
raw_records'--argjson typemapalready has the same ceiling.subagent files prints
sub_files[@]: unbound variable(inside$(...), rows unaffected). Also,scan_transcriptpasses ids to jq positionally, so anagent--x.jsonlfile fails the wholeorchestrator scan (
jq: Unknown option). Worth separate issues.