vern-llm 2.4.2 → 2.5.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 +3 -2
- package/dist/index.cjs +7 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +502 -197
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +502 -197
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +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';
|
|
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' | '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';
|
|
11
11
|
/**
|
|
12
12
|
* Tool contract codes: a model or provider response defect, not a
|
|
13
13
|
* transient provider fault. Deterministic on the wire request, so
|
|
@@ -187,9 +187,10 @@ declare class LLMError extends Error {
|
|
|
187
187
|
* `nonRetryableStatus` list. False for `parse`/`validation`/
|
|
188
188
|
* `invalid_params`/`aborted` types (the caller's own input, the model's
|
|
189
189
|
* 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`
|
|
190
|
+
* provider being unhealthy), the tool contract codes, the local
|
|
191
|
+
* rate limit codes, and the middleware timeout code.
|
|
192
|
+
* Subclasses (see `FallbackExhaustedError`) may override this when `type`
|
|
193
|
+
* alone carries no retry signal.
|
|
193
194
|
*/
|
|
194
195
|
get retryable(): boolean;
|
|
195
196
|
/**
|
|
@@ -303,8 +304,303 @@ declare class TieredCacheAdapter<T = unknown> implements CacheAdapter<T> {
|
|
|
303
304
|
}
|
|
304
305
|
|
|
305
306
|
//#endregion
|
|
306
|
-
//#region src/
|
|
307
|
+
//#region src/types/events.d.ts
|
|
307
308
|
//# sourceMappingURL=cache.d.ts.map
|
|
309
|
+
/**
|
|
310
|
+
* Reports what happened during a call. Fire and forget, mirroring
|
|
311
|
+
* `onUsage`: the return value is never read and a throwing handler cannot
|
|
312
|
+
* change what the call does, only what gets reported about it.
|
|
313
|
+
*/
|
|
314
|
+
type VernLLMEvent = {
|
|
315
|
+
kind: 'retry';
|
|
316
|
+
requestId: string;
|
|
317
|
+
provider: string;
|
|
318
|
+
/** The model actually resolved for this call (honors a per-call `model` override). */
|
|
319
|
+
model: string;
|
|
320
|
+
/** The 1-based retry ordinal (the 1st retry is `1`, not the overall attempt count). */
|
|
321
|
+
attempt: number;
|
|
322
|
+
maxRetries: number;
|
|
323
|
+
delayMs: number;
|
|
324
|
+
retryAfterHonored: boolean;
|
|
325
|
+
error: LLMError;
|
|
326
|
+
} | {
|
|
327
|
+
kind: 'circuit_state';
|
|
328
|
+
provider: string;
|
|
329
|
+
/**
|
|
330
|
+
* The model of the call that triggered this specific transition
|
|
331
|
+
* (whatever was passed to the `assertClosed`/`recordSuccess`/
|
|
332
|
+
* `recordFailure` call that caused it), not a property of the
|
|
333
|
+
* circuit itself: the breaker still counts failures across every
|
|
334
|
+
* model together, so a threshold crossing can be the sum of
|
|
335
|
+
* several different models' failures even though only the
|
|
336
|
+
* triggering call's `model` is reported here.
|
|
337
|
+
*/
|
|
338
|
+
model: string;
|
|
339
|
+
from: CircuitState;
|
|
340
|
+
to: CircuitState;
|
|
341
|
+
consecutiveFailures: number;
|
|
342
|
+
} | {
|
|
343
|
+
kind: 'fallback';
|
|
344
|
+
requestId: string;
|
|
345
|
+
/** Provider name of the target that just failed. */
|
|
346
|
+
from: string;
|
|
347
|
+
/** Provider name of the target about to be tried next. */
|
|
348
|
+
to: string;
|
|
349
|
+
/** `-1` for the primary target, otherwise the index into `fallback`. */
|
|
350
|
+
fromIndex: number;
|
|
351
|
+
toIndex: number;
|
|
352
|
+
/** The normalized error that caused `from` to be abandoned. */
|
|
353
|
+
error: LLMError;
|
|
354
|
+
/** Time spent on `from`, including its own retries, before giving up. */
|
|
355
|
+
elapsedMs: number;
|
|
356
|
+
} | {
|
|
357
|
+
kind: 'rate_limited';
|
|
358
|
+
requestId: string;
|
|
359
|
+
provider: string;
|
|
360
|
+
/** The model actually resolved for this call (honors a per-call `model` override). */
|
|
361
|
+
model: string;
|
|
362
|
+
/** How long this attempt sat queued for capacity before it was let through. */
|
|
363
|
+
waitedMs: number;
|
|
364
|
+
/** Which configured bucket was blocking this attempt just before it cleared. */
|
|
365
|
+
reason: 'concurrency' | 'rpm' | 'tpm';
|
|
366
|
+
} | {
|
|
367
|
+
kind: 'middleware';
|
|
368
|
+
requestId: string;
|
|
369
|
+
/** This middleware's `name`, or its array position if unnamed. */
|
|
370
|
+
middleware: string;
|
|
371
|
+
hook: 'transform' | 'wrap_short_circuit' | 'enabled_skip';
|
|
372
|
+
/** For `hook: 'transform'` only: which top-level fields the merged patch touched. */
|
|
373
|
+
patchedFields?: string[];
|
|
374
|
+
};
|
|
375
|
+
type OnEvent = (event: VernLLMEvent) => void;
|
|
376
|
+
|
|
377
|
+
//#endregion
|
|
378
|
+
//#region src/types/middleware.d.ts
|
|
379
|
+
//# sourceMappingURL=events.d.ts.map
|
|
380
|
+
/** Capabilities of the target a middleware hook is currently looking at. */
|
|
381
|
+
interface MiddlewareCapabilities {
|
|
382
|
+
/**
|
|
383
|
+
* Whether this target honors `response_format: { type: 'json_object' }`
|
|
384
|
+
* as a real constraint. Mirrors `LLMClient.supportsJsonObjectMode`.
|
|
385
|
+
* `false` for `fromAnthropic` and `fromBedrock`.
|
|
386
|
+
*/
|
|
387
|
+
supportsJsonObjectMode: boolean;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* A typed reference to one slot in `ctx.state`. Create one with
|
|
391
|
+
* `createStateKey`, export it, and import the same reference wherever
|
|
392
|
+
* another middleware needs to read or write the same value. There's no
|
|
393
|
+
* string key anywhere in this path, so a typo becomes a missing import
|
|
394
|
+
* or an undefined variable, a compile error, instead of a silently
|
|
395
|
+
* created new property.
|
|
396
|
+
*/
|
|
397
|
+
interface MiddlewareStateKey<T> {
|
|
398
|
+
readonly debugName: string;
|
|
399
|
+
/**
|
|
400
|
+
* Never set at runtime; exists purely so `T` is actually used
|
|
401
|
+
* somewhere in this interface's shape (a phantom type), which is what
|
|
402
|
+
* lets `MiddlewareStateBag.get`/`set` infer the right type for a given
|
|
403
|
+
* key instead of two `MiddlewareStateKey<string>` and
|
|
404
|
+
* `MiddlewareStateKey<number>` keys being structurally identical.
|
|
405
|
+
*/
|
|
406
|
+
readonly __phantom?: T;
|
|
407
|
+
}
|
|
408
|
+
/** Creates a new, distinct `MiddlewareStateKey`. `debugName` is used only in log lines and the `'middleware'` event; it never affects equality. */
|
|
409
|
+
declare function createStateKey<T>(debugName: string): MiddlewareStateKey<T>;
|
|
410
|
+
/**
|
|
411
|
+
* Typed, per-logical-call storage two middleware can deliberately share a
|
|
412
|
+
* value through (a span ID one sets, another reads). Backed by a plain
|
|
413
|
+
* `Map` internally, created once per logical call and never read or
|
|
414
|
+
* written by VernLLM itself.
|
|
415
|
+
*/
|
|
416
|
+
interface MiddlewareStateBag {
|
|
417
|
+
get<T>(key: MiddlewareStateKey<T>): T | undefined;
|
|
418
|
+
set<T>(key: MiddlewareStateKey<T>, value: T): void;
|
|
419
|
+
}
|
|
420
|
+
/** A plain, `Map`-backed `MiddlewareStateBag`. */
|
|
421
|
+
declare function createMiddlewareStateBag(): MiddlewareStateBag;
|
|
422
|
+
/** Fields every `MiddlewareContext` variant carries, regardless of `stage`. */
|
|
423
|
+
interface MiddlewareContextBase {
|
|
424
|
+
requestId: string;
|
|
425
|
+
/** Capabilities of the target this stage's identity fields describe. */
|
|
426
|
+
capabilities: MiddlewareCapabilities;
|
|
427
|
+
signal?: AbortSignal;
|
|
428
|
+
/** Shared, collision-proof state for two middleware to deliberately coordinate through. See `MiddlewareStateBag`. */
|
|
429
|
+
state: MiddlewareStateBag;
|
|
430
|
+
/** Simple, string-keyed scratch space, pre-namespaced to this one middleware so two middleware can never collide here even by accident. */
|
|
431
|
+
own: Record<string, unknown>;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* The `ctx` `transform` receives, and every attempt-scoped event context
|
|
435
|
+
* (`'retry'`, `'fallback'`, `'circuit_state'`, `'middleware'`). Built once
|
|
436
|
+
* a specific target has actually been selected for this attempt, so every
|
|
437
|
+
* field describes the real target, not a placeholder.
|
|
438
|
+
*/
|
|
439
|
+
interface AttemptContext extends MiddlewareContextBase {
|
|
440
|
+
stage: 'attempt';
|
|
441
|
+
/** The target this attempt is actually dispatched to. */
|
|
442
|
+
requestedProvider: string;
|
|
443
|
+
requestedModel: string;
|
|
444
|
+
isFallbackAttempt: boolean;
|
|
445
|
+
/**
|
|
446
|
+
* The real, current attempt number for this dispatch.
|
|
447
|
+
*
|
|
448
|
+
* Exception: on a `'circuit_state'` event triggered by a pre-dispatch
|
|
449
|
+
* check (`assertClosed`, before any attempt has been made), this is
|
|
450
|
+
* `1` regardless of which attempt is about to run, since no attempt
|
|
451
|
+
* exists yet to report. Every other `'circuit_state'` event, and every
|
|
452
|
+
* other attempt-scoped event, reports the real attempt number.
|
|
453
|
+
*/
|
|
454
|
+
attempt: number;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* The `ctx` `wrap` receives before `next()` resolves (and `onError`'s own
|
|
458
|
+
* `ctx`, built the same way under the hood). Built once, before any
|
|
459
|
+
* fallback target is chosen, so it only ever describes the primary
|
|
460
|
+
* target. There is no real "requested" target yet, and no attempt count,
|
|
461
|
+
* fallback flag, or per-attempt capability to report. Read `next()`'s
|
|
462
|
+
* resolved `CallResult.meta` once you need to know what actually
|
|
463
|
+
* happened.
|
|
464
|
+
*/
|
|
465
|
+
interface PreDispatchContext extends MiddlewareContextBase {
|
|
466
|
+
stage: 'pre-dispatch';
|
|
467
|
+
/** The primary target only, not necessarily who ends up answering. */
|
|
468
|
+
primaryProvider: string;
|
|
469
|
+
primaryModel: string;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* `enabled` and `onEvent` are called from both stages (gating/observing
|
|
473
|
+
* `transform` as well as `wrap`), so they receive this union and must
|
|
474
|
+
* narrow on `ctx.stage` before reading stage-specific fields.
|
|
475
|
+
* `transform` and `wrap` themselves receive the single variant that's
|
|
476
|
+
* always accurate for them (`AttemptContext`/`PreDispatchContext`
|
|
477
|
+
* respectively). See `VernLLMMiddleware`.
|
|
478
|
+
*/
|
|
479
|
+
type MiddlewareContext = AttemptContext | PreDispatchContext;
|
|
480
|
+
/** The `response_format` shape `RequestBuilder` can put on the wire. */
|
|
481
|
+
type WireResponseFormat = {
|
|
482
|
+
type: 'json_object';
|
|
483
|
+
} | {
|
|
484
|
+
type: 'json_schema';
|
|
485
|
+
json_schema: {
|
|
486
|
+
name: string;
|
|
487
|
+
schema: Record<string, unknown>;
|
|
488
|
+
strict?: boolean;
|
|
489
|
+
description?: string;
|
|
490
|
+
};
|
|
491
|
+
};
|
|
492
|
+
/** A tool as it appears on the wire, OpenAI's `function`-wrapped shape. */
|
|
493
|
+
interface WireTool {
|
|
494
|
+
type: 'function';
|
|
495
|
+
function: {
|
|
496
|
+
name: string;
|
|
497
|
+
description: string;
|
|
498
|
+
parameters: Record<string, unknown>;
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* The wire-shaped request `RequestBuilder.build()` produces for one call
|
|
503
|
+
* attempt, before dispatch. Read only inside `transform`; return a patch
|
|
504
|
+
* of the fields you want to change instead of the whole object.
|
|
505
|
+
*/
|
|
506
|
+
interface WireCallRequest {
|
|
507
|
+
model: string;
|
|
508
|
+
temperature?: number;
|
|
509
|
+
max_tokens: number;
|
|
510
|
+
response_format?: WireResponseFormat;
|
|
511
|
+
reasoning_effort?: 'minimal' | 'low' | 'medium' | 'high';
|
|
512
|
+
budget_tokens?: number;
|
|
513
|
+
tools?: WireTool[];
|
|
514
|
+
tool_choice?: WireToolChoice;
|
|
515
|
+
messages: WireMessage[];
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* What `transform` returns: a patch merged onto the request that
|
|
519
|
+
* `RequestBuilder.build()` (plus every earlier middleware's own patch)
|
|
520
|
+
* already produced, not a replacement for it. `model` and
|
|
521
|
+
* `response_format` can't be expressed here at all, since everything
|
|
522
|
+
* downstream that attributes a call to a target keys off the values
|
|
523
|
+
* `RequestBuilder` already resolved for those two fields, not off
|
|
524
|
+
* whatever ends up on the wire request. `messages`/`tools` are joined by
|
|
525
|
+
* a separate `add*` field, appended rather than replaced, so two
|
|
526
|
+
* independently written middleware can each add to the list without one
|
|
527
|
+
* silently clobbering what the other already added.
|
|
528
|
+
*/
|
|
529
|
+
interface WireCallRequestPatch {
|
|
530
|
+
temperature?: number;
|
|
531
|
+
max_tokens?: number;
|
|
532
|
+
reasoning_effort?: 'minimal' | 'low' | 'medium' | 'high';
|
|
533
|
+
budget_tokens?: number;
|
|
534
|
+
tool_choice?: WireToolChoice;
|
|
535
|
+
/** Replaces the whole message list. Prefer `addMessages` unless a full replace is genuinely the intent. */
|
|
536
|
+
messages?: WireMessage[];
|
|
537
|
+
/** Appended after whatever earlier middleware already added. Never clobbers a prior addition. */
|
|
538
|
+
addMessages?: WireMessage[];
|
|
539
|
+
/** Replaces the whole tool list. Prefer `addTools`, same reasoning as `messages`/`addMessages`. */
|
|
540
|
+
tools?: WireTool[];
|
|
541
|
+
/** Appended after whatever earlier middleware already added. Never clobbers a prior addition. */
|
|
542
|
+
addTools?: WireTool[];
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* The settled outcome of one logical call, passed to `wrap`'s `next()`.
|
|
546
|
+
* `meta` is populated once a target has actually answered, for both
|
|
547
|
+
* streaming and non-streaming calls (`undefined` only on a cache hit,
|
|
548
|
+
* where nothing was actually spent).
|
|
549
|
+
*/
|
|
550
|
+
interface CallResult<T = unknown> {
|
|
551
|
+
value: T;
|
|
552
|
+
meta?: CallMeta;
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* One entry in `VernLLMOptions.middleware`. All four hooks are optional;
|
|
556
|
+
* an entry that sets none of them is inert. See the middleware docs for
|
|
557
|
+
* how `transform`, `wrap`, `onEvent`, and `enabled` compose across
|
|
558
|
+
* several entries.
|
|
559
|
+
*/
|
|
560
|
+
interface VernLLMMiddleware {
|
|
561
|
+
/** Used in log lines and the `'middleware'` event. Defaults to this entry's array position when omitted. */
|
|
562
|
+
name?: string;
|
|
563
|
+
/** Sort key for composition order, ascending, ties broken by array order. See the middleware docs for what "lower runs first" means for `wrap`. */
|
|
564
|
+
priority?: number;
|
|
565
|
+
/**
|
|
566
|
+
* Boolean for a static on/off switch, or a predicate evaluated per
|
|
567
|
+
* call. A throwing, rejecting, or timed-out predicate is logged and
|
|
568
|
+
* treated as `false` for that call.
|
|
569
|
+
*/
|
|
570
|
+
enabled?: boolean | ((ctx: MiddlewareContext) => boolean | Promise<boolean>);
|
|
571
|
+
/** Per-middleware override of the instance-level `middlewareTimeoutMs`, applied to this entry's `transform` and function `enabled`. `<= 0` means unbounded (no timer at all). */
|
|
572
|
+
timeoutMs?: number;
|
|
573
|
+
/** 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. */
|
|
574
|
+
transform?: (request: Readonly<WireCallRequest>, ctx: AttemptContext) => WireCallRequestPatch | Promise<WireCallRequestPatch>;
|
|
575
|
+
/**
|
|
576
|
+
* Wraps one whole logical call, exactly once, regardless of how many
|
|
577
|
+
* retries or fallback targets ran underneath it. `ctx` is built once,
|
|
578
|
+
* before any fallback target is chosen, so it only describes the
|
|
579
|
+
* primary target. There is no `requestedProvider`/`isFallbackAttempt`/
|
|
580
|
+
* `attempt` to read here. Read `next()`'s resolved `CallResult.meta`
|
|
581
|
+
* for what actually happened.
|
|
582
|
+
*/
|
|
583
|
+
wrap?: (request: Readonly<WireCallRequest>, next: () => Promise<CallResult>, ctx: PreDispatchContext) => Promise<CallResult>;
|
|
584
|
+
/** 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. */
|
|
585
|
+
onEvent?: (event: VernLLMEvent, ctx: MiddlewareContext) => void;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
//#endregion
|
|
589
|
+
//#region src/circuitBreaker.d.ts
|
|
590
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
591
|
+
/** The call this mutation happened as part of, forwarded to `onStateChange` untouched. `CircuitBreaker` never inspects it. */
|
|
592
|
+
interface CircuitBreakerCallContext {
|
|
593
|
+
requestId: string;
|
|
594
|
+
state: MiddlewareStateBag;
|
|
595
|
+
signal?: AbortSignal;
|
|
596
|
+
/**
|
|
597
|
+
* The real, current attempt number for this dispatch, when the call
|
|
598
|
+
* site actually has one in scope (i.e. after a dispatch was made or
|
|
599
|
+
* failed). Omitted for calls that happen before any attempt exists,
|
|
600
|
+
* like `assertClosed`'s pre-dispatch check.
|
|
601
|
+
*/
|
|
602
|
+
attempt?: number;
|
|
603
|
+
}
|
|
308
604
|
interface CircuitBreakerOptions {
|
|
309
605
|
/** Consecutive failures before the circuit opens, default 5 */
|
|
310
606
|
threshold?: number;
|
|
@@ -323,7 +619,8 @@ interface CircuitBreakerOptions {
|
|
|
323
619
|
* here. With `isolateByModel` on, it's exact: each model has its own
|
|
324
620
|
* counter, so the transition really was caused solely by that model.
|
|
325
621
|
*/
|
|
326
|
-
onStateChange?: (from: CircuitState, to: CircuitState, consecutiveFailures: number, model?: string
|
|
622
|
+
onStateChange?: (from: CircuitState, to: CircuitState, consecutiveFailures: number, model?: string, /** See `CircuitBreakerCallContext`. */
|
|
623
|
+
context?: CircuitBreakerCallContext) => void;
|
|
327
624
|
/**
|
|
328
625
|
* Track a separate circuit per resolved model instead of one shared
|
|
329
626
|
* circuit for the whole instance. A failure on one model then never
|
|
@@ -367,9 +664,9 @@ declare class CircuitBreaker {
|
|
|
367
664
|
* elapsed, or half-open with no trial currently running), this call
|
|
368
665
|
* becomes that trial
|
|
369
666
|
*/
|
|
370
|
-
assertClosed(model?: string): void;
|
|
371
|
-
recordSuccess(model?: string): void;
|
|
372
|
-
recordFailure(model?: string): void;
|
|
667
|
+
assertClosed(model?: string, context?: CircuitBreakerCallContext): void;
|
|
668
|
+
recordSuccess(model?: string, context?: CircuitBreakerCallContext): void;
|
|
669
|
+
recordFailure(model?: string, context?: CircuitBreakerCallContext): void;
|
|
373
670
|
/**
|
|
374
671
|
* With `isolateByModel` off (the default), `model` is ignored and the
|
|
375
672
|
* one shared circuit's state is returned, unchanged from every version
|
|
@@ -385,7 +682,7 @@ declare class CircuitBreaker {
|
|
|
385
682
|
* threshold-crossing failure would, and clears any in-flight half-open
|
|
386
683
|
* trial since it no longer applies once the circuit is (re)opened.
|
|
387
684
|
*/
|
|
388
|
-
open(model?: string): void;
|
|
685
|
+
open(model?: string, context?: CircuitBreakerCallContext): void;
|
|
389
686
|
/**
|
|
390
687
|
* Manually closes the circuit and resets its failure count, e.g. once a
|
|
391
688
|
* provider is confirmed healthy again without waiting out the cooldown.
|
|
@@ -393,7 +690,7 @@ declare class CircuitBreaker {
|
|
|
393
690
|
* per-model bucket under `isolateByModel`, once idle) but without
|
|
394
691
|
* requiring an actual successful call first.
|
|
395
692
|
*/
|
|
396
|
-
close(model?: string): void;
|
|
693
|
+
close(model?: string, context?: CircuitBreakerCallContext): void;
|
|
397
694
|
}
|
|
398
695
|
|
|
399
696
|
//#endregion
|
|
@@ -616,6 +913,19 @@ declare class FallbackExhaustedError extends LLMError {
|
|
|
616
913
|
}
|
|
617
914
|
/** Narrows `err` to {@link FallbackExhaustedError}, for direct access to its `attempts` (`provider`/`model` per failed target) without a manual `instanceof` check. */
|
|
618
915
|
declare function isFallbackExhaustedError(err: unknown): err is FallbackExhaustedError;
|
|
916
|
+
/**
|
|
917
|
+
* Creates an empty ref box to pass as `CallParams['meta']`, so a caller can
|
|
918
|
+
* read the `CallMeta` written by `call()` on the same line as the result
|
|
919
|
+
* instead of pre-declaring a `{ current?: CallMeta }` by hand.
|
|
920
|
+
*
|
|
921
|
+
* @example
|
|
922
|
+
* const meta = metaRef();
|
|
923
|
+
* const result = await vern.call({ userContent: '...', meta });
|
|
924
|
+
* meta.current?.provider;
|
|
925
|
+
*/
|
|
926
|
+
declare function metaRef(): {
|
|
927
|
+
current?: CallMeta;
|
|
928
|
+
};
|
|
619
929
|
|
|
620
930
|
//#endregion
|
|
621
931
|
//#region src/types/schema.d.ts
|
|
@@ -687,7 +997,7 @@ interface ToolDefinition<Name extends string = string, Args = unknown> {
|
|
|
687
997
|
* to `string` unless annotated `as const`, which silently defeats
|
|
688
998
|
* `ToolCall` narrowing the moment a second tool is added to the same
|
|
689
999
|
* `tools: [...]` array (single-tool arrays still narrow fine even without
|
|
690
|
-
* this, since there's nothing to discriminate against
|
|
1000
|
+
* this, since there's nothing to discriminate against but that stops
|
|
691
1001
|
* being true as soon as a second tool shows up). Wrapping the same object
|
|
692
1002
|
* in `defineTool()` preserves the literal `name` type without requiring
|
|
693
1003
|
* `as const` at every call site.
|
|
@@ -704,7 +1014,7 @@ type ToolCallFor<T> = T extends ToolDefinition<infer N, infer A> ? {
|
|
|
704
1014
|
*
|
|
705
1015
|
* When `Tools` is a literal tuple (e.g. inferred from `tools: [getWeather,
|
|
706
1016
|
* cancelOrder]` at a `call()`/`cachedCall()` site), this is a discriminated
|
|
707
|
-
* union keyed by `name
|
|
1017
|
+
* union keyed by `name`. Checking `call.name === 'get_weather'` narrows
|
|
708
1018
|
* `call.arguments` to that tool's `Args` with no cast needed. Without a
|
|
709
1019
|
* literal `Tools` (the default), this collapses back to today's
|
|
710
1020
|
* `{ id: string; name: string; arguments: unknown }`.
|
|
@@ -928,13 +1238,21 @@ interface ImageBlock {
|
|
|
928
1238
|
}
|
|
929
1239
|
/** A single segment of multimodal `userContent`. */
|
|
930
1240
|
type ContentBlock = TextBlock | ImageBlock;
|
|
931
|
-
|
|
1241
|
+
/**
|
|
1242
|
+
* Every field of a call request except the `reserveUsage`/`refundUsage`
|
|
1243
|
+
* hooks from `UsageHooks`. `CallParams` is this plus `UsageHooks`; the
|
|
1244
|
+
* `Cached*` param types below are call sites that want the request shape
|
|
1245
|
+
* without those two hooks (usage is metered once, at the `cachedCall`
|
|
1246
|
+
* level, not per-request), and use this directly instead of re-deriving
|
|
1247
|
+
* it with `Omit<CallParams<T>, 'reserveUsage' | 'refundUsage'>` each time.
|
|
1248
|
+
*/
|
|
1249
|
+
interface LLMRequestShape<T = unknown, Tools extends readonly ToolDefinition[] = ToolDefinition[]> {
|
|
932
1250
|
systemPrompt?: string;
|
|
933
1251
|
/** Current user message, as text or multimodal content blocks. */
|
|
934
1252
|
userContent: string | ContentBlock[];
|
|
935
1253
|
/**
|
|
936
1254
|
* Previous conversation turns. Must alternate roles; tool turns must follow
|
|
937
|
-
* assistant tool calls. Invalid history throws LLMError('
|
|
1255
|
+
* assistant tool calls. Invalid history throws LLMError('invalid_params').
|
|
938
1256
|
*/
|
|
939
1257
|
history?: ConversationTurn[];
|
|
940
1258
|
/**
|
|
@@ -947,6 +1265,20 @@ interface CallParams<T = unknown, Tools extends readonly ToolDefinition[] = Tool
|
|
|
947
1265
|
maxTokens?: number;
|
|
948
1266
|
requestId?: string;
|
|
949
1267
|
signal?: AbortSignal;
|
|
1268
|
+
/**
|
|
1269
|
+
* Total time budget in ms for this whole call, across every retry and
|
|
1270
|
+
* every fallback target. Unlike timeoutMs, which resets on each attempt,
|
|
1271
|
+
* this is a single clock starting when call is invoked. The call is
|
|
1272
|
+
* aborted once this elapses, even mid retry or mid fallback, the same
|
|
1273
|
+
* way an aborted signal is today. Omit for no overall deadline, only
|
|
1274
|
+
* the existing per attempt timeoutMs applies.
|
|
1275
|
+
*
|
|
1276
|
+
* Only bounds getting to a final result: choosing a target, retrying,
|
|
1277
|
+
* and opening a stream. It does not extend to the time spent reading a
|
|
1278
|
+
* stream after it has opened. Use chunkIdleTimeoutMs for gaps between
|
|
1279
|
+
* chunks once a stream is open.
|
|
1280
|
+
*/
|
|
1281
|
+
deadlineMs?: number;
|
|
950
1282
|
/**
|
|
951
1283
|
* Per-call override for the instance's `chunkIdleTimeoutMs` (max gap
|
|
952
1284
|
* between stream chunks once opened). Only applies when `stream: true`.
|
|
@@ -1019,15 +1351,24 @@ interface CallParams<T = unknown, Tools extends readonly ToolDefinition[] = Tool
|
|
|
1019
1351
|
* Optional out-parameter for provider identity. Pass `{}` (or any object
|
|
1020
1352
|
* with a mutable `current` property) and `call()` writes a `CallMeta`
|
|
1021
1353
|
* into `meta.current` before returning, alongside whatever `onUsage`
|
|
1022
|
-
* already reports.
|
|
1023
|
-
*
|
|
1024
|
-
* `
|
|
1025
|
-
*
|
|
1354
|
+
* already reports. This includes `stream: true`: the target is chosen
|
|
1355
|
+
* once the stream opens, which is also the point `call()` itself
|
|
1356
|
+
* returns `{ chunks, finalResult }`, so `meta.current` is already set
|
|
1357
|
+
* by then. `TokenUsage.provider`/`usedFallback` from `onUsage` reports
|
|
1358
|
+
* the same information asynchronously, for both streaming and
|
|
1359
|
+
* non-streaming calls.
|
|
1360
|
+
*
|
|
1361
|
+
* `meta.current` is only written once execution actually reaches and
|
|
1362
|
+
* selects a provider target. A `wrap` middleware that short-circuits
|
|
1363
|
+
* without calling `next()` never reaches that point, so `meta.current`
|
|
1364
|
+
* is left untouched; if the same holder object is reused across calls,
|
|
1365
|
+
* it can still hold a prior call's target.
|
|
1026
1366
|
*/
|
|
1027
1367
|
meta?: {
|
|
1028
1368
|
current?: CallMeta;
|
|
1029
1369
|
};
|
|
1030
1370
|
}
|
|
1371
|
+
interface CallParams<T = unknown, Tools extends readonly ToolDefinition[] = ToolDefinition[]> extends LLMRequestShape<T, Tools>, UsageHooks {}
|
|
1031
1372
|
/**
|
|
1032
1373
|
* A `CallParams` variant where tool calling is explicitly enabled.
|
|
1033
1374
|
*
|
|
@@ -1119,7 +1460,7 @@ interface CachedCallInput extends UsageHooks {
|
|
|
1119
1460
|
* the caching docs for why.
|
|
1120
1461
|
*/
|
|
1121
1462
|
type CachedCallParams<T> = CachedCallInput & {
|
|
1122
|
-
call:
|
|
1463
|
+
call: LLMRequestShape<T>;
|
|
1123
1464
|
};
|
|
1124
1465
|
/**
|
|
1125
1466
|
* Parameters for a cached LLM call with tool calling enabled.
|
|
@@ -1132,7 +1473,9 @@ type CachedCallParams<T> = CachedCallInput & {
|
|
|
1132
1473
|
* from `call`'s type here too.
|
|
1133
1474
|
*/
|
|
1134
1475
|
type CachedToolCallParams<T, Tools extends readonly ToolDefinition[] = ToolDefinition[]> = CachedCallInput & {
|
|
1135
|
-
call:
|
|
1476
|
+
call: LLMRequestShape<T, Tools> & {
|
|
1477
|
+
tools: NonNullable<LLMRequestShape<T, Tools>['tools']>;
|
|
1478
|
+
};
|
|
1136
1479
|
};
|
|
1137
1480
|
/**
|
|
1138
1481
|
* Parameters for a cached LLM call with `call.tools` set conditionally.
|
|
@@ -1141,7 +1484,9 @@ type CachedToolCallParams<T, Tools extends readonly ToolDefinition[] = ToolDefin
|
|
|
1141
1484
|
* `ConditionalToolCallParams` for why this overload exists.
|
|
1142
1485
|
*/
|
|
1143
1486
|
type CachedConditionalToolCallParams<T, Tools extends readonly ToolDefinition[] = ToolDefinition[]> = CachedCallInput & {
|
|
1144
|
-
call:
|
|
1487
|
+
call: LLMRequestShape<T, Tools> & {
|
|
1488
|
+
tools: Tools | undefined;
|
|
1489
|
+
};
|
|
1145
1490
|
};
|
|
1146
1491
|
/** Cached conditional tool-call parameters whose non-tool result is plain text. */
|
|
1147
1492
|
type CachedConditionalStringToolCallParams<Tools extends readonly ToolDefinition[] = ToolDefinition[]> = CachedConditionalToolCallParams<string, Tools> & {
|
|
@@ -1154,14 +1499,20 @@ type CachedConditionalStringToolCallParams<Tools extends readonly ToolDefinition
|
|
|
1154
1499
|
* `cachedCall()` overload that returns a plain `string`.
|
|
1155
1500
|
*/
|
|
1156
1501
|
type CachedJsonModeDisabledCallParams = CachedCallInput & {
|
|
1157
|
-
call: Omit<
|
|
1502
|
+
call: Omit<LLMRequestShape<unknown>, 'jsonSchema'> & {
|
|
1503
|
+
jsonMode: false;
|
|
1504
|
+
jsonSchema?: never;
|
|
1505
|
+
};
|
|
1158
1506
|
};
|
|
1159
1507
|
/**
|
|
1160
1508
|
* Parameters for a cached LLM call with `jsonMode: true` and no `schema`.
|
|
1161
1509
|
* Selects the `cachedCall()` overload that returns a `JsonValue`.
|
|
1162
1510
|
*/
|
|
1163
1511
|
type CachedJsonModeEnabledCallParams = CachedCallInput & {
|
|
1164
|
-
call: Omit<
|
|
1512
|
+
call: Omit<LLMRequestShape<JsonValue>, 'schema'> & {
|
|
1513
|
+
jsonMode: true;
|
|
1514
|
+
schema?: never;
|
|
1515
|
+
};
|
|
1165
1516
|
};
|
|
1166
1517
|
|
|
1167
1518
|
//#endregion
|
|
@@ -1282,10 +1633,12 @@ type WireStreamChunk = {
|
|
|
1282
1633
|
* like).
|
|
1283
1634
|
*
|
|
1284
1635
|
* `reserveUsage`/`refundUsage` are omitted from `call`'s type; see
|
|
1285
|
-
* `CachedCallParams` for why
|
|
1636
|
+
* `CachedCallParams` for why they belong at the top level here too.
|
|
1286
1637
|
*/
|
|
1287
1638
|
type CachedStreamCallParams<T> = CachedCallInput & {
|
|
1288
|
-
call:
|
|
1639
|
+
call: LLMRequestShape<T> & {
|
|
1640
|
+
stream: true;
|
|
1641
|
+
};
|
|
1289
1642
|
};
|
|
1290
1643
|
/**
|
|
1291
1644
|
* Parameters for a cached, streaming LLM call with tool calling enabled.
|
|
@@ -1295,7 +1648,10 @@ type CachedStreamCallParams<T> = CachedCallInput & {
|
|
|
1295
1648
|
* replayed-chunks-on-hit behavior as `CachedStreamCallParams<T>`.
|
|
1296
1649
|
*/
|
|
1297
1650
|
type CachedStreamToolCallParams<T, Tools extends readonly ToolDefinition[] = ToolDefinition[]> = CachedCallInput & {
|
|
1298
|
-
call:
|
|
1651
|
+
call: LLMRequestShape<T, Tools> & {
|
|
1652
|
+
stream: true;
|
|
1653
|
+
tools: NonNullable<LLMRequestShape<T, Tools>['tools']>;
|
|
1654
|
+
};
|
|
1299
1655
|
};
|
|
1300
1656
|
/**
|
|
1301
1657
|
* Parameters for a cached, streaming LLM call with `call.tools` set
|
|
@@ -1305,7 +1661,10 @@ type CachedStreamToolCallParams<T, Tools extends readonly ToolDefinition[] = Too
|
|
|
1305
1661
|
* `ConditionalToolCallParams` for why this overload exists.
|
|
1306
1662
|
*/
|
|
1307
1663
|
type CachedStreamConditionalToolCallParams<T, Tools extends readonly ToolDefinition[] = ToolDefinition[]> = CachedCallInput & {
|
|
1308
|
-
call:
|
|
1664
|
+
call: LLMRequestShape<T, Tools> & {
|
|
1665
|
+
stream: true;
|
|
1666
|
+
tools: Tools | undefined;
|
|
1667
|
+
};
|
|
1309
1668
|
};
|
|
1310
1669
|
/** Cached streaming conditional tool-call parameters whose non-tool result is text. */
|
|
1311
1670
|
type CachedStreamConditionalStringToolCallParams<Tools extends readonly ToolDefinition[] = ToolDefinition[]> = CachedStreamConditionalToolCallParams<string, Tools> & {
|
|
@@ -1319,7 +1678,11 @@ type CachedStreamConditionalStringToolCallParams<Tools extends readonly ToolDefi
|
|
|
1319
1678
|
* cached value (on a hit) is a plain `string`.
|
|
1320
1679
|
*/
|
|
1321
1680
|
type CachedStreamJsonModeDisabledCallParams = CachedCallInput & {
|
|
1322
|
-
call: Omit<
|
|
1681
|
+
call: Omit<LLMRequestShape<unknown>, 'jsonSchema'> & {
|
|
1682
|
+
stream: true;
|
|
1683
|
+
jsonMode: false;
|
|
1684
|
+
jsonSchema?: never;
|
|
1685
|
+
};
|
|
1323
1686
|
};
|
|
1324
1687
|
/**
|
|
1325
1688
|
* Parameters for a cached, streaming LLM call with `jsonMode: true` and no
|
|
@@ -1327,7 +1690,11 @@ type CachedStreamJsonModeDisabledCallParams = CachedCallInput & {
|
|
|
1327
1690
|
* miss) or cached value (on a hit) is a `JsonValue`.
|
|
1328
1691
|
*/
|
|
1329
1692
|
type CachedStreamJsonModeEnabledCallParams = CachedCallInput & {
|
|
1330
|
-
call: Omit<
|
|
1693
|
+
call: Omit<LLMRequestShape<JsonValue>, 'schema'> & {
|
|
1694
|
+
stream: true;
|
|
1695
|
+
jsonMode: true;
|
|
1696
|
+
schema?: never;
|
|
1697
|
+
};
|
|
1331
1698
|
};
|
|
1332
1699
|
|
|
1333
1700
|
//#endregion
|
|
@@ -1483,72 +1850,9 @@ declare class ConsoleLogger implements Logger {
|
|
|
1483
1850
|
error(message: string, meta?: Record<string, unknown>): void;
|
|
1484
1851
|
}
|
|
1485
1852
|
|
|
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
1853
|
//#endregion
|
|
1550
1854
|
//#region src/types/options.d.ts
|
|
1551
|
-
//# sourceMappingURL=
|
|
1855
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
1552
1856
|
interface VernLLMOptions {
|
|
1553
1857
|
client: LLMClient;
|
|
1554
1858
|
model: string;
|
|
@@ -1680,11 +1984,61 @@ interface VernLLMOptions {
|
|
|
1680
1984
|
* and moves on for everything else.
|
|
1681
1985
|
*/
|
|
1682
1986
|
fallbackOn?: FallbackOn;
|
|
1987
|
+
/**
|
|
1988
|
+
* Transforms outgoing requests and/or wraps whole logical calls,
|
|
1989
|
+
* without touching retry, circuit breaker, or fallback internals.
|
|
1990
|
+
* Defaults to an empty array. See `VernLLMMiddleware` for the four
|
|
1991
|
+
* available hooks (`transform`, `wrap`, `onEvent`, `enabled`).
|
|
1992
|
+
*/
|
|
1993
|
+
middleware?: VernLLMMiddleware[];
|
|
1994
|
+
/**
|
|
1995
|
+
* Bounds `transform` and a function `enabled`, the same way every
|
|
1996
|
+
* other blocking operation in the package is already bounded.
|
|
1997
|
+
* Overridable per middleware via that entry's own `timeoutMs`.
|
|
1998
|
+
* `<= 0` means unbounded (no timer at all). Default 5000.
|
|
1999
|
+
*/
|
|
2000
|
+
middlewareTimeoutMs?: number;
|
|
1683
2001
|
}
|
|
1684
2002
|
|
|
1685
2003
|
//#endregion
|
|
1686
|
-
//#region src/
|
|
2004
|
+
//#region src/types/createMiddleware.d.ts
|
|
1687
2005
|
//# sourceMappingURL=options.d.ts.map
|
|
2006
|
+
/**
|
|
2007
|
+
* `VernLLMMiddleware` plus `onError`, a convenience for the common "I
|
|
2008
|
+
* only care about failures" case. Everything else is passed through to
|
|
2009
|
+
* the resulting `VernLLMMiddleware` unchanged; setting `wrap` directly
|
|
2010
|
+
* alongside `onError` is an error, since `onError` builds its own `wrap`
|
|
2011
|
+
* under the hood, and building it around a `wrap` you also supplied
|
|
2012
|
+
* would silently drop one of the two.
|
|
2013
|
+
*/
|
|
2014
|
+
type CreateMiddlewareOptions = Omit<VernLLMMiddleware, 'wrap'> & {
|
|
2015
|
+
wrap?: undefined;
|
|
2016
|
+
/**
|
|
2017
|
+
* Called with this call's terminal error, if it fails: the same error
|
|
2018
|
+
* `wrap`'s own `next()` would reject with. Never called on success,
|
|
2019
|
+
* and never called for a failure some *other* middleware's `wrap`
|
|
2020
|
+
* already swallowed by short-circuiting with its own `CallResult`.
|
|
2021
|
+
* The original error is always rethrown afterward, `onError` only
|
|
2022
|
+
* observes it, exactly like `onUsage`/`onEvent` elsewhere: a throwing
|
|
2023
|
+
* `onError` is discarded (not logged, this helper has no `Logger` of
|
|
2024
|
+
* its own to log through) and otherwise has no effect on the call.
|
|
2025
|
+
* `ctx` is `wrap`'s own pre-dispatch context (`onError` builds a `wrap`
|
|
2026
|
+
* under the hood), so it only describes the primary target.
|
|
2027
|
+
*/
|
|
2028
|
+
onError?: (error: LLMError, ctx: PreDispatchContext) => void | Promise<void>;
|
|
2029
|
+
};
|
|
2030
|
+
/**
|
|
2031
|
+
* Builds a `VernLLMMiddleware` entry. Plain pass-through when `onError`
|
|
2032
|
+
* is omitted; when it's set, wraps it in a `wrap` that calls `next()`,
|
|
2033
|
+
* reports `onError` on a rejection, and always rethrows the original
|
|
2034
|
+
* error afterward, so `onError` never changes what the call itself
|
|
2035
|
+
* returns or throws, only what gets observed about it.
|
|
2036
|
+
*/
|
|
2037
|
+
declare function createMiddleware(options: CreateMiddlewareOptions): VernLLMMiddleware;
|
|
2038
|
+
|
|
2039
|
+
//#endregion
|
|
2040
|
+
//#region src/vernLLM.d.ts
|
|
2041
|
+
//# sourceMappingURL=createMiddleware.d.ts.map
|
|
1688
2042
|
/**
|
|
1689
2043
|
* A LLM call framework for resilience, observability and control. This is VernLLM!
|
|
1690
2044
|
*
|
|
@@ -1698,21 +2052,37 @@ declare class VernLLM {
|
|
|
1698
2052
|
/**
|
|
1699
2053
|
* One `CallExecutor` per provider target: index 0 is the primary,
|
|
1700
2054
|
* everything after it is a `fallback` target, in the order declared.
|
|
1701
|
-
*
|
|
1702
|
-
*
|
|
1703
|
-
* moving to the next entry only when `fallbackOn` says to.
|
|
2055
|
+
* Walked by `runFallbackChain`, moving to the next entry only when
|
|
2056
|
+
* `fallbackOn` says to.
|
|
1704
2057
|
*/
|
|
1705
2058
|
private readonly executors;
|
|
1706
2059
|
/** Decides whether a failed target is followed by the next one or the chain stops. See `VernLLMOptions['fallbackOn']`. */
|
|
1707
2060
|
private readonly fallbackOn;
|
|
1708
2061
|
/** Reports a `'fallback'` event when the chain moves to the next target. Shared `onEvent` plumbing, same as every executor's. */
|
|
1709
2062
|
private readonly reportEvent;
|
|
2063
|
+
/** Owns cache reads/writes and in-flight coalescing for `cachedCall()`. Only calls back into `this.call()` as an opaque function. */
|
|
2064
|
+
private readonly cacheOrchestrator;
|
|
2065
|
+
/** See `VernLLMOptions.middleware`. Sorted once here by `priority`, ascending, ties broken by original array order. */
|
|
2066
|
+
private readonly middleware;
|
|
2067
|
+
/** See `VernLLMOptions.middlewareTimeoutMs`. Bounds `transform` and a function `enabled`; `wrap` itself is never bounded by this. */
|
|
2068
|
+
private readonly middlewareTimeoutMs;
|
|
1710
2069
|
/**
|
|
1711
|
-
*
|
|
1712
|
-
*
|
|
1713
|
-
*
|
|
2070
|
+
* Maps `cachedCall()`'s inner `this.call(...)` params to its own
|
|
2071
|
+
* `middlewareState`, so that call's own `runOperation` skips wrapping
|
|
2072
|
+
* again and reuses the same state bag `wrap` just ran with (so a
|
|
2073
|
+
* value `wrap` sets is visible to `transform`, same as a direct
|
|
2074
|
+
* call). Keyed by object identity, not `requestId`, since two
|
|
2075
|
+
* concurrent `cachedCall()`s can share an explicit `requestId`.
|
|
1714
2076
|
*/
|
|
1715
|
-
private readonly
|
|
2077
|
+
private readonly cachedCallInnerParams;
|
|
2078
|
+
/**
|
|
2079
|
+
* Shares one `CallMeta` holder across every `cachedCall()` in flight
|
|
2080
|
+
* for the same resolved cache key, so a joining invocation (never
|
|
2081
|
+
* calls `call()` itself) reports the trigger's real metadata instead
|
|
2082
|
+
* of `undefined`. A true cache hit never creates an entry, so it
|
|
2083
|
+
* still reports no metadata correctly.
|
|
2084
|
+
*/
|
|
2085
|
+
private readonly cachedCallMeta;
|
|
1716
2086
|
/**
|
|
1717
2087
|
* @param options Client, model, and tunables. Defaults: `maxRetries` 1,
|
|
1718
2088
|
* `timeoutMs` 25000, `baseDelayMs` 500, `defaultMaxTokens` 1000,
|
|
@@ -1722,72 +2092,23 @@ declare class VernLLM {
|
|
|
1722
2092
|
constructor(options: VernLLMOptions);
|
|
1723
2093
|
/** Logs a failed refundUsage attempt via the configured logger. */
|
|
1724
2094
|
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;
|
|
2095
|
+
/** Everything `executeLogicalCall`/`executeLogicalStreamCall` (in `logicalCall.ts`) need from this instance, gathered once so `call()` doesn't rebuild it per invocation. */
|
|
2096
|
+
private get logicalCallDependencies();
|
|
2097
|
+
/** Everything `runOperation` (in `runOperation.ts`) needs from this instance, gathered once so `call()`/`cachedCall()` don't rebuild it per invocation. */
|
|
2098
|
+
private get runOperationDependencies();
|
|
1740
2099
|
/**
|
|
1741
2100
|
* Makes a single logical LLM call, retrying on failure per the configured
|
|
1742
2101
|
* 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.
|
|
2102
|
+
* aborted. Rejects with a normalized `LLMError` on exhausted retries.
|
|
1761
2103
|
*
|
|
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).
|
|
2104
|
+
* Supports `tools`, `stream`, and JSON mode/schema, in any combination.
|
|
2105
|
+
* See the Tool Calling and Streaming docs for return-shape details and
|
|
2106
|
+
* the TypeScript overloads that select between them.
|
|
1782
2107
|
*
|
|
1783
2108
|
* @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`.
|
|
2109
|
+
* @returns The parsed response (or raw string if `jsonMode` is false), a
|
|
2110
|
+
* `CallWithToolsResult<T>` when `tools` is set, or a `{ chunks,
|
|
2111
|
+
* finalResult }` `StreamCallResult` when `stream: true`. See `StreamCallResult`.
|
|
1791
2112
|
*/
|
|
1792
2113
|
call<T = unknown>(params: StreamEnabledCallParams<T> & ToolsDisabledCallParams<T>): Promise<StreamCallResult<ContentResult<T>>>;
|
|
1793
2114
|
call<T = unknown, const Tools extends readonly ToolDefinition[] = ToolDefinition[]>(params: StreamEnabledCallParams<T, Tools> & ToolEnabledCallParams<T, Tools>): Promise<StreamCallResult<CallWithToolsResult<T, Tools>>>;
|
|
@@ -1821,35 +2142,19 @@ declare class VernLLM {
|
|
|
1821
2142
|
deleteCache(key: string): Promise<void>;
|
|
1822
2143
|
/**
|
|
1823
2144
|
* 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.
|
|
2145
|
+
* automatically get retry/timeout/circuit-breaker behavior. Concurrent
|
|
2146
|
+
* misses for the same `cacheKey` share a single in-flight call, avoiding
|
|
2147
|
+
* cache stampedes. Supports `stream: true` and `tools` in any combination.
|
|
1836
2148
|
*
|
|
1837
|
-
*
|
|
1838
|
-
* `
|
|
1839
|
-
*
|
|
1840
|
-
* caching library at the application level instead.
|
|
2149
|
+
* When `call.tools` is set, this caches the whole result including any
|
|
2150
|
+
* `tool_calls` decision, not just final answers; use a short `ttl` or a
|
|
2151
|
+
* separate `cacheKey` if a tool's result shouldn't be reused across calls.
|
|
1841
2152
|
*
|
|
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
|
|
2153
|
+
* @param params `cacheKey`, `ttl`, optional
|
|
1848
2154
|
* `reserveUsage`/`refundUsage`/`signal`, plus `call`, the `CallParams`
|
|
1849
|
-
*
|
|
1850
|
-
*
|
|
1851
|
-
*
|
|
1852
|
-
* request, set `signal` inside `call`.
|
|
2155
|
+
* to pass through to `this.call(...)`. The top-level `signal` governs
|
|
2156
|
+
* the cached operation and its usage hooks only; to also abort the
|
|
2157
|
+
* underlying provider request, set `signal` inside `call`.
|
|
1853
2158
|
* @returns The cached value on a hit, or the freshly-called result on a miss.
|
|
1854
2159
|
*/
|
|
1855
2160
|
cachedCall<T, const Tools extends readonly ToolDefinition[] = ToolDefinition[]>(params: CachedStreamToolCallParams<T, Tools>): Promise<StreamCallResult<CallWithToolsResult<T, Tools>>>;
|
|
@@ -1896,11 +2201,11 @@ declare class VernLLM {
|
|
|
1896
2201
|
* @throws {RangeError} If `target.index` names no target.
|
|
1897
2202
|
*/
|
|
1898
2203
|
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
2204
|
}
|
|
2205
|
+
|
|
2206
|
+
//#endregion
|
|
2207
|
+
//#region src/paramsHelpers.d.ts
|
|
2208
|
+
//# sourceMappingURL=vernLLM.d.ts.map
|
|
1904
2209
|
/**
|
|
1905
2210
|
* Identity function preserving `params`'s own precise type, unlike a `:
|
|
1906
2211
|
* CallParams<T>` annotation, which would widen `tools` away and break the
|
|
@@ -1939,7 +2244,7 @@ declare function defineCachedCallParams<P extends CachedCallParams<unknown>>(par
|
|
|
1939
2244
|
|
|
1940
2245
|
//#endregion
|
|
1941
2246
|
//#region src/adapters/internal/sse.d.ts
|
|
1942
|
-
//# sourceMappingURL=
|
|
2247
|
+
//# sourceMappingURL=paramsHelpers.d.ts.map
|
|
1943
2248
|
/**
|
|
1944
2249
|
* Parses a Server-Sent-Events byte/text stream into the JSON payload of
|
|
1945
2250
|
* each `data:` frame, in arrival order. Generic over transport: works with
|
|
@@ -2000,8 +2305,8 @@ type SupportedImageMimeType = (typeof SUPPORTED_IMAGE_MIME_TYPES)[number];
|
|
|
2000
2305
|
|
|
2001
2306
|
/**
|
|
2002
2307
|
* A static allow-list or predicate naming which models support native,
|
|
2003
|
-
* schema-constrained output as its own request field
|
|
2004
|
-
* `output_config.format
|
|
2308
|
+
* schema-constrained output as its own request field. Anthropic's
|
|
2309
|
+
* `output_config.format` and Bedrock's `outputConfig.textFormat` separate
|
|
2005
2310
|
* from `tools`/`tool_choice`, so it can be combined with real,
|
|
2006
2311
|
* caller-supplied `tools` in the same request.
|
|
2007
2312
|
*
|
|
@@ -2677,7 +2982,7 @@ type BedrockConverseStreamEvent = {
|
|
|
2677
2982
|
interface BedrockAdapterOptions {
|
|
2678
2983
|
/**
|
|
2679
2984
|
* Optional preflight check for tool-use support, needed whenever a
|
|
2680
|
-
* `jsonSchema` call ends up sending Converse `toolConfig
|
|
2985
|
+
* `jsonSchema` call ends up sending Converse `toolConfig`, either the
|
|
2681
2986
|
* legacy forced-single-tool-call emulation, or real `tools` sent
|
|
2682
2987
|
* alongside native structured output (`outputConfig`). VernLLM never
|
|
2683
2988
|
* guesses capability from a failed call's error message (AWS's error
|
|
@@ -3132,5 +3437,5 @@ declare const from01AI: typeof fromOpenAICompatible;
|
|
|
3132
3437
|
//#endregion
|
|
3133
3438
|
//# sourceMappingURL=openaiCompatible.d.ts.map
|
|
3134
3439
|
|
|
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 };
|
|
3440
|
+
export { AnthropicClient, AssistantContent, AttemptContext, BedrockConverseClient, CacheAdapter, CachedCallParams, CachedConditionalToolCallParams, CachedJsonModeDisabledCallParams, CachedJsonModeEnabledCallParams, CachedStreamCallParams, CachedStreamConditionalToolCallParams, CachedStreamJsonModeDisabledCallParams, CachedStreamJsonModeEnabledCallParams, CachedStreamToolCallParams, CachedToolCallParams, CallMeta, CallParams, CallResult, CallWithToolsResult, CircuitBreaker, CircuitBreakerOptions, CircuitState, CircuitTarget, ConditionalToolCallParams, ConsoleLogger, ContentBlock, ContentResult, ConversationTurn, CreateMiddlewareOptions, DuplicateToolNamesIssue, FallbackAttempt, FallbackExhaustedError, FallbackOn, FallbackTarget, FetchAdapterConfig, GeminiClient, HistoryToolResultIssue, ImageBlock, InMemoryCacheAdapter, JsonModeDisabledCallParams, JsonModeEnabledCallParams, JsonSchemaSpec, JsonValue, LLMClient, LLMError, LLMErrorCode, LLMErrorIssuesByCode, LLMErrorSnapshot, LLMErrorType, LLMRequestShape, LLMRequestSnapshot, Logger, MiddlewareCapabilities, MiddlewareContext, MiddlewareContextBase, MiddlewareStateBag, MiddlewareStateKey, NormalizedCacheAdapter, OnEvent, OnUsage, PreDispatchContext, 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, VernLLMMiddleware, VernLLMOptions, WireCallRequest, WireCallRequestPatch, WireMessage, WireRequest, WireResponseFormat, WireStreamChunk, WireTool, WireToolCall, 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 };
|
|
3136
3441
|
//# sourceMappingURL=index.d.ts.map
|