@yourgpt/llm-sdk 2.6.0-beta.2 → 2.6.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.
Files changed (74) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +87 -17
  3. package/dist/adapters/index.d.mts +11 -13
  4. package/dist/adapters/index.d.ts +11 -13
  5. package/dist/adapters/index.js +406 -114
  6. package/dist/adapters/index.mjs +406 -114
  7. package/dist/audio-K-Z3-Bce.d.mts +191 -0
  8. package/dist/audio-K-Z3-Bce.d.ts +191 -0
  9. package/dist/{base-BICaQaRS.d.mts → base-6LzczuCg.d.ts} +8 -1
  10. package/dist/{base-CpRPB8u8.d.ts → base-DySbTP8C.d.mts} +8 -1
  11. package/dist/decisions-CJzOt87t.d.mts +137 -0
  12. package/dist/decisions-CJzOt87t.d.ts +137 -0
  13. package/dist/fallback/index.d.mts +4 -4
  14. package/dist/fallback/index.d.ts +4 -4
  15. package/dist/http-BQxUT5A9.d.mts +9 -0
  16. package/dist/http-BQxUT5A9.d.ts +9 -0
  17. package/dist/index.d.mts +17 -9
  18. package/dist/index.d.ts +17 -9
  19. package/dist/index.js +698 -205
  20. package/dist/index.mjs +695 -206
  21. package/dist/providers/anthropic/index.d.mts +7 -4
  22. package/dist/providers/anthropic/index.d.ts +7 -4
  23. package/dist/providers/anthropic/index.js +389 -115
  24. package/dist/providers/anthropic/index.mjs +389 -115
  25. package/dist/providers/azure/index.d.mts +3 -3
  26. package/dist/providers/azure/index.d.ts +3 -3
  27. package/dist/providers/cloudflare/index.d.mts +11 -0
  28. package/dist/providers/cloudflare/index.d.ts +11 -0
  29. package/dist/providers/cloudflare/index.js +743 -0
  30. package/dist/providers/cloudflare/index.mjs +741 -0
  31. package/dist/providers/fireworks/index.d.mts +3 -3
  32. package/dist/providers/fireworks/index.d.ts +3 -3
  33. package/dist/providers/fireworks/index.js +181 -60
  34. package/dist/providers/fireworks/index.mjs +181 -60
  35. package/dist/providers/google/index.d.mts +3 -3
  36. package/dist/providers/google/index.d.ts +3 -3
  37. package/dist/providers/google/index.js +181 -60
  38. package/dist/providers/google/index.mjs +181 -60
  39. package/dist/providers/ollama/index.d.mts +4 -4
  40. package/dist/providers/ollama/index.d.ts +4 -4
  41. package/dist/providers/openai/index.d.mts +38 -6
  42. package/dist/providers/openai/index.d.ts +38 -6
  43. package/dist/providers/openai/index.js +1451 -85
  44. package/dist/providers/openai/index.mjs +1449 -86
  45. package/dist/providers/openrouter/index.d.mts +21 -4
  46. package/dist/providers/openrouter/index.d.ts +21 -4
  47. package/dist/providers/openrouter/index.js +1040 -131
  48. package/dist/providers/openrouter/index.mjs +1040 -132
  49. package/dist/providers/togetherai/index.d.mts +3 -3
  50. package/dist/providers/togetherai/index.d.ts +3 -3
  51. package/dist/providers/togetherai/index.js +181 -60
  52. package/dist/providers/togetherai/index.mjs +181 -60
  53. package/dist/providers/typesafe/index.d.mts +8 -0
  54. package/dist/providers/typesafe/index.d.ts +8 -0
  55. package/dist/providers/typesafe/index.js +735 -0
  56. package/dist/providers/typesafe/index.mjs +733 -0
  57. package/dist/providers/xai/index.d.mts +3 -3
  58. package/dist/providers/xai/index.d.ts +3 -3
  59. package/dist/providers/xai/index.js +181 -60
  60. package/dist/providers/xai/index.mjs +181 -60
  61. package/dist/{types-DCFqkJAy.d.ts → types-B0y6VZSQ.d.ts} +1 -1
  62. package/dist/{types-DHQEMFHA.d.mts → types-BXQMtaCX.d.ts} +17 -3
  63. package/dist/{types-C3RgRbEC.d.mts → types-BY6BVhFg.d.mts} +1 -1
  64. package/dist/{types-Dikj3En4.d.ts → types-C7_qVSSd.d.mts} +17 -3
  65. package/dist/{types-Dg1Bcg1k.d.mts → types-D7lzMMLu.d.mts} +13 -1
  66. package/dist/{types-Dg1Bcg1k.d.ts → types-D7lzMMLu.d.ts} +13 -1
  67. package/dist/yourgpt/index.d.mts +1 -1
  68. package/dist/yourgpt/index.d.ts +1 -1
  69. package/docs/decisions.md +174 -0
  70. package/docs/media.md +201 -0
  71. package/docs/multimodal-and-audio.md +9 -2
  72. package/package.json +34 -12
  73. package/dist/audio-BBSwnjo8.d.mts +0 -92
  74. package/dist/audio-BBSwnjo8.d.ts +0 -92
@@ -1,7 +1,7 @@
1
- import { L as LanguageModel } from '../../types-Dg1Bcg1k.mjs';
2
- import { A as AIProvider } from '../../types-DHQEMFHA.mjs';
1
+ import { L as LanguageModel } from '../../types-D7lzMMLu.mjs';
2
+ import { A as AIProvider } from '../../types-C7_qVSSd.mjs';
3
3
  import 'zod';
4
- import '../../base-BICaQaRS.mjs';
4
+ import '../../base-DySbTP8C.mjs';
5
5
 
6
6
  /**
7
7
  * Fireworks Provider
@@ -1,7 +1,7 @@
1
- import { L as LanguageModel } from '../../types-Dg1Bcg1k.js';
2
- import { A as AIProvider } from '../../types-Dikj3En4.js';
1
+ import { L as LanguageModel } from '../../types-D7lzMMLu.js';
2
+ import { A as AIProvider } from '../../types-BXQMtaCX.js';
3
3
  import 'zod';
4
- import '../../base-CpRPB8u8.js';
4
+ import '../../base-6LzczuCg.js';
5
5
 
6
6
  /**
7
7
  * Fireworks Provider
@@ -113,6 +113,19 @@ function capabilities(model) {
113
113
  const supportsNone = major === 5 && minor >= 1 && !chat || /^gpt-6-(?:sol|luna)(?:-\d{4}-\d{2}-\d{2})?$/i.test(model);
114
114
  return { major, minor, reasoning, supportsNone };
115
115
  }
116
+ function filterOpenAIResponseInclude(model, include, options = {}) {
117
+ const c = capabilities(model);
118
+ let result = include;
119
+ if (options.parameterPolicy !== "passthrough" && c.reasoning && !(options.reasoningEffort === "none" && c.supportsNone) && include.includes("message.output_text.logprobs")) {
120
+ result = include.filter(
121
+ (value) => value !== "message.output_text.logprobs"
122
+ );
123
+ (options.onWarning ?? console.warn)(
124
+ `[llm-sdk] ${model}: omitted message.output_text.logprobs because reasoning is enabled.`
125
+ );
126
+ }
127
+ return result.length ? result : void 0;
128
+ }
116
129
  function requiresOpenAIResponses(model, baseUrl, options = {}) {
117
130
  if (options.parameterPolicy === "passthrough") return false;
118
131
  const c = capabilities(model);
@@ -274,6 +287,7 @@ function toOpenAIResponseFormat(rf) {
274
287
  };
275
288
  }
276
289
  function toOpenAIResponsesTextFormat(rf) {
290
+ if (rf?.type === "json_object") return { type: "json_object" };
277
291
  if (!rf || rf.type !== "json_schema") return void 0;
278
292
  return {
279
293
  type: "json_schema",
@@ -588,6 +602,63 @@ function formatMessages(messages) {
588
602
  });
589
603
  }
590
604
 
605
+ // src/core/provider-error.ts
606
+ function invalidProviderResponse(message) {
607
+ return Object.assign(new Error(message), {
608
+ name: "InvalidProviderResponseError",
609
+ status: 502,
610
+ code: "INVALID_PROVIDER_RESPONSE"
611
+ });
612
+ }
613
+ function providerErrorEvent(error, code) {
614
+ const details = error ?? {};
615
+ const event = {
616
+ type: "error",
617
+ message: error instanceof Error ? error.message : String(error),
618
+ code,
619
+ ...typeof details.status === "number" ? { status: details.status } : {},
620
+ ...typeof details.code === "string" ? { providerCode: details.code } : {},
621
+ ...typeof details.param === "string" ? { param: details.param } : {},
622
+ ...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
623
+ };
624
+ Object.defineProperty(event, "cause", { value: error, enumerable: false });
625
+ return event;
626
+ }
627
+ function throwIfAborted(signal) {
628
+ if (!signal?.aborted) return;
629
+ const error = new Error("The operation was aborted");
630
+ error.name = "AbortError";
631
+ throw error;
632
+ }
633
+
634
+ // src/core/tool-validation.ts
635
+ function parseToolArguments(value) {
636
+ let args = value;
637
+ if (typeof value === "string") {
638
+ try {
639
+ args = JSON.parse(value || "{}");
640
+ } catch {
641
+ throw invalidProviderResponse("Tool arguments are not valid JSON");
642
+ }
643
+ }
644
+ if (args === null || typeof args !== "object" || Array.isArray(args))
645
+ throw invalidProviderResponse("Tool arguments must be a JSON object");
646
+ return args;
647
+ }
648
+ function validateToolCalls(calls) {
649
+ const ids = /* @__PURE__ */ new Set();
650
+ for (const call of calls) {
651
+ if (!call || typeof call.id !== "string" || !call.id || typeof call.name !== "string" || !call.name || ids.has(call.id))
652
+ throw invalidProviderResponse(
653
+ "Tool calls have missing or duplicate identities"
654
+ );
655
+ ids.add(call.id);
656
+ if (typeof call.args === "string")
657
+ throw invalidProviderResponse("Parsed tool arguments must be an object");
658
+ parseToolArguments(call.args);
659
+ }
660
+ }
661
+
591
662
  // src/core/openai-responses.ts
592
663
  function resolveOpenAITransport(defaults, overrides) {
593
664
  return {
@@ -635,6 +706,54 @@ function responseMetadata(response) {
635
706
  }
636
707
  };
637
708
  }
709
+ function responseReplayMetadata(metadata) {
710
+ const response = metadata?.openai?.response;
711
+ if (!response) return metadata;
712
+ const output = response.output.map((item) => {
713
+ const fields = ["type", "id", "status"];
714
+ switch (item.type) {
715
+ case "reasoning":
716
+ fields.push("encrypted_content");
717
+ break;
718
+ case "message":
719
+ fields.push("role", "phase");
720
+ break;
721
+ case "function_call":
722
+ fields.push("call_id", "name", "namespace", "arguments");
723
+ break;
724
+ case "tool_search_call":
725
+ fields.push("call_id", "execution", "arguments");
726
+ break;
727
+ case "tool_search_output":
728
+ fields.push("call_id", "tools");
729
+ break;
730
+ case "web_search_call":
731
+ fields.push("action");
732
+ break;
733
+ default:
734
+ return stripItemDiagnostics(item);
735
+ }
736
+ const replay = Object.fromEntries(
737
+ fields.filter((key) => item[key] !== void 0).map((key) => [key, item[key]])
738
+ );
739
+ if (item.type === "reasoning") replay.summary = [];
740
+ if (item.type === "message")
741
+ replay.content = Array.isArray(item.content) ? item.content.flatMap(
742
+ (part) => part?.type === "output_text" && typeof part.text === "string" ? [{ type: "output_text", text: part.text, annotations: [] }] : part?.type === "refusal" && typeof part.refusal === "string" ? [{ type: "refusal", refusal: part.refusal }] : []
743
+ ) : [];
744
+ return stripItemDiagnostics(replay);
745
+ });
746
+ return { openai: { response: { output, refusals: [] } } };
747
+ }
748
+ function stripItemDiagnostics(item) {
749
+ const {
750
+ usage: _usage,
751
+ logprobs: _logprobs,
752
+ metadata: _metadata,
753
+ ...state
754
+ } = item;
755
+ return state;
756
+ }
638
757
  function getResponseReplay(metadata) {
639
758
  const response = metadata?.openai?.response;
640
759
  if (response === void 0) return void 0;
@@ -643,29 +762,7 @@ function getResponseReplay(metadata) {
643
762
  "Invalid OpenAI Responses replay metadata: output must contain typed items"
644
763
  );
645
764
  }
646
- return response.output;
647
- }
648
-
649
- // src/core/provider-error.ts
650
- function providerErrorEvent(error, code) {
651
- const details = error ?? {};
652
- const event = {
653
- type: "error",
654
- message: error instanceof Error ? error.message : String(error),
655
- code,
656
- ...typeof details.status === "number" ? { status: details.status } : {},
657
- ...typeof details.code === "string" ? { providerCode: details.code } : {},
658
- ...typeof details.param === "string" ? { param: details.param } : {},
659
- ...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
660
- };
661
- Object.defineProperty(event, "cause", { value: error, enumerable: false });
662
- return event;
663
- }
664
- function throwIfAborted(signal) {
665
- if (!signal?.aborted) return;
666
- const error = new Error("The operation was aborted");
667
- error.name = "AbortError";
668
- throw error;
765
+ return responseReplayMetadata(metadata)?.openai?.response?.output;
669
766
  }
670
767
 
671
768
  // src/core/utils.ts
@@ -675,9 +772,6 @@ function generateId(prefix = "id") {
675
772
  function generateMessageId() {
676
773
  return generateId("msg");
677
774
  }
678
- function generateToolCallId() {
679
- return generateId("call");
680
- }
681
775
 
682
776
  // src/adapters/openai.ts
683
777
  var OpenAIAdapter = class _OpenAIAdapter {
@@ -701,6 +795,8 @@ var OpenAIAdapter = class _OpenAIAdapter {
701
795
  apiKey: this.config.apiKey,
702
796
  baseURL: this.config.baseUrl,
703
797
  organization: this.config.organization,
798
+ project: this.config.project,
799
+ timeout: this.config.timeout,
704
800
  defaultHeaders: this.config.headers
705
801
  });
706
802
  }
@@ -823,7 +919,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
823
919
  formatRawMessages(messages, preserveProviderMetadata = false) {
824
920
  return messages.map((message) => {
825
921
  const { attachments, providerMetadata, modelOutput, ...rest } = message;
826
- let content = message.role === "tool" && !preserveProviderMetadata ? textToolOutput(modelOutput, String(message.content ?? "")) : message.content;
922
+ let content = message.role === "tool" && !preserveProviderMetadata && modelOutput !== void 0 ? textToolOutput(modelOutput, "") : message.content;
827
923
  if (preserveProviderMetadata && modelOutput)
828
924
  rest.modelOutput = modelOutput;
829
925
  if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
@@ -926,17 +1022,32 @@ var OpenAIAdapter = class _OpenAIAdapter {
926
1022
  const seenCallIds = /* @__PURE__ */ new Set();
927
1023
  const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => {
928
1024
  if (typeof item.call_id !== "string" || !item.call_id || typeof item.name !== "string" || !item.name || typeof item.arguments !== "string" || item.status && item.status !== "completed") {
929
- throw new Error("Responses contains an incomplete function call");
1025
+ throw invalidProviderResponse(
1026
+ "Responses contains an incomplete function call"
1027
+ );
930
1028
  }
931
1029
  if (seenCallIds.has(item.call_id))
932
- throw new Error("Responses contains duplicate function call IDs");
1030
+ throw invalidProviderResponse(
1031
+ "Responses contains duplicate function call IDs"
1032
+ );
933
1033
  seenCallIds.add(item.call_id);
934
- const args = JSON.parse(item.arguments);
1034
+ let args;
1035
+ try {
1036
+ args = JSON.parse(item.arguments);
1037
+ } catch {
1038
+ throw invalidProviderResponse(
1039
+ "Responses function arguments must be valid JSON"
1040
+ );
1041
+ }
935
1042
  if (!args || typeof args !== "object" || Array.isArray(args))
936
- throw new Error(
1043
+ throw invalidProviderResponse(
937
1044
  "Responses function arguments must be a JSON object"
938
1045
  );
939
- return { id: item.call_id, name: item.name, args };
1046
+ return {
1047
+ id: item.call_id,
1048
+ name: item.name,
1049
+ args
1050
+ };
940
1051
  }) : [];
941
1052
  return {
942
1053
  content,
@@ -967,6 +1078,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
967
1078
  request.config?.responseFormat
968
1079
  );
969
1080
  const modelIdForPayload = request.config?.model || this.model;
1081
+ const include = filterOpenAIResponseInclude(
1082
+ modelIdForPayload,
1083
+ [
1084
+ .../* @__PURE__ */ new Set([
1085
+ ...options?.include ?? [],
1086
+ ...options?.store === false ? ["reasoning.encrypted_content"] : []
1087
+ ])
1088
+ ],
1089
+ this.parameterOptions(request)
1090
+ );
970
1091
  const payload = {
971
1092
  model: modelIdForPayload,
972
1093
  instructions: request.systemPrompt,
@@ -990,14 +1111,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
990
1111
  ...options?.promptCacheKey !== void 0 ? { prompt_cache_key: options.promptCacheKey } : {},
991
1112
  ...options?.promptCacheOptions !== void 0 ? { prompt_cache_options: options.promptCacheOptions } : {},
992
1113
  ...options?.promptCacheRetention !== void 0 ? { prompt_cache_retention: options.promptCacheRetention } : {},
993
- ...options?.store === false || options?.include ? {
994
- include: [
995
- .../* @__PURE__ */ new Set([
996
- ...options?.include ?? [],
997
- ...options?.store === false ? ["reasoning.encrypted_content"] : []
998
- ])
999
- ]
1000
- } : {},
1114
+ ...include ? { include } : {},
1001
1115
  ...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
1002
1116
  stream
1003
1117
  };
@@ -1179,7 +1293,9 @@ var OpenAIAdapter = class _OpenAIAdapter {
1179
1293
  const uniqueCalls = /* @__PURE__ */ new Map();
1180
1294
  for (const call of toolCalls.values()) {
1181
1295
  if (!call.id || !call.name)
1182
- throw new Error("Responses stream contains an incomplete tool call");
1296
+ throw invalidProviderResponse(
1297
+ "Responses stream contains an incomplete tool call"
1298
+ );
1183
1299
  uniqueCalls.set(call.id, call);
1184
1300
  }
1185
1301
  toolCalls.clear();
@@ -1366,15 +1482,20 @@ var OpenAIAdapter = class _OpenAIAdapter {
1366
1482
  }
1367
1483
  throwIfAborted(request.signal);
1368
1484
  if (!finishReason)
1369
- throw new Error("OpenAI stream ended without a finish reason");
1485
+ throw invalidProviderResponse(
1486
+ "OpenAI stream ended without a finish reason"
1487
+ );
1370
1488
  if (toolCalls.size && !["tool_calls", "function_call"].includes(finishReason)) {
1371
- throw new Error("OpenAI stream ended with incomplete tool calls");
1372
- }
1373
- for (const call of toolCalls.values()) {
1374
- if (!call.id || !call.name)
1375
- throw new Error("OpenAI stream contains an incomplete tool call");
1376
- JSON.parse(call.arguments || "{}");
1489
+ throw invalidProviderResponse(
1490
+ "OpenAI stream ended with incomplete tool calls"
1491
+ );
1377
1492
  }
1493
+ validateToolCalls(
1494
+ [...toolCalls.values()].map((call) => ({
1495
+ ...call,
1496
+ args: parseToolArguments(call.arguments)
1497
+ }))
1498
+ );
1378
1499
  for (const call of toolCalls.values()) {
1379
1500
  yield {
1380
1501
  type: "action:start",
@@ -1458,20 +1579,20 @@ var OpenAIAdapter = class _OpenAIAdapter {
1458
1579
  logProviderPayload("openai", "response payload", response, request.debug);
1459
1580
  const choice = response.choices?.[0];
1460
1581
  const message = choice?.message;
1582
+ const toolCalls = (message?.tool_calls ?? []).map((toolCall) => ({
1583
+ id: toolCall.id,
1584
+ name: toolCall.function?.name,
1585
+ args: parseToolArguments(toolCall.function?.arguments ?? "{}"),
1586
+ ...toolCall.extra_content ? { extra_content: toolCall.extra_content } : {}
1587
+ }));
1588
+ validateToolCalls(toolCalls);
1589
+ if (toolCalls.length && choice?.finish_reason && !["tool_calls", "function_call"].includes(choice.finish_reason))
1590
+ throw invalidProviderResponse(
1591
+ "OpenAI response ended with incomplete tool calls"
1592
+ );
1461
1593
  return {
1462
1594
  content: message?.content ?? "",
1463
- toolCalls: message?.tool_calls?.map((toolCall) => ({
1464
- id: toolCall.id ?? generateToolCallId(),
1465
- name: toolCall.function?.name ?? "",
1466
- args: (() => {
1467
- try {
1468
- return JSON.parse(toolCall.function?.arguments ?? "{}");
1469
- } catch {
1470
- return {};
1471
- }
1472
- })(),
1473
- ...toolCall.extra_content ? { extra_content: toolCall.extra_content } : {}
1474
- })) ?? [],
1595
+ toolCalls,
1475
1596
  usage: response.usage ? {
1476
1597
  promptTokens: response.usage.prompt_tokens,
1477
1598
  completionTokens: response.usage.completion_tokens,