Skip to content

feat(batch): async wait/reconcile primitives for the Batches API - #111

Merged
Patel230 merged 2 commits into
mainfrom
feat/batch-async-reconcile
Aug 23, 2026
Merged

feat(batch): async wait/reconcile primitives for the Batches API#111
Patel230 merged 2 commits into
mainfrom
feat/batch-async-reconcile

Conversation

@Patel230

Copy link
Copy Markdown
Contributor

Summary

Completes the BatchClient surface for real async usage, adopting the reconcile pattern proven in agent-fleet orchestration (Orca/grok-cli): batch result rows are eventually consistent — an individual request's row can lag the batch reaching a terminal state — so naive pollers either miss rows or storm the API.

Additions (client/batch_async.go)

  • WaitUntilDone — polls until a terminal state with exponential backoff + jitter capped at MaxInterval, honoring Retry-After on 429/5xx, failing fast on other non-200s, bounded by Timeout (default 10m)
  • RequestResults — fetches + parses the JSONL results document; each BatchRequestResult preserves the provider payload byte-exact for per-provider decoding
  • PollRequestResult — reconciles one custom_id: waits for batch completion, then tolerates eventual consistency via bounded extra attempts before surfacing ErrResultNotVisible
  • backoffDelay helper with jitter and Retry-After override

Testing

8 new httptest-based cases: terminal transition, timeout, Retry-After honored on 429 (timing-verified), fail-fast 401, JSONL parsing, lag tolerance, not-visible exhaustion, Retry-After override. Full client suite green.

Completes the BatchClient surface for real async usage:

- WaitUntilDone polls until a terminal state (ended/completed/failed/
  expired/canceled) with exponential backoff + jitter capped at
  MaxInterval, honoring Retry-After headers on 429/5xx, failing fast on
  other non-200s, and bounding total wall-clock via Timeout.
- RequestResults fetches and parses the JSONL results document into
  BatchRequestResult rows that preserve the provider payload byte-exact
  for per-provider decoding.
- PollRequestResult reconciles one custom_id: waits for batch completion,
  then tolerates eventual consistency where the results endpoint lags
  completion (bounded extra attempts), surfacing ErrResultNotVisible only
  after the row is genuinely absent.
- backoffDelay helper with jitter and Retry-After override.

Motivated by agent-fleet orchestration patterns (Orca/grok-cli): batch
result rows are eventually consistent and naive pollers either miss rows
or storm the API; these primitives make the reconcile loop correct by
construction.

Tests: 8 new httptest-based cases covering terminal transition, timeout,
Retry-After honoring on 429, fail-fast on 401, JSONL parsing, lag
tolerance, not-visible exhaustion, and Retry-After override in backoff.
@Patel230
Patel230 merged commit fa60fa6 into main Aug 23, 2026
16 checks passed
@Patel230
Patel230 deleted the feat/batch-async-reconcile branch August 23, 2026 15:37
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