@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/README.md +14 -15
- package/dist/index.cjs +170 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -4
- package/dist/index.d.ts +16 -4
- package/dist/index.js +170 -46
- 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.3" : "unknown"
|
|
585
585
|
};
|
|
586
586
|
function warnCrossCopy(other, joined) {
|
|
587
587
|
if (other === thisCopy) return;
|
|
@@ -3850,7 +3850,7 @@ var OPENAI_PRICING = {
|
|
|
3850
3850
|
"gpt-4.1-mini": [4e-7, 16e-7, 0.25],
|
|
3851
3851
|
"gpt-4.1-nano": [1e-7, 4e-7, 0.25],
|
|
3852
3852
|
o3: [2e-6, 8e-6, 0.25],
|
|
3853
|
-
"o3-mini": [11e-7, 44e-7, 0.
|
|
3853
|
+
"o3-mini": [11e-7, 44e-7, 0.5],
|
|
3854
3854
|
"o4-mini": [11e-7, 44e-7, 0.25],
|
|
3855
3855
|
"gpt-5": [125e-8, 1e-5, 0.1],
|
|
3856
3856
|
"gpt-5-mini": [25e-8, 2e-6, 0.1],
|
|
@@ -3873,6 +3873,13 @@ var DIRECT_OPENAI_CATALOG = [
|
|
|
3873
3873
|
long: { input: 20 / M, cachedInput: 2 / M, cacheWrite: 25 / M, output: 75 / M },
|
|
3874
3874
|
contextBoundary: LONG_CONTEXT_BOUNDARY
|
|
3875
3875
|
},
|
|
3876
|
+
{
|
|
3877
|
+
aliases: ["gpt-6.1-sol"],
|
|
3878
|
+
// Rechecked 2026-10-15 against https://developers.openai.com/api/docs/pricing.
|
|
3879
|
+
short: { input: 2 / M, cachedInput: 0.1 / M, cacheWrite: 2.5 / M, output: 10 / M },
|
|
3880
|
+
long: { input: 4 / M, cachedInput: 0.2 / M, cacheWrite: 5 / M, output: 15 / M },
|
|
3881
|
+
contextBoundary: LONG_CONTEXT_BOUNDARY
|
|
3882
|
+
},
|
|
3876
3883
|
{
|
|
3877
3884
|
aliases: ["gpt-6-sol"],
|
|
3878
3885
|
short: { input: 2 / M, cachedInput: 0.2 / M, cacheWrite: 2.5 / M, output: 10 / M },
|
|
@@ -4252,12 +4259,12 @@ var BASE_EFFORTS = ["minimal", "low", "medium", "high"];
|
|
|
4252
4259
|
function bothEndpoints(value) {
|
|
4253
4260
|
return { chat: value, responses: value };
|
|
4254
4261
|
}
|
|
4255
|
-
function gpt6(id,
|
|
4262
|
+
function gpt6(id, responsesEfforts, chatTools, chatEfforts = responsesEfforts) {
|
|
4256
4263
|
return {
|
|
4257
4264
|
id,
|
|
4258
4265
|
family: "gpt-6",
|
|
4259
4266
|
reasoning: true,
|
|
4260
|
-
efforts:
|
|
4267
|
+
efforts: { chat: chatEfforts, responses: responsesEfforts },
|
|
4261
4268
|
defaultEffort: "medium",
|
|
4262
4269
|
// Same policy as GPT-5.x: a portable `temperature` is dropped while
|
|
4263
4270
|
// reasoning is active (including the active default). A raw
|
|
@@ -4285,6 +4292,13 @@ function gpt56(id) {
|
|
|
4285
4292
|
var OPENAI_EXACT_MODELS = new Map(
|
|
4286
4293
|
[
|
|
4287
4294
|
gpt6("gpt-6-astra", ["low", "medium", "high", "xhigh", "max"], "never"),
|
|
4295
|
+
// Live Chat Completions rejects max; Responses accepts it (2026-10-15).
|
|
4296
|
+
gpt6("gpt-6.1-sol", ["low", "medium", "high", "xhigh", "max"], "never", [
|
|
4297
|
+
"low",
|
|
4298
|
+
"medium",
|
|
4299
|
+
"high",
|
|
4300
|
+
"xhigh"
|
|
4301
|
+
]),
|
|
4288
4302
|
gpt6("gpt-6-sol", ["none", "low", "medium", "high", "xhigh", "max"], "effort-none-only"),
|
|
4289
4303
|
gpt6("gpt-6-luna", ["none", "low", "medium", "high", "xhigh", "max"], "effort-none-only"),
|
|
4290
4304
|
gpt56("gpt-5.6"),
|
|
@@ -4428,15 +4442,15 @@ function validateOpenAIFinalRequestBody(body, endpoint) {
|
|
|
4428
4442
|
}
|
|
4429
4443
|
}
|
|
4430
4444
|
if (activeReasoning) {
|
|
4445
|
+
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'.`;
|
|
4431
4446
|
const forbidden = endpoint === "chat" ? ["temperature", "top_p", "top_logprobs", "logprobs"] : ["temperature", "top_p", "top_logprobs"];
|
|
4432
4447
|
for (const key of forbidden) {
|
|
4433
|
-
if (body[key] !== void 0)
|
|
4434
|
-
fail(key, `Remove ${key} or set reasoning effort to 'none' on Sol or Luna.`);
|
|
4448
|
+
if (body[key] !== void 0) fail(key, remediation(key));
|
|
4435
4449
|
}
|
|
4436
4450
|
if (endpoint === "responses" && Array.isArray(body.include) && body.include.includes("message.output_text.logprobs")) {
|
|
4437
4451
|
fail(
|
|
4438
4452
|
"message.output_text.logprobs",
|
|
4439
|
-
"
|
|
4453
|
+
remediation("message.output_text.logprobs from include")
|
|
4440
4454
|
);
|
|
4441
4455
|
}
|
|
4442
4456
|
}
|
|
@@ -4489,8 +4503,8 @@ var OpenAIProvider = class extends OpenAICompatibleProvider {
|
|
|
4489
4503
|
constructor(options = {}) {
|
|
4490
4504
|
super({ profile: OPENAI_PROFILE, ...options });
|
|
4491
4505
|
}
|
|
4492
|
-
/** Report a clamped `effort` — Chat
|
|
4493
|
-
*
|
|
4506
|
+
/** Report a clamped `effort` — Chat caps `'max'` at `'xhigh'` on GPT-5.6 and
|
|
4507
|
+
* GPT-6.1 Sol, and maps `'none'` to the model's supported floor. */
|
|
4494
4508
|
effortResolution(options) {
|
|
4495
4509
|
return resolveOpenAIEffortResolution(
|
|
4496
4510
|
options,
|
|
@@ -5146,6 +5160,17 @@ var ANTHROPIC_THINKING_BINDING_BETA = "thinking-binding-controls-2026-08-01";
|
|
|
5146
5160
|
function isRecord(value) {
|
|
5147
5161
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5148
5162
|
}
|
|
5163
|
+
function isFinalThinkingAdaptive(capability, body) {
|
|
5164
|
+
const thinking = body.thinking;
|
|
5165
|
+
if (thinking === void 0) {
|
|
5166
|
+
return capability.thinking === "adaptive-default-on" || capability.thinking === "adaptive-always-on";
|
|
5167
|
+
}
|
|
5168
|
+
return isRecord(thinking) && thinking.type === "adaptive";
|
|
5169
|
+
}
|
|
5170
|
+
var NATIVE_CLAUDE_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
|
|
5171
|
+
function isNativeClaudeEffort(value) {
|
|
5172
|
+
return NATIVE_CLAUDE_EFFORTS.includes(value);
|
|
5173
|
+
}
|
|
5149
5174
|
function hasReplayedThinking(body) {
|
|
5150
5175
|
return Array.isArray(body.messages) && body.messages.some(
|
|
5151
5176
|
(message) => isRecord(message) && Array.isArray(message.content) && message.content.some(
|
|
@@ -5180,11 +5205,40 @@ function hasAnthropicProviderFileImage(messages) {
|
|
|
5180
5205
|
);
|
|
5181
5206
|
}
|
|
5182
5207
|
var CLAUDE_CAPABILITIES = {
|
|
5208
|
+
// Thinking off is `between_tools` (progress updates between tool calls);
|
|
5209
|
+
// `disabled` is a provider 400. Forced tool choice is a 400.
|
|
5210
|
+
"claude-sonnet-5-5": {
|
|
5211
|
+
thinking: "adaptive-default-on",
|
|
5212
|
+
effortLevels: ["low", "medium", "high", "xhigh", "max"],
|
|
5213
|
+
manualBudget: false,
|
|
5214
|
+
stripTemperature: true,
|
|
5215
|
+
disableAt: "high",
|
|
5216
|
+
offShape: "between_tools",
|
|
5217
|
+
forcedToolChoice: "rejected",
|
|
5218
|
+
defaultOnlySampling: true,
|
|
5219
|
+
strictThinking: true,
|
|
5220
|
+
thinkingBinding: true
|
|
5221
|
+
},
|
|
5222
|
+
// Thinking off is `disabled`, only at effort high or below. Forced tool
|
|
5223
|
+
// choice is accepted (the provider skips thinking for that turn).
|
|
5224
|
+
"claude-haiku-5-5": {
|
|
5225
|
+
thinking: "adaptive-default-on",
|
|
5226
|
+
effortLevels: ["low", "medium", "high", "xhigh", "max"],
|
|
5227
|
+
manualBudget: false,
|
|
5228
|
+
stripTemperature: true,
|
|
5229
|
+
disableAt: "high",
|
|
5230
|
+
defaultOnlySampling: true,
|
|
5231
|
+
strictThinking: true,
|
|
5232
|
+
thinkingBinding: true
|
|
5233
|
+
},
|
|
5183
5234
|
"claude-opus-5-5": {
|
|
5184
5235
|
thinking: "adaptive-always-on",
|
|
5185
5236
|
effortLevels: ["low", "medium", "high", "xhigh", "max"],
|
|
5186
5237
|
manualBudget: false,
|
|
5187
5238
|
stripTemperature: true,
|
|
5239
|
+
forcedToolChoice: "rejected",
|
|
5240
|
+
defaultOnlySampling: true,
|
|
5241
|
+
strictThinking: true,
|
|
5188
5242
|
thinkingBinding: true
|
|
5189
5243
|
},
|
|
5190
5244
|
"claude-fable-5-1": {
|
|
@@ -5192,6 +5246,9 @@ var CLAUDE_CAPABILITIES = {
|
|
|
5192
5246
|
effortLevels: ["low", "medium", "high", "xhigh", "max"],
|
|
5193
5247
|
manualBudget: false,
|
|
5194
5248
|
stripTemperature: true,
|
|
5249
|
+
forcedToolChoice: "rejected",
|
|
5250
|
+
defaultOnlySampling: true,
|
|
5251
|
+
strictThinking: true,
|
|
5195
5252
|
thinkingBinding: true
|
|
5196
5253
|
},
|
|
5197
5254
|
"claude-fable-5": {
|
|
@@ -5286,6 +5343,15 @@ function resolveClaudeCapability(model) {
|
|
|
5286
5343
|
}
|
|
5287
5344
|
var DEFAULT_CACHE_READ_MULTIPLIER = 0.1;
|
|
5288
5345
|
var ANTHROPIC_RATES = {
|
|
5346
|
+
// Sonnet 5.5 cache reads are 0.05x ($0.10/MTok): the pricing table, its
|
|
5347
|
+
// footnote, the models overview, and the prompt-caching guide agree
|
|
5348
|
+
// (re-checked 2026-10-07).
|
|
5349
|
+
"claude-sonnet-5-5": { input: 2e-6, output: 1e-5, cacheReadMultiplier: 0.05 },
|
|
5350
|
+
"claude-haiku-5-5": {
|
|
5351
|
+
input: 1e-7,
|
|
5352
|
+
output: 5e-7,
|
|
5353
|
+
longPrompt: { aboveTokens: 1e5, card: { input: 5e-7, output: 25e-7 } }
|
|
5354
|
+
},
|
|
5289
5355
|
"claude-opus-5-5": { input: 4e-6, output: 2e-5, cacheReadMultiplier: 0.05 },
|
|
5290
5356
|
"claude-fable-5-1": { input: 1e-5, output: 5e-5, cacheReadMultiplier: 0.025 },
|
|
5291
5357
|
"claude-fable-5": { input: 1e-5, output: 5e-5 },
|
|
@@ -5348,14 +5414,16 @@ function estimateAnthropicCost(model, usage) {
|
|
|
5348
5414
|
return void 0;
|
|
5349
5415
|
}
|
|
5350
5416
|
const cacheWriteTotal = safeTokenSum(cacheWrite5m, cacheWrite1h);
|
|
5351
|
-
|
|
5417
|
+
const promptTokens = cacheWriteTotal === void 0 ? void 0 : safeTokenSum(usage.inputTokens, cacheRead, cacheWriteTotal);
|
|
5418
|
+
if (cacheWriteTotal === void 0 || promptTokens === void 0) {
|
|
5352
5419
|
return void 0;
|
|
5353
5420
|
}
|
|
5354
5421
|
if (usage.aggregateCacheWriteTokens !== void 0 && (!isValidTokenCount(usage.aggregateCacheWriteTokens) || usage.aggregateCacheWriteTokens !== cacheWriteTotal)) {
|
|
5355
5422
|
return void 0;
|
|
5356
5423
|
}
|
|
5357
|
-
const
|
|
5358
|
-
const
|
|
5424
|
+
const card = rate.longPrompt && promptTokens > rate.longPrompt.aboveTokens ? rate.longPrompt.card : rate;
|
|
5425
|
+
const { input, output } = card;
|
|
5426
|
+
const cacheReadRate = input * (card.cacheReadMultiplier ?? DEFAULT_CACHE_READ_MULTIPLIER);
|
|
5359
5427
|
return usage.inputTokens * input + cacheRead * cacheReadRate + cacheWrite5m * input * 1.25 + cacheWrite1h * input * 2 + usage.outputTokens * output;
|
|
5360
5428
|
}
|
|
5361
5429
|
var THINKING_BUDGETS = {
|
|
@@ -5417,7 +5485,7 @@ function resolveClaudeThinking(model, resolved) {
|
|
|
5417
5485
|
};
|
|
5418
5486
|
}
|
|
5419
5487
|
return {
|
|
5420
|
-
thinking: { type: "disabled" },
|
|
5488
|
+
thinking: { type: capability.offShape ?? "disabled" },
|
|
5421
5489
|
outputConfig: activeEffort ? { effort: activeEffort } : void 0,
|
|
5422
5490
|
stripTemperature: true
|
|
5423
5491
|
};
|
|
@@ -5823,50 +5891,106 @@ var AnthropicProvider = class {
|
|
|
5823
5891
|
...betas.length > 0 ? { "anthropic-beta": betas.join(",") } : {}
|
|
5824
5892
|
};
|
|
5825
5893
|
}
|
|
5894
|
+
/**
|
|
5895
|
+
* Whether the final body needs the binding beta header. Runs after
|
|
5896
|
+
* `validateAndBindFinalBody`, which has already injected `block_binding`
|
|
5897
|
+
* wherever it applies, so the header follows the final body rather than
|
|
5898
|
+
* re-deriving the injection rule.
|
|
5899
|
+
*/
|
|
5826
5900
|
requiresBindingBeta(body) {
|
|
5901
|
+
const capability = resolveClaudeCapability(String(body.model));
|
|
5827
5902
|
const thinking = body.thinking;
|
|
5828
|
-
return
|
|
5903
|
+
return capability?.thinkingBinding === true && isRecord(thinking) && thinking.type === "adaptive" && thinking.block_binding !== void 0;
|
|
5829
5904
|
}
|
|
5905
|
+
/**
|
|
5906
|
+
* Validate the final body (after `providerOptions`) against the effective
|
|
5907
|
+
* model's capability, then inject `block_binding` where it applies. Every
|
|
5908
|
+
* rule is gated on its own capability field and is a no-op when unset, so a
|
|
5909
|
+
* model only gets the guards its provider contract calls for.
|
|
5910
|
+
*/
|
|
5830
5911
|
validateAndBindFinalBody(body) {
|
|
5831
5912
|
const model = typeof body.model === "string" ? body.model : "";
|
|
5832
|
-
|
|
5913
|
+
const capability = resolveClaudeCapability(model);
|
|
5914
|
+
if (!capability) return;
|
|
5833
5915
|
const reject = (option, remediation) => {
|
|
5834
5916
|
throw new UnsupportedModelOptionError({ provider: this.name, model, option, remediation });
|
|
5835
5917
|
};
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
|
|
5853
|
-
|
|
5854
|
-
|
|
5918
|
+
if (capability.forcedToolChoice === "rejected") {
|
|
5919
|
+
const toolChoice = body.tool_choice;
|
|
5920
|
+
if (isRecord(toolChoice) && (toolChoice.type === "any" || toolChoice.type === "tool")) {
|
|
5921
|
+
reject("forced tool choice", "Use toolChoice: 'auto' or 'none' on this model.");
|
|
5922
|
+
}
|
|
5923
|
+
}
|
|
5924
|
+
if (capability.strictThinking) {
|
|
5925
|
+
const offShape = capability.thinking === "adaptive-always-on" ? void 0 : capability.offShape ?? "disabled";
|
|
5926
|
+
const thinking = body.thinking;
|
|
5927
|
+
const outputConfig = body.output_config;
|
|
5928
|
+
const effort = isRecord(outputConfig) ? outputConfig.effort : void 0;
|
|
5929
|
+
if (thinking !== void 0 && offShape === void 0) {
|
|
5930
|
+
if (!isRecord(thinking) || thinking.type !== "adaptive" || thinking.budget_tokens !== void 0) {
|
|
5931
|
+
reject(
|
|
5932
|
+
"manual or disabled thinking",
|
|
5933
|
+
"Use thinking: { type: 'adaptive' } and output_config.effort."
|
|
5934
|
+
);
|
|
5935
|
+
}
|
|
5936
|
+
} else if (thinking !== void 0) {
|
|
5937
|
+
if (!isRecord(thinking) || thinking.type !== "adaptive" && thinking.type !== offShape) {
|
|
5938
|
+
reject(
|
|
5939
|
+
"thinking.type",
|
|
5940
|
+
`Use thinking: { type: 'adaptive' }, or { type: '${offShape}' } to turn thinking off.`
|
|
5941
|
+
);
|
|
5942
|
+
}
|
|
5943
|
+
const record = thinking;
|
|
5944
|
+
if (record.type === "adaptive" && record.budget_tokens !== void 0) {
|
|
5945
|
+
reject("thinking.budget_tokens", "Use output_config.effort instead of budget_tokens.");
|
|
5946
|
+
}
|
|
5947
|
+
if (record.type === offShape) {
|
|
5948
|
+
const extra = Object.keys(record).filter((key) => key !== "type");
|
|
5949
|
+
if (extra.length > 0) {
|
|
5950
|
+
reject(
|
|
5951
|
+
`thinking.${offShape}.${extra[0]}`,
|
|
5952
|
+
`Send thinking: { type: '${offShape}' } with no other fields.`
|
|
5953
|
+
);
|
|
5954
|
+
}
|
|
5955
|
+
}
|
|
5956
|
+
}
|
|
5957
|
+
if (outputConfig !== void 0 && (!isRecord(outputConfig) || effort !== void 0 && !isNativeClaudeEffort(effort))) {
|
|
5958
|
+
reject("output_config.effort", "Use low, medium, high, xhigh, or max effort.");
|
|
5959
|
+
}
|
|
5960
|
+
if (offShape !== void 0 && isRecord(thinking) && thinking.type === offShape && effort !== void 0 && capability.disableAt && !isEffortAtOrBelow(effort, capability.disableAt)) {
|
|
5961
|
+
reject(
|
|
5962
|
+
"output_config.effort",
|
|
5963
|
+
`Thinking can be turned off only at effort '${capability.disableAt}' or below; lower the effort or use adaptive thinking.`
|
|
5964
|
+
);
|
|
5965
|
+
}
|
|
5855
5966
|
}
|
|
5856
|
-
if (
|
|
5857
|
-
|
|
5967
|
+
if (capability.defaultOnlySampling) {
|
|
5968
|
+
if (body.temperature !== void 0 && body.temperature !== 1) {
|
|
5969
|
+
reject("temperature", "Omit temperature or use the default value 1.");
|
|
5970
|
+
}
|
|
5971
|
+
if (body.top_p !== void 0 && body.top_p !== 0.99) {
|
|
5972
|
+
reject("top_p", "Omit top_p or use the default value 0.99.");
|
|
5973
|
+
}
|
|
5974
|
+
if (body.temperature !== void 0 && body.top_p !== void 0) {
|
|
5975
|
+
reject("temperature and top_p", "Send at most one of temperature and top_p.");
|
|
5976
|
+
}
|
|
5977
|
+
if (body.top_k !== void 0) {
|
|
5978
|
+
reject("top_k", "Omit top_k on this model.");
|
|
5979
|
+
}
|
|
5858
5980
|
}
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5981
|
+
if (capability.thinkingBinding === true && isFinalThinkingAdaptive(capability, body)) {
|
|
5982
|
+
const thinking = isRecord(body.thinking) ? body.thinking : { type: "adaptive" };
|
|
5983
|
+
const binding = thinking.block_binding;
|
|
5984
|
+
if (binding !== void 0 && (!isRecord(binding) || binding.prefix_mismatch_behavior !== "error" && binding.prefix_mismatch_behavior !== "drop_block")) {
|
|
5985
|
+
reject("thinking.block_binding", "Use prefix_mismatch_behavior: 'error' or 'drop_block'.");
|
|
5986
|
+
}
|
|
5987
|
+
if (hasReplayedThinking(body)) {
|
|
5988
|
+
body.thinking = {
|
|
5989
|
+
...thinking,
|
|
5990
|
+
block_binding: binding ?? { prefix_mismatch_behavior: "drop_block" }
|
|
5991
|
+
};
|
|
5992
|
+
}
|
|
5865
5993
|
}
|
|
5866
|
-
body.thinking = {
|
|
5867
|
-
...thinking,
|
|
5868
|
-
block_binding: binding ?? { prefix_mismatch_behavior: "drop_block" }
|
|
5869
|
-
};
|
|
5870
5994
|
}
|
|
5871
5995
|
/** Extract a human-readable message from an API error response body. */
|
|
5872
5996
|
extractErrorMessage(body, status) {
|