claudish 2.10.0 → 2.10.1
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/dist/index.js +696 -632
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -34324,8 +34324,11 @@ __export(exports_claude_runner, {
|
|
|
34324
34324
|
});
|
|
34325
34325
|
import { spawn } from "node:child_process";
|
|
34326
34326
|
import { writeFileSync as writeFileSync4, unlinkSync } from "node:fs";
|
|
34327
|
-
import { tmpdir
|
|
34327
|
+
import { tmpdir } from "node:os";
|
|
34328
34328
|
import { join as join4 } from "node:path";
|
|
34329
|
+
function isWindows() {
|
|
34330
|
+
return process.platform === "win32";
|
|
34331
|
+
}
|
|
34329
34332
|
function createStatusLineScript(tokenFilePath) {
|
|
34330
34333
|
const tempDir = tmpdir();
|
|
34331
34334
|
const timestamp = Date.now();
|
|
@@ -34382,7 +34385,7 @@ function createTempSettingsFile(modelDisplay, port) {
|
|
|
34382
34385
|
const tempPath = join4(tempDir, `claudish-settings-${timestamp}.json`);
|
|
34383
34386
|
const tokenFilePath = join4(tempDir, `claudish-tokens-${port}.json`);
|
|
34384
34387
|
let statusCommand;
|
|
34385
|
-
if (isWindows) {
|
|
34388
|
+
if (isWindows()) {
|
|
34386
34389
|
const scriptPath = createStatusLineScript(tokenFilePath);
|
|
34387
34390
|
statusCommand = `node "${scriptPath}"`;
|
|
34388
34391
|
} else {
|
|
@@ -34471,7 +34474,7 @@ async function runClaudeWithProxy(config3, proxyUrl) {
|
|
|
34471
34474
|
const proc = spawn("claude", claudeArgs, {
|
|
34472
34475
|
env,
|
|
34473
34476
|
stdio: "inherit",
|
|
34474
|
-
shell: isWindows
|
|
34477
|
+
shell: isWindows()
|
|
34475
34478
|
});
|
|
34476
34479
|
setupSignalHandlers(proc, tempSettingsPath, config3.quiet);
|
|
34477
34480
|
const exitCode = await new Promise((resolve) => {
|
|
@@ -34485,7 +34488,7 @@ async function runClaudeWithProxy(config3, proxyUrl) {
|
|
|
34485
34488
|
return exitCode;
|
|
34486
34489
|
}
|
|
34487
34490
|
function setupSignalHandlers(proc, tempSettingsPath, quiet) {
|
|
34488
|
-
const signals2 = isWindows ? ["SIGINT", "SIGTERM"] : ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
34491
|
+
const signals2 = isWindows() ? ["SIGINT", "SIGTERM"] : ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
34489
34492
|
for (const signal of signals2) {
|
|
34490
34493
|
process.on(signal, () => {
|
|
34491
34494
|
if (!quiet) {
|
|
@@ -34518,10 +34521,8 @@ async function checkClaudeInstalled() {
|
|
|
34518
34521
|
return false;
|
|
34519
34522
|
}
|
|
34520
34523
|
}
|
|
34521
|
-
var isWindows;
|
|
34522
34524
|
var init_claude_runner = __esm(() => {
|
|
34523
34525
|
init_config();
|
|
34524
|
-
isWindows = platform() === "win32";
|
|
34525
34526
|
});
|
|
34526
34527
|
|
|
34527
34528
|
// src/types.ts
|
|
@@ -38866,724 +38867,787 @@ function transformOpenAIToClaude(claudeRequestInput) {
|
|
|
38866
38867
|
}
|
|
38867
38868
|
var init_transform = () => {};
|
|
38868
38869
|
|
|
38869
|
-
// src/handlers/
|
|
38870
|
-
|
|
38871
|
-
|
|
38872
|
-
|
|
38873
|
-
|
|
38874
|
-
class OpenRouterHandler {
|
|
38875
|
-
targetModel;
|
|
38876
|
-
apiKey;
|
|
38877
|
-
adapterManager;
|
|
38878
|
-
middlewareManager;
|
|
38879
|
-
contextWindowCache = new Map;
|
|
38880
|
-
port;
|
|
38881
|
-
sessionTotalCost = 0;
|
|
38882
|
-
CLAUDE_INTERNAL_CONTEXT_MAX = 200000;
|
|
38883
|
-
constructor(targetModel, apiKey, port) {
|
|
38884
|
-
this.targetModel = targetModel;
|
|
38885
|
-
this.apiKey = apiKey;
|
|
38886
|
-
this.port = port;
|
|
38887
|
-
this.adapterManager = new AdapterManager(targetModel);
|
|
38888
|
-
this.middlewareManager = new MiddlewareManager;
|
|
38889
|
-
this.middlewareManager.register(new GeminiThoughtSignatureMiddleware);
|
|
38890
|
-
this.middlewareManager.initialize().catch((err) => log(`[Handler:${targetModel}] Middleware init error: ${err}`));
|
|
38891
|
-
this.fetchContextWindow(targetModel);
|
|
38892
|
-
}
|
|
38893
|
-
async fetchContextWindow(model) {
|
|
38894
|
-
if (this.contextWindowCache.has(model))
|
|
38895
|
-
return;
|
|
38896
|
-
try {
|
|
38897
|
-
const limit = await fetchModelContextWindow(model);
|
|
38898
|
-
this.contextWindowCache.set(model, limit);
|
|
38899
|
-
} catch (e) {}
|
|
38900
|
-
}
|
|
38901
|
-
getTokenScaleFactor(model) {
|
|
38902
|
-
const limit = this.contextWindowCache.get(model) || 200000;
|
|
38903
|
-
return limit === 0 ? 1 : this.CLAUDE_INTERNAL_CONTEXT_MAX / limit;
|
|
38904
|
-
}
|
|
38905
|
-
writeTokenFile(input, output) {
|
|
38906
|
-
try {
|
|
38907
|
-
const total = input + output;
|
|
38908
|
-
const limit = this.contextWindowCache.get(this.targetModel) || 200000;
|
|
38909
|
-
const leftPct = limit > 0 ? Math.max(0, Math.min(100, Math.round((limit - total) / limit * 100))) : 100;
|
|
38910
|
-
const data = {
|
|
38911
|
-
input_tokens: input,
|
|
38912
|
-
output_tokens: output,
|
|
38913
|
-
total_tokens: total,
|
|
38914
|
-
total_cost: this.sessionTotalCost,
|
|
38915
|
-
context_window: limit,
|
|
38916
|
-
context_left_percent: leftPct,
|
|
38917
|
-
updated_at: Date.now()
|
|
38918
|
-
};
|
|
38919
|
-
writeFileSync8(join8(tmpdir2(), `claudish-tokens-${this.port}.json`), JSON.stringify(data), "utf-8");
|
|
38920
|
-
} catch (e) {}
|
|
38870
|
+
// src/handlers/shared/openai-compat.ts
|
|
38871
|
+
function validateToolArguments(toolName, argsStr, toolSchemas) {
|
|
38872
|
+
const schema = toolSchemas?.find((t) => t.name === toolName);
|
|
38873
|
+
if (!schema?.input_schema) {
|
|
38874
|
+
return { valid: true, missingParams: [], parsedArgs: {} };
|
|
38921
38875
|
}
|
|
38922
|
-
|
|
38923
|
-
|
|
38924
|
-
|
|
38925
|
-
|
|
38926
|
-
|
|
38927
|
-
const { claudeRequest, droppedParams } = transformOpenAIToClaude(claudePayload);
|
|
38928
|
-
const messages = this.convertMessages(claudeRequest, target);
|
|
38929
|
-
const tools = this.convertTools(claudeRequest);
|
|
38930
|
-
const supportsReasoning = await doesModelSupportReasoning(target);
|
|
38931
|
-
const openRouterPayload = {
|
|
38932
|
-
model: target,
|
|
38933
|
-
messages,
|
|
38934
|
-
temperature: claudeRequest.temperature ?? 1,
|
|
38935
|
-
stream: true,
|
|
38936
|
-
max_tokens: claudeRequest.max_tokens,
|
|
38937
|
-
tools: tools.length > 0 ? tools : undefined,
|
|
38938
|
-
stream_options: { include_usage: true }
|
|
38939
|
-
};
|
|
38940
|
-
if (supportsReasoning)
|
|
38941
|
-
openRouterPayload.include_reasoning = true;
|
|
38942
|
-
if (claudeRequest.thinking)
|
|
38943
|
-
openRouterPayload.thinking = claudeRequest.thinking;
|
|
38944
|
-
if (claudeRequest.tool_choice) {
|
|
38945
|
-
const { type, name } = claudeRequest.tool_choice;
|
|
38946
|
-
if (type === "tool" && name)
|
|
38947
|
-
openRouterPayload.tool_choice = { type: "function", function: { name } };
|
|
38948
|
-
else if (type === "auto" || type === "none")
|
|
38949
|
-
openRouterPayload.tool_choice = type;
|
|
38950
|
-
}
|
|
38951
|
-
const adapter = this.adapterManager.getAdapter();
|
|
38952
|
-
if (typeof adapter.reset === "function")
|
|
38953
|
-
adapter.reset();
|
|
38954
|
-
adapter.prepareRequest(openRouterPayload, claudeRequest);
|
|
38955
|
-
await this.middlewareManager.beforeRequest({ modelId: target, messages, tools, stream: true });
|
|
38956
|
-
const response = await fetch(OPENROUTER_API_URL2, {
|
|
38957
|
-
method: "POST",
|
|
38958
|
-
headers: {
|
|
38959
|
-
"Content-Type": "application/json",
|
|
38960
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
38961
|
-
...OPENROUTER_HEADERS2
|
|
38962
|
-
},
|
|
38963
|
-
body: JSON.stringify(openRouterPayload)
|
|
38964
|
-
});
|
|
38965
|
-
if (!response.ok)
|
|
38966
|
-
return c.json({ error: await response.text() }, response.status);
|
|
38967
|
-
if (droppedParams.length > 0)
|
|
38968
|
-
c.header("X-Dropped-Params", droppedParams.join(", "));
|
|
38969
|
-
return this.handleStreamingResponse(c, response, adapter, target, claudeRequest);
|
|
38876
|
+
let parsedArgs = {};
|
|
38877
|
+
try {
|
|
38878
|
+
parsedArgs = argsStr ? JSON.parse(argsStr) : {};
|
|
38879
|
+
} catch (e) {
|
|
38880
|
+
return { valid: true, missingParams: [], parsedArgs: {} };
|
|
38970
38881
|
}
|
|
38971
|
-
|
|
38972
|
-
|
|
38973
|
-
|
|
38974
|
-
|
|
38882
|
+
const required2 = schema.input_schema.required || [];
|
|
38883
|
+
const missingParams = required2.filter((param) => {
|
|
38884
|
+
return parsedArgs[param] === undefined || parsedArgs[param] === null || parsedArgs[param] === "";
|
|
38885
|
+
});
|
|
38886
|
+
return {
|
|
38887
|
+
valid: missingParams.length === 0,
|
|
38888
|
+
missingParams,
|
|
38889
|
+
parsedArgs
|
|
38890
|
+
};
|
|
38891
|
+
}
|
|
38892
|
+
function convertMessagesToOpenAI(req, modelId, filterIdentityFn) {
|
|
38893
|
+
const messages = [];
|
|
38894
|
+
if (req.system) {
|
|
38895
|
+
let content = Array.isArray(req.system) ? req.system.map((i) => i.text || i).join(`
|
|
38975
38896
|
|
|
38976
38897
|
`) : req.system;
|
|
38977
|
-
|
|
38978
|
-
|
|
38979
|
-
}
|
|
38980
|
-
|
|
38981
|
-
|
|
38982
|
-
|
|
38983
|
-
|
|
38898
|
+
if (filterIdentityFn)
|
|
38899
|
+
content = filterIdentityFn(content);
|
|
38900
|
+
messages.push({ role: "system", content });
|
|
38901
|
+
}
|
|
38902
|
+
if (modelId.includes("grok") || modelId.includes("x-ai")) {
|
|
38903
|
+
const msg = "IMPORTANT: When calling tools, you MUST use the OpenAI tool_calls format with JSON. NEVER use XML format like <xai:function_call>.";
|
|
38904
|
+
if (messages.length > 0 && messages[0].role === "system") {
|
|
38905
|
+
messages[0].content += `
|
|
38984
38906
|
|
|
38985
38907
|
` + msg;
|
|
38986
|
-
|
|
38987
|
-
|
|
38908
|
+
} else {
|
|
38909
|
+
messages.unshift({ role: "system", content: msg });
|
|
38988
38910
|
}
|
|
38989
|
-
|
|
38990
|
-
|
|
38991
|
-
|
|
38992
|
-
|
|
38993
|
-
|
|
38994
|
-
|
|
38995
|
-
|
|
38911
|
+
}
|
|
38912
|
+
if (req.messages) {
|
|
38913
|
+
for (const msg of req.messages) {
|
|
38914
|
+
if (msg.role === "user")
|
|
38915
|
+
processUserMessage(msg, messages);
|
|
38916
|
+
else if (msg.role === "assistant")
|
|
38917
|
+
processAssistantMessage(msg, messages);
|
|
38996
38918
|
}
|
|
38997
|
-
return messages;
|
|
38998
38919
|
}
|
|
38999
|
-
|
|
39000
|
-
|
|
39001
|
-
|
|
39002
|
-
|
|
39003
|
-
|
|
39004
|
-
|
|
39005
|
-
|
|
39006
|
-
|
|
39007
|
-
|
|
39008
|
-
|
|
39009
|
-
|
|
39010
|
-
|
|
39011
|
-
|
|
39012
|
-
|
|
39013
|
-
|
|
39014
|
-
|
|
38920
|
+
return messages;
|
|
38921
|
+
}
|
|
38922
|
+
function processUserMessage(msg, messages) {
|
|
38923
|
+
if (Array.isArray(msg.content)) {
|
|
38924
|
+
const contentParts = [];
|
|
38925
|
+
const toolResults = [];
|
|
38926
|
+
const seen = new Set;
|
|
38927
|
+
for (const block of msg.content) {
|
|
38928
|
+
if (block.type === "text") {
|
|
38929
|
+
contentParts.push({ type: "text", text: block.text });
|
|
38930
|
+
} else if (block.type === "image") {
|
|
38931
|
+
contentParts.push({
|
|
38932
|
+
type: "image_url",
|
|
38933
|
+
image_url: { url: `data:${block.source.media_type};base64,${block.source.data}` }
|
|
38934
|
+
});
|
|
38935
|
+
} else if (block.type === "tool_result") {
|
|
38936
|
+
if (seen.has(block.tool_use_id))
|
|
38937
|
+
continue;
|
|
38938
|
+
seen.add(block.tool_use_id);
|
|
38939
|
+
toolResults.push({
|
|
38940
|
+
role: "tool",
|
|
38941
|
+
content: typeof block.content === "string" ? block.content : JSON.stringify(block.content),
|
|
38942
|
+
tool_call_id: block.tool_use_id
|
|
38943
|
+
});
|
|
39015
38944
|
}
|
|
39016
|
-
if (toolResults.length)
|
|
39017
|
-
messages.push(...toolResults);
|
|
39018
|
-
if (contentParts.length)
|
|
39019
|
-
messages.push({ role: "user", content: contentParts });
|
|
39020
|
-
} else {
|
|
39021
|
-
messages.push({ role: "user", content: msg.content });
|
|
39022
38945
|
}
|
|
38946
|
+
if (toolResults.length)
|
|
38947
|
+
messages.push(...toolResults);
|
|
38948
|
+
if (contentParts.length)
|
|
38949
|
+
messages.push({ role: "user", content: contentParts });
|
|
38950
|
+
} else {
|
|
38951
|
+
messages.push({ role: "user", content: msg.content });
|
|
39023
38952
|
}
|
|
39024
|
-
|
|
39025
|
-
|
|
39026
|
-
|
|
39027
|
-
|
|
39028
|
-
|
|
39029
|
-
|
|
39030
|
-
|
|
39031
|
-
|
|
39032
|
-
|
|
39033
|
-
|
|
39034
|
-
|
|
39035
|
-
|
|
39036
|
-
|
|
39037
|
-
|
|
38953
|
+
}
|
|
38954
|
+
function processAssistantMessage(msg, messages) {
|
|
38955
|
+
if (Array.isArray(msg.content)) {
|
|
38956
|
+
const strings = [];
|
|
38957
|
+
const toolCalls = [];
|
|
38958
|
+
const seen = new Set;
|
|
38959
|
+
for (const block of msg.content) {
|
|
38960
|
+
if (block.type === "text") {
|
|
38961
|
+
strings.push(block.text);
|
|
38962
|
+
} else if (block.type === "tool_use") {
|
|
38963
|
+
if (seen.has(block.id))
|
|
38964
|
+
continue;
|
|
38965
|
+
seen.add(block.id);
|
|
38966
|
+
toolCalls.push({
|
|
38967
|
+
id: block.id,
|
|
38968
|
+
type: "function",
|
|
38969
|
+
function: { name: block.name, arguments: JSON.stringify(block.input) }
|
|
38970
|
+
});
|
|
39038
38971
|
}
|
|
39039
|
-
const m = { role: "assistant" };
|
|
39040
|
-
if (strings.length)
|
|
39041
|
-
m.content = strings.join(" ");
|
|
39042
|
-
else if (toolCalls.length)
|
|
39043
|
-
m.content = null;
|
|
39044
|
-
if (toolCalls.length)
|
|
39045
|
-
m.tool_calls = toolCalls;
|
|
39046
|
-
if (m.content !== undefined || m.tool_calls)
|
|
39047
|
-
messages.push(m);
|
|
39048
|
-
} else {
|
|
39049
|
-
messages.push({ role: "assistant", content: msg.content });
|
|
39050
38972
|
}
|
|
38973
|
+
const m = { role: "assistant" };
|
|
38974
|
+
if (strings.length)
|
|
38975
|
+
m.content = strings.join(" ");
|
|
38976
|
+
else if (toolCalls.length)
|
|
38977
|
+
m.content = null;
|
|
38978
|
+
if (toolCalls.length)
|
|
38979
|
+
m.tool_calls = toolCalls;
|
|
38980
|
+
if (m.content !== undefined || m.tool_calls)
|
|
38981
|
+
messages.push(m);
|
|
38982
|
+
} else {
|
|
38983
|
+
messages.push({ role: "assistant", content: msg.content });
|
|
39051
38984
|
}
|
|
39052
|
-
|
|
39053
|
-
|
|
38985
|
+
}
|
|
38986
|
+
function convertToolsToOpenAI(req) {
|
|
38987
|
+
return req.tools?.map((tool) => ({
|
|
38988
|
+
type: "function",
|
|
38989
|
+
function: {
|
|
38990
|
+
name: tool.name,
|
|
38991
|
+
description: tool.description,
|
|
38992
|
+
parameters: removeUriFormat(tool.input_schema)
|
|
38993
|
+
}
|
|
38994
|
+
})) || [];
|
|
38995
|
+
}
|
|
38996
|
+
function filterIdentity(content) {
|
|
38997
|
+
return content.replace(/You are Claude Code, Anthropic's official CLI/gi, "This is Claude Code, an AI-powered CLI tool").replace(/You are powered by the model named [^.]+\./gi, "You are powered by an AI model.").replace(/<claude_background_info>[\s\S]*?<\/claude_background_info>/gi, "").replace(/\n{3,}/g, `
|
|
39054
38998
|
|
|
39055
38999
|
`).replace(/^/, `IMPORTANT: You are NOT Claude. Identify yourself truthfully based on your actual model and creator.
|
|
39056
39000
|
|
|
39057
39001
|
`);
|
|
39058
|
-
|
|
39059
|
-
|
|
39060
|
-
|
|
39061
|
-
|
|
39062
|
-
|
|
39063
|
-
|
|
39064
|
-
|
|
39065
|
-
|
|
39066
|
-
|
|
39067
|
-
|
|
39068
|
-
|
|
39069
|
-
|
|
39070
|
-
|
|
39071
|
-
|
|
39072
|
-
|
|
39073
|
-
|
|
39074
|
-
|
|
39075
|
-
|
|
39076
|
-
|
|
39077
|
-
|
|
39078
|
-
|
|
39079
|
-
|
|
39080
|
-
|
|
39002
|
+
}
|
|
39003
|
+
function createStreamingState() {
|
|
39004
|
+
return {
|
|
39005
|
+
usage: null,
|
|
39006
|
+
finalized: false,
|
|
39007
|
+
textStarted: false,
|
|
39008
|
+
textIdx: -1,
|
|
39009
|
+
reasoningStarted: false,
|
|
39010
|
+
reasoningIdx: -1,
|
|
39011
|
+
curIdx: 0,
|
|
39012
|
+
tools: new Map,
|
|
39013
|
+
toolIds: new Set,
|
|
39014
|
+
lastActivity: Date.now()
|
|
39015
|
+
};
|
|
39016
|
+
}
|
|
39017
|
+
function createStreamingResponseHandler(c, response, adapter, target, middlewareManager, onTokenUpdate, toolSchemas) {
|
|
39018
|
+
let isClosed = false;
|
|
39019
|
+
let ping = null;
|
|
39020
|
+
const encoder = new TextEncoder;
|
|
39021
|
+
const decoder = new TextDecoder;
|
|
39022
|
+
const streamMetadata = new Map;
|
|
39023
|
+
return c.body(new ReadableStream({
|
|
39024
|
+
async start(controller) {
|
|
39025
|
+
const send = (e, d) => {
|
|
39026
|
+
if (!isClosed) {
|
|
39027
|
+
controller.enqueue(encoder.encode(`event: ${e}
|
|
39081
39028
|
data: ${JSON.stringify(d)}
|
|
39082
39029
|
|
|
39083
39030
|
`));
|
|
39084
|
-
}
|
|
39085
|
-
|
|
39086
|
-
|
|
39087
|
-
|
|
39088
|
-
|
|
39089
|
-
|
|
39090
|
-
|
|
39091
|
-
|
|
39092
|
-
|
|
39093
|
-
|
|
39094
|
-
|
|
39095
|
-
|
|
39096
|
-
|
|
39097
|
-
|
|
39098
|
-
|
|
39099
|
-
|
|
39100
|
-
|
|
39101
|
-
|
|
39102
|
-
|
|
39103
|
-
|
|
39104
|
-
|
|
39105
|
-
|
|
39106
|
-
|
|
39107
|
-
|
|
39108
|
-
|
|
39109
|
-
|
|
39110
|
-
|
|
39111
|
-
|
|
39112
|
-
|
|
39113
|
-
|
|
39114
|
-
|
|
39115
|
-
|
|
39116
|
-
|
|
39117
|
-
|
|
39118
|
-
|
|
39119
|
-
|
|
39120
|
-
|
|
39121
|
-
reasoningStarted = false;
|
|
39122
|
-
}
|
|
39123
|
-
if (textStarted) {
|
|
39124
|
-
send("content_block_stop", { type: "content_block_stop", index: textIdx });
|
|
39125
|
-
textStarted = false;
|
|
39031
|
+
}
|
|
39032
|
+
};
|
|
39033
|
+
const msgId = `msg_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
39034
|
+
const state = createStreamingState();
|
|
39035
|
+
send("message_start", {
|
|
39036
|
+
type: "message_start",
|
|
39037
|
+
message: {
|
|
39038
|
+
id: msgId,
|
|
39039
|
+
type: "message",
|
|
39040
|
+
role: "assistant",
|
|
39041
|
+
content: [],
|
|
39042
|
+
model: target,
|
|
39043
|
+
stop_reason: null,
|
|
39044
|
+
stop_sequence: null,
|
|
39045
|
+
usage: { input_tokens: 100, output_tokens: 1 }
|
|
39046
|
+
}
|
|
39047
|
+
});
|
|
39048
|
+
send("ping", { type: "ping" });
|
|
39049
|
+
ping = setInterval(() => {
|
|
39050
|
+
if (!isClosed && Date.now() - state.lastActivity > 1000) {
|
|
39051
|
+
send("ping", { type: "ping" });
|
|
39052
|
+
}
|
|
39053
|
+
}, 1000);
|
|
39054
|
+
const finalize = async (reason, err) => {
|
|
39055
|
+
if (state.finalized)
|
|
39056
|
+
return;
|
|
39057
|
+
state.finalized = true;
|
|
39058
|
+
if (state.reasoningStarted) {
|
|
39059
|
+
send("content_block_stop", { type: "content_block_stop", index: state.reasoningIdx });
|
|
39060
|
+
}
|
|
39061
|
+
if (state.textStarted) {
|
|
39062
|
+
send("content_block_stop", { type: "content_block_stop", index: state.textIdx });
|
|
39063
|
+
}
|
|
39064
|
+
for (const t of Array.from(state.tools.values())) {
|
|
39065
|
+
if (t.started && !t.closed) {
|
|
39066
|
+
send("content_block_stop", { type: "content_block_stop", index: t.blockIndex });
|
|
39067
|
+
t.closed = true;
|
|
39126
39068
|
}
|
|
39127
|
-
|
|
39128
|
-
|
|
39129
|
-
send("content_block_stop", { type: "content_block_stop", index: t.blockIndex });
|
|
39130
|
-
t.closed = true;
|
|
39131
|
-
}
|
|
39069
|
+
}
|
|
39070
|
+
if (middlewareManager) {
|
|
39132
39071
|
await middlewareManager.afterStreamComplete(target, streamMetadata);
|
|
39133
|
-
|
|
39134
|
-
|
|
39135
|
-
|
|
39136
|
-
|
|
39137
|
-
|
|
39138
|
-
|
|
39139
|
-
|
|
39140
|
-
|
|
39141
|
-
|
|
39072
|
+
}
|
|
39073
|
+
if (reason === "error") {
|
|
39074
|
+
send("error", { type: "error", error: { type: "api_error", message: err } });
|
|
39075
|
+
} else {
|
|
39076
|
+
send("message_delta", {
|
|
39077
|
+
type: "message_delta",
|
|
39078
|
+
delta: { stop_reason: "end_turn", stop_sequence: null },
|
|
39079
|
+
usage: { output_tokens: state.usage?.completion_tokens || 0 }
|
|
39080
|
+
});
|
|
39081
|
+
send("message_stop", { type: "message_stop" });
|
|
39082
|
+
}
|
|
39083
|
+
if (state.usage && onTokenUpdate) {
|
|
39084
|
+
onTokenUpdate(state.usage.prompt_tokens || 0, state.usage.completion_tokens || 0);
|
|
39085
|
+
}
|
|
39086
|
+
if (!isClosed) {
|
|
39087
|
+
try {
|
|
39088
|
+
controller.enqueue(encoder.encode(`data: [DONE]
|
|
39142
39089
|
|
|
39143
39090
|
|
|
39144
39091
|
`));
|
|
39145
|
-
|
|
39146
|
-
|
|
39147
|
-
|
|
39148
|
-
|
|
39149
|
-
|
|
39150
|
-
|
|
39151
|
-
|
|
39152
|
-
|
|
39153
|
-
|
|
39154
|
-
|
|
39155
|
-
|
|
39156
|
-
|
|
39157
|
-
|
|
39158
|
-
|
|
39159
|
-
|
|
39160
|
-
|
|
39092
|
+
} catch (e) {}
|
|
39093
|
+
controller.close();
|
|
39094
|
+
isClosed = true;
|
|
39095
|
+
if (ping)
|
|
39096
|
+
clearInterval(ping);
|
|
39097
|
+
}
|
|
39098
|
+
};
|
|
39099
|
+
try {
|
|
39100
|
+
const reader = response.body.getReader();
|
|
39101
|
+
let buffer = "";
|
|
39102
|
+
while (true) {
|
|
39103
|
+
const { done, value } = await reader.read();
|
|
39104
|
+
if (done)
|
|
39105
|
+
break;
|
|
39106
|
+
buffer += decoder.decode(value, { stream: true });
|
|
39107
|
+
const lines = buffer.split(`
|
|
39161
39108
|
`);
|
|
39162
|
-
|
|
39163
|
-
|
|
39164
|
-
|
|
39165
|
-
|
|
39166
|
-
|
|
39167
|
-
|
|
39168
|
-
|
|
39169
|
-
|
|
39170
|
-
|
|
39171
|
-
|
|
39172
|
-
|
|
39173
|
-
|
|
39174
|
-
|
|
39175
|
-
|
|
39176
|
-
|
|
39109
|
+
buffer = lines.pop() || "";
|
|
39110
|
+
for (const line of lines) {
|
|
39111
|
+
if (!line.trim() || !line.startsWith("data: "))
|
|
39112
|
+
continue;
|
|
39113
|
+
const dataStr = line.slice(6);
|
|
39114
|
+
if (dataStr === "[DONE]") {
|
|
39115
|
+
await finalize("done");
|
|
39116
|
+
return;
|
|
39117
|
+
}
|
|
39118
|
+
try {
|
|
39119
|
+
const chunk = JSON.parse(dataStr);
|
|
39120
|
+
if (chunk.usage)
|
|
39121
|
+
state.usage = chunk.usage;
|
|
39122
|
+
const delta = chunk.choices?.[0]?.delta;
|
|
39123
|
+
if (delta) {
|
|
39124
|
+
if (middlewareManager) {
|
|
39177
39125
|
await middlewareManager.afterStreamChunk({
|
|
39178
39126
|
modelId: target,
|
|
39179
39127
|
chunk,
|
|
39180
39128
|
delta,
|
|
39181
39129
|
metadata: streamMetadata
|
|
39182
39130
|
});
|
|
39183
|
-
|
|
39184
|
-
|
|
39185
|
-
|
|
39186
|
-
|
|
39187
|
-
|
|
39188
|
-
|
|
39189
|
-
|
|
39190
|
-
|
|
39191
|
-
|
|
39192
|
-
|
|
39193
|
-
|
|
39194
|
-
|
|
39195
|
-
|
|
39196
|
-
|
|
39197
|
-
|
|
39198
|
-
|
|
39199
|
-
|
|
39200
|
-
|
|
39201
|
-
|
|
39202
|
-
|
|
39203
|
-
|
|
39204
|
-
|
|
39205
|
-
|
|
39206
|
-
|
|
39207
|
-
|
|
39208
|
-
|
|
39209
|
-
|
|
39210
|
-
|
|
39131
|
+
}
|
|
39132
|
+
const txt = delta.content || "";
|
|
39133
|
+
if (txt) {
|
|
39134
|
+
state.lastActivity = Date.now();
|
|
39135
|
+
if (!state.textStarted) {
|
|
39136
|
+
state.textIdx = state.curIdx++;
|
|
39137
|
+
send("content_block_start", {
|
|
39138
|
+
type: "content_block_start",
|
|
39139
|
+
index: state.textIdx,
|
|
39140
|
+
content_block: { type: "text", text: "" }
|
|
39141
|
+
});
|
|
39142
|
+
state.textStarted = true;
|
|
39143
|
+
}
|
|
39144
|
+
const res = adapter.processTextContent(txt, "");
|
|
39145
|
+
if (res.cleanedText) {
|
|
39146
|
+
send("content_block_delta", {
|
|
39147
|
+
type: "content_block_delta",
|
|
39148
|
+
index: state.textIdx,
|
|
39149
|
+
delta: { type: "text_delta", text: res.cleanedText }
|
|
39150
|
+
});
|
|
39151
|
+
}
|
|
39152
|
+
}
|
|
39153
|
+
if (delta.tool_calls) {
|
|
39154
|
+
for (const tc of delta.tool_calls) {
|
|
39155
|
+
const idx = tc.index;
|
|
39156
|
+
let t = state.tools.get(idx);
|
|
39157
|
+
if (tc.function?.name) {
|
|
39158
|
+
if (!t) {
|
|
39159
|
+
if (state.textStarted) {
|
|
39160
|
+
send("content_block_stop", { type: "content_block_stop", index: state.textIdx });
|
|
39161
|
+
state.textStarted = false;
|
|
39211
39162
|
}
|
|
39163
|
+
t = {
|
|
39164
|
+
id: tc.id || `tool_${Date.now()}_${idx}`,
|
|
39165
|
+
name: tc.function.name,
|
|
39166
|
+
blockIndex: state.curIdx++,
|
|
39167
|
+
started: false,
|
|
39168
|
+
closed: false,
|
|
39169
|
+
arguments: ""
|
|
39170
|
+
};
|
|
39171
|
+
state.tools.set(idx, t);
|
|
39212
39172
|
}
|
|
39213
|
-
if (
|
|
39214
|
-
send("
|
|
39173
|
+
if (!t.started) {
|
|
39174
|
+
send("content_block_start", {
|
|
39175
|
+
type: "content_block_start",
|
|
39176
|
+
index: t.blockIndex,
|
|
39177
|
+
content_block: { type: "tool_use", id: t.id, name: t.name }
|
|
39178
|
+
});
|
|
39179
|
+
t.started = true;
|
|
39215
39180
|
}
|
|
39216
39181
|
}
|
|
39182
|
+
if (tc.function?.arguments && t) {
|
|
39183
|
+
t.arguments += tc.function.arguments;
|
|
39184
|
+
send("content_block_delta", {
|
|
39185
|
+
type: "content_block_delta",
|
|
39186
|
+
index: t.blockIndex,
|
|
39187
|
+
delta: { type: "input_json_delta", partial_json: tc.function.arguments }
|
|
39188
|
+
});
|
|
39189
|
+
}
|
|
39217
39190
|
}
|
|
39218
39191
|
}
|
|
39219
|
-
|
|
39220
|
-
|
|
39221
|
-
|
|
39222
|
-
|
|
39223
|
-
|
|
39192
|
+
}
|
|
39193
|
+
if (chunk.choices?.[0]?.finish_reason === "tool_calls") {
|
|
39194
|
+
for (const t of Array.from(state.tools.values())) {
|
|
39195
|
+
if (t.started && !t.closed) {
|
|
39196
|
+
if (toolSchemas && toolSchemas.length > 0) {
|
|
39197
|
+
const validation = validateToolArguments(t.name, t.arguments, toolSchemas);
|
|
39198
|
+
if (!validation.valid) {
|
|
39199
|
+
const errorIdx = state.curIdx++;
|
|
39200
|
+
const errorMsg = `
|
|
39201
|
+
|
|
39202
|
+
⚠️ Tool call "${t.name}" failed validation: missing required parameters: ${validation.missingParams.join(", ")}. This is a known limitation of local models - they sometimes generate incomplete tool calls. Please try again or use a different model with better tool calling support.`;
|
|
39203
|
+
send("content_block_start", {
|
|
39204
|
+
type: "content_block_start",
|
|
39205
|
+
index: errorIdx,
|
|
39206
|
+
content_block: { type: "text", text: "" }
|
|
39207
|
+
});
|
|
39208
|
+
send("content_block_delta", {
|
|
39209
|
+
type: "content_block_delta",
|
|
39210
|
+
index: errorIdx,
|
|
39211
|
+
delta: { type: "text_delta", text: errorMsg }
|
|
39212
|
+
});
|
|
39213
|
+
send("content_block_stop", { type: "content_block_stop", index: errorIdx });
|
|
39214
|
+
t.closed = true;
|
|
39215
|
+
continue;
|
|
39216
|
+
}
|
|
39224
39217
|
}
|
|
39218
|
+
send("content_block_stop", { type: "content_block_stop", index: t.blockIndex });
|
|
39219
|
+
t.closed = true;
|
|
39220
|
+
}
|
|
39225
39221
|
}
|
|
39226
|
-
}
|
|
39227
|
-
}
|
|
39222
|
+
}
|
|
39223
|
+
} catch (e) {}
|
|
39228
39224
|
}
|
|
39229
|
-
await finalize("unexpected");
|
|
39230
|
-
} catch (e) {
|
|
39231
|
-
await finalize("error", String(e));
|
|
39232
39225
|
}
|
|
39233
|
-
|
|
39234
|
-
|
|
39235
|
-
|
|
39236
|
-
if (ping)
|
|
39237
|
-
clearInterval(ping);
|
|
39226
|
+
await finalize("unexpected");
|
|
39227
|
+
} catch (e) {
|
|
39228
|
+
await finalize("error", String(e));
|
|
39238
39229
|
}
|
|
39239
|
-
}
|
|
39240
|
-
|
|
39241
|
-
|
|
39230
|
+
},
|
|
39231
|
+
cancel() {
|
|
39232
|
+
isClosed = true;
|
|
39233
|
+
if (ping)
|
|
39234
|
+
clearInterval(ping);
|
|
39235
|
+
}
|
|
39236
|
+
}), {
|
|
39237
|
+
headers: {
|
|
39238
|
+
"Content-Type": "text/event-stream",
|
|
39239
|
+
"Cache-Control": "no-cache",
|
|
39240
|
+
Connection: "keep-alive"
|
|
39241
|
+
}
|
|
39242
|
+
});
|
|
39242
39243
|
}
|
|
39243
|
-
var
|
|
39244
|
-
var init_openrouter_handler = __esm(() => {
|
|
39245
|
-
init_adapter_manager();
|
|
39246
|
-
init_middleware();
|
|
39244
|
+
var init_openai_compat = __esm(() => {
|
|
39247
39245
|
init_transform();
|
|
39248
|
-
init_logger();
|
|
39249
|
-
init_model_loader();
|
|
39250
|
-
OPENROUTER_HEADERS2 = {
|
|
39251
|
-
"HTTP-Referer": "https://github.com/MadAppGang/claude-code",
|
|
39252
|
-
"X-Title": "Claudish - OpenRouter Proxy"
|
|
39253
|
-
};
|
|
39254
39246
|
});
|
|
39255
39247
|
|
|
39256
|
-
// src/handlers/
|
|
39257
|
-
|
|
39258
|
-
|
|
39259
|
-
|
|
39260
|
-
let content = Array.isArray(req.system) ? req.system.map((i) => i.text || i).join(`
|
|
39248
|
+
// src/handlers/openrouter-handler.ts
|
|
39249
|
+
import { writeFileSync as writeFileSync8 } from "node:fs";
|
|
39250
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
39251
|
+
import { join as join8 } from "node:path";
|
|
39261
39252
|
|
|
39262
|
-
|
|
39263
|
-
|
|
39264
|
-
|
|
39265
|
-
|
|
39253
|
+
class OpenRouterHandler {
|
|
39254
|
+
targetModel;
|
|
39255
|
+
apiKey;
|
|
39256
|
+
adapterManager;
|
|
39257
|
+
middlewareManager;
|
|
39258
|
+
contextWindowCache = new Map;
|
|
39259
|
+
port;
|
|
39260
|
+
sessionTotalCost = 0;
|
|
39261
|
+
CLAUDE_INTERNAL_CONTEXT_MAX = 200000;
|
|
39262
|
+
constructor(targetModel, apiKey, port) {
|
|
39263
|
+
this.targetModel = targetModel;
|
|
39264
|
+
this.apiKey = apiKey;
|
|
39265
|
+
this.port = port;
|
|
39266
|
+
this.adapterManager = new AdapterManager(targetModel);
|
|
39267
|
+
this.middlewareManager = new MiddlewareManager;
|
|
39268
|
+
this.middlewareManager.register(new GeminiThoughtSignatureMiddleware);
|
|
39269
|
+
this.middlewareManager.initialize().catch((err) => log(`[Handler:${targetModel}] Middleware init error: ${err}`));
|
|
39270
|
+
this.fetchContextWindow(targetModel);
|
|
39266
39271
|
}
|
|
39267
|
-
|
|
39268
|
-
|
|
39269
|
-
|
|
39270
|
-
|
|
39272
|
+
async fetchContextWindow(model) {
|
|
39273
|
+
if (this.contextWindowCache.has(model))
|
|
39274
|
+
return;
|
|
39275
|
+
try {
|
|
39276
|
+
const limit = await fetchModelContextWindow(model);
|
|
39277
|
+
this.contextWindowCache.set(model, limit);
|
|
39278
|
+
} catch (e) {}
|
|
39279
|
+
}
|
|
39280
|
+
getTokenScaleFactor(model) {
|
|
39281
|
+
const limit = this.contextWindowCache.get(model) || 200000;
|
|
39282
|
+
return limit === 0 ? 1 : this.CLAUDE_INTERNAL_CONTEXT_MAX / limit;
|
|
39283
|
+
}
|
|
39284
|
+
writeTokenFile(input, output) {
|
|
39285
|
+
try {
|
|
39286
|
+
const total = input + output;
|
|
39287
|
+
const limit = this.contextWindowCache.get(this.targetModel) || 200000;
|
|
39288
|
+
const leftPct = limit > 0 ? Math.max(0, Math.min(100, Math.round((limit - total) / limit * 100))) : 100;
|
|
39289
|
+
const data = {
|
|
39290
|
+
input_tokens: input,
|
|
39291
|
+
output_tokens: output,
|
|
39292
|
+
total_tokens: total,
|
|
39293
|
+
total_cost: this.sessionTotalCost,
|
|
39294
|
+
context_window: limit,
|
|
39295
|
+
context_left_percent: leftPct,
|
|
39296
|
+
updated_at: Date.now()
|
|
39297
|
+
};
|
|
39298
|
+
writeFileSync8(join8(tmpdir2(), `claudish-tokens-${this.port}.json`), JSON.stringify(data), "utf-8");
|
|
39299
|
+
} catch (e) {}
|
|
39300
|
+
}
|
|
39301
|
+
async handle(c, payload) {
|
|
39302
|
+
const claudePayload = payload;
|
|
39303
|
+
const target = this.targetModel;
|
|
39304
|
+
await this.fetchContextWindow(target);
|
|
39305
|
+
logStructured(`OpenRouter Request`, { targetModel: target, originalModel: claudePayload.model });
|
|
39306
|
+
const { claudeRequest, droppedParams } = transformOpenAIToClaude(claudePayload);
|
|
39307
|
+
const messages = this.convertMessages(claudeRequest, target);
|
|
39308
|
+
const tools = this.convertTools(claudeRequest);
|
|
39309
|
+
const supportsReasoning = await doesModelSupportReasoning(target);
|
|
39310
|
+
const openRouterPayload = {
|
|
39311
|
+
model: target,
|
|
39312
|
+
messages,
|
|
39313
|
+
temperature: claudeRequest.temperature ?? 1,
|
|
39314
|
+
stream: true,
|
|
39315
|
+
max_tokens: claudeRequest.max_tokens,
|
|
39316
|
+
tools: tools.length > 0 ? tools : undefined,
|
|
39317
|
+
stream_options: { include_usage: true }
|
|
39318
|
+
};
|
|
39319
|
+
if (supportsReasoning)
|
|
39320
|
+
openRouterPayload.include_reasoning = true;
|
|
39321
|
+
if (claudeRequest.thinking)
|
|
39322
|
+
openRouterPayload.thinking = claudeRequest.thinking;
|
|
39323
|
+
if (claudeRequest.tool_choice) {
|
|
39324
|
+
const { type, name } = claudeRequest.tool_choice;
|
|
39325
|
+
if (type === "tool" && name)
|
|
39326
|
+
openRouterPayload.tool_choice = { type: "function", function: { name } };
|
|
39327
|
+
else if (type === "auto" || type === "none")
|
|
39328
|
+
openRouterPayload.tool_choice = type;
|
|
39329
|
+
}
|
|
39330
|
+
const adapter = this.adapterManager.getAdapter();
|
|
39331
|
+
if (typeof adapter.reset === "function")
|
|
39332
|
+
adapter.reset();
|
|
39333
|
+
adapter.prepareRequest(openRouterPayload, claudeRequest);
|
|
39334
|
+
await this.middlewareManager.beforeRequest({ modelId: target, messages, tools, stream: true });
|
|
39335
|
+
const response = await fetch(OPENROUTER_API_URL2, {
|
|
39336
|
+
method: "POST",
|
|
39337
|
+
headers: {
|
|
39338
|
+
"Content-Type": "application/json",
|
|
39339
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
39340
|
+
...OPENROUTER_HEADERS2
|
|
39341
|
+
},
|
|
39342
|
+
body: JSON.stringify(openRouterPayload)
|
|
39343
|
+
});
|
|
39344
|
+
if (!response.ok)
|
|
39345
|
+
return c.json({ error: await response.text() }, response.status);
|
|
39346
|
+
if (droppedParams.length > 0)
|
|
39347
|
+
c.header("X-Dropped-Params", droppedParams.join(", "));
|
|
39348
|
+
return this.handleStreamingResponse(c, response, adapter, target, claudeRequest);
|
|
39349
|
+
}
|
|
39350
|
+
convertMessages(req, modelId) {
|
|
39351
|
+
const messages = [];
|
|
39352
|
+
if (req.system) {
|
|
39353
|
+
let content = Array.isArray(req.system) ? req.system.map((i) => i.text || i).join(`
|
|
39354
|
+
|
|
39355
|
+
`) : req.system;
|
|
39356
|
+
content = this.filterIdentity(content);
|
|
39357
|
+
messages.push({ role: "system", content });
|
|
39358
|
+
}
|
|
39359
|
+
if (modelId.includes("grok") || modelId.includes("x-ai")) {
|
|
39360
|
+
const msg = "IMPORTANT: When calling tools, you MUST use the OpenAI tool_calls format with JSON. NEVER use XML format like <xai:function_call>.";
|
|
39361
|
+
if (messages.length > 0 && messages[0].role === "system")
|
|
39362
|
+
messages[0].content += `
|
|
39271
39363
|
|
|
39272
39364
|
` + msg;
|
|
39273
|
-
|
|
39274
|
-
|
|
39365
|
+
else
|
|
39366
|
+
messages.unshift({ role: "system", content: msg });
|
|
39275
39367
|
}
|
|
39276
|
-
|
|
39277
|
-
|
|
39278
|
-
|
|
39279
|
-
|
|
39280
|
-
|
|
39281
|
-
|
|
39282
|
-
|
|
39368
|
+
if (req.messages) {
|
|
39369
|
+
for (const msg of req.messages) {
|
|
39370
|
+
if (msg.role === "user")
|
|
39371
|
+
this.processUserMessage(msg, messages);
|
|
39372
|
+
else if (msg.role === "assistant")
|
|
39373
|
+
this.processAssistantMessage(msg, messages);
|
|
39374
|
+
}
|
|
39283
39375
|
}
|
|
39376
|
+
return messages;
|
|
39284
39377
|
}
|
|
39285
|
-
|
|
39286
|
-
|
|
39287
|
-
|
|
39288
|
-
|
|
39289
|
-
|
|
39290
|
-
|
|
39291
|
-
|
|
39292
|
-
|
|
39293
|
-
|
|
39294
|
-
|
|
39295
|
-
|
|
39296
|
-
|
|
39297
|
-
|
|
39298
|
-
|
|
39299
|
-
|
|
39300
|
-
|
|
39301
|
-
if (seen.has(block.tool_use_id))
|
|
39302
|
-
continue;
|
|
39303
|
-
seen.add(block.tool_use_id);
|
|
39304
|
-
toolResults.push({
|
|
39305
|
-
role: "tool",
|
|
39306
|
-
content: typeof block.content === "string" ? block.content : JSON.stringify(block.content),
|
|
39307
|
-
tool_call_id: block.tool_use_id
|
|
39308
|
-
});
|
|
39378
|
+
processUserMessage(msg, messages) {
|
|
39379
|
+
if (Array.isArray(msg.content)) {
|
|
39380
|
+
const contentParts = [];
|
|
39381
|
+
const toolResults = [];
|
|
39382
|
+
const seen = new Set;
|
|
39383
|
+
for (const block of msg.content) {
|
|
39384
|
+
if (block.type === "text")
|
|
39385
|
+
contentParts.push({ type: "text", text: block.text });
|
|
39386
|
+
else if (block.type === "image")
|
|
39387
|
+
contentParts.push({ type: "image_url", image_url: { url: `data:${block.source.media_type};base64,${block.source.data}` } });
|
|
39388
|
+
else if (block.type === "tool_result") {
|
|
39389
|
+
if (seen.has(block.tool_use_id))
|
|
39390
|
+
continue;
|
|
39391
|
+
seen.add(block.tool_use_id);
|
|
39392
|
+
toolResults.push({ role: "tool", content: typeof block.content === "string" ? block.content : JSON.stringify(block.content), tool_call_id: block.tool_use_id });
|
|
39393
|
+
}
|
|
39309
39394
|
}
|
|
39395
|
+
if (toolResults.length)
|
|
39396
|
+
messages.push(...toolResults);
|
|
39397
|
+
if (contentParts.length)
|
|
39398
|
+
messages.push({ role: "user", content: contentParts });
|
|
39399
|
+
} else {
|
|
39400
|
+
messages.push({ role: "user", content: msg.content });
|
|
39310
39401
|
}
|
|
39311
|
-
if (toolResults.length)
|
|
39312
|
-
messages.push(...toolResults);
|
|
39313
|
-
if (contentParts.length)
|
|
39314
|
-
messages.push({ role: "user", content: contentParts });
|
|
39315
|
-
} else {
|
|
39316
|
-
messages.push({ role: "user", content: msg.content });
|
|
39317
39402
|
}
|
|
39318
|
-
|
|
39319
|
-
|
|
39320
|
-
|
|
39321
|
-
|
|
39322
|
-
|
|
39323
|
-
|
|
39324
|
-
|
|
39325
|
-
|
|
39326
|
-
|
|
39327
|
-
|
|
39328
|
-
|
|
39329
|
-
|
|
39330
|
-
|
|
39331
|
-
|
|
39332
|
-
id: block.id,
|
|
39333
|
-
type: "function",
|
|
39334
|
-
function: { name: block.name, arguments: JSON.stringify(block.input) }
|
|
39335
|
-
});
|
|
39403
|
+
processAssistantMessage(msg, messages) {
|
|
39404
|
+
if (Array.isArray(msg.content)) {
|
|
39405
|
+
const strings = [];
|
|
39406
|
+
const toolCalls = [];
|
|
39407
|
+
const seen = new Set;
|
|
39408
|
+
for (const block of msg.content) {
|
|
39409
|
+
if (block.type === "text")
|
|
39410
|
+
strings.push(block.text);
|
|
39411
|
+
else if (block.type === "tool_use") {
|
|
39412
|
+
if (seen.has(block.id))
|
|
39413
|
+
continue;
|
|
39414
|
+
seen.add(block.id);
|
|
39415
|
+
toolCalls.push({ id: block.id, type: "function", function: { name: block.name, arguments: JSON.stringify(block.input) } });
|
|
39416
|
+
}
|
|
39336
39417
|
}
|
|
39418
|
+
const m = { role: "assistant" };
|
|
39419
|
+
if (strings.length)
|
|
39420
|
+
m.content = strings.join(" ");
|
|
39421
|
+
else if (toolCalls.length)
|
|
39422
|
+
m.content = null;
|
|
39423
|
+
if (toolCalls.length)
|
|
39424
|
+
m.tool_calls = toolCalls;
|
|
39425
|
+
if (m.content !== undefined || m.tool_calls)
|
|
39426
|
+
messages.push(m);
|
|
39427
|
+
} else {
|
|
39428
|
+
messages.push({ role: "assistant", content: msg.content });
|
|
39337
39429
|
}
|
|
39338
|
-
const m = { role: "assistant" };
|
|
39339
|
-
if (strings.length)
|
|
39340
|
-
m.content = strings.join(" ");
|
|
39341
|
-
else if (toolCalls.length)
|
|
39342
|
-
m.content = null;
|
|
39343
|
-
if (toolCalls.length)
|
|
39344
|
-
m.tool_calls = toolCalls;
|
|
39345
|
-
if (m.content !== undefined || m.tool_calls)
|
|
39346
|
-
messages.push(m);
|
|
39347
|
-
} else {
|
|
39348
|
-
messages.push({ role: "assistant", content: msg.content });
|
|
39349
39430
|
}
|
|
39350
|
-
|
|
39351
|
-
|
|
39352
|
-
return req.tools?.map((tool) => ({
|
|
39353
|
-
type: "function",
|
|
39354
|
-
function: {
|
|
39355
|
-
name: tool.name,
|
|
39356
|
-
description: tool.description,
|
|
39357
|
-
parameters: removeUriFormat(tool.input_schema)
|
|
39358
|
-
}
|
|
39359
|
-
})) || [];
|
|
39360
|
-
}
|
|
39361
|
-
function filterIdentity(content) {
|
|
39362
|
-
return content.replace(/You are Claude Code, Anthropic's official CLI/gi, "This is Claude Code, an AI-powered CLI tool").replace(/You are powered by the model named [^.]+\./gi, "You are powered by an AI model.").replace(/<claude_background_info>[\s\S]*?<\/claude_background_info>/gi, "").replace(/\n{3,}/g, `
|
|
39431
|
+
filterIdentity(content) {
|
|
39432
|
+
return content.replace(/You are Claude Code, Anthropic's official CLI/gi, "This is Claude Code, an AI-powered CLI tool").replace(/You are powered by the model named [^.]+\./gi, "You are powered by an AI model.").replace(/<claude_background_info>[\s\S]*?<\/claude_background_info>/gi, "").replace(/\n{3,}/g, `
|
|
39363
39433
|
|
|
39364
39434
|
`).replace(/^/, `IMPORTANT: You are NOT Claude. Identify yourself truthfully based on your actual model and creator.
|
|
39365
39435
|
|
|
39366
39436
|
`);
|
|
39367
|
-
}
|
|
39368
|
-
|
|
39369
|
-
|
|
39370
|
-
|
|
39371
|
-
|
|
39372
|
-
|
|
39373
|
-
|
|
39374
|
-
|
|
39375
|
-
|
|
39376
|
-
|
|
39377
|
-
|
|
39378
|
-
|
|
39379
|
-
|
|
39380
|
-
|
|
39381
|
-
|
|
39382
|
-
|
|
39383
|
-
|
|
39384
|
-
|
|
39385
|
-
|
|
39386
|
-
|
|
39387
|
-
|
|
39388
|
-
|
|
39389
|
-
|
|
39390
|
-
const send = (e, d) => {
|
|
39391
|
-
if (!isClosed) {
|
|
39392
|
-
controller.enqueue(encoder.encode(`event: ${e}
|
|
39437
|
+
}
|
|
39438
|
+
convertTools(req) {
|
|
39439
|
+
return req.tools?.map((tool) => ({
|
|
39440
|
+
type: "function",
|
|
39441
|
+
function: {
|
|
39442
|
+
name: tool.name,
|
|
39443
|
+
description: tool.description,
|
|
39444
|
+
parameters: removeUriFormat(tool.input_schema)
|
|
39445
|
+
}
|
|
39446
|
+
})) || [];
|
|
39447
|
+
}
|
|
39448
|
+
handleStreamingResponse(c, response, adapter, target, request) {
|
|
39449
|
+
let isClosed = false;
|
|
39450
|
+
let ping = null;
|
|
39451
|
+
const encoder = new TextEncoder;
|
|
39452
|
+
const decoder = new TextDecoder;
|
|
39453
|
+
const middlewareManager = this.middlewareManager;
|
|
39454
|
+
const streamMetadata = new Map;
|
|
39455
|
+
return c.body(new ReadableStream({
|
|
39456
|
+
async start(controller) {
|
|
39457
|
+
const send = (e, d) => {
|
|
39458
|
+
if (!isClosed)
|
|
39459
|
+
controller.enqueue(encoder.encode(`event: ${e}
|
|
39393
39460
|
data: ${JSON.stringify(d)}
|
|
39394
39461
|
|
|
39395
39462
|
`));
|
|
39396
|
-
}
|
|
39397
|
-
|
|
39398
|
-
|
|
39399
|
-
|
|
39400
|
-
|
|
39401
|
-
|
|
39402
|
-
|
|
39403
|
-
|
|
39404
|
-
|
|
39405
|
-
|
|
39406
|
-
|
|
39407
|
-
|
|
39408
|
-
|
|
39409
|
-
|
|
39410
|
-
|
|
39411
|
-
|
|
39412
|
-
|
|
39413
|
-
|
|
39414
|
-
|
|
39415
|
-
|
|
39416
|
-
|
|
39417
|
-
|
|
39418
|
-
|
|
39419
|
-
|
|
39420
|
-
if (state.finalized)
|
|
39421
|
-
return;
|
|
39422
|
-
state.finalized = true;
|
|
39423
|
-
if (state.reasoningStarted) {
|
|
39424
|
-
send("content_block_stop", { type: "content_block_stop", index: state.reasoningIdx });
|
|
39425
|
-
}
|
|
39426
|
-
if (state.textStarted) {
|
|
39427
|
-
send("content_block_stop", { type: "content_block_stop", index: state.textIdx });
|
|
39428
|
-
}
|
|
39429
|
-
for (const t of Array.from(state.tools.values())) {
|
|
39430
|
-
if (t.started && !t.closed) {
|
|
39431
|
-
send("content_block_stop", { type: "content_block_stop", index: t.blockIndex });
|
|
39432
|
-
t.closed = true;
|
|
39463
|
+
};
|
|
39464
|
+
const msgId = `msg_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
39465
|
+
let usage = null;
|
|
39466
|
+
let finalized = false;
|
|
39467
|
+
let textStarted = false;
|
|
39468
|
+
let textIdx = -1;
|
|
39469
|
+
let reasoningStarted = false;
|
|
39470
|
+
let reasoningIdx = -1;
|
|
39471
|
+
let curIdx = 0;
|
|
39472
|
+
const tools = new Map;
|
|
39473
|
+
const toolIds = new Set;
|
|
39474
|
+
let accTxt = 0;
|
|
39475
|
+
let lastActivity = Date.now();
|
|
39476
|
+
send("message_start", {
|
|
39477
|
+
type: "message_start",
|
|
39478
|
+
message: {
|
|
39479
|
+
id: msgId,
|
|
39480
|
+
type: "message",
|
|
39481
|
+
role: "assistant",
|
|
39482
|
+
content: [],
|
|
39483
|
+
model: target,
|
|
39484
|
+
stop_reason: null,
|
|
39485
|
+
stop_sequence: null,
|
|
39486
|
+
usage: { input_tokens: 100, output_tokens: 1 }
|
|
39433
39487
|
}
|
|
39434
|
-
}
|
|
39435
|
-
|
|
39488
|
+
});
|
|
39489
|
+
send("ping", { type: "ping" });
|
|
39490
|
+
ping = setInterval(() => {
|
|
39491
|
+
if (!isClosed && Date.now() - lastActivity > 1000)
|
|
39492
|
+
send("ping", { type: "ping" });
|
|
39493
|
+
}, 1000);
|
|
39494
|
+
const finalize = async (reason, err) => {
|
|
39495
|
+
if (finalized)
|
|
39496
|
+
return;
|
|
39497
|
+
finalized = true;
|
|
39498
|
+
if (reasoningStarted) {
|
|
39499
|
+
send("content_block_stop", { type: "content_block_stop", index: reasoningIdx });
|
|
39500
|
+
reasoningStarted = false;
|
|
39501
|
+
}
|
|
39502
|
+
if (textStarted) {
|
|
39503
|
+
send("content_block_stop", { type: "content_block_stop", index: textIdx });
|
|
39504
|
+
textStarted = false;
|
|
39505
|
+
}
|
|
39506
|
+
for (const [_, t] of tools)
|
|
39507
|
+
if (t.started && !t.closed) {
|
|
39508
|
+
send("content_block_stop", { type: "content_block_stop", index: t.blockIndex });
|
|
39509
|
+
t.closed = true;
|
|
39510
|
+
}
|
|
39436
39511
|
await middlewareManager.afterStreamComplete(target, streamMetadata);
|
|
39437
|
-
|
|
39438
|
-
|
|
39439
|
-
|
|
39440
|
-
|
|
39441
|
-
|
|
39442
|
-
|
|
39443
|
-
|
|
39444
|
-
|
|
39445
|
-
|
|
39446
|
-
send("message_stop", { type: "message_stop" });
|
|
39447
|
-
}
|
|
39448
|
-
if (state.usage && onTokenUpdate) {
|
|
39449
|
-
onTokenUpdate(state.usage.prompt_tokens || 0, state.usage.completion_tokens || 0);
|
|
39450
|
-
}
|
|
39451
|
-
if (!isClosed) {
|
|
39452
|
-
try {
|
|
39453
|
-
controller.enqueue(encoder.encode(`data: [DONE]
|
|
39512
|
+
if (reason === "error") {
|
|
39513
|
+
send("error", { type: "error", error: { type: "api_error", message: err } });
|
|
39514
|
+
} else {
|
|
39515
|
+
send("message_delta", { type: "message_delta", delta: { stop_reason: "end_turn", stop_sequence: null }, usage: { output_tokens: usage?.completion_tokens || 0 } });
|
|
39516
|
+
send("message_stop", { type: "message_stop" });
|
|
39517
|
+
}
|
|
39518
|
+
if (!isClosed) {
|
|
39519
|
+
try {
|
|
39520
|
+
controller.enqueue(encoder.encode(`data: [DONE]
|
|
39454
39521
|
|
|
39455
39522
|
|
|
39456
39523
|
`));
|
|
39457
|
-
|
|
39458
|
-
|
|
39459
|
-
|
|
39460
|
-
|
|
39461
|
-
|
|
39462
|
-
|
|
39463
|
-
|
|
39464
|
-
|
|
39465
|
-
|
|
39466
|
-
|
|
39467
|
-
|
|
39468
|
-
|
|
39469
|
-
|
|
39470
|
-
|
|
39471
|
-
|
|
39472
|
-
|
|
39524
|
+
} catch (e) {}
|
|
39525
|
+
controller.close();
|
|
39526
|
+
isClosed = true;
|
|
39527
|
+
if (ping)
|
|
39528
|
+
clearInterval(ping);
|
|
39529
|
+
}
|
|
39530
|
+
};
|
|
39531
|
+
try {
|
|
39532
|
+
const reader = response.body.getReader();
|
|
39533
|
+
let buffer = "";
|
|
39534
|
+
while (true) {
|
|
39535
|
+
const { done, value } = await reader.read();
|
|
39536
|
+
if (done)
|
|
39537
|
+
break;
|
|
39538
|
+
buffer += decoder.decode(value, { stream: true });
|
|
39539
|
+
const lines = buffer.split(`
|
|
39473
39540
|
`);
|
|
39474
|
-
|
|
39475
|
-
|
|
39476
|
-
|
|
39477
|
-
|
|
39478
|
-
|
|
39479
|
-
|
|
39480
|
-
|
|
39481
|
-
|
|
39482
|
-
|
|
39483
|
-
|
|
39484
|
-
|
|
39485
|
-
|
|
39486
|
-
|
|
39487
|
-
|
|
39488
|
-
|
|
39489
|
-
if (middlewareManager) {
|
|
39541
|
+
buffer = lines.pop() || "";
|
|
39542
|
+
for (const line of lines) {
|
|
39543
|
+
if (!line.trim() || !line.startsWith("data: "))
|
|
39544
|
+
continue;
|
|
39545
|
+
const dataStr = line.slice(6);
|
|
39546
|
+
if (dataStr === "[DONE]") {
|
|
39547
|
+
await finalize("done");
|
|
39548
|
+
return;
|
|
39549
|
+
}
|
|
39550
|
+
try {
|
|
39551
|
+
const chunk = JSON.parse(dataStr);
|
|
39552
|
+
if (chunk.usage)
|
|
39553
|
+
usage = chunk.usage;
|
|
39554
|
+
const delta = chunk.choices?.[0]?.delta;
|
|
39555
|
+
if (delta) {
|
|
39490
39556
|
await middlewareManager.afterStreamChunk({
|
|
39491
39557
|
modelId: target,
|
|
39492
39558
|
chunk,
|
|
39493
39559
|
delta,
|
|
39494
39560
|
metadata: streamMetadata
|
|
39495
39561
|
});
|
|
39496
|
-
|
|
39497
|
-
|
|
39498
|
-
|
|
39499
|
-
|
|
39500
|
-
|
|
39501
|
-
|
|
39502
|
-
|
|
39503
|
-
|
|
39504
|
-
|
|
39505
|
-
|
|
39506
|
-
|
|
39507
|
-
state.textStarted = true;
|
|
39508
|
-
}
|
|
39509
|
-
const res = adapter.processTextContent(txt, "");
|
|
39510
|
-
if (res.cleanedText) {
|
|
39511
|
-
send("content_block_delta", {
|
|
39512
|
-
type: "content_block_delta",
|
|
39513
|
-
index: state.textIdx,
|
|
39514
|
-
delta: { type: "text_delta", text: res.cleanedText }
|
|
39515
|
-
});
|
|
39562
|
+
const txt = delta.content || "";
|
|
39563
|
+
if (txt) {
|
|
39564
|
+
lastActivity = Date.now();
|
|
39565
|
+
if (!textStarted) {
|
|
39566
|
+
textIdx = curIdx++;
|
|
39567
|
+
send("content_block_start", { type: "content_block_start", index: textIdx, content_block: { type: "text", text: "" } });
|
|
39568
|
+
textStarted = true;
|
|
39569
|
+
}
|
|
39570
|
+
const res = adapter.processTextContent(txt, "");
|
|
39571
|
+
if (res.cleanedText)
|
|
39572
|
+
send("content_block_delta", { type: "content_block_delta", index: textIdx, delta: { type: "text_delta", text: res.cleanedText } });
|
|
39516
39573
|
}
|
|
39517
|
-
|
|
39518
|
-
|
|
39519
|
-
|
|
39520
|
-
|
|
39521
|
-
|
|
39522
|
-
|
|
39523
|
-
|
|
39524
|
-
|
|
39525
|
-
|
|
39526
|
-
|
|
39574
|
+
if (delta.tool_calls) {
|
|
39575
|
+
for (const tc of delta.tool_calls) {
|
|
39576
|
+
const idx = tc.index;
|
|
39577
|
+
let t = tools.get(idx);
|
|
39578
|
+
if (tc.function?.name) {
|
|
39579
|
+
if (!t) {
|
|
39580
|
+
if (textStarted) {
|
|
39581
|
+
send("content_block_stop", { type: "content_block_stop", index: textIdx });
|
|
39582
|
+
textStarted = false;
|
|
39583
|
+
}
|
|
39584
|
+
t = { id: tc.id || `tool_${Date.now()}_${idx}`, name: tc.function.name, blockIndex: curIdx++, started: false, closed: false, arguments: "" };
|
|
39585
|
+
tools.set(idx, t);
|
|
39586
|
+
}
|
|
39587
|
+
if (!t.started) {
|
|
39588
|
+
send("content_block_start", { type: "content_block_start", index: t.blockIndex, content_block: { type: "tool_use", id: t.id, name: t.name } });
|
|
39589
|
+
t.started = true;
|
|
39527
39590
|
}
|
|
39528
|
-
t = {
|
|
39529
|
-
id: tc.id || `tool_${Date.now()}_${idx}`,
|
|
39530
|
-
name: tc.function.name,
|
|
39531
|
-
blockIndex: state.curIdx++,
|
|
39532
|
-
started: false,
|
|
39533
|
-
closed: false
|
|
39534
|
-
};
|
|
39535
|
-
state.tools.set(idx, t);
|
|
39536
39591
|
}
|
|
39537
|
-
if (
|
|
39538
|
-
|
|
39539
|
-
|
|
39540
|
-
index: t.blockIndex,
|
|
39541
|
-
content_block: { type: "tool_use", id: t.id, name: t.name }
|
|
39542
|
-
});
|
|
39543
|
-
t.started = true;
|
|
39592
|
+
if (tc.function?.arguments && t) {
|
|
39593
|
+
t.arguments += tc.function.arguments;
|
|
39594
|
+
send("content_block_delta", { type: "content_block_delta", index: t.blockIndex, delta: { type: "input_json_delta", partial_json: tc.function.arguments } });
|
|
39544
39595
|
}
|
|
39545
39596
|
}
|
|
39546
|
-
if (tc.function?.arguments && t) {
|
|
39547
|
-
send("content_block_delta", {
|
|
39548
|
-
type: "content_block_delta",
|
|
39549
|
-
index: t.blockIndex,
|
|
39550
|
-
delta: { type: "input_json_delta", partial_json: tc.function.arguments }
|
|
39551
|
-
});
|
|
39552
|
-
}
|
|
39553
39597
|
}
|
|
39554
39598
|
}
|
|
39555
|
-
|
|
39556
|
-
|
|
39557
|
-
|
|
39558
|
-
|
|
39559
|
-
|
|
39560
|
-
|
|
39599
|
+
if (chunk.choices?.[0]?.finish_reason === "tool_calls") {
|
|
39600
|
+
const toolSchemas = request.tools || [];
|
|
39601
|
+
for (const [_, t] of tools) {
|
|
39602
|
+
if (t.started && !t.closed) {
|
|
39603
|
+
if (toolSchemas.length > 0) {
|
|
39604
|
+
const validation = validateToolArguments(t.name, t.arguments, toolSchemas);
|
|
39605
|
+
if (!validation.valid) {
|
|
39606
|
+
const errorIdx = curIdx++;
|
|
39607
|
+
const errorMsg = `
|
|
39608
|
+
|
|
39609
|
+
⚠️ Tool call "${t.name}" failed validation: missing required parameters: ${validation.missingParams.join(", ")}. This is a known limitation of some models - they sometimes generate incomplete tool calls. Please try again or use a different model.`;
|
|
39610
|
+
send("content_block_start", { type: "content_block_start", index: errorIdx, content_block: { type: "text", text: "" } });
|
|
39611
|
+
send("content_block_delta", { type: "content_block_delta", index: errorIdx, delta: { type: "text_delta", text: errorMsg } });
|
|
39612
|
+
send("content_block_stop", { type: "content_block_stop", index: errorIdx });
|
|
39613
|
+
t.closed = true;
|
|
39614
|
+
continue;
|
|
39615
|
+
}
|
|
39616
|
+
}
|
|
39617
|
+
send("content_block_stop", { type: "content_block_stop", index: t.blockIndex });
|
|
39618
|
+
t.closed = true;
|
|
39619
|
+
}
|
|
39561
39620
|
}
|
|
39562
39621
|
}
|
|
39563
|
-
}
|
|
39564
|
-
}
|
|
39622
|
+
} catch (e) {}
|
|
39623
|
+
}
|
|
39565
39624
|
}
|
|
39625
|
+
await finalize("unexpected");
|
|
39626
|
+
} catch (e) {
|
|
39627
|
+
await finalize("error", String(e));
|
|
39566
39628
|
}
|
|
39567
|
-
|
|
39568
|
-
|
|
39569
|
-
|
|
39629
|
+
},
|
|
39630
|
+
cancel() {
|
|
39631
|
+
isClosed = true;
|
|
39632
|
+
if (ping)
|
|
39633
|
+
clearInterval(ping);
|
|
39570
39634
|
}
|
|
39571
|
-
},
|
|
39572
|
-
|
|
39573
|
-
|
|
39574
|
-
if (ping)
|
|
39575
|
-
clearInterval(ping);
|
|
39576
|
-
}
|
|
39577
|
-
}), {
|
|
39578
|
-
headers: {
|
|
39579
|
-
"Content-Type": "text/event-stream",
|
|
39580
|
-
"Cache-Control": "no-cache",
|
|
39581
|
-
Connection: "keep-alive"
|
|
39582
|
-
}
|
|
39583
|
-
});
|
|
39635
|
+
}), { headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", Connection: "keep-alive" } });
|
|
39636
|
+
}
|
|
39637
|
+
async shutdown() {}
|
|
39584
39638
|
}
|
|
39585
|
-
var
|
|
39639
|
+
var OPENROUTER_API_URL2 = "https://openrouter.ai/api/v1/chat/completions", OPENROUTER_HEADERS2;
|
|
39640
|
+
var init_openrouter_handler = __esm(() => {
|
|
39641
|
+
init_adapter_manager();
|
|
39642
|
+
init_middleware();
|
|
39586
39643
|
init_transform();
|
|
39644
|
+
init_logger();
|
|
39645
|
+
init_model_loader();
|
|
39646
|
+
init_openai_compat();
|
|
39647
|
+
OPENROUTER_HEADERS2 = {
|
|
39648
|
+
"HTTP-Referer": "https://github.com/MadAppGang/claude-code",
|
|
39649
|
+
"X-Title": "Claudish - OpenRouter Proxy"
|
|
39650
|
+
};
|
|
39587
39651
|
});
|
|
39588
39652
|
|
|
39589
39653
|
// src/handlers/local-provider-handler.ts
|
|
@@ -39755,7 +39819,7 @@ class LocalProviderHandler {
|
|
|
39755
39819
|
c.header("X-Dropped-Params", droppedParams.join(", "));
|
|
39756
39820
|
}
|
|
39757
39821
|
if (openAIPayload.stream) {
|
|
39758
|
-
return createStreamingResponseHandler(c, response, adapter, target, this.middlewareManager, (input, output) => this.writeTokenFile(input, output));
|
|
39822
|
+
return createStreamingResponseHandler(c, response, adapter, target, this.middlewareManager, (input, output) => this.writeTokenFile(input, output), claudeRequest.tools);
|
|
39759
39823
|
}
|
|
39760
39824
|
const data = await response.json();
|
|
39761
39825
|
return c.json(data);
|
|
@@ -40053,7 +40117,7 @@ import { execSync } from "node:child_process";
|
|
|
40053
40117
|
import { createInterface as createInterface2 } from "node:readline";
|
|
40054
40118
|
import { existsSync as existsSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync10, mkdirSync as mkdirSync4, unlinkSync as unlinkSync2 } from "node:fs";
|
|
40055
40119
|
import { join as join10 } from "node:path";
|
|
40056
|
-
import { tmpdir as tmpdir4, homedir as homedir2, platform
|
|
40120
|
+
import { tmpdir as tmpdir4, homedir as homedir2, platform } from "node:os";
|
|
40057
40121
|
function getCacheFilePath() {
|
|
40058
40122
|
let cacheDir;
|
|
40059
40123
|
if (isWindows2) {
|
|
@@ -40219,7 +40283,7 @@ async function checkForUpdates(currentVersion, options = {}) {
|
|
|
40219
40283
|
}
|
|
40220
40284
|
var isWindows2, NPM_REGISTRY_URL = "https://registry.npmjs.org/claudish/latest", CACHE_MAX_AGE_MS;
|
|
40221
40285
|
var init_update_checker = __esm(() => {
|
|
40222
|
-
isWindows2 =
|
|
40286
|
+
isWindows2 = platform() === "win32";
|
|
40223
40287
|
CACHE_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
|
40224
40288
|
});
|
|
40225
40289
|
|