@byfriends/kosong 0.1.0 → 0.2.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 (29) hide show
  1. package/dist/{anthropic-Dm_GqFgS.d.mts → anthropic-0CVG5rBE.d.mts} +1 -2
  2. package/dist/{provider-DiJKWMsQ.d.mts → errors-wlT14tC4.d.mts} +227 -2
  3. package/dist/{google-genai-hX0X6CF3.d.mts → google-genai-xKK8lI_R.d.mts} +1 -2
  4. package/dist/index.d.mts +66 -12
  5. package/dist/index.mjs +945 -21
  6. package/dist/{openai-common-08qin3UI.mjs → openai-common-Dl42y_vn.mjs} +27 -2
  7. package/dist/{openai-common-B6cK2ig3.d.mts → openai-common-DwkxUSyI.d.mts} +7 -3
  8. package/dist/{openai-responses-BxOwxtd3.d.mts → openai-responses-DZ9mQ5RA.d.mts} +2 -2
  9. package/dist/providers/anthropic.d.mts +1 -1
  10. package/dist/providers/anthropic.mjs +56 -68
  11. package/dist/providers/google-genai.d.mts +1 -1
  12. package/dist/providers/google-genai.mjs +1 -2
  13. package/dist/providers/openai-common.d.mts +1 -1
  14. package/dist/providers/openai-common.mjs +1 -1
  15. package/dist/providers/openai-responses.d.mts +1 -1
  16. package/dist/providers/openai-responses.mjs +21 -4
  17. package/dist/request-auth-BMXt8jRu.mjs +341 -0
  18. package/package.json +1 -11
  19. package/dist/capability-registry-CMBuEYcf.mjs +0 -161
  20. package/dist/chat-completions-stream-BuMu_xr9.mjs +0 -62
  21. package/dist/errors-DweKbIOf.d.mts +0 -42
  22. package/dist/openai-compat-CMrIk-ib.d.mts +0 -132
  23. package/dist/openai-compat-CWbwO4b7.mjs +0 -801
  24. package/dist/openai-legacy-B6CVfLlr.d.mts +0 -71
  25. package/dist/providers/openai-compat.d.mts +0 -2
  26. package/dist/providers/openai-compat.mjs +0 -2
  27. package/dist/providers/openai-legacy.d.mts +0 -2
  28. package/dist/providers/openai-legacy.mjs +0 -248
  29. package/dist/request-auth-DCWSyCKI.mjs +0 -63
@@ -171,16 +171,41 @@ function isFunctionToolCall(tc) {
171
171
  return tc.type === "function";
172
172
  }
173
173
  /**
174
+ * Model name prefixes / exact names known to support the `xhigh` reasoning
175
+ * effort level. All other OpenAI-compatible models clamp `xhigh` / `max`
176
+ * down to `high`.
177
+ */
178
+ const XHIGH_SUPPORT_PREFIXES = [
179
+ "gpt-5.",
180
+ "gpt-5-",
181
+ "o3-pro",
182
+ "o4-mini"
183
+ ];
184
+ function supportsXhighReasoningEffort(model) {
185
+ const normalized = model.toLowerCase();
186
+ return XHIGH_SUPPORT_PREFIXES.some((prefix) => normalized.startsWith(prefix));
187
+ }
188
+ /**
174
189
  * Map kosong `ThinkingEffort` to OpenAI `reasoning_effort` string.
190
+ *
191
+ * When `model` is provided, `xhigh` / `max` are clamped to `'high'` with a
192
+ * `console.warn` if the model is not known to support the `xhigh` effort
193
+ * level. When `model` is omitted the mapping is pass-through (backward
194
+ * compatible).
175
195
  */
176
- function thinkingEffortToReasoningEffort(effort) {
196
+ function thinkingEffortToReasoningEffort(effort, model) {
177
197
  switch (effort) {
178
198
  case "off": return;
179
199
  case "low": return "low";
180
200
  case "medium": return "medium";
181
201
  case "high": return "high";
182
202
  case "xhigh":
183
- case "max": return "xhigh";
203
+ case "max":
204
+ if (model !== void 0 && !supportsXhighReasoningEffort(model)) {
205
+ console.warn(`effort '${effort}' clamped to 'high' for model ${model}`);
206
+ return "high";
207
+ }
208
+ return "xhigh";
184
209
  default: throw new Error(`Unknown thinking effort: ${String(effort)}`);
185
210
  }
186
211
  }
@@ -1,5 +1,4 @@
1
- import { b as Message, c as TokenUsage, n as FinishReason, o as ThinkingEffort, p as Tool, v as ContentPart } from "./provider-DiJKWMsQ.mjs";
2
- import { o as ChatProviderError } from "./errors-DweKbIOf.mjs";
1
+ import { M as ContentPart, P as Message, c as FinishReason, f as ThinkingEffort, h as TokenUsage, o as ChatProviderError, x as Tool } from "./errors-wlT14tC4.mjs";
3
2
 
4
3
  //#region src/providers/openai-common.d.ts
5
4
  interface OpenAIContentPart {
@@ -58,8 +57,13 @@ declare function isFunctionToolCall<T extends {
58
57
  }>(tc: T): tc is T & FunctionToolCallShape;
59
58
  /**
60
59
  * Map kosong `ThinkingEffort` to OpenAI `reasoning_effort` string.
60
+ *
61
+ * When `model` is provided, `xhigh` / `max` are clamped to `'high'` with a
62
+ * `console.warn` if the model is not known to support the `xhigh` effort
63
+ * level. When `model` is omitted the mapping is pass-through (backward
64
+ * compatible).
61
65
  */
62
- declare function thinkingEffortToReasoningEffort(effort: ThinkingEffort): string | undefined;
66
+ declare function thinkingEffortToReasoningEffort(effort: ThinkingEffort, model?: string): string | undefined;
63
67
  /**
64
68
  * Map OpenAI `reasoning_effort` string back to kosong `ThinkingEffort`.
65
69
  */
@@ -1,5 +1,5 @@
1
- import { S as StreamedMessagePart, a as StreamedMessage, b as Message, c as TokenUsage, i as ProviderRequestAuth, m as ModelCapability, n as FinishReason, o as ThinkingEffort, p as Tool, r as GenerateOptions, t as ChatProvider } from "./provider-DiJKWMsQ.mjs";
2
- import { i as ToolMessageConversion } from "./openai-common-B6cK2ig3.mjs";
1
+ import { I as StreamedMessagePart, P as Message, S as ModelCapability, c as FinishReason, d as StreamedMessage, f as ThinkingEffort, h as TokenUsage, l as GenerateOptions, s as ChatProvider, u as ProviderRequestAuth, x as Tool } from "./errors-wlT14tC4.mjs";
2
+ import { i as ToolMessageConversion } from "./openai-common-DwkxUSyI.mjs";
3
3
  import OpenAI from "openai";
4
4
 
5
5
  //#region src/providers/openai-responses.d.ts
@@ -1,2 +1,2 @@
1
- import { i as resolveDefaultMaxTokens, n as AnthropicOptions, r as convertAnthropicError, t as AnthropicChatProvider } from "../anthropic-Dm_GqFgS.mjs";
1
+ import { i as resolveDefaultMaxTokens, n as AnthropicOptions, r as convertAnthropicError, t as AnthropicChatProvider } from "../anthropic-0CVG5rBE.mjs";
2
2
  export { AnthropicChatProvider, AnthropicOptions, convertAnthropicError, resolveDefaultMaxTokens };
@@ -1,6 +1,5 @@
1
1
  import { a as APITimeoutError, o as ChatProviderError, s as normalizeAPIStatusError, t as APIConnectionError$1 } from "../errors-WFxxzL1B.mjs";
2
- import { n as requireProviderApiKey, r as resolveAuthBackedClient, t as mergeRequestHeaders } from "../request-auth-DCWSyCKI.mjs";
3
- import { t as getAnthropicModelCapability } from "../capability-registry-CMBuEYcf.mjs";
2
+ import { i as getAnthropicModelCapability, n as requireProviderApiKey, r as resolveAuthBackedClient, t as mergeRequestHeaders } from "../request-auth-BMXt8jRu.mjs";
4
3
  import Anthropic, { APIConnectionError, APIConnectionTimeoutError, APIError, AnthropicError } from "@anthropic-ai/sdk";
5
4
  //#region src/providers/anthropic.ts
6
5
  /**
@@ -170,34 +169,24 @@ function supportsAdaptiveThinking(model) {
170
169
  if (match === null) return false;
171
170
  return versionAtLeast(parseVersion(match), ADAPTIVE_MIN_VERSION);
172
171
  }
173
- function isOpus47(model) {
172
+ function supportsXhigh(model) {
174
173
  const match = OPUS_VERSION_RE.exec(model.toLowerCase());
175
174
  if (match === null) return false;
176
175
  const version = parseVersion(match);
177
- return version.major === 4 && version.minor === 7;
178
- }
179
- function supportsEffortParam(model) {
180
- if (supportsAdaptiveThinking(model)) return true;
181
- const normalized = model.toLowerCase();
182
- return normalized.includes("opus-4-5") || normalized.includes("opus-4.5");
176
+ return version.major === 4 && (version.minor === 7 || version.minor === 8);
183
177
  }
184
178
  function clampEffort(effort, model) {
185
179
  if (effort === "off") return effort;
186
- if (effort === "xhigh" && !isOpus47(model)) return "high";
187
- if (effort === "max" && !supportsAdaptiveThinking(model)) return "high";
180
+ if (effort === "xhigh" && !supportsXhigh(model)) {
181
+ console.warn(`effort 'xhigh' clamped to 'high' for model ${model}`);
182
+ return "high";
183
+ }
184
+ if (effort === "max" && !supportsAdaptiveThinking(model)) {
185
+ console.warn(`effort 'max' clamped to 'high' for model ${model}`);
186
+ return "high";
187
+ }
188
188
  return effort;
189
189
  }
190
- function budgetTokensForEffort(effort) {
191
- switch (effort) {
192
- case "low": return 1024;
193
- case "medium": return 4096;
194
- case "high": return 32e3;
195
- case "off":
196
- case "xhigh":
197
- case "max": throw new Error(`Unsupported budget-based thinking effort: ${effort}`);
198
- }
199
- throw new Error(`Unknown thinking effort: ${String(effort)}`);
200
- }
201
190
  const CACHE_CONTROL = { type: "ephemeral" };
202
191
  /**
203
192
  * Content block types that support cache_control injection.
@@ -212,14 +201,22 @@ const CACHEABLE_TYPES = new Set([
212
201
  "server_tool_use",
213
202
  "web_search_tool_result"
214
203
  ]);
215
- function injectCacheControlOnLastBlock(messages) {
216
- const lastMessage = messages.at(-1);
217
- if (lastMessage === void 0) return;
218
- const content = lastMessage.content;
219
- if (!Array.isArray(content) || content.length === 0) return;
220
- const lastBlock = content.at(-1);
221
- if (lastBlock === void 0) return;
222
- if (CACHEABLE_TYPES.has(lastBlock.type)) lastBlock.cache_control = CACHE_CONTROL;
204
+ /**
205
+ * Convert a PromptPlan to Anthropic TextBlockParam[] with cache control.
206
+ *
207
+ * Injects cache_control on blocks with cacheScope other than 'none'.
208
+ */
209
+ function promptPlanToSystemBlocks(promptPlan) {
210
+ const blocks = [];
211
+ for (const block of promptPlan.blocks) {
212
+ const textBlock = {
213
+ type: "text",
214
+ text: block.text
215
+ };
216
+ if (block.cacheScope !== "none") textBlock.cache_control = CACHE_CONTROL;
217
+ blocks.push(textBlock);
218
+ }
219
+ return blocks;
223
220
  }
224
221
  /**
225
222
  * Check whether a MessageParam is a user message whose content consists
@@ -300,9 +297,11 @@ function convertMessage(message) {
300
297
  };
301
298
  if (role === "tool") {
302
299
  if (message.toolCallId === void 0) throw new ChatProviderError("Tool message missing `toolCallId`.");
300
+ const block = toolResultToBlock(message.toolCallId, message.content);
301
+ if (message.cacheHint?.isLastTurnEnd || message.cacheHint?.isSuddenLargeContext) block.cache_control = CACHE_CONTROL;
303
302
  return {
304
303
  role: "user",
305
- content: [toolResultToBlock(message.toolCallId, message.content)]
304
+ content: [block]
306
305
  };
307
306
  }
308
307
  const blocks = [];
@@ -336,6 +335,10 @@ function convertMessage(message) {
336
335
  input: toolInput
337
336
  });
338
337
  }
338
+ if (message.cacheHint?.isLastTurnEnd || message.cacheHint?.isSuddenLargeContext) {
339
+ const lastBlock = blocks.at(-1);
340
+ if (lastBlock !== void 0 && CACHEABLE_TYPES.has(lastBlock.type)) lastBlock.cache_control = CACHE_CONTROL;
341
+ }
339
342
  return {
340
343
  role,
341
344
  content: blocks
@@ -563,20 +566,15 @@ var AnthropicChatProvider = class {
563
566
  const thinkingConfig = this._generationKwargs.thinking;
564
567
  if (thinkingConfig === void 0 || thinkingConfig === null) return null;
565
568
  if (thinkingConfig.type === "disabled") return "off";
566
- if (thinkingConfig.type === "adaptive") {
567
- const effort = this._generationKwargs.output_config?.effort;
568
- if (effort === void 0 || effort === null) return "high";
569
- switch (effort) {
570
- case "low":
571
- case "medium":
572
- case "high":
573
- case "xhigh":
574
- case "max": return effort;
575
- }
569
+ const effort = this._generationKwargs.output_config?.effort;
570
+ if (effort === void 0 || effort === null) return "high";
571
+ switch (effort) {
572
+ case "low":
573
+ case "medium":
574
+ case "high":
575
+ case "xhigh":
576
+ case "max": return effort;
576
577
  }
577
- const budget = thinkingConfig.budget_tokens ?? 0;
578
- if (budget <= 1024) return "low";
579
- if (budget <= 4096) return "medium";
580
578
  return "high";
581
579
  }
582
580
  get modelParameters() {
@@ -589,11 +587,16 @@ var AnthropicChatProvider = class {
589
587
  return getAnthropicModelCapability(model ?? this._model);
590
588
  }
591
589
  async generate(systemPrompt, tools, history, options) {
592
- const system = systemPrompt ? [{
590
+ let system;
591
+ if (options?.promptPlan) {
592
+ const systemBlocks = promptPlanToSystemBlocks(options.promptPlan);
593
+ system = systemBlocks.length > 0 ? systemBlocks : void 0;
594
+ } else if (systemPrompt) system = [{
593
595
  type: "text",
594
596
  text: systemPrompt,
595
597
  cache_control: CACHE_CONTROL
596
- }] : void 0;
598
+ }];
599
+ else system = void 0;
597
600
  const messages = [];
598
601
  for (const msg of history) {
599
602
  const converted = convertMessage(msg);
@@ -601,7 +604,6 @@ var AnthropicChatProvider = class {
601
604
  if (last !== void 0 && isToolResultOnly(last) && isToolResultOnly(converted)) last.content = [...last.content, ...converted.content];
602
605
  else messages.push(converted);
603
606
  }
604
- injectCacheControlOnLastBlock(messages);
605
607
  const kwargs = {};
606
608
  if (this._generationKwargs.max_tokens !== void 0) kwargs["max_tokens"] = this._generationKwargs.max_tokens;
607
609
  if (this._generationKwargs.temperature !== void 0) kwargs["temperature"] = this._generationKwargs.temperature;
@@ -664,7 +666,7 @@ var AnthropicChatProvider = class {
664
666
  withThinking(effort) {
665
667
  if (effort === "off") {
666
668
  let newBetas = [...this._generationKwargs.betaFeatures ?? []];
667
- if (supportsAdaptiveThinking(this._model)) newBetas = newBetas.filter((b) => b !== INTERLEAVED_THINKING_BETA);
669
+ newBetas = newBetas.filter((b) => b !== INTERLEAVED_THINKING_BETA);
668
670
  const clone = this._withGenerationKwargs({
669
671
  thinking: { type: "disabled" },
670
672
  betaFeatures: newBetas
@@ -675,29 +677,15 @@ var AnthropicChatProvider = class {
675
677
  const effectiveEffort = clampEffort(effort, this._model);
676
678
  if (effectiveEffort === "off") throw new Error("Non-off thinking effort unexpectedly clamped to off.");
677
679
  let newBetas = [...this._generationKwargs.betaFeatures ?? []];
678
- if (supportsAdaptiveThinking(this._model)) {
679
- newBetas = newBetas.filter((b) => b !== INTERLEAVED_THINKING_BETA);
680
- return this._withGenerationKwargs({
681
- thinking: {
682
- type: "adaptive",
683
- display: "summarized"
684
- },
685
- output_config: { effort: effectiveEffort },
686
- betaFeatures: newBetas
687
- });
688
- }
689
- const kwargs = {
680
+ newBetas = newBetas.filter((b) => b !== INTERLEAVED_THINKING_BETA);
681
+ return this._withGenerationKwargs({
690
682
  thinking: {
691
- type: "enabled",
692
- budget_tokens: budgetTokensForEffort(effectiveEffort)
683
+ type: "adaptive",
684
+ display: "summarized"
693
685
  },
686
+ output_config: { effort: effectiveEffort },
694
687
  betaFeatures: newBetas
695
- };
696
- if (supportsEffortParam(this._model)) kwargs.output_config = { effort: effectiveEffort };
697
- else kwargs.output_config = void 0;
698
- const clone = this._withGenerationKwargs(kwargs);
699
- if (!supportsEffortParam(this._model)) delete clone._generationKwargs.output_config;
700
- return clone;
688
+ });
701
689
  }
702
690
  withGenerationKwargs(kwargs) {
703
691
  return this._withGenerationKwargs(kwargs);
@@ -1,2 +1,2 @@
1
- import { a as convertGoogleGenAIError, i as GoogleGenAIStreamedMessage, n as GoogleGenAIGenerationKwargs, o as messagesToGoogleGenAIContents, r as GoogleGenAIOptions, t as GoogleGenAIChatProvider } from "../google-genai-hX0X6CF3.mjs";
1
+ import { a as convertGoogleGenAIError, i as GoogleGenAIStreamedMessage, n as GoogleGenAIGenerationKwargs, o as messagesToGoogleGenAIContents, r as GoogleGenAIOptions, t as GoogleGenAIChatProvider } from "../google-genai-xKK8lI_R.mjs";
2
2
  export { GoogleGenAIChatProvider, GoogleGenAIGenerationKwargs, GoogleGenAIOptions, GoogleGenAIStreamedMessage, convertGoogleGenAIError, messagesToGoogleGenAIContents };
@@ -1,6 +1,5 @@
1
1
  import { a as APITimeoutError, o as ChatProviderError, s as normalizeAPIStatusError, t as APIConnectionError } from "../errors-WFxxzL1B.mjs";
2
- import { n as requireProviderApiKey, r as resolveAuthBackedClient } from "../request-auth-DCWSyCKI.mjs";
3
- import { n as getGoogleGenAIModelCapability } from "../capability-registry-CMBuEYcf.mjs";
2
+ import { a as getGoogleGenAIModelCapability, n as requireProviderApiKey, r as resolveAuthBackedClient } from "../request-auth-BMXt8jRu.mjs";
4
3
  import { ApiError, GoogleGenAI } from "@google/genai";
5
4
  //#region src/providers/google-genai.ts
6
5
  /**
@@ -1,2 +1,2 @@
1
- import { a as convertContentPart, c as extractUsage, d as reasoningEffortToThinkingEffort, f as thinkingEffortToReasoningEffort, i as ToolMessageConversion, l as isFunctionToolCall, n as OpenAIContentPart, o as convertOpenAIError, p as toolToOpenAI, r as OpenAIToolParam, s as convertToolMessageContent, t as FunctionToolCallShape, u as normalizeOpenAIFinishReason } from "../openai-common-B6cK2ig3.mjs";
1
+ import { a as convertContentPart, c as extractUsage, d as reasoningEffortToThinkingEffort, f as thinkingEffortToReasoningEffort, i as ToolMessageConversion, l as isFunctionToolCall, n as OpenAIContentPart, o as convertOpenAIError, p as toolToOpenAI, r as OpenAIToolParam, s as convertToolMessageContent, t as FunctionToolCallShape, u as normalizeOpenAIFinishReason } from "../openai-common-DwkxUSyI.mjs";
2
2
  export { FunctionToolCallShape, OpenAIContentPart, OpenAIToolParam, ToolMessageConversion, convertContentPart, convertOpenAIError, convertToolMessageContent, extractUsage, isFunctionToolCall, normalizeOpenAIFinishReason, reasoningEffortToThinkingEffort, thinkingEffortToReasoningEffort, toolToOpenAI };
@@ -1,2 +1,2 @@
1
- import { a as isFunctionToolCall, c as thinkingEffortToReasoningEffort, i as extractUsage, l as toolToOpenAI, n as convertOpenAIError, o as normalizeOpenAIFinishReason, r as convertToolMessageContent, s as reasoningEffortToThinkingEffort, t as convertContentPart } from "../openai-common-08qin3UI.mjs";
1
+ import { a as isFunctionToolCall, c as thinkingEffortToReasoningEffort, i as extractUsage, l as toolToOpenAI, n as convertOpenAIError, o as normalizeOpenAIFinishReason, r as convertToolMessageContent, s as reasoningEffortToThinkingEffort, t as convertContentPart } from "../openai-common-Dl42y_vn.mjs";
2
2
  export { convertContentPart, convertOpenAIError, convertToolMessageContent, extractUsage, isFunctionToolCall, normalizeOpenAIFinishReason, reasoningEffortToThinkingEffort, thinkingEffortToReasoningEffort, toolToOpenAI };
@@ -1,2 +1,2 @@
1
- import { i as OpenAIResponsesStreamedMessage, n as OpenAIResponsesGenerationKwargs, r as OpenAIResponsesOptions, t as OpenAIResponsesChatProvider } from "../openai-responses-BxOwxtd3.mjs";
1
+ import { i as OpenAIResponsesStreamedMessage, n as OpenAIResponsesGenerationKwargs, r as OpenAIResponsesOptions, t as OpenAIResponsesChatProvider } from "../openai-responses-DZ9mQ5RA.mjs";
2
2
  export { OpenAIResponsesChatProvider, OpenAIResponsesGenerationKwargs, OpenAIResponsesOptions, OpenAIResponsesStreamedMessage };
@@ -1,8 +1,8 @@
1
- import { c as thinkingEffortToReasoningEffort, n as convertOpenAIError, p as extractText, s as reasoningEffortToThinkingEffort } from "../openai-common-08qin3UI.mjs";
1
+ import { c as thinkingEffortToReasoningEffort, n as convertOpenAIError, p as extractText, s as reasoningEffortToThinkingEffort } from "../openai-common-Dl42y_vn.mjs";
2
2
  import { o as ChatProviderError } from "../errors-WFxxzL1B.mjs";
3
- import { n as requireProviderApiKey, r as resolveAuthBackedClient, t as mergeRequestHeaders } from "../request-auth-DCWSyCKI.mjs";
4
- import { a as usesOpenAIResponsesDeveloperRole, i as getOpenAIResponsesModelCapability } from "../capability-registry-CMBuEYcf.mjs";
3
+ import { l as usesOpenAIResponsesDeveloperRole, n as requireProviderApiKey, r as resolveAuthBackedClient, s as getOpenAIResponsesModelCapability, t as mergeRequestHeaders } from "../request-auth-BMXt8jRu.mjs";
5
4
  import OpenAI from "openai";
5
+ import { createHash } from "node:crypto";
6
6
  //#region src/providers/openai-responses.ts
7
7
  /**
8
8
  * Normalize the Responses API status / incomplete_details into the unified
@@ -45,6 +45,19 @@ function normalizeResponsesFinishReason(status, incompleteReason) {
45
45
  rawFinishReason: null
46
46
  };
47
47
  }
48
+ /**
49
+ * Derive a stable cache key from cacheable blocks in a PromptPlan.
50
+ *
51
+ * Only blocks with cacheScope 'global' are included in the hash, as OpenAI
52
+ * only supports caching the prefix (global scope).
53
+ */
54
+ function deriveCacheKeyFromPromptPlan(promptPlan) {
55
+ if (!promptPlan || promptPlan.blocks.length === 0) return void 0;
56
+ const cacheableTexts = [];
57
+ for (const block of promptPlan.blocks) if (block.cacheScope === "global") cacheableTexts.push(block.text);
58
+ if (cacheableTexts.length === 0) return void 0;
59
+ return createHash("sha256").update(cacheableTexts.join("")).digest("hex");
60
+ }
48
61
  function asRawObject(value) {
49
62
  if (value === null || typeof value !== "object" || Array.isArray(value)) return null;
50
63
  return value;
@@ -574,6 +587,10 @@ var OpenAIResponsesChatProvider = class {
574
587
  stream: this._stream,
575
588
  ...kwargs
576
589
  };
590
+ if (options?.promptPlan) {
591
+ const cacheKey = deriveCacheKeyFromPromptPlan(options.promptPlan);
592
+ if (cacheKey) createParams["prompt_cache_key"] = cacheKey;
593
+ }
577
594
  if (!("responses" in client) || typeof client.responses?.create !== "function") throw new Error("OpenAI SDK version does not support Responses API. Upgrade to >=4.x with responses support.");
578
595
  return new OpenAIResponsesStreamedMessage(await client.responses.create(createParams, options?.signal ? { signal: options.signal } : void 0), this._stream);
579
596
  } catch (error) {
@@ -581,7 +598,7 @@ var OpenAIResponsesChatProvider = class {
581
598
  }
582
599
  }
583
600
  withThinking(effort) {
584
- const reasoningEffort = thinkingEffortToReasoningEffort(effort);
601
+ const reasoningEffort = thinkingEffortToReasoningEffort(effort, this._model);
585
602
  const clone = this._clone();
586
603
  clone._generationKwargs = {
587
604
  ...clone._generationKwargs,