@modelrelay/sdk 0.4.0 → 0.7.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 +851 -33
- package/dist/index.d.cts +626 -12
- package/dist/index.d.ts +626 -12
- package/dist/index.js +824 -30
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -218,7 +218,7 @@ function isTokenReusable(token) {
|
|
|
218
218
|
// package.json
|
|
219
219
|
var package_default = {
|
|
220
220
|
name: "@modelrelay/sdk",
|
|
221
|
-
version: "0.
|
|
221
|
+
version: "0.7.0",
|
|
222
222
|
description: "TypeScript SDK for the ModelRelay API",
|
|
223
223
|
type: "module",
|
|
224
224
|
main: "dist/index.cjs",
|
|
@@ -252,15 +252,14 @@ var package_default = {
|
|
|
252
252
|
devDependencies: {
|
|
253
253
|
tsup: "^8.2.4",
|
|
254
254
|
typescript: "^5.6.3",
|
|
255
|
-
vitest: "^2.1.4"
|
|
255
|
+
vitest: "^2.1.4",
|
|
256
|
+
zod: "^3.23.0"
|
|
256
257
|
}
|
|
257
258
|
};
|
|
258
259
|
|
|
259
260
|
// src/types.ts
|
|
260
261
|
var SDK_VERSION = package_default.version || "0.0.0";
|
|
261
262
|
var DEFAULT_BASE_URL = "https://api.modelrelay.ai/api/v1";
|
|
262
|
-
var STAGING_BASE_URL = "https://api-stg.modelrelay.ai/api/v1";
|
|
263
|
-
var SANDBOX_BASE_URL = "https://api.sandbox.modelrelay.ai/api/v1";
|
|
264
263
|
var DEFAULT_CLIENT_HEADER = `modelrelay-ts/${SDK_VERSION}`;
|
|
265
264
|
var DEFAULT_CONNECT_TIMEOUT_MS = 5e3;
|
|
266
265
|
var DEFAULT_REQUEST_TIMEOUT_MS = 6e4;
|
|
@@ -282,7 +281,6 @@ var Providers = {
|
|
|
282
281
|
OpenAI: "openai",
|
|
283
282
|
Anthropic: "anthropic",
|
|
284
283
|
Grok: "grok",
|
|
285
|
-
OpenRouter: "openrouter",
|
|
286
284
|
Echo: "echo"
|
|
287
285
|
};
|
|
288
286
|
var Models = {
|
|
@@ -292,11 +290,23 @@ var Models = {
|
|
|
292
290
|
AnthropicClaude35HaikuLatest: "anthropic/claude-3-5-haiku-latest",
|
|
293
291
|
AnthropicClaude35SonnetLatest: "anthropic/claude-3-5-sonnet-latest",
|
|
294
292
|
AnthropicClaudeOpus45: "anthropic/claude-opus-4-5-20251101",
|
|
295
|
-
|
|
293
|
+
AnthropicClaude35Haiku: "anthropic/claude-3.5-haiku",
|
|
296
294
|
Grok2: "grok-2",
|
|
297
|
-
|
|
295
|
+
Grok4_1FastNonReasoning: "grok-4-1-fast-non-reasoning",
|
|
296
|
+
Grok4_1FastReasoning: "grok-4-1-fast-reasoning",
|
|
298
297
|
Echo1: "echo-1"
|
|
299
298
|
};
|
|
299
|
+
var ToolTypes = {
|
|
300
|
+
Function: "function",
|
|
301
|
+
WebSearch: "web_search",
|
|
302
|
+
XSearch: "x_search",
|
|
303
|
+
CodeExecution: "code_execution"
|
|
304
|
+
};
|
|
305
|
+
var ToolChoiceTypes = {
|
|
306
|
+
Auto: "auto",
|
|
307
|
+
Required: "required",
|
|
308
|
+
None: "none"
|
|
309
|
+
};
|
|
300
310
|
function mergeMetrics(base, override) {
|
|
301
311
|
if (!base && !override) return void 0;
|
|
302
312
|
return {
|
|
@@ -533,7 +543,7 @@ var ChatCompletionsStream = class {
|
|
|
533
543
|
const context = this.enrichContext(evt);
|
|
534
544
|
this.context = context;
|
|
535
545
|
this.trace?.streamEvent?.({ context, event: evt });
|
|
536
|
-
if (evt.type === "message_start" || evt.type === "message_delta" || evt.type === "message_stop") {
|
|
546
|
+
if (evt.type === "message_start" || evt.type === "message_delta" || evt.type === "message_stop" || evt.type === "tool_use_start" || evt.type === "tool_use_delta" || evt.type === "tool_use_stop") {
|
|
537
547
|
this.recordFirstToken();
|
|
538
548
|
}
|
|
539
549
|
if (evt.type === "message_stop" && evt.usage && this.metrics?.usage) {
|
|
@@ -618,11 +628,15 @@ function mapChatEvent(raw, requestId) {
|
|
|
618
628
|
const model = normalizeModelId(p.model || p?.message?.model);
|
|
619
629
|
const stopReason = normalizeStopReason(p.stop_reason);
|
|
620
630
|
const textDelta = extractTextDelta(p);
|
|
631
|
+
const toolCallDelta = extractToolCallDelta(p, type);
|
|
632
|
+
const toolCalls = extractToolCalls(p, type);
|
|
621
633
|
return {
|
|
622
634
|
type,
|
|
623
635
|
event: raw.event || type,
|
|
624
636
|
data: p,
|
|
625
637
|
textDelta,
|
|
638
|
+
toolCallDelta,
|
|
639
|
+
toolCalls,
|
|
626
640
|
responseId,
|
|
627
641
|
model,
|
|
628
642
|
stopReason,
|
|
@@ -642,6 +656,12 @@ function normalizeEventType(eventName, payload) {
|
|
|
642
656
|
return "message_delta";
|
|
643
657
|
case "message_stop":
|
|
644
658
|
return "message_stop";
|
|
659
|
+
case "tool_use_start":
|
|
660
|
+
return "tool_use_start";
|
|
661
|
+
case "tool_use_delta":
|
|
662
|
+
return "tool_use_delta";
|
|
663
|
+
case "tool_use_stop":
|
|
664
|
+
return "tool_use_stop";
|
|
645
665
|
case "ping":
|
|
646
666
|
return "ping";
|
|
647
667
|
default:
|
|
@@ -652,6 +672,9 @@ function extractTextDelta(payload) {
|
|
|
652
672
|
if (!payload || typeof payload !== "object") {
|
|
653
673
|
return void 0;
|
|
654
674
|
}
|
|
675
|
+
if (typeof payload.text_delta === "string" && payload.text_delta !== "") {
|
|
676
|
+
return payload.text_delta;
|
|
677
|
+
}
|
|
655
678
|
if (typeof payload.delta === "string") {
|
|
656
679
|
return payload.delta;
|
|
657
680
|
}
|
|
@@ -665,9 +688,56 @@ function extractTextDelta(payload) {
|
|
|
665
688
|
}
|
|
666
689
|
return void 0;
|
|
667
690
|
}
|
|
691
|
+
function extractToolCallDelta(payload, type) {
|
|
692
|
+
if (!payload || typeof payload !== "object") {
|
|
693
|
+
return void 0;
|
|
694
|
+
}
|
|
695
|
+
if (type !== "tool_use_start" && type !== "tool_use_delta") {
|
|
696
|
+
return void 0;
|
|
697
|
+
}
|
|
698
|
+
if (payload.tool_call_delta) {
|
|
699
|
+
const d = payload.tool_call_delta;
|
|
700
|
+
return {
|
|
701
|
+
index: d.index ?? 0,
|
|
702
|
+
id: d.id,
|
|
703
|
+
type: d.type,
|
|
704
|
+
function: d.function ? {
|
|
705
|
+
name: d.function.name,
|
|
706
|
+
arguments: d.function.arguments
|
|
707
|
+
} : void 0
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
if (typeof payload.index === "number" || payload.id || payload.name) {
|
|
711
|
+
return {
|
|
712
|
+
index: payload.index ?? 0,
|
|
713
|
+
id: payload.id,
|
|
714
|
+
type: payload.tool_type,
|
|
715
|
+
function: payload.name || payload.arguments ? {
|
|
716
|
+
name: payload.name,
|
|
717
|
+
arguments: payload.arguments
|
|
718
|
+
} : void 0
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
return void 0;
|
|
722
|
+
}
|
|
723
|
+
function extractToolCalls(payload, type) {
|
|
724
|
+
if (!payload || typeof payload !== "object") {
|
|
725
|
+
return void 0;
|
|
726
|
+
}
|
|
727
|
+
if (type !== "tool_use_stop" && type !== "message_stop") {
|
|
728
|
+
return void 0;
|
|
729
|
+
}
|
|
730
|
+
if (payload.tool_calls?.length) {
|
|
731
|
+
return normalizeToolCalls(payload.tool_calls);
|
|
732
|
+
}
|
|
733
|
+
if (payload.tool_call) {
|
|
734
|
+
return normalizeToolCalls([payload.tool_call]);
|
|
735
|
+
}
|
|
736
|
+
return void 0;
|
|
737
|
+
}
|
|
668
738
|
function normalizeChatResponse(payload, requestId) {
|
|
669
739
|
const p = payload;
|
|
670
|
-
|
|
740
|
+
const response = {
|
|
671
741
|
id: p?.id,
|
|
672
742
|
provider: normalizeProvider(p?.provider),
|
|
673
743
|
content: Array.isArray(p?.content) ? p.content : p?.content ? [String(p.content)] : [],
|
|
@@ -676,6 +746,17 @@ function normalizeChatResponse(payload, requestId) {
|
|
|
676
746
|
usage: normalizeUsage(p?.usage),
|
|
677
747
|
requestId
|
|
678
748
|
};
|
|
749
|
+
if (p?.tool_calls?.length) {
|
|
750
|
+
response.toolCalls = normalizeToolCalls(p.tool_calls);
|
|
751
|
+
}
|
|
752
|
+
return response;
|
|
753
|
+
}
|
|
754
|
+
function normalizeToolCalls(toolCalls) {
|
|
755
|
+
return toolCalls.map((tc) => ({
|
|
756
|
+
id: tc.id,
|
|
757
|
+
type: tc.type || ToolTypes.Function,
|
|
758
|
+
function: tc.function ? { name: tc.function.name, arguments: tc.function.arguments } : void 0
|
|
759
|
+
}));
|
|
679
760
|
}
|
|
680
761
|
function normalizeUsage(payload) {
|
|
681
762
|
if (!payload) {
|
|
@@ -703,13 +784,65 @@ function buildProxyBody(params, metadata) {
|
|
|
703
784
|
if (metadata && Object.keys(metadata).length > 0) body.metadata = metadata;
|
|
704
785
|
if (params.stop?.length) body.stop = params.stop;
|
|
705
786
|
if (params.stopSequences?.length) body.stop_sequences = params.stopSequences;
|
|
787
|
+
if (params.tools?.length) body.tools = normalizeTools(params.tools);
|
|
788
|
+
if (params.toolChoice) body.tool_choice = normalizeToolChoice(params.toolChoice);
|
|
706
789
|
return body;
|
|
707
790
|
}
|
|
708
791
|
function normalizeMessages(messages) {
|
|
709
|
-
return messages.map((msg) =>
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
792
|
+
return messages.map((msg) => {
|
|
793
|
+
const normalized = {
|
|
794
|
+
role: msg.role || "user",
|
|
795
|
+
content: msg.content
|
|
796
|
+
};
|
|
797
|
+
if (msg.toolCalls?.length) {
|
|
798
|
+
normalized.tool_calls = msg.toolCalls.map((tc) => ({
|
|
799
|
+
id: tc.id,
|
|
800
|
+
type: tc.type,
|
|
801
|
+
function: tc.function ? { name: tc.function.name, arguments: tc.function.arguments } : void 0
|
|
802
|
+
}));
|
|
803
|
+
}
|
|
804
|
+
if (msg.toolCallId) {
|
|
805
|
+
normalized.tool_call_id = msg.toolCallId;
|
|
806
|
+
}
|
|
807
|
+
return normalized;
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
function normalizeTools(tools) {
|
|
811
|
+
return tools.map((tool) => {
|
|
812
|
+
const normalized = { type: tool.type };
|
|
813
|
+
if (tool.function) {
|
|
814
|
+
normalized.function = {
|
|
815
|
+
name: tool.function.name,
|
|
816
|
+
description: tool.function.description,
|
|
817
|
+
parameters: tool.function.parameters
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
if (tool.webSearch) {
|
|
821
|
+
normalized.web_search = {
|
|
822
|
+
allowed_domains: tool.webSearch.allowedDomains,
|
|
823
|
+
excluded_domains: tool.webSearch.excludedDomains,
|
|
824
|
+
max_uses: tool.webSearch.maxUses
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
if (tool.xSearch) {
|
|
828
|
+
normalized.x_search = {
|
|
829
|
+
allowed_handles: tool.xSearch.allowedHandles,
|
|
830
|
+
excluded_handles: tool.xSearch.excludedHandles,
|
|
831
|
+
from_date: tool.xSearch.fromDate,
|
|
832
|
+
to_date: tool.xSearch.toDate
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
if (tool.codeExecution) {
|
|
836
|
+
normalized.code_execution = {
|
|
837
|
+
language: tool.codeExecution.language,
|
|
838
|
+
timeout_ms: tool.codeExecution.timeoutMs
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
return normalized;
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
function normalizeToolChoice(tc) {
|
|
845
|
+
return { type: tc.type };
|
|
713
846
|
}
|
|
714
847
|
function requestIdFromHeaders(headers) {
|
|
715
848
|
return headers.get(REQUEST_ID_HEADER) || headers.get("X-Request-Id") || void 0;
|
|
@@ -863,13 +996,50 @@ var CustomersClient = class {
|
|
|
863
996
|
}
|
|
864
997
|
};
|
|
865
998
|
|
|
999
|
+
// src/tiers.ts
|
|
1000
|
+
var TiersClient = class {
|
|
1001
|
+
constructor(http, cfg) {
|
|
1002
|
+
this.http = http;
|
|
1003
|
+
this.apiKey = cfg.apiKey;
|
|
1004
|
+
}
|
|
1005
|
+
ensureApiKey() {
|
|
1006
|
+
if (!this.apiKey || !this.apiKey.startsWith("mr_pk_") && !this.apiKey.startsWith("mr_sk_")) {
|
|
1007
|
+
throw new ConfigError(
|
|
1008
|
+
"API key (mr_pk_* or mr_sk_*) required for tier operations"
|
|
1009
|
+
);
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
/**
|
|
1013
|
+
* List all tiers in the project.
|
|
1014
|
+
*/
|
|
1015
|
+
async list() {
|
|
1016
|
+
this.ensureApiKey();
|
|
1017
|
+
const response = await this.http.json("/tiers", {
|
|
1018
|
+
method: "GET",
|
|
1019
|
+
apiKey: this.apiKey
|
|
1020
|
+
});
|
|
1021
|
+
return response.tiers;
|
|
1022
|
+
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Get a tier by ID.
|
|
1025
|
+
*/
|
|
1026
|
+
async get(tierId) {
|
|
1027
|
+
this.ensureApiKey();
|
|
1028
|
+
if (!tierId?.trim()) {
|
|
1029
|
+
throw new ConfigError("tierId is required");
|
|
1030
|
+
}
|
|
1031
|
+
const response = await this.http.json(`/tiers/${tierId}`, {
|
|
1032
|
+
method: "GET",
|
|
1033
|
+
apiKey: this.apiKey
|
|
1034
|
+
});
|
|
1035
|
+
return response.tier;
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
|
|
866
1039
|
// src/http.ts
|
|
867
1040
|
var HTTPClient = class {
|
|
868
1041
|
constructor(cfg) {
|
|
869
|
-
const
|
|
870
|
-
const resolvedBase = normalizeBaseUrl(
|
|
871
|
-
cfg.baseUrl || baseFromEnv || DEFAULT_BASE_URL
|
|
872
|
-
);
|
|
1042
|
+
const resolvedBase = normalizeBaseUrl(cfg.baseUrl || DEFAULT_BASE_URL);
|
|
873
1043
|
if (!isValidHttpUrl(resolvedBase)) {
|
|
874
1044
|
throw new ConfigError(
|
|
875
1045
|
"baseUrl must start with http:// or https://"
|
|
@@ -1082,12 +1252,6 @@ function normalizeBaseUrl(value) {
|
|
|
1082
1252
|
function isValidHttpUrl(value) {
|
|
1083
1253
|
return /^https?:\/\//i.test(value);
|
|
1084
1254
|
}
|
|
1085
|
-
function baseUrlForEnvironment(env) {
|
|
1086
|
-
if (!env || env === "production") return void 0;
|
|
1087
|
-
if (env === "staging") return STAGING_BASE_URL;
|
|
1088
|
-
if (env === "sandbox") return SANDBOX_BASE_URL;
|
|
1089
|
-
return void 0;
|
|
1090
|
-
}
|
|
1091
1255
|
function normalizeRetryConfig(retry) {
|
|
1092
1256
|
if (retry === false) return void 0;
|
|
1093
1257
|
const cfg = retry || {};
|
|
@@ -1199,6 +1363,610 @@ function withRequestId(context, headers) {
|
|
|
1199
1363
|
return { ...context, requestId };
|
|
1200
1364
|
}
|
|
1201
1365
|
|
|
1366
|
+
// src/tools.ts
|
|
1367
|
+
function zodToJsonSchema(schema, options = {}) {
|
|
1368
|
+
const result = convertZodType(schema);
|
|
1369
|
+
if (options.includeSchema) {
|
|
1370
|
+
const schemaVersion = options.target === "draft-04" ? "http://json-schema.org/draft-04/schema#" : options.target === "draft-2019-09" ? "https://json-schema.org/draft/2019-09/schema" : options.target === "draft-2020-12" ? "https://json-schema.org/draft/2020-12/schema" : "http://json-schema.org/draft-07/schema#";
|
|
1371
|
+
return { $schema: schemaVersion, ...result };
|
|
1372
|
+
}
|
|
1373
|
+
return result;
|
|
1374
|
+
}
|
|
1375
|
+
function convertZodType(schema) {
|
|
1376
|
+
const def = schema._def;
|
|
1377
|
+
const typeName = def.typeName;
|
|
1378
|
+
switch (typeName) {
|
|
1379
|
+
case "ZodString":
|
|
1380
|
+
return convertZodString(def);
|
|
1381
|
+
case "ZodNumber":
|
|
1382
|
+
return convertZodNumber(def);
|
|
1383
|
+
case "ZodBoolean":
|
|
1384
|
+
return { type: "boolean" };
|
|
1385
|
+
case "ZodNull":
|
|
1386
|
+
return { type: "null" };
|
|
1387
|
+
case "ZodArray":
|
|
1388
|
+
return convertZodArray(def);
|
|
1389
|
+
case "ZodObject":
|
|
1390
|
+
return convertZodObject(def);
|
|
1391
|
+
case "ZodEnum":
|
|
1392
|
+
return convertZodEnum(def);
|
|
1393
|
+
case "ZodNativeEnum":
|
|
1394
|
+
return convertZodNativeEnum(def);
|
|
1395
|
+
case "ZodLiteral":
|
|
1396
|
+
return { const: def.value };
|
|
1397
|
+
case "ZodUnion":
|
|
1398
|
+
return convertZodUnion(def);
|
|
1399
|
+
case "ZodOptional": {
|
|
1400
|
+
const inner = convertZodType(def.innerType);
|
|
1401
|
+
if (def.description && !inner.description) {
|
|
1402
|
+
inner.description = def.description;
|
|
1403
|
+
}
|
|
1404
|
+
return inner;
|
|
1405
|
+
}
|
|
1406
|
+
case "ZodNullable":
|
|
1407
|
+
return convertZodNullable(def);
|
|
1408
|
+
case "ZodDefault":
|
|
1409
|
+
return { ...convertZodType(def.innerType), default: def.defaultValue() };
|
|
1410
|
+
case "ZodEffects":
|
|
1411
|
+
return convertZodType(def.schema);
|
|
1412
|
+
case "ZodRecord":
|
|
1413
|
+
return convertZodRecord(def);
|
|
1414
|
+
case "ZodTuple":
|
|
1415
|
+
return convertZodTuple(def);
|
|
1416
|
+
case "ZodAny":
|
|
1417
|
+
case "ZodUnknown":
|
|
1418
|
+
return {};
|
|
1419
|
+
default:
|
|
1420
|
+
return {};
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
function convertZodString(def) {
|
|
1424
|
+
const result = { type: "string" };
|
|
1425
|
+
const checks = def.checks;
|
|
1426
|
+
if (checks) {
|
|
1427
|
+
for (const check of checks) {
|
|
1428
|
+
switch (check.kind) {
|
|
1429
|
+
case "min":
|
|
1430
|
+
result.minLength = check.value;
|
|
1431
|
+
break;
|
|
1432
|
+
case "max":
|
|
1433
|
+
result.maxLength = check.value;
|
|
1434
|
+
break;
|
|
1435
|
+
case "length":
|
|
1436
|
+
result.minLength = check.value;
|
|
1437
|
+
result.maxLength = check.value;
|
|
1438
|
+
break;
|
|
1439
|
+
case "email":
|
|
1440
|
+
result.format = "email";
|
|
1441
|
+
break;
|
|
1442
|
+
case "url":
|
|
1443
|
+
result.format = "uri";
|
|
1444
|
+
break;
|
|
1445
|
+
case "uuid":
|
|
1446
|
+
result.format = "uuid";
|
|
1447
|
+
break;
|
|
1448
|
+
case "datetime":
|
|
1449
|
+
result.format = "date-time";
|
|
1450
|
+
break;
|
|
1451
|
+
case "regex":
|
|
1452
|
+
result.pattern = check.value.source;
|
|
1453
|
+
break;
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
if (def.description) {
|
|
1458
|
+
result.description = def.description;
|
|
1459
|
+
}
|
|
1460
|
+
return result;
|
|
1461
|
+
}
|
|
1462
|
+
function convertZodNumber(def) {
|
|
1463
|
+
const result = { type: "number" };
|
|
1464
|
+
const checks = def.checks;
|
|
1465
|
+
if (checks) {
|
|
1466
|
+
for (const check of checks) {
|
|
1467
|
+
switch (check.kind) {
|
|
1468
|
+
case "int":
|
|
1469
|
+
result.type = "integer";
|
|
1470
|
+
break;
|
|
1471
|
+
case "min":
|
|
1472
|
+
if (check.inclusive === false) {
|
|
1473
|
+
result.exclusiveMinimum = check.value;
|
|
1474
|
+
} else {
|
|
1475
|
+
result.minimum = check.value;
|
|
1476
|
+
}
|
|
1477
|
+
break;
|
|
1478
|
+
case "max":
|
|
1479
|
+
if (check.inclusive === false) {
|
|
1480
|
+
result.exclusiveMaximum = check.value;
|
|
1481
|
+
} else {
|
|
1482
|
+
result.maximum = check.value;
|
|
1483
|
+
}
|
|
1484
|
+
break;
|
|
1485
|
+
case "multipleOf":
|
|
1486
|
+
result.multipleOf = check.value;
|
|
1487
|
+
break;
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
if (def.description) {
|
|
1492
|
+
result.description = def.description;
|
|
1493
|
+
}
|
|
1494
|
+
return result;
|
|
1495
|
+
}
|
|
1496
|
+
function convertZodArray(def) {
|
|
1497
|
+
const result = {
|
|
1498
|
+
type: "array",
|
|
1499
|
+
items: convertZodType(def.type)
|
|
1500
|
+
};
|
|
1501
|
+
if (def.minLength !== void 0 && def.minLength !== null) {
|
|
1502
|
+
result.minItems = def.minLength.value;
|
|
1503
|
+
}
|
|
1504
|
+
if (def.maxLength !== void 0 && def.maxLength !== null) {
|
|
1505
|
+
result.maxItems = def.maxLength.value;
|
|
1506
|
+
}
|
|
1507
|
+
if (def.description) {
|
|
1508
|
+
result.description = def.description;
|
|
1509
|
+
}
|
|
1510
|
+
return result;
|
|
1511
|
+
}
|
|
1512
|
+
function convertZodObject(def) {
|
|
1513
|
+
const shape = def.shape;
|
|
1514
|
+
const shapeObj = typeof shape === "function" ? shape() : shape;
|
|
1515
|
+
const properties = {};
|
|
1516
|
+
const required = [];
|
|
1517
|
+
for (const [key, value] of Object.entries(shapeObj)) {
|
|
1518
|
+
properties[key] = convertZodType(value);
|
|
1519
|
+
const valueDef = value._def;
|
|
1520
|
+
const isOptional = valueDef.typeName === "ZodOptional" || valueDef.typeName === "ZodDefault" || valueDef.typeName === "ZodNullable" && valueDef.innerType?._def?.typeName === "ZodDefault";
|
|
1521
|
+
if (!isOptional) {
|
|
1522
|
+
required.push(key);
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
const result = {
|
|
1526
|
+
type: "object",
|
|
1527
|
+
properties
|
|
1528
|
+
};
|
|
1529
|
+
if (required.length > 0) {
|
|
1530
|
+
result.required = required;
|
|
1531
|
+
}
|
|
1532
|
+
if (def.description) {
|
|
1533
|
+
result.description = def.description;
|
|
1534
|
+
}
|
|
1535
|
+
const unknownKeys = def.unknownKeys;
|
|
1536
|
+
if (unknownKeys === "strict") {
|
|
1537
|
+
result.additionalProperties = false;
|
|
1538
|
+
}
|
|
1539
|
+
return result;
|
|
1540
|
+
}
|
|
1541
|
+
function convertZodEnum(def) {
|
|
1542
|
+
const result = {
|
|
1543
|
+
type: "string",
|
|
1544
|
+
enum: def.values
|
|
1545
|
+
};
|
|
1546
|
+
if (def.description) {
|
|
1547
|
+
result.description = def.description;
|
|
1548
|
+
}
|
|
1549
|
+
return result;
|
|
1550
|
+
}
|
|
1551
|
+
function convertZodNativeEnum(def) {
|
|
1552
|
+
const enumValues = def.values;
|
|
1553
|
+
const values = Object.values(enumValues).filter(
|
|
1554
|
+
(v) => typeof v === "string" || typeof v === "number"
|
|
1555
|
+
);
|
|
1556
|
+
const result = { enum: values };
|
|
1557
|
+
if (def.description) {
|
|
1558
|
+
result.description = def.description;
|
|
1559
|
+
}
|
|
1560
|
+
return result;
|
|
1561
|
+
}
|
|
1562
|
+
function convertZodUnion(def) {
|
|
1563
|
+
const options = def.options;
|
|
1564
|
+
const result = {
|
|
1565
|
+
anyOf: options.map(convertZodType)
|
|
1566
|
+
};
|
|
1567
|
+
if (def.description) {
|
|
1568
|
+
result.description = def.description;
|
|
1569
|
+
}
|
|
1570
|
+
return result;
|
|
1571
|
+
}
|
|
1572
|
+
function convertZodNullable(def) {
|
|
1573
|
+
const inner = convertZodType(def.innerType);
|
|
1574
|
+
return {
|
|
1575
|
+
anyOf: [inner, { type: "null" }]
|
|
1576
|
+
};
|
|
1577
|
+
}
|
|
1578
|
+
function convertZodRecord(def) {
|
|
1579
|
+
const result = {
|
|
1580
|
+
type: "object",
|
|
1581
|
+
additionalProperties: convertZodType(def.valueType)
|
|
1582
|
+
};
|
|
1583
|
+
if (def.description) {
|
|
1584
|
+
result.description = def.description;
|
|
1585
|
+
}
|
|
1586
|
+
return result;
|
|
1587
|
+
}
|
|
1588
|
+
function convertZodTuple(def) {
|
|
1589
|
+
const items = def.items;
|
|
1590
|
+
const result = {
|
|
1591
|
+
type: "array",
|
|
1592
|
+
items: items.map(convertZodType),
|
|
1593
|
+
minItems: items.length,
|
|
1594
|
+
maxItems: items.length
|
|
1595
|
+
};
|
|
1596
|
+
if (def.description) {
|
|
1597
|
+
result.description = def.description;
|
|
1598
|
+
}
|
|
1599
|
+
return result;
|
|
1600
|
+
}
|
|
1601
|
+
function createFunctionToolFromSchema(name, description, schema, options) {
|
|
1602
|
+
const jsonSchema = zodToJsonSchema(schema, options);
|
|
1603
|
+
return createFunctionTool(name, description, jsonSchema);
|
|
1604
|
+
}
|
|
1605
|
+
function createFunctionTool(name, description, parameters) {
|
|
1606
|
+
const fn = { name, description };
|
|
1607
|
+
if (parameters) {
|
|
1608
|
+
fn.parameters = parameters;
|
|
1609
|
+
}
|
|
1610
|
+
return {
|
|
1611
|
+
type: ToolTypes.Function,
|
|
1612
|
+
function: fn
|
|
1613
|
+
};
|
|
1614
|
+
}
|
|
1615
|
+
function createWebSearchTool(options) {
|
|
1616
|
+
return {
|
|
1617
|
+
type: ToolTypes.WebSearch,
|
|
1618
|
+
webSearch: options ? {
|
|
1619
|
+
allowedDomains: options.allowedDomains,
|
|
1620
|
+
excludedDomains: options.excludedDomains,
|
|
1621
|
+
maxUses: options.maxUses
|
|
1622
|
+
} : void 0
|
|
1623
|
+
};
|
|
1624
|
+
}
|
|
1625
|
+
function toolChoiceAuto() {
|
|
1626
|
+
return { type: ToolChoiceTypes.Auto };
|
|
1627
|
+
}
|
|
1628
|
+
function toolChoiceRequired() {
|
|
1629
|
+
return { type: ToolChoiceTypes.Required };
|
|
1630
|
+
}
|
|
1631
|
+
function toolChoiceNone() {
|
|
1632
|
+
return { type: ToolChoiceTypes.None };
|
|
1633
|
+
}
|
|
1634
|
+
function hasToolCalls(response) {
|
|
1635
|
+
return (response.toolCalls?.length ?? 0) > 0;
|
|
1636
|
+
}
|
|
1637
|
+
function firstToolCall(response) {
|
|
1638
|
+
return response.toolCalls?.[0];
|
|
1639
|
+
}
|
|
1640
|
+
function toolResultMessage(toolCallId, result) {
|
|
1641
|
+
const content = typeof result === "string" ? result : JSON.stringify(result);
|
|
1642
|
+
return {
|
|
1643
|
+
role: "tool",
|
|
1644
|
+
content,
|
|
1645
|
+
toolCallId
|
|
1646
|
+
};
|
|
1647
|
+
}
|
|
1648
|
+
function respondToToolCall(call, result) {
|
|
1649
|
+
return toolResultMessage(call.id, result);
|
|
1650
|
+
}
|
|
1651
|
+
function assistantMessageWithToolCalls(content, toolCalls) {
|
|
1652
|
+
return {
|
|
1653
|
+
role: "assistant",
|
|
1654
|
+
content,
|
|
1655
|
+
toolCalls
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1658
|
+
var ToolCallAccumulator = class {
|
|
1659
|
+
constructor() {
|
|
1660
|
+
this.calls = /* @__PURE__ */ new Map();
|
|
1661
|
+
}
|
|
1662
|
+
/**
|
|
1663
|
+
* Processes a streaming tool call delta.
|
|
1664
|
+
* Returns true if this started a new tool call.
|
|
1665
|
+
*/
|
|
1666
|
+
processDelta(delta) {
|
|
1667
|
+
const existing = this.calls.get(delta.index);
|
|
1668
|
+
if (!existing) {
|
|
1669
|
+
this.calls.set(delta.index, {
|
|
1670
|
+
id: delta.id ?? "",
|
|
1671
|
+
type: delta.type ?? ToolTypes.Function,
|
|
1672
|
+
function: {
|
|
1673
|
+
name: delta.function?.name ?? "",
|
|
1674
|
+
arguments: delta.function?.arguments ?? ""
|
|
1675
|
+
}
|
|
1676
|
+
});
|
|
1677
|
+
return true;
|
|
1678
|
+
}
|
|
1679
|
+
if (delta.function) {
|
|
1680
|
+
if (delta.function.name) {
|
|
1681
|
+
existing.function = existing.function ?? { name: "", arguments: "" };
|
|
1682
|
+
existing.function.name = delta.function.name;
|
|
1683
|
+
}
|
|
1684
|
+
if (delta.function.arguments) {
|
|
1685
|
+
existing.function = existing.function ?? { name: "", arguments: "" };
|
|
1686
|
+
existing.function.arguments += delta.function.arguments;
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
return false;
|
|
1690
|
+
}
|
|
1691
|
+
/**
|
|
1692
|
+
* Returns all accumulated tool calls in index order.
|
|
1693
|
+
*/
|
|
1694
|
+
getToolCalls() {
|
|
1695
|
+
if (this.calls.size === 0) {
|
|
1696
|
+
return [];
|
|
1697
|
+
}
|
|
1698
|
+
const maxIdx = Math.max(...this.calls.keys());
|
|
1699
|
+
const result = [];
|
|
1700
|
+
for (let i = 0; i <= maxIdx; i++) {
|
|
1701
|
+
const call = this.calls.get(i);
|
|
1702
|
+
if (call) {
|
|
1703
|
+
result.push(call);
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
return result;
|
|
1707
|
+
}
|
|
1708
|
+
/**
|
|
1709
|
+
* Returns a specific tool call by index, or undefined if not found.
|
|
1710
|
+
*/
|
|
1711
|
+
getToolCall(index) {
|
|
1712
|
+
return this.calls.get(index);
|
|
1713
|
+
}
|
|
1714
|
+
/**
|
|
1715
|
+
* Clears all accumulated tool calls.
|
|
1716
|
+
*/
|
|
1717
|
+
reset() {
|
|
1718
|
+
this.calls.clear();
|
|
1719
|
+
}
|
|
1720
|
+
};
|
|
1721
|
+
var ToolArgsError = class extends Error {
|
|
1722
|
+
constructor(message, toolCallId, toolName, rawArguments) {
|
|
1723
|
+
super(message);
|
|
1724
|
+
this.name = "ToolArgsError";
|
|
1725
|
+
this.toolCallId = toolCallId;
|
|
1726
|
+
this.toolName = toolName;
|
|
1727
|
+
this.rawArguments = rawArguments;
|
|
1728
|
+
}
|
|
1729
|
+
};
|
|
1730
|
+
function parseToolArgs(call, schema) {
|
|
1731
|
+
const toolName = call.function?.name ?? "unknown";
|
|
1732
|
+
const rawArgs = call.function?.arguments ?? "";
|
|
1733
|
+
let parsed;
|
|
1734
|
+
try {
|
|
1735
|
+
parsed = rawArgs ? JSON.parse(rawArgs) : {};
|
|
1736
|
+
} catch (err) {
|
|
1737
|
+
const message = err instanceof Error ? err.message : "Invalid JSON in arguments";
|
|
1738
|
+
throw new ToolArgsError(
|
|
1739
|
+
`Failed to parse arguments for tool '${toolName}': ${message}`,
|
|
1740
|
+
call.id,
|
|
1741
|
+
toolName,
|
|
1742
|
+
rawArgs
|
|
1743
|
+
);
|
|
1744
|
+
}
|
|
1745
|
+
try {
|
|
1746
|
+
return schema.parse(parsed);
|
|
1747
|
+
} catch (err) {
|
|
1748
|
+
let message;
|
|
1749
|
+
if (err instanceof Error) {
|
|
1750
|
+
const zodErr = err;
|
|
1751
|
+
if (zodErr.errors && Array.isArray(zodErr.errors)) {
|
|
1752
|
+
const issues = zodErr.errors.map((e) => {
|
|
1753
|
+
const path = e.path.length > 0 ? `${e.path.join(".")}: ` : "";
|
|
1754
|
+
return `${path}${e.message}`;
|
|
1755
|
+
}).join("; ");
|
|
1756
|
+
message = issues;
|
|
1757
|
+
} else {
|
|
1758
|
+
message = err.message;
|
|
1759
|
+
}
|
|
1760
|
+
} else {
|
|
1761
|
+
message = String(err);
|
|
1762
|
+
}
|
|
1763
|
+
throw new ToolArgsError(
|
|
1764
|
+
`Invalid arguments for tool '${toolName}': ${message}`,
|
|
1765
|
+
call.id,
|
|
1766
|
+
toolName,
|
|
1767
|
+
rawArgs
|
|
1768
|
+
);
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
function tryParseToolArgs(call, schema) {
|
|
1772
|
+
try {
|
|
1773
|
+
const data = parseToolArgs(call, schema);
|
|
1774
|
+
return { success: true, data };
|
|
1775
|
+
} catch (err) {
|
|
1776
|
+
if (err instanceof ToolArgsError) {
|
|
1777
|
+
return { success: false, error: err };
|
|
1778
|
+
}
|
|
1779
|
+
const toolName = call.function?.name ?? "unknown";
|
|
1780
|
+
const rawArgs = call.function?.arguments ?? "";
|
|
1781
|
+
return {
|
|
1782
|
+
success: false,
|
|
1783
|
+
error: new ToolArgsError(
|
|
1784
|
+
err instanceof Error ? err.message : String(err),
|
|
1785
|
+
call.id,
|
|
1786
|
+
toolName,
|
|
1787
|
+
rawArgs
|
|
1788
|
+
)
|
|
1789
|
+
};
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
function parseToolArgsRaw(call) {
|
|
1793
|
+
const toolName = call.function?.name ?? "unknown";
|
|
1794
|
+
const rawArgs = call.function?.arguments ?? "";
|
|
1795
|
+
try {
|
|
1796
|
+
return rawArgs ? JSON.parse(rawArgs) : {};
|
|
1797
|
+
} catch (err) {
|
|
1798
|
+
const message = err instanceof Error ? err.message : "Invalid JSON in arguments";
|
|
1799
|
+
throw new ToolArgsError(
|
|
1800
|
+
`Failed to parse arguments for tool '${toolName}': ${message}`,
|
|
1801
|
+
call.id,
|
|
1802
|
+
toolName,
|
|
1803
|
+
rawArgs
|
|
1804
|
+
);
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
var ToolRegistry = class {
|
|
1808
|
+
constructor() {
|
|
1809
|
+
this.handlers = /* @__PURE__ */ new Map();
|
|
1810
|
+
}
|
|
1811
|
+
/**
|
|
1812
|
+
* Registers a handler function for a tool name.
|
|
1813
|
+
* @param name - The tool name (must match the function name in the tool definition)
|
|
1814
|
+
* @param handler - Function to execute when this tool is called
|
|
1815
|
+
* @returns this for chaining
|
|
1816
|
+
*/
|
|
1817
|
+
register(name, handler) {
|
|
1818
|
+
this.handlers.set(name, handler);
|
|
1819
|
+
return this;
|
|
1820
|
+
}
|
|
1821
|
+
/**
|
|
1822
|
+
* Unregisters a tool handler.
|
|
1823
|
+
* @param name - The tool name to unregister
|
|
1824
|
+
* @returns true if the handler was removed, false if it didn't exist
|
|
1825
|
+
*/
|
|
1826
|
+
unregister(name) {
|
|
1827
|
+
return this.handlers.delete(name);
|
|
1828
|
+
}
|
|
1829
|
+
/**
|
|
1830
|
+
* Checks if a handler is registered for the given tool name.
|
|
1831
|
+
*/
|
|
1832
|
+
has(name) {
|
|
1833
|
+
return this.handlers.has(name);
|
|
1834
|
+
}
|
|
1835
|
+
/**
|
|
1836
|
+
* Returns the list of registered tool names.
|
|
1837
|
+
*/
|
|
1838
|
+
getRegisteredTools() {
|
|
1839
|
+
return Array.from(this.handlers.keys());
|
|
1840
|
+
}
|
|
1841
|
+
/**
|
|
1842
|
+
* Executes a single tool call.
|
|
1843
|
+
* @param call - The tool call to execute
|
|
1844
|
+
* @returns The execution result
|
|
1845
|
+
*/
|
|
1846
|
+
async execute(call) {
|
|
1847
|
+
const toolName = call.function?.name ?? "";
|
|
1848
|
+
const handler = this.handlers.get(toolName);
|
|
1849
|
+
if (!handler) {
|
|
1850
|
+
return {
|
|
1851
|
+
toolCallId: call.id,
|
|
1852
|
+
toolName,
|
|
1853
|
+
result: null,
|
|
1854
|
+
error: `Unknown tool: '${toolName}'. Available tools: ${this.getRegisteredTools().join(", ") || "none"}`
|
|
1855
|
+
};
|
|
1856
|
+
}
|
|
1857
|
+
let args;
|
|
1858
|
+
try {
|
|
1859
|
+
args = call.function?.arguments ? JSON.parse(call.function.arguments) : {};
|
|
1860
|
+
} catch (err) {
|
|
1861
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
1862
|
+
return {
|
|
1863
|
+
toolCallId: call.id,
|
|
1864
|
+
toolName,
|
|
1865
|
+
result: null,
|
|
1866
|
+
error: `Invalid JSON in arguments: ${errorMessage}`,
|
|
1867
|
+
isRetryable: true
|
|
1868
|
+
};
|
|
1869
|
+
}
|
|
1870
|
+
try {
|
|
1871
|
+
const result = await handler(args, call);
|
|
1872
|
+
return {
|
|
1873
|
+
toolCallId: call.id,
|
|
1874
|
+
toolName,
|
|
1875
|
+
result
|
|
1876
|
+
};
|
|
1877
|
+
} catch (err) {
|
|
1878
|
+
const isRetryable = err instanceof ToolArgsError;
|
|
1879
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
1880
|
+
return {
|
|
1881
|
+
toolCallId: call.id,
|
|
1882
|
+
toolName,
|
|
1883
|
+
result: null,
|
|
1884
|
+
error: errorMessage,
|
|
1885
|
+
isRetryable
|
|
1886
|
+
};
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
/**
|
|
1890
|
+
* Executes multiple tool calls in parallel.
|
|
1891
|
+
* @param calls - Array of tool calls to execute
|
|
1892
|
+
* @returns Array of execution results in the same order as input
|
|
1893
|
+
*/
|
|
1894
|
+
async executeAll(calls) {
|
|
1895
|
+
return Promise.all(calls.map((call) => this.execute(call)));
|
|
1896
|
+
}
|
|
1897
|
+
/**
|
|
1898
|
+
* Converts execution results to tool result messages.
|
|
1899
|
+
* Useful for appending to the conversation history.
|
|
1900
|
+
* @param results - Array of execution results
|
|
1901
|
+
* @returns Array of ChatMessage objects with role "tool"
|
|
1902
|
+
*/
|
|
1903
|
+
resultsToMessages(results) {
|
|
1904
|
+
return results.map((r) => {
|
|
1905
|
+
const content = r.error ? `Error: ${r.error}` : typeof r.result === "string" ? r.result : JSON.stringify(r.result);
|
|
1906
|
+
return toolResultMessage(r.toolCallId, content);
|
|
1907
|
+
});
|
|
1908
|
+
}
|
|
1909
|
+
};
|
|
1910
|
+
function formatToolErrorForModel(result) {
|
|
1911
|
+
const lines = [
|
|
1912
|
+
`Tool call error for '${result.toolName}': ${result.error}`
|
|
1913
|
+
];
|
|
1914
|
+
if (result.isRetryable) {
|
|
1915
|
+
lines.push("");
|
|
1916
|
+
lines.push("Please correct the arguments and try again.");
|
|
1917
|
+
}
|
|
1918
|
+
return lines.join("\n");
|
|
1919
|
+
}
|
|
1920
|
+
function hasRetryableErrors(results) {
|
|
1921
|
+
return results.some((r) => r.error && r.isRetryable);
|
|
1922
|
+
}
|
|
1923
|
+
function getRetryableErrors(results) {
|
|
1924
|
+
return results.filter((r) => r.error && r.isRetryable);
|
|
1925
|
+
}
|
|
1926
|
+
function createRetryMessages(results) {
|
|
1927
|
+
return results.filter((r) => r.error && r.isRetryable).map((r) => toolResultMessage(r.toolCallId, formatToolErrorForModel(r)));
|
|
1928
|
+
}
|
|
1929
|
+
async function executeWithRetry(registry, toolCalls, options = {}) {
|
|
1930
|
+
const maxRetries = options.maxRetries ?? 2;
|
|
1931
|
+
let currentCalls = toolCalls;
|
|
1932
|
+
let attempt = 0;
|
|
1933
|
+
const successfulResults = /* @__PURE__ */ new Map();
|
|
1934
|
+
while (attempt <= maxRetries) {
|
|
1935
|
+
const results = await registry.executeAll(currentCalls);
|
|
1936
|
+
for (const result of results) {
|
|
1937
|
+
if (!result.error || !result.isRetryable) {
|
|
1938
|
+
successfulResults.set(result.toolCallId, result);
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
const retryableResults = getRetryableErrors(results);
|
|
1942
|
+
if (retryableResults.length === 0 || !options.onRetry) {
|
|
1943
|
+
for (const result of results) {
|
|
1944
|
+
if (result.error && result.isRetryable) {
|
|
1945
|
+
successfulResults.set(result.toolCallId, result);
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
return Array.from(successfulResults.values());
|
|
1949
|
+
}
|
|
1950
|
+
attempt++;
|
|
1951
|
+
if (attempt > maxRetries) {
|
|
1952
|
+
for (const result of retryableResults) {
|
|
1953
|
+
successfulResults.set(result.toolCallId, result);
|
|
1954
|
+
}
|
|
1955
|
+
return Array.from(successfulResults.values());
|
|
1956
|
+
}
|
|
1957
|
+
const errorMessages = createRetryMessages(retryableResults);
|
|
1958
|
+
const newCalls = await options.onRetry(errorMessages, attempt);
|
|
1959
|
+
if (newCalls.length === 0) {
|
|
1960
|
+
for (const result of retryableResults) {
|
|
1961
|
+
successfulResults.set(result.toolCallId, result);
|
|
1962
|
+
}
|
|
1963
|
+
return Array.from(successfulResults.values());
|
|
1964
|
+
}
|
|
1965
|
+
currentCalls = newCalls;
|
|
1966
|
+
}
|
|
1967
|
+
return Array.from(successfulResults.values());
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1202
1970
|
// src/index.ts
|
|
1203
1971
|
var ModelRelay = class {
|
|
1204
1972
|
constructor(options) {
|
|
@@ -1206,7 +1974,7 @@ var ModelRelay = class {
|
|
|
1206
1974
|
if (!cfg.key && !cfg.token) {
|
|
1207
1975
|
throw new ConfigError("Provide an API key or access token");
|
|
1208
1976
|
}
|
|
1209
|
-
this.baseUrl = resolveBaseUrl(cfg.
|
|
1977
|
+
this.baseUrl = resolveBaseUrl(cfg.baseUrl);
|
|
1210
1978
|
const http = new HTTPClient({
|
|
1211
1979
|
baseUrl: this.baseUrl,
|
|
1212
1980
|
apiKey: cfg.key,
|
|
@@ -1217,7 +1985,6 @@ var ModelRelay = class {
|
|
|
1217
1985
|
timeoutMs: cfg.timeoutMs,
|
|
1218
1986
|
retry: cfg.retry,
|
|
1219
1987
|
defaultHeaders: cfg.defaultHeaders,
|
|
1220
|
-
environment: cfg.environment,
|
|
1221
1988
|
metrics: cfg.metrics,
|
|
1222
1989
|
trace: cfg.trace
|
|
1223
1990
|
});
|
|
@@ -1235,10 +2002,13 @@ var ModelRelay = class {
|
|
|
1235
2002
|
this.customers = new CustomersClient(http, {
|
|
1236
2003
|
apiKey: cfg.key
|
|
1237
2004
|
});
|
|
2005
|
+
this.tiers = new TiersClient(http, {
|
|
2006
|
+
apiKey: cfg.key
|
|
2007
|
+
});
|
|
1238
2008
|
}
|
|
1239
2009
|
};
|
|
1240
|
-
function resolveBaseUrl(
|
|
1241
|
-
const base = override ||
|
|
2010
|
+
function resolveBaseUrl(override) {
|
|
2011
|
+
const base = override || DEFAULT_BASE_URL;
|
|
1242
2012
|
return base.replace(/\/+$/, "");
|
|
1243
2013
|
}
|
|
1244
2014
|
export {
|
|
@@ -1256,11 +2026,26 @@ export {
|
|
|
1256
2026
|
ModelRelayError,
|
|
1257
2027
|
Models,
|
|
1258
2028
|
Providers,
|
|
1259
|
-
SANDBOX_BASE_URL,
|
|
1260
2029
|
SDK_VERSION,
|
|
1261
|
-
STAGING_BASE_URL,
|
|
1262
2030
|
StopReasons,
|
|
2031
|
+
TiersClient,
|
|
2032
|
+
ToolArgsError,
|
|
2033
|
+
ToolCallAccumulator,
|
|
2034
|
+
ToolChoiceTypes,
|
|
2035
|
+
ToolRegistry,
|
|
2036
|
+
ToolTypes,
|
|
1263
2037
|
TransportError,
|
|
2038
|
+
assistantMessageWithToolCalls,
|
|
2039
|
+
createFunctionTool,
|
|
2040
|
+
createFunctionToolFromSchema,
|
|
2041
|
+
createRetryMessages,
|
|
2042
|
+
createWebSearchTool,
|
|
2043
|
+
executeWithRetry,
|
|
2044
|
+
firstToolCall,
|
|
2045
|
+
formatToolErrorForModel,
|
|
2046
|
+
getRetryableErrors,
|
|
2047
|
+
hasRetryableErrors,
|
|
2048
|
+
hasToolCalls,
|
|
1264
2049
|
isPublishableKey,
|
|
1265
2050
|
mergeMetrics,
|
|
1266
2051
|
mergeTrace,
|
|
@@ -1269,6 +2054,15 @@ export {
|
|
|
1269
2054
|
normalizeProvider,
|
|
1270
2055
|
normalizeStopReason,
|
|
1271
2056
|
parseErrorResponse,
|
|
2057
|
+
parseToolArgs,
|
|
2058
|
+
parseToolArgsRaw,
|
|
1272
2059
|
providerToString,
|
|
1273
|
-
|
|
2060
|
+
respondToToolCall,
|
|
2061
|
+
stopReasonToString,
|
|
2062
|
+
toolChoiceAuto,
|
|
2063
|
+
toolChoiceNone,
|
|
2064
|
+
toolChoiceRequired,
|
|
2065
|
+
toolResultMessage,
|
|
2066
|
+
tryParseToolArgs,
|
|
2067
|
+
zodToJsonSchema
|
|
1274
2068
|
};
|