@akon-labs/nexus-cli 0.1.7 → 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 +6 -0
- package/dist/cli.js +1192 -529
- 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 -573
- package/dist/rpc-entry.js +1192 -529
- package/dist/vendor/ai.js +110 -15
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/cli.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.05446, output: 0.10892, cacheRead: 0.010892, 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.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.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: 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.06, output: 0.18, cacheRead: 0.028, 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
|
}
|
|
@@ -57095,14 +57189,14 @@ function tryLoadObservatoryCache(repo) {
|
|
|
57095
57189
|
if (now - lastCheckAt < CHECK_INTERVAL_MS)
|
|
57096
57190
|
return;
|
|
57097
57191
|
lastCheckAt = now;
|
|
57098
|
-
const
|
|
57192
|
+
const path12 = observatoryCachePath(repo);
|
|
57099
57193
|
try {
|
|
57100
|
-
const stat3 = statSync9(
|
|
57194
|
+
const stat3 = statSync9(path12);
|
|
57101
57195
|
if (now - stat3.mtimeMs > MAX_CACHE_AGE_MS)
|
|
57102
57196
|
return;
|
|
57103
57197
|
if (stat3.mtimeMs <= loadedMtimeMs)
|
|
57104
57198
|
return;
|
|
57105
|
-
const parsed = JSON.parse(readFileSync17(
|
|
57199
|
+
const parsed = JSON.parse(readFileSync17(path12, "utf8"));
|
|
57106
57200
|
if (!Array.isArray(parsed.communities) || parsed.communities.length === 0)
|
|
57107
57201
|
return;
|
|
57108
57202
|
loadedMtimeMs = stat3.mtimeMs;
|
|
@@ -60006,10 +60100,10 @@ var TreeList = class {
|
|
|
60006
60100
|
};
|
|
60007
60101
|
switch (name) {
|
|
60008
60102
|
case "read": {
|
|
60009
|
-
const
|
|
60103
|
+
const path12 = shortenPath3(String(args.path || args.file_path || ""));
|
|
60010
60104
|
const offset = args.offset;
|
|
60011
60105
|
const limit = args.limit;
|
|
60012
|
-
let display =
|
|
60106
|
+
let display = path12;
|
|
60013
60107
|
if (offset !== void 0 || limit !== void 0) {
|
|
60014
60108
|
const start = offset ?? 1;
|
|
60015
60109
|
const end = limit !== void 0 ? start + limit - 1 : "";
|
|
@@ -60018,12 +60112,12 @@ var TreeList = class {
|
|
|
60018
60112
|
return `[read: ${display}]`;
|
|
60019
60113
|
}
|
|
60020
60114
|
case "write": {
|
|
60021
|
-
const
|
|
60022
|
-
return `[write: ${
|
|
60115
|
+
const path12 = shortenPath3(String(args.path || args.file_path || ""));
|
|
60116
|
+
return `[write: ${path12}]`;
|
|
60023
60117
|
}
|
|
60024
60118
|
case "edit": {
|
|
60025
|
-
const
|
|
60026
|
-
return `[edit: ${
|
|
60119
|
+
const path12 = shortenPath3(String(args.path || args.file_path || ""));
|
|
60120
|
+
return `[edit: ${path12}]`;
|
|
60027
60121
|
}
|
|
60028
60122
|
case "bash": {
|
|
60029
60123
|
const rawCmd = String(args.command || "");
|
|
@@ -60032,17 +60126,17 @@ var TreeList = class {
|
|
|
60032
60126
|
}
|
|
60033
60127
|
case "grep": {
|
|
60034
60128
|
const pattern = String(args.pattern || "");
|
|
60035
|
-
const
|
|
60036
|
-
return `[grep: /${pattern}/ in ${
|
|
60129
|
+
const path12 = shortenPath3(String(args.path || "."));
|
|
60130
|
+
return `[grep: /${pattern}/ in ${path12}]`;
|
|
60037
60131
|
}
|
|
60038
60132
|
case "find": {
|
|
60039
60133
|
const pattern = String(args.pattern || "");
|
|
60040
|
-
const
|
|
60041
|
-
return `[find: ${pattern} in ${
|
|
60134
|
+
const path12 = shortenPath3(String(args.path || "."));
|
|
60135
|
+
return `[find: ${pattern} in ${path12}]`;
|
|
60042
60136
|
}
|
|
60043
60137
|
case "ls": {
|
|
60044
|
-
const
|
|
60045
|
-
return `[ls: ${
|
|
60138
|
+
const path12 = shortenPath3(String(args.path || "."));
|
|
60139
|
+
return `[ls: ${path12}]`;
|
|
60046
60140
|
}
|
|
60047
60141
|
default: {
|
|
60048
60142
|
const argsStr = JSON.stringify(args).slice(0, 40);
|
|
@@ -61524,8 +61618,8 @@ var InteractiveMode = class _InteractiveMode {
|
|
|
61524
61618
|
}
|
|
61525
61619
|
return result;
|
|
61526
61620
|
}
|
|
61527
|
-
formatExtensionDisplayPath(
|
|
61528
|
-
let result = this.formatDisplayPath(
|
|
61621
|
+
formatExtensionDisplayPath(path12) {
|
|
61622
|
+
let result = this.formatDisplayPath(path12);
|
|
61529
61623
|
result = result.replace(/\/index\.ts$/, "").replace(/\/index\.js$/, "");
|
|
61530
61624
|
return result;
|
|
61531
61625
|
}
|
|
@@ -66672,8 +66766,8 @@ async function runRpcMode(runtimeHost) {
|
|
|
66672
66766
|
return success(id, "get_session_stats", stats);
|
|
66673
66767
|
}
|
|
66674
66768
|
case "export_html": {
|
|
66675
|
-
const
|
|
66676
|
-
return success(id, "export_html", { path:
|
|
66769
|
+
const path12 = await session.exportToHtml(command.outputPath);
|
|
66770
|
+
return success(id, "export_html", { path: path12 });
|
|
66677
66771
|
}
|
|
66678
66772
|
case "switch_session": {
|
|
66679
66773
|
const result = await runtimeHost.switchSession(command.sessionPath);
|
|
@@ -67625,7 +67719,7 @@ var DefaultResourceLoader = class {
|
|
|
67625
67719
|
return this.appendSystemPrompt;
|
|
67626
67720
|
}
|
|
67627
67721
|
getAppendSystemPromptSources() {
|
|
67628
|
-
return this.appendSystemPromptSourcePaths.map((
|
|
67722
|
+
return this.appendSystemPromptSourcePaths.map((path12) => ({ path: path12 }));
|
|
67629
67723
|
}
|
|
67630
67724
|
extendResources(paths) {
|
|
67631
67725
|
const skillPaths = this.normalizeExtensionPaths(paths.skillPaths ?? []);
|
|
@@ -67793,8 +67887,8 @@ var DefaultResourceLoader = class {
|
|
|
67793
67887
|
extensionsResult.errors.push(...inlineExtensions.errors);
|
|
67794
67888
|
return extensionsResult;
|
|
67795
67889
|
}
|
|
67796
|
-
resolveExtensionLoadPath(
|
|
67797
|
-
return resolvePath(
|
|
67890
|
+
resolveExtensionLoadPath(path12) {
|
|
67891
|
+
return resolvePath(path12, this.cwd, { normalizeUnicodeSpaces: true });
|
|
67798
67892
|
}
|
|
67799
67893
|
async loadFinalExtensionSet(extensionPaths, preTrustExtensions) {
|
|
67800
67894
|
if (!preTrustExtensions) {
|
|
@@ -67807,8 +67901,8 @@ var DefaultResourceLoader = class {
|
|
|
67807
67901
|
}
|
|
67808
67902
|
const preloadedByPath = new Map(preTrustExtensions.extensions.filter((extension) => !extension.path.startsWith("<inline:")).map((extension) => [extension.resolvedPath, extension]));
|
|
67809
67903
|
const failedPreloadPaths = new Set(preTrustExtensions.errors.map((error) => this.resolveExtensionLoadPath(error.path)));
|
|
67810
|
-
const remainingPaths = extensionPaths.filter((
|
|
67811
|
-
const resolvedPath = this.resolveExtensionLoadPath(
|
|
67904
|
+
const remainingPaths = extensionPaths.filter((path12) => {
|
|
67905
|
+
const resolvedPath = this.resolveExtensionLoadPath(path12);
|
|
67812
67906
|
return !preloadedByPath.has(resolvedPath) && !failedPreloadPaths.has(resolvedPath);
|
|
67813
67907
|
});
|
|
67814
67908
|
const remainingExtensions = await loadExtensionsCached(remainingPaths, this.cwd, this.eventBus, preTrustExtensions.runtime);
|
|
@@ -67817,7 +67911,7 @@ var DefaultResourceLoader = class {
|
|
|
67817
67911
|
loadedByPath.set(extension.resolvedPath, extension);
|
|
67818
67912
|
}
|
|
67819
67913
|
const inlineExtensions = preTrustExtensions.extensions.filter((extension) => extension.path.startsWith("<inline:"));
|
|
67820
|
-
const orderedExtensions = extensionPaths.map((
|
|
67914
|
+
const orderedExtensions = extensionPaths.map((path12) => loadedByPath.get(this.resolveExtensionLoadPath(path12))).filter((extension) => extension !== void 0);
|
|
67821
67915
|
orderedExtensions.push(...inlineExtensions);
|
|
67822
67916
|
const extensionsResult = {
|
|
67823
67917
|
extensions: orderedExtensions,
|
|
@@ -68676,6 +68770,21 @@ function parseUsage2(value) {
|
|
|
68676
68770
|
...typeof usage.remaining === "number" ? { remaining: usage.remaining } : {}
|
|
68677
68771
|
};
|
|
68678
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
|
+
}
|
|
68679
68788
|
function formatCreditBalance(policy) {
|
|
68680
68789
|
if (!policy?.usage)
|
|
68681
68790
|
return void 0;
|
|
@@ -68685,16 +68794,17 @@ function formatCreditBalance(policy) {
|
|
|
68685
68794
|
function gatewayCachePath() {
|
|
68686
68795
|
return join37(dirname22(gitNexusConfigPath()), "gateway.json");
|
|
68687
68796
|
}
|
|
68688
|
-
function readGatewayCache(
|
|
68797
|
+
function readGatewayCache(path12 = gatewayCachePath()) {
|
|
68689
68798
|
try {
|
|
68690
|
-
const parsed = JSON.parse(readFileSync19(
|
|
68799
|
+
const parsed = JSON.parse(readFileSync19(path12, "utf8"));
|
|
68691
68800
|
if (typeof parsed.contextWindow !== "number" || typeof parsed.maxTokens !== "number")
|
|
68692
68801
|
return void 0;
|
|
68693
68802
|
return {
|
|
68694
68803
|
configured: parsed.configured === true,
|
|
68695
68804
|
contextWindow: parsed.contextWindow,
|
|
68696
68805
|
maxTokens: parsed.maxTokens,
|
|
68697
|
-
usage: parseUsage2(parsed.usage)
|
|
68806
|
+
usage: parseUsage2(parsed.usage),
|
|
68807
|
+
delegation: parseDelegation(parsed.delegation)
|
|
68698
68808
|
};
|
|
68699
68809
|
} catch {
|
|
68700
68810
|
return void 0;
|
|
@@ -68731,7 +68841,8 @@ async function refreshGatewayPolicy(config, options = {}) {
|
|
|
68731
68841
|
configured: body.configured === true,
|
|
68732
68842
|
contextWindow: body.contextWindow,
|
|
68733
68843
|
maxTokens: body.maxTokens,
|
|
68734
|
-
usage: parseUsage2(body.usage)
|
|
68844
|
+
usage: parseUsage2(body.usage),
|
|
68845
|
+
delegation: parseDelegation(body.delegation)
|
|
68735
68846
|
};
|
|
68736
68847
|
if (!existsSync24(dirname22(cachePath)))
|
|
68737
68848
|
mkdirSync12(dirname22(cachePath), { recursive: true, mode: 448 });
|
|
@@ -68784,11 +68895,551 @@ function registerAutoProvider(pi, config, policy) {
|
|
|
68784
68895
|
}
|
|
68785
68896
|
|
|
68786
68897
|
// dist/extensions/gitnexus/index.js
|
|
68787
|
-
import { existsSync as
|
|
68898
|
+
import { existsSync as existsSync26 } from "node:fs";
|
|
68788
68899
|
import { homedir as homedir12 } from "node:os";
|
|
68789
|
-
import { join as
|
|
68900
|
+
import { join as join39 } from "node:path";
|
|
68790
68901
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
68791
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
|
+
|
|
68792
69443
|
// dist/extensions/gitnexus/augment.js
|
|
68793
69444
|
var AUGMENT_TIMEOUT_MS = 3e3;
|
|
68794
69445
|
var AUGMENT_MAX_CHARS = 1500;
|
|
@@ -68861,11 +69512,11 @@ function registerChangeTracking(pi, cwd) {
|
|
|
68861
69512
|
execute: async (id, params, signal, onUpdate, ctx) => {
|
|
68862
69513
|
const result = await edit.execute(id, params, signal, onUpdate, ctx);
|
|
68863
69514
|
try {
|
|
68864
|
-
const
|
|
69515
|
+
const path12 = String(params?.path ?? "");
|
|
68865
69516
|
const diff = result.details?.diff;
|
|
68866
69517
|
const { added, removed } = countDiff(diff);
|
|
68867
|
-
if (
|
|
68868
|
-
graphRailStore.recordChange(
|
|
69518
|
+
if (path12 && (added > 0 || removed > 0))
|
|
69519
|
+
graphRailStore.recordChange(path12, added, removed);
|
|
68869
69520
|
} catch {
|
|
68870
69521
|
}
|
|
68871
69522
|
return result;
|
|
@@ -68877,10 +69528,10 @@ function registerChangeTracking(pi, cwd) {
|
|
|
68877
69528
|
const result = await write.execute(id, params, signal, onUpdate, ctx);
|
|
68878
69529
|
try {
|
|
68879
69530
|
const p = params;
|
|
68880
|
-
const
|
|
69531
|
+
const path12 = String(p?.path ?? "");
|
|
68881
69532
|
const lineCount = String(p?.content ?? "").split("\n").length;
|
|
68882
|
-
if (
|
|
68883
|
-
graphRailStore.recordChange(
|
|
69533
|
+
if (path12)
|
|
69534
|
+
graphRailStore.recordChange(path12, lineCount, 0);
|
|
68884
69535
|
} catch {
|
|
68885
69536
|
}
|
|
68886
69537
|
return result;
|
|
@@ -68889,7 +69540,7 @@ function registerChangeTracking(pi, cwd) {
|
|
|
68889
69540
|
}
|
|
68890
69541
|
|
|
68891
69542
|
// dist/extensions/gitnexus/observatory.js
|
|
68892
|
-
import { spawn as
|
|
69543
|
+
import { spawn as spawn13 } from "node:child_process";
|
|
68893
69544
|
import { appendFileSync as appendFileSync5 } from "node:fs";
|
|
68894
69545
|
function trace(message) {
|
|
68895
69546
|
if (!process.env.NEXUS_TRACE)
|
|
@@ -68903,7 +69554,7 @@ function trace(message) {
|
|
|
68903
69554
|
function spawnObservatoryFetch(config, repo) {
|
|
68904
69555
|
try {
|
|
68905
69556
|
const script = buildFetchScript();
|
|
68906
|
-
const child =
|
|
69557
|
+
const child = spawn13(process.execPath, ["-e", script], {
|
|
68907
69558
|
detached: true,
|
|
68908
69559
|
stdio: "ignore",
|
|
68909
69560
|
env: {
|
|
@@ -69041,7 +69692,7 @@ function parseHubJson(text) {
|
|
|
69041
69692
|
return void 0;
|
|
69042
69693
|
}
|
|
69043
69694
|
}
|
|
69044
|
-
function
|
|
69695
|
+
function basename14(filePath) {
|
|
69045
69696
|
if (!filePath)
|
|
69046
69697
|
return "";
|
|
69047
69698
|
return filePath.split("/").pop() ?? filePath;
|
|
@@ -69271,7 +69922,7 @@ function formatQuery(text, theme2) {
|
|
|
69271
69922
|
if (shownSymbols.length > 0) {
|
|
69272
69923
|
lines.push(theme2.fg("muted", "symbols:"));
|
|
69273
69924
|
for (const sym of shownSymbols) {
|
|
69274
|
-
const loc = sym.filePath ? `${
|
|
69925
|
+
const loc = sym.filePath ? `${basename14(sym.filePath)}${sym.startLine ? `:${sym.startLine}` : ""}` : "";
|
|
69275
69926
|
lines.push(` ${theme2.fg("accent", "\u2022")} ${sym.name} ${theme2.fg("muted", loc)}`);
|
|
69276
69927
|
}
|
|
69277
69928
|
}
|
|
@@ -69402,7 +70053,7 @@ function matchCurrentRepo(inventory, slug) {
|
|
|
69402
70053
|
|
|
69403
70054
|
// dist/extensions/gitnexus/tools.js
|
|
69404
70055
|
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
69405
|
-
import { Type as
|
|
70056
|
+
import { Type as Type18 } from "typebox";
|
|
69406
70057
|
function aliasParam(args, canonical, aliases) {
|
|
69407
70058
|
if (args[canonical] !== void 0)
|
|
69408
70059
|
return args;
|
|
@@ -69481,7 +70132,7 @@ function makeHubTool(ctx, options) {
|
|
|
69481
70132
|
}
|
|
69482
70133
|
};
|
|
69483
70134
|
}
|
|
69484
|
-
var repoParam =
|
|
70135
|
+
var repoParam = Type18.Optional(Type18.String({
|
|
69485
70136
|
description: "Indexed repository name or @group. Omit for the current repository."
|
|
69486
70137
|
}));
|
|
69487
70138
|
function createGitNexusTools(ctx) {
|
|
@@ -69491,11 +70142,11 @@ function createGitNexusTools(ctx) {
|
|
|
69491
70142
|
label: "GitNexus query",
|
|
69492
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.",
|
|
69493
70144
|
promptSnippet: "gitnexus_query: find execution flows by concept in the knowledge graph",
|
|
69494
|
-
parameters:
|
|
69495
|
-
query:
|
|
69496
|
-
goal:
|
|
69497
|
-
task_context:
|
|
69498
|
-
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)" })),
|
|
69499
70150
|
repo: repoParam
|
|
69500
70151
|
})
|
|
69501
70152
|
});
|
|
@@ -69505,10 +70156,10 @@ function createGitNexusTools(ctx) {
|
|
|
69505
70156
|
label: "GitNexus context",
|
|
69506
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.",
|
|
69507
70158
|
promptSnippet: "gitnexus_context: all callers/callees/flows of one symbol",
|
|
69508
|
-
parameters:
|
|
69509
|
-
name:
|
|
69510
|
-
file_path:
|
|
69511
|
-
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'" })),
|
|
69512
70163
|
repo: repoParam
|
|
69513
70164
|
}),
|
|
69514
70165
|
prepareArguments: (args) => aliasParam(args ?? {}, "name", ["target", "symbol"])
|
|
@@ -69522,9 +70173,9 @@ function createGitNexusTools(ctx) {
|
|
|
69522
70173
|
promptGuidelines: [
|
|
69523
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."
|
|
69524
70175
|
],
|
|
69525
|
-
parameters:
|
|
69526
|
-
target:
|
|
69527
|
-
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"' })),
|
|
69528
70179
|
repo: repoParam
|
|
69529
70180
|
}),
|
|
69530
70181
|
prepareArguments: (args) => aliasParam(args ?? {}, "target", ["name", "symbol"]),
|
|
@@ -69536,7 +70187,7 @@ function createGitNexusTools(ctx) {
|
|
|
69536
70187
|
label: "GitNexus detect changes",
|
|
69537
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.",
|
|
69538
70189
|
promptSnippet: "gitnexus_detect_changes: map local diff to affected flows",
|
|
69539
|
-
parameters:
|
|
70190
|
+
parameters: Type18.Object({ repo: repoParam }),
|
|
69540
70191
|
mapArgs: (params) => {
|
|
69541
70192
|
const diff = spawnSync9("git", ["diff", "--name-only", "HEAD"], {
|
|
69542
70193
|
cwd: ctx.cwd,
|
|
@@ -69555,8 +70206,8 @@ function createGitNexusTools(ctx) {
|
|
|
69555
70206
|
promptGuidelines: [
|
|
69556
70207
|
"Prefer gitnexus_query/context/impact; reach for gitnexus_cypher only when they cannot express the question."
|
|
69557
70208
|
],
|
|
69558
|
-
parameters:
|
|
69559
|
-
query:
|
|
70209
|
+
parameters: Type18.Object({
|
|
70210
|
+
query: Type18.String({ description: "Cypher query to execute" }),
|
|
69560
70211
|
repo: repoParam
|
|
69561
70212
|
})
|
|
69562
70213
|
});
|
|
@@ -69565,14 +70216,14 @@ function createGitNexusTools(ctx) {
|
|
|
69565
70216
|
hubTool: "list_repos",
|
|
69566
70217
|
label: "GitNexus repos",
|
|
69567
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.",
|
|
69568
|
-
parameters:
|
|
70219
|
+
parameters: Type18.Object({}),
|
|
69569
70220
|
mapArgs: () => ({})
|
|
69570
70221
|
});
|
|
69571
70222
|
return [query, context, impact, detectChanges, cypher, listRepos];
|
|
69572
70223
|
}
|
|
69573
70224
|
|
|
69574
70225
|
// dist/extensions/gitnexus/index.js
|
|
69575
|
-
function resolveGitNexusSkillsDir(moduleUrl = import.meta.url, pathExists2 =
|
|
70226
|
+
function resolveGitNexusSkillsDir(moduleUrl = import.meta.url, pathExists2 = existsSync26) {
|
|
69576
70227
|
const candidates = [
|
|
69577
70228
|
fileURLToPath7(new URL("./skills/", moduleUrl)),
|
|
69578
70229
|
fileURLToPath7(new URL("./extensions/gitnexus/skills/", moduleUrl))
|
|
@@ -69584,11 +70235,21 @@ function gitnexusExtension(pi) {
|
|
|
69584
70235
|
let current;
|
|
69585
70236
|
let activeClient;
|
|
69586
70237
|
let toolsRegistered = false;
|
|
70238
|
+
let delegationRegistered = false;
|
|
69587
70239
|
let startupNotice;
|
|
69588
70240
|
let loginRequired = false;
|
|
69589
70241
|
const cwd = process.cwd();
|
|
69590
70242
|
let gatewayPolicy = readGatewayCache();
|
|
69591
|
-
|
|
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();
|
|
69592
70253
|
function updateCreditStatus(ctx) {
|
|
69593
70254
|
ctx.ui.setStatus("nexus-credits", formatCreditBalance(gatewayPolicy));
|
|
69594
70255
|
}
|
|
@@ -69654,10 +70315,11 @@ function gitnexusExtension(pi) {
|
|
|
69654
70315
|
const config = resolveGitNexusConfig();
|
|
69655
70316
|
if (config)
|
|
69656
70317
|
gatewayPolicy = await refreshGatewayPolicy(config);
|
|
70318
|
+
registerDelegationIfAvailable();
|
|
69657
70319
|
updateCreditStatus(ctx);
|
|
69658
70320
|
});
|
|
69659
70321
|
pi.on("resources_discover", (event) => {
|
|
69660
|
-
const hasOwnGitnexusSkills =
|
|
70322
|
+
const hasOwnGitnexusSkills = existsSync26(join39(event.cwd, ".agents", "skills", "gitnexus")) || existsSync26(join39(homedir12(), ".agents", "skills", "gitnexus-debugging"));
|
|
69661
70323
|
if (hasOwnGitnexusSkills)
|
|
69662
70324
|
return;
|
|
69663
70325
|
const skillsDir = resolveGitNexusSkillsDir();
|
|
@@ -69680,9 +70342,9 @@ ${buildGitNexusPrompt(inventory, current)}` };
|
|
|
69680
70342
|
if (pasted) {
|
|
69681
70343
|
try {
|
|
69682
70344
|
await new GitNexusClient({ hubUrl, token: pasted }).callTool("list_repos", {});
|
|
69683
|
-
const
|
|
70345
|
+
const path12 = saveGitNexusConfig({ hubUrl, token: pasted });
|
|
69684
70346
|
await connect2();
|
|
69685
|
-
ctx.ui.notify(`GitNexus token saved to ${
|
|
70347
|
+
ctx.ui.notify(`GitNexus token saved to ${path12}. ${startupNotice ?? ""}`, "info");
|
|
69686
70348
|
} catch (error) {
|
|
69687
70349
|
const message = error instanceof Error ? error.message : String(error);
|
|
69688
70350
|
ctx.ui.notify(`GitNexus login failed: ${message}`, "error");
|
|
@@ -69704,9 +70366,9 @@ ${buildGitNexusPrompt(inventory, current)}` };
|
|
|
69704
70366
|
deviceName
|
|
69705
70367
|
};
|
|
69706
70368
|
await new GitNexusClient(config).callTool("list_repos", {});
|
|
69707
|
-
const
|
|
70369
|
+
const path12 = saveGitNexusConfig(config);
|
|
69708
70370
|
await connect2();
|
|
69709
|
-
ctx.ui.notify(`Signed in. Token saved to ${
|
|
70371
|
+
ctx.ui.notify(`Signed in. Token saved to ${path12}. ${startupNotice ?? ""}`, "info");
|
|
69710
70372
|
} catch (error) {
|
|
69711
70373
|
const message = error instanceof Error ? error.message : String(error);
|
|
69712
70374
|
ctx.ui.notify(`GitNexus login failed: ${message}`, "error");
|
|
@@ -69733,10 +70395,10 @@ ${buildGitNexusPrompt(inventory, current)}` };
|
|
|
69733
70395
|
}
|
|
69734
70396
|
|
|
69735
70397
|
// dist/extensions/mcp/index.js
|
|
69736
|
-
import { Type as
|
|
70398
|
+
import { Type as Type19 } from "typebox";
|
|
69737
70399
|
|
|
69738
70400
|
// dist/extensions/mcp/client.js
|
|
69739
|
-
import { spawn as
|
|
70401
|
+
import { spawn as spawn14 } from "node:child_process";
|
|
69740
70402
|
var MCP_PROTOCOL_VERSION = "2025-06-18";
|
|
69741
70403
|
var REQUEST_TIMEOUT_MS4 = 6e4;
|
|
69742
70404
|
var McpClientError = class extends Error {
|
|
@@ -69842,7 +70504,7 @@ var StdioTransport = class {
|
|
|
69842
70504
|
return this.child;
|
|
69843
70505
|
let child;
|
|
69844
70506
|
try {
|
|
69845
|
-
child =
|
|
70507
|
+
child = spawn14(this.command, this.args, {
|
|
69846
70508
|
stdio: ["pipe", "pipe", "pipe"],
|
|
69847
70509
|
env: { ...process.env, ...this.env },
|
|
69848
70510
|
cwd: this.cwd
|
|
@@ -69980,7 +70642,7 @@ var McpClient = class {
|
|
|
69980
70642
|
// dist/extensions/mcp/config.js
|
|
69981
70643
|
import { readFileSync as readFileSync20 } from "node:fs";
|
|
69982
70644
|
import { homedir as homedir13 } from "node:os";
|
|
69983
|
-
import { join as
|
|
70645
|
+
import { join as join40 } from "node:path";
|
|
69984
70646
|
function stringRecord(value) {
|
|
69985
70647
|
if (!value || typeof value !== "object")
|
|
69986
70648
|
return {};
|
|
@@ -70035,19 +70697,19 @@ function parseMcpConfig(text, source) {
|
|
|
70035
70697
|
return { servers, diagnostics };
|
|
70036
70698
|
}
|
|
70037
70699
|
function mcpConfigPaths(cwd, home = homedir13()) {
|
|
70038
|
-
return [
|
|
70700
|
+
return [join40(home, ".config", "nexus", "mcp.json"), join40(cwd, CONFIG_DIR_NAME, "mcp.json")];
|
|
70039
70701
|
}
|
|
70040
|
-
function loadMcpConfig(cwd, readFile4 = (
|
|
70702
|
+
function loadMcpConfig(cwd, readFile4 = (path12) => readFileSync20(path12, "utf8"), home) {
|
|
70041
70703
|
const byName = /* @__PURE__ */ new Map();
|
|
70042
70704
|
const diagnostics = [];
|
|
70043
|
-
for (const
|
|
70705
|
+
for (const path12 of mcpConfigPaths(cwd, home)) {
|
|
70044
70706
|
let text;
|
|
70045
70707
|
try {
|
|
70046
|
-
text = readFile4(
|
|
70708
|
+
text = readFile4(path12);
|
|
70047
70709
|
} catch {
|
|
70048
70710
|
continue;
|
|
70049
70711
|
}
|
|
70050
|
-
const parsed = parseMcpConfig(text,
|
|
70712
|
+
const parsed = parseMcpConfig(text, path12);
|
|
70051
70713
|
diagnostics.push(...parsed.diagnostics);
|
|
70052
70714
|
for (const server of parsed.servers)
|
|
70053
70715
|
byName.set(server.name, server);
|
|
@@ -70079,7 +70741,7 @@ function defineProxyTool(client, serverName, schema) {
|
|
|
70079
70741
|
// Pass the server's own JSON Schema straight through. Type.Unsafe wraps it
|
|
70080
70742
|
// without reinterpreting it, so the model sees the parameters the server
|
|
70081
70743
|
// documented and we never reject a payload the server would have accepted.
|
|
70082
|
-
parameters:
|
|
70744
|
+
parameters: Type19.Unsafe(schema.inputSchema ?? { type: "object", properties: {} }),
|
|
70083
70745
|
execute: async (_id, params, signal) => {
|
|
70084
70746
|
const result = await client.callTool(schema.name, params ?? {}, signal);
|
|
70085
70747
|
return {
|
|
@@ -70125,23 +70787,23 @@ function mcpExtension(pi) {
|
|
|
70125
70787
|
}
|
|
70126
70788
|
|
|
70127
70789
|
// dist/extensions/web-access.js
|
|
70128
|
-
import { existsSync as
|
|
70129
|
-
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";
|
|
70130
70792
|
var WEB_ACCESS_NPM_FALLBACK_SOURCE = "npm:pi-web-access@0.22.0";
|
|
70131
70793
|
function resolveWebAccessExtensionSource() {
|
|
70132
70794
|
const packageDir = getPackageDir();
|
|
70133
70795
|
const sourceCandidates = [
|
|
70134
|
-
|
|
70135
|
-
|
|
70796
|
+
join41(packageDir, "node_modules", "pi-web-access", "index.ts"),
|
|
70797
|
+
join41(packageDir, "..", "..", "node_modules", "pi-web-access", "index.ts")
|
|
70136
70798
|
];
|
|
70137
70799
|
const bundledCandidates = [
|
|
70138
|
-
|
|
70139
|
-
|
|
70800
|
+
join41(packageDir, "dist", "vendor", "web-access.js"),
|
|
70801
|
+
join41(packageDir, "vendor", "web-access.js")
|
|
70140
70802
|
];
|
|
70141
70803
|
const isTypeScriptSourceRuntime2 = import.meta.url.endsWith(".ts");
|
|
70142
70804
|
const candidates = isTypeScriptSourceRuntime2 ? [...sourceCandidates, ...bundledCandidates] : [...bundledCandidates, ...sourceCandidates];
|
|
70143
70805
|
for (const candidate of candidates) {
|
|
70144
|
-
if (
|
|
70806
|
+
if (existsSync27(candidate))
|
|
70145
70807
|
return candidate;
|
|
70146
70808
|
}
|
|
70147
70809
|
return WEB_ACCESS_NPM_FALLBACK_SOURCE;
|
|
@@ -70173,17 +70835,17 @@ var DEFAULT_SEARCH_ROUTING = {
|
|
|
70173
70835
|
],
|
|
70174
70836
|
fallbackOn: ["quota", "transient", "network", "invalid-response"]
|
|
70175
70837
|
};
|
|
70176
|
-
function
|
|
70838
|
+
function isRecord2(value) {
|
|
70177
70839
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
70178
70840
|
}
|
|
70179
70841
|
function prepareWebAccessConfig(agentDir) {
|
|
70180
70842
|
setAppEnv("CODING_AGENT_DIR", agentDir);
|
|
70181
|
-
const configPath2 =
|
|
70843
|
+
const configPath2 = join41(agentDir, WEB_ACCESS_CONFIG_FILENAME);
|
|
70182
70844
|
let config = {};
|
|
70183
|
-
if (
|
|
70845
|
+
if (existsSync27(configPath2)) {
|
|
70184
70846
|
try {
|
|
70185
70847
|
const parsed = JSON.parse(readFileSync21(configPath2, "utf-8"));
|
|
70186
|
-
if (!
|
|
70848
|
+
if (!isRecord2(parsed)) {
|
|
70187
70849
|
return { changed: false };
|
|
70188
70850
|
}
|
|
70189
70851
|
config = parsed;
|
|
@@ -70199,7 +70861,7 @@ function prepareWebAccessConfig(agentDir) {
|
|
|
70199
70861
|
if (config.toolNames === void 0) {
|
|
70200
70862
|
config.toolNames = { webSearch: DEFAULT_WEB_SEARCH_TOOL_NAME };
|
|
70201
70863
|
changed = true;
|
|
70202
|
-
} else if (
|
|
70864
|
+
} else if (isRecord2(config.toolNames) && config.toolNames.webSearch === void 0) {
|
|
70203
70865
|
config.toolNames.webSearch = DEFAULT_WEB_SEARCH_TOOL_NAME;
|
|
70204
70866
|
changed = true;
|
|
70205
70867
|
}
|
|
@@ -70235,8 +70897,8 @@ function prepareWebAccessConfig(agentDir) {
|
|
|
70235
70897
|
}
|
|
70236
70898
|
function readConfiguredWebSearchToolName(agentDir) {
|
|
70237
70899
|
try {
|
|
70238
|
-
const parsed = JSON.parse(readFileSync21(
|
|
70239
|
-
if (!
|
|
70900
|
+
const parsed = JSON.parse(readFileSync21(join41(agentDir, WEB_ACCESS_CONFIG_FILENAME), "utf-8"));
|
|
70901
|
+
if (!isRecord2(parsed) || !isRecord2(parsed.toolNames))
|
|
70240
70902
|
return void 0;
|
|
70241
70903
|
return typeof parsed.toolNames.webSearch === "string" ? parsed.toolNames.webSearch : void 0;
|
|
70242
70904
|
} catch {
|
|
@@ -70347,6 +71009,7 @@ function webSearchConcurrencyExtension(pi) {
|
|
|
70347
71009
|
// dist/extensions/index.js
|
|
70348
71010
|
var builtInExtensions = [
|
|
70349
71011
|
{ name: "gitnexus", factory: gitnexusExtension },
|
|
71012
|
+
{ name: "delegated-worker-runtime", factory: delegatedWorkerRuntime, hidden: true },
|
|
70350
71013
|
// No-op until the user writes an mcp.json; connecting nothing costs nothing.
|
|
70351
71014
|
{ name: "mcp", factory: mcpExtension },
|
|
70352
71015
|
{ name: "web-search-concurrency", factory: webSearchConcurrencyExtension }
|
|
@@ -70354,20 +71017,20 @@ var builtInExtensions = [
|
|
|
70354
71017
|
|
|
70355
71018
|
// dist/migrations.js
|
|
70356
71019
|
import chalk10 from "chalk";
|
|
70357
|
-
import { existsSync as
|
|
70358
|
-
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";
|
|
70359
71022
|
var MIGRATION_GUIDE_URL = "https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/CHANGELOG.md#extensions-migration";
|
|
70360
71023
|
var EXTENSIONS_DOC_URL = "https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/docs/extensions.md";
|
|
70361
71024
|
function migrateAuthToAuthJson() {
|
|
70362
71025
|
const agentDir = getAgentDir();
|
|
70363
|
-
const authPath =
|
|
70364
|
-
const oauthPath =
|
|
70365
|
-
const settingsPath =
|
|
70366
|
-
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))
|
|
70367
71030
|
return [];
|
|
70368
71031
|
const migrated = {};
|
|
70369
71032
|
const providers = [];
|
|
70370
|
-
if (
|
|
71033
|
+
if (existsSync28(oauthPath)) {
|
|
70371
71034
|
try {
|
|
70372
71035
|
const oauth = JSON.parse(readFileSync22(oauthPath, "utf-8"));
|
|
70373
71036
|
for (const [provider, cred] of Object.entries(oauth)) {
|
|
@@ -70378,7 +71041,7 @@ function migrateAuthToAuthJson() {
|
|
|
70378
71041
|
} catch {
|
|
70379
71042
|
}
|
|
70380
71043
|
}
|
|
70381
|
-
if (
|
|
71044
|
+
if (existsSync28(settingsPath)) {
|
|
70382
71045
|
try {
|
|
70383
71046
|
const content = readFileSync22(settingsPath, "utf-8");
|
|
70384
71047
|
const settings = JSON.parse(content);
|
|
@@ -70405,7 +71068,7 @@ function migrateSessionsFromAgentRoot() {
|
|
|
70405
71068
|
const agentDir = getAgentDir();
|
|
70406
71069
|
let files;
|
|
70407
71070
|
try {
|
|
70408
|
-
files = readdirSync10(agentDir).filter((f) => f.endsWith(".jsonl")).map((f) =>
|
|
71071
|
+
files = readdirSync10(agentDir).filter((f) => f.endsWith(".jsonl")).map((f) => join42(agentDir, f));
|
|
70409
71072
|
} catch {
|
|
70410
71073
|
return;
|
|
70411
71074
|
}
|
|
@@ -70422,13 +71085,13 @@ function migrateSessionsFromAgentRoot() {
|
|
|
70422
71085
|
continue;
|
|
70423
71086
|
const cwd = header.cwd;
|
|
70424
71087
|
const safePath = `--${cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
|
|
70425
|
-
const correctDir =
|
|
70426
|
-
if (!
|
|
71088
|
+
const correctDir = join42(agentDir, "sessions", safePath);
|
|
71089
|
+
if (!existsSync28(correctDir)) {
|
|
70427
71090
|
mkdirSync14(correctDir, { recursive: true });
|
|
70428
71091
|
}
|
|
70429
71092
|
const fileName = file.split("/").pop() || file.split("\\").pop();
|
|
70430
|
-
const newPath =
|
|
70431
|
-
if (
|
|
71093
|
+
const newPath = join42(correctDir, fileName);
|
|
71094
|
+
if (existsSync28(newPath))
|
|
70432
71095
|
continue;
|
|
70433
71096
|
renameSync2(file, newPath);
|
|
70434
71097
|
} catch {
|
|
@@ -70436,9 +71099,9 @@ function migrateSessionsFromAgentRoot() {
|
|
|
70436
71099
|
}
|
|
70437
71100
|
}
|
|
70438
71101
|
function migrateCommandsToPrompts(baseDir, label) {
|
|
70439
|
-
const commandsDir =
|
|
70440
|
-
const promptsDir =
|
|
70441
|
-
if (
|
|
71102
|
+
const commandsDir = join42(baseDir, "commands");
|
|
71103
|
+
const promptsDir = join42(baseDir, "prompts");
|
|
71104
|
+
if (existsSync28(commandsDir) && !existsSync28(promptsDir)) {
|
|
70442
71105
|
try {
|
|
70443
71106
|
renameSync2(commandsDir, promptsDir);
|
|
70444
71107
|
console.log(chalk10.green(`Migrated ${label} commands/ \u2192 prompts/`));
|
|
@@ -70450,8 +71113,8 @@ function migrateCommandsToPrompts(baseDir, label) {
|
|
|
70450
71113
|
return false;
|
|
70451
71114
|
}
|
|
70452
71115
|
function migrateKeybindingsConfigFile() {
|
|
70453
|
-
const configPath2 =
|
|
70454
|
-
if (!
|
|
71116
|
+
const configPath2 = join42(getAgentDir(), "keybindings.json");
|
|
71117
|
+
if (!existsSync28(configPath2))
|
|
70455
71118
|
return;
|
|
70456
71119
|
try {
|
|
70457
71120
|
const parsed = JSON.parse(readFileSync22(configPath2, "utf-8"));
|
|
@@ -70468,20 +71131,20 @@ function migrateKeybindingsConfigFile() {
|
|
|
70468
71131
|
}
|
|
70469
71132
|
function migrateToolsToBin() {
|
|
70470
71133
|
const agentDir = getAgentDir();
|
|
70471
|
-
const toolsDir =
|
|
71134
|
+
const toolsDir = join42(agentDir, "tools");
|
|
70472
71135
|
const binDir = getBinDir();
|
|
70473
|
-
if (!
|
|
71136
|
+
if (!existsSync28(toolsDir))
|
|
70474
71137
|
return;
|
|
70475
71138
|
const binaries = ["fd", "rg", "fd.exe", "rg.exe"];
|
|
70476
71139
|
let movedAny = false;
|
|
70477
71140
|
for (const bin of binaries) {
|
|
70478
|
-
const oldPath =
|
|
70479
|
-
const newPath =
|
|
70480
|
-
if (
|
|
70481
|
-
if (!
|
|
71141
|
+
const oldPath = join42(toolsDir, bin);
|
|
71142
|
+
const newPath = join42(binDir, bin);
|
|
71143
|
+
if (existsSync28(oldPath)) {
|
|
71144
|
+
if (!existsSync28(binDir)) {
|
|
70482
71145
|
mkdirSync14(binDir, { recursive: true });
|
|
70483
71146
|
}
|
|
70484
|
-
if (!
|
|
71147
|
+
if (!existsSync28(newPath)) {
|
|
70485
71148
|
try {
|
|
70486
71149
|
renameSync2(oldPath, newPath);
|
|
70487
71150
|
movedAny = true;
|
|
@@ -70500,13 +71163,13 @@ function migrateToolsToBin() {
|
|
|
70500
71163
|
}
|
|
70501
71164
|
}
|
|
70502
71165
|
function checkDeprecatedExtensionDirs(baseDir, label) {
|
|
70503
|
-
const hooksDir =
|
|
70504
|
-
const toolsDir =
|
|
71166
|
+
const hooksDir = join42(baseDir, "hooks");
|
|
71167
|
+
const toolsDir = join42(baseDir, "tools");
|
|
70505
71168
|
const warnings = [];
|
|
70506
|
-
if (
|
|
71169
|
+
if (existsSync28(hooksDir)) {
|
|
70507
71170
|
warnings.push(`${label} hooks/ directory found. Hooks have been renamed to extensions.`);
|
|
70508
71171
|
}
|
|
70509
|
-
if (
|
|
71172
|
+
if (existsSync28(toolsDir)) {
|
|
70510
71173
|
try {
|
|
70511
71174
|
const entries = readdirSync10(toolsDir);
|
|
70512
71175
|
const customTools = entries.filter((e) => {
|
|
@@ -70523,7 +71186,7 @@ function checkDeprecatedExtensionDirs(baseDir, label) {
|
|
|
70523
71186
|
}
|
|
70524
71187
|
function migrateExtensionSystem(cwd) {
|
|
70525
71188
|
const agentDir = getAgentDir();
|
|
70526
|
-
const projectDir =
|
|
71189
|
+
const projectDir = join42(cwd, CONFIG_DIR_NAME);
|
|
70527
71190
|
migrateCommandsToPrompts(agentDir, "Global");
|
|
70528
71191
|
migrateCommandsToPrompts(projectDir, "Project");
|
|
70529
71192
|
const warnings = [
|
|
@@ -70565,12 +71228,12 @@ function runMigrations(cwd) {
|
|
|
70565
71228
|
}
|
|
70566
71229
|
|
|
70567
71230
|
// dist/package-manager-cli.js
|
|
70568
|
-
import { join as
|
|
71231
|
+
import { join as join45 } from "node:path";
|
|
70569
71232
|
import chalk11 from "chalk";
|
|
70570
71233
|
|
|
70571
71234
|
// dist/modes/interactive/components/config-selector.js
|
|
70572
71235
|
import { homedir as homedir14 } from "node:os";
|
|
70573
|
-
import { basename as
|
|
71236
|
+
import { basename as basename15, dirname as dirname24, join as join43, relative as relative7 } from "node:path";
|
|
70574
71237
|
var RESOURCE_TYPES2 = ["extensions", "skills", "prompts", "themes"];
|
|
70575
71238
|
var RESOURCE_TYPE_LABELS = {
|
|
70576
71239
|
extensions: "Extensions",
|
|
@@ -70607,7 +71270,7 @@ function buildGroups(resolved, agentDir) {
|
|
|
70607
71270
|
const groupMap = /* @__PURE__ */ new Map();
|
|
70608
71271
|
const addToGroup = (resources, resourceType) => {
|
|
70609
71272
|
for (const res of resources) {
|
|
70610
|
-
const { path:
|
|
71273
|
+
const { path: path12, enabled, metadata } = res;
|
|
70611
71274
|
const groupKey = `${metadata.origin}:${metadata.scope}:${metadata.source}:${metadata.baseDir ?? ""}`;
|
|
70612
71275
|
if (!groupMap.has(groupKey)) {
|
|
70613
71276
|
groupMap.set(groupKey, {
|
|
@@ -70630,8 +71293,8 @@ function buildGroups(resolved, agentDir) {
|
|
|
70630
71293
|
};
|
|
70631
71294
|
group.subgroups.push(subgroup);
|
|
70632
71295
|
}
|
|
70633
|
-
const fileName =
|
|
70634
|
-
const parentFolder =
|
|
71296
|
+
const fileName = basename15(path12);
|
|
71297
|
+
const parentFolder = basename15(dirname24(path12));
|
|
70635
71298
|
let displayName;
|
|
70636
71299
|
if (resourceType === "extensions" && parentFolder !== "extensions") {
|
|
70637
71300
|
displayName = `${parentFolder}/${fileName}`;
|
|
@@ -70641,7 +71304,7 @@ function buildGroups(resolved, agentDir) {
|
|
|
70641
71304
|
displayName = fileName;
|
|
70642
71305
|
}
|
|
70643
71306
|
subgroup.items.push({
|
|
70644
|
-
path:
|
|
71307
|
+
path: path12,
|
|
70645
71308
|
enabled,
|
|
70646
71309
|
metadata,
|
|
70647
71310
|
resourceType,
|
|
@@ -71203,7 +71866,7 @@ var ResourceList = class {
|
|
|
71203
71866
|
return item.metadata.scope === "project" ? "project" : "user";
|
|
71204
71867
|
}
|
|
71205
71868
|
getTopLevelBaseDir(scope) {
|
|
71206
|
-
return scope === "project" ?
|
|
71869
|
+
return scope === "project" ? join43(this.cwd, CONFIG_DIR_NAME) : this.agentDir;
|
|
71207
71870
|
}
|
|
71208
71871
|
getResourcePattern(item) {
|
|
71209
71872
|
const scope = item.metadata.scope;
|
|
@@ -71358,18 +72021,18 @@ async function getLatestPiRelease(currentVersion, options = {}) {
|
|
|
71358
72021
|
}
|
|
71359
72022
|
|
|
71360
72023
|
// dist/utils/windows-self-update.js
|
|
71361
|
-
import { randomUUID as
|
|
71362
|
-
import { copyFileSync as copyFileSync2, existsSync as
|
|
71363
|
-
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";
|
|
71364
72027
|
var QUARANTINE_DIR_NAME = ".pi-native-quarantine";
|
|
71365
|
-
function normalizePath2(
|
|
71366
|
-
return toNamespacedPath(resolve14(
|
|
72028
|
+
function normalizePath2(path12) {
|
|
72029
|
+
return toNamespacedPath(resolve14(path12));
|
|
71367
72030
|
}
|
|
71368
72031
|
function getQuarantineRoot(packageDir) {
|
|
71369
72032
|
let current = resolve14(packageDir);
|
|
71370
72033
|
while (true) {
|
|
71371
|
-
if (
|
|
71372
|
-
return
|
|
72034
|
+
if (basename16(current).toLowerCase() === "node_modules") {
|
|
72035
|
+
return join44(current, QUARANTINE_DIR_NAME);
|
|
71373
72036
|
}
|
|
71374
72037
|
const parent = dirname25(current);
|
|
71375
72038
|
if (parent === current) {
|
|
@@ -71420,12 +72083,12 @@ function quarantineWindowsNativeDependencies(packageDir) {
|
|
|
71420
72083
|
if (loadedFiles.length === 0) {
|
|
71421
72084
|
return;
|
|
71422
72085
|
}
|
|
71423
|
-
const quarantineRunDir =
|
|
72086
|
+
const quarantineRunDir = join44(quarantineRoot, `${Date.now()}-${process.pid}-${randomUUID7()}`);
|
|
71424
72087
|
for (const loadedFile of loadedFiles) {
|
|
71425
|
-
if (!
|
|
72088
|
+
if (!existsSync29(loadedFile)) {
|
|
71426
72089
|
continue;
|
|
71427
72090
|
}
|
|
71428
|
-
const quarantinePath =
|
|
72091
|
+
const quarantinePath = join44(quarantineRunDir, relative8(resolvedPackageDir, loadedFile));
|
|
71429
72092
|
mkdirSync15(dirname25(quarantinePath), { recursive: true });
|
|
71430
72093
|
renameSync3(loadedFile, quarantinePath);
|
|
71431
72094
|
copyFileSync2(quarantinePath, loadedFile);
|
|
@@ -71749,8 +72412,8 @@ async function refreshModelCatalogs(agentDir) {
|
|
|
71749
72412
|
const timeout = setTimeout(() => controller.abort(), 15e3);
|
|
71750
72413
|
try {
|
|
71751
72414
|
const modelRuntime = await ModelRuntime.create({
|
|
71752
|
-
authPath:
|
|
71753
|
-
modelsPath:
|
|
72415
|
+
authPath: join45(agentDir, "auth.json"),
|
|
72416
|
+
modelsPath: join45(agentDir, "models.json"),
|
|
71754
72417
|
allowModelNetwork: false,
|
|
71755
72418
|
signal: controller.signal
|
|
71756
72419
|
});
|
|
@@ -72325,9 +72988,9 @@ function validateSessionIdFlags(parsed) {
|
|
|
72325
72988
|
process.exit(1);
|
|
72326
72989
|
}
|
|
72327
72990
|
}
|
|
72328
|
-
function openSessionOrExit(
|
|
72991
|
+
function openSessionOrExit(path12, sessionDir) {
|
|
72329
72992
|
try {
|
|
72330
|
-
return SessionManager.open(
|
|
72993
|
+
return SessionManager.open(path12, sessionDir);
|
|
72331
72994
|
} catch (error) {
|
|
72332
72995
|
const message = error instanceof Error ? error.message : String(error);
|
|
72333
72996
|
console.error(chalk12.red(`Error: ${message}`));
|
|
@@ -72684,9 +73347,9 @@ async function main(args, options) {
|
|
|
72684
73347
|
...projectTrustDiagnostics,
|
|
72685
73348
|
...services2.diagnostics,
|
|
72686
73349
|
...collectSettingsDiagnostics(settingsManager2, "runtime creation"),
|
|
72687
|
-
...resourceLoader2.getExtensions().errors.map(({ path:
|
|
73350
|
+
...resourceLoader2.getExtensions().errors.map(({ path: path12, error }) => ({
|
|
72688
73351
|
type: "error",
|
|
72689
|
-
message: `Failed to load extension "${
|
|
73352
|
+
message: `Failed to load extension "${path12}": ${error}`
|
|
72690
73353
|
}))
|
|
72691
73354
|
];
|
|
72692
73355
|
const modelPatterns = parsed.models ?? settingsManager2.getEnabledModels();
|