@modelrelay/sdk 0.20.0 → 0.22.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.cjs +82 -18
- package/dist/index.d.cts +69 -5
- package/dist/index.d.ts +69 -5
- package/dist/index.js +78 -18
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -64,6 +64,10 @@ __export(index_exports, {
|
|
|
64
64
|
getRetryableErrors: () => getRetryableErrors,
|
|
65
65
|
hasRetryableErrors: () => hasRetryableErrors,
|
|
66
66
|
hasToolCalls: () => hasToolCalls,
|
|
67
|
+
isEmailRequired: () => isEmailRequired,
|
|
68
|
+
isNoFreeTier: () => isNoFreeTier,
|
|
69
|
+
isNoTiers: () => isNoTiers,
|
|
70
|
+
isProvisioningError: () => isProvisioningError,
|
|
67
71
|
isPublishableKey: () => isPublishableKey,
|
|
68
72
|
mergeMetrics: () => mergeMetrics,
|
|
69
73
|
mergeTrace: () => mergeTrace,
|
|
@@ -100,7 +104,9 @@ var ErrorCodes = {
|
|
|
100
104
|
/** No tiers configured for the project - create a tier first. */
|
|
101
105
|
NO_TIERS: "NO_TIERS",
|
|
102
106
|
/** No free tier available for auto-provisioning - create a free tier or use checkout flow. */
|
|
103
|
-
NO_FREE_TIER: "NO_FREE_TIER"
|
|
107
|
+
NO_FREE_TIER: "NO_FREE_TIER",
|
|
108
|
+
/** Email required for auto-provisioning a new customer. */
|
|
109
|
+
EMAIL_REQUIRED: "EMAIL_REQUIRED"
|
|
104
110
|
};
|
|
105
111
|
var ModelRelayError = class extends Error {
|
|
106
112
|
constructor(message, opts) {
|
|
@@ -185,14 +191,33 @@ var APIError = class extends ModelRelayError {
|
|
|
185
191
|
return this.code === ErrorCodes.NO_FREE_TIER;
|
|
186
192
|
}
|
|
187
193
|
/**
|
|
188
|
-
* Returns true if
|
|
194
|
+
* Returns true if email is required for auto-provisioning a new customer.
|
|
195
|
+
* To resolve: provide the 'email' field in FrontendTokenRequest.
|
|
196
|
+
*/
|
|
197
|
+
isEmailRequired() {
|
|
198
|
+
return this.code === ErrorCodes.EMAIL_REQUIRED;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Returns true if this is a customer provisioning error (NO_TIERS, NO_FREE_TIER, or EMAIL_REQUIRED).
|
|
189
202
|
* These errors occur when calling frontendToken() with a customer that doesn't exist
|
|
190
203
|
* and automatic provisioning cannot complete.
|
|
191
204
|
*/
|
|
192
205
|
isProvisioningError() {
|
|
193
|
-
return this.isNoTiers() || this.isNoFreeTier();
|
|
206
|
+
return this.isNoTiers() || this.isNoFreeTier() || this.isEmailRequired();
|
|
194
207
|
}
|
|
195
208
|
};
|
|
209
|
+
function isEmailRequired(err) {
|
|
210
|
+
return err instanceof APIError && err.isEmailRequired();
|
|
211
|
+
}
|
|
212
|
+
function isNoFreeTier(err) {
|
|
213
|
+
return err instanceof APIError && err.isNoFreeTier();
|
|
214
|
+
}
|
|
215
|
+
function isNoTiers(err) {
|
|
216
|
+
return err instanceof APIError && err.isNoTiers();
|
|
217
|
+
}
|
|
218
|
+
function isProvisioningError(err) {
|
|
219
|
+
return err instanceof APIError && err.isProvisioningError();
|
|
220
|
+
}
|
|
196
221
|
async function parseErrorResponse(response, retries) {
|
|
197
222
|
const requestId = response.headers.get("X-ModelRelay-Chat-Request-Id") || response.headers.get("X-Request-Id") || void 0;
|
|
198
223
|
const fallbackMessage = response.statusText || "Request failed";
|
|
@@ -208,8 +233,8 @@ async function parseErrorResponse(response, retries) {
|
|
|
208
233
|
try {
|
|
209
234
|
const parsed = JSON.parse(bodyText);
|
|
210
235
|
const parsedObj = typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
211
|
-
if (parsedObj?.error) {
|
|
212
|
-
const errPayload =
|
|
236
|
+
if (parsedObj?.error && typeof parsedObj.error === "object") {
|
|
237
|
+
const errPayload = parsedObj.error;
|
|
213
238
|
const message = errPayload?.message || fallbackMessage;
|
|
214
239
|
const code = errPayload?.code || void 0;
|
|
215
240
|
const fields = Array.isArray(errPayload?.fields) ? errPayload?.fields : void 0;
|
|
@@ -261,20 +286,47 @@ var AuthClient = class {
|
|
|
261
286
|
this.customer = cfg.customer;
|
|
262
287
|
}
|
|
263
288
|
/**
|
|
264
|
-
* Exchange a publishable key for a short-lived frontend token.
|
|
289
|
+
* Exchange a publishable key for a short-lived frontend token for an existing customer.
|
|
265
290
|
* Tokens are cached until they are close to expiry.
|
|
291
|
+
*
|
|
292
|
+
* Use this method when the customer already exists in the system.
|
|
293
|
+
* For auto-provisioning new customers, use frontendTokenAutoProvision instead.
|
|
266
294
|
*/
|
|
267
295
|
async frontendToken(request) {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
296
|
+
if (!request.publishableKey?.trim()) {
|
|
297
|
+
throw new ConfigError("publishableKey is required");
|
|
298
|
+
}
|
|
299
|
+
if (!request.customerId?.trim()) {
|
|
300
|
+
throw new ConfigError("customerId is required");
|
|
301
|
+
}
|
|
302
|
+
return this.sendFrontendTokenRequest(request);
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Exchange a publishable key for a frontend token, creating the customer if needed.
|
|
306
|
+
* The customer will be auto-provisioned on the project's free tier.
|
|
307
|
+
* Tokens are cached until they are close to expiry.
|
|
308
|
+
*
|
|
309
|
+
* Use this method when the customer may not exist and should be created automatically.
|
|
310
|
+
* The email is required for auto-provisioning.
|
|
311
|
+
*/
|
|
312
|
+
async frontendTokenAutoProvision(request) {
|
|
313
|
+
if (!request.publishableKey?.trim()) {
|
|
314
|
+
throw new ConfigError("publishableKey is required");
|
|
315
|
+
}
|
|
316
|
+
if (!request.customerId?.trim()) {
|
|
317
|
+
throw new ConfigError("customerId is required");
|
|
271
318
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
throw new ConfigError("customerId is required to mint a frontend token");
|
|
319
|
+
if (!request.email?.trim()) {
|
|
320
|
+
throw new ConfigError("email is required for auto-provisioning");
|
|
275
321
|
}
|
|
276
|
-
|
|
277
|
-
|
|
322
|
+
return this.sendFrontendTokenRequest(request);
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Internal method to send frontend token requests.
|
|
326
|
+
*/
|
|
327
|
+
async sendFrontendTokenRequest(request) {
|
|
328
|
+
const { publishableKey, customerId, deviceId, ttlSeconds } = request;
|
|
329
|
+
const email = "email" in request ? request.email : void 0;
|
|
278
330
|
const cacheKey = `${publishableKey}:${customerId}:${deviceId || ""}`;
|
|
279
331
|
const cached = this.cachedFrontend.get(cacheKey);
|
|
280
332
|
if (cached && isTokenReusable(cached)) {
|
|
@@ -290,6 +342,9 @@ var AuthClient = class {
|
|
|
290
342
|
if (typeof ttlSeconds === "number" && ttlSeconds > 0) {
|
|
291
343
|
payload.ttl_seconds = ttlSeconds;
|
|
292
344
|
}
|
|
345
|
+
if (email) {
|
|
346
|
+
payload.email = email;
|
|
347
|
+
}
|
|
293
348
|
const response = await this.http.json(
|
|
294
349
|
"/auth/frontend-token",
|
|
295
350
|
{
|
|
@@ -317,10 +372,15 @@ var AuthClient = class {
|
|
|
317
372
|
throw new ConfigError("API key or token is required");
|
|
318
373
|
}
|
|
319
374
|
if (isPublishableKey(this.apiKey)) {
|
|
375
|
+
const resolvedCustomerId = customerId || overrides?.id || this.customer?.id;
|
|
376
|
+
if (!resolvedCustomerId) {
|
|
377
|
+
throw new ConfigError("customerId is required to mint a frontend token");
|
|
378
|
+
}
|
|
320
379
|
const token = await this.frontendToken({
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
380
|
+
publishableKey: this.apiKey,
|
|
381
|
+
customerId: resolvedCustomerId,
|
|
382
|
+
deviceId: overrides?.deviceId || this.customer?.deviceId,
|
|
383
|
+
ttlSeconds: overrides?.ttlSeconds ?? this.customer?.ttlSeconds
|
|
324
384
|
});
|
|
325
385
|
return createAccessTokenAuth(token.token);
|
|
326
386
|
}
|
|
@@ -374,7 +434,7 @@ function isTokenReusable(token) {
|
|
|
374
434
|
// package.json
|
|
375
435
|
var package_default = {
|
|
376
436
|
name: "@modelrelay/sdk",
|
|
377
|
-
version: "0.
|
|
437
|
+
version: "0.22.0",
|
|
378
438
|
description: "TypeScript SDK for the ModelRelay API",
|
|
379
439
|
type: "module",
|
|
380
440
|
main: "dist/index.cjs",
|
|
@@ -2538,6 +2598,10 @@ function resolveBaseUrl(override) {
|
|
|
2538
2598
|
getRetryableErrors,
|
|
2539
2599
|
hasRetryableErrors,
|
|
2540
2600
|
hasToolCalls,
|
|
2601
|
+
isEmailRequired,
|
|
2602
|
+
isNoFreeTier,
|
|
2603
|
+
isNoTiers,
|
|
2604
|
+
isProvisioningError,
|
|
2541
2605
|
isPublishableKey,
|
|
2542
2606
|
mergeMetrics,
|
|
2543
2607
|
mergeTrace,
|
package/dist/index.d.cts
CHANGED
|
@@ -180,10 +180,35 @@ interface FrontendCustomer {
|
|
|
180
180
|
deviceId?: string;
|
|
181
181
|
ttlSeconds?: number;
|
|
182
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* Request for fetching a frontend token for an existing customer.
|
|
185
|
+
* Use this when the customer already exists in the system.
|
|
186
|
+
*/
|
|
183
187
|
interface FrontendTokenRequest {
|
|
184
|
-
|
|
188
|
+
/** Publishable key (mr_pk_*) - required for authentication. */
|
|
189
|
+
publishableKey: string;
|
|
190
|
+
/** Customer identifier - required to issue a token for this customer. */
|
|
191
|
+
customerId: string;
|
|
192
|
+
/** Optional device identifier for tracking/rate limiting. */
|
|
193
|
+
deviceId?: string;
|
|
194
|
+
/** Optional TTL in seconds for the issued token. */
|
|
195
|
+
ttlSeconds?: number;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Request for fetching a frontend token with auto-provisioning.
|
|
199
|
+
* Use this when the customer may not exist and should be created on the free tier.
|
|
200
|
+
* The email is required for auto-provisioning.
|
|
201
|
+
*/
|
|
202
|
+
interface FrontendTokenAutoProvisionRequest {
|
|
203
|
+
/** Publishable key (mr_pk_*) - required for authentication. */
|
|
204
|
+
publishableKey: string;
|
|
205
|
+
/** Customer identifier - required to issue a token for this customer. */
|
|
185
206
|
customerId: string;
|
|
207
|
+
/** Email address - required for auto-provisioning a new customer. */
|
|
208
|
+
email: string;
|
|
209
|
+
/** Optional device identifier for tracking/rate limiting. */
|
|
186
210
|
deviceId?: string;
|
|
211
|
+
/** Optional TTL in seconds for the issued token. */
|
|
187
212
|
ttlSeconds?: number;
|
|
188
213
|
}
|
|
189
214
|
interface FrontendToken {
|
|
@@ -640,10 +665,26 @@ declare class AuthClient {
|
|
|
640
665
|
private cachedFrontend;
|
|
641
666
|
constructor(http: HTTPClient, cfg: AuthConfig);
|
|
642
667
|
/**
|
|
643
|
-
* Exchange a publishable key for a short-lived frontend token.
|
|
668
|
+
* Exchange a publishable key for a short-lived frontend token for an existing customer.
|
|
644
669
|
* Tokens are cached until they are close to expiry.
|
|
670
|
+
*
|
|
671
|
+
* Use this method when the customer already exists in the system.
|
|
672
|
+
* For auto-provisioning new customers, use frontendTokenAutoProvision instead.
|
|
645
673
|
*/
|
|
646
|
-
frontendToken(request
|
|
674
|
+
frontendToken(request: FrontendTokenRequest): Promise<FrontendToken>;
|
|
675
|
+
/**
|
|
676
|
+
* Exchange a publishable key for a frontend token, creating the customer if needed.
|
|
677
|
+
* The customer will be auto-provisioned on the project's free tier.
|
|
678
|
+
* Tokens are cached until they are close to expiry.
|
|
679
|
+
*
|
|
680
|
+
* Use this method when the customer may not exist and should be created automatically.
|
|
681
|
+
* The email is required for auto-provisioning.
|
|
682
|
+
*/
|
|
683
|
+
frontendTokenAutoProvision(request: FrontendTokenAutoProvisionRequest): Promise<FrontendToken>;
|
|
684
|
+
/**
|
|
685
|
+
* Internal method to send frontend token requests.
|
|
686
|
+
*/
|
|
687
|
+
private sendFrontendTokenRequest;
|
|
647
688
|
/**
|
|
648
689
|
* Determine the correct auth headers for chat completions.
|
|
649
690
|
* Publishable keys are automatically exchanged for frontend tokens.
|
|
@@ -981,6 +1022,8 @@ declare const ErrorCodes: {
|
|
|
981
1022
|
readonly NO_TIERS: "NO_TIERS";
|
|
982
1023
|
/** No free tier available for auto-provisioning - create a free tier or use checkout flow. */
|
|
983
1024
|
readonly NO_FREE_TIER: "NO_FREE_TIER";
|
|
1025
|
+
/** Email required for auto-provisioning a new customer. */
|
|
1026
|
+
readonly EMAIL_REQUIRED: "EMAIL_REQUIRED";
|
|
984
1027
|
};
|
|
985
1028
|
type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
|
|
986
1029
|
type ErrorCategory = "config" | "transport" | "api";
|
|
@@ -1048,12 +1091,33 @@ declare class APIError extends ModelRelayError {
|
|
|
1048
1091
|
*/
|
|
1049
1092
|
isNoFreeTier(): boolean;
|
|
1050
1093
|
/**
|
|
1051
|
-
* Returns true if
|
|
1094
|
+
* Returns true if email is required for auto-provisioning a new customer.
|
|
1095
|
+
* To resolve: provide the 'email' field in FrontendTokenRequest.
|
|
1096
|
+
*/
|
|
1097
|
+
isEmailRequired(): boolean;
|
|
1098
|
+
/**
|
|
1099
|
+
* Returns true if this is a customer provisioning error (NO_TIERS, NO_FREE_TIER, or EMAIL_REQUIRED).
|
|
1052
1100
|
* These errors occur when calling frontendToken() with a customer that doesn't exist
|
|
1053
1101
|
* and automatic provisioning cannot complete.
|
|
1054
1102
|
*/
|
|
1055
1103
|
isProvisioningError(): boolean;
|
|
1056
1104
|
}
|
|
1105
|
+
/**
|
|
1106
|
+
* Returns true if the error indicates email is required for auto-provisioning.
|
|
1107
|
+
*/
|
|
1108
|
+
declare function isEmailRequired(err: unknown): boolean;
|
|
1109
|
+
/**
|
|
1110
|
+
* Returns true if the error indicates no free tier is available.
|
|
1111
|
+
*/
|
|
1112
|
+
declare function isNoFreeTier(err: unknown): boolean;
|
|
1113
|
+
/**
|
|
1114
|
+
* Returns true if the error indicates no tiers are configured.
|
|
1115
|
+
*/
|
|
1116
|
+
declare function isNoTiers(err: unknown): boolean;
|
|
1117
|
+
/**
|
|
1118
|
+
* Returns true if the error is a customer provisioning error.
|
|
1119
|
+
*/
|
|
1120
|
+
declare function isProvisioningError(err: unknown): boolean;
|
|
1057
1121
|
declare function parseErrorResponse(response: Response, retries?: RetryMetadata): Promise<APIError>;
|
|
1058
1122
|
|
|
1059
1123
|
/**
|
|
@@ -1482,4 +1546,4 @@ declare class ModelRelay {
|
|
|
1482
1546
|
constructor(options: ModelRelayOptions);
|
|
1483
1547
|
}
|
|
1484
1548
|
|
|
1485
|
-
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 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 FrontendTokenRequest, type FunctionCall, type FunctionCallDelta, type FunctionTool, type HttpRequestMetrics, type JsonSchemaOptions, type KnownStopReason, type MessageDeltaData, 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 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, isPublishableKey, mergeMetrics, mergeTrace, modelToString, normalizeModelId, normalizeStopReason, parseErrorResponse, parseToolArgs, parseToolArgsRaw, respondToToolCall, stopReasonToString, toolChoiceAuto, toolChoiceNone, toolChoiceRequired, toolResultMessage, tryParseToolArgs, zodToJsonSchema };
|
|
1549
|
+
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 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 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 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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -180,10 +180,35 @@ interface FrontendCustomer {
|
|
|
180
180
|
deviceId?: string;
|
|
181
181
|
ttlSeconds?: number;
|
|
182
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* Request for fetching a frontend token for an existing customer.
|
|
185
|
+
* Use this when the customer already exists in the system.
|
|
186
|
+
*/
|
|
183
187
|
interface FrontendTokenRequest {
|
|
184
|
-
|
|
188
|
+
/** Publishable key (mr_pk_*) - required for authentication. */
|
|
189
|
+
publishableKey: string;
|
|
190
|
+
/** Customer identifier - required to issue a token for this customer. */
|
|
191
|
+
customerId: string;
|
|
192
|
+
/** Optional device identifier for tracking/rate limiting. */
|
|
193
|
+
deviceId?: string;
|
|
194
|
+
/** Optional TTL in seconds for the issued token. */
|
|
195
|
+
ttlSeconds?: number;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Request for fetching a frontend token with auto-provisioning.
|
|
199
|
+
* Use this when the customer may not exist and should be created on the free tier.
|
|
200
|
+
* The email is required for auto-provisioning.
|
|
201
|
+
*/
|
|
202
|
+
interface FrontendTokenAutoProvisionRequest {
|
|
203
|
+
/** Publishable key (mr_pk_*) - required for authentication. */
|
|
204
|
+
publishableKey: string;
|
|
205
|
+
/** Customer identifier - required to issue a token for this customer. */
|
|
185
206
|
customerId: string;
|
|
207
|
+
/** Email address - required for auto-provisioning a new customer. */
|
|
208
|
+
email: string;
|
|
209
|
+
/** Optional device identifier for tracking/rate limiting. */
|
|
186
210
|
deviceId?: string;
|
|
211
|
+
/** Optional TTL in seconds for the issued token. */
|
|
187
212
|
ttlSeconds?: number;
|
|
188
213
|
}
|
|
189
214
|
interface FrontendToken {
|
|
@@ -640,10 +665,26 @@ declare class AuthClient {
|
|
|
640
665
|
private cachedFrontend;
|
|
641
666
|
constructor(http: HTTPClient, cfg: AuthConfig);
|
|
642
667
|
/**
|
|
643
|
-
* Exchange a publishable key for a short-lived frontend token.
|
|
668
|
+
* Exchange a publishable key for a short-lived frontend token for an existing customer.
|
|
644
669
|
* Tokens are cached until they are close to expiry.
|
|
670
|
+
*
|
|
671
|
+
* Use this method when the customer already exists in the system.
|
|
672
|
+
* For auto-provisioning new customers, use frontendTokenAutoProvision instead.
|
|
645
673
|
*/
|
|
646
|
-
frontendToken(request
|
|
674
|
+
frontendToken(request: FrontendTokenRequest): Promise<FrontendToken>;
|
|
675
|
+
/**
|
|
676
|
+
* Exchange a publishable key for a frontend token, creating the customer if needed.
|
|
677
|
+
* The customer will be auto-provisioned on the project's free tier.
|
|
678
|
+
* Tokens are cached until they are close to expiry.
|
|
679
|
+
*
|
|
680
|
+
* Use this method when the customer may not exist and should be created automatically.
|
|
681
|
+
* The email is required for auto-provisioning.
|
|
682
|
+
*/
|
|
683
|
+
frontendTokenAutoProvision(request: FrontendTokenAutoProvisionRequest): Promise<FrontendToken>;
|
|
684
|
+
/**
|
|
685
|
+
* Internal method to send frontend token requests.
|
|
686
|
+
*/
|
|
687
|
+
private sendFrontendTokenRequest;
|
|
647
688
|
/**
|
|
648
689
|
* Determine the correct auth headers for chat completions.
|
|
649
690
|
* Publishable keys are automatically exchanged for frontend tokens.
|
|
@@ -981,6 +1022,8 @@ declare const ErrorCodes: {
|
|
|
981
1022
|
readonly NO_TIERS: "NO_TIERS";
|
|
982
1023
|
/** No free tier available for auto-provisioning - create a free tier or use checkout flow. */
|
|
983
1024
|
readonly NO_FREE_TIER: "NO_FREE_TIER";
|
|
1025
|
+
/** Email required for auto-provisioning a new customer. */
|
|
1026
|
+
readonly EMAIL_REQUIRED: "EMAIL_REQUIRED";
|
|
984
1027
|
};
|
|
985
1028
|
type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
|
|
986
1029
|
type ErrorCategory = "config" | "transport" | "api";
|
|
@@ -1048,12 +1091,33 @@ declare class APIError extends ModelRelayError {
|
|
|
1048
1091
|
*/
|
|
1049
1092
|
isNoFreeTier(): boolean;
|
|
1050
1093
|
/**
|
|
1051
|
-
* Returns true if
|
|
1094
|
+
* Returns true if email is required for auto-provisioning a new customer.
|
|
1095
|
+
* To resolve: provide the 'email' field in FrontendTokenRequest.
|
|
1096
|
+
*/
|
|
1097
|
+
isEmailRequired(): boolean;
|
|
1098
|
+
/**
|
|
1099
|
+
* Returns true if this is a customer provisioning error (NO_TIERS, NO_FREE_TIER, or EMAIL_REQUIRED).
|
|
1052
1100
|
* These errors occur when calling frontendToken() with a customer that doesn't exist
|
|
1053
1101
|
* and automatic provisioning cannot complete.
|
|
1054
1102
|
*/
|
|
1055
1103
|
isProvisioningError(): boolean;
|
|
1056
1104
|
}
|
|
1105
|
+
/**
|
|
1106
|
+
* Returns true if the error indicates email is required for auto-provisioning.
|
|
1107
|
+
*/
|
|
1108
|
+
declare function isEmailRequired(err: unknown): boolean;
|
|
1109
|
+
/**
|
|
1110
|
+
* Returns true if the error indicates no free tier is available.
|
|
1111
|
+
*/
|
|
1112
|
+
declare function isNoFreeTier(err: unknown): boolean;
|
|
1113
|
+
/**
|
|
1114
|
+
* Returns true if the error indicates no tiers are configured.
|
|
1115
|
+
*/
|
|
1116
|
+
declare function isNoTiers(err: unknown): boolean;
|
|
1117
|
+
/**
|
|
1118
|
+
* Returns true if the error is a customer provisioning error.
|
|
1119
|
+
*/
|
|
1120
|
+
declare function isProvisioningError(err: unknown): boolean;
|
|
1057
1121
|
declare function parseErrorResponse(response: Response, retries?: RetryMetadata): Promise<APIError>;
|
|
1058
1122
|
|
|
1059
1123
|
/**
|
|
@@ -1482,4 +1546,4 @@ declare class ModelRelay {
|
|
|
1482
1546
|
constructor(options: ModelRelayOptions);
|
|
1483
1547
|
}
|
|
1484
1548
|
|
|
1485
|
-
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 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 FrontendTokenRequest, type FunctionCall, type FunctionCallDelta, type FunctionTool, type HttpRequestMetrics, type JsonSchemaOptions, type KnownStopReason, type MessageDeltaData, 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 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, isPublishableKey, mergeMetrics, mergeTrace, modelToString, normalizeModelId, normalizeStopReason, parseErrorResponse, parseToolArgs, parseToolArgsRaw, respondToToolCall, stopReasonToString, toolChoiceAuto, toolChoiceNone, toolChoiceRequired, toolResultMessage, tryParseToolArgs, zodToJsonSchema };
|
|
1549
|
+
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 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 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 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 };
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,9 @@ var ErrorCodes = {
|
|
|
14
14
|
/** No tiers configured for the project - create a tier first. */
|
|
15
15
|
NO_TIERS: "NO_TIERS",
|
|
16
16
|
/** No free tier available for auto-provisioning - create a free tier or use checkout flow. */
|
|
17
|
-
NO_FREE_TIER: "NO_FREE_TIER"
|
|
17
|
+
NO_FREE_TIER: "NO_FREE_TIER",
|
|
18
|
+
/** Email required for auto-provisioning a new customer. */
|
|
19
|
+
EMAIL_REQUIRED: "EMAIL_REQUIRED"
|
|
18
20
|
};
|
|
19
21
|
var ModelRelayError = class extends Error {
|
|
20
22
|
constructor(message, opts) {
|
|
@@ -99,14 +101,33 @@ var APIError = class extends ModelRelayError {
|
|
|
99
101
|
return this.code === ErrorCodes.NO_FREE_TIER;
|
|
100
102
|
}
|
|
101
103
|
/**
|
|
102
|
-
* Returns true if
|
|
104
|
+
* Returns true if email is required for auto-provisioning a new customer.
|
|
105
|
+
* To resolve: provide the 'email' field in FrontendTokenRequest.
|
|
106
|
+
*/
|
|
107
|
+
isEmailRequired() {
|
|
108
|
+
return this.code === ErrorCodes.EMAIL_REQUIRED;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Returns true if this is a customer provisioning error (NO_TIERS, NO_FREE_TIER, or EMAIL_REQUIRED).
|
|
103
112
|
* These errors occur when calling frontendToken() with a customer that doesn't exist
|
|
104
113
|
* and automatic provisioning cannot complete.
|
|
105
114
|
*/
|
|
106
115
|
isProvisioningError() {
|
|
107
|
-
return this.isNoTiers() || this.isNoFreeTier();
|
|
116
|
+
return this.isNoTiers() || this.isNoFreeTier() || this.isEmailRequired();
|
|
108
117
|
}
|
|
109
118
|
};
|
|
119
|
+
function isEmailRequired(err) {
|
|
120
|
+
return err instanceof APIError && err.isEmailRequired();
|
|
121
|
+
}
|
|
122
|
+
function isNoFreeTier(err) {
|
|
123
|
+
return err instanceof APIError && err.isNoFreeTier();
|
|
124
|
+
}
|
|
125
|
+
function isNoTiers(err) {
|
|
126
|
+
return err instanceof APIError && err.isNoTiers();
|
|
127
|
+
}
|
|
128
|
+
function isProvisioningError(err) {
|
|
129
|
+
return err instanceof APIError && err.isProvisioningError();
|
|
130
|
+
}
|
|
110
131
|
async function parseErrorResponse(response, retries) {
|
|
111
132
|
const requestId = response.headers.get("X-ModelRelay-Chat-Request-Id") || response.headers.get("X-Request-Id") || void 0;
|
|
112
133
|
const fallbackMessage = response.statusText || "Request failed";
|
|
@@ -122,8 +143,8 @@ async function parseErrorResponse(response, retries) {
|
|
|
122
143
|
try {
|
|
123
144
|
const parsed = JSON.parse(bodyText);
|
|
124
145
|
const parsedObj = typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
125
|
-
if (parsedObj?.error) {
|
|
126
|
-
const errPayload =
|
|
146
|
+
if (parsedObj?.error && typeof parsedObj.error === "object") {
|
|
147
|
+
const errPayload = parsedObj.error;
|
|
127
148
|
const message = errPayload?.message || fallbackMessage;
|
|
128
149
|
const code = errPayload?.code || void 0;
|
|
129
150
|
const fields = Array.isArray(errPayload?.fields) ? errPayload?.fields : void 0;
|
|
@@ -175,20 +196,47 @@ var AuthClient = class {
|
|
|
175
196
|
this.customer = cfg.customer;
|
|
176
197
|
}
|
|
177
198
|
/**
|
|
178
|
-
* Exchange a publishable key for a short-lived frontend token.
|
|
199
|
+
* Exchange a publishable key for a short-lived frontend token for an existing customer.
|
|
179
200
|
* Tokens are cached until they are close to expiry.
|
|
201
|
+
*
|
|
202
|
+
* Use this method when the customer already exists in the system.
|
|
203
|
+
* For auto-provisioning new customers, use frontendTokenAutoProvision instead.
|
|
180
204
|
*/
|
|
181
205
|
async frontendToken(request) {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
206
|
+
if (!request.publishableKey?.trim()) {
|
|
207
|
+
throw new ConfigError("publishableKey is required");
|
|
208
|
+
}
|
|
209
|
+
if (!request.customerId?.trim()) {
|
|
210
|
+
throw new ConfigError("customerId is required");
|
|
211
|
+
}
|
|
212
|
+
return this.sendFrontendTokenRequest(request);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Exchange a publishable key for a frontend token, creating the customer if needed.
|
|
216
|
+
* The customer will be auto-provisioned on the project's free tier.
|
|
217
|
+
* Tokens are cached until they are close to expiry.
|
|
218
|
+
*
|
|
219
|
+
* Use this method when the customer may not exist and should be created automatically.
|
|
220
|
+
* The email is required for auto-provisioning.
|
|
221
|
+
*/
|
|
222
|
+
async frontendTokenAutoProvision(request) {
|
|
223
|
+
if (!request.publishableKey?.trim()) {
|
|
224
|
+
throw new ConfigError("publishableKey is required");
|
|
225
|
+
}
|
|
226
|
+
if (!request.customerId?.trim()) {
|
|
227
|
+
throw new ConfigError("customerId is required");
|
|
185
228
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
throw new ConfigError("customerId is required to mint a frontend token");
|
|
229
|
+
if (!request.email?.trim()) {
|
|
230
|
+
throw new ConfigError("email is required for auto-provisioning");
|
|
189
231
|
}
|
|
190
|
-
|
|
191
|
-
|
|
232
|
+
return this.sendFrontendTokenRequest(request);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Internal method to send frontend token requests.
|
|
236
|
+
*/
|
|
237
|
+
async sendFrontendTokenRequest(request) {
|
|
238
|
+
const { publishableKey, customerId, deviceId, ttlSeconds } = request;
|
|
239
|
+
const email = "email" in request ? request.email : void 0;
|
|
192
240
|
const cacheKey = `${publishableKey}:${customerId}:${deviceId || ""}`;
|
|
193
241
|
const cached = this.cachedFrontend.get(cacheKey);
|
|
194
242
|
if (cached && isTokenReusable(cached)) {
|
|
@@ -204,6 +252,9 @@ var AuthClient = class {
|
|
|
204
252
|
if (typeof ttlSeconds === "number" && ttlSeconds > 0) {
|
|
205
253
|
payload.ttl_seconds = ttlSeconds;
|
|
206
254
|
}
|
|
255
|
+
if (email) {
|
|
256
|
+
payload.email = email;
|
|
257
|
+
}
|
|
207
258
|
const response = await this.http.json(
|
|
208
259
|
"/auth/frontend-token",
|
|
209
260
|
{
|
|
@@ -231,10 +282,15 @@ var AuthClient = class {
|
|
|
231
282
|
throw new ConfigError("API key or token is required");
|
|
232
283
|
}
|
|
233
284
|
if (isPublishableKey(this.apiKey)) {
|
|
285
|
+
const resolvedCustomerId = customerId || overrides?.id || this.customer?.id;
|
|
286
|
+
if (!resolvedCustomerId) {
|
|
287
|
+
throw new ConfigError("customerId is required to mint a frontend token");
|
|
288
|
+
}
|
|
234
289
|
const token = await this.frontendToken({
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
290
|
+
publishableKey: this.apiKey,
|
|
291
|
+
customerId: resolvedCustomerId,
|
|
292
|
+
deviceId: overrides?.deviceId || this.customer?.deviceId,
|
|
293
|
+
ttlSeconds: overrides?.ttlSeconds ?? this.customer?.ttlSeconds
|
|
238
294
|
});
|
|
239
295
|
return createAccessTokenAuth(token.token);
|
|
240
296
|
}
|
|
@@ -288,7 +344,7 @@ function isTokenReusable(token) {
|
|
|
288
344
|
// package.json
|
|
289
345
|
var package_default = {
|
|
290
346
|
name: "@modelrelay/sdk",
|
|
291
|
-
version: "0.
|
|
347
|
+
version: "0.22.0",
|
|
292
348
|
description: "TypeScript SDK for the ModelRelay API",
|
|
293
349
|
type: "module",
|
|
294
350
|
main: "dist/index.cjs",
|
|
@@ -2451,6 +2507,10 @@ export {
|
|
|
2451
2507
|
getRetryableErrors,
|
|
2452
2508
|
hasRetryableErrors,
|
|
2453
2509
|
hasToolCalls,
|
|
2510
|
+
isEmailRequired,
|
|
2511
|
+
isNoFreeTier,
|
|
2512
|
+
isNoTiers,
|
|
2513
|
+
isProvisioningError,
|
|
2454
2514
|
isPublishableKey,
|
|
2455
2515
|
mergeMetrics,
|
|
2456
2516
|
mergeTrace,
|