@axlsdk/axl 0.25.1 → 0.25.3

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.d.cts CHANGED
@@ -7378,8 +7378,8 @@ type DirectOpenAIPricingContext = {
7378
7378
  };
7379
7379
  };
7380
7380
  /**
7381
- * Estimate OpenAI call cost from token usage. Exact match first, then
7382
- * longest-prefix match for versioned models (e.g. `gpt-4o-2024-05-13`).
7381
+ * Estimate OpenAI call cost from token usage using exact catalog IDs only.
7382
+ * Explicitly listed snapshots (e.g. `gpt-4o-2024-05-13`) have their own rows.
7383
7383
  *
7384
7384
  * Returns `undefined` when the model is not in the table — callers must treat
7385
7385
  * that as "unknown cost", never as free (a silent `0` would break
@@ -7409,8 +7409,8 @@ declare class OpenAIProvider extends OpenAICompatibleProvider {
7409
7409
  dangerouslyAllowInsecureHttp?: boolean;
7410
7410
  rateLimit?: RateLimitConfig;
7411
7411
  });
7412
- /** Report a clamped `effort` — Chat Completions caps `'max'` at `'xhigh'` and
7413
- * rejects `'none'` before gpt-5.1 (clamped to `'minimal'`). */
7412
+ /** Report a clamped `effort` — Chat caps `'max'` at `'xhigh'` on GPT-5.6 and
7413
+ * GPT-6.1 Sol, and maps `'none'` to the model's supported floor. */
7414
7414
  effortResolution(options: Pick<ChatOptions, 'model' | 'effort' | 'thinkingBudget' | 'includeThoughts' | 'providerOptions'>): EffortResolution | undefined;
7415
7415
  protected validateFinalRequestBody(body: Record<string, unknown>): void;
7416
7416
  protected computeCost(model: string, usage: ProviderResponse['usage'], _reportedCost: number | undefined, context?: DirectOpenAIPricingContext): number | undefined;
@@ -7534,7 +7534,19 @@ declare class AnthropicProvider implements Provider {
7534
7534
  chat(messages: ChatMessage[], options: ChatOptions): Promise<ProviderResponse>;
7535
7535
  stream(messages: ChatMessage[], options: ChatOptions): AsyncGenerator<StreamChunk>;
7536
7536
  private buildHeaders;
7537
+ /**
7538
+ * Whether the final body needs the binding beta header. Runs after
7539
+ * `validateAndBindFinalBody`, which has already injected `block_binding`
7540
+ * wherever it applies, so the header follows the final body rather than
7541
+ * re-deriving the injection rule.
7542
+ */
7537
7543
  private requiresBindingBeta;
7544
+ /**
7545
+ * Validate the final body (after `providerOptions`) against the effective
7546
+ * model's capability, then inject `block_binding` where it applies. Every
7547
+ * rule is gated on its own capability field and is a no-op when unset, so a
7548
+ * model only gets the guards its provider contract calls for.
7549
+ */
7538
7550
  private validateAndBindFinalBody;
7539
7551
  /** Extract a human-readable message from an API error response body. */
7540
7552
  private extractErrorMessage;
package/dist/index.d.ts CHANGED
@@ -7378,8 +7378,8 @@ type DirectOpenAIPricingContext = {
7378
7378
  };
7379
7379
  };
7380
7380
  /**
7381
- * Estimate OpenAI call cost from token usage. Exact match first, then
7382
- * longest-prefix match for versioned models (e.g. `gpt-4o-2024-05-13`).
7381
+ * Estimate OpenAI call cost from token usage using exact catalog IDs only.
7382
+ * Explicitly listed snapshots (e.g. `gpt-4o-2024-05-13`) have their own rows.
7383
7383
  *
7384
7384
  * Returns `undefined` when the model is not in the table — callers must treat
7385
7385
  * that as "unknown cost", never as free (a silent `0` would break
@@ -7409,8 +7409,8 @@ declare class OpenAIProvider extends OpenAICompatibleProvider {
7409
7409
  dangerouslyAllowInsecureHttp?: boolean;
7410
7410
  rateLimit?: RateLimitConfig;
7411
7411
  });
7412
- /** Report a clamped `effort` — Chat Completions caps `'max'` at `'xhigh'` and
7413
- * rejects `'none'` before gpt-5.1 (clamped to `'minimal'`). */
7412
+ /** Report a clamped `effort` — Chat caps `'max'` at `'xhigh'` on GPT-5.6 and
7413
+ * GPT-6.1 Sol, and maps `'none'` to the model's supported floor. */
7414
7414
  effortResolution(options: Pick<ChatOptions, 'model' | 'effort' | 'thinkingBudget' | 'includeThoughts' | 'providerOptions'>): EffortResolution | undefined;
7415
7415
  protected validateFinalRequestBody(body: Record<string, unknown>): void;
7416
7416
  protected computeCost(model: string, usage: ProviderResponse['usage'], _reportedCost: number | undefined, context?: DirectOpenAIPricingContext): number | undefined;
@@ -7534,7 +7534,19 @@ declare class AnthropicProvider implements Provider {
7534
7534
  chat(messages: ChatMessage[], options: ChatOptions): Promise<ProviderResponse>;
7535
7535
  stream(messages: ChatMessage[], options: ChatOptions): AsyncGenerator<StreamChunk>;
7536
7536
  private buildHeaders;
7537
+ /**
7538
+ * Whether the final body needs the binding beta header. Runs after
7539
+ * `validateAndBindFinalBody`, which has already injected `block_binding`
7540
+ * wherever it applies, so the header follows the final body rather than
7541
+ * re-deriving the injection rule.
7542
+ */
7537
7543
  private requiresBindingBeta;
7544
+ /**
7545
+ * Validate the final body (after `providerOptions`) against the effective
7546
+ * model's capability, then inject `block_binding` where it applies. Every
7547
+ * rule is gated on its own capability field and is a no-op when unset, so a
7548
+ * model only gets the guards its provider contract calls for.
7549
+ */
7538
7550
  private validateAndBindFinalBody;
7539
7551
  /** Extract a human-readable message from an API error response body. */
7540
7552
  private extractErrorMessage;
package/dist/index.js CHANGED
@@ -348,7 +348,7 @@ var sharedGuard = typeof installedGuard === "object" && installedGuard !== null
348
348
  var buildPath = typeof __AXL_BUILD_PATH__ === "string" ? __AXL_BUILD_PATH__ : "<source>";
349
349
  var thisCopy = {
350
350
  path: buildPath.startsWith("file:") ? fileURLToPath(buildPath) : buildPath,
351
- version: true ? "0.25.1" : "unknown"
351
+ version: true ? "0.25.3" : "unknown"
352
352
  };
353
353
  function warnCrossCopy(other, joined) {
354
354
  if (other === thisCopy) return;
@@ -3617,7 +3617,7 @@ var OPENAI_PRICING = {
3617
3617
  "gpt-4.1-mini": [4e-7, 16e-7, 0.25],
3618
3618
  "gpt-4.1-nano": [1e-7, 4e-7, 0.25],
3619
3619
  o3: [2e-6, 8e-6, 0.25],
3620
- "o3-mini": [11e-7, 44e-7, 0.25],
3620
+ "o3-mini": [11e-7, 44e-7, 0.5],
3621
3621
  "o4-mini": [11e-7, 44e-7, 0.25],
3622
3622
  "gpt-5": [125e-8, 1e-5, 0.1],
3623
3623
  "gpt-5-mini": [25e-8, 2e-6, 0.1],
@@ -3640,6 +3640,13 @@ var DIRECT_OPENAI_CATALOG = [
3640
3640
  long: { input: 20 / M, cachedInput: 2 / M, cacheWrite: 25 / M, output: 75 / M },
3641
3641
  contextBoundary: LONG_CONTEXT_BOUNDARY
3642
3642
  },
3643
+ {
3644
+ aliases: ["gpt-6.1-sol"],
3645
+ // Rechecked 2026-10-15 against https://developers.openai.com/api/docs/pricing.
3646
+ short: { input: 2 / M, cachedInput: 0.1 / M, cacheWrite: 2.5 / M, output: 10 / M },
3647
+ long: { input: 4 / M, cachedInput: 0.2 / M, cacheWrite: 5 / M, output: 15 / M },
3648
+ contextBoundary: LONG_CONTEXT_BOUNDARY
3649
+ },
3643
3650
  {
3644
3651
  aliases: ["gpt-6-sol"],
3645
3652
  short: { input: 2 / M, cachedInput: 0.2 / M, cacheWrite: 2.5 / M, output: 10 / M },
@@ -4019,12 +4026,12 @@ var BASE_EFFORTS = ["minimal", "low", "medium", "high"];
4019
4026
  function bothEndpoints(value) {
4020
4027
  return { chat: value, responses: value };
4021
4028
  }
4022
- function gpt6(id, efforts, chatTools) {
4029
+ function gpt6(id, responsesEfforts, chatTools, chatEfforts = responsesEfforts) {
4023
4030
  return {
4024
4031
  id,
4025
4032
  family: "gpt-6",
4026
4033
  reasoning: true,
4027
- efforts: bothEndpoints(efforts),
4034
+ efforts: { chat: chatEfforts, responses: responsesEfforts },
4028
4035
  defaultEffort: "medium",
4029
4036
  // Same policy as GPT-5.x: a portable `temperature` is dropped while
4030
4037
  // reasoning is active (including the active default). A raw
@@ -4052,6 +4059,13 @@ function gpt56(id) {
4052
4059
  var OPENAI_EXACT_MODELS = new Map(
4053
4060
  [
4054
4061
  gpt6("gpt-6-astra", ["low", "medium", "high", "xhigh", "max"], "never"),
4062
+ // Live Chat Completions rejects max; Responses accepts it (2026-10-15).
4063
+ gpt6("gpt-6.1-sol", ["low", "medium", "high", "xhigh", "max"], "never", [
4064
+ "low",
4065
+ "medium",
4066
+ "high",
4067
+ "xhigh"
4068
+ ]),
4055
4069
  gpt6("gpt-6-sol", ["none", "low", "medium", "high", "xhigh", "max"], "effort-none-only"),
4056
4070
  gpt6("gpt-6-luna", ["none", "low", "medium", "high", "xhigh", "max"], "effort-none-only"),
4057
4071
  gpt56("gpt-5.6"),
@@ -4195,15 +4209,15 @@ function validateOpenAIFinalRequestBody(body, endpoint) {
4195
4209
  }
4196
4210
  }
4197
4211
  if (activeReasoning) {
4212
+ const remediation = (key) => descriptor.efforts[endpoint].includes("none") ? `Remove ${key} or set reasoning effort to 'none'.` : `Remove ${key}; ${model} does not support reasoning effort 'none'.`;
4198
4213
  const forbidden = endpoint === "chat" ? ["temperature", "top_p", "top_logprobs", "logprobs"] : ["temperature", "top_p", "top_logprobs"];
4199
4214
  for (const key of forbidden) {
4200
- if (body[key] !== void 0)
4201
- fail(key, `Remove ${key} or set reasoning effort to 'none' on Sol or Luna.`);
4215
+ if (body[key] !== void 0) fail(key, remediation(key));
4202
4216
  }
4203
4217
  if (endpoint === "responses" && Array.isArray(body.include) && body.include.includes("message.output_text.logprobs")) {
4204
4218
  fail(
4205
4219
  "message.output_text.logprobs",
4206
- "Remove it from include or set reasoning effort to none on Sol or Luna."
4220
+ remediation("message.output_text.logprobs from include")
4207
4221
  );
4208
4222
  }
4209
4223
  }
@@ -4256,8 +4270,8 @@ var OpenAIProvider = class extends OpenAICompatibleProvider {
4256
4270
  constructor(options = {}) {
4257
4271
  super({ profile: OPENAI_PROFILE, ...options });
4258
4272
  }
4259
- /** Report a clamped `effort` — Chat Completions caps `'max'` at `'xhigh'` and
4260
- * rejects `'none'` before gpt-5.1 (clamped to `'minimal'`). */
4273
+ /** Report a clamped `effort` — Chat caps `'max'` at `'xhigh'` on GPT-5.6 and
4274
+ * GPT-6.1 Sol, and maps `'none'` to the model's supported floor. */
4261
4275
  effortResolution(options) {
4262
4276
  return resolveOpenAIEffortResolution(
4263
4277
  options,
@@ -4913,6 +4927,17 @@ var ANTHROPIC_THINKING_BINDING_BETA = "thinking-binding-controls-2026-08-01";
4913
4927
  function isRecord(value) {
4914
4928
  return value !== null && typeof value === "object" && !Array.isArray(value);
4915
4929
  }
4930
+ function isFinalThinkingAdaptive(capability, body) {
4931
+ const thinking = body.thinking;
4932
+ if (thinking === void 0) {
4933
+ return capability.thinking === "adaptive-default-on" || capability.thinking === "adaptive-always-on";
4934
+ }
4935
+ return isRecord(thinking) && thinking.type === "adaptive";
4936
+ }
4937
+ var NATIVE_CLAUDE_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
4938
+ function isNativeClaudeEffort(value) {
4939
+ return NATIVE_CLAUDE_EFFORTS.includes(value);
4940
+ }
4916
4941
  function hasReplayedThinking(body) {
4917
4942
  return Array.isArray(body.messages) && body.messages.some(
4918
4943
  (message) => isRecord(message) && Array.isArray(message.content) && message.content.some(
@@ -4947,11 +4972,40 @@ function hasAnthropicProviderFileImage(messages) {
4947
4972
  );
4948
4973
  }
4949
4974
  var CLAUDE_CAPABILITIES = {
4975
+ // Thinking off is `between_tools` (progress updates between tool calls);
4976
+ // `disabled` is a provider 400. Forced tool choice is a 400.
4977
+ "claude-sonnet-5-5": {
4978
+ thinking: "adaptive-default-on",
4979
+ effortLevels: ["low", "medium", "high", "xhigh", "max"],
4980
+ manualBudget: false,
4981
+ stripTemperature: true,
4982
+ disableAt: "high",
4983
+ offShape: "between_tools",
4984
+ forcedToolChoice: "rejected",
4985
+ defaultOnlySampling: true,
4986
+ strictThinking: true,
4987
+ thinkingBinding: true
4988
+ },
4989
+ // Thinking off is `disabled`, only at effort high or below. Forced tool
4990
+ // choice is accepted (the provider skips thinking for that turn).
4991
+ "claude-haiku-5-5": {
4992
+ thinking: "adaptive-default-on",
4993
+ effortLevels: ["low", "medium", "high", "xhigh", "max"],
4994
+ manualBudget: false,
4995
+ stripTemperature: true,
4996
+ disableAt: "high",
4997
+ defaultOnlySampling: true,
4998
+ strictThinking: true,
4999
+ thinkingBinding: true
5000
+ },
4950
5001
  "claude-opus-5-5": {
4951
5002
  thinking: "adaptive-always-on",
4952
5003
  effortLevels: ["low", "medium", "high", "xhigh", "max"],
4953
5004
  manualBudget: false,
4954
5005
  stripTemperature: true,
5006
+ forcedToolChoice: "rejected",
5007
+ defaultOnlySampling: true,
5008
+ strictThinking: true,
4955
5009
  thinkingBinding: true
4956
5010
  },
4957
5011
  "claude-fable-5-1": {
@@ -4959,6 +5013,9 @@ var CLAUDE_CAPABILITIES = {
4959
5013
  effortLevels: ["low", "medium", "high", "xhigh", "max"],
4960
5014
  manualBudget: false,
4961
5015
  stripTemperature: true,
5016
+ forcedToolChoice: "rejected",
5017
+ defaultOnlySampling: true,
5018
+ strictThinking: true,
4962
5019
  thinkingBinding: true
4963
5020
  },
4964
5021
  "claude-fable-5": {
@@ -5053,6 +5110,15 @@ function resolveClaudeCapability(model) {
5053
5110
  }
5054
5111
  var DEFAULT_CACHE_READ_MULTIPLIER = 0.1;
5055
5112
  var ANTHROPIC_RATES = {
5113
+ // Sonnet 5.5 cache reads are 0.05x ($0.10/MTok): the pricing table, its
5114
+ // footnote, the models overview, and the prompt-caching guide agree
5115
+ // (re-checked 2026-10-07).
5116
+ "claude-sonnet-5-5": { input: 2e-6, output: 1e-5, cacheReadMultiplier: 0.05 },
5117
+ "claude-haiku-5-5": {
5118
+ input: 1e-7,
5119
+ output: 5e-7,
5120
+ longPrompt: { aboveTokens: 1e5, card: { input: 5e-7, output: 25e-7 } }
5121
+ },
5056
5122
  "claude-opus-5-5": { input: 4e-6, output: 2e-5, cacheReadMultiplier: 0.05 },
5057
5123
  "claude-fable-5-1": { input: 1e-5, output: 5e-5, cacheReadMultiplier: 0.025 },
5058
5124
  "claude-fable-5": { input: 1e-5, output: 5e-5 },
@@ -5115,14 +5181,16 @@ function estimateAnthropicCost(model, usage) {
5115
5181
  return void 0;
5116
5182
  }
5117
5183
  const cacheWriteTotal = safeTokenSum(cacheWrite5m, cacheWrite1h);
5118
- if (cacheWriteTotal === void 0 || safeTokenSum(usage.inputTokens, cacheRead, cacheWriteTotal) === void 0) {
5184
+ const promptTokens = cacheWriteTotal === void 0 ? void 0 : safeTokenSum(usage.inputTokens, cacheRead, cacheWriteTotal);
5185
+ if (cacheWriteTotal === void 0 || promptTokens === void 0) {
5119
5186
  return void 0;
5120
5187
  }
5121
5188
  if (usage.aggregateCacheWriteTokens !== void 0 && (!isValidTokenCount(usage.aggregateCacheWriteTokens) || usage.aggregateCacheWriteTokens !== cacheWriteTotal)) {
5122
5189
  return void 0;
5123
5190
  }
5124
- const { input, output } = rate;
5125
- const cacheReadRate = input * (rate.cacheReadMultiplier ?? DEFAULT_CACHE_READ_MULTIPLIER);
5191
+ const card = rate.longPrompt && promptTokens > rate.longPrompt.aboveTokens ? rate.longPrompt.card : rate;
5192
+ const { input, output } = card;
5193
+ const cacheReadRate = input * (card.cacheReadMultiplier ?? DEFAULT_CACHE_READ_MULTIPLIER);
5126
5194
  return usage.inputTokens * input + cacheRead * cacheReadRate + cacheWrite5m * input * 1.25 + cacheWrite1h * input * 2 + usage.outputTokens * output;
5127
5195
  }
5128
5196
  var THINKING_BUDGETS = {
@@ -5184,7 +5252,7 @@ function resolveClaudeThinking(model, resolved) {
5184
5252
  };
5185
5253
  }
5186
5254
  return {
5187
- thinking: { type: "disabled" },
5255
+ thinking: { type: capability.offShape ?? "disabled" },
5188
5256
  outputConfig: activeEffort ? { effort: activeEffort } : void 0,
5189
5257
  stripTemperature: true
5190
5258
  };
@@ -5590,50 +5658,106 @@ var AnthropicProvider = class {
5590
5658
  ...betas.length > 0 ? { "anthropic-beta": betas.join(",") } : {}
5591
5659
  };
5592
5660
  }
5661
+ /**
5662
+ * Whether the final body needs the binding beta header. Runs after
5663
+ * `validateAndBindFinalBody`, which has already injected `block_binding`
5664
+ * wherever it applies, so the header follows the final body rather than
5665
+ * re-deriving the injection rule.
5666
+ */
5593
5667
  requiresBindingBeta(body) {
5668
+ const capability = resolveClaudeCapability(String(body.model));
5594
5669
  const thinking = body.thinking;
5595
- return resolveClaudeCapability(String(body.model))?.thinkingBinding === true && (hasReplayedThinking(body) || isRecord(thinking) && thinking.block_binding !== void 0);
5670
+ return capability?.thinkingBinding === true && isRecord(thinking) && thinking.type === "adaptive" && thinking.block_binding !== void 0;
5596
5671
  }
5672
+ /**
5673
+ * Validate the final body (after `providerOptions`) against the effective
5674
+ * model's capability, then inject `block_binding` where it applies. Every
5675
+ * rule is gated on its own capability field and is a no-op when unset, so a
5676
+ * model only gets the guards its provider contract calls for.
5677
+ */
5597
5678
  validateAndBindFinalBody(body) {
5598
5679
  const model = typeof body.model === "string" ? body.model : "";
5599
- if (resolveClaudeCapability(model)?.thinkingBinding !== true) return;
5680
+ const capability = resolveClaudeCapability(model);
5681
+ if (!capability) return;
5600
5682
  const reject = (option, remediation) => {
5601
5683
  throw new UnsupportedModelOptionError({ provider: this.name, model, option, remediation });
5602
5684
  };
5603
- const toolChoice = body.tool_choice;
5604
- if (isRecord(toolChoice) && (toolChoice.type === "any" || toolChoice.type === "tool")) {
5605
- reject("forced tool choice", "Use toolChoice: 'auto' or 'none' on this model.");
5606
- }
5607
- if (body.thinking !== void 0 && (!isRecord(body.thinking) || body.thinking.type !== "adaptive" || body.thinking.budget_tokens !== void 0)) {
5608
- reject(
5609
- "manual or disabled thinking",
5610
- "Use thinking: { type: 'adaptive' } and output_config.effort."
5611
- );
5612
- }
5613
- const outputConfig = body.output_config;
5614
- if (outputConfig !== void 0 && (!isRecord(outputConfig) || outputConfig.effort !== void 0 && !["low", "medium", "high", "xhigh", "max"].includes(String(outputConfig.effort)))) {
5615
- reject("output_config.effort", "Use low, medium, high, xhigh, or max effort.");
5616
- }
5617
- if (body.temperature !== void 0 && body.temperature !== 1) {
5618
- reject("temperature", "Omit temperature or use the default value 1.");
5619
- }
5620
- if (body.top_p !== void 0 && (typeof body.top_p !== "number" || body.top_p < 0.99 || body.top_p > 1)) {
5621
- reject("top_p", "Omit top_p or use a value from 0.99 to 1.");
5685
+ if (capability.forcedToolChoice === "rejected") {
5686
+ const toolChoice = body.tool_choice;
5687
+ if (isRecord(toolChoice) && (toolChoice.type === "any" || toolChoice.type === "tool")) {
5688
+ reject("forced tool choice", "Use toolChoice: 'auto' or 'none' on this model.");
5689
+ }
5690
+ }
5691
+ if (capability.strictThinking) {
5692
+ const offShape = capability.thinking === "adaptive-always-on" ? void 0 : capability.offShape ?? "disabled";
5693
+ const thinking = body.thinking;
5694
+ const outputConfig = body.output_config;
5695
+ const effort = isRecord(outputConfig) ? outputConfig.effort : void 0;
5696
+ if (thinking !== void 0 && offShape === void 0) {
5697
+ if (!isRecord(thinking) || thinking.type !== "adaptive" || thinking.budget_tokens !== void 0) {
5698
+ reject(
5699
+ "manual or disabled thinking",
5700
+ "Use thinking: { type: 'adaptive' } and output_config.effort."
5701
+ );
5702
+ }
5703
+ } else if (thinking !== void 0) {
5704
+ if (!isRecord(thinking) || thinking.type !== "adaptive" && thinking.type !== offShape) {
5705
+ reject(
5706
+ "thinking.type",
5707
+ `Use thinking: { type: 'adaptive' }, or { type: '${offShape}' } to turn thinking off.`
5708
+ );
5709
+ }
5710
+ const record = thinking;
5711
+ if (record.type === "adaptive" && record.budget_tokens !== void 0) {
5712
+ reject("thinking.budget_tokens", "Use output_config.effort instead of budget_tokens.");
5713
+ }
5714
+ if (record.type === offShape) {
5715
+ const extra = Object.keys(record).filter((key) => key !== "type");
5716
+ if (extra.length > 0) {
5717
+ reject(
5718
+ `thinking.${offShape}.${extra[0]}`,
5719
+ `Send thinking: { type: '${offShape}' } with no other fields.`
5720
+ );
5721
+ }
5722
+ }
5723
+ }
5724
+ if (outputConfig !== void 0 && (!isRecord(outputConfig) || effort !== void 0 && !isNativeClaudeEffort(effort))) {
5725
+ reject("output_config.effort", "Use low, medium, high, xhigh, or max effort.");
5726
+ }
5727
+ if (offShape !== void 0 && isRecord(thinking) && thinking.type === offShape && effort !== void 0 && capability.disableAt && !isEffortAtOrBelow(effort, capability.disableAt)) {
5728
+ reject(
5729
+ "output_config.effort",
5730
+ `Thinking can be turned off only at effort '${capability.disableAt}' or below; lower the effort or use adaptive thinking.`
5731
+ );
5732
+ }
5622
5733
  }
5623
- if (body.top_k !== void 0) {
5624
- reject("top_k", "Omit top_k on this model.");
5734
+ if (capability.defaultOnlySampling) {
5735
+ if (body.temperature !== void 0 && body.temperature !== 1) {
5736
+ reject("temperature", "Omit temperature or use the default value 1.");
5737
+ }
5738
+ if (body.top_p !== void 0 && body.top_p !== 0.99) {
5739
+ reject("top_p", "Omit top_p or use the default value 0.99.");
5740
+ }
5741
+ if (body.temperature !== void 0 && body.top_p !== void 0) {
5742
+ reject("temperature and top_p", "Send at most one of temperature and top_p.");
5743
+ }
5744
+ if (body.top_k !== void 0) {
5745
+ reject("top_k", "Omit top_k on this model.");
5746
+ }
5625
5747
  }
5626
- const replayed = hasReplayedThinking(body);
5627
- if (!replayed) return;
5628
- const thinking = isRecord(body.thinking) ? body.thinking : { type: "adaptive" };
5629
- const binding = thinking.block_binding;
5630
- if (binding !== void 0 && (!isRecord(binding) || binding.prefix_mismatch_behavior !== "error" && binding.prefix_mismatch_behavior !== "drop_block")) {
5631
- reject("thinking.block_binding", "Use prefix_mismatch_behavior: 'error' or 'drop_block'.");
5748
+ if (capability.thinkingBinding === true && isFinalThinkingAdaptive(capability, body)) {
5749
+ const thinking = isRecord(body.thinking) ? body.thinking : { type: "adaptive" };
5750
+ const binding = thinking.block_binding;
5751
+ if (binding !== void 0 && (!isRecord(binding) || binding.prefix_mismatch_behavior !== "error" && binding.prefix_mismatch_behavior !== "drop_block")) {
5752
+ reject("thinking.block_binding", "Use prefix_mismatch_behavior: 'error' or 'drop_block'.");
5753
+ }
5754
+ if (hasReplayedThinking(body)) {
5755
+ body.thinking = {
5756
+ ...thinking,
5757
+ block_binding: binding ?? { prefix_mismatch_behavior: "drop_block" }
5758
+ };
5759
+ }
5632
5760
  }
5633
- body.thinking = {
5634
- ...thinking,
5635
- block_binding: binding ?? { prefix_mismatch_behavior: "drop_block" }
5636
- };
5637
5761
  }
5638
5762
  /** Extract a human-readable message from an API error response body. */
5639
5763
  extractErrorMessage(body, status) {