Skip to content

fix(pool,convert): atomic RPM admission, <tool_calls> plural dialect, failover knob doc - #356

Merged
trefeon merged 3 commits into
mainfrom
fix/rpm-admit-atomic-toolcalls-plural
Sep 5, 2026
Merged

fix(pool,convert): atomic RPM admission, <tool_calls> plural dialect, failover knob doc#356
trefeon merged 3 commits into
mainfrom
fix/rpm-admit-atomic-toolcalls-plural

Conversation

@trefeon

@trefeon trefeon commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Problems

  1. MAX_REQUESTS_PER_MINUTE race: admission was checked in Acquire but recorded later in Chat. A concurrent burst (agent spawn batches of 6-8) all passed the cap before any record landed — e.g. a 5/min cap admitted 8. Observed: user set 5/min and bursts went through.
  2. <tool_calls> plural dialect: some models emit the plural wrapper around the same <function=...> payload. The extractor only knew singular/pipe/fence forms, so plural blocks leaked as literal <tool_calls> text to the harness and never became tool calls.
  3. Misleading knob text: RATE_LIMIT_FAILOVER description did not say turn_spend_limited is TERMINAL and excluded from failover.

Changes

  • pool: tryAdmitRequest (roster lock) + bridgeTryAdmitRequest (bridgeMu) record the admission atomically at lease-grant time; grant fails over to the next token when the window filled concurrently. Pool.Chat no longer records admissions (success-side RPD/usage records stay). Dead recordRequestEntry paths removed.
  • convert: new xmlShapeToolCalls stream shape (opener/closer/split-opener/dangling scrub) + 5th block-regex group for the non-stream path; payload parsing (function heads/params/JSON) is shape-agnostic.
  • keycatalog: RATE_LIMIT_FAILOVER description states the terminal exclusion.
  • Fixture regenerated (FP_REGEN_FIXTURE=1).

Verification

  • TestAcquireRPMAdmitBurstIsAtomic / TestBridgeRPMAdmitBurstIsAtomic: 2 concurrent acquires, cap=1 -> exactly 1 admits (deterministic; pre-fix both admitted).
  • TestAcquireCountsAdmissionAtGrant: count is 1 right after Acquire with no chat.
  • TestExtractXMLToolCallsPluralDialect / TestXMLStreamExtractorPluralDialect / TestXMLStreamExtractorPluralDanglingFlush.
  • Full hermetic backend suite green; go vet clean.

… failover knob doc

- pool: MAX_REQUESTS_PER_MINUTE counted atomically at lease-grant time
  (tryAdmitRequest under the owning lock) instead of check-in-Acquire /
  record-in-Chat — the old split let concurrent bursts (agent spawn
  batches) pass the cap before any record landed. Same for bridge
  (bridgeTryAdmitRequest). Removes the now-dead recordRequestEntry paths.
- convert: handle the <tool_calls> (plural) XML dialect some models emit:
  new xmlShapeToolCalls shape, closer, opener, dangling-tag scrub, and
  the 5th block-regex group — plural blocks now extract into native
  tool_calls deltas instead of leaking literal <tool_calls> text to the
  harness.
- config: RATE_LIMIT_FAILOVER description now states turn_spend_limited
  is TERMINAL and excluded from failover (default true).
- tests: pooled + bridge burst-atomicity (2 concurrent acquires, cap=1
  -> exactly 1 admits), admission counted at grant, plural non-stream /
  split-opener / dangling-Flush.
- config-meta.json fixture regenerated.
Copilot AI balanced review requested due to automatic review settings September 5, 2026 20:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@trefeon
trefeon merged commit ae91152 into main Sep 5, 2026
6 checks passed
@trefeon
trefeon deleted the fix/rpm-admit-atomic-toolcalls-plural branch September 5, 2026 20:59
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