@yourgpt/llm-sdk 2.6.0-beta.3 → 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 +46 -10
  3. package/dist/adapters/index.d.mts +11 -13
  4. package/dist/adapters/index.d.ts +11 -13
  5. package/dist/adapters/index.js +327 -100
  6. package/dist/adapters/index.mjs +327 -100
  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 +14 -8
  18. package/dist/index.d.ts +14 -8
  19. package/dist/index.js +599 -195
  20. package/dist/index.mjs +596 -196
  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 +383 -102
  24. package/dist/providers/anthropic/index.mjs +383 -102
  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 +108 -59
  34. package/dist/providers/fireworks/index.mjs +108 -59
  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 +108 -59
  38. package/dist/providers/google/index.mjs +108 -59
  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 +1378 -84
  44. package/dist/providers/openai/index.mjs +1376 -85
  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 +967 -130
  48. package/dist/providers/openrouter/index.mjs +967 -131
  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 +108 -59
  52. package/dist/providers/togetherai/index.mjs +108 -59
  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 +108 -59
  60. package/dist/providers/xai/index.mjs +108 -59
  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
  * Together AI 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
  * Together AI 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",
@@ -593,6 +607,63 @@ function formatMessages(messages) {
593
607
  });
594
608
  }
595
609
 
610
+ // src/core/provider-error.ts
611
+ function invalidProviderResponse(message) {
612
+ return Object.assign(new Error(message), {
613
+ name: "InvalidProviderResponseError",
614
+ status: 502,
615
+ code: "INVALID_PROVIDER_RESPONSE"
616
+ });
617
+ }
618
+ function providerErrorEvent(error, code) {
619
+ const details = error ?? {};
620
+ const event = {
621
+ type: "error",
622
+ message: error instanceof Error ? error.message : String(error),
623
+ code,
624
+ ...typeof details.status === "number" ? { status: details.status } : {},
625
+ ...typeof details.code === "string" ? { providerCode: details.code } : {},
626
+ ...typeof details.param === "string" ? { param: details.param } : {},
627
+ ...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
628
+ };
629
+ Object.defineProperty(event, "cause", { value: error, enumerable: false });
630
+ return event;
631
+ }
632
+ function throwIfAborted(signal) {
633
+ if (!signal?.aborted) return;
634
+ const error = new Error("The operation was aborted");
635
+ error.name = "AbortError";
636
+ throw error;
637
+ }
638
+
639
+ // src/core/tool-validation.ts
640
+ function parseToolArguments(value) {
641
+ let args = value;
642
+ if (typeof value === "string") {
643
+ try {
644
+ args = JSON.parse(value || "{}");
645
+ } catch {
646
+ throw invalidProviderResponse("Tool arguments are not valid JSON");
647
+ }
648
+ }
649
+ if (args === null || typeof args !== "object" || Array.isArray(args))
650
+ throw invalidProviderResponse("Tool arguments must be a JSON object");
651
+ return args;
652
+ }
653
+ function validateToolCalls(calls) {
654
+ const ids = /* @__PURE__ */ new Set();
655
+ for (const call of calls) {
656
+ if (!call || typeof call.id !== "string" || !call.id || typeof call.name !== "string" || !call.name || ids.has(call.id))
657
+ throw invalidProviderResponse(
658
+ "Tool calls have missing or duplicate identities"
659
+ );
660
+ ids.add(call.id);
661
+ if (typeof call.args === "string")
662
+ throw invalidProviderResponse("Parsed tool arguments must be an object");
663
+ parseToolArguments(call.args);
664
+ }
665
+ }
666
+
596
667
  // src/core/openai-responses.ts
597
668
  function resolveOpenAITransport(defaults, overrides) {
598
669
  return {
@@ -699,35 +770,6 @@ function getResponseReplay(metadata) {
699
770
  return responseReplayMetadata(metadata)?.openai?.response?.output;
700
771
  }
701
772
 
702
- // src/core/provider-error.ts
703
- function invalidProviderResponse(message) {
704
- return Object.assign(new Error(message), {
705
- name: "InvalidProviderResponseError",
706
- status: 502,
707
- code: "INVALID_PROVIDER_RESPONSE"
708
- });
709
- }
710
- function providerErrorEvent(error, code) {
711
- const details = error ?? {};
712
- const event = {
713
- type: "error",
714
- message: error instanceof Error ? error.message : String(error),
715
- code,
716
- ...typeof details.status === "number" ? { status: details.status } : {},
717
- ...typeof details.code === "string" ? { providerCode: details.code } : {},
718
- ...typeof details.param === "string" ? { param: details.param } : {},
719
- ...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
720
- };
721
- Object.defineProperty(event, "cause", { value: error, enumerable: false });
722
- return event;
723
- }
724
- function throwIfAborted(signal) {
725
- if (!signal?.aborted) return;
726
- const error = new Error("The operation was aborted");
727
- error.name = "AbortError";
728
- throw error;
729
- }
730
-
731
773
  // src/core/utils.ts
732
774
  function generateId(prefix = "id") {
733
775
  return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
@@ -735,9 +777,6 @@ function generateId(prefix = "id") {
735
777
  function generateMessageId() {
736
778
  return generateId("msg");
737
779
  }
738
- function generateToolCallId() {
739
- return generateId("call");
740
- }
741
780
 
742
781
  // src/adapters/openai.ts
743
782
  var OpenAIAdapter = class _OpenAIAdapter {
@@ -761,6 +800,8 @@ var OpenAIAdapter = class _OpenAIAdapter {
761
800
  apiKey: this.config.apiKey,
762
801
  baseURL: this.config.baseUrl,
763
802
  organization: this.config.organization,
803
+ project: this.config.project,
804
+ timeout: this.config.timeout,
764
805
  defaultHeaders: this.config.headers
765
806
  });
766
807
  }
@@ -1042,6 +1083,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
1042
1083
  request.config?.responseFormat
1043
1084
  );
1044
1085
  const modelIdForPayload = request.config?.model || this.model;
1086
+ const include = filterOpenAIResponseInclude(
1087
+ modelIdForPayload,
1088
+ [
1089
+ .../* @__PURE__ */ new Set([
1090
+ ...options?.include ?? [],
1091
+ ...options?.store === false ? ["reasoning.encrypted_content"] : []
1092
+ ])
1093
+ ],
1094
+ this.parameterOptions(request)
1095
+ );
1045
1096
  const payload = {
1046
1097
  model: modelIdForPayload,
1047
1098
  instructions: request.systemPrompt,
@@ -1065,14 +1116,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
1065
1116
  ...options?.promptCacheKey !== void 0 ? { prompt_cache_key: options.promptCacheKey } : {},
1066
1117
  ...options?.promptCacheOptions !== void 0 ? { prompt_cache_options: options.promptCacheOptions } : {},
1067
1118
  ...options?.promptCacheRetention !== void 0 ? { prompt_cache_retention: options.promptCacheRetention } : {},
1068
- ...options?.store === false || options?.include ? {
1069
- include: [
1070
- .../* @__PURE__ */ new Set([
1071
- ...options?.include ?? [],
1072
- ...options?.store === false ? ["reasoning.encrypted_content"] : []
1073
- ])
1074
- ]
1075
- } : {},
1119
+ ...include ? { include } : {},
1076
1120
  ...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
1077
1121
  stream
1078
1122
  };
@@ -1443,15 +1487,20 @@ var OpenAIAdapter = class _OpenAIAdapter {
1443
1487
  }
1444
1488
  throwIfAborted(request.signal);
1445
1489
  if (!finishReason)
1446
- throw new Error("OpenAI stream ended without a finish reason");
1490
+ throw invalidProviderResponse(
1491
+ "OpenAI stream ended without a finish reason"
1492
+ );
1447
1493
  if (toolCalls.size && !["tool_calls", "function_call"].includes(finishReason)) {
1448
- throw new Error("OpenAI stream ended with incomplete tool calls");
1449
- }
1450
- for (const call of toolCalls.values()) {
1451
- if (!call.id || !call.name)
1452
- throw new Error("OpenAI stream contains an incomplete tool call");
1453
- JSON.parse(call.arguments || "{}");
1494
+ throw invalidProviderResponse(
1495
+ "OpenAI stream ended with incomplete tool calls"
1496
+ );
1454
1497
  }
1498
+ validateToolCalls(
1499
+ [...toolCalls.values()].map((call) => ({
1500
+ ...call,
1501
+ args: parseToolArguments(call.arguments)
1502
+ }))
1503
+ );
1455
1504
  for (const call of toolCalls.values()) {
1456
1505
  yield {
1457
1506
  type: "action:start",
@@ -1535,20 +1584,20 @@ var OpenAIAdapter = class _OpenAIAdapter {
1535
1584
  logProviderPayload("openai", "response payload", response, request.debug);
1536
1585
  const choice = response.choices?.[0];
1537
1586
  const message = choice?.message;
1587
+ const toolCalls = (message?.tool_calls ?? []).map((toolCall) => ({
1588
+ id: toolCall.id,
1589
+ name: toolCall.function?.name,
1590
+ args: parseToolArguments(toolCall.function?.arguments ?? "{}"),
1591
+ ...toolCall.extra_content ? { extra_content: toolCall.extra_content } : {}
1592
+ }));
1593
+ validateToolCalls(toolCalls);
1594
+ if (toolCalls.length && choice?.finish_reason && !["tool_calls", "function_call"].includes(choice.finish_reason))
1595
+ throw invalidProviderResponse(
1596
+ "OpenAI response ended with incomplete tool calls"
1597
+ );
1538
1598
  return {
1539
1599
  content: message?.content ?? "",
1540
- toolCalls: message?.tool_calls?.map((toolCall) => ({
1541
- id: toolCall.id ?? generateToolCallId(),
1542
- name: toolCall.function?.name ?? "",
1543
- args: (() => {
1544
- try {
1545
- return JSON.parse(toolCall.function?.arguments ?? "{}");
1546
- } catch {
1547
- return {};
1548
- }
1549
- })(),
1550
- ...toolCall.extra_content ? { extra_content: toolCall.extra_content } : {}
1551
- })) ?? [],
1600
+ toolCalls,
1552
1601
  usage: response.usage ? {
1553
1602
  promptTokens: response.usage.prompt_tokens,
1554
1603
  completionTokens: response.usage.completion_tokens,
@@ -111,6 +111,19 @@ function capabilities(model) {
111
111
  const supportsNone = major === 5 && minor >= 1 && !chat || /^gpt-6-(?:sol|luna)(?:-\d{4}-\d{2}-\d{2})?$/i.test(model);
112
112
  return { major, minor, reasoning, supportsNone };
113
113
  }
114
+ function filterOpenAIResponseInclude(model, include, options = {}) {
115
+ const c = capabilities(model);
116
+ let result = include;
117
+ if (options.parameterPolicy !== "passthrough" && c.reasoning && !(options.reasoningEffort === "none" && c.supportsNone) && include.includes("message.output_text.logprobs")) {
118
+ result = include.filter(
119
+ (value) => value !== "message.output_text.logprobs"
120
+ );
121
+ (options.onWarning ?? console.warn)(
122
+ `[llm-sdk] ${model}: omitted message.output_text.logprobs because reasoning is enabled.`
123
+ );
124
+ }
125
+ return result.length ? result : void 0;
126
+ }
114
127
  function requiresOpenAIResponses(model, baseUrl, options = {}) {
115
128
  if (options.parameterPolicy === "passthrough") return false;
116
129
  const c = capabilities(model);
@@ -272,6 +285,7 @@ function toOpenAIResponseFormat(rf) {
272
285
  };
273
286
  }
274
287
  function toOpenAIResponsesTextFormat(rf) {
288
+ if (rf?.type === "json_object") return { type: "json_object" };
275
289
  if (!rf || rf.type !== "json_schema") return void 0;
276
290
  return {
277
291
  type: "json_schema",
@@ -591,6 +605,63 @@ function formatMessages(messages) {
591
605
  });
592
606
  }
593
607
 
608
+ // src/core/provider-error.ts
609
+ function invalidProviderResponse(message) {
610
+ return Object.assign(new Error(message), {
611
+ name: "InvalidProviderResponseError",
612
+ status: 502,
613
+ code: "INVALID_PROVIDER_RESPONSE"
614
+ });
615
+ }
616
+ function providerErrorEvent(error, code) {
617
+ const details = error ?? {};
618
+ const event = {
619
+ type: "error",
620
+ message: error instanceof Error ? error.message : String(error),
621
+ code,
622
+ ...typeof details.status === "number" ? { status: details.status } : {},
623
+ ...typeof details.code === "string" ? { providerCode: details.code } : {},
624
+ ...typeof details.param === "string" ? { param: details.param } : {},
625
+ ...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
626
+ };
627
+ Object.defineProperty(event, "cause", { value: error, enumerable: false });
628
+ return event;
629
+ }
630
+ function throwIfAborted(signal) {
631
+ if (!signal?.aborted) return;
632
+ const error = new Error("The operation was aborted");
633
+ error.name = "AbortError";
634
+ throw error;
635
+ }
636
+
637
+ // src/core/tool-validation.ts
638
+ function parseToolArguments(value) {
639
+ let args = value;
640
+ if (typeof value === "string") {
641
+ try {
642
+ args = JSON.parse(value || "{}");
643
+ } catch {
644
+ throw invalidProviderResponse("Tool arguments are not valid JSON");
645
+ }
646
+ }
647
+ if (args === null || typeof args !== "object" || Array.isArray(args))
648
+ throw invalidProviderResponse("Tool arguments must be a JSON object");
649
+ return args;
650
+ }
651
+ function validateToolCalls(calls) {
652
+ const ids = /* @__PURE__ */ new Set();
653
+ for (const call of calls) {
654
+ if (!call || typeof call.id !== "string" || !call.id || typeof call.name !== "string" || !call.name || ids.has(call.id))
655
+ throw invalidProviderResponse(
656
+ "Tool calls have missing or duplicate identities"
657
+ );
658
+ ids.add(call.id);
659
+ if (typeof call.args === "string")
660
+ throw invalidProviderResponse("Parsed tool arguments must be an object");
661
+ parseToolArguments(call.args);
662
+ }
663
+ }
664
+
594
665
  // src/core/openai-responses.ts
595
666
  function resolveOpenAITransport(defaults, overrides) {
596
667
  return {
@@ -697,35 +768,6 @@ function getResponseReplay(metadata) {
697
768
  return responseReplayMetadata(metadata)?.openai?.response?.output;
698
769
  }
699
770
 
700
- // src/core/provider-error.ts
701
- function invalidProviderResponse(message) {
702
- return Object.assign(new Error(message), {
703
- name: "InvalidProviderResponseError",
704
- status: 502,
705
- code: "INVALID_PROVIDER_RESPONSE"
706
- });
707
- }
708
- function providerErrorEvent(error, code) {
709
- const details = error ?? {};
710
- const event = {
711
- type: "error",
712
- message: error instanceof Error ? error.message : String(error),
713
- code,
714
- ...typeof details.status === "number" ? { status: details.status } : {},
715
- ...typeof details.code === "string" ? { providerCode: details.code } : {},
716
- ...typeof details.param === "string" ? { param: details.param } : {},
717
- ...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
718
- };
719
- Object.defineProperty(event, "cause", { value: error, enumerable: false });
720
- return event;
721
- }
722
- function throwIfAborted(signal) {
723
- if (!signal?.aborted) return;
724
- const error = new Error("The operation was aborted");
725
- error.name = "AbortError";
726
- throw error;
727
- }
728
-
729
771
  // src/core/utils.ts
730
772
  function generateId(prefix = "id") {
731
773
  return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
@@ -733,9 +775,6 @@ function generateId(prefix = "id") {
733
775
  function generateMessageId() {
734
776
  return generateId("msg");
735
777
  }
736
- function generateToolCallId() {
737
- return generateId("call");
738
- }
739
778
 
740
779
  // src/adapters/openai.ts
741
780
  var OpenAIAdapter = class _OpenAIAdapter {
@@ -759,6 +798,8 @@ var OpenAIAdapter = class _OpenAIAdapter {
759
798
  apiKey: this.config.apiKey,
760
799
  baseURL: this.config.baseUrl,
761
800
  organization: this.config.organization,
801
+ project: this.config.project,
802
+ timeout: this.config.timeout,
762
803
  defaultHeaders: this.config.headers
763
804
  });
764
805
  }
@@ -1040,6 +1081,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
1040
1081
  request.config?.responseFormat
1041
1082
  );
1042
1083
  const modelIdForPayload = request.config?.model || this.model;
1084
+ const include = filterOpenAIResponseInclude(
1085
+ modelIdForPayload,
1086
+ [
1087
+ .../* @__PURE__ */ new Set([
1088
+ ...options?.include ?? [],
1089
+ ...options?.store === false ? ["reasoning.encrypted_content"] : []
1090
+ ])
1091
+ ],
1092
+ this.parameterOptions(request)
1093
+ );
1043
1094
  const payload = {
1044
1095
  model: modelIdForPayload,
1045
1096
  instructions: request.systemPrompt,
@@ -1063,14 +1114,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
1063
1114
  ...options?.promptCacheKey !== void 0 ? { prompt_cache_key: options.promptCacheKey } : {},
1064
1115
  ...options?.promptCacheOptions !== void 0 ? { prompt_cache_options: options.promptCacheOptions } : {},
1065
1116
  ...options?.promptCacheRetention !== void 0 ? { prompt_cache_retention: options.promptCacheRetention } : {},
1066
- ...options?.store === false || options?.include ? {
1067
- include: [
1068
- .../* @__PURE__ */ new Set([
1069
- ...options?.include ?? [],
1070
- ...options?.store === false ? ["reasoning.encrypted_content"] : []
1071
- ])
1072
- ]
1073
- } : {},
1117
+ ...include ? { include } : {},
1074
1118
  ...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
1075
1119
  stream
1076
1120
  };
@@ -1441,15 +1485,20 @@ var OpenAIAdapter = class _OpenAIAdapter {
1441
1485
  }
1442
1486
  throwIfAborted(request.signal);
1443
1487
  if (!finishReason)
1444
- throw new Error("OpenAI stream ended without a finish reason");
1488
+ throw invalidProviderResponse(
1489
+ "OpenAI stream ended without a finish reason"
1490
+ );
1445
1491
  if (toolCalls.size && !["tool_calls", "function_call"].includes(finishReason)) {
1446
- throw new Error("OpenAI stream ended with incomplete tool calls");
1447
- }
1448
- for (const call of toolCalls.values()) {
1449
- if (!call.id || !call.name)
1450
- throw new Error("OpenAI stream contains an incomplete tool call");
1451
- JSON.parse(call.arguments || "{}");
1492
+ throw invalidProviderResponse(
1493
+ "OpenAI stream ended with incomplete tool calls"
1494
+ );
1452
1495
  }
1496
+ validateToolCalls(
1497
+ [...toolCalls.values()].map((call) => ({
1498
+ ...call,
1499
+ args: parseToolArguments(call.arguments)
1500
+ }))
1501
+ );
1453
1502
  for (const call of toolCalls.values()) {
1454
1503
  yield {
1455
1504
  type: "action:start",
@@ -1533,20 +1582,20 @@ var OpenAIAdapter = class _OpenAIAdapter {
1533
1582
  logProviderPayload("openai", "response payload", response, request.debug);
1534
1583
  const choice = response.choices?.[0];
1535
1584
  const message = choice?.message;
1585
+ const toolCalls = (message?.tool_calls ?? []).map((toolCall) => ({
1586
+ id: toolCall.id,
1587
+ name: toolCall.function?.name,
1588
+ args: parseToolArguments(toolCall.function?.arguments ?? "{}"),
1589
+ ...toolCall.extra_content ? { extra_content: toolCall.extra_content } : {}
1590
+ }));
1591
+ validateToolCalls(toolCalls);
1592
+ if (toolCalls.length && choice?.finish_reason && !["tool_calls", "function_call"].includes(choice.finish_reason))
1593
+ throw invalidProviderResponse(
1594
+ "OpenAI response ended with incomplete tool calls"
1595
+ );
1536
1596
  return {
1537
1597
  content: message?.content ?? "",
1538
- toolCalls: message?.tool_calls?.map((toolCall) => ({
1539
- id: toolCall.id ?? generateToolCallId(),
1540
- name: toolCall.function?.name ?? "",
1541
- args: (() => {
1542
- try {
1543
- return JSON.parse(toolCall.function?.arguments ?? "{}");
1544
- } catch {
1545
- return {};
1546
- }
1547
- })(),
1548
- ...toolCall.extra_content ? { extra_content: toolCall.extra_content } : {}
1549
- })) ?? [],
1598
+ toolCalls,
1550
1599
  usage: response.usage ? {
1551
1600
  promptTokens: response.usage.prompt_tokens,
1552
1601
  completionTokens: response.usage.completion_tokens,
@@ -0,0 +1,8 @@
1
+ import { j as DecisionModel } from '../../decisions-CJzOt87t.mjs';
2
+ import { D as DecisionProviderOptions } from '../../http-BQxUT5A9.mjs';
3
+
4
+ type TypeSafeDecisionProviderOptions = DecisionProviderOptions;
5
+ /** Native Jev System One API; credentials are separate from OpenRouter. */
6
+ declare function typesafeDecision(modelId?: string, options?: TypeSafeDecisionProviderOptions): DecisionModel;
7
+
8
+ export { type TypeSafeDecisionProviderOptions, typesafeDecision };
@@ -0,0 +1,8 @@
1
+ import { j as DecisionModel } from '../../decisions-CJzOt87t.js';
2
+ import { D as DecisionProviderOptions } from '../../http-BQxUT5A9.js';
3
+
4
+ type TypeSafeDecisionProviderOptions = DecisionProviderOptions;
5
+ /** Native Jev System One API; credentials are separate from OpenRouter. */
6
+ declare function typesafeDecision(modelId?: string, options?: TypeSafeDecisionProviderOptions): DecisionModel;
7
+
8
+ export { type TypeSafeDecisionProviderOptions, typesafeDecision };