@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/README.md
CHANGED
|
@@ -105,7 +105,7 @@ import { lookupOrder } from '../tools/db.js';
|
|
|
105
105
|
|
|
106
106
|
export const supportAgent = agent({
|
|
107
107
|
name: 'support',
|
|
108
|
-
model: 'openai-responses:gpt-
|
|
108
|
+
model: 'openai-responses:gpt-6-sol',
|
|
109
109
|
system: 'You are a customer support agent. Use tools to look up order information.',
|
|
110
110
|
tools: [lookupOrder],
|
|
111
111
|
});
|
|
@@ -206,13 +206,12 @@ import { agent } from '@axlsdk/axl';
|
|
|
206
206
|
|
|
207
207
|
const researcher = agent({
|
|
208
208
|
name: 'researcher',
|
|
209
|
-
model: 'openai-responses:gpt-
|
|
209
|
+
model: 'openai-responses:gpt-6-sol',
|
|
210
210
|
system: 'You are a research assistant.',
|
|
211
211
|
tools: [calculator],
|
|
212
212
|
effort: 'high',
|
|
213
213
|
maxTurns: 10,
|
|
214
214
|
timeout: '30s',
|
|
215
|
-
temperature: 0.7,
|
|
216
215
|
version: 'v1.2',
|
|
217
216
|
});
|
|
218
217
|
```
|
|
@@ -223,8 +222,8 @@ Dynamic model and system prompt selection:
|
|
|
223
222
|
const dynamicAgent = agent({
|
|
224
223
|
model: (ctx) =>
|
|
225
224
|
ctx.metadata?.tier === 'premium'
|
|
226
|
-
? 'openai-responses:gpt-
|
|
227
|
-
: 'openai-responses:gpt-
|
|
225
|
+
? 'openai-responses:gpt-6-sol'
|
|
226
|
+
: 'openai-responses:gpt-6-luna',
|
|
228
227
|
system: (ctx) => `You are a ${ctx.metadata?.role ?? 'general'} assistant.`,
|
|
229
228
|
});
|
|
230
229
|
```
|
|
@@ -263,7 +262,7 @@ for precedence, nested asks, and provider timing details.
|
|
|
263
262
|
|
|
264
263
|
```typescript
|
|
265
264
|
const router = agent({
|
|
266
|
-
model: 'openai-responses:gpt-
|
|
265
|
+
model: 'openai-responses:gpt-6-luna',
|
|
267
266
|
system: 'Route to the right specialist.',
|
|
268
267
|
handoffs: (ctx) => {
|
|
269
268
|
const base = [
|
|
@@ -298,7 +297,7 @@ The `effort` parameter provides a unified way to control reasoning depth across
|
|
|
298
297
|
```typescript
|
|
299
298
|
// Simple levels — works on any provider
|
|
300
299
|
const reasoner = agent({
|
|
301
|
-
model: 'anthropic:claude-opus-
|
|
300
|
+
model: 'anthropic:claude-opus-5-5',
|
|
302
301
|
system: 'You are a careful analyst.',
|
|
303
302
|
effort: 'high', // 'none' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'
|
|
304
303
|
});
|
|
@@ -402,8 +401,8 @@ To observe events between `ctx.ask()` calls — e.g., streaming `partial_object`
|
|
|
402
401
|
// compiles standalone.
|
|
403
402
|
const outlineSchema = z.object({ outline: z.array(z.string()) });
|
|
404
403
|
const draftSchema = z.object({ draft: z.string() });
|
|
405
|
-
const planner = agent({ model: 'openai:gpt-
|
|
406
|
-
const writer = agent({ model: 'openai:gpt-
|
|
404
|
+
const planner = agent({ model: 'openai-responses:gpt-6-sol', system: 'Plan an outline.' });
|
|
405
|
+
const writer = agent({ model: 'openai-responses:gpt-6-sol', system: 'Write a draft.' });
|
|
407
406
|
|
|
408
407
|
const wf = workflow({
|
|
409
408
|
name: 'two-step',
|
|
@@ -631,7 +630,7 @@ const containsPII = (text: string) => /\b\d{3}-\d{2}-\d{4}\b/.test(text);
|
|
|
631
630
|
const isOffTopic = (text: string) => !text.toLowerCase().includes('support');
|
|
632
631
|
|
|
633
632
|
const safe = agent({
|
|
634
|
-
model: 'openai-responses:gpt-
|
|
633
|
+
model: 'openai-responses:gpt-6-sol',
|
|
635
634
|
system: 'You are a helpful assistant.',
|
|
636
635
|
guardrails: {
|
|
637
636
|
input: async (prompt, ctx) => {
|
|
@@ -786,7 +785,7 @@ const session = runtime.session('user-123', {
|
|
|
786
785
|
history: {
|
|
787
786
|
maxMessages: 100,
|
|
788
787
|
summarize: true,
|
|
789
|
-
summaryModel: 'openai-responses:gpt-
|
|
788
|
+
summaryModel: 'openai-responses:gpt-6-luna',
|
|
790
789
|
},
|
|
791
790
|
persist: true,
|
|
792
791
|
});
|
|
@@ -826,10 +825,10 @@ import {
|
|
|
826
825
|
Four native adapters using the `provider:model` URI scheme (plus the OpenAI-compatible presets above):
|
|
827
826
|
|
|
828
827
|
```
|
|
829
|
-
openai-responses:gpt-
|
|
830
|
-
openai:gpt-
|
|
831
|
-
anthropic:claude-
|
|
832
|
-
google:gemini-3.
|
|
828
|
+
openai-responses:gpt-6-sol # OpenAI Responses API (preferred over Chat Completions)
|
|
829
|
+
openai:gpt-6-sol # OpenAI Chat Completions (text; use Responses for tools)
|
|
830
|
+
anthropic:claude-sonnet-5-5 # Anthropic (also claude-haiku-5-5, claude-opus-5-5)
|
|
831
|
+
google:gemini-3.8-flash # Google Gemini
|
|
833
832
|
```
|
|
834
833
|
|
|
835
834
|
See [docs/providers.md](../../docs/providers.md) for the full model list including reasoning models.
|
package/dist/index.cjs
CHANGED
|
@@ -581,7 +581,7 @@ var sharedGuard = typeof installedGuard === "object" && installedGuard !== null
|
|
|
581
581
|
var buildPath = typeof __AXL_BUILD_PATH__ === "string" ? __AXL_BUILD_PATH__ : "<source>";
|
|
582
582
|
var thisCopy = {
|
|
583
583
|
path: buildPath.startsWith("file:") ? (0, import_node_url.fileURLToPath)(buildPath) : buildPath,
|
|
584
|
-
version: true ? "0.25.
|
|
584
|
+
version: true ? "0.25.2" : "unknown"
|
|
585
585
|
};
|
|
586
586
|
function warnCrossCopy(other, joined) {
|
|
587
587
|
if (other === thisCopy) return;
|
|
@@ -5146,6 +5146,17 @@ var ANTHROPIC_THINKING_BINDING_BETA = "thinking-binding-controls-2026-08-01";
|
|
|
5146
5146
|
function isRecord(value) {
|
|
5147
5147
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5148
5148
|
}
|
|
5149
|
+
function isFinalThinkingAdaptive(capability, body) {
|
|
5150
|
+
const thinking = body.thinking;
|
|
5151
|
+
if (thinking === void 0) {
|
|
5152
|
+
return capability.thinking === "adaptive-default-on" || capability.thinking === "adaptive-always-on";
|
|
5153
|
+
}
|
|
5154
|
+
return isRecord(thinking) && thinking.type === "adaptive";
|
|
5155
|
+
}
|
|
5156
|
+
var NATIVE_CLAUDE_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
|
|
5157
|
+
function isNativeClaudeEffort(value) {
|
|
5158
|
+
return NATIVE_CLAUDE_EFFORTS.includes(value);
|
|
5159
|
+
}
|
|
5149
5160
|
function hasReplayedThinking(body) {
|
|
5150
5161
|
return Array.isArray(body.messages) && body.messages.some(
|
|
5151
5162
|
(message) => isRecord(message) && Array.isArray(message.content) && message.content.some(
|
|
@@ -5180,11 +5191,40 @@ function hasAnthropicProviderFileImage(messages) {
|
|
|
5180
5191
|
);
|
|
5181
5192
|
}
|
|
5182
5193
|
var CLAUDE_CAPABILITIES = {
|
|
5194
|
+
// Thinking off is `between_tools` (progress updates between tool calls);
|
|
5195
|
+
// `disabled` is a provider 400. Forced tool choice is a 400.
|
|
5196
|
+
"claude-sonnet-5-5": {
|
|
5197
|
+
thinking: "adaptive-default-on",
|
|
5198
|
+
effortLevels: ["low", "medium", "high", "xhigh", "max"],
|
|
5199
|
+
manualBudget: false,
|
|
5200
|
+
stripTemperature: true,
|
|
5201
|
+
disableAt: "high",
|
|
5202
|
+
offShape: "between_tools",
|
|
5203
|
+
forcedToolChoice: "rejected",
|
|
5204
|
+
defaultOnlySampling: true,
|
|
5205
|
+
strictThinking: true,
|
|
5206
|
+
thinkingBinding: true
|
|
5207
|
+
},
|
|
5208
|
+
// Thinking off is `disabled`, only at effort high or below. Forced tool
|
|
5209
|
+
// choice is accepted (the provider skips thinking for that turn).
|
|
5210
|
+
"claude-haiku-5-5": {
|
|
5211
|
+
thinking: "adaptive-default-on",
|
|
5212
|
+
effortLevels: ["low", "medium", "high", "xhigh", "max"],
|
|
5213
|
+
manualBudget: false,
|
|
5214
|
+
stripTemperature: true,
|
|
5215
|
+
disableAt: "high",
|
|
5216
|
+
defaultOnlySampling: true,
|
|
5217
|
+
strictThinking: true,
|
|
5218
|
+
thinkingBinding: true
|
|
5219
|
+
},
|
|
5183
5220
|
"claude-opus-5-5": {
|
|
5184
5221
|
thinking: "adaptive-always-on",
|
|
5185
5222
|
effortLevels: ["low", "medium", "high", "xhigh", "max"],
|
|
5186
5223
|
manualBudget: false,
|
|
5187
5224
|
stripTemperature: true,
|
|
5225
|
+
forcedToolChoice: "rejected",
|
|
5226
|
+
defaultOnlySampling: true,
|
|
5227
|
+
strictThinking: true,
|
|
5188
5228
|
thinkingBinding: true
|
|
5189
5229
|
},
|
|
5190
5230
|
"claude-fable-5-1": {
|
|
@@ -5192,6 +5232,9 @@ var CLAUDE_CAPABILITIES = {
|
|
|
5192
5232
|
effortLevels: ["low", "medium", "high", "xhigh", "max"],
|
|
5193
5233
|
manualBudget: false,
|
|
5194
5234
|
stripTemperature: true,
|
|
5235
|
+
forcedToolChoice: "rejected",
|
|
5236
|
+
defaultOnlySampling: true,
|
|
5237
|
+
strictThinking: true,
|
|
5195
5238
|
thinkingBinding: true
|
|
5196
5239
|
},
|
|
5197
5240
|
"claude-fable-5": {
|
|
@@ -5286,6 +5329,15 @@ function resolveClaudeCapability(model) {
|
|
|
5286
5329
|
}
|
|
5287
5330
|
var DEFAULT_CACHE_READ_MULTIPLIER = 0.1;
|
|
5288
5331
|
var ANTHROPIC_RATES = {
|
|
5332
|
+
// Sonnet 5.5 cache reads are 0.05x ($0.10/MTok): the pricing table, its
|
|
5333
|
+
// footnote, the models overview, and the prompt-caching guide agree
|
|
5334
|
+
// (re-checked 2026-10-07).
|
|
5335
|
+
"claude-sonnet-5-5": { input: 2e-6, output: 1e-5, cacheReadMultiplier: 0.05 },
|
|
5336
|
+
"claude-haiku-5-5": {
|
|
5337
|
+
input: 1e-7,
|
|
5338
|
+
output: 5e-7,
|
|
5339
|
+
longPrompt: { aboveTokens: 1e5, card: { input: 5e-7, output: 25e-7 } }
|
|
5340
|
+
},
|
|
5289
5341
|
"claude-opus-5-5": { input: 4e-6, output: 2e-5, cacheReadMultiplier: 0.05 },
|
|
5290
5342
|
"claude-fable-5-1": { input: 1e-5, output: 5e-5, cacheReadMultiplier: 0.025 },
|
|
5291
5343
|
"claude-fable-5": { input: 1e-5, output: 5e-5 },
|
|
@@ -5348,14 +5400,16 @@ function estimateAnthropicCost(model, usage) {
|
|
|
5348
5400
|
return void 0;
|
|
5349
5401
|
}
|
|
5350
5402
|
const cacheWriteTotal = safeTokenSum(cacheWrite5m, cacheWrite1h);
|
|
5351
|
-
|
|
5403
|
+
const promptTokens = cacheWriteTotal === void 0 ? void 0 : safeTokenSum(usage.inputTokens, cacheRead, cacheWriteTotal);
|
|
5404
|
+
if (cacheWriteTotal === void 0 || promptTokens === void 0) {
|
|
5352
5405
|
return void 0;
|
|
5353
5406
|
}
|
|
5354
5407
|
if (usage.aggregateCacheWriteTokens !== void 0 && (!isValidTokenCount(usage.aggregateCacheWriteTokens) || usage.aggregateCacheWriteTokens !== cacheWriteTotal)) {
|
|
5355
5408
|
return void 0;
|
|
5356
5409
|
}
|
|
5357
|
-
const
|
|
5358
|
-
const
|
|
5410
|
+
const card = rate.longPrompt && promptTokens > rate.longPrompt.aboveTokens ? rate.longPrompt.card : rate;
|
|
5411
|
+
const { input, output } = card;
|
|
5412
|
+
const cacheReadRate = input * (card.cacheReadMultiplier ?? DEFAULT_CACHE_READ_MULTIPLIER);
|
|
5359
5413
|
return usage.inputTokens * input + cacheRead * cacheReadRate + cacheWrite5m * input * 1.25 + cacheWrite1h * input * 2 + usage.outputTokens * output;
|
|
5360
5414
|
}
|
|
5361
5415
|
var THINKING_BUDGETS = {
|
|
@@ -5417,7 +5471,7 @@ function resolveClaudeThinking(model, resolved) {
|
|
|
5417
5471
|
};
|
|
5418
5472
|
}
|
|
5419
5473
|
return {
|
|
5420
|
-
thinking: { type: "disabled" },
|
|
5474
|
+
thinking: { type: capability.offShape ?? "disabled" },
|
|
5421
5475
|
outputConfig: activeEffort ? { effort: activeEffort } : void 0,
|
|
5422
5476
|
stripTemperature: true
|
|
5423
5477
|
};
|
|
@@ -5823,50 +5877,106 @@ var AnthropicProvider = class {
|
|
|
5823
5877
|
...betas.length > 0 ? { "anthropic-beta": betas.join(",") } : {}
|
|
5824
5878
|
};
|
|
5825
5879
|
}
|
|
5880
|
+
/**
|
|
5881
|
+
* Whether the final body needs the binding beta header. Runs after
|
|
5882
|
+
* `validateAndBindFinalBody`, which has already injected `block_binding`
|
|
5883
|
+
* wherever it applies, so the header follows the final body rather than
|
|
5884
|
+
* re-deriving the injection rule.
|
|
5885
|
+
*/
|
|
5826
5886
|
requiresBindingBeta(body) {
|
|
5887
|
+
const capability = resolveClaudeCapability(String(body.model));
|
|
5827
5888
|
const thinking = body.thinking;
|
|
5828
|
-
return
|
|
5889
|
+
return capability?.thinkingBinding === true && isRecord(thinking) && thinking.type === "adaptive" && thinking.block_binding !== void 0;
|
|
5829
5890
|
}
|
|
5891
|
+
/**
|
|
5892
|
+
* Validate the final body (after `providerOptions`) against the effective
|
|
5893
|
+
* model's capability, then inject `block_binding` where it applies. Every
|
|
5894
|
+
* rule is gated on its own capability field and is a no-op when unset, so a
|
|
5895
|
+
* model only gets the guards its provider contract calls for.
|
|
5896
|
+
*/
|
|
5830
5897
|
validateAndBindFinalBody(body) {
|
|
5831
5898
|
const model = typeof body.model === "string" ? body.model : "";
|
|
5832
|
-
|
|
5899
|
+
const capability = resolveClaudeCapability(model);
|
|
5900
|
+
if (!capability) return;
|
|
5833
5901
|
const reject = (option, remediation) => {
|
|
5834
5902
|
throw new UnsupportedModelOptionError({ provider: this.name, model, option, remediation });
|
|
5835
5903
|
};
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
|
|
5853
|
-
|
|
5854
|
-
|
|
5904
|
+
if (capability.forcedToolChoice === "rejected") {
|
|
5905
|
+
const toolChoice = body.tool_choice;
|
|
5906
|
+
if (isRecord(toolChoice) && (toolChoice.type === "any" || toolChoice.type === "tool")) {
|
|
5907
|
+
reject("forced tool choice", "Use toolChoice: 'auto' or 'none' on this model.");
|
|
5908
|
+
}
|
|
5909
|
+
}
|
|
5910
|
+
if (capability.strictThinking) {
|
|
5911
|
+
const offShape = capability.thinking === "adaptive-always-on" ? void 0 : capability.offShape ?? "disabled";
|
|
5912
|
+
const thinking = body.thinking;
|
|
5913
|
+
const outputConfig = body.output_config;
|
|
5914
|
+
const effort = isRecord(outputConfig) ? outputConfig.effort : void 0;
|
|
5915
|
+
if (thinking !== void 0 && offShape === void 0) {
|
|
5916
|
+
if (!isRecord(thinking) || thinking.type !== "adaptive" || thinking.budget_tokens !== void 0) {
|
|
5917
|
+
reject(
|
|
5918
|
+
"manual or disabled thinking",
|
|
5919
|
+
"Use thinking: { type: 'adaptive' } and output_config.effort."
|
|
5920
|
+
);
|
|
5921
|
+
}
|
|
5922
|
+
} else if (thinking !== void 0) {
|
|
5923
|
+
if (!isRecord(thinking) || thinking.type !== "adaptive" && thinking.type !== offShape) {
|
|
5924
|
+
reject(
|
|
5925
|
+
"thinking.type",
|
|
5926
|
+
`Use thinking: { type: 'adaptive' }, or { type: '${offShape}' } to turn thinking off.`
|
|
5927
|
+
);
|
|
5928
|
+
}
|
|
5929
|
+
const record = thinking;
|
|
5930
|
+
if (record.type === "adaptive" && record.budget_tokens !== void 0) {
|
|
5931
|
+
reject("thinking.budget_tokens", "Use output_config.effort instead of budget_tokens.");
|
|
5932
|
+
}
|
|
5933
|
+
if (record.type === offShape) {
|
|
5934
|
+
const extra = Object.keys(record).filter((key) => key !== "type");
|
|
5935
|
+
if (extra.length > 0) {
|
|
5936
|
+
reject(
|
|
5937
|
+
`thinking.${offShape}.${extra[0]}`,
|
|
5938
|
+
`Send thinking: { type: '${offShape}' } with no other fields.`
|
|
5939
|
+
);
|
|
5940
|
+
}
|
|
5941
|
+
}
|
|
5942
|
+
}
|
|
5943
|
+
if (outputConfig !== void 0 && (!isRecord(outputConfig) || effort !== void 0 && !isNativeClaudeEffort(effort))) {
|
|
5944
|
+
reject("output_config.effort", "Use low, medium, high, xhigh, or max effort.");
|
|
5945
|
+
}
|
|
5946
|
+
if (offShape !== void 0 && isRecord(thinking) && thinking.type === offShape && effort !== void 0 && capability.disableAt && !isEffortAtOrBelow(effort, capability.disableAt)) {
|
|
5947
|
+
reject(
|
|
5948
|
+
"output_config.effort",
|
|
5949
|
+
`Thinking can be turned off only at effort '${capability.disableAt}' or below; lower the effort or use adaptive thinking.`
|
|
5950
|
+
);
|
|
5951
|
+
}
|
|
5855
5952
|
}
|
|
5856
|
-
if (
|
|
5857
|
-
|
|
5953
|
+
if (capability.defaultOnlySampling) {
|
|
5954
|
+
if (body.temperature !== void 0 && body.temperature !== 1) {
|
|
5955
|
+
reject("temperature", "Omit temperature or use the default value 1.");
|
|
5956
|
+
}
|
|
5957
|
+
if (body.top_p !== void 0 && body.top_p !== 0.99) {
|
|
5958
|
+
reject("top_p", "Omit top_p or use the default value 0.99.");
|
|
5959
|
+
}
|
|
5960
|
+
if (body.temperature !== void 0 && body.top_p !== void 0) {
|
|
5961
|
+
reject("temperature and top_p", "Send at most one of temperature and top_p.");
|
|
5962
|
+
}
|
|
5963
|
+
if (body.top_k !== void 0) {
|
|
5964
|
+
reject("top_k", "Omit top_k on this model.");
|
|
5965
|
+
}
|
|
5858
5966
|
}
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5967
|
+
if (capability.thinkingBinding === true && isFinalThinkingAdaptive(capability, body)) {
|
|
5968
|
+
const thinking = isRecord(body.thinking) ? body.thinking : { type: "adaptive" };
|
|
5969
|
+
const binding = thinking.block_binding;
|
|
5970
|
+
if (binding !== void 0 && (!isRecord(binding) || binding.prefix_mismatch_behavior !== "error" && binding.prefix_mismatch_behavior !== "drop_block")) {
|
|
5971
|
+
reject("thinking.block_binding", "Use prefix_mismatch_behavior: 'error' or 'drop_block'.");
|
|
5972
|
+
}
|
|
5973
|
+
if (hasReplayedThinking(body)) {
|
|
5974
|
+
body.thinking = {
|
|
5975
|
+
...thinking,
|
|
5976
|
+
block_binding: binding ?? { prefix_mismatch_behavior: "drop_block" }
|
|
5977
|
+
};
|
|
5978
|
+
}
|
|
5865
5979
|
}
|
|
5866
|
-
body.thinking = {
|
|
5867
|
-
...thinking,
|
|
5868
|
-
block_binding: binding ?? { prefix_mismatch_behavior: "drop_block" }
|
|
5869
|
-
};
|
|
5870
5980
|
}
|
|
5871
5981
|
/** Extract a human-readable message from an API error response body. */
|
|
5872
5982
|
extractErrorMessage(body, status) {
|