feat(ai): add max thinking level

This commit is contained in:
Mario Zechner
2026-07-09 22:30:53 +02:00
parent 8973ae28ab
commit fbdd46389c
61 changed files with 441 additions and 168 deletions
+4
View File
@@ -2,6 +2,10 @@
## [Unreleased]
### Added
- Added a separate opt-in `max` thinking level, including native `xhigh` and `max` support for GPT-5.6 and Anthropic adaptive-thinking effort metadata matching Anthropic's documentation: `max` on all adaptive Claude models, native `xhigh` on Opus 4.7/4.8, Sonnet 5, and Fable 5 only.
### Fixed
- Fixed post-compaction output-token budgeting to ignore stale assistant usage from before the compaction boundary ([#6464](https://github.com/earendil-works/pi/issues/6464)).
+4 -2
View File
@@ -730,7 +730,7 @@ if (model.reasoning) {
const response = await models.completeSimple(model, {
messages: [{ role: 'user', content: 'Solve: 2x + 5 = 13', timestamp: Date.now() }]
}, {
reasoning: 'medium' // 'minimal' | 'low' | 'medium' | 'high' | 'xhigh'
reasoning: 'medium' // 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'
});
// Access thinking and text blocks
@@ -743,6 +743,8 @@ for (const block of response.content) {
}
```
`xhigh` and `max` are model-specific, opt-in levels. Use `getSupportedThinkingLevels(model)` to determine whether a concrete model exposes either level; models such as GPT-5.6 can expose both.
### Provider-Specific Options (stream/complete)
`models.stream()`/`complete()` accept the owning API's full option set. Use `hasApi()` to narrow a dynamically looked-up model to its API for full option typing:
@@ -999,7 +1001,7 @@ Custom models can carry `headers` (e.g. proxies behind bot detection) and `compa
Some OpenAI-compatible servers do not understand the `developer` role used for reasoning-capable models. For those providers, set `compat.supportsDeveloperRole` to `false` so the system prompt is sent as a `system` message instead. If the server also does not support `reasoning_effort`, set `compat.supportsReasoningEffort` to `false` too. This commonly applies to Ollama, vLLM, SGLang, and similar OpenAI-compatible servers.
Use model-level `thinkingLevelMap` to describe model-specific thinking controls. Keys are pi thinking levels (`off`, `minimal`, `low`, `medium`, `high`, `xhigh`). Missing keys use provider defaults, string values are sent to the provider, and `null` marks a level unsupported.
Use model-level `thinkingLevelMap` to describe model-specific thinking controls. Keys are pi thinking levels (`off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`). Missing standard levels through `high` use provider defaults; `xhigh` and `max` are opt-in and require a non-null map entry. String values are sent to the provider, `null` marks a level unsupported, and maps may skip levels.
```typescript
const ollamaReasoningModel: Model<'openai-completions'> = {
+34 -11
View File
@@ -160,7 +160,7 @@ const ZAI_GLM52_THINKING_LEVEL_MAP = {
low: "high",
medium: "high",
high: "high",
xhigh: "max",
max: "max",
} as const;
const OPENCODE_GO_GLM52_THINKING_LEVEL_MAP = {
off: null,
@@ -168,7 +168,7 @@ const OPENCODE_GO_GLM52_THINKING_LEVEL_MAP = {
low: null,
medium: null,
high: "high",
xhigh: "max",
max: "max",
} as const;
const EAGER_TOOL_INPUT_STREAMING_UNSUPPORTED_ANTHROPIC_MODELS = new Set([
"github-copilot:claude-haiku-4.5",
@@ -181,7 +181,7 @@ const DEEPSEEK_V4_THINKING_LEVEL_MAP = {
low: null,
medium: null,
high: "high",
xhigh: "max",
max: "max",
} as const;
const ANT_LING_RING_THINKING_LEVEL_MAP = {
@@ -235,7 +235,7 @@ const GITHUB_COPILOT_EXTENDED_CONTEXT_MODELS = new Set([
const GITHUB_COPILOT_THINKING_LEVEL_OVERRIDES = {
"claude-opus-4.7": { minimal: "low" },
"claude-opus-4.8": { minimal: "low" },
"claude-sonnet-4.6": { minimal: "low", xhigh: "max" },
"claude-sonnet-4.6": { minimal: "low", max: "max" },
} satisfies Record<string, NonNullable<Model<Api>["thinkingLevelMap"]>>;
function mergeThinkingLevelMap(model: Model<any>, map: NonNullable<Model<any>["thinkingLevelMap"]>): void {
@@ -271,6 +271,16 @@ function supportsOpenAiXhigh(modelId: string): boolean {
);
}
function supportsOpenAiMax(model: Model<Api>): boolean {
return (
model.id.includes("gpt-5.6") &&
(model.api === "openai-responses" ||
model.api === "azure-openai-responses" ||
model.api === "openai-codex-responses" ||
model.api === "openai-completions")
);
}
function isGoogleThinkingApi(model: Model<any>): boolean {
return model.api === "google-generative-ai" || model.api === "google-vertex";
}
@@ -472,28 +482,41 @@ function applyThinkingLevelMetadata(model: Model<any>): void {
if (supportsOpenAiXhigh(model.id)) {
mergeThinkingLevelMap(model, { xhigh: "xhigh" });
}
if (supportsOpenAiMax(model)) {
mergeThinkingLevelMap(model, { max: "max" });
}
if (model.provider === "openai" && model.id === "gpt-5.5") {
mergeThinkingLevelMap(model, { minimal: null });
}
if (model.id.endsWith("gpt-5.5-pro")) {
mergeThinkingLevelMap(model, { off: null, minimal: null, low: null });
}
if (model.id.includes("opus-4-6") || model.id.includes("opus-4.6")) {
mergeThinkingLevelMap(model, { xhigh: "max" });
// Anthropic adaptive-thinking effort support (per Anthropic adaptive thinking docs):
// - "max" is available on all adaptive-thinking Claude models.
// - "xhigh" is only available on Opus 4.7/4.8, Sonnet 5, and Fable 5.
if (
model.id.includes("opus-4-6") ||
model.id.includes("opus-4.6") ||
model.id.includes("sonnet-4-6") ||
model.id.includes("sonnet-4.6")
) {
mergeThinkingLevelMap(model, { max: "max" });
}
if (
model.id.includes("opus-4-7") ||
model.id.includes("opus-4.7") ||
model.id.includes("opus-4-8") ||
model.id.includes("opus-4.8")
model.id.includes("opus-4.8") ||
model.id.includes("sonnet-5") ||
model.id.includes("sonnet.5")
) {
mergeThinkingLevelMap(model, { xhigh: "xhigh" });
mergeThinkingLevelMap(model, { xhigh: "xhigh", max: "max" });
}
if (
(model.api === "anthropic-messages" || model.api === "bedrock-converse-stream") &&
model.id.includes("fable-5")
) {
mergeThinkingLevelMap(model, { off: null, xhigh: "xhigh" });
mergeThinkingLevelMap(model, { off: null, xhigh: "xhigh", max: "max" });
}
if (model.api === "anthropic-messages" && isAnthropicAdaptiveThinkingModel(model.id)) {
mergeAnthropicMessagesCompat(model, { forceAdaptiveThinking: true });
@@ -505,7 +528,7 @@ function applyThinkingLevelMetadata(model: Model<any>): void {
mergeThinkingLevelMap(
model,
model.provider === "openrouter"
? { ...DEEPSEEK_V4_THINKING_LEVEL_MAP, xhigh: "xhigh" }
? { ...DEEPSEEK_V4_THINKING_LEVEL_MAP, xhigh: "xhigh", max: null }
: DEEPSEEK_V4_THINKING_LEVEL_MAP,
);
}
@@ -544,7 +567,7 @@ function applyThinkingLevelMetadata(model: Model<any>): void {
mergeThinkingLevelMap(model, { xhigh: "xhigh" });
}
if (model.provider === "fireworks" && model.id.includes("glm-5p2")) {
mergeThinkingLevelMap(model, { off: "none", minimal: null, low: "high", medium: "high", xhigh: "max" });
mergeThinkingLevelMap(model, { off: "none", minimal: null, low: "high", medium: "high", max: "max" });
}
if (model.provider === "opencode-go" && model.id === "glm-5.2") {
mergeThinkingLevelMap(model, OPENCODE_GO_GLM52_THINKING_LEVEL_MAP);
+2 -1
View File
@@ -742,7 +742,8 @@ export const stream: StreamFunction<"anthropic-messages", AnthropicOptions> = (
/**
* Map ThinkingLevel to Anthropic effort levels for adaptive thinking.
* Note: effort "max" is only valid on Opus 4.6, while Opus 4.7+ and Fable 5 support "xhigh".
* Note: effort "max" is available on all adaptive-thinking Claude models, while native
* "xhigh" is only available on Opus 4.7/4.8, Sonnet 5, and Fable 5.
*/
function mapThinkingLevelToEffort(
model: Model<"anthropic-messages">,
@@ -52,7 +52,7 @@ function formatAzureOpenAIError(error: unknown): string {
// Azure OpenAI Responses-specific options
export interface AzureOpenAIResponsesOptions extends StreamOptions {
reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh";
reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
reasoningSummary?: "auto" | "detailed" | "concise" | null;
azureApiVersion?: string;
azureResourceName?: string;
@@ -582,7 +582,9 @@ function supportsAdaptiveThinking(modelId: string, modelName?: string): boolean
function supportsNativeXhighEffort(model: Model<"bedrock-converse-stream">): boolean {
const candidates = getModelMatchCandidates(model.id, model.name);
return candidates.some((s) => s.includes("opus-4-7") || s.includes("opus-4-8") || s.includes("fable-5"));
return candidates.some(
(s) => s.includes("opus-4-7") || s.includes("opus-4-8") || s.includes("sonnet-5") || s.includes("fable-5"),
);
}
function mapThinkingLevelToEffort(
@@ -1025,11 +1027,12 @@ function buildAdditionalModelRequestFields(
low: 2048,
medium: 8192,
high: 16384,
xhigh: 16384, // Claude doesn't support xhigh, clamp to high
xhigh: 16384, // Budget-based Claude clamps extended levels to high
max: 16384,
};
// Custom budgets override defaults (xhigh not in ThinkingBudgets, use high)
const level = options.reasoning === "xhigh" ? "high" : options.reasoning;
// Custom budgets only cover token-based levels through high.
const level = options.reasoning === "xhigh" || options.reasoning === "max" ? "high" : options.reasoning;
const budget = options.thinkingBudgets?.[level] ?? defaultBudgets[options.reasoning];
return {
+1 -1
View File
@@ -400,7 +400,7 @@ function buildParams(
return params;
}
type ClampedThinkingLevel = Exclude<ThinkingLevel, "xhigh">;
type ClampedThinkingLevel = Exclude<ThinkingLevel, "xhigh" | "max">;
function isGemma4Model(model: Model<"google-generative-ai">): boolean {
return /gemma-?4/.test(model.id.toLowerCase());
+1 -1
View File
@@ -498,7 +498,7 @@ function buildParams(
return params;
}
type ClampedThinkingLevel = Exclude<PiThinkingLevel, "xhigh">;
type ClampedThinkingLevel = Exclude<PiThinkingLevel, "xhigh" | "max">;
function isGemini3ProModel(model: Model<"google-generative-ai">): boolean {
return /gemini-3(?:\.\d+)?-pro/.test(model.id.toLowerCase());
@@ -80,7 +80,7 @@ const CODEX_RESPONSE_STATUSES = new Set<CodexResponseStatus>([
// ============================================================================
export interface OpenAICodexResponsesOptions extends StreamOptions {
reasoningEffort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh";
reasoningEffort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
reasoningSummary?: "auto" | "concise" | "detailed" | "off" | "on" | null;
serviceTier?: ResponseCreateParamsStreaming["service_tier"];
textVerbosity?: "low" | "medium" | "high";
+1 -1
View File
@@ -109,7 +109,7 @@ function isEncryptedReasoningDetail(detail: unknown): detail is OpenAIEncryptedR
export interface OpenAICompletionsOptions extends StreamOptions {
toolChoice?: "auto" | "none" | "required" | { type: "function"; function: { name: string } };
reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh";
reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
}
interface OpenAICompatCacheControl {
+1 -1
View File
@@ -78,7 +78,7 @@ function formatOpenAIResponsesError(error: unknown): string {
// OpenAI Responses-specific options
export interface OpenAIResponsesOptions extends StreamOptions {
reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh";
reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
reasoningSummary?: "auto" | "detailed" | "concise" | null;
serviceTier?: ResponseCreateParamsStreaming["service_tier"];
}
+2 -2
View File
@@ -44,8 +44,8 @@ export function buildBaseOptions(
};
}
export function clampReasoning(effort: ThinkingLevel | undefined): Exclude<ThinkingLevel, "xhigh"> | undefined {
return effort === "xhigh" ? "high" : effort;
export function clampReasoning(effort: ThinkingLevel | undefined): Exclude<ThinkingLevel, "xhigh" | "max"> | undefined {
return effort === "xhigh" || effort === "max" ? "high" : effort;
}
export function adjustMaxTokensForThinking(
+2 -2
View File
@@ -394,7 +394,7 @@ export function calculateCost<TApi extends Api>(model: Model<TApi>, usage: Usage
return usage.cost;
}
const EXTENDED_THINKING_LEVELS: ModelThinkingLevel[] = ["off", "minimal", "low", "medium", "high", "xhigh"];
const EXTENDED_THINKING_LEVELS: ModelThinkingLevel[] = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
export function getSupportedThinkingLevels<TApi extends Api>(model: Model<TApi>): ModelThinkingLevel[] {
if (!model.reasoning) return ["off"];
@@ -402,7 +402,7 @@ export function getSupportedThinkingLevels<TApi extends Api>(model: Model<TApi>)
return EXTENDED_THINKING_LEVELS.filter((level) => {
const mapped = model.thinkingLevelMap?.[level];
if (mapped === null) return false;
if (level === "xhigh") return mapped !== undefined;
if (level === "xhigh" || level === "max") return mapped !== undefined;
return true;
});
}
@@ -79,7 +79,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
thinkingLevelMap: {"off":null,"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 10,
@@ -148,7 +148,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"max"},
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -166,7 +166,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -184,7 +184,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -219,6 +219,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 3,
@@ -236,6 +237,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2,
@@ -270,7 +272,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"max"},
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 16.5,
@@ -288,7 +290,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -323,6 +325,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 3.3,
@@ -340,6 +343,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2,
@@ -408,7 +412,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.eu-central-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
thinkingLevelMap: {"off":null,"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 11,
@@ -460,7 +464,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.eu-central-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"max"},
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 5.5,
@@ -478,7 +482,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.eu-central-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5.5,
@@ -496,7 +500,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.eu-central-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5.5,
@@ -531,6 +535,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.eu-central-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 3.3,
@@ -548,6 +553,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.eu-central-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2.2,
@@ -565,7 +571,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
thinkingLevelMap: {"off":null,"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 10,
@@ -617,7 +623,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"max"},
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -635,7 +641,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -653,7 +659,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -688,6 +694,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 3,
@@ -705,6 +712,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2,
@@ -773,7 +781,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -791,7 +799,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -826,6 +834,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 3,
@@ -843,6 +852,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2,
@@ -1508,7 +1518,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
thinkingLevelMap: {"off":null,"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 10,
@@ -1577,7 +1587,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"max"},
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -1595,7 +1605,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -1613,7 +1623,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -1648,6 +1658,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 3,
@@ -1665,6 +1676,7 @@ export const AMAZON_BEDROCK_MODELS = {
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2,
@@ -12,7 +12,7 @@ export const ANTHROPIC_MODELS = {
baseUrl: "https://api.anthropic.com",
compat: {"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
thinkingLevelMap: {"off":null,"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 10,
@@ -133,7 +133,7 @@ export const ANTHROPIC_MODELS = {
baseUrl: "https://api.anthropic.com",
compat: {"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"xhigh":"max"},
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -152,7 +152,7 @@ export const ANTHROPIC_MODELS = {
baseUrl: "https://api.anthropic.com",
compat: {"forceAdaptiveThinking":true,"supportsTemperature":false},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -171,7 +171,7 @@ export const ANTHROPIC_MODELS = {
baseUrl: "https://api.anthropic.com",
compat: {"forceAdaptiveThinking":true,"supportsTemperature":false},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -224,6 +224,7 @@ export const ANTHROPIC_MODELS = {
baseUrl: "https://api.anthropic.com",
compat: {"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 3,
@@ -242,6 +243,7 @@ export const ANTHROPIC_MODELS = {
baseUrl: "https://api.anthropic.com",
compat: {"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2,
@@ -613,7 +613,7 @@ export const AZURE_OPENAI_RESPONSES_MODELS = {
provider: "azure-openai-responses",
baseUrl: "",
reasoning: true,
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
thinkingLevelMap: {"off":null,"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -631,7 +631,7 @@ export const AZURE_OPENAI_RESPONSES_MODELS = {
provider: "azure-openai-responses",
baseUrl: "",
reasoning: true,
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
thinkingLevelMap: {"off":null,"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 1,
@@ -649,7 +649,7 @@ export const AZURE_OPENAI_RESPONSES_MODELS = {
provider: "azure-openai-responses",
baseUrl: "",
reasoning: true,
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
thinkingLevelMap: {"off":null,"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -667,7 +667,7 @@ export const AZURE_OPENAI_RESPONSES_MODELS = {
provider: "azure-openai-responses",
baseUrl: "",
reasoning: true,
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
thinkingLevelMap: {"off":null,"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2.5,
@@ -120,7 +120,7 @@ export const CLOUDFLARE_AI_GATEWAY_MODELS = {
baseUrl: "https://gateway.ai.cloudflare.com/v1/{CLOUDFLARE_ACCOUNT_ID}/{CLOUDFLARE_GATEWAY_ID}/anthropic",
compat: {"sendSessionAffinityHeaders":true,"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
thinkingLevelMap: {"off":null,"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 10,
@@ -211,7 +211,7 @@ export const CLOUDFLARE_AI_GATEWAY_MODELS = {
baseUrl: "https://gateway.ai.cloudflare.com/v1/{CLOUDFLARE_ACCOUNT_ID}/{CLOUDFLARE_GATEWAY_ID}/anthropic",
compat: {"sendSessionAffinityHeaders":true,"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"xhigh":"max"},
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -230,7 +230,7 @@ export const CLOUDFLARE_AI_GATEWAY_MODELS = {
baseUrl: "https://gateway.ai.cloudflare.com/v1/{CLOUDFLARE_ACCOUNT_ID}/{CLOUDFLARE_GATEWAY_ID}/anthropic",
compat: {"sendSessionAffinityHeaders":true,"forceAdaptiveThinking":true,"supportsTemperature":false},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -249,7 +249,7 @@ export const CLOUDFLARE_AI_GATEWAY_MODELS = {
baseUrl: "https://gateway.ai.cloudflare.com/v1/{CLOUDFLARE_ACCOUNT_ID}/{CLOUDFLARE_GATEWAY_ID}/anthropic",
compat: {"sendSessionAffinityHeaders":true,"forceAdaptiveThinking":true,"supportsTemperature":false},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -304,6 +304,7 @@ export const CLOUDFLARE_AI_GATEWAY_MODELS = {
baseUrl: "https://gateway.ai.cloudflare.com/v1/{CLOUDFLARE_ACCOUNT_ID}/{CLOUDFLARE_GATEWAY_ID}/anthropic",
compat: {"sendSessionAffinityHeaders":true,"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 3,
@@ -322,6 +323,7 @@ export const CLOUDFLARE_AI_GATEWAY_MODELS = {
baseUrl: "https://gateway.ai.cloudflare.com/v1/{CLOUDFLARE_ACCOUNT_ID}/{CLOUDFLARE_GATEWAY_ID}/anthropic",
compat: {"sendSessionAffinityHeaders":true,"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2,
+2 -2
View File
@@ -12,7 +12,7 @@ export const DEEPSEEK_MODELS = {
baseUrl: "https://api.deepseek.com",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"deepseek"},
reasoning: true,
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","xhigh":"max"},
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","max":"max"},
input: ["text"],
cost: {
input: 0.14,
@@ -31,7 +31,7 @@ export const DEEPSEEK_MODELS = {
baseUrl: "https://api.deepseek.com",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"deepseek"},
reasoning: true,
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","xhigh":"max"},
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","max":"max"},
input: ["text"],
cost: {
input: 0.435,
@@ -66,7 +66,7 @@ export const FIREWORKS_MODELS = {
baseUrl: "https://api.fireworks.ai/inference/v1",
compat: {"supportsStore":false,"supportsDeveloperRole":false},
reasoning: true,
thinkingLevelMap: {"off":"none","minimal":null,"low":"high","medium":"high","xhigh":"max"},
thinkingLevelMap: {"off":"none","minimal":null,"low":"high","medium":"high","max":"max"},
input: ["text"],
cost: {
input: 1.4,
@@ -229,7 +229,7 @@ export const FIREWORKS_MODELS = {
baseUrl: "https://api.fireworks.ai/inference/v1",
compat: {"supportsStore":false,"supportsDeveloperRole":false},
reasoning: true,
thinkingLevelMap: {"off":"none","minimal":null,"low":"high","medium":"high","xhigh":"max"},
thinkingLevelMap: {"off":"none","minimal":null,"low":"high","medium":"high","max":"max"},
input: ["text"],
cost: {
input: 2.1,
@@ -69,7 +69,7 @@ export const GITHUB_COPILOT_MODELS = {
headers: {"User-Agent":"GitHubCopilotChat/0.35.0","Editor-Version":"vscode/1.107.0","Editor-Plugin-Version":"copilot-chat/0.35.0","Copilot-Integration-Id":"vscode-chat"},
compat: {"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"xhigh":"max"},
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -89,7 +89,7 @@ export const GITHUB_COPILOT_MODELS = {
headers: {"User-Agent":"GitHubCopilotChat/0.35.0","Editor-Version":"vscode/1.107.0","Editor-Plugin-Version":"copilot-chat/0.35.0","Copilot-Integration-Id":"vscode-chat"},
compat: {"forceAdaptiveThinking":true,"supportsTemperature":false},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","minimal":"low"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max","minimal":"low"},
input: ["text", "image"],
cost: {
input: 5,
@@ -109,7 +109,7 @@ export const GITHUB_COPILOT_MODELS = {
headers: {"User-Agent":"GitHubCopilotChat/0.35.0","Editor-Version":"vscode/1.107.0","Editor-Plugin-Version":"copilot-chat/0.35.0","Copilot-Integration-Id":"vscode-chat"},
compat: {"forceAdaptiveThinking":true,"supportsTemperature":false},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","minimal":"low"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max","minimal":"low"},
input: ["text", "image"],
cost: {
input: 5,
@@ -167,7 +167,7 @@ export const GITHUB_COPILOT_MODELS = {
headers: {"User-Agent":"GitHubCopilotChat/0.35.0","Editor-Version":"vscode/1.107.0","Editor-Plugin-Version":"copilot-chat/0.35.0","Copilot-Integration-Id":"vscode-chat"},
compat: {"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"minimal":"low","xhigh":"max"},
thinkingLevelMap: {"max":"max","minimal":"low"},
input: ["text", "image"],
cost: {
input: 3,
@@ -187,6 +187,7 @@ export const GITHUB_COPILOT_MODELS = {
headers: {"User-Agent":"GitHubCopilotChat/0.35.0","Editor-Version":"vscode/1.107.0","Editor-Plugin-Version":"copilot-chat/0.35.0","Copilot-Integration-Id":"vscode-chat"},
compat: {"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2,
@@ -83,7 +83,7 @@ export const OPENAI_CODEX_MODELS = {
provider: "openai-codex",
baseUrl: "https://chatgpt.com/backend-api",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","minimal":"low"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max","minimal":"low"},
input: ["text", "image"],
cost: {
input: 1,
@@ -101,7 +101,7 @@ export const OPENAI_CODEX_MODELS = {
provider: "openai-codex",
baseUrl: "https://chatgpt.com/backend-api",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","minimal":"low"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max","minimal":"low"},
input: ["text", "image"],
cost: {
input: 5,
@@ -119,7 +119,7 @@ export const OPENAI_CODEX_MODELS = {
provider: "openai-codex",
baseUrl: "https://chatgpt.com/backend-api",
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","minimal":"low"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max","minimal":"low"},
input: ["text", "image"],
cost: {
input: 2.5,
+4 -4
View File
@@ -613,7 +613,7 @@ export const OPENAI_MODELS = {
provider: "openai",
baseUrl: "https://api.openai.com/v1",
reasoning: true,
thinkingLevelMap: {"off":"none","xhigh":"xhigh"},
thinkingLevelMap: {"off":"none","xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -631,7 +631,7 @@ export const OPENAI_MODELS = {
provider: "openai",
baseUrl: "https://api.openai.com/v1",
reasoning: true,
thinkingLevelMap: {"off":"none","xhigh":"xhigh"},
thinkingLevelMap: {"off":"none","xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 1,
@@ -649,7 +649,7 @@ export const OPENAI_MODELS = {
provider: "openai",
baseUrl: "https://api.openai.com/v1",
reasoning: true,
thinkingLevelMap: {"off":"none","xhigh":"xhigh"},
thinkingLevelMap: {"off":"none","xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -667,7 +667,7 @@ export const OPENAI_MODELS = {
provider: "openai",
baseUrl: "https://api.openai.com/v1",
reasoning: true,
thinkingLevelMap: {"off":"none","xhigh":"xhigh"},
thinkingLevelMap: {"off":"none","xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2.5,
@@ -12,7 +12,7 @@ export const OPENCODE_GO_MODELS = {
baseUrl: "https://opencode.ai/zen/go/v1",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"maxTokensField":"max_tokens","requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"deepseek"},
reasoning: true,
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","xhigh":"max"},
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","max":"max"},
input: ["text"],
cost: {
input: 0.14,
@@ -31,7 +31,7 @@ export const OPENCODE_GO_MODELS = {
baseUrl: "https://opencode.ai/zen/go/v1",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"maxTokensField":"max_tokens","requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"deepseek"},
reasoning: true,
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","xhigh":"max"},
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","max":"max"},
input: ["text"],
cost: {
input: 1.74,
@@ -68,7 +68,7 @@ export const OPENCODE_GO_MODELS = {
baseUrl: "https://opencode.ai/zen/go/v1",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"maxTokensField":"max_tokens"},
reasoning: true,
thinkingLevelMap: {"off":null,"minimal":null,"low":null,"medium":null,"high":"high","xhigh":"max"},
thinkingLevelMap: {"off":null,"minimal":null,"low":null,"medium":null,"high":"high","max":"max"},
input: ["text"],
cost: {
input: 1.4,
+9 -7
View File
@@ -30,7 +30,7 @@ export const OPENCODE_MODELS = {
baseUrl: "https://opencode.ai/zen",
compat: {"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
thinkingLevelMap: {"off":null,"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 10,
@@ -100,7 +100,7 @@ export const OPENCODE_MODELS = {
baseUrl: "https://opencode.ai/zen",
compat: {"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"xhigh":"max"},
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -119,7 +119,7 @@ export const OPENCODE_MODELS = {
baseUrl: "https://opencode.ai/zen",
compat: {"forceAdaptiveThinking":true,"supportsTemperature":false},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -138,7 +138,7 @@ export const OPENCODE_MODELS = {
baseUrl: "https://opencode.ai/zen",
compat: {"forceAdaptiveThinking":true,"supportsTemperature":false},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -191,6 +191,7 @@ export const OPENCODE_MODELS = {
baseUrl: "https://opencode.ai/zen",
compat: {"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 3,
@@ -209,6 +210,7 @@ export const OPENCODE_MODELS = {
baseUrl: "https://opencode.ai/zen",
compat: {"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2,
@@ -227,7 +229,7 @@ export const OPENCODE_MODELS = {
baseUrl: "https://opencode.ai/zen/v1",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"maxTokensField":"max_tokens","supportsLongCacheRetention":false,"requiresReasoningContentOnAssistantMessages":true},
reasoning: true,
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","xhigh":"max"},
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","max":"max"},
input: ["text"],
cost: {
input: 0.14,
@@ -246,7 +248,7 @@ export const OPENCODE_MODELS = {
baseUrl: "https://opencode.ai/zen/v1",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"maxTokensField":"max_tokens","requiresReasoningContentOnAssistantMessages":true},
reasoning: true,
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","xhigh":"max"},
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","max":"max"},
input: ["text"],
cost: {
input: 0,
@@ -265,7 +267,7 @@ export const OPENCODE_MODELS = {
baseUrl: "https://opencode.ai/zen/v1",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"maxTokensField":"max_tokens","supportsLongCacheRetention":false,"requiresReasoningContentOnAssistantMessages":true},
reasoning: true,
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","xhigh":"max"},
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","max":"max"},
input: ["text"],
cost: {
input: 1.74,
+16 -14
View File
@@ -282,7 +282,7 @@ export const OPENROUTER_MODELS = {
baseUrl: "https://openrouter.ai/api/v1",
compat: {"thinkingFormat":"openrouter","cacheControlFormat":"anthropic"},
reasoning: true,
thinkingLevelMap: {"xhigh":"max"},
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -301,7 +301,7 @@ export const OPENROUTER_MODELS = {
baseUrl: "https://openrouter.ai/api/v1",
compat: {"thinkingFormat":"openrouter","cacheControlFormat":"anthropic"},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -320,7 +320,7 @@ export const OPENROUTER_MODELS = {
baseUrl: "https://openrouter.ai/api/v1",
compat: {"thinkingFormat":"openrouter","cacheControlFormat":"anthropic"},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 30,
@@ -339,7 +339,7 @@ export const OPENROUTER_MODELS = {
baseUrl: "https://openrouter.ai/api/v1",
compat: {"thinkingFormat":"openrouter","cacheControlFormat":"anthropic"},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -358,7 +358,7 @@ export const OPENROUTER_MODELS = {
baseUrl: "https://openrouter.ai/api/v1",
compat: {"thinkingFormat":"openrouter","cacheControlFormat":"anthropic"},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 10,
@@ -413,6 +413,7 @@ export const OPENROUTER_MODELS = {
baseUrl: "https://openrouter.ai/api/v1",
compat: {"thinkingFormat":"openrouter","cacheControlFormat":"anthropic"},
reasoning: true,
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 3,
@@ -431,6 +432,7 @@ export const OPENROUTER_MODELS = {
baseUrl: "https://openrouter.ai/api/v1",
compat: {"thinkingFormat":"openrouter","cacheControlFormat":"anthropic"},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2,
@@ -791,7 +793,7 @@ export const OPENROUTER_MODELS = {
baseUrl: "https://openrouter.ai/api/v1",
compat: {"supportsDeveloperRole":false,"thinkingFormat":"openrouter","requiresReasoningContentOnAssistantMessages":true},
reasoning: true,
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh"},
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","max":null,"xhigh":"xhigh"},
input: ["text"],
cost: {
input: 0.09,
@@ -810,7 +812,7 @@ export const OPENROUTER_MODELS = {
baseUrl: "https://openrouter.ai/api/v1",
compat: {"supportsDeveloperRole":false,"thinkingFormat":"openrouter","requiresReasoningContentOnAssistantMessages":true},
reasoning: true,
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh"},
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","max":null,"xhigh":"xhigh"},
input: ["text"],
cost: {
input: 0.435,
@@ -1486,7 +1488,7 @@ export const OPENROUTER_MODELS = {
cacheWrite: 0,
},
contextWindow: 1048576,
maxTokens: 512000,
maxTokens: 131072,
} satisfies Model<"openai-completions">,
"mistralai/codestral-2508": {
id: "mistralai/codestral-2508",
@@ -2804,7 +2806,7 @@ export const OPENROUTER_MODELS = {
baseUrl: "https://openrouter.ai/api/v1",
compat: {"thinkingFormat":"openrouter"},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 1,
@@ -2823,7 +2825,7 @@ export const OPENROUTER_MODELS = {
baseUrl: "https://openrouter.ai/api/v1",
compat: {"thinkingFormat":"openrouter"},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 1,
@@ -2842,7 +2844,7 @@ export const OPENROUTER_MODELS = {
baseUrl: "https://openrouter.ai/api/v1",
compat: {"thinkingFormat":"openrouter"},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -2861,7 +2863,7 @@ export const OPENROUTER_MODELS = {
baseUrl: "https://openrouter.ai/api/v1",
compat: {"thinkingFormat":"openrouter"},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -2880,7 +2882,7 @@ export const OPENROUTER_MODELS = {
baseUrl: "https://openrouter.ai/api/v1",
compat: {"thinkingFormat":"openrouter"},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2.5,
@@ -2899,7 +2901,7 @@ export const OPENROUTER_MODELS = {
baseUrl: "https://openrouter.ai/api/v1",
compat: {"thinkingFormat":"openrouter"},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2.5,
@@ -522,7 +522,7 @@ export const VERCEL_AI_GATEWAY_MODELS = {
baseUrl: "https://ai-gateway.vercel.sh",
compat: {"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
thinkingLevelMap: {"off":null,"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 10,
@@ -609,7 +609,7 @@ export const VERCEL_AI_GATEWAY_MODELS = {
baseUrl: "https://ai-gateway.vercel.sh",
compat: {"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"xhigh":"max"},
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -628,7 +628,7 @@ export const VERCEL_AI_GATEWAY_MODELS = {
baseUrl: "https://ai-gateway.vercel.sh",
compat: {"forceAdaptiveThinking":true,"supportsTemperature":false},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -647,7 +647,7 @@ export const VERCEL_AI_GATEWAY_MODELS = {
baseUrl: "https://ai-gateway.vercel.sh",
compat: {"forceAdaptiveThinking":true,"supportsTemperature":false},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh"},
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 5,
@@ -700,6 +700,7 @@ export const VERCEL_AI_GATEWAY_MODELS = {
baseUrl: "https://ai-gateway.vercel.sh",
compat: {"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"max":"max"},
input: ["text", "image"],
cost: {
input: 3,
@@ -718,6 +719,7 @@ export const VERCEL_AI_GATEWAY_MODELS = {
baseUrl: "https://ai-gateway.vercel.sh",
compat: {"forceAdaptiveThinking":true},
reasoning: true,
thinkingLevelMap: {"xhigh":"xhigh","max":"max"},
input: ["text", "image"],
cost: {
input: 2,
@@ -84,7 +84,7 @@ export const ZAI_CODING_CN_MODELS = {
baseUrl: "https://open.bigmodel.cn/api/coding/paas/v4",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"thinkingFormat":"zai","zaiToolStream":true},
reasoning: true,
thinkingLevelMap: {"minimal":null,"low":"high","medium":"high","high":"high","xhigh":"max"},
thinkingLevelMap: {"minimal":null,"low":"high","medium":"high","high":"high","max":"max"},
input: ["text"],
cost: {
input: 0,
+1 -1
View File
@@ -84,7 +84,7 @@ export const ZAI_MODELS = {
baseUrl: "https://api.z.ai/api/coding/paas/v4",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"thinkingFormat":"zai","zaiToolStream":true},
reasoning: true,
thinkingLevelMap: {"minimal":null,"low":"high","medium":"high","high":"high","xhigh":"max"},
thinkingLevelMap: {"minimal":null,"low":"high","medium":"high","high":"high","max":"max"},
input: ["text"],
cost: {
input: 0,
+1 -1
View File
@@ -71,7 +71,7 @@ export type KnownImagesProvider = "openrouter";
export type ImagesProviderId = KnownImagesProvider | string;
export type ThinkingLevel = "minimal" | "low" | "medium" | "high" | "xhigh";
export type ThinkingLevel = "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
export type ModelThinkingLevel = "off" | ThinkingLevel;
export type ThinkingLevelMap = Partial<Record<ModelThinkingLevel, string | null>>;
export type ChatTemplateKwargValue =
@@ -19,7 +19,7 @@ import {
import { getModel } from "../src/compat.ts";
import type { AssistantMessage, Context, Message, Model, Tool, ToolResultMessage, Transport } from "../src/types.ts";
type ThinkingLevel = "minimal" | "low" | "medium" | "high" | "xhigh";
type ThinkingLevel = "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
interface Args {
turns: number;
@@ -58,7 +58,14 @@ function parseArgs(argv: string[]): Args {
break;
case "--reasoning": {
const value = required(argv[++i], arg);
if (value !== "minimal" && value !== "low" && value !== "medium" && value !== "high" && value !== "xhigh") {
if (
value !== "minimal" &&
value !== "low" &&
value !== "medium" &&
value !== "high" &&
value !== "xhigh" &&
value !== "max"
) {
throw new Error(`Invalid --reasoning: ${value}`);
}
reasoning = value;
@@ -90,7 +97,7 @@ function printHelp(): void {
Options:
--turns <n> Number of user turns. Default: ${DEFAULT_TURNS}
--transport <mode> sse | websocket | websocket-cached | auto. Default: websocket-cached
--reasoning <level> minimal | low | medium | high | xhigh. Default: low
--reasoning <level> minimal | low | medium | high | xhigh | max. Default: low
--max-tokens <n> Max output tokens per model request. Default: ${DEFAULT_MAX_TOKENS}
--session-id <id> Session id for websocket/cache state
`);
@@ -57,12 +57,14 @@ describe("Copilot Claude via Anthropic Messages", () => {
it("applies Copilot-specific adaptive thinking effort overrides", () => {
const opus47 = getModel("github-copilot", "claude-opus-4.7");
expect(opus47.thinkingLevelMap).toMatchObject({ minimal: "low", xhigh: "xhigh" });
expect(opus47.thinkingLevelMap).toMatchObject({ minimal: "low", xhigh: "xhigh", max: "max" });
expect(getSupportedThinkingLevels(opus47)).toContain("xhigh");
expect(getSupportedThinkingLevels(opus47)).toContain("max");
const sonnet46 = getModel("github-copilot", "claude-sonnet-4.6");
expect(sonnet46.thinkingLevelMap).toMatchObject({ minimal: "low", xhigh: "max" });
expect(getSupportedThinkingLevels(sonnet46)).toContain("xhigh");
expect(sonnet46.thinkingLevelMap).toMatchObject({ minimal: "low", max: "max" });
expect(getSupportedThinkingLevels(sonnet46)).toContain("max");
expect(getSupportedThinkingLevels(sonnet46)).not.toContain("xhigh");
});
it("uses Bearer auth, Copilot headers, and valid Anthropic Messages payload", async () => {
+89
View File
@@ -0,0 +1,89 @@
import { describe, expect, it } from "vitest";
import { streamSimple as streamSimpleOpenAICodexResponses } from "../src/api/openai-codex-responses.ts";
import { clampThinkingLevel, getModel, getSupportedThinkingLevels } from "../src/compat.ts";
import type { Context, Model } from "../src/types.ts";
function mockToken(): string {
const payload = Buffer.from(
JSON.stringify({ "https://api.openai.com/auth": { chatgpt_account_id: "acc_test" } }),
"utf8",
).toString("base64");
return `aaa.${payload}.bbb`;
}
describe("max thinking level", () => {
it("is opt-in for ordinary reasoning models", () => {
const model: Model<"openai-completions"> = {
id: "ordinary-reasoning",
name: "Ordinary Reasoning",
api: "openai-completions",
provider: "test",
baseUrl: "https://example.com/v1",
reasoning: true,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128000,
maxTokens: 4096,
};
expect(getSupportedThinkingLevels(model)).toEqual(["off", "minimal", "low", "medium", "high"]);
expect(clampThinkingLevel(model, "max")).toBe("high");
});
it.each(["gpt-5.6-luna", "gpt-5.6-sol", "gpt-5.6-terra"] as const)(
"exposes xhigh and max for openai-codex/%s",
(modelId) => {
const model = getModel("openai-codex", modelId);
expect(model).toBeDefined();
expect(model?.thinkingLevelMap).toMatchObject({ xhigh: "xhigh", max: "max" });
expect(getSupportedThinkingLevels(model!)).toEqual([
"off",
"minimal",
"low",
"medium",
"high",
"xhigh",
"max",
]);
},
);
it("supports a hole between high and max", () => {
const model: Model<"openai-completions"> = {
id: "high-and-max",
name: "High and Max",
api: "openai-completions",
provider: "test",
baseUrl: "https://example.com/v1",
reasoning: true,
thinkingLevelMap: { xhigh: null, max: "max" },
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128000,
maxTokens: 4096,
};
expect(getSupportedThinkingLevels(model)).toEqual(["off", "minimal", "low", "medium", "high", "max"]);
expect(clampThinkingLevel(model, "xhigh")).toBe("max");
});
it("sends max to the Codex Responses API", async () => {
const model = getModel("openai-codex", "gpt-5.6-sol")!;
const context: Context = {
systemPrompt: "You are a helpful assistant.",
messages: [{ role: "user", content: "Hello", timestamp: Date.now() }],
};
let payload: unknown;
await streamSimpleOpenAICodexResponses(model, context, {
apiKey: mockToken(),
reasoning: "max",
onPayload: (request) => {
payload = request;
throw new Error("payload captured");
},
}).result();
expect(payload).toMatchObject({ reasoning: { effort: "max", summary: "auto" } });
});
});
@@ -305,7 +305,7 @@ describe("openai-completions tool_choice", () => {
low: "high",
medium: "high",
high: "high",
xhigh: "max",
max: "max",
});
}
});
@@ -316,7 +316,7 @@ describe("openai-completions tool_choice", () => {
{ reasoning: "low", effort: "high" },
{ reasoning: "medium", effort: "high" },
{ reasoning: "high", effort: "high" },
{ reasoning: "xhigh", effort: "max" },
{ reasoning: "max", effort: "max" },
] as const;
for (const testCase of cases) {
+38 -16
View File
@@ -2,35 +2,47 @@ import { describe, expect, it } from "vitest";
import { getModel, getSupportedThinkingLevels } from "../src/compat.ts";
describe("getSupportedThinkingLevels", () => {
it("includes xhigh for Anthropic Opus 4.6 on anthropic-messages API", () => {
it("includes max but not xhigh for Anthropic Opus 4.6 on anthropic-messages API", () => {
const model = getModel("anthropic", "claude-opus-4-6");
expect(model).toBeDefined();
expect(getSupportedThinkingLevels(model!)).toContain("xhigh");
expect(getSupportedThinkingLevels(model!)).toContain("max");
expect(getSupportedThinkingLevels(model!)).not.toContain("xhigh");
});
it("includes xhigh for Anthropic Opus 4.8 on anthropic-messages API", () => {
it("includes xhigh and max for Anthropic Opus 4.8 on anthropic-messages API", () => {
const model = getModel("anthropic", "claude-opus-4-8");
expect(model).toBeDefined();
expect(getSupportedThinkingLevels(model!)).toContain("xhigh");
expect(getSupportedThinkingLevels(model!)).toContain("max");
});
it("includes xhigh for Anthropic Opus 4.8 on anthropic-messages API", () => {
const model = getModel("anthropic", "claude-opus-4-8");
it("includes max but not xhigh for Anthropic Sonnet 4.6 on anthropic-messages API", () => {
const model = getModel("anthropic", "claude-sonnet-4-6");
expect(model).toBeDefined();
expect(getSupportedThinkingLevels(model!)).toContain("max");
expect(getSupportedThinkingLevels(model!)).not.toContain("xhigh");
});
it("includes xhigh and max for Anthropic Sonnet 5 on anthropic-messages API", () => {
const model = getModel("anthropic", "claude-sonnet-5");
expect(model).toBeDefined();
expect(getSupportedThinkingLevels(model!)).toContain("xhigh");
expect(getSupportedThinkingLevels(model!)).toContain("max");
});
it("includes xhigh but not off for Anthropic Claude Fable 5 on anthropic-messages API", () => {
it("includes xhigh and max but not off for Anthropic Claude Fable 5 on anthropic-messages API", () => {
const model = getModel("anthropic", "claude-fable-5");
expect(model).toBeDefined();
expect(getSupportedThinkingLevels(model!)).toContain("xhigh");
expect(getSupportedThinkingLevels(model!)).toContain("max");
expect(getSupportedThinkingLevels(model!)).not.toContain("off");
});
it("does not include xhigh for Claude Sonnet 4.5", () => {
it("does not include xhigh or max for Claude Sonnet 4.5", () => {
const model = getModel("anthropic", "claude-sonnet-4-5");
expect(model).toBeDefined();
expect(getSupportedThinkingLevels(model!)).not.toContain("xhigh");
expect(getSupportedThinkingLevels(model!)).not.toContain("max");
});
it.each(["gpt-5.4", "gpt-5.5", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"] as const)(
@@ -43,11 +55,19 @@ describe("getSupportedThinkingLevels", () => {
);
it.each(["gpt-5.6", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"] as const)(
"includes xhigh for OpenAI %s models",
"includes xhigh and max for OpenAI %s models",
(modelId) => {
const model = getModel("openai", modelId);
expect(model).toBeDefined();
expect(getSupportedThinkingLevels(model!)).toContain("xhigh");
expect(getSupportedThinkingLevels(model!)).toEqual([
"off",
"minimal",
"low",
"medium",
"high",
"xhigh",
"max",
]);
},
);
@@ -63,16 +83,16 @@ describe("getSupportedThinkingLevels", () => {
expect(getSupportedThinkingLevels(model!)).toEqual(["medium", "high", "xhigh"]);
});
it("includes only high/xhigh plus off for DeepSeek V4 Flash on the DeepSeek provider", () => {
it("includes only high/max plus off for DeepSeek V4 Flash on the DeepSeek provider", () => {
const model = getModel("deepseek", "deepseek-v4-flash");
expect(model).toBeDefined();
expect(getSupportedThinkingLevels(model!)).toEqual(["off", "high", "xhigh"]);
expect(getSupportedThinkingLevels(model!)).toEqual(["off", "high", "max"]);
});
it("includes only high/xhigh plus off for DeepSeek V4 Flash on opencode-go", () => {
it("includes only high/max plus off for DeepSeek V4 Flash on opencode-go", () => {
const model = getModel("opencode-go", "deepseek-v4-flash");
expect(model).toBeDefined();
expect(getSupportedThinkingLevels(model!)).toEqual(["off", "high", "xhigh"]);
expect(getSupportedThinkingLevels(model!)).toEqual(["off", "high", "max"]);
});
it("includes only high plus off for OpenCode Go Kimi K2.6", () => {
@@ -102,16 +122,18 @@ describe("getSupportedThinkingLevels", () => {
expect(getSupportedThinkingLevels(model!)).toEqual(["off", "high", "xhigh"]);
});
it("includes xhigh for OpenRouter Opus 4.6 (openai-completions API)", () => {
it("includes max but not xhigh for OpenRouter Opus 4.6 (openai-completions API)", () => {
const model = getModel("openrouter", "anthropic/claude-opus-4.6");
expect(model).toBeDefined();
expect(getSupportedThinkingLevels(model!)).toContain("xhigh");
expect(getSupportedThinkingLevels(model!)).toContain("max");
expect(getSupportedThinkingLevels(model!)).not.toContain("xhigh");
});
it("includes xhigh but not off for Bedrock Claude Fable 5", () => {
it("includes xhigh and max but not off for Bedrock Claude Fable 5", () => {
const model = getModel("amazon-bedrock", "global.anthropic.claude-fable-5");
expect(model).toBeDefined();
expect(getSupportedThinkingLevels(model!)).toContain("xhigh");
expect(getSupportedThinkingLevels(model!)).toContain("max");
expect(getSupportedThinkingLevels(model!)).not.toContain("off");
});
});