feat(ai): add max thinking level
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Added the `max` model thinking level after `xhigh`.
|
||||
|
||||
## [0.80.5] - 2026-07-09
|
||||
|
||||
## [0.80.4] - 2026-07-09
|
||||
|
||||
@@ -164,7 +164,7 @@ const agent = new Agent({
|
||||
initialState: {
|
||||
systemPrompt: string,
|
||||
model: Model<any>,
|
||||
thinkingLevel: "off" | "minimal" | "low" | "medium" | "high" | "xhigh",
|
||||
thinkingLevel: "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max",
|
||||
tools: AgentTool<any>[],
|
||||
messages: AgentMessage[],
|
||||
},
|
||||
|
||||
@@ -283,10 +283,10 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
|
||||
|
||||
/**
|
||||
* Thinking/reasoning level for models that support it.
|
||||
* Note: "xhigh" is only supported by selected model families. Use model thinking-level metadata
|
||||
* from @earendil-works/pi-ai to detect support for a concrete model.
|
||||
* Note: "xhigh" and "max" are only supported by selected model families. Use model
|
||||
* thinking-level metadata from @earendil-works/pi-ai to detect support for a concrete model.
|
||||
*/
|
||||
export type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
|
||||
export type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
|
||||
|
||||
/**
|
||||
* Extensible interface for custom app messages.
|
||||
|
||||
@@ -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)).
|
||||
|
||||
@@ -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'> = {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"];
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Added the opt-in `max` thinking level across CLI, SDK, RPC, model selection, and themes. Custom themes can define `thinkingMax`; existing themes fall back to `thinkingXhigh`.
|
||||
|
||||
## [0.80.5] - 2026-07-09
|
||||
|
||||
## [0.80.4] - 2026-07-09
|
||||
|
||||
@@ -551,7 +551,7 @@ cat README.md | pi -p "Summarize this text"
|
||||
| `--provider <name>` | Provider (anthropic, openai, google, etc.) |
|
||||
| `--model <pattern>` | Model pattern or ID (supports `provider/id` and optional `:<thinking>`) |
|
||||
| `--api-key <key>` | API key (overrides env vars) |
|
||||
| `--thinking <level>` | `off`, `minimal`, `low`, `medium`, `high`, `xhigh` |
|
||||
| `--thinking <level>` | `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max` |
|
||||
| `--models <patterns>` | Comma-separated patterns for Ctrl+P cycling |
|
||||
| `--list-models [search]` | List available models |
|
||||
|
||||
|
||||
@@ -204,7 +204,7 @@ The `api` field determines which streaming implementation is used:
|
||||
| `google-vertex` | Google Vertex AI API |
|
||||
| `bedrock-converse-stream` | Amazon Bedrock Converse API |
|
||||
|
||||
Most OpenAI-compatible providers work with `openai-completions`. Use model-level `thinkingLevelMap` for model-specific thinking levels, and `compat` for provider quirks:
|
||||
Most OpenAI-compatible providers work with `openai-completions`. Use model-level `thinkingLevelMap` for model-specific thinking levels, and `compat` for provider quirks. The `xhigh` and `max` levels are opt-in, require non-null map entries, and may be separated by unsupported holes:
|
||||
|
||||
```typescript
|
||||
models: [{
|
||||
@@ -216,7 +216,8 @@ models: [{
|
||||
low: null,
|
||||
medium: null,
|
||||
high: "default",
|
||||
xhigh: "max"
|
||||
xhigh: null,
|
||||
max: "max"
|
||||
},
|
||||
compat: {
|
||||
supportsDeveloperRole: false, // use "system" instead of "developer"
|
||||
@@ -684,7 +685,7 @@ interface ProviderModelConfig {
|
||||
reasoning: boolean;
|
||||
|
||||
/** Maps pi thinking levels to provider/model-specific values; null marks a level unsupported. */
|
||||
thinkingLevelMap?: Partial<Record<"off" | "minimal" | "low" | "medium" | "high" | "xhigh", string | null>>;
|
||||
thinkingLevelMap?: Partial<Record<"off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", string | null>>;
|
||||
|
||||
/** Supported input types. */
|
||||
input: ("text" | "image")[];
|
||||
|
||||
@@ -1657,7 +1657,7 @@ if (model) {
|
||||
Get or set the thinking level. Level is clamped to model capabilities (non-reasoning models always use "off"). Changes emit `thinking_level_select`.
|
||||
|
||||
```typescript
|
||||
const current = pi.getThinkingLevel(); // "off" | "minimal" | "low" | "medium" | "high" | "xhigh"
|
||||
const current = pi.getThinkingLevel(); // "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max"
|
||||
pi.setThinkingLevel("high");
|
||||
```
|
||||
|
||||
|
||||
@@ -214,13 +214,13 @@ Current behavior:
|
||||
|
||||
### Thinking Level Map
|
||||
|
||||
Use `thinkingLevelMap` on a model to describe model-specific thinking controls. Keys are pi thinking levels: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`.
|
||||
Use `thinkingLevelMap` on a model to describe model-specific thinking controls. Keys are pi thinking levels: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`. Maps may contain holes; for example, a model can expose `high` and `max` without exposing `xhigh`.
|
||||
|
||||
Values are tristate:
|
||||
|
||||
| Value | Meaning |
|
||||
|-------|---------|
|
||||
| omitted | Level is supported and uses the provider's default mapping |
|
||||
| omitted | Standard levels through `high` use the provider's default mapping; extended `xhigh` and `max` levels are unsupported |
|
||||
| string | Level is supported and this value is sent to the provider |
|
||||
| `null` | Level is unsupported and hidden/skipped/clamped away |
|
||||
|
||||
@@ -235,7 +235,8 @@ Example for a model that only supports off, high, and max reasoning:
|
||||
"low": null,
|
||||
"medium": null,
|
||||
"high": "high",
|
||||
"xhigh": "max"
|
||||
"xhigh": null,
|
||||
"max": "max"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -286,9 +286,9 @@ Set the reasoning/thinking level for models that support it.
|
||||
{"type": "set_thinking_level", "level": "high"}
|
||||
```
|
||||
|
||||
Levels: `"off"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, `"xhigh"`
|
||||
Levels: `"off"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, `"xhigh"`, `"max"`
|
||||
|
||||
Note: `"xhigh"` is only supported by OpenAI codex-max models.
|
||||
`"xhigh"` and `"max"` are exposed only when supported by the selected model. Some models, including GPT-5.6, expose both.
|
||||
|
||||
Response:
|
||||
```json
|
||||
|
||||
@@ -387,7 +387,7 @@ const available = await modelRegistry.getAvailable();
|
||||
|
||||
const { session } = await createAgentSession({
|
||||
model: opus,
|
||||
thinkingLevel: "medium", // off, minimal, low, medium, high, xhigh
|
||||
thinkingLevel: "medium", // off, minimal, low, medium, high, xhigh, max
|
||||
|
||||
// Models for cycling (Ctrl+P in interactive mode)
|
||||
scopedModels: [
|
||||
|
||||
@@ -29,7 +29,7 @@ Use `/trust` in interactive mode to save a project trust decision for future ses
|
||||
|---------|------|---------|-------------|
|
||||
| `defaultProvider` | string | - | Default provider (e.g., `"anthropic"`, `"openai"`) |
|
||||
| `defaultModel` | string | - | Default model ID |
|
||||
| `defaultThinkingLevel` | string | - | `"off"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, `"xhigh"` |
|
||||
| `defaultThinkingLevel` | string | - | `"off"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, `"xhigh"`, `"max"` |
|
||||
| `hideThinkingBlock` | boolean | `false` | Hide thinking blocks in output |
|
||||
| `showCacheMissNotices` | boolean | `false` | Show transcript notices for significant prompt-cache misses |
|
||||
| `thinkingBudgets` | object | - | Custom token budgets per thinking level |
|
||||
|
||||
@@ -109,6 +109,7 @@ vim ~/.pi/agent/themes/my-theme.json
|
||||
"thinkingMedium": "#00ffff",
|
||||
"thinkingHigh": "#ff00ff",
|
||||
"thinkingXhigh": "#ff0000",
|
||||
"thinkingMax": "#ff0088",
|
||||
"bashMode": "#ffaa00"
|
||||
}
|
||||
}
|
||||
@@ -139,13 +140,13 @@ vim ~/.pi/agent/themes/my-theme.json
|
||||
|
||||
- `name` is required, must be unique, and must not contain `/`.
|
||||
- `vars` is optional. Define reusable colors here, then reference them in `colors`.
|
||||
- `colors` must define all 51 required tokens.
|
||||
- `colors` must define all 51 required tokens. `thinkingMax` is optional and falls back to `thinkingXhigh`.
|
||||
|
||||
The `$schema` field enables editor auto-completion and validation.
|
||||
|
||||
## Color Tokens
|
||||
|
||||
Every theme must define all 51 color tokens. There are no optional colors.
|
||||
Every theme must define all 51 required color tokens. `thinkingMax` is optional for compatibility with existing themes; when omitted, it uses `thinkingXhigh`.
|
||||
|
||||
### Core UI (11 colors)
|
||||
|
||||
@@ -216,7 +217,7 @@ Every theme must define all 51 color tokens. There are no optional colors.
|
||||
| `syntaxOperator` | Operators |
|
||||
| `syntaxPunctuation` | Punctuation |
|
||||
|
||||
### Thinking Level Borders (6 colors)
|
||||
### Thinking Level Borders (6 required, 1 optional)
|
||||
|
||||
Editor border colors indicating thinking level (visual hierarchy from subtle to prominent):
|
||||
|
||||
@@ -228,6 +229,7 @@ Editor border colors indicating thinking level (visual hierarchy from subtle to
|
||||
| `thinkingMedium` | Medium thinking |
|
||||
| `thinkingHigh` | High thinking |
|
||||
| `thinkingXhigh` | Extra high thinking |
|
||||
| `thinkingMax` | Maximum thinking; optional, falls back to `thinkingXhigh` |
|
||||
|
||||
### Bash Mode (1 color)
|
||||
|
||||
|
||||
@@ -424,7 +424,7 @@ renderResult(result, options, theme, context) {
|
||||
| Diffs | `toolDiffAdded`, `toolDiffRemoved`, `toolDiffContext` |
|
||||
| Markdown | `mdHeading`, `mdLink`, `mdLinkUrl`, `mdCode`, `mdCodeBlock`, `mdCodeBlockBorder`, `mdQuote`, `mdQuoteBorder`, `mdHr`, `mdListBullet` |
|
||||
| Syntax | `syntaxComment`, `syntaxKeyword`, `syntaxFunction`, `syntaxVariable`, `syntaxString`, `syntaxNumber`, `syntaxType`, `syntaxOperator`, `syntaxPunctuation` |
|
||||
| Thinking | `thinkingOff`, `thinkingMinimal`, `thinkingLow`, `thinkingMedium`, `thinkingHigh`, `thinkingXhigh` |
|
||||
| Thinking | `thinkingOff`, `thinkingMinimal`, `thinkingLow`, `thinkingMedium`, `thinkingHigh`, `thinkingXhigh`, `thinkingMax` |
|
||||
| Modes | `bashMode` |
|
||||
|
||||
**Background colors** (`theme.bg(color, text)`):
|
||||
|
||||
@@ -183,7 +183,7 @@ cat README.md | pi -p "Summarize this text"
|
||||
| `--provider <name>` | Provider, such as `anthropic`, `openai`, or `google` |
|
||||
| `--model <pattern>` | Model pattern or ID; supports `provider/id` and optional `:<thinking>` |
|
||||
| `--api-key <key>` | API key, overriding environment variables |
|
||||
| `--thinking <level>` | `off`, `minimal`, `low`, `medium`, `high`, `xhigh` |
|
||||
| `--thinking <level>` | `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max` |
|
||||
| `--models <patterns>` | Comma-separated patterns for Ctrl+P cycling |
|
||||
| `--list-models [search]` | List available models |
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ interface Preset {
|
||||
/** Model ID (e.g., "claude-sonnet-4-5") */
|
||||
model?: string;
|
||||
/** Thinking level */
|
||||
thinkingLevel?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
|
||||
thinkingLevel?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
|
||||
/** Tools to enable (replaces default set) */
|
||||
tools?: string[];
|
||||
/** Instructions to append to system prompt */
|
||||
@@ -100,7 +100,7 @@ function loadPresets(cwd: string): PresetsConfig {
|
||||
|
||||
interface OriginalState {
|
||||
model: Model<Api> | undefined;
|
||||
thinkingLevel: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
|
||||
thinkingLevel: "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
|
||||
tools: string[];
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ export interface Args {
|
||||
diagnostics: Array<{ type: "warning" | "error"; message: string }>;
|
||||
}
|
||||
|
||||
const VALID_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh"] as const;
|
||||
const VALID_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"] as const;
|
||||
|
||||
export function isValidThinkingLevel(level: string): level is ThinkingLevel {
|
||||
return VALID_THINKING_LEVELS.includes(level as ThinkingLevel);
|
||||
@@ -258,7 +258,7 @@ ${chalk.bold("Options:")}
|
||||
Applies to built-in, extension, and custom tools
|
||||
--exclude-tools, -xt <tools> Comma-separated denylist of tool names to disable
|
||||
Applies to built-in, extension, and custom tools
|
||||
--thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh
|
||||
--thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh, max
|
||||
--extension, -e <path> Load an extension file (can be used multiple times)
|
||||
--no-extensions, -ne Disable extension discovery (explicit -e paths still work)
|
||||
--skill <path> Load a skill file or directory (can be used multiple times)
|
||||
|
||||
@@ -94,6 +94,7 @@ const ThinkingLevelMapSchema = Type.Object({
|
||||
medium: Type.Optional(ThinkingLevelMapValueSchema),
|
||||
high: Type.Optional(ThinkingLevelMapValueSchema),
|
||||
xhigh: Type.Optional(ThinkingLevelMapValueSchema),
|
||||
max: Type.Optional(ThinkingLevelMapValueSchema),
|
||||
});
|
||||
|
||||
const ChatTemplateKwargScalarSchema = Type.Union([Type.String(), Type.Number(), Type.Boolean(), Type.Null()]);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
|
||||
import type { Transport } from "@earendil-works/pi-ai";
|
||||
import { randomUUID } from "crypto";
|
||||
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
||||
@@ -83,7 +84,7 @@ export interface Settings {
|
||||
lastChangelogVersion?: string;
|
||||
defaultProvider?: string;
|
||||
defaultModel?: string;
|
||||
defaultThinkingLevel?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
|
||||
defaultThinkingLevel?: ThinkingLevel;
|
||||
transport?: TransportSetting; // default: "auto"
|
||||
steeringMode?: "all" | "one-at-a-time";
|
||||
followUpMode?: "all" | "one-at-a-time";
|
||||
@@ -736,11 +737,11 @@ export class SettingsManager {
|
||||
this.save();
|
||||
}
|
||||
|
||||
getDefaultThinkingLevel(): "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | undefined {
|
||||
getDefaultThinkingLevel(): ThinkingLevel | undefined {
|
||||
return this.settings.defaultThinkingLevel;
|
||||
}
|
||||
|
||||
setDefaultThinkingLevel(level: "off" | "minimal" | "low" | "medium" | "high" | "xhigh"): void {
|
||||
setDefaultThinkingLevel(level: ThinkingLevel): void {
|
||||
this.globalSettings.defaultThinkingLevel = level;
|
||||
this.markModified("defaultThinkingLevel");
|
||||
this.save();
|
||||
|
||||
@@ -35,7 +35,8 @@ const THINKING_DESCRIPTIONS: Record<ThinkingLevel, string> = {
|
||||
low: "Light reasoning (~2k tokens)",
|
||||
medium: "Moderate reasoning (~8k tokens)",
|
||||
high: "Deep reasoning (~16k tokens)",
|
||||
xhigh: "Maximum reasoning (~32k tokens)",
|
||||
xhigh: "Extra-high reasoning (~32k tokens)",
|
||||
max: "Maximum reasoning",
|
||||
};
|
||||
|
||||
const DEFAULT_PROJECT_TRUST_LABELS: Record<DefaultProjectTrust, string> = {
|
||||
|
||||
@@ -14,7 +14,8 @@ const LEVEL_DESCRIPTIONS: Record<ThinkingLevel, string> = {
|
||||
low: "Light reasoning (~2k tokens)",
|
||||
medium: "Moderate reasoning (~8k tokens)",
|
||||
high: "Deep reasoning (~16k tokens)",
|
||||
xhigh: "Maximum reasoning (~32k tokens)",
|
||||
xhigh: "Extra-high reasoning (~32k tokens)",
|
||||
max: "Maximum reasoning",
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
"thinkingMedium": "#81a2be",
|
||||
"thinkingHigh": "#b294bb",
|
||||
"thinkingXhigh": "#d183e8",
|
||||
"thinkingMax": "#ff5fff",
|
||||
|
||||
"bashMode": "green"
|
||||
},
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
"thinkingMedium": "teal",
|
||||
"thinkingHigh": "#875f87",
|
||||
"thinkingXhigh": "#8b008b",
|
||||
"thinkingMax": "#af005f",
|
||||
|
||||
"bashMode": "green"
|
||||
},
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
},
|
||||
"colors": {
|
||||
"type": "object",
|
||||
"description": "Theme color definitions (all required)",
|
||||
"description": "Theme color definitions (thinkingMax is optional and falls back to thinkingXhigh)",
|
||||
"required": [
|
||||
"accent",
|
||||
"border",
|
||||
@@ -287,7 +287,11 @@
|
||||
},
|
||||
"thinkingXhigh": {
|
||||
"$ref": "#/$defs/colorValue",
|
||||
"description": "Thinking level border: xhigh (OpenAI codex-max only)"
|
||||
"description": "Thinking level border: xhigh"
|
||||
},
|
||||
"thinkingMax": {
|
||||
"$ref": "#/$defs/colorValue",
|
||||
"description": "Thinking level border: max (falls back to thinkingXhigh when omitted)"
|
||||
},
|
||||
"bashMode": {
|
||||
"$ref": "#/$defs/colorValue",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
|
||||
import {
|
||||
type EditorTheme,
|
||||
getCapabilities,
|
||||
@@ -88,6 +89,7 @@ const ThemeJsonSchema = Type.Object({
|
||||
thinkingMedium: ColorValueSchema,
|
||||
thinkingHigh: ColorValueSchema,
|
||||
thinkingXhigh: ColorValueSchema,
|
||||
thinkingMax: Type.Optional(ColorValueSchema),
|
||||
// Bash Mode (1 color)
|
||||
bashMode: ColorValueSchema,
|
||||
}),
|
||||
@@ -149,6 +151,7 @@ export type ThemeColor =
|
||||
| "thinkingMedium"
|
||||
| "thinkingHigh"
|
||||
| "thinkingXhigh"
|
||||
| "thinkingMax"
|
||||
| "bashMode";
|
||||
|
||||
export type ThemeBg =
|
||||
@@ -316,6 +319,10 @@ function resolveThemeColors<T extends Record<string, ColorValue>>(
|
||||
return resolved as Record<keyof T, string | number>;
|
||||
}
|
||||
|
||||
function withThemeColorFallbacks(colors: ThemeJson["colors"]): ThemeJson["colors"] & { thinkingMax: ColorValue } {
|
||||
return { ...colors, thinkingMax: colors.thinkingMax ?? colors.thinkingXhigh };
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Theme Class
|
||||
// ============================================================================
|
||||
@@ -339,7 +346,8 @@ export class Theme {
|
||||
this.sourceInfo = options.sourceInfo;
|
||||
this.mode = mode;
|
||||
this.fgColors = new Map();
|
||||
for (const [key, value] of Object.entries(fgColors) as [ThemeColor, string | number][]) {
|
||||
const colors = { ...fgColors, thinkingMax: fgColors.thinkingMax ?? fgColors.thinkingXhigh };
|
||||
for (const [key, value] of Object.entries(colors) as [ThemeColor, string | number][]) {
|
||||
this.fgColors.set(key, fgAnsi(value, mode));
|
||||
}
|
||||
this.bgColors = new Map();
|
||||
@@ -396,7 +404,7 @@ export class Theme {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
getThinkingBorderColor(level: "off" | "minimal" | "low" | "medium" | "high" | "xhigh"): (str: string) => string {
|
||||
getThinkingBorderColor(level: ThinkingLevel): (str: string) => string {
|
||||
// Map thinking levels to dedicated theme colors
|
||||
switch (level) {
|
||||
case "off":
|
||||
@@ -411,6 +419,8 @@ export class Theme {
|
||||
return (str: string) => this.fg("thinkingHigh", str);
|
||||
case "xhigh":
|
||||
return (str: string) => this.fg("thinkingXhigh", str);
|
||||
case "max":
|
||||
return (str: string) => this.fg("thinkingMax", str);
|
||||
default:
|
||||
return (str: string) => this.fg("thinkingOff", str);
|
||||
}
|
||||
@@ -586,7 +596,7 @@ function loadThemeJson(name: string): ThemeJson {
|
||||
|
||||
function createTheme(themeJson: ThemeJson, mode?: ColorMode, sourcePath?: string): Theme {
|
||||
const colorMode = mode ?? (getCapabilities().trueColor ? "truecolor" : "256color");
|
||||
const resolvedColors = resolveThemeColors(themeJson.colors, themeJson.vars);
|
||||
const resolvedColors = resolveThemeColors(withThemeColorFallbacks(themeJson.colors), themeJson.vars);
|
||||
const fgColors: Record<ThemeColor, string | number> = {} as Record<ThemeColor, string | number>;
|
||||
const bgColors: Record<ThemeBg, string | number> = {} as Record<ThemeBg, string | number>;
|
||||
const bgColorKeys: Set<string> = new Set([
|
||||
@@ -1013,7 +1023,7 @@ export function getResolvedThemeColors(themeName?: string): Record<string, strin
|
||||
const name = themeName ?? currentThemeName ?? getDefaultTheme();
|
||||
const isLight = name === "light";
|
||||
const themeJson = loadThemeJson(name);
|
||||
const resolved = resolveThemeColors(themeJson.colors, themeJson.vars);
|
||||
const resolved = resolveThemeColors(withThemeColorFallbacks(themeJson.colors), themeJson.vars);
|
||||
|
||||
// Default text color for empty values (terminal uses default fg color)
|
||||
const defaultText = isLight ? "#000000" : "#e5e5e7";
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { dirname, join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { isValidThinkingLevel } from "../src/cli/args.ts";
|
||||
import { SettingsManager } from "../src/core/settings-manager.ts";
|
||||
import { loadThemeFromPath } from "../src/modes/interactive/theme/theme.ts";
|
||||
|
||||
const tempDirs: string[] = [];
|
||||
|
||||
afterEach(() => {
|
||||
for (const dir of tempDirs.splice(0)) {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
describe("max thinking level", () => {
|
||||
it("is accepted by CLI and settings", async () => {
|
||||
expect(isValidThinkingLevel("max")).toBe(true);
|
||||
|
||||
const settings = SettingsManager.inMemory();
|
||||
settings.setDefaultThinkingLevel("max");
|
||||
await settings.flush();
|
||||
expect(settings.getDefaultThinkingLevel()).toBe("max");
|
||||
});
|
||||
|
||||
it("falls back to thinkingXhigh for legacy themes", () => {
|
||||
const testDir = mkdtempSync(join(tmpdir(), "pi-max-theme-"));
|
||||
tempDirs.push(testDir);
|
||||
const currentDir = dirname(fileURLToPath(import.meta.url));
|
||||
const darkTheme = JSON.parse(
|
||||
readFileSync(join(currentDir, "../src/modes/interactive/theme/dark.json"), "utf8"),
|
||||
) as { name: string; colors: Record<string, unknown> };
|
||||
darkTheme.name = "legacy-theme";
|
||||
delete darkTheme.colors.thinkingMax;
|
||||
const themePath = join(testDir, "legacy-theme.json");
|
||||
writeFileSync(themePath, JSON.stringify(darkTheme));
|
||||
|
||||
const legacyTheme = loadThemeFromPath(themePath);
|
||||
expect(legacyTheme.getThinkingBorderColor("max")("border")).toBe(
|
||||
legacyTheme.getThinkingBorderColor("xhigh")("border"),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -107,7 +107,7 @@ describe("parseModelPattern", () => {
|
||||
});
|
||||
|
||||
test("all valid thinking levels work", () => {
|
||||
for (const level of ["off", "minimal", "low", "medium", "high", "xhigh"]) {
|
||||
for (const level of ["off", "minimal", "low", "medium", "high", "xhigh", "max"]) {
|
||||
const result = parseModelPattern(`sonnet:${level}`, allModels);
|
||||
expect(result.model?.id).toBe("claude-sonnet-4-5");
|
||||
expect(result.thinkingLevel).toBe(level);
|
||||
@@ -520,7 +520,7 @@ describe("resolveCliModel", () => {
|
||||
getAll: () => modelsWithNeuralwatt,
|
||||
} as unknown as Parameters<typeof resolveCliModel>[0]["modelRegistry"];
|
||||
|
||||
for (const level of ["off", "minimal", "low", "medium", "high", "xhigh"]) {
|
||||
for (const level of ["off", "minimal", "low", "medium", "high", "xhigh", "max"]) {
|
||||
const result = resolveCliModel({
|
||||
cliModel: `neuralwatt/zai-org/GLM-5.1-FP8:${level}`,
|
||||
modelRegistry: registry,
|
||||
|
||||
@@ -78,6 +78,26 @@ describe("AgentSession model and extension characterization", () => {
|
||||
expect(harness.session.cycleThinkingLevel()).toBeUndefined();
|
||||
});
|
||||
|
||||
it("cycles xhigh before max when both are supported", async () => {
|
||||
const harness = await createHarness({ models: [{ id: "faux-1", reasoning: true }] });
|
||||
harnesses.push(harness);
|
||||
harness.getModel().thinkingLevelMap = { xhigh: "xhigh", max: "max" };
|
||||
|
||||
expect(harness.session.getAvailableThinkingLevels()).toEqual([
|
||||
"off",
|
||||
"minimal",
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"xhigh",
|
||||
"max",
|
||||
]);
|
||||
harness.session.setThinkingLevel("high");
|
||||
expect(harness.session.cycleThinkingLevel()).toBe("xhigh");
|
||||
expect(harness.session.cycleThinkingLevel()).toBe("max");
|
||||
expect(harness.session.cycleThinkingLevel()).toBe("off");
|
||||
});
|
||||
|
||||
it("throws when setModel is called without configured auth", async () => {
|
||||
const harness = await createHarness({
|
||||
models: [
|
||||
|
||||
Reference in New Issue
Block a user