Skip to content

Honor the concurrency option in evaluate() - #6

Open
ruanmartinelli wants to merge 2 commits into
mainfrom
claude/honor-concurrency
Open

Honor the concurrency option in evaluate()#6
ruanmartinelli wants to merge 2 commits into
mainfrom
claude/honor-concurrency

Conversation

@ruanmartinelli

@ruanmartinelli ruanmartinelli commented Jul 5, 2026

Copy link
Copy Markdown
Owner

EvalConfig.concurrency was accepted but silently ignored — cases always ran serially, which makes real evals (network-bound model calls) slow. This wires it up.

What

  • Cases run through p-map (the library's first runtime dependency): order-preserving, at most concurrency cases in flight, rejections propagate.
  • The per-case body of evaluate is extracted into a runCase helper and scheduled through the pool. Behavior of a single case (scoring, usage accounting, error handling) is unchanged.
  • Default stays 1 (serial), so existing callers see identical behavior. Models are still swept one at a time, keeping per-model rate limits predictable.
  • concurrency is validated as a positive integer.
  • Docs updated: the types.ts comment and the README row no longer say "not yet honored".

Tests

Coverage asserts: serial by default, at most concurrency cases in flight, results stay in case order under out-of-order completion, identical scoring vs serial, and rejection of 0 / -1 / 1.5. These evaluate-level tests are the behavior contract regardless of the pool implementation. pnpm typecheck && pnpm test: 75 passing.

History

The first commit used a hand-rolled mapConcurrent util; the second swaps it for p-map per review feedback.

Note

This touches the same case loop as #7 (task error capture) — whichever merges first, the other rebases trivially; I'm happy to do that.

🤖 Generated with Claude Code

https://claude.ai/code/session_015XMPpi4PX2bWwAoMLaZZ4k

The concurrency option was accepted in EvalConfig but silently ignored;
cases always ran serially. Now up to config.concurrency cases run at
once within each model (default 1, preserving the old serial behavior);
models are still swept one at a time so per-model rate limits stay
predictable.

- add mapConcurrent to utils: an order-preserving worker-pool map
- extract the per-case body of evaluate into runCase so it can be
  scheduled through the pool
- validate concurrency as a positive integer
- update the types comment and README row that said 'not yet honored'

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015XMPpi4PX2bWwAoMLaZZ4k
Swap the hand-rolled mapConcurrent pool for p-map, the battle-tested
equivalent. Behavior is unchanged: order-preserving, at most
config.concurrency cases in flight, rejections propagate. The
evaluate-level concurrency tests stay as the behavior contract; the
pool's own unit tests go with it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015XMPpi4PX2bWwAoMLaZZ4k
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.

2 participants