@axlsdk/axl 0.25.1 → 0.25.2
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/README.md +14 -15
- package/dist/index.cjs +148 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +148 -38
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -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
|
@@ -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.
|
|
351
|
+
version: true ? "0.25.2" : "unknown"
|
|
352
352
|
};
|
|
353
353
|
function warnCrossCopy(other, joined) {
|
|
354
354
|
if (other === thisCopy) return;
|
|
@@ -4913,6 +4913,17 @@ var ANTHROPIC_THINKING_BINDING_BETA = "thinking-binding-controls-2026-08-01";
|
|
|
4913
4913
|
function isRecord(value) {
|
|
4914
4914
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4915
4915
|
}
|
|
4916
|
+
function isFinalThinkingAdaptive(capability, body) {
|
|
4917
|
+
const thinking = body.thinking;
|
|
4918
|
+
if (thinking === void 0) {
|
|
4919
|
+
return capability.thinking === "adaptive-default-on" || capability.thinking === "adaptive-always-on";
|
|
4920
|
+
}
|
|
4921
|
+
return isRecord(thinking) && thinking.type === "adaptive";
|
|
4922
|
+
}
|
|
4923
|
+
var NATIVE_CLAUDE_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
|
|
4924
|
+
function isNativeClaudeEffort(value) {
|
|
4925
|
+
return NATIVE_CLAUDE_EFFORTS.includes(value);
|
|
4926
|
+
}
|
|
4916
4927
|
function hasReplayedThinking(body) {
|
|
4917
4928
|
return Array.isArray(body.messages) && body.messages.some(
|
|
4918
4929
|
(message) => isRecord(message) && Array.isArray(message.content) && message.content.some(
|
|
@@ -4947,11 +4958,40 @@ function hasAnthropicProviderFileImage(messages) {
|
|
|
4947
4958
|
);
|
|
4948
4959
|
}
|
|
4949
4960
|
var CLAUDE_CAPABILITIES = {
|
|
4961
|
+
// Thinking off is `between_tools` (progress updates between tool calls);
|
|
4962
|
+
// `disabled` is a provider 400. Forced tool choice is a 400.
|
|
4963
|
+
"claude-sonnet-5-5": {
|
|
4964
|
+
thinking: "adaptive-default-on",
|
|
4965
|
+
effortLevels: ["low", "medium", "high", "xhigh", "max"],
|
|
4966
|
+
manualBudget: false,
|
|
4967
|
+
stripTemperature: true,
|
|
4968
|
+
disableAt: "high",
|
|
4969
|
+
offShape: "between_tools",
|
|
4970
|
+
forcedToolChoice: "rejected",
|
|
4971
|
+
defaultOnlySampling: true,
|
|
4972
|
+
strictThinking: true,
|
|
4973
|
+
thinkingBinding: true
|
|
4974
|
+
},
|
|
4975
|
+
// Thinking off is `disabled`, only at effort high or below. Forced tool
|
|
4976
|
+
// choice is accepted (the provider skips thinking for that turn).
|
|
4977
|
+
"claude-haiku-5-5": {
|
|
4978
|
+
thinking: "adaptive-default-on",
|
|
4979
|
+
effortLevels: ["low", "medium", "high", "xhigh", "max"],
|
|
4980
|
+
manualBudget: false,
|
|
4981
|
+
stripTemperature: true,
|
|
4982
|
+
disableAt: "high",
|
|
4983
|
+
defaultOnlySampling: true,
|
|
4984
|
+
strictThinking: true,
|
|
4985
|
+
thinkingBinding: true
|
|
4986
|
+
},
|
|
4950
4987
|
"claude-opus-5-5": {
|
|
4951
4988
|
thinking: "adaptive-always-on",
|
|
4952
4989
|
effortLevels: ["low", "medium", "high", "xhigh", "max"],
|
|
4953
4990
|
manualBudget: false,
|
|
4954
4991
|
stripTemperature: true,
|
|
4992
|
+
forcedToolChoice: "rejected",
|
|
4993
|
+
defaultOnlySampling: true,
|
|
4994
|
+
strictThinking: true,
|
|
4955
4995
|
thinkingBinding: true
|
|
4956
4996
|
},
|
|
4957
4997
|
"claude-fable-5-1": {
|
|
@@ -4959,6 +4999,9 @@ var CLAUDE_CAPABILITIES = {
|
|
|
4959
4999
|
effortLevels: ["low", "medium", "high", "xhigh", "max"],
|
|
4960
5000
|
manualBudget: false,
|
|
4961
5001
|
stripTemperature: true,
|
|
5002
|
+
forcedToolChoice: "rejected",
|
|
5003
|
+
defaultOnlySampling: true,
|
|
5004
|
+
strictThinking: true,
|
|
4962
5005
|
thinkingBinding: true
|
|
4963
5006
|
},
|
|
4964
5007
|
"claude-fable-5": {
|
|
@@ -5053,6 +5096,15 @@ function resolveClaudeCapability(model) {
|
|
|
5053
5096
|
}
|
|
5054
5097
|
var DEFAULT_CACHE_READ_MULTIPLIER = 0.1;
|
|
5055
5098
|
var ANTHROPIC_RATES = {
|
|
5099
|
+
// Sonnet 5.5 cache reads are 0.05x ($0.10/MTok): the pricing table, its
|
|
5100
|
+
// footnote, the models overview, and the prompt-caching guide agree
|
|
5101
|
+
// (re-checked 2026-10-07).
|
|
5102
|
+
"claude-sonnet-5-5": { input: 2e-6, output: 1e-5, cacheReadMultiplier: 0.05 },
|
|
5103
|
+
"claude-haiku-5-5": {
|
|
5104
|
+
input: 1e-7,
|
|
5105
|
+
output: 5e-7,
|
|
5106
|
+
longPrompt: { aboveTokens: 1e5, card: { input: 5e-7, output: 25e-7 } }
|
|
5107
|
+
},
|
|
5056
5108
|
"claude-opus-5-5": { input: 4e-6, output: 2e-5, cacheReadMultiplier: 0.05 },
|
|
5057
5109
|
"claude-fable-5-1": { input: 1e-5, output: 5e-5, cacheReadMultiplier: 0.025 },
|
|
5058
5110
|
"claude-fable-5": { input: 1e-5, output: 5e-5 },
|
|
@@ -5115,14 +5167,16 @@ function estimateAnthropicCost(model, usage) {
|
|
|
5115
5167
|
return void 0;
|
|
5116
5168
|
}
|
|
5117
5169
|
const cacheWriteTotal = safeTokenSum(cacheWrite5m, cacheWrite1h);
|
|
5118
|
-
|
|
5170
|
+
const promptTokens = cacheWriteTotal === void 0 ? void 0 : safeTokenSum(usage.inputTokens, cacheRead, cacheWriteTotal);
|
|
5171
|
+
if (cacheWriteTotal === void 0 || promptTokens === void 0) {
|
|
5119
5172
|
return void 0;
|
|
5120
5173
|
}
|
|
5121
5174
|
if (usage.aggregateCacheWriteTokens !== void 0 && (!isValidTokenCount(usage.aggregateCacheWriteTokens) || usage.aggregateCacheWriteTokens !== cacheWriteTotal)) {
|
|
5122
5175
|
return void 0;
|
|
5123
5176
|
}
|
|
5124
|
-
const
|
|
5125
|
-
const
|
|
5177
|
+
const card = rate.longPrompt && promptTokens > rate.longPrompt.aboveTokens ? rate.longPrompt.card : rate;
|
|
5178
|
+
const { input, output } = card;
|
|
5179
|
+
const cacheReadRate = input * (card.cacheReadMultiplier ?? DEFAULT_CACHE_READ_MULTIPLIER);
|
|
5126
5180
|
return usage.inputTokens * input + cacheRead * cacheReadRate + cacheWrite5m * input * 1.25 + cacheWrite1h * input * 2 + usage.outputTokens * output;
|
|
5127
5181
|
}
|
|
5128
5182
|
var THINKING_BUDGETS = {
|
|
@@ -5184,7 +5238,7 @@ function resolveClaudeThinking(model, resolved) {
|
|
|
5184
5238
|
};
|
|
5185
5239
|
}
|
|
5186
5240
|
return {
|
|
5187
|
-
thinking: { type: "disabled" },
|
|
5241
|
+
thinking: { type: capability.offShape ?? "disabled" },
|
|
5188
5242
|
outputConfig: activeEffort ? { effort: activeEffort } : void 0,
|
|
5189
5243
|
stripTemperature: true
|
|
5190
5244
|
};
|
|
@@ -5590,50 +5644,106 @@ var AnthropicProvider = class {
|
|
|
5590
5644
|
...betas.length > 0 ? { "anthropic-beta": betas.join(",") } : {}
|
|
5591
5645
|
};
|
|
5592
5646
|
}
|
|
5647
|
+
/**
|
|
5648
|
+
* Whether the final body needs the binding beta header. Runs after
|
|
5649
|
+
* `validateAndBindFinalBody`, which has already injected `block_binding`
|
|
5650
|
+
* wherever it applies, so the header follows the final body rather than
|
|
5651
|
+
* re-deriving the injection rule.
|
|
5652
|
+
*/
|
|
5593
5653
|
requiresBindingBeta(body) {
|
|
5654
|
+
const capability = resolveClaudeCapability(String(body.model));
|
|
5594
5655
|
const thinking = body.thinking;
|
|
5595
|
-
return
|
|
5656
|
+
return capability?.thinkingBinding === true && isRecord(thinking) && thinking.type === "adaptive" && thinking.block_binding !== void 0;
|
|
5596
5657
|
}
|
|
5658
|
+
/**
|
|
5659
|
+
* Validate the final body (after `providerOptions`) against the effective
|
|
5660
|
+
* model's capability, then inject `block_binding` where it applies. Every
|
|
5661
|
+
* rule is gated on its own capability field and is a no-op when unset, so a
|
|
5662
|
+
* model only gets the guards its provider contract calls for.
|
|
5663
|
+
*/
|
|
5597
5664
|
validateAndBindFinalBody(body) {
|
|
5598
5665
|
const model = typeof body.model === "string" ? body.model : "";
|
|
5599
|
-
|
|
5666
|
+
const capability = resolveClaudeCapability(model);
|
|
5667
|
+
if (!capability) return;
|
|
5600
5668
|
const reject = (option, remediation) => {
|
|
5601
5669
|
throw new UnsupportedModelOptionError({ provider: this.name, model, option, remediation });
|
|
5602
5670
|
};
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5671
|
+
if (capability.forcedToolChoice === "rejected") {
|
|
5672
|
+
const toolChoice = body.tool_choice;
|
|
5673
|
+
if (isRecord(toolChoice) && (toolChoice.type === "any" || toolChoice.type === "tool")) {
|
|
5674
|
+
reject("forced tool choice", "Use toolChoice: 'auto' or 'none' on this model.");
|
|
5675
|
+
}
|
|
5676
|
+
}
|
|
5677
|
+
if (capability.strictThinking) {
|
|
5678
|
+
const offShape = capability.thinking === "adaptive-always-on" ? void 0 : capability.offShape ?? "disabled";
|
|
5679
|
+
const thinking = body.thinking;
|
|
5680
|
+
const outputConfig = body.output_config;
|
|
5681
|
+
const effort = isRecord(outputConfig) ? outputConfig.effort : void 0;
|
|
5682
|
+
if (thinking !== void 0 && offShape === void 0) {
|
|
5683
|
+
if (!isRecord(thinking) || thinking.type !== "adaptive" || thinking.budget_tokens !== void 0) {
|
|
5684
|
+
reject(
|
|
5685
|
+
"manual or disabled thinking",
|
|
5686
|
+
"Use thinking: { type: 'adaptive' } and output_config.effort."
|
|
5687
|
+
);
|
|
5688
|
+
}
|
|
5689
|
+
} else if (thinking !== void 0) {
|
|
5690
|
+
if (!isRecord(thinking) || thinking.type !== "adaptive" && thinking.type !== offShape) {
|
|
5691
|
+
reject(
|
|
5692
|
+
"thinking.type",
|
|
5693
|
+
`Use thinking: { type: 'adaptive' }, or { type: '${offShape}' } to turn thinking off.`
|
|
5694
|
+
);
|
|
5695
|
+
}
|
|
5696
|
+
const record = thinking;
|
|
5697
|
+
if (record.type === "adaptive" && record.budget_tokens !== void 0) {
|
|
5698
|
+
reject("thinking.budget_tokens", "Use output_config.effort instead of budget_tokens.");
|
|
5699
|
+
}
|
|
5700
|
+
if (record.type === offShape) {
|
|
5701
|
+
const extra = Object.keys(record).filter((key) => key !== "type");
|
|
5702
|
+
if (extra.length > 0) {
|
|
5703
|
+
reject(
|
|
5704
|
+
`thinking.${offShape}.${extra[0]}`,
|
|
5705
|
+
`Send thinking: { type: '${offShape}' } with no other fields.`
|
|
5706
|
+
);
|
|
5707
|
+
}
|
|
5708
|
+
}
|
|
5709
|
+
}
|
|
5710
|
+
if (outputConfig !== void 0 && (!isRecord(outputConfig) || effort !== void 0 && !isNativeClaudeEffort(effort))) {
|
|
5711
|
+
reject("output_config.effort", "Use low, medium, high, xhigh, or max effort.");
|
|
5712
|
+
}
|
|
5713
|
+
if (offShape !== void 0 && isRecord(thinking) && thinking.type === offShape && effort !== void 0 && capability.disableAt && !isEffortAtOrBelow(effort, capability.disableAt)) {
|
|
5714
|
+
reject(
|
|
5715
|
+
"output_config.effort",
|
|
5716
|
+
`Thinking can be turned off only at effort '${capability.disableAt}' or below; lower the effort or use adaptive thinking.`
|
|
5717
|
+
);
|
|
5718
|
+
}
|
|
5622
5719
|
}
|
|
5623
|
-
if (
|
|
5624
|
-
|
|
5720
|
+
if (capability.defaultOnlySampling) {
|
|
5721
|
+
if (body.temperature !== void 0 && body.temperature !== 1) {
|
|
5722
|
+
reject("temperature", "Omit temperature or use the default value 1.");
|
|
5723
|
+
}
|
|
5724
|
+
if (body.top_p !== void 0 && body.top_p !== 0.99) {
|
|
5725
|
+
reject("top_p", "Omit top_p or use the default value 0.99.");
|
|
5726
|
+
}
|
|
5727
|
+
if (body.temperature !== void 0 && body.top_p !== void 0) {
|
|
5728
|
+
reject("temperature and top_p", "Send at most one of temperature and top_p.");
|
|
5729
|
+
}
|
|
5730
|
+
if (body.top_k !== void 0) {
|
|
5731
|
+
reject("top_k", "Omit top_k on this model.");
|
|
5732
|
+
}
|
|
5625
5733
|
}
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5734
|
+
if (capability.thinkingBinding === true && isFinalThinkingAdaptive(capability, body)) {
|
|
5735
|
+
const thinking = isRecord(body.thinking) ? body.thinking : { type: "adaptive" };
|
|
5736
|
+
const binding = thinking.block_binding;
|
|
5737
|
+
if (binding !== void 0 && (!isRecord(binding) || binding.prefix_mismatch_behavior !== "error" && binding.prefix_mismatch_behavior !== "drop_block")) {
|
|
5738
|
+
reject("thinking.block_binding", "Use prefix_mismatch_behavior: 'error' or 'drop_block'.");
|
|
5739
|
+
}
|
|
5740
|
+
if (hasReplayedThinking(body)) {
|
|
5741
|
+
body.thinking = {
|
|
5742
|
+
...thinking,
|
|
5743
|
+
block_binding: binding ?? { prefix_mismatch_behavior: "drop_block" }
|
|
5744
|
+
};
|
|
5745
|
+
}
|
|
5632
5746
|
}
|
|
5633
|
-
body.thinking = {
|
|
5634
|
-
...thinking,
|
|
5635
|
-
block_binding: binding ?? { prefix_mismatch_behavior: "drop_block" }
|
|
5636
|
-
};
|
|
5637
5747
|
}
|
|
5638
5748
|
/** Extract a human-readable message from an API error response body. */
|
|
5639
5749
|
extractErrorMessage(body, status) {
|