vern-llm 2.4.2 → 2.6.0
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/README.md +6 -4
- package/dist/index.cjs +7 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +889 -348
- package/dist/index.d.cts.map +1 -1
- package/dist/{index.d.ts → index.d.mts} +890 -349
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +15 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +26 -24
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -15
- package/dist/index.js.map +0 -1
|
@@ -7,16 +7,7 @@ type LLMErrorType = 'timeout' | 'api' | 'network' | 'parse' | 'validation' | 'in
|
|
|
7
7
|
* e.g. `authentication`/`authorization` apply the same way regardless of
|
|
8
8
|
* which type wraps them.
|
|
9
9
|
*/
|
|
10
|
-
type LLMErrorCode = 'unknown_tool' | 'duplicate_tool_call_id' | 'tool_choice_none_violated' | 'unexpected_tool_calls' | 'unsupported_capability' | 'duplicate_tool_names' | 'unknown_tool_choice' | 'duplicate_tool_result_ids' | 'unknown_tool_result_ids' | 'missing_tool_results' | 'rate_limit_queue_full' | 'rate_limit_queue_timeout' | 'rate_limit_capacity_exceeded' | 'provider_rate_limited' | 'request_timeout' | 'idle_timeout' | 'authentication' | 'authorization' | 'not_found' | 'payload_too_large' | 'server_error' | 'empty_response' | 'connection_failed' | 'circuit_cooling_down' | 'circuit_trial_in_flight' | 'fallback_exhausted' | 'tool_arguments_parse_failed' | 'stream_frame_invalid';
|
|
11
|
-
/**
|
|
12
|
-
* Tool contract codes: a model or provider response defect, not a
|
|
13
|
-
* transient provider fault. Deterministic on the wire request, so
|
|
14
|
-
* retrying can't change the outcome and it shouldn't count toward the
|
|
15
|
-
* circuit breaker either. Shared by `LLMError.retryable` below and by
|
|
16
|
-
* `CallExecutor`'s own retry/breaker accounting, so the two can't drift
|
|
17
|
-
* apart.
|
|
18
|
-
*/
|
|
19
|
-
|
|
10
|
+
type LLMErrorCode = 'unknown_tool' | 'duplicate_tool_call_id' | 'tool_choice_none_violated' | 'unexpected_tool_calls' | 'unsupported_capability' | 'duplicate_tool_names' | 'unknown_tool_choice' | 'duplicate_tool_result_ids' | 'unknown_tool_result_ids' | 'missing_tool_results' | 'middleware_threw' | 'rate_limit_queue_full' | 'rate_limit_queue_timeout' | 'rate_limit_capacity_exceeded' | 'provider_rate_limited' | 'retry_budget_exhausted' | 'request_timeout' | 'idle_timeout' | 'middleware_timeout' | 'deadline_exceeded' | 'authentication' | 'authorization' | 'not_found' | 'payload_too_large' | 'server_error' | 'empty_response' | 'connection_failed' | 'circuit_cooling_down' | 'circuit_trial_in_flight' | 'fallback_exhausted' | 'tool_arguments_parse_failed' | 'stream_frame_invalid' | 'soft_failure_detected';
|
|
20
11
|
/** One tool call's contract failure, used to report every bad call in a response at once. */
|
|
21
12
|
interface ToolIssue {
|
|
22
13
|
name: string;
|
|
@@ -133,21 +124,6 @@ interface LLMRequestSnapshot {
|
|
|
133
124
|
/** Wall clock time the attempt started, ms since epoch. */
|
|
134
125
|
startedAt: number;
|
|
135
126
|
}
|
|
136
|
-
/**
|
|
137
|
-
* Builds a point-in-time, plain data copy of one attempt's outgoing
|
|
138
|
-
* request. Mirrors `LLMError.toSnapshot()`: never thrown or dispatched
|
|
139
|
-
* again, safe to serialize and store. A plain function rather than a
|
|
140
|
-
* method, since unlike `LLMError` a request has no throwable identity or
|
|
141
|
-
* derived state worth wrapping in a class.
|
|
142
|
-
*
|
|
143
|
-
* `startedAt` is optional so existing call sites (and tests) that don't
|
|
144
|
-
* care about exact timing keep working, but a caller that has a real
|
|
145
|
-
* capture time should always pass it: this function may run well after
|
|
146
|
-
* the request was actually dispatched (e.g. `callExecutor` only builds
|
|
147
|
-
* the snapshot once an attempt has failed), so defaulting to `Date.now()`
|
|
148
|
-
* here would record failure-handling time, not request-start time.
|
|
149
|
-
*/
|
|
150
|
-
|
|
151
127
|
/**
|
|
152
128
|
* One failed attempt on the way to a terminal error: which attempt index
|
|
153
129
|
* it was, and a snapshot of the error it failed with. The base shape
|
|
@@ -187,11 +163,20 @@ declare class LLMError extends Error {
|
|
|
187
163
|
* `nonRetryableStatus` list. False for `parse`/`validation`/
|
|
188
164
|
* `invalid_params`/`aborted` types (the caller's own input, the model's
|
|
189
165
|
* own response, or intentional cancellation, none of which are the
|
|
190
|
-
* provider being unhealthy), the tool contract codes,
|
|
191
|
-
* rate limit codes
|
|
192
|
-
* override this when `type`
|
|
166
|
+
* provider being unhealthy), the tool contract codes, the local
|
|
167
|
+
* rate limit codes, and the middleware timeout code.
|
|
168
|
+
* Subclasses (see `FallbackExhaustedError`) may override this when `type`
|
|
169
|
+
* alone carries no retry signal.
|
|
193
170
|
*/
|
|
194
171
|
get retryable(): boolean;
|
|
172
|
+
/**
|
|
173
|
+
* Whether this failure should count toward the circuit breaker's
|
|
174
|
+
* failure threshold. Not the same question as `retryable`:
|
|
175
|
+
* `quota_exceeded` is retryable but says nothing about provider
|
|
176
|
+
* health, so it's excluded here even though `retryable` is true for
|
|
177
|
+
* it. Always false whenever `retryable` is false.
|
|
178
|
+
*/
|
|
179
|
+
get countsTowardBreaker(): boolean;
|
|
195
180
|
/**
|
|
196
181
|
* Copies this error's fields into an {@link LLMErrorSnapshot}, for
|
|
197
182
|
* recording as a `RetryAttempt`/`FallbackAttempt`. `retryable` is
|
|
@@ -234,10 +219,9 @@ declare function isLLMError(err: unknown): err is LLMError;
|
|
|
234
219
|
declare function hasIssues<C extends keyof LLMErrorIssuesByCode>(err: LLMError, code: C): err is LLMError & {
|
|
235
220
|
code: C;
|
|
236
221
|
issues: LLMErrorIssuesByCode[C];
|
|
237
|
-
};
|
|
222
|
+
};
|
|
223
|
+
//#endregion
|
|
238
224
|
//#region src/types/cache.d.ts
|
|
239
|
-
|
|
240
|
-
//# sourceMappingURL=errors.d.ts.map
|
|
241
225
|
interface CacheAdapter<T = unknown> {
|
|
242
226
|
get(key: string): Promise<{
|
|
243
227
|
hit: boolean;
|
|
@@ -248,13 +232,20 @@ interface CacheAdapter<T = unknown> {
|
|
|
248
232
|
resolveKey?(key: string): Promise<string>;
|
|
249
233
|
}
|
|
250
234
|
/**
|
|
251
|
-
*
|
|
252
|
-
*
|
|
235
|
+
* Which entry `InMemoryCacheAdapter` evicts once `maxSize` is exceeded.
|
|
236
|
+
* `'fifo'` (default) drops the oldest inserted entry. `'lru'` drops the
|
|
237
|
+
* least recently read or written entry.
|
|
238
|
+
*/
|
|
239
|
+
type EvictionOption = 'fifo' | 'lru';
|
|
240
|
+
/**
|
|
241
|
+
* Trivial default so the package works out of the box with no external deps.
|
|
242
|
+
* Not shared across processes, swap in Redis/Upstash/etc for production.
|
|
253
243
|
*/
|
|
254
244
|
declare class InMemoryCacheAdapter<T = unknown> implements CacheAdapter<T> {
|
|
255
245
|
private readonly maxSize;
|
|
256
246
|
private store;
|
|
257
|
-
|
|
247
|
+
private readonly eviction;
|
|
248
|
+
constructor(maxSize?: number, eviction?: EvictionOption);
|
|
258
249
|
get(key: string): Promise<{
|
|
259
250
|
hit: boolean;
|
|
260
251
|
value: T | null;
|
|
@@ -301,104 +292,512 @@ declare class TieredCacheAdapter<T = unknown> implements CacheAdapter<T> {
|
|
|
301
292
|
set(key: string, value: T, ttl: number): Promise<void>;
|
|
302
293
|
delete(key: string): Promise<void>;
|
|
303
294
|
}
|
|
304
|
-
|
|
295
|
+
//#endregion
|
|
296
|
+
//#region src/types/events.d.ts
|
|
297
|
+
/**
|
|
298
|
+
* Reports what happened during a call. Fire and forget, mirroring
|
|
299
|
+
* `onUsage`: the return value is never read and a throwing handler cannot
|
|
300
|
+
* change what the call does, only what gets reported about it.
|
|
301
|
+
*/
|
|
302
|
+
type VernLLMEvent = {
|
|
303
|
+
kind: 'retry';
|
|
304
|
+
requestId: string;
|
|
305
|
+
provider: string;
|
|
306
|
+
/** The model actually resolved for this call (honors a per-call `model` override). */
|
|
307
|
+
model: string;
|
|
308
|
+
/** The 1-based retry ordinal (the 1st retry is `1`, not the overall attempt count). */
|
|
309
|
+
attempt: number;
|
|
310
|
+
maxRetries: number;
|
|
311
|
+
delayMs: number;
|
|
312
|
+
retryAfterHonored: boolean;
|
|
313
|
+
error: LLMError;
|
|
314
|
+
} | {
|
|
315
|
+
kind: 'circuit_state';
|
|
316
|
+
provider: string;
|
|
317
|
+
/**
|
|
318
|
+
* The model of the call that triggered this specific transition
|
|
319
|
+
* (whatever was passed to the `assertClosed`/`recordSuccess`/
|
|
320
|
+
* `recordFailure` call that caused it), not a property of the
|
|
321
|
+
* circuit itself: the breaker still counts failures across every
|
|
322
|
+
* model together, so a threshold crossing can be the sum of
|
|
323
|
+
* several different models' failures even though only the
|
|
324
|
+
* triggering call's `model` is reported here.
|
|
325
|
+
*/
|
|
326
|
+
model: string;
|
|
327
|
+
from: CircuitState;
|
|
328
|
+
to: CircuitState;
|
|
329
|
+
consecutiveFailures: number;
|
|
330
|
+
} | {
|
|
331
|
+
kind: 'fallback';
|
|
332
|
+
requestId: string;
|
|
333
|
+
/** Provider name of the target that just failed. */
|
|
334
|
+
from: string;
|
|
335
|
+
/** Provider name of the target about to be tried next. */
|
|
336
|
+
to: string;
|
|
337
|
+
/** `-1` for the primary target, otherwise the index into `fallback`. */
|
|
338
|
+
fromIndex: number;
|
|
339
|
+
toIndex: number;
|
|
340
|
+
/** The normalized error that caused `from` to be abandoned. */
|
|
341
|
+
error: LLMError;
|
|
342
|
+
/** Time spent on `from`, including its own retries, before giving up. */
|
|
343
|
+
elapsedMs: number;
|
|
344
|
+
} | {
|
|
345
|
+
kind: 'rate_limited';
|
|
346
|
+
requestId: string;
|
|
347
|
+
provider: string;
|
|
348
|
+
/** The model actually resolved for this call (honors a per-call `model` override). */
|
|
349
|
+
model: string;
|
|
350
|
+
/** How long this attempt sat queued for capacity before it was let through. */
|
|
351
|
+
waitedMs: number;
|
|
352
|
+
/** Which configured bucket was blocking this attempt just before it cleared. */
|
|
353
|
+
reason: 'concurrency' | 'rpm' | 'tpm';
|
|
354
|
+
} | {
|
|
355
|
+
kind: 'middleware';
|
|
356
|
+
requestId: string;
|
|
357
|
+
/** This middleware's `name`, or its array position if unnamed. */
|
|
358
|
+
middleware: string;
|
|
359
|
+
hook: 'transform' | 'wrap_short_circuit' | 'enabled_skip';
|
|
360
|
+
/** For `hook: 'transform'` only: which top-level fields the merged patch touched. */
|
|
361
|
+
patchedFields?: string[];
|
|
362
|
+
};
|
|
363
|
+
type OnEvent = (event: VernLLMEvent) => void;
|
|
364
|
+
//#endregion
|
|
365
|
+
//#region src/types/middleware.d.ts
|
|
366
|
+
/** Capabilities of the target a middleware hook is currently looking at. */
|
|
367
|
+
interface MiddlewareCapabilities {
|
|
368
|
+
/**
|
|
369
|
+
* Whether this target honors `response_format: { type: 'json_object' }`
|
|
370
|
+
* as a real constraint. Mirrors `LLMClient.supportsJsonObjectMode`.
|
|
371
|
+
* `false` for `fromAnthropic` and `fromBedrock`.
|
|
372
|
+
*/
|
|
373
|
+
supportsJsonObjectMode: boolean;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* A typed reference to one slot in `ctx.state`. Create one with
|
|
377
|
+
* `createStateKey`, export it, and import the same reference wherever
|
|
378
|
+
* another middleware needs to read or write the same value. There's no
|
|
379
|
+
* string key anywhere in this path, so a typo becomes a missing import
|
|
380
|
+
* or an undefined variable, a compile error, instead of a silently
|
|
381
|
+
* created new property.
|
|
382
|
+
*/
|
|
383
|
+
interface MiddlewareStateKey<T> {
|
|
384
|
+
readonly debugName: string;
|
|
385
|
+
/**
|
|
386
|
+
* Never set at runtime; exists purely so `T` is actually used
|
|
387
|
+
* somewhere in this interface's shape (a phantom type), which is what
|
|
388
|
+
* lets `MiddlewareStateBag.get`/`set` infer the right type for a given
|
|
389
|
+
* key instead of two `MiddlewareStateKey<string>` and
|
|
390
|
+
* `MiddlewareStateKey<number>` keys being structurally identical.
|
|
391
|
+
*/
|
|
392
|
+
readonly __phantom?: T;
|
|
393
|
+
}
|
|
394
|
+
/** Creates a new, distinct `MiddlewareStateKey`. `debugName` is used only in log lines and the `'middleware'` event; it never affects equality. */
|
|
395
|
+
declare function createStateKey<T>(debugName: string): MiddlewareStateKey<T>;
|
|
396
|
+
/**
|
|
397
|
+
* Typed, per-logical-call storage two middleware can deliberately share a
|
|
398
|
+
* value through (a span ID one sets, another reads). Backed by a plain
|
|
399
|
+
* `Map` internally, created once per logical call and never read or
|
|
400
|
+
* written by VernLLM itself.
|
|
401
|
+
*/
|
|
402
|
+
interface MiddlewareStateBag {
|
|
403
|
+
get<T>(key: MiddlewareStateKey<T>): T | undefined;
|
|
404
|
+
set<T>(key: MiddlewareStateKey<T>, value: T): void;
|
|
405
|
+
}
|
|
406
|
+
/** A plain, `Map`-backed `MiddlewareStateBag`. */
|
|
407
|
+
declare function createMiddlewareStateBag(): MiddlewareStateBag;
|
|
408
|
+
/** Fields every `MiddlewareContext` variant carries, regardless of `stage`. */
|
|
409
|
+
interface MiddlewareContextBase {
|
|
410
|
+
requestId: string;
|
|
411
|
+
/** Capabilities of the target this stage's identity fields describe. */
|
|
412
|
+
capabilities: MiddlewareCapabilities;
|
|
413
|
+
signal?: AbortSignal;
|
|
414
|
+
/** Shared, collision-proof state for two middleware to deliberately coordinate through. See `MiddlewareStateBag`. */
|
|
415
|
+
state: MiddlewareStateBag;
|
|
416
|
+
/** Simple, string-keyed scratch space, pre-namespaced to this one middleware so two middleware can never collide here even by accident. */
|
|
417
|
+
own: Record<string, unknown>;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* The `ctx` `transform` receives, and every attempt-scoped event context
|
|
421
|
+
* (`'retry'`, `'fallback'`, `'circuit_state'`, `'middleware'`). Built once
|
|
422
|
+
* a specific target has actually been selected for this attempt, so every
|
|
423
|
+
* field describes the real target, not a placeholder.
|
|
424
|
+
*/
|
|
425
|
+
interface AttemptContext extends MiddlewareContextBase {
|
|
426
|
+
stage: 'attempt';
|
|
427
|
+
/** The target this attempt is actually dispatched to. */
|
|
428
|
+
requestedProvider: string;
|
|
429
|
+
requestedModel: string;
|
|
430
|
+
isFallbackAttempt: boolean;
|
|
431
|
+
/**
|
|
432
|
+
* The real, current attempt number for this dispatch.
|
|
433
|
+
*
|
|
434
|
+
* Exception: on a `'circuit_state'` event triggered by a pre-dispatch
|
|
435
|
+
* check (`assertClosed`, before any attempt has been made), this is
|
|
436
|
+
* `1` regardless of which attempt is about to run, since no attempt
|
|
437
|
+
* exists yet to report. Every other `'circuit_state'` event, and every
|
|
438
|
+
* other attempt-scoped event, reports the real attempt number.
|
|
439
|
+
*/
|
|
440
|
+
attempt: number;
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* The `ctx` `wrap` receives before `next()` resolves (and `onError`'s own
|
|
444
|
+
* `ctx`, built the same way under the hood). Built once, before any
|
|
445
|
+
* fallback target is chosen, so it only ever describes the primary
|
|
446
|
+
* target. There is no real "requested" target yet, and no attempt count,
|
|
447
|
+
* fallback flag, or per-attempt capability to report. Read `next()`'s
|
|
448
|
+
* resolved `CallResult.meta` once you need to know what actually
|
|
449
|
+
* happened.
|
|
450
|
+
*/
|
|
451
|
+
interface PreDispatchContext extends MiddlewareContextBase {
|
|
452
|
+
stage: 'pre-dispatch';
|
|
453
|
+
/** The primary target only, not necessarily who ends up answering. */
|
|
454
|
+
primaryProvider: string;
|
|
455
|
+
primaryModel: string;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* `enabled` and `onEvent` are called from both stages (gating/observing
|
|
459
|
+
* `transform` as well as `wrap`), so they receive this union and must
|
|
460
|
+
* narrow on `ctx.stage` before reading stage-specific fields.
|
|
461
|
+
* `transform` and `wrap` themselves receive the single variant that's
|
|
462
|
+
* always accurate for them (`AttemptContext`/`PreDispatchContext`
|
|
463
|
+
* respectively). See `VernLLMMiddleware`.
|
|
464
|
+
*/
|
|
465
|
+
type MiddlewareContext = AttemptContext | PreDispatchContext;
|
|
466
|
+
/** The `response_format` shape `RequestBuilder` can put on the wire. */
|
|
467
|
+
type WireResponseFormat = {
|
|
468
|
+
type: 'json_object';
|
|
469
|
+
} | {
|
|
470
|
+
type: 'json_schema';
|
|
471
|
+
json_schema: {
|
|
472
|
+
name: string;
|
|
473
|
+
schema: Record<string, unknown>;
|
|
474
|
+
strict?: boolean;
|
|
475
|
+
description?: string;
|
|
476
|
+
};
|
|
477
|
+
};
|
|
478
|
+
/** A tool as it appears on the wire, OpenAI's `function`-wrapped shape. */
|
|
479
|
+
interface WireTool {
|
|
480
|
+
type: 'function';
|
|
481
|
+
function: {
|
|
482
|
+
name: string;
|
|
483
|
+
description: string;
|
|
484
|
+
parameters: Record<string, unknown>;
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* The wire-shaped request `RequestBuilder.build()` produces for one call
|
|
489
|
+
* attempt, before dispatch. Read only inside `transform`; return a patch
|
|
490
|
+
* of the fields you want to change instead of the whole object.
|
|
491
|
+
*/
|
|
492
|
+
interface WireCallRequest {
|
|
493
|
+
model: string;
|
|
494
|
+
temperature?: number;
|
|
495
|
+
max_tokens: number;
|
|
496
|
+
response_format?: WireResponseFormat;
|
|
497
|
+
reasoning_effort?: 'minimal' | 'low' | 'medium' | 'high';
|
|
498
|
+
budget_tokens?: number;
|
|
499
|
+
tools?: WireTool[];
|
|
500
|
+
tool_choice?: WireToolChoice;
|
|
501
|
+
messages: WireMessage[];
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* What `transform` returns: a patch merged onto the request that
|
|
505
|
+
* `RequestBuilder.build()` (plus every earlier middleware's own patch)
|
|
506
|
+
* already produced, not a replacement for it. `model` and
|
|
507
|
+
* `response_format` can't be expressed here at all, since everything
|
|
508
|
+
* downstream that attributes a call to a target keys off the values
|
|
509
|
+
* `RequestBuilder` already resolved for those two fields, not off
|
|
510
|
+
* whatever ends up on the wire request. `messages`/`tools` are joined by
|
|
511
|
+
* a separate `add*` field, appended rather than replaced, so two
|
|
512
|
+
* independently written middleware can each add to the list without one
|
|
513
|
+
* silently clobbering what the other already added.
|
|
514
|
+
*/
|
|
515
|
+
interface WireCallRequestPatch {
|
|
516
|
+
temperature?: number;
|
|
517
|
+
max_tokens?: number;
|
|
518
|
+
reasoning_effort?: 'minimal' | 'low' | 'medium' | 'high';
|
|
519
|
+
budget_tokens?: number;
|
|
520
|
+
tool_choice?: WireToolChoice;
|
|
521
|
+
/** Replaces the whole message list. Prefer `addMessages` unless a full replace is genuinely the intent. */
|
|
522
|
+
messages?: WireMessage[];
|
|
523
|
+
/** Appended after whatever earlier middleware already added. Never clobbers a prior addition. */
|
|
524
|
+
addMessages?: WireMessage[];
|
|
525
|
+
/** Replaces the whole tool list. Prefer `addTools`, same reasoning as `messages`/`addMessages`. */
|
|
526
|
+
tools?: WireTool[];
|
|
527
|
+
/** Appended after whatever earlier middleware already added. Never clobbers a prior addition. */
|
|
528
|
+
addTools?: WireTool[];
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* The settled outcome of one logical call, passed to `wrap`'s `next()`.
|
|
532
|
+
* `meta` is populated once a target has actually answered, for both
|
|
533
|
+
* streaming and non-streaming calls (`undefined` only on a cache hit,
|
|
534
|
+
* where nothing was actually spent).
|
|
535
|
+
*/
|
|
536
|
+
interface CallResult<T = unknown> {
|
|
537
|
+
value: T;
|
|
538
|
+
meta?: CallMeta;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* One entry in `VernLLMOptions.middleware`. All four hooks are optional;
|
|
542
|
+
* an entry that sets none of them is inert. See the middleware docs for
|
|
543
|
+
* how `transform`, `wrap`, `onEvent`, and `enabled` compose across
|
|
544
|
+
* several entries.
|
|
545
|
+
*/
|
|
546
|
+
interface VernLLMMiddleware {
|
|
547
|
+
/** Used in log lines and the `'middleware'` event. Defaults to this entry's array position when omitted. */
|
|
548
|
+
name?: string;
|
|
549
|
+
/** Sort key for composition order, ascending, ties broken by array order. See the middleware docs for what "lower runs first" means for `wrap`. */
|
|
550
|
+
priority?: number;
|
|
551
|
+
/**
|
|
552
|
+
* Boolean for a static on/off switch, or a predicate evaluated per
|
|
553
|
+
* call. A throwing, rejecting, or timed-out predicate is logged and
|
|
554
|
+
* treated as `false` for that call.
|
|
555
|
+
*/
|
|
556
|
+
enabled?: boolean | ((ctx: MiddlewareContext) => boolean | Promise<boolean>);
|
|
557
|
+
/** Per-middleware override of the instance-level `middlewareTimeoutMs`, applied to this entry's `transform` and function `enabled`. `<= 0` means unbounded (no timer at all). */
|
|
558
|
+
timeoutMs?: number;
|
|
559
|
+
/** Transforms the outgoing wire request for one attempt. Runs once per attempt, including retries. `ctx` is always accurate to the real target for this attempt. */
|
|
560
|
+
transform?: (request: Readonly<WireCallRequest>, ctx: AttemptContext) => WireCallRequestPatch | Promise<WireCallRequestPatch>;
|
|
561
|
+
/**
|
|
562
|
+
* Wraps one whole logical call, exactly once, regardless of how many
|
|
563
|
+
* retries or fallback targets ran underneath it. `ctx` is built once,
|
|
564
|
+
* before any fallback target is chosen, so it only describes the
|
|
565
|
+
* primary target. There is no `requestedProvider`/`isFallbackAttempt`/
|
|
566
|
+
* `attempt` to read here. Read `next()`'s resolved `CallResult.meta`
|
|
567
|
+
* for what actually happened.
|
|
568
|
+
*/
|
|
569
|
+
wrap?: (request: Readonly<WireCallRequest>, next: () => Promise<CallResult>, ctx: PreDispatchContext) => Promise<CallResult>;
|
|
570
|
+
/** Observes the same events reported on `VernLLMOptions.onEvent`, filtered by this middleware's own `enabled`. Called from both stages; narrow on `ctx.stage` before reading stage-specific fields. */
|
|
571
|
+
onEvent?: (event: VernLLMEvent, ctx: MiddlewareContext) => void;
|
|
572
|
+
}
|
|
305
573
|
//#endregion
|
|
306
574
|
//#region src/circuitBreaker.d.ts
|
|
307
|
-
|
|
575
|
+
/** The call this mutation happened as part of, forwarded to `onStateChange` untouched. */
|
|
576
|
+
interface CircuitBreakerCallContext {
|
|
577
|
+
requestId: string;
|
|
578
|
+
state: MiddlewareStateBag;
|
|
579
|
+
signal?: AbortSignal;
|
|
580
|
+
/** Omitted for calls before any attempt exists, like `assertClosed`'s pre-dispatch check. */
|
|
581
|
+
attempt?: number;
|
|
582
|
+
}
|
|
308
583
|
interface CircuitBreakerOptions {
|
|
309
584
|
/** Consecutive failures before the circuit opens, default 5 */
|
|
310
585
|
threshold?: number;
|
|
311
586
|
/** How long the circuit stays open before allowing a trial request, in ms. Default 30000 */
|
|
312
587
|
cooldownMs?: number;
|
|
313
588
|
/**
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
*
|
|
317
|
-
* of `assertClosed`/`recordSuccess`/`recordFailure` caused it).
|
|
318
|
-
*
|
|
319
|
-
* With `isolateByModel` off (the default), this is a label only: the
|
|
320
|
-
* breaker still counts failures across every model together, so a
|
|
321
|
-
* threshold crossing can be the sum of several different models'
|
|
322
|
-
* failures even though only the triggering call's `model` is reported
|
|
323
|
-
* here. With `isolateByModel` on, it's exact: each model has its own
|
|
324
|
-
* counter, so the transition really was caused solely by that model.
|
|
589
|
+
* Fires after every real state change, never a no-op transition. `model`
|
|
590
|
+
* is the resolved model of whichever call triggered it. With
|
|
591
|
+
* `isolateByModel` off, failures are still counted across every model.
|
|
325
592
|
*/
|
|
326
|
-
onStateChange?: (from: CircuitState, to: CircuitState, consecutiveFailures: number, model?: string) => void;
|
|
593
|
+
onStateChange?: (from: CircuitState, to: CircuitState, consecutiveFailures: number, model?: string, context?: CircuitBreakerCallContext) => void;
|
|
327
594
|
/**
|
|
328
595
|
* Track a separate circuit per resolved model instead of one shared
|
|
329
|
-
* circuit
|
|
330
|
-
*
|
|
331
|
-
* an outage spread across many distinct models (each model's counter
|
|
332
|
-
* must independently cross `threshold`). Default false: one shared
|
|
333
|
-
* circuit, matching every version before this option existed.
|
|
334
|
-
*
|
|
335
|
-
* A call that omits `model` (only possible calling `CircuitBreaker`
|
|
336
|
-
* directly, `VernLLM` always passes one) falls into one shared bucket
|
|
337
|
-
* alongside every other call that also omits it.
|
|
596
|
+
* circuit. Default false. A call that omits `model` falls into one
|
|
597
|
+
* shared bucket alongside every other call that also omits it.
|
|
338
598
|
*/
|
|
339
599
|
isolateByModel?: boolean;
|
|
600
|
+
/** Trial calls allowed through per half-open cycle. Default 1, clamped to at least 1. */
|
|
601
|
+
halfOpenProbes?: number;
|
|
602
|
+
/** Fraction of `halfOpenProbes` that must succeed to close the circuit. Default 1, clamped to `[0, 1]`. */
|
|
603
|
+
halfOpenSuccessRatio?: number;
|
|
604
|
+
/**
|
|
605
|
+
* Grows `cooldownMs` on each repeat open instead of a fixed wait.
|
|
606
|
+
* `{ multiplier, maxMs }` covers exponential growth; a `CooldownBackoff`
|
|
607
|
+
* function covers anything else. Omitted means `cooldownMs` stays fixed.
|
|
608
|
+
*/
|
|
609
|
+
cooldownBackoff?: ExponentialBackoffOptions | CooldownBackoff;
|
|
610
|
+
/**
|
|
611
|
+
* Decides when a bucket's failures should open the circuit.
|
|
612
|
+
* `{ kind: 'consecutive', threshold }` (the default) opens after that
|
|
613
|
+
* many failures in a row. `{ kind: 'rolling', windowMs, minCalls,
|
|
614
|
+
* failureRatio }` opens once at least `minCalls` calls have landed in
|
|
615
|
+
* the trailing `windowMs` and the failure ratio reaches `failureRatio`.
|
|
616
|
+
* `minCalls` must be a non-negative integer; `failureRatio` must be
|
|
617
|
+
* finite and within `[0, 1]`. Both are validated at construction,
|
|
618
|
+
* thrown as `RangeError`. A `TrippingPolicy` covers anything else, one
|
|
619
|
+
* instance shared across every model automatically under
|
|
620
|
+
* `isolateByModel`, since it tracks its own state per key rather than
|
|
621
|
+
* owning one flat counter.
|
|
622
|
+
*/
|
|
623
|
+
tripping?: TrippingOption;
|
|
624
|
+
}
|
|
625
|
+
/** Computes the cooldown for a bucket's `reopenCount`-th repeat open. */
|
|
626
|
+
type CooldownBackoff = (reopenCount: number, baseCooldownMs: number) => number;
|
|
627
|
+
interface ExponentialBackoffOptions {
|
|
628
|
+
/** Growth factor applied per repeat open, e.g. 2 doubles each time. */
|
|
629
|
+
multiplier: number;
|
|
630
|
+
/** Upper bound on the computed cooldown, in ms. Default `Infinity`. */
|
|
631
|
+
maxMs?: number;
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Decides when a bucket's failures should open the circuit. Keyed by
|
|
635
|
+
* `key` (a resolved model, or the shared bucket's key when
|
|
636
|
+
* `isolateByModel` is off) rather than holding one flat counter, so a
|
|
637
|
+
* single `TrippingPolicy` instance is always safe to share across every
|
|
638
|
+
* bucket: `CircuitBreaker` never needs to clone or construct a fresh one
|
|
639
|
+
* per model, `isolateByModel` isolation falls out of `key` alone.
|
|
640
|
+
*/
|
|
641
|
+
interface TrippingPolicy {
|
|
642
|
+
onSuccess(key: string): void;
|
|
643
|
+
/** Returns true if this failure should open the circuit for `key`. */
|
|
644
|
+
onFailure(key: string): boolean;
|
|
645
|
+
reset(key: string): void;
|
|
646
|
+
/**
|
|
647
|
+
* Called when `key`'s bucket is discarded (closed and idle, under
|
|
648
|
+
* `isolateByModel`), so a keyed policy can release that key's state.
|
|
649
|
+
* Optional: omit if there's nothing to release.
|
|
650
|
+
*/
|
|
651
|
+
forget?(key: string): void;
|
|
652
|
+
}
|
|
653
|
+
declare class ConsecutiveTripping implements TrippingPolicy {
|
|
654
|
+
private readonly threshold;
|
|
655
|
+
private failuresByKey;
|
|
656
|
+
constructor(threshold: number);
|
|
657
|
+
onSuccess(key: string): void;
|
|
658
|
+
onFailure(key: string): boolean;
|
|
659
|
+
reset(key: string): void;
|
|
660
|
+
forget(key: string): void;
|
|
661
|
+
}
|
|
662
|
+
declare class RollingTripping implements TrippingPolicy {
|
|
663
|
+
private readonly windowMs;
|
|
664
|
+
private readonly minCalls;
|
|
665
|
+
private readonly failureRatio;
|
|
666
|
+
private ratiosByKey;
|
|
667
|
+
constructor(windowMs: number, minCalls: number, failureRatio: number);
|
|
668
|
+
private ratioFor;
|
|
669
|
+
onSuccess(key: string): void;
|
|
670
|
+
onFailure(key: string): boolean;
|
|
671
|
+
reset(key: string): void;
|
|
672
|
+
forget(key: string): void;
|
|
340
673
|
}
|
|
674
|
+
/** Not exported. Internal shorthand union for `CircuitBreakerOptions.tripping`. */
|
|
675
|
+
type TrippingOption = {
|
|
676
|
+
kind: 'consecutive';
|
|
677
|
+
threshold: number;
|
|
678
|
+
} | {
|
|
679
|
+
kind: 'rolling';
|
|
680
|
+
windowMs: number;
|
|
681
|
+
minCalls: number;
|
|
682
|
+
failureRatio: number;
|
|
683
|
+
} | TrippingPolicy;
|
|
341
684
|
type CircuitState = 'closed' | 'open' | 'half-open';
|
|
342
685
|
/**
|
|
343
|
-
* Per retry VernLLM-instance circuit breaker. Tracks consecutive failures
|
|
344
|
-
* calls. Once the threshold is hit, short-circuits new calls with
|
|
345
|
-
* LLMError('circuit_open')
|
|
346
|
-
* cooldown elapses and a single trial call is allowed through
|
|
686
|
+
* Per retry VernLLM-instance circuit breaker. Tracks consecutive failures
|
|
687
|
+
* across calls. Once the threshold is hit, short-circuits new calls with
|
|
688
|
+
* LLMError('circuit_open') until the cooldown elapses and a trial succeeds.
|
|
347
689
|
*/
|
|
348
690
|
declare class CircuitBreaker {
|
|
349
|
-
private readonly threshold;
|
|
350
691
|
private readonly cooldownMs;
|
|
351
692
|
private readonly onStateChange?;
|
|
352
|
-
/** Whether this breaker tracks failures per model instead of one shared circuit.
|
|
693
|
+
/** Whether this breaker tracks failures per model instead of one shared circuit. */
|
|
353
694
|
readonly isolateByModel: boolean;
|
|
695
|
+
private readonly halfOpenProbes;
|
|
696
|
+
private readonly halfOpenSuccessRatio;
|
|
697
|
+
private readonly cooldownBackoff?;
|
|
698
|
+
/** One instance, keyed per model internally. See `TrippingPolicy`. */
|
|
699
|
+
private readonly tripping;
|
|
354
700
|
private readonly sharedBucket;
|
|
355
701
|
private readonly bucketsByModel;
|
|
356
702
|
constructor(options?: CircuitBreakerOptions);
|
|
357
|
-
/** Returns the bucket for a model if one already exists, without allocating. */
|
|
358
|
-
private lookupBucket;
|
|
359
|
-
/** Creates and stores a bucket for a model when the first mutation needs one. */
|
|
360
|
-
private ensureBucketFor;
|
|
361
|
-
/** Every state mutation routes through here, so `onStateChange` fires exactly once per real change. */
|
|
362
|
-
private transition;
|
|
363
703
|
/**
|
|
364
704
|
* Throws if the circuit is open and the cooldown hasn't elapsed, or if
|
|
365
|
-
*
|
|
366
|
-
* Otherwise, if the circuit just became eligible for a trial (cooldown
|
|
367
|
-
* elapsed, or half-open with no trial currently running), this call
|
|
368
|
-
* becomes that trial
|
|
369
|
-
*/
|
|
370
|
-
assertClosed(model?: string): void;
|
|
371
|
-
recordSuccess(model?: string): void;
|
|
372
|
-
recordFailure(model?: string): void;
|
|
373
|
-
/**
|
|
374
|
-
* With `isolateByModel` off (the default), `model` is ignored and the
|
|
375
|
-
* one shared circuit's state is returned, unchanged from every version
|
|
376
|
-
* before this option existed. With `isolateByModel` on, returns that
|
|
377
|
-
* model's own state, `'closed'` for a model never seen yet, same as a
|
|
378
|
-
* fresh breaker.
|
|
705
|
+
* half-open with every trial slot claimed. Otherwise claims a trial slot.
|
|
379
706
|
*/
|
|
707
|
+
assertClosed(model?: string, context?: CircuitBreakerCallContext): void;
|
|
708
|
+
recordSuccess(model?: string, context?: CircuitBreakerCallContext): void;
|
|
709
|
+
/** `code`, when present, is the failing `LLMError`'s `code`. Missing attributes to `'unknown'`. */
|
|
710
|
+
recordFailure(model?: string, context?: CircuitBreakerCallContext, code?: LLMErrorCode): void;
|
|
711
|
+
/** With `isolateByModel` off, `model` is ignored and the shared circuit's state is returned. */
|
|
380
712
|
getState(model?: string): CircuitState;
|
|
713
|
+
/** Failure counts by `LLMErrorCode` for `model`'s bucket. Returned as a plain object copy. */
|
|
714
|
+
getFailureBreakdown(model?: string): Partial<Record<LLMErrorCode | 'unknown', number>>;
|
|
715
|
+
/** Manually opens the circuit, as if `threshold` consecutive failures had just happened. */
|
|
716
|
+
open(model?: string, context?: CircuitBreakerCallContext): void;
|
|
717
|
+
/** Manually closes the circuit and resets its failure count, without requiring a real success first. */
|
|
718
|
+
close(model?: string, context?: CircuitBreakerCallContext): void;
|
|
719
|
+
/**
|
|
720
|
+
* Opens `bucket`: stamps `openedAt`/`cooldownMsForOpen` and transitions
|
|
721
|
+
* to `open`. Shared by `recordFailure`'s trip, `settleTrialIfComplete`'s
|
|
722
|
+
* reopen, and the manual `open()`, all of which reach this with
|
|
723
|
+
* `bucket.trial` already `null`.
|
|
724
|
+
*/
|
|
725
|
+
private openBucket;
|
|
726
|
+
/** Computes and clamps the cooldown for `bucket`'s current `reopenCount`. Called once, on open. */
|
|
727
|
+
private computeCooldown;
|
|
728
|
+
/** Returns the bucket for a model if one already exists, without allocating. */
|
|
729
|
+
private lookupBucket;
|
|
381
730
|
/**
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
*
|
|
386
|
-
*
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
/**
|
|
390
|
-
* Manually closes the circuit and resets its failure count, e.g. once a
|
|
391
|
-
* provider is confirmed healthy again without waiting out the cooldown.
|
|
392
|
-
* Mirrors `recordSuccess`'s bookkeeping (including dropping the
|
|
393
|
-
* per-model bucket under `isolateByModel`, once idle) but without
|
|
394
|
-
* requiring an actual successful call first.
|
|
731
|
+
* The key `tripping` is called with. Real per-model isolation under
|
|
732
|
+
* `isolateByModel`, matching `ensureBucketFor`/`lookupBucket`'s own
|
|
733
|
+
* per-model key. Otherwise one fixed shared key regardless of what
|
|
734
|
+
* `model` was passed, matching `sharedBucket` being the one and only
|
|
735
|
+
* bucket in that mode: `model` is never allowed to split tripping state
|
|
736
|
+
* when `isolateByModel` is off, the same way it never splits which
|
|
737
|
+
* bucket a call lands in.
|
|
395
738
|
*/
|
|
396
|
-
|
|
739
|
+
private trippingKeyFor;
|
|
740
|
+
/** Creates and stores a bucket for a model when the first mutation needs one. */
|
|
741
|
+
private ensureBucketFor;
|
|
742
|
+
/** Drops an idle model's bucket and lets `tripping` release that key's state too. */
|
|
743
|
+
private forgetModel;
|
|
744
|
+
/** Every state mutation routes through here, so `onStateChange` fires exactly once per real change. */
|
|
745
|
+
private transition;
|
|
746
|
+
/** Once every admitted trial has reported in, closes or reopens based on `halfOpenSuccessRatio`. */
|
|
747
|
+
private settleTrialIfComplete;
|
|
748
|
+
}
|
|
749
|
+
//#endregion
|
|
750
|
+
//#region src/internal/retryBudget.d.ts
|
|
751
|
+
/**
|
|
752
|
+
* Tunables for a `RetryBudget`. `windowMs`/`minCalls` behave the same as
|
|
753
|
+
* `RollingTripping`'s (see `circuitBreaker.ts`): `minCalls` gates the
|
|
754
|
+
* check so a cold start with too little traffic to judge doesn't trip.
|
|
755
|
+
* `retryRatio` is the max fraction of calls in the window allowed to be
|
|
756
|
+
* retries before the budget stops allowing more. `minCalls` must be a
|
|
757
|
+
* non-negative integer; `retryRatio` must be finite and within `[0, 1]`.
|
|
758
|
+
* Both are validated at construction, thrown as `RangeError`.
|
|
759
|
+
*/
|
|
760
|
+
interface RetryBudgetOptions {
|
|
761
|
+
windowMs: number;
|
|
762
|
+
minCalls: number;
|
|
763
|
+
retryRatio: number;
|
|
764
|
+
}
|
|
765
|
+
/**
|
|
766
|
+
* Caps how much of a target's recent traffic is allowed to be retries,
|
|
767
|
+
* independent of the circuit breaker. The breaker asks whether the
|
|
768
|
+
* provider is healthy; this asks whether retrying is still worth the
|
|
769
|
+
* capacity it costs, regardless of provider health. Reuses `RollingRatio`,
|
|
770
|
+
* the same primitive `RollingTripping` is built on, rather than a second
|
|
771
|
+
* hand rolled window.
|
|
772
|
+
*/
|
|
773
|
+
declare class RetryBudget {
|
|
774
|
+
private readonly options;
|
|
775
|
+
private readonly ratio;
|
|
776
|
+
constructor(options: RetryBudgetOptions);
|
|
777
|
+
/**
|
|
778
|
+
* Throws `LLMError('retry_budget_exhausted')` once at least `minCalls`
|
|
779
|
+
* calls have landed in the trailing `windowMs` and the retry ratio
|
|
780
|
+
* among them has reached `retryRatio`. A no-op otherwise.
|
|
781
|
+
*/
|
|
782
|
+
assertAvailable(): void;
|
|
783
|
+
/** Records one attempt. `isRetry` is false for a call's first attempt, true for every attempt after it. */
|
|
784
|
+
recordAttempt(isRetry: boolean): void;
|
|
785
|
+
/** Current traffic and retry ratio in the trailing window. */
|
|
786
|
+
getSnapshot(): {
|
|
787
|
+
attempts: number;
|
|
788
|
+
retryRatio: number;
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
//#endregion
|
|
792
|
+
//#region src/internal/utils/rateLimitHint.utils.d.ts
|
|
793
|
+
/** A normalized read of a provider's rate limit headers. */
|
|
794
|
+
interface ProviderRateLimitHint {
|
|
795
|
+
remainingRequests?: number;
|
|
796
|
+
limitRequests?: number;
|
|
797
|
+
resetAfterMs?: number;
|
|
397
798
|
}
|
|
398
|
-
|
|
399
799
|
//#endregion
|
|
400
800
|
//#region src/rateLimit.d.ts
|
|
401
|
-
//# sourceMappingURL=circuitBreaker.d.ts.map
|
|
402
801
|
/** The request shape sent to `LLMClient['chat']['completions']['create']`, used for token estimation. */
|
|
403
802
|
type WireRequest = Parameters<LLMClient['chat']['completions']['create']>[0];
|
|
404
803
|
/** Which configured bucket is currently blocking a call. */
|
|
@@ -427,6 +826,27 @@ interface RateLimitOptions {
|
|
|
427
826
|
* chars/4 heuristic over message content plus `max_tokens`.
|
|
428
827
|
*/
|
|
429
828
|
estimateTokens?: (request: WireRequest) => number;
|
|
829
|
+
/**
|
|
830
|
+
* AIMD against the `requestsPerMinute` bucket. Omit for a fixed
|
|
831
|
+
* ceiling, today's behavior. Requires `requestsPerMinute`.
|
|
832
|
+
*/
|
|
833
|
+
aimd?: AimdOptions;
|
|
834
|
+
}
|
|
835
|
+
interface AimdOptions {
|
|
836
|
+
/** Added to the requests-per-minute ceiling on every clean release. */
|
|
837
|
+
increaseBy: number;
|
|
838
|
+
/** Multiplied against the ceiling on a rate-limit signal. Must be in `(0, 1]`; clamped otherwise. */
|
|
839
|
+
decreaseFactor: number;
|
|
840
|
+
/** Floor the ceiling never shrinks below. */
|
|
841
|
+
minCapacity: number;
|
|
842
|
+
/** Ceiling the bucket never grows above. */
|
|
843
|
+
maxCapacity: number;
|
|
844
|
+
/**
|
|
845
|
+
* Shrink proactively once a provider hint reports `remainingRequests`
|
|
846
|
+
* at or below this, before a real 429 happens. Default 0, meaning
|
|
847
|
+
* off.
|
|
848
|
+
*/
|
|
849
|
+
proactiveFloor?: number;
|
|
430
850
|
}
|
|
431
851
|
interface RateLimitAcquireResult {
|
|
432
852
|
/**
|
|
@@ -435,7 +855,7 @@ interface RateLimitAcquireResult {
|
|
|
435
855
|
* Idempotent: only the first call does anything. Must run in a
|
|
436
856
|
* `finally` block so a slot is never leaked on a failed attempt.
|
|
437
857
|
*/
|
|
438
|
-
release: (actualTokens?: number) => void;
|
|
858
|
+
release: (actualTokens?: number, success?: boolean) => void;
|
|
439
859
|
/** How long this attempt waited in queue before capacity was available. */
|
|
440
860
|
waitedMs: number;
|
|
441
861
|
/** Which bucket was blocking this attempt just before it cleared, if any wait happened. */
|
|
@@ -443,19 +863,35 @@ interface RateLimitAcquireResult {
|
|
|
443
863
|
}
|
|
444
864
|
/** Default `estimateTokens`: chars/4 over every message's content, plus the requested `max_tokens`. */
|
|
445
865
|
declare function defaultEstimateTokens(request: WireRequest): number;
|
|
866
|
+
/**
|
|
867
|
+
* What VernLLM's dispatch layer needs from a limiter. `RateLimiter`
|
|
868
|
+
* implements this; a caller wanting cross-process coordination can hand
|
|
869
|
+
* over their own instance instead, see `buildRateLimit`. Every method is
|
|
870
|
+
* required, `RateLimiter` itself already no-ops the AIMD methods when
|
|
871
|
+
* `aimd` isn't configured, so a custom limiter follows the same pattern.
|
|
872
|
+
*/
|
|
873
|
+
interface RateLimiterAdapter {
|
|
874
|
+
estimate(request: WireRequest): number;
|
|
875
|
+
acquire(estimatedTokens: number, signal?: AbortSignal): Promise<RateLimitAcquireResult>;
|
|
876
|
+
signalRateLimit(): void;
|
|
877
|
+
reactToRateLimitHint(hint: ProviderRateLimitHint | undefined): void;
|
|
878
|
+
}
|
|
446
879
|
/**
|
|
447
880
|
* Per-target rate limiter. Up to three buckets (requests/min, tokens/min,
|
|
448
881
|
* concurrency) behind one FIFO queue, so a large call isn't starved by a
|
|
449
882
|
* stream of small ones. Any bucket omitted from `options` has infinite
|
|
450
883
|
* capacity and never blocks.
|
|
451
884
|
*/
|
|
452
|
-
declare class RateLimiter {
|
|
885
|
+
declare class RateLimiter implements RateLimiterAdapter {
|
|
453
886
|
private readonly requests?;
|
|
454
887
|
private readonly tokens?;
|
|
455
888
|
private readonly concurrency?;
|
|
889
|
+
/** Buckets in acquire precedence order (concurrency, rpm, tpm), omitted ones filtered out. Built once so order can't drift between `tryAcquireBuckets` and `scheduleWake`. */
|
|
890
|
+
private readonly buckets;
|
|
456
891
|
private readonly maxQueueMs;
|
|
457
892
|
private readonly maxQueueSize;
|
|
458
893
|
private readonly estimateTokensFn;
|
|
894
|
+
private readonly aimd?;
|
|
459
895
|
private readonly queue;
|
|
460
896
|
/**
|
|
461
897
|
* A single scheduled re-check for the head of the queue when it's
|
|
@@ -476,12 +912,7 @@ declare class RateLimiter {
|
|
|
476
912
|
acquire(estimatedTokens: number, signal?: AbortSignal): Promise<RateLimitAcquireResult>;
|
|
477
913
|
private queueFullError;
|
|
478
914
|
private enqueue;
|
|
479
|
-
/**
|
|
480
|
-
* Checks and takes from every configured bucket as one atomic unit: if
|
|
481
|
-
* any bucket lacks capacity, whatever was already taken from the
|
|
482
|
-
* earlier ones in this attempt is rolled back before reporting which
|
|
483
|
-
* bucket blocked.
|
|
484
|
-
*/
|
|
915
|
+
/** Takes from every configured bucket as one atomic unit, in `this.buckets`' order. Rolls back whatever was already taken if any bucket lacks capacity. */
|
|
485
916
|
private tryAcquireBuckets;
|
|
486
917
|
/** Drains the queue head first. Stops at the first waiter that still can't proceed, so no one is starved out of turn. */
|
|
487
918
|
private drain;
|
|
@@ -498,13 +929,37 @@ declare class RateLimiter {
|
|
|
498
929
|
* bucket is a real spend that only recovers via its own refill, and the
|
|
499
930
|
* tokens bucket is reconciled against `actualTokens` rather than fully
|
|
500
931
|
* refunded, since real tokens really were spent.
|
|
932
|
+
*
|
|
933
|
+
* `success` defaults to `false`: the AIMD ceiling only grows when the
|
|
934
|
+
* caller explicitly confirms a successful attempt. A failed or
|
|
935
|
+
* rate-limited attempt still releases its slot (so nothing leaks), but
|
|
936
|
+
* must not also grow the ceiling right back up after
|
|
937
|
+
* `signalRateLimit()` just shrank it.
|
|
501
938
|
*/
|
|
502
939
|
private makeRelease;
|
|
940
|
+
/** Shared guard and resize call behind both AIMD halves below; only the arithmetic differs. */
|
|
941
|
+
private resizeRequestsCeiling;
|
|
942
|
+
/** AIMD's additive-increase half: grows the ceiling by `aimd.increaseBy` on a clean release. No-op without `aimd`/`requestsPerMinute`. */
|
|
943
|
+
private growOnSuccess;
|
|
944
|
+
/**
|
|
945
|
+
* AIMD's multiplicative-decrease half. Called on a real 429, and,
|
|
946
|
+
* where an adapter can produce a hint, proactively via
|
|
947
|
+
* `reactToRateLimitHint`. Never throws or blocks a call itself, only
|
|
948
|
+
* adjusts the ceiling as a side effect.
|
|
949
|
+
*/
|
|
950
|
+
signalRateLimit(): void;
|
|
951
|
+
/**
|
|
952
|
+
* AIMD's proactive entry point: shrinks via `signalRateLimit()` if
|
|
953
|
+
* `hint.remainingRequests` is at or below `aimd.proactiveFloor`.
|
|
954
|
+
*/
|
|
955
|
+
reactToRateLimitHint(hint: ProviderRateLimitHint | undefined): void;
|
|
503
956
|
}
|
|
504
|
-
|
|
957
|
+
//#endregion
|
|
958
|
+
//#region src/internal/utils/rateLimitAdapter.utils.d.ts
|
|
959
|
+
/** Not exported. Internal shorthand only, so this union isn't duplicated between the public option fields and `buildRateLimit`'s own signature. */
|
|
960
|
+
type RateLimitOption = RateLimitOptions | RateLimiterAdapter;
|
|
505
961
|
//#endregion
|
|
506
962
|
//#region src/types/fallback.d.ts
|
|
507
|
-
//# sourceMappingURL=rateLimit.d.ts.map
|
|
508
963
|
/**
|
|
509
964
|
* One provider to try after the primary (or after an earlier fallback
|
|
510
965
|
* target) fails. Order is the policy: VernLLM never reorders, scores, or
|
|
@@ -513,11 +968,11 @@ declare class RateLimiter {
|
|
|
513
968
|
* Most per-target overrides fall back to the parent `VernLLM` instance's
|
|
514
969
|
* own option when omitted, so a target only needs to specify what's
|
|
515
970
|
* actually different about it (a different client/model is the common
|
|
516
|
-
* case). `circuitBreaker` and `
|
|
517
|
-
* never inherited from the parent, since a breaker
|
|
518
|
-
* the primary provider's limits is rarely
|
|
519
|
-
* them unset on a target to run it without
|
|
520
|
-
* one configured.
|
|
971
|
+
* case). `circuitBreaker`, `rateLimit`, and `retryBudget` are the
|
|
972
|
+
* exception: they are never inherited from the parent, since a breaker,
|
|
973
|
+
* limiter, or budget tuned for the primary provider's limits is rarely
|
|
974
|
+
* right for a fallback's. Leave them unset on a target to run it without
|
|
975
|
+
* one, even if the parent has one configured.
|
|
521
976
|
*/
|
|
522
977
|
interface FallbackTarget {
|
|
523
978
|
client: LLMClient;
|
|
@@ -536,7 +991,16 @@ interface FallbackTarget {
|
|
|
536
991
|
/** This target's own circuit breaker, independent of every other target's. Not inherited from the parent's `circuitBreaker`. */
|
|
537
992
|
circuitBreaker?: boolean | CircuitBreakerOptions;
|
|
538
993
|
/** This target's own rate limiter, independent of every other target's. Not inherited from the parent's `rateLimit`. */
|
|
539
|
-
rateLimit?:
|
|
994
|
+
rateLimit?: RateLimitOption;
|
|
995
|
+
/** This target's own retry budget, independent of every other target's. Not inherited from the parent's `retryBudget`. */
|
|
996
|
+
retryBudget?: RetryBudgetOptions;
|
|
997
|
+
/**
|
|
998
|
+
* Reclassifies an otherwise-successful result from this target as a
|
|
999
|
+
* failure. Falls back to the parent `VernLLM` instance's own
|
|
1000
|
+
* `detectSoftFailure` when omitted, same as most other per-target
|
|
1001
|
+
* options (unlike `circuitBreaker`/`rateLimit`, which never inherit).
|
|
1002
|
+
*/
|
|
1003
|
+
detectSoftFailure?: DetectSoftFailure;
|
|
540
1004
|
}
|
|
541
1005
|
/**
|
|
542
1006
|
* Written into `CallParams['meta']` once `call()` resolves, so a caller
|
|
@@ -616,10 +1080,21 @@ declare class FallbackExhaustedError extends LLMError {
|
|
|
616
1080
|
}
|
|
617
1081
|
/** Narrows `err` to {@link FallbackExhaustedError}, for direct access to its `attempts` (`provider`/`model` per failed target) without a manual `instanceof` check. */
|
|
618
1082
|
declare function isFallbackExhaustedError(err: unknown): err is FallbackExhaustedError;
|
|
619
|
-
|
|
1083
|
+
/**
|
|
1084
|
+
* Creates an empty ref box to pass as `CallParams['meta']`, so a caller can
|
|
1085
|
+
* read the `CallMeta` written by `call()` on the same line as the result
|
|
1086
|
+
* instead of pre-declaring a `{ current?: CallMeta }` by hand.
|
|
1087
|
+
*
|
|
1088
|
+
* @example
|
|
1089
|
+
* const meta = metaRef();
|
|
1090
|
+
* const result = await vern.call({ userContent: '...', meta });
|
|
1091
|
+
* meta.current?.provider;
|
|
1092
|
+
*/
|
|
1093
|
+
declare function metaRef(): {
|
|
1094
|
+
current?: CallMeta;
|
|
1095
|
+
};
|
|
620
1096
|
//#endregion
|
|
621
1097
|
//#region src/types/schema.d.ts
|
|
622
|
-
//# sourceMappingURL=fallback.d.ts.map
|
|
623
1098
|
/**
|
|
624
1099
|
* Minimal structural type for a Zod-like schema, so this package doesnt need
|
|
625
1100
|
* a hard dependency on a specific Zod major version. Any object exposing
|
|
@@ -649,10 +1124,8 @@ interface JsonSchemaSpec {
|
|
|
649
1124
|
strict?: boolean;
|
|
650
1125
|
description?: string;
|
|
651
1126
|
}
|
|
652
|
-
|
|
653
1127
|
//#endregion
|
|
654
1128
|
//#region src/types/tools.d.ts
|
|
655
|
-
//# sourceMappingURL=schema.d.ts.map
|
|
656
1129
|
/**
|
|
657
1130
|
* Describes a capability the model may request, not the capability
|
|
658
1131
|
* itself. VernLLM transports this to the provider and parses what comes
|
|
@@ -687,7 +1160,7 @@ interface ToolDefinition<Name extends string = string, Args = unknown> {
|
|
|
687
1160
|
* to `string` unless annotated `as const`, which silently defeats
|
|
688
1161
|
* `ToolCall` narrowing the moment a second tool is added to the same
|
|
689
1162
|
* `tools: [...]` array (single-tool arrays still narrow fine even without
|
|
690
|
-
* this, since there's nothing to discriminate against
|
|
1163
|
+
* this, since there's nothing to discriminate against but that stops
|
|
691
1164
|
* being true as soon as a second tool shows up). Wrapping the same object
|
|
692
1165
|
* in `defineTool()` preserves the literal `name` type without requiring
|
|
693
1166
|
* `as const` at every call site.
|
|
@@ -704,7 +1177,7 @@ type ToolCallFor<T> = T extends ToolDefinition<infer N, infer A> ? {
|
|
|
704
1177
|
*
|
|
705
1178
|
* When `Tools` is a literal tuple (e.g. inferred from `tools: [getWeather,
|
|
706
1179
|
* cancelOrder]` at a `call()`/`cachedCall()` site), this is a discriminated
|
|
707
|
-
* union keyed by `name
|
|
1180
|
+
* union keyed by `name`. Checking `call.name === 'get_weather'` narrows
|
|
708
1181
|
* `call.arguments` to that tool's `Args` with no cast needed. Without a
|
|
709
1182
|
* literal `Tools` (the default), this collapses back to today's
|
|
710
1183
|
* `{ id: string; name: string; arguments: unknown }`.
|
|
@@ -803,7 +1276,6 @@ declare function isToolCallResult<Tools extends readonly ToolDefinition[] | unde
|
|
|
803
1276
|
type ToolChoice = 'auto' | 'none' | 'required' | {
|
|
804
1277
|
name: string;
|
|
805
1278
|
};
|
|
806
|
-
|
|
807
1279
|
//#endregion
|
|
808
1280
|
//#region src/types/usage.d.ts
|
|
809
1281
|
type ReserveUsage = (params: {
|
|
@@ -869,10 +1341,8 @@ type OnUsage = (usage: TokenUsage) => void;
|
|
|
869
1341
|
* to report.
|
|
870
1342
|
*/
|
|
871
1343
|
type OnUsageFailure = (usage: TokenUsage, error: LLMError) => void;
|
|
872
|
-
|
|
873
1344
|
//#endregion
|
|
874
1345
|
//#region src/types/call.d.ts
|
|
875
|
-
//# sourceMappingURL=usage.d.ts.map
|
|
876
1346
|
/**
|
|
877
1347
|
* Any valid JSON value: a primitive, `null`, or a JSON array/object made
|
|
878
1348
|
* of the same. This is what `call()` returns when `jsonMode: true`.
|
|
@@ -928,13 +1398,21 @@ interface ImageBlock {
|
|
|
928
1398
|
}
|
|
929
1399
|
/** A single segment of multimodal `userContent`. */
|
|
930
1400
|
type ContentBlock = TextBlock | ImageBlock;
|
|
931
|
-
|
|
1401
|
+
/**
|
|
1402
|
+
* Every field of a call request except the `reserveUsage`/`refundUsage`
|
|
1403
|
+
* hooks from `UsageHooks`. `CallParams` is this plus `UsageHooks`; the
|
|
1404
|
+
* `Cached*` param types below are call sites that want the request shape
|
|
1405
|
+
* without those two hooks (usage is metered once, at the `cachedCall`
|
|
1406
|
+
* level, not per-request), and use this directly instead of re-deriving
|
|
1407
|
+
* it with `Omit<CallParams<T>, 'reserveUsage' | 'refundUsage'>` each time.
|
|
1408
|
+
*/
|
|
1409
|
+
interface LLMRequestShape<T = unknown, Tools extends readonly ToolDefinition[] = ToolDefinition[]> {
|
|
932
1410
|
systemPrompt?: string;
|
|
933
1411
|
/** Current user message, as text or multimodal content blocks. */
|
|
934
1412
|
userContent: string | ContentBlock[];
|
|
935
1413
|
/**
|
|
936
1414
|
* Previous conversation turns. Must alternate roles; tool turns must follow
|
|
937
|
-
* assistant tool calls. Invalid history throws LLMError('
|
|
1415
|
+
* assistant tool calls. Invalid history throws LLMError('invalid_params').
|
|
938
1416
|
*/
|
|
939
1417
|
history?: ConversationTurn[];
|
|
940
1418
|
/**
|
|
@@ -947,6 +1425,20 @@ interface CallParams<T = unknown, Tools extends readonly ToolDefinition[] = Tool
|
|
|
947
1425
|
maxTokens?: number;
|
|
948
1426
|
requestId?: string;
|
|
949
1427
|
signal?: AbortSignal;
|
|
1428
|
+
/**
|
|
1429
|
+
* Total time budget in ms for this whole call, across every retry and
|
|
1430
|
+
* every fallback target. Unlike timeoutMs, which resets on each attempt,
|
|
1431
|
+
* this is a single clock starting when call is invoked. The call is
|
|
1432
|
+
* aborted once this elapses, even mid retry or mid fallback, the same
|
|
1433
|
+
* way an aborted signal is today. Omit for no overall deadline, only
|
|
1434
|
+
* the existing per attempt timeoutMs applies.
|
|
1435
|
+
*
|
|
1436
|
+
* Only bounds getting to a final result: choosing a target, retrying,
|
|
1437
|
+
* and opening a stream. It does not extend to the time spent reading a
|
|
1438
|
+
* stream after it has opened. Use chunkIdleTimeoutMs for gaps between
|
|
1439
|
+
* chunks once a stream is open.
|
|
1440
|
+
*/
|
|
1441
|
+
deadlineMs?: number;
|
|
950
1442
|
/**
|
|
951
1443
|
* Per-call override for the instance's `chunkIdleTimeoutMs` (max gap
|
|
952
1444
|
* between stream chunks once opened). Only applies when `stream: true`.
|
|
@@ -1019,15 +1511,24 @@ interface CallParams<T = unknown, Tools extends readonly ToolDefinition[] = Tool
|
|
|
1019
1511
|
* Optional out-parameter for provider identity. Pass `{}` (or any object
|
|
1020
1512
|
* with a mutable `current` property) and `call()` writes a `CallMeta`
|
|
1021
1513
|
* into `meta.current` before returning, alongside whatever `onUsage`
|
|
1022
|
-
* already reports.
|
|
1023
|
-
*
|
|
1024
|
-
* `
|
|
1025
|
-
*
|
|
1514
|
+
* already reports. This includes `stream: true`: the target is chosen
|
|
1515
|
+
* once the stream opens, which is also the point `call()` itself
|
|
1516
|
+
* returns `{ chunks, finalResult }`, so `meta.current` is already set
|
|
1517
|
+
* by then. `TokenUsage.provider`/`usedFallback` from `onUsage` reports
|
|
1518
|
+
* the same information asynchronously, for both streaming and
|
|
1519
|
+
* non-streaming calls.
|
|
1520
|
+
*
|
|
1521
|
+
* `meta.current` is only written once execution actually reaches and
|
|
1522
|
+
* selects a provider target. A `wrap` middleware that short-circuits
|
|
1523
|
+
* without calling `next()` never reaches that point, so `meta.current`
|
|
1524
|
+
* is left untouched; if the same holder object is reused across calls,
|
|
1525
|
+
* it can still hold a prior call's target.
|
|
1026
1526
|
*/
|
|
1027
1527
|
meta?: {
|
|
1028
1528
|
current?: CallMeta;
|
|
1029
1529
|
};
|
|
1030
1530
|
}
|
|
1531
|
+
interface CallParams<T = unknown, Tools extends readonly ToolDefinition[] = ToolDefinition[]> extends LLMRequestShape<T, Tools>, UsageHooks {}
|
|
1031
1532
|
/**
|
|
1032
1533
|
* A `CallParams` variant where tool calling is explicitly enabled.
|
|
1033
1534
|
*
|
|
@@ -1119,7 +1620,7 @@ interface CachedCallInput extends UsageHooks {
|
|
|
1119
1620
|
* the caching docs for why.
|
|
1120
1621
|
*/
|
|
1121
1622
|
type CachedCallParams<T> = CachedCallInput & {
|
|
1122
|
-
call:
|
|
1623
|
+
call: LLMRequestShape<T>;
|
|
1123
1624
|
};
|
|
1124
1625
|
/**
|
|
1125
1626
|
* Parameters for a cached LLM call with tool calling enabled.
|
|
@@ -1132,7 +1633,9 @@ type CachedCallParams<T> = CachedCallInput & {
|
|
|
1132
1633
|
* from `call`'s type here too.
|
|
1133
1634
|
*/
|
|
1134
1635
|
type CachedToolCallParams<T, Tools extends readonly ToolDefinition[] = ToolDefinition[]> = CachedCallInput & {
|
|
1135
|
-
call:
|
|
1636
|
+
call: LLMRequestShape<T, Tools> & {
|
|
1637
|
+
tools: NonNullable<LLMRequestShape<T, Tools>['tools']>;
|
|
1638
|
+
};
|
|
1136
1639
|
};
|
|
1137
1640
|
/**
|
|
1138
1641
|
* Parameters for a cached LLM call with `call.tools` set conditionally.
|
|
@@ -1141,7 +1644,9 @@ type CachedToolCallParams<T, Tools extends readonly ToolDefinition[] = ToolDefin
|
|
|
1141
1644
|
* `ConditionalToolCallParams` for why this overload exists.
|
|
1142
1645
|
*/
|
|
1143
1646
|
type CachedConditionalToolCallParams<T, Tools extends readonly ToolDefinition[] = ToolDefinition[]> = CachedCallInput & {
|
|
1144
|
-
call:
|
|
1647
|
+
call: LLMRequestShape<T, Tools> & {
|
|
1648
|
+
tools: Tools | undefined;
|
|
1649
|
+
};
|
|
1145
1650
|
};
|
|
1146
1651
|
/** Cached conditional tool-call parameters whose non-tool result is plain text. */
|
|
1147
1652
|
type CachedConditionalStringToolCallParams<Tools extends readonly ToolDefinition[] = ToolDefinition[]> = CachedConditionalToolCallParams<string, Tools> & {
|
|
@@ -1154,19 +1659,41 @@ type CachedConditionalStringToolCallParams<Tools extends readonly ToolDefinition
|
|
|
1154
1659
|
* `cachedCall()` overload that returns a plain `string`.
|
|
1155
1660
|
*/
|
|
1156
1661
|
type CachedJsonModeDisabledCallParams = CachedCallInput & {
|
|
1157
|
-
call: Omit<
|
|
1662
|
+
call: Omit<LLMRequestShape<unknown>, 'jsonSchema'> & {
|
|
1663
|
+
jsonMode: false;
|
|
1664
|
+
jsonSchema?: never;
|
|
1665
|
+
};
|
|
1158
1666
|
};
|
|
1159
1667
|
/**
|
|
1160
1668
|
* Parameters for a cached LLM call with `jsonMode: true` and no `schema`.
|
|
1161
1669
|
* Selects the `cachedCall()` overload that returns a `JsonValue`.
|
|
1162
1670
|
*/
|
|
1163
1671
|
type CachedJsonModeEnabledCallParams = CachedCallInput & {
|
|
1164
|
-
call: Omit<
|
|
1672
|
+
call: Omit<LLMRequestShape<JsonValue>, 'schema'> & {
|
|
1673
|
+
jsonMode: true;
|
|
1674
|
+
schema?: never;
|
|
1675
|
+
};
|
|
1165
1676
|
};
|
|
1166
|
-
|
|
1677
|
+
/** Context handed to `DetectSoftFailure` alongside the response it's inspecting. */
|
|
1678
|
+
interface SoftFailureMeta {
|
|
1679
|
+
requestId: string;
|
|
1680
|
+
model: string;
|
|
1681
|
+
providerName: string;
|
|
1682
|
+
isFallback: boolean;
|
|
1683
|
+
/** 1-based, matching `CallMeta.attempts`. */
|
|
1684
|
+
attempt: number;
|
|
1685
|
+
}
|
|
1686
|
+
/**
|
|
1687
|
+
* Inspects an otherwise-successful result and optionally reclassifies it
|
|
1688
|
+
* as a failure. Returning `undefined` leaves the result as a success;
|
|
1689
|
+
* returning an `LLMErrorCode` fails the attempt with that code, feeding
|
|
1690
|
+
* the same retry and circuit-breaker paths a thrown error would. A
|
|
1691
|
+
* result that parses fine but is empty, truncated, or a low-confidence
|
|
1692
|
+
* refusal is otherwise invisible to both.
|
|
1693
|
+
*/
|
|
1694
|
+
type DetectSoftFailure<T = unknown> = (result: T | CallWithToolsResult<T>, meta: SoftFailureMeta) => LLMErrorCode | undefined;
|
|
1167
1695
|
//#endregion
|
|
1168
1696
|
//#region src/types/stream.d.ts
|
|
1169
|
-
//# sourceMappingURL=call.d.ts.map
|
|
1170
1697
|
/** One incremental unit of a streaming response, as delivered to the caller. */
|
|
1171
1698
|
type StreamChunk = {
|
|
1172
1699
|
type: 'text-delta';
|
|
@@ -1271,6 +1798,18 @@ type WireStreamChunk = {
|
|
|
1271
1798
|
* Never surfaced to callers as a `StreamChunk`.
|
|
1272
1799
|
*/
|
|
1273
1800
|
type: 'ping';
|
|
1801
|
+
} | {
|
|
1802
|
+
/**
|
|
1803
|
+
* AIMD's proactive rate-limit hint, read off the stream's
|
|
1804
|
+
* response headers (where the adapter/SDK can get at them) and
|
|
1805
|
+
* yielded once, as early as possible. Mirrors `attachRateLimitHint`
|
|
1806
|
+
* for the non-streaming path, just carried as a chunk instead of a
|
|
1807
|
+
* hidden property on a response object, since a stream has no
|
|
1808
|
+
* single response value to attach one to. Never surfaced to
|
|
1809
|
+
* callers as a `StreamChunk`.
|
|
1810
|
+
*/
|
|
1811
|
+
type: 'rate_limit_hint';
|
|
1812
|
+
hint: ProviderRateLimitHint;
|
|
1274
1813
|
};
|
|
1275
1814
|
/**
|
|
1276
1815
|
* Parameters for a cached, streaming LLM call without tool calling.
|
|
@@ -1282,10 +1821,12 @@ type WireStreamChunk = {
|
|
|
1282
1821
|
* like).
|
|
1283
1822
|
*
|
|
1284
1823
|
* `reserveUsage`/`refundUsage` are omitted from `call`'s type; see
|
|
1285
|
-
* `CachedCallParams` for why
|
|
1824
|
+
* `CachedCallParams` for why they belong at the top level here too.
|
|
1286
1825
|
*/
|
|
1287
1826
|
type CachedStreamCallParams<T> = CachedCallInput & {
|
|
1288
|
-
call:
|
|
1827
|
+
call: LLMRequestShape<T> & {
|
|
1828
|
+
stream: true;
|
|
1829
|
+
};
|
|
1289
1830
|
};
|
|
1290
1831
|
/**
|
|
1291
1832
|
* Parameters for a cached, streaming LLM call with tool calling enabled.
|
|
@@ -1295,7 +1836,10 @@ type CachedStreamCallParams<T> = CachedCallInput & {
|
|
|
1295
1836
|
* replayed-chunks-on-hit behavior as `CachedStreamCallParams<T>`.
|
|
1296
1837
|
*/
|
|
1297
1838
|
type CachedStreamToolCallParams<T, Tools extends readonly ToolDefinition[] = ToolDefinition[]> = CachedCallInput & {
|
|
1298
|
-
call:
|
|
1839
|
+
call: LLMRequestShape<T, Tools> & {
|
|
1840
|
+
stream: true;
|
|
1841
|
+
tools: NonNullable<LLMRequestShape<T, Tools>['tools']>;
|
|
1842
|
+
};
|
|
1299
1843
|
};
|
|
1300
1844
|
/**
|
|
1301
1845
|
* Parameters for a cached, streaming LLM call with `call.tools` set
|
|
@@ -1305,7 +1849,10 @@ type CachedStreamToolCallParams<T, Tools extends readonly ToolDefinition[] = Too
|
|
|
1305
1849
|
* `ConditionalToolCallParams` for why this overload exists.
|
|
1306
1850
|
*/
|
|
1307
1851
|
type CachedStreamConditionalToolCallParams<T, Tools extends readonly ToolDefinition[] = ToolDefinition[]> = CachedCallInput & {
|
|
1308
|
-
call:
|
|
1852
|
+
call: LLMRequestShape<T, Tools> & {
|
|
1853
|
+
stream: true;
|
|
1854
|
+
tools: Tools | undefined;
|
|
1855
|
+
};
|
|
1309
1856
|
};
|
|
1310
1857
|
/** Cached streaming conditional tool-call parameters whose non-tool result is text. */
|
|
1311
1858
|
type CachedStreamConditionalStringToolCallParams<Tools extends readonly ToolDefinition[] = ToolDefinition[]> = CachedStreamConditionalToolCallParams<string, Tools> & {
|
|
@@ -1319,7 +1866,11 @@ type CachedStreamConditionalStringToolCallParams<Tools extends readonly ToolDefi
|
|
|
1319
1866
|
* cached value (on a hit) is a plain `string`.
|
|
1320
1867
|
*/
|
|
1321
1868
|
type CachedStreamJsonModeDisabledCallParams = CachedCallInput & {
|
|
1322
|
-
call: Omit<
|
|
1869
|
+
call: Omit<LLMRequestShape<unknown>, 'jsonSchema'> & {
|
|
1870
|
+
stream: true;
|
|
1871
|
+
jsonMode: false;
|
|
1872
|
+
jsonSchema?: never;
|
|
1873
|
+
};
|
|
1323
1874
|
};
|
|
1324
1875
|
/**
|
|
1325
1876
|
* Parameters for a cached, streaming LLM call with `jsonMode: true` and no
|
|
@@ -1327,12 +1878,14 @@ type CachedStreamJsonModeDisabledCallParams = CachedCallInput & {
|
|
|
1327
1878
|
* miss) or cached value (on a hit) is a `JsonValue`.
|
|
1328
1879
|
*/
|
|
1329
1880
|
type CachedStreamJsonModeEnabledCallParams = CachedCallInput & {
|
|
1330
|
-
call: Omit<
|
|
1881
|
+
call: Omit<LLMRequestShape<JsonValue>, 'schema'> & {
|
|
1882
|
+
stream: true;
|
|
1883
|
+
jsonMode: true;
|
|
1884
|
+
schema?: never;
|
|
1885
|
+
};
|
|
1331
1886
|
};
|
|
1332
|
-
|
|
1333
1887
|
//#endregion
|
|
1334
1888
|
//#region src/types/client.d.ts
|
|
1335
|
-
//# sourceMappingURL=stream.d.ts.map
|
|
1336
1889
|
/** A tool call as it appears on the wire, OpenAI's `function`-wrapped shape. */
|
|
1337
1890
|
interface WireToolCall {
|
|
1338
1891
|
id: string;
|
|
@@ -1462,10 +2015,20 @@ interface LLMClient {
|
|
|
1462
2015
|
};
|
|
1463
2016
|
};
|
|
1464
2017
|
}
|
|
1465
|
-
|
|
2018
|
+
//#endregion
|
|
2019
|
+
//#region src/internal/utils/cacheAdapter.utils.d.ts
|
|
2020
|
+
/**
|
|
2021
|
+
* Not exported. Internal shorthand for `VernLLMOptions.cache`, so the
|
|
2022
|
+
* union isn't duplicated between that field and `buildCache`'s own
|
|
2023
|
+
* signature. A caller never writes this type by name, either a config
|
|
2024
|
+
* object literal or a real `CacheAdapter`.
|
|
2025
|
+
*/
|
|
2026
|
+
type CacheOption = {
|
|
2027
|
+
maxSize?: number;
|
|
2028
|
+
eviction?: EvictionOption;
|
|
2029
|
+
} | CacheAdapter;
|
|
1466
2030
|
//#endregion
|
|
1467
2031
|
//#region src/logger.d.ts
|
|
1468
|
-
//# sourceMappingURL=client.d.ts.map
|
|
1469
2032
|
interface Logger {
|
|
1470
2033
|
debug(message: string): void;
|
|
1471
2034
|
warn(message: string): void;
|
|
@@ -1482,73 +2045,8 @@ declare class ConsoleLogger implements Logger {
|
|
|
1482
2045
|
warn(message: string): void;
|
|
1483
2046
|
error(message: string, meta?: Record<string, unknown>): void;
|
|
1484
2047
|
}
|
|
1485
|
-
|
|
1486
|
-
//#endregion
|
|
1487
|
-
//#region src/types/events.d.ts
|
|
1488
|
-
//# sourceMappingURL=logger.d.ts.map
|
|
1489
|
-
/**
|
|
1490
|
-
* Reports what happened during a call. Fire and forget, mirroring
|
|
1491
|
-
* `onUsage`: the return value is never read and a throwing handler cannot
|
|
1492
|
-
* change what the call does, only what gets reported about it.
|
|
1493
|
-
*/
|
|
1494
|
-
type VernLLMEvent = {
|
|
1495
|
-
kind: 'retry';
|
|
1496
|
-
requestId: string;
|
|
1497
|
-
provider: string;
|
|
1498
|
-
/** The model actually resolved for this call (honors a per-call `model` override). */
|
|
1499
|
-
model: string;
|
|
1500
|
-
/** The 1-based retry ordinal (the 1st retry is `1`, not the overall attempt count). */
|
|
1501
|
-
attempt: number;
|
|
1502
|
-
maxRetries: number;
|
|
1503
|
-
delayMs: number;
|
|
1504
|
-
retryAfterHonored: boolean;
|
|
1505
|
-
error: LLMError;
|
|
1506
|
-
} | {
|
|
1507
|
-
kind: 'circuit_state';
|
|
1508
|
-
provider: string;
|
|
1509
|
-
/**
|
|
1510
|
-
* The model of the call that triggered this specific transition
|
|
1511
|
-
* (whatever was passed to the `assertClosed`/`recordSuccess`/
|
|
1512
|
-
* `recordFailure` call that caused it), not a property of the
|
|
1513
|
-
* circuit itself: the breaker still counts failures across every
|
|
1514
|
-
* model together, so a threshold crossing can be the sum of
|
|
1515
|
-
* several different models' failures even though only the
|
|
1516
|
-
* triggering call's `model` is reported here.
|
|
1517
|
-
*/
|
|
1518
|
-
model: string;
|
|
1519
|
-
from: CircuitState;
|
|
1520
|
-
to: CircuitState;
|
|
1521
|
-
consecutiveFailures: number;
|
|
1522
|
-
} | {
|
|
1523
|
-
kind: 'fallback';
|
|
1524
|
-
requestId: string;
|
|
1525
|
-
/** Provider name of the target that just failed. */
|
|
1526
|
-
from: string;
|
|
1527
|
-
/** Provider name of the target about to be tried next. */
|
|
1528
|
-
to: string;
|
|
1529
|
-
/** `-1` for the primary target, otherwise the index into `fallback`. */
|
|
1530
|
-
fromIndex: number;
|
|
1531
|
-
toIndex: number;
|
|
1532
|
-
/** The normalized error that caused `from` to be abandoned. */
|
|
1533
|
-
error: LLMError;
|
|
1534
|
-
/** Time spent on `from`, including its own retries, before giving up. */
|
|
1535
|
-
elapsedMs: number;
|
|
1536
|
-
} | {
|
|
1537
|
-
kind: 'rate_limited';
|
|
1538
|
-
requestId: string;
|
|
1539
|
-
provider: string;
|
|
1540
|
-
/** The model actually resolved for this call (honors a per-call `model` override). */
|
|
1541
|
-
model: string;
|
|
1542
|
-
/** How long this attempt sat queued for capacity before it was let through. */
|
|
1543
|
-
waitedMs: number;
|
|
1544
|
-
/** Which configured bucket was blocking this attempt just before it cleared. */
|
|
1545
|
-
reason: 'concurrency' | 'rpm' | 'tpm';
|
|
1546
|
-
};
|
|
1547
|
-
type OnEvent = (event: VernLLMEvent) => void;
|
|
1548
|
-
|
|
1549
2048
|
//#endregion
|
|
1550
2049
|
//#region src/types/options.d.ts
|
|
1551
|
-
//# sourceMappingURL=events.d.ts.map
|
|
1552
2050
|
interface VernLLMOptions {
|
|
1553
2051
|
client: LLMClient;
|
|
1554
2052
|
model: string;
|
|
@@ -1617,8 +2115,24 @@ interface VernLLMOptions {
|
|
|
1617
2115
|
* (no redaction).
|
|
1618
2116
|
*/
|
|
1619
2117
|
redact?: (text: string) => string;
|
|
1620
|
-
/**
|
|
1621
|
-
|
|
2118
|
+
/**
|
|
2119
|
+
* Cache for cachedCall. `{ maxSize, eviction }` configures the
|
|
2120
|
+
* built-in in-memory adapter (`eviction` default `'fifo'`). Pass a
|
|
2121
|
+
* `CacheAdapter` directly for a real backend. Default: in-memory,
|
|
2122
|
+
* maxSize 1000, fifo.
|
|
2123
|
+
*/
|
|
2124
|
+
cache?: CacheOption;
|
|
2125
|
+
/**
|
|
2126
|
+
* Reclassifies an otherwise-successful result as a failure, e.g. a
|
|
2127
|
+
* response that parsed fine but came back empty or truncated. Runs
|
|
2128
|
+
* once per attempt, right after a response is validated. Returning
|
|
2129
|
+
* `undefined` leaves the result untouched; returning an
|
|
2130
|
+
* `LLMErrorCode` fails that attempt with it, feeding the same retry
|
|
2131
|
+
* and circuit-breaker paths a thrown error would. A throwing hook is
|
|
2132
|
+
* caught, logged, and treated as no soft failure, so a broken hook
|
|
2133
|
+
* degrades safely instead of failing every call.
|
|
2134
|
+
*/
|
|
2135
|
+
detectSoftFailure?: DetectSoftFailure;
|
|
1622
2136
|
/** HTTP status codes that should fail fast without retrying. Default [400, 401, 403, 404, 422] */
|
|
1623
2137
|
nonRetryableStatus?: number[];
|
|
1624
2138
|
/** Custom JSON parser. Must return undefined/null on failure. Default: JSON.parse wrapped in try/catch */
|
|
@@ -1657,8 +2171,22 @@ interface VernLLMOptions {
|
|
|
1657
2171
|
* letting the provider reject them. Independent of the `Retry-After`
|
|
1658
2172
|
* handling already applied to a provider 429: this avoids tripping the
|
|
1659
2173
|
* limit in the first place. Omit for unlimited (the default).
|
|
2174
|
+
*
|
|
2175
|
+
* A plain config object builds an in-process limiter. Pass a
|
|
2176
|
+
* `RateLimiterAdapter` instead for cross-process coordination.
|
|
2177
|
+
*/
|
|
2178
|
+
rateLimit?: RateLimitOption;
|
|
2179
|
+
/**
|
|
2180
|
+
* Caps how much of this target's recent traffic is allowed to be
|
|
2181
|
+
* retries, independent of `circuitBreaker`. Once at least `minCalls`
|
|
2182
|
+
* calls have landed in the trailing `windowMs` and the retry ratio
|
|
2183
|
+
* among them reaches `retryRatio`, further retries against this target
|
|
2184
|
+
* throw `LLMError('retry_budget_exhausted')` instead of retrying,
|
|
2185
|
+
* protecting the target's real capacity even while its breaker is
|
|
2186
|
+
* still closed. Omit for no budget (the default). Never inherited by
|
|
2187
|
+
* `fallback` targets, same as `circuitBreaker`/`rateLimit`.
|
|
1660
2188
|
*/
|
|
1661
|
-
|
|
2189
|
+
retryBudget?: RetryBudgetOptions;
|
|
1662
2190
|
/**
|
|
1663
2191
|
* Ordered targets tried after the primary, in order, once it (and its
|
|
1664
2192
|
* own retries) is exhausted or abandoned. Order is the policy: VernLLM
|
|
@@ -1680,11 +2208,57 @@ interface VernLLMOptions {
|
|
|
1680
2208
|
* and moves on for everything else.
|
|
1681
2209
|
*/
|
|
1682
2210
|
fallbackOn?: FallbackOn;
|
|
2211
|
+
/**
|
|
2212
|
+
* Transforms outgoing requests and/or wraps whole logical calls,
|
|
2213
|
+
* without touching retry, circuit breaker, or fallback internals.
|
|
2214
|
+
* Defaults to an empty array. See `VernLLMMiddleware` for the four
|
|
2215
|
+
* available hooks (`transform`, `wrap`, `onEvent`, `enabled`).
|
|
2216
|
+
*/
|
|
2217
|
+
middleware?: VernLLMMiddleware[];
|
|
2218
|
+
/**
|
|
2219
|
+
* Bounds `transform` and a function `enabled`, the same way every
|
|
2220
|
+
* other blocking operation in the package is already bounded.
|
|
2221
|
+
* Overridable per middleware via that entry's own `timeoutMs`.
|
|
2222
|
+
* `<= 0` means unbounded (no timer at all). Default 5000.
|
|
2223
|
+
*/
|
|
2224
|
+
middlewareTimeoutMs?: number;
|
|
1683
2225
|
}
|
|
1684
|
-
|
|
2226
|
+
//#endregion
|
|
2227
|
+
//#region src/types/createMiddleware.d.ts
|
|
2228
|
+
/**
|
|
2229
|
+
* `VernLLMMiddleware` plus `onError`, a convenience for the common "I
|
|
2230
|
+
* only care about failures" case. Everything else is passed through to
|
|
2231
|
+
* the resulting `VernLLMMiddleware` unchanged; setting `wrap` directly
|
|
2232
|
+
* alongside `onError` is an error, since `onError` builds its own `wrap`
|
|
2233
|
+
* under the hood, and building it around a `wrap` you also supplied
|
|
2234
|
+
* would silently drop one of the two.
|
|
2235
|
+
*/
|
|
2236
|
+
type CreateMiddlewareOptions = Omit<VernLLMMiddleware, 'wrap'> & {
|
|
2237
|
+
wrap?: undefined;
|
|
2238
|
+
/**
|
|
2239
|
+
* Called with this call's terminal error, if it fails: the same error
|
|
2240
|
+
* `wrap`'s own `next()` would reject with. Never called on success,
|
|
2241
|
+
* and never called for a failure some *other* middleware's `wrap`
|
|
2242
|
+
* already swallowed by short-circuiting with its own `CallResult`.
|
|
2243
|
+
* The original error is always rethrown afterward, `onError` only
|
|
2244
|
+
* observes it, exactly like `onUsage`/`onEvent` elsewhere: a throwing
|
|
2245
|
+
* `onError` is discarded (not logged, this helper has no `Logger` of
|
|
2246
|
+
* its own to log through) and otherwise has no effect on the call.
|
|
2247
|
+
* `ctx` is `wrap`'s own pre-dispatch context (`onError` builds a `wrap`
|
|
2248
|
+
* under the hood), so it only describes the primary target.
|
|
2249
|
+
*/
|
|
2250
|
+
onError?: (error: LLMError, ctx: PreDispatchContext) => void | Promise<void>;
|
|
2251
|
+
};
|
|
2252
|
+
/**
|
|
2253
|
+
* Builds a `VernLLMMiddleware` entry. Plain pass-through when `onError`
|
|
2254
|
+
* is omitted; when it's set, wraps it in a `wrap` that calls `next()`,
|
|
2255
|
+
* reports `onError` on a rejection, and always rethrows the original
|
|
2256
|
+
* error afterward, so `onError` never changes what the call itself
|
|
2257
|
+
* returns or throws, only what gets observed about it.
|
|
2258
|
+
*/
|
|
2259
|
+
declare function createMiddleware(options: CreateMiddlewareOptions): VernLLMMiddleware;
|
|
1685
2260
|
//#endregion
|
|
1686
2261
|
//#region src/vernLLM.d.ts
|
|
1687
|
-
//# sourceMappingURL=options.d.ts.map
|
|
1688
2262
|
/**
|
|
1689
2263
|
* A LLM call framework for resilience, observability and control. This is VernLLM!
|
|
1690
2264
|
*
|
|
@@ -1698,21 +2272,37 @@ declare class VernLLM {
|
|
|
1698
2272
|
/**
|
|
1699
2273
|
* One `CallExecutor` per provider target: index 0 is the primary,
|
|
1700
2274
|
* everything after it is a `fallback` target, in the order declared.
|
|
1701
|
-
*
|
|
1702
|
-
*
|
|
1703
|
-
* moving to the next entry only when `fallbackOn` says to.
|
|
2275
|
+
* Walked by `runFallbackChain`, moving to the next entry only when
|
|
2276
|
+
* `fallbackOn` says to.
|
|
1704
2277
|
*/
|
|
1705
2278
|
private readonly executors;
|
|
1706
2279
|
/** Decides whether a failed target is followed by the next one or the chain stops. See `VernLLMOptions['fallbackOn']`. */
|
|
1707
2280
|
private readonly fallbackOn;
|
|
1708
2281
|
/** Reports a `'fallback'` event when the chain moves to the next target. Shared `onEvent` plumbing, same as every executor's. */
|
|
1709
2282
|
private readonly reportEvent;
|
|
2283
|
+
/** Owns cache reads/writes and in-flight coalescing for `cachedCall()`. Only calls back into `this.call()` as an opaque function. */
|
|
2284
|
+
private readonly cacheOrchestrator;
|
|
2285
|
+
/** See `VernLLMOptions.middleware`. Sorted once here by `priority`, ascending, ties broken by original array order. */
|
|
2286
|
+
private readonly middleware;
|
|
2287
|
+
/** See `VernLLMOptions.middlewareTimeoutMs`. Bounds `transform` and a function `enabled`; `wrap` itself is never bounded by this. */
|
|
2288
|
+
private readonly middlewareTimeoutMs;
|
|
1710
2289
|
/**
|
|
1711
|
-
*
|
|
1712
|
-
*
|
|
1713
|
-
*
|
|
2290
|
+
* Maps `cachedCall()`'s inner `this.call(...)` params to its own
|
|
2291
|
+
* `middlewareState`, so that call's own `runOperation` skips wrapping
|
|
2292
|
+
* again and reuses the same state bag `wrap` just ran with (so a
|
|
2293
|
+
* value `wrap` sets is visible to `transform`, same as a direct
|
|
2294
|
+
* call). Keyed by object identity, not `requestId`, since two
|
|
2295
|
+
* concurrent `cachedCall()`s can share an explicit `requestId`.
|
|
1714
2296
|
*/
|
|
1715
|
-
private readonly
|
|
2297
|
+
private readonly cachedCallInnerParams;
|
|
2298
|
+
/**
|
|
2299
|
+
* Shares one `CallMeta` holder across every `cachedCall()` in flight
|
|
2300
|
+
* for the same resolved cache key, so a joining invocation (never
|
|
2301
|
+
* calls `call()` itself) reports the trigger's real metadata instead
|
|
2302
|
+
* of `undefined`. A true cache hit never creates an entry, so it
|
|
2303
|
+
* still reports no metadata correctly.
|
|
2304
|
+
*/
|
|
2305
|
+
private readonly cachedCallMeta;
|
|
1716
2306
|
/**
|
|
1717
2307
|
* @param options Client, model, and tunables. Defaults: `maxRetries` 1,
|
|
1718
2308
|
* `timeoutMs` 25000, `baseDelayMs` 500, `defaultMaxTokens` 1000,
|
|
@@ -1722,72 +2312,23 @@ declare class VernLLM {
|
|
|
1722
2312
|
constructor(options: VernLLMOptions);
|
|
1723
2313
|
/** Logs a failed refundUsage attempt via the configured logger. */
|
|
1724
2314
|
private logRefundError;
|
|
1725
|
-
/**
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
* loop's single iteration path is unchanged from pre-fallback behavior.
|
|
1730
|
-
*
|
|
1731
|
-
* For streaming, `attempt` is `executor.runStream`, whose own retries
|
|
1732
|
-
* only cover *opening* the stream (see `CallExecutor.runStream`). A
|
|
1733
|
-
* mid-stream failure surfaces through `finalResult` after this function
|
|
1734
|
-
* has already returned, so it's never seen here and never falls over,
|
|
1735
|
-
* per the streaming limitation: splicing a second model's output into a
|
|
1736
|
-
* response the consumer has already partially rendered would corrupt
|
|
1737
|
-
* it.
|
|
1738
|
-
*/
|
|
1739
|
-
private runFallbackChain;
|
|
2315
|
+
/** Everything `executeLogicalCall`/`executeLogicalStreamCall` (in `logicalCall.ts`) need from this instance, gathered once so `call()` doesn't rebuild it per invocation. */
|
|
2316
|
+
private get logicalCallDependencies();
|
|
2317
|
+
/** Everything `runOperation` (in `runOperation.ts`) needs from this instance, gathered once so `call()`/`cachedCall()` don't rebuild it per invocation. */
|
|
2318
|
+
private get runOperationDependencies();
|
|
1740
2319
|
/**
|
|
1741
2320
|
* Makes a single logical LLM call, retrying on failure per the configured
|
|
1742
2321
|
* policy. Fails fast if the breaker is open or the signal is already
|
|
1743
|
-
* aborted. Rejects with a normalized LLMError on exhausted retries.
|
|
1744
|
-
*
|
|
1745
|
-
* When `tools` is set, returns a `CallWithToolsResult<T>` instead of `T`:
|
|
1746
|
-
* `{ type: 'content', content }` or `{ type: 'tool_calls', toolCalls,
|
|
1747
|
-
* content? }`. VernLLM never executes tools; run them yourself and
|
|
1748
|
-
* continue via `history` (see `ConversationTurn`). Mutually exclusive
|
|
1749
|
-
* with `jsonSchema`/`schema`.
|
|
1750
|
-
*
|
|
1751
|
-
* TypeScript picks the tools-aware overload (`CallWithToolsResult<T>`)
|
|
1752
|
-
* when `tools` is a literal array on `params`, and the conditional-tools
|
|
1753
|
-
* overload (`T | CallWithToolsResult<T>`, see `ConditionalToolCallParams`)
|
|
1754
|
-
* when `tools` is present but statically `ToolDefinition[] | undefined`,
|
|
1755
|
-
* e.g. `const tools = condition ? [myTool] : undefined`. Either way, use
|
|
1756
|
-
* `isToolCallResult()` to narrow the result once `tools` isn't a literal
|
|
1757
|
-
* array: TypeScript's static type can't know from the `ConditionalToolCallParams`
|
|
1758
|
-
* shape alone whether tools actually ran on a given call. Only omitting
|
|
1759
|
-
* `tools` entirely resolves to the plain `T` overload, since then tools
|
|
1760
|
-
* genuinely cannot have run. See the Tool Calling docs for details.
|
|
2322
|
+
* aborted. Rejects with a normalized `LLMError` on exhausted retries.
|
|
1761
2323
|
*
|
|
1762
|
-
*
|
|
1763
|
-
*
|
|
1764
|
-
*
|
|
1765
|
-
* conditionally on a plain `CallParams<T>` still resolves to `Promise<T>`
|
|
1766
|
-
* (or `Promise<CallWithToolsResult<T>>`) at the type level even though
|
|
1767
|
-
* the actual runtime result is the `{ chunks, finalResult }` streaming
|
|
1768
|
-
* shape whenever `stream` evaluates to `true`, callers doing this should
|
|
1769
|
-
* narrow/cast accordingly rather than relying on the static return type.
|
|
1770
|
-
*
|
|
1771
|
-
* Pinning `T` explicitly (`call<string>(...)`) alongside a literal
|
|
1772
|
-
* `tools` array loses per-tool `arguments` typing: TypeScript's own
|
|
1773
|
-
* generic inference rules mean providing *any* explicit type argument
|
|
1774
|
-
* suppresses inference for every subsequent type parameter in that call,
|
|
1775
|
-
* `Tools` included, regardless of its `const` modifier or default. This
|
|
1776
|
-
* isn't specific to this overload, it's true of all TypeScript generic
|
|
1777
|
-
* calls with a partial explicit type argument list. Pass `Tools`
|
|
1778
|
-
* explicitly too when pinning `T` this way, e.g. `call<string, typeof
|
|
1779
|
-
* myTools>(...)`, or prefer inferring `T` from `schema`/`jsonSchema`
|
|
1780
|
-
* instead (which doesn't touch the type argument list, so `Tools` still
|
|
1781
|
-
* infers normally).
|
|
2324
|
+
* Supports `tools`, `stream`, and JSON mode/schema, in any combination.
|
|
2325
|
+
* See the Tool Calling and Streaming docs for return-shape details and
|
|
2326
|
+
* the TypeScript overloads that select between them.
|
|
1782
2327
|
*
|
|
1783
2328
|
* @param params System/user content plus per-call overrides. See `CallParams`.
|
|
1784
|
-
* @returns
|
|
1785
|
-
*
|
|
1786
|
-
*
|
|
1787
|
-
* the model is then structurally barred from returning a `tool_calls`
|
|
1788
|
-
* result. With `stream: true` (statically): a `{ chunks, finalResult }`
|
|
1789
|
-
* `StreamCallResult`, `finalResult` resolving to whichever of the above
|
|
1790
|
-
* shapes applies once the stream completes. See `StreamCallResult`.
|
|
2329
|
+
* @returns The parsed response (or raw string if `jsonMode` is false), a
|
|
2330
|
+
* `CallWithToolsResult<T>` when `tools` is set, or a `{ chunks,
|
|
2331
|
+
* finalResult }` `StreamCallResult` when `stream: true`. See `StreamCallResult`.
|
|
1791
2332
|
*/
|
|
1792
2333
|
call<T = unknown>(params: StreamEnabledCallParams<T> & ToolsDisabledCallParams<T>): Promise<StreamCallResult<ContentResult<T>>>;
|
|
1793
2334
|
call<T = unknown, const Tools extends readonly ToolDefinition[] = ToolDefinition[]>(params: StreamEnabledCallParams<T, Tools> & ToolEnabledCallParams<T, Tools>): Promise<StreamCallResult<CallWithToolsResult<T, Tools>>>;
|
|
@@ -1821,35 +2362,19 @@ declare class VernLLM {
|
|
|
1821
2362
|
deleteCache(key: string): Promise<void>;
|
|
1822
2363
|
/**
|
|
1823
2364
|
* Cache wrapper composing `call` + caching, so cached LLM calls
|
|
1824
|
-
* automatically get retry/timeout/circuit-breaker behavior.
|
|
1825
|
-
* `
|
|
1826
|
-
*
|
|
1827
|
-
* stampedes. Supports `stream: true` and `tools` in any combination.
|
|
1828
|
-
*
|
|
1829
|
-
* When `call.tools` is set, this caches the whole `CallWithToolsResult`,
|
|
1830
|
-
* including `tool_calls` results, not just final answers. Whether
|
|
1831
|
-
* that's appropriate depends on the tool: caching "the model decided to
|
|
1832
|
-
* call get_weather" is usually fine to reuse briefly, but caching a
|
|
1833
|
-
* decision made under permissions or account state that can change
|
|
1834
|
-
* between calls is not. Use a short `ttl` or a separate `cacheKey` for
|
|
1835
|
-
* such tools if this distinction matters.
|
|
2365
|
+
* automatically get retry/timeout/circuit-breaker behavior. Concurrent
|
|
2366
|
+
* misses for the same `cacheKey` share a single in-flight call, avoiding
|
|
2367
|
+
* cache stampedes. Supports `stream: true` and `tools` in any combination.
|
|
1836
2368
|
*
|
|
1837
|
-
*
|
|
1838
|
-
* `
|
|
1839
|
-
*
|
|
1840
|
-
* caching library at the application level instead.
|
|
2369
|
+
* When `call.tools` is set, this caches the whole result including any
|
|
2370
|
+
* `tool_calls` decision, not just final answers; use a short `ttl` or a
|
|
2371
|
+
* separate `cacheKey` if a tool's result shouldn't be reused across calls.
|
|
1841
2372
|
*
|
|
1842
|
-
*
|
|
1843
|
-
* here too: pinning `T` explicitly (`cachedCall<string>(...)`) alongside
|
|
1844
|
-
* a literal `call.tools` array loses per-tool `arguments` typing, pass
|
|
1845
|
-
* `Tools` explicitly too in that case.
|
|
1846
|
-
*
|
|
1847
|
-
* @param params `cacheKey`, `ttl`, and optional
|
|
2373
|
+
* @param params `cacheKey`, `ttl`, optional
|
|
1848
2374
|
* `reserveUsage`/`refundUsage`/`signal`, plus `call`, the `CallParams`
|
|
1849
|
-
*
|
|
1850
|
-
*
|
|
1851
|
-
*
|
|
1852
|
-
* request, set `signal` inside `call`.
|
|
2375
|
+
* to pass through to `this.call(...)`. The top-level `signal` governs
|
|
2376
|
+
* the cached operation and its usage hooks only; to also abort the
|
|
2377
|
+
* underlying provider request, set `signal` inside `call`.
|
|
1853
2378
|
* @returns The cached value on a hit, or the freshly-called result on a miss.
|
|
1854
2379
|
*/
|
|
1855
2380
|
cachedCall<T, const Tools extends readonly ToolDefinition[] = ToolDefinition[]>(params: CachedStreamToolCallParams<T, Tools>): Promise<StreamCallResult<CallWithToolsResult<T, Tools>>>;
|
|
@@ -1873,6 +2398,26 @@ declare class VernLLM {
|
|
|
1873
2398
|
* target that doesn't exist.
|
|
1874
2399
|
*/
|
|
1875
2400
|
getCircuitState(target?: CircuitTarget): CircuitState | undefined;
|
|
2401
|
+
/**
|
|
2402
|
+
* @param target.index Which target to read. Defaults to the primary.
|
|
2403
|
+
* @param target.model Which model bucket to read, if the target isolates by model.
|
|
2404
|
+
* @returns Failure counts by `LLMErrorCode`, `'unknown'` for a missing
|
|
2405
|
+
* code, or `undefined` if that target has no breaker.
|
|
2406
|
+
* @throws {RangeError} If `target.index` names no target.
|
|
2407
|
+
*/
|
|
2408
|
+
getFailureBreakdown(target?: CircuitTarget): Partial<Record<LLMErrorCode | 'unknown', number>> | undefined;
|
|
2409
|
+
/**
|
|
2410
|
+
* @param target.index Which target to read. Defaults to the primary.
|
|
2411
|
+
* @returns This target's current retry traffic/ratio in the trailing
|
|
2412
|
+
* window, or `undefined` if that target has no retry budget
|
|
2413
|
+
* configured. A budget is target-scoped, not model-scoped, so unlike
|
|
2414
|
+
* `getFailureBreakdown` there's no `target.model` to pass.
|
|
2415
|
+
* @throws {RangeError} If `target.index` names no target.
|
|
2416
|
+
*/
|
|
2417
|
+
getRetryBudgetState(target?: Pick<CircuitTarget, 'index'>): {
|
|
2418
|
+
attempts: number;
|
|
2419
|
+
retryRatio: number;
|
|
2420
|
+
} | undefined;
|
|
1876
2421
|
/**
|
|
1877
2422
|
* @param model Which model bucket to read, for targets that isolate by model.
|
|
1878
2423
|
* @returns Every target's state, in chain order.
|
|
@@ -1896,11 +2441,9 @@ declare class VernLLM {
|
|
|
1896
2441
|
* @throws {RangeError} If `target.index` names no target.
|
|
1897
2442
|
*/
|
|
1898
2443
|
closeCircuit(target?: CircuitTarget): void;
|
|
1899
|
-
/** Resolves a target index so every circuit-breaker method agrees on what counts as valid. */
|
|
1900
|
-
private resolveExecutor;
|
|
1901
|
-
/** Warns when `model` can't do anything on this target, so it's never silently ignored. */
|
|
1902
|
-
private warnIfModelUnsupported;
|
|
1903
2444
|
}
|
|
2445
|
+
//#endregion
|
|
2446
|
+
//#region src/paramsHelpers.d.ts
|
|
1904
2447
|
/**
|
|
1905
2448
|
* Identity function preserving `params`'s own precise type, unlike a `:
|
|
1906
2449
|
* CallParams<T>` annotation, which would widen `tools` away and break the
|
|
@@ -1936,10 +2479,8 @@ declare function defineCallParams<P extends CallParams<unknown>>(params: P): P;
|
|
|
1936
2479
|
* ```
|
|
1937
2480
|
*/
|
|
1938
2481
|
declare function defineCachedCallParams<P extends CachedCallParams<unknown>>(params: P): P;
|
|
1939
|
-
|
|
1940
2482
|
//#endregion
|
|
1941
2483
|
//#region src/adapters/internal/sse.d.ts
|
|
1942
|
-
//# sourceMappingURL=vernLLM.d.ts.map
|
|
1943
2484
|
/**
|
|
1944
2485
|
* Parses a Server-Sent-Events byte/text stream into the JSON payload of
|
|
1945
2486
|
* each `data:` frame, in arrival order. Generic over transport: works with
|
|
@@ -1975,33 +2516,22 @@ declare function parseSseStream(source: AsyncIterable<Uint8Array | string>): Asy
|
|
|
1975
2516
|
* alive" separately from a genuinely empty frame (`NO_DATA`, kept internal).
|
|
1976
2517
|
*/
|
|
1977
2518
|
declare const SSE_PING: unique symbol;
|
|
1978
|
-
|
|
1979
2519
|
//#endregion
|
|
1980
2520
|
//#region src/adapters/internal/imageFormat.d.ts
|
|
1981
|
-
//# sourceMappingURL=sse.d.ts.map
|
|
1982
2521
|
/**
|
|
1983
2522
|
* MIME types accepted for `ImageBlock.mimeType` across all adapters. This is
|
|
1984
2523
|
* the intersection of what Anthropic, Gemini, OpenAI-compatible, and Bedrock
|
|
1985
2524
|
* Converse all natively support, so a `ContentBlock[]` that validates for
|
|
1986
2525
|
* one provider validates for all of them.
|
|
1987
2526
|
*/
|
|
1988
|
-
declare const SUPPORTED_IMAGE_MIME_TYPES: readonly [
|
|
2527
|
+
declare const SUPPORTED_IMAGE_MIME_TYPES: readonly ['image/png', 'image/jpeg', 'image/gif', 'image/webp'];
|
|
1989
2528
|
type SupportedImageMimeType = (typeof SUPPORTED_IMAGE_MIME_TYPES)[number];
|
|
1990
|
-
|
|
1991
2529
|
//#endregion
|
|
1992
2530
|
//#region src/adapters/internal/nativeStructuredOutput.d.ts
|
|
1993
|
-
/**
|
|
1994
|
-
* Validates an `ImageBlock.mimeType` against the shared supported set.
|
|
1995
|
-
* Throws a non-retryable `LLMError('invalid_params')`, since an unsupported
|
|
1996
|
-
* mimeType is a bug in the caller's own input, deterministic before any
|
|
1997
|
-
* request is built, the same class of failure as every other check in
|
|
1998
|
-
* `RequestBuilder`.
|
|
1999
|
-
*/
|
|
2000
|
-
|
|
2001
2531
|
/**
|
|
2002
2532
|
* A static allow-list or predicate naming which models support native,
|
|
2003
|
-
* schema-constrained output as its own request field
|
|
2004
|
-
* `output_config.format
|
|
2533
|
+
* schema-constrained output as its own request field. Anthropic's
|
|
2534
|
+
* `output_config.format` and Bedrock's `outputConfig.textFormat` separate
|
|
2005
2535
|
* from `tools`/`tool_choice`, so it can be combined with real,
|
|
2006
2536
|
* caller-supplied `tools` in the same request.
|
|
2007
2537
|
*
|
|
@@ -2018,10 +2548,8 @@ type SupportedImageMimeType = (typeof SUPPORTED_IMAGE_MIME_TYPES)[number];
|
|
|
2018
2548
|
* exactly this package's behavior before native support was added.
|
|
2019
2549
|
*/
|
|
2020
2550
|
type ModelCapabilityOverride = string[] | ((model: string) => boolean);
|
|
2021
|
-
|
|
2022
2551
|
//#endregion
|
|
2023
2552
|
//#region src/adapters/internal/reasoningBudget.utils.d.ts
|
|
2024
|
-
/** Resolves whether `model` is covered by a caller-supplied allow-list/predicate. */
|
|
2025
2553
|
/**
|
|
2026
2554
|
* Shared conversion between the two reasoning controls VernLLM exposes:
|
|
2027
2555
|
* `reasoningEffort` (a tier string, OpenAI's native shape) and
|
|
@@ -2042,7 +2570,6 @@ type ModelCapabilityOverride = string[] | ((model: string) => boolean);
|
|
|
2042
2570
|
* doesn't match these numbers.
|
|
2043
2571
|
*/
|
|
2044
2572
|
type EffortTokenTable = Record<'minimal' | 'low' | 'medium' | 'high', number>;
|
|
2045
|
-
|
|
2046
2573
|
//#endregion
|
|
2047
2574
|
//#region src/adapters/anthropic.d.ts
|
|
2048
2575
|
/** Anthropic's native per-block content shape for a message. */
|
|
@@ -2196,6 +2723,13 @@ interface AnthropicAdapterOptions {
|
|
|
2196
2723
|
* predicate.
|
|
2197
2724
|
*/
|
|
2198
2725
|
adaptiveOnlyModels?: ModelCapabilityOverride;
|
|
2726
|
+
/**
|
|
2727
|
+
* Whether the client's `messages.create` supports `.withResponse()`
|
|
2728
|
+
* (needed for AIMD's proactive path). Default `false`, since
|
|
2729
|
+
* `AnthropicClient` is structural and a test fake or thin wrapper
|
|
2730
|
+
* won't implement it.
|
|
2731
|
+
*/
|
|
2732
|
+
supportsWithResponse?: boolean;
|
|
2199
2733
|
}
|
|
2200
2734
|
/**
|
|
2201
2735
|
* Wraps an Anthropic SDK client so it satisfies the same `LLMClient`
|
|
@@ -2229,7 +2763,6 @@ interface AnthropicAdapterOptions {
|
|
|
2229
2763
|
* `output_config.format` or a forced tool call).
|
|
2230
2764
|
*/
|
|
2231
2765
|
declare function fromAnthropic(anthropicClient: AnthropicClient, options?: AnthropicAdapterOptions): LLMClient;
|
|
2232
|
-
|
|
2233
2766
|
//#endregion
|
|
2234
2767
|
//#region src/adapters/gemini.d.ts
|
|
2235
2768
|
/**
|
|
@@ -2442,7 +2975,6 @@ interface GeminiAdapterOptions {
|
|
|
2442
2975
|
thinkingLevelModels?: ModelCapabilityOverride;
|
|
2443
2976
|
}
|
|
2444
2977
|
declare function fromGemini(client: GeminiClient, options?: GeminiAdapterOptions): LLMClient;
|
|
2445
|
-
|
|
2446
2978
|
//#endregion
|
|
2447
2979
|
//#region src/adapters/bedrock.d.ts
|
|
2448
2980
|
/** Bedrock Converse's supported inline image formats. */
|
|
@@ -2677,7 +3209,7 @@ type BedrockConverseStreamEvent = {
|
|
|
2677
3209
|
interface BedrockAdapterOptions {
|
|
2678
3210
|
/**
|
|
2679
3211
|
* Optional preflight check for tool-use support, needed whenever a
|
|
2680
|
-
* `jsonSchema` call ends up sending Converse `toolConfig
|
|
3212
|
+
* `jsonSchema` call ends up sending Converse `toolConfig`, either the
|
|
2681
3213
|
* legacy forced-single-tool-call emulation, or real `tools` sent
|
|
2682
3214
|
* alongside native structured output (`outputConfig`). VernLLM never
|
|
2683
3215
|
* guesses capability from a failed call's error message (AWS's error
|
|
@@ -2802,7 +3334,6 @@ interface AwsSendClient {
|
|
|
2802
3334
|
* `create` branch above unwraps it.
|
|
2803
3335
|
*/
|
|
2804
3336
|
declare function fromBedrock(bedrockClient: BedrockConverseClient | AwsSendClient, options?: BedrockAdapterOptions): LLMClient;
|
|
2805
|
-
|
|
2806
3337
|
//#endregion
|
|
2807
3338
|
//#region src/adapters/fetch.d.ts
|
|
2808
3339
|
/** The chat-completion-shaped request VernLLM builds internally */
|
|
@@ -2920,6 +3451,11 @@ interface FetchAdapterConfig {
|
|
|
2920
3451
|
* silently empty stream.
|
|
2921
3452
|
*/
|
|
2922
3453
|
mapStreamEvent?: (event: unknown) => WireStreamChunk | WireStreamChunk[] | undefined;
|
|
3454
|
+
/**
|
|
3455
|
+
* Optional. How to read AIMD's proactive rate limit hint off a
|
|
3456
|
+
* successful response. Defaults to OpenAI's header set.
|
|
3457
|
+
*/
|
|
3458
|
+
parseRateLimitHint?: (headers: ResponseLike['headers']) => ProviderRateLimitHint;
|
|
2923
3459
|
}
|
|
2924
3460
|
/**
|
|
2925
3461
|
* A fetch-based escape hatch for providers with no SDK, or where pulling one
|
|
@@ -2944,7 +3480,6 @@ interface FetchAdapterConfig {
|
|
|
2944
3480
|
* `mapStreamEvent` seam via `WireStreamChunk`'s `tool_call_delta` variant,
|
|
2945
3481
|
* no separate config is needed for streaming vs non-streaming tool calls.
|
|
2946
3482
|
*
|
|
2947
|
-
|
|
2948
3483
|
* `createStream` requires `mapStreamEvent` (there's no non-streaming
|
|
2949
3484
|
* response to fall back on, unlike the other three optional streaming
|
|
2950
3485
|
* seams). It opens the request via `requestStream` (defaults to native
|
|
@@ -2961,7 +3496,6 @@ interface FetchAdapterConfig {
|
|
|
2961
3496
|
* `fetch`.
|
|
2962
3497
|
*/
|
|
2963
3498
|
declare function fromFetch(config: FetchAdapterConfig): LLMClient;
|
|
2964
|
-
|
|
2965
3499
|
//#endregion
|
|
2966
3500
|
//#region src/adapters/openaiCompatible.d.ts
|
|
2967
3501
|
/**
|
|
@@ -3021,6 +3555,12 @@ interface OpenAICompatibleAdapterOptions {
|
|
|
3021
3555
|
* effect when `reasoningEffort` is set directly.
|
|
3022
3556
|
*/
|
|
3023
3557
|
reasoningEffortTokens?: Partial<EffortTokenTable>;
|
|
3558
|
+
/**
|
|
3559
|
+
* Whether the client's request builder supports `.withResponse()`
|
|
3560
|
+
* (needed for AIMD's proactive path). Default `false`, since not
|
|
3561
|
+
* every "OpenAI-compatible" client is confirmed to support it.
|
|
3562
|
+
*/
|
|
3563
|
+
supportsWithResponse?: boolean;
|
|
3024
3564
|
}
|
|
3025
3565
|
declare function fromOpenAICompatible(client: unknown, options?: OpenAICompatibleAdapterOptions): LLMClient;
|
|
3026
3566
|
/**
|
|
@@ -3030,11 +3570,15 @@ declare function fromOpenAICompatible(client: unknown, options?: OpenAICompatibl
|
|
|
3030
3570
|
* variant) in ways that no longer structurally satisfy VernLLM's
|
|
3031
3571
|
* provider-agnostic `ContentBlock[]` on `userContent`, so passing the SDK
|
|
3032
3572
|
* instance directly can fail to typecheck depending on the installed
|
|
3033
|
-
* `openai` version. Wrapping with `fromOpenAI()`
|
|
3034
|
-
* `
|
|
3035
|
-
*
|
|
3036
|
-
*
|
|
3037
|
-
*
|
|
3573
|
+
* `openai` version. Wrapping with `fromOpenAI()` sidesteps that by
|
|
3574
|
+
* translating through `unknown` at the boundary, and also picks up
|
|
3575
|
+
* multimodal image translation and `createStream` wiring that a raw
|
|
3576
|
+
* client doesn't have. See Migration Notes for details.
|
|
3577
|
+
*
|
|
3578
|
+
* `supportsWithResponse` defaults to `false` here too:
|
|
3579
|
+
* `client` is `unknown`, so there's no way to verify it's really the
|
|
3580
|
+
* official `openai` package's client versus a fake or a test double.
|
|
3581
|
+
* Pass `supportsWithResponse: true` once you've confirmed it.
|
|
3038
3582
|
*/
|
|
3039
3583
|
declare const fromOpenAI: typeof fromOpenAICompatible;
|
|
3040
3584
|
/** Groqs SDK matches the OpenAI wire format */
|
|
@@ -3128,9 +3672,6 @@ declare const fromInfermatic: typeof fromOpenAICompatible;
|
|
|
3128
3672
|
declare const fromAtlasCloud: typeof fromOpenAICompatible;
|
|
3129
3673
|
/** 01.AI's (Yi models) API is OpenAI-compatible */
|
|
3130
3674
|
declare const from01AI: typeof fromOpenAICompatible;
|
|
3131
|
-
|
|
3132
3675
|
//#endregion
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
export { AnthropicClient, AssistantContent, BedrockConverseClient, CacheAdapter, CachedCallParams, CachedConditionalToolCallParams, CachedJsonModeDisabledCallParams, CachedJsonModeEnabledCallParams, CachedStreamCallParams, CachedStreamConditionalToolCallParams, CachedStreamJsonModeDisabledCallParams, CachedStreamJsonModeEnabledCallParams, CachedStreamToolCallParams, CachedToolCallParams, CallMeta, CallParams, CallWithToolsResult, CircuitBreaker, CircuitBreakerOptions, CircuitState, CircuitTarget, ConditionalToolCallParams, ConsoleLogger, ContentBlock, ContentResult, ConversationTurn, DuplicateToolNamesIssue, FallbackAttempt, FallbackExhaustedError, FallbackOn, FallbackTarget, FetchAdapterConfig, GeminiClient, HistoryToolResultIssue, ImageBlock, InMemoryCacheAdapter, JsonModeDisabledCallParams, JsonModeEnabledCallParams, JsonSchemaSpec, JsonValue, LLMClient, LLMError, LLMErrorCode, LLMErrorIssuesByCode, LLMErrorSnapshot, LLMErrorType, LLMRequestSnapshot, Logger, NormalizedCacheAdapter, OnEvent, OnUsage, RateLimitAcquireResult, RateLimitOptions, RateLimitReason, RateLimiter, RefundUsage, ReserveUsage, RetryAttempt, SSE_PING, SchemaLike, StreamCallResult, StreamChunk, StreamEnabledCallParams, StreamJsonModeDisabledCallParams, StreamJsonModeEnabledCallParams, TargetCircuitState, TextBlock, TieredCacheAdapter, TokenUsage, ToolCall, ToolCallResult, ToolChoice, ToolDefinition, ToolEnabledCallParams, ToolIssue, ToolResult, ToolsDisabledCallParams, UnknownToolChoiceIssue, UnsupportedCapabilityIssue, VernLLM, VernLLMEvent, VernLLMOptions, WireMessage, WireRequest, WireStreamChunk, WireToolCall, WireToolChoice, defaultEstimateTokens, defaultFallbackOn, defineCachedCallParams, defineCallParams, defineTool, from01AI, fromAnthropic, fromAnyscale, fromAtlasCloud, fromBaseten, fromBedrock, fromCerebras, fromCloudflareWorkersAI, fromDeepInfra, fromDeepSeek, fromFeatherless, fromFetch, fromFireworks, fromFriendli, fromGemini, fromGroq, fromHyperbolic, fromInferenceNet, fromInfermatic, fromLMStudio, fromLambdaLabs, fromLepton, fromMiniMax, fromMistral, fromMoonshot, fromNebius, fromNovita, fromNvidiaNIM, fromOllama, fromOpenAI, fromOpenAICompatible, fromOpenRouter, fromParasail, fromPerplexity, fromSambaNova, fromSiliconFlow, fromSnowflakeCortex, fromStepFun, fromTogether, fromVLLM, fromVercelAIGateway, fromXAI, fromZhipu, hasIssues, isFallbackExhaustedError, isLLMError, isToolCallResult, parseSseStream };
|
|
3136
|
-
//# sourceMappingURL=index.d.ts.map
|
|
3676
|
+
export { type AnthropicClient, type AssistantContent, type AttemptContext, type BedrockConverseClient, type CacheAdapter, type CachedCallParams, type CachedConditionalToolCallParams, type CachedJsonModeDisabledCallParams, type CachedJsonModeEnabledCallParams, type CachedStreamCallParams, type CachedStreamConditionalToolCallParams, type CachedStreamJsonModeDisabledCallParams, type CachedStreamJsonModeEnabledCallParams, type CachedStreamToolCallParams, type CachedToolCallParams, type CallMeta, type CallParams, type CallResult, type CallWithToolsResult, CircuitBreaker, type CircuitBreakerOptions, type CircuitState, type CircuitTarget, type ConditionalToolCallParams, ConsecutiveTripping, ConsoleLogger, type ContentBlock, type ContentResult, type ConversationTurn, type CooldownBackoff, type CreateMiddlewareOptions, type DuplicateToolNamesIssue, type EvictionOption, type ExponentialBackoffOptions, type FallbackAttempt, FallbackExhaustedError, type FallbackOn, type FallbackTarget, type FetchAdapterConfig, type GeminiClient, type HistoryToolResultIssue, type ImageBlock, InMemoryCacheAdapter, type JsonModeDisabledCallParams, type JsonModeEnabledCallParams, type JsonSchemaSpec, type JsonValue, type LLMClient, LLMError, type LLMErrorCode, type LLMErrorIssuesByCode, type LLMErrorSnapshot, type LLMErrorType, type LLMRequestShape, type LLMRequestSnapshot, type Logger, type MiddlewareCapabilities, type MiddlewareContext, type MiddlewareContextBase, type MiddlewareStateBag, type MiddlewareStateKey, NormalizedCacheAdapter, type OnEvent, type OnUsage, type PreDispatchContext, type RateLimitAcquireResult, type RateLimitOptions, type RateLimitReason, RateLimiter, type RateLimiterAdapter, type RefundUsage, type ReserveUsage, type RetryAttempt, RetryBudget, type RetryBudgetOptions, RollingTripping, SSE_PING, type SchemaLike, type StreamCallResult, type StreamChunk, type StreamEnabledCallParams, type StreamJsonModeDisabledCallParams, type StreamJsonModeEnabledCallParams, type TargetCircuitState, type TextBlock, TieredCacheAdapter, type TokenUsage, type ToolCall, type ToolCallResult, type ToolChoice, type ToolDefinition, type ToolEnabledCallParams, type ToolIssue, type ToolResult, type ToolsDisabledCallParams, type TrippingPolicy, type UnknownToolChoiceIssue, type UnsupportedCapabilityIssue, VernLLM, type VernLLMEvent, type VernLLMMiddleware, type VernLLMOptions, type WireCallRequest, type WireCallRequestPatch, type WireMessage, type WireRequest, type WireResponseFormat, type WireStreamChunk, type WireTool, type WireToolCall, type WireToolChoice, createMiddleware, createMiddlewareStateBag, createStateKey, defaultEstimateTokens, defaultFallbackOn, defineCachedCallParams, defineCallParams, defineTool, from01AI, fromAnthropic, fromAnyscale, fromAtlasCloud, fromBaseten, fromBedrock, fromCerebras, fromCloudflareWorkersAI, fromDeepInfra, fromDeepSeek, fromFeatherless, fromFetch, fromFireworks, fromFriendli, fromGemini, fromGroq, fromHyperbolic, fromInferenceNet, fromInfermatic, fromLMStudio, fromLambdaLabs, fromLepton, fromMiniMax, fromMistral, fromMoonshot, fromNebius, fromNovita, fromNvidiaNIM, fromOllama, fromOpenAI, fromOpenAICompatible, fromOpenRouter, fromParasail, fromPerplexity, fromSambaNova, fromSiliconFlow, fromSnowflakeCortex, fromStepFun, fromTogether, fromVLLM, fromVercelAIGateway, fromXAI, fromZhipu, hasIssues, isFallbackExhaustedError, isLLMError, isToolCallResult, metaRef, parseSseStream };
|
|
3677
|
+
//# sourceMappingURL=index.d.mts.map
|