Skip to content

refactor: decompose runSession in token-benchmark.ts#2040

Open
carlos-alm wants to merge 1 commit into
fix/issue-1904-benchmark-hub-selection-queries-pick-nonfrom
fix/issue-1906-scripts-token-benchmark-ts-runsession-exceeds
Open

refactor: decompose runSession in token-benchmark.ts#2040
carlos-alm wants to merge 1 commit into
fix/issue-1904-benchmark-hub-selection-queries-pick-nonfrom
fix/issue-1906-scripts-token-benchmark-ts-runsession-exceeds

Conversation

@carlos-alm

Copy link
Copy Markdown
Contributor

Summary

Pure decomposition (no behavior change) of runSession, which exceeded cognitive/cyclomatic/maxNesting thresholds:

Function cognitive cyclomatic maxNesting
runSession (before) 27 25 4
runSession (after) 2 3 0

Following the issue's suggested seams and the existing scripts/lib/ convention (bench-timing.ts, hub-selection.ts), the extracted pieces went into a new scripts/lib/session-metrics.ts:

  • buildSessionOptions — mode-dependent systemPrompt/mcpServers option building (kept local to token-benchmark.ts, since it closes over script-level CLI-flag constants)
  • extractUsageMetrics + firstTruthy — the SDK-result usage/turn field-fallback logic (snake_case vs. camelCase), which was the single biggest contributor via five a || b || 0 chains
  • collectToolUseBlocks + tallyToolCalls — the nested for (msg) { for (block) { if (tool_use) ... } } scan, split into a flat collection pass + a flat tally pass (both using early continues to drop nesting)

Moving the pure helpers into scripts/lib/ (rather than keeping them as unexported functions in the script) makes them unit-testable in isolation — token-benchmark.ts itself can't be imported for testing since it runs main() unconditionally at module load.

Closes #1906

Test plan

  • New tests/unit/session-metrics.test.ts (13 tests) covering firstTruthy, extractUsageMetrics, collectToolUseBlocks, tallyToolCalls — including firstTruthy's ||-chain (not ??) falsy-0 semantics, which the refactor must preserve exactly
  • npx vitest run tests/unit/session-metrics.test.ts tests/unit/hub-selection.test.ts — 18/18 pass
  • npm test (excluding the unrelated 34-language resolution-benchmark.test.ts, which takes 10+ minutes and has zero relation to this script) — 3133 passed, 305 skipped, 6 pre-existing failures unrelated to this change (missing @optave/codegraph-darwin-arm64 native binary in this worktree's node_modules — a known local-dev-environment gap, not caused by this diff)
  • npm run lint — clean on all touched files (scripts/ confirmed outside Biome's scope; tests/unit/session-metrics.test.ts is in scope and clean)
  • node --experimental-strip-types --check on both changed scripts/ files — syntax OK
  • codegraph diff-impact --staged -T confirms the 21 changed/added functions have zero transitive callers outside these two files
  • git diff confirms the moved logic is behavior-identical (same field-fallback order, same iteration order, same return shapes)

Stacked on #1904 (base branch fix/issue-1904-benchmark-hub-selection-queries-pick-non) — only the token-benchmark.ts/session-metrics.ts diff is this issue's change.

runSession exceeded codegraph's cognitive/cyclomatic/maxNesting
thresholds (27/25/4). Extracts the pure, non-orchestration pieces into
scripts/lib/session-metrics.ts, matching the existing scripts/lib/
convention: buildSessionOptions (mode-dependent options), the usage/turn
field-fallback logic (extractUsageMetrics + firstTruthy), and the
tool_use-block scan (collectToolUseBlocks + tallyToolCalls). Pure
behavior-preserving decomposition, same pattern as #1775's
runBuildBenchmarks/runQueryBenchmarks extraction.

runSession is now 2/3/0. Adds tests/unit/session-metrics.test.ts
covering the extracted helpers, including firstTruthy's `||`-chain
(not `??`) falsy-0 semantics.
@greptile-apps

greptile-apps Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Pure decomposition of runSession in token-benchmark.ts into focused helpers, with no behavior change. The extracted logic (extractUsageMetrics, collectToolUseBlocks, tallyToolCalls) moves into a new scripts/lib/session-metrics.ts so it is unit-testable without mocking the Agent SDK.

  • buildSessionOptions is kept local to token-benchmark.ts since it closes over CLI-flag-level constants (MODEL, MAX_TURNS, etc.).
  • extractUsageMetrics preserves the original ||-chain falsy semantics (not ??) via firstTruthy, which the new test suite explicitly pins.
  • 13 new unit tests cover all four extracted functions including the snake_case vs. camelCase field-fallback edge cases.

Confidence Score: 5/5

Safe to merge; the change is a pure decomposition of an existing function with no observable behavior differences.

Every extracted helper is a direct translation of the original inline code, the critical ||-chain falsy semantics are explicitly pinned by the new unit tests, and the buildSessionOptions split retains the same module-level constant closure. No logic was altered, no new side effects were introduced, and the 13-test suite passes end-to-end.

No files require special attention.

Important Files Changed

Filename Overview
scripts/lib/session-metrics.ts New library file with four pure, well-documented helpers extracted from runSession; logic is faithful to the original and fully covered by the new test suite.
scripts/token-benchmark.ts runSession slimmed to option-building + SDK call + result spreading; buildSessionOptions correctly retains closure over module-level constants; all original logic preserved.
tests/unit/session-metrics.test.ts 13 tests covering all four exported functions, including the critical

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    RS["runSession(mode, issue, nextjsDir)"]
    BSO["buildSessionOptions(mode, nextjsDir)"]
    SDK["query({ prompt, options })"]
    EUM["extractUsageMetrics(result)"]
    TTC["tallyToolCalls(messages)"]
    CTUB["collectToolUseBlocks(messages)"]
    FT["firstTruthy(...values)"]
    RET["return { ...usage, durationMs, toolCalls, uniqueFilesRead, filesIdentified, … }"]

    RS --> BSO
    BSO -->|"closes over MODEL, MAX_TURNS, MAX_BUDGET, *_PROMPT, root"| RS
    RS --> SDK
    SDK --> EUM
    EUM --> FT
    SDK --> TTC
    TTC --> CTUB
    EUM --> RET
    TTC --> RET
    RS --> RET

    subgraph "scripts/lib/session-metrics.ts"
        EUM
        TTC
        CTUB
        FT
    end

    subgraph "scripts/token-benchmark.ts"
        RS
        BSO
        SDK
        RET
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    RS["runSession(mode, issue, nextjsDir)"]
    BSO["buildSessionOptions(mode, nextjsDir)"]
    SDK["query({ prompt, options })"]
    EUM["extractUsageMetrics(result)"]
    TTC["tallyToolCalls(messages)"]
    CTUB["collectToolUseBlocks(messages)"]
    FT["firstTruthy(...values)"]
    RET["return { ...usage, durationMs, toolCalls, uniqueFilesRead, filesIdentified, … }"]

    RS --> BSO
    BSO -->|"closes over MODEL, MAX_TURNS, MAX_BUDGET, *_PROMPT, root"| RS
    RS --> SDK
    SDK --> EUM
    EUM --> FT
    SDK --> TTC
    TTC --> CTUB
    EUM --> RET
    TTC --> RET
    RS --> RET

    subgraph "scripts/lib/session-metrics.ts"
        EUM
        TTC
        CTUB
        FT
    end

    subgraph "scripts/token-benchmark.ts"
        RS
        BSO
        SDK
        RET
    end
Loading

Reviews (1): Last reviewed commit: "refactor(scripts): decompose runSession ..." | Re-trigger Greptile

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Codegraph Impact Analysis

21 functions changed6 callers affected across 2 files

  • firstTruthy in scripts/lib/session-metrics.ts:17 (3 transitive callers)
  • UsageMetrics.inputTokens in scripts/lib/session-metrics.ts:25 (0 transitive callers)
  • UsageMetrics.outputTokens in scripts/lib/session-metrics.ts:26 (0 transitive callers)
  • UsageMetrics.cacheReadInputTokens in scripts/lib/session-metrics.ts:27 (0 transitive callers)
  • UsageMetrics.totalCostUsd in scripts/lib/session-metrics.ts:28 (0 transitive callers)
  • UsageMetrics.numTurns in scripts/lib/session-metrics.ts:29 (0 transitive callers)
  • SessionResult.usage in scripts/lib/session-metrics.ts:33 (0 transitive callers)
  • SessionResult.num_turns in scripts/lib/session-metrics.ts:34 (0 transitive callers)
  • SessionResult.numTurns in scripts/lib/session-metrics.ts:35 (0 transitive callers)
  • extractUsageMetrics in scripts/lib/session-metrics.ts:42 (3 transitive callers)
  • ToolUseBlock.type in scripts/lib/session-metrics.ts:59 (0 transitive callers)
  • ToolUseBlock.name in scripts/lib/session-metrics.ts:60 (0 transitive callers)
  • ToolUseBlock.input in scripts/lib/session-metrics.ts:61 (0 transitive callers)
  • AssistantMessage.role in scripts/lib/session-metrics.ts:65 (0 transitive callers)
  • AssistantMessage.content in scripts/lib/session-metrics.ts:66 (0 transitive callers)
  • collectToolUseBlocks in scripts/lib/session-metrics.ts:73 (3 transitive callers)
  • ToolCallTally.toolCalls in scripts/lib/session-metrics.ts:86 (0 transitive callers)
  • ToolCallTally.uniqueFilesRead in scripts/lib/session-metrics.ts:87 (0 transitive callers)
  • tallyToolCalls in scripts/lib/session-metrics.ts:94 (3 transitive callers)
  • buildSessionOptions in scripts/token-benchmark.ts:179 (3 transitive callers)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant