You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Flip the `http2` client option default from `false` to `true`, so the SDK
uses its native `node:http2` multiplexing transport by default on Node.js
instead of one HTTP/1.1 connection per request. Web/Deno/Bun are unaffected
(platform fetch already speaks h2), and a user-supplied `fetch` still wins.
Opting out: pass `http2: false` for the HTTP/1.1 `node-fetch` transport. To
keep existing `httpAgent` users working, a bare `httpAgent` (with no explicit
`http2`) keeps the client on HTTP/1.1 and emits a one-time warning; pass
`http2: false` to select HTTP/1.1 explicitly and silence it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
On Node.js, the SDK can send requests over HTTP/2, which multiplexes many concurrent requests over a small number of TLS connections instead of opening a connection per request. Enable it with the `http2` option:
360
+
On Node.js, the SDK sends requests over HTTP/2 **by default**, multiplexing many concurrent requests over a small number of TLS connections instead of opening a connection per request. The transport is built on Node's native `node:http2` and manages a bounded pool of persistent H2 sessions per origin, auto-scaling with load. On the web, Deno, and other runtimes the platform `fetch` already speaks HTTP/2, so this option is a no-op there.
361
+
362
+
To tune the pool — for example to raise the number of connections for a high-concurrency workload — pass options as `http2`:
361
363
362
364
<!-- prettier-ignore -->
363
365
```ts
364
366
const runloop =newRunloopSDK({
365
-
http2: true,
367
+
http2: { maxConnections: 20 },
366
368
});
367
369
```
368
370
369
-
Requests are routed through an [undici](https://github.com/nodejs/undici) connection pool with HTTP/2 enabled, falling back to HTTP/1.1 for origins that don't negotiate h2 via ALPN. It is intended for HTTP/2-capable origins such as the Runloop API. This transport uses undici and therefore **requires Node.js >= 20.18.1** (see Requirements).
370
-
371
-
`http2: true` uses a default bounded pool. To control the pool yourself — for example to raise the number of connections or multiplexed streams for a high-concurrency workload — pass a configured undici `Dispatcher` (such as an `Agent`) instead. The SDK uses it verbatim and does not manage its lifecycle, the same way it treats a custom `httpAgent`:
371
+
To opt out and use the HTTP/1.1 `node-fetch` transport, set `http2: false`:
The `httpAgent` option does not apply to the HTTP/2 transport (undici has no Node `http.Agent` concept); set `http2` to a `Dispatcher` to tune connections. A one-time warning is emitted if both `http2`and `httpAgent` are provided.
380
+
The `httpAgent` option only applies to the HTTP/1.1 transport — the H2 pool manages its own connections. Passing an `httpAgent` without an explicit `http2` value keeps the client on HTTP/1.1 (with a one-time warning); pass `http2: false` to select HTTP/1.1 explicitly and silence the warning. A custom `fetch` always takes precedence over `http2`.
// Emitted at most once per process when `http2` and `httpAgent` are combined (see
345
-
// the constructor). Module-scoped flag mirrors the `fileFromPathWarned` pattern in
346
-
// _shims/node-runtime.ts.
350
+
// Emitted at most once per process each (see the constructor). Module-scoped flags
351
+
// mirror the `fileFromPathWarned` pattern in _shims/node-runtime.ts.
352
+
//
353
+
// `http2HttpAgentWarned` — user explicitly set `http2` *and* `httpAgent`; the agent
354
+
// is ignored on the H2 path.
355
+
// `http2DefaultAgentWarned`— user set `httpAgent` without an explicit `http2` value, so
356
+
// the client stays on HTTP/1.1 rather than the H2 default.
347
357
lethttp2HttpAgentWarned=false;
358
+
lethttp2DefaultAgentWarned=false;
348
359
349
360
exportclassRunloopextendsCore.APIClient{
350
361
bearerToken: string;
@@ -359,7 +370,7 @@ export class Runloop extends Core.APIClient {
359
370
* @param {number} [opts.timeout=30 seconds] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
360
371
* @param {number} [opts.httpAgent] - An HTTP agent used to manage HTTP(s) connections.
361
372
* @param {Core.Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
362
-
* @param {boolean | H2FetchOptions} [opts.http2=false] - Send requests over HTTP/2 (Node only; ignored when `fetch` is provided). `true` uses the default bounded pool; pass H2FetchOptions to tune.
373
+
* @param {boolean | H2FetchOptions} [opts.http2=true] - Send requests over HTTP/2 (Node only; ignored when `fetch` is provided). Enabled by default; pass `false` to use HTTP/1.1, or H2FetchOptions to tune the pool.
363
374
* @param {number} [opts.maxRetries=5] - The maximum number of times the client will retry a request.
364
375
* @param {Core.Headers} opts.defaultHeaders - Default headers to include with every request to the API.
365
376
* @param {Core.DefaultQuery} opts.defaultQuery - Default query parameters to include with every request to the API.
@@ -381,15 +392,43 @@ export class Runloop extends Core.APIClient {
381
392
baseURL: baseURL||`https://api.runloop.ai`,
382
393
};
383
394
384
-
// `httpAgent` does not apply to the HTTP/2 transport — it manages its own
385
-
// persistent connections. Warn once instead of silently ignoring.
0 commit comments