@modelrelay/sdk 0.24.0 → 0.27.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/dist/index.d.ts CHANGED
@@ -560,10 +560,29 @@ interface ChatCompletionEvent<T = unknown> {
560
560
  raw: string;
561
561
  }
562
562
  type StructuredJSONRecordType = "start" | "update" | "completion" | "error";
563
+ /**
564
+ * Recursively makes all properties optional.
565
+ * Useful for typing partial payloads during progressive streaming before
566
+ * all fields are complete.
567
+ *
568
+ * @example
569
+ * interface Article { title: string; body: string; }
570
+ * type PartialArticle = DeepPartial<Article>;
571
+ * // { title?: string; body?: string; }
572
+ */
573
+ type DeepPartial<T> = T extends object ? {
574
+ [P in keyof T]?: DeepPartial<T[P]>;
575
+ } : T;
563
576
  interface StructuredJSONEvent<T> {
564
577
  type: "update" | "completion";
565
578
  payload: T;
566
579
  requestId?: string;
580
+ /**
581
+ * Set of field paths that are complete (have their closing delimiter).
582
+ * Use dot notation for nested fields (e.g., "metadata.author").
583
+ * Check with completeFields.has("fieldName").
584
+ */
585
+ completeFields: Set<string>;
567
586
  }
568
587
  interface APIFrontendToken {
569
588
  token: string;
@@ -752,889 +771,1128 @@ declare class AuthClient {
752
771
  }
753
772
  declare function isPublishableKey(value?: string | null): boolean;
754
773
 
755
- interface ChatRequestOptions {
756
- /**
757
- * Abort the HTTP request and stream consumption.
758
- */
759
- signal?: AbortSignal;
760
- /**
761
- * Override the Accept header to switch between streaming and blocking responses.
762
- */
763
- stream?: boolean;
764
- /**
765
- * Optional request id header. `params.requestId` takes precedence if provided.
766
- */
767
- requestId?: string;
768
- /**
769
- * Additional HTTP headers for this request.
770
- */
771
- headers?: Record<string, string>;
772
- /**
773
- * Additional metadata merged into the request body.
774
- */
775
- metadata?: Record<string, string>;
776
- /**
777
- * Override the per-request timeout in milliseconds (set to 0 to disable).
778
- */
779
- timeoutMs?: number;
780
- /**
781
- * Override the connect timeout in milliseconds (set to 0 to disable).
782
- */
783
- connectTimeoutMs?: number;
784
- /**
785
- * Override retry behavior for this call. Set to `false` to disable retries.
786
- */
787
- retry?: RetryConfig | false;
788
- /**
789
- * Per-call metrics callbacks (merged over client defaults).
790
- */
791
- metrics?: MetricsCallbacks;
792
- /**
793
- * Per-call trace/log hooks (merged over client defaults).
794
- */
795
- trace?: TraceCallbacks;
796
- }
797
- declare class ChatClient {
798
- readonly completions: ChatCompletionsClient;
799
- private readonly http;
800
- private readonly auth;
801
- private readonly defaultMetadata?;
802
- private readonly metrics?;
803
- private readonly trace?;
804
- constructor(http: HTTPClient, auth: AuthClient, cfg?: {
805
- defaultMetadata?: Record<string, string>;
806
- metrics?: MetricsCallbacks;
807
- trace?: TraceCallbacks;
808
- });
809
- /**
810
- * Create a customer-attributed chat client for the given customer ID.
811
- * The customer's tier determines the model - no model parameter is needed or allowed.
812
- *
813
- * @example
814
- * ```typescript
815
- * const stream = await client.chat.forCustomer("user-123").create({
816
- * messages: [{ role: "user", content: "Hello!" }],
817
- * });
818
- * ```
819
- */
820
- forCustomer(customerId: string): CustomerChatClient;
821
- }
822
- declare class ChatCompletionsClient {
823
- private readonly http;
824
- private readonly auth;
825
- private readonly defaultMetadata?;
826
- private readonly metrics?;
827
- private readonly trace?;
828
- constructor(http: HTTPClient, auth: AuthClient, defaultMetadata?: Record<string, string>, metrics?: MetricsCallbacks, trace?: TraceCallbacks);
829
- create(params: ChatCompletionCreateParams & {
830
- stream: false;
831
- }, options?: ChatRequestOptions): Promise<ChatCompletionResponse>;
832
- create(params: ChatCompletionCreateParams, options: ChatRequestOptions & {
833
- stream: false;
834
- }): Promise<ChatCompletionResponse>;
835
- create(params: ChatCompletionCreateParams, options?: ChatRequestOptions): Promise<ChatCompletionsStream>;
836
- /**
837
- * Stream structured JSON responses using the NDJSON contract defined for
838
- * /llm/proxy. The request must include a structured responseFormat.
839
- */
840
- streamJSON<T>(params: ChatCompletionCreateParams & {
841
- responseFormat: ResponseFormat;
842
- }, options?: ChatRequestOptions): Promise<StructuredJSONStream<T>>;
843
- }
844
- /**
845
- * Client for customer-attributed chat completions.
846
- * The customer's tier determines the model - no model parameter is needed or allowed.
847
- */
848
- declare class CustomerChatClient {
849
- private readonly http;
850
- private readonly auth;
851
- private readonly customerId;
852
- private readonly defaultMetadata?;
853
- private readonly metrics?;
854
- private readonly trace?;
855
- constructor(http: HTTPClient, auth: AuthClient, customerId: string, defaultMetadata?: Record<string, string>, metrics?: MetricsCallbacks, trace?: TraceCallbacks);
856
- create(params: CustomerChatParams & {
857
- stream: false;
858
- }, options?: ChatRequestOptions): Promise<ChatCompletionResponse>;
859
- create(params: CustomerChatParams, options: ChatRequestOptions & {
860
- stream: false;
861
- }): Promise<ChatCompletionResponse>;
862
- create(params: CustomerChatParams, options?: ChatRequestOptions): Promise<ChatCompletionsStream>;
863
- /**
864
- * Stream structured JSON responses using the NDJSON contract.
865
- * The request must include a structured responseFormat.
866
- */
867
- streamJSON<T>(params: CustomerChatParams & {
868
- responseFormat: ResponseFormat;
869
- }, options?: ChatRequestOptions): Promise<StructuredJSONStream<T>>;
870
- }
871
- declare class ChatCompletionsStream implements AsyncIterable<ChatCompletionEvent> {
872
- private readonly response;
873
- private readonly requestId?;
874
- private context;
875
- private readonly metrics?;
876
- private readonly trace?;
877
- private readonly startedAt;
878
- private firstTokenEmitted;
879
- private closed;
880
- constructor(response: Response, requestId: string | undefined, context: RequestContext, metrics?: MetricsCallbacks, trace?: TraceCallbacks);
881
- cancel(reason?: unknown): Promise<void>;
882
- [Symbol.asyncIterator](): AsyncIterator<ChatCompletionEvent>;
883
- private handleStreamEvent;
884
- private enrichContext;
885
- private recordFirstToken;
886
- }
887
- declare class StructuredJSONStream<T> implements AsyncIterable<StructuredJSONEvent<T>> {
888
- private readonly response;
889
- private readonly requestId?;
890
- private context;
891
- private readonly metrics?;
892
- private readonly trace?;
893
- private closed;
894
- private sawTerminal;
895
- constructor(response: Response, requestId: string | undefined, context: RequestContext, metrics?: MetricsCallbacks, trace?: TraceCallbacks);
896
- cancel(reason?: unknown): Promise<void>;
897
- [Symbol.asyncIterator](): AsyncIterator<StructuredJSONEvent<T>>;
898
- collect(): Promise<T>;
899
- private parseRecord;
900
- private traceStructuredEvent;
901
- }
902
-
903
774
  /**
904
- * Customer metadata as an arbitrary key-value object.
775
+ * Creates a user message.
905
776
  */
906
- type CustomerMetadata = Record<string, unknown>;
777
+ declare function createUserMessage(content: string): ChatMessage;
907
778
  /**
908
- * Customer represents a customer in a ModelRelay project.
779
+ * Creates an assistant message.
909
780
  */
910
- interface Customer {
911
- id: string;
912
- project_id: string;
913
- tier_id: string;
914
- tier_code?: string;
915
- external_id: string;
916
- email: string;
917
- metadata?: CustomerMetadata;
918
- stripe_customer_id?: string;
919
- stripe_subscription_id?: string;
920
- subscription_status?: string;
921
- current_period_start?: string;
922
- current_period_end?: string;
923
- created_at: string;
924
- updated_at: string;
925
- }
781
+ declare function createAssistantMessage(content: string): ChatMessage;
926
782
  /**
927
- * Request to create a customer.
783
+ * Creates a system message.
928
784
  */
929
- interface CustomerCreateRequest {
930
- tier_id: string;
931
- external_id: string;
932
- email: string;
933
- metadata?: CustomerMetadata;
934
- }
785
+ declare function createSystemMessage(content: string): ChatMessage;
935
786
  /**
936
- * Request to upsert a customer by external_id.
787
+ * Creates a tool call object.
937
788
  */
938
- interface CustomerUpsertRequest {
939
- tier_id: string;
940
- external_id: string;
941
- email: string;
942
- metadata?: CustomerMetadata;
943
- }
789
+ declare function createToolCall(id: string, name: string, args: string, type?: ToolType): ToolCall;
944
790
  /**
945
- * Request to claim a customer by email, setting their external_id.
946
- * Used when a customer subscribes via Stripe Checkout (email only) and later
947
- * authenticates to the app, needing to link their identity.
791
+ * Creates a function call object.
948
792
  */
949
- interface CustomerClaimRequest {
950
- email: string;
951
- external_id: string;
952
- }
793
+ declare function createFunctionCall(name: string, args: string): FunctionCall;
953
794
  /**
954
- * Request to create a checkout session.
795
+ * Interface for Zod-like schema types.
796
+ * Compatible with Zod's ZodType and similar libraries.
955
797
  */
956
- interface CheckoutSessionRequest {
957
- success_url: string;
958
- cancel_url: string;
798
+ interface ZodLikeSchema {
799
+ _def: {
800
+ typeName: string;
801
+ [key: string]: unknown;
802
+ };
803
+ parse(data: unknown): unknown;
804
+ safeParse(data: unknown): {
805
+ success: boolean;
806
+ data?: unknown;
807
+ error?: unknown;
808
+ };
959
809
  }
960
810
  /**
961
- * Checkout session response.
811
+ * Options for JSON Schema generation.
962
812
  */
963
- interface CheckoutSession {
964
- session_id: string;
965
- url: string;
813
+ interface JsonSchemaOptions {
814
+ /** Whether to include $schema property. Defaults to false. */
815
+ includeSchema?: boolean;
816
+ /** Target JSON Schema version. Defaults to "draft-07". */
817
+ target?: "draft-04" | "draft-07" | "draft-2019-09" | "draft-2020-12";
966
818
  }
967
819
  /**
968
- * Subscription status response.
820
+ * Converts a Zod schema to JSON Schema.
821
+ * This is a simplified implementation that handles common Zod types.
822
+ * For full Zod support, consider using the 'zod-to-json-schema' package.
823
+ *
824
+ * @param schema - A Zod schema
825
+ * @param options - Optional JSON Schema generation options
826
+ * @returns A JSON Schema object
969
827
  */
970
- interface SubscriptionStatus {
971
- active: boolean;
972
- subscription_id?: string;
973
- status?: string;
974
- current_period_start?: string;
975
- current_period_end?: string;
976
- }
977
- interface CustomersClientConfig {
978
- apiKey?: string;
979
- }
828
+ declare function zodToJsonSchema(schema: ZodLikeSchema, options?: JsonSchemaOptions): Record<string, unknown>;
980
829
  /**
981
- * CustomersClient provides methods to manage customers in a project.
982
- * Requires a secret key (mr_sk_*) for authentication.
983
- */
984
- declare class CustomersClient {
985
- private readonly http;
986
- private readonly apiKey?;
987
- constructor(http: HTTPClient, cfg: CustomersClientConfig);
988
- private ensureSecretKey;
989
- /**
990
- * List all customers in the project.
991
- */
992
- list(): Promise<Customer[]>;
993
- /**
994
- * Create a new customer in the project.
995
- */
996
- create(request: CustomerCreateRequest): Promise<Customer>;
997
- /**
998
- * Get a customer by ID.
999
- */
1000
- get(customerId: string): Promise<Customer>;
1001
- /**
1002
- * Upsert a customer by external_id.
1003
- * If a customer with the given external_id exists, it is updated.
1004
- * Otherwise, a new customer is created.
1005
- */
1006
- upsert(request: CustomerUpsertRequest): Promise<Customer>;
830
+ * Creates a function tool from a Zod schema.
831
+ *
832
+ * This function automatically converts a Zod schema to a JSON Schema
833
+ * and creates a tool definition. It eliminates the need to manually
834
+ * write JSON schemas for tool parameters.
835
+ *
836
+ * @example
837
+ * ```typescript
838
+ * import { z } from "zod";
839
+ * import { createFunctionToolFromSchema } from "@modelrelay/sdk";
840
+ *
841
+ * const weatherParams = z.object({
842
+ * location: z.string().describe("City name"),
843
+ * unit: z.enum(["celsius", "fahrenheit"]).default("celsius"),
844
+ * });
845
+ *
846
+ * const weatherTool = createFunctionToolFromSchema(
847
+ * "get_weather",
848
+ * "Get weather for a location",
849
+ * weatherParams
850
+ * );
851
+ * ```
852
+ *
853
+ * @param name - The tool name
854
+ * @param description - A description of what the tool does
855
+ * @param schema - A Zod schema defining the tool's parameters
856
+ * @param options - Optional JSON Schema generation options
857
+ * @returns A Tool definition with the JSON schema derived from the Zod schema
858
+ */
859
+ declare function createFunctionToolFromSchema(name: string, description: string, schema: ZodLikeSchema, options?: JsonSchemaOptions): Tool;
860
+ /**
861
+ * Creates a function tool with the given name, description, and JSON schema.
862
+ */
863
+ declare function createFunctionTool(name: string, description: string, parameters?: Record<string, unknown>): Tool;
864
+ /**
865
+ * Creates a web tool with optional domain filters and mode.
866
+ */
867
+ declare function createWebTool(options?: {
868
+ mode?: WebToolMode;
869
+ allowedDomains?: string[];
870
+ excludedDomains?: string[];
871
+ maxUses?: number;
872
+ }): Tool;
873
+ /**
874
+ * Returns a ToolChoice that lets the model decide when to use tools.
875
+ */
876
+ declare function toolChoiceAuto(): ToolChoice;
877
+ /**
878
+ * Returns a ToolChoice that forces the model to use a tool.
879
+ */
880
+ declare function toolChoiceRequired(): ToolChoice;
881
+ /**
882
+ * Returns a ToolChoice that prevents the model from using tools.
883
+ */
884
+ declare function toolChoiceNone(): ToolChoice;
885
+ /**
886
+ * Returns true if the response contains tool calls.
887
+ */
888
+ declare function hasToolCalls(response: ChatCompletionResponse): boolean;
889
+ /**
890
+ * Returns the first tool call from a response, or undefined if none exist.
891
+ */
892
+ declare function firstToolCall(response: ChatCompletionResponse): ToolCall | undefined;
893
+ /**
894
+ * Creates a message containing the result of a tool call.
895
+ */
896
+ declare function toolResultMessage(toolCallId: string, result: unknown): ChatMessage;
897
+ /**
898
+ * Creates a tool result message from a ToolCall.
899
+ * Convenience wrapper around toolResultMessage using the call's ID.
900
+ */
901
+ declare function respondToToolCall(call: ToolCall, result: unknown): ChatMessage;
902
+ /**
903
+ * Creates an assistant message that includes tool calls.
904
+ * Used to include the assistant's tool-calling turn in conversation history.
905
+ */
906
+ declare function assistantMessageWithToolCalls(content: string, toolCalls: ToolCall[]): ChatMessage;
907
+ /**
908
+ * Accumulates streaming tool call deltas into complete tool calls.
909
+ */
910
+ declare class ToolCallAccumulator {
911
+ private calls;
1007
912
  /**
1008
- * Claim a customer by email, setting their external_id.
1009
- * Used when a customer subscribes via Stripe Checkout (email only) and later
1010
- * authenticates to the app, needing to link their identity.
1011
- *
1012
- * @throws {APIError} with status 404 if customer not found by email
1013
- * @throws {APIError} with status 409 if customer already claimed or external_id in use
913
+ * Processes a streaming tool call delta.
914
+ * Returns true if this started a new tool call.
1014
915
  */
1015
- claim(request: CustomerClaimRequest): Promise<Customer>;
916
+ processDelta(delta: ToolCallDelta): boolean;
1016
917
  /**
1017
- * Delete a customer by ID.
918
+ * Returns all accumulated tool calls in index order.
1018
919
  */
1019
- delete(customerId: string): Promise<void>;
920
+ getToolCalls(): ToolCall[];
1020
921
  /**
1021
- * Create a Stripe checkout session for a customer.
922
+ * Returns a specific tool call by index, or undefined if not found.
1022
923
  */
1023
- createCheckoutSession(customerId: string, request: CheckoutSessionRequest): Promise<CheckoutSession>;
924
+ getToolCall(index: number): ToolCall | undefined;
1024
925
  /**
1025
- * Get the subscription status for a customer.
926
+ * Clears all accumulated tool calls.
1026
927
  */
1027
- getSubscription(customerId: string): Promise<SubscriptionStatus>;
928
+ reset(): void;
1028
929
  }
1029
-
1030
930
  /**
1031
- * Billing interval for a tier.
931
+ * Error thrown when tool argument parsing or validation fails.
932
+ * Contains a descriptive message suitable for sending back to the model.
1032
933
  */
1033
- type PriceInterval = "month" | "year";
934
+ declare class ToolArgsError extends Error {
935
+ /** The tool call ID for correlation */
936
+ readonly toolCallId: string;
937
+ /** The tool name that was called */
938
+ readonly toolName: string;
939
+ /** The raw arguments string that failed to parse */
940
+ readonly rawArguments: string;
941
+ constructor(message: string, toolCallId: string, toolName: string, rawArguments: string);
942
+ }
1034
943
  /**
1035
- * Tier represents a pricing tier in a ModelRelay project.
944
+ * Schema interface compatible with Zod, Yup, and similar validation libraries.
945
+ * Any object with a `parse` method that returns the validated type works.
1036
946
  */
1037
- interface Tier {
1038
- id: string;
1039
- project_id: string;
1040
- tier_code: string;
1041
- display_name: string;
1042
- spend_limit_cents: number;
1043
- stripe_price_id?: string;
1044
- price_amount?: number;
1045
- price_currency?: string;
1046
- price_interval?: PriceInterval;
1047
- trial_days?: number;
1048
- created_at: string;
1049
- updated_at: string;
947
+ interface Schema<T> {
948
+ parse(data: unknown): T;
1050
949
  }
1051
950
  /**
1052
- * Request to create a tier checkout session (Stripe-first flow).
1053
- * Stripe collects the customer's email during checkout.
951
+ * Parses and validates tool call arguments using a schema.
952
+ *
953
+ * Works with any schema library that has a `parse` method (Zod, Yup, etc.).
954
+ * Throws a descriptive ToolArgsError if parsing or validation fails.
955
+ *
956
+ * @example
957
+ * ```typescript
958
+ * import { z } from "zod";
959
+ *
960
+ * const WeatherArgs = z.object({
961
+ * location: z.string(),
962
+ * unit: z.enum(["celsius", "fahrenheit"]).default("celsius"),
963
+ * });
964
+ *
965
+ * // In your tool handler:
966
+ * const args = parseToolArgs(toolCall, WeatherArgs);
967
+ * // args is typed as { location: string; unit: "celsius" | "fahrenheit" }
968
+ * ```
969
+ *
970
+ * @param call - The tool call containing arguments to parse
971
+ * @param schema - A schema with a `parse` method (Zod, Yup, etc.)
972
+ * @returns The parsed and validated arguments with proper types
973
+ * @throws {ToolArgsError} If JSON parsing or schema validation fails
1054
974
  */
1055
- interface TierCheckoutRequest {
1056
- success_url: string;
1057
- cancel_url: string;
1058
- }
975
+ declare function parseToolArgs<T>(call: ToolCall, schema: Schema<T>): T;
1059
976
  /**
1060
- * Tier checkout session response.
977
+ * Attempts to parse tool arguments, returning a result object instead of throwing.
978
+ *
979
+ * @example
980
+ * ```typescript
981
+ * const result = tryParseToolArgs(toolCall, WeatherArgs);
982
+ * if (result.success) {
983
+ * console.log(result.data.location);
984
+ * } else {
985
+ * console.error(result.error.message);
986
+ * }
987
+ * ```
988
+ *
989
+ * @param call - The tool call containing arguments to parse
990
+ * @param schema - A schema with a `parse` method
991
+ * @returns An object with either { success: true, data: T } or { success: false, error: ToolArgsError }
1061
992
  */
1062
- interface TierCheckoutSession {
1063
- session_id: string;
1064
- url: string;
1065
- }
1066
- interface TiersClientConfig {
1067
- apiKey?: string;
993
+ declare function tryParseToolArgs<T>(call: ToolCall, schema: Schema<T>): {
994
+ success: true;
995
+ data: T;
996
+ } | {
997
+ success: false;
998
+ error: ToolArgsError;
999
+ };
1000
+ /**
1001
+ * Parses raw JSON arguments without schema validation.
1002
+ * Useful when you want JSON parsing error handling but not schema validation.
1003
+ *
1004
+ * @param call - The tool call containing arguments to parse
1005
+ * @returns The parsed JSON as an unknown type
1006
+ * @throws {ToolArgsError} If JSON parsing fails
1007
+ */
1008
+ declare function parseToolArgsRaw(call: ToolCall): unknown;
1009
+ /**
1010
+ * Handler function type for tool execution.
1011
+ * Can be sync or async, receives parsed arguments and returns a result.
1012
+ */
1013
+ type ToolHandler<T = unknown, R = unknown> = (args: T, call: ToolCall) => R | Promise<R>;
1014
+ /**
1015
+ * Result of executing a tool call.
1016
+ */
1017
+ interface ToolExecutionResult {
1018
+ toolCallId: string;
1019
+ toolName: string;
1020
+ result: unknown;
1021
+ error?: string;
1022
+ /**
1023
+ * True if the error is due to malformed arguments (JSON parse or validation failure)
1024
+ * and the model should be given a chance to retry with corrected arguments.
1025
+ */
1026
+ isRetryable?: boolean;
1068
1027
  }
1069
1028
  /**
1070
- * TiersClient provides methods to query tiers in a project.
1071
- * Works with both publishable keys (mr_pk_*) and secret keys (mr_sk_*).
1029
+ * Registry for mapping tool names to handler functions with automatic dispatch.
1030
+ *
1031
+ * @example
1032
+ * ```typescript
1033
+ * const registry = new ToolRegistry()
1034
+ * .register("get_weather", async (args) => {
1035
+ * return { temp: 72, unit: "fahrenheit" };
1036
+ * })
1037
+ * .register("search", async (args) => {
1038
+ * return { results: ["result1", "result2"] };
1039
+ * });
1040
+ *
1041
+ * // Execute all tool calls from a response
1042
+ * const results = await registry.executeAll(response.toolCalls);
1043
+ *
1044
+ * // Convert results to messages for the next request
1045
+ * const messages = registry.resultsToMessages(results);
1046
+ * ```
1072
1047
  */
1073
- declare class TiersClient {
1074
- private readonly http;
1075
- private readonly apiKey?;
1076
- constructor(http: HTTPClient, cfg: TiersClientConfig);
1077
- private ensureApiKey;
1078
- private ensureSecretKey;
1048
+ declare class ToolRegistry {
1049
+ private handlers;
1050
+ /**
1051
+ * Registers a handler function for a tool name.
1052
+ * @param name - The tool name (must match the function name in the tool definition)
1053
+ * @param handler - Function to execute when this tool is called
1054
+ * @returns this for chaining
1055
+ */
1056
+ register<T = unknown, R = unknown>(name: string, handler: ToolHandler<T, R>): this;
1057
+ /**
1058
+ * Unregisters a tool handler.
1059
+ * @param name - The tool name to unregister
1060
+ * @returns true if the handler was removed, false if it didn't exist
1061
+ */
1062
+ unregister(name: string): boolean;
1063
+ /**
1064
+ * Checks if a handler is registered for the given tool name.
1065
+ */
1066
+ has(name: string): boolean;
1067
+ /**
1068
+ * Returns the list of registered tool names.
1069
+ */
1070
+ getRegisteredTools(): string[];
1079
1071
  /**
1080
- * List all tiers in the project.
1072
+ * Executes a single tool call.
1073
+ * @param call - The tool call to execute
1074
+ * @returns The execution result
1081
1075
  */
1082
- list(): Promise<Tier[]>;
1076
+ execute(call: ToolCall): Promise<ToolExecutionResult>;
1083
1077
  /**
1084
- * Get a tier by ID.
1078
+ * Executes multiple tool calls in parallel.
1079
+ * @param calls - Array of tool calls to execute
1080
+ * @returns Array of execution results in the same order as input
1085
1081
  */
1086
- get(tierId: string): Promise<Tier>;
1082
+ executeAll(calls: ToolCall[]): Promise<ToolExecutionResult[]>;
1087
1083
  /**
1088
- * Create a Stripe checkout session for a tier (Stripe-first flow).
1089
- *
1090
- * This enables users to subscribe before authenticating. Stripe collects
1091
- * the customer's email during checkout. After checkout completes, a
1092
- * customer record is created with the email from Stripe. The customer
1093
- * can later be linked to an identity via POST /customers/claim.
1094
- *
1095
- * Requires a secret key (mr_sk_*).
1096
- *
1097
- * @param tierId - The tier ID to create a checkout session for
1098
- * @param request - Checkout session request with redirect URLs
1099
- * @returns Checkout session with Stripe URL
1084
+ * Converts execution results to tool result messages.
1085
+ * Useful for appending to the conversation history.
1086
+ * @param results - Array of execution results
1087
+ * @returns Array of ChatMessage objects with role "tool"
1100
1088
  */
1101
- checkout(tierId: string, request: TierCheckoutRequest): Promise<TierCheckoutSession>;
1089
+ resultsToMessages(results: ToolExecutionResult[]): ChatMessage[];
1102
1090
  }
1103
-
1104
1091
  /**
1105
- * API error codes returned by the server.
1106
- * These constants can be used for programmatic error handling.
1092
+ * Formats a tool execution error into a message suitable for sending back to the model.
1093
+ * The message is designed to help the model understand what went wrong and correct it.
1094
+ *
1095
+ * @example
1096
+ * ```typescript
1097
+ * const result = await registry.execute(toolCall);
1098
+ * if (result.error && result.isRetryable) {
1099
+ * const errorMessage = formatToolErrorForModel(result);
1100
+ * messages.push(toolResultMessage(result.toolCallId, errorMessage));
1101
+ * // Continue conversation to let model retry
1102
+ * }
1103
+ * ```
1107
1104
  */
1108
- declare const ErrorCodes: {
1109
- readonly NOT_FOUND: "NOT_FOUND";
1110
- readonly VALIDATION_ERROR: "VALIDATION_ERROR";
1111
- readonly RATE_LIMIT: "RATE_LIMIT";
1112
- readonly UNAUTHORIZED: "UNAUTHORIZED";
1113
- readonly FORBIDDEN: "FORBIDDEN";
1114
- readonly CONFLICT: "CONFLICT";
1115
- readonly INTERNAL_ERROR: "INTERNAL_ERROR";
1116
- readonly SERVICE_UNAVAILABLE: "SERVICE_UNAVAILABLE";
1117
- readonly INVALID_INPUT: "INVALID_INPUT";
1118
- readonly PAYMENT_REQUIRED: "PAYMENT_REQUIRED";
1119
- readonly METHOD_NOT_ALLOWED: "METHOD_NOT_ALLOWED";
1120
- /** No tiers configured for the project - create a tier first. */
1121
- readonly NO_TIERS: "NO_TIERS";
1122
- /** No free tier available for auto-provisioning - create a free tier or use checkout flow. */
1123
- readonly NO_FREE_TIER: "NO_FREE_TIER";
1124
- /** Email required for auto-provisioning a new customer. */
1125
- readonly EMAIL_REQUIRED: "EMAIL_REQUIRED";
1126
- };
1127
- type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
1128
- type ErrorCategory = "config" | "transport" | "api";
1129
- declare class ModelRelayError extends Error {
1130
- category: ErrorCategory;
1131
- status?: number;
1132
- code?: string;
1133
- requestId?: string;
1134
- fields?: FieldError[];
1135
- data?: unknown;
1136
- retries?: RetryMetadata;
1137
- cause?: unknown;
1138
- constructor(message: string, opts: {
1139
- category: ErrorCategory;
1140
- status?: number;
1141
- code?: string;
1142
- requestId?: string;
1143
- fields?: FieldError[];
1144
- data?: unknown;
1145
- retries?: RetryMetadata;
1146
- cause?: unknown;
1147
- });
1148
- }
1149
- declare class ConfigError extends ModelRelayError {
1150
- constructor(message: string, data?: unknown);
1151
- }
1152
- declare class TransportError extends ModelRelayError {
1153
- kind: TransportErrorKind;
1154
- constructor(message: string, opts: {
1155
- kind: TransportErrorKind;
1156
- retries?: RetryMetadata;
1157
- cause?: unknown;
1158
- });
1159
- }
1160
- declare class APIError extends ModelRelayError {
1161
- constructor(message: string, opts: {
1162
- status: number;
1163
- code?: string;
1164
- requestId?: string;
1165
- fields?: FieldError[];
1166
- data?: unknown;
1167
- retries?: RetryMetadata;
1168
- });
1169
- /** Returns true if the error is a not found error. */
1170
- isNotFound(): boolean;
1171
- /** Returns true if the error is a validation error. */
1172
- isValidation(): boolean;
1173
- /** Returns true if the error is a rate limit error. */
1174
- isRateLimit(): boolean;
1175
- /** Returns true if the error is an unauthorized error. */
1176
- isUnauthorized(): boolean;
1177
- /** Returns true if the error is a forbidden error. */
1178
- isForbidden(): boolean;
1179
- /** Returns true if the error is a service unavailable error. */
1180
- isUnavailable(): boolean;
1181
- /**
1182
- * Returns true if the error indicates no tiers are configured.
1183
- * To resolve: create at least one tier in your project dashboard.
1184
- */
1185
- isNoTiers(): boolean;
1186
- /**
1187
- * Returns true if the error indicates no free tier is available for auto-provisioning.
1188
- * To resolve: either create a free tier for automatic customer creation,
1189
- * or use the checkout flow to create paying customers first.
1190
- */
1191
- isNoFreeTier(): boolean;
1105
+ declare function formatToolErrorForModel(result: ToolExecutionResult): string;
1106
+ /**
1107
+ * Checks if any results have retryable errors.
1108
+ *
1109
+ * @example
1110
+ * ```typescript
1111
+ * const results = await registry.executeAll(toolCalls);
1112
+ * if (hasRetryableErrors(results)) {
1113
+ * // Send error messages back to model and continue conversation
1114
+ * }
1115
+ * ```
1116
+ */
1117
+ declare function hasRetryableErrors(results: ToolExecutionResult[]): boolean;
1118
+ /**
1119
+ * Filters results to only those with retryable errors.
1120
+ */
1121
+ declare function getRetryableErrors(results: ToolExecutionResult[]): ToolExecutionResult[];
1122
+ /**
1123
+ * Creates tool result messages for retryable errors, formatted to help the model correct them.
1124
+ *
1125
+ * @example
1126
+ * ```typescript
1127
+ * const results = await registry.executeAll(toolCalls);
1128
+ * if (hasRetryableErrors(results)) {
1129
+ * const retryMessages = createRetryMessages(results);
1130
+ * messages.push(...retryMessages);
1131
+ * // Make another API call to let model retry
1132
+ * }
1133
+ * ```
1134
+ */
1135
+ declare function createRetryMessages(results: ToolExecutionResult[]): ChatMessage[];
1136
+ /**
1137
+ * Options for executeWithRetry.
1138
+ */
1139
+ interface RetryOptions {
1192
1140
  /**
1193
- * Returns true if email is required for auto-provisioning a new customer.
1194
- * To resolve: provide the 'email' field in FrontendTokenRequest.
1141
+ * Maximum number of retry attempts for parse/validation errors.
1142
+ * @default 2
1195
1143
  */
1196
- isEmailRequired(): boolean;
1144
+ maxRetries?: number;
1197
1145
  /**
1198
- * Returns true if this is a customer provisioning error (NO_TIERS, NO_FREE_TIER, or EMAIL_REQUIRED).
1199
- * These errors occur when calling frontendToken() with a customer that doesn't exist
1200
- * and automatic provisioning cannot complete.
1146
+ * Callback invoked when a retryable error occurs.
1147
+ * Should return new tool calls from the model's response.
1148
+ * If not provided, executeWithRetry will not retry automatically.
1149
+ *
1150
+ * @param errorMessages - Messages to send back to the model
1151
+ * @param attempt - Current attempt number (1-based)
1152
+ * @returns New tool calls from the model, or empty array to stop retrying
1201
1153
  */
1202
- isProvisioningError(): boolean;
1154
+ onRetry?: (errorMessages: ChatMessage[], attempt: number) => Promise<ToolCall[]>;
1203
1155
  }
1204
1156
  /**
1205
- * Returns true if the error indicates email is required for auto-provisioning.
1157
+ * Executes tool calls with automatic retry on parse/validation errors.
1158
+ *
1159
+ * This is a higher-level utility that wraps registry.executeAll with retry logic.
1160
+ * When a retryable error occurs, it calls the onRetry callback to get new tool calls
1161
+ * from the model and continues execution.
1162
+ *
1163
+ * **Result Preservation**: Successful results are preserved across retries. If you
1164
+ * execute multiple tool calls and only some fail, the successful results are kept
1165
+ * and merged with the results from retry attempts. Results are keyed by toolCallId,
1166
+ * so if a retry returns a call with the same ID as a previous result, the newer
1167
+ * result will replace it.
1168
+ *
1169
+ * @example
1170
+ * ```typescript
1171
+ * const results = await executeWithRetry(registry, toolCalls, {
1172
+ * maxRetries: 2,
1173
+ * onRetry: async (errorMessages, attempt) => {
1174
+ * console.log(`Retry attempt ${attempt}`);
1175
+ * // Add error messages to conversation and call the model again
1176
+ * messages.push(assistantMessageWithToolCalls("", toolCalls));
1177
+ * messages.push(...errorMessages);
1178
+ * const response = await client.chat.completions.create({ messages, tools });
1179
+ * return response.toolCalls ?? [];
1180
+ * },
1181
+ * });
1182
+ * ```
1183
+ *
1184
+ * @param registry - The tool registry to use for execution
1185
+ * @param toolCalls - Initial tool calls to execute
1186
+ * @param options - Retry configuration
1187
+ * @returns Final execution results after all retries, including preserved successes
1206
1188
  */
1207
- declare function isEmailRequired(err: unknown): boolean;
1189
+ declare function executeWithRetry(registry: ToolRegistry, toolCalls: ToolCall[], options?: RetryOptions): Promise<ToolExecutionResult[]>;
1190
+
1208
1191
  /**
1209
- * Returns true if the error indicates no free tier is available.
1192
+ * Ergonomic structured output API with Zod schema inference and validation.
1193
+ *
1194
+ * This module provides type-safe structured outputs using Zod schemas for
1195
+ * automatic JSON schema generation. The API handles schema construction,
1196
+ * validation retries with error feedback, and strongly-typed result parsing.
1197
+ *
1198
+ * @example
1199
+ * ```typescript
1200
+ * import { z } from 'zod';
1201
+ *
1202
+ * const PersonSchema = z.object({
1203
+ * name: z.string(),
1204
+ * age: z.number(),
1205
+ * });
1206
+ *
1207
+ * const result = await client.chat.completions.structured(
1208
+ * PersonSchema,
1209
+ * { model: "claude-sonnet-4-20250514", messages: [...] },
1210
+ * { maxRetries: 2 }
1211
+ * );
1212
+ *
1213
+ * console.log(result.value.name, result.value.age);
1214
+ * ```
1210
1215
  */
1211
- declare function isNoFreeTier(err: unknown): boolean;
1216
+
1212
1217
  /**
1213
- * Returns true if the error indicates no tiers are configured.
1218
+ * Record of a single structured output attempt.
1214
1219
  */
1215
- declare function isNoTiers(err: unknown): boolean;
1220
+ interface AttemptRecord {
1221
+ /** Which attempt (1-based). */
1222
+ attempt: number;
1223
+ /** Raw JSON returned by the model. */
1224
+ rawJson: string;
1225
+ /** The error that occurred. */
1226
+ error: StructuredErrorKind;
1227
+ }
1216
1228
  /**
1217
- * Returns true if the error is a customer provisioning error.
1229
+ * Specific kind of structured output error.
1218
1230
  */
1219
- declare function isProvisioningError(err: unknown): boolean;
1220
- declare function parseErrorResponse(response: Response, retries?: RetryMetadata): Promise<APIError>;
1221
-
1231
+ type StructuredErrorKind = {
1232
+ kind: "decode";
1233
+ message: string;
1234
+ } | {
1235
+ kind: "validation";
1236
+ issues: ValidationIssue[];
1237
+ };
1222
1238
  /**
1223
- * Creates a user message.
1239
+ * A single field-level validation issue.
1224
1240
  */
1225
- declare function createUserMessage(content: string): ChatMessage;
1241
+ interface ValidationIssue {
1242
+ /** JSON path to the problematic field (e.g., "person.address.city"). */
1243
+ path?: string;
1244
+ /** Description of the issue. */
1245
+ message: string;
1246
+ }
1226
1247
  /**
1227
- * Creates an assistant message.
1248
+ * Error returned when structured output fails on first attempt (before retries).
1228
1249
  */
1229
- declare function createAssistantMessage(content: string): ChatMessage;
1250
+ declare class StructuredDecodeError extends Error {
1251
+ readonly rawJson: string;
1252
+ readonly attempt: number;
1253
+ constructor(message: string, rawJson: string, attempt: number);
1254
+ }
1230
1255
  /**
1231
- * Creates a system message.
1256
+ * Error returned when all retry attempts are exhausted.
1232
1257
  */
1233
- declare function createSystemMessage(content: string): ChatMessage;
1258
+ declare class StructuredExhaustedError extends Error {
1259
+ readonly lastRawJson: string;
1260
+ readonly allAttempts: AttemptRecord[];
1261
+ readonly finalError: StructuredErrorKind;
1262
+ constructor(lastRawJson: string, allAttempts: AttemptRecord[], finalError: StructuredErrorKind);
1263
+ }
1234
1264
  /**
1235
- * Creates a tool call object.
1265
+ * Handler for customizing retry behavior on validation failures.
1266
+ *
1267
+ * Implement this interface to customize how retry messages are constructed
1268
+ * when validation fails. The default implementation appends a simple
1269
+ * error message asking the model to correct its output.
1236
1270
  */
1237
- declare function createToolCall(id: string, name: string, args: string, type?: ToolType): ToolCall;
1271
+ interface RetryHandler {
1272
+ /**
1273
+ * Called when validation fails. Returns messages to append to the conversation
1274
+ * for the retry, or `null` to stop retrying immediately.
1275
+ *
1276
+ * @param attempt - Current attempt number (1-based)
1277
+ * @param rawJson - The raw JSON that failed validation
1278
+ * @param error - The validation/decode error that occurred
1279
+ * @param originalMessages - The original conversation messages
1280
+ */
1281
+ onValidationError(attempt: number, rawJson: string, error: StructuredErrorKind, originalMessages: ChatMessage[]): ChatMessage[] | null;
1282
+ }
1238
1283
  /**
1239
- * Creates a function call object.
1284
+ * Default retry handler that appends a simple error correction message.
1240
1285
  */
1241
- declare function createFunctionCall(name: string, args: string): FunctionCall;
1286
+ declare const defaultRetryHandler: RetryHandler;
1242
1287
  /**
1243
- * Interface for Zod-like schema types.
1244
- * Compatible with Zod's ZodType and similar libraries.
1288
+ * Options for structured output requests.
1245
1289
  */
1246
- interface ZodLikeSchema {
1247
- _def: {
1248
- typeName: string;
1249
- [key: string]: unknown;
1250
- };
1251
- parse(data: unknown): unknown;
1252
- safeParse(data: unknown): {
1253
- success: boolean;
1254
- data?: unknown;
1255
- error?: unknown;
1256
- };
1290
+ interface StructuredOptions {
1291
+ /** Maximum number of retry attempts on validation failure (default: 0). */
1292
+ maxRetries?: number;
1293
+ /** Handler for customizing retry messages. */
1294
+ retryHandler?: RetryHandler;
1295
+ /** Override the schema name (defaults to "response"). */
1296
+ schemaName?: string;
1257
1297
  }
1258
1298
  /**
1259
- * Options for JSON Schema generation.
1299
+ * Result of a successful structured output request.
1260
1300
  */
1261
- interface JsonSchemaOptions {
1262
- /** Whether to include $schema property. Defaults to false. */
1263
- includeSchema?: boolean;
1264
- /** Target JSON Schema version. Defaults to "draft-07". */
1265
- target?: "draft-04" | "draft-07" | "draft-2019-09" | "draft-2020-12";
1301
+ interface StructuredResult<T> {
1302
+ /** The parsed, validated value. */
1303
+ value: T;
1304
+ /** Number of attempts made (1 = first attempt succeeded). */
1305
+ attempts: number;
1306
+ /** Request ID from the server (if available). */
1307
+ requestId?: string;
1266
1308
  }
1267
1309
  /**
1268
- * Converts a Zod schema to JSON Schema.
1269
- * This is a simplified implementation that handles common Zod types.
1270
- * For full Zod support, consider using the 'zod-to-json-schema' package.
1310
+ * Creates a ResponseFormat from a Zod schema with automatic JSON schema generation.
1271
1311
  *
1272
- * @param schema - A Zod schema
1273
- * @param options - Optional JSON Schema generation options
1274
- * @returns A JSON Schema object
1275
- */
1276
- declare function zodToJsonSchema(schema: ZodLikeSchema, options?: JsonSchemaOptions): Record<string, unknown>;
1277
- /**
1278
- * Creates a function tool from a Zod schema.
1312
+ * This function uses `zodToJsonSchema` to convert a Zod schema to JSON Schema,
1313
+ * then wraps it in a ResponseFormat with `type = "json_schema"` and `strict = true`.
1279
1314
  *
1280
- * This function automatically converts a Zod schema to a JSON Schema
1281
- * and creates a tool definition. It eliminates the need to manually
1282
- * write JSON schemas for tool parameters.
1315
+ * @param schema - A Zod schema
1316
+ * @param name - Optional schema name (defaults to "response")
1317
+ * @returns A ResponseFormat configured for structured outputs
1283
1318
  *
1284
1319
  * @example
1285
1320
  * ```typescript
1286
- * import { z } from "zod";
1287
- * import { createFunctionToolFromSchema } from "@modelrelay/sdk";
1321
+ * import { z } from 'zod';
1288
1322
  *
1289
- * const weatherParams = z.object({
1290
- * location: z.string().describe("City name"),
1291
- * unit: z.enum(["celsius", "fahrenheit"]).default("celsius"),
1323
+ * const WeatherSchema = z.object({
1324
+ * temperature: z.number(),
1325
+ * conditions: z.string(),
1292
1326
  * });
1293
1327
  *
1294
- * const weatherTool = createFunctionToolFromSchema(
1295
- * "get_weather",
1296
- * "Get weather for a location",
1297
- * weatherParams
1298
- * );
1328
+ * const format = responseFormatFromZod(WeatherSchema, "weather");
1299
1329
  * ```
1300
- *
1301
- * @param name - The tool name
1302
- * @param description - A description of what the tool does
1303
- * @param schema - A Zod schema defining the tool's parameters
1304
- * @param options - Optional JSON Schema generation options
1305
- * @returns A Tool definition with the JSON schema derived from the Zod schema
1306
1330
  */
1307
- declare function createFunctionToolFromSchema(name: string, description: string, schema: ZodLikeSchema, options?: JsonSchemaOptions): Tool;
1331
+ declare function responseFormatFromZod(schema: ZodLikeSchema, name?: string): ResponseFormat;
1308
1332
  /**
1309
- * Creates a function tool with the given name, description, and JSON schema.
1333
+ * Validates parsed data against a Zod schema.
1334
+ *
1335
+ * @param schema - A Zod schema to validate against
1336
+ * @param data - The data to validate
1337
+ * @returns A result object with success/failure and data/error
1310
1338
  */
1311
- declare function createFunctionTool(name: string, description: string, parameters?: Record<string, unknown>): Tool;
1339
+ declare function validateWithZod<T>(schema: ZodLikeSchema, data: unknown): {
1340
+ success: true;
1341
+ data: T;
1342
+ } | {
1343
+ success: false;
1344
+ error: string;
1345
+ };
1346
+
1347
+ interface ChatRequestOptions {
1348
+ /**
1349
+ * Abort the HTTP request and stream consumption.
1350
+ */
1351
+ signal?: AbortSignal;
1352
+ /**
1353
+ * Override the Accept header to switch between streaming and blocking responses.
1354
+ */
1355
+ stream?: boolean;
1356
+ /**
1357
+ * Optional request id header. `params.requestId` takes precedence if provided.
1358
+ */
1359
+ requestId?: string;
1360
+ /**
1361
+ * Additional HTTP headers for this request.
1362
+ */
1363
+ headers?: Record<string, string>;
1364
+ /**
1365
+ * Additional metadata merged into the request body.
1366
+ */
1367
+ metadata?: Record<string, string>;
1368
+ /**
1369
+ * Override the per-request timeout in milliseconds (set to 0 to disable).
1370
+ */
1371
+ timeoutMs?: number;
1372
+ /**
1373
+ * Override the connect timeout in milliseconds (set to 0 to disable).
1374
+ */
1375
+ connectTimeoutMs?: number;
1376
+ /**
1377
+ * Override retry behavior for this call. Set to `false` to disable retries.
1378
+ */
1379
+ retry?: RetryConfig | false;
1380
+ /**
1381
+ * Per-call metrics callbacks (merged over client defaults).
1382
+ */
1383
+ metrics?: MetricsCallbacks;
1384
+ /**
1385
+ * Per-call trace/log hooks (merged over client defaults).
1386
+ */
1387
+ trace?: TraceCallbacks;
1388
+ }
1389
+ declare class ChatClient {
1390
+ readonly completions: ChatCompletionsClient;
1391
+ private readonly http;
1392
+ private readonly auth;
1393
+ private readonly defaultMetadata?;
1394
+ private readonly metrics?;
1395
+ private readonly trace?;
1396
+ constructor(http: HTTPClient, auth: AuthClient, cfg?: {
1397
+ defaultMetadata?: Record<string, string>;
1398
+ metrics?: MetricsCallbacks;
1399
+ trace?: TraceCallbacks;
1400
+ });
1401
+ /**
1402
+ * Create a customer-attributed chat client for the given customer ID.
1403
+ * The customer's tier determines the model - no model parameter is needed or allowed.
1404
+ *
1405
+ * @example
1406
+ * ```typescript
1407
+ * const stream = await client.chat.forCustomer("user-123").create({
1408
+ * messages: [{ role: "user", content: "Hello!" }],
1409
+ * });
1410
+ * ```
1411
+ */
1412
+ forCustomer(customerId: string): CustomerChatClient;
1413
+ }
1414
+ declare class ChatCompletionsClient {
1415
+ private readonly http;
1416
+ private readonly auth;
1417
+ private readonly defaultMetadata?;
1418
+ private readonly metrics?;
1419
+ private readonly trace?;
1420
+ constructor(http: HTTPClient, auth: AuthClient, defaultMetadata?: Record<string, string>, metrics?: MetricsCallbacks, trace?: TraceCallbacks);
1421
+ create(params: ChatCompletionCreateParams & {
1422
+ stream: false;
1423
+ }, options?: ChatRequestOptions): Promise<ChatCompletionResponse>;
1424
+ create(params: ChatCompletionCreateParams, options: ChatRequestOptions & {
1425
+ stream: false;
1426
+ }): Promise<ChatCompletionResponse>;
1427
+ create(params: ChatCompletionCreateParams, options?: ChatRequestOptions): Promise<ChatCompletionsStream>;
1428
+ /**
1429
+ * Stream structured JSON responses using the NDJSON contract defined for
1430
+ * /llm/proxy. The request must include a structured responseFormat.
1431
+ */
1432
+ streamJSON<T>(params: ChatCompletionCreateParams & {
1433
+ responseFormat: ResponseFormat;
1434
+ }, options?: ChatRequestOptions): Promise<StructuredJSONStream<T>>;
1435
+ /**
1436
+ * Send a structured output request with a Zod schema.
1437
+ *
1438
+ * Auto-generates JSON schema from the Zod schema, validates the response,
1439
+ * and retries on validation failure if configured.
1440
+ *
1441
+ * @param schema - A Zod schema defining the expected response structure
1442
+ * @param params - Chat completion parameters (excluding responseFormat)
1443
+ * @param options - Request options including retry configuration
1444
+ * @returns A typed result with the parsed value
1445
+ *
1446
+ * @example
1447
+ * ```typescript
1448
+ * import { z } from 'zod';
1449
+ *
1450
+ * const PersonSchema = z.object({
1451
+ * name: z.string(),
1452
+ * age: z.number(),
1453
+ * });
1454
+ *
1455
+ * const result = await client.chat.completions.structured(
1456
+ * PersonSchema,
1457
+ * { model: "claude-sonnet-4-20250514", messages: [...] },
1458
+ * { maxRetries: 2 }
1459
+ * );
1460
+ * ```
1461
+ */
1462
+ structured<T>(schema: ZodLikeSchema, params: Omit<ChatCompletionCreateParams, "responseFormat">, options?: ChatRequestOptions & StructuredOptions): Promise<StructuredResult<T>>;
1463
+ /**
1464
+ * Stream structured output with a Zod schema.
1465
+ *
1466
+ * Auto-generates JSON schema from the Zod schema. Note that streaming
1467
+ * does not support retries - for retry behavior, use `structured()`.
1468
+ *
1469
+ * @param schema - A Zod schema defining the expected response structure
1470
+ * @param params - Chat completion parameters (excluding responseFormat)
1471
+ * @param options - Request options
1472
+ * @returns A structured JSON stream
1473
+ *
1474
+ * @example
1475
+ * ```typescript
1476
+ * import { z } from 'zod';
1477
+ *
1478
+ * const PersonSchema = z.object({
1479
+ * name: z.string(),
1480
+ * age: z.number(),
1481
+ * });
1482
+ *
1483
+ * const stream = await client.chat.completions.streamStructured(
1484
+ * PersonSchema,
1485
+ * { model: "claude-sonnet-4-20250514", messages: [...] },
1486
+ * );
1487
+ *
1488
+ * for await (const event of stream) {
1489
+ * console.log(event.type, event.payload);
1490
+ * }
1491
+ * ```
1492
+ */
1493
+ streamStructured<T>(schema: ZodLikeSchema, params: Omit<ChatCompletionCreateParams, "responseFormat">, options?: ChatRequestOptions & Pick<StructuredOptions, "schemaName">): Promise<StructuredJSONStream<T>>;
1494
+ }
1312
1495
  /**
1313
- * Creates a web tool with optional domain filters and mode.
1496
+ * Client for customer-attributed chat completions.
1497
+ * The customer's tier determines the model - no model parameter is needed or allowed.
1314
1498
  */
1315
- declare function createWebTool(options?: {
1316
- mode?: WebToolMode;
1317
- allowedDomains?: string[];
1318
- excludedDomains?: string[];
1319
- maxUses?: number;
1320
- }): Tool;
1499
+ declare class CustomerChatClient {
1500
+ private readonly http;
1501
+ private readonly auth;
1502
+ private readonly customerId;
1503
+ private readonly defaultMetadata?;
1504
+ private readonly metrics?;
1505
+ private readonly trace?;
1506
+ constructor(http: HTTPClient, auth: AuthClient, customerId: string, defaultMetadata?: Record<string, string>, metrics?: MetricsCallbacks, trace?: TraceCallbacks);
1507
+ create(params: CustomerChatParams & {
1508
+ stream: false;
1509
+ }, options?: ChatRequestOptions): Promise<ChatCompletionResponse>;
1510
+ create(params: CustomerChatParams, options: ChatRequestOptions & {
1511
+ stream: false;
1512
+ }): Promise<ChatCompletionResponse>;
1513
+ create(params: CustomerChatParams, options?: ChatRequestOptions): Promise<ChatCompletionsStream>;
1514
+ /**
1515
+ * Stream structured JSON responses using the NDJSON contract.
1516
+ * The request must include a structured responseFormat.
1517
+ */
1518
+ streamJSON<T>(params: CustomerChatParams & {
1519
+ responseFormat: ResponseFormat;
1520
+ }, options?: ChatRequestOptions): Promise<StructuredJSONStream<T>>;
1521
+ /**
1522
+ * Send a structured output request with a Zod schema for customer-attributed calls.
1523
+ *
1524
+ * Auto-generates JSON schema from the Zod schema, validates the response,
1525
+ * and retries on validation failure if configured.
1526
+ *
1527
+ * @param schema - A Zod schema defining the expected response structure
1528
+ * @param params - Customer chat parameters (excluding responseFormat)
1529
+ * @param options - Request options including retry configuration
1530
+ * @returns A typed result with the parsed value
1531
+ */
1532
+ structured<T>(schema: ZodLikeSchema, params: Omit<CustomerChatParams, "responseFormat">, options?: ChatRequestOptions & StructuredOptions): Promise<StructuredResult<T>>;
1533
+ /**
1534
+ * Stream structured output with a Zod schema for customer-attributed calls.
1535
+ *
1536
+ * Auto-generates JSON schema from the Zod schema. Note that streaming
1537
+ * does not support retries - for retry behavior, use `structured()`.
1538
+ *
1539
+ * @param schema - A Zod schema defining the expected response structure
1540
+ * @param params - Customer chat parameters (excluding responseFormat)
1541
+ * @param options - Request options
1542
+ * @returns A structured JSON stream
1543
+ */
1544
+ streamStructured<T>(schema: ZodLikeSchema, params: Omit<CustomerChatParams, "responseFormat">, options?: ChatRequestOptions & Pick<StructuredOptions, "schemaName">): Promise<StructuredJSONStream<T>>;
1545
+ }
1546
+ declare class ChatCompletionsStream implements AsyncIterable<ChatCompletionEvent> {
1547
+ private readonly response;
1548
+ private readonly requestId?;
1549
+ private context;
1550
+ private readonly metrics?;
1551
+ private readonly trace?;
1552
+ private readonly startedAt;
1553
+ private firstTokenEmitted;
1554
+ private closed;
1555
+ constructor(response: Response, requestId: string | undefined, context: RequestContext, metrics?: MetricsCallbacks, trace?: TraceCallbacks);
1556
+ cancel(reason?: unknown): Promise<void>;
1557
+ [Symbol.asyncIterator](): AsyncIterator<ChatCompletionEvent>;
1558
+ private handleStreamEvent;
1559
+ private enrichContext;
1560
+ private recordFirstToken;
1561
+ }
1562
+ declare class StructuredJSONStream<T> implements AsyncIterable<StructuredJSONEvent<T>> {
1563
+ private readonly response;
1564
+ private readonly requestId?;
1565
+ private context;
1566
+ private readonly metrics?;
1567
+ private readonly trace?;
1568
+ private closed;
1569
+ private sawTerminal;
1570
+ constructor(response: Response, requestId: string | undefined, context: RequestContext, metrics?: MetricsCallbacks, trace?: TraceCallbacks);
1571
+ cancel(reason?: unknown): Promise<void>;
1572
+ [Symbol.asyncIterator](): AsyncIterator<StructuredJSONEvent<T>>;
1573
+ collect(): Promise<T>;
1574
+ private parseRecord;
1575
+ private traceStructuredEvent;
1576
+ }
1577
+
1321
1578
  /**
1322
- * Returns a ToolChoice that lets the model decide when to use tools.
1579
+ * Customer metadata as an arbitrary key-value object.
1323
1580
  */
1324
- declare function toolChoiceAuto(): ToolChoice;
1581
+ type CustomerMetadata = Record<string, unknown>;
1325
1582
  /**
1326
- * Returns a ToolChoice that forces the model to use a tool.
1583
+ * Customer represents a customer in a ModelRelay project.
1327
1584
  */
1328
- declare function toolChoiceRequired(): ToolChoice;
1585
+ interface Customer {
1586
+ id: string;
1587
+ project_id: string;
1588
+ tier_id: string;
1589
+ tier_code?: string;
1590
+ external_id: string;
1591
+ email: string;
1592
+ metadata?: CustomerMetadata;
1593
+ stripe_customer_id?: string;
1594
+ stripe_subscription_id?: string;
1595
+ subscription_status?: string;
1596
+ current_period_start?: string;
1597
+ current_period_end?: string;
1598
+ created_at: string;
1599
+ updated_at: string;
1600
+ }
1329
1601
  /**
1330
- * Returns a ToolChoice that prevents the model from using tools.
1602
+ * Request to create a customer.
1331
1603
  */
1332
- declare function toolChoiceNone(): ToolChoice;
1604
+ interface CustomerCreateRequest {
1605
+ tier_id: string;
1606
+ external_id: string;
1607
+ email: string;
1608
+ metadata?: CustomerMetadata;
1609
+ }
1333
1610
  /**
1334
- * Returns true if the response contains tool calls.
1611
+ * Request to upsert a customer by external_id.
1335
1612
  */
1336
- declare function hasToolCalls(response: ChatCompletionResponse): boolean;
1613
+ interface CustomerUpsertRequest {
1614
+ tier_id: string;
1615
+ external_id: string;
1616
+ email: string;
1617
+ metadata?: CustomerMetadata;
1618
+ }
1337
1619
  /**
1338
- * Returns the first tool call from a response, or undefined if none exist.
1620
+ * Request to claim a customer by email, setting their external_id.
1621
+ * Used when a customer subscribes via Stripe Checkout (email only) and later
1622
+ * authenticates to the app, needing to link their identity.
1339
1623
  */
1340
- declare function firstToolCall(response: ChatCompletionResponse): ToolCall | undefined;
1624
+ interface CustomerClaimRequest {
1625
+ email: string;
1626
+ external_id: string;
1627
+ }
1341
1628
  /**
1342
- * Creates a message containing the result of a tool call.
1629
+ * Request to create a checkout session.
1343
1630
  */
1344
- declare function toolResultMessage(toolCallId: string, result: unknown): ChatMessage;
1631
+ interface CheckoutSessionRequest {
1632
+ success_url: string;
1633
+ cancel_url: string;
1634
+ }
1345
1635
  /**
1346
- * Creates a tool result message from a ToolCall.
1347
- * Convenience wrapper around toolResultMessage using the call's ID.
1636
+ * Checkout session response.
1348
1637
  */
1349
- declare function respondToToolCall(call: ToolCall, result: unknown): ChatMessage;
1638
+ interface CheckoutSession {
1639
+ session_id: string;
1640
+ url: string;
1641
+ }
1350
1642
  /**
1351
- * Creates an assistant message that includes tool calls.
1352
- * Used to include the assistant's tool-calling turn in conversation history.
1643
+ * Subscription status response.
1353
1644
  */
1354
- declare function assistantMessageWithToolCalls(content: string, toolCalls: ToolCall[]): ChatMessage;
1645
+ interface SubscriptionStatus {
1646
+ active: boolean;
1647
+ subscription_id?: string;
1648
+ status?: string;
1649
+ current_period_start?: string;
1650
+ current_period_end?: string;
1651
+ }
1652
+ interface CustomersClientConfig {
1653
+ apiKey?: string;
1654
+ }
1355
1655
  /**
1356
- * Accumulates streaming tool call deltas into complete tool calls.
1656
+ * CustomersClient provides methods to manage customers in a project.
1657
+ * Requires a secret key (mr_sk_*) for authentication.
1357
1658
  */
1358
- declare class ToolCallAccumulator {
1359
- private calls;
1659
+ declare class CustomersClient {
1660
+ private readonly http;
1661
+ private readonly apiKey?;
1662
+ constructor(http: HTTPClient, cfg: CustomersClientConfig);
1663
+ private ensureSecretKey;
1360
1664
  /**
1361
- * Processes a streaming tool call delta.
1362
- * Returns true if this started a new tool call.
1665
+ * List all customers in the project.
1363
1666
  */
1364
- processDelta(delta: ToolCallDelta): boolean;
1667
+ list(): Promise<Customer[]>;
1365
1668
  /**
1366
- * Returns all accumulated tool calls in index order.
1669
+ * Create a new customer in the project.
1367
1670
  */
1368
- getToolCalls(): ToolCall[];
1671
+ create(request: CustomerCreateRequest): Promise<Customer>;
1369
1672
  /**
1370
- * Returns a specific tool call by index, or undefined if not found.
1673
+ * Get a customer by ID.
1371
1674
  */
1372
- getToolCall(index: number): ToolCall | undefined;
1675
+ get(customerId: string): Promise<Customer>;
1373
1676
  /**
1374
- * Clears all accumulated tool calls.
1677
+ * Upsert a customer by external_id.
1678
+ * If a customer with the given external_id exists, it is updated.
1679
+ * Otherwise, a new customer is created.
1375
1680
  */
1376
- reset(): void;
1681
+ upsert(request: CustomerUpsertRequest): Promise<Customer>;
1682
+ /**
1683
+ * Claim a customer by email, setting their external_id.
1684
+ * Used when a customer subscribes via Stripe Checkout (email only) and later
1685
+ * authenticates to the app, needing to link their identity.
1686
+ *
1687
+ * @throws {APIError} with status 404 if customer not found by email
1688
+ * @throws {APIError} with status 409 if customer already claimed or external_id in use
1689
+ */
1690
+ claim(request: CustomerClaimRequest): Promise<Customer>;
1691
+ /**
1692
+ * Delete a customer by ID.
1693
+ */
1694
+ delete(customerId: string): Promise<void>;
1695
+ /**
1696
+ * Create a Stripe checkout session for a customer.
1697
+ */
1698
+ createCheckoutSession(customerId: string, request: CheckoutSessionRequest): Promise<CheckoutSession>;
1699
+ /**
1700
+ * Get the subscription status for a customer.
1701
+ */
1702
+ getSubscription(customerId: string): Promise<SubscriptionStatus>;
1377
1703
  }
1704
+
1378
1705
  /**
1379
- * Error thrown when tool argument parsing or validation fails.
1380
- * Contains a descriptive message suitable for sending back to the model.
1706
+ * Billing interval for a tier.
1381
1707
  */
1382
- declare class ToolArgsError extends Error {
1383
- /** The tool call ID for correlation */
1384
- readonly toolCallId: string;
1385
- /** The tool name that was called */
1386
- readonly toolName: string;
1387
- /** The raw arguments string that failed to parse */
1388
- readonly rawArguments: string;
1389
- constructor(message: string, toolCallId: string, toolName: string, rawArguments: string);
1390
- }
1708
+ type PriceInterval = "month" | "year";
1391
1709
  /**
1392
- * Schema interface compatible with Zod, Yup, and similar validation libraries.
1393
- * Any object with a `parse` method that returns the validated type works.
1710
+ * Tier represents a pricing tier in a ModelRelay project.
1394
1711
  */
1395
- interface Schema<T> {
1396
- parse(data: unknown): T;
1712
+ interface Tier {
1713
+ id: string;
1714
+ project_id: string;
1715
+ tier_code: string;
1716
+ display_name: string;
1717
+ spend_limit_cents: number;
1718
+ stripe_price_id?: string;
1719
+ price_amount?: number;
1720
+ price_currency?: string;
1721
+ price_interval?: PriceInterval;
1722
+ trial_days?: number;
1723
+ created_at: string;
1724
+ updated_at: string;
1397
1725
  }
1398
1726
  /**
1399
- * Parses and validates tool call arguments using a schema.
1400
- *
1401
- * Works with any schema library that has a `parse` method (Zod, Yup, etc.).
1402
- * Throws a descriptive ToolArgsError if parsing or validation fails.
1403
- *
1404
- * @example
1405
- * ```typescript
1406
- * import { z } from "zod";
1407
- *
1408
- * const WeatherArgs = z.object({
1409
- * location: z.string(),
1410
- * unit: z.enum(["celsius", "fahrenheit"]).default("celsius"),
1411
- * });
1412
- *
1413
- * // In your tool handler:
1414
- * const args = parseToolArgs(toolCall, WeatherArgs);
1415
- * // args is typed as { location: string; unit: "celsius" | "fahrenheit" }
1416
- * ```
1417
- *
1418
- * @param call - The tool call containing arguments to parse
1419
- * @param schema - A schema with a `parse` method (Zod, Yup, etc.)
1420
- * @returns The parsed and validated arguments with proper types
1421
- * @throws {ToolArgsError} If JSON parsing or schema validation fails
1422
- */
1423
- declare function parseToolArgs<T>(call: ToolCall, schema: Schema<T>): T;
1424
- /**
1425
- * Attempts to parse tool arguments, returning a result object instead of throwing.
1426
- *
1427
- * @example
1428
- * ```typescript
1429
- * const result = tryParseToolArgs(toolCall, WeatherArgs);
1430
- * if (result.success) {
1431
- * console.log(result.data.location);
1432
- * } else {
1433
- * console.error(result.error.message);
1434
- * }
1435
- * ```
1436
- *
1437
- * @param call - The tool call containing arguments to parse
1438
- * @param schema - A schema with a `parse` method
1439
- * @returns An object with either { success: true, data: T } or { success: false, error: ToolArgsError }
1440
- */
1441
- declare function tryParseToolArgs<T>(call: ToolCall, schema: Schema<T>): {
1442
- success: true;
1443
- data: T;
1444
- } | {
1445
- success: false;
1446
- error: ToolArgsError;
1447
- };
1448
- /**
1449
- * Parses raw JSON arguments without schema validation.
1450
- * Useful when you want JSON parsing error handling but not schema validation.
1451
- *
1452
- * @param call - The tool call containing arguments to parse
1453
- * @returns The parsed JSON as an unknown type
1454
- * @throws {ToolArgsError} If JSON parsing fails
1455
- */
1456
- declare function parseToolArgsRaw(call: ToolCall): unknown;
1457
- /**
1458
- * Handler function type for tool execution.
1459
- * Can be sync or async, receives parsed arguments and returns a result.
1460
- */
1461
- type ToolHandler<T = unknown, R = unknown> = (args: T, call: ToolCall) => R | Promise<R>;
1462
- /**
1463
- * Result of executing a tool call.
1727
+ * Request to create a tier checkout session (Stripe-first flow).
1728
+ * Stripe collects the customer's email during checkout.
1464
1729
  */
1465
- interface ToolExecutionResult {
1466
- toolCallId: string;
1467
- toolName: string;
1468
- result: unknown;
1469
- error?: string;
1470
- /**
1471
- * True if the error is due to malformed arguments (JSON parse or validation failure)
1472
- * and the model should be given a chance to retry with corrected arguments.
1473
- */
1474
- isRetryable?: boolean;
1730
+ interface TierCheckoutRequest {
1731
+ success_url: string;
1732
+ cancel_url: string;
1475
1733
  }
1476
1734
  /**
1477
- * Registry for mapping tool names to handler functions with automatic dispatch.
1478
- *
1479
- * @example
1480
- * ```typescript
1481
- * const registry = new ToolRegistry()
1482
- * .register("get_weather", async (args) => {
1483
- * return { temp: 72, unit: "fahrenheit" };
1484
- * })
1485
- * .register("search", async (args) => {
1486
- * return { results: ["result1", "result2"] };
1487
- * });
1488
- *
1489
- * // Execute all tool calls from a response
1490
- * const results = await registry.executeAll(response.toolCalls);
1491
- *
1492
- * // Convert results to messages for the next request
1493
- * const messages = registry.resultsToMessages(results);
1494
- * ```
1735
+ * Tier checkout session response.
1495
1736
  */
1496
- declare class ToolRegistry {
1497
- private handlers;
1737
+ interface TierCheckoutSession {
1738
+ session_id: string;
1739
+ url: string;
1740
+ }
1741
+ interface TiersClientConfig {
1742
+ apiKey?: string;
1743
+ }
1744
+ /**
1745
+ * TiersClient provides methods to query tiers in a project.
1746
+ * Works with both publishable keys (mr_pk_*) and secret keys (mr_sk_*).
1747
+ */
1748
+ declare class TiersClient {
1749
+ private readonly http;
1750
+ private readonly apiKey?;
1751
+ constructor(http: HTTPClient, cfg: TiersClientConfig);
1752
+ private ensureApiKey;
1753
+ private ensureSecretKey;
1498
1754
  /**
1499
- * Registers a handler function for a tool name.
1500
- * @param name - The tool name (must match the function name in the tool definition)
1501
- * @param handler - Function to execute when this tool is called
1502
- * @returns this for chaining
1755
+ * List all tiers in the project.
1503
1756
  */
1504
- register<T = unknown, R = unknown>(name: string, handler: ToolHandler<T, R>): this;
1757
+ list(): Promise<Tier[]>;
1505
1758
  /**
1506
- * Unregisters a tool handler.
1507
- * @param name - The tool name to unregister
1508
- * @returns true if the handler was removed, false if it didn't exist
1759
+ * Get a tier by ID.
1509
1760
  */
1510
- unregister(name: string): boolean;
1761
+ get(tierId: string): Promise<Tier>;
1511
1762
  /**
1512
- * Checks if a handler is registered for the given tool name.
1763
+ * Create a Stripe checkout session for a tier (Stripe-first flow).
1764
+ *
1765
+ * This enables users to subscribe before authenticating. Stripe collects
1766
+ * the customer's email during checkout. After checkout completes, a
1767
+ * customer record is created with the email from Stripe. The customer
1768
+ * can later be linked to an identity via POST /customers/claim.
1769
+ *
1770
+ * Requires a secret key (mr_sk_*).
1771
+ *
1772
+ * @param tierId - The tier ID to create a checkout session for
1773
+ * @param request - Checkout session request with redirect URLs
1774
+ * @returns Checkout session with Stripe URL
1513
1775
  */
1514
- has(name: string): boolean;
1776
+ checkout(tierId: string, request: TierCheckoutRequest): Promise<TierCheckoutSession>;
1777
+ }
1778
+
1779
+ /**
1780
+ * API error codes returned by the server.
1781
+ * These constants can be used for programmatic error handling.
1782
+ */
1783
+ declare const ErrorCodes: {
1784
+ readonly NOT_FOUND: "NOT_FOUND";
1785
+ readonly VALIDATION_ERROR: "VALIDATION_ERROR";
1786
+ readonly RATE_LIMIT: "RATE_LIMIT";
1787
+ readonly UNAUTHORIZED: "UNAUTHORIZED";
1788
+ readonly FORBIDDEN: "FORBIDDEN";
1789
+ readonly CONFLICT: "CONFLICT";
1790
+ readonly INTERNAL_ERROR: "INTERNAL_ERROR";
1791
+ readonly SERVICE_UNAVAILABLE: "SERVICE_UNAVAILABLE";
1792
+ readonly INVALID_INPUT: "INVALID_INPUT";
1793
+ readonly PAYMENT_REQUIRED: "PAYMENT_REQUIRED";
1794
+ readonly METHOD_NOT_ALLOWED: "METHOD_NOT_ALLOWED";
1795
+ /** No tiers configured for the project - create a tier first. */
1796
+ readonly NO_TIERS: "NO_TIERS";
1797
+ /** No free tier available for auto-provisioning - create a free tier or use checkout flow. */
1798
+ readonly NO_FREE_TIER: "NO_FREE_TIER";
1799
+ /** Email required for auto-provisioning a new customer. */
1800
+ readonly EMAIL_REQUIRED: "EMAIL_REQUIRED";
1801
+ };
1802
+ type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
1803
+ type ErrorCategory = "config" | "transport" | "api";
1804
+ declare class ModelRelayError extends Error {
1805
+ category: ErrorCategory;
1806
+ status?: number;
1807
+ code?: string;
1808
+ requestId?: string;
1809
+ fields?: FieldError[];
1810
+ data?: unknown;
1811
+ retries?: RetryMetadata;
1812
+ cause?: unknown;
1813
+ constructor(message: string, opts: {
1814
+ category: ErrorCategory;
1815
+ status?: number;
1816
+ code?: string;
1817
+ requestId?: string;
1818
+ fields?: FieldError[];
1819
+ data?: unknown;
1820
+ retries?: RetryMetadata;
1821
+ cause?: unknown;
1822
+ });
1823
+ }
1824
+ declare class ConfigError extends ModelRelayError {
1825
+ constructor(message: string, data?: unknown);
1826
+ }
1827
+ declare class TransportError extends ModelRelayError {
1828
+ kind: TransportErrorKind;
1829
+ constructor(message: string, opts: {
1830
+ kind: TransportErrorKind;
1831
+ retries?: RetryMetadata;
1832
+ cause?: unknown;
1833
+ });
1834
+ }
1835
+ declare class APIError extends ModelRelayError {
1836
+ constructor(message: string, opts: {
1837
+ status: number;
1838
+ code?: string;
1839
+ requestId?: string;
1840
+ fields?: FieldError[];
1841
+ data?: unknown;
1842
+ retries?: RetryMetadata;
1843
+ });
1844
+ /** Returns true if the error is a not found error. */
1845
+ isNotFound(): boolean;
1846
+ /** Returns true if the error is a validation error. */
1847
+ isValidation(): boolean;
1848
+ /** Returns true if the error is a rate limit error. */
1849
+ isRateLimit(): boolean;
1850
+ /** Returns true if the error is an unauthorized error. */
1851
+ isUnauthorized(): boolean;
1852
+ /** Returns true if the error is a forbidden error. */
1853
+ isForbidden(): boolean;
1854
+ /** Returns true if the error is a service unavailable error. */
1855
+ isUnavailable(): boolean;
1515
1856
  /**
1516
- * Returns the list of registered tool names.
1857
+ * Returns true if the error indicates no tiers are configured.
1858
+ * To resolve: create at least one tier in your project dashboard.
1517
1859
  */
1518
- getRegisteredTools(): string[];
1860
+ isNoTiers(): boolean;
1519
1861
  /**
1520
- * Executes a single tool call.
1521
- * @param call - The tool call to execute
1522
- * @returns The execution result
1862
+ * Returns true if the error indicates no free tier is available for auto-provisioning.
1863
+ * To resolve: either create a free tier for automatic customer creation,
1864
+ * or use the checkout flow to create paying customers first.
1523
1865
  */
1524
- execute(call: ToolCall): Promise<ToolExecutionResult>;
1866
+ isNoFreeTier(): boolean;
1525
1867
  /**
1526
- * Executes multiple tool calls in parallel.
1527
- * @param calls - Array of tool calls to execute
1528
- * @returns Array of execution results in the same order as input
1868
+ * Returns true if email is required for auto-provisioning a new customer.
1869
+ * To resolve: provide the 'email' field in FrontendTokenRequest.
1529
1870
  */
1530
- executeAll(calls: ToolCall[]): Promise<ToolExecutionResult[]>;
1871
+ isEmailRequired(): boolean;
1531
1872
  /**
1532
- * Converts execution results to tool result messages.
1533
- * Useful for appending to the conversation history.
1534
- * @param results - Array of execution results
1535
- * @returns Array of ChatMessage objects with role "tool"
1873
+ * Returns true if this is a customer provisioning error (NO_TIERS, NO_FREE_TIER, or EMAIL_REQUIRED).
1874
+ * These errors occur when calling frontendToken() with a customer that doesn't exist
1875
+ * and automatic provisioning cannot complete.
1536
1876
  */
1537
- resultsToMessages(results: ToolExecutionResult[]): ChatMessage[];
1877
+ isProvisioningError(): boolean;
1538
1878
  }
1539
1879
  /**
1540
- * Formats a tool execution error into a message suitable for sending back to the model.
1541
- * The message is designed to help the model understand what went wrong and correct it.
1542
- *
1543
- * @example
1544
- * ```typescript
1545
- * const result = await registry.execute(toolCall);
1546
- * if (result.error && result.isRetryable) {
1547
- * const errorMessage = formatToolErrorForModel(result);
1548
- * messages.push(toolResultMessage(result.toolCallId, errorMessage));
1549
- * // Continue conversation to let model retry
1550
- * }
1551
- * ```
1552
- */
1553
- declare function formatToolErrorForModel(result: ToolExecutionResult): string;
1554
- /**
1555
- * Checks if any results have retryable errors.
1556
- *
1557
- * @example
1558
- * ```typescript
1559
- * const results = await registry.executeAll(toolCalls);
1560
- * if (hasRetryableErrors(results)) {
1561
- * // Send error messages back to model and continue conversation
1562
- * }
1563
- * ```
1564
- */
1565
- declare function hasRetryableErrors(results: ToolExecutionResult[]): boolean;
1566
- /**
1567
- * Filters results to only those with retryable errors.
1880
+ * Returns true if the error indicates email is required for auto-provisioning.
1568
1881
  */
1569
- declare function getRetryableErrors(results: ToolExecutionResult[]): ToolExecutionResult[];
1882
+ declare function isEmailRequired(err: unknown): boolean;
1570
1883
  /**
1571
- * Creates tool result messages for retryable errors, formatted to help the model correct them.
1572
- *
1573
- * @example
1574
- * ```typescript
1575
- * const results = await registry.executeAll(toolCalls);
1576
- * if (hasRetryableErrors(results)) {
1577
- * const retryMessages = createRetryMessages(results);
1578
- * messages.push(...retryMessages);
1579
- * // Make another API call to let model retry
1580
- * }
1581
- * ```
1884
+ * Returns true if the error indicates no free tier is available.
1582
1885
  */
1583
- declare function createRetryMessages(results: ToolExecutionResult[]): ChatMessage[];
1886
+ declare function isNoFreeTier(err: unknown): boolean;
1584
1887
  /**
1585
- * Options for executeWithRetry.
1888
+ * Returns true if the error indicates no tiers are configured.
1586
1889
  */
1587
- interface RetryOptions {
1588
- /**
1589
- * Maximum number of retry attempts for parse/validation errors.
1590
- * @default 2
1591
- */
1592
- maxRetries?: number;
1593
- /**
1594
- * Callback invoked when a retryable error occurs.
1595
- * Should return new tool calls from the model's response.
1596
- * If not provided, executeWithRetry will not retry automatically.
1597
- *
1598
- * @param errorMessages - Messages to send back to the model
1599
- * @param attempt - Current attempt number (1-based)
1600
- * @returns New tool calls from the model, or empty array to stop retrying
1601
- */
1602
- onRetry?: (errorMessages: ChatMessage[], attempt: number) => Promise<ToolCall[]>;
1603
- }
1890
+ declare function isNoTiers(err: unknown): boolean;
1604
1891
  /**
1605
- * Executes tool calls with automatic retry on parse/validation errors.
1606
- *
1607
- * This is a higher-level utility that wraps registry.executeAll with retry logic.
1608
- * When a retryable error occurs, it calls the onRetry callback to get new tool calls
1609
- * from the model and continues execution.
1610
- *
1611
- * **Result Preservation**: Successful results are preserved across retries. If you
1612
- * execute multiple tool calls and only some fail, the successful results are kept
1613
- * and merged with the results from retry attempts. Results are keyed by toolCallId,
1614
- * so if a retry returns a call with the same ID as a previous result, the newer
1615
- * result will replace it.
1616
- *
1617
- * @example
1618
- * ```typescript
1619
- * const results = await executeWithRetry(registry, toolCalls, {
1620
- * maxRetries: 2,
1621
- * onRetry: async (errorMessages, attempt) => {
1622
- * console.log(`Retry attempt ${attempt}`);
1623
- * // Add error messages to conversation and call the model again
1624
- * messages.push(assistantMessageWithToolCalls("", toolCalls));
1625
- * messages.push(...errorMessages);
1626
- * const response = await client.chat.completions.create({ messages, tools });
1627
- * return response.toolCalls ?? [];
1628
- * },
1629
- * });
1630
- * ```
1631
- *
1632
- * @param registry - The tool registry to use for execution
1633
- * @param toolCalls - Initial tool calls to execute
1634
- * @param options - Retry configuration
1635
- * @returns Final execution results after all retries, including preserved successes
1892
+ * Returns true if the error is a customer provisioning error.
1636
1893
  */
1637
- declare function executeWithRetry(registry: ToolRegistry, toolCalls: ToolCall[], options?: RetryOptions): Promise<ToolExecutionResult[]>;
1894
+ declare function isProvisioningError(err: unknown): boolean;
1895
+ declare function parseErrorResponse(response: Response, retries?: RetryMetadata): Promise<APIError>;
1638
1896
 
1639
1897
  declare class ModelRelay {
1640
1898
  readonly chat: ChatClient;
@@ -1645,4 +1903,4 @@ declare class ModelRelay {
1645
1903
  constructor(options: ModelRelayOptions);
1646
1904
  }
1647
1905
 
1648
- 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, CustomerChatClient, type CustomerChatParams, type CustomerClaimRequest, 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 FrontendTokenAutoProvisionRequest, type FrontendTokenRequest, type FunctionCall, type FunctionCallDelta, type FunctionTool, type HttpRequestMetrics, type JsonSchemaOptions, type KnownStopReason, type MessageDeltaData, type MessageRole, MessageRoles, type MessageStartData, type MessageStopData, type MetricsCallbacks, type ModelId, ModelRelay, type ModelRelayBaseOptions, ModelRelayError, type ModelRelayKeyOptions, type ModelRelayOptions, type ModelRelayOptionsLegacy, type ModelRelayTokenOptions, type NonEmptyArray, type PriceInterval, type Project, type ProviderId, type RequestContext, type ResponseFormat, type ResponseFormatType, ResponseFormatTypes, type ResponseJSONSchemaFormat, type RetryConfig, type RetryMetadata, type RetryOptions, SDK_VERSION, type Schema, type StopReason, StopReasons, type StreamFirstTokenMetrics, type StructuredJSONEvent, type StructuredJSONRecordType, StructuredJSONStream, type SubscriptionStatus, type Tier, type TierCheckoutRequest, type TierCheckoutSession, TiersClient, type TokenType, 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 WebSearchConfig, type WebToolMode, WebToolModes, type XSearchConfig, type ZodLikeSchema, assistantMessageWithToolCalls, createAccessTokenAuth, createApiKeyAuth, createAssistantMessage, createFunctionCall, createFunctionTool, createFunctionToolFromSchema, createRetryMessages, createSystemMessage, createToolCall, createUsage, createUserMessage, createWebTool, executeWithRetry, firstToolCall, formatToolErrorForModel, getRetryableErrors, hasRetryableErrors, hasToolCalls, isEmailRequired, isNoFreeTier, isNoTiers, isProvisioningError, isPublishableKey, mergeMetrics, mergeTrace, modelToString, normalizeModelId, normalizeStopReason, parseErrorResponse, parseToolArgs, parseToolArgsRaw, respondToToolCall, stopReasonToString, toolChoiceAuto, toolChoiceNone, toolChoiceRequired, toolResultMessage, tryParseToolArgs, zodToJsonSchema };
1906
+ export { type APIChatResponse, type APIChatUsage, type APICheckoutSession, type APICustomerRef, APIError, type APIFrontendToken, type APIKey, type AttemptRecord, AuthClient, type AuthHeaders, ChatClient, type ChatCompletionCreateParams, type ChatCompletionEvent, type ChatCompletionResponse, ChatCompletionsStream, type ChatEventType, type ChatMessage, type CheckoutSession, type CheckoutSessionRequest, type CodeExecConfig, ConfigError, type Customer, CustomerChatClient, type CustomerChatParams, type CustomerClaimRequest, type CustomerCreateRequest, type CustomerMetadata, type CustomerUpsertRequest, CustomersClient, DEFAULT_BASE_URL, DEFAULT_CLIENT_HEADER, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_REQUEST_TIMEOUT_MS, type DeepPartial, type ErrorCategory, type ErrorCode, ErrorCodes, type FieldError, type FrontendCustomer, type FrontendToken, type FrontendTokenAutoProvisionRequest, type FrontendTokenRequest, type FunctionCall, type FunctionCallDelta, type FunctionTool, type HttpRequestMetrics, type JsonSchemaOptions, type KnownStopReason, type MessageDeltaData, type MessageRole, MessageRoles, type MessageStartData, type MessageStopData, type MetricsCallbacks, type ModelId, ModelRelay, type ModelRelayBaseOptions, ModelRelayError, type ModelRelayKeyOptions, type ModelRelayOptions, type ModelRelayOptionsLegacy, type ModelRelayTokenOptions, type NonEmptyArray, type PriceInterval, type Project, type ProviderId, type RequestContext, type ResponseFormat, type ResponseFormatType, ResponseFormatTypes, type ResponseJSONSchemaFormat, type RetryConfig, type RetryHandler, type RetryMetadata, type RetryOptions, SDK_VERSION, type Schema, type StopReason, StopReasons, type StreamFirstTokenMetrics, StructuredDecodeError, type StructuredErrorKind, StructuredExhaustedError, type StructuredJSONEvent, type StructuredJSONRecordType, StructuredJSONStream, type StructuredOptions, type StructuredResult, type SubscriptionStatus, type Tier, type TierCheckoutRequest, type TierCheckoutSession, TiersClient, type TokenType, 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 ValidationIssue, type WebSearchConfig, type WebToolMode, WebToolModes, type XSearchConfig, type ZodLikeSchema, assistantMessageWithToolCalls, createAccessTokenAuth, createApiKeyAuth, createAssistantMessage, createFunctionCall, createFunctionTool, createFunctionToolFromSchema, createRetryMessages, createSystemMessage, createToolCall, createUsage, createUserMessage, createWebTool, defaultRetryHandler, executeWithRetry, firstToolCall, formatToolErrorForModel, getRetryableErrors, hasRetryableErrors, hasToolCalls, isEmailRequired, isNoFreeTier, isNoTiers, isProvisioningError, isPublishableKey, mergeMetrics, mergeTrace, modelToString, normalizeModelId, normalizeStopReason, parseErrorResponse, parseToolArgs, parseToolArgsRaw, respondToToolCall, responseFormatFromZod, stopReasonToString, toolChoiceAuto, toolChoiceNone, toolChoiceRequired, toolResultMessage, tryParseToolArgs, validateWithZod, zodToJsonSchema };