@jaypie/llm 1.3.10 → 1.3.11

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.
@@ -1,6 +1,7 @@
1
1
  import * as _jaypie_types from '@jaypie/types';
2
2
  import { JsonObject, AnyValue, NaturalMap, NaturalSchema, JsonReturn } from '@jaypie/types';
3
3
  import { z } from 'zod/v4';
4
+ import { JaypieError } from '@jaypie/errors';
4
5
 
5
6
  /**
6
7
  * Provider-neutral reasoning-effort levels — a five-point relative scale that
@@ -324,7 +325,7 @@ declare enum LlmResponseStatus {
324
325
  Incomplete = "incomplete",
325
326
  InProgress = "in_progress"
326
327
  }
327
- interface LlmError {
328
+ interface LlmError$1 {
328
329
  detail?: string;
329
330
  status: number | string;
330
331
  title: string;
@@ -593,6 +594,15 @@ interface LlmOperateOptions {
593
594
  turns?: boolean | number;
594
595
  user?: string;
595
596
  }
597
+ /**
598
+ * A single model name, or a preference-ordered array of model names.
599
+ * An array is interpreted as a fallback chain: index 0 is primary, later
600
+ * entries are tried in order when earlier ones fail (provider auto-detected
601
+ * per entry). Accepted by the `Llm` constructor and static/instance
602
+ * `operate`/`send`/`stream` methods; normalized to a scalar model plus a
603
+ * derived fallback chain before reaching providers.
604
+ */
605
+ type LlmModelOption = string | string[];
596
606
  interface LlmOptions {
597
607
  apiKey?: string;
598
608
  /** Chain of fallback providers to try if primary fails */
@@ -610,7 +620,7 @@ interface LlmUsageItem {
610
620
  type LlmUsage = LlmUsageItem[];
611
621
  interface LlmOperateResponse {
612
622
  content?: string | JsonObject;
613
- error?: LlmError;
623
+ error?: LlmError$1;
614
624
  /** Number of providers attempted (1 = primary only, >1 = fallback(s) used) */
615
625
  fallbackAttempts?: number;
616
626
  /** Whether a fallback provider was used instead of the primary */
@@ -636,9 +646,13 @@ declare class Llm implements LlmProvider {
636
646
  private _llm;
637
647
  private _options;
638
648
  private _provider;
639
- constructor(providerName?: LlmProviderName | string, options?: LlmOptions);
649
+ constructor(providerName?: LlmProviderName | string, options?: Omit<LlmOptions, "model"> & {
650
+ model?: LlmModelOption;
651
+ });
640
652
  private createProvider;
641
- send(message: string, options?: LlmMessageOptions): Promise<string | JsonObject>;
653
+ send(message: string, options?: Omit<LlmMessageOptions, "model"> & {
654
+ model?: LlmModelOption;
655
+ }): Promise<string | JsonObject>;
642
656
  /**
643
657
  * Resolves the fallback chain from instance config and per-call options.
644
658
  * Per-call options take precedence over instance config.
@@ -649,23 +663,27 @@ declare class Llm implements LlmProvider {
649
663
  * Creates a fallback Llm instance lazily when needed.
650
664
  */
651
665
  private createFallbackInstance;
652
- operate(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions): Promise<LlmOperateResponse>;
653
- stream(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions): AsyncIterable<LlmStreamChunk>;
654
- static send(message: string, options?: LlmMessageOptions & {
666
+ operate(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: Omit<LlmOperateOptions, "model"> & {
667
+ model?: LlmModelOption;
668
+ }): Promise<LlmOperateResponse>;
669
+ stream(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: Omit<LlmOperateOptions, "model"> & {
670
+ model?: LlmModelOption;
671
+ }): AsyncIterable<LlmStreamChunk>;
672
+ static send(message: string, options?: Omit<LlmMessageOptions, "model"> & {
655
673
  llm?: LlmProviderName;
656
674
  apiKey?: string;
657
- model?: string;
675
+ model?: string | string[];
658
676
  }): Promise<string | JsonObject>;
659
- static operate(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions & {
677
+ static operate(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: Omit<LlmOperateOptions, "model"> & {
660
678
  apiKey?: string;
661
679
  fallback?: LlmFallbackConfig[] | false;
662
680
  llm?: LlmProviderName;
663
- model?: string;
681
+ model?: string | string[];
664
682
  }): Promise<LlmOperateResponse>;
665
- static stream(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions & {
683
+ static stream(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: Omit<LlmOperateOptions, "model"> & {
666
684
  llm?: LlmProviderName;
667
685
  apiKey?: string;
668
- model?: string;
686
+ model?: string | string[];
669
687
  }): AsyncIterable<LlmStreamChunk>;
670
688
  }
671
689
 
@@ -696,6 +714,87 @@ declare class JaypieToolkit extends Toolkit {
696
714
  }
697
715
  declare const toolkit: JaypieToolkit;
698
716
 
717
+ /**
718
+ * Categories of errors for retry logic
719
+ */
720
+ declare enum ErrorCategory {
721
+ /** Error is transient and can be retried */
722
+ Retryable = "retryable",
723
+ /** Error is due to short-term rate limiting (retry after a delay) */
724
+ RateLimit = "rate_limit",
725
+ /**
726
+ * Provider quota is exhausted or the account cannot be billed
727
+ * (insufficient funds, daily quota, plan limit). Terminal and actionable —
728
+ * retrying within the request budget will not help.
729
+ */
730
+ Quota = "quota",
731
+ /** Error cannot be recovered from */
732
+ Unrecoverable = "unrecoverable",
733
+ /** Error type is unknown */
734
+ Unknown = "unknown"
735
+ }
736
+
737
+ interface LlmErrorOptions {
738
+ /** Provider name that produced the error (e.g. "anthropic", "google") */
739
+ provider?: string;
740
+ /** Model in use when the error occurred */
741
+ model?: string;
742
+ /** Milliseconds to wait before retrying, when the provider suggests one */
743
+ retryAfterMs?: number;
744
+ /** The original provider error, preserved for inspection */
745
+ cause?: unknown;
746
+ }
747
+ /**
748
+ * Normalized, provider-agnostic LLM error. Thrown by the operate/stream retry
749
+ * layer when a request cannot be completed, so consumers can `catch` a stable
750
+ * type regardless of which provider failed. Extends {@link JaypieError} so
751
+ * `isJaypieError()` and `.status` continue to work; the original provider error
752
+ * is preserved on `.cause`.
753
+ */
754
+ declare class LlmError extends JaypieError {
755
+ readonly category: ErrorCategory;
756
+ readonly provider?: string;
757
+ readonly model?: string;
758
+ readonly retryAfterMs?: number;
759
+ readonly cause?: unknown;
760
+ constructor(message: string, category: ErrorCategory, { status, title, provider, model, retryAfterMs, cause, }?: LlmErrorOptions & {
761
+ status?: number;
762
+ title?: string;
763
+ });
764
+ }
765
+ /**
766
+ * Short-term rate limiting (per-minute 429). Terminal within the request
767
+ * budget; `retryAfterMs` carries the provider's suggested wait when available.
768
+ */
769
+ declare class LlmRateLimitError extends LlmError {
770
+ constructor(message: string, options?: LlmErrorOptions);
771
+ }
772
+ /**
773
+ * Provider quota is exhausted or the account cannot be billed. Terminal and
774
+ * actionable. `reason` distinguishes an exhausted usage quota from insufficient
775
+ * funds.
776
+ */
777
+ declare class LlmQuotaError extends LlmError {
778
+ readonly reason: "quota" | "billing";
779
+ constructor(message: string, { reason, ...options }?: LlmErrorOptions & {
780
+ reason?: "quota" | "billing";
781
+ });
782
+ }
783
+ /**
784
+ * The request cannot be recovered from (bad request, authentication,
785
+ * permission, not found). Terminal.
786
+ */
787
+ declare class LlmUnrecoverableError extends LlmError {
788
+ constructor(message: string, options?: LlmErrorOptions);
789
+ }
790
+ /**
791
+ * A transient or unknown error survived the retry budget. Terminal only because
792
+ * retries were exhausted; the underlying condition may succeed later.
793
+ */
794
+ declare class LlmTransientError extends LlmError {
795
+ constructor(message: string, options?: LlmErrorOptions);
796
+ }
797
+
699
798
  /**
700
799
  * Extracts reasoning text from LLM history items.
701
800
  *
@@ -798,5 +897,5 @@ declare class XaiProvider implements LlmProvider {
798
897
  stream(input: string | LlmHistory | LlmInputMessage, options?: LlmOperateOptions): AsyncIterable<LlmStreamChunk>;
799
898
  }
800
899
 
801
- export { BedrockProvider, GoogleProvider as GeminiProvider, GoogleProvider, JaypieToolkit, constants as LLM, Llm, LlmMessageRole, LlmMessageType, LlmProgressEventType, LlmStreamChunkType, OpenRouterProvider, Toolkit, XaiProvider, extractReasoning, isLlmOperateInput, isLlmOperateInputContent, isLlmOperateInputFile, isLlmOperateInputImage, jsonSchemaToNaturalSchema, naturalSchemaToJsonSchema, toolkit, tools };
802
- export type { LlmEffort, LlmFallbackConfig, LlmHistory, LlmInputContent, LlmInputContentFile, LlmInputContentImage, LlmInputContentText, LlmInputMessage, LlmMessageOptions, LlmOperateInput, LlmOperateInputContent, LlmOperateInputFile, LlmOperateInputImage, LlmOperateOptions, LlmOperateResponse, LlmOptions, LlmProgressCallback, LlmProgressEvent, LlmProgressToolCall, LlmProvider, LlmStreamChunk, LlmStreamChunkDone, LlmStreamChunkError, LlmStreamChunkText, LlmStreamChunkToolCall, LlmStreamChunkToolResult, LlmTool };
900
+ export { BedrockProvider, ErrorCategory, GoogleProvider as GeminiProvider, GoogleProvider, JaypieToolkit, constants as LLM, Llm, LlmError, LlmMessageRole, LlmMessageType, LlmProgressEventType, LlmQuotaError, LlmRateLimitError, LlmStreamChunkType, LlmTransientError, LlmUnrecoverableError, OpenRouterProvider, Toolkit, XaiProvider, extractReasoning, isLlmOperateInput, isLlmOperateInputContent, isLlmOperateInputFile, isLlmOperateInputImage, jsonSchemaToNaturalSchema, naturalSchemaToJsonSchema, toolkit, tools };
901
+ export type { LlmEffort, LlmErrorOptions, LlmFallbackConfig, LlmHistory, LlmInputContent, LlmInputContentFile, LlmInputContentImage, LlmInputContentText, LlmInputMessage, LlmMessageOptions, LlmModelOption, LlmOperateInput, LlmOperateInputContent, LlmOperateInputFile, LlmOperateInputImage, LlmOperateOptions, LlmOperateResponse, LlmOptions, LlmProgressCallback, LlmProgressEvent, LlmProgressToolCall, LlmProvider, LlmStreamChunk, LlmStreamChunkDone, LlmStreamChunkError, LlmStreamChunkText, LlmStreamChunkToolCall, LlmStreamChunkToolResult, LlmTool };
@@ -1,13 +1,16 @@
1
1
  export { default as Llm } from "./Llm.js";
2
2
  export * as LLM from "./constants.js";
3
3
  export type { LlmEffort } from "./constants.js";
4
- export type { LlmFallbackConfig, LlmHistory, LlmInputContent, LlmInputContentFile, LlmInputContentImage, LlmInputContentText, LlmInputMessage, LlmMessageOptions, LlmOperateInput, LlmOperateInputContent, LlmOperateInputFile, LlmOperateInputImage, LlmOperateOptions, LlmOperateResponse, LlmOptions, LlmProgressCallback, LlmProgressEvent, LlmProgressToolCall, LlmProvider, } from "./types/LlmProvider.interface.js";
4
+ export type { LlmFallbackConfig, LlmHistory, LlmInputContent, LlmInputContentFile, LlmInputContentImage, LlmInputContentText, LlmInputMessage, LlmMessageOptions, LlmModelOption, LlmOperateInput, LlmOperateInputContent, LlmOperateInputFile, LlmOperateInputImage, LlmOperateOptions, LlmOperateResponse, LlmOptions, LlmProgressCallback, LlmProgressEvent, LlmProgressToolCall, LlmProvider, } from "./types/LlmProvider.interface.js";
5
5
  export { LlmMessageRole, LlmMessageType, LlmProgressEventType, } from "./types/LlmProvider.interface.js";
6
6
  export { isLlmOperateInput, isLlmOperateInputContent, isLlmOperateInputFile, isLlmOperateInputImage, } from "./types/LlmOperateInput.guards.js";
7
7
  export type { LlmTool } from "./types/LlmTool.interface.js";
8
8
  export type { LlmStreamChunk, LlmStreamChunkDone, LlmStreamChunkError, LlmStreamChunkText, LlmStreamChunkToolCall, LlmStreamChunkToolResult, } from "./types/LlmStreamChunk.interface.js";
9
9
  export { LlmStreamChunkType } from "./types/LlmStreamChunk.interface.js";
10
10
  export { JaypieToolkit, toolkit, Toolkit, tools } from "./tools/index.js";
11
+ export { LlmError, LlmQuotaError, LlmRateLimitError, LlmTransientError, LlmUnrecoverableError, } from "./errors/LlmError.js";
12
+ export type { LlmErrorOptions } from "./errors/LlmError.js";
13
+ export { ErrorCategory } from "./operate/types.js";
11
14
  export { extractReasoning } from "./util/extractReasoning.js";
12
15
  export { jsonSchemaToNaturalSchema, naturalSchemaToJsonSchema, } from "./util/jsonSchema.js";
13
16
  export { BedrockProvider } from "./providers/bedrock/index.js";
@@ -1,13 +1,20 @@
1
1
  import { HookRunner, LlmHooks } from "../hooks/HookRunner.js";
2
2
  import { RetryPolicy } from "./RetryPolicy.js";
3
+ import { ClassifiedError } from "../types.js";
3
4
  export interface RetryContext {
4
5
  input: unknown;
5
6
  options?: unknown;
6
7
  providerRequest: unknown;
8
+ /** Provider name, carried onto the thrown LlmError */
9
+ provider?: string;
10
+ /** Model in use, carried onto the thrown LlmError */
11
+ model?: string;
7
12
  }
8
13
  export interface ErrorClassifier {
9
14
  isRetryable(error: unknown): boolean;
10
15
  isKnownError(error: unknown): boolean;
16
+ /** Full classification, used to throw a typed LlmError on terminal failure */
17
+ classify(error: unknown): ClassifiedError;
11
18
  }
12
19
  export interface RetryExecutorConfig {
13
20
  errorClassifier: ErrorClassifier;
@@ -27,6 +34,12 @@ export declare class RetryExecutor {
27
34
  private readonly hookRunner;
28
35
  private readonly errorClassifier;
29
36
  constructor(config: RetryExecutorConfig);
37
+ /**
38
+ * Build the typed, provider-agnostic error thrown when a request cannot be
39
+ * completed — classified (rate limit / quota / unrecoverable / transient)
40
+ * and carrying the provider, model, and original error as `cause`.
41
+ */
42
+ private toTerminalError;
30
43
  /**
31
44
  * Execute an operation with retry logic.
32
45
  * Each attempt receives an AbortSignal. On failure, the signal is aborted
@@ -97,8 +97,14 @@ export interface ProviderToolDefinition {
97
97
  export declare enum ErrorCategory {
98
98
  /** Error is transient and can be retried */
99
99
  Retryable = "retryable",
100
- /** Error is due to rate limiting */
100
+ /** Error is due to short-term rate limiting (retry after a delay) */
101
101
  RateLimit = "rate_limit",
102
+ /**
103
+ * Provider quota is exhausted or the account cannot be billed
104
+ * (insufficient funds, daily quota, plan limit). Terminal and actionable —
105
+ * retrying within the request budget will not help.
106
+ */
107
+ Quota = "quota",
102
108
  /** Error cannot be recovered from */
103
109
  Unrecoverable = "unrecoverable",
104
110
  /** Error type is unknown */
@@ -116,6 +122,11 @@ export interface ClassifiedError {
116
122
  shouldRetry: boolean;
117
123
  /** Suggested delay before retry (if applicable) */
118
124
  suggestedDelayMs?: number;
125
+ /**
126
+ * For {@link ErrorCategory.Quota}, distinguishes an exhausted usage quota
127
+ * from an account that cannot be billed (insufficient funds).
128
+ */
129
+ reason?: "quota" | "billing";
119
130
  }
120
131
  import type { ResponseBuilder } from "./response/ResponseBuilder.js";
121
132
  /**
@@ -295,6 +295,15 @@ export interface LlmOperateOptions {
295
295
  turns?: boolean | number;
296
296
  user?: string;
297
297
  }
298
+ /**
299
+ * A single model name, or a preference-ordered array of model names.
300
+ * An array is interpreted as a fallback chain: index 0 is primary, later
301
+ * entries are tried in order when earlier ones fail (provider auto-detected
302
+ * per entry). Accepted by the `Llm` constructor and static/instance
303
+ * `operate`/`send`/`stream` methods; normalized to a scalar model plus a
304
+ * derived fallback chain before reaching providers.
305
+ */
306
+ export type LlmModelOption = string | string[];
298
307
  export interface LlmOptions {
299
308
  apiKey?: string;
300
309
  /** Chain of fallback providers to try if primary fails */
@@ -0,0 +1,13 @@
1
+ import { ClassifiedError } from "../operate/types.js";
2
+ /**
3
+ * Shared, provider-agnostic first pass over an error. Returns a
4
+ * {@link ClassifiedError} when the message unambiguously identifies a
5
+ * cross-provider condition (retryable structured-output timeout, exhausted
6
+ * quota, or a billing failure), or `undefined` to defer to the adapter's own
7
+ * status/name classification.
8
+ *
9
+ * Adapters call this before their existing logic so that, for example, a
10
+ * `429` carrying a daily-quota message is classified as {@link
11
+ * ErrorCategory.Quota} rather than {@link ErrorCategory.RateLimit}.
12
+ */
13
+ export declare function classifyProviderError(error: unknown): ClassifiedError | undefined;
@@ -0,0 +1,17 @@
1
+ import { LlmFallbackConfig } from "../types/LlmProvider.interface.js";
2
+ /**
3
+ * Normalizes a `model` option that may be a single model name or a
4
+ * preference-ordered array of model names.
5
+ *
6
+ * A `string[]` is interpreted as a fallback chain: index `0` is the primary
7
+ * model, indices `1..` become fallback entries with an auto-detected provider
8
+ * (reusing `determineModelProvider`, exactly as the constructor's first
9
+ * argument does).
10
+ *
11
+ * Returns the primary model plus the derived fallback chain. A bare string
12
+ * yields an empty chain and is unchanged.
13
+ */
14
+ export declare function resolveModelChain(model?: string | string[]): {
15
+ model?: string;
16
+ fallback: LlmFallbackConfig[];
17
+ };
package/dist/esm/Llm.d.ts CHANGED
@@ -1,15 +1,19 @@
1
1
  import { JsonObject } from "@jaypie/types";
2
2
  import { LlmProviderName } from "./constants.js";
3
- import { LlmFallbackConfig, LlmHistory, LlmInputMessage, LlmMessageOptions, LlmOperateInput, LlmOperateOptions, LlmOperateResponse, LlmOptions, LlmProvider } from "./types/LlmProvider.interface.js";
3
+ import { LlmFallbackConfig, LlmHistory, LlmInputMessage, LlmMessageOptions, LlmModelOption, LlmOperateInput, LlmOperateOptions, LlmOperateResponse, LlmOptions, LlmProvider } from "./types/LlmProvider.interface.js";
4
4
  import { LlmStreamChunk } from "./types/LlmStreamChunk.interface.js";
5
5
  declare class Llm implements LlmProvider {
6
6
  private _fallbackConfig?;
7
7
  private _llm;
8
8
  private _options;
9
9
  private _provider;
10
- constructor(providerName?: LlmProviderName | string, options?: LlmOptions);
10
+ constructor(providerName?: LlmProviderName | string, options?: Omit<LlmOptions, "model"> & {
11
+ model?: LlmModelOption;
12
+ });
11
13
  private createProvider;
12
- send(message: string, options?: LlmMessageOptions): Promise<string | JsonObject>;
14
+ send(message: string, options?: Omit<LlmMessageOptions, "model"> & {
15
+ model?: LlmModelOption;
16
+ }): Promise<string | JsonObject>;
13
17
  /**
14
18
  * Resolves the fallback chain from instance config and per-call options.
15
19
  * Per-call options take precedence over instance config.
@@ -20,23 +24,27 @@ declare class Llm implements LlmProvider {
20
24
  * Creates a fallback Llm instance lazily when needed.
21
25
  */
22
26
  private createFallbackInstance;
23
- operate(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions): Promise<LlmOperateResponse>;
24
- stream(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions): AsyncIterable<LlmStreamChunk>;
25
- static send(message: string, options?: LlmMessageOptions & {
27
+ operate(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: Omit<LlmOperateOptions, "model"> & {
28
+ model?: LlmModelOption;
29
+ }): Promise<LlmOperateResponse>;
30
+ stream(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: Omit<LlmOperateOptions, "model"> & {
31
+ model?: LlmModelOption;
32
+ }): AsyncIterable<LlmStreamChunk>;
33
+ static send(message: string, options?: Omit<LlmMessageOptions, "model"> & {
26
34
  llm?: LlmProviderName;
27
35
  apiKey?: string;
28
- model?: string;
36
+ model?: string | string[];
29
37
  }): Promise<string | JsonObject>;
30
- static operate(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions & {
38
+ static operate(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: Omit<LlmOperateOptions, "model"> & {
31
39
  apiKey?: string;
32
40
  fallback?: LlmFallbackConfig[] | false;
33
41
  llm?: LlmProviderName;
34
- model?: string;
42
+ model?: string | string[];
35
43
  }): Promise<LlmOperateResponse>;
36
- static stream(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions & {
44
+ static stream(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: Omit<LlmOperateOptions, "model"> & {
37
45
  llm?: LlmProviderName;
38
46
  apiKey?: string;
39
- model?: string;
47
+ model?: string | string[];
40
48
  }): AsyncIterable<LlmStreamChunk>;
41
49
  }
42
50
  export default Llm;
@@ -0,0 +1,62 @@
1
+ import { JaypieError } from "@jaypie/errors";
2
+ import { ErrorCategory } from "../operate/types.js";
3
+ export interface LlmErrorOptions {
4
+ /** Provider name that produced the error (e.g. "anthropic", "google") */
5
+ provider?: string;
6
+ /** Model in use when the error occurred */
7
+ model?: string;
8
+ /** Milliseconds to wait before retrying, when the provider suggests one */
9
+ retryAfterMs?: number;
10
+ /** The original provider error, preserved for inspection */
11
+ cause?: unknown;
12
+ }
13
+ /**
14
+ * Normalized, provider-agnostic LLM error. Thrown by the operate/stream retry
15
+ * layer when a request cannot be completed, so consumers can `catch` a stable
16
+ * type regardless of which provider failed. Extends {@link JaypieError} so
17
+ * `isJaypieError()` and `.status` continue to work; the original provider error
18
+ * is preserved on `.cause`.
19
+ */
20
+ export declare class LlmError extends JaypieError {
21
+ readonly category: ErrorCategory;
22
+ readonly provider?: string;
23
+ readonly model?: string;
24
+ readonly retryAfterMs?: number;
25
+ readonly cause?: unknown;
26
+ constructor(message: string, category: ErrorCategory, { status, title, provider, model, retryAfterMs, cause, }?: LlmErrorOptions & {
27
+ status?: number;
28
+ title?: string;
29
+ });
30
+ }
31
+ /**
32
+ * Short-term rate limiting (per-minute 429). Terminal within the request
33
+ * budget; `retryAfterMs` carries the provider's suggested wait when available.
34
+ */
35
+ export declare class LlmRateLimitError extends LlmError {
36
+ constructor(message: string, options?: LlmErrorOptions);
37
+ }
38
+ /**
39
+ * Provider quota is exhausted or the account cannot be billed. Terminal and
40
+ * actionable. `reason` distinguishes an exhausted usage quota from insufficient
41
+ * funds.
42
+ */
43
+ export declare class LlmQuotaError extends LlmError {
44
+ readonly reason: "quota" | "billing";
45
+ constructor(message: string, { reason, ...options }?: LlmErrorOptions & {
46
+ reason?: "quota" | "billing";
47
+ });
48
+ }
49
+ /**
50
+ * The request cannot be recovered from (bad request, authentication,
51
+ * permission, not found). Terminal.
52
+ */
53
+ export declare class LlmUnrecoverableError extends LlmError {
54
+ constructor(message: string, options?: LlmErrorOptions);
55
+ }
56
+ /**
57
+ * A transient or unknown error survived the retry budget. Terminal only because
58
+ * retries were exhausted; the underlying condition may succeed later.
59
+ */
60
+ export declare class LlmTransientError extends LlmError {
61
+ constructor(message: string, options?: LlmErrorOptions);
62
+ }
@@ -0,0 +1,11 @@
1
+ import { ClassifiedError } from "../operate/types.js";
2
+ import { LlmError } from "./LlmError.js";
3
+ /**
4
+ * Map a {@link ClassifiedError} to the matching {@link LlmError} subclass,
5
+ * preserving the original error as `cause`. Used by the retry layer to throw a
6
+ * stable, catchable type instead of a bare gateway error.
7
+ */
8
+ export declare function toLlmError(classified: ClassifiedError, context?: {
9
+ provider?: string;
10
+ model?: string;
11
+ }): LlmError;
@@ -1,6 +1,7 @@
1
1
  import * as _jaypie_types from '@jaypie/types';
2
2
  import { JsonObject, AnyValue, NaturalMap, NaturalSchema, JsonReturn } from '@jaypie/types';
3
3
  import { z } from 'zod/v4';
4
+ import { JaypieError } from '@jaypie/errors';
4
5
 
5
6
  /**
6
7
  * Provider-neutral reasoning-effort levels — a five-point relative scale that
@@ -324,7 +325,7 @@ declare enum LlmResponseStatus {
324
325
  Incomplete = "incomplete",
325
326
  InProgress = "in_progress"
326
327
  }
327
- interface LlmError {
328
+ interface LlmError$1 {
328
329
  detail?: string;
329
330
  status: number | string;
330
331
  title: string;
@@ -593,6 +594,15 @@ interface LlmOperateOptions {
593
594
  turns?: boolean | number;
594
595
  user?: string;
595
596
  }
597
+ /**
598
+ * A single model name, or a preference-ordered array of model names.
599
+ * An array is interpreted as a fallback chain: index 0 is primary, later
600
+ * entries are tried in order when earlier ones fail (provider auto-detected
601
+ * per entry). Accepted by the `Llm` constructor and static/instance
602
+ * `operate`/`send`/`stream` methods; normalized to a scalar model plus a
603
+ * derived fallback chain before reaching providers.
604
+ */
605
+ type LlmModelOption = string | string[];
596
606
  interface LlmOptions {
597
607
  apiKey?: string;
598
608
  /** Chain of fallback providers to try if primary fails */
@@ -610,7 +620,7 @@ interface LlmUsageItem {
610
620
  type LlmUsage = LlmUsageItem[];
611
621
  interface LlmOperateResponse {
612
622
  content?: string | JsonObject;
613
- error?: LlmError;
623
+ error?: LlmError$1;
614
624
  /** Number of providers attempted (1 = primary only, >1 = fallback(s) used) */
615
625
  fallbackAttempts?: number;
616
626
  /** Whether a fallback provider was used instead of the primary */
@@ -636,9 +646,13 @@ declare class Llm implements LlmProvider {
636
646
  private _llm;
637
647
  private _options;
638
648
  private _provider;
639
- constructor(providerName?: LlmProviderName | string, options?: LlmOptions);
649
+ constructor(providerName?: LlmProviderName | string, options?: Omit<LlmOptions, "model"> & {
650
+ model?: LlmModelOption;
651
+ });
640
652
  private createProvider;
641
- send(message: string, options?: LlmMessageOptions): Promise<string | JsonObject>;
653
+ send(message: string, options?: Omit<LlmMessageOptions, "model"> & {
654
+ model?: LlmModelOption;
655
+ }): Promise<string | JsonObject>;
642
656
  /**
643
657
  * Resolves the fallback chain from instance config and per-call options.
644
658
  * Per-call options take precedence over instance config.
@@ -649,23 +663,27 @@ declare class Llm implements LlmProvider {
649
663
  * Creates a fallback Llm instance lazily when needed.
650
664
  */
651
665
  private createFallbackInstance;
652
- operate(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions): Promise<LlmOperateResponse>;
653
- stream(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions): AsyncIterable<LlmStreamChunk>;
654
- static send(message: string, options?: LlmMessageOptions & {
666
+ operate(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: Omit<LlmOperateOptions, "model"> & {
667
+ model?: LlmModelOption;
668
+ }): Promise<LlmOperateResponse>;
669
+ stream(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: Omit<LlmOperateOptions, "model"> & {
670
+ model?: LlmModelOption;
671
+ }): AsyncIterable<LlmStreamChunk>;
672
+ static send(message: string, options?: Omit<LlmMessageOptions, "model"> & {
655
673
  llm?: LlmProviderName;
656
674
  apiKey?: string;
657
- model?: string;
675
+ model?: string | string[];
658
676
  }): Promise<string | JsonObject>;
659
- static operate(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions & {
677
+ static operate(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: Omit<LlmOperateOptions, "model"> & {
660
678
  apiKey?: string;
661
679
  fallback?: LlmFallbackConfig[] | false;
662
680
  llm?: LlmProviderName;
663
- model?: string;
681
+ model?: string | string[];
664
682
  }): Promise<LlmOperateResponse>;
665
- static stream(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions & {
683
+ static stream(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: Omit<LlmOperateOptions, "model"> & {
666
684
  llm?: LlmProviderName;
667
685
  apiKey?: string;
668
- model?: string;
686
+ model?: string | string[];
669
687
  }): AsyncIterable<LlmStreamChunk>;
670
688
  }
671
689
 
@@ -696,6 +714,87 @@ declare class JaypieToolkit extends Toolkit {
696
714
  }
697
715
  declare const toolkit: JaypieToolkit;
698
716
 
717
+ /**
718
+ * Categories of errors for retry logic
719
+ */
720
+ declare enum ErrorCategory {
721
+ /** Error is transient and can be retried */
722
+ Retryable = "retryable",
723
+ /** Error is due to short-term rate limiting (retry after a delay) */
724
+ RateLimit = "rate_limit",
725
+ /**
726
+ * Provider quota is exhausted or the account cannot be billed
727
+ * (insufficient funds, daily quota, plan limit). Terminal and actionable —
728
+ * retrying within the request budget will not help.
729
+ */
730
+ Quota = "quota",
731
+ /** Error cannot be recovered from */
732
+ Unrecoverable = "unrecoverable",
733
+ /** Error type is unknown */
734
+ Unknown = "unknown"
735
+ }
736
+
737
+ interface LlmErrorOptions {
738
+ /** Provider name that produced the error (e.g. "anthropic", "google") */
739
+ provider?: string;
740
+ /** Model in use when the error occurred */
741
+ model?: string;
742
+ /** Milliseconds to wait before retrying, when the provider suggests one */
743
+ retryAfterMs?: number;
744
+ /** The original provider error, preserved for inspection */
745
+ cause?: unknown;
746
+ }
747
+ /**
748
+ * Normalized, provider-agnostic LLM error. Thrown by the operate/stream retry
749
+ * layer when a request cannot be completed, so consumers can `catch` a stable
750
+ * type regardless of which provider failed. Extends {@link JaypieError} so
751
+ * `isJaypieError()` and `.status` continue to work; the original provider error
752
+ * is preserved on `.cause`.
753
+ */
754
+ declare class LlmError extends JaypieError {
755
+ readonly category: ErrorCategory;
756
+ readonly provider?: string;
757
+ readonly model?: string;
758
+ readonly retryAfterMs?: number;
759
+ readonly cause?: unknown;
760
+ constructor(message: string, category: ErrorCategory, { status, title, provider, model, retryAfterMs, cause, }?: LlmErrorOptions & {
761
+ status?: number;
762
+ title?: string;
763
+ });
764
+ }
765
+ /**
766
+ * Short-term rate limiting (per-minute 429). Terminal within the request
767
+ * budget; `retryAfterMs` carries the provider's suggested wait when available.
768
+ */
769
+ declare class LlmRateLimitError extends LlmError {
770
+ constructor(message: string, options?: LlmErrorOptions);
771
+ }
772
+ /**
773
+ * Provider quota is exhausted or the account cannot be billed. Terminal and
774
+ * actionable. `reason` distinguishes an exhausted usage quota from insufficient
775
+ * funds.
776
+ */
777
+ declare class LlmQuotaError extends LlmError {
778
+ readonly reason: "quota" | "billing";
779
+ constructor(message: string, { reason, ...options }?: LlmErrorOptions & {
780
+ reason?: "quota" | "billing";
781
+ });
782
+ }
783
+ /**
784
+ * The request cannot be recovered from (bad request, authentication,
785
+ * permission, not found). Terminal.
786
+ */
787
+ declare class LlmUnrecoverableError extends LlmError {
788
+ constructor(message: string, options?: LlmErrorOptions);
789
+ }
790
+ /**
791
+ * A transient or unknown error survived the retry budget. Terminal only because
792
+ * retries were exhausted; the underlying condition may succeed later.
793
+ */
794
+ declare class LlmTransientError extends LlmError {
795
+ constructor(message: string, options?: LlmErrorOptions);
796
+ }
797
+
699
798
  /**
700
799
  * Extracts reasoning text from LLM history items.
701
800
  *
@@ -798,5 +897,5 @@ declare class XaiProvider implements LlmProvider {
798
897
  stream(input: string | LlmHistory | LlmInputMessage, options?: LlmOperateOptions): AsyncIterable<LlmStreamChunk>;
799
898
  }
800
899
 
801
- export { BedrockProvider, GoogleProvider as GeminiProvider, GoogleProvider, JaypieToolkit, constants as LLM, Llm, LlmMessageRole, LlmMessageType, LlmProgressEventType, LlmStreamChunkType, OpenRouterProvider, Toolkit, XaiProvider, extractReasoning, isLlmOperateInput, isLlmOperateInputContent, isLlmOperateInputFile, isLlmOperateInputImage, jsonSchemaToNaturalSchema, naturalSchemaToJsonSchema, toolkit, tools };
802
- export type { LlmEffort, LlmFallbackConfig, LlmHistory, LlmInputContent, LlmInputContentFile, LlmInputContentImage, LlmInputContentText, LlmInputMessage, LlmMessageOptions, LlmOperateInput, LlmOperateInputContent, LlmOperateInputFile, LlmOperateInputImage, LlmOperateOptions, LlmOperateResponse, LlmOptions, LlmProgressCallback, LlmProgressEvent, LlmProgressToolCall, LlmProvider, LlmStreamChunk, LlmStreamChunkDone, LlmStreamChunkError, LlmStreamChunkText, LlmStreamChunkToolCall, LlmStreamChunkToolResult, LlmTool };
900
+ export { BedrockProvider, ErrorCategory, GoogleProvider as GeminiProvider, GoogleProvider, JaypieToolkit, constants as LLM, Llm, LlmError, LlmMessageRole, LlmMessageType, LlmProgressEventType, LlmQuotaError, LlmRateLimitError, LlmStreamChunkType, LlmTransientError, LlmUnrecoverableError, OpenRouterProvider, Toolkit, XaiProvider, extractReasoning, isLlmOperateInput, isLlmOperateInputContent, isLlmOperateInputFile, isLlmOperateInputImage, jsonSchemaToNaturalSchema, naturalSchemaToJsonSchema, toolkit, tools };
901
+ export type { LlmEffort, LlmErrorOptions, LlmFallbackConfig, LlmHistory, LlmInputContent, LlmInputContentFile, LlmInputContentImage, LlmInputContentText, LlmInputMessage, LlmMessageOptions, LlmModelOption, LlmOperateInput, LlmOperateInputContent, LlmOperateInputFile, LlmOperateInputImage, LlmOperateOptions, LlmOperateResponse, LlmOptions, LlmProgressCallback, LlmProgressEvent, LlmProgressToolCall, LlmProvider, LlmStreamChunk, LlmStreamChunkDone, LlmStreamChunkError, LlmStreamChunkText, LlmStreamChunkToolCall, LlmStreamChunkToolResult, LlmTool };