@modelrelay/sdk 0.5.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 +806 -33
- package/dist/index.d.cts +583 -14
- package/dist/index.d.ts +583 -14
- package/dist/index.js +780 -30
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -34,12 +34,26 @@ __export(index_exports, {
|
|
|
34
34
|
ModelRelayError: () => ModelRelayError,
|
|
35
35
|
Models: () => Models,
|
|
36
36
|
Providers: () => Providers,
|
|
37
|
-
SANDBOX_BASE_URL: () => SANDBOX_BASE_URL,
|
|
38
37
|
SDK_VERSION: () => SDK_VERSION,
|
|
39
|
-
STAGING_BASE_URL: () => STAGING_BASE_URL,
|
|
40
38
|
StopReasons: () => StopReasons,
|
|
41
39
|
TiersClient: () => TiersClient,
|
|
40
|
+
ToolArgsError: () => ToolArgsError,
|
|
41
|
+
ToolCallAccumulator: () => ToolCallAccumulator,
|
|
42
|
+
ToolChoiceTypes: () => ToolChoiceTypes,
|
|
43
|
+
ToolRegistry: () => ToolRegistry,
|
|
44
|
+
ToolTypes: () => ToolTypes,
|
|
42
45
|
TransportError: () => TransportError,
|
|
46
|
+
assistantMessageWithToolCalls: () => assistantMessageWithToolCalls,
|
|
47
|
+
createFunctionTool: () => createFunctionTool,
|
|
48
|
+
createFunctionToolFromSchema: () => createFunctionToolFromSchema,
|
|
49
|
+
createRetryMessages: () => createRetryMessages,
|
|
50
|
+
createWebSearchTool: () => createWebSearchTool,
|
|
51
|
+
executeWithRetry: () => executeWithRetry,
|
|
52
|
+
firstToolCall: () => firstToolCall,
|
|
53
|
+
formatToolErrorForModel: () => formatToolErrorForModel,
|
|
54
|
+
getRetryableErrors: () => getRetryableErrors,
|
|
55
|
+
hasRetryableErrors: () => hasRetryableErrors,
|
|
56
|
+
hasToolCalls: () => hasToolCalls,
|
|
43
57
|
isPublishableKey: () => isPublishableKey,
|
|
44
58
|
mergeMetrics: () => mergeMetrics,
|
|
45
59
|
mergeTrace: () => mergeTrace,
|
|
@@ -48,8 +62,17 @@ __export(index_exports, {
|
|
|
48
62
|
normalizeProvider: () => normalizeProvider,
|
|
49
63
|
normalizeStopReason: () => normalizeStopReason,
|
|
50
64
|
parseErrorResponse: () => parseErrorResponse,
|
|
65
|
+
parseToolArgs: () => parseToolArgs,
|
|
66
|
+
parseToolArgsRaw: () => parseToolArgsRaw,
|
|
51
67
|
providerToString: () => providerToString,
|
|
52
|
-
|
|
68
|
+
respondToToolCall: () => respondToToolCall,
|
|
69
|
+
stopReasonToString: () => stopReasonToString,
|
|
70
|
+
toolChoiceAuto: () => toolChoiceAuto,
|
|
71
|
+
toolChoiceNone: () => toolChoiceNone,
|
|
72
|
+
toolChoiceRequired: () => toolChoiceRequired,
|
|
73
|
+
toolResultMessage: () => toolResultMessage,
|
|
74
|
+
tryParseToolArgs: () => tryParseToolArgs,
|
|
75
|
+
zodToJsonSchema: () => zodToJsonSchema
|
|
53
76
|
});
|
|
54
77
|
module.exports = __toCommonJS(index_exports);
|
|
55
78
|
|
|
@@ -273,7 +296,7 @@ function isTokenReusable(token) {
|
|
|
273
296
|
// package.json
|
|
274
297
|
var package_default = {
|
|
275
298
|
name: "@modelrelay/sdk",
|
|
276
|
-
version: "0.
|
|
299
|
+
version: "0.7.0",
|
|
277
300
|
description: "TypeScript SDK for the ModelRelay API",
|
|
278
301
|
type: "module",
|
|
279
302
|
main: "dist/index.cjs",
|
|
@@ -307,15 +330,14 @@ var package_default = {
|
|
|
307
330
|
devDependencies: {
|
|
308
331
|
tsup: "^8.2.4",
|
|
309
332
|
typescript: "^5.6.3",
|
|
310
|
-
vitest: "^2.1.4"
|
|
333
|
+
vitest: "^2.1.4",
|
|
334
|
+
zod: "^3.23.0"
|
|
311
335
|
}
|
|
312
336
|
};
|
|
313
337
|
|
|
314
338
|
// src/types.ts
|
|
315
339
|
var SDK_VERSION = package_default.version || "0.0.0";
|
|
316
340
|
var DEFAULT_BASE_URL = "https://api.modelrelay.ai/api/v1";
|
|
317
|
-
var STAGING_BASE_URL = "https://api-stg.modelrelay.ai/api/v1";
|
|
318
|
-
var SANDBOX_BASE_URL = "https://api.sandbox.modelrelay.ai/api/v1";
|
|
319
341
|
var DEFAULT_CLIENT_HEADER = `modelrelay-ts/${SDK_VERSION}`;
|
|
320
342
|
var DEFAULT_CONNECT_TIMEOUT_MS = 5e3;
|
|
321
343
|
var DEFAULT_REQUEST_TIMEOUT_MS = 6e4;
|
|
@@ -337,7 +359,6 @@ var Providers = {
|
|
|
337
359
|
OpenAI: "openai",
|
|
338
360
|
Anthropic: "anthropic",
|
|
339
361
|
Grok: "grok",
|
|
340
|
-
OpenRouter: "openrouter",
|
|
341
362
|
Echo: "echo"
|
|
342
363
|
};
|
|
343
364
|
var Models = {
|
|
@@ -347,11 +368,23 @@ var Models = {
|
|
|
347
368
|
AnthropicClaude35HaikuLatest: "anthropic/claude-3-5-haiku-latest",
|
|
348
369
|
AnthropicClaude35SonnetLatest: "anthropic/claude-3-5-sonnet-latest",
|
|
349
370
|
AnthropicClaudeOpus45: "anthropic/claude-opus-4-5-20251101",
|
|
350
|
-
|
|
371
|
+
AnthropicClaude35Haiku: "anthropic/claude-3.5-haiku",
|
|
351
372
|
Grok2: "grok-2",
|
|
352
|
-
|
|
373
|
+
Grok4_1FastNonReasoning: "grok-4-1-fast-non-reasoning",
|
|
374
|
+
Grok4_1FastReasoning: "grok-4-1-fast-reasoning",
|
|
353
375
|
Echo1: "echo-1"
|
|
354
376
|
};
|
|
377
|
+
var ToolTypes = {
|
|
378
|
+
Function: "function",
|
|
379
|
+
WebSearch: "web_search",
|
|
380
|
+
XSearch: "x_search",
|
|
381
|
+
CodeExecution: "code_execution"
|
|
382
|
+
};
|
|
383
|
+
var ToolChoiceTypes = {
|
|
384
|
+
Auto: "auto",
|
|
385
|
+
Required: "required",
|
|
386
|
+
None: "none"
|
|
387
|
+
};
|
|
355
388
|
function mergeMetrics(base, override) {
|
|
356
389
|
if (!base && !override) return void 0;
|
|
357
390
|
return {
|
|
@@ -588,7 +621,7 @@ var ChatCompletionsStream = class {
|
|
|
588
621
|
const context = this.enrichContext(evt);
|
|
589
622
|
this.context = context;
|
|
590
623
|
this.trace?.streamEvent?.({ context, event: evt });
|
|
591
|
-
if (evt.type === "message_start" || evt.type === "message_delta" || evt.type === "message_stop") {
|
|
624
|
+
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") {
|
|
592
625
|
this.recordFirstToken();
|
|
593
626
|
}
|
|
594
627
|
if (evt.type === "message_stop" && evt.usage && this.metrics?.usage) {
|
|
@@ -673,11 +706,15 @@ function mapChatEvent(raw, requestId) {
|
|
|
673
706
|
const model = normalizeModelId(p.model || p?.message?.model);
|
|
674
707
|
const stopReason = normalizeStopReason(p.stop_reason);
|
|
675
708
|
const textDelta = extractTextDelta(p);
|
|
709
|
+
const toolCallDelta = extractToolCallDelta(p, type);
|
|
710
|
+
const toolCalls = extractToolCalls(p, type);
|
|
676
711
|
return {
|
|
677
712
|
type,
|
|
678
713
|
event: raw.event || type,
|
|
679
714
|
data: p,
|
|
680
715
|
textDelta,
|
|
716
|
+
toolCallDelta,
|
|
717
|
+
toolCalls,
|
|
681
718
|
responseId,
|
|
682
719
|
model,
|
|
683
720
|
stopReason,
|
|
@@ -697,6 +734,12 @@ function normalizeEventType(eventName, payload) {
|
|
|
697
734
|
return "message_delta";
|
|
698
735
|
case "message_stop":
|
|
699
736
|
return "message_stop";
|
|
737
|
+
case "tool_use_start":
|
|
738
|
+
return "tool_use_start";
|
|
739
|
+
case "tool_use_delta":
|
|
740
|
+
return "tool_use_delta";
|
|
741
|
+
case "tool_use_stop":
|
|
742
|
+
return "tool_use_stop";
|
|
700
743
|
case "ping":
|
|
701
744
|
return "ping";
|
|
702
745
|
default:
|
|
@@ -707,6 +750,9 @@ function extractTextDelta(payload) {
|
|
|
707
750
|
if (!payload || typeof payload !== "object") {
|
|
708
751
|
return void 0;
|
|
709
752
|
}
|
|
753
|
+
if (typeof payload.text_delta === "string" && payload.text_delta !== "") {
|
|
754
|
+
return payload.text_delta;
|
|
755
|
+
}
|
|
710
756
|
if (typeof payload.delta === "string") {
|
|
711
757
|
return payload.delta;
|
|
712
758
|
}
|
|
@@ -720,9 +766,56 @@ function extractTextDelta(payload) {
|
|
|
720
766
|
}
|
|
721
767
|
return void 0;
|
|
722
768
|
}
|
|
769
|
+
function extractToolCallDelta(payload, type) {
|
|
770
|
+
if (!payload || typeof payload !== "object") {
|
|
771
|
+
return void 0;
|
|
772
|
+
}
|
|
773
|
+
if (type !== "tool_use_start" && type !== "tool_use_delta") {
|
|
774
|
+
return void 0;
|
|
775
|
+
}
|
|
776
|
+
if (payload.tool_call_delta) {
|
|
777
|
+
const d = payload.tool_call_delta;
|
|
778
|
+
return {
|
|
779
|
+
index: d.index ?? 0,
|
|
780
|
+
id: d.id,
|
|
781
|
+
type: d.type,
|
|
782
|
+
function: d.function ? {
|
|
783
|
+
name: d.function.name,
|
|
784
|
+
arguments: d.function.arguments
|
|
785
|
+
} : void 0
|
|
786
|
+
};
|
|
787
|
+
}
|
|
788
|
+
if (typeof payload.index === "number" || payload.id || payload.name) {
|
|
789
|
+
return {
|
|
790
|
+
index: payload.index ?? 0,
|
|
791
|
+
id: payload.id,
|
|
792
|
+
type: payload.tool_type,
|
|
793
|
+
function: payload.name || payload.arguments ? {
|
|
794
|
+
name: payload.name,
|
|
795
|
+
arguments: payload.arguments
|
|
796
|
+
} : void 0
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
return void 0;
|
|
800
|
+
}
|
|
801
|
+
function extractToolCalls(payload, type) {
|
|
802
|
+
if (!payload || typeof payload !== "object") {
|
|
803
|
+
return void 0;
|
|
804
|
+
}
|
|
805
|
+
if (type !== "tool_use_stop" && type !== "message_stop") {
|
|
806
|
+
return void 0;
|
|
807
|
+
}
|
|
808
|
+
if (payload.tool_calls?.length) {
|
|
809
|
+
return normalizeToolCalls(payload.tool_calls);
|
|
810
|
+
}
|
|
811
|
+
if (payload.tool_call) {
|
|
812
|
+
return normalizeToolCalls([payload.tool_call]);
|
|
813
|
+
}
|
|
814
|
+
return void 0;
|
|
815
|
+
}
|
|
723
816
|
function normalizeChatResponse(payload, requestId) {
|
|
724
817
|
const p = payload;
|
|
725
|
-
|
|
818
|
+
const response = {
|
|
726
819
|
id: p?.id,
|
|
727
820
|
provider: normalizeProvider(p?.provider),
|
|
728
821
|
content: Array.isArray(p?.content) ? p.content : p?.content ? [String(p.content)] : [],
|
|
@@ -731,6 +824,17 @@ function normalizeChatResponse(payload, requestId) {
|
|
|
731
824
|
usage: normalizeUsage(p?.usage),
|
|
732
825
|
requestId
|
|
733
826
|
};
|
|
827
|
+
if (p?.tool_calls?.length) {
|
|
828
|
+
response.toolCalls = normalizeToolCalls(p.tool_calls);
|
|
829
|
+
}
|
|
830
|
+
return response;
|
|
831
|
+
}
|
|
832
|
+
function normalizeToolCalls(toolCalls) {
|
|
833
|
+
return toolCalls.map((tc) => ({
|
|
834
|
+
id: tc.id,
|
|
835
|
+
type: tc.type || ToolTypes.Function,
|
|
836
|
+
function: tc.function ? { name: tc.function.name, arguments: tc.function.arguments } : void 0
|
|
837
|
+
}));
|
|
734
838
|
}
|
|
735
839
|
function normalizeUsage(payload) {
|
|
736
840
|
if (!payload) {
|
|
@@ -758,13 +862,65 @@ function buildProxyBody(params, metadata) {
|
|
|
758
862
|
if (metadata && Object.keys(metadata).length > 0) body.metadata = metadata;
|
|
759
863
|
if (params.stop?.length) body.stop = params.stop;
|
|
760
864
|
if (params.stopSequences?.length) body.stop_sequences = params.stopSequences;
|
|
865
|
+
if (params.tools?.length) body.tools = normalizeTools(params.tools);
|
|
866
|
+
if (params.toolChoice) body.tool_choice = normalizeToolChoice(params.toolChoice);
|
|
761
867
|
return body;
|
|
762
868
|
}
|
|
763
869
|
function normalizeMessages(messages) {
|
|
764
|
-
return messages.map((msg) =>
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
870
|
+
return messages.map((msg) => {
|
|
871
|
+
const normalized = {
|
|
872
|
+
role: msg.role || "user",
|
|
873
|
+
content: msg.content
|
|
874
|
+
};
|
|
875
|
+
if (msg.toolCalls?.length) {
|
|
876
|
+
normalized.tool_calls = msg.toolCalls.map((tc) => ({
|
|
877
|
+
id: tc.id,
|
|
878
|
+
type: tc.type,
|
|
879
|
+
function: tc.function ? { name: tc.function.name, arguments: tc.function.arguments } : void 0
|
|
880
|
+
}));
|
|
881
|
+
}
|
|
882
|
+
if (msg.toolCallId) {
|
|
883
|
+
normalized.tool_call_id = msg.toolCallId;
|
|
884
|
+
}
|
|
885
|
+
return normalized;
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
function normalizeTools(tools) {
|
|
889
|
+
return tools.map((tool) => {
|
|
890
|
+
const normalized = { type: tool.type };
|
|
891
|
+
if (tool.function) {
|
|
892
|
+
normalized.function = {
|
|
893
|
+
name: tool.function.name,
|
|
894
|
+
description: tool.function.description,
|
|
895
|
+
parameters: tool.function.parameters
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
if (tool.webSearch) {
|
|
899
|
+
normalized.web_search = {
|
|
900
|
+
allowed_domains: tool.webSearch.allowedDomains,
|
|
901
|
+
excluded_domains: tool.webSearch.excludedDomains,
|
|
902
|
+
max_uses: tool.webSearch.maxUses
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
if (tool.xSearch) {
|
|
906
|
+
normalized.x_search = {
|
|
907
|
+
allowed_handles: tool.xSearch.allowedHandles,
|
|
908
|
+
excluded_handles: tool.xSearch.excludedHandles,
|
|
909
|
+
from_date: tool.xSearch.fromDate,
|
|
910
|
+
to_date: tool.xSearch.toDate
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
if (tool.codeExecution) {
|
|
914
|
+
normalized.code_execution = {
|
|
915
|
+
language: tool.codeExecution.language,
|
|
916
|
+
timeout_ms: tool.codeExecution.timeoutMs
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
return normalized;
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
function normalizeToolChoice(tc) {
|
|
923
|
+
return { type: tc.type };
|
|
768
924
|
}
|
|
769
925
|
function requestIdFromHeaders(headers) {
|
|
770
926
|
return headers.get(REQUEST_ID_HEADER) || headers.get("X-Request-Id") || void 0;
|
|
@@ -961,10 +1117,7 @@ var TiersClient = class {
|
|
|
961
1117
|
// src/http.ts
|
|
962
1118
|
var HTTPClient = class {
|
|
963
1119
|
constructor(cfg) {
|
|
964
|
-
const
|
|
965
|
-
const resolvedBase = normalizeBaseUrl(
|
|
966
|
-
cfg.baseUrl || baseFromEnv || DEFAULT_BASE_URL
|
|
967
|
-
);
|
|
1120
|
+
const resolvedBase = normalizeBaseUrl(cfg.baseUrl || DEFAULT_BASE_URL);
|
|
968
1121
|
if (!isValidHttpUrl(resolvedBase)) {
|
|
969
1122
|
throw new ConfigError(
|
|
970
1123
|
"baseUrl must start with http:// or https://"
|
|
@@ -1177,12 +1330,6 @@ function normalizeBaseUrl(value) {
|
|
|
1177
1330
|
function isValidHttpUrl(value) {
|
|
1178
1331
|
return /^https?:\/\//i.test(value);
|
|
1179
1332
|
}
|
|
1180
|
-
function baseUrlForEnvironment(env) {
|
|
1181
|
-
if (!env || env === "production") return void 0;
|
|
1182
|
-
if (env === "staging") return STAGING_BASE_URL;
|
|
1183
|
-
if (env === "sandbox") return SANDBOX_BASE_URL;
|
|
1184
|
-
return void 0;
|
|
1185
|
-
}
|
|
1186
1333
|
function normalizeRetryConfig(retry) {
|
|
1187
1334
|
if (retry === false) return void 0;
|
|
1188
1335
|
const cfg = retry || {};
|
|
@@ -1294,6 +1441,610 @@ function withRequestId(context, headers) {
|
|
|
1294
1441
|
return { ...context, requestId };
|
|
1295
1442
|
}
|
|
1296
1443
|
|
|
1444
|
+
// src/tools.ts
|
|
1445
|
+
function zodToJsonSchema(schema, options = {}) {
|
|
1446
|
+
const result = convertZodType(schema);
|
|
1447
|
+
if (options.includeSchema) {
|
|
1448
|
+
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#";
|
|
1449
|
+
return { $schema: schemaVersion, ...result };
|
|
1450
|
+
}
|
|
1451
|
+
return result;
|
|
1452
|
+
}
|
|
1453
|
+
function convertZodType(schema) {
|
|
1454
|
+
const def = schema._def;
|
|
1455
|
+
const typeName = def.typeName;
|
|
1456
|
+
switch (typeName) {
|
|
1457
|
+
case "ZodString":
|
|
1458
|
+
return convertZodString(def);
|
|
1459
|
+
case "ZodNumber":
|
|
1460
|
+
return convertZodNumber(def);
|
|
1461
|
+
case "ZodBoolean":
|
|
1462
|
+
return { type: "boolean" };
|
|
1463
|
+
case "ZodNull":
|
|
1464
|
+
return { type: "null" };
|
|
1465
|
+
case "ZodArray":
|
|
1466
|
+
return convertZodArray(def);
|
|
1467
|
+
case "ZodObject":
|
|
1468
|
+
return convertZodObject(def);
|
|
1469
|
+
case "ZodEnum":
|
|
1470
|
+
return convertZodEnum(def);
|
|
1471
|
+
case "ZodNativeEnum":
|
|
1472
|
+
return convertZodNativeEnum(def);
|
|
1473
|
+
case "ZodLiteral":
|
|
1474
|
+
return { const: def.value };
|
|
1475
|
+
case "ZodUnion":
|
|
1476
|
+
return convertZodUnion(def);
|
|
1477
|
+
case "ZodOptional": {
|
|
1478
|
+
const inner = convertZodType(def.innerType);
|
|
1479
|
+
if (def.description && !inner.description) {
|
|
1480
|
+
inner.description = def.description;
|
|
1481
|
+
}
|
|
1482
|
+
return inner;
|
|
1483
|
+
}
|
|
1484
|
+
case "ZodNullable":
|
|
1485
|
+
return convertZodNullable(def);
|
|
1486
|
+
case "ZodDefault":
|
|
1487
|
+
return { ...convertZodType(def.innerType), default: def.defaultValue() };
|
|
1488
|
+
case "ZodEffects":
|
|
1489
|
+
return convertZodType(def.schema);
|
|
1490
|
+
case "ZodRecord":
|
|
1491
|
+
return convertZodRecord(def);
|
|
1492
|
+
case "ZodTuple":
|
|
1493
|
+
return convertZodTuple(def);
|
|
1494
|
+
case "ZodAny":
|
|
1495
|
+
case "ZodUnknown":
|
|
1496
|
+
return {};
|
|
1497
|
+
default:
|
|
1498
|
+
return {};
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
function convertZodString(def) {
|
|
1502
|
+
const result = { type: "string" };
|
|
1503
|
+
const checks = def.checks;
|
|
1504
|
+
if (checks) {
|
|
1505
|
+
for (const check of checks) {
|
|
1506
|
+
switch (check.kind) {
|
|
1507
|
+
case "min":
|
|
1508
|
+
result.minLength = check.value;
|
|
1509
|
+
break;
|
|
1510
|
+
case "max":
|
|
1511
|
+
result.maxLength = check.value;
|
|
1512
|
+
break;
|
|
1513
|
+
case "length":
|
|
1514
|
+
result.minLength = check.value;
|
|
1515
|
+
result.maxLength = check.value;
|
|
1516
|
+
break;
|
|
1517
|
+
case "email":
|
|
1518
|
+
result.format = "email";
|
|
1519
|
+
break;
|
|
1520
|
+
case "url":
|
|
1521
|
+
result.format = "uri";
|
|
1522
|
+
break;
|
|
1523
|
+
case "uuid":
|
|
1524
|
+
result.format = "uuid";
|
|
1525
|
+
break;
|
|
1526
|
+
case "datetime":
|
|
1527
|
+
result.format = "date-time";
|
|
1528
|
+
break;
|
|
1529
|
+
case "regex":
|
|
1530
|
+
result.pattern = check.value.source;
|
|
1531
|
+
break;
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
if (def.description) {
|
|
1536
|
+
result.description = def.description;
|
|
1537
|
+
}
|
|
1538
|
+
return result;
|
|
1539
|
+
}
|
|
1540
|
+
function convertZodNumber(def) {
|
|
1541
|
+
const result = { type: "number" };
|
|
1542
|
+
const checks = def.checks;
|
|
1543
|
+
if (checks) {
|
|
1544
|
+
for (const check of checks) {
|
|
1545
|
+
switch (check.kind) {
|
|
1546
|
+
case "int":
|
|
1547
|
+
result.type = "integer";
|
|
1548
|
+
break;
|
|
1549
|
+
case "min":
|
|
1550
|
+
if (check.inclusive === false) {
|
|
1551
|
+
result.exclusiveMinimum = check.value;
|
|
1552
|
+
} else {
|
|
1553
|
+
result.minimum = check.value;
|
|
1554
|
+
}
|
|
1555
|
+
break;
|
|
1556
|
+
case "max":
|
|
1557
|
+
if (check.inclusive === false) {
|
|
1558
|
+
result.exclusiveMaximum = check.value;
|
|
1559
|
+
} else {
|
|
1560
|
+
result.maximum = check.value;
|
|
1561
|
+
}
|
|
1562
|
+
break;
|
|
1563
|
+
case "multipleOf":
|
|
1564
|
+
result.multipleOf = check.value;
|
|
1565
|
+
break;
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
if (def.description) {
|
|
1570
|
+
result.description = def.description;
|
|
1571
|
+
}
|
|
1572
|
+
return result;
|
|
1573
|
+
}
|
|
1574
|
+
function convertZodArray(def) {
|
|
1575
|
+
const result = {
|
|
1576
|
+
type: "array",
|
|
1577
|
+
items: convertZodType(def.type)
|
|
1578
|
+
};
|
|
1579
|
+
if (def.minLength !== void 0 && def.minLength !== null) {
|
|
1580
|
+
result.minItems = def.minLength.value;
|
|
1581
|
+
}
|
|
1582
|
+
if (def.maxLength !== void 0 && def.maxLength !== null) {
|
|
1583
|
+
result.maxItems = def.maxLength.value;
|
|
1584
|
+
}
|
|
1585
|
+
if (def.description) {
|
|
1586
|
+
result.description = def.description;
|
|
1587
|
+
}
|
|
1588
|
+
return result;
|
|
1589
|
+
}
|
|
1590
|
+
function convertZodObject(def) {
|
|
1591
|
+
const shape = def.shape;
|
|
1592
|
+
const shapeObj = typeof shape === "function" ? shape() : shape;
|
|
1593
|
+
const properties = {};
|
|
1594
|
+
const required = [];
|
|
1595
|
+
for (const [key, value] of Object.entries(shapeObj)) {
|
|
1596
|
+
properties[key] = convertZodType(value);
|
|
1597
|
+
const valueDef = value._def;
|
|
1598
|
+
const isOptional = valueDef.typeName === "ZodOptional" || valueDef.typeName === "ZodDefault" || valueDef.typeName === "ZodNullable" && valueDef.innerType?._def?.typeName === "ZodDefault";
|
|
1599
|
+
if (!isOptional) {
|
|
1600
|
+
required.push(key);
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
const result = {
|
|
1604
|
+
type: "object",
|
|
1605
|
+
properties
|
|
1606
|
+
};
|
|
1607
|
+
if (required.length > 0) {
|
|
1608
|
+
result.required = required;
|
|
1609
|
+
}
|
|
1610
|
+
if (def.description) {
|
|
1611
|
+
result.description = def.description;
|
|
1612
|
+
}
|
|
1613
|
+
const unknownKeys = def.unknownKeys;
|
|
1614
|
+
if (unknownKeys === "strict") {
|
|
1615
|
+
result.additionalProperties = false;
|
|
1616
|
+
}
|
|
1617
|
+
return result;
|
|
1618
|
+
}
|
|
1619
|
+
function convertZodEnum(def) {
|
|
1620
|
+
const result = {
|
|
1621
|
+
type: "string",
|
|
1622
|
+
enum: def.values
|
|
1623
|
+
};
|
|
1624
|
+
if (def.description) {
|
|
1625
|
+
result.description = def.description;
|
|
1626
|
+
}
|
|
1627
|
+
return result;
|
|
1628
|
+
}
|
|
1629
|
+
function convertZodNativeEnum(def) {
|
|
1630
|
+
const enumValues = def.values;
|
|
1631
|
+
const values = Object.values(enumValues).filter(
|
|
1632
|
+
(v) => typeof v === "string" || typeof v === "number"
|
|
1633
|
+
);
|
|
1634
|
+
const result = { enum: values };
|
|
1635
|
+
if (def.description) {
|
|
1636
|
+
result.description = def.description;
|
|
1637
|
+
}
|
|
1638
|
+
return result;
|
|
1639
|
+
}
|
|
1640
|
+
function convertZodUnion(def) {
|
|
1641
|
+
const options = def.options;
|
|
1642
|
+
const result = {
|
|
1643
|
+
anyOf: options.map(convertZodType)
|
|
1644
|
+
};
|
|
1645
|
+
if (def.description) {
|
|
1646
|
+
result.description = def.description;
|
|
1647
|
+
}
|
|
1648
|
+
return result;
|
|
1649
|
+
}
|
|
1650
|
+
function convertZodNullable(def) {
|
|
1651
|
+
const inner = convertZodType(def.innerType);
|
|
1652
|
+
return {
|
|
1653
|
+
anyOf: [inner, { type: "null" }]
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
function convertZodRecord(def) {
|
|
1657
|
+
const result = {
|
|
1658
|
+
type: "object",
|
|
1659
|
+
additionalProperties: convertZodType(def.valueType)
|
|
1660
|
+
};
|
|
1661
|
+
if (def.description) {
|
|
1662
|
+
result.description = def.description;
|
|
1663
|
+
}
|
|
1664
|
+
return result;
|
|
1665
|
+
}
|
|
1666
|
+
function convertZodTuple(def) {
|
|
1667
|
+
const items = def.items;
|
|
1668
|
+
const result = {
|
|
1669
|
+
type: "array",
|
|
1670
|
+
items: items.map(convertZodType),
|
|
1671
|
+
minItems: items.length,
|
|
1672
|
+
maxItems: items.length
|
|
1673
|
+
};
|
|
1674
|
+
if (def.description) {
|
|
1675
|
+
result.description = def.description;
|
|
1676
|
+
}
|
|
1677
|
+
return result;
|
|
1678
|
+
}
|
|
1679
|
+
function createFunctionToolFromSchema(name, description, schema, options) {
|
|
1680
|
+
const jsonSchema = zodToJsonSchema(schema, options);
|
|
1681
|
+
return createFunctionTool(name, description, jsonSchema);
|
|
1682
|
+
}
|
|
1683
|
+
function createFunctionTool(name, description, parameters) {
|
|
1684
|
+
const fn = { name, description };
|
|
1685
|
+
if (parameters) {
|
|
1686
|
+
fn.parameters = parameters;
|
|
1687
|
+
}
|
|
1688
|
+
return {
|
|
1689
|
+
type: ToolTypes.Function,
|
|
1690
|
+
function: fn
|
|
1691
|
+
};
|
|
1692
|
+
}
|
|
1693
|
+
function createWebSearchTool(options) {
|
|
1694
|
+
return {
|
|
1695
|
+
type: ToolTypes.WebSearch,
|
|
1696
|
+
webSearch: options ? {
|
|
1697
|
+
allowedDomains: options.allowedDomains,
|
|
1698
|
+
excludedDomains: options.excludedDomains,
|
|
1699
|
+
maxUses: options.maxUses
|
|
1700
|
+
} : void 0
|
|
1701
|
+
};
|
|
1702
|
+
}
|
|
1703
|
+
function toolChoiceAuto() {
|
|
1704
|
+
return { type: ToolChoiceTypes.Auto };
|
|
1705
|
+
}
|
|
1706
|
+
function toolChoiceRequired() {
|
|
1707
|
+
return { type: ToolChoiceTypes.Required };
|
|
1708
|
+
}
|
|
1709
|
+
function toolChoiceNone() {
|
|
1710
|
+
return { type: ToolChoiceTypes.None };
|
|
1711
|
+
}
|
|
1712
|
+
function hasToolCalls(response) {
|
|
1713
|
+
return (response.toolCalls?.length ?? 0) > 0;
|
|
1714
|
+
}
|
|
1715
|
+
function firstToolCall(response) {
|
|
1716
|
+
return response.toolCalls?.[0];
|
|
1717
|
+
}
|
|
1718
|
+
function toolResultMessage(toolCallId, result) {
|
|
1719
|
+
const content = typeof result === "string" ? result : JSON.stringify(result);
|
|
1720
|
+
return {
|
|
1721
|
+
role: "tool",
|
|
1722
|
+
content,
|
|
1723
|
+
toolCallId
|
|
1724
|
+
};
|
|
1725
|
+
}
|
|
1726
|
+
function respondToToolCall(call, result) {
|
|
1727
|
+
return toolResultMessage(call.id, result);
|
|
1728
|
+
}
|
|
1729
|
+
function assistantMessageWithToolCalls(content, toolCalls) {
|
|
1730
|
+
return {
|
|
1731
|
+
role: "assistant",
|
|
1732
|
+
content,
|
|
1733
|
+
toolCalls
|
|
1734
|
+
};
|
|
1735
|
+
}
|
|
1736
|
+
var ToolCallAccumulator = class {
|
|
1737
|
+
constructor() {
|
|
1738
|
+
this.calls = /* @__PURE__ */ new Map();
|
|
1739
|
+
}
|
|
1740
|
+
/**
|
|
1741
|
+
* Processes a streaming tool call delta.
|
|
1742
|
+
* Returns true if this started a new tool call.
|
|
1743
|
+
*/
|
|
1744
|
+
processDelta(delta) {
|
|
1745
|
+
const existing = this.calls.get(delta.index);
|
|
1746
|
+
if (!existing) {
|
|
1747
|
+
this.calls.set(delta.index, {
|
|
1748
|
+
id: delta.id ?? "",
|
|
1749
|
+
type: delta.type ?? ToolTypes.Function,
|
|
1750
|
+
function: {
|
|
1751
|
+
name: delta.function?.name ?? "",
|
|
1752
|
+
arguments: delta.function?.arguments ?? ""
|
|
1753
|
+
}
|
|
1754
|
+
});
|
|
1755
|
+
return true;
|
|
1756
|
+
}
|
|
1757
|
+
if (delta.function) {
|
|
1758
|
+
if (delta.function.name) {
|
|
1759
|
+
existing.function = existing.function ?? { name: "", arguments: "" };
|
|
1760
|
+
existing.function.name = delta.function.name;
|
|
1761
|
+
}
|
|
1762
|
+
if (delta.function.arguments) {
|
|
1763
|
+
existing.function = existing.function ?? { name: "", arguments: "" };
|
|
1764
|
+
existing.function.arguments += delta.function.arguments;
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
return false;
|
|
1768
|
+
}
|
|
1769
|
+
/**
|
|
1770
|
+
* Returns all accumulated tool calls in index order.
|
|
1771
|
+
*/
|
|
1772
|
+
getToolCalls() {
|
|
1773
|
+
if (this.calls.size === 0) {
|
|
1774
|
+
return [];
|
|
1775
|
+
}
|
|
1776
|
+
const maxIdx = Math.max(...this.calls.keys());
|
|
1777
|
+
const result = [];
|
|
1778
|
+
for (let i = 0; i <= maxIdx; i++) {
|
|
1779
|
+
const call = this.calls.get(i);
|
|
1780
|
+
if (call) {
|
|
1781
|
+
result.push(call);
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
return result;
|
|
1785
|
+
}
|
|
1786
|
+
/**
|
|
1787
|
+
* Returns a specific tool call by index, or undefined if not found.
|
|
1788
|
+
*/
|
|
1789
|
+
getToolCall(index) {
|
|
1790
|
+
return this.calls.get(index);
|
|
1791
|
+
}
|
|
1792
|
+
/**
|
|
1793
|
+
* Clears all accumulated tool calls.
|
|
1794
|
+
*/
|
|
1795
|
+
reset() {
|
|
1796
|
+
this.calls.clear();
|
|
1797
|
+
}
|
|
1798
|
+
};
|
|
1799
|
+
var ToolArgsError = class extends Error {
|
|
1800
|
+
constructor(message, toolCallId, toolName, rawArguments) {
|
|
1801
|
+
super(message);
|
|
1802
|
+
this.name = "ToolArgsError";
|
|
1803
|
+
this.toolCallId = toolCallId;
|
|
1804
|
+
this.toolName = toolName;
|
|
1805
|
+
this.rawArguments = rawArguments;
|
|
1806
|
+
}
|
|
1807
|
+
};
|
|
1808
|
+
function parseToolArgs(call, schema) {
|
|
1809
|
+
const toolName = call.function?.name ?? "unknown";
|
|
1810
|
+
const rawArgs = call.function?.arguments ?? "";
|
|
1811
|
+
let parsed;
|
|
1812
|
+
try {
|
|
1813
|
+
parsed = rawArgs ? JSON.parse(rawArgs) : {};
|
|
1814
|
+
} catch (err) {
|
|
1815
|
+
const message = err instanceof Error ? err.message : "Invalid JSON in arguments";
|
|
1816
|
+
throw new ToolArgsError(
|
|
1817
|
+
`Failed to parse arguments for tool '${toolName}': ${message}`,
|
|
1818
|
+
call.id,
|
|
1819
|
+
toolName,
|
|
1820
|
+
rawArgs
|
|
1821
|
+
);
|
|
1822
|
+
}
|
|
1823
|
+
try {
|
|
1824
|
+
return schema.parse(parsed);
|
|
1825
|
+
} catch (err) {
|
|
1826
|
+
let message;
|
|
1827
|
+
if (err instanceof Error) {
|
|
1828
|
+
const zodErr = err;
|
|
1829
|
+
if (zodErr.errors && Array.isArray(zodErr.errors)) {
|
|
1830
|
+
const issues = zodErr.errors.map((e) => {
|
|
1831
|
+
const path = e.path.length > 0 ? `${e.path.join(".")}: ` : "";
|
|
1832
|
+
return `${path}${e.message}`;
|
|
1833
|
+
}).join("; ");
|
|
1834
|
+
message = issues;
|
|
1835
|
+
} else {
|
|
1836
|
+
message = err.message;
|
|
1837
|
+
}
|
|
1838
|
+
} else {
|
|
1839
|
+
message = String(err);
|
|
1840
|
+
}
|
|
1841
|
+
throw new ToolArgsError(
|
|
1842
|
+
`Invalid arguments for tool '${toolName}': ${message}`,
|
|
1843
|
+
call.id,
|
|
1844
|
+
toolName,
|
|
1845
|
+
rawArgs
|
|
1846
|
+
);
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
function tryParseToolArgs(call, schema) {
|
|
1850
|
+
try {
|
|
1851
|
+
const data = parseToolArgs(call, schema);
|
|
1852
|
+
return { success: true, data };
|
|
1853
|
+
} catch (err) {
|
|
1854
|
+
if (err instanceof ToolArgsError) {
|
|
1855
|
+
return { success: false, error: err };
|
|
1856
|
+
}
|
|
1857
|
+
const toolName = call.function?.name ?? "unknown";
|
|
1858
|
+
const rawArgs = call.function?.arguments ?? "";
|
|
1859
|
+
return {
|
|
1860
|
+
success: false,
|
|
1861
|
+
error: new ToolArgsError(
|
|
1862
|
+
err instanceof Error ? err.message : String(err),
|
|
1863
|
+
call.id,
|
|
1864
|
+
toolName,
|
|
1865
|
+
rawArgs
|
|
1866
|
+
)
|
|
1867
|
+
};
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
function parseToolArgsRaw(call) {
|
|
1871
|
+
const toolName = call.function?.name ?? "unknown";
|
|
1872
|
+
const rawArgs = call.function?.arguments ?? "";
|
|
1873
|
+
try {
|
|
1874
|
+
return rawArgs ? JSON.parse(rawArgs) : {};
|
|
1875
|
+
} catch (err) {
|
|
1876
|
+
const message = err instanceof Error ? err.message : "Invalid JSON in arguments";
|
|
1877
|
+
throw new ToolArgsError(
|
|
1878
|
+
`Failed to parse arguments for tool '${toolName}': ${message}`,
|
|
1879
|
+
call.id,
|
|
1880
|
+
toolName,
|
|
1881
|
+
rawArgs
|
|
1882
|
+
);
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
var ToolRegistry = class {
|
|
1886
|
+
constructor() {
|
|
1887
|
+
this.handlers = /* @__PURE__ */ new Map();
|
|
1888
|
+
}
|
|
1889
|
+
/**
|
|
1890
|
+
* Registers a handler function for a tool name.
|
|
1891
|
+
* @param name - The tool name (must match the function name in the tool definition)
|
|
1892
|
+
* @param handler - Function to execute when this tool is called
|
|
1893
|
+
* @returns this for chaining
|
|
1894
|
+
*/
|
|
1895
|
+
register(name, handler) {
|
|
1896
|
+
this.handlers.set(name, handler);
|
|
1897
|
+
return this;
|
|
1898
|
+
}
|
|
1899
|
+
/**
|
|
1900
|
+
* Unregisters a tool handler.
|
|
1901
|
+
* @param name - The tool name to unregister
|
|
1902
|
+
* @returns true if the handler was removed, false if it didn't exist
|
|
1903
|
+
*/
|
|
1904
|
+
unregister(name) {
|
|
1905
|
+
return this.handlers.delete(name);
|
|
1906
|
+
}
|
|
1907
|
+
/**
|
|
1908
|
+
* Checks if a handler is registered for the given tool name.
|
|
1909
|
+
*/
|
|
1910
|
+
has(name) {
|
|
1911
|
+
return this.handlers.has(name);
|
|
1912
|
+
}
|
|
1913
|
+
/**
|
|
1914
|
+
* Returns the list of registered tool names.
|
|
1915
|
+
*/
|
|
1916
|
+
getRegisteredTools() {
|
|
1917
|
+
return Array.from(this.handlers.keys());
|
|
1918
|
+
}
|
|
1919
|
+
/**
|
|
1920
|
+
* Executes a single tool call.
|
|
1921
|
+
* @param call - The tool call to execute
|
|
1922
|
+
* @returns The execution result
|
|
1923
|
+
*/
|
|
1924
|
+
async execute(call) {
|
|
1925
|
+
const toolName = call.function?.name ?? "";
|
|
1926
|
+
const handler = this.handlers.get(toolName);
|
|
1927
|
+
if (!handler) {
|
|
1928
|
+
return {
|
|
1929
|
+
toolCallId: call.id,
|
|
1930
|
+
toolName,
|
|
1931
|
+
result: null,
|
|
1932
|
+
error: `Unknown tool: '${toolName}'. Available tools: ${this.getRegisteredTools().join(", ") || "none"}`
|
|
1933
|
+
};
|
|
1934
|
+
}
|
|
1935
|
+
let args;
|
|
1936
|
+
try {
|
|
1937
|
+
args = call.function?.arguments ? JSON.parse(call.function.arguments) : {};
|
|
1938
|
+
} catch (err) {
|
|
1939
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
1940
|
+
return {
|
|
1941
|
+
toolCallId: call.id,
|
|
1942
|
+
toolName,
|
|
1943
|
+
result: null,
|
|
1944
|
+
error: `Invalid JSON in arguments: ${errorMessage}`,
|
|
1945
|
+
isRetryable: true
|
|
1946
|
+
};
|
|
1947
|
+
}
|
|
1948
|
+
try {
|
|
1949
|
+
const result = await handler(args, call);
|
|
1950
|
+
return {
|
|
1951
|
+
toolCallId: call.id,
|
|
1952
|
+
toolName,
|
|
1953
|
+
result
|
|
1954
|
+
};
|
|
1955
|
+
} catch (err) {
|
|
1956
|
+
const isRetryable = err instanceof ToolArgsError;
|
|
1957
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
1958
|
+
return {
|
|
1959
|
+
toolCallId: call.id,
|
|
1960
|
+
toolName,
|
|
1961
|
+
result: null,
|
|
1962
|
+
error: errorMessage,
|
|
1963
|
+
isRetryable
|
|
1964
|
+
};
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
/**
|
|
1968
|
+
* Executes multiple tool calls in parallel.
|
|
1969
|
+
* @param calls - Array of tool calls to execute
|
|
1970
|
+
* @returns Array of execution results in the same order as input
|
|
1971
|
+
*/
|
|
1972
|
+
async executeAll(calls) {
|
|
1973
|
+
return Promise.all(calls.map((call) => this.execute(call)));
|
|
1974
|
+
}
|
|
1975
|
+
/**
|
|
1976
|
+
* Converts execution results to tool result messages.
|
|
1977
|
+
* Useful for appending to the conversation history.
|
|
1978
|
+
* @param results - Array of execution results
|
|
1979
|
+
* @returns Array of ChatMessage objects with role "tool"
|
|
1980
|
+
*/
|
|
1981
|
+
resultsToMessages(results) {
|
|
1982
|
+
return results.map((r) => {
|
|
1983
|
+
const content = r.error ? `Error: ${r.error}` : typeof r.result === "string" ? r.result : JSON.stringify(r.result);
|
|
1984
|
+
return toolResultMessage(r.toolCallId, content);
|
|
1985
|
+
});
|
|
1986
|
+
}
|
|
1987
|
+
};
|
|
1988
|
+
function formatToolErrorForModel(result) {
|
|
1989
|
+
const lines = [
|
|
1990
|
+
`Tool call error for '${result.toolName}': ${result.error}`
|
|
1991
|
+
];
|
|
1992
|
+
if (result.isRetryable) {
|
|
1993
|
+
lines.push("");
|
|
1994
|
+
lines.push("Please correct the arguments and try again.");
|
|
1995
|
+
}
|
|
1996
|
+
return lines.join("\n");
|
|
1997
|
+
}
|
|
1998
|
+
function hasRetryableErrors(results) {
|
|
1999
|
+
return results.some((r) => r.error && r.isRetryable);
|
|
2000
|
+
}
|
|
2001
|
+
function getRetryableErrors(results) {
|
|
2002
|
+
return results.filter((r) => r.error && r.isRetryable);
|
|
2003
|
+
}
|
|
2004
|
+
function createRetryMessages(results) {
|
|
2005
|
+
return results.filter((r) => r.error && r.isRetryable).map((r) => toolResultMessage(r.toolCallId, formatToolErrorForModel(r)));
|
|
2006
|
+
}
|
|
2007
|
+
async function executeWithRetry(registry, toolCalls, options = {}) {
|
|
2008
|
+
const maxRetries = options.maxRetries ?? 2;
|
|
2009
|
+
let currentCalls = toolCalls;
|
|
2010
|
+
let attempt = 0;
|
|
2011
|
+
const successfulResults = /* @__PURE__ */ new Map();
|
|
2012
|
+
while (attempt <= maxRetries) {
|
|
2013
|
+
const results = await registry.executeAll(currentCalls);
|
|
2014
|
+
for (const result of results) {
|
|
2015
|
+
if (!result.error || !result.isRetryable) {
|
|
2016
|
+
successfulResults.set(result.toolCallId, result);
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
const retryableResults = getRetryableErrors(results);
|
|
2020
|
+
if (retryableResults.length === 0 || !options.onRetry) {
|
|
2021
|
+
for (const result of results) {
|
|
2022
|
+
if (result.error && result.isRetryable) {
|
|
2023
|
+
successfulResults.set(result.toolCallId, result);
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
return Array.from(successfulResults.values());
|
|
2027
|
+
}
|
|
2028
|
+
attempt++;
|
|
2029
|
+
if (attempt > maxRetries) {
|
|
2030
|
+
for (const result of retryableResults) {
|
|
2031
|
+
successfulResults.set(result.toolCallId, result);
|
|
2032
|
+
}
|
|
2033
|
+
return Array.from(successfulResults.values());
|
|
2034
|
+
}
|
|
2035
|
+
const errorMessages = createRetryMessages(retryableResults);
|
|
2036
|
+
const newCalls = await options.onRetry(errorMessages, attempt);
|
|
2037
|
+
if (newCalls.length === 0) {
|
|
2038
|
+
for (const result of retryableResults) {
|
|
2039
|
+
successfulResults.set(result.toolCallId, result);
|
|
2040
|
+
}
|
|
2041
|
+
return Array.from(successfulResults.values());
|
|
2042
|
+
}
|
|
2043
|
+
currentCalls = newCalls;
|
|
2044
|
+
}
|
|
2045
|
+
return Array.from(successfulResults.values());
|
|
2046
|
+
}
|
|
2047
|
+
|
|
1297
2048
|
// src/index.ts
|
|
1298
2049
|
var ModelRelay = class {
|
|
1299
2050
|
constructor(options) {
|
|
@@ -1301,7 +2052,7 @@ var ModelRelay = class {
|
|
|
1301
2052
|
if (!cfg.key && !cfg.token) {
|
|
1302
2053
|
throw new ConfigError("Provide an API key or access token");
|
|
1303
2054
|
}
|
|
1304
|
-
this.baseUrl = resolveBaseUrl(cfg.
|
|
2055
|
+
this.baseUrl = resolveBaseUrl(cfg.baseUrl);
|
|
1305
2056
|
const http = new HTTPClient({
|
|
1306
2057
|
baseUrl: this.baseUrl,
|
|
1307
2058
|
apiKey: cfg.key,
|
|
@@ -1312,7 +2063,6 @@ var ModelRelay = class {
|
|
|
1312
2063
|
timeoutMs: cfg.timeoutMs,
|
|
1313
2064
|
retry: cfg.retry,
|
|
1314
2065
|
defaultHeaders: cfg.defaultHeaders,
|
|
1315
|
-
environment: cfg.environment,
|
|
1316
2066
|
metrics: cfg.metrics,
|
|
1317
2067
|
trace: cfg.trace
|
|
1318
2068
|
});
|
|
@@ -1335,8 +2085,8 @@ var ModelRelay = class {
|
|
|
1335
2085
|
});
|
|
1336
2086
|
}
|
|
1337
2087
|
};
|
|
1338
|
-
function resolveBaseUrl(
|
|
1339
|
-
const base = override ||
|
|
2088
|
+
function resolveBaseUrl(override) {
|
|
2089
|
+
const base = override || DEFAULT_BASE_URL;
|
|
1340
2090
|
return base.replace(/\/+$/, "");
|
|
1341
2091
|
}
|
|
1342
2092
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1355,12 +2105,26 @@ function resolveBaseUrl(env, override) {
|
|
|
1355
2105
|
ModelRelayError,
|
|
1356
2106
|
Models,
|
|
1357
2107
|
Providers,
|
|
1358
|
-
SANDBOX_BASE_URL,
|
|
1359
2108
|
SDK_VERSION,
|
|
1360
|
-
STAGING_BASE_URL,
|
|
1361
2109
|
StopReasons,
|
|
1362
2110
|
TiersClient,
|
|
2111
|
+
ToolArgsError,
|
|
2112
|
+
ToolCallAccumulator,
|
|
2113
|
+
ToolChoiceTypes,
|
|
2114
|
+
ToolRegistry,
|
|
2115
|
+
ToolTypes,
|
|
1363
2116
|
TransportError,
|
|
2117
|
+
assistantMessageWithToolCalls,
|
|
2118
|
+
createFunctionTool,
|
|
2119
|
+
createFunctionToolFromSchema,
|
|
2120
|
+
createRetryMessages,
|
|
2121
|
+
createWebSearchTool,
|
|
2122
|
+
executeWithRetry,
|
|
2123
|
+
firstToolCall,
|
|
2124
|
+
formatToolErrorForModel,
|
|
2125
|
+
getRetryableErrors,
|
|
2126
|
+
hasRetryableErrors,
|
|
2127
|
+
hasToolCalls,
|
|
1364
2128
|
isPublishableKey,
|
|
1365
2129
|
mergeMetrics,
|
|
1366
2130
|
mergeTrace,
|
|
@@ -1369,6 +2133,15 @@ function resolveBaseUrl(env, override) {
|
|
|
1369
2133
|
normalizeProvider,
|
|
1370
2134
|
normalizeStopReason,
|
|
1371
2135
|
parseErrorResponse,
|
|
2136
|
+
parseToolArgs,
|
|
2137
|
+
parseToolArgsRaw,
|
|
1372
2138
|
providerToString,
|
|
1373
|
-
|
|
2139
|
+
respondToToolCall,
|
|
2140
|
+
stopReasonToString,
|
|
2141
|
+
toolChoiceAuto,
|
|
2142
|
+
toolChoiceNone,
|
|
2143
|
+
toolChoiceRequired,
|
|
2144
|
+
toolResultMessage,
|
|
2145
|
+
tryParseToolArgs,
|
|
2146
|
+
zodToJsonSchema
|
|
1374
2147
|
});
|