@akon-labs/nexus-cli 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +2 -3
- package/dist/cli.js +1192 -649
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +0 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/extensions/gitnexus/gateway.d.ts +2 -0
- package/dist/extensions/gitnexus/gateway.d.ts.map +1 -1
- package/dist/extensions/gitnexus/gateway.js +27 -0
- package/dist/extensions/gitnexus/gateway.js.map +1 -1
- package/dist/extensions/gitnexus/index.d.ts.map +1 -1
- package/dist/extensions/gitnexus/index.js +16 -1
- package/dist/extensions/gitnexus/index.js.map +1 -1
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +2 -0
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/subagent/index.d.ts +110 -0
- package/dist/extensions/subagent/index.d.ts.map +1 -0
- package/dist/extensions/subagent/index.js +568 -0
- package/dist/extensions/subagent/index.js.map +1 -0
- package/dist/index.js +1236 -693
- package/dist/modes/interactive/interactive-mode.d.ts +0 -5
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +0 -122
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/rpc-entry.js +1192 -649
- package/dist/vendor/ai.js +110 -15
- package/docs/rpc.md +1 -1
- package/docs/usage.md +0 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/rpc-entry.js
CHANGED
|
@@ -175,15 +175,15 @@ function defaultProviderAuthContext() {
|
|
|
175
175
|
const value = getProcessEnv()?.[name];
|
|
176
176
|
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
177
177
|
},
|
|
178
|
-
async fileExists(
|
|
178
|
+
async fileExists(path12) {
|
|
179
179
|
try {
|
|
180
|
-
const
|
|
181
|
-
let resolved =
|
|
180
|
+
const fs8 = await importNodeModule("node:fs/promises");
|
|
181
|
+
let resolved = path12;
|
|
182
182
|
if (resolved.startsWith("~")) {
|
|
183
|
-
const
|
|
184
|
-
resolved =
|
|
183
|
+
const os6 = await importNodeModule("node:os");
|
|
184
|
+
resolved = os6.homedir() + resolved.slice(1);
|
|
185
185
|
}
|
|
186
|
-
await
|
|
186
|
+
await fs8.access(resolved);
|
|
187
187
|
return true;
|
|
188
188
|
} catch {
|
|
189
189
|
return false;
|
|
@@ -392,7 +392,7 @@ async function resolveProviderAuthWithSignal(provider, credentials, authContext,
|
|
|
392
392
|
function overlayEnvAuthContext(base, env) {
|
|
393
393
|
return {
|
|
394
394
|
env: async (name) => env[name] || await base.env(name),
|
|
395
|
-
fileExists: (
|
|
395
|
+
fileExists: (path12) => base.fileExists(path12)
|
|
396
396
|
};
|
|
397
397
|
}
|
|
398
398
|
async function resolveStoredOAuth(credentials, providerId, oauth, stored, signal, minOAuthValidityMs) {
|
|
@@ -6892,6 +6892,15 @@ function isEncryptedReasoningDetail(detail) {
|
|
|
6892
6892
|
const candidate = detail;
|
|
6893
6893
|
return candidate.type === "reasoning.encrypted" && typeof candidate.id === "string" && candidate.id.length > 0 && typeof candidate.data === "string" && candidate.data.length > 0;
|
|
6894
6894
|
}
|
|
6895
|
+
function parseEncryptedReasoningDetail(signature) {
|
|
6896
|
+
if (!signature) return void 0;
|
|
6897
|
+
try {
|
|
6898
|
+
const detail = JSON.parse(signature);
|
|
6899
|
+
return isEncryptedReasoningDetail(detail) ? detail : void 0;
|
|
6900
|
+
} catch {
|
|
6901
|
+
return void 0;
|
|
6902
|
+
}
|
|
6903
|
+
}
|
|
6895
6904
|
function resolveCacheRetention3(cacheRetention, env) {
|
|
6896
6905
|
if (cacheRetention) {
|
|
6897
6906
|
return cacheRetention;
|
|
@@ -7288,6 +7297,18 @@ function convertMessages4(model, context, compat, options) {
|
|
|
7288
7297
|
assistantMsg.content = assistantText;
|
|
7289
7298
|
}
|
|
7290
7299
|
const toolCalls = msg.content.filter(isToolCallBlock);
|
|
7300
|
+
const reasoningDetails = msg.content.map((block) => {
|
|
7301
|
+
if (block.type === "thinking") {
|
|
7302
|
+
return parseEncryptedReasoningDetail(block.thinkingSignature);
|
|
7303
|
+
}
|
|
7304
|
+
if (block.type === "toolCall") {
|
|
7305
|
+
return parseEncryptedReasoningDetail(block.thoughtSignature);
|
|
7306
|
+
}
|
|
7307
|
+
return void 0;
|
|
7308
|
+
}).filter((detail) => detail !== void 0);
|
|
7309
|
+
if (reasoningDetails.length > 0) {
|
|
7310
|
+
assistantMsg.reasoning_details = reasoningDetails;
|
|
7311
|
+
}
|
|
7291
7312
|
if (toolCalls.length > 0) {
|
|
7292
7313
|
assistantMsg.tool_calls = toolCalls.map((tc) => {
|
|
7293
7314
|
const customInputProperty = options?.grammarToolInputProperties?.get(tc.name);
|
|
@@ -7310,23 +7331,13 @@ function convertMessages4(model, context, compat, options) {
|
|
|
7310
7331
|
}
|
|
7311
7332
|
};
|
|
7312
7333
|
});
|
|
7313
|
-
const reasoningDetails = toolCalls.filter((tc) => tc.thoughtSignature).map((tc) => {
|
|
7314
|
-
try {
|
|
7315
|
-
return JSON.parse(tc.thoughtSignature);
|
|
7316
|
-
} catch {
|
|
7317
|
-
return null;
|
|
7318
|
-
}
|
|
7319
|
-
}).filter(Boolean);
|
|
7320
|
-
if (reasoningDetails.length > 0) {
|
|
7321
|
-
assistantMsg.reasoning_details = reasoningDetails;
|
|
7322
|
-
}
|
|
7323
7334
|
}
|
|
7324
7335
|
if (compat.requiresReasoningContentOnAssistantMessages && model.reasoning && assistantMsg.reasoning_content === void 0) {
|
|
7325
7336
|
assistantMsg.reasoning_content = "";
|
|
7326
7337
|
}
|
|
7327
7338
|
const content = assistantMsg.content;
|
|
7328
7339
|
const hasContent = content !== null && content !== void 0 && (typeof content === "string" ? content.length > 0 : content.length > 0);
|
|
7329
|
-
if (!hasContent && !assistantMsg.tool_calls) {
|
|
7340
|
+
if (!hasContent && !assistantMsg.tool_calls && reasoningDetails.length === 0) {
|
|
7330
7341
|
continue;
|
|
7331
7342
|
}
|
|
7332
7343
|
params.push(assistantMsg);
|
|
@@ -7879,6 +7890,14 @@ var init_openai_completions = __esm({
|
|
|
7879
7890
|
for (const block of blocks) {
|
|
7880
7891
|
finishBlock(block);
|
|
7881
7892
|
}
|
|
7893
|
+
for (const serializedDetail of pendingReasoningDetailsByToolCallId.values()) {
|
|
7894
|
+
blocks.push({
|
|
7895
|
+
type: "thinking",
|
|
7896
|
+
thinking: "",
|
|
7897
|
+
thinkingSignature: serializedDetail,
|
|
7898
|
+
redacted: true
|
|
7899
|
+
});
|
|
7900
|
+
}
|
|
7882
7901
|
if (options?.signal?.aborted) {
|
|
7883
7902
|
throw new Error("Request was aborted");
|
|
7884
7903
|
}
|
|
@@ -12038,6 +12057,36 @@ var IMAGE_MODELS = {
|
|
|
12038
12057
|
cacheWrite: 0
|
|
12039
12058
|
}
|
|
12040
12059
|
},
|
|
12060
|
+
"bytedance-seed/seedream-5-0-lite": {
|
|
12061
|
+
id: "bytedance-seed/seedream-5-0-lite",
|
|
12062
|
+
name: "ByteDance Seed: Seedream 5.0 Lite",
|
|
12063
|
+
api: "openrouter-images",
|
|
12064
|
+
provider: "openrouter",
|
|
12065
|
+
baseUrl: "https://openrouter.ai/api/v1",
|
|
12066
|
+
input: ["text", "image"],
|
|
12067
|
+
output: ["image"],
|
|
12068
|
+
cost: {
|
|
12069
|
+
input: 0,
|
|
12070
|
+
output: 0,
|
|
12071
|
+
cacheRead: 0,
|
|
12072
|
+
cacheWrite: 0
|
|
12073
|
+
}
|
|
12074
|
+
},
|
|
12075
|
+
"bytedance-seed/seedream-5-0-pro": {
|
|
12076
|
+
id: "bytedance-seed/seedream-5-0-pro",
|
|
12077
|
+
name: "ByteDance Seed: Seedream 5.0 Pro",
|
|
12078
|
+
api: "openrouter-images",
|
|
12079
|
+
provider: "openrouter",
|
|
12080
|
+
baseUrl: "https://openrouter.ai/api/v1",
|
|
12081
|
+
input: ["text", "image"],
|
|
12082
|
+
output: ["image"],
|
|
12083
|
+
cost: {
|
|
12084
|
+
input: 0,
|
|
12085
|
+
output: 0,
|
|
12086
|
+
cacheRead: 0,
|
|
12087
|
+
cacheWrite: 0
|
|
12088
|
+
}
|
|
12089
|
+
},
|
|
12041
12090
|
"google/gemini-2.5-flash-image": {
|
|
12042
12091
|
id: "google/gemini-2.5-flash-image",
|
|
12043
12092
|
name: "Google: Nano Banana (Gemini 2.5 Flash Image)",
|
|
@@ -12050,7 +12099,7 @@ var IMAGE_MODELS = {
|
|
|
12050
12099
|
input: 0.3,
|
|
12051
12100
|
output: 2.5,
|
|
12052
12101
|
cacheRead: 0.03,
|
|
12053
|
-
cacheWrite: 0.
|
|
12102
|
+
cacheWrite: 0.0833333333333333
|
|
12054
12103
|
}
|
|
12055
12104
|
},
|
|
12056
12105
|
"google/gemini-3-pro-image": {
|
|
@@ -12323,6 +12372,36 @@ var IMAGE_MODELS = {
|
|
|
12323
12372
|
cacheWrite: 0
|
|
12324
12373
|
}
|
|
12325
12374
|
},
|
|
12375
|
+
"qwen/qwen-image-3": {
|
|
12376
|
+
id: "qwen/qwen-image-3",
|
|
12377
|
+
name: "Qwen: Qwen Image 3",
|
|
12378
|
+
api: "openrouter-images",
|
|
12379
|
+
provider: "openrouter",
|
|
12380
|
+
baseUrl: "https://openrouter.ai/api/v1",
|
|
12381
|
+
input: ["text", "image"],
|
|
12382
|
+
output: ["image"],
|
|
12383
|
+
cost: {
|
|
12384
|
+
input: 0,
|
|
12385
|
+
output: 0,
|
|
12386
|
+
cacheRead: 0,
|
|
12387
|
+
cacheWrite: 0
|
|
12388
|
+
}
|
|
12389
|
+
},
|
|
12390
|
+
"qwen/qwen-image-3-pro": {
|
|
12391
|
+
id: "qwen/qwen-image-3-pro",
|
|
12392
|
+
name: "Qwen: Qwen Image 3 Pro",
|
|
12393
|
+
api: "openrouter-images",
|
|
12394
|
+
provider: "openrouter",
|
|
12395
|
+
baseUrl: "https://openrouter.ai/api/v1",
|
|
12396
|
+
input: ["text", "image"],
|
|
12397
|
+
output: ["image"],
|
|
12398
|
+
cost: {
|
|
12399
|
+
input: 0,
|
|
12400
|
+
output: 0,
|
|
12401
|
+
cacheRead: 0,
|
|
12402
|
+
cacheWrite: 0
|
|
12403
|
+
}
|
|
12404
|
+
},
|
|
12326
12405
|
"recraft/recraft-v3": {
|
|
12327
12406
|
id: "recraft/recraft-v3",
|
|
12328
12407
|
name: "Recraft: Recraft V3",
|
|
@@ -12548,9 +12627,24 @@ var IMAGE_MODELS = {
|
|
|
12548
12627
|
cacheWrite: 0
|
|
12549
12628
|
}
|
|
12550
12629
|
},
|
|
12630
|
+
"x-ai/grok-imagine-image-2.0": {
|
|
12631
|
+
id: "x-ai/grok-imagine-image-2.0",
|
|
12632
|
+
name: "xAI: Grok Imagine Image 2.0",
|
|
12633
|
+
api: "openrouter-images",
|
|
12634
|
+
provider: "openrouter",
|
|
12635
|
+
baseUrl: "https://openrouter.ai/api/v1",
|
|
12636
|
+
input: ["text", "image"],
|
|
12637
|
+
output: ["image"],
|
|
12638
|
+
cost: {
|
|
12639
|
+
input: 0,
|
|
12640
|
+
output: 0,
|
|
12641
|
+
cacheRead: 0,
|
|
12642
|
+
cacheWrite: 0
|
|
12643
|
+
}
|
|
12644
|
+
},
|
|
12551
12645
|
"x-ai/grok-imagine-image-quality": {
|
|
12552
12646
|
id: "x-ai/grok-imagine-image-quality",
|
|
12553
|
-
name: "
|
|
12647
|
+
name: "SpaceXAI: Grok Imagine Image Quality",
|
|
12554
12648
|
api: "openrouter-images",
|
|
12555
12649
|
provider: "openrouter",
|
|
12556
12650
|
baseUrl: "https://openrouter.ai/api/v1",
|
|
@@ -13915,8 +14009,8 @@ function formatValidationPath(error) {
|
|
|
13915
14009
|
return basePath ? `${basePath}.${requiredProperty}` : requiredProperty;
|
|
13916
14010
|
}
|
|
13917
14011
|
}
|
|
13918
|
-
const
|
|
13919
|
-
return
|
|
14012
|
+
const path12 = error.instancePath.replace(/^\//, "").replace(/\//g, ".");
|
|
14013
|
+
return path12 || "root";
|
|
13920
14014
|
}
|
|
13921
14015
|
function validateToolCall(tools, toolCall) {
|
|
13922
14016
|
const tool = tools.find((t) => t.name === toolCall.name);
|
|
@@ -14139,13 +14233,13 @@ var opencode_default = { "anthropic-messages": { "claude-fable-5": { id: "claude
|
|
|
14139
14233
|
var OPENCODE_MODELS = flattenModelCatalog("opencode", opencode_default);
|
|
14140
14234
|
|
|
14141
14235
|
// ../ai/src/providers/data/opencode-go.json
|
|
14142
|
-
var opencode_go_default = { "anthropic-messages": { "minimax-m3": { id: "minimax-m3", name: "MiniMax-M3", api: "anthropic-messages", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 131072 } }, "openai-completions": { "deepseek-v4-flash": { id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 0.22, output: 0.66, cacheRead: 7e-3, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens", requiresReasoningContentOnAssistantMessages: true, thinkingFormat: "deepseek" }, contextWindow: 1e6, maxTokens: 384e3, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: "max" } }, "deepseek-v4-flash-vision-exp": { id: "deepseek-v4-flash-vision-exp", name: "DeepSeek V4 Flash Vision Exp", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.22, output: 0.66, cacheRead: 7e-3, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens", requiresReasoningContentOnAssistantMessages: true, thinkingFormat: "deepseek" }, contextWindow: 1e6, maxTokens: 384e3, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: "max" } }, "deepseek-v4-pro": { id: "deepseek-v4-pro", name: "DeepSeek V4 Pro (New)", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 0.66, output: 1.98, cacheRead: 0.022, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens", requiresReasoningContentOnAssistantMessages: true, thinkingFormat: "deepseek" }, contextWindow: 1e6, maxTokens: 384e3, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: "max" } }, "glm-5.1": { id: "glm-5.1", name: "GLM-5.1", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 202752, maxTokens: 32768 }, "glm-5.2": { id: "glm-5.2", name: "GLM-5.2", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: null, medium: null, high: "high", xhigh: null, max: "max" } }, "glm-5.3": { id: "glm-5.3", name: "GLM-5.3", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: null, high: "high", xhigh: null, max: "max" } }, hy3: { id: "hy3", name: "Hy3 (8x usage)", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 0.0175, output: 0.0725, cacheRead: 4375e-6, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 256e3, maxTokens: 64e3, thinkingLevelMap: { off: "none", minimal: null, low: "low", medium: null, high: "high", xhigh: null, max: null } }, "kimi-k2.6": { id: "kimi-k2.6", name: "Kimi K2.6", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, thinkingFormat: "deepseek", supportsReasoningEffort: false, maxTokensField: "max_tokens", supportsLongCacheRetention: false }, contextWindow: 262144, maxTokens: 65536, thinkingLevelMap: { minimal: null, low: null, medium: null } }, "kimi-k2.7-code": { id: "kimi-k2.7-code", name: "Kimi K2.7 Code", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 262144, maxTokens: 262144 }, "kimi-k3": { id: "kimi-k3", name: "Kimi K3", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1048576, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: null, medium: null, high: null, xhigh: null, max: "max" } }, "mimo-v2.5": { id: "mimo-v2.5", name: "MiMo V2.5", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.14, output: 0.28, cacheRead: 28e-4, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 128e3 }, "mimo-v2.5-pro": { id: "mimo-v2.5-pro", name: "MiMo V2.5 Pro", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 0.435, output: 0.87, cacheRead: 3625e-6, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1048576, maxTokens: 128e3 }, "minimax-m2.7": { id: "minimax-m2.7", name: "MiniMax-M2.7", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 204800, maxTokens: 131072 }, "ox-alpha-free": { id: "ox-alpha-free", name: "Ox Alpha Free (Unlimited)", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: null, high: "high", xhigh: null, max: "max" } }, "qwen3.6-plus": { id: "qwen3.6-plus", name: "Qwen3.6 Plus", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0.625 }, compat: { supportsStore: false, supportsDeveloperRole: false, thinkingFormat: "qwen", maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 65536 }, "qwen3.7-max": { id: "qwen3.7-max", name: "Qwen3.7 Max", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 2.5, output: 7.5, cacheRead: 0.5, cacheWrite: 3.125 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 65536 }, "qwen3.7-plus": { id: "qwen3.7-plus", name: "Qwen3.7 Plus", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.4, output: 1.6, cacheRead: 0.04, cacheWrite: 0.5 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 65536 }, "qwen3.8-max": { id: "qwen3.8-max", name: "Qwen3.8 Max", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 2.5 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072 } }, "openai-responses": { "gpt-5.6-luna": { id: "gpt-5.6-luna", name: "GPT-5.6 Luna", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, compat: { sessionAffinityFormat: "openai-nosession" }, contextWindow: 105e4, maxTokens: 128e3, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: "max" } }, "grok-4.5": { id: "grok-4.5", name: "Grok 4.5", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, compat: { sessionAffinityFormat: "openai-nosession" }, contextWindow: 5e5, maxTokens: 5e5, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null } }, "muse-spark-1.2-contributor": { id: "muse-spark-1.2-contributor", name: "Muse Spark 1.2 Contributor", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.2, cacheRead: 2e-3, cacheWrite: 0 }, compat: { sessionAffinityFormat: "openai-nosession" }, contextWindow: 1048576, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: null } } } };
|
|
14236
|
+
var opencode_go_default = { "anthropic-messages": { "minimax-m3": { id: "minimax-m3", name: "MiniMax-M3", api: "anthropic-messages", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 131072 } }, "openai-completions": { "deepseek-v4-flash": { id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 0.22, output: 0.66, cacheRead: 7e-3, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens", requiresReasoningContentOnAssistantMessages: true, thinkingFormat: "deepseek" }, contextWindow: 1e6, maxTokens: 384e3, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: "max" } }, "deepseek-v4-flash-vision-exp": { id: "deepseek-v4-flash-vision-exp", name: "DeepSeek V4 Flash Vision Exp", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.22, output: 0.66, cacheRead: 7e-3, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens", requiresReasoningContentOnAssistantMessages: true, thinkingFormat: "deepseek" }, contextWindow: 1e6, maxTokens: 384e3, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: "max" } }, "deepseek-v4-pro": { id: "deepseek-v4-pro", name: "DeepSeek V4 Pro (New)", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 0.66, output: 1.98, cacheRead: 0.022, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens", requiresReasoningContentOnAssistantMessages: true, thinkingFormat: "deepseek" }, contextWindow: 1e6, maxTokens: 384e3, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: "max" } }, "glm-5.1": { id: "glm-5.1", name: "GLM-5.1", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 202752, maxTokens: 32768 }, "glm-5.2": { id: "glm-5.2", name: "GLM-5.2", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: null, medium: null, high: "high", xhigh: null, max: "max" } }, "glm-5.3": { id: "glm-5.3", name: "GLM-5.3", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: null, high: "high", xhigh: null, max: "max" } }, hy3: { id: "hy3", name: "Hy3 (8x usage)", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 0.0175, output: 0.0725, cacheRead: 4375e-6, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 256e3, maxTokens: 64e3, thinkingLevelMap: { off: "none", minimal: null, low: "low", medium: null, high: "high", xhigh: null, max: null } }, "kimi-k2.6": { id: "kimi-k2.6", name: "Kimi K2.6", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, thinkingFormat: "deepseek", supportsReasoningEffort: false, maxTokensField: "max_tokens", supportsLongCacheRetention: false }, contextWindow: 262144, maxTokens: 65536, thinkingLevelMap: { minimal: null, low: null, medium: null } }, "kimi-k2.7-code": { id: "kimi-k2.7-code", name: "Kimi K2.7 Code", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 262144, maxTokens: 262144 }, "kimi-k3": { id: "kimi-k3", name: "Kimi K3", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1048576, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: null, medium: null, high: null, xhigh: null, max: "max" } }, "longcat-2.0": { id: "longcat-2.0", name: "LongCat-2.0", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 0.3, output: 1.2, cacheRead: 6e-3, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072 }, "mimo-v2.5": { id: "mimo-v2.5", name: "MiMo V2.5", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.14, output: 0.28, cacheRead: 28e-4, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 128e3 }, "mimo-v2.5-pro": { id: "mimo-v2.5-pro", name: "MiMo V2.5 Pro", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 0.435, output: 0.87, cacheRead: 3625e-6, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1048576, maxTokens: 128e3 }, "minimax-m2.7": { id: "minimax-m2.7", name: "MiniMax-M2.7", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 204800, maxTokens: 131072 }, "ox-alpha-free": { id: "ox-alpha-free", name: "Ox Alpha Free (Unlimited)", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: null, high: "high", xhigh: null, max: "max" } }, "qwen3.6-plus": { id: "qwen3.6-plus", name: "Qwen3.6 Plus", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0.625 }, compat: { supportsStore: false, supportsDeveloperRole: false, thinkingFormat: "qwen", maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 65536 }, "qwen3.7-max": { id: "qwen3.7-max", name: "Qwen3.7 Max", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text"], cost: { input: 2.5, output: 7.5, cacheRead: 0.5, cacheWrite: 3.125 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 65536 }, "qwen3.7-plus": { id: "qwen3.7-plus", name: "Qwen3.7 Plus", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.4, output: 1.6, cacheRead: 0.04, cacheWrite: 0.5 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 65536 }, "qwen3.8-max": { id: "qwen3.8-max", name: "Qwen3.8 Max", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 2.5 }, compat: { supportsStore: false, supportsDeveloperRole: false, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072 } }, "openai-responses": { "gpt-5.6-luna": { id: "gpt-5.6-luna", name: "GPT-5.6 Luna", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, compat: { sessionAffinityFormat: "openai-nosession" }, contextWindow: 105e4, maxTokens: 128e3, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: "max" } }, "grok-4.5": { id: "grok-4.5", name: "Grok 4.5", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, compat: { sessionAffinityFormat: "openai-nosession" }, contextWindow: 5e5, maxTokens: 5e5, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null } }, "muse-spark-1.2-contributor": { id: "muse-spark-1.2-contributor", name: "Muse Spark 1.2 Contributor", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/zen/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.2, cacheRead: 2e-3, cacheWrite: 0 }, compat: { sessionAffinityFormat: "openai-nosession" }, contextWindow: 1048576, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: null } } } };
|
|
14143
14237
|
|
|
14144
14238
|
// ../ai/src/providers/opencode-go.models.ts
|
|
14145
14239
|
var OPENCODE_GO_MODELS = flattenModelCatalog("opencode-go", opencode_go_default);
|
|
14146
14240
|
|
|
14147
14241
|
// ../ai/src/providers/data/openrouter.json
|
|
14148
|
-
var openrouter_default = { "openai-completions": { "aion-labs/aion-2.0": { id: "aion-labs/aion-2.0", name: "AionLabs: Aion-2.0", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.8, output: 1.6, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "aion-labs/aion-3.0": { id: "aion-labs/aion-3.0", name: "AionLabs: Aion-3.0", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 3, output: 6, cacheRead: 0.75, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "aion-labs/aion-3.0-mini": { id: "aion-labs/aion-3.0-mini", name: "AionLabs: Aion-3.0-Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.7, output: 1.4, cacheRead: 0.18, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "amazon/nova-2-lite-v1": { id: "amazon/nova-2-lite-v1", name: "Amazon: Nova 2 Lite", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 2.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 65535, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "amazon/nova-lite-v1": { id: "amazon/nova-lite-v1", name: "Amazon: Nova Lite 1.0", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.06, output: 0.24, cacheRead: 0, cacheWrite: 0 }, contextWindow: 3e5, maxTokens: 5120, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "amazon/nova-micro-v1": { id: "amazon/nova-micro-v1", name: "Amazon: Nova Micro 1.0", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.035, output: 0.14, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 5120, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "amazon/nova-premier-v1": { id: "amazon/nova-premier-v1", name: "Amazon: Nova Premier 1.0", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 2.5, output: 12.5, cacheRead: 0.625, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 32e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "amazon/nova-pro-v1": { id: "amazon/nova-pro-v1", name: "Amazon: Nova Pro 1.0", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.8, output: 3.2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 3e5, maxTokens: 5120, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "anthropic/claude-3-haiku": { id: "anthropic/claude-3-haiku", name: "Anthropic: Claude 3 Haiku", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.25, output: 1.25, cacheRead: 0.03, cacheWrite: 0.3 }, contextWindow: 2e5, maxTokens: 4096, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-fable-5": { id: "anthropic/claude-fable-5", name: "Anthropic: Claude Fable 5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { off: null, xhigh: "xhigh", max: "max" } }, "anthropic/claude-fable-5:batch": { id: "anthropic/claude-fable-5:batch", name: "Anthropic: Claude Fable 5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { off: null, xhigh: "xhigh", max: "max" } }, "anthropic/claude-haiku-4.5": { id: "anthropic/claude-haiku-4.5", name: "Anthropic: Claude Haiku 4.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, contextWindow: 2e5, maxTokens: 64e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-haiku-4.5:batch": { id: "anthropic/claude-haiku-4.5:batch", name: "Anthropic: Claude Haiku 4.5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.5, output: 2.5, cacheRead: 0.05, cacheWrite: 0.625 }, contextWindow: 2e5, maxTokens: 64e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-opus-4": { id: "anthropic/claude-opus-4", name: "Anthropic: Claude Opus 4", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 }, contextWindow: 2e5, maxTokens: 32e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-opus-4.1": { id: "anthropic/claude-opus-4.1", name: "Anthropic: Claude Opus 4.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 }, contextWindow: 2e5, maxTokens: 32e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-opus-4.1:batch": { id: "anthropic/claude-opus-4.1:batch", name: "Anthropic: Claude Opus 4.1 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 7.5, output: 37.5, cacheRead: 0.75, cacheWrite: 9.375 }, contextWindow: 2e5, maxTokens: 32e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-opus-4.5": { id: "anthropic/claude-opus-4.5", name: "Anthropic: Claude Opus 4.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, contextWindow: 2e5, maxTokens: 64e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-opus-4.5:batch": { id: "anthropic/claude-opus-4.5:batch", name: "Anthropic: Claude Opus 4.5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, contextWindow: 2e5, maxTokens: 64e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-opus-4.6": { id: "anthropic/claude-opus-4.6", name: "Anthropic: Claude Opus 4.6", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { max: "max" } }, "anthropic/claude-opus-4.6:batch": { id: "anthropic/claude-opus-4.6:batch", name: "Anthropic: Claude Opus 4.6 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { max: "max" } }, "anthropic/claude-opus-4.7": { id: "anthropic/claude-opus-4.7", name: "Anthropic: Claude Opus 4.7", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-4.7-fast": { id: "anthropic/claude-opus-4.7-fast", name: "Anthropic: Claude Opus 4.7 (Fast)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 30, output: 150, cacheRead: 3, cacheWrite: 37.5 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-4.7:batch": { id: "anthropic/claude-opus-4.7:batch", name: "Anthropic: Claude Opus 4.7 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-4.8": { id: "anthropic/claude-opus-4.8", name: "Anthropic: Claude Opus 4.8", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-4.8-fast": { id: "anthropic/claude-opus-4.8-fast", name: "Anthropic: Claude Opus 4.8 (Fast)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-4.8:batch": { id: "anthropic/claude-opus-4.8:batch", name: "Anthropic: Claude Opus 4.8 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-5": { id: "anthropic/claude-opus-5", name: "Claude Opus 5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-5-fast": { id: "anthropic/claude-opus-5-fast", name: "Claude Opus 5 (Fast)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-5:batch": { id: "anthropic/claude-opus-5:batch", name: "Claude Opus 5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-sonnet-4": { id: "anthropic/claude-sonnet-4", name: "Anthropic: Claude Sonnet 4", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, contextWindow: 2e5, maxTokens: 64e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-sonnet-4.5": { id: "anthropic/claude-sonnet-4.5", name: "Anthropic: Claude Sonnet 4.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, contextWindow: 1e6, maxTokens: 64e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-sonnet-4.5:batch": { id: "anthropic/claude-sonnet-4.5:batch", name: "Anthropic: Claude Sonnet 4.5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 1.875 }, contextWindow: 1e6, maxTokens: 64e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-sonnet-4.6": { id: "anthropic/claude-sonnet-4.6", name: "Anthropic: Claude Sonnet 4.6", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { max: "max" } }, "anthropic/claude-sonnet-4.6:batch": { id: "anthropic/claude-sonnet-4.6:batch", name: "Anthropic: Claude Sonnet 4.6 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 1.875 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { max: "max" } }, "anthropic/claude-sonnet-5": { id: "anthropic/claude-sonnet-5", name: "Anthropic: Claude Sonnet 5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-sonnet-5:batch": { id: "anthropic/claude-sonnet-5:batch", name: "Anthropic: Claude Sonnet 5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "arcee-ai/trinity-large-thinking": { id: "arcee-ai/trinity-large-thinking", name: "Arcee AI: Trinity Large Thinking", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.22, output: 0.85, cacheRead: 0.06, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "arcee-ai/virtuoso-large": { id: "arcee-ai/virtuoso-large", name: "Arcee AI: Virtuoso Large", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.75, output: 1.2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 64e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, auto: { id: "auto", name: "Auto", api: "openai-completions", provider: "openrouter", baseUrl: "https://openrouter.ai/api/v1", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 2e6, maxTokens: 3e4, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "bytedance-seed/seed-1.6": { id: "bytedance-seed/seed-1.6", name: "ByteDance Seed: Seed 1.6", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "bytedance-seed/seed-1.6-flash": { id: "bytedance-seed/seed-1.6-flash", name: "ByteDance Seed: Seed 1.6 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.075, output: 0.3, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "bytedance-seed/seed-2-1-turbo": { id: "bytedance-seed/seed-2-1-turbo", name: "ByteDance Seed: Seed 2.1 Turbo", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.5, output: 2.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "bytedance-seed/seed-2.0-code": { id: "bytedance-seed/seed-2.0-code", name: "ByteDance Seed: Seed-2.0-Code", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.5, output: 3, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "bytedance-seed/seed-2.0-lite": { id: "bytedance-seed/seed-2.0-lite", name: "ByteDance Seed: Seed-2.0-Lite", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "bytedance-seed/seed-2.0-mini": { id: "bytedance-seed/seed-2.0-mini", name: "ByteDance Seed: Seed-2.0-Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "cohere/command-r-08-2024": { id: "cohere/command-r-08-2024", name: "Cohere: Command R (08-2024)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "cohere/command-r-plus-08-2024": { id: "cohere/command-r-plus-08-2024", name: "Cohere: Command R+ (08-2024)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 2.5, output: 10, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "cohere/north-mini-code:free": { id: "cohere/north-mini-code:free", name: "Cohere: North Mini Code (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 64e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-chat": { id: "deepseek/deepseek-chat", name: "DeepSeek: DeepSeek V3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.2574, output: 1.0287, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-chat-v3-0324": { id: "deepseek/deepseek-chat-v3-0324", name: "DeepSeek: DeepSeek V3 0324", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.25, output: 1, cacheRead: 0, cacheWrite: 0 }, contextWindow: 163840, maxTokens: 163840, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-chat-v3.1": { id: "deepseek/deepseek-chat-v3.1", name: "DeepSeek: DeepSeek V3.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.55, output: 1.65, cacheRead: 0.55, cacheWrite: 0 }, contextWindow: 161e3, maxTokens: 161e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-r1": { id: "deepseek/deepseek-r1", name: "DeepSeek: R1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.7, output: 2.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 64e3, maxTokens: 16e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-r1-0528": { id: "deepseek/deepseek-r1-0528", name: "DeepSeek: R1 0528", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.5, output: 2.15, cacheRead: 0.35, cacheWrite: 0 }, contextWindow: 163840, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-v3.1-terminus": { id: "deepseek/deepseek-v3.1-terminus", name: "DeepSeek: DeepSeek V3.1 Terminus", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.27, output: 1, cacheRead: 0.135, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-v3.2": { id: "deepseek/deepseek-v3.2", name: "DeepSeek: DeepSeek V3.2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.26, output: 0.38, cacheRead: 0.13, cacheWrite: 0 }, contextWindow: 163840, maxTokens: 163840, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-v3.2-exp": { id: "deepseek/deepseek-v3.2-exp", name: "DeepSeek: DeepSeek V3.2 Exp", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.27, output: 0.41, cacheRead: 0, cacheWrite: 0 }, contextWindow: 163840, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-v4-flash": { id: "deepseek/deepseek-v4-flash", name: "DeepSeek: DeepSeek V4 Flash 0423", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.05726, output: 0.11452, cacheRead: 0.011452, cacheWrite: 0 }, contextWindow: 1024e3, maxTokens: 384e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", requiresReasoningContentOnAssistantMessages: true }, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: null, xhigh: "xhigh" } }, "deepseek/deepseek-v4-flash-0731": { id: "deepseek/deepseek-v4-flash-0731", name: "DeepSeek: DeepSeek V4 Flash 0731", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.08, output: 0.18, cacheRead: 0.016, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 384e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", requiresReasoningContentOnAssistantMessages: true }, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: null, xhigh: "xhigh" } }, "deepseek/deepseek-v4-flash-vision-exp": { id: "deepseek/deepseek-v4-flash-vision-exp", name: "DeepSeek: DeepSeek V4 Flash Vision Exp", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.22, output: 0.66, cacheRead: 7e-3, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 384e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", requiresReasoningContentOnAssistantMessages: true }, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: null, xhigh: "xhigh" } }, "deepseek/deepseek-v4-pro": { id: "deepseek/deepseek-v4-pro", name: "DeepSeek: DeepSeek V4 Pro 0423", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.413772, output: 0.827544, cacheRead: 0.034481, cacheWrite: 0 }, contextWindow: 1024e3, maxTokens: 384e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", requiresReasoningContentOnAssistantMessages: true }, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: null, xhigh: "xhigh" } }, "deepseek/deepseek-v4-pro-0813": { id: "deepseek/deepseek-v4-pro-0813", name: "DeepSeek: DeepSeek V4 Pro 0813", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.122, output: 3.366, cacheRead: 0.0374, cacheWrite: 0 }, contextWindow: 1048575, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", requiresReasoningContentOnAssistantMessages: true }, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: null, xhigh: "xhigh" } }, "dots-studio/dots-3-note-preview:free": { id: "dots-studio/dots-3-note-preview:free", name: "Dots Studio: Dots3-Note Preview (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 512e3, maxTokens: 512e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-flash": { id: "google/gemini-2.5-flash", name: "Google: Gemini 2.5 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0.083333 }, contextWindow: 1048576, maxTokens: 65535, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-flash-lite": { id: "google/gemini-2.5-flash-lite", name: "Google: Gemini 2.5 Flash Lite", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.4, cacheRead: 0.01, cacheWrite: 0.083333 }, contextWindow: 1048576, maxTokens: 65535, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-flash-lite:batch": { id: "google/gemini-2.5-flash-lite:batch", name: "Google: Gemini 2.5 Flash Lite (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.05, output: 0.2, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65535, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-flash:batch": { id: "google/gemini-2.5-flash:batch", name: "Google: Gemini 2.5 Flash (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.15, output: 1.25, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65535, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-pro": { id: "google/gemini-2.5-pro", name: "Google: Gemini 2.5 Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0.375 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-pro-preview": { id: "google/gemini-2.5-pro-preview", name: "Google: Gemini 2.5 Pro Preview 06-05", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0.375 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-pro-preview-05-06": { id: "google/gemini-2.5-pro-preview-05-06", name: "Google: Gemini 2.5 Pro Preview 05-06", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0.375 }, contextWindow: 1048576, maxTokens: 65535, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-pro:batch": { id: "google/gemini-2.5-pro:batch", name: "Google: Gemini 2.5 Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.625, output: 5, cacheRead: 0.125, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3-flash-preview": { id: "google/gemini-3-flash-preview", name: "Google: Gemini 3 Flash Preview", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0.083333 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3-flash-preview:batch": { id: "google/gemini-3-flash-preview:batch", name: "Google: Gemini 3 Flash Preview (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 1.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3-pro-image": { id: "google/gemini-3-pro-image", name: "Google: Nano Banana Pro (Gemini 3 Pro Image)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, contextWindow: 65536, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.1-flash-lite": { id: "google/gemini-3.1-flash-lite", name: "Google: Gemini 3.1 Flash Lite", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0.083333 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.1-flash-lite-preview": { id: "google/gemini-3.1-flash-lite-preview", name: "Google: Gemini 3.1 Flash Lite Preview", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0.083333 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.1-flash-lite:batch": { id: "google/gemini-3.1-flash-lite:batch", name: "Google: Gemini 3.1 Flash Lite (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.125, output: 0.75, cacheRead: 0.0125, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.1-pro-preview": { id: "google/gemini-3.1-pro-preview", name: "Google: Gemini 3.1 Pro Preview", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.1-pro-preview-customtools": { id: "google/gemini-3.1-pro-preview-customtools", name: "Google: Gemini 3.1 Pro Preview Custom Tools", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.1-pro-preview:batch": { id: "google/gemini-3.1-pro-preview:batch", name: "Google: Gemini 3.1 Pro Preview (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 6, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.5-flash": { id: "google/gemini-3.5-flash", name: "Google: Gemini 3.5 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0.083333 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.5-flash-lite": { id: "google/gemini-3.5-flash-lite", name: "Google: Gemini 3.5 Flash Lite", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0.083333 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.5-flash-lite:batch": { id: "google/gemini-3.5-flash-lite:batch", name: "Google: Gemini 3.5 Flash Lite (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.15, output: 1.25, cacheRead: 0.015, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.5-flash:batch": { id: "google/gemini-3.5-flash:batch", name: "Google: Gemini 3.5 Flash (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.6-flash": { id: "google/gemini-3.6-flash", name: "Google: Gemini 3.6 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0.041667 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.6-flash:batch": { id: "google/gemini-3.6-flash:batch", name: "Google: Gemini 3.6 Flash (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.375, output: 1.875, cacheRead: 0.0375, cacheWrite: 0.041667 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.7-flash": { id: "google/gemini-3.7-flash", name: "Google: Gemini 3.7 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.375, output: 1.875, cacheRead: 0.0375, cacheWrite: 0.020833 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.7-flash:batch": { id: "google/gemini-3.7-flash:batch", name: "Google: Gemini 3.7 Flash (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1875, output: 0.9375, cacheRead: 0.01875, cacheWrite: 0.020833 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemma-3-12b-it": { id: "google/gemma-3-12b-it", name: "Google: Gemma 3 12B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.05, output: 0.15, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemma-3-27b-it": { id: "google/gemma-3-27b-it", name: "Google: Gemma 3 27B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.08, output: 0.45, cacheRead: 0.04, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemma-4-26b-a4b-it": { id: "google/gemma-4-26b-a4b-it", name: "Google: Gemma 4 26B A4B ", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.07, output: 0.34, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemma-4-26b-a4b-it:free": { id: "google/gemma-4-26b-a4b-it:free", name: "Google: Gemma 4 26B A4B (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemma-4-31b-it": { id: "google/gemma-4-31b-it", name: "Google: Gemma 4 31B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.34, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemma-4-31b-it:free": { id: "google/gemma-4-31b-it:free", name: "Google: Gemma 4 31B (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "ibm-granite/granite-4.1-8b": { id: "ibm-granite/granite-4.1-8b", name: "IBM: Granite 4.1 8B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.05, output: 0.1, cacheRead: 0.05, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "inception/mercury-2": { id: "inception/mercury-2", name: "Inception: Mercury 2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.25, output: 0.75, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 5e4, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" }, thinkingLevelMap: { off: null } }, "inclusionai/ling-2.6-1t": { id: "inclusionai/ling-2.6-1t", name: "inclusionAI: Ling-2.6-1T", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.075, output: 0.625, cacheRead: 0.015, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "inclusionai/ling-2.6-flash": { id: "inclusionai/ling-2.6-flash", name: "inclusionAI: Ling-2.6-flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.01, output: 0.03, cacheRead: 2e-3, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "inclusionai/ling-3.0-flash": { id: "inclusionai/ling-3.0-flash", name: "Ling-3.0-flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.021, output: 0.063, cacheRead: 42e-4, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "inclusionai/ring-2.6-1t": { id: "inclusionai/ring-2.6-1t", name: "inclusionAI: Ring-2.6-1T", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.075, output: 0.625, cacheRead: 0.015, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "kwaipilot/kat-coder-air-v2.5": { id: "kwaipilot/kat-coder-air-v2.5", name: "Kwaipilot: KAT-Coder-Air V2.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.15, output: 0.6, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 8e4, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "kwaipilot/kat-coder-pro-v2": { id: "kwaipilot/kat-coder-pro-v2", name: "Kwaipilot: KAT-Coder-Pro V2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 8e4, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "kwaipilot/kat-coder-pro-v2.5": { id: "kwaipilot/kat-coder-pro-v2.5", name: "Kwaipilot: KAT-Coder-Pro V2.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.74, output: 2.96, cacheRead: 0.15, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 8e4, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "liquid/lfm-2.5-2.6b:free": { id: "liquid/lfm-2.5-2.6b:free", name: "LiquidAI: LFM2.5-2.6B (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 65536, maxTokens: 8192, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meituan/longcat-2.0": { id: "meituan/longcat-2.0", name: "Meituan: LongCat 2.0", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.3, output: 1.2, cacheRead: 6e-3, cacheWrite: 0 }, contextWindow: 1048756, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta-llama/llama-3.1-70b-instruct": { id: "meta-llama/llama-3.1-70b-instruct", name: "Meta: Llama 3.1 70B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.4, output: 0.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta-llama/llama-3.1-8b-instruct": { id: "meta-llama/llama-3.1-8b-instruct", name: "Meta: Llama 3.1 8B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.05, output: 0.08, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta-llama/llama-3.3-70b-instruct": { id: "meta-llama/llama-3.3-70b-instruct", name: "Meta: Llama 3.3 70B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.1, output: 0.32, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta-llama/llama-4-maverick": { id: "meta-llama/llama-4-maverick", name: "Meta: Llama 4 Maverick", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.2, output: 0.8, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta-llama/llama-4-scout": { id: "meta-llama/llama-4-scout", name: "Meta: Llama 4 Scout", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.1, output: 0.3, cacheRead: 0, cacheWrite: 0 }, contextWindow: 327680, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta/muse-glimmer-30b": { id: "meta/muse-glimmer-30b", name: "Meta: Muse Glimmer 30B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.35, output: 1.5, cacheRead: 0.04, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta/muse-spark-1.1": { id: "meta/muse-spark-1.1", name: "Meta: Muse Spark 1.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta/muse-spark-1.2": { id: "meta/muse-spark-1.2", name: "Meta: Muse Spark 1.2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta/muse-spark-1.2-contributor": { id: "meta/muse-spark-1.2-contributor", name: "Meta: Muse Spark 1.2 Contributor", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.2, cacheRead: 2e-3, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "minimax/minimax-m1": { id: "minimax/minimax-m1", name: "MiniMax: MiniMax M1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.55, output: 2.2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 4e4, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "minimax/minimax-m2": { id: "minimax/minimax-m2", name: "MiniMax: MiniMax M2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.255, output: 1.02, cacheRead: 0, cacheWrite: 0 }, contextWindow: 204800, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "minimax/minimax-m2.1": { id: "minimax/minimax-m2.1", name: "MiniMax: MiniMax M2.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.3, output: 1.2, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 204800, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "minimax/minimax-m2.5": { id: "minimax/minimax-m2.5", name: "MiniMax: MiniMax M2.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.27, output: 1.08, cacheRead: 0.027, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "minimax/minimax-m2.7": { id: "minimax/minimax-m2.7", name: "MiniMax: MiniMax M2.7", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, contextWindow: 204800, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "minimax/minimax-m3": { id: "minimax/minimax-m3", name: "MiniMax: MiniMax M3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, contextWindow: 524288, maxTokens: 512e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "minimax/minimax-m3:batch": { id: "minimax/minimax-m3:batch", name: "MiniMax: MiniMax M3 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, contextWindow: 524288, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/codestral-2508": { id: "mistralai/codestral-2508", name: "Mistral: Codestral 2508", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.3, output: 0.9, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/ministral-14b-2512": { id: "mistralai/ministral-14b-2512", name: "Mistral: Ministral 3 14B 2512", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.2, output: 0.2, cacheRead: 0.02, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/ministral-3b-2512": { id: "mistralai/ministral-3b-2512", name: "Mistral: Ministral 3 3B 2512", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.1, output: 0.1, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/ministral-8b-2512": { id: "mistralai/ministral-8b-2512", name: "Mistral: Ministral 3 8B 2512", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.15, output: 0.15, cacheRead: 0.015, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-large": { id: "mistralai/mistral-large", name: "Mistral Large", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-large-2407": { id: "mistralai/mistral-large-2407", name: "Mistral Large 2407", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-large-2512": { id: "mistralai/mistral-large-2512", name: "Mistral: Mistral Large 3 2512", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.5, output: 1.5, cacheRead: 0.05, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-medium-3": { id: "mistralai/mistral-medium-3", name: "Mistral: Mistral Medium 3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-medium-3-5": { id: "mistralai/mistral-medium-3-5", name: "Mistral: Mistral Medium 3.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.5, output: 7.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-medium-3.1": { id: "mistralai/mistral-medium-3.1", name: "Mistral: Mistral Medium 3.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-nemo": { id: "mistralai/mistral-nemo", name: "Mistral: Mistral Nemo", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.019, output: 0.03, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-saba": { id: "mistralai/mistral-saba", name: "Mistral: Saba", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.2, output: 0.6, cacheRead: 0.02, cacheWrite: 0 }, contextWindow: 32768, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-small-2603": { id: "mistralai/mistral-small-2603", name: "Mistral: Mistral Small 4", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.15, output: 0.6, cacheRead: 0.015, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-small-3.2-24b-instruct": { id: "mistralai/mistral-small-3.2-24b-instruct", name: "Mistral: Mistral Small 3.2 24B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.075, output: 0.2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mixtral-8x22b-instruct": { id: "mistralai/mixtral-8x22b-instruct", name: "Mistral: Mixtral 8x22B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 65536, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/voxtral-small-24b-2507": { id: "mistralai/voxtral-small-24b-2507", name: "Mistral: Voxtral Small 24B 2507", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.1, output: 0.3, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 32e3, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "moonshotai/kimi-k2": { id: "moonshotai/kimi-k2", name: "MoonshotAI: Kimi K2 0711", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.57, output: 2.3, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 100352, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "moonshotai/kimi-k2-0905": { id: "moonshotai/kimi-k2-0905", name: "MoonshotAI: Kimi K2 0905", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.6, output: 2.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 100352, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "moonshotai/kimi-k2-thinking": { id: "moonshotai/kimi-k2-thinking", name: "MoonshotAI: Kimi K2 Thinking", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.6, output: 2.5, cacheRead: 0.15, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 100352, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "moonshotai/kimi-k2.5": { id: "moonshotai/kimi-k2.5", name: "MoonshotAI: Kimi K2.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.41, output: 2.06, cacheRead: 0.07, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "moonshotai/kimi-k2.6": { id: "moonshotai/kimi-k2.6", name: "MoonshotAI: Kimi K2.6", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.5415, output: 2.28, cacheRead: 0.0912, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", requiresReasoningContentOnAssistantMessages: true } }, "moonshotai/kimi-k2.7-code": { id: "moonshotai/kimi-k2.7-code", name: "MoonshotAI: Kimi K2.7 Code", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.67, output: 3.4, cacheRead: 0.17, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "moonshotai/kimi-k2.7-code:batch": { id: "moonshotai/kimi-k2.7-code:batch", name: "MoonshotAI: Kimi K2.7 Code (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "moonshotai/kimi-k3": { id: "moonshotai/kimi-k3", name: "MoonshotAI: Kimi K3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nex-agi/nex-n2-mini": { id: "nex-agi/nex-n2-mini", name: "Nex AGI: Nex-N2-Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.025, output: 0.1, cacheRead: 25e-4, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nex-agi/nex-n2-pro": { id: "nex-agi/nex-n2-pro", name: "Nex AGI: Nex-N2-Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 1, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-nano-30b-a3b": { id: "nvidia/nemotron-3-nano-30b-a3b", name: "NVIDIA: Nemotron 3 Nano 30B A3B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.05, output: 0.2, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-nano-30b-a3b:free": { id: "nvidia/nemotron-3-nano-30b-a3b:free", name: "NVIDIA: Nemotron 3 Nano 30B A3B (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free": { id: "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free", name: "NVIDIA: Nemotron 3 Nano Omni (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-super-120b-a12b": { id: "nvidia/nemotron-3-super-120b-a12b", name: "NVIDIA: Nemotron 3 Super", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.085, output: 0.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-super-120b-a12b:free": { id: "nvidia/nemotron-3-super-120b-a12b:free", name: "NVIDIA: Nemotron 3 Super (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-ultra-550b-a55b": { id: "nvidia/nemotron-3-ultra-550b-a55b", name: "NVIDIA: Nemotron 3 Ultra", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.6, output: 3.6, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 512288, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-ultra-550b-a55b:batch": { id: "nvidia/nemotron-3-ultra-550b-a55b:batch", name: "NVIDIA: Nemotron 3 Ultra (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.6, output: 3.6, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 512288, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-ultra-550b-a55b:free": { id: "nvidia/nemotron-3-ultra-550b-a55b:free", name: "NVIDIA: Nemotron 3 Ultra (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3.5-lightning": { id: "nvidia/nemotron-3.5-lightning", name: "NVIDIA: Nemotron 3.5 Lightning", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.08, output: 0.2, cacheRead: 0.04, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3.5-lightning:free": { id: "nvidia/nemotron-3.5-lightning:free", name: "NVIDIA: Nemotron 3.5 Lightning (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-nano-12b-v2-vl:free": { id: "nvidia/nemotron-nano-12b-v2-vl:free", name: "NVIDIA: Nemotron Nano 12B 2 VL (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-nano-9b-v2:free": { id: "nvidia/nemotron-nano-9b-v2:free", name: "NVIDIA: Nemotron Nano 9B V2 (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "openai/gpt-3.5-turbo": { id: "openai/gpt-3.5-turbo", name: "OpenAI: GPT-3.5 Turbo", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.5, output: 1.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 16385, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-3.5-turbo-0613": { id: "openai/gpt-3.5-turbo-0613", name: "OpenAI: GPT-3.5 Turbo (older v0613)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 1, output: 2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 4095, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-3.5-turbo-16k": { id: "openai/gpt-3.5-turbo-16k", name: "OpenAI: GPT-3.5 Turbo 16k", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 3, output: 4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 16385, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-3.5-turbo:batch": { id: "openai/gpt-3.5-turbo:batch", name: "OpenAI: GPT-3.5 Turbo (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.25, output: 0.75, cacheRead: 0, cacheWrite: 0 }, contextWindow: 16385, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4": { id: "openai/gpt-4", name: "OpenAI: GPT-4", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 30, output: 60, cacheRead: 0, cacheWrite: 0 }, contextWindow: 8191, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4-turbo": { id: "openai/gpt-4-turbo", name: "OpenAI: GPT-4 Turbo", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 10, output: 30, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4-turbo-preview": { id: "openai/gpt-4-turbo-preview", name: "OpenAI: GPT-4 Turbo Preview", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 10, output: 30, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4-turbo:batch": { id: "openai/gpt-4-turbo:batch", name: "OpenAI: GPT-4 Turbo (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 5, output: 15, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4.1": { id: "openai/gpt-4.1", name: "OpenAI: GPT-4.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, contextWindow: 1047576, maxTokens: 32768, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4.1-mini": { id: "openai/gpt-4.1-mini", name: "OpenAI: GPT-4.1 Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.4, output: 1.6, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 1047576, maxTokens: 32768, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4.1-mini:batch": { id: "openai/gpt-4.1-mini:batch", name: "OpenAI: GPT-4.1 Mini (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.2, output: 0.8, cacheRead: 0.05, cacheWrite: 0 }, contextWindow: 1047576, maxTokens: 32768, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4.1-nano": { id: "openai/gpt-4.1-nano", name: "OpenAI: GPT-4.1 Nano", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.1, output: 0.4, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 1047576, maxTokens: 32768, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4.1-nano:batch": { id: "openai/gpt-4.1-nano:batch", name: "OpenAI: GPT-4.1 Nano (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.05, output: 0.2, cacheRead: 0.0125, cacheWrite: 0 }, contextWindow: 1047576, maxTokens: 32768, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4.1:batch": { id: "openai/gpt-4.1:batch", name: "OpenAI: GPT-4.1 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 1, output: 4, cacheRead: 0.25, cacheWrite: 0 }, contextWindow: 1047576, maxTokens: 32768, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o": { id: "openai/gpt-4o", name: "OpenAI: GPT-4o", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o-2024-05-13": { id: "openai/gpt-4o-2024-05-13", name: "OpenAI: GPT-4o (2024-05-13)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 5, output: 15, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o-2024-08-06": { id: "openai/gpt-4o-2024-08-06", name: "OpenAI: GPT-4o (2024-08-06)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o-2024-11-20": { id: "openai/gpt-4o-2024-11-20", name: "OpenAI: GPT-4o (2024-11-20)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o-mini": { id: "openai/gpt-4o-mini", name: "OpenAI: GPT-4o-mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.15, output: 0.6, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o-mini-2024-07-18": { id: "openai/gpt-4o-mini-2024-07-18", name: "OpenAI: GPT-4o-mini (2024-07-18)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.15, output: 0.6, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o-mini:batch": { id: "openai/gpt-4o-mini:batch", name: "OpenAI: GPT-4o-mini (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.075, output: 0.3, cacheRead: 0.0375, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o:batch": { id: "openai/gpt-4o:batch", name: "OpenAI: GPT-4o (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 1.25, output: 5, cacheRead: 0.625, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5": { id: "openai/gpt-5", name: "OpenAI: GPT-5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5-codex:batch": { id: "openai/gpt-5-codex:batch", name: "OpenAI: GPT-5 Codex (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.625, output: 5, cacheRead: 0.0625, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5-mini": { id: "openai/gpt-5-mini", name: "OpenAI: GPT-5 Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 2, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5-mini:batch": { id: "openai/gpt-5-mini:batch", name: "OpenAI: GPT-5 Mini (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.125, output: 1, cacheRead: 0.0125, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5-nano": { id: "openai/gpt-5-nano", name: "OpenAI: GPT-5 Nano", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.05, output: 0.4, cacheRead: 5e-3, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5-nano:batch": { id: "openai/gpt-5-nano:batch", name: "OpenAI: GPT-5 Nano (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.025, output: 0.2, cacheRead: 25e-4, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5-pro": { id: "openai/gpt-5-pro", name: "OpenAI: GPT-5 Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 15, output: 120, cacheRead: 0, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5-pro:batch": { id: "openai/gpt-5-pro:batch", name: "OpenAI: GPT-5 Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 7.5, output: 60, cacheRead: 0, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5.1": { id: "openai/gpt-5.1", name: "OpenAI: GPT-5.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5.1-codex": { id: "openai/gpt-5.1-codex", name: "OpenAI: GPT-5.1-Codex", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.13, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5.1-codex-max": { id: "openai/gpt-5.1-codex-max", name: "OpenAI: GPT-5.1-Codex-Max", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5.1-codex-mini": { id: "openai/gpt-5.1-codex-mini", name: "OpenAI: GPT-5.1-Codex-Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 2, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5.1:batch": { id: "openai/gpt-5.1:batch", name: "OpenAI: GPT-5.1 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.625, output: 5, cacheRead: 0.0625, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5.2": { id: "openai/gpt-5.2", name: "OpenAI: GPT-5.2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.2-chat": { id: "openai/gpt-5.2-chat", name: "OpenAI: GPT-5.2 Chat", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 32e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.2-codex": { id: "openai/gpt-5.2-codex", name: "OpenAI: GPT-5.2-Codex", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.2-pro": { id: "openai/gpt-5.2-pro", name: "OpenAI: GPT-5.2 Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 21, output: 168, cacheRead: 0, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.2-pro:batch": { id: "openai/gpt-5.2-pro:batch", name: "OpenAI: GPT-5.2 Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 10.5, output: 84, cacheRead: 0, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.2:batch": { id: "openai/gpt-5.2:batch", name: "OpenAI: GPT-5.2 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.875, output: 7, cacheRead: 0.0875, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.3-codex": { id: "openai/gpt-5.3-codex", name: "OpenAI: GPT-5.3-Codex", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4": { id: "openai/gpt-5.4", name: "OpenAI: GPT-5.4", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4-mini": { id: "openai/gpt-5.4-mini", name: "OpenAI: GPT-5.4 Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4-mini:batch": { id: "openai/gpt-5.4-mini:batch", name: "OpenAI: GPT-5.4 Mini (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.375, output: 2.25, cacheRead: 0.0375, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4-nano": { id: "openai/gpt-5.4-nano", name: "OpenAI: GPT-5.4 Nano", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.2, output: 1.25, cacheRead: 0.02, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4-nano:batch": { id: "openai/gpt-5.4-nano:batch", name: "OpenAI: GPT-5.4 Nano (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.625, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4-pro": { id: "openai/gpt-5.4-pro", name: "OpenAI: GPT-5.4 Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4-pro:batch": { id: "openai/gpt-5.4-pro:batch", name: "OpenAI: GPT-5.4 Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 15, output: 90, cacheRead: 0, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4:batch": { id: "openai/gpt-5.4:batch", name: "OpenAI: GPT-5.4 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 7.5, cacheRead: 0.125, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.5": { id: "openai/gpt-5.5", name: "OpenAI: GPT-5.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.5-pro": { id: "openai/gpt-5.5-pro", name: "OpenAI: GPT-5.5 Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", off: null, minimal: null, low: null } }, "openai/gpt-5.5-pro:batch": { id: "openai/gpt-5.5-pro:batch", name: "OpenAI: GPT-5.5 Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 15, output: 90, cacheRead: 0, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.5:batch": { id: "openai/gpt-5.5:batch", name: "OpenAI: GPT-5.5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.6-luna": { id: "openai/gpt-5.6-luna", name: "OpenAI: GPT-5.6 Luna", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-luna-pro": { id: "openai/gpt-5.6-luna-pro", name: "OpenAI: GPT-5.6 Luna Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-luna-pro:batch": { id: "openai/gpt-5.6-luna-pro:batch", name: "OpenAI: GPT-5.6 Luna Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.6, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-luna:batch": { id: "openai/gpt-5.6-luna:batch", name: "OpenAI: GPT-5.6 Luna (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.6, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-sol": { id: "openai/gpt-5.6-sol", name: "OpenAI: GPT-5.6 Sol", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-sol-pro": { id: "openai/gpt-5.6-sol-pro", name: "OpenAI: GPT-5.6 Sol Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-sol-pro:batch": { id: "openai/gpt-5.6-sol-pro:batch", name: "OpenAI: GPT-5.6 Sol Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-sol:batch": { id: "openai/gpt-5.6-sol:batch", name: "OpenAI: GPT-5.6 Sol (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-terra": { id: "openai/gpt-5.6-terra", name: "OpenAI: GPT-5.6 Terra", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-terra-pro": { id: "openai/gpt-5.6-terra-pro", name: "OpenAI: GPT-5.6 Terra Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-terra-pro:batch": { id: "openai/gpt-5.6-terra-pro:batch", name: "OpenAI: GPT-5.6 Terra Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 6, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-terra:batch": { id: "openai/gpt-5.6-terra:batch", name: "OpenAI: GPT-5.6 Terra (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 6, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5:batch": { id: "openai/gpt-5:batch", name: "OpenAI: GPT-5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.625, output: 5, cacheRead: 0.0625, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-audio": { id: "openai/gpt-audio", name: "OpenAI: GPT Audio", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 2.5, output: 10, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-audio-mini": { id: "openai/gpt-audio-mini", name: "OpenAI: GPT Audio Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.6, output: 2.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-chat-latest": { id: "openai/gpt-chat-latest", name: "OpenAI: GPT Chat Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-oss-120b": { id: "openai/gpt-oss-120b", name: "OpenAI: gpt-oss-120b", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.037, output: 0.17, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 131072, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-oss-20b": { id: "openai/gpt-oss-20b", name: "OpenAI: gpt-oss-20b", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.03, output: 0.13, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 131072, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-oss-safeguard-20b": { id: "openai/gpt-oss-safeguard-20b", name: "OpenAI: gpt-oss-safeguard-20b", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.075, output: 0.3, cacheRead: 0.0375, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 65536, compat: { thinkingFormat: "openrouter" } }, "openai/o1": { id: "openai/o1", name: "OpenAI: o1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 15, output: 60, cacheRead: 7.5, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o1:batch": { id: "openai/o1:batch", name: "OpenAI: o1 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 7.5, output: 30, cacheRead: 3.75, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3": { id: "openai/o3", name: "OpenAI: o3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3-mini": { id: "openai/o3-mini", name: "OpenAI: o3 Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.1, output: 4.4, cacheRead: 0.55, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3-mini-high": { id: "openai/o3-mini-high", name: "OpenAI: o3 Mini High", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.1, output: 4.4, cacheRead: 0.55, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3-mini-high:batch": { id: "openai/o3-mini-high:batch", name: "OpenAI: o3 Mini High (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.55, output: 2.2, cacheRead: 0.275, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3-mini:batch": { id: "openai/o3-mini:batch", name: "OpenAI: o3 Mini (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.55, output: 2.2, cacheRead: 0.275, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3-pro": { id: "openai/o3-pro", name: "OpenAI: o3 Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 20, output: 80, cacheRead: 0, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3-pro:batch": { id: "openai/o3-pro:batch", name: "OpenAI: o3 Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 10, output: 40, cacheRead: 0, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3:batch": { id: "openai/o3:batch", name: "OpenAI: o3 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 4, cacheRead: 0.25, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o4-mini": { id: "openai/o4-mini", name: "OpenAI: o4 Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.1, output: 4.4, cacheRead: 0.275, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o4-mini-high": { id: "openai/o4-mini-high", name: "OpenAI: o4 Mini High", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.1, output: 4.4, cacheRead: 0.275, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o4-mini-high:batch": { id: "openai/o4-mini-high:batch", name: "OpenAI: o4 Mini High (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.55, output: 2.2, cacheRead: 0.1375, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o4-mini:batch": { id: "openai/o4-mini:batch", name: "OpenAI: o4 Mini (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.55, output: 2.2, cacheRead: 0.1375, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openrouter/auto": { id: "openrouter/auto", name: "Auto Router", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: -1e6, output: -1e6, cacheRead: 0, cacheWrite: 0 }, contextWindow: 2e6, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "openrouter/auto-beta": { id: "openrouter/auto-beta", name: "Auto Router (Beta)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: -1e6, output: -1e6, cacheRead: 0, cacheWrite: 0 }, contextWindow: 2e6, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "openrouter/free": { id: "openrouter/free", name: "Free Models Router", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "openrouter/fusion": { id: "openrouter/fusion", name: "OpenRouter: Fusion", api: "openai-completions", provider: "openrouter", baseUrl: "https://openrouter.ai/api/v1", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 3e4, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "poolside/laguna-s-2.1": { id: "poolside/laguna-s-2.1", name: "Poolside: Laguna S 2.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.09, output: 0.18, cacheRead: 9e-3, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "poolside/laguna-s-2.1:free": { id: "poolside/laguna-s-2.1:free", name: "Poolside: Laguna S 2.1 (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "poolside/laguna-xs-2.1": { id: "poolside/laguna-xs-2.1", name: "Poolside: Laguna XS 2.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.06, output: 0.12, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "poolside/laguna-xs-2.1:free": { id: "poolside/laguna-xs-2.1:free", name: "Poolside: Laguna XS 2.1 (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen-2.5-72b-instruct": { id: "qwen/qwen-2.5-72b-instruct", name: "Qwen2.5 72B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.36, output: 0.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 32768, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen-2.5-7b-instruct": { id: "qwen/qwen-2.5-7b-instruct", name: "Qwen: Qwen2.5 7B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.1, output: 0.2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 32768, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen-plus": { id: "qwen/qwen-plus", name: "Qwen: Qwen-Plus", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.26, output: 0.78, cacheRead: 0.052, cacheWrite: 0.325 }, contextWindow: 1e6, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen-plus-2025-07-28": { id: "qwen/qwen-plus-2025-07-28", name: "Qwen: Qwen Plus 0728", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.26, output: 0.78, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen-plus-2025-07-28:thinking": { id: "qwen/qwen-plus-2025-07-28:thinking", name: "Qwen: Qwen Plus 0728 (thinking)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.26, output: 0.78, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-14b": { id: "qwen/qwen3-14b", name: "Qwen: Qwen3 14B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.12, output: 0.24, cacheRead: 0, cacheWrite: 0 }, contextWindow: 40960, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-235b-a22b": { id: "qwen/qwen3-235b-a22b", name: "Qwen: Qwen3 235B A22B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.455, output: 1.82, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 8192, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-235b-a22b-2507": { id: "qwen/qwen3-235b-a22b-2507", name: "Qwen: Qwen3 235B A22B Instruct 2507", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.09, output: 0.55, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-235b-a22b-thinking-2507": { id: "qwen/qwen3-235b-a22b-thinking-2507", name: "Qwen: Qwen3 235B A22B Thinking 2507", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.23, output: 2.3, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-30b-a3b": { id: "qwen/qwen3-30b-a3b", name: "Qwen: Qwen3 30B A3B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.13, output: 0.52, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 8192, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-30b-a3b-instruct-2507": { id: "qwen/qwen3-30b-a3b-instruct-2507", name: "Qwen: Qwen3 30B A3B Instruct 2507", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.04815, output: 0.19305, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 32e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-30b-a3b-thinking-2507": { id: "qwen/qwen3-30b-a3b-thinking-2507", name: "Qwen: Qwen3 30B A3B Thinking 2507", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.2, output: 2.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 81920, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-32b": { id: "qwen/qwen3-32b", name: "Qwen: Qwen3 32B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.08, output: 0.28, cacheRead: 0, cacheWrite: 0 }, contextWindow: 40960, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-8b": { id: "qwen/qwen3-8b", name: "Qwen: Qwen3 8B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.117, output: 0.455, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 8192, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-coder": { id: "qwen/qwen3-coder", name: "Qwen: Qwen3 Coder 480B A35B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.3, output: 1, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-coder-30b-a3b-instruct": { id: "qwen/qwen3-coder-30b-a3b-instruct", name: "Qwen: Qwen3 Coder 30B A3B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.07, output: 0.28, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-coder-flash": { id: "qwen/qwen3-coder-flash", name: "Qwen: Qwen3 Coder Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.195, output: 0.975, cacheRead: 0.039, cacheWrite: 0.24375 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-coder-next": { id: "qwen/qwen3-coder-next", name: "Qwen: Qwen3 Coder Next", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.12, output: 0.8, cacheRead: 0.07, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-coder-plus": { id: "qwen/qwen3-coder-plus", name: "Qwen: Qwen3 Coder Plus", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.65, output: 3.25, cacheRead: 0.13, cacheWrite: 0.8125 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-max": { id: "qwen/qwen3-max", name: "Qwen: Qwen3 Max", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.78, output: 3.9, cacheRead: 0.156, cacheWrite: 0.975 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-max-thinking": { id: "qwen/qwen3-max-thinking", name: "Qwen: Qwen3 Max Thinking", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.78, output: 3.9, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-next-80b-a3b-instruct": { id: "qwen/qwen3-next-80b-a3b-instruct", name: "Qwen: Qwen3 Next 80B A3B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.1, output: 1.1, cacheRead: 0.07, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-next-80b-a3b-thinking": { id: "qwen/qwen3-next-80b-a3b-thinking", name: "Qwen: Qwen3 Next 80B A3B Thinking", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.15, output: 1.2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-vl-235b-a22b-instruct": { id: "qwen/qwen3-vl-235b-a22b-instruct", name: "Qwen: Qwen3 VL 235B A22B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.21, output: 1.9, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-vl-235b-a22b-thinking": { id: "qwen/qwen3-vl-235b-a22b-thinking", name: "Qwen: Qwen3 VL 235B A22B Thinking", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.4, output: 4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-vl-30b-a3b-instruct": { id: "qwen/qwen3-vl-30b-a3b-instruct", name: "Qwen: Qwen3 VL 30B A3B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.13, output: 0.52, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-vl-30b-a3b-thinking": { id: "qwen/qwen3-vl-30b-a3b-thinking", name: "Qwen: Qwen3 VL 30B A3B Thinking", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.2, output: 2.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-vl-32b-instruct": { id: "qwen/qwen3-vl-32b-instruct", name: "Qwen: Qwen3 VL 32B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.104, output: 0.416, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-vl-8b-instruct": { id: "qwen/qwen3-vl-8b-instruct", name: "Qwen: Qwen3 VL 8B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.117, output: 0.455, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-vl-8b-thinking": { id: "qwen/qwen3-vl-8b-thinking", name: "Qwen: Qwen3 VL 8B Thinking", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.18, output: 2.1, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-122b-a10b": { id: "qwen/qwen3.5-122b-a10b", name: "Qwen: Qwen3.5-122B-A10B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.26, output: 2.08, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-27b": { id: "qwen/qwen3.5-27b", name: "Qwen: Qwen3.5-27B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.195, output: 1.56, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-35b-a3b": { id: "qwen/qwen3.5-35b-a3b", name: "Qwen: Qwen3.5-35B-A3B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 1.25, cacheRead: 0.25, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-397b-a17b": { id: "qwen/qwen3.5-397b-a17b", name: "Qwen: Qwen3.5 397B A17B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.39, output: 2.34, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-9b": { id: "qwen/qwen3.5-9b", name: "Qwen: Qwen3.5-9B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.15, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-flash-02-23": { id: "qwen/qwen3.5-flash-02-23", name: "Qwen: Qwen3.5-Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.065, output: 0.26, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-plus-02-15": { id: "qwen/qwen3.5-plus-02-15", name: "Qwen: Qwen3.5 Plus 2026-02-15", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.26, output: 1.56, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-plus-20260420": { id: "qwen/qwen3.5-plus-20260420", name: "Qwen: Qwen3.5 Plus 2026-04-20", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 1.8, cacheRead: 0, cacheWrite: 0.375 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.6-27b": { id: "qwen/qwen3.6-27b", name: "Qwen: Qwen3.6 27B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.6, output: 3.6, cacheRead: 0.12, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.6-35b-a3b": { id: "qwen/qwen3.6-35b-a3b", name: "Qwen: Qwen3.6 35B A3B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.14, output: 1, cacheRead: 0.05, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.6-flash": { id: "qwen/qwen3.6-flash", name: "Qwen: Qwen3.6 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1875, output: 1.125, cacheRead: 0, cacheWrite: 0.234375 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.6-max-preview": { id: "qwen/qwen3.6-max-preview", name: "Qwen: Qwen3.6 Max Preview", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.027, output: 6.162, cacheRead: 0, cacheWrite: 1.28375 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.6-plus": { id: "qwen/qwen3.6-plus", name: "Qwen: Qwen3.6 Plus", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.325, output: 1.95, cacheRead: 0, cacheWrite: 0.40625 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.7-flash": { id: "qwen/qwen3.7-flash", name: "Qwen: Qwen3.7 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.03, output: 0.13, cacheRead: 6e-3, cacheWrite: 0.038 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.7-max": { id: "qwen/qwen3.7-max", name: "Qwen: Qwen3.7 Max", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.475, output: 4.425, cacheRead: 0.295, cacheWrite: 1.84375 }, contextWindow: 1e6, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.7-plus": { id: "qwen/qwen3.7-plus", name: "Qwen: Qwen3.7 Plus", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.32, output: 1.28, cacheRead: 0.064, cacheWrite: 0.4 }, contextWindow: 1e6, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.8-2.4t-a95b": { id: "qwen/qwen3.8-2.4t-a95b", name: "Qwen: Qwen3.8 2.4T A95B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.8-27b": { id: "qwen/qwen3.8-27b", name: "Qwen: Qwen3.8 27B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.4, output: 3, cacheRead: 0.05, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.8-max": { id: "qwen/qwen3.8-max", name: "Qwen: Qwen3.8 Max", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 2.5 }, contextWindow: 1e6, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "rekaai/reka-edge": { id: "rekaai/reka-edge", name: "Reka Edge", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.1, output: 0.1, cacheRead: 0, cacheWrite: 0 }, contextWindow: 16384, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "relace/relace-search": { id: "relace/relace-search", name: "Relace: Relace Search", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 1, output: 3, cacheRead: 0, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "sakana/fugu-ultra": { id: "sakana/fugu-ultra", name: "Sakana: Fugu Ultra", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "sakana/sakana-namazu": { id: "sakana/sakana-namazu", name: "Sakana: Sakana Namazu", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.95, output: 4, cacheRead: 0.15, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "sao10k/l3.1-euryale-70b": { id: "sao10k/l3.1-euryale-70b", name: "Sao10K: Llama 3.1 Euryale 70B v2.2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.85, output: 0.85, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "stealth/ox-alpha": { id: "stealth/ox-alpha", name: "Ox Alpha", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "stepfun/step-3.5-flash": { id: "stepfun/step-3.5-flash", name: "StepFun: Step 3.5 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.1, output: 0.3, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "stepfun/step-3.7-flash": { id: "stepfun/step-3.7-flash", name: "StepFun: Step 3.7 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.2, output: 1.15, cacheRead: 0.04, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 256e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "tencent/hy3": { id: "tencent/hy3", name: "Tencent: Hy3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.132, output: 0.528, cacheRead: 0.033, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "tencent/hy3-preview": { id: "tencent/hy3-preview", name: "Tencent: Hy3 preview", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.18, output: 0.6, cacheRead: 0.06, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "thedrummer/unslopnemo-12b": { id: "thedrummer/unslopnemo-12b", name: "TheDrummer: UnslopNemo 12B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.4, output: 0.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1024e3, maxTokens: 1024e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "thinkingmachines/inkling": { id: "thinkingmachines/inkling", name: "Thinking Machines: Inkling", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.95, output: 4.05, cacheRead: 0.16, cacheWrite: 0 }, contextWindow: 524288, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "thinkingmachines/inkling-small": { id: "thinkingmachines/inkling-small", name: "Thinking Machines: Inkling Small", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.45, output: 1.2, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 524288, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "thinkingmachines/inkling-small:free": { id: "thinkingmachines/inkling-small:free", name: "Thinking Machines: Inkling Small (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "thinkingmachines/inkling:batch": { id: "thinkingmachines/inkling:batch", name: "Thinking Machines: Inkling (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 4.05, cacheRead: 0.17, cacheWrite: 0 }, contextWindow: 524288, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "thinkingmachines/inkling:free": { id: "thinkingmachines/inkling:free", name: "Thinking Machines: Inkling (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "upstage/solar-pro-3": { id: "upstage/solar-pro-3", name: "Upstage: Solar Pro 3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.15, output: 0.6, cacheRead: 0.015, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "upstage/solar-pro4": { id: "upstage/solar-pro4", name: "Upstage: Solar Pro 4", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.03, output: 0.12, cacheRead: 6e-3, cacheWrite: 0 }, contextWindow: 524288, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "x-ai/grok-4.20": { id: "x-ai/grok-4.20", name: "SpaceXAI: Grok 4.20", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 2e6, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "x-ai/grok-4.3": { id: "x-ai/grok-4.3", name: "SpaceXAI: Grok 4.3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "x-ai/grok-4.5": { id: "x-ai/grok-4.5", name: "SpaceXAI: Grok 4.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.3, cacheWrite: 0 }, contextWindow: 5e5, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "x-ai/grok-4.6": { id: "x-ai/grok-4.6", name: "SpaceXAI: Grok 4.6", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, contextWindow: 5e5, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "x-ai/grok-build-0.1": { id: "x-ai/grok-build-0.1", name: "SpaceXAI: Grok Build 0.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 2, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "xiaomi/mimo-v2.5": { id: "xiaomi/mimo-v2.5", name: "Xiaomi: MiMo-V2.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.14, output: 0.28, cacheRead: 28e-4, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "xiaomi/mimo-v2.5-pro": { id: "xiaomi/mimo-v2.5-pro", name: "Xiaomi: MiMo-V2.5-Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.435, output: 0.87, cacheRead: 36e-4, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-4.5": { id: "z-ai/glm-4.5", name: "Z.ai: GLM 4.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.6, output: 2.2, cacheRead: 0.11, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 98304, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-4.5-air": { id: "z-ai/glm-4.5-air", name: "Z.ai: GLM 4.5 Air", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.13, output: 0.85, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 98304, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-4.5v": { id: "z-ai/glm-4.5v", name: "Z.ai: GLM 4.5V", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.6, output: 1.8, cacheRead: 0.11, cacheWrite: 0 }, contextWindow: 65536, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-4.6": { id: "z-ai/glm-4.6", name: "Z.ai: GLM 4.6", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.5, output: 2, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 202752, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-4.6v": { id: "z-ai/glm-4.6v", name: "Z.ai: GLM 4.6V", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 0.9, cacheRead: 0.055, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-4.7": { id: "z-ai/glm-4.7", name: "Z.ai: GLM 4.7", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.4, output: 1.75, cacheRead: 0.08, cacheWrite: 0 }, contextWindow: 202752, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-4.7-flash": { id: "z-ai/glm-4.7-flash", name: "Z.ai: GLM 4.7 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.06, output: 0.4, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 202752, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-5": { id: "z-ai/glm-5", name: "Z.ai: GLM 5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.6, output: 1.9, cacheRead: 0.119, cacheWrite: 0 }, contextWindow: 198e3, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-5-turbo": { id: "z-ai/glm-5-turbo", name: "Z.ai: GLM 5 Turbo", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.2, output: 4, cacheRead: 0.24, cacheWrite: 0 }, contextWindow: 202752, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-5.1": { id: "z-ai/glm-5.1", name: "Z.ai: GLM 5.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.966, output: 3.036, cacheRead: 0.1794, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-5.2": { id: "z-ai/glm-5.2", name: "Z.ai: GLM 5.2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.966, output: 3.036, cacheRead: 0.1932, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "z-ai/glm-5.2:batch": { id: "z-ai/glm-5.2:batch", name: "Z.ai: GLM 5.2 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, contextWindow: 1048575, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-5.2:free": { id: "z-ai/glm-5.2:free", name: "Z.ai: GLM 5.2 (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 256e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-5.3": { id: "z-ai/glm-5.3", name: "Z.ai: GLM 5.3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-5v-turbo": { id: "z-ai/glm-5v-turbo", name: "Z.ai: GLM 5V Turbo", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.2, output: 4, cacheRead: 0.24, cacheWrite: 0 }, contextWindow: 202752, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "~anthropic/claude-fable-latest": { id: "~anthropic/claude-fable-latest", name: "Anthropic: Claude Fable Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, contextWindow: 1e6, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "~anthropic/claude-haiku-latest": { id: "~anthropic/claude-haiku-latest", name: "Anthropic Claude Haiku Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, contextWindow: 2e5, maxTokens: 64e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "~anthropic/claude-opus-latest": { id: "~anthropic/claude-opus-latest", name: "Anthropic: Claude Opus Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, contextWindow: 1e6, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "~anthropic/claude-sonnet-latest": { id: "~anthropic/claude-sonnet-latest", name: "Anthropic Claude Sonnet Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, contextWindow: 1e6, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "~deepseek/deepseek-v4-flash-latest": { id: "~deepseek/deepseek-v4-flash-latest", name: "DeepSeek V4 Flash Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.0639, output: 0.1278, cacheRead: 0.01278, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", requiresReasoningContentOnAssistantMessages: true }, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: null, xhigh: "xhigh" } }, "~google/gemini-flash-latest": { id: "~google/gemini-flash-latest", name: "Google Gemini Flash Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.375, output: 1.875, cacheRead: 0.0375, cacheWrite: 0.020833 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "~google/gemini-pro-latest": { id: "~google/gemini-pro-latest", name: "Google Gemini Pro Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "~moonshotai/kimi-latest": { id: "~moonshotai/kimi-latest", name: "MoonshotAI Kimi Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.6, output: 13, cacheRead: 0.29, cacheWrite: 0 }, contextWindow: 974842, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "~openai/gpt-latest": { id: "~openai/gpt-latest", name: "OpenAI GPT Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, contextWindow: 105e4, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "~openai/gpt-mini-latest": { id: "~openai/gpt-mini-latest", name: "OpenAI GPT Mini Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "~x-ai/grok-latest": { id: "~x-ai/grok-latest", name: "xAI: Grok Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, contextWindow: 5e5, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "~z-ai/glm-latest": { id: "~z-ai/glm-latest", name: "Z.ai: GLM Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } } } };
|
|
14242
|
+
var openrouter_default = { "openai-completions": { "aion-labs/aion-2.0": { id: "aion-labs/aion-2.0", name: "AionLabs: Aion-2.0", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.8, output: 1.6, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "aion-labs/aion-3.0": { id: "aion-labs/aion-3.0", name: "AionLabs: Aion-3.0", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 3, output: 6, cacheRead: 0.75, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "aion-labs/aion-3.0-mini": { id: "aion-labs/aion-3.0-mini", name: "AionLabs: Aion-3.0-Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.7, output: 1.4, cacheRead: 0.18, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "amazon/nova-2-lite-v1": { id: "amazon/nova-2-lite-v1", name: "Amazon: Nova 2 Lite", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 2.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 65535, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "amazon/nova-lite-v1": { id: "amazon/nova-lite-v1", name: "Amazon: Nova Lite 1.0", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.06, output: 0.24, cacheRead: 0, cacheWrite: 0 }, contextWindow: 3e5, maxTokens: 5120, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "amazon/nova-micro-v1": { id: "amazon/nova-micro-v1", name: "Amazon: Nova Micro 1.0", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.035, output: 0.14, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 5120, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "amazon/nova-premier-v1": { id: "amazon/nova-premier-v1", name: "Amazon: Nova Premier 1.0", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 2.5, output: 12.5, cacheRead: 0.625, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 32e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "amazon/nova-pro-v1": { id: "amazon/nova-pro-v1", name: "Amazon: Nova Pro 1.0", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.8, output: 3.2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 3e5, maxTokens: 5120, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "anthropic/claude-3-haiku": { id: "anthropic/claude-3-haiku", name: "Anthropic: Claude 3 Haiku", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.25, output: 1.25, cacheRead: 0.03, cacheWrite: 0.3 }, contextWindow: 2e5, maxTokens: 4096, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-fable-5": { id: "anthropic/claude-fable-5", name: "Anthropic: Claude Fable 5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { off: null, xhigh: "xhigh", max: "max" } }, "anthropic/claude-fable-5:batch": { id: "anthropic/claude-fable-5:batch", name: "Anthropic: Claude Fable 5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { off: null, xhigh: "xhigh", max: "max" } }, "anthropic/claude-haiku-4.5": { id: "anthropic/claude-haiku-4.5", name: "Anthropic: Claude Haiku 4.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, contextWindow: 2e5, maxTokens: 64e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-haiku-4.5:batch": { id: "anthropic/claude-haiku-4.5:batch", name: "Anthropic: Claude Haiku 4.5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.5, output: 2.5, cacheRead: 0.05, cacheWrite: 0.625 }, contextWindow: 2e5, maxTokens: 64e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-opus-4": { id: "anthropic/claude-opus-4", name: "Anthropic: Claude Opus 4", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 }, contextWindow: 2e5, maxTokens: 32e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-opus-4.1": { id: "anthropic/claude-opus-4.1", name: "Anthropic: Claude Opus 4.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 }, contextWindow: 2e5, maxTokens: 32e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-opus-4.1:batch": { id: "anthropic/claude-opus-4.1:batch", name: "Anthropic: Claude Opus 4.1 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 7.5, output: 37.5, cacheRead: 0.75, cacheWrite: 9.375 }, contextWindow: 2e5, maxTokens: 32e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-opus-4.5": { id: "anthropic/claude-opus-4.5", name: "Anthropic: Claude Opus 4.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, contextWindow: 2e5, maxTokens: 64e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-opus-4.5:batch": { id: "anthropic/claude-opus-4.5:batch", name: "Anthropic: Claude Opus 4.5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, contextWindow: 2e5, maxTokens: 64e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-opus-4.6": { id: "anthropic/claude-opus-4.6", name: "Anthropic: Claude Opus 4.6", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { max: "max" } }, "anthropic/claude-opus-4.6:batch": { id: "anthropic/claude-opus-4.6:batch", name: "Anthropic: Claude Opus 4.6 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { max: "max" } }, "anthropic/claude-opus-4.7": { id: "anthropic/claude-opus-4.7", name: "Anthropic: Claude Opus 4.7", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-4.7-fast": { id: "anthropic/claude-opus-4.7-fast", name: "Anthropic: Claude Opus 4.7 (Fast)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 30, output: 150, cacheRead: 3, cacheWrite: 37.5 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-4.7:batch": { id: "anthropic/claude-opus-4.7:batch", name: "Anthropic: Claude Opus 4.7 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-4.8": { id: "anthropic/claude-opus-4.8", name: "Anthropic: Claude Opus 4.8", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-4.8-fast": { id: "anthropic/claude-opus-4.8-fast", name: "Anthropic: Claude Opus 4.8 (Fast)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-4.8:batch": { id: "anthropic/claude-opus-4.8:batch", name: "Anthropic: Claude Opus 4.8 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-5": { id: "anthropic/claude-opus-5", name: "Claude Opus 5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-5-fast": { id: "anthropic/claude-opus-5-fast", name: "Claude Opus 5 (Fast)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-opus-5:batch": { id: "anthropic/claude-opus-5:batch", name: "Claude Opus 5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-sonnet-4": { id: "anthropic/claude-sonnet-4", name: "Anthropic: Claude Sonnet 4", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, contextWindow: 2e5, maxTokens: 64e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-sonnet-4.5": { id: "anthropic/claude-sonnet-4.5", name: "Anthropic: Claude Sonnet 4.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, contextWindow: 1e6, maxTokens: 64e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-sonnet-4.5:batch": { id: "anthropic/claude-sonnet-4.5:batch", name: "Anthropic: Claude Sonnet 4.5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 1.875 }, contextWindow: 1e6, maxTokens: 64e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "anthropic/claude-sonnet-4.6": { id: "anthropic/claude-sonnet-4.6", name: "Anthropic: Claude Sonnet 4.6", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { max: "max" } }, "anthropic/claude-sonnet-4.6:batch": { id: "anthropic/claude-sonnet-4.6:batch", name: "Anthropic: Claude Sonnet 4.6 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 1.875 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { max: "max" } }, "anthropic/claude-sonnet-5": { id: "anthropic/claude-sonnet-5", name: "Anthropic: Claude Sonnet 5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "anthropic/claude-sonnet-5:batch": { id: "anthropic/claude-sonnet-5:batch", name: "Anthropic: Claude Sonnet 5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, contextWindow: 1e6, maxTokens: 128e3, compat: { thinkingFormat: "openrouter", cacheControlFormat: "anthropic" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "arcee-ai/trinity-large-thinking": { id: "arcee-ai/trinity-large-thinking", name: "Arcee AI: Trinity Large Thinking", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.22, output: 0.85, cacheRead: 0.06, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "arcee-ai/virtuoso-large": { id: "arcee-ai/virtuoso-large", name: "Arcee AI: Virtuoso Large", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.75, output: 1.2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 64e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, auto: { id: "auto", name: "Auto", api: "openai-completions", provider: "openrouter", baseUrl: "https://openrouter.ai/api/v1", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 2e6, maxTokens: 3e4, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "bytedance-seed/seed-1.6": { id: "bytedance-seed/seed-1.6", name: "ByteDance Seed: Seed 1.6", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "bytedance-seed/seed-1.6-flash": { id: "bytedance-seed/seed-1.6-flash", name: "ByteDance Seed: Seed 1.6 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.075, output: 0.3, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "bytedance-seed/seed-2-1-turbo": { id: "bytedance-seed/seed-2-1-turbo", name: "ByteDance Seed: Seed 2.1 Turbo", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.5, output: 2.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "bytedance-seed/seed-2.0-code": { id: "bytedance-seed/seed-2.0-code", name: "ByteDance Seed: Seed-2.0-Code", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.5, output: 3, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "bytedance-seed/seed-2.0-lite": { id: "bytedance-seed/seed-2.0-lite", name: "ByteDance Seed: Seed-2.0-Lite", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "bytedance-seed/seed-2.0-mini": { id: "bytedance-seed/seed-2.0-mini", name: "ByteDance Seed: Seed-2.0-Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "cohere/command-r-08-2024": { id: "cohere/command-r-08-2024", name: "Cohere: Command R (08-2024)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "cohere/command-r-plus-08-2024": { id: "cohere/command-r-plus-08-2024", name: "Cohere: Command R+ (08-2024)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 2.5, output: 10, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "cohere/north-mini-code:free": { id: "cohere/north-mini-code:free", name: "Cohere: North Mini Code (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 64e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-chat": { id: "deepseek/deepseek-chat", name: "DeepSeek: DeepSeek V3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.2574, output: 1.0287, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-chat-v3-0324": { id: "deepseek/deepseek-chat-v3-0324", name: "DeepSeek: DeepSeek V3 0324", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.25, output: 1, cacheRead: 0, cacheWrite: 0 }, contextWindow: 163840, maxTokens: 163840, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-chat-v3.1": { id: "deepseek/deepseek-chat-v3.1", name: "DeepSeek: DeepSeek V3.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.55, output: 1.65, cacheRead: 0.55, cacheWrite: 0 }, contextWindow: 161e3, maxTokens: 161e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-r1": { id: "deepseek/deepseek-r1", name: "DeepSeek: R1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.7, output: 2.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 64e3, maxTokens: 16e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-r1-0528": { id: "deepseek/deepseek-r1-0528", name: "DeepSeek: R1 0528", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.5, output: 2.15, cacheRead: 0.35, cacheWrite: 0 }, contextWindow: 163840, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-v3.1-terminus": { id: "deepseek/deepseek-v3.1-terminus", name: "DeepSeek: DeepSeek V3.1 Terminus", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.27, output: 1, cacheRead: 0.135, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-v3.2": { id: "deepseek/deepseek-v3.2", name: "DeepSeek: DeepSeek V3.2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.26, output: 0.38, cacheRead: 0.13, cacheWrite: 0 }, contextWindow: 163840, maxTokens: 163840, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-v3.2-exp": { id: "deepseek/deepseek-v3.2-exp", name: "DeepSeek: DeepSeek V3.2 Exp", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.27, output: 0.41, cacheRead: 0, cacheWrite: 0 }, contextWindow: 163840, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "deepseek/deepseek-v4-flash": { id: "deepseek/deepseek-v4-flash", name: "DeepSeek: DeepSeek V4 Flash 0423", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.0574, output: 0.1148, cacheRead: 0.01148, cacheWrite: 0 }, contextWindow: 1024e3, maxTokens: 384e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", requiresReasoningContentOnAssistantMessages: true }, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: null, xhigh: "xhigh" } }, "deepseek/deepseek-v4-flash-0731": { id: "deepseek/deepseek-v4-flash-0731", name: "DeepSeek: DeepSeek V4 Flash 0731", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.14, output: 0.28, cacheRead: 0.028, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", requiresReasoningContentOnAssistantMessages: true }, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: null, xhigh: "xhigh" } }, "deepseek/deepseek-v4-flash-vision-exp": { id: "deepseek/deepseek-v4-flash-vision-exp", name: "DeepSeek: DeepSeek V4 Flash Vision Exp", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.22, output: 0.66, cacheRead: 7e-3, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 384e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", requiresReasoningContentOnAssistantMessages: true }, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: null, xhigh: "xhigh" } }, "deepseek/deepseek-v4-pro": { id: "deepseek/deepseek-v4-pro", name: "DeepSeek: DeepSeek V4 Pro 0423", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.526176, output: 1.052352, cacheRead: 0.043848, cacheWrite: 0 }, contextWindow: 1024e3, maxTokens: 384e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", requiresReasoningContentOnAssistantMessages: true }, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: null, xhigh: "xhigh" } }, "deepseek/deepseek-v4-pro-0813": { id: "deepseek/deepseek-v4-pro-0813", name: "DeepSeek: DeepSeek V4 Pro 0813", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.122, output: 3.366, cacheRead: 0.0374, cacheWrite: 0 }, contextWindow: 1048575, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", requiresReasoningContentOnAssistantMessages: true }, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: null, xhigh: "xhigh" } }, "dots-studio/dots-3-note-preview:free": { id: "dots-studio/dots-3-note-preview:free", name: "Dots Studio: Dots3-Note Preview (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 512e3, maxTokens: 512e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-flash": { id: "google/gemini-2.5-flash", name: "Google: Gemini 2.5 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0.083333 }, contextWindow: 1048576, maxTokens: 65535, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-flash-lite": { id: "google/gemini-2.5-flash-lite", name: "Google: Gemini 2.5 Flash Lite", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.4, cacheRead: 0.01, cacheWrite: 0.083333 }, contextWindow: 1048576, maxTokens: 65535, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-flash-lite:batch": { id: "google/gemini-2.5-flash-lite:batch", name: "Google: Gemini 2.5 Flash Lite (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.05, output: 0.2, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65535, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-flash:batch": { id: "google/gemini-2.5-flash:batch", name: "Google: Gemini 2.5 Flash (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.15, output: 1.25, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65535, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-pro": { id: "google/gemini-2.5-pro", name: "Google: Gemini 2.5 Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0.375 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-pro-preview": { id: "google/gemini-2.5-pro-preview", name: "Google: Gemini 2.5 Pro Preview 06-05", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0.375 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-pro-preview-05-06": { id: "google/gemini-2.5-pro-preview-05-06", name: "Google: Gemini 2.5 Pro Preview 05-06", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0.375 }, contextWindow: 1048576, maxTokens: 65535, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-2.5-pro:batch": { id: "google/gemini-2.5-pro:batch", name: "Google: Gemini 2.5 Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.625, output: 5, cacheRead: 0.125, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3-flash-preview": { id: "google/gemini-3-flash-preview", name: "Google: Gemini 3 Flash Preview", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0.083333 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3-flash-preview:batch": { id: "google/gemini-3-flash-preview:batch", name: "Google: Gemini 3 Flash Preview (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 1.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3-pro-image": { id: "google/gemini-3-pro-image", name: "Google: Nano Banana Pro (Gemini 3 Pro Image)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, contextWindow: 65536, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.1-flash-lite": { id: "google/gemini-3.1-flash-lite", name: "Google: Gemini 3.1 Flash Lite", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0.083333 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.1-flash-lite-preview": { id: "google/gemini-3.1-flash-lite-preview", name: "Google: Gemini 3.1 Flash Lite Preview", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0.083333 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.1-flash-lite:batch": { id: "google/gemini-3.1-flash-lite:batch", name: "Google: Gemini 3.1 Flash Lite (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.125, output: 0.75, cacheRead: 0.0125, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.1-pro-preview": { id: "google/gemini-3.1-pro-preview", name: "Google: Gemini 3.1 Pro Preview", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.1-pro-preview-customtools": { id: "google/gemini-3.1-pro-preview-customtools", name: "Google: Gemini 3.1 Pro Preview Custom Tools", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.1-pro-preview:batch": { id: "google/gemini-3.1-pro-preview:batch", name: "Google: Gemini 3.1 Pro Preview (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 6, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.5-flash": { id: "google/gemini-3.5-flash", name: "Google: Gemini 3.5 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0.083333 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.5-flash-lite": { id: "google/gemini-3.5-flash-lite", name: "Google: Gemini 3.5 Flash Lite", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0.083333 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.5-flash-lite:batch": { id: "google/gemini-3.5-flash-lite:batch", name: "Google: Gemini 3.5 Flash Lite (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.15, output: 1.25, cacheRead: 0.015, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.5-flash:batch": { id: "google/gemini-3.5-flash:batch", name: "Google: Gemini 3.5 Flash (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.6-flash": { id: "google/gemini-3.6-flash", name: "Google: Gemini 3.6 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0.041667 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.6-flash:batch": { id: "google/gemini-3.6-flash:batch", name: "Google: Gemini 3.6 Flash (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.375, output: 1.875, cacheRead: 0.0375, cacheWrite: 0.041667 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.7-flash": { id: "google/gemini-3.7-flash", name: "Google: Gemini 3.7 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.375, output: 1.875, cacheRead: 0.0375, cacheWrite: 0.020833 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemini-3.7-flash:batch": { id: "google/gemini-3.7-flash:batch", name: "Google: Gemini 3.7 Flash (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1875, output: 0.9375, cacheRead: 0.01875, cacheWrite: 0.020833 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemma-3-12b-it": { id: "google/gemma-3-12b-it", name: "Google: Gemma 3 12B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.05, output: 0.15, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemma-3-27b-it": { id: "google/gemma-3-27b-it", name: "Google: Gemma 3 27B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.08, output: 0.45, cacheRead: 0.04, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemma-4-26b-a4b-it": { id: "google/gemma-4-26b-a4b-it", name: "Google: Gemma 4 26B A4B ", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.07, output: 0.34, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemma-4-26b-a4b-it:free": { id: "google/gemma-4-26b-a4b-it:free", name: "Google: Gemma 4 26B A4B (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemma-4-31b-it": { id: "google/gemma-4-31b-it", name: "Google: Gemma 4 31B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.34, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "google/gemma-4-31b-it:free": { id: "google/gemma-4-31b-it:free", name: "Google: Gemma 4 31B (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "ibm-granite/granite-4.1-8b": { id: "ibm-granite/granite-4.1-8b", name: "IBM: Granite 4.1 8B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.05, output: 0.1, cacheRead: 0.05, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "inception/mercury-2": { id: "inception/mercury-2", name: "Inception: Mercury 2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.25, output: 0.75, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 5e4, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" }, thinkingLevelMap: { off: null } }, "inclusionai/ling-3.0-flash": { id: "inclusionai/ling-3.0-flash", name: "Ling-3.0-flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.021, output: 0.063, cacheRead: 42e-4, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "kwaipilot/kat-coder-air-v2.5": { id: "kwaipilot/kat-coder-air-v2.5", name: "Kwaipilot: KAT-Coder-Air V2.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.15, output: 0.6, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 8e4, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "kwaipilot/kat-coder-pro-v2": { id: "kwaipilot/kat-coder-pro-v2", name: "Kwaipilot: KAT-Coder-Pro V2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 8e4, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "kwaipilot/kat-coder-pro-v2.5": { id: "kwaipilot/kat-coder-pro-v2.5", name: "Kwaipilot: KAT-Coder-Pro V2.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.74, output: 2.96, cacheRead: 0.15, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 8e4, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "liquid/lfm-2.5-2.6b:free": { id: "liquid/lfm-2.5-2.6b:free", name: "LiquidAI: LFM2.5-2.6B (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 65536, maxTokens: 8192, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meituan/longcat-2.0": { id: "meituan/longcat-2.0", name: "Meituan: LongCat 2.0", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.3, output: 1.2, cacheRead: 6e-3, cacheWrite: 0 }, contextWindow: 1048756, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta-llama/llama-3.1-70b-instruct": { id: "meta-llama/llama-3.1-70b-instruct", name: "Meta: Llama 3.1 70B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.4, output: 0.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta-llama/llama-3.1-8b-instruct": { id: "meta-llama/llama-3.1-8b-instruct", name: "Meta: Llama 3.1 8B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.05, output: 0.08, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta-llama/llama-3.3-70b-instruct": { id: "meta-llama/llama-3.3-70b-instruct", name: "Meta: Llama 3.3 70B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.1, output: 0.32, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta-llama/llama-4-maverick": { id: "meta-llama/llama-4-maverick", name: "Meta: Llama 4 Maverick", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.2, output: 0.8, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta-llama/llama-4-scout": { id: "meta-llama/llama-4-scout", name: "Meta: Llama 4 Scout", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.1, output: 0.3, cacheRead: 0, cacheWrite: 0 }, contextWindow: 327680, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta/muse-glimmer-30b": { id: "meta/muse-glimmer-30b", name: "Meta: Muse Glimmer 30B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.35, output: 1.5, cacheRead: 0.04, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta/muse-spark-1.1": { id: "meta/muse-spark-1.1", name: "Meta: Muse Spark 1.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta/muse-spark-1.2": { id: "meta/muse-spark-1.2", name: "Meta: Muse Spark 1.2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "meta/muse-spark-1.2-contributor": { id: "meta/muse-spark-1.2-contributor", name: "Meta: Muse Spark 1.2 Contributor", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.2, cacheRead: 2e-3, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "minimax/minimax-m1": { id: "minimax/minimax-m1", name: "MiniMax: MiniMax M1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.55, output: 2.2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 4e4, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "minimax/minimax-m2": { id: "minimax/minimax-m2", name: "MiniMax: MiniMax M2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.255, output: 1.02, cacheRead: 0, cacheWrite: 0 }, contextWindow: 204800, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "minimax/minimax-m2.1": { id: "minimax/minimax-m2.1", name: "MiniMax: MiniMax M2.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.3, output: 1.2, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 204800, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "minimax/minimax-m2.5": { id: "minimax/minimax-m2.5", name: "MiniMax: MiniMax M2.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.27, output: 1.08, cacheRead: 0.027, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "minimax/minimax-m2.7": { id: "minimax/minimax-m2.7", name: "MiniMax: MiniMax M2.7", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.24, output: 0.96, cacheRead: 0.048, cacheWrite: 0 }, contextWindow: 196608, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "minimax/minimax-m3": { id: "minimax/minimax-m3", name: "MiniMax: MiniMax M3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, contextWindow: 524288, maxTokens: 512e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "minimax/minimax-m3:batch": { id: "minimax/minimax-m3:batch", name: "MiniMax: MiniMax M3 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, contextWindow: 524288, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/codestral-2508": { id: "mistralai/codestral-2508", name: "Mistral: Codestral 2508", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.3, output: 0.9, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/ministral-14b-2512": { id: "mistralai/ministral-14b-2512", name: "Mistral: Ministral 3 14B 2512", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.2, output: 0.2, cacheRead: 0.02, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/ministral-3b-2512": { id: "mistralai/ministral-3b-2512", name: "Mistral: Ministral 3 3B 2512", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.1, output: 0.1, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/ministral-8b-2512": { id: "mistralai/ministral-8b-2512", name: "Mistral: Ministral 3 8B 2512", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.15, output: 0.15, cacheRead: 0.015, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-large": { id: "mistralai/mistral-large", name: "Mistral Large", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-large-2407": { id: "mistralai/mistral-large-2407", name: "Mistral Large 2407", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-large-2512": { id: "mistralai/mistral-large-2512", name: "Mistral: Mistral Large 3 2512", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.5, output: 1.5, cacheRead: 0.05, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-medium-3": { id: "mistralai/mistral-medium-3", name: "Mistral: Mistral Medium 3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-medium-3-5": { id: "mistralai/mistral-medium-3-5", name: "Mistral: Mistral Medium 3.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.5, output: 7.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-medium-3.1": { id: "mistralai/mistral-medium-3.1", name: "Mistral: Mistral Medium 3.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-nemo": { id: "mistralai/mistral-nemo", name: "Mistral: Mistral Nemo", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.019, output: 0.03, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-saba": { id: "mistralai/mistral-saba", name: "Mistral: Saba", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.2, output: 0.6, cacheRead: 0.02, cacheWrite: 0 }, contextWindow: 32768, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-small-2603": { id: "mistralai/mistral-small-2603", name: "Mistral: Mistral Small 4", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.15, output: 0.6, cacheRead: 0.015, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mistral-small-3.2-24b-instruct": { id: "mistralai/mistral-small-3.2-24b-instruct", name: "Mistral: Mistral Small 3.2 24B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.075, output: 0.2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/mixtral-8x22b-instruct": { id: "mistralai/mixtral-8x22b-instruct", name: "Mistral: Mixtral 8x22B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 65536, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "mistralai/voxtral-small-24b-2507": { id: "mistralai/voxtral-small-24b-2507", name: "Mistral: Voxtral Small 24B 2507", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.1, output: 0.3, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 32e3, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "moonshotai/kimi-k2": { id: "moonshotai/kimi-k2", name: "MoonshotAI: Kimi K2 0711", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.57, output: 2.3, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 100352, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "moonshotai/kimi-k2-0905": { id: "moonshotai/kimi-k2-0905", name: "MoonshotAI: Kimi K2 0905", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.6, output: 2.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 100352, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "moonshotai/kimi-k2-thinking": { id: "moonshotai/kimi-k2-thinking", name: "MoonshotAI: Kimi K2 Thinking", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.6, output: 2.5, cacheRead: 0.15, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 100352, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "moonshotai/kimi-k2.5": { id: "moonshotai/kimi-k2.5", name: "MoonshotAI: Kimi K2.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.41, output: 2.06, cacheRead: 0.07, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "moonshotai/kimi-k2.6": { id: "moonshotai/kimi-k2.6", name: "MoonshotAI: Kimi K2.6", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", requiresReasoningContentOnAssistantMessages: true } }, "moonshotai/kimi-k2.7-code": { id: "moonshotai/kimi-k2.7-code", name: "MoonshotAI: Kimi K2.7 Code", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.67, output: 3.4, cacheRead: 0.17, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "moonshotai/kimi-k2.7-code:batch": { id: "moonshotai/kimi-k2.7-code:batch", name: "MoonshotAI: Kimi K2.7 Code (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "moonshotai/kimi-k3": { id: "moonshotai/kimi-k3", name: "MoonshotAI: Kimi K3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nex-agi/nex-n2-mini": { id: "nex-agi/nex-n2-mini", name: "Nex AGI: Nex-N2-Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.025, output: 0.1, cacheRead: 25e-4, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nex-agi/nex-n2-pro": { id: "nex-agi/nex-n2-pro", name: "Nex AGI: Nex-N2-Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 1, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-nano-30b-a3b": { id: "nvidia/nemotron-3-nano-30b-a3b", name: "NVIDIA: Nemotron 3 Nano 30B A3B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.05, output: 0.2, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-nano-30b-a3b:free": { id: "nvidia/nemotron-3-nano-30b-a3b:free", name: "NVIDIA: Nemotron 3 Nano 30B A3B (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free": { id: "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free", name: "NVIDIA: Nemotron 3 Nano Omni (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-super-120b-a12b": { id: "nvidia/nemotron-3-super-120b-a12b", name: "NVIDIA: Nemotron 3 Super", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.085, output: 0.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-super-120b-a12b:free": { id: "nvidia/nemotron-3-super-120b-a12b:free", name: "NVIDIA: Nemotron 3 Super (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-ultra-550b-a55b": { id: "nvidia/nemotron-3-ultra-550b-a55b", name: "NVIDIA: Nemotron 3 Ultra", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.6, output: 3.6, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 512288, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-ultra-550b-a55b:batch": { id: "nvidia/nemotron-3-ultra-550b-a55b:batch", name: "NVIDIA: Nemotron 3 Ultra (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.6, output: 3.6, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 512288, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3-ultra-550b-a55b:free": { id: "nvidia/nemotron-3-ultra-550b-a55b:free", name: "NVIDIA: Nemotron 3 Ultra (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3.5-lightning": { id: "nvidia/nemotron-3.5-lightning", name: "NVIDIA: Nemotron 3.5 Lightning", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.08, output: 0.2, cacheRead: 0.04, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-3.5-lightning:free": { id: "nvidia/nemotron-3.5-lightning:free", name: "NVIDIA: Nemotron 3.5 Lightning (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-nano-12b-v2-vl:free": { id: "nvidia/nemotron-nano-12b-v2-vl:free", name: "NVIDIA: Nemotron Nano 12B 2 VL (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "nvidia/nemotron-nano-9b-v2:free": { id: "nvidia/nemotron-nano-9b-v2:free", name: "NVIDIA: Nemotron Nano 9B V2 (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "openai/gpt-3.5-turbo": { id: "openai/gpt-3.5-turbo", name: "OpenAI: GPT-3.5 Turbo", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.5, output: 1.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 16385, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-3.5-turbo-0613": { id: "openai/gpt-3.5-turbo-0613", name: "OpenAI: GPT-3.5 Turbo (older v0613)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 1, output: 2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 4095, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-3.5-turbo-16k": { id: "openai/gpt-3.5-turbo-16k", name: "OpenAI: GPT-3.5 Turbo 16k", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 3, output: 4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 16385, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-3.5-turbo:batch": { id: "openai/gpt-3.5-turbo:batch", name: "OpenAI: GPT-3.5 Turbo (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.25, output: 0.75, cacheRead: 0, cacheWrite: 0 }, contextWindow: 16385, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4": { id: "openai/gpt-4", name: "OpenAI: GPT-4", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 30, output: 60, cacheRead: 0, cacheWrite: 0 }, contextWindow: 8191, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4-turbo": { id: "openai/gpt-4-turbo", name: "OpenAI: GPT-4 Turbo", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 10, output: 30, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4-turbo-preview": { id: "openai/gpt-4-turbo-preview", name: "OpenAI: GPT-4 Turbo Preview", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 10, output: 30, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4-turbo:batch": { id: "openai/gpt-4-turbo:batch", name: "OpenAI: GPT-4 Turbo (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 5, output: 15, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4.1": { id: "openai/gpt-4.1", name: "OpenAI: GPT-4.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, contextWindow: 1047576, maxTokens: 32768, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4.1-mini": { id: "openai/gpt-4.1-mini", name: "OpenAI: GPT-4.1 Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.4, output: 1.6, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 1047576, maxTokens: 32768, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4.1-mini:batch": { id: "openai/gpt-4.1-mini:batch", name: "OpenAI: GPT-4.1 Mini (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.2, output: 0.8, cacheRead: 0.05, cacheWrite: 0 }, contextWindow: 1047576, maxTokens: 32768, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4.1-nano": { id: "openai/gpt-4.1-nano", name: "OpenAI: GPT-4.1 Nano", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.1, output: 0.4, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 1047576, maxTokens: 32768, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4.1-nano:batch": { id: "openai/gpt-4.1-nano:batch", name: "OpenAI: GPT-4.1 Nano (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.05, output: 0.2, cacheRead: 0.0125, cacheWrite: 0 }, contextWindow: 1047576, maxTokens: 32768, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4.1:batch": { id: "openai/gpt-4.1:batch", name: "OpenAI: GPT-4.1 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 1, output: 4, cacheRead: 0.25, cacheWrite: 0 }, contextWindow: 1047576, maxTokens: 32768, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o": { id: "openai/gpt-4o", name: "OpenAI: GPT-4o", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o-2024-05-13": { id: "openai/gpt-4o-2024-05-13", name: "OpenAI: GPT-4o (2024-05-13)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 5, output: 15, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 4096, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o-2024-08-06": { id: "openai/gpt-4o-2024-08-06", name: "OpenAI: GPT-4o (2024-08-06)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o-2024-11-20": { id: "openai/gpt-4o-2024-11-20", name: "OpenAI: GPT-4o (2024-11-20)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o-mini": { id: "openai/gpt-4o-mini", name: "OpenAI: GPT-4o-mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.15, output: 0.6, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o-mini-2024-07-18": { id: "openai/gpt-4o-mini-2024-07-18", name: "OpenAI: GPT-4o-mini (2024-07-18)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.15, output: 0.6, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o-mini:batch": { id: "openai/gpt-4o-mini:batch", name: "OpenAI: GPT-4o-mini (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.075, output: 0.3, cacheRead: 0.0375, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-4o:batch": { id: "openai/gpt-4o:batch", name: "OpenAI: GPT-4o (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 1.25, output: 5, cacheRead: 0.625, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5": { id: "openai/gpt-5", name: "OpenAI: GPT-5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5-codex:batch": { id: "openai/gpt-5-codex:batch", name: "OpenAI: GPT-5 Codex (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.625, output: 5, cacheRead: 0.0625, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5-mini": { id: "openai/gpt-5-mini", name: "OpenAI: GPT-5 Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 2, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5-mini:batch": { id: "openai/gpt-5-mini:batch", name: "OpenAI: GPT-5 Mini (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.125, output: 1, cacheRead: 0.0125, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5-nano": { id: "openai/gpt-5-nano", name: "OpenAI: GPT-5 Nano", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.05, output: 0.4, cacheRead: 5e-3, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5-nano:batch": { id: "openai/gpt-5-nano:batch", name: "OpenAI: GPT-5 Nano (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.025, output: 0.2, cacheRead: 25e-4, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5-pro": { id: "openai/gpt-5-pro", name: "OpenAI: GPT-5 Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 15, output: 120, cacheRead: 0, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5-pro:batch": { id: "openai/gpt-5-pro:batch", name: "OpenAI: GPT-5 Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 7.5, output: 60, cacheRead: 0, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5.1": { id: "openai/gpt-5.1", name: "OpenAI: GPT-5.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5.1-codex": { id: "openai/gpt-5.1-codex", name: "OpenAI: GPT-5.1-Codex", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.13, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5.1-codex-max": { id: "openai/gpt-5.1-codex-max", name: "OpenAI: GPT-5.1-Codex-Max", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5.1-codex-mini": { id: "openai/gpt-5.1-codex-mini", name: "OpenAI: GPT-5.1-Codex-Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 2, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5.1:batch": { id: "openai/gpt-5.1:batch", name: "OpenAI: GPT-5.1 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.625, output: 5, cacheRead: 0.0625, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-5.2": { id: "openai/gpt-5.2", name: "OpenAI: GPT-5.2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.2-chat": { id: "openai/gpt-5.2-chat", name: "OpenAI: GPT-5.2 Chat", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 32e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.2-codex": { id: "openai/gpt-5.2-codex", name: "OpenAI: GPT-5.2-Codex", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.2-pro": { id: "openai/gpt-5.2-pro", name: "OpenAI: GPT-5.2 Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 21, output: 168, cacheRead: 0, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.2-pro:batch": { id: "openai/gpt-5.2-pro:batch", name: "OpenAI: GPT-5.2 Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 10.5, output: 84, cacheRead: 0, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.2:batch": { id: "openai/gpt-5.2:batch", name: "OpenAI: GPT-5.2 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.875, output: 7, cacheRead: 0.0875, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.3-codex": { id: "openai/gpt-5.3-codex", name: "OpenAI: GPT-5.3-Codex", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4": { id: "openai/gpt-5.4", name: "OpenAI: GPT-5.4", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4-mini": { id: "openai/gpt-5.4-mini", name: "OpenAI: GPT-5.4 Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4-mini:batch": { id: "openai/gpt-5.4-mini:batch", name: "OpenAI: GPT-5.4 Mini (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.375, output: 2.25, cacheRead: 0.0375, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4-nano": { id: "openai/gpt-5.4-nano", name: "OpenAI: GPT-5.4 Nano", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.2, output: 1.25, cacheRead: 0.02, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4-nano:batch": { id: "openai/gpt-5.4-nano:batch", name: "OpenAI: GPT-5.4 Nano (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.625, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4-pro": { id: "openai/gpt-5.4-pro", name: "OpenAI: GPT-5.4 Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4-pro:batch": { id: "openai/gpt-5.4-pro:batch", name: "OpenAI: GPT-5.4 Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 15, output: 90, cacheRead: 0, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.4:batch": { id: "openai/gpt-5.4:batch", name: "OpenAI: GPT-5.4 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 7.5, cacheRead: 0.125, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.5": { id: "openai/gpt-5.5", name: "OpenAI: GPT-5.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.5-pro": { id: "openai/gpt-5.5-pro", name: "OpenAI: GPT-5.5 Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", off: null, minimal: null, low: null } }, "openai/gpt-5.5-pro:batch": { id: "openai/gpt-5.5-pro:batch", name: "OpenAI: GPT-5.5 Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 15, output: 90, cacheRead: 0, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.5:batch": { id: "openai/gpt-5.5:batch", name: "OpenAI: GPT-5.5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "openai/gpt-5.6-luna": { id: "openai/gpt-5.6-luna", name: "OpenAI: GPT-5.6 Luna", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-luna-pro": { id: "openai/gpt-5.6-luna-pro", name: "OpenAI: GPT-5.6 Luna Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-luna-pro:batch": { id: "openai/gpt-5.6-luna-pro:batch", name: "OpenAI: GPT-5.6 Luna Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.6, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-luna:batch": { id: "openai/gpt-5.6-luna:batch", name: "OpenAI: GPT-5.6 Luna (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.6, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-sol": { id: "openai/gpt-5.6-sol", name: "OpenAI: GPT-5.6 Sol", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-sol-pro": { id: "openai/gpt-5.6-sol-pro", name: "OpenAI: GPT-5.6 Sol Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-sol-pro:batch": { id: "openai/gpt-5.6-sol-pro:batch", name: "OpenAI: GPT-5.6 Sol Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-sol:batch": { id: "openai/gpt-5.6-sol:batch", name: "OpenAI: GPT-5.6 Sol (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-terra": { id: "openai/gpt-5.6-terra", name: "OpenAI: GPT-5.6 Terra", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-terra-pro": { id: "openai/gpt-5.6-terra-pro", name: "OpenAI: GPT-5.6 Terra Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-terra-pro:batch": { id: "openai/gpt-5.6-terra-pro:batch", name: "OpenAI: GPT-5.6 Terra Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 6, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5.6-terra:batch": { id: "openai/gpt-5.6-terra:batch", name: "OpenAI: GPT-5.6 Terra (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 6, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 105e4, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh", max: "max" } }, "openai/gpt-5:batch": { id: "openai/gpt-5:batch", name: "OpenAI: GPT-5 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.625, output: 5, cacheRead: 0.0625, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-audio": { id: "openai/gpt-audio", name: "OpenAI: GPT Audio", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 2.5, output: 10, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-audio-mini": { id: "openai/gpt-audio-mini", name: "OpenAI: GPT Audio Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.6, output: 2.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 16384, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-chat-latest": { id: "openai/gpt-chat-latest", name: "OpenAI: GPT Chat Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-oss-120b": { id: "openai/gpt-oss-120b", name: "OpenAI: gpt-oss-120b", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.037, output: 0.17, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 131072, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-oss-20b": { id: "openai/gpt-oss-20b", name: "OpenAI: gpt-oss-20b", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.03, output: 0.13, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 131072, compat: { thinkingFormat: "openrouter" } }, "openai/gpt-oss-safeguard-20b": { id: "openai/gpt-oss-safeguard-20b", name: "OpenAI: gpt-oss-safeguard-20b", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.075, output: 0.3, cacheRead: 0.0375, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 65536, compat: { thinkingFormat: "openrouter" } }, "openai/o1": { id: "openai/o1", name: "OpenAI: o1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 15, output: 60, cacheRead: 7.5, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o1:batch": { id: "openai/o1:batch", name: "OpenAI: o1 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 7.5, output: 30, cacheRead: 3.75, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3": { id: "openai/o3", name: "OpenAI: o3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3-mini": { id: "openai/o3-mini", name: "OpenAI: o3 Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.1, output: 4.4, cacheRead: 0.55, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3-mini-high": { id: "openai/o3-mini-high", name: "OpenAI: o3 Mini High", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.1, output: 4.4, cacheRead: 0.55, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3-mini-high:batch": { id: "openai/o3-mini-high:batch", name: "OpenAI: o3 Mini High (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.55, output: 2.2, cacheRead: 0.275, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3-mini:batch": { id: "openai/o3-mini:batch", name: "OpenAI: o3 Mini (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.55, output: 2.2, cacheRead: 0.275, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3-pro": { id: "openai/o3-pro", name: "OpenAI: o3 Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 20, output: 80, cacheRead: 0, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3-pro:batch": { id: "openai/o3-pro:batch", name: "OpenAI: o3 Pro (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 10, output: 40, cacheRead: 0, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o3:batch": { id: "openai/o3:batch", name: "OpenAI: o3 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 4, cacheRead: 0.25, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o4-mini": { id: "openai/o4-mini", name: "OpenAI: o4 Mini", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.1, output: 4.4, cacheRead: 0.275, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o4-mini-high": { id: "openai/o4-mini-high", name: "OpenAI: o4 Mini High", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.1, output: 4.4, cacheRead: 0.275, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o4-mini-high:batch": { id: "openai/o4-mini-high:batch", name: "OpenAI: o4 Mini High (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.55, output: 2.2, cacheRead: 0.1375, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openai/o4-mini:batch": { id: "openai/o4-mini:batch", name: "OpenAI: o4 Mini (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.55, output: 2.2, cacheRead: 0.1375, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 1e5, compat: { thinkingFormat: "openrouter" } }, "openrouter/auto": { id: "openrouter/auto", name: "Auto Router", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: -1e6, output: -1e6, cacheRead: 0, cacheWrite: 0 }, contextWindow: 2e6, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "openrouter/auto-beta": { id: "openrouter/auto-beta", name: "Auto Router (Beta)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: -1e6, output: -1e6, cacheRead: 0, cacheWrite: 0 }, contextWindow: 2e6, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "openrouter/free": { id: "openrouter/free", name: "Free Models Router", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "openrouter/fusion": { id: "openrouter/fusion", name: "OpenRouter: Fusion", api: "openai-completions", provider: "openrouter", baseUrl: "https://openrouter.ai/api/v1", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 3e4, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "poolside/laguna-s-2.1": { id: "poolside/laguna-s-2.1", name: "Poolside: Laguna S 2.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.09, output: 0.18, cacheRead: 9e-3, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "poolside/laguna-s-2.1:free": { id: "poolside/laguna-s-2.1:free", name: "Poolside: Laguna S 2.1 (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "poolside/laguna-xs-2.1": { id: "poolside/laguna-xs-2.1", name: "Poolside: Laguna XS 2.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.06, output: 0.12, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "poolside/laguna-xs-2.1:free": { id: "poolside/laguna-xs-2.1:free", name: "Poolside: Laguna XS 2.1 (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen-2.5-72b-instruct": { id: "qwen/qwen-2.5-72b-instruct", name: "Qwen2.5 72B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.36, output: 0.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 32768, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen-2.5-7b-instruct": { id: "qwen/qwen-2.5-7b-instruct", name: "Qwen: Qwen2.5 7B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.1, output: 0.2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 32768, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen-plus": { id: "qwen/qwen-plus", name: "Qwen: Qwen-Plus", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.26, output: 0.78, cacheRead: 0.052, cacheWrite: 0.325 }, contextWindow: 1e6, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen-plus-2025-07-28": { id: "qwen/qwen-plus-2025-07-28", name: "Qwen: Qwen Plus 0728", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.26, output: 0.78, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen-plus-2025-07-28:thinking": { id: "qwen/qwen-plus-2025-07-28:thinking", name: "Qwen: Qwen Plus 0728 (thinking)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.26, output: 0.78, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-14b": { id: "qwen/qwen3-14b", name: "Qwen: Qwen3 14B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.12, output: 0.24, cacheRead: 0, cacheWrite: 0 }, contextWindow: 40960, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-235b-a22b": { id: "qwen/qwen3-235b-a22b", name: "Qwen: Qwen3 235B A22B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.455, output: 1.82, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 8192, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-235b-a22b-2507": { id: "qwen/qwen3-235b-a22b-2507", name: "Qwen: Qwen3 235B A22B Instruct 2507", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.09, output: 0.55, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-235b-a22b-thinking-2507": { id: "qwen/qwen3-235b-a22b-thinking-2507", name: "Qwen: Qwen3 235B A22B Thinking 2507", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.23, output: 2.3, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-30b-a3b": { id: "qwen/qwen3-30b-a3b", name: "Qwen: Qwen3 30B A3B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.12, output: 0.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 40960, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-30b-a3b-instruct-2507": { id: "qwen/qwen3-30b-a3b-instruct-2507", name: "Qwen: Qwen3 30B A3B Instruct 2507", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.04815, output: 0.19305, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 32e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-30b-a3b-thinking-2507": { id: "qwen/qwen3-30b-a3b-thinking-2507", name: "Qwen: Qwen3 30B A3B Thinking 2507", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.2, output: 2.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 81920, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-32b": { id: "qwen/qwen3-32b", name: "Qwen: Qwen3 32B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.08, output: 0.28, cacheRead: 0, cacheWrite: 0 }, contextWindow: 40960, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-8b": { id: "qwen/qwen3-8b", name: "Qwen: Qwen3 8B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.117, output: 0.455, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 8192, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-coder": { id: "qwen/qwen3-coder", name: "Qwen: Qwen3 Coder 480B A35B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.3, output: 1, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-coder-30b-a3b-instruct": { id: "qwen/qwen3-coder-30b-a3b-instruct", name: "Qwen: Qwen3 Coder 30B A3B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.07, output: 0.28, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-coder-flash": { id: "qwen/qwen3-coder-flash", name: "Qwen: Qwen3 Coder Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.195, output: 0.975, cacheRead: 0.039, cacheWrite: 0.24375 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-coder-next": { id: "qwen/qwen3-coder-next", name: "Qwen: Qwen3 Coder Next", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.12, output: 0.8, cacheRead: 0.07, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-coder-plus": { id: "qwen/qwen3-coder-plus", name: "Qwen: Qwen3 Coder Plus", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.65, output: 3.25, cacheRead: 0.13, cacheWrite: 0.8125 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-max": { id: "qwen/qwen3-max", name: "Qwen: Qwen3 Max", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.78, output: 3.9, cacheRead: 0.156, cacheWrite: 0.975 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-max-thinking": { id: "qwen/qwen3-max-thinking", name: "Qwen: Qwen3 Max Thinking", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.78, output: 3.9, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-next-80b-a3b-instruct": { id: "qwen/qwen3-next-80b-a3b-instruct", name: "Qwen: Qwen3 Next 80B A3B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.1, output: 1.1, cacheRead: 0.07, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-next-80b-a3b-thinking": { id: "qwen/qwen3-next-80b-a3b-thinking", name: "Qwen: Qwen3 Next 80B A3B Thinking", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.15, output: 1.2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-vl-235b-a22b-instruct": { id: "qwen/qwen3-vl-235b-a22b-instruct", name: "Qwen: Qwen3 VL 235B A22B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.21, output: 1.9, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-vl-235b-a22b-thinking": { id: "qwen/qwen3-vl-235b-a22b-thinking", name: "Qwen: Qwen3 VL 235B A22B Thinking", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.4, output: 4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-vl-30b-a3b-instruct": { id: "qwen/qwen3-vl-30b-a3b-instruct", name: "Qwen: Qwen3 VL 30B A3B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.13, output: 0.52, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-vl-30b-a3b-thinking": { id: "qwen/qwen3-vl-30b-a3b-thinking", name: "Qwen: Qwen3 VL 30B A3B Thinking", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.2, output: 2.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-vl-32b-instruct": { id: "qwen/qwen3-vl-32b-instruct", name: "Qwen: Qwen3 VL 32B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.104, output: 0.416, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-vl-8b-instruct": { id: "qwen/qwen3-vl-8b-instruct", name: "Qwen: Qwen3 VL 8B Instruct", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.117, output: 0.455, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3-vl-8b-thinking": { id: "qwen/qwen3-vl-8b-thinking", name: "Qwen: Qwen3 VL 8B Thinking", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.18, output: 2.1, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-122b-a10b": { id: "qwen/qwen3.5-122b-a10b", name: "Qwen: Qwen3.5-122B-A10B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.26, output: 2.08, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-27b": { id: "qwen/qwen3.5-27b", name: "Qwen: Qwen3.5-27B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.195, output: 1.56, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-35b-a3b": { id: "qwen/qwen3.5-35b-a3b", name: "Qwen: Qwen3.5-35B-A3B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.25, output: 1.25, cacheRead: 0.25, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-397b-a17b": { id: "qwen/qwen3.5-397b-a17b", name: "Qwen: Qwen3.5 397B A17B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.5, output: 3.6, cacheRead: 0.3, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-9b": { id: "qwen/qwen3.5-9b", name: "Qwen: Qwen3.5-9B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.15, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-flash-02-23": { id: "qwen/qwen3.5-flash-02-23", name: "Qwen: Qwen3.5-Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.065, output: 0.26, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-plus-02-15": { id: "qwen/qwen3.5-plus-02-15", name: "Qwen: Qwen3.5 Plus 2026-02-15", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.26, output: 1.56, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.5-plus-20260420": { id: "qwen/qwen3.5-plus-20260420", name: "Qwen: Qwen3.5 Plus 2026-04-20", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 1.8, cacheRead: 0, cacheWrite: 0.375 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.6-27b": { id: "qwen/qwen3.6-27b", name: "Qwen: Qwen3.6 27B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.32, output: 3.2, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 81920, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.6-35b-a3b": { id: "qwen/qwen3.6-35b-a3b", name: "Qwen: Qwen3.6 35B A3B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.14, output: 1, cacheRead: 0.05, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.6-flash": { id: "qwen/qwen3.6-flash", name: "Qwen: Qwen3.6 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.1875, output: 1.125, cacheRead: 0, cacheWrite: 0.234375 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.6-max-preview": { id: "qwen/qwen3.6-max-preview", name: "Qwen: Qwen3.6 Max Preview", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.027, output: 6.162, cacheRead: 0, cacheWrite: 1.28375 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.6-plus": { id: "qwen/qwen3.6-plus", name: "Qwen: Qwen3.6 Plus", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.325, output: 1.95, cacheRead: 0, cacheWrite: 0.40625 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.7-flash": { id: "qwen/qwen3.7-flash", name: "Qwen: Qwen3.7 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.03, output: 0.13, cacheRead: 6e-3, cacheWrite: 0.038 }, contextWindow: 1e6, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.7-max": { id: "qwen/qwen3.7-max", name: "Qwen: Qwen3.7 Max", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.475, output: 4.425, cacheRead: 0.295, cacheWrite: 1.84375 }, contextWindow: 1e6, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.7-plus": { id: "qwen/qwen3.7-plus", name: "Qwen: Qwen3.7 Plus", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.32, output: 1.28, cacheRead: 0.064, cacheWrite: 0.4 }, contextWindow: 1e6, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.8-2.4t-a95b": { id: "qwen/qwen3.8-2.4t-a95b", name: "Qwen: Qwen3.8 2.4T A95B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.8-27b": { id: "qwen/qwen3.8-27b", name: "Qwen: Qwen3.8 27B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.4, output: 3, cacheRead: 0.05, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "qwen/qwen3.8-max": { id: "qwen/qwen3.8-max", name: "Qwen: Qwen3.8 Max", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 2.5 }, contextWindow: 1e6, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "rekaai/reka-edge": { id: "rekaai/reka-edge", name: "Reka Edge", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text", "image"], cost: { input: 0.1, output: 0.1, cacheRead: 0, cacheWrite: 0 }, contextWindow: 16384, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "relace/relace-search": { id: "relace/relace-search", name: "Relace: Relace Search", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 1, output: 3, cacheRead: 0, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "sakana/fugu-ultra": { id: "sakana/fugu-ultra", name: "Sakana: Fugu Ultra", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "sakana/sakana-namazu": { id: "sakana/sakana-namazu", name: "Sakana: Sakana Namazu", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.95, output: 4, cacheRead: 0.15, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "sao10k/l3.1-euryale-70b": { id: "sao10k/l3.1-euryale-70b", name: "Sao10K: Llama 3.1 Euryale 70B v2.2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.85, output: 0.85, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "stealth/ox-alpha": { id: "stealth/ox-alpha", name: "Ox Alpha", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "stepfun/step-3.5-flash": { id: "stepfun/step-3.5-flash", name: "StepFun: Step 3.5 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.1, output: 0.3, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "stepfun/step-3.7-flash": { id: "stepfun/step-3.7-flash", name: "StepFun: Step 3.7 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.2, output: 1.15, cacheRead: 0.04, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 256e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "tencent/hy3": { id: "tencent/hy3", name: "Tencent: Hy3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.132, output: 0.528, cacheRead: 0.033, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "tencent/hy3-preview": { id: "tencent/hy3-preview", name: "Tencent: Hy3 preview", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.18, output: 0.6, cacheRead: 0.06, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "thedrummer/unslopnemo-12b": { id: "thedrummer/unslopnemo-12b", name: "TheDrummer: UnslopNemo 12B", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: false, input: ["text"], cost: { input: 0.4, output: 0.4, cacheRead: 0, cacheWrite: 0 }, contextWindow: 32768, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "thinkingmachines/inkling": { id: "thinkingmachines/inkling", name: "Thinking Machines: Inkling", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 4.05, cacheRead: 0.17, cacheWrite: 0 }, contextWindow: 524288, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "thinkingmachines/inkling-small": { id: "thinkingmachines/inkling-small", name: "Thinking Machines: Inkling Small", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.45, output: 1.2, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 524288, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "thinkingmachines/inkling-small:free": { id: "thinkingmachines/inkling-small:free", name: "Thinking Machines: Inkling Small (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "thinkingmachines/inkling:batch": { id: "thinkingmachines/inkling:batch", name: "Thinking Machines: Inkling (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 4.05, cacheRead: 0.17, cacheWrite: 0 }, contextWindow: 524288, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "thinkingmachines/inkling:free": { id: "thinkingmachines/inkling:free", name: "Thinking Machines: Inkling (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 262144, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "upstage/solar-pro-3": { id: "upstage/solar-pro-3", name: "Upstage: Solar Pro 3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.15, output: 0.6, cacheRead: 0.015, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "upstage/solar-pro4": { id: "upstage/solar-pro4", name: "Upstage: Solar Pro 4", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.03, output: 0.12, cacheRead: 6e-3, cacheWrite: 0 }, contextWindow: 524288, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "x-ai/grok-4.20": { id: "x-ai/grok-4.20", name: "SpaceXAI: Grok 4.20", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 2e6, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "x-ai/grok-4.3": { id: "x-ai/grok-4.3", name: "SpaceXAI: Grok 4.3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 1e6, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "x-ai/grok-4.5": { id: "x-ai/grok-4.5", name: "SpaceXAI: Grok 4.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.3, cacheWrite: 0 }, contextWindow: 5e5, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "x-ai/grok-4.6": { id: "x-ai/grok-4.6", name: "SpaceXAI: Grok 4.6", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, contextWindow: 5e5, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "x-ai/grok-build-0.1": { id: "x-ai/grok-build-0.1", name: "SpaceXAI: Grok Build 0.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 2, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "xiaomi/mimo-v2.5": { id: "xiaomi/mimo-v2.5", name: "Xiaomi: MiMo-V2.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.14, output: 0.28, cacheRead: 28e-4, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "xiaomi/mimo-v2.5-pro": { id: "xiaomi/mimo-v2.5-pro", name: "Xiaomi: MiMo-V2.5-Pro", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.435, output: 0.87, cacheRead: 36e-4, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-4.5": { id: "z-ai/glm-4.5", name: "Z.ai: GLM 4.5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.6, output: 2.2, cacheRead: 0.11, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 98304, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-4.5-air": { id: "z-ai/glm-4.5-air", name: "Z.ai: GLM 4.5 Air", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.13, output: 0.85, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 98304, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-4.5v": { id: "z-ai/glm-4.5v", name: "Z.ai: GLM 4.5V", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.6, output: 1.8, cacheRead: 0.11, cacheWrite: 0 }, contextWindow: 65536, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-4.6": { id: "z-ai/glm-4.6", name: "Z.ai: GLM 4.6", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.5, output: 2, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 202752, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-4.6v": { id: "z-ai/glm-4.6v", name: "Z.ai: GLM 4.6V", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 0.9, cacheRead: 0.055, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 32768, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-4.7": { id: "z-ai/glm-4.7", name: "Z.ai: GLM 4.7", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.4, output: 1.75, cacheRead: 0.08, cacheWrite: 0 }, contextWindow: 202752, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-4.7-flash": { id: "z-ai/glm-4.7-flash", name: "Z.ai: GLM 4.7 Flash", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.06, output: 0.4, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 202752, maxTokens: 16384, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-5": { id: "z-ai/glm-5", name: "Z.ai: GLM 5", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.6, output: 1.9, cacheRead: 0.119, cacheWrite: 0 }, contextWindow: 198e3, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-5-turbo": { id: "z-ai/glm-5-turbo", name: "Z.ai: GLM 5 Turbo", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.2, output: 4, cacheRead: 0.24, cacheWrite: 0 }, contextWindow: 202752, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-5.1": { id: "z-ai/glm-5.1", name: "Z.ai: GLM 5.1", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.966, output: 3.036, cacheRead: 0.1794, cacheWrite: 0 }, contextWindow: 2e5, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-5.2": { id: "z-ai/glm-5.2", name: "Z.ai: GLM 5.2", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.966, output: 3.036, cacheRead: 0.1932, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" }, thinkingLevelMap: { xhigh: "xhigh" } }, "z-ai/glm-5.2:batch": { id: "z-ai/glm-5.2:batch", name: "Z.ai: GLM 5.2 (batch)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, contextWindow: 1048575, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-5.2:free": { id: "z-ai/glm-5.2:free", name: "Z.ai: GLM 5.2 (free)", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 256e3, maxTokens: 256e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-5.3": { id: "z-ai/glm-5.3", name: "Z.ai: GLM 5.3", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "z-ai/glm-5v-turbo": { id: "z-ai/glm-5v-turbo", name: "Z.ai: GLM 5V Turbo", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1.2, output: 4, cacheRead: 0.24, cacheWrite: 0 }, contextWindow: 202752, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "~anthropic/claude-fable-latest": { id: "~anthropic/claude-fable-latest", name: "Anthropic: Claude Fable Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, contextWindow: 1e6, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "~anthropic/claude-haiku-latest": { id: "~anthropic/claude-haiku-latest", name: "Anthropic Claude Haiku Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, contextWindow: 2e5, maxTokens: 64e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "~anthropic/claude-opus-latest": { id: "~anthropic/claude-opus-latest", name: "Anthropic: Claude Opus Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, contextWindow: 1e6, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "~anthropic/claude-sonnet-latest": { id: "~anthropic/claude-sonnet-latest", name: "Anthropic Claude Sonnet Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, contextWindow: 1e6, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", cacheControlFormat: "anthropic" } }, "~deepseek/deepseek-v4-flash-latest": { id: "~deepseek/deepseek-v4-flash-latest", name: "DeepSeek V4 Flash Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 0.04, output: 0.08, cacheRead: 8e-3, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 1048576, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter", requiresReasoningContentOnAssistantMessages: true }, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: null, xhigh: "xhigh" } }, "~google/gemini-flash-latest": { id: "~google/gemini-flash-latest", name: "Google Gemini Flash Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.375, output: 1.875, cacheRead: 0.0375, cacheWrite: 0.020833 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "~google/gemini-pro-latest": { id: "~google/gemini-pro-latest", name: "Google Gemini Pro Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, contextWindow: 1048576, maxTokens: 65536, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "~moonshotai/kimi-latest": { id: "~moonshotai/kimi-latest", name: "MoonshotAI Kimi Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2.6, output: 13, cacheRead: 0.29, cacheWrite: 0 }, contextWindow: 974842, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "~openai/gpt-latest": { id: "~openai/gpt-latest", name: "OpenAI GPT Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, contextWindow: 105e4, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "~openai/gpt-mini-latest": { id: "~openai/gpt-mini-latest", name: "OpenAI GPT Mini Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 4e5, maxTokens: 128e3, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "~x-ai/grok-latest": { id: "~x-ai/grok-latest", name: "xAI: Grok Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, contextWindow: 5e5, maxTokens: 4096, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } }, "~z-ai/glm-latest": { id: "~z-ai/glm-latest", name: "Z.ai: GLM Latest", api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", provider: "openrouter", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 131072, compat: { supportsDeveloperRole: false, thinkingFormat: "openrouter" } } } };
|
|
14149
14243
|
|
|
14150
14244
|
// ../ai/src/providers/openrouter.models.ts
|
|
14151
14245
|
var OPENROUTER_MODELS = flattenModelCatalog("openrouter", openrouter_default);
|
|
@@ -14563,7 +14657,7 @@ function cloudflareWorkersAIProvider() {
|
|
|
14563
14657
|
}
|
|
14564
14658
|
|
|
14565
14659
|
// ../ai/src/providers/data/.manifest.json
|
|
14566
|
-
var manifest_default = { schemaVersion: 3, generatedAt: "2026-08-
|
|
14660
|
+
var manifest_default = { schemaVersion: 3, generatedAt: "2026-08-24T11:22:29.095Z", structureHash: "5dce9c34b838a5dd1d7f031d30b0d6d06c6d2902a38098885d75f238ba569c7f", files: { "amazon-bedrock.json": "71441520503c82d14c788a16fdbd5314adc5b7b34abd65a3f260b96f493c2e90", "ant-ling.json": "4979fe79d99ed97382d7ce40170c6132e932e77906de1eb54464c042e7d63633", "anthropic.json": "e22c277e3a1ffddc3d2701b72787c9e0bd67b835de6b4cb806677b6b6a89a2f7", "azure-openai-responses.json": "5315b6a2299fefbdbb6cc13a720544077c9498132ad5e3a7d76a8c1daa8e9335", "baseten.json": "950433e7fcf9357ae3423b27fc0d32568b6e0990bb35c6e961dcb9740a6bba1b", "cerebras.json": "38272a7525d6680c71bb4bb3c4085e871768b400832e2013b0e7fd92f8fd4f05", "cloudflare-ai-gateway.json": "244af2cfdfaf75c4135ce4c7865220057647c2d8744b52af1d55392879df8d28", "cloudflare-workers-ai.json": "89e63a18886ecedd1d995cc90e4bfe06f73e2a79117b2f54f58fe60cdcf63df5", "deepseek.json": "0dcc807a4e5827b488c6ceac87884ff6e735e01cf4f2ddfec9dd812e6fde041b", "fireworks.json": "b587d1ba3380b5785a52f67b8a5eae11c447e667488fb2b6b0865a89c2692e4a", "github-copilot.json": "ed5b1e17f95adba904a2b9c909bb28a8542ba1185467080f9f56b2ea93b0429b", "google-vertex.json": "fb7586fc955da7b7d7d11d641954f496fbbb42cf3e4cbba66d7116ea3b37d5ed", "google.json": "b5572904165d37ab594eafc3ab7f29774e35747b5dd211144ec01532db9217c1", "groq.json": "f1eb899453e70b5e4479fe6eb78869ee99121fa6d4a019a5a05ab42d2ada8992", "huggingface.json": "b2f15353177738beb5c0865ffcd92cc470e1c8ba6b6a4d2707cda12212a6043b", "kimi-coding.json": "ba42a26a69e5cb2122c0b384ba572efae93f42239ad86f26c2b7320a14aa75a1", "minimax-cn.json": "8ccd71ff838f4b78bb88809babb0dc32a4fcfaec2bc4f4083841000428df4f77", "minimax.json": "253edd4c910a41c8bb252400ba099f3a4de0a8900ce154319288ab091b372987", "mistral.json": "4f9d84bf1ba10cb14ff2c9e23e77d63441756ef3500375dd4ad10094614b215b", "moonshotai-cn.json": "1e6146ff3477883636448c0f44222f0a52b3c4562ef8f4eecf7e941cdd59d12e", "moonshotai.json": "d8d5209873058ddccd37c1f026833e2ea3f9476c3dc9628b4a940d407acc0b2e", "nvidia.json": "f9e2737a9d7ccb77ccc14083422dae03e0b786d169660670f739ddb3f0533eb5", "openai-codex.json": "4a73818291987693fcb53e9e61b4be3429ffd78b3f64ea877a34c5f9928c89e1", "openai.json": "60a1af0fd4c407733079283bb485ab1d8d592abf25f13632d83ba40425e11177", "opencode-go.json": "f7b88230cf767cf1ddefd3acf3ad7e377dab9cbeb55d3dad7b6acf7111a801f8", "opencode.json": "2ef1476a30c692a18d52242e955082a1a122a75c709ba4f10749ef762c54531a", "openrouter.json": "6dbbf84366da2ef97af845baebc719e54a063105d920cb3f55684b351c678c9d", "qwen-token-plan-cn.json": "700cb41cdee4c0ae2a5159eb3ab43f4cedc9d43e87c6fd1bcd410d71431f9856", "qwen-token-plan.json": "f85715f7f2023a162c47d1a84ba73747e2580d0a9aa33799b3232ce19527c1ab", "together.json": "f7c9ba0441c1cbb8af41aaea3cfaa12559e1235a7335898e705d5918dc308c97", "vercel-ai-gateway.json": "7857ae0ce938685455f9b570b55cecdfb9b5e8aa82baff4645669d4d8b7ba9e5", "xai.json": "282838b0546d63106c81f1703cdf5ed31ebfe0c5f13a4bec0d590472cbbe03f2", "xiaomi-token-plan-ams.json": "7ce8ed244672c45737d286ff3ca9c3a2686a5d4b2f0c5f71ab9348c14b14daf3", "xiaomi-token-plan-cn.json": "684892b5fe6fa371d6040d2011c0fa33facd650d2eaf19f5dbee8efb33016200", "xiaomi-token-plan-sgp.json": "b19e79b82ac4fdcb080e6d220106797504c885ed70b27fc2b3c1aa4810f32963", "xiaomi.json": "810368d3828c8bb9498012a0d48639030c0c216b8c13e79da02daa515aa23448", "zai-coding-cn.json": "663466fef5cca84909b9929671a48fefb3721c0990c61bbec05d8b1692247310", "zai.json": "fd81b25003c3e653ee319c2ba0ce353a4f02df1a409246c8d0f96d13dd0ec592" } };
|
|
14567
14661
|
|
|
14568
14662
|
// ../ai/src/providers/deepseek.ts
|
|
14569
14663
|
init_models();
|
|
@@ -15490,16 +15584,16 @@ import { homedir } from "node:os";
|
|
|
15490
15584
|
import { isAbsolute, join, resolve as nodeResolvePath, relative, sep } from "node:path";
|
|
15491
15585
|
import { fileURLToPath } from "node:url";
|
|
15492
15586
|
var UNICODE_SPACES = /[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g;
|
|
15493
|
-
function canonicalizePath(
|
|
15587
|
+
function canonicalizePath(path12) {
|
|
15494
15588
|
try {
|
|
15495
|
-
return realpathSync(
|
|
15589
|
+
return realpathSync(path12);
|
|
15496
15590
|
} catch {
|
|
15497
|
-
return
|
|
15591
|
+
return path12;
|
|
15498
15592
|
}
|
|
15499
15593
|
}
|
|
15500
|
-
function getFileRevision(
|
|
15594
|
+
function getFileRevision(path12) {
|
|
15501
15595
|
try {
|
|
15502
|
-
const stats = statSync(
|
|
15596
|
+
const stats = statSync(path12, { bigint: true });
|
|
15503
15597
|
return `${stats.dev}:${stats.ino}:${stats.size}:${stats.mtimeNs}:${stats.ctimeNs}`;
|
|
15504
15598
|
} catch {
|
|
15505
15599
|
return void 0;
|
|
@@ -15561,13 +15655,13 @@ function formatPathRelativeToCwdOrAbsolute(filePath, cwd) {
|
|
|
15561
15655
|
const absolutePath = resolvePath(filePath, cwd);
|
|
15562
15656
|
return (getCwdRelativePath(absolutePath, cwd) ?? absolutePath).split(sep).join("/");
|
|
15563
15657
|
}
|
|
15564
|
-
function markPathIgnoredByCloudSync(
|
|
15658
|
+
function markPathIgnoredByCloudSync(path12) {
|
|
15565
15659
|
const attrs = process.platform === "darwin" ? ["com.dropbox.ignored", "com.apple.fileprovider.ignore#P"] : process.platform === "linux" ? ["user.com.dropbox.ignored"] : [];
|
|
15566
15660
|
for (const attr of attrs) {
|
|
15567
15661
|
if (process.platform === "darwin") {
|
|
15568
|
-
spawnProcessSync("xattr", ["-w", attr, "1",
|
|
15662
|
+
spawnProcessSync("xattr", ["-w", attr, "1", path12], { encoding: "utf-8", stdio: "ignore" });
|
|
15569
15663
|
} else {
|
|
15570
|
-
spawnProcessSync("setfattr", ["-n", attr, "-v", "1",
|
|
15664
|
+
spawnProcessSync("setfattr", ["-n", attr, "-v", "1", path12], { encoding: "utf-8", stdio: "ignore" });
|
|
15571
15665
|
}
|
|
15572
15666
|
}
|
|
15573
15667
|
}
|
|
@@ -15620,19 +15714,19 @@ function detectInstallMethod() {
|
|
|
15620
15714
|
}
|
|
15621
15715
|
function getInferredNpmInstall() {
|
|
15622
15716
|
const packageDir = getPackageDir();
|
|
15623
|
-
const
|
|
15624
|
-
const parent =
|
|
15717
|
+
const path12 = process.platform === "win32" || packageDir.includes("\\") ? win32 : { basename, dirname };
|
|
15718
|
+
const parent = path12.dirname(packageDir);
|
|
15625
15719
|
let root;
|
|
15626
|
-
if (
|
|
15627
|
-
root =
|
|
15628
|
-
} else if (
|
|
15720
|
+
if (path12.basename(parent).startsWith("@") && path12.basename(path12.dirname(parent)) === "node_modules") {
|
|
15721
|
+
root = path12.dirname(parent);
|
|
15722
|
+
} else if (path12.basename(parent) === "node_modules") {
|
|
15629
15723
|
root = parent;
|
|
15630
15724
|
}
|
|
15631
15725
|
if (!root)
|
|
15632
15726
|
return void 0;
|
|
15633
|
-
const rootParent =
|
|
15634
|
-
if (
|
|
15635
|
-
return { root, prefix:
|
|
15727
|
+
const rootParent = path12.dirname(root);
|
|
15728
|
+
if (path12.basename(rootParent) === "lib")
|
|
15729
|
+
return { root, prefix: path12.dirname(rootParent) };
|
|
15636
15730
|
return void 0;
|
|
15637
15731
|
}
|
|
15638
15732
|
function getSelfUpdateCommandForMethod(method, installedPackageName, updatePackageTarget = installedPackageName, npmCommand) {
|
|
@@ -15739,8 +15833,8 @@ function getGlobalPackageRoots(method, _packageName, npmCommand) {
|
|
|
15739
15833
|
return [];
|
|
15740
15834
|
}
|
|
15741
15835
|
}
|
|
15742
|
-
function normalizeExistingPathForComparison(
|
|
15743
|
-
const resolvedPath = resolve(
|
|
15836
|
+
function normalizeExistingPathForComparison(path12, resolveSymlinks) {
|
|
15837
|
+
const resolvedPath = resolve(path12);
|
|
15744
15838
|
if (!existsSync(resolvedPath)) {
|
|
15745
15839
|
return void 0;
|
|
15746
15840
|
}
|
|
@@ -15757,8 +15851,8 @@ function normalizeExistingPathForComparison(path11, resolveSymlinks) {
|
|
|
15757
15851
|
}
|
|
15758
15852
|
return normalizedPath;
|
|
15759
15853
|
}
|
|
15760
|
-
function getPathComparisonCandidates(
|
|
15761
|
-
return Array.from(new Set([normalizeExistingPathForComparison(
|
|
15854
|
+
function getPathComparisonCandidates(path12) {
|
|
15855
|
+
return Array.from(new Set([normalizeExistingPathForComparison(path12, false), normalizeExistingPathForComparison(path12, true)].filter((candidate) => !!candidate)));
|
|
15762
15856
|
}
|
|
15763
15857
|
function getEntrypointPackageDir() {
|
|
15764
15858
|
const entrypoint = process.argv[1];
|
|
@@ -15902,8 +15996,8 @@ function deleteAppEnv(suffix, env = process.env) {
|
|
|
15902
15996
|
delete env[name];
|
|
15903
15997
|
}
|
|
15904
15998
|
}
|
|
15905
|
-
function expandTildePath(
|
|
15906
|
-
return normalizePath(
|
|
15999
|
+
function expandTildePath(path12) {
|
|
16000
|
+
return normalizePath(path12);
|
|
15907
16001
|
}
|
|
15908
16002
|
function getShareViewerUrl(gistId) {
|
|
15909
16003
|
const baseUrl = readAppEnv("SHARE_VIEWER_URL");
|
|
@@ -17954,15 +18048,15 @@ function parsePathPrefix(prefix) {
|
|
|
17954
18048
|
}
|
|
17955
18049
|
return { rawPrefix: prefix, isAtPrefix: false, isQuotedPrefix: false };
|
|
17956
18050
|
}
|
|
17957
|
-
function buildCompletionValue(
|
|
17958
|
-
const needsQuotes = options.isQuotedPrefix ||
|
|
18051
|
+
function buildCompletionValue(path12, options) {
|
|
18052
|
+
const needsQuotes = options.isQuotedPrefix || path12.includes(" ");
|
|
17959
18053
|
const prefix = options.isAtPrefix ? "@" : "";
|
|
17960
18054
|
if (!needsQuotes) {
|
|
17961
|
-
return `${prefix}${
|
|
18055
|
+
return `${prefix}${path12}`;
|
|
17962
18056
|
}
|
|
17963
18057
|
const openQuote = `${prefix}"`;
|
|
17964
18058
|
const closeQuote = '"';
|
|
17965
|
-
return `${openQuote}${
|
|
18059
|
+
return `${openQuote}${path12}${closeQuote}`;
|
|
17966
18060
|
}
|
|
17967
18061
|
async function walkDirectoryWithFd(baseDir, fdPath, query, maxResults, signal) {
|
|
17968
18062
|
const args = [
|
|
@@ -18211,14 +18305,14 @@ var CombinedAutocompleteProvider = class {
|
|
|
18211
18305
|
return null;
|
|
18212
18306
|
}
|
|
18213
18307
|
// Expand home directory (~/) to actual home path
|
|
18214
|
-
expandHomePath(
|
|
18215
|
-
if (
|
|
18216
|
-
const expandedPath = join4(homedir3(),
|
|
18217
|
-
return
|
|
18218
|
-
} else if (
|
|
18308
|
+
expandHomePath(path12) {
|
|
18309
|
+
if (path12.startsWith("~/")) {
|
|
18310
|
+
const expandedPath = join4(homedir3(), path12.slice(2));
|
|
18311
|
+
return path12.endsWith("/") && !expandedPath.endsWith("/") ? `${expandedPath}/` : expandedPath;
|
|
18312
|
+
} else if (path12 === "~") {
|
|
18219
18313
|
return homedir3();
|
|
18220
18314
|
}
|
|
18221
|
-
return
|
|
18315
|
+
return path12;
|
|
18222
18316
|
}
|
|
18223
18317
|
resolveScopedFuzzyQuery(rawQuery) {
|
|
18224
18318
|
const normalizedQuery = toDisplayPath(rawQuery);
|
|
@@ -29421,11 +29515,11 @@ function orderKeybindingsConfig(config) {
|
|
|
29421
29515
|
}
|
|
29422
29516
|
return ordered2;
|
|
29423
29517
|
}
|
|
29424
|
-
function loadRawConfig(
|
|
29425
|
-
if (!existsSync3(
|
|
29518
|
+
function loadRawConfig(path12) {
|
|
29519
|
+
if (!existsSync3(path12))
|
|
29426
29520
|
return void 0;
|
|
29427
29521
|
try {
|
|
29428
|
-
const parsed = JSON.parse(readFileSync3(
|
|
29522
|
+
const parsed = JSON.parse(readFileSync3(path12, "utf-8"));
|
|
29429
29523
|
if (typeof parsed !== "object" || parsed === null)
|
|
29430
29524
|
return void 0;
|
|
29431
29525
|
return parsed;
|
|
@@ -29452,8 +29546,8 @@ var KeybindingsManager2 = class _KeybindingsManager extends KeybindingsManager {
|
|
|
29452
29546
|
getEffectiveConfig() {
|
|
29453
29547
|
return this.getResolvedBindings();
|
|
29454
29548
|
}
|
|
29455
|
-
static loadFromFile(
|
|
29456
|
-
const rawConfig = loadRawConfig(
|
|
29549
|
+
static loadFromFile(path12) {
|
|
29550
|
+
const rawConfig = loadRawConfig(path12);
|
|
29457
29551
|
if (!rawConfig)
|
|
29458
29552
|
return {};
|
|
29459
29553
|
return toKeybindingsConfig(migrateKeybindingsConfig(rawConfig).config);
|
|
@@ -29578,16 +29672,16 @@ function parseGenericGitUrl(url) {
|
|
|
29578
29672
|
const { repo: repoWithoutRef, ref } = splitRef(url);
|
|
29579
29673
|
let repo = repoWithoutRef;
|
|
29580
29674
|
let host = "";
|
|
29581
|
-
let
|
|
29675
|
+
let path12 = "";
|
|
29582
29676
|
const scpLikeMatch = repoWithoutRef.match(/^git@([^:]+):(.+)$/);
|
|
29583
29677
|
if (scpLikeMatch) {
|
|
29584
29678
|
host = scpLikeMatch[1] ?? "";
|
|
29585
|
-
|
|
29679
|
+
path12 = scpLikeMatch[2] ?? "";
|
|
29586
29680
|
} else if (repoWithoutRef.startsWith("https://") || repoWithoutRef.startsWith("http://") || repoWithoutRef.startsWith("ssh://") || repoWithoutRef.startsWith("git://")) {
|
|
29587
29681
|
try {
|
|
29588
29682
|
const parsed = new URL(repoWithoutRef);
|
|
29589
29683
|
host = parsed.hostname;
|
|
29590
|
-
|
|
29684
|
+
path12 = parsed.pathname.replace(/^\/+/, "");
|
|
29591
29685
|
} catch {
|
|
29592
29686
|
return null;
|
|
29593
29687
|
}
|
|
@@ -29597,13 +29691,13 @@ function parseGenericGitUrl(url) {
|
|
|
29597
29691
|
return null;
|
|
29598
29692
|
}
|
|
29599
29693
|
host = repoWithoutRef.slice(0, slashIndex);
|
|
29600
|
-
|
|
29694
|
+
path12 = repoWithoutRef.slice(slashIndex + 1);
|
|
29601
29695
|
if (!host.includes(".") && host !== "localhost") {
|
|
29602
29696
|
return null;
|
|
29603
29697
|
}
|
|
29604
29698
|
repo = `https://${repoWithoutRef}`;
|
|
29605
29699
|
}
|
|
29606
|
-
return buildGitSource({ repo, host, path:
|
|
29700
|
+
return buildGitSource({ repo, host, path: path12, ref });
|
|
29607
29701
|
}
|
|
29608
29702
|
function parseGitUrl(source) {
|
|
29609
29703
|
const trimmed = source.trim();
|
|
@@ -30336,17 +30430,17 @@ var DefaultPackageManager = class {
|
|
|
30336
30430
|
getInstalledPath(source, scope) {
|
|
30337
30431
|
const parsed = this.parseSource(source);
|
|
30338
30432
|
if (parsed.type === "npm") {
|
|
30339
|
-
const
|
|
30340
|
-
return existsSync4(
|
|
30433
|
+
const path12 = this.getNpmInstallPath(parsed, scope);
|
|
30434
|
+
return existsSync4(path12) ? path12 : void 0;
|
|
30341
30435
|
}
|
|
30342
30436
|
if (parsed.type === "git") {
|
|
30343
|
-
const
|
|
30344
|
-
return existsSync4(
|
|
30437
|
+
const path12 = this.getGitInstallPath(parsed, scope);
|
|
30438
|
+
return existsSync4(path12) ? path12 : void 0;
|
|
30345
30439
|
}
|
|
30346
30440
|
if (parsed.type === "local") {
|
|
30347
30441
|
const baseDir = this.getBaseDirForScope(scope);
|
|
30348
|
-
const
|
|
30349
|
-
return existsSync4(
|
|
30442
|
+
const path12 = this.resolvePathFromBase(parsed.path, baseDir);
|
|
30443
|
+
return existsSync4(path12) ? path12 : void 0;
|
|
30350
30444
|
}
|
|
30351
30445
|
return void 0;
|
|
30352
30446
|
}
|
|
@@ -31348,9 +31442,9 @@ var DefaultPackageManager = class {
|
|
|
31348
31442
|
const output = this.runNpmCommandSync(["list", "-g", "--depth", "0", "--json"]);
|
|
31349
31443
|
const entries = JSON.parse(output);
|
|
31350
31444
|
for (const entry of entries) {
|
|
31351
|
-
const
|
|
31352
|
-
if (
|
|
31353
|
-
return
|
|
31445
|
+
const path12 = entry.dependencies?.[packageName]?.path;
|
|
31446
|
+
if (path12)
|
|
31447
|
+
return path12;
|
|
31354
31448
|
}
|
|
31355
31449
|
return void 0;
|
|
31356
31450
|
}
|
|
@@ -31604,9 +31698,9 @@ var DefaultPackageManager = class {
|
|
|
31604
31698
|
const projectAgentsSkillDirs = projectTrusted ? collectAncestorAgentsSkillDirs(this.cwd).filter((dir) => resolve3(dir) !== resolve3(userAgentsSkillsDir)) : [];
|
|
31605
31699
|
const addResources = (resourceType, paths, metadata, overrides, baseDir) => {
|
|
31606
31700
|
const target = this.getTargetMap(accumulator, resourceType);
|
|
31607
|
-
for (const
|
|
31608
|
-
const enabled = isEnabledByOverrides(
|
|
31609
|
-
this.addResource(target,
|
|
31701
|
+
for (const path12 of paths) {
|
|
31702
|
+
const enabled = isEnabledByOverrides(path12, overrides, baseDir);
|
|
31703
|
+
this.addResource(target, path12, metadata, enabled);
|
|
31610
31704
|
}
|
|
31611
31705
|
};
|
|
31612
31706
|
if (projectTrusted) {
|
|
@@ -31667,11 +31761,11 @@ var DefaultPackageManager = class {
|
|
|
31667
31761
|
throw new Error(`Unknown resource type: ${resourceType}`);
|
|
31668
31762
|
}
|
|
31669
31763
|
}
|
|
31670
|
-
addResource(map,
|
|
31671
|
-
if (!
|
|
31764
|
+
addResource(map, path12, metadata, enabled) {
|
|
31765
|
+
if (!path12)
|
|
31672
31766
|
return;
|
|
31673
|
-
if (!map.has(
|
|
31674
|
-
map.set(
|
|
31767
|
+
if (!map.has(path12)) {
|
|
31768
|
+
map.set(path12, { metadata, enabled });
|
|
31675
31769
|
}
|
|
31676
31770
|
}
|
|
31677
31771
|
createAccumulator() {
|
|
@@ -31684,8 +31778,8 @@ var DefaultPackageManager = class {
|
|
|
31684
31778
|
}
|
|
31685
31779
|
toResolvedPaths(accumulator) {
|
|
31686
31780
|
const mapToResolved = (entries) => {
|
|
31687
|
-
const resolved = Array.from(entries.entries()).map(([
|
|
31688
|
-
path:
|
|
31781
|
+
const resolved = Array.from(entries.entries()).map(([path12, { metadata, enabled }]) => ({
|
|
31782
|
+
path: path12,
|
|
31689
31783
|
enabled,
|
|
31690
31784
|
metadata
|
|
31691
31785
|
}));
|
|
@@ -31829,13 +31923,13 @@ var FileSettingsStorage = class {
|
|
|
31829
31923
|
this.globalSettingsPath = join13(resolvedAgentDir, "settings.json");
|
|
31830
31924
|
this.projectSettingsPath = join13(resolvedCwd, CONFIG_DIR_NAME, "settings.json");
|
|
31831
31925
|
}
|
|
31832
|
-
acquireLockSyncWithRetry(
|
|
31926
|
+
acquireLockSyncWithRetry(path12) {
|
|
31833
31927
|
const maxAttempts = 10;
|
|
31834
31928
|
const delayMs = 20;
|
|
31835
31929
|
let lastError;
|
|
31836
31930
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
31837
31931
|
try {
|
|
31838
|
-
return lockfile.lockSync(
|
|
31932
|
+
return lockfile.lockSync(path12, { realpath: false });
|
|
31839
31933
|
} catch (error) {
|
|
31840
31934
|
const code = typeof error === "object" && error !== null && "code" in error ? String(error.code) : void 0;
|
|
31841
31935
|
if (code !== "ELOCKED" || attempt === maxAttempts) {
|
|
@@ -31850,24 +31944,24 @@ var FileSettingsStorage = class {
|
|
|
31850
31944
|
throw lastError ?? new Error("Failed to acquire settings lock");
|
|
31851
31945
|
}
|
|
31852
31946
|
withLock(scope, fn) {
|
|
31853
|
-
const
|
|
31854
|
-
const dir = dirname8(
|
|
31947
|
+
const path12 = scope === "global" ? this.globalSettingsPath : this.projectSettingsPath;
|
|
31948
|
+
const dir = dirname8(path12);
|
|
31855
31949
|
let release;
|
|
31856
31950
|
try {
|
|
31857
|
-
const fileExists2 = existsSync5(
|
|
31951
|
+
const fileExists2 = existsSync5(path12);
|
|
31858
31952
|
if (fileExists2) {
|
|
31859
|
-
release = this.acquireLockSyncWithRetry(
|
|
31953
|
+
release = this.acquireLockSyncWithRetry(path12);
|
|
31860
31954
|
}
|
|
31861
|
-
const current = fileExists2 ? readFileSync6(
|
|
31955
|
+
const current = fileExists2 ? readFileSync6(path12, "utf-8") : void 0;
|
|
31862
31956
|
const next = fn(current);
|
|
31863
31957
|
if (next !== void 0) {
|
|
31864
31958
|
if (!existsSync5(dir)) {
|
|
31865
31959
|
mkdirSync4(dir, { recursive: true });
|
|
31866
31960
|
}
|
|
31867
31961
|
if (!release) {
|
|
31868
|
-
release = this.acquireLockSyncWithRetry(
|
|
31962
|
+
release = this.acquireLockSyncWithRetry(path12);
|
|
31869
31963
|
}
|
|
31870
|
-
writeFileSync4(
|
|
31964
|
+
writeFileSync4(path12, next, "utf-8");
|
|
31871
31965
|
}
|
|
31872
31966
|
} finally {
|
|
31873
31967
|
if (release) {
|
|
@@ -32357,8 +32451,8 @@ var SettingsManager = class _SettingsManager {
|
|
|
32357
32451
|
const shellPath = this.settings.shellPath;
|
|
32358
32452
|
return shellPath ? normalizePath(shellPath) : shellPath;
|
|
32359
32453
|
}
|
|
32360
|
-
setShellPath(
|
|
32361
|
-
this.globalSettings.shellPath =
|
|
32454
|
+
setShellPath(path12) {
|
|
32455
|
+
this.globalSettings.shellPath = path12;
|
|
32362
32456
|
this.markModified("shellPath");
|
|
32363
32457
|
this.save();
|
|
32364
32458
|
}
|
|
@@ -32685,9 +32779,9 @@ function closeWatcher(watcher) {
|
|
|
32685
32779
|
} catch {
|
|
32686
32780
|
}
|
|
32687
32781
|
}
|
|
32688
|
-
function watchWithErrorHandler(
|
|
32782
|
+
function watchWithErrorHandler(path12, listener, onError) {
|
|
32689
32783
|
try {
|
|
32690
|
-
const watcher = watch(
|
|
32784
|
+
const watcher = watch(path12, listener);
|
|
32691
32785
|
watcher.on("error", onError);
|
|
32692
32786
|
return watcher;
|
|
32693
32787
|
} catch {
|
|
@@ -33255,8 +33349,8 @@ function parseThemeJson(label, json) {
|
|
|
33255
33349
|
}
|
|
33256
33350
|
continue;
|
|
33257
33351
|
}
|
|
33258
|
-
const
|
|
33259
|
-
otherErrors.push(` - ${
|
|
33352
|
+
const path12 = error.instancePath || "/";
|
|
33353
|
+
otherErrors.push(` - ${path12}: ${error.message}`);
|
|
33260
33354
|
}
|
|
33261
33355
|
let errorMessage = `Invalid theme "${label}":
|
|
33262
33356
|
`;
|
|
@@ -34831,9 +34925,9 @@ Sign in to GitNexus to use ${APP_NAME}.
|
|
|
34831
34925
|
deviceName
|
|
34832
34926
|
};
|
|
34833
34927
|
await new GitNexusClient(config).callTool("list_repos", {}, AbortSignal.timeout(15e3));
|
|
34834
|
-
const
|
|
34928
|
+
const path12 = saveGitNexusConfig(config);
|
|
34835
34929
|
io.write(`
|
|
34836
|
-
Signed in. Credential saved to ${
|
|
34930
|
+
Signed in. Credential saved to ${path12}
|
|
34837
34931
|
|
|
34838
34932
|
`);
|
|
34839
34933
|
return true;
|
|
@@ -35010,14 +35104,14 @@ function filterAndSortSessions(sessions, query, sortMode, nameFilter = "all") {
|
|
|
35010
35104
|
}
|
|
35011
35105
|
|
|
35012
35106
|
// dist/modes/interactive/components/session-selector.js
|
|
35013
|
-
function shortenPath(
|
|
35107
|
+
function shortenPath(path12) {
|
|
35014
35108
|
const home = os2.homedir();
|
|
35015
|
-
if (!
|
|
35016
|
-
return
|
|
35017
|
-
if (
|
|
35018
|
-
return `~${
|
|
35109
|
+
if (!path12)
|
|
35110
|
+
return path12;
|
|
35111
|
+
if (path12.startsWith(home)) {
|
|
35112
|
+
return `~${path12.slice(home.length)}`;
|
|
35019
35113
|
}
|
|
35020
|
-
return
|
|
35114
|
+
return path12;
|
|
35021
35115
|
}
|
|
35022
35116
|
function formatSessionDate(date) {
|
|
35023
35117
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -35039,10 +35133,10 @@ function formatSessionDate(date) {
|
|
|
35039
35133
|
return `${Math.floor(diffDays / 30)}mo`;
|
|
35040
35134
|
return `${Math.floor(diffDays / 365)}y`;
|
|
35041
35135
|
}
|
|
35042
|
-
function canonicalizePath2(
|
|
35043
|
-
if (!
|
|
35044
|
-
return
|
|
35045
|
-
return canonicalizePath(
|
|
35136
|
+
function canonicalizePath2(path12) {
|
|
35137
|
+
if (!path12)
|
|
35138
|
+
return path12;
|
|
35139
|
+
return canonicalizePath(path12);
|
|
35046
35140
|
}
|
|
35047
35141
|
var SessionSelectorHeader = class {
|
|
35048
35142
|
scope;
|
|
@@ -35084,8 +35178,8 @@ var SessionSelectorHeader = class {
|
|
|
35084
35178
|
setShowRenameHint(show) {
|
|
35085
35179
|
this.showRenameHint = show;
|
|
35086
35180
|
}
|
|
35087
|
-
setConfirmingDeletePath(
|
|
35088
|
-
this.confirmingDeletePath =
|
|
35181
|
+
setConfirmingDeletePath(path12) {
|
|
35182
|
+
this.confirmingDeletePath = path12;
|
|
35089
35183
|
}
|
|
35090
35184
|
clearStatusTimeout() {
|
|
35091
35185
|
if (!this.statusTimeout)
|
|
@@ -35313,9 +35407,9 @@ var SessionList = class {
|
|
|
35313
35407
|
}
|
|
35314
35408
|
this.selectedIndex = Math.min(this.selectedIndex, Math.max(0, this.filteredSessions.length - 1));
|
|
35315
35409
|
}
|
|
35316
|
-
setConfirmingDeletePath(
|
|
35317
|
-
this.confirmingDeletePath =
|
|
35318
|
-
this.onDeleteConfirmationChange?.(
|
|
35410
|
+
setConfirmingDeletePath(path12) {
|
|
35411
|
+
this.confirmingDeletePath = path12;
|
|
35412
|
+
this.onDeleteConfirmationChange?.(path12);
|
|
35319
35413
|
}
|
|
35320
35414
|
startDeleteConfirmationForSelectedSession() {
|
|
35321
35415
|
const selected = this.filteredSessions[this.selectedIndex];
|
|
@@ -35327,10 +35421,10 @@ var SessionList = class {
|
|
|
35327
35421
|
}
|
|
35328
35422
|
this.setConfirmingDeletePath(selected.session.path);
|
|
35329
35423
|
}
|
|
35330
|
-
isCurrentSessionPath(
|
|
35424
|
+
isCurrentSessionPath(path12) {
|
|
35331
35425
|
if (!this.currentSessionCanonicalPath)
|
|
35332
35426
|
return false;
|
|
35333
|
-
return (canonicalizePath2(
|
|
35427
|
+
return (canonicalizePath2(path12) ?? path12) === this.currentSessionCanonicalPath;
|
|
35334
35428
|
}
|
|
35335
35429
|
invalidate() {
|
|
35336
35430
|
}
|
|
@@ -35631,8 +35725,8 @@ var SessionSelectorComponent = class extends Container {
|
|
|
35631
35725
|
this.header.setShowPath(showPath);
|
|
35632
35726
|
this.requestRender();
|
|
35633
35727
|
};
|
|
35634
|
-
this.sessionList.onDeleteConfirmationChange = (
|
|
35635
|
-
this.header.setConfirmingDeletePath(
|
|
35728
|
+
this.sessionList.onDeleteConfirmationChange = (path12) => {
|
|
35729
|
+
this.header.setConfirmingDeletePath(path12);
|
|
35636
35730
|
this.requestRender();
|
|
35637
35731
|
};
|
|
35638
35732
|
this.sessionList.onError = (msg) => {
|
|
@@ -35808,11 +35902,11 @@ async function selectSession(currentSessionsLoader, allSessionsLoader, settingsM
|
|
|
35808
35902
|
const keybindings = KeybindingsManager2.create();
|
|
35809
35903
|
setKeybindings(keybindings);
|
|
35810
35904
|
let resolved = false;
|
|
35811
|
-
const selector = new SessionSelectorComponent(currentSessionsLoader, allSessionsLoader, (
|
|
35905
|
+
const selector = new SessionSelectorComponent(currentSessionsLoader, allSessionsLoader, (path12) => {
|
|
35812
35906
|
if (!resolved) {
|
|
35813
35907
|
resolved = true;
|
|
35814
35908
|
ui.stop();
|
|
35815
|
-
resolve15(
|
|
35909
|
+
resolve15(path12);
|
|
35816
35910
|
}
|
|
35817
35911
|
}, () => {
|
|
35818
35912
|
if (!resolved) {
|
|
@@ -36724,13 +36818,13 @@ var ExtensionRunner = class {
|
|
|
36724
36818
|
const handlerResult = await handler(event, ctx);
|
|
36725
36819
|
const result = handlerResult;
|
|
36726
36820
|
if (result?.skillPaths?.length) {
|
|
36727
|
-
skillPaths.push(...result.skillPaths.map((
|
|
36821
|
+
skillPaths.push(...result.skillPaths.map((path12) => ({ path: path12, extensionPath: ext.path })));
|
|
36728
36822
|
}
|
|
36729
36823
|
if (result?.promptPaths?.length) {
|
|
36730
|
-
promptPaths.push(...result.promptPaths.map((
|
|
36824
|
+
promptPaths.push(...result.promptPaths.map((path12) => ({ path: path12, extensionPath: ext.path })));
|
|
36731
36825
|
}
|
|
36732
36826
|
if (result?.themePaths?.length) {
|
|
36733
|
-
themePaths.push(...result.themePaths.map((
|
|
36827
|
+
themePaths.push(...result.themePaths.map((path12) => ({ path: path12, extensionPath: ext.path })));
|
|
36734
36828
|
}
|
|
36735
36829
|
} catch (err2) {
|
|
36736
36830
|
const message = err2 instanceof Error ? err2.message : String(err2);
|
|
@@ -37055,19 +37149,19 @@ function buildSessionPath(entries, leafId, byId) {
|
|
|
37055
37149
|
if (!leaf) {
|
|
37056
37150
|
return [];
|
|
37057
37151
|
}
|
|
37058
|
-
const
|
|
37152
|
+
const path12 = [];
|
|
37059
37153
|
let current = leaf;
|
|
37060
37154
|
while (current) {
|
|
37061
|
-
|
|
37155
|
+
path12.push(current);
|
|
37062
37156
|
current = current.parentId ? index.get(current.parentId) : void 0;
|
|
37063
37157
|
}
|
|
37064
|
-
|
|
37065
|
-
return
|
|
37158
|
+
path12.reverse();
|
|
37159
|
+
return path12;
|
|
37066
37160
|
}
|
|
37067
|
-
function getSessionContextSettings(
|
|
37161
|
+
function getSessionContextSettings(path12) {
|
|
37068
37162
|
let thinkingLevel = "off";
|
|
37069
37163
|
let model = null;
|
|
37070
|
-
for (const entry of
|
|
37164
|
+
for (const entry of path12) {
|
|
37071
37165
|
if (entry.type === "thinking_level_change") {
|
|
37072
37166
|
thinkingLevel = entry.thinkingLevel;
|
|
37073
37167
|
} else if (entry.type === "model_change") {
|
|
@@ -37100,24 +37194,24 @@ function sessionEntryToContextMessages(entry) {
|
|
|
37100
37194
|
return [];
|
|
37101
37195
|
}
|
|
37102
37196
|
function buildContextEntries(entries, leafId, byId) {
|
|
37103
|
-
const
|
|
37197
|
+
const path12 = buildSessionPath(entries, leafId, byId);
|
|
37104
37198
|
let compaction = null;
|
|
37105
|
-
for (const entry of
|
|
37199
|
+
for (const entry of path12) {
|
|
37106
37200
|
if (entry.type === "compaction") {
|
|
37107
37201
|
compaction = entry;
|
|
37108
37202
|
}
|
|
37109
37203
|
}
|
|
37110
37204
|
if (!compaction) {
|
|
37111
|
-
return
|
|
37205
|
+
return path12;
|
|
37112
37206
|
}
|
|
37113
|
-
const compactionIdx =
|
|
37207
|
+
const compactionIdx = path12.findIndex((entry) => entry.id === compaction.id);
|
|
37114
37208
|
if (compactionIdx < 0) {
|
|
37115
|
-
return
|
|
37209
|
+
return path12;
|
|
37116
37210
|
}
|
|
37117
37211
|
const contextEntries = [compaction];
|
|
37118
37212
|
let foundFirstKept = false;
|
|
37119
37213
|
for (let i = 0; i < compactionIdx; i++) {
|
|
37120
|
-
const entry =
|
|
37214
|
+
const entry = path12[i];
|
|
37121
37215
|
if (entry.id === compaction.firstKeptEntryId) {
|
|
37122
37216
|
foundFirstKept = true;
|
|
37123
37217
|
}
|
|
@@ -37125,12 +37219,12 @@ function buildContextEntries(entries, leafId, byId) {
|
|
|
37125
37219
|
contextEntries.push(entry);
|
|
37126
37220
|
}
|
|
37127
37221
|
}
|
|
37128
|
-
contextEntries.push(...
|
|
37222
|
+
contextEntries.push(...path12.slice(compactionIdx + 1));
|
|
37129
37223
|
return contextEntries;
|
|
37130
37224
|
}
|
|
37131
37225
|
function buildSessionContext(entries, leafId, byId) {
|
|
37132
|
-
const
|
|
37133
|
-
const { thinkingLevel, model } = getSessionContextSettings(
|
|
37226
|
+
const path12 = buildSessionPath(entries, leafId, byId);
|
|
37227
|
+
const { thinkingLevel, model } = getSessionContextSettings(path12);
|
|
37134
37228
|
const messages = buildContextEntries(entries, leafId, byId).flatMap(sessionEntryToContextMessages);
|
|
37135
37229
|
return { messages, thinkingLevel, model };
|
|
37136
37230
|
}
|
|
@@ -37273,7 +37367,7 @@ function findMostRecentSession(sessionDir, cwd) {
|
|
|
37273
37367
|
const resolvedSessionDir = normalizePath(sessionDir);
|
|
37274
37368
|
const resolvedCwd = cwd ? resolvePath(cwd) : void 0;
|
|
37275
37369
|
try {
|
|
37276
|
-
const files = readdirSync4(resolvedSessionDir).filter((f) => f.endsWith(".jsonl")).map((f) => join15(resolvedSessionDir, f)).map((
|
|
37370
|
+
const files = readdirSync4(resolvedSessionDir).filter((f) => f.endsWith(".jsonl")).map((f) => join15(resolvedSessionDir, f)).map((path12) => ({ path: path12, header: readSessionHeaderForDiscovery(path12) })).filter((file) => file.header !== null && (!resolvedCwd || sessionCwdMatches(getSessionHeaderCwd(file.header), resolvedCwd))).map(({ path: path12 }) => ({ path: path12, mtime: statSync5(path12).mtime })).sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
|
|
37277
37371
|
return files[0]?.path || null;
|
|
37278
37372
|
} catch {
|
|
37279
37373
|
return null;
|
|
@@ -37775,15 +37869,15 @@ var SessionManager = class _SessionManager {
|
|
|
37775
37869
|
* Use buildSessionContext() to get the resolved messages for the LLM.
|
|
37776
37870
|
*/
|
|
37777
37871
|
getBranch(fromId) {
|
|
37778
|
-
const
|
|
37872
|
+
const path12 = [];
|
|
37779
37873
|
const startId = fromId ?? this.leafId;
|
|
37780
37874
|
let current = startId ? this.byId.get(startId) : void 0;
|
|
37781
37875
|
while (current) {
|
|
37782
|
-
|
|
37876
|
+
path12.push(current);
|
|
37783
37877
|
current = current.parentId ? this.byId.get(current.parentId) : void 0;
|
|
37784
37878
|
}
|
|
37785
|
-
|
|
37786
|
-
return
|
|
37879
|
+
path12.reverse();
|
|
37880
|
+
return path12;
|
|
37787
37881
|
}
|
|
37788
37882
|
/**
|
|
37789
37883
|
* Build the active, compaction-aware entry list for context/rendering.
|
|
@@ -37903,13 +37997,13 @@ var SessionManager = class _SessionManager {
|
|
|
37903
37997
|
*/
|
|
37904
37998
|
createBranchedSession(leafId) {
|
|
37905
37999
|
const previousSessionFile = this.sessionFile;
|
|
37906
|
-
const
|
|
37907
|
-
if (
|
|
38000
|
+
const path12 = this.getBranch(leafId);
|
|
38001
|
+
if (path12.length === 0) {
|
|
37908
38002
|
throw new Error(`Entry ${leafId} not found`);
|
|
37909
38003
|
}
|
|
37910
38004
|
const pathWithoutLabels = [];
|
|
37911
38005
|
let pathParentId = null;
|
|
37912
|
-
for (const entry of
|
|
38006
|
+
for (const entry of path12) {
|
|
37913
38007
|
if (entry.type === "label")
|
|
37914
38008
|
continue;
|
|
37915
38009
|
pathWithoutLabels.push({ ...entry, parentId: pathParentId });
|
|
@@ -37998,8 +38092,8 @@ var SessionManager = class _SessionManager {
|
|
|
37998
38092
|
* @param sessionDir Optional session directory for /new or /branch. If omitted, derives from file's parent.
|
|
37999
38093
|
* @param cwdOverride Optional cwd override instead of the session header cwd.
|
|
38000
38094
|
*/
|
|
38001
|
-
static open(
|
|
38002
|
-
const resolvedPath = resolvePath(
|
|
38095
|
+
static open(path12, sessionDir, cwdOverride) {
|
|
38096
|
+
const resolvedPath = resolvePath(path12);
|
|
38003
38097
|
let header = null;
|
|
38004
38098
|
let preloadedFileEntries;
|
|
38005
38099
|
if (cwdOverride === void 0 && existsSync10(resolvedPath)) {
|
|
@@ -38209,8 +38303,8 @@ import { execSync as execSync2, spawnSync as spawnSync3 } from "child_process";
|
|
|
38209
38303
|
import { existsSync as existsSync11 } from "node:fs";
|
|
38210
38304
|
import { delimiter } from "node:path";
|
|
38211
38305
|
import { spawn as spawn3, spawnSync as spawnSync2 } from "child_process";
|
|
38212
|
-
function isLegacyWslBashPath(
|
|
38213
|
-
const normalized =
|
|
38306
|
+
function isLegacyWslBashPath(path12) {
|
|
38307
|
+
const normalized = path12.replace(/\//g, "\\").toLowerCase();
|
|
38214
38308
|
return /^[a-z]:\\windows\\(?:system32|sysnative)\\bash\.exe$/.test(normalized);
|
|
38215
38309
|
}
|
|
38216
38310
|
function getBashShellConfig(shell) {
|
|
@@ -38263,9 +38357,9 @@ function getShellConfig(customShellPath) {
|
|
|
38263
38357
|
if (programFilesX86) {
|
|
38264
38358
|
paths.push(`${programFilesX86}\\Git\\bin\\bash.exe`);
|
|
38265
38359
|
}
|
|
38266
|
-
for (const
|
|
38267
|
-
if (existsSync11(
|
|
38268
|
-
return getBashShellConfig(
|
|
38360
|
+
for (const path12 of paths) {
|
|
38361
|
+
if (existsSync11(path12)) {
|
|
38362
|
+
return getBashShellConfig(path12);
|
|
38269
38363
|
}
|
|
38270
38364
|
}
|
|
38271
38365
|
const bashOnPath2 = findBashOnPath();
|
|
@@ -38571,13 +38665,13 @@ var FileAuthStorageBackend = class {
|
|
|
38571
38665
|
chmodSync2(this.authPath, 384);
|
|
38572
38666
|
}
|
|
38573
38667
|
}
|
|
38574
|
-
acquireLockSyncWithRetry(
|
|
38668
|
+
acquireLockSyncWithRetry(path12) {
|
|
38575
38669
|
const maxAttempts = 10;
|
|
38576
38670
|
const delayMs = 20;
|
|
38577
38671
|
let lastError;
|
|
38578
38672
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
38579
38673
|
try {
|
|
38580
|
-
return lockfile2.lockSync(
|
|
38674
|
+
return lockfile2.lockSync(path12, { realpath: false });
|
|
38581
38675
|
} catch (error) {
|
|
38582
38676
|
const code = typeof error === "object" && error !== null && "code" in error ? String(error.code) : void 0;
|
|
38583
38677
|
if (code !== "ELOCKED" || attempt === maxAttempts) {
|
|
@@ -39064,8 +39158,8 @@ function formatValidationPath2(error) {
|
|
|
39064
39158
|
return basePath ? `${basePath}.${requiredProperty}` : requiredProperty;
|
|
39065
39159
|
}
|
|
39066
39160
|
}
|
|
39067
|
-
const
|
|
39068
|
-
return
|
|
39161
|
+
const path12 = error.instancePath.replace(/^\//, "").replace(/\//g, ".");
|
|
39162
|
+
return path12 || "root";
|
|
39069
39163
|
}
|
|
39070
39164
|
function deepFreeze(value) {
|
|
39071
39165
|
if (typeof value !== "object" || value === null || Object.isFrozen(value))
|
|
@@ -39084,16 +39178,16 @@ var ModelConfig = class _ModelConfig {
|
|
|
39084
39178
|
static async load(modelsJsonPath) {
|
|
39085
39179
|
if (!modelsJsonPath)
|
|
39086
39180
|
return new _ModelConfig(/* @__PURE__ */ new Map());
|
|
39087
|
-
const
|
|
39181
|
+
const path12 = normalizePath(modelsJsonPath);
|
|
39088
39182
|
let content;
|
|
39089
39183
|
try {
|
|
39090
|
-
content = await readFile2(
|
|
39184
|
+
content = await readFile2(path12, "utf-8");
|
|
39091
39185
|
} catch (error) {
|
|
39092
39186
|
if (error.code === "ENOENT")
|
|
39093
39187
|
return new _ModelConfig(/* @__PURE__ */ new Map());
|
|
39094
39188
|
return new _ModelConfig(/* @__PURE__ */ new Map(), `Failed to load models.json: ${error instanceof Error ? error.message : error}
|
|
39095
39189
|
|
|
39096
|
-
File: ${
|
|
39190
|
+
File: ${path12}`);
|
|
39097
39191
|
}
|
|
39098
39192
|
let parsed;
|
|
39099
39193
|
try {
|
|
@@ -39101,14 +39195,14 @@ File: ${path11}`);
|
|
|
39101
39195
|
} catch (error) {
|
|
39102
39196
|
return new _ModelConfig(/* @__PURE__ */ new Map(), `Failed to parse models.json: ${error instanceof Error ? error.message : error}
|
|
39103
39197
|
|
|
39104
|
-
File: ${
|
|
39198
|
+
File: ${path12}`);
|
|
39105
39199
|
}
|
|
39106
39200
|
if (!validateModelsConfig.Check(parsed)) {
|
|
39107
39201
|
const errors = validateModelsConfig.Errors(parsed).map((error) => ` - ${formatValidationPath2(error)}: ${error.message}`).join("\n") || "Unknown schema error";
|
|
39108
39202
|
return new _ModelConfig(/* @__PURE__ */ new Map(), `Invalid models.json schema:
|
|
39109
39203
|
${errors}
|
|
39110
39204
|
|
|
39111
|
-
File: ${
|
|
39205
|
+
File: ${path12}`);
|
|
39112
39206
|
}
|
|
39113
39207
|
const config = parsed;
|
|
39114
39208
|
const providers = /* @__PURE__ */ new Map();
|
|
@@ -39151,8 +39245,8 @@ var FileModelsStore = class {
|
|
|
39151
39245
|
storage;
|
|
39152
39246
|
path;
|
|
39153
39247
|
readState;
|
|
39154
|
-
constructor(
|
|
39155
|
-
this.path = normalizePath(
|
|
39248
|
+
constructor(path12 = join17(getAgentDir(), "models-store.json")) {
|
|
39249
|
+
this.path = normalizePath(path12);
|
|
39156
39250
|
this.storage = new FileAuthStorageBackend(this.path);
|
|
39157
39251
|
this.readState = sharedModelsFileReadState?.path === this.path ? sharedModelsFileReadState.readState : { data: {} };
|
|
39158
39252
|
if (!sharedModelsFileReadState) {
|
|
@@ -42126,8 +42220,8 @@ function fileResult(result, message) {
|
|
|
42126
42220
|
}
|
|
42127
42221
|
return result.value;
|
|
42128
42222
|
}
|
|
42129
|
-
function invalidFile(
|
|
42130
|
-
return new SessionError("invalid_entry", `Invalid JSONL v4 session ${
|
|
42223
|
+
function invalidFile(path12, line, message, cause) {
|
|
42224
|
+
return new SessionError("invalid_entry", `Invalid JSONL v4 session ${path12}: line ${line} ${message}`, cause);
|
|
42131
42225
|
}
|
|
42132
42226
|
|
|
42133
42227
|
// ../agent/src/harness/session/jsonl/codec.ts
|
|
@@ -42155,58 +42249,58 @@ var OPERATION_KINDS = /* @__PURE__ */ new Set(["run", "compaction", "navigation"
|
|
|
42155
42249
|
function isObject2(value) {
|
|
42156
42250
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
42157
42251
|
}
|
|
42158
|
-
function parseObject(line,
|
|
42252
|
+
function parseObject(line, path12, lineNumber) {
|
|
42159
42253
|
let value;
|
|
42160
42254
|
try {
|
|
42161
42255
|
value = JSON.parse(line);
|
|
42162
42256
|
} catch (error) {
|
|
42163
|
-
throw invalidFile(
|
|
42257
|
+
throw invalidFile(path12, lineNumber, "is not valid JSON", error instanceof Error ? error : void 0);
|
|
42164
42258
|
}
|
|
42165
|
-
if (!isObject2(value)) throw invalidFile(
|
|
42259
|
+
if (!isObject2(value)) throw invalidFile(path12, lineNumber, "is not a JSON object");
|
|
42166
42260
|
return value;
|
|
42167
42261
|
}
|
|
42168
|
-
function requireString(value,
|
|
42169
|
-
if (typeof value !== "string") throw invalidFile(
|
|
42262
|
+
function requireString(value, path12, line, field) {
|
|
42263
|
+
if (typeof value !== "string") throw invalidFile(path12, line, `has invalid ${field}`);
|
|
42170
42264
|
return value;
|
|
42171
42265
|
}
|
|
42172
|
-
function requireSequence(value,
|
|
42173
|
-
if (!Number.isSafeInteger(value) || value <= 0) throw invalidFile(
|
|
42266
|
+
function requireSequence(value, path12, line) {
|
|
42267
|
+
if (!Number.isSafeInteger(value) || value <= 0) throw invalidFile(path12, line, "has invalid seq");
|
|
42174
42268
|
return value;
|
|
42175
42269
|
}
|
|
42176
|
-
function requireTimestamp(value,
|
|
42177
|
-
if (!Number.isSafeInteger(value) || value < 0) throw invalidFile(
|
|
42270
|
+
function requireTimestamp(value, path12, line) {
|
|
42271
|
+
if (!Number.isSafeInteger(value) || value < 0) throw invalidFile(path12, line, "has invalid timestamp");
|
|
42178
42272
|
return value;
|
|
42179
42273
|
}
|
|
42180
|
-
function requireNullableId(value,
|
|
42274
|
+
function requireNullableId(value, path12, line, field) {
|
|
42181
42275
|
if (value !== null && typeof value !== "string") {
|
|
42182
|
-
throw invalidFile(
|
|
42276
|
+
throw invalidFile(path12, line, `has invalid ${field}`);
|
|
42183
42277
|
}
|
|
42184
42278
|
return value;
|
|
42185
42279
|
}
|
|
42186
|
-
function parseHeader(line,
|
|
42187
|
-
const value = parseObject(line,
|
|
42188
|
-
if (value.kind !== "header") throw invalidFile(
|
|
42189
|
-
if (value.version !== 4) throw invalidFile(
|
|
42280
|
+
function parseHeader(line, path12) {
|
|
42281
|
+
const value = parseObject(line, path12, 1);
|
|
42282
|
+
if (value.kind !== "header") throw invalidFile(path12, 1, "is not a header");
|
|
42283
|
+
if (value.version !== 4) throw invalidFile(path12, 1, "has unsupported session version");
|
|
42190
42284
|
const parentSessionId = value.parentSessionId;
|
|
42191
42285
|
if (parentSessionId !== void 0 && typeof parentSessionId !== "string") {
|
|
42192
|
-
throw invalidFile(
|
|
42286
|
+
throw invalidFile(path12, 1, "has invalid parentSessionId");
|
|
42193
42287
|
}
|
|
42194
42288
|
const legacyParentSessionPath = value.legacyParentSessionPath;
|
|
42195
42289
|
if (legacyParentSessionPath !== void 0 && typeof legacyParentSessionPath !== "string") {
|
|
42196
|
-
throw invalidFile(
|
|
42290
|
+
throw invalidFile(path12, 1, "has invalid legacyParentSessionPath");
|
|
42197
42291
|
}
|
|
42198
42292
|
if (parentSessionId !== void 0 && legacyParentSessionPath !== void 0) {
|
|
42199
|
-
throw invalidFile(
|
|
42293
|
+
throw invalidFile(path12, 1, "has both parentSessionId and legacyParentSessionPath");
|
|
42200
42294
|
}
|
|
42201
42295
|
const metadataValue = value.metadata;
|
|
42202
|
-
if (metadataValue !== void 0 && !isObject2(metadataValue)) throw invalidFile(
|
|
42296
|
+
if (metadataValue !== void 0 && !isObject2(metadataValue)) throw invalidFile(path12, 1, "has invalid metadata");
|
|
42203
42297
|
const metadata = metadataValue;
|
|
42204
42298
|
return {
|
|
42205
42299
|
kind: "header",
|
|
42206
42300
|
version: 4,
|
|
42207
|
-
id: requireString(value.id,
|
|
42208
|
-
createdAt: requireTimestamp(value.createdAt,
|
|
42209
|
-
cwd: requireString(value.cwd,
|
|
42301
|
+
id: requireString(value.id, path12, 1, "id"),
|
|
42302
|
+
createdAt: requireTimestamp(value.createdAt, path12, 1),
|
|
42303
|
+
cwd: requireString(value.cwd, path12, 1, "cwd"),
|
|
42210
42304
|
parentSessionId,
|
|
42211
42305
|
legacyParentSessionPath,
|
|
42212
42306
|
metadata
|
|
@@ -42216,12 +42310,12 @@ function encodeHeader(header) {
|
|
|
42216
42310
|
return `${JSON.stringify(header)}
|
|
42217
42311
|
`;
|
|
42218
42312
|
}
|
|
42219
|
-
function metadataFromHeader(header,
|
|
42313
|
+
function metadataFromHeader(header, path12, modifiedAt) {
|
|
42220
42314
|
return {
|
|
42221
42315
|
id: header.id,
|
|
42222
42316
|
createdAt: header.createdAt,
|
|
42223
42317
|
cwd: header.cwd,
|
|
42224
|
-
path:
|
|
42318
|
+
path: path12,
|
|
42225
42319
|
modifiedAt,
|
|
42226
42320
|
sourceFormat: 4,
|
|
42227
42321
|
...header.parentSessionId === void 0 ? {} : { parentSessionId: header.parentSessionId },
|
|
@@ -42229,38 +42323,38 @@ function metadataFromHeader(header, path11, modifiedAt) {
|
|
|
42229
42323
|
...header.metadata === void 0 ? {} : { metadata: header.metadata }
|
|
42230
42324
|
};
|
|
42231
42325
|
}
|
|
42232
|
-
function parseMutation(line,
|
|
42233
|
-
const value = parseObject(line,
|
|
42234
|
-
const seq = requireSequence(value.seq,
|
|
42326
|
+
function parseMutation(line, path12, lineNumber) {
|
|
42327
|
+
const value = parseObject(line, path12, lineNumber);
|
|
42328
|
+
const seq = requireSequence(value.seq, path12, lineNumber);
|
|
42235
42329
|
switch (value.kind) {
|
|
42236
42330
|
case "entry": {
|
|
42237
|
-
const lane = value.lane === void 0 ? void 0 : requireString(value.lane,
|
|
42238
|
-
const id = requireString(value.id,
|
|
42239
|
-
const type = requireString(value.type,
|
|
42331
|
+
const lane = value.lane === void 0 ? void 0 : requireString(value.lane, path12, lineNumber, "lane");
|
|
42332
|
+
const id = requireString(value.id, path12, lineNumber, "id");
|
|
42333
|
+
const type = requireString(value.type, path12, lineNumber, "entry type");
|
|
42240
42334
|
if (!ENTRY_TYPES.has(type))
|
|
42241
|
-
throw invalidFile(
|
|
42242
|
-
const parentId = requireNullableId(value.parentId,
|
|
42243
|
-
const timestamp = requireTimestamp(value.timestamp,
|
|
42244
|
-
if (type === "custom") requireString(value.customType,
|
|
42335
|
+
throw invalidFile(path12, lineNumber, `has unknown entry type ${type}`);
|
|
42336
|
+
const parentId = requireNullableId(value.parentId, path12, lineNumber, "parentId");
|
|
42337
|
+
const timestamp = requireTimestamp(value.timestamp, path12, lineNumber);
|
|
42338
|
+
if (type === "custom") requireString(value.customType, path12, lineNumber, "customType");
|
|
42245
42339
|
const { kind: _kind, lane: _lane, ...entryFields } = value;
|
|
42246
42340
|
const entry = { ...entryFields, id, type, parentId, seq, timestamp };
|
|
42247
42341
|
return lane === void 0 ? { kind: "entry", entry } : { kind: "entry", lane, entry };
|
|
42248
42342
|
}
|
|
42249
42343
|
case "record": {
|
|
42250
|
-
const id = requireString(value.id,
|
|
42251
|
-
const lane = requireString(value.lane,
|
|
42252
|
-
const type = requireString(value.type,
|
|
42344
|
+
const id = requireString(value.id, path12, lineNumber, "id");
|
|
42345
|
+
const lane = requireString(value.lane, path12, lineNumber, "lane");
|
|
42346
|
+
const type = requireString(value.type, path12, lineNumber, "record type");
|
|
42253
42347
|
if (!RECORD_TYPES.has(type))
|
|
42254
|
-
throw invalidFile(
|
|
42255
|
-
const timestamp = requireTimestamp(value.timestamp,
|
|
42348
|
+
throw invalidFile(path12, lineNumber, `has unknown record type ${type}`);
|
|
42349
|
+
const timestamp = requireTimestamp(value.timestamp, path12, lineNumber);
|
|
42256
42350
|
if (type === "operation_started") {
|
|
42257
|
-
if (!isObject2(value.intent)) throw invalidFile(
|
|
42258
|
-
const operationKind = requireString(value.intent.kind,
|
|
42351
|
+
if (!isObject2(value.intent)) throw invalidFile(path12, lineNumber, "has invalid intent");
|
|
42352
|
+
const operationKind = requireString(value.intent.kind, path12, lineNumber, "operation kind");
|
|
42259
42353
|
if (!OPERATION_KINDS.has(operationKind)) {
|
|
42260
|
-
throw invalidFile(
|
|
42354
|
+
throw invalidFile(path12, lineNumber, `has unknown operation kind ${operationKind}`);
|
|
42261
42355
|
}
|
|
42262
42356
|
}
|
|
42263
|
-
if (type === "operation_finished") requireString(value.runId,
|
|
42357
|
+
if (type === "operation_finished") requireString(value.runId, path12, lineNumber, "runId");
|
|
42264
42358
|
const { kind: _kind, ...recordFields } = value;
|
|
42265
42359
|
return {
|
|
42266
42360
|
kind: "record",
|
|
@@ -42271,28 +42365,28 @@ function parseMutation(line, path11, lineNumber) {
|
|
|
42271
42365
|
return {
|
|
42272
42366
|
kind: "lane",
|
|
42273
42367
|
seq,
|
|
42274
|
-
lane: requireString(value.lane,
|
|
42275
|
-
leafId: requireNullableId(value.leafId,
|
|
42368
|
+
lane: requireString(value.lane, path12, lineNumber, "lane"),
|
|
42369
|
+
leafId: requireNullableId(value.leafId, path12, lineNumber, "leafId")
|
|
42276
42370
|
};
|
|
42277
42371
|
case "fact":
|
|
42278
42372
|
if (value.fact === "name") {
|
|
42279
|
-
return { kind: "fact", seq, fact: "name", name: requireString(value.name,
|
|
42373
|
+
return { kind: "fact", seq, fact: "name", name: requireString(value.name, path12, lineNumber, "name") };
|
|
42280
42374
|
}
|
|
42281
42375
|
if (value.fact === "label") {
|
|
42282
42376
|
if (value.label !== void 0 && typeof value.label !== "string") {
|
|
42283
|
-
throw invalidFile(
|
|
42377
|
+
throw invalidFile(path12, lineNumber, "has invalid label");
|
|
42284
42378
|
}
|
|
42285
42379
|
return {
|
|
42286
42380
|
kind: "fact",
|
|
42287
42381
|
seq,
|
|
42288
42382
|
fact: "label",
|
|
42289
|
-
targetId: requireString(value.targetId,
|
|
42383
|
+
targetId: requireString(value.targetId, path12, lineNumber, "targetId"),
|
|
42290
42384
|
label: value.label
|
|
42291
42385
|
};
|
|
42292
42386
|
}
|
|
42293
|
-
throw invalidFile(
|
|
42387
|
+
throw invalidFile(path12, lineNumber, "has unknown fact type");
|
|
42294
42388
|
default:
|
|
42295
|
-
throw invalidFile(
|
|
42389
|
+
throw invalidFile(path12, lineNumber, "has unknown mutation kind");
|
|
42296
42390
|
}
|
|
42297
42391
|
}
|
|
42298
42392
|
function encodeMutation(mutation) {
|
|
@@ -42548,37 +42642,37 @@ var SessionState = class {
|
|
|
42548
42642
|
|
|
42549
42643
|
// ../agent/src/harness/session/jsonl/storage.ts
|
|
42550
42644
|
var JsonlSessionStorage = class _JsonlSessionStorage {
|
|
42551
|
-
constructor(
|
|
42645
|
+
constructor(fs8, metadata) {
|
|
42552
42646
|
this.state = new SessionState();
|
|
42553
42647
|
this.tail = Promise.resolve();
|
|
42554
|
-
this.fs =
|
|
42648
|
+
this.fs = fs8;
|
|
42555
42649
|
this.metadata = structuredClone(metadata);
|
|
42556
42650
|
}
|
|
42557
|
-
static async load(
|
|
42558
|
-
const content = fileResult(await
|
|
42651
|
+
static async load(fs8, path12) {
|
|
42652
|
+
const content = fileResult(await fs8.readTextFile(path12), `Failed to read session ${path12}`);
|
|
42559
42653
|
const physicalLines = content.split("\n");
|
|
42560
42654
|
if (physicalLines.at(-1) === "") physicalLines.pop();
|
|
42561
|
-
if (physicalLines.length === 0 || !physicalLines[0]) throw invalidFile(
|
|
42562
|
-
const header = parseHeader(physicalLines[0],
|
|
42563
|
-
const fileInfo = fileResult(await
|
|
42564
|
-
const storage = new _JsonlSessionStorage(
|
|
42655
|
+
if (physicalLines.length === 0 || !physicalLines[0]) throw invalidFile(path12, 1, "is missing a header");
|
|
42656
|
+
const header = parseHeader(physicalLines[0], path12);
|
|
42657
|
+
const fileInfo = fileResult(await fs8.fileInfo(path12), `Failed to read session metadata ${path12}`);
|
|
42658
|
+
const storage = new _JsonlSessionStorage(fs8, metadataFromHeader(header, path12, fileInfo.mtimeMs));
|
|
42565
42659
|
for (let index = 1; index < physicalLines.length; index++) {
|
|
42566
42660
|
const line = physicalLines[index];
|
|
42567
42661
|
let mutation;
|
|
42568
42662
|
try {
|
|
42569
|
-
mutation = parseMutation(line,
|
|
42663
|
+
mutation = parseMutation(line, path12, index + 1);
|
|
42570
42664
|
} catch (error) {
|
|
42571
42665
|
if (index !== physicalLines.length - 1 || !(error instanceof SessionError) || error.cause === void 0)
|
|
42572
42666
|
throw error;
|
|
42573
42667
|
const validPrefix = `${physicalLines.slice(0, index).join("\n")}
|
|
42574
42668
|
`;
|
|
42575
|
-
fileResult(await
|
|
42669
|
+
fileResult(await fs8.writeFile(path12, validPrefix), `Failed to truncate torn session tail ${path12}`);
|
|
42576
42670
|
return storage;
|
|
42577
42671
|
}
|
|
42578
|
-
storage.applyMutation(mutation,
|
|
42672
|
+
storage.applyMutation(mutation, path12, index + 1);
|
|
42579
42673
|
}
|
|
42580
42674
|
if (!content.endsWith("\n")) {
|
|
42581
|
-
fileResult(await
|
|
42675
|
+
fileResult(await fs8.appendFile(path12, "\n"), `Failed to repair unterminated session tail ${path12}`);
|
|
42582
42676
|
}
|
|
42583
42677
|
return storage;
|
|
42584
42678
|
}
|
|
@@ -42729,9 +42823,9 @@ var JsonlSessionStorage = class _JsonlSessionStorage {
|
|
|
42729
42823
|
`Failed to append session ${this.metadata.path}`
|
|
42730
42824
|
);
|
|
42731
42825
|
}
|
|
42732
|
-
applyMutation(mutation,
|
|
42826
|
+
applyMutation(mutation, path12 = this.metadata.path, line = this.state.nextSequence + 1) {
|
|
42733
42827
|
this.state.applyMutation(mutation, (message) => {
|
|
42734
|
-
throw invalidFile(
|
|
42828
|
+
throw invalidFile(path12, line, message);
|
|
42735
42829
|
});
|
|
42736
42830
|
}
|
|
42737
42831
|
};
|
|
@@ -42825,7 +42919,7 @@ var JsonlSessionRepo = class {
|
|
|
42825
42919
|
const cwd = fileResult(await this.fs.absolutePath(options.cwd), `Failed to resolve session cwd ${options.cwd}`);
|
|
42826
42920
|
const createdAt = Date.now();
|
|
42827
42921
|
const sessionDirectory = await this.sessionDirectory(cwd);
|
|
42828
|
-
const
|
|
42922
|
+
const path12 = fileResult(
|
|
42829
42923
|
await this.fs.joinPath([sessionDirectory, sessionFileName(createdAt, id)]),
|
|
42830
42924
|
`Failed to resolve path for session ${id}`
|
|
42831
42925
|
);
|
|
@@ -42840,9 +42934,9 @@ var JsonlSessionRepo = class {
|
|
|
42840
42934
|
metadata: options.metadata
|
|
42841
42935
|
};
|
|
42842
42936
|
fileResult(await this.fs.createDir(sessionDirectory, { recursive: true }), `Failed to create sessions directory`);
|
|
42843
|
-
fileResult(await this.fs.writeFile(
|
|
42844
|
-
const fileInfo = fileResult(await this.fs.fileInfo(
|
|
42845
|
-
const storage = new JsonlSessionStorage(this.fs, metadataFromHeader(header,
|
|
42937
|
+
fileResult(await this.fs.writeFile(path12, encodeHeader(header)), `Failed to create session ${path12}`);
|
|
42938
|
+
const fileInfo = fileResult(await this.fs.fileInfo(path12), `Failed to read session metadata ${path12}`);
|
|
42939
|
+
const storage = new JsonlSessionStorage(this.fs, metadataFromHeader(header, path12, fileInfo.mtimeMs));
|
|
42846
42940
|
return { session: new Session(storage), storage };
|
|
42847
42941
|
}
|
|
42848
42942
|
async listDirect(options) {
|
|
@@ -43105,11 +43199,11 @@ function toError(error) {
|
|
|
43105
43199
|
}
|
|
43106
43200
|
}
|
|
43107
43201
|
var FileError = class extends Error {
|
|
43108
|
-
constructor(code, message,
|
|
43202
|
+
constructor(code, message, path12, cause) {
|
|
43109
43203
|
super(message, cause === void 0 ? void 0 : { cause });
|
|
43110
43204
|
this.name = "FileError";
|
|
43111
43205
|
this.code = code;
|
|
43112
|
-
this.path =
|
|
43206
|
+
this.path = path12;
|
|
43113
43207
|
}
|
|
43114
43208
|
};
|
|
43115
43209
|
var ExecutionError = class extends Error {
|
|
@@ -43151,17 +43245,17 @@ function extractFileOpsFromMessage(message, fileOps) {
|
|
|
43151
43245
|
if (!("arguments" in block) || !("name" in block)) continue;
|
|
43152
43246
|
const args = block.arguments;
|
|
43153
43247
|
if (!args) continue;
|
|
43154
|
-
const
|
|
43155
|
-
if (!
|
|
43248
|
+
const path12 = typeof args.path === "string" ? args.path : void 0;
|
|
43249
|
+
if (!path12) continue;
|
|
43156
43250
|
switch (block.name) {
|
|
43157
43251
|
case "read":
|
|
43158
|
-
fileOps.read.add(
|
|
43252
|
+
fileOps.read.add(path12);
|
|
43159
43253
|
break;
|
|
43160
43254
|
case "write":
|
|
43161
|
-
fileOps.written.add(
|
|
43255
|
+
fileOps.written.add(path12);
|
|
43162
43256
|
break;
|
|
43163
43257
|
case "edit":
|
|
43164
|
-
fileOps.edited.add(
|
|
43258
|
+
fileOps.edited.add(path12);
|
|
43165
43259
|
break;
|
|
43166
43260
|
}
|
|
43167
43261
|
}
|
|
@@ -44057,15 +44151,15 @@ import { parse } from "yaml";
|
|
|
44057
44151
|
async function loadPromptTemplates(env, paths) {
|
|
44058
44152
|
const promptTemplates = [];
|
|
44059
44153
|
const diagnostics = [];
|
|
44060
|
-
for (const
|
|
44061
|
-
const infoResult = await env.fileInfo(
|
|
44154
|
+
for (const path12 of Array.isArray(paths) ? paths : [paths]) {
|
|
44155
|
+
const infoResult = await env.fileInfo(path12);
|
|
44062
44156
|
if (!infoResult.ok) {
|
|
44063
44157
|
if (infoResult.error.code !== "not_found") {
|
|
44064
44158
|
diagnostics.push({
|
|
44065
44159
|
type: "warning",
|
|
44066
44160
|
code: "file_info_failed",
|
|
44067
44161
|
message: infoResult.error.message,
|
|
44068
|
-
path:
|
|
44162
|
+
path: path12
|
|
44069
44163
|
});
|
|
44070
44164
|
}
|
|
44071
44165
|
continue;
|
|
@@ -44539,15 +44633,15 @@ async function resolveKind2(env, info, diagnostics) {
|
|
|
44539
44633
|
}
|
|
44540
44634
|
return target.value.kind === "file" || target.value.kind === "directory" ? target.value.kind : void 0;
|
|
44541
44635
|
}
|
|
44542
|
-
function dirnameEnvPath(
|
|
44543
|
-
const normalized =
|
|
44636
|
+
function dirnameEnvPath(path12) {
|
|
44637
|
+
const normalized = path12.replace(/[\\/]+$/, "");
|
|
44544
44638
|
const separatorIndex = Math.max(normalized.lastIndexOf("/"), normalized.lastIndexOf("\\"));
|
|
44545
44639
|
if (separatorIndex === 2 && normalized[1] === ":") return normalized.slice(0, 3);
|
|
44546
44640
|
return separatorIndex <= 0 ? "/" : normalized.slice(0, separatorIndex);
|
|
44547
44641
|
}
|
|
44548
|
-
function relativeEnvPath(root,
|
|
44642
|
+
function relativeEnvPath(root, path12) {
|
|
44549
44643
|
const normalizedRoot = root.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
44550
|
-
const normalizedPath =
|
|
44644
|
+
const normalizedPath = path12.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
44551
44645
|
if (normalizedPath === normalizedRoot) return "";
|
|
44552
44646
|
return normalizedPath.startsWith(`${normalizedRoot}/`) ? normalizedPath.slice(normalizedRoot.length + 1) : normalizedPath.replace(/^\/+/, "");
|
|
44553
44647
|
}
|
|
@@ -45671,48 +45765,48 @@ function countOccurrences(content, oldText) {
|
|
|
45671
45765
|
const fuzzyOldText = normalizeForFuzzyMatch(oldText);
|
|
45672
45766
|
return fuzzyContent.split(fuzzyOldText).length - 1;
|
|
45673
45767
|
}
|
|
45674
|
-
function getNotFoundError(
|
|
45768
|
+
function getNotFoundError(path12, editIndex, totalEdits) {
|
|
45675
45769
|
if (totalEdits === 1) {
|
|
45676
45770
|
return new Error(
|
|
45677
|
-
`Could not find the exact text in ${
|
|
45771
|
+
`Could not find the exact text in ${path12}. The old text must match exactly including all whitespace and newlines.`
|
|
45678
45772
|
);
|
|
45679
45773
|
}
|
|
45680
45774
|
return new Error(
|
|
45681
|
-
`Could not find edits[${editIndex}] in ${
|
|
45775
|
+
`Could not find edits[${editIndex}] in ${path12}. The oldText must match exactly including all whitespace and newlines.`
|
|
45682
45776
|
);
|
|
45683
45777
|
}
|
|
45684
|
-
function getDuplicateError(
|
|
45778
|
+
function getDuplicateError(path12, editIndex, totalEdits, occurrences) {
|
|
45685
45779
|
if (totalEdits === 1) {
|
|
45686
45780
|
return new Error(
|
|
45687
|
-
`Found ${occurrences} occurrences of the text in ${
|
|
45781
|
+
`Found ${occurrences} occurrences of the text in ${path12}. The text must be unique. Please provide more context to make it unique.`
|
|
45688
45782
|
);
|
|
45689
45783
|
}
|
|
45690
45784
|
return new Error(
|
|
45691
|
-
`Found ${occurrences} occurrences of edits[${editIndex}] in ${
|
|
45785
|
+
`Found ${occurrences} occurrences of edits[${editIndex}] in ${path12}. Each oldText must be unique. Please provide more context to make it unique.`
|
|
45692
45786
|
);
|
|
45693
45787
|
}
|
|
45694
|
-
function getEmptyOldTextError(
|
|
45788
|
+
function getEmptyOldTextError(path12, editIndex, totalEdits) {
|
|
45695
45789
|
if (totalEdits === 1) {
|
|
45696
|
-
return new Error(`oldText must not be empty in ${
|
|
45790
|
+
return new Error(`oldText must not be empty in ${path12}.`);
|
|
45697
45791
|
}
|
|
45698
|
-
return new Error(`edits[${editIndex}].oldText must not be empty in ${
|
|
45792
|
+
return new Error(`edits[${editIndex}].oldText must not be empty in ${path12}.`);
|
|
45699
45793
|
}
|
|
45700
|
-
function getNoChangeError(
|
|
45794
|
+
function getNoChangeError(path12, totalEdits) {
|
|
45701
45795
|
if (totalEdits === 1) {
|
|
45702
45796
|
return new Error(
|
|
45703
|
-
`No changes made to ${
|
|
45797
|
+
`No changes made to ${path12}. The replacement produced identical content. This might indicate an issue with special characters or the text not existing as expected.`
|
|
45704
45798
|
);
|
|
45705
45799
|
}
|
|
45706
|
-
return new Error(`No changes made to ${
|
|
45800
|
+
return new Error(`No changes made to ${path12}. The replacements produced identical content.`);
|
|
45707
45801
|
}
|
|
45708
|
-
function applyEditsToNormalizedContent(normalizedContent, edits,
|
|
45802
|
+
function applyEditsToNormalizedContent(normalizedContent, edits, path12) {
|
|
45709
45803
|
const normalizedEdits = edits.map((edit) => ({
|
|
45710
45804
|
oldText: normalizeToLF(edit.oldText),
|
|
45711
45805
|
newText: normalizeToLF(edit.newText)
|
|
45712
45806
|
}));
|
|
45713
45807
|
for (let i = 0; i < normalizedEdits.length; i++) {
|
|
45714
45808
|
if (normalizedEdits[i].oldText.length === 0) {
|
|
45715
|
-
throw getEmptyOldTextError(
|
|
45809
|
+
throw getEmptyOldTextError(path12, i, normalizedEdits.length);
|
|
45716
45810
|
}
|
|
45717
45811
|
}
|
|
45718
45812
|
const initialMatches = normalizedEdits.map((edit) => fuzzyFindText(normalizedContent, edit.oldText));
|
|
@@ -45723,11 +45817,11 @@ function applyEditsToNormalizedContent(normalizedContent, edits, path11) {
|
|
|
45723
45817
|
const edit = normalizedEdits[i];
|
|
45724
45818
|
const matchResult = fuzzyFindText(replacementBaseContent, edit.oldText);
|
|
45725
45819
|
if (!matchResult.found) {
|
|
45726
|
-
throw getNotFoundError(
|
|
45820
|
+
throw getNotFoundError(path12, i, normalizedEdits.length);
|
|
45727
45821
|
}
|
|
45728
45822
|
const occurrences = countOccurrences(replacementBaseContent, edit.oldText);
|
|
45729
45823
|
if (occurrences > 1) {
|
|
45730
|
-
throw getDuplicateError(
|
|
45824
|
+
throw getDuplicateError(path12, i, normalizedEdits.length, occurrences);
|
|
45731
45825
|
}
|
|
45732
45826
|
matchedEdits.push({
|
|
45733
45827
|
editIndex: i,
|
|
@@ -45742,19 +45836,19 @@ function applyEditsToNormalizedContent(normalizedContent, edits, path11) {
|
|
|
45742
45836
|
const current = matchedEdits[i];
|
|
45743
45837
|
if (previous.matchIndex + previous.matchLength > current.matchIndex) {
|
|
45744
45838
|
throw new Error(
|
|
45745
|
-
`edits[${previous.editIndex}] and edits[${current.editIndex}] overlap in ${
|
|
45839
|
+
`edits[${previous.editIndex}] and edits[${current.editIndex}] overlap in ${path12}. Merge them into one edit or target disjoint regions.`
|
|
45746
45840
|
);
|
|
45747
45841
|
}
|
|
45748
45842
|
}
|
|
45749
45843
|
const baseContent = normalizedContent;
|
|
45750
45844
|
const newContent = usedFuzzyMatch ? applyReplacementsPreservingUnchangedLines(normalizedContent, replacementBaseContent, matchedEdits) : applyReplacements(replacementBaseContent, matchedEdits);
|
|
45751
45845
|
if (baseContent === newContent) {
|
|
45752
|
-
throw getNoChangeError(
|
|
45846
|
+
throw getNoChangeError(path12, normalizedEdits.length);
|
|
45753
45847
|
}
|
|
45754
45848
|
return { baseContent, newContent };
|
|
45755
45849
|
}
|
|
45756
|
-
function generateUnifiedPatch(
|
|
45757
|
-
return Diff.createTwoFilesPatch(
|
|
45850
|
+
function generateUnifiedPatch(path12, oldContent, newContent, contextLines = 4) {
|
|
45851
|
+
return Diff.createTwoFilesPatch(path12, path12, oldContent, newContent, void 0, void 0, {
|
|
45758
45852
|
context: contextLines,
|
|
45759
45853
|
headerOptions: Diff.FILE_HEADERS_ONLY
|
|
45760
45854
|
});
|
|
@@ -45871,17 +45965,17 @@ function getState(env) {
|
|
|
45871
45965
|
}
|
|
45872
45966
|
return state2;
|
|
45873
45967
|
}
|
|
45874
|
-
async function getMutationQueueKey(env,
|
|
45875
|
-
const absolutePath = getOrThrow(await env.absolutePath(
|
|
45968
|
+
async function getMutationQueueKey(env, path12) {
|
|
45969
|
+
const absolutePath = getOrThrow(await env.absolutePath(path12));
|
|
45876
45970
|
const canonicalPath = await env.canonicalPath(absolutePath);
|
|
45877
45971
|
if (canonicalPath.ok) return canonicalPath.value;
|
|
45878
45972
|
if (canonicalPath.error.code === "not_found" || canonicalPath.error.code === "not_supported") return absolutePath;
|
|
45879
45973
|
throw canonicalPath.error;
|
|
45880
45974
|
}
|
|
45881
|
-
async function withFileMutationQueue(env,
|
|
45975
|
+
async function withFileMutationQueue(env, path12, fn) {
|
|
45882
45976
|
const state2 = getState(env);
|
|
45883
45977
|
const registration = state2.registration.then(async () => {
|
|
45884
|
-
const key2 = await getMutationQueueKey(env,
|
|
45978
|
+
const key2 = await getMutationQueueKey(env, path12);
|
|
45885
45979
|
const currentQueue2 = state2.queues.get(key2) ?? Promise.resolve();
|
|
45886
45980
|
let releaseNext2 = () => {
|
|
45887
45981
|
};
|
|
@@ -45909,15 +46003,15 @@ async function withFileMutationQueue(env, path11, fn) {
|
|
|
45909
46003
|
// ../agent/src/harness/tools/path-utils.ts
|
|
45910
46004
|
var UNICODE_SPACES2 = /[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g;
|
|
45911
46005
|
var NARROW_NO_BREAK_SPACE2 = "\u202F";
|
|
45912
|
-
function normalizeToolPath(
|
|
45913
|
-
const normalized =
|
|
46006
|
+
function normalizeToolPath(path12) {
|
|
46007
|
+
const normalized = path12.replace(UNICODE_SPACES2, " ");
|
|
45914
46008
|
return normalized.startsWith("@") ? normalized.slice(1) : normalized;
|
|
45915
46009
|
}
|
|
45916
|
-
async function resolveToolPath(env,
|
|
45917
|
-
return getOrThrow(await env.absolutePath(normalizeToolPath(
|
|
46010
|
+
async function resolveToolPath(env, path12, signal) {
|
|
46011
|
+
return getOrThrow(await env.absolutePath(normalizeToolPath(path12), signal));
|
|
45918
46012
|
}
|
|
45919
|
-
async function resolveReadToolPath(env,
|
|
45920
|
-
const resolved = await resolveToolPath(env,
|
|
46013
|
+
async function resolveReadToolPath(env, path12, signal) {
|
|
46014
|
+
const resolved = await resolveToolPath(env, path12, signal);
|
|
45921
46015
|
const variants = [
|
|
45922
46016
|
resolved,
|
|
45923
46017
|
resolved.replace(/ (AM|PM)\./gi, `${NARROW_NO_BREAK_SPACE2}$1.`),
|
|
@@ -45973,8 +46067,8 @@ function validateEditInput(input) {
|
|
|
45973
46067
|
}
|
|
45974
46068
|
return { path: input.path, edits: input.edits };
|
|
45975
46069
|
}
|
|
45976
|
-
function editAccessError(
|
|
45977
|
-
return new Error(`Could not edit file: ${
|
|
46070
|
+
function editAccessError(path12, error) {
|
|
46071
|
+
return new Error(`Could not edit file: ${path12}. Error code: ${error.code}.`, { cause: error });
|
|
45978
46072
|
}
|
|
45979
46073
|
function createEditTool() {
|
|
45980
46074
|
return {
|
|
@@ -45984,33 +46078,33 @@ function createEditTool() {
|
|
|
45984
46078
|
parameters: editSchema,
|
|
45985
46079
|
prepareArguments: prepareEditArguments,
|
|
45986
46080
|
async execute(_toolCallId, input, signal, _onUpdate, { env }) {
|
|
45987
|
-
const { path:
|
|
45988
|
-
const absolutePath = await resolveToolPath(env,
|
|
46081
|
+
const { path: path12, edits } = validateEditInput(input);
|
|
46082
|
+
const absolutePath = await resolveToolPath(env, path12, signal);
|
|
45989
46083
|
return withFileMutationQueue(env, absolutePath, async () => {
|
|
45990
46084
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
45991
46085
|
const info = await env.fileInfo(absolutePath, signal);
|
|
45992
|
-
if (!info.ok) throw editAccessError(
|
|
46086
|
+
if (!info.ok) throw editAccessError(path12, info.error);
|
|
45993
46087
|
if (info.value.kind !== "file" && info.value.kind !== "symlink") {
|
|
45994
|
-
throw new Error(`Could not edit file: ${
|
|
46088
|
+
throw new Error(`Could not edit file: ${path12}. Path is not a file.`);
|
|
45995
46089
|
}
|
|
45996
46090
|
const readResult = await env.readTextFile(absolutePath, signal);
|
|
45997
|
-
if (!readResult.ok) throw editAccessError(
|
|
46091
|
+
if (!readResult.ok) throw editAccessError(path12, readResult.error);
|
|
45998
46092
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
45999
46093
|
const { bom, text: content } = stripBom(readResult.value);
|
|
46000
46094
|
const originalEnding = detectLineEnding(content);
|
|
46001
46095
|
const normalizedContent = normalizeToLF(content);
|
|
46002
|
-
const { baseContent, newContent } = applyEditsToNormalizedContent(normalizedContent, edits,
|
|
46096
|
+
const { baseContent, newContent } = applyEditsToNormalizedContent(normalizedContent, edits, path12);
|
|
46003
46097
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
46004
46098
|
const finalContent = bom + restoreLineEndings(newContent, originalEnding);
|
|
46005
46099
|
const writeResult = await env.writeFile(absolutePath, finalContent, signal);
|
|
46006
|
-
if (!writeResult.ok) throw editAccessError(
|
|
46100
|
+
if (!writeResult.ok) throw editAccessError(path12, writeResult.error);
|
|
46007
46101
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
46008
46102
|
const diffResult = generateDiffString(baseContent, newContent);
|
|
46009
46103
|
return {
|
|
46010
|
-
content: [{ type: "text", text: `Successfully replaced ${edits.length} block(s) in ${
|
|
46104
|
+
content: [{ type: "text", text: `Successfully replaced ${edits.length} block(s) in ${path12}.` }],
|
|
46011
46105
|
details: {
|
|
46012
46106
|
diff: diffResult.diff,
|
|
46013
|
-
patch: generateUnifiedPatch(
|
|
46107
|
+
patch: generateUnifiedPatch(path12, baseContent, newContent),
|
|
46014
46108
|
firstChangedLine: diffResult.firstChangedLine
|
|
46015
46109
|
}
|
|
46016
46110
|
};
|
|
@@ -46117,8 +46211,8 @@ function createReadTool(options) {
|
|
|
46117
46211
|
label: "read",
|
|
46118
46212
|
description: `Read the contents of a file. Supports text files and images (jpg, png, gif, webp, bmp). Images are sent as attachments. For text files, output is truncated to ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES2 / 1024}KB (whichever is hit first). Use offset/limit for large files. When you need the full file, continue with offset until complete.`,
|
|
46119
46213
|
parameters: readSchema,
|
|
46120
|
-
async execute(_toolCallId, { path:
|
|
46121
|
-
const absolutePath = await resolveReadToolPath(env,
|
|
46214
|
+
async execute(_toolCallId, { path: path12, offset, limit }, signal, _onUpdate, { env }) {
|
|
46215
|
+
const absolutePath = await resolveReadToolPath(env, path12, signal);
|
|
46122
46216
|
const bytes = getOrThrow(await env.readBinaryFile(absolutePath, signal));
|
|
46123
46217
|
const mimeType = detectSupportedImageMimeType2(bytes);
|
|
46124
46218
|
if (mimeType) {
|
|
@@ -46184,7 +46278,7 @@ ${processed.hints.join("\n")}` : "";
|
|
|
46184
46278
|
let details;
|
|
46185
46279
|
if (truncation.firstLineExceedsLimit) {
|
|
46186
46280
|
const firstLineSize = formatSize(new TextEncoder().encode(allLines[startLine]).byteLength);
|
|
46187
|
-
outputText = `[Line ${startLineDisplay} is ${firstLineSize}, exceeds ${formatSize(DEFAULT_MAX_BYTES2)} limit. Use bash: sed -n '${startLineDisplay}p' ${
|
|
46281
|
+
outputText = `[Line ${startLineDisplay} is ${firstLineSize}, exceeds ${formatSize(DEFAULT_MAX_BYTES2)} limit. Use bash: sed -n '${startLineDisplay}p' ${path12} | head -c ${DEFAULT_MAX_BYTES2}]`;
|
|
46188
46282
|
details = { truncation };
|
|
46189
46283
|
} else if (truncation.truncated) {
|
|
46190
46284
|
const endLineDisplay = startLineDisplay + truncation.outputLines - 1;
|
|
@@ -46226,14 +46320,14 @@ function createWriteTool() {
|
|
|
46226
46320
|
label: "write",
|
|
46227
46321
|
description: "Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Automatically creates parent directories.",
|
|
46228
46322
|
parameters: writeSchema,
|
|
46229
|
-
async execute(_toolCallId, { path:
|
|
46230
|
-
const absolutePath = await resolveToolPath(env,
|
|
46323
|
+
async execute(_toolCallId, { path: path12, content }, signal, _onUpdate, { env }) {
|
|
46324
|
+
const absolutePath = await resolveToolPath(env, path12, signal);
|
|
46231
46325
|
return withFileMutationQueue(env, absolutePath, async () => {
|
|
46232
46326
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
46233
46327
|
getOrThrow(await env.writeFile(absolutePath, content, signal));
|
|
46234
46328
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
46235
46329
|
return {
|
|
46236
|
-
content: [{ type: "text", text: `Successfully wrote ${content.length} bytes to ${
|
|
46330
|
+
content: [{ type: "text", text: `Successfully wrote ${content.length} bytes to ${path12}` }],
|
|
46237
46331
|
details: void 0
|
|
46238
46332
|
};
|
|
46239
46333
|
});
|
|
@@ -47028,18 +47122,18 @@ function extractFileOpsFromMessage2(message, fileOps) {
|
|
|
47028
47122
|
const args = block.arguments;
|
|
47029
47123
|
if (!args)
|
|
47030
47124
|
continue;
|
|
47031
|
-
const
|
|
47032
|
-
if (!
|
|
47125
|
+
const path12 = typeof args.path === "string" ? args.path : void 0;
|
|
47126
|
+
if (!path12)
|
|
47033
47127
|
continue;
|
|
47034
47128
|
switch (block.name) {
|
|
47035
47129
|
case "read":
|
|
47036
|
-
fileOps.read.add(
|
|
47130
|
+
fileOps.read.add(path12);
|
|
47037
47131
|
break;
|
|
47038
47132
|
case "write":
|
|
47039
|
-
fileOps.written.add(
|
|
47133
|
+
fileOps.written.add(path12);
|
|
47040
47134
|
break;
|
|
47041
47135
|
case "edit":
|
|
47042
|
-
fileOps.edited.add(
|
|
47136
|
+
fileOps.edited.add(path12);
|
|
47043
47137
|
break;
|
|
47044
47138
|
}
|
|
47045
47139
|
}
|
|
@@ -48463,18 +48557,18 @@ import { existsSync as existsSync14, readdirSync as readdirSync5, readFileSync a
|
|
|
48463
48557
|
import { basename as basename5, dirname as dirname11, join as join21, resolve as resolve5, sep as sep4 } from "path";
|
|
48464
48558
|
|
|
48465
48559
|
// dist/core/source-info.js
|
|
48466
|
-
function createSourceInfo(
|
|
48560
|
+
function createSourceInfo(path12, metadata) {
|
|
48467
48561
|
return {
|
|
48468
|
-
path:
|
|
48562
|
+
path: path12,
|
|
48469
48563
|
source: metadata.source,
|
|
48470
48564
|
scope: metadata.scope,
|
|
48471
48565
|
origin: metadata.origin,
|
|
48472
48566
|
baseDir: metadata.baseDir
|
|
48473
48567
|
};
|
|
48474
48568
|
}
|
|
48475
|
-
function createSyntheticSourceInfo(
|
|
48569
|
+
function createSyntheticSourceInfo(path12, options) {
|
|
48476
48570
|
return {
|
|
48477
|
-
path:
|
|
48571
|
+
path: path12,
|
|
48478
48572
|
source: options.source,
|
|
48479
48573
|
scope: options.scope ?? "temporary",
|
|
48480
48574
|
origin: options.origin ?? "top-level",
|
|
@@ -49316,14 +49410,14 @@ var OutputAccumulator = class {
|
|
|
49316
49410
|
// dist/core/tools/render-utils.js
|
|
49317
49411
|
import * as os3 from "node:os";
|
|
49318
49412
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
49319
|
-
function shortenPath2(
|
|
49320
|
-
if (typeof
|
|
49413
|
+
function shortenPath2(path12) {
|
|
49414
|
+
if (typeof path12 !== "string")
|
|
49321
49415
|
return "";
|
|
49322
49416
|
const home = os3.homedir();
|
|
49323
|
-
if (
|
|
49324
|
-
return `~${
|
|
49417
|
+
if (path12.startsWith(home)) {
|
|
49418
|
+
return `~${path12.slice(home.length)}`;
|
|
49325
49419
|
}
|
|
49326
|
-
return
|
|
49420
|
+
return path12;
|
|
49327
49421
|
}
|
|
49328
49422
|
function linkPath(styledText, rawPath, cwd) {
|
|
49329
49423
|
if (!getCapabilities().hyperlinks)
|
|
@@ -49978,38 +50072,38 @@ function countOccurrences2(content, oldText) {
|
|
|
49978
50072
|
const fuzzyOldText = normalizeForFuzzyMatch2(oldText);
|
|
49979
50073
|
return fuzzyContent.split(fuzzyOldText).length - 1;
|
|
49980
50074
|
}
|
|
49981
|
-
function getNotFoundError2(
|
|
50075
|
+
function getNotFoundError2(path12, editIndex, totalEdits) {
|
|
49982
50076
|
if (totalEdits === 1) {
|
|
49983
|
-
return new Error(`Could not find the exact text in ${
|
|
50077
|
+
return new Error(`Could not find the exact text in ${path12}. The old text must match exactly including all whitespace and newlines.`);
|
|
49984
50078
|
}
|
|
49985
|
-
return new Error(`Could not find edits[${editIndex}] in ${
|
|
50079
|
+
return new Error(`Could not find edits[${editIndex}] in ${path12}. The oldText must match exactly including all whitespace and newlines.`);
|
|
49986
50080
|
}
|
|
49987
|
-
function getDuplicateError2(
|
|
50081
|
+
function getDuplicateError2(path12, editIndex, totalEdits, occurrences) {
|
|
49988
50082
|
if (totalEdits === 1) {
|
|
49989
|
-
return new Error(`Found ${occurrences} occurrences of the text in ${
|
|
50083
|
+
return new Error(`Found ${occurrences} occurrences of the text in ${path12}. The text must be unique. Please provide more context to make it unique.`);
|
|
49990
50084
|
}
|
|
49991
|
-
return new Error(`Found ${occurrences} occurrences of edits[${editIndex}] in ${
|
|
50085
|
+
return new Error(`Found ${occurrences} occurrences of edits[${editIndex}] in ${path12}. Each oldText must be unique. Please provide more context to make it unique.`);
|
|
49992
50086
|
}
|
|
49993
|
-
function getEmptyOldTextError2(
|
|
50087
|
+
function getEmptyOldTextError2(path12, editIndex, totalEdits) {
|
|
49994
50088
|
if (totalEdits === 1) {
|
|
49995
|
-
return new Error(`oldText must not be empty in ${
|
|
50089
|
+
return new Error(`oldText must not be empty in ${path12}.`);
|
|
49996
50090
|
}
|
|
49997
|
-
return new Error(`edits[${editIndex}].oldText must not be empty in ${
|
|
50091
|
+
return new Error(`edits[${editIndex}].oldText must not be empty in ${path12}.`);
|
|
49998
50092
|
}
|
|
49999
|
-
function getNoChangeError2(
|
|
50093
|
+
function getNoChangeError2(path12, totalEdits) {
|
|
50000
50094
|
if (totalEdits === 1) {
|
|
50001
|
-
return new Error(`No changes made to ${
|
|
50095
|
+
return new Error(`No changes made to ${path12}. The replacement produced identical content. This might indicate an issue with special characters or the text not existing as expected.`);
|
|
50002
50096
|
}
|
|
50003
|
-
return new Error(`No changes made to ${
|
|
50097
|
+
return new Error(`No changes made to ${path12}. The replacements produced identical content.`);
|
|
50004
50098
|
}
|
|
50005
|
-
function applyEditsToNormalizedContent2(normalizedContent, edits,
|
|
50099
|
+
function applyEditsToNormalizedContent2(normalizedContent, edits, path12) {
|
|
50006
50100
|
const normalizedEdits = edits.map((edit) => ({
|
|
50007
50101
|
oldText: normalizeToLF2(edit.oldText),
|
|
50008
50102
|
newText: normalizeToLF2(edit.newText)
|
|
50009
50103
|
}));
|
|
50010
50104
|
for (let i = 0; i < normalizedEdits.length; i++) {
|
|
50011
50105
|
if (normalizedEdits[i].oldText.length === 0) {
|
|
50012
|
-
throw getEmptyOldTextError2(
|
|
50106
|
+
throw getEmptyOldTextError2(path12, i, normalizedEdits.length);
|
|
50013
50107
|
}
|
|
50014
50108
|
}
|
|
50015
50109
|
const initialMatches = normalizedEdits.map((edit) => fuzzyFindText2(normalizedContent, edit.oldText));
|
|
@@ -50020,11 +50114,11 @@ function applyEditsToNormalizedContent2(normalizedContent, edits, path11) {
|
|
|
50020
50114
|
const edit = normalizedEdits[i];
|
|
50021
50115
|
const matchResult = fuzzyFindText2(replacementBaseContent, edit.oldText);
|
|
50022
50116
|
if (!matchResult.found) {
|
|
50023
|
-
throw getNotFoundError2(
|
|
50117
|
+
throw getNotFoundError2(path12, i, normalizedEdits.length);
|
|
50024
50118
|
}
|
|
50025
50119
|
const occurrences = countOccurrences2(replacementBaseContent, edit.oldText);
|
|
50026
50120
|
if (occurrences > 1) {
|
|
50027
|
-
throw getDuplicateError2(
|
|
50121
|
+
throw getDuplicateError2(path12, i, normalizedEdits.length, occurrences);
|
|
50028
50122
|
}
|
|
50029
50123
|
matchedEdits.push({
|
|
50030
50124
|
editIndex: i,
|
|
@@ -50038,18 +50132,18 @@ function applyEditsToNormalizedContent2(normalizedContent, edits, path11) {
|
|
|
50038
50132
|
const previous = matchedEdits[i - 1];
|
|
50039
50133
|
const current = matchedEdits[i];
|
|
50040
50134
|
if (previous.matchIndex + previous.matchLength > current.matchIndex) {
|
|
50041
|
-
throw new Error(`edits[${previous.editIndex}] and edits[${current.editIndex}] overlap in ${
|
|
50135
|
+
throw new Error(`edits[${previous.editIndex}] and edits[${current.editIndex}] overlap in ${path12}. Merge them into one edit or target disjoint regions.`);
|
|
50042
50136
|
}
|
|
50043
50137
|
}
|
|
50044
50138
|
const baseContent = normalizedContent;
|
|
50045
50139
|
const newContent = usedFuzzyMatch ? applyReplacementsPreservingUnchangedLines2(normalizedContent, replacementBaseContent, matchedEdits) : applyReplacements2(replacementBaseContent, matchedEdits);
|
|
50046
50140
|
if (baseContent === newContent) {
|
|
50047
|
-
throw getNoChangeError2(
|
|
50141
|
+
throw getNoChangeError2(path12, normalizedEdits.length);
|
|
50048
50142
|
}
|
|
50049
50143
|
return { baseContent, newContent };
|
|
50050
50144
|
}
|
|
50051
|
-
function generateUnifiedPatch2(
|
|
50052
|
-
return Diff3.createTwoFilesPatch(
|
|
50145
|
+
function generateUnifiedPatch2(path12, oldContent, newContent, contextLines = 4) {
|
|
50146
|
+
return Diff3.createTwoFilesPatch(path12, path12, oldContent, newContent, void 0, void 0, {
|
|
50053
50147
|
context: contextLines,
|
|
50054
50148
|
headerOptions: Diff3.FILE_HEADERS_ONLY
|
|
50055
50149
|
});
|
|
@@ -50155,19 +50249,19 @@ function generateDiffString2(oldContent, newContent, contextLines = 4) {
|
|
|
50155
50249
|
}
|
|
50156
50250
|
return { diff: output.join("\n"), firstChangedLine };
|
|
50157
50251
|
}
|
|
50158
|
-
async function computeEditsDiff(
|
|
50159
|
-
const absolutePath = resolveToCwd(
|
|
50252
|
+
async function computeEditsDiff(path12, edits, cwd) {
|
|
50253
|
+
const absolutePath = resolveToCwd(path12, cwd);
|
|
50160
50254
|
try {
|
|
50161
50255
|
try {
|
|
50162
50256
|
await access3(absolutePath, constants4.R_OK);
|
|
50163
50257
|
} catch (error) {
|
|
50164
50258
|
const errorMessage = error instanceof Error && "code" in error ? `Error code: ${error.code}` : String(error);
|
|
50165
|
-
return { error: `Could not edit file: ${
|
|
50259
|
+
return { error: `Could not edit file: ${path12}. ${errorMessage}.` };
|
|
50166
50260
|
}
|
|
50167
50261
|
const rawContent = await readFile3(absolutePath, "utf-8");
|
|
50168
50262
|
const { text: content } = stripBom2(rawContent);
|
|
50169
50263
|
const normalizedContent = normalizeToLF2(content);
|
|
50170
|
-
const { baseContent, newContent } = applyEditsToNormalizedContent2(normalizedContent, edits,
|
|
50264
|
+
const { baseContent, newContent } = applyEditsToNormalizedContent2(normalizedContent, edits, path12);
|
|
50171
50265
|
return generateDiffString2(baseContent, newContent);
|
|
50172
50266
|
} catch (err2) {
|
|
50173
50267
|
return { error: err2 instanceof Error ? err2.message : String(err2) };
|
|
@@ -50232,9 +50326,9 @@ var editSchema2 = Type10.Object({
|
|
|
50232
50326
|
})
|
|
50233
50327
|
}, {});
|
|
50234
50328
|
var defaultEditOperations = {
|
|
50235
|
-
readFile: (
|
|
50236
|
-
writeFile: (
|
|
50237
|
-
access: (
|
|
50329
|
+
readFile: (path12) => fsReadFile(path12),
|
|
50330
|
+
writeFile: (path12, content) => fsWriteFile(path12, content, "utf-8"),
|
|
50331
|
+
access: (path12) => fsAccess2(path12, constants5.R_OK | constants5.W_OK)
|
|
50238
50332
|
};
|
|
50239
50333
|
function prepareEditArguments2(input) {
|
|
50240
50334
|
if (!input || typeof input !== "object") {
|
|
@@ -50289,15 +50383,15 @@ function getRenderablePreviewInput(args) {
|
|
|
50289
50383
|
if (!args) {
|
|
50290
50384
|
return null;
|
|
50291
50385
|
}
|
|
50292
|
-
const
|
|
50293
|
-
if (!
|
|
50386
|
+
const path12 = typeof args.path === "string" ? args.path : typeof args.file_path === "string" ? args.file_path : null;
|
|
50387
|
+
if (!path12) {
|
|
50294
50388
|
return null;
|
|
50295
50389
|
}
|
|
50296
50390
|
if (Array.isArray(args.edits) && args.edits.length > 0 && args.edits.every((edit) => typeof edit?.oldText === "string" && typeof edit?.newText === "string")) {
|
|
50297
|
-
return { path:
|
|
50391
|
+
return { path: path12, edits: args.edits };
|
|
50298
50392
|
}
|
|
50299
50393
|
if (typeof args.oldText === "string" && typeof args.newText === "string") {
|
|
50300
|
-
return { path:
|
|
50394
|
+
return { path: path12, edits: [{ oldText: args.oldText, newText: args.newText }] };
|
|
50301
50395
|
}
|
|
50302
50396
|
return null;
|
|
50303
50397
|
}
|
|
@@ -50371,8 +50465,8 @@ function createEditToolDefinition(cwd, options) {
|
|
|
50371
50465
|
renderShell: "self",
|
|
50372
50466
|
prepareArguments: prepareEditArguments2,
|
|
50373
50467
|
async execute(_toolCallId, input, signal, _onUpdate, _ctx) {
|
|
50374
|
-
const { path:
|
|
50375
|
-
const absolutePath = resolveToCwd(
|
|
50468
|
+
const { path: path12, edits } = validateEditInput2(input);
|
|
50469
|
+
const absolutePath = resolveToCwd(path12, cwd);
|
|
50376
50470
|
return withFileMutationQueue2(absolutePath, async () => {
|
|
50377
50471
|
const throwIfAborted = () => {
|
|
50378
50472
|
if (signal?.aborted)
|
|
@@ -50384,7 +50478,7 @@ function createEditToolDefinition(cwd, options) {
|
|
|
50384
50478
|
} catch (error) {
|
|
50385
50479
|
throwIfAborted();
|
|
50386
50480
|
const errorMessage = error instanceof Error && "code" in error ? `Error code: ${error.code}` : String(error);
|
|
50387
|
-
throw new Error(`Could not edit file: ${
|
|
50481
|
+
throw new Error(`Could not edit file: ${path12}. ${errorMessage}.`);
|
|
50388
50482
|
}
|
|
50389
50483
|
throwIfAborted();
|
|
50390
50484
|
const buffer = await ops.readFile(absolutePath);
|
|
@@ -50393,18 +50487,18 @@ function createEditToolDefinition(cwd, options) {
|
|
|
50393
50487
|
const { bom, text: content } = stripBom2(rawContent);
|
|
50394
50488
|
const originalEnding = detectLineEnding2(content);
|
|
50395
50489
|
const normalizedContent = normalizeToLF2(content);
|
|
50396
|
-
const { baseContent, newContent } = applyEditsToNormalizedContent2(normalizedContent, edits,
|
|
50490
|
+
const { baseContent, newContent } = applyEditsToNormalizedContent2(normalizedContent, edits, path12);
|
|
50397
50491
|
throwIfAborted();
|
|
50398
50492
|
const finalContent = bom + restoreLineEndings2(newContent, originalEnding);
|
|
50399
50493
|
await ops.writeFile(absolutePath, finalContent);
|
|
50400
50494
|
throwIfAborted();
|
|
50401
50495
|
const diffResult = generateDiffString2(baseContent, newContent);
|
|
50402
|
-
const patch = generateUnifiedPatch2(
|
|
50496
|
+
const patch = generateUnifiedPatch2(path12, baseContent, newContent);
|
|
50403
50497
|
return {
|
|
50404
50498
|
content: [
|
|
50405
50499
|
{
|
|
50406
50500
|
type: "text",
|
|
50407
|
-
text: `Successfully replaced ${edits.length} block(s) in ${
|
|
50501
|
+
text: `Successfully replaced ${edits.length} block(s) in ${path12}.`
|
|
50408
50502
|
}
|
|
50409
50503
|
],
|
|
50410
50504
|
details: { diff: diffResult.diff, patch, firstChangedLine: diffResult.firstChangedLine }
|
|
@@ -50749,11 +50843,11 @@ async function ensureTool(tool, silent = false) {
|
|
|
50749
50843
|
console.log(chalk7.dim(`${config.name} not found. Downloading...`));
|
|
50750
50844
|
}
|
|
50751
50845
|
try {
|
|
50752
|
-
const
|
|
50846
|
+
const path12 = await downloadTool(tool);
|
|
50753
50847
|
if (!silent) {
|
|
50754
|
-
console.log(chalk7.dim(`${config.name} installed to ${
|
|
50848
|
+
console.log(chalk7.dim(`${config.name} installed to ${path12}`));
|
|
50755
50849
|
}
|
|
50756
|
-
return
|
|
50850
|
+
return path12;
|
|
50757
50851
|
} catch (e) {
|
|
50758
50852
|
if (!silent) {
|
|
50759
50853
|
console.log(chalk7.yellow(`Failed to download ${config.name}: ${e instanceof Error ? e.message : e}`));
|
|
@@ -50785,10 +50879,10 @@ var defaultFindOperations = {
|
|
|
50785
50879
|
function formatFindCall(args, theme2) {
|
|
50786
50880
|
const pattern = str(args?.pattern);
|
|
50787
50881
|
const rawPath = str(args?.path);
|
|
50788
|
-
const
|
|
50882
|
+
const path12 = rawPath !== null ? shortenPath2(rawPath || ".") : null;
|
|
50789
50883
|
const limit = args?.limit;
|
|
50790
50884
|
const invalidArg = invalidArgText(theme2);
|
|
50791
|
-
let text = theme2.fg("toolTitle", theme2.bold("find")) + " " + (pattern === null ? invalidArg : theme2.fg("accent", pattern || "")) + theme2.fg("toolOutput", ` in ${
|
|
50885
|
+
let text = theme2.fg("toolTitle", theme2.bold("find")) + " " + (pattern === null ? invalidArg : theme2.fg("accent", pattern || "")) + theme2.fg("toolOutput", ` in ${path12 === null ? invalidArg : path12}`);
|
|
50792
50886
|
if (limit !== void 0) {
|
|
50793
50887
|
text += theme2.fg("toolOutput", ` (limit ${limit})`);
|
|
50794
50888
|
}
|
|
@@ -51064,11 +51158,11 @@ var defaultGrepOperations = {
|
|
|
51064
51158
|
function formatGrepCall(args, theme2) {
|
|
51065
51159
|
const pattern = str(args?.pattern);
|
|
51066
51160
|
const rawPath = str(args?.path);
|
|
51067
|
-
const
|
|
51161
|
+
const path12 = rawPath !== null ? shortenPath2(rawPath || ".") : null;
|
|
51068
51162
|
const glob = str(args?.glob);
|
|
51069
51163
|
const limit = args?.limit;
|
|
51070
51164
|
const invalidArg = invalidArgText(theme2);
|
|
51071
|
-
let text = theme2.fg("toolTitle", theme2.bold("grep")) + " " + (pattern === null ? invalidArg : theme2.fg("accent", `/${pattern || ""}/`)) + theme2.fg("toolOutput", ` in ${
|
|
51165
|
+
let text = theme2.fg("toolTitle", theme2.bold("grep")) + " " + (pattern === null ? invalidArg : theme2.fg("accent", `/${pattern || ""}/`)) + theme2.fg("toolOutput", ` in ${path12 === null ? invalidArg : path12}`);
|
|
51072
51166
|
if (glob)
|
|
51073
51167
|
text += theme2.fg("toolOutput", ` (${glob})`);
|
|
51074
51168
|
if (limit !== void 0)
|
|
@@ -51387,7 +51481,7 @@ function createLsToolDefinition(cwd, options) {
|
|
|
51387
51481
|
description: `List directory contents. Returns entries sorted alphabetically, with '/' suffix for directories. Includes dotfiles. Output is truncated to ${DEFAULT_LIMIT3} entries or ${DEFAULT_MAX_BYTES3 / 1024}KB (whichever is hit first).`,
|
|
51388
51482
|
promptSnippet: "List directory contents",
|
|
51389
51483
|
parameters: lsSchema,
|
|
51390
|
-
async execute(_toolCallId, { path:
|
|
51484
|
+
async execute(_toolCallId, { path: path12, limit }, signal, _onUpdate, _ctx) {
|
|
51391
51485
|
return new Promise((resolve15, reject) => {
|
|
51392
51486
|
if (signal?.aborted) {
|
|
51393
51487
|
reject(new Error("Operation aborted"));
|
|
@@ -51397,7 +51491,7 @@ function createLsToolDefinition(cwd, options) {
|
|
|
51397
51491
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
51398
51492
|
(async () => {
|
|
51399
51493
|
try {
|
|
51400
|
-
const dirPath = resolveToCwd(
|
|
51494
|
+
const dirPath = resolveToCwd(path12 || ".", cwd);
|
|
51401
51495
|
const effectiveLimit = limit ?? DEFAULT_LIMIT3;
|
|
51402
51496
|
if (!await ops.exists(dirPath)) {
|
|
51403
51497
|
reject(new Error(`Path not found: ${dirPath}`));
|
|
@@ -51496,8 +51590,8 @@ var readSchema2 = Type14.Object({
|
|
|
51496
51590
|
});
|
|
51497
51591
|
var COMPACT_RESOURCE_FILE_NAMES = /* @__PURE__ */ new Set(["AGENTS.override.md", "AGENTS.md", "AGENTS.MD", "CLAUDE.md", "CLAUDE.MD"]);
|
|
51498
51592
|
var defaultReadOperations = {
|
|
51499
|
-
readFile: (
|
|
51500
|
-
access: (
|
|
51593
|
+
readFile: (path12) => fsReadFile3(path12),
|
|
51594
|
+
access: (path12) => fsAccess3(path12, constants6.R_OK),
|
|
51501
51595
|
detectImageMimeType: detectSupportedImageMimeTypeFromFile
|
|
51502
51596
|
};
|
|
51503
51597
|
function formatReadLineRange(args, theme2) {
|
|
@@ -51611,7 +51705,7 @@ function createReadToolDefinition(cwd, options) {
|
|
|
51611
51705
|
promptSnippet: "Read file contents",
|
|
51612
51706
|
promptGuidelines: ["Use read to examine files instead of cat or sed."],
|
|
51613
51707
|
parameters: readSchema2,
|
|
51614
|
-
async execute(_toolCallId, { path:
|
|
51708
|
+
async execute(_toolCallId, { path: path12, offset, limit }, signal, _onUpdate, ctx) {
|
|
51615
51709
|
return new Promise((resolve15, reject) => {
|
|
51616
51710
|
if (signal?.aborted) {
|
|
51617
51711
|
reject(new Error("Operation aborted"));
|
|
@@ -51625,7 +51719,7 @@ function createReadToolDefinition(cwd, options) {
|
|
|
51625
51719
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
51626
51720
|
(async () => {
|
|
51627
51721
|
try {
|
|
51628
|
-
const absolutePath = await resolveReadPathAsync(
|
|
51722
|
+
const absolutePath = await resolveReadPathAsync(path12, cwd);
|
|
51629
51723
|
if (aborted)
|
|
51630
51724
|
return;
|
|
51631
51725
|
await ops.access(absolutePath);
|
|
@@ -51681,7 +51775,7 @@ ${nonVisionImageNote}`;
|
|
|
51681
51775
|
let outputText;
|
|
51682
51776
|
if (truncation.firstLineExceedsLimit) {
|
|
51683
51777
|
const firstLineSize = formatSize2(Buffer.byteLength(allLines[startLine], "utf-8"));
|
|
51684
|
-
outputText = `[Line ${startLineDisplay} is ${firstLineSize}, exceeds ${formatSize2(DEFAULT_MAX_BYTES3)} limit. Use bash: sed -n '${startLineDisplay}p' ${
|
|
51778
|
+
outputText = `[Line ${startLineDisplay} is ${firstLineSize}, exceeds ${formatSize2(DEFAULT_MAX_BYTES3)} limit. Use bash: sed -n '${startLineDisplay}p' ${path12} | head -c ${DEFAULT_MAX_BYTES3}]`;
|
|
51685
51779
|
details = { truncation };
|
|
51686
51780
|
} else if (truncation.truncated) {
|
|
51687
51781
|
const endLineDisplay = startLineDisplay + truncation.outputLines - 1;
|
|
@@ -51866,7 +51960,7 @@ var writeSchema2 = Type16.Object({
|
|
|
51866
51960
|
content: Type16.String({ description: "Content to write to the file" })
|
|
51867
51961
|
});
|
|
51868
51962
|
var defaultWriteOperations = {
|
|
51869
|
-
writeFile: (
|
|
51963
|
+
writeFile: (path12, content) => fsWriteFile2(path12, content, "utf-8"),
|
|
51870
51964
|
mkdir: (dir) => fsMkdir(dir, { recursive: true }).then(() => {
|
|
51871
51965
|
})
|
|
51872
51966
|
};
|
|
@@ -51990,8 +52084,8 @@ function createWriteToolDefinition(cwd, options) {
|
|
|
51990
52084
|
promptSnippet: "Create or overwrite files",
|
|
51991
52085
|
promptGuidelines: ["Use write only for new files or complete rewrites."],
|
|
51992
52086
|
parameters: writeSchema2,
|
|
51993
|
-
async execute(_toolCallId, { path:
|
|
51994
|
-
const absolutePath = resolveToCwd(
|
|
52087
|
+
async execute(_toolCallId, { path: path12, content }, signal, _onUpdate, _ctx) {
|
|
52088
|
+
const absolutePath = resolveToCwd(path12, cwd);
|
|
51995
52089
|
const dir = dirname14(absolutePath);
|
|
51996
52090
|
return withFileMutationQueue2(absolutePath, async () => {
|
|
51997
52091
|
const throwIfAborted = () => {
|
|
@@ -52004,7 +52098,7 @@ function createWriteToolDefinition(cwd, options) {
|
|
|
52004
52098
|
await ops.writeFile(absolutePath, content);
|
|
52005
52099
|
throwIfAborted();
|
|
52006
52100
|
return {
|
|
52007
|
-
content: [{ type: "text", text: `Successfully wrote ${content.length} bytes to ${
|
|
52101
|
+
content: [{ type: "text", text: `Successfully wrote ${content.length} bytes to ${path12}` }],
|
|
52008
52102
|
details: void 0
|
|
52009
52103
|
};
|
|
52010
52104
|
});
|
|
@@ -54888,30 +54982,30 @@ function getProjectTrustOptions(cwd, options) {
|
|
|
54888
54982
|
}
|
|
54889
54983
|
return trustOptions;
|
|
54890
54984
|
}
|
|
54891
|
-
function readTrustFile(
|
|
54892
|
-
if (!existsSync18(
|
|
54985
|
+
function readTrustFile(path12) {
|
|
54986
|
+
if (!existsSync18(path12)) {
|
|
54893
54987
|
return {};
|
|
54894
54988
|
}
|
|
54895
54989
|
let parsed;
|
|
54896
54990
|
try {
|
|
54897
|
-
parsed = JSON.parse(readFileSync13(
|
|
54991
|
+
parsed = JSON.parse(readFileSync13(path12, "utf-8"));
|
|
54898
54992
|
} catch (error) {
|
|
54899
54993
|
const message = error instanceof Error ? error.message : String(error);
|
|
54900
|
-
throw new Error(`Failed to read trust store ${
|
|
54994
|
+
throw new Error(`Failed to read trust store ${path12}: ${message}`);
|
|
54901
54995
|
}
|
|
54902
54996
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
54903
|
-
throw new Error(`Invalid trust store ${
|
|
54997
|
+
throw new Error(`Invalid trust store ${path12}: expected an object`);
|
|
54904
54998
|
}
|
|
54905
54999
|
const data = {};
|
|
54906
55000
|
for (const [key, value] of Object.entries(parsed)) {
|
|
54907
55001
|
if (value !== true && value !== false && value !== null) {
|
|
54908
|
-
throw new Error(`Invalid trust store ${
|
|
55002
|
+
throw new Error(`Invalid trust store ${path12}: value for ${JSON.stringify(key)} must be true, false, or null`);
|
|
54909
55003
|
}
|
|
54910
55004
|
data[key] = value;
|
|
54911
55005
|
}
|
|
54912
55006
|
return data;
|
|
54913
55007
|
}
|
|
54914
|
-
function writeTrustFile(
|
|
55008
|
+
function writeTrustFile(path12, data) {
|
|
54915
55009
|
const sorted = {};
|
|
54916
55010
|
for (const key of Object.keys(data).sort()) {
|
|
54917
55011
|
const value = data[key];
|
|
@@ -54919,19 +55013,19 @@ function writeTrustFile(path11, data) {
|
|
|
54919
55013
|
sorted[key] = value;
|
|
54920
55014
|
}
|
|
54921
55015
|
}
|
|
54922
|
-
mkdirSync9(dirname16(
|
|
54923
|
-
writeFileSync9(
|
|
55016
|
+
mkdirSync9(dirname16(path12), { recursive: true });
|
|
55017
|
+
writeFileSync9(path12, `${JSON.stringify(sorted, null, 2)}
|
|
54924
55018
|
`, "utf-8");
|
|
54925
55019
|
}
|
|
54926
|
-
function acquireTrustLockSync(
|
|
54927
|
-
const trustDir = dirname16(
|
|
55020
|
+
function acquireTrustLockSync(path12) {
|
|
55021
|
+
const trustDir = dirname16(path12);
|
|
54928
55022
|
mkdirSync9(trustDir, { recursive: true });
|
|
54929
55023
|
const maxAttempts = 10;
|
|
54930
55024
|
const delayMs = 20;
|
|
54931
55025
|
let lastError;
|
|
54932
55026
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
54933
55027
|
try {
|
|
54934
|
-
return lockfile3.lockSync(trustDir, { realpath: false, lockfilePath: `${
|
|
55028
|
+
return lockfile3.lockSync(trustDir, { realpath: false, lockfilePath: `${path12}.lock` });
|
|
54935
55029
|
} catch (error) {
|
|
54936
55030
|
const code = typeof error === "object" && error !== null && "code" in error ? String(error.code) : void 0;
|
|
54937
55031
|
if (code !== "ELOCKED" || attempt === maxAttempts) {
|
|
@@ -54948,8 +55042,8 @@ function acquireTrustLockSync(path11) {
|
|
|
54948
55042
|
}
|
|
54949
55043
|
throw new Error("Failed to acquire trust store lock");
|
|
54950
55044
|
}
|
|
54951
|
-
function withTrustFileLock(
|
|
54952
|
-
const release = acquireTrustLockSync(
|
|
55045
|
+
function withTrustFileLock(path12, fn) {
|
|
55046
|
+
const release = acquireTrustLockSync(path12);
|
|
54953
55047
|
try {
|
|
54954
55048
|
return fn();
|
|
54955
55049
|
} finally {
|
|
@@ -54996,8 +55090,8 @@ var ProjectTrustStore = class {
|
|
|
54996
55090
|
setMany(decisions) {
|
|
54997
55091
|
withTrustFileLock(this.trustPath, () => {
|
|
54998
55092
|
const data = readTrustFile(this.trustPath);
|
|
54999
|
-
for (const { path:
|
|
55000
|
-
const key = normalizeCwd(
|
|
55093
|
+
for (const { path: path12, decision } of decisions) {
|
|
55094
|
+
const key = normalizeCwd(path12);
|
|
55001
55095
|
if (decision === null) {
|
|
55002
55096
|
delete data[key];
|
|
55003
55097
|
} else {
|
|
@@ -55443,13 +55537,13 @@ var graphRailStore = {
|
|
|
55443
55537
|
state.query = query;
|
|
55444
55538
|
emit();
|
|
55445
55539
|
},
|
|
55446
|
-
recordChange(
|
|
55447
|
-
const existing = state.changes.find((c) => c.path ===
|
|
55540
|
+
recordChange(path12, added, removed) {
|
|
55541
|
+
const existing = state.changes.find((c) => c.path === path12);
|
|
55448
55542
|
if (existing) {
|
|
55449
55543
|
existing.added += added;
|
|
55450
55544
|
existing.removed += removed;
|
|
55451
55545
|
} else {
|
|
55452
|
-
state.changes.push({ path:
|
|
55546
|
+
state.changes.push({ path: path12, added, removed });
|
|
55453
55547
|
if (state.changes.length > 6)
|
|
55454
55548
|
state.changes.shift();
|
|
55455
55549
|
}
|
|
@@ -55482,7 +55576,6 @@ var BUILTIN_SLASH_COMMANDS = [
|
|
|
55482
55576
|
{ name: "copy", description: "Copy last agent message to clipboard", secondary: true },
|
|
55483
55577
|
{ name: "name", description: "Set session display name", secondary: true },
|
|
55484
55578
|
{ name: "session", description: "Show session info and stats" },
|
|
55485
|
-
{ name: "hotkeys", description: "Show all keyboard shortcuts" },
|
|
55486
55579
|
{ name: "fork", description: "Create a new fork from a previous user message", secondary: true },
|
|
55487
55580
|
{ name: "clone", description: "Duplicate the current session at the current position", secondary: true },
|
|
55488
55581
|
{ name: "tree", description: "Navigate session tree (switch branches)", secondary: true },
|
|
@@ -57096,14 +57189,14 @@ function tryLoadObservatoryCache(repo) {
|
|
|
57096
57189
|
if (now - lastCheckAt < CHECK_INTERVAL_MS)
|
|
57097
57190
|
return;
|
|
57098
57191
|
lastCheckAt = now;
|
|
57099
|
-
const
|
|
57192
|
+
const path12 = observatoryCachePath(repo);
|
|
57100
57193
|
try {
|
|
57101
|
-
const stat3 = statSync9(
|
|
57194
|
+
const stat3 = statSync9(path12);
|
|
57102
57195
|
if (now - stat3.mtimeMs > MAX_CACHE_AGE_MS)
|
|
57103
57196
|
return;
|
|
57104
57197
|
if (stat3.mtimeMs <= loadedMtimeMs)
|
|
57105
57198
|
return;
|
|
57106
|
-
const parsed = JSON.parse(readFileSync17(
|
|
57199
|
+
const parsed = JSON.parse(readFileSync17(path12, "utf8"));
|
|
57107
57200
|
if (!Array.isArray(parsed.communities) || parsed.communities.length === 0)
|
|
57108
57201
|
return;
|
|
57109
57202
|
loadedMtimeMs = stat3.mtimeMs;
|
|
@@ -60007,10 +60100,10 @@ var TreeList = class {
|
|
|
60007
60100
|
};
|
|
60008
60101
|
switch (name) {
|
|
60009
60102
|
case "read": {
|
|
60010
|
-
const
|
|
60103
|
+
const path12 = shortenPath3(String(args.path || args.file_path || ""));
|
|
60011
60104
|
const offset = args.offset;
|
|
60012
60105
|
const limit = args.limit;
|
|
60013
|
-
let display =
|
|
60106
|
+
let display = path12;
|
|
60014
60107
|
if (offset !== void 0 || limit !== void 0) {
|
|
60015
60108
|
const start = offset ?? 1;
|
|
60016
60109
|
const end = limit !== void 0 ? start + limit - 1 : "";
|
|
@@ -60019,12 +60112,12 @@ var TreeList = class {
|
|
|
60019
60112
|
return `[read: ${display}]`;
|
|
60020
60113
|
}
|
|
60021
60114
|
case "write": {
|
|
60022
|
-
const
|
|
60023
|
-
return `[write: ${
|
|
60115
|
+
const path12 = shortenPath3(String(args.path || args.file_path || ""));
|
|
60116
|
+
return `[write: ${path12}]`;
|
|
60024
60117
|
}
|
|
60025
60118
|
case "edit": {
|
|
60026
|
-
const
|
|
60027
|
-
return `[edit: ${
|
|
60119
|
+
const path12 = shortenPath3(String(args.path || args.file_path || ""));
|
|
60120
|
+
return `[edit: ${path12}]`;
|
|
60028
60121
|
}
|
|
60029
60122
|
case "bash": {
|
|
60030
60123
|
const rawCmd = String(args.command || "");
|
|
@@ -60033,17 +60126,17 @@ var TreeList = class {
|
|
|
60033
60126
|
}
|
|
60034
60127
|
case "grep": {
|
|
60035
60128
|
const pattern = String(args.pattern || "");
|
|
60036
|
-
const
|
|
60037
|
-
return `[grep: /${pattern}/ in ${
|
|
60129
|
+
const path12 = shortenPath3(String(args.path || "."));
|
|
60130
|
+
return `[grep: /${pattern}/ in ${path12}]`;
|
|
60038
60131
|
}
|
|
60039
60132
|
case "find": {
|
|
60040
60133
|
const pattern = String(args.pattern || "");
|
|
60041
|
-
const
|
|
60042
|
-
return `[find: ${pattern} in ${
|
|
60134
|
+
const path12 = shortenPath3(String(args.path || "."));
|
|
60135
|
+
return `[find: ${pattern} in ${path12}]`;
|
|
60043
60136
|
}
|
|
60044
60137
|
case "ls": {
|
|
60045
|
-
const
|
|
60046
|
-
return `[ls: ${
|
|
60138
|
+
const path12 = shortenPath3(String(args.path || "."));
|
|
60139
|
+
return `[ls: ${path12}]`;
|
|
60047
60140
|
}
|
|
60048
60141
|
default: {
|
|
60049
60142
|
const argsStr = JSON.stringify(args).slice(0, 40);
|
|
@@ -61525,8 +61618,8 @@ var InteractiveMode = class _InteractiveMode {
|
|
|
61525
61618
|
}
|
|
61526
61619
|
return result;
|
|
61527
61620
|
}
|
|
61528
|
-
formatExtensionDisplayPath(
|
|
61529
|
-
let result = this.formatDisplayPath(
|
|
61621
|
+
formatExtensionDisplayPath(path12) {
|
|
61622
|
+
let result = this.formatDisplayPath(path12);
|
|
61530
61623
|
result = result.replace(/\/index\.ts$/, "").replace(/\/index\.js$/, "");
|
|
61531
61624
|
return result;
|
|
61532
61625
|
}
|
|
@@ -62870,11 +62963,6 @@ ${message}`, ["Yes", "No"], opts);
|
|
|
62870
62963
|
this.editor.setText("");
|
|
62871
62964
|
return;
|
|
62872
62965
|
}
|
|
62873
|
-
if (text === "/hotkeys") {
|
|
62874
|
-
this.handleHotkeysCommand();
|
|
62875
|
-
this.editor.setText("");
|
|
62876
|
-
return;
|
|
62877
|
-
}
|
|
62878
62966
|
if (text === "/theme") {
|
|
62879
62967
|
this.showThemeSelector();
|
|
62880
62968
|
this.editor.setText("");
|
|
@@ -65485,120 +65573,6 @@ ${theme.fg("dim", "Cache Re-billed:")} ${detail}`;
|
|
|
65485
65573
|
getAppKeyDisplay(action) {
|
|
65486
65574
|
return keyDisplayText(action);
|
|
65487
65575
|
}
|
|
65488
|
-
/**
|
|
65489
|
-
* Get capitalized display string for an editor keybinding action.
|
|
65490
|
-
*/
|
|
65491
|
-
getEditorKeyDisplay(action) {
|
|
65492
|
-
return keyDisplayText(action);
|
|
65493
|
-
}
|
|
65494
|
-
handleHotkeysCommand() {
|
|
65495
|
-
const cursorUp = this.getEditorKeyDisplay("tui.editor.cursorUp");
|
|
65496
|
-
const cursorDown = this.getEditorKeyDisplay("tui.editor.cursorDown");
|
|
65497
|
-
const cursorLeft = this.getEditorKeyDisplay("tui.editor.cursorLeft");
|
|
65498
|
-
const cursorRight = this.getEditorKeyDisplay("tui.editor.cursorRight");
|
|
65499
|
-
const cursorWordLeft = this.getEditorKeyDisplay("tui.editor.cursorWordLeft");
|
|
65500
|
-
const cursorWordRight = this.getEditorKeyDisplay("tui.editor.cursorWordRight");
|
|
65501
|
-
const cursorLineStart = this.getEditorKeyDisplay("tui.editor.cursorLineStart");
|
|
65502
|
-
const cursorLineEnd = this.getEditorKeyDisplay("tui.editor.cursorLineEnd");
|
|
65503
|
-
const jumpForward = this.getEditorKeyDisplay("tui.editor.jumpForward");
|
|
65504
|
-
const jumpBackward = this.getEditorKeyDisplay("tui.editor.jumpBackward");
|
|
65505
|
-
const pageUp = this.getEditorKeyDisplay("tui.editor.pageUp");
|
|
65506
|
-
const pageDown = this.getEditorKeyDisplay("tui.editor.pageDown");
|
|
65507
|
-
const submit = this.getEditorKeyDisplay("tui.input.submit");
|
|
65508
|
-
const newLine = this.getEditorKeyDisplay("tui.input.newLine");
|
|
65509
|
-
const deleteWordBackward = this.getEditorKeyDisplay("tui.editor.deleteWordBackward");
|
|
65510
|
-
const deleteWordForward = this.getEditorKeyDisplay("tui.editor.deleteWordForward");
|
|
65511
|
-
const deleteToLineStart = this.getEditorKeyDisplay("tui.editor.deleteToLineStart");
|
|
65512
|
-
const deleteToLineEnd = this.getEditorKeyDisplay("tui.editor.deleteToLineEnd");
|
|
65513
|
-
const yank = this.getEditorKeyDisplay("tui.editor.yank");
|
|
65514
|
-
const yankPop = this.getEditorKeyDisplay("tui.editor.yankPop");
|
|
65515
|
-
const undo = this.getEditorKeyDisplay("tui.editor.undo");
|
|
65516
|
-
const tab = this.getEditorKeyDisplay("tui.input.tab");
|
|
65517
|
-
const interrupt = this.getAppKeyDisplay("app.interrupt");
|
|
65518
|
-
const clear = this.getAppKeyDisplay("app.clear");
|
|
65519
|
-
const exit = this.getAppKeyDisplay("app.exit");
|
|
65520
|
-
const suspend = this.getAppKeyDisplay("app.suspend");
|
|
65521
|
-
const cycleThinkingLevel = this.getAppKeyDisplay("app.thinking.cycle");
|
|
65522
|
-
const cycleModelForward = this.getAppKeyDisplay("app.model.cycleForward");
|
|
65523
|
-
const selectModel = this.getAppKeyDisplay("app.model.select");
|
|
65524
|
-
const expandTools = this.getAppKeyDisplay("app.tools.expand");
|
|
65525
|
-
const toggleThinking = this.getAppKeyDisplay("app.thinking.toggle");
|
|
65526
|
-
const externalEditor = this.getAppKeyDisplay("app.editor.external");
|
|
65527
|
-
const cycleModelBackward = this.getAppKeyDisplay("app.model.cycleBackward");
|
|
65528
|
-
const copyMessage = this.getAppKeyDisplay("app.message.copy");
|
|
65529
|
-
const followUp = this.getAppKeyDisplay("app.message.followUp");
|
|
65530
|
-
const dequeue = this.getAppKeyDisplay("app.message.dequeue");
|
|
65531
|
-
const pasteImage = this.getAppKeyDisplay("app.clipboard.pasteImage");
|
|
65532
|
-
let hotkeys = `
|
|
65533
|
-
**Navigation**
|
|
65534
|
-
| Key | Action |
|
|
65535
|
-
|-----|--------|
|
|
65536
|
-
| \`${cursorUp}\` / \`${cursorDown}\` / \`${cursorLeft}\` / \`${cursorRight}\` | Move cursor / browse history |
|
|
65537
|
-
| \`${cursorWordLeft}\` / \`${cursorWordRight}\` | Move by word |
|
|
65538
|
-
| \`${cursorLineStart}\` | Start of line |
|
|
65539
|
-
| \`${cursorLineEnd}\` | End of line |
|
|
65540
|
-
| \`${jumpForward}\` | Jump forward to character |
|
|
65541
|
-
| \`${jumpBackward}\` | Jump backward to character |
|
|
65542
|
-
| \`${pageUp}\` / \`${pageDown}\` | Scroll by page |
|
|
65543
|
-
|
|
65544
|
-
**Editing**
|
|
65545
|
-
| Key | Action |
|
|
65546
|
-
|-----|--------|
|
|
65547
|
-
| \`${submit}\` | Send message |
|
|
65548
|
-
| \`${newLine}\` | New line${process.platform === "win32" ? " (Ctrl+Enter on Windows Terminal)" : ""} |
|
|
65549
|
-
| \`${deleteWordBackward}\` | Delete word backwards |
|
|
65550
|
-
| \`${deleteWordForward}\` | Delete word forwards |
|
|
65551
|
-
| \`${deleteToLineStart}\` | Delete to start of line |
|
|
65552
|
-
| \`${deleteToLineEnd}\` | Delete to end of line |
|
|
65553
|
-
| \`${yank}\` | Paste the most-recently-deleted text |
|
|
65554
|
-
| \`${yankPop}\` | Cycle through the deleted text after pasting |
|
|
65555
|
-
| \`${undo}\` | Undo |
|
|
65556
|
-
|
|
65557
|
-
**Other**
|
|
65558
|
-
| Key | Action |
|
|
65559
|
-
|-----|--------|
|
|
65560
|
-
| \`${tab}\` | Path completion / accept autocomplete |
|
|
65561
|
-
| \`${interrupt}\` | Cancel autocomplete / abort streaming |
|
|
65562
|
-
| \`${clear}\` | Clear editor (first) / exit (second) |
|
|
65563
|
-
| \`${exit}\` | Exit (when editor is empty) |
|
|
65564
|
-
| \`${suspend}\` | Suspend to background |
|
|
65565
|
-
| \`${cycleThinkingLevel}\` | Cycle thinking level |
|
|
65566
|
-
| \`${cycleModelForward}\` / \`${cycleModelBackward}\` | Cycle models |
|
|
65567
|
-
| \`${selectModel}\` | Open model selector |
|
|
65568
|
-
| \`${expandTools}\` | Toggle tool output expansion |
|
|
65569
|
-
| \`${toggleThinking}\` | Toggle thinking block visibility |
|
|
65570
|
-
| \`${externalEditor}\` | Edit message in external editor |
|
|
65571
|
-
| \`${copyMessage}\` | Copy last assistant message |
|
|
65572
|
-
| \`${followUp}\` | Queue follow-up message |
|
|
65573
|
-
| \`${dequeue}\` | Restore queued messages |
|
|
65574
|
-
| \`${pasteImage}\` | Paste image or text from clipboard |
|
|
65575
|
-
| \`/\` | Slash commands |
|
|
65576
|
-
| \`!\` | Run bash command |
|
|
65577
|
-
| \`!!\` | Run bash command (excluded from context) |
|
|
65578
|
-
`;
|
|
65579
|
-
const extensionRunner = this.session.extensionRunner;
|
|
65580
|
-
const shortcuts = extensionRunner.getShortcuts(this.keybindings.getEffectiveConfig());
|
|
65581
|
-
if (shortcuts.size > 0) {
|
|
65582
|
-
hotkeys += `
|
|
65583
|
-
**Extensions**
|
|
65584
|
-
| Key | Action |
|
|
65585
|
-
|-----|--------|
|
|
65586
|
-
`;
|
|
65587
|
-
for (const [key, shortcut] of shortcuts) {
|
|
65588
|
-
const description = shortcut.description ?? shortcut.extensionPath;
|
|
65589
|
-
const keyDisplay = formatKeyText(key, { capitalize: true });
|
|
65590
|
-
hotkeys += `| \`${keyDisplay}\` | ${description} |
|
|
65591
|
-
`;
|
|
65592
|
-
}
|
|
65593
|
-
}
|
|
65594
|
-
this.chatContainer.addChild(new Spacer(1));
|
|
65595
|
-
this.chatContainer.addChild(new DynamicBorder());
|
|
65596
|
-
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", "Keyboard Shortcuts")), 1, 0));
|
|
65597
|
-
this.chatContainer.addChild(new Spacer(1));
|
|
65598
|
-
this.chatContainer.addChild(new Markdown(hotkeys.trim(), 1, 1, this.getMarkdownThemeWithSettings()));
|
|
65599
|
-
this.chatContainer.addChild(new DynamicBorder());
|
|
65600
|
-
this.ui.requestRender();
|
|
65601
|
-
}
|
|
65602
65576
|
async handleClearCommand() {
|
|
65603
65577
|
this.clearStatusIndicator();
|
|
65604
65578
|
try {
|
|
@@ -66792,8 +66766,8 @@ async function runRpcMode(runtimeHost) {
|
|
|
66792
66766
|
return success(id, "get_session_stats", stats);
|
|
66793
66767
|
}
|
|
66794
66768
|
case "export_html": {
|
|
66795
|
-
const
|
|
66796
|
-
return success(id, "export_html", { path:
|
|
66769
|
+
const path12 = await session.exportToHtml(command.outputPath);
|
|
66770
|
+
return success(id, "export_html", { path: path12 });
|
|
66797
66771
|
}
|
|
66798
66772
|
case "switch_session": {
|
|
66799
66773
|
const result = await runtimeHost.switchSession(command.sessionPath);
|
|
@@ -67745,7 +67719,7 @@ var DefaultResourceLoader = class {
|
|
|
67745
67719
|
return this.appendSystemPrompt;
|
|
67746
67720
|
}
|
|
67747
67721
|
getAppendSystemPromptSources() {
|
|
67748
|
-
return this.appendSystemPromptSourcePaths.map((
|
|
67722
|
+
return this.appendSystemPromptSourcePaths.map((path12) => ({ path: path12 }));
|
|
67749
67723
|
}
|
|
67750
67724
|
extendResources(paths) {
|
|
67751
67725
|
const skillPaths = this.normalizeExtensionPaths(paths.skillPaths ?? []);
|
|
@@ -67913,8 +67887,8 @@ var DefaultResourceLoader = class {
|
|
|
67913
67887
|
extensionsResult.errors.push(...inlineExtensions.errors);
|
|
67914
67888
|
return extensionsResult;
|
|
67915
67889
|
}
|
|
67916
|
-
resolveExtensionLoadPath(
|
|
67917
|
-
return resolvePath(
|
|
67890
|
+
resolveExtensionLoadPath(path12) {
|
|
67891
|
+
return resolvePath(path12, this.cwd, { normalizeUnicodeSpaces: true });
|
|
67918
67892
|
}
|
|
67919
67893
|
async loadFinalExtensionSet(extensionPaths, preTrustExtensions) {
|
|
67920
67894
|
if (!preTrustExtensions) {
|
|
@@ -67927,8 +67901,8 @@ var DefaultResourceLoader = class {
|
|
|
67927
67901
|
}
|
|
67928
67902
|
const preloadedByPath = new Map(preTrustExtensions.extensions.filter((extension) => !extension.path.startsWith("<inline:")).map((extension) => [extension.resolvedPath, extension]));
|
|
67929
67903
|
const failedPreloadPaths = new Set(preTrustExtensions.errors.map((error) => this.resolveExtensionLoadPath(error.path)));
|
|
67930
|
-
const remainingPaths = extensionPaths.filter((
|
|
67931
|
-
const resolvedPath = this.resolveExtensionLoadPath(
|
|
67904
|
+
const remainingPaths = extensionPaths.filter((path12) => {
|
|
67905
|
+
const resolvedPath = this.resolveExtensionLoadPath(path12);
|
|
67932
67906
|
return !preloadedByPath.has(resolvedPath) && !failedPreloadPaths.has(resolvedPath);
|
|
67933
67907
|
});
|
|
67934
67908
|
const remainingExtensions = await loadExtensionsCached(remainingPaths, this.cwd, this.eventBus, preTrustExtensions.runtime);
|
|
@@ -67937,7 +67911,7 @@ var DefaultResourceLoader = class {
|
|
|
67937
67911
|
loadedByPath.set(extension.resolvedPath, extension);
|
|
67938
67912
|
}
|
|
67939
67913
|
const inlineExtensions = preTrustExtensions.extensions.filter((extension) => extension.path.startsWith("<inline:"));
|
|
67940
|
-
const orderedExtensions = extensionPaths.map((
|
|
67914
|
+
const orderedExtensions = extensionPaths.map((path12) => loadedByPath.get(this.resolveExtensionLoadPath(path12))).filter((extension) => extension !== void 0);
|
|
67941
67915
|
orderedExtensions.push(...inlineExtensions);
|
|
67942
67916
|
const extensionsResult = {
|
|
67943
67917
|
extensions: orderedExtensions,
|
|
@@ -68796,6 +68770,21 @@ function parseUsage2(value) {
|
|
|
68796
68770
|
...typeof usage.remaining === "number" ? { remaining: usage.remaining } : {}
|
|
68797
68771
|
};
|
|
68798
68772
|
}
|
|
68773
|
+
function parseDelegation(value) {
|
|
68774
|
+
if (!value || typeof value !== "object")
|
|
68775
|
+
return void 0;
|
|
68776
|
+
const delegation = value;
|
|
68777
|
+
if (delegation.enabled !== true || delegation.version !== 1 || typeof delegation.maxParallel !== "number" || !Number.isSafeInteger(delegation.maxParallel) || delegation.maxParallel < 1 || typeof delegation.maxTaskBytes !== "number" || !Number.isSafeInteger(delegation.maxTaskBytes) || delegation.maxTaskBytes < 1 || typeof delegation.workerTimeoutMs !== "number" || !Number.isSafeInteger(delegation.workerTimeoutMs) || delegation.workerTimeoutMs < 1) {
|
|
68778
|
+
return void 0;
|
|
68779
|
+
}
|
|
68780
|
+
return {
|
|
68781
|
+
enabled: true,
|
|
68782
|
+
version: 1,
|
|
68783
|
+
maxParallel: delegation.maxParallel,
|
|
68784
|
+
maxTaskBytes: delegation.maxTaskBytes,
|
|
68785
|
+
workerTimeoutMs: delegation.workerTimeoutMs
|
|
68786
|
+
};
|
|
68787
|
+
}
|
|
68799
68788
|
function formatCreditBalance(policy) {
|
|
68800
68789
|
if (!policy?.usage)
|
|
68801
68790
|
return void 0;
|
|
@@ -68805,16 +68794,17 @@ function formatCreditBalance(policy) {
|
|
|
68805
68794
|
function gatewayCachePath() {
|
|
68806
68795
|
return join37(dirname22(gitNexusConfigPath()), "gateway.json");
|
|
68807
68796
|
}
|
|
68808
|
-
function readGatewayCache(
|
|
68797
|
+
function readGatewayCache(path12 = gatewayCachePath()) {
|
|
68809
68798
|
try {
|
|
68810
|
-
const parsed = JSON.parse(readFileSync19(
|
|
68799
|
+
const parsed = JSON.parse(readFileSync19(path12, "utf8"));
|
|
68811
68800
|
if (typeof parsed.contextWindow !== "number" || typeof parsed.maxTokens !== "number")
|
|
68812
68801
|
return void 0;
|
|
68813
68802
|
return {
|
|
68814
68803
|
configured: parsed.configured === true,
|
|
68815
68804
|
contextWindow: parsed.contextWindow,
|
|
68816
68805
|
maxTokens: parsed.maxTokens,
|
|
68817
|
-
usage: parseUsage2(parsed.usage)
|
|
68806
|
+
usage: parseUsage2(parsed.usage),
|
|
68807
|
+
delegation: parseDelegation(parsed.delegation)
|
|
68818
68808
|
};
|
|
68819
68809
|
} catch {
|
|
68820
68810
|
return void 0;
|
|
@@ -68851,7 +68841,8 @@ async function refreshGatewayPolicy(config, options = {}) {
|
|
|
68851
68841
|
configured: body.configured === true,
|
|
68852
68842
|
contextWindow: body.contextWindow,
|
|
68853
68843
|
maxTokens: body.maxTokens,
|
|
68854
|
-
usage: parseUsage2(body.usage)
|
|
68844
|
+
usage: parseUsage2(body.usage),
|
|
68845
|
+
delegation: parseDelegation(body.delegation)
|
|
68855
68846
|
};
|
|
68856
68847
|
if (!existsSync24(dirname22(cachePath)))
|
|
68857
68848
|
mkdirSync12(dirname22(cachePath), { recursive: true, mode: 448 });
|
|
@@ -68904,11 +68895,551 @@ function registerAutoProvider(pi, config, policy) {
|
|
|
68904
68895
|
}
|
|
68905
68896
|
|
|
68906
68897
|
// dist/extensions/gitnexus/index.js
|
|
68907
|
-
import { existsSync as
|
|
68898
|
+
import { existsSync as existsSync26 } from "node:fs";
|
|
68908
68899
|
import { homedir as homedir12 } from "node:os";
|
|
68909
|
-
import { join as
|
|
68900
|
+
import { join as join39 } from "node:path";
|
|
68910
68901
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
68911
68902
|
|
|
68903
|
+
// dist/extensions/subagent/index.js
|
|
68904
|
+
import { execFile as execFile2, spawn as spawn12 } from "node:child_process";
|
|
68905
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
68906
|
+
import * as fs7 from "node:fs";
|
|
68907
|
+
import * as os5 from "node:os";
|
|
68908
|
+
import * as path11 from "node:path";
|
|
68909
|
+
import { Type as Type17 } from "typebox";
|
|
68910
|
+
var DELEGATE_TASK_TOOL_NAME = "delegate_task";
|
|
68911
|
+
var INTERNAL_WORKER_MARKER_ENV = "NEXUS_INTERNAL_DELEGATED_WORKER";
|
|
68912
|
+
var INTERNAL_WORKER_SESSION_ENV = "NEXUS_INTERNAL_WORKER_SESSION_ID";
|
|
68913
|
+
var INTERNAL_WORKER_TASK_ENV = "NEXUS_INTERNAL_WORKER_TASK_ID";
|
|
68914
|
+
var INTERNAL_WORKER_RUN_ENV = "NEXUS_INTERNAL_WORKER_RUN_ID";
|
|
68915
|
+
var INTERNAL_WORKER_ROOT_REQUEST_ENV = "NEXUS_INTERNAL_WORKER_ROOT_REQUEST_ID";
|
|
68916
|
+
var INTERNAL_WORKER_PARENT_REQUEST_ENV = "NEXUS_INTERNAL_WORKER_PARENT_REQUEST_ID";
|
|
68917
|
+
var INTERNAL_WORKER_GRANT_HEADER = "x-nexus-worker-grant";
|
|
68918
|
+
var INTERNAL_WORKER_TASK_HEADER = "x-nexus-worker-task-id";
|
|
68919
|
+
var SESSION_AFFINITY_HEADER = "x-session-affinity";
|
|
68920
|
+
var RUN_ID_HEADER = "x-nexus-run-id";
|
|
68921
|
+
var REQUEST_ID_HEADER = "x-nexus-request-id";
|
|
68922
|
+
var ROOT_REQUEST_ID_HEADER = "x-nexus-root-request-id";
|
|
68923
|
+
var PARENT_REQUEST_ID_HEADER = "x-nexus-parent-request-id";
|
|
68924
|
+
var DELEGATION_ID_HEADER = "x-nexus-delegation-id";
|
|
68925
|
+
var REQUEST_SCOPE_HEADER = "x-nexus-request-scope";
|
|
68926
|
+
var MAX_DELEGATED_TURNS = 12;
|
|
68927
|
+
var MAX_DELEGATIONS_PER_RUN = 3;
|
|
68928
|
+
var DELEGATED_WORKER_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
68929
|
+
var DELEGATED_OUTPUT_CAP_BYTES = 32 * 1024;
|
|
68930
|
+
var DELEGATED_EVENT_CAP_BYTES = 1024 * 1024;
|
|
68931
|
+
var MAX_DELEGATED_TASK_BYTES = 32 * 1024;
|
|
68932
|
+
var WORKER_GRANT_TIMEOUT_MS = 1e4;
|
|
68933
|
+
var INVALID_WORKER_GRANT = "unavailable";
|
|
68934
|
+
var MAX_ROOT_REVIEW_TOOL_CALLS = 8;
|
|
68935
|
+
var MAX_PARALLEL_MUTATING_WORKERS = 1;
|
|
68936
|
+
var ROOT_REVIEW_TOOLS = /* @__PURE__ */ new Set([
|
|
68937
|
+
"read",
|
|
68938
|
+
"grep",
|
|
68939
|
+
"find",
|
|
68940
|
+
"ls",
|
|
68941
|
+
"gitnexus_query",
|
|
68942
|
+
"gitnexus_context",
|
|
68943
|
+
"gitnexus_impact",
|
|
68944
|
+
"gitnexus_detect_changes",
|
|
68945
|
+
"gitnexus_cypher",
|
|
68946
|
+
"gitnexus_list_repos",
|
|
68947
|
+
"web_search",
|
|
68948
|
+
"web_fetch"
|
|
68949
|
+
]);
|
|
68950
|
+
var DELEGATED_WORKER_TOOLS = [
|
|
68951
|
+
"read",
|
|
68952
|
+
"grep",
|
|
68953
|
+
"find",
|
|
68954
|
+
"ls",
|
|
68955
|
+
"bash",
|
|
68956
|
+
"write",
|
|
68957
|
+
"edit",
|
|
68958
|
+
"gitnexus_query",
|
|
68959
|
+
"gitnexus_context",
|
|
68960
|
+
"gitnexus_impact",
|
|
68961
|
+
"gitnexus_detect_changes",
|
|
68962
|
+
"gitnexus_cypher",
|
|
68963
|
+
"gitnexus_list_repos"
|
|
68964
|
+
];
|
|
68965
|
+
var WORKER_SYSTEM_PROMPT = `You are an internal implementation worker for Nexus Agent.
|
|
68966
|
+
|
|
68967
|
+
Complete only the narrowly delegated task. Inspect the repository before editing, follow its local instructions, and verify the changed behavior. Do not delegate work or broaden scope. Do not discuss model names, providers, routing, credits, or internal architecture.
|
|
68968
|
+
|
|
68969
|
+
Finish with a concise report containing:
|
|
68970
|
+
- changes made
|
|
68971
|
+
- verification run and results
|
|
68972
|
+
- blockers or remaining risks`;
|
|
68973
|
+
function isRecord(value) {
|
|
68974
|
+
return typeof value === "object" && value !== null;
|
|
68975
|
+
}
|
|
68976
|
+
function parseAssistantSnapshot(value) {
|
|
68977
|
+
if (!isRecord(value) || value.role !== "assistant" || !Array.isArray(value.content))
|
|
68978
|
+
return void 0;
|
|
68979
|
+
const text = value.content.filter(isRecord).filter((part) => part.type === "text" && typeof part.text === "string").map((part) => part.text).join("\n");
|
|
68980
|
+
return {
|
|
68981
|
+
text,
|
|
68982
|
+
...typeof value.stopReason === "string" ? { stopReason: value.stopReason } : {}
|
|
68983
|
+
};
|
|
68984
|
+
}
|
|
68985
|
+
function composeDelegatedTask(task, acceptanceCriteria, relevantPaths) {
|
|
68986
|
+
const sections = [`Task:
|
|
68987
|
+
${task.trim()}`];
|
|
68988
|
+
if (acceptanceCriteria.length > 0) {
|
|
68989
|
+
sections.push(`Acceptance criteria:
|
|
68990
|
+
${acceptanceCriteria.map((criterion) => `- ${criterion}`).join("\n")}`);
|
|
68991
|
+
}
|
|
68992
|
+
if (relevantPaths.length > 0) {
|
|
68993
|
+
sections.push(`Relevant paths:
|
|
68994
|
+
${relevantPaths.map((filePath) => `- ${filePath}`).join("\n")}`);
|
|
68995
|
+
}
|
|
68996
|
+
return sections.join("\n\n");
|
|
68997
|
+
}
|
|
68998
|
+
function buildDelegatedWorkerArgs(task, promptPath) {
|
|
68999
|
+
return [
|
|
69000
|
+
"--mode",
|
|
69001
|
+
"json",
|
|
69002
|
+
"-p",
|
|
69003
|
+
"--no-session",
|
|
69004
|
+
"--model",
|
|
69005
|
+
`${AUTO_PROVIDER_ID}/${AUTO_MODEL_ID}`,
|
|
69006
|
+
"--tools",
|
|
69007
|
+
DELEGATED_WORKER_TOOLS.join(","),
|
|
69008
|
+
"--exclude-tools",
|
|
69009
|
+
`${DELEGATE_TASK_TOOL_NAME},subagent`,
|
|
69010
|
+
"--append-system-prompt",
|
|
69011
|
+
promptPath,
|
|
69012
|
+
task
|
|
69013
|
+
];
|
|
69014
|
+
}
|
|
69015
|
+
function getNexusInvocation(args) {
|
|
69016
|
+
const currentScript = process.argv[1];
|
|
69017
|
+
const isBunVirtualScript = currentScript?.startsWith("/$bunfs/root/");
|
|
69018
|
+
if (currentScript && !isBunVirtualScript && fs7.existsSync(currentScript)) {
|
|
69019
|
+
return { command: process.execPath, args: [currentScript, ...args] };
|
|
69020
|
+
}
|
|
69021
|
+
const execName = path11.basename(process.execPath).toLowerCase();
|
|
69022
|
+
const isGenericRuntime = /^(node|bun)(\.exe)?$/.test(execName);
|
|
69023
|
+
return isGenericRuntime ? { command: "nexus", args } : { command: process.execPath, args };
|
|
69024
|
+
}
|
|
69025
|
+
async function writeWorkerPrompt() {
|
|
69026
|
+
const dir = await fs7.promises.mkdtemp(path11.join(os5.tmpdir(), "nexus-worker-"));
|
|
69027
|
+
const filePath = path11.join(dir, "system.md");
|
|
69028
|
+
await withFileMutationQueue2(filePath, async () => {
|
|
69029
|
+
await fs7.promises.writeFile(filePath, WORKER_SYSTEM_PROMPT, { encoding: "utf8", mode: 384 });
|
|
69030
|
+
});
|
|
69031
|
+
return { dir, filePath };
|
|
69032
|
+
}
|
|
69033
|
+
function truncateUtf8(value, cap) {
|
|
69034
|
+
if (Buffer.byteLength(value, "utf8") <= cap)
|
|
69035
|
+
return { value, truncated: false };
|
|
69036
|
+
const suffix = "\n\n[Report truncated]";
|
|
69037
|
+
let truncated = value.slice(0, Math.max(0, cap - Buffer.byteLength(suffix, "utf8")));
|
|
69038
|
+
while (Buffer.byteLength(`${truncated}${suffix}`, "utf8") > cap)
|
|
69039
|
+
truncated = truncated.slice(0, -1);
|
|
69040
|
+
return { value: `${truncated}${suffix}`, truncated: true };
|
|
69041
|
+
}
|
|
69042
|
+
function createHubDelegationController(config, options = {}) {
|
|
69043
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
69044
|
+
return {
|
|
69045
|
+
async createWorkerGrant(request) {
|
|
69046
|
+
const controller = new AbortController();
|
|
69047
|
+
const onAbort = () => controller.abort();
|
|
69048
|
+
if (request.signal?.aborted)
|
|
69049
|
+
controller.abort();
|
|
69050
|
+
else
|
|
69051
|
+
request.signal?.addEventListener("abort", onAbort, { once: true });
|
|
69052
|
+
const timeout = setTimeout(() => controller.abort(), options.timeoutMs ?? WORKER_GRANT_TIMEOUT_MS);
|
|
69053
|
+
try {
|
|
69054
|
+
const response = await fetchImpl(`${hubApiBase(config.hubUrl)}/llm/worker-grants`, {
|
|
69055
|
+
method: "POST",
|
|
69056
|
+
headers: {
|
|
69057
|
+
"content-type": "application/json",
|
|
69058
|
+
accept: "application/json",
|
|
69059
|
+
authorization: `Bearer ${config.token}`,
|
|
69060
|
+
[RUN_ID_HEADER]: request.runId,
|
|
69061
|
+
[REQUEST_ID_HEADER]: request.requestId,
|
|
69062
|
+
[ROOT_REQUEST_ID_HEADER]: request.rootRequestId,
|
|
69063
|
+
[PARENT_REQUEST_ID_HEADER]: request.parentRequestId,
|
|
69064
|
+
[DELEGATION_ID_HEADER]: request.taskId,
|
|
69065
|
+
[REQUEST_SCOPE_HEADER]: "worker",
|
|
69066
|
+
...config.deviceFingerprint ? { "x-device-fingerprint": config.deviceFingerprint } : {},
|
|
69067
|
+
...config.deviceName ? { "x-device-name": config.deviceName } : {}
|
|
69068
|
+
},
|
|
69069
|
+
body: JSON.stringify({ sessionId: request.sessionId, taskId: request.taskId }),
|
|
69070
|
+
signal: controller.signal
|
|
69071
|
+
});
|
|
69072
|
+
if (!response.ok) {
|
|
69073
|
+
await response.body?.cancel().catch(() => {
|
|
69074
|
+
});
|
|
69075
|
+
throw new Error("Worker authorization unavailable");
|
|
69076
|
+
}
|
|
69077
|
+
const body = await response.json();
|
|
69078
|
+
if (!isRecord(body) || typeof body.grant !== "string" || !body.grant.trim() || typeof body.expiresAt !== "string" || !body.expiresAt.trim() || !Number.isFinite(Date.parse(body.expiresAt))) {
|
|
69079
|
+
throw new Error("Invalid worker authorization response");
|
|
69080
|
+
}
|
|
69081
|
+
return { token: body.grant, expiresAt: body.expiresAt };
|
|
69082
|
+
} finally {
|
|
69083
|
+
clearTimeout(timeout);
|
|
69084
|
+
request.signal?.removeEventListener("abort", onAbort);
|
|
69085
|
+
}
|
|
69086
|
+
}
|
|
69087
|
+
};
|
|
69088
|
+
}
|
|
69089
|
+
function isDelegatedWorkerProcess(env = process.env) {
|
|
69090
|
+
return env[INTERNAL_WORKER_MARKER_ENV] === "1";
|
|
69091
|
+
}
|
|
69092
|
+
function consumeWorkerContext(env = process.env) {
|
|
69093
|
+
if (!isDelegatedWorkerProcess(env))
|
|
69094
|
+
return void 0;
|
|
69095
|
+
const sessionId = env[INTERNAL_WORKER_SESSION_ENV]?.trim();
|
|
69096
|
+
const taskId = env[INTERNAL_WORKER_TASK_ENV]?.trim();
|
|
69097
|
+
const runId = env[INTERNAL_WORKER_RUN_ENV]?.trim();
|
|
69098
|
+
const rootRequestId = env[INTERNAL_WORKER_ROOT_REQUEST_ENV]?.trim();
|
|
69099
|
+
const parentRequestId = env[INTERNAL_WORKER_PARENT_REQUEST_ENV]?.trim();
|
|
69100
|
+
delete env[INTERNAL_WORKER_SESSION_ENV];
|
|
69101
|
+
delete env[INTERNAL_WORKER_TASK_ENV];
|
|
69102
|
+
delete env[INTERNAL_WORKER_RUN_ENV];
|
|
69103
|
+
delete env[INTERNAL_WORKER_ROOT_REQUEST_ENV];
|
|
69104
|
+
delete env[INTERNAL_WORKER_PARENT_REQUEST_ENV];
|
|
69105
|
+
if (!sessionId || !taskId || !runId || !rootRequestId || !parentRequestId)
|
|
69106
|
+
return void 0;
|
|
69107
|
+
return { sessionId, taskId, runId, rootRequestId, parentRequestId };
|
|
69108
|
+
}
|
|
69109
|
+
function killProcessTree2(pid, signal) {
|
|
69110
|
+
if (pid === void 0)
|
|
69111
|
+
return;
|
|
69112
|
+
if (process.platform === "win32") {
|
|
69113
|
+
execFile2("taskkill", ["/T", "/F", "/PID", String(pid)], () => void 0);
|
|
69114
|
+
return;
|
|
69115
|
+
}
|
|
69116
|
+
try {
|
|
69117
|
+
process.kill(-pid, signal);
|
|
69118
|
+
} catch {
|
|
69119
|
+
}
|
|
69120
|
+
}
|
|
69121
|
+
async function runDelegatedWorker(options) {
|
|
69122
|
+
const prompt = await writeWorkerPrompt();
|
|
69123
|
+
const task = composeDelegatedTask(options.task, options.acceptanceCriteria, options.relevantPaths);
|
|
69124
|
+
const args = buildDelegatedWorkerArgs(task, prompt.filePath);
|
|
69125
|
+
let output = "";
|
|
69126
|
+
let turns = 0;
|
|
69127
|
+
let terminalStatus;
|
|
69128
|
+
let assistantFailed = false;
|
|
69129
|
+
let eventBytes = 0;
|
|
69130
|
+
try {
|
|
69131
|
+
const exitCode = await new Promise((resolve15) => {
|
|
69132
|
+
const invocation = getNexusInvocation(args);
|
|
69133
|
+
const child = spawn12(invocation.command, invocation.args, {
|
|
69134
|
+
cwd: options.cwd,
|
|
69135
|
+
detached: true,
|
|
69136
|
+
env: {
|
|
69137
|
+
...process.env,
|
|
69138
|
+
[INTERNAL_WORKER_MARKER_ENV]: "1",
|
|
69139
|
+
[INTERNAL_WORKER_SESSION_ENV]: options.workerContext.sessionId,
|
|
69140
|
+
[INTERNAL_WORKER_TASK_ENV]: options.workerContext.taskId,
|
|
69141
|
+
[INTERNAL_WORKER_RUN_ENV]: options.workerContext.runId,
|
|
69142
|
+
[INTERNAL_WORKER_ROOT_REQUEST_ENV]: options.workerContext.rootRequestId,
|
|
69143
|
+
[INTERNAL_WORKER_PARENT_REQUEST_ENV]: options.workerContext.parentRequestId
|
|
69144
|
+
},
|
|
69145
|
+
shell: false,
|
|
69146
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
69147
|
+
windowsHide: true
|
|
69148
|
+
});
|
|
69149
|
+
let buffer = "";
|
|
69150
|
+
let settled = false;
|
|
69151
|
+
let stopped = false;
|
|
69152
|
+
let forceKillTimer;
|
|
69153
|
+
const finish = (code) => {
|
|
69154
|
+
if (settled)
|
|
69155
|
+
return;
|
|
69156
|
+
settled = true;
|
|
69157
|
+
clearTimeout(timeoutTimer);
|
|
69158
|
+
clearTimeout(forceKillTimer);
|
|
69159
|
+
options.signal?.removeEventListener("abort", abortHandler);
|
|
69160
|
+
resolve15(code);
|
|
69161
|
+
};
|
|
69162
|
+
const stop = (status2) => {
|
|
69163
|
+
if (stopped)
|
|
69164
|
+
return;
|
|
69165
|
+
stopped = true;
|
|
69166
|
+
terminalStatus = status2;
|
|
69167
|
+
killProcessTree2(child.pid, "SIGTERM");
|
|
69168
|
+
forceKillTimer = setTimeout(() => {
|
|
69169
|
+
if (process.platform !== "win32")
|
|
69170
|
+
killProcessTree2(child.pid, "SIGKILL");
|
|
69171
|
+
finish(1);
|
|
69172
|
+
}, 5e3);
|
|
69173
|
+
};
|
|
69174
|
+
const emitProgress = () => {
|
|
69175
|
+
options.onUpdate?.({
|
|
69176
|
+
content: [{ type: "text", text: "Delegated work is in progress." }],
|
|
69177
|
+
details: { status: "running", turns }
|
|
69178
|
+
});
|
|
69179
|
+
};
|
|
69180
|
+
const processLine = (line) => {
|
|
69181
|
+
if (!line.trim())
|
|
69182
|
+
return;
|
|
69183
|
+
let parsed;
|
|
69184
|
+
try {
|
|
69185
|
+
parsed = JSON.parse(line);
|
|
69186
|
+
} catch {
|
|
69187
|
+
return;
|
|
69188
|
+
}
|
|
69189
|
+
if (!isRecord(parsed) || parsed.type !== "message_end")
|
|
69190
|
+
return;
|
|
69191
|
+
const snapshot = parseAssistantSnapshot(parsed.message);
|
|
69192
|
+
if (!snapshot)
|
|
69193
|
+
return;
|
|
69194
|
+
turns += 1;
|
|
69195
|
+
if (snapshot.text)
|
|
69196
|
+
output = snapshot.text;
|
|
69197
|
+
if (snapshot.stopReason === "error" || snapshot.stopReason === "aborted")
|
|
69198
|
+
assistantFailed = true;
|
|
69199
|
+
emitProgress();
|
|
69200
|
+
if (turns >= MAX_DELEGATED_TURNS)
|
|
69201
|
+
stop("turn_limit");
|
|
69202
|
+
};
|
|
69203
|
+
const abortHandler = () => stop("aborted");
|
|
69204
|
+
const timeoutTimer = setTimeout(() => stop("timeout"), Math.min(Math.max(1e3, options.timeoutMs ?? DELEGATED_WORKER_TIMEOUT_MS), DELEGATED_WORKER_TIMEOUT_MS));
|
|
69205
|
+
child.stdout.on("data", (chunk) => {
|
|
69206
|
+
eventBytes += Buffer.byteLength(chunk);
|
|
69207
|
+
if (eventBytes > DELEGATED_EVENT_CAP_BYTES) {
|
|
69208
|
+
assistantFailed = true;
|
|
69209
|
+
stop("event_limit");
|
|
69210
|
+
return;
|
|
69211
|
+
}
|
|
69212
|
+
buffer += chunk.toString();
|
|
69213
|
+
if (Buffer.byteLength(buffer, "utf8") > DELEGATED_EVENT_CAP_BYTES) {
|
|
69214
|
+
buffer = "";
|
|
69215
|
+
assistantFailed = true;
|
|
69216
|
+
return;
|
|
69217
|
+
}
|
|
69218
|
+
const lines = buffer.split("\n");
|
|
69219
|
+
buffer = lines.pop() ?? "";
|
|
69220
|
+
for (const line of lines)
|
|
69221
|
+
processLine(line);
|
|
69222
|
+
});
|
|
69223
|
+
child.stderr.on("data", () => void 0);
|
|
69224
|
+
child.on("close", (code) => {
|
|
69225
|
+
if (buffer.trim())
|
|
69226
|
+
processLine(buffer);
|
|
69227
|
+
finish(code ?? (terminalStatus ? 1 : 0));
|
|
69228
|
+
});
|
|
69229
|
+
child.on("error", () => finish(1));
|
|
69230
|
+
if (options.signal?.aborted)
|
|
69231
|
+
abortHandler();
|
|
69232
|
+
else
|
|
69233
|
+
options.signal?.addEventListener("abort", abortHandler, { once: true });
|
|
69234
|
+
});
|
|
69235
|
+
const limitedOutput = truncateUtf8(output, DELEGATED_OUTPUT_CAP_BYTES);
|
|
69236
|
+
const status = terminalStatus ?? (exitCode === 0 && !assistantFailed ? "completed" : "failed");
|
|
69237
|
+
return {
|
|
69238
|
+
status,
|
|
69239
|
+
turns,
|
|
69240
|
+
exitCode,
|
|
69241
|
+
output: limitedOutput.value,
|
|
69242
|
+
outputTruncated: limitedOutput.truncated
|
|
69243
|
+
};
|
|
69244
|
+
} finally {
|
|
69245
|
+
await fs7.promises.rm(prompt.dir, { recursive: true, force: true });
|
|
69246
|
+
}
|
|
69247
|
+
}
|
|
69248
|
+
var DelegateTaskParameters = Type17.Object({
|
|
69249
|
+
task: Type17.String({ description: "A narrow implementation task with explicit boundaries", maxLength: 32768 }),
|
|
69250
|
+
acceptanceCriteria: Type17.Optional(Type17.Array(Type17.String({ maxLength: 2e3 }), { maxItems: 10 })),
|
|
69251
|
+
relevantPaths: Type17.Optional(Type17.Array(Type17.String({ maxLength: 1e3 }), { maxItems: 20 }))
|
|
69252
|
+
});
|
|
69253
|
+
function resultContent(result) {
|
|
69254
|
+
const report = result.output.trim() || "No implementation report was returned.";
|
|
69255
|
+
if (result.status === "completed")
|
|
69256
|
+
return `Delegated implementation completed.
|
|
69257
|
+
|
|
69258
|
+
${report}`;
|
|
69259
|
+
return `Delegated implementation did not complete (${result.status}).
|
|
69260
|
+
|
|
69261
|
+
Partial report:
|
|
69262
|
+
${report}`;
|
|
69263
|
+
}
|
|
69264
|
+
function registerDelegateTaskTool(pi, capability) {
|
|
69265
|
+
const maxTaskBytes = Math.min(Math.max(1, Math.floor(capability.maxTaskBytes)), MAX_DELEGATED_TASK_BYTES);
|
|
69266
|
+
const workerTimeoutMs = Math.min(Math.max(1e3, Math.floor(capability.workerTimeoutMs)), DELEGATED_WORKER_TIMEOUT_MS);
|
|
69267
|
+
const runId = randomUUID6();
|
|
69268
|
+
let rootRequestId;
|
|
69269
|
+
let latestRootRequestId;
|
|
69270
|
+
let activeWorkers = 0;
|
|
69271
|
+
let invocationCount = 0;
|
|
69272
|
+
let rootReviewToolCalls = 0;
|
|
69273
|
+
pi.on("before_agent_start", (event) => {
|
|
69274
|
+
invocationCount = 0;
|
|
69275
|
+
rootReviewToolCalls = 0;
|
|
69276
|
+
return {
|
|
69277
|
+
systemPrompt: `${event.systemPrompt}
|
|
69278
|
+
|
|
69279
|
+
Implementation policy: perform implementation, mutation, shell, and repeated tool loops through delegate_task. Keep this parent conversation focused on planning and final review. Use only bounded read-only tools to inspect worker changes, verify graph impact, and reach the final answer.`
|
|
69280
|
+
};
|
|
69281
|
+
});
|
|
69282
|
+
pi.on("before_provider_headers", (event, ctx) => {
|
|
69283
|
+
if (!isAutoModel(ctx.model) || isDelegatedWorkerProcess())
|
|
69284
|
+
return;
|
|
69285
|
+
const requestId = randomUUID6();
|
|
69286
|
+
rootRequestId ??= requestId;
|
|
69287
|
+
latestRootRequestId = requestId;
|
|
69288
|
+
event.headers[RUN_ID_HEADER] = runId;
|
|
69289
|
+
event.headers[REQUEST_ID_HEADER] = requestId;
|
|
69290
|
+
event.headers[ROOT_REQUEST_ID_HEADER] = rootRequestId;
|
|
69291
|
+
event.headers[REQUEST_SCOPE_HEADER] = "root";
|
|
69292
|
+
});
|
|
69293
|
+
pi.on("tool_call", (event, ctx) => {
|
|
69294
|
+
if (!isAutoModel(ctx.model) || isDelegatedWorkerProcess() || event.toolName === DELEGATE_TASK_TOOL_NAME) {
|
|
69295
|
+
return;
|
|
69296
|
+
}
|
|
69297
|
+
if (!ROOT_REVIEW_TOOLS.has(event.toolName)) {
|
|
69298
|
+
return {
|
|
69299
|
+
block: true,
|
|
69300
|
+
reason: "This parent run is review-only. Use delegate_task for implementation, mutation, shell commands, tests, or other execution."
|
|
69301
|
+
};
|
|
69302
|
+
}
|
|
69303
|
+
if (rootReviewToolCalls >= MAX_ROOT_REVIEW_TOOL_CALLS) {
|
|
69304
|
+
return {
|
|
69305
|
+
block: true,
|
|
69306
|
+
reason: "The bounded parent review budget is exhausted. Delegate further investigation or finalize the review."
|
|
69307
|
+
};
|
|
69308
|
+
}
|
|
69309
|
+
rootReviewToolCalls += 1;
|
|
69310
|
+
});
|
|
69311
|
+
pi.registerTool({
|
|
69312
|
+
name: DELEGATE_TASK_TOOL_NAME,
|
|
69313
|
+
label: "Work",
|
|
69314
|
+
description: "Delegate one narrow implementation task to an isolated internal worker. Keep planning, user communication, and final verification in this conversation.",
|
|
69315
|
+
promptGuidelines: [
|
|
69316
|
+
"Use delegate_task for bounded implementation, mutation, command execution, tests, and repeated tool work after you have formed a plan.",
|
|
69317
|
+
"You remain responsible for reviewing the returned report, verifying the result, and communicating with the user."
|
|
69318
|
+
],
|
|
69319
|
+
parameters: DelegateTaskParameters,
|
|
69320
|
+
executionMode: "sequential",
|
|
69321
|
+
async execute(_toolCallId, params, signal, onUpdate, ctx) {
|
|
69322
|
+
if (!isAutoModel(ctx.model)) {
|
|
69323
|
+
return {
|
|
69324
|
+
content: [{ type: "text", text: "Delegated work is unavailable for the active mode." }],
|
|
69325
|
+
details: { status: "failed", turns: 0 }
|
|
69326
|
+
};
|
|
69327
|
+
}
|
|
69328
|
+
if (!ctx.isProjectTrusted()) {
|
|
69329
|
+
return {
|
|
69330
|
+
content: [{ type: "text", text: "Delegated work requires a trusted project." }],
|
|
69331
|
+
details: { status: "failed", turns: 0 }
|
|
69332
|
+
};
|
|
69333
|
+
}
|
|
69334
|
+
if (activeWorkers >= MAX_PARALLEL_MUTATING_WORKERS || invocationCount >= MAX_DELEGATIONS_PER_RUN) {
|
|
69335
|
+
return {
|
|
69336
|
+
content: [{ type: "text", text: "Delegated work is temporarily unavailable for this run." }],
|
|
69337
|
+
details: { status: "failed", turns: 0 }
|
|
69338
|
+
};
|
|
69339
|
+
}
|
|
69340
|
+
const request = {
|
|
69341
|
+
task: params.task,
|
|
69342
|
+
acceptanceCriteria: params.acceptanceCriteria ?? [],
|
|
69343
|
+
relevantPaths: params.relevantPaths ?? [],
|
|
69344
|
+
cwd: ctx.cwd,
|
|
69345
|
+
signal
|
|
69346
|
+
};
|
|
69347
|
+
if (Buffer.byteLength(composeDelegatedTask(request.task, request.acceptanceCriteria, request.relevantPaths), "utf8") > maxTaskBytes) {
|
|
69348
|
+
return {
|
|
69349
|
+
content: [{ type: "text", text: "Delegated work is too large for one bounded task." }],
|
|
69350
|
+
details: { status: "failed", turns: 0 }
|
|
69351
|
+
};
|
|
69352
|
+
}
|
|
69353
|
+
activeWorkers += 1;
|
|
69354
|
+
invocationCount += 1;
|
|
69355
|
+
try {
|
|
69356
|
+
const delegationId = randomUUID6();
|
|
69357
|
+
rootRequestId ??= randomUUID6();
|
|
69358
|
+
const result = await runDelegatedWorker({
|
|
69359
|
+
...request,
|
|
69360
|
+
workerContext: {
|
|
69361
|
+
sessionId: ctx.sessionManager.getSessionId(),
|
|
69362
|
+
taskId: delegationId,
|
|
69363
|
+
runId,
|
|
69364
|
+
rootRequestId,
|
|
69365
|
+
parentRequestId: latestRootRequestId ?? rootRequestId
|
|
69366
|
+
},
|
|
69367
|
+
timeoutMs: workerTimeoutMs,
|
|
69368
|
+
onUpdate
|
|
69369
|
+
});
|
|
69370
|
+
return {
|
|
69371
|
+
content: [{ type: "text", text: resultContent(result) }],
|
|
69372
|
+
details: {
|
|
69373
|
+
status: result.status,
|
|
69374
|
+
turns: result.turns,
|
|
69375
|
+
exitCode: result.exitCode,
|
|
69376
|
+
outputTruncated: result.outputTruncated
|
|
69377
|
+
}
|
|
69378
|
+
};
|
|
69379
|
+
} catch {
|
|
69380
|
+
return {
|
|
69381
|
+
content: [{ type: "text", text: "Delegated work could not be started." }],
|
|
69382
|
+
details: { status: "failed", turns: 0 }
|
|
69383
|
+
};
|
|
69384
|
+
} finally {
|
|
69385
|
+
activeWorkers -= 1;
|
|
69386
|
+
}
|
|
69387
|
+
},
|
|
69388
|
+
renderCall(_args, theme2) {
|
|
69389
|
+
return new Text(theme2.fg("toolTitle", theme2.bold("Working\u2026")), 0, 0);
|
|
69390
|
+
},
|
|
69391
|
+
renderResult(result, _options, theme2) {
|
|
69392
|
+
const details = result.details;
|
|
69393
|
+
if (details?.status === "running")
|
|
69394
|
+
return new Text(theme2.fg("muted", "Working\u2026"), 0, 0);
|
|
69395
|
+
if (details?.status === "completed")
|
|
69396
|
+
return new Text(theme2.fg("success", "Work completed"), 0, 0);
|
|
69397
|
+
return new Text(theme2.fg("error", "Work needs attention"), 0, 0);
|
|
69398
|
+
}
|
|
69399
|
+
});
|
|
69400
|
+
}
|
|
69401
|
+
function registerWorkerGrantHeaders(pi, workerContext, controller) {
|
|
69402
|
+
pi.on("before_provider_headers", async (event, ctx) => {
|
|
69403
|
+
if (!isAutoModel(ctx.model)) {
|
|
69404
|
+
ctx.abort();
|
|
69405
|
+
return;
|
|
69406
|
+
}
|
|
69407
|
+
const requestId = randomUUID6();
|
|
69408
|
+
event.headers[INTERNAL_WORKER_GRANT_HEADER] = INVALID_WORKER_GRANT;
|
|
69409
|
+
event.headers[INTERNAL_WORKER_TASK_HEADER] = workerContext.taskId;
|
|
69410
|
+
event.headers[SESSION_AFFINITY_HEADER] = workerContext.sessionId;
|
|
69411
|
+
event.headers[RUN_ID_HEADER] = workerContext.runId;
|
|
69412
|
+
event.headers[REQUEST_ID_HEADER] = requestId;
|
|
69413
|
+
event.headers[ROOT_REQUEST_ID_HEADER] = workerContext.rootRequestId;
|
|
69414
|
+
event.headers[PARENT_REQUEST_ID_HEADER] = workerContext.parentRequestId;
|
|
69415
|
+
event.headers[DELEGATION_ID_HEADER] = workerContext.taskId;
|
|
69416
|
+
event.headers[REQUEST_SCOPE_HEADER] = "worker";
|
|
69417
|
+
if (!controller)
|
|
69418
|
+
return;
|
|
69419
|
+
const grant = await controller.createWorkerGrant({
|
|
69420
|
+
...workerContext,
|
|
69421
|
+
requestId,
|
|
69422
|
+
signal: ctx.signal
|
|
69423
|
+
});
|
|
69424
|
+
event.headers[INTERNAL_WORKER_GRANT_HEADER] = grant.token;
|
|
69425
|
+
});
|
|
69426
|
+
}
|
|
69427
|
+
function delegatedWorkerRuntime(pi) {
|
|
69428
|
+
const isWorker = isDelegatedWorkerProcess();
|
|
69429
|
+
const workerContext = consumeWorkerContext();
|
|
69430
|
+
if (!isWorker)
|
|
69431
|
+
return;
|
|
69432
|
+
const config = resolveGitNexusConfig();
|
|
69433
|
+
const failClosedContext = {
|
|
69434
|
+
sessionId: "unavailable",
|
|
69435
|
+
taskId: "unavailable",
|
|
69436
|
+
runId: "unavailable",
|
|
69437
|
+
rootRequestId: "unavailable",
|
|
69438
|
+
parentRequestId: "unavailable"
|
|
69439
|
+
};
|
|
69440
|
+
registerWorkerGrantHeaders(pi, workerContext ?? failClosedContext, workerContext && config ? createHubDelegationController(config) : void 0);
|
|
69441
|
+
}
|
|
69442
|
+
|
|
68912
69443
|
// dist/extensions/gitnexus/augment.js
|
|
68913
69444
|
var AUGMENT_TIMEOUT_MS = 3e3;
|
|
68914
69445
|
var AUGMENT_MAX_CHARS = 1500;
|
|
@@ -68981,11 +69512,11 @@ function registerChangeTracking(pi, cwd) {
|
|
|
68981
69512
|
execute: async (id, params, signal, onUpdate, ctx) => {
|
|
68982
69513
|
const result = await edit.execute(id, params, signal, onUpdate, ctx);
|
|
68983
69514
|
try {
|
|
68984
|
-
const
|
|
69515
|
+
const path12 = String(params?.path ?? "");
|
|
68985
69516
|
const diff = result.details?.diff;
|
|
68986
69517
|
const { added, removed } = countDiff(diff);
|
|
68987
|
-
if (
|
|
68988
|
-
graphRailStore.recordChange(
|
|
69518
|
+
if (path12 && (added > 0 || removed > 0))
|
|
69519
|
+
graphRailStore.recordChange(path12, added, removed);
|
|
68989
69520
|
} catch {
|
|
68990
69521
|
}
|
|
68991
69522
|
return result;
|
|
@@ -68997,10 +69528,10 @@ function registerChangeTracking(pi, cwd) {
|
|
|
68997
69528
|
const result = await write.execute(id, params, signal, onUpdate, ctx);
|
|
68998
69529
|
try {
|
|
68999
69530
|
const p = params;
|
|
69000
|
-
const
|
|
69531
|
+
const path12 = String(p?.path ?? "");
|
|
69001
69532
|
const lineCount = String(p?.content ?? "").split("\n").length;
|
|
69002
|
-
if (
|
|
69003
|
-
graphRailStore.recordChange(
|
|
69533
|
+
if (path12)
|
|
69534
|
+
graphRailStore.recordChange(path12, lineCount, 0);
|
|
69004
69535
|
} catch {
|
|
69005
69536
|
}
|
|
69006
69537
|
return result;
|
|
@@ -69009,7 +69540,7 @@ function registerChangeTracking(pi, cwd) {
|
|
|
69009
69540
|
}
|
|
69010
69541
|
|
|
69011
69542
|
// dist/extensions/gitnexus/observatory.js
|
|
69012
|
-
import { spawn as
|
|
69543
|
+
import { spawn as spawn13 } from "node:child_process";
|
|
69013
69544
|
import { appendFileSync as appendFileSync5 } from "node:fs";
|
|
69014
69545
|
function trace(message) {
|
|
69015
69546
|
if (!process.env.NEXUS_TRACE)
|
|
@@ -69023,7 +69554,7 @@ function trace(message) {
|
|
|
69023
69554
|
function spawnObservatoryFetch(config, repo) {
|
|
69024
69555
|
try {
|
|
69025
69556
|
const script = buildFetchScript();
|
|
69026
|
-
const child =
|
|
69557
|
+
const child = spawn13(process.execPath, ["-e", script], {
|
|
69027
69558
|
detached: true,
|
|
69028
69559
|
stdio: "ignore",
|
|
69029
69560
|
env: {
|
|
@@ -69161,7 +69692,7 @@ function parseHubJson(text) {
|
|
|
69161
69692
|
return void 0;
|
|
69162
69693
|
}
|
|
69163
69694
|
}
|
|
69164
|
-
function
|
|
69695
|
+
function basename14(filePath) {
|
|
69165
69696
|
if (!filePath)
|
|
69166
69697
|
return "";
|
|
69167
69698
|
return filePath.split("/").pop() ?? filePath;
|
|
@@ -69391,7 +69922,7 @@ function formatQuery(text, theme2) {
|
|
|
69391
69922
|
if (shownSymbols.length > 0) {
|
|
69392
69923
|
lines.push(theme2.fg("muted", "symbols:"));
|
|
69393
69924
|
for (const sym of shownSymbols) {
|
|
69394
|
-
const loc = sym.filePath ? `${
|
|
69925
|
+
const loc = sym.filePath ? `${basename14(sym.filePath)}${sym.startLine ? `:${sym.startLine}` : ""}` : "";
|
|
69395
69926
|
lines.push(` ${theme2.fg("accent", "\u2022")} ${sym.name} ${theme2.fg("muted", loc)}`);
|
|
69396
69927
|
}
|
|
69397
69928
|
}
|
|
@@ -69522,7 +70053,7 @@ function matchCurrentRepo(inventory, slug) {
|
|
|
69522
70053
|
|
|
69523
70054
|
// dist/extensions/gitnexus/tools.js
|
|
69524
70055
|
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
69525
|
-
import { Type as
|
|
70056
|
+
import { Type as Type18 } from "typebox";
|
|
69526
70057
|
function aliasParam(args, canonical, aliases) {
|
|
69527
70058
|
if (args[canonical] !== void 0)
|
|
69528
70059
|
return args;
|
|
@@ -69601,7 +70132,7 @@ function makeHubTool(ctx, options) {
|
|
|
69601
70132
|
}
|
|
69602
70133
|
};
|
|
69603
70134
|
}
|
|
69604
|
-
var repoParam =
|
|
70135
|
+
var repoParam = Type18.Optional(Type18.String({
|
|
69605
70136
|
description: "Indexed repository name or @group. Omit for the current repository."
|
|
69606
70137
|
}));
|
|
69607
70138
|
function createGitNexusTools(ctx) {
|
|
@@ -69611,11 +70142,11 @@ function createGitNexusTools(ctx) {
|
|
|
69611
70142
|
label: "GitNexus query",
|
|
69612
70143
|
description: "Query the code knowledge graph for execution flows related to a concept. Returns processes (call chains) ranked by relevance, each with its symbols and file locations. WHEN TO USE: understanding how code works together \u2014 execution flows and relationships, not just file matches. Complements grep. AFTER THIS: use gitnexus_context on a specific symbol for its 360-degree view.",
|
|
69613
70144
|
promptSnippet: "gitnexus_query: find execution flows by concept in the knowledge graph",
|
|
69614
|
-
parameters:
|
|
69615
|
-
query:
|
|
69616
|
-
goal:
|
|
69617
|
-
task_context:
|
|
69618
|
-
limit:
|
|
70145
|
+
parameters: Type18.Object({
|
|
70146
|
+
query: Type18.String({ description: "Natural language or keyword search query" }),
|
|
70147
|
+
goal: Type18.Optional(Type18.String({ description: "What you want to find. Helps ranking." })),
|
|
70148
|
+
task_context: Type18.Optional(Type18.String({ description: "What you are working on. Helps ranking." })),
|
|
70149
|
+
limit: Type18.Optional(Type18.Number({ description: "Max processes to return (default 5)" })),
|
|
69619
70150
|
repo: repoParam
|
|
69620
70151
|
})
|
|
69621
70152
|
});
|
|
@@ -69625,10 +70156,10 @@ function createGitNexusTools(ctx) {
|
|
|
69625
70156
|
label: "GitNexus context",
|
|
69626
70157
|
description: "360-degree view of a single code symbol: categorized incoming/outgoing references (calls, imports, extends, implements, overrides, field reads/writes), process participation, and file location. WHEN TO USE: after gitnexus_query, or whenever you need all callers/callees of a symbol. AFTER THIS: use gitnexus_impact if you plan to change it.",
|
|
69627
70158
|
promptSnippet: "gitnexus_context: all callers/callees/flows of one symbol",
|
|
69628
|
-
parameters:
|
|
69629
|
-
name:
|
|
69630
|
-
file_path:
|
|
69631
|
-
kind:
|
|
70159
|
+
parameters: Type18.Object({
|
|
70160
|
+
name: Type18.String({ description: 'Symbol name (e.g. "validateUser", "AuthService")' }),
|
|
70161
|
+
file_path: Type18.Optional(Type18.String({ description: "File path to disambiguate common names" })),
|
|
70162
|
+
kind: Type18.Optional(Type18.String({ description: "Kind filter, e.g. 'Function' | 'Class' | 'Method'" })),
|
|
69632
70163
|
repo: repoParam
|
|
69633
70164
|
}),
|
|
69634
70165
|
prepareArguments: (args) => aliasParam(args ?? {}, "name", ["target", "symbol"])
|
|
@@ -69642,9 +70173,9 @@ function createGitNexusTools(ctx) {
|
|
|
69642
70173
|
promptGuidelines: [
|
|
69643
70174
|
"Before editing a function, class, or method that the graph knows, run gitnexus_impact on it first and surface HIGH/CRITICAL risk to the user."
|
|
69644
70175
|
],
|
|
69645
|
-
parameters:
|
|
69646
|
-
target:
|
|
69647
|
-
direction:
|
|
70176
|
+
parameters: Type18.Object({
|
|
70177
|
+
target: Type18.String({ description: "Symbol to analyze" }),
|
|
70178
|
+
direction: Type18.Optional(Type18.String({ description: '"upstream" (callers, default), "downstream" (callees), or "both"' })),
|
|
69648
70179
|
repo: repoParam
|
|
69649
70180
|
}),
|
|
69650
70181
|
prepareArguments: (args) => aliasParam(args ?? {}, "target", ["name", "symbol"]),
|
|
@@ -69656,7 +70187,7 @@ function createGitNexusTools(ctx) {
|
|
|
69656
70187
|
label: "GitNexus detect changes",
|
|
69657
70188
|
description: "Map the current git diff to indexed symbols and trace which execution flows are impacted. WHEN TO USE: before committing \u2014 to understand what your changes affect and what to test.",
|
|
69658
70189
|
promptSnippet: "gitnexus_detect_changes: map local diff to affected flows",
|
|
69659
|
-
parameters:
|
|
70190
|
+
parameters: Type18.Object({ repo: repoParam }),
|
|
69660
70191
|
mapArgs: (params) => {
|
|
69661
70192
|
const diff = spawnSync9("git", ["diff", "--name-only", "HEAD"], {
|
|
69662
70193
|
cwd: ctx.cwd,
|
|
@@ -69675,8 +70206,8 @@ function createGitNexusTools(ctx) {
|
|
|
69675
70206
|
promptGuidelines: [
|
|
69676
70207
|
"Prefer gitnexus_query/context/impact; reach for gitnexus_cypher only when they cannot express the question."
|
|
69677
70208
|
],
|
|
69678
|
-
parameters:
|
|
69679
|
-
query:
|
|
70209
|
+
parameters: Type18.Object({
|
|
70210
|
+
query: Type18.String({ description: "Cypher query to execute" }),
|
|
69680
70211
|
repo: repoParam
|
|
69681
70212
|
})
|
|
69682
70213
|
});
|
|
@@ -69685,14 +70216,14 @@ function createGitNexusTools(ctx) {
|
|
|
69685
70216
|
hubTool: "list_repos",
|
|
69686
70217
|
label: "GitNexus repos",
|
|
69687
70218
|
description: "List all repositories (and multi-repo @groups) indexed on GitNexus, with symbol/relationship counts and indexed dates. WHEN TO USE: to discover or refresh what you can query across repositories.",
|
|
69688
|
-
parameters:
|
|
70219
|
+
parameters: Type18.Object({}),
|
|
69689
70220
|
mapArgs: () => ({})
|
|
69690
70221
|
});
|
|
69691
70222
|
return [query, context, impact, detectChanges, cypher, listRepos];
|
|
69692
70223
|
}
|
|
69693
70224
|
|
|
69694
70225
|
// dist/extensions/gitnexus/index.js
|
|
69695
|
-
function resolveGitNexusSkillsDir(moduleUrl = import.meta.url, pathExists2 =
|
|
70226
|
+
function resolveGitNexusSkillsDir(moduleUrl = import.meta.url, pathExists2 = existsSync26) {
|
|
69696
70227
|
const candidates = [
|
|
69697
70228
|
fileURLToPath7(new URL("./skills/", moduleUrl)),
|
|
69698
70229
|
fileURLToPath7(new URL("./extensions/gitnexus/skills/", moduleUrl))
|
|
@@ -69704,11 +70235,21 @@ function gitnexusExtension(pi) {
|
|
|
69704
70235
|
let current;
|
|
69705
70236
|
let activeClient;
|
|
69706
70237
|
let toolsRegistered = false;
|
|
70238
|
+
let delegationRegistered = false;
|
|
69707
70239
|
let startupNotice;
|
|
69708
70240
|
let loginRequired = false;
|
|
69709
70241
|
const cwd = process.cwd();
|
|
69710
70242
|
let gatewayPolicy = readGatewayCache();
|
|
69711
|
-
|
|
70243
|
+
const initialConfig = resolveGitNexusConfig();
|
|
70244
|
+
registerAutoProvider(pi, initialConfig, gatewayPolicy);
|
|
70245
|
+
function registerDelegationIfAvailable() {
|
|
70246
|
+
if (delegationRegistered || isDelegatedWorkerProcess() || !resolveGitNexusConfig() || !gatewayPolicy?.delegation) {
|
|
70247
|
+
return;
|
|
70248
|
+
}
|
|
70249
|
+
registerDelegateTaskTool(pi, gatewayPolicy.delegation);
|
|
70250
|
+
delegationRegistered = true;
|
|
70251
|
+
}
|
|
70252
|
+
registerDelegationIfAvailable();
|
|
69712
70253
|
function updateCreditStatus(ctx) {
|
|
69713
70254
|
ctx.ui.setStatus("nexus-credits", formatCreditBalance(gatewayPolicy));
|
|
69714
70255
|
}
|
|
@@ -69774,10 +70315,11 @@ function gitnexusExtension(pi) {
|
|
|
69774
70315
|
const config = resolveGitNexusConfig();
|
|
69775
70316
|
if (config)
|
|
69776
70317
|
gatewayPolicy = await refreshGatewayPolicy(config);
|
|
70318
|
+
registerDelegationIfAvailable();
|
|
69777
70319
|
updateCreditStatus(ctx);
|
|
69778
70320
|
});
|
|
69779
70321
|
pi.on("resources_discover", (event) => {
|
|
69780
|
-
const hasOwnGitnexusSkills =
|
|
70322
|
+
const hasOwnGitnexusSkills = existsSync26(join39(event.cwd, ".agents", "skills", "gitnexus")) || existsSync26(join39(homedir12(), ".agents", "skills", "gitnexus-debugging"));
|
|
69781
70323
|
if (hasOwnGitnexusSkills)
|
|
69782
70324
|
return;
|
|
69783
70325
|
const skillsDir = resolveGitNexusSkillsDir();
|
|
@@ -69800,9 +70342,9 @@ ${buildGitNexusPrompt(inventory, current)}` };
|
|
|
69800
70342
|
if (pasted) {
|
|
69801
70343
|
try {
|
|
69802
70344
|
await new GitNexusClient({ hubUrl, token: pasted }).callTool("list_repos", {});
|
|
69803
|
-
const
|
|
70345
|
+
const path12 = saveGitNexusConfig({ hubUrl, token: pasted });
|
|
69804
70346
|
await connect2();
|
|
69805
|
-
ctx.ui.notify(`GitNexus token saved to ${
|
|
70347
|
+
ctx.ui.notify(`GitNexus token saved to ${path12}. ${startupNotice ?? ""}`, "info");
|
|
69806
70348
|
} catch (error) {
|
|
69807
70349
|
const message = error instanceof Error ? error.message : String(error);
|
|
69808
70350
|
ctx.ui.notify(`GitNexus login failed: ${message}`, "error");
|
|
@@ -69824,9 +70366,9 @@ ${buildGitNexusPrompt(inventory, current)}` };
|
|
|
69824
70366
|
deviceName
|
|
69825
70367
|
};
|
|
69826
70368
|
await new GitNexusClient(config).callTool("list_repos", {});
|
|
69827
|
-
const
|
|
70369
|
+
const path12 = saveGitNexusConfig(config);
|
|
69828
70370
|
await connect2();
|
|
69829
|
-
ctx.ui.notify(`Signed in. Token saved to ${
|
|
70371
|
+
ctx.ui.notify(`Signed in. Token saved to ${path12}. ${startupNotice ?? ""}`, "info");
|
|
69830
70372
|
} catch (error) {
|
|
69831
70373
|
const message = error instanceof Error ? error.message : String(error);
|
|
69832
70374
|
ctx.ui.notify(`GitNexus login failed: ${message}`, "error");
|
|
@@ -69853,10 +70395,10 @@ ${buildGitNexusPrompt(inventory, current)}` };
|
|
|
69853
70395
|
}
|
|
69854
70396
|
|
|
69855
70397
|
// dist/extensions/mcp/index.js
|
|
69856
|
-
import { Type as
|
|
70398
|
+
import { Type as Type19 } from "typebox";
|
|
69857
70399
|
|
|
69858
70400
|
// dist/extensions/mcp/client.js
|
|
69859
|
-
import { spawn as
|
|
70401
|
+
import { spawn as spawn14 } from "node:child_process";
|
|
69860
70402
|
var MCP_PROTOCOL_VERSION = "2025-06-18";
|
|
69861
70403
|
var REQUEST_TIMEOUT_MS4 = 6e4;
|
|
69862
70404
|
var McpClientError = class extends Error {
|
|
@@ -69962,7 +70504,7 @@ var StdioTransport = class {
|
|
|
69962
70504
|
return this.child;
|
|
69963
70505
|
let child;
|
|
69964
70506
|
try {
|
|
69965
|
-
child =
|
|
70507
|
+
child = spawn14(this.command, this.args, {
|
|
69966
70508
|
stdio: ["pipe", "pipe", "pipe"],
|
|
69967
70509
|
env: { ...process.env, ...this.env },
|
|
69968
70510
|
cwd: this.cwd
|
|
@@ -70100,7 +70642,7 @@ var McpClient = class {
|
|
|
70100
70642
|
// dist/extensions/mcp/config.js
|
|
70101
70643
|
import { readFileSync as readFileSync20 } from "node:fs";
|
|
70102
70644
|
import { homedir as homedir13 } from "node:os";
|
|
70103
|
-
import { join as
|
|
70645
|
+
import { join as join40 } from "node:path";
|
|
70104
70646
|
function stringRecord(value) {
|
|
70105
70647
|
if (!value || typeof value !== "object")
|
|
70106
70648
|
return {};
|
|
@@ -70155,19 +70697,19 @@ function parseMcpConfig(text, source) {
|
|
|
70155
70697
|
return { servers, diagnostics };
|
|
70156
70698
|
}
|
|
70157
70699
|
function mcpConfigPaths(cwd, home = homedir13()) {
|
|
70158
|
-
return [
|
|
70700
|
+
return [join40(home, ".config", "nexus", "mcp.json"), join40(cwd, CONFIG_DIR_NAME, "mcp.json")];
|
|
70159
70701
|
}
|
|
70160
|
-
function loadMcpConfig(cwd, readFile4 = (
|
|
70702
|
+
function loadMcpConfig(cwd, readFile4 = (path12) => readFileSync20(path12, "utf8"), home) {
|
|
70161
70703
|
const byName = /* @__PURE__ */ new Map();
|
|
70162
70704
|
const diagnostics = [];
|
|
70163
|
-
for (const
|
|
70705
|
+
for (const path12 of mcpConfigPaths(cwd, home)) {
|
|
70164
70706
|
let text;
|
|
70165
70707
|
try {
|
|
70166
|
-
text = readFile4(
|
|
70708
|
+
text = readFile4(path12);
|
|
70167
70709
|
} catch {
|
|
70168
70710
|
continue;
|
|
70169
70711
|
}
|
|
70170
|
-
const parsed = parseMcpConfig(text,
|
|
70712
|
+
const parsed = parseMcpConfig(text, path12);
|
|
70171
70713
|
diagnostics.push(...parsed.diagnostics);
|
|
70172
70714
|
for (const server of parsed.servers)
|
|
70173
70715
|
byName.set(server.name, server);
|
|
@@ -70199,7 +70741,7 @@ function defineProxyTool(client, serverName, schema) {
|
|
|
70199
70741
|
// Pass the server's own JSON Schema straight through. Type.Unsafe wraps it
|
|
70200
70742
|
// without reinterpreting it, so the model sees the parameters the server
|
|
70201
70743
|
// documented and we never reject a payload the server would have accepted.
|
|
70202
|
-
parameters:
|
|
70744
|
+
parameters: Type19.Unsafe(schema.inputSchema ?? { type: "object", properties: {} }),
|
|
70203
70745
|
execute: async (_id, params, signal) => {
|
|
70204
70746
|
const result = await client.callTool(schema.name, params ?? {}, signal);
|
|
70205
70747
|
return {
|
|
@@ -70245,23 +70787,23 @@ function mcpExtension(pi) {
|
|
|
70245
70787
|
}
|
|
70246
70788
|
|
|
70247
70789
|
// dist/extensions/web-access.js
|
|
70248
|
-
import { existsSync as
|
|
70249
|
-
import { join as
|
|
70790
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync13, readFileSync as readFileSync21, writeFileSync as writeFileSync13 } from "node:fs";
|
|
70791
|
+
import { join as join41 } from "node:path";
|
|
70250
70792
|
var WEB_ACCESS_NPM_FALLBACK_SOURCE = "npm:pi-web-access@0.22.0";
|
|
70251
70793
|
function resolveWebAccessExtensionSource() {
|
|
70252
70794
|
const packageDir = getPackageDir();
|
|
70253
70795
|
const sourceCandidates = [
|
|
70254
|
-
|
|
70255
|
-
|
|
70796
|
+
join41(packageDir, "node_modules", "pi-web-access", "index.ts"),
|
|
70797
|
+
join41(packageDir, "..", "..", "node_modules", "pi-web-access", "index.ts")
|
|
70256
70798
|
];
|
|
70257
70799
|
const bundledCandidates = [
|
|
70258
|
-
|
|
70259
|
-
|
|
70800
|
+
join41(packageDir, "dist", "vendor", "web-access.js"),
|
|
70801
|
+
join41(packageDir, "vendor", "web-access.js")
|
|
70260
70802
|
];
|
|
70261
70803
|
const isTypeScriptSourceRuntime2 = import.meta.url.endsWith(".ts");
|
|
70262
70804
|
const candidates = isTypeScriptSourceRuntime2 ? [...sourceCandidates, ...bundledCandidates] : [...bundledCandidates, ...sourceCandidates];
|
|
70263
70805
|
for (const candidate of candidates) {
|
|
70264
|
-
if (
|
|
70806
|
+
if (existsSync27(candidate))
|
|
70265
70807
|
return candidate;
|
|
70266
70808
|
}
|
|
70267
70809
|
return WEB_ACCESS_NPM_FALLBACK_SOURCE;
|
|
@@ -70293,17 +70835,17 @@ var DEFAULT_SEARCH_ROUTING = {
|
|
|
70293
70835
|
],
|
|
70294
70836
|
fallbackOn: ["quota", "transient", "network", "invalid-response"]
|
|
70295
70837
|
};
|
|
70296
|
-
function
|
|
70838
|
+
function isRecord2(value) {
|
|
70297
70839
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
70298
70840
|
}
|
|
70299
70841
|
function prepareWebAccessConfig(agentDir) {
|
|
70300
70842
|
setAppEnv("CODING_AGENT_DIR", agentDir);
|
|
70301
|
-
const configPath2 =
|
|
70843
|
+
const configPath2 = join41(agentDir, WEB_ACCESS_CONFIG_FILENAME);
|
|
70302
70844
|
let config = {};
|
|
70303
|
-
if (
|
|
70845
|
+
if (existsSync27(configPath2)) {
|
|
70304
70846
|
try {
|
|
70305
70847
|
const parsed = JSON.parse(readFileSync21(configPath2, "utf-8"));
|
|
70306
|
-
if (!
|
|
70848
|
+
if (!isRecord2(parsed)) {
|
|
70307
70849
|
return { changed: false };
|
|
70308
70850
|
}
|
|
70309
70851
|
config = parsed;
|
|
@@ -70319,7 +70861,7 @@ function prepareWebAccessConfig(agentDir) {
|
|
|
70319
70861
|
if (config.toolNames === void 0) {
|
|
70320
70862
|
config.toolNames = { webSearch: DEFAULT_WEB_SEARCH_TOOL_NAME };
|
|
70321
70863
|
changed = true;
|
|
70322
|
-
} else if (
|
|
70864
|
+
} else if (isRecord2(config.toolNames) && config.toolNames.webSearch === void 0) {
|
|
70323
70865
|
config.toolNames.webSearch = DEFAULT_WEB_SEARCH_TOOL_NAME;
|
|
70324
70866
|
changed = true;
|
|
70325
70867
|
}
|
|
@@ -70355,8 +70897,8 @@ function prepareWebAccessConfig(agentDir) {
|
|
|
70355
70897
|
}
|
|
70356
70898
|
function readConfiguredWebSearchToolName(agentDir) {
|
|
70357
70899
|
try {
|
|
70358
|
-
const parsed = JSON.parse(readFileSync21(
|
|
70359
|
-
if (!
|
|
70900
|
+
const parsed = JSON.parse(readFileSync21(join41(agentDir, WEB_ACCESS_CONFIG_FILENAME), "utf-8"));
|
|
70901
|
+
if (!isRecord2(parsed) || !isRecord2(parsed.toolNames))
|
|
70360
70902
|
return void 0;
|
|
70361
70903
|
return typeof parsed.toolNames.webSearch === "string" ? parsed.toolNames.webSearch : void 0;
|
|
70362
70904
|
} catch {
|
|
@@ -70467,6 +71009,7 @@ function webSearchConcurrencyExtension(pi) {
|
|
|
70467
71009
|
// dist/extensions/index.js
|
|
70468
71010
|
var builtInExtensions = [
|
|
70469
71011
|
{ name: "gitnexus", factory: gitnexusExtension },
|
|
71012
|
+
{ name: "delegated-worker-runtime", factory: delegatedWorkerRuntime, hidden: true },
|
|
70470
71013
|
// No-op until the user writes an mcp.json; connecting nothing costs nothing.
|
|
70471
71014
|
{ name: "mcp", factory: mcpExtension },
|
|
70472
71015
|
{ name: "web-search-concurrency", factory: webSearchConcurrencyExtension }
|
|
@@ -70474,20 +71017,20 @@ var builtInExtensions = [
|
|
|
70474
71017
|
|
|
70475
71018
|
// dist/migrations.js
|
|
70476
71019
|
import chalk10 from "chalk";
|
|
70477
|
-
import { existsSync as
|
|
70478
|
-
import { dirname as dirname23, join as
|
|
71020
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync14, readdirSync as readdirSync10, readFileSync as readFileSync22, renameSync as renameSync2, rmSync as rmSync5, writeFileSync as writeFileSync14 } from "fs";
|
|
71021
|
+
import { dirname as dirname23, join as join42 } from "path";
|
|
70479
71022
|
var MIGRATION_GUIDE_URL = "https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/CHANGELOG.md#extensions-migration";
|
|
70480
71023
|
var EXTENSIONS_DOC_URL = "https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/docs/extensions.md";
|
|
70481
71024
|
function migrateAuthToAuthJson() {
|
|
70482
71025
|
const agentDir = getAgentDir();
|
|
70483
|
-
const authPath =
|
|
70484
|
-
const oauthPath =
|
|
70485
|
-
const settingsPath =
|
|
70486
|
-
if (
|
|
71026
|
+
const authPath = join42(agentDir, "auth.json");
|
|
71027
|
+
const oauthPath = join42(agentDir, "oauth.json");
|
|
71028
|
+
const settingsPath = join42(agentDir, "settings.json");
|
|
71029
|
+
if (existsSync28(authPath))
|
|
70487
71030
|
return [];
|
|
70488
71031
|
const migrated = {};
|
|
70489
71032
|
const providers = [];
|
|
70490
|
-
if (
|
|
71033
|
+
if (existsSync28(oauthPath)) {
|
|
70491
71034
|
try {
|
|
70492
71035
|
const oauth = JSON.parse(readFileSync22(oauthPath, "utf-8"));
|
|
70493
71036
|
for (const [provider, cred] of Object.entries(oauth)) {
|
|
@@ -70498,7 +71041,7 @@ function migrateAuthToAuthJson() {
|
|
|
70498
71041
|
} catch {
|
|
70499
71042
|
}
|
|
70500
71043
|
}
|
|
70501
|
-
if (
|
|
71044
|
+
if (existsSync28(settingsPath)) {
|
|
70502
71045
|
try {
|
|
70503
71046
|
const content = readFileSync22(settingsPath, "utf-8");
|
|
70504
71047
|
const settings = JSON.parse(content);
|
|
@@ -70525,7 +71068,7 @@ function migrateSessionsFromAgentRoot() {
|
|
|
70525
71068
|
const agentDir = getAgentDir();
|
|
70526
71069
|
let files;
|
|
70527
71070
|
try {
|
|
70528
|
-
files = readdirSync10(agentDir).filter((f) => f.endsWith(".jsonl")).map((f) =>
|
|
71071
|
+
files = readdirSync10(agentDir).filter((f) => f.endsWith(".jsonl")).map((f) => join42(agentDir, f));
|
|
70529
71072
|
} catch {
|
|
70530
71073
|
return;
|
|
70531
71074
|
}
|
|
@@ -70542,13 +71085,13 @@ function migrateSessionsFromAgentRoot() {
|
|
|
70542
71085
|
continue;
|
|
70543
71086
|
const cwd = header.cwd;
|
|
70544
71087
|
const safePath = `--${cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
|
|
70545
|
-
const correctDir =
|
|
70546
|
-
if (!
|
|
71088
|
+
const correctDir = join42(agentDir, "sessions", safePath);
|
|
71089
|
+
if (!existsSync28(correctDir)) {
|
|
70547
71090
|
mkdirSync14(correctDir, { recursive: true });
|
|
70548
71091
|
}
|
|
70549
71092
|
const fileName = file.split("/").pop() || file.split("\\").pop();
|
|
70550
|
-
const newPath =
|
|
70551
|
-
if (
|
|
71093
|
+
const newPath = join42(correctDir, fileName);
|
|
71094
|
+
if (existsSync28(newPath))
|
|
70552
71095
|
continue;
|
|
70553
71096
|
renameSync2(file, newPath);
|
|
70554
71097
|
} catch {
|
|
@@ -70556,9 +71099,9 @@ function migrateSessionsFromAgentRoot() {
|
|
|
70556
71099
|
}
|
|
70557
71100
|
}
|
|
70558
71101
|
function migrateCommandsToPrompts(baseDir, label) {
|
|
70559
|
-
const commandsDir =
|
|
70560
|
-
const promptsDir =
|
|
70561
|
-
if (
|
|
71102
|
+
const commandsDir = join42(baseDir, "commands");
|
|
71103
|
+
const promptsDir = join42(baseDir, "prompts");
|
|
71104
|
+
if (existsSync28(commandsDir) && !existsSync28(promptsDir)) {
|
|
70562
71105
|
try {
|
|
70563
71106
|
renameSync2(commandsDir, promptsDir);
|
|
70564
71107
|
console.log(chalk10.green(`Migrated ${label} commands/ \u2192 prompts/`));
|
|
@@ -70570,8 +71113,8 @@ function migrateCommandsToPrompts(baseDir, label) {
|
|
|
70570
71113
|
return false;
|
|
70571
71114
|
}
|
|
70572
71115
|
function migrateKeybindingsConfigFile() {
|
|
70573
|
-
const configPath2 =
|
|
70574
|
-
if (!
|
|
71116
|
+
const configPath2 = join42(getAgentDir(), "keybindings.json");
|
|
71117
|
+
if (!existsSync28(configPath2))
|
|
70575
71118
|
return;
|
|
70576
71119
|
try {
|
|
70577
71120
|
const parsed = JSON.parse(readFileSync22(configPath2, "utf-8"));
|
|
@@ -70588,20 +71131,20 @@ function migrateKeybindingsConfigFile() {
|
|
|
70588
71131
|
}
|
|
70589
71132
|
function migrateToolsToBin() {
|
|
70590
71133
|
const agentDir = getAgentDir();
|
|
70591
|
-
const toolsDir =
|
|
71134
|
+
const toolsDir = join42(agentDir, "tools");
|
|
70592
71135
|
const binDir = getBinDir();
|
|
70593
|
-
if (!
|
|
71136
|
+
if (!existsSync28(toolsDir))
|
|
70594
71137
|
return;
|
|
70595
71138
|
const binaries = ["fd", "rg", "fd.exe", "rg.exe"];
|
|
70596
71139
|
let movedAny = false;
|
|
70597
71140
|
for (const bin of binaries) {
|
|
70598
|
-
const oldPath =
|
|
70599
|
-
const newPath =
|
|
70600
|
-
if (
|
|
70601
|
-
if (!
|
|
71141
|
+
const oldPath = join42(toolsDir, bin);
|
|
71142
|
+
const newPath = join42(binDir, bin);
|
|
71143
|
+
if (existsSync28(oldPath)) {
|
|
71144
|
+
if (!existsSync28(binDir)) {
|
|
70602
71145
|
mkdirSync14(binDir, { recursive: true });
|
|
70603
71146
|
}
|
|
70604
|
-
if (!
|
|
71147
|
+
if (!existsSync28(newPath)) {
|
|
70605
71148
|
try {
|
|
70606
71149
|
renameSync2(oldPath, newPath);
|
|
70607
71150
|
movedAny = true;
|
|
@@ -70620,13 +71163,13 @@ function migrateToolsToBin() {
|
|
|
70620
71163
|
}
|
|
70621
71164
|
}
|
|
70622
71165
|
function checkDeprecatedExtensionDirs(baseDir, label) {
|
|
70623
|
-
const hooksDir =
|
|
70624
|
-
const toolsDir =
|
|
71166
|
+
const hooksDir = join42(baseDir, "hooks");
|
|
71167
|
+
const toolsDir = join42(baseDir, "tools");
|
|
70625
71168
|
const warnings = [];
|
|
70626
|
-
if (
|
|
71169
|
+
if (existsSync28(hooksDir)) {
|
|
70627
71170
|
warnings.push(`${label} hooks/ directory found. Hooks have been renamed to extensions.`);
|
|
70628
71171
|
}
|
|
70629
|
-
if (
|
|
71172
|
+
if (existsSync28(toolsDir)) {
|
|
70630
71173
|
try {
|
|
70631
71174
|
const entries = readdirSync10(toolsDir);
|
|
70632
71175
|
const customTools = entries.filter((e) => {
|
|
@@ -70643,7 +71186,7 @@ function checkDeprecatedExtensionDirs(baseDir, label) {
|
|
|
70643
71186
|
}
|
|
70644
71187
|
function migrateExtensionSystem(cwd) {
|
|
70645
71188
|
const agentDir = getAgentDir();
|
|
70646
|
-
const projectDir =
|
|
71189
|
+
const projectDir = join42(cwd, CONFIG_DIR_NAME);
|
|
70647
71190
|
migrateCommandsToPrompts(agentDir, "Global");
|
|
70648
71191
|
migrateCommandsToPrompts(projectDir, "Project");
|
|
70649
71192
|
const warnings = [
|
|
@@ -70685,12 +71228,12 @@ function runMigrations(cwd) {
|
|
|
70685
71228
|
}
|
|
70686
71229
|
|
|
70687
71230
|
// dist/package-manager-cli.js
|
|
70688
|
-
import { join as
|
|
71231
|
+
import { join as join45 } from "node:path";
|
|
70689
71232
|
import chalk11 from "chalk";
|
|
70690
71233
|
|
|
70691
71234
|
// dist/modes/interactive/components/config-selector.js
|
|
70692
71235
|
import { homedir as homedir14 } from "node:os";
|
|
70693
|
-
import { basename as
|
|
71236
|
+
import { basename as basename15, dirname as dirname24, join as join43, relative as relative7 } from "node:path";
|
|
70694
71237
|
var RESOURCE_TYPES2 = ["extensions", "skills", "prompts", "themes"];
|
|
70695
71238
|
var RESOURCE_TYPE_LABELS = {
|
|
70696
71239
|
extensions: "Extensions",
|
|
@@ -70727,7 +71270,7 @@ function buildGroups(resolved, agentDir) {
|
|
|
70727
71270
|
const groupMap = /* @__PURE__ */ new Map();
|
|
70728
71271
|
const addToGroup = (resources, resourceType) => {
|
|
70729
71272
|
for (const res of resources) {
|
|
70730
|
-
const { path:
|
|
71273
|
+
const { path: path12, enabled, metadata } = res;
|
|
70731
71274
|
const groupKey = `${metadata.origin}:${metadata.scope}:${metadata.source}:${metadata.baseDir ?? ""}`;
|
|
70732
71275
|
if (!groupMap.has(groupKey)) {
|
|
70733
71276
|
groupMap.set(groupKey, {
|
|
@@ -70750,8 +71293,8 @@ function buildGroups(resolved, agentDir) {
|
|
|
70750
71293
|
};
|
|
70751
71294
|
group.subgroups.push(subgroup);
|
|
70752
71295
|
}
|
|
70753
|
-
const fileName =
|
|
70754
|
-
const parentFolder =
|
|
71296
|
+
const fileName = basename15(path12);
|
|
71297
|
+
const parentFolder = basename15(dirname24(path12));
|
|
70755
71298
|
let displayName;
|
|
70756
71299
|
if (resourceType === "extensions" && parentFolder !== "extensions") {
|
|
70757
71300
|
displayName = `${parentFolder}/${fileName}`;
|
|
@@ -70761,7 +71304,7 @@ function buildGroups(resolved, agentDir) {
|
|
|
70761
71304
|
displayName = fileName;
|
|
70762
71305
|
}
|
|
70763
71306
|
subgroup.items.push({
|
|
70764
|
-
path:
|
|
71307
|
+
path: path12,
|
|
70765
71308
|
enabled,
|
|
70766
71309
|
metadata,
|
|
70767
71310
|
resourceType,
|
|
@@ -71323,7 +71866,7 @@ var ResourceList = class {
|
|
|
71323
71866
|
return item.metadata.scope === "project" ? "project" : "user";
|
|
71324
71867
|
}
|
|
71325
71868
|
getTopLevelBaseDir(scope) {
|
|
71326
|
-
return scope === "project" ?
|
|
71869
|
+
return scope === "project" ? join43(this.cwd, CONFIG_DIR_NAME) : this.agentDir;
|
|
71327
71870
|
}
|
|
71328
71871
|
getResourcePattern(item) {
|
|
71329
71872
|
const scope = item.metadata.scope;
|
|
@@ -71478,18 +72021,18 @@ async function getLatestPiRelease(currentVersion, options = {}) {
|
|
|
71478
72021
|
}
|
|
71479
72022
|
|
|
71480
72023
|
// dist/utils/windows-self-update.js
|
|
71481
|
-
import { randomUUID as
|
|
71482
|
-
import { copyFileSync as copyFileSync2, existsSync as
|
|
71483
|
-
import { basename as
|
|
72024
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
72025
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync29, mkdirSync as mkdirSync15, renameSync as renameSync3, rmSync as rmSync6 } from "node:fs";
|
|
72026
|
+
import { basename as basename16, dirname as dirname25, join as join44, relative as relative8, resolve as resolve14, toNamespacedPath } from "node:path";
|
|
71484
72027
|
var QUARANTINE_DIR_NAME = ".pi-native-quarantine";
|
|
71485
|
-
function normalizePath2(
|
|
71486
|
-
return toNamespacedPath(resolve14(
|
|
72028
|
+
function normalizePath2(path12) {
|
|
72029
|
+
return toNamespacedPath(resolve14(path12));
|
|
71487
72030
|
}
|
|
71488
72031
|
function getQuarantineRoot(packageDir) {
|
|
71489
72032
|
let current = resolve14(packageDir);
|
|
71490
72033
|
while (true) {
|
|
71491
|
-
if (
|
|
71492
|
-
return
|
|
72034
|
+
if (basename16(current).toLowerCase() === "node_modules") {
|
|
72035
|
+
return join44(current, QUARANTINE_DIR_NAME);
|
|
71493
72036
|
}
|
|
71494
72037
|
const parent = dirname25(current);
|
|
71495
72038
|
if (parent === current) {
|
|
@@ -71540,12 +72083,12 @@ function quarantineWindowsNativeDependencies(packageDir) {
|
|
|
71540
72083
|
if (loadedFiles.length === 0) {
|
|
71541
72084
|
return;
|
|
71542
72085
|
}
|
|
71543
|
-
const quarantineRunDir =
|
|
72086
|
+
const quarantineRunDir = join44(quarantineRoot, `${Date.now()}-${process.pid}-${randomUUID7()}`);
|
|
71544
72087
|
for (const loadedFile of loadedFiles) {
|
|
71545
|
-
if (!
|
|
72088
|
+
if (!existsSync29(loadedFile)) {
|
|
71546
72089
|
continue;
|
|
71547
72090
|
}
|
|
71548
|
-
const quarantinePath =
|
|
72091
|
+
const quarantinePath = join44(quarantineRunDir, relative8(resolvedPackageDir, loadedFile));
|
|
71549
72092
|
mkdirSync15(dirname25(quarantinePath), { recursive: true });
|
|
71550
72093
|
renameSync3(loadedFile, quarantinePath);
|
|
71551
72094
|
copyFileSync2(quarantinePath, loadedFile);
|
|
@@ -71869,8 +72412,8 @@ async function refreshModelCatalogs(agentDir) {
|
|
|
71869
72412
|
const timeout = setTimeout(() => controller.abort(), 15e3);
|
|
71870
72413
|
try {
|
|
71871
72414
|
const modelRuntime = await ModelRuntime.create({
|
|
71872
|
-
authPath:
|
|
71873
|
-
modelsPath:
|
|
72415
|
+
authPath: join45(agentDir, "auth.json"),
|
|
72416
|
+
modelsPath: join45(agentDir, "models.json"),
|
|
71874
72417
|
allowModelNetwork: false,
|
|
71875
72418
|
signal: controller.signal
|
|
71876
72419
|
});
|
|
@@ -72445,9 +72988,9 @@ function validateSessionIdFlags(parsed) {
|
|
|
72445
72988
|
process.exit(1);
|
|
72446
72989
|
}
|
|
72447
72990
|
}
|
|
72448
|
-
function openSessionOrExit(
|
|
72991
|
+
function openSessionOrExit(path12, sessionDir) {
|
|
72449
72992
|
try {
|
|
72450
|
-
return SessionManager.open(
|
|
72993
|
+
return SessionManager.open(path12, sessionDir);
|
|
72451
72994
|
} catch (error) {
|
|
72452
72995
|
const message = error instanceof Error ? error.message : String(error);
|
|
72453
72996
|
console.error(chalk12.red(`Error: ${message}`));
|
|
@@ -72804,9 +73347,9 @@ async function main(args, options) {
|
|
|
72804
73347
|
...projectTrustDiagnostics,
|
|
72805
73348
|
...services2.diagnostics,
|
|
72806
73349
|
...collectSettingsDiagnostics(settingsManager2, "runtime creation"),
|
|
72807
|
-
...resourceLoader2.getExtensions().errors.map(({ path:
|
|
73350
|
+
...resourceLoader2.getExtensions().errors.map(({ path: path12, error }) => ({
|
|
72808
73351
|
type: "error",
|
|
72809
|
-
message: `Failed to load extension "${
|
|
73352
|
+
message: `Failed to load extension "${path12}": ${error}`
|
|
72810
73353
|
}))
|
|
72811
73354
|
];
|
|
72812
73355
|
const modelPatterns = parsed.models ?? settingsManager2.getEnabledModels();
|