@prestyj/ai 4.12.0 → 4.13.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -255,6 +255,18 @@ declare class StreamResult implements AsyncIterable<StreamEvent> {
255
255
  private resolveResponse;
256
256
  private rejectResponse;
257
257
  private resolveWait;
258
+ /**
259
+ * High-water mark: when the buffer exceeds this many unconsumed events,
260
+ * the pump pauses until the consumer drains below the low-water mark.
261
+ * Prevents unbounded memory growth when a consumer is slow.
262
+ * Only active when someone IS iterating — if nobody iterates (the `then()`
263
+ * path), backpressure is skipped so the pump can complete and resolve.
264
+ */
265
+ private static readonly HIGH_WATER;
266
+ private static readonly LOW_WATER;
267
+ private iterating;
268
+ private paused;
269
+ private resolveDrain;
258
270
  constructor(generator: AsyncGenerator<StreamEvent, StreamResponse>, signal?: AbortSignal);
259
271
  private pump;
260
272
  private _nextWithAbort;
package/dist/index.d.ts CHANGED
@@ -255,6 +255,18 @@ declare class StreamResult implements AsyncIterable<StreamEvent> {
255
255
  private resolveResponse;
256
256
  private rejectResponse;
257
257
  private resolveWait;
258
+ /**
259
+ * High-water mark: when the buffer exceeds this many unconsumed events,
260
+ * the pump pauses until the consumer drains below the low-water mark.
261
+ * Prevents unbounded memory growth when a consumer is slow.
262
+ * Only active when someone IS iterating — if nobody iterates (the `then()`
263
+ * path), backpressure is skipped so the pump can complete and resolve.
264
+ */
265
+ private static readonly HIGH_WATER;
266
+ private static readonly LOW_WATER;
267
+ private iterating;
268
+ private paused;
269
+ private resolveDrain;
258
270
  constructor(generator: AsyncGenerator<StreamEvent, StreamResponse>, signal?: AbortSignal);
259
271
  private pump;
260
272
  private _nextWithAbort;
package/dist/index.js CHANGED
@@ -281,7 +281,7 @@ var EventStream = class {
281
281
  }
282
282
  }
283
283
  };
284
- var StreamResult = class {
284
+ var StreamResult = class _StreamResult {
285
285
  response;
286
286
  buffer = [];
287
287
  done = false;
@@ -289,6 +289,18 @@ var StreamResult = class {
289
289
  resolveResponse;
290
290
  rejectResponse;
291
291
  resolveWait = null;
292
+ /**
293
+ * High-water mark: when the buffer exceeds this many unconsumed events,
294
+ * the pump pauses until the consumer drains below the low-water mark.
295
+ * Prevents unbounded memory growth when a consumer is slow.
296
+ * Only active when someone IS iterating — if nobody iterates (the `then()`
297
+ * path), backpressure is skipped so the pump can complete and resolve.
298
+ */
299
+ static HIGH_WATER = 5e3;
300
+ static LOW_WATER = 1e3;
301
+ iterating = false;
302
+ paused = false;
303
+ resolveDrain = null;
292
304
  constructor(generator, signal) {
293
305
  this.response = new Promise((resolve, reject) => {
294
306
  this.resolveResponse = resolve;
@@ -303,6 +315,13 @@ var StreamResult = class {
303
315
  this.buffer.push(next.value);
304
316
  this.resolveWait?.();
305
317
  this.resolveWait = null;
318
+ if (this.iterating && this.buffer.length > _StreamResult.HIGH_WATER) {
319
+ this.paused = true;
320
+ await new Promise((r) => {
321
+ this.resolveDrain = r;
322
+ });
323
+ this.paused = false;
324
+ }
306
325
  next = await this._nextWithAbort(generator, signal);
307
326
  }
308
327
  this.done = true;
@@ -341,11 +360,20 @@ var StreamResult = class {
341
360
  }
342
361
  }
343
362
  async *[Symbol.asyncIterator]() {
363
+ this.iterating = true;
344
364
  let index = 0;
345
365
  while (true) {
346
366
  while (index < this.buffer.length) {
347
367
  yield this.buffer[index++];
348
368
  }
369
+ if (this.paused && index > _StreamResult.LOW_WATER) {
370
+ this.resolveDrain?.();
371
+ this.resolveDrain = null;
372
+ }
373
+ if (index > 0 && !this.paused) {
374
+ this.buffer.splice(0, index);
375
+ index = 0;
376
+ }
349
377
  if (this.error) throw this.error;
350
378
  if (this.done) return;
351
379
  await new Promise((r) => {
@@ -358,6 +386,11 @@ var StreamResult = class {
358
386
  }
359
387
  }
360
388
  then(onfulfilled, onrejected) {
389
+ if (this.paused) {
390
+ this.paused = false;
391
+ this.resolveDrain?.();
392
+ this.resolveDrain = null;
393
+ }
361
394
  return this.response.then(onfulfilled, onrejected);
362
395
  }
363
396
  };
@@ -980,6 +1013,7 @@ function parseToolArguments(argsJson) {
980
1013
  }
981
1014
 
982
1015
  // src/providers/anthropic.ts
1016
+ var NON_STREAMING_TIMEOUT_MS = 60 * 60 * 1e3;
983
1017
  var anthropicClientCache = /* @__PURE__ */ new Map();
984
1018
  function createClient(options) {
985
1019
  const isOAuth = options.apiKey?.startsWith("sk-ant-oat");
@@ -1146,8 +1180,9 @@ async function* runStream(options) {
1146
1180
  ...betaHeaders.length ? { headers: { "anthropic-beta": betaHeaders.join(",") } } : {}
1147
1181
  };
1148
1182
  if (!useStreaming) {
1183
+ const nonStreamingClient = client.withOptions({ timeout: NON_STREAMING_TIMEOUT_MS });
1149
1184
  try {
1150
- const message = await client.messages.create(
1185
+ const message = await nonStreamingClient.messages.create(
1151
1186
  { ...params, stream: false },
1152
1187
  requestOptions
1153
1188
  );