Skip to content

feat: add max concurrency limit for guard() chunk/PDF-page analysis - #1164

Open
serhiy-bzhezytskyy wants to merge 2 commits into
superagent-ai:mainfrom
serhiy-bzhezytskyy:feature/guard-max-concurrency
Open

serhiy-bzhezytskyy wants to merge 2 commits into
superagent-ai:mainfrom
serhiy-bzhezytskyy:feature/guard-max-concurrency

Conversation

@serhiy-bzhezytskyy

@serhiy-bzhezytskyy serhiy-bzhezytskyy commented Sep 24, 2026 •

Copy link
Copy Markdown

Summary

Adds an optional maxConcurrency (TypeScript) / max_concurrency (Python) setting to guard() that bounds how many provider requests run at once when analyzing multiple text chunks or PDF pages. Unset, behavior is unchanged (unbounded, same as today).

Fixes #1161

Problem

guard() currently starts one provider request per chunk/page via an unbounded Promise.all() (TypeScript) / asyncio.gather() (Python). A large input can create a large burst of concurrent provider requests, increasing the likelihood of rate limits, connection/memory pressure, and fallback bursts, with no per-call way to apply backpressure.

Solution

  • Both SDKs get a small bounded-concurrency helper (mapWithConcurrency in TS, _gather_with_concurrency in Python) that runs at most N callbacks at once, preserving result order and existing error-propagation/aggregation semantics.
  • Falls back to the existing unbounded path whenever the option is unset or >= the number of items, so every existing caller sees identical behavior.
  • Validates the value is a positive integer, mirroring the existing chunkSize/chunk_size validation pattern.
  • Applied consistently to both call sites in both SDKs (text chunking and PDF-page analysis), per the issue's own requirement that behavior stay consistent between the two SDKs.

Test results

  • TypeScript: 4 new tests (bounds in-flight calls, full concurrency when unset, rejects 0 and non-integer values) -- full suite 166/166 passing
  • Python: 3 new tests (bounds in-flight calls, full concurrency when unset, rejects non-positive values) -- full suite 155/155 passing
  • No existing test needed changes; ordering, aggregation, and error-propagation semantics are unchanged.

Note

Low Risk
Opt-in SDK change with backward-compatible defaults; only throttles parallel provider calls without altering guard classification or aggregation semantics.

Overview
Adds an optional maxConcurrency / max_concurrency setting on guard() in the Python and TypeScript SDKs so callers can cap how many provider requests run at once when large text is chunked or PDF pages are analyzed in parallel.

Each SDK introduces a bounded-concurrency helper (mapWithConcurrency in TS, _gather_with_concurrency in Python) and wires it into the existing text-chunk and PDF-page paths instead of unbounded Promise.all / asyncio.gather. Unset (or a value ≥ item count) keeps today’s unbounded behavior; invalid values are rejected with the same positive-integer validation pattern as chunkSize.

New unit tests assert in-flight call limits, default full concurrency, and validation errors.

Reviewed by Cursor Bugbot for commit 04c693b. Configure here.

@vercel

vercel Bot commented Sep 24, 2026

Copy link
Copy Markdown

@serhiy-bzhezytskyy is attempting to deploy a commit to the Superagent Team on Vercel.

A member of the Team first needs to authorize it.

@open-cla

open-cla Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Contributor License Agreement

All contributors are covered by a CLA.

This branch has not been deployed

No deployments
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.

[Feature]: Add configurable concurrency limits for guard chunk and PDF-page analysis

1 participant