@modelrelay/sdk 0.5.0 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,7 +1,5 @@
1
1
  declare const SDK_VERSION: string;
2
2
  declare const DEFAULT_BASE_URL = "https://api.modelrelay.ai/api/v1";
3
- declare const STAGING_BASE_URL = "https://api-stg.modelrelay.ai/api/v1";
4
- declare const SANDBOX_BASE_URL = "https://api.sandbox.modelrelay.ai/api/v1";
5
3
  declare const DEFAULT_CLIENT_HEADER: string;
6
4
  declare const DEFAULT_CONNECT_TIMEOUT_MS = 5000;
7
5
  declare const DEFAULT_REQUEST_TIMEOUT_MS = 60000;
@@ -27,8 +25,8 @@ type StopReason = KnownStopReason | {
27
25
  declare const Providers: {
28
26
  readonly OpenAI: "openai";
29
27
  readonly Anthropic: "anthropic";
30
- readonly Grok: "grok";
31
- readonly OpenRouter: "openrouter";
28
+ readonly XAI: "xai";
29
+ readonly GoogleAIStudio: "google-ai-studio";
32
30
  readonly Echo: "echo";
33
31
  };
34
32
  type KnownProvider = (typeof Providers)[keyof typeof Providers];
@@ -36,22 +34,123 @@ type ProviderId = KnownProvider | {
36
34
  other: string;
37
35
  };
38
36
  declare const Models: {
39
- readonly OpenAIGpt4o: "openai/gpt-4o";
40
- readonly OpenAIGpt4oMini: "openai/gpt-4o-mini";
41
- readonly OpenAIGpt51: "openai/gpt-5.1";
42
- readonly AnthropicClaude35HaikuLatest: "anthropic/claude-3-5-haiku-latest";
43
- readonly AnthropicClaude35SonnetLatest: "anthropic/claude-3-5-sonnet-latest";
44
- readonly AnthropicClaudeOpus45: "anthropic/claude-opus-4-5-20251101";
45
- readonly OpenRouterClaude35Haiku: "anthropic/claude-3.5-haiku";
37
+ readonly Gpt4o: "gpt-4o";
38
+ readonly Gpt4oMini: "gpt-4o-mini";
39
+ readonly Gpt51: "gpt-5.1";
40
+ readonly Claude35HaikuLatest: "claude-3-5-haiku-latest";
41
+ readonly Claude35SonnetLatest: "claude-3-5-sonnet-latest";
42
+ readonly ClaudeOpus45: "claude-opus-4-5";
43
+ readonly Claude35Haiku: "claude-3.5-haiku";
46
44
  readonly Grok2: "grok-2";
47
- readonly Grok4Fast: "grok-4-fast";
45
+ readonly Grok4_1FastNonReasoning: "grok-4-1-fast-non-reasoning";
46
+ readonly Grok4_1FastReasoning: "grok-4-1-fast-reasoning";
48
47
  readonly Echo1: "echo-1";
49
48
  };
50
49
  type KnownModel = (typeof Models)[keyof typeof Models];
51
50
  type ModelId = KnownModel | {
52
51
  other: string;
53
- } | string;
54
- interface ModelRelayOptions {
52
+ };
53
+ /**
54
+ * Common configuration options for the ModelRelay client.
55
+ */
56
+ interface ModelRelayBaseOptions {
57
+ /**
58
+ * Optional base URL override. Defaults to production API.
59
+ */
60
+ baseUrl?: string;
61
+ fetch?: typeof fetch;
62
+ /**
63
+ * Default customer metadata used when exchanging publishable keys for frontend tokens.
64
+ */
65
+ customer?: FrontendCustomer;
66
+ /**
67
+ * Optional client header override for telemetry.
68
+ */
69
+ clientHeader?: string;
70
+ /**
71
+ * Default connect timeout in milliseconds (applies to each attempt).
72
+ */
73
+ connectTimeoutMs?: number;
74
+ /**
75
+ * Default request timeout in milliseconds (non-streaming). Set to 0 to disable.
76
+ */
77
+ timeoutMs?: number;
78
+ /**
79
+ * Retry configuration applied to all requests (can be overridden per call). Set to `false` to disable retries.
80
+ */
81
+ retry?: RetryConfig | false;
82
+ /**
83
+ * Default HTTP headers applied to every request.
84
+ */
85
+ defaultHeaders?: Record<string, string>;
86
+ /**
87
+ * Default metadata merged into every chat completion request.
88
+ */
89
+ defaultMetadata?: Record<string, string>;
90
+ /**
91
+ * Optional metrics callbacks for latency/usage.
92
+ */
93
+ metrics?: MetricsCallbacks;
94
+ /**
95
+ * Optional trace/log hooks for request + stream lifecycle.
96
+ */
97
+ trace?: TraceCallbacks;
98
+ }
99
+ /**
100
+ * Configuration options requiring an API key.
101
+ */
102
+ interface ModelRelayKeyOptions extends ModelRelayBaseOptions {
103
+ /**
104
+ * API key (secret or publishable). Required.
105
+ * - Secret keys (`mr_sk_...`) are for server-side API calls.
106
+ * - Publishable keys (`mr_pk_...`) are for frontend token exchange.
107
+ */
108
+ key: string;
109
+ /**
110
+ * Optional bearer token (takes precedence over key for requests when provided).
111
+ */
112
+ token?: string;
113
+ }
114
+ /**
115
+ * Configuration options requiring an access token.
116
+ */
117
+ interface ModelRelayTokenOptions extends ModelRelayBaseOptions {
118
+ /**
119
+ * Optional API key.
120
+ */
121
+ key?: string;
122
+ /**
123
+ * Bearer token to call the API directly (server or frontend token). Required.
124
+ */
125
+ token: string;
126
+ }
127
+ /**
128
+ * ModelRelay client configuration.
129
+ *
130
+ * You must provide at least one of `key` or `token` for authentication.
131
+ * This is enforced at compile time through discriminated union types.
132
+ *
133
+ * @example With API key (server-side)
134
+ * ```typescript
135
+ * const client = new ModelRelay({ key: "mr_sk_..." });
136
+ * ```
137
+ *
138
+ * @example With access token (frontend or after token exchange)
139
+ * ```typescript
140
+ * const client = new ModelRelay({ token: frontendToken });
141
+ * ```
142
+ *
143
+ * @example With publishable key (frontend token exchange)
144
+ * ```typescript
145
+ * const client = new ModelRelay({ key: "mr_pk_...", customer: { id: "user123" } });
146
+ * ```
147
+ */
148
+ type ModelRelayOptions = ModelRelayKeyOptions | ModelRelayTokenOptions;
149
+ /**
150
+ * @deprecated Use ModelRelayOptions instead. This type allows empty configuration
151
+ * which will fail at runtime.
152
+ */
153
+ interface ModelRelayOptionsLegacy {
55
154
  /**
56
155
  * API key (secret or publishable). Publishable keys are required for frontend token exchange.
57
156
  */
@@ -61,9 +160,8 @@ interface ModelRelayOptions {
61
160
  */
62
161
  token?: string;
63
162
  /**
64
- * Optional environment preset; overridden by `baseUrl` when provided.
163
+ * Optional base URL override. Defaults to production API.
65
164
  */
66
- environment?: Environment;
67
165
  baseUrl?: string;
68
166
  fetch?: typeof fetch;
69
167
  /**
@@ -103,7 +201,6 @@ interface ModelRelayOptions {
103
201
  */
104
202
  trace?: TraceCallbacks;
105
203
  }
106
- type Environment = "production" | "staging" | "sandbox";
107
204
  interface FrontendCustomer {
108
205
  id: string;
109
206
  deviceId?: string;
@@ -142,6 +239,10 @@ interface Usage {
142
239
  outputTokens: number;
143
240
  totalTokens: number;
144
241
  }
242
+ /**
243
+ * Creates a Usage object with automatic totalTokens calculation if not provided.
244
+ */
245
+ declare function createUsage(inputTokens: number, outputTokens: number, totalTokens?: number): Usage;
145
246
  interface UsageSummary {
146
247
  plan: string;
147
248
  planType?: string;
@@ -164,9 +265,68 @@ interface Project {
164
265
  interface ChatMessage {
165
266
  role: string;
166
267
  content: string;
268
+ toolCalls?: ToolCall[];
269
+ toolCallId?: string;
270
+ }
271
+ declare const ToolTypes: {
272
+ readonly Function: "function";
273
+ readonly Web: "web";
274
+ readonly XSearch: "x_search";
275
+ readonly CodeExecution: "code_execution";
276
+ };
277
+ type ToolType = (typeof ToolTypes)[keyof typeof ToolTypes];
278
+ interface FunctionTool {
279
+ name: string;
280
+ description?: string;
281
+ parameters?: Record<string, unknown>;
282
+ }
283
+ type WebToolMode = "auto" | "search_only" | "fetch_only" | "search_and_fetch";
284
+ interface WebToolConfig {
285
+ allowedDomains?: string[];
286
+ excludedDomains?: string[];
287
+ maxUses?: number;
288
+ mode?: WebToolMode;
289
+ }
290
+ interface XSearchConfig {
291
+ allowedHandles?: string[];
292
+ excludedHandles?: string[];
293
+ fromDate?: string;
294
+ toDate?: string;
295
+ }
296
+ interface CodeExecConfig {
297
+ language?: string;
298
+ timeoutMs?: number;
299
+ }
300
+ interface Tool {
301
+ type: ToolType;
302
+ function?: FunctionTool;
303
+ web?: WebToolConfig;
304
+ xSearch?: XSearchConfig;
305
+ codeExecution?: CodeExecConfig;
306
+ }
307
+ declare const ToolChoiceTypes: {
308
+ readonly Auto: "auto";
309
+ readonly Required: "required";
310
+ readonly None: "none";
311
+ };
312
+ type ToolChoiceType = (typeof ToolChoiceTypes)[keyof typeof ToolChoiceTypes];
313
+ interface ToolChoice {
314
+ type: ToolChoiceType;
315
+ }
316
+ interface FunctionCall {
317
+ name: string;
318
+ arguments: string;
319
+ }
320
+ interface ToolCall {
321
+ id: string;
322
+ type: ToolType;
323
+ function?: FunctionCall;
167
324
  }
168
325
  interface ChatCompletionCreateParams {
169
- model: ModelId;
326
+ /**
327
+ * Model to use for the request. Optional - if omitted, the tier's default model is used.
328
+ */
329
+ model?: KnownModel;
170
330
  messages: NonEmptyArray<ChatMessage>;
171
331
  provider?: ProviderId;
172
332
  maxTokens?: number;
@@ -174,6 +334,14 @@ interface ChatCompletionCreateParams {
174
334
  metadata?: Record<string, string>;
175
335
  stop?: string[];
176
336
  stopSequences?: string[];
337
+ /**
338
+ * Tools available for the model to call.
339
+ */
340
+ tools?: Tool[];
341
+ /**
342
+ * Controls how the model responds to tool calls.
343
+ */
344
+ toolChoice?: ToolChoice;
177
345
  /**
178
346
  * When using publishable keys, a customer id is required to mint a frontend token.
179
347
  */
@@ -195,6 +363,7 @@ interface ChatCompletionResponse {
195
363
  model?: ModelId;
196
364
  usage: Usage;
197
365
  requestId?: string;
366
+ toolCalls?: ToolCall[];
198
367
  }
199
368
  interface FieldError {
200
369
  field?: string;
@@ -267,7 +436,7 @@ declare function normalizeProvider(value?: unknown): ProviderId | undefined;
267
436
  declare function providerToString(value?: ProviderId): string | undefined;
268
437
  declare function normalizeModelId(value: unknown): ModelId | undefined;
269
438
  declare function modelToString(value: ModelId): string;
270
- type ChatEventType = "message_start" | "message_delta" | "message_stop" | "ping" | "custom";
439
+ type ChatEventType = "message_start" | "message_delta" | "message_stop" | "tool_use_start" | "tool_use_delta" | "tool_use_stop" | "ping" | "custom";
271
440
  interface MessageStartData {
272
441
  responseId?: string;
273
442
  model?: string;
@@ -290,11 +459,27 @@ interface MessageStopData {
290
459
  model?: ModelId;
291
460
  [key: string]: unknown;
292
461
  }
462
+ /** Incremental update to a tool call during streaming. */
463
+ interface ToolCallDelta {
464
+ index: number;
465
+ id?: string;
466
+ type?: string;
467
+ function?: FunctionCallDelta;
468
+ }
469
+ /** Incremental function call data. */
470
+ interface FunctionCallDelta {
471
+ name?: string;
472
+ arguments?: string;
473
+ }
293
474
  interface ChatCompletionEvent<T = unknown> {
294
475
  type: ChatEventType;
295
476
  event: string;
296
477
  data?: T;
297
478
  textDelta?: string;
479
+ /** Incremental tool call update during streaming. */
480
+ toolCallDelta?: ToolCallDelta;
481
+ /** Completed tool calls when type is tool_use_stop or message_stop. */
482
+ toolCalls?: ToolCall[];
298
483
  responseId?: string;
299
484
  model?: ModelId;
300
485
  stopReason?: StopReason;
@@ -424,7 +609,6 @@ declare class HTTPClient {
424
609
  timeoutMs?: number;
425
610
  retry?: RetryConfig | false;
426
611
  defaultHeaders?: Record<string, string>;
427
- environment?: Environment;
428
612
  metrics?: MetricsCallbacks;
429
613
  trace?: TraceCallbacks;
430
614
  });
@@ -441,6 +625,14 @@ interface AuthHeaders {
441
625
  apiKey?: string;
442
626
  accessToken?: string;
443
627
  }
628
+ /**
629
+ * Creates AuthHeaders with an API key.
630
+ */
631
+ declare function createApiKeyAuth(apiKey: string): AuthHeaders;
632
+ /**
633
+ * Creates AuthHeaders with an access token.
634
+ */
635
+ declare function createAccessTokenAuth(accessToken: string): AuthHeaders;
444
636
  declare class AuthClient {
445
637
  private readonly http;
446
638
  private readonly apiKey?;
@@ -560,7 +752,7 @@ interface Customer {
560
752
  tier_id: string;
561
753
  tier_code?: string;
562
754
  external_id: string;
563
- email?: string;
755
+ email: string;
564
756
  metadata?: CustomerMetadata;
565
757
  stripe_customer_id?: string;
566
758
  stripe_subscription_id?: string;
@@ -576,7 +768,7 @@ interface Customer {
576
768
  interface CustomerCreateRequest {
577
769
  tier_id: string;
578
770
  external_id: string;
579
- email?: string;
771
+ email: string;
580
772
  metadata?: CustomerMetadata;
581
773
  }
582
774
  /**
@@ -585,7 +777,7 @@ interface CustomerCreateRequest {
585
777
  interface CustomerUpsertRequest {
586
778
  tier_id: string;
587
779
  external_id: string;
588
- email?: string;
780
+ email: string;
589
781
  metadata?: CustomerMetadata;
590
782
  }
591
783
  /**
@@ -668,8 +860,7 @@ interface Tier {
668
860
  project_id: string;
669
861
  tier_code: string;
670
862
  display_name: string;
671
- actions_limit: number;
672
- token_limit: number;
863
+ spend_limit_cents: number;
673
864
  stripe_price_id?: string;
674
865
  price_amount?: number;
675
866
  price_currency?: string;
@@ -700,6 +891,24 @@ declare class TiersClient {
700
891
  get(tierId: string): Promise<Tier>;
701
892
  }
702
893
 
894
+ /**
895
+ * API error codes returned by the server.
896
+ * These constants can be used for programmatic error handling.
897
+ */
898
+ declare const ErrorCodes: {
899
+ readonly NOT_FOUND: "NOT_FOUND";
900
+ readonly VALIDATION_ERROR: "VALIDATION_ERROR";
901
+ readonly RATE_LIMIT: "RATE_LIMIT";
902
+ readonly UNAUTHORIZED: "UNAUTHORIZED";
903
+ readonly FORBIDDEN: "FORBIDDEN";
904
+ readonly CONFLICT: "CONFLICT";
905
+ readonly INTERNAL_ERROR: "INTERNAL_ERROR";
906
+ readonly SERVICE_UNAVAILABLE: "SERVICE_UNAVAILABLE";
907
+ readonly INVALID_INPUT: "INVALID_INPUT";
908
+ readonly PAYMENT_REQUIRED: "PAYMENT_REQUIRED";
909
+ readonly METHOD_NOT_ALLOWED: "METHOD_NOT_ALLOWED";
910
+ };
911
+ type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
703
912
  type ErrorCategory = "config" | "transport" | "api";
704
913
  declare class ModelRelayError extends Error {
705
914
  category: ErrorCategory;
@@ -741,9 +950,438 @@ declare class APIError extends ModelRelayError {
741
950
  data?: unknown;
742
951
  retries?: RetryMetadata;
743
952
  });
953
+ /** Returns true if the error is a not found error. */
954
+ isNotFound(): boolean;
955
+ /** Returns true if the error is a validation error. */
956
+ isValidation(): boolean;
957
+ /** Returns true if the error is a rate limit error. */
958
+ isRateLimit(): boolean;
959
+ /** Returns true if the error is an unauthorized error. */
960
+ isUnauthorized(): boolean;
961
+ /** Returns true if the error is a forbidden error. */
962
+ isForbidden(): boolean;
963
+ /** Returns true if the error is a service unavailable error. */
964
+ isUnavailable(): boolean;
744
965
  }
745
966
  declare function parseErrorResponse(response: Response, retries?: RetryMetadata): Promise<APIError>;
746
967
 
968
+ /**
969
+ * Creates a user message.
970
+ */
971
+ declare function createUserMessage(content: string): ChatMessage;
972
+ /**
973
+ * Creates an assistant message.
974
+ */
975
+ declare function createAssistantMessage(content: string): ChatMessage;
976
+ /**
977
+ * Creates a system message.
978
+ */
979
+ declare function createSystemMessage(content: string): ChatMessage;
980
+ /**
981
+ * Creates a tool call object.
982
+ */
983
+ declare function createToolCall(id: string, name: string, args: string, type?: ToolType): ToolCall;
984
+ /**
985
+ * Creates a function call object.
986
+ */
987
+ declare function createFunctionCall(name: string, args: string): FunctionCall;
988
+ /**
989
+ * Interface for Zod-like schema types.
990
+ * Compatible with Zod's ZodType and similar libraries.
991
+ */
992
+ interface ZodLikeSchema {
993
+ _def: {
994
+ typeName: string;
995
+ [key: string]: unknown;
996
+ };
997
+ parse(data: unknown): unknown;
998
+ safeParse(data: unknown): {
999
+ success: boolean;
1000
+ data?: unknown;
1001
+ error?: unknown;
1002
+ };
1003
+ }
1004
+ /**
1005
+ * Options for JSON Schema generation.
1006
+ */
1007
+ interface JsonSchemaOptions {
1008
+ /** Whether to include $schema property. Defaults to false. */
1009
+ includeSchema?: boolean;
1010
+ /** Target JSON Schema version. Defaults to "draft-07". */
1011
+ target?: "draft-04" | "draft-07" | "draft-2019-09" | "draft-2020-12";
1012
+ }
1013
+ /**
1014
+ * Converts a Zod schema to JSON Schema.
1015
+ * This is a simplified implementation that handles common Zod types.
1016
+ * For full Zod support, consider using the 'zod-to-json-schema' package.
1017
+ *
1018
+ * @param schema - A Zod schema
1019
+ * @param options - Optional JSON Schema generation options
1020
+ * @returns A JSON Schema object
1021
+ */
1022
+ declare function zodToJsonSchema(schema: ZodLikeSchema, options?: JsonSchemaOptions): Record<string, unknown>;
1023
+ /**
1024
+ * Creates a function tool from a Zod schema.
1025
+ *
1026
+ * This function automatically converts a Zod schema to a JSON Schema
1027
+ * and creates a tool definition. It eliminates the need to manually
1028
+ * write JSON schemas for tool parameters.
1029
+ *
1030
+ * @example
1031
+ * ```typescript
1032
+ * import { z } from "zod";
1033
+ * import { createFunctionToolFromSchema } from "@modelrelay/sdk";
1034
+ *
1035
+ * const weatherParams = z.object({
1036
+ * location: z.string().describe("City name"),
1037
+ * unit: z.enum(["celsius", "fahrenheit"]).default("celsius"),
1038
+ * });
1039
+ *
1040
+ * const weatherTool = createFunctionToolFromSchema(
1041
+ * "get_weather",
1042
+ * "Get weather for a location",
1043
+ * weatherParams
1044
+ * );
1045
+ * ```
1046
+ *
1047
+ * @param name - The tool name
1048
+ * @param description - A description of what the tool does
1049
+ * @param schema - A Zod schema defining the tool's parameters
1050
+ * @param options - Optional JSON Schema generation options
1051
+ * @returns A Tool definition with the JSON schema derived from the Zod schema
1052
+ */
1053
+ declare function createFunctionToolFromSchema(name: string, description: string, schema: ZodLikeSchema, options?: JsonSchemaOptions): Tool;
1054
+ /**
1055
+ * Creates a function tool with the given name, description, and JSON schema.
1056
+ */
1057
+ declare function createFunctionTool(name: string, description: string, parameters?: Record<string, unknown>): Tool;
1058
+ /**
1059
+ * Creates a web tool with optional domain filters and mode.
1060
+ */
1061
+ declare function createWebTool(options?: {
1062
+ mode?: WebToolMode;
1063
+ allowedDomains?: string[];
1064
+ excludedDomains?: string[];
1065
+ maxUses?: number;
1066
+ }): Tool;
1067
+ /**
1068
+ * Returns a ToolChoice that lets the model decide when to use tools.
1069
+ */
1070
+ declare function toolChoiceAuto(): ToolChoice;
1071
+ /**
1072
+ * Returns a ToolChoice that forces the model to use a tool.
1073
+ */
1074
+ declare function toolChoiceRequired(): ToolChoice;
1075
+ /**
1076
+ * Returns a ToolChoice that prevents the model from using tools.
1077
+ */
1078
+ declare function toolChoiceNone(): ToolChoice;
1079
+ /**
1080
+ * Returns true if the response contains tool calls.
1081
+ */
1082
+ declare function hasToolCalls(response: ChatCompletionResponse): boolean;
1083
+ /**
1084
+ * Returns the first tool call from a response, or undefined if none exist.
1085
+ */
1086
+ declare function firstToolCall(response: ChatCompletionResponse): ToolCall | undefined;
1087
+ /**
1088
+ * Creates a message containing the result of a tool call.
1089
+ */
1090
+ declare function toolResultMessage(toolCallId: string, result: unknown): ChatMessage;
1091
+ /**
1092
+ * Creates a tool result message from a ToolCall.
1093
+ * Convenience wrapper around toolResultMessage using the call's ID.
1094
+ */
1095
+ declare function respondToToolCall(call: ToolCall, result: unknown): ChatMessage;
1096
+ /**
1097
+ * Creates an assistant message that includes tool calls.
1098
+ * Used to include the assistant's tool-calling turn in conversation history.
1099
+ */
1100
+ declare function assistantMessageWithToolCalls(content: string, toolCalls: ToolCall[]): ChatMessage;
1101
+ /**
1102
+ * Accumulates streaming tool call deltas into complete tool calls.
1103
+ */
1104
+ declare class ToolCallAccumulator {
1105
+ private calls;
1106
+ /**
1107
+ * Processes a streaming tool call delta.
1108
+ * Returns true if this started a new tool call.
1109
+ */
1110
+ processDelta(delta: ToolCallDelta): boolean;
1111
+ /**
1112
+ * Returns all accumulated tool calls in index order.
1113
+ */
1114
+ getToolCalls(): ToolCall[];
1115
+ /**
1116
+ * Returns a specific tool call by index, or undefined if not found.
1117
+ */
1118
+ getToolCall(index: number): ToolCall | undefined;
1119
+ /**
1120
+ * Clears all accumulated tool calls.
1121
+ */
1122
+ reset(): void;
1123
+ }
1124
+ /**
1125
+ * Error thrown when tool argument parsing or validation fails.
1126
+ * Contains a descriptive message suitable for sending back to the model.
1127
+ */
1128
+ declare class ToolArgsError extends Error {
1129
+ /** The tool call ID for correlation */
1130
+ readonly toolCallId: string;
1131
+ /** The tool name that was called */
1132
+ readonly toolName: string;
1133
+ /** The raw arguments string that failed to parse */
1134
+ readonly rawArguments: string;
1135
+ constructor(message: string, toolCallId: string, toolName: string, rawArguments: string);
1136
+ }
1137
+ /**
1138
+ * Schema interface compatible with Zod, Yup, and similar validation libraries.
1139
+ * Any object with a `parse` method that returns the validated type works.
1140
+ */
1141
+ interface Schema<T> {
1142
+ parse(data: unknown): T;
1143
+ }
1144
+ /**
1145
+ * Parses and validates tool call arguments using a schema.
1146
+ *
1147
+ * Works with any schema library that has a `parse` method (Zod, Yup, etc.).
1148
+ * Throws a descriptive ToolArgsError if parsing or validation fails.
1149
+ *
1150
+ * @example
1151
+ * ```typescript
1152
+ * import { z } from "zod";
1153
+ *
1154
+ * const WeatherArgs = z.object({
1155
+ * location: z.string(),
1156
+ * unit: z.enum(["celsius", "fahrenheit"]).default("celsius"),
1157
+ * });
1158
+ *
1159
+ * // In your tool handler:
1160
+ * const args = parseToolArgs(toolCall, WeatherArgs);
1161
+ * // args is typed as { location: string; unit: "celsius" | "fahrenheit" }
1162
+ * ```
1163
+ *
1164
+ * @param call - The tool call containing arguments to parse
1165
+ * @param schema - A schema with a `parse` method (Zod, Yup, etc.)
1166
+ * @returns The parsed and validated arguments with proper types
1167
+ * @throws {ToolArgsError} If JSON parsing or schema validation fails
1168
+ */
1169
+ declare function parseToolArgs<T>(call: ToolCall, schema: Schema<T>): T;
1170
+ /**
1171
+ * Attempts to parse tool arguments, returning a result object instead of throwing.
1172
+ *
1173
+ * @example
1174
+ * ```typescript
1175
+ * const result = tryParseToolArgs(toolCall, WeatherArgs);
1176
+ * if (result.success) {
1177
+ * console.log(result.data.location);
1178
+ * } else {
1179
+ * console.error(result.error.message);
1180
+ * }
1181
+ * ```
1182
+ *
1183
+ * @param call - The tool call containing arguments to parse
1184
+ * @param schema - A schema with a `parse` method
1185
+ * @returns An object with either { success: true, data: T } or { success: false, error: ToolArgsError }
1186
+ */
1187
+ declare function tryParseToolArgs<T>(call: ToolCall, schema: Schema<T>): {
1188
+ success: true;
1189
+ data: T;
1190
+ } | {
1191
+ success: false;
1192
+ error: ToolArgsError;
1193
+ };
1194
+ /**
1195
+ * Parses raw JSON arguments without schema validation.
1196
+ * Useful when you want JSON parsing error handling but not schema validation.
1197
+ *
1198
+ * @param call - The tool call containing arguments to parse
1199
+ * @returns The parsed JSON as an unknown type
1200
+ * @throws {ToolArgsError} If JSON parsing fails
1201
+ */
1202
+ declare function parseToolArgsRaw(call: ToolCall): unknown;
1203
+ /**
1204
+ * Handler function type for tool execution.
1205
+ * Can be sync or async, receives parsed arguments and returns a result.
1206
+ */
1207
+ type ToolHandler<T = unknown, R = unknown> = (args: T, call: ToolCall) => R | Promise<R>;
1208
+ /**
1209
+ * Result of executing a tool call.
1210
+ */
1211
+ interface ToolExecutionResult {
1212
+ toolCallId: string;
1213
+ toolName: string;
1214
+ result: unknown;
1215
+ error?: string;
1216
+ /**
1217
+ * True if the error is due to malformed arguments (JSON parse or validation failure)
1218
+ * and the model should be given a chance to retry with corrected arguments.
1219
+ */
1220
+ isRetryable?: boolean;
1221
+ }
1222
+ /**
1223
+ * Registry for mapping tool names to handler functions with automatic dispatch.
1224
+ *
1225
+ * @example
1226
+ * ```typescript
1227
+ * const registry = new ToolRegistry()
1228
+ * .register("get_weather", async (args) => {
1229
+ * return { temp: 72, unit: "fahrenheit" };
1230
+ * })
1231
+ * .register("search", async (args) => {
1232
+ * return { results: ["result1", "result2"] };
1233
+ * });
1234
+ *
1235
+ * // Execute all tool calls from a response
1236
+ * const results = await registry.executeAll(response.toolCalls);
1237
+ *
1238
+ * // Convert results to messages for the next request
1239
+ * const messages = registry.resultsToMessages(results);
1240
+ * ```
1241
+ */
1242
+ declare class ToolRegistry {
1243
+ private handlers;
1244
+ /**
1245
+ * Registers a handler function for a tool name.
1246
+ * @param name - The tool name (must match the function name in the tool definition)
1247
+ * @param handler - Function to execute when this tool is called
1248
+ * @returns this for chaining
1249
+ */
1250
+ register<T = unknown, R = unknown>(name: string, handler: ToolHandler<T, R>): this;
1251
+ /**
1252
+ * Unregisters a tool handler.
1253
+ * @param name - The tool name to unregister
1254
+ * @returns true if the handler was removed, false if it didn't exist
1255
+ */
1256
+ unregister(name: string): boolean;
1257
+ /**
1258
+ * Checks if a handler is registered for the given tool name.
1259
+ */
1260
+ has(name: string): boolean;
1261
+ /**
1262
+ * Returns the list of registered tool names.
1263
+ */
1264
+ getRegisteredTools(): string[];
1265
+ /**
1266
+ * Executes a single tool call.
1267
+ * @param call - The tool call to execute
1268
+ * @returns The execution result
1269
+ */
1270
+ execute(call: ToolCall): Promise<ToolExecutionResult>;
1271
+ /**
1272
+ * Executes multiple tool calls in parallel.
1273
+ * @param calls - Array of tool calls to execute
1274
+ * @returns Array of execution results in the same order as input
1275
+ */
1276
+ executeAll(calls: ToolCall[]): Promise<ToolExecutionResult[]>;
1277
+ /**
1278
+ * Converts execution results to tool result messages.
1279
+ * Useful for appending to the conversation history.
1280
+ * @param results - Array of execution results
1281
+ * @returns Array of ChatMessage objects with role "tool"
1282
+ */
1283
+ resultsToMessages(results: ToolExecutionResult[]): ChatMessage[];
1284
+ }
1285
+ /**
1286
+ * Formats a tool execution error into a message suitable for sending back to the model.
1287
+ * The message is designed to help the model understand what went wrong and correct it.
1288
+ *
1289
+ * @example
1290
+ * ```typescript
1291
+ * const result = await registry.execute(toolCall);
1292
+ * if (result.error && result.isRetryable) {
1293
+ * const errorMessage = formatToolErrorForModel(result);
1294
+ * messages.push(toolResultMessage(result.toolCallId, errorMessage));
1295
+ * // Continue conversation to let model retry
1296
+ * }
1297
+ * ```
1298
+ */
1299
+ declare function formatToolErrorForModel(result: ToolExecutionResult): string;
1300
+ /**
1301
+ * Checks if any results have retryable errors.
1302
+ *
1303
+ * @example
1304
+ * ```typescript
1305
+ * const results = await registry.executeAll(toolCalls);
1306
+ * if (hasRetryableErrors(results)) {
1307
+ * // Send error messages back to model and continue conversation
1308
+ * }
1309
+ * ```
1310
+ */
1311
+ declare function hasRetryableErrors(results: ToolExecutionResult[]): boolean;
1312
+ /**
1313
+ * Filters results to only those with retryable errors.
1314
+ */
1315
+ declare function getRetryableErrors(results: ToolExecutionResult[]): ToolExecutionResult[];
1316
+ /**
1317
+ * Creates tool result messages for retryable errors, formatted to help the model correct them.
1318
+ *
1319
+ * @example
1320
+ * ```typescript
1321
+ * const results = await registry.executeAll(toolCalls);
1322
+ * if (hasRetryableErrors(results)) {
1323
+ * const retryMessages = createRetryMessages(results);
1324
+ * messages.push(...retryMessages);
1325
+ * // Make another API call to let model retry
1326
+ * }
1327
+ * ```
1328
+ */
1329
+ declare function createRetryMessages(results: ToolExecutionResult[]): ChatMessage[];
1330
+ /**
1331
+ * Options for executeWithRetry.
1332
+ */
1333
+ interface RetryOptions {
1334
+ /**
1335
+ * Maximum number of retry attempts for parse/validation errors.
1336
+ * @default 2
1337
+ */
1338
+ maxRetries?: number;
1339
+ /**
1340
+ * Callback invoked when a retryable error occurs.
1341
+ * Should return new tool calls from the model's response.
1342
+ * If not provided, executeWithRetry will not retry automatically.
1343
+ *
1344
+ * @param errorMessages - Messages to send back to the model
1345
+ * @param attempt - Current attempt number (1-based)
1346
+ * @returns New tool calls from the model, or empty array to stop retrying
1347
+ */
1348
+ onRetry?: (errorMessages: ChatMessage[], attempt: number) => Promise<ToolCall[]>;
1349
+ }
1350
+ /**
1351
+ * Executes tool calls with automatic retry on parse/validation errors.
1352
+ *
1353
+ * This is a higher-level utility that wraps registry.executeAll with retry logic.
1354
+ * When a retryable error occurs, it calls the onRetry callback to get new tool calls
1355
+ * from the model and continues execution.
1356
+ *
1357
+ * **Result Preservation**: Successful results are preserved across retries. If you
1358
+ * execute multiple tool calls and only some fail, the successful results are kept
1359
+ * and merged with the results from retry attempts. Results are keyed by toolCallId,
1360
+ * so if a retry returns a call with the same ID as a previous result, the newer
1361
+ * result will replace it.
1362
+ *
1363
+ * @example
1364
+ * ```typescript
1365
+ * const results = await executeWithRetry(registry, toolCalls, {
1366
+ * maxRetries: 2,
1367
+ * onRetry: async (errorMessages, attempt) => {
1368
+ * console.log(`Retry attempt ${attempt}`);
1369
+ * // Add error messages to conversation and call the model again
1370
+ * messages.push(assistantMessageWithToolCalls("", toolCalls));
1371
+ * messages.push(...errorMessages);
1372
+ * const response = await client.chat.completions.create({ messages, tools });
1373
+ * return response.toolCalls ?? [];
1374
+ * },
1375
+ * });
1376
+ * ```
1377
+ *
1378
+ * @param registry - The tool registry to use for execution
1379
+ * @param toolCalls - Initial tool calls to execute
1380
+ * @param options - Retry configuration
1381
+ * @returns Final execution results after all retries, including preserved successes
1382
+ */
1383
+ declare function executeWithRetry(registry: ToolRegistry, toolCalls: ToolCall[], options?: RetryOptions): Promise<ToolExecutionResult[]>;
1384
+
747
1385
  declare class ModelRelay {
748
1386
  readonly chat: ChatClient;
749
1387
  readonly auth: AuthClient;
@@ -753,4 +1391,4 @@ declare class ModelRelay {
753
1391
  constructor(options: ModelRelayOptions);
754
1392
  }
755
1393
 
756
- export { type APIChatResponse, type APIChatUsage, type APICheckoutSession, type APICustomerRef, APIError, type APIFrontendToken, type APIKey, AuthClient, ChatClient, type ChatCompletionCreateParams, type ChatCompletionEvent, type ChatCompletionResponse, ChatCompletionsStream, type ChatEventType, type ChatMessage, type CheckoutSession, type CheckoutSessionRequest, ConfigError, type Customer, type CustomerCreateRequest, type CustomerMetadata, type CustomerUpsertRequest, CustomersClient, DEFAULT_BASE_URL, DEFAULT_CLIENT_HEADER, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_REQUEST_TIMEOUT_MS, type Environment, type ErrorCategory, type FieldError, type FrontendCustomer, type FrontendToken, type FrontendTokenRequest, type HttpRequestMetrics, type KnownModel, type KnownProvider, type KnownStopReason, type MessageDeltaData, type MessageStartData, type MessageStopData, type MetricsCallbacks, type ModelId, ModelRelay, ModelRelayError, type ModelRelayOptions, Models, type NonEmptyArray, type PriceInterval, type Project, type ProviderId, Providers, type RequestContext, type RetryConfig, type RetryMetadata, SANDBOX_BASE_URL, SDK_VERSION, STAGING_BASE_URL, type StopReason, StopReasons, type StreamFirstTokenMetrics, type SubscriptionStatus, type Tier, TiersClient, type TokenUsageMetrics, type TraceCallbacks, TransportError, type TransportErrorKind, type Usage, type UsageSummary, isPublishableKey, mergeMetrics, mergeTrace, modelToString, normalizeModelId, normalizeProvider, normalizeStopReason, parseErrorResponse, providerToString, stopReasonToString };
1394
+ export { type APIChatResponse, type APIChatUsage, type APICheckoutSession, type APICustomerRef, APIError, type APIFrontendToken, type APIKey, AuthClient, type AuthHeaders, ChatClient, type ChatCompletionCreateParams, type ChatCompletionEvent, type ChatCompletionResponse, ChatCompletionsStream, type ChatEventType, type ChatMessage, type CheckoutSession, type CheckoutSessionRequest, type CodeExecConfig, ConfigError, type Customer, type CustomerCreateRequest, type CustomerMetadata, type CustomerUpsertRequest, CustomersClient, DEFAULT_BASE_URL, DEFAULT_CLIENT_HEADER, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_REQUEST_TIMEOUT_MS, type ErrorCategory, type ErrorCode, ErrorCodes, type FieldError, type FrontendCustomer, type FrontendToken, type FrontendTokenRequest, type FunctionCall, type FunctionCallDelta, type FunctionTool, type HttpRequestMetrics, type JsonSchemaOptions, type KnownModel, type KnownProvider, type KnownStopReason, type MessageDeltaData, type MessageStartData, type MessageStopData, type MetricsCallbacks, type ModelId, ModelRelay, type ModelRelayBaseOptions, ModelRelayError, type ModelRelayKeyOptions, type ModelRelayOptions, type ModelRelayOptionsLegacy, type ModelRelayTokenOptions, Models, type NonEmptyArray, type PriceInterval, type Project, type ProviderId, Providers, type RequestContext, type RetryConfig, type RetryMetadata, type RetryOptions, SDK_VERSION, type Schema, type StopReason, StopReasons, type StreamFirstTokenMetrics, type SubscriptionStatus, type Tier, TiersClient, type TokenUsageMetrics, type Tool, ToolArgsError, type ToolCall, ToolCallAccumulator, type ToolCallDelta, type ToolChoice, type ToolChoiceType, ToolChoiceTypes, type ToolExecutionResult, type ToolHandler, ToolRegistry, type ToolType, ToolTypes, type TraceCallbacks, TransportError, type TransportErrorKind, type Usage, type UsageSummary, type WebToolConfig, type WebToolMode, type XSearchConfig, type ZodLikeSchema, assistantMessageWithToolCalls, createAccessTokenAuth, createApiKeyAuth, createAssistantMessage, createFunctionCall, createFunctionTool, createFunctionToolFromSchema, createRetryMessages, createSystemMessage, createToolCall, createUsage, createUserMessage, createWebTool, executeWithRetry, firstToolCall, formatToolErrorForModel, getRetryableErrors, hasRetryableErrors, hasToolCalls, isPublishableKey, mergeMetrics, mergeTrace, modelToString, normalizeModelId, normalizeProvider, normalizeStopReason, parseErrorResponse, parseToolArgs, parseToolArgsRaw, providerToString, respondToToolCall, stopReasonToString, toolChoiceAuto, toolChoiceNone, toolChoiceRequired, toolResultMessage, tryParseToolArgs, zodToJsonSchema };