@musistudio/claude-code-router 1.0.62 → 1.0.63
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/README.md +2 -1
- package/README_zh.md +2 -1
- package/dist/cli.js +267 -161
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -534,7 +534,7 @@ A huge thank you to all our sponsors for their generous support!
|
|
|
534
534
|
|
|
535
535
|
- [AIHubmix](https://aihubmix.com/)
|
|
536
536
|
- [BurnCloud](https://ai.burncloud.com)
|
|
537
|
-
- [302.
|
|
537
|
+
- [302.AI](https://share.302.ai/ZGVF9w)
|
|
538
538
|
- @Simon Leischnig
|
|
539
539
|
- [@duanshuaimin](https://github.com/duanshuaimin)
|
|
540
540
|
- [@vrgitadmin](https://github.com/vrgitadmin)
|
|
@@ -620,5 +620,6 @@ A huge thank you to all our sponsors for their generous support!
|
|
|
620
620
|
- @\*\*东
|
|
621
621
|
- @\*落
|
|
622
622
|
- @哆\*k
|
|
623
|
+
- @\*涛
|
|
623
624
|
|
|
624
625
|
(If your name is masked, please contact me via my homepage email to update it with your GitHub username.)
|
package/README_zh.md
CHANGED
|
@@ -480,7 +480,7 @@ jobs:
|
|
|
480
480
|
|
|
481
481
|
- [AIHubmix](https://aihubmix.com/)
|
|
482
482
|
- [BurnCloud](https://ai.burncloud.com)
|
|
483
|
-
- [302.
|
|
483
|
+
- [302.AI](https://share.302.ai/ZGVF9w)
|
|
484
484
|
- @Simon Leischnig
|
|
485
485
|
- [@duanshuaimin](https://github.com/duanshuaimin)
|
|
486
486
|
- [@vrgitadmin](https://github.com/vrgitadmin)
|
|
@@ -566,6 +566,7 @@ jobs:
|
|
|
566
566
|
- @\*\*东
|
|
567
567
|
- @\*落
|
|
568
568
|
- @哆\*k
|
|
569
|
+
- @\*涛
|
|
569
570
|
|
|
570
571
|
(如果您的名字被屏蔽,请通过我的主页电子邮件与我联系,以便使用您的 GitHub 用户名进行更新。)
|
|
571
572
|
|
package/dist/cli.js
CHANGED
|
@@ -1147,7 +1147,7 @@ var require_lib = __commonJS({
|
|
|
1147
1147
|
});
|
|
1148
1148
|
|
|
1149
1149
|
// src/constants.ts
|
|
1150
|
-
var import_node_path, import_node_os, HOME_DIR, CONFIG_FILE, PLUGINS_DIR, PID_FILE, REFERENCE_COUNT_FILE;
|
|
1150
|
+
var import_node_path, import_node_os, HOME_DIR, CONFIG_FILE, PLUGINS_DIR, PID_FILE, REFERENCE_COUNT_FILE, CLAUDE_PROJECTS_DIR;
|
|
1151
1151
|
var init_constants = __esm({
|
|
1152
1152
|
"src/constants.ts"() {
|
|
1153
1153
|
"use strict";
|
|
@@ -1158,6 +1158,7 @@ var init_constants = __esm({
|
|
|
1158
1158
|
PLUGINS_DIR = import_node_path.default.join(HOME_DIR, "plugins");
|
|
1159
1159
|
PID_FILE = import_node_path.default.join(HOME_DIR, ".claude-code-router.pid");
|
|
1160
1160
|
REFERENCE_COUNT_FILE = import_node_path.default.join(import_node_os.default.tmpdir(), "claude-code-reference-count.txt");
|
|
1161
|
+
CLAUDE_PROJECTS_DIR = import_node_path.default.join(import_node_os.default.homedir(), ".claude", "projects");
|
|
1161
1162
|
}
|
|
1162
1163
|
});
|
|
1163
1164
|
|
|
@@ -6588,7 +6589,7 @@ var require_thread_stream = __commonJS({
|
|
|
6588
6589
|
var { version: version2 } = require_package();
|
|
6589
6590
|
var { EventEmitter: EventEmitter2 } = require("events");
|
|
6590
6591
|
var { Worker } = require("worker_threads");
|
|
6591
|
-
var { join:
|
|
6592
|
+
var { join: join7 } = require("path");
|
|
6592
6593
|
var { pathToFileURL } = require("url");
|
|
6593
6594
|
var { wait } = require_wait();
|
|
6594
6595
|
var {
|
|
@@ -6624,7 +6625,7 @@ var require_thread_stream = __commonJS({
|
|
|
6624
6625
|
function createWorker(stream, opts) {
|
|
6625
6626
|
const { filename, workerData } = opts;
|
|
6626
6627
|
const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
|
|
6627
|
-
const toExecute = bundlerOverrides["thread-stream-worker"] ||
|
|
6628
|
+
const toExecute = bundlerOverrides["thread-stream-worker"] || join7(__dirname, "lib", "worker.js");
|
|
6628
6629
|
const worker = new Worker(toExecute, {
|
|
6629
6630
|
...opts.workerOpts,
|
|
6630
6631
|
trackUnmanagedFds: false,
|
|
@@ -7010,7 +7011,7 @@ var require_transport = __commonJS({
|
|
|
7010
7011
|
"use strict";
|
|
7011
7012
|
var { createRequire } = require("module");
|
|
7012
7013
|
var getCallers = require_caller();
|
|
7013
|
-
var { join:
|
|
7014
|
+
var { join: join7, isAbsolute, sep: sep2 } = require("node:path");
|
|
7014
7015
|
var sleep = require_atomic_sleep();
|
|
7015
7016
|
var onExit2 = require_on_exit_leak_free();
|
|
7016
7017
|
var ThreadStream = require_thread_stream();
|
|
@@ -7073,7 +7074,7 @@ var require_transport = __commonJS({
|
|
|
7073
7074
|
throw new Error("only one of target or targets can be specified");
|
|
7074
7075
|
}
|
|
7075
7076
|
if (targets) {
|
|
7076
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
7077
|
+
target = bundlerOverrides["pino-worker"] || join7(__dirname, "worker.js");
|
|
7077
7078
|
options.targets = targets.filter((dest) => dest.target).map((dest) => {
|
|
7078
7079
|
return {
|
|
7079
7080
|
...dest,
|
|
@@ -7091,7 +7092,7 @@ var require_transport = __commonJS({
|
|
|
7091
7092
|
});
|
|
7092
7093
|
});
|
|
7093
7094
|
} else if (pipeline) {
|
|
7094
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
7095
|
+
target = bundlerOverrides["pino-worker"] || join7(__dirname, "worker.js");
|
|
7095
7096
|
options.pipelines = [pipeline.map((dest) => {
|
|
7096
7097
|
return {
|
|
7097
7098
|
...dest,
|
|
@@ -7113,7 +7114,7 @@ var require_transport = __commonJS({
|
|
|
7113
7114
|
return origin;
|
|
7114
7115
|
}
|
|
7115
7116
|
if (origin === "pino/file") {
|
|
7116
|
-
return
|
|
7117
|
+
return join7(__dirname, "..", "file.js");
|
|
7117
7118
|
}
|
|
7118
7119
|
let fixTarget2;
|
|
7119
7120
|
for (const filePath of callers) {
|
|
@@ -8103,7 +8104,7 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
8103
8104
|
return circularValue;
|
|
8104
8105
|
}
|
|
8105
8106
|
let res = "";
|
|
8106
|
-
let
|
|
8107
|
+
let join7 = ",";
|
|
8107
8108
|
const originalIndentation = indentation;
|
|
8108
8109
|
if (Array.isArray(value)) {
|
|
8109
8110
|
if (value.length === 0) {
|
|
@@ -8117,7 +8118,7 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
8117
8118
|
indentation += spacer;
|
|
8118
8119
|
res += `
|
|
8119
8120
|
${indentation}`;
|
|
8120
|
-
|
|
8121
|
+
join7 = `,
|
|
8121
8122
|
${indentation}`;
|
|
8122
8123
|
}
|
|
8123
8124
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -8125,13 +8126,13 @@ ${indentation}`;
|
|
|
8125
8126
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
8126
8127
|
const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
|
|
8127
8128
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
8128
|
-
res +=
|
|
8129
|
+
res += join7;
|
|
8129
8130
|
}
|
|
8130
8131
|
const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
|
|
8131
8132
|
res += tmp !== void 0 ? tmp : "null";
|
|
8132
8133
|
if (value.length - 1 > maximumBreadth) {
|
|
8133
8134
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
8134
|
-
res += `${
|
|
8135
|
+
res += `${join7}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
8135
8136
|
}
|
|
8136
8137
|
if (spacer !== "") {
|
|
8137
8138
|
res += `
|
|
@@ -8152,7 +8153,7 @@ ${originalIndentation}`;
|
|
|
8152
8153
|
let separator = "";
|
|
8153
8154
|
if (spacer !== "") {
|
|
8154
8155
|
indentation += spacer;
|
|
8155
|
-
|
|
8156
|
+
join7 = `,
|
|
8156
8157
|
${indentation}`;
|
|
8157
8158
|
whitespace = " ";
|
|
8158
8159
|
}
|
|
@@ -8166,13 +8167,13 @@ ${indentation}`;
|
|
|
8166
8167
|
const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
|
|
8167
8168
|
if (tmp !== void 0) {
|
|
8168
8169
|
res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
|
|
8169
|
-
separator =
|
|
8170
|
+
separator = join7;
|
|
8170
8171
|
}
|
|
8171
8172
|
}
|
|
8172
8173
|
if (keyLength > maximumBreadth) {
|
|
8173
8174
|
const removedKeys = keyLength - maximumBreadth;
|
|
8174
8175
|
res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
|
|
8175
|
-
separator =
|
|
8176
|
+
separator = join7;
|
|
8176
8177
|
}
|
|
8177
8178
|
if (spacer !== "" && separator.length > 1) {
|
|
8178
8179
|
res = `
|
|
@@ -8213,7 +8214,7 @@ ${originalIndentation}`;
|
|
|
8213
8214
|
}
|
|
8214
8215
|
const originalIndentation = indentation;
|
|
8215
8216
|
let res = "";
|
|
8216
|
-
let
|
|
8217
|
+
let join7 = ",";
|
|
8217
8218
|
if (Array.isArray(value)) {
|
|
8218
8219
|
if (value.length === 0) {
|
|
8219
8220
|
return "[]";
|
|
@@ -8226,7 +8227,7 @@ ${originalIndentation}`;
|
|
|
8226
8227
|
indentation += spacer;
|
|
8227
8228
|
res += `
|
|
8228
8229
|
${indentation}`;
|
|
8229
|
-
|
|
8230
|
+
join7 = `,
|
|
8230
8231
|
${indentation}`;
|
|
8231
8232
|
}
|
|
8232
8233
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -8234,13 +8235,13 @@ ${indentation}`;
|
|
|
8234
8235
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
8235
8236
|
const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
|
|
8236
8237
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
8237
|
-
res +=
|
|
8238
|
+
res += join7;
|
|
8238
8239
|
}
|
|
8239
8240
|
const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
|
|
8240
8241
|
res += tmp !== void 0 ? tmp : "null";
|
|
8241
8242
|
if (value.length - 1 > maximumBreadth) {
|
|
8242
8243
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
8243
|
-
res += `${
|
|
8244
|
+
res += `${join7}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
8244
8245
|
}
|
|
8245
8246
|
if (spacer !== "") {
|
|
8246
8247
|
res += `
|
|
@@ -8253,7 +8254,7 @@ ${originalIndentation}`;
|
|
|
8253
8254
|
let whitespace = "";
|
|
8254
8255
|
if (spacer !== "") {
|
|
8255
8256
|
indentation += spacer;
|
|
8256
|
-
|
|
8257
|
+
join7 = `,
|
|
8257
8258
|
${indentation}`;
|
|
8258
8259
|
whitespace = " ";
|
|
8259
8260
|
}
|
|
@@ -8262,7 +8263,7 @@ ${indentation}`;
|
|
|
8262
8263
|
const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
|
|
8263
8264
|
if (tmp !== void 0) {
|
|
8264
8265
|
res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
|
|
8265
|
-
separator =
|
|
8266
|
+
separator = join7;
|
|
8266
8267
|
}
|
|
8267
8268
|
}
|
|
8268
8269
|
if (spacer !== "" && separator.length > 1) {
|
|
@@ -8320,20 +8321,20 @@ ${originalIndentation}`;
|
|
|
8320
8321
|
indentation += spacer;
|
|
8321
8322
|
let res2 = `
|
|
8322
8323
|
${indentation}`;
|
|
8323
|
-
const
|
|
8324
|
+
const join8 = `,
|
|
8324
8325
|
${indentation}`;
|
|
8325
8326
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
8326
8327
|
let i = 0;
|
|
8327
8328
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
8328
8329
|
const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
|
|
8329
8330
|
res2 += tmp2 !== void 0 ? tmp2 : "null";
|
|
8330
|
-
res2 +=
|
|
8331
|
+
res2 += join8;
|
|
8331
8332
|
}
|
|
8332
8333
|
const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
|
|
8333
8334
|
res2 += tmp !== void 0 ? tmp : "null";
|
|
8334
8335
|
if (value.length - 1 > maximumBreadth) {
|
|
8335
8336
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
8336
|
-
res2 += `${
|
|
8337
|
+
res2 += `${join8}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
8337
8338
|
}
|
|
8338
8339
|
res2 += `
|
|
8339
8340
|
${originalIndentation}`;
|
|
@@ -8349,16 +8350,16 @@ ${originalIndentation}`;
|
|
|
8349
8350
|
return '"[Object]"';
|
|
8350
8351
|
}
|
|
8351
8352
|
indentation += spacer;
|
|
8352
|
-
const
|
|
8353
|
+
const join7 = `,
|
|
8353
8354
|
${indentation}`;
|
|
8354
8355
|
let res = "";
|
|
8355
8356
|
let separator = "";
|
|
8356
8357
|
let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
|
|
8357
8358
|
if (isTypedArrayWithEntries(value)) {
|
|
8358
|
-
res += stringifyTypedArray(value,
|
|
8359
|
+
res += stringifyTypedArray(value, join7, maximumBreadth);
|
|
8359
8360
|
keys = keys.slice(value.length);
|
|
8360
8361
|
maximumPropertiesToStringify -= value.length;
|
|
8361
|
-
separator =
|
|
8362
|
+
separator = join7;
|
|
8362
8363
|
}
|
|
8363
8364
|
if (deterministic) {
|
|
8364
8365
|
keys = sort(keys, comparator);
|
|
@@ -8369,13 +8370,13 @@ ${indentation}`;
|
|
|
8369
8370
|
const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
|
|
8370
8371
|
if (tmp !== void 0) {
|
|
8371
8372
|
res += `${separator}${strEscape(key2)}: ${tmp}`;
|
|
8372
|
-
separator =
|
|
8373
|
+
separator = join7;
|
|
8373
8374
|
}
|
|
8374
8375
|
}
|
|
8375
8376
|
if (keyLength > maximumBreadth) {
|
|
8376
8377
|
const removedKeys = keyLength - maximumBreadth;
|
|
8377
8378
|
res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
|
|
8378
|
-
separator =
|
|
8379
|
+
separator = join7;
|
|
8379
8380
|
}
|
|
8380
8381
|
if (separator !== "") {
|
|
8381
8382
|
res = `
|
|
@@ -65835,7 +65836,7 @@ var require_send = __commonJS({
|
|
|
65835
65836
|
var { parseTokenList } = require_parseTokenList();
|
|
65836
65837
|
var { createHttpError } = require_createHttpError();
|
|
65837
65838
|
var extname = path7.extname;
|
|
65838
|
-
var
|
|
65839
|
+
var join7 = path7.join;
|
|
65839
65840
|
var normalize = path7.normalize;
|
|
65840
65841
|
var resolve = path7.resolve;
|
|
65841
65842
|
var sep2 = path7.sep;
|
|
@@ -65922,7 +65923,7 @@ var require_send = __commonJS({
|
|
|
65922
65923
|
return { statusCode: 403 };
|
|
65923
65924
|
}
|
|
65924
65925
|
parts = path8.split(sep2);
|
|
65925
|
-
path8 = normalize(
|
|
65926
|
+
path8 = normalize(join7(root, path8));
|
|
65926
65927
|
} else {
|
|
65927
65928
|
if (UP_PATH_REGEXP.test(path8)) {
|
|
65928
65929
|
debug('malicious path "%s"', path8);
|
|
@@ -66026,8 +66027,8 @@ var require_send = __commonJS({
|
|
|
66026
66027
|
}
|
|
66027
66028
|
function tryStat(path8) {
|
|
66028
66029
|
return new Promise((resolve2) => {
|
|
66029
|
-
fs6.stat(path8, function onstat(error,
|
|
66030
|
-
resolve2({ error, stat:
|
|
66030
|
+
fs6.stat(path8, function onstat(error, stat3) {
|
|
66031
|
+
resolve2({ error, stat: stat3 });
|
|
66031
66032
|
});
|
|
66032
66033
|
});
|
|
66033
66034
|
}
|
|
@@ -66062,7 +66063,7 @@ var require_send = __commonJS({
|
|
|
66062
66063
|
return sendError(500, err);
|
|
66063
66064
|
}
|
|
66064
66065
|
}
|
|
66065
|
-
function sendNotModified(headers, path8,
|
|
66066
|
+
function sendNotModified(headers, path8, stat3) {
|
|
66066
66067
|
debug("not modified");
|
|
66067
66068
|
delete headers["Content-Encoding"];
|
|
66068
66069
|
delete headers["Content-Language"];
|
|
@@ -66075,11 +66076,11 @@ var require_send = __commonJS({
|
|
|
66075
66076
|
stream: Readable.from(""),
|
|
66076
66077
|
// metadata
|
|
66077
66078
|
type: "file",
|
|
66078
|
-
metadata: { path: path8, stat:
|
|
66079
|
+
metadata: { path: path8, stat: stat3 }
|
|
66079
66080
|
};
|
|
66080
66081
|
}
|
|
66081
|
-
function sendFileDirectly(request, path8,
|
|
66082
|
-
let len =
|
|
66082
|
+
function sendFileDirectly(request, path8, stat3, options) {
|
|
66083
|
+
let len = stat3.size;
|
|
66083
66084
|
let offset = options.start ?? 0;
|
|
66084
66085
|
let statusCode = 200;
|
|
66085
66086
|
const headers = {};
|
|
@@ -66097,12 +66098,12 @@ var require_send = __commonJS({
|
|
|
66097
66098
|
headers["Cache-Control"] = cacheControl;
|
|
66098
66099
|
}
|
|
66099
66100
|
if (options.lastModified) {
|
|
66100
|
-
const modified =
|
|
66101
|
+
const modified = stat3.mtime.toUTCString();
|
|
66101
66102
|
debug("modified %s", modified);
|
|
66102
66103
|
headers["Last-Modified"] = modified;
|
|
66103
66104
|
}
|
|
66104
66105
|
if (options.etag) {
|
|
66105
|
-
const etag = 'W/"' +
|
|
66106
|
+
const etag = 'W/"' + stat3.size.toString(16) + "-" + stat3.mtime.getTime().toString(16) + '"';
|
|
66106
66107
|
debug("etag %s", etag);
|
|
66107
66108
|
headers.ETag = etag;
|
|
66108
66109
|
}
|
|
@@ -66121,7 +66122,7 @@ var require_send = __commonJS({
|
|
|
66121
66122
|
return sendError(412);
|
|
66122
66123
|
}
|
|
66123
66124
|
if (isNotModifiedFailure(request, headers)) {
|
|
66124
|
-
return sendNotModified(headers, path8,
|
|
66125
|
+
return sendNotModified(headers, path8, stat3);
|
|
66125
66126
|
}
|
|
66126
66127
|
}
|
|
66127
66128
|
len = Math.max(0, len - offset);
|
|
@@ -66163,7 +66164,7 @@ var require_send = __commonJS({
|
|
|
66163
66164
|
stream: Readable.from(""),
|
|
66164
66165
|
// metadata
|
|
66165
66166
|
type: "file",
|
|
66166
|
-
metadata: { path: path8, stat:
|
|
66167
|
+
metadata: { path: path8, stat: stat3 }
|
|
66167
66168
|
};
|
|
66168
66169
|
}
|
|
66169
66170
|
const stream2 = fs6.createReadStream(path8, {
|
|
@@ -66177,7 +66178,7 @@ var require_send = __commonJS({
|
|
|
66177
66178
|
stream: stream2,
|
|
66178
66179
|
// metadata
|
|
66179
66180
|
type: "file",
|
|
66180
|
-
metadata: { path: path8, stat:
|
|
66181
|
+
metadata: { path: path8, stat: stat3 }
|
|
66181
66182
|
};
|
|
66182
66183
|
}
|
|
66183
66184
|
function sendRedirect(path8, options) {
|
|
@@ -66205,14 +66206,14 @@ var require_send = __commonJS({
|
|
|
66205
66206
|
let err;
|
|
66206
66207
|
for (let i = 0; i < options.index.length; i++) {
|
|
66207
66208
|
const index = options.index[i];
|
|
66208
|
-
const p =
|
|
66209
|
-
const { error, stat:
|
|
66209
|
+
const p = join7(path8, index);
|
|
66210
|
+
const { error, stat: stat3 } = await tryStat(p);
|
|
66210
66211
|
if (error) {
|
|
66211
66212
|
err = error;
|
|
66212
66213
|
continue;
|
|
66213
66214
|
}
|
|
66214
|
-
if (
|
|
66215
|
-
return sendFileDirectly(request, p,
|
|
66215
|
+
if (stat3.isDirectory()) continue;
|
|
66216
|
+
return sendFileDirectly(request, p, stat3, options);
|
|
66216
66217
|
}
|
|
66217
66218
|
if (err) {
|
|
66218
66219
|
return sendStatError(err);
|
|
@@ -66220,22 +66221,22 @@ var require_send = __commonJS({
|
|
|
66220
66221
|
return sendError(404);
|
|
66221
66222
|
}
|
|
66222
66223
|
async function sendFile(request, path8, options) {
|
|
66223
|
-
const { error, stat:
|
|
66224
|
+
const { error, stat: stat3 } = await tryStat(path8);
|
|
66224
66225
|
if (error && error.code === "ENOENT" && !extname(path8) && path8[path8.length - 1] !== sep2) {
|
|
66225
66226
|
let err = error;
|
|
66226
66227
|
for (let i = 0; i < options.extensions.length; i++) {
|
|
66227
66228
|
const extension = options.extensions[i];
|
|
66228
66229
|
const p = path8 + "." + extension;
|
|
66229
|
-
const { error: error2, stat:
|
|
66230
|
+
const { error: error2, stat: stat4 } = await tryStat(p);
|
|
66230
66231
|
if (error2) {
|
|
66231
66232
|
err = error2;
|
|
66232
66233
|
continue;
|
|
66233
66234
|
}
|
|
66234
|
-
if (
|
|
66235
|
+
if (stat4.isDirectory()) {
|
|
66235
66236
|
err = null;
|
|
66236
66237
|
continue;
|
|
66237
66238
|
}
|
|
66238
|
-
return sendFileDirectly(request, p,
|
|
66239
|
+
return sendFileDirectly(request, p, stat4, options);
|
|
66239
66240
|
}
|
|
66240
66241
|
if (err) {
|
|
66241
66242
|
return sendStatError(err);
|
|
@@ -66243,8 +66244,8 @@ var require_send = __commonJS({
|
|
|
66243
66244
|
return sendError(404);
|
|
66244
66245
|
}
|
|
66245
66246
|
if (error) return sendStatError(error);
|
|
66246
|
-
if (
|
|
66247
|
-
return sendFileDirectly(request, path8,
|
|
66247
|
+
if (stat3.isDirectory()) return sendRedirect(path8, options);
|
|
66248
|
+
return sendFileDirectly(request, path8, stat3, options);
|
|
66248
66249
|
}
|
|
66249
66250
|
async function send(request, _path, options) {
|
|
66250
66251
|
const opts = normalizeOptions(options);
|
|
@@ -67755,7 +67756,7 @@ var require_package3 = __commonJS({
|
|
|
67755
67756
|
"package.json"(exports2, module2) {
|
|
67756
67757
|
module2.exports = {
|
|
67757
67758
|
name: "@musistudio/claude-code-router",
|
|
67758
|
-
version: "1.0.
|
|
67759
|
+
version: "1.0.63",
|
|
67759
67760
|
description: "Use Claude Code without an Anthropics account and route it to another LLM provider",
|
|
67760
67761
|
bin: {
|
|
67761
67762
|
ccr: "dist/cli.js"
|
|
@@ -70925,9 +70926,9 @@ var require_ansi_escapes = __commonJS({
|
|
|
70925
70926
|
|
|
70926
70927
|
// src/index.ts
|
|
70927
70928
|
var import_fs5 = require("fs");
|
|
70928
|
-
var
|
|
70929
|
+
var import_promises6 = require("fs/promises");
|
|
70929
70930
|
var import_os2 = require("os");
|
|
70930
|
-
var
|
|
70931
|
+
var import_path5 = require("path");
|
|
70931
70932
|
init_utils();
|
|
70932
70933
|
|
|
70933
70934
|
// node_modules/.pnpm/@musistudio+llms@1.0.38_ws@8.18.3/node_modules/@musistudio/llms/dist/esm/server.mjs
|
|
@@ -82288,7 +82289,7 @@ var pR = Al;
|
|
|
82288
82289
|
// src/server.ts
|
|
82289
82290
|
init_utils();
|
|
82290
82291
|
init_utils();
|
|
82291
|
-
var
|
|
82292
|
+
var import_path3 = require("path");
|
|
82292
82293
|
var import_static = __toESM(require_static());
|
|
82293
82294
|
var import_fs2 = require("fs");
|
|
82294
82295
|
var import_os = require("os");
|
|
@@ -82332,6 +82333,9 @@ var sessionUsageCache = new LRUCache(100);
|
|
|
82332
82333
|
|
|
82333
82334
|
// src/utils/router.ts
|
|
82334
82335
|
var import_promises3 = require("fs/promises");
|
|
82336
|
+
var import_promises4 = require("fs/promises");
|
|
82337
|
+
var import_path2 = require("path");
|
|
82338
|
+
init_constants();
|
|
82335
82339
|
var enc = (0, import_tiktoken.get_encoding)("cl100k_base");
|
|
82336
82340
|
var calculateTokenCount = (messages, system, tools) => {
|
|
82337
82341
|
let tokenCount = 0;
|
|
@@ -82380,7 +82384,40 @@ var calculateTokenCount = (messages, system, tools) => {
|
|
|
82380
82384
|
}
|
|
82381
82385
|
return tokenCount;
|
|
82382
82386
|
};
|
|
82387
|
+
var readConfigFile2 = async (filePath) => {
|
|
82388
|
+
try {
|
|
82389
|
+
await (0, import_promises3.access)(filePath);
|
|
82390
|
+
const content = await (0, import_promises3.readFile)(filePath, "utf8");
|
|
82391
|
+
return JSON.parse(content);
|
|
82392
|
+
} catch (error) {
|
|
82393
|
+
return null;
|
|
82394
|
+
}
|
|
82395
|
+
};
|
|
82396
|
+
var getProjectSpecificRouter = async (req) => {
|
|
82397
|
+
if (req.sessionId) {
|
|
82398
|
+
const project = await searchProjectBySession(req.sessionId);
|
|
82399
|
+
if (project) {
|
|
82400
|
+
const projectConfigPath = (0, import_path2.join)(HOME_DIR, project, "config.json");
|
|
82401
|
+
const sessionConfigPath = (0, import_path2.join)(
|
|
82402
|
+
HOME_DIR,
|
|
82403
|
+
project,
|
|
82404
|
+
`${req.sessionId}.json`
|
|
82405
|
+
);
|
|
82406
|
+
const sessionConfig = await readConfigFile2(sessionConfigPath);
|
|
82407
|
+
if (sessionConfig && sessionConfig.Router) {
|
|
82408
|
+
return sessionConfig.Router;
|
|
82409
|
+
}
|
|
82410
|
+
const projectConfig = await readConfigFile2(projectConfigPath);
|
|
82411
|
+
if (projectConfig && projectConfig.Router) {
|
|
82412
|
+
return projectConfig.Router;
|
|
82413
|
+
}
|
|
82414
|
+
}
|
|
82415
|
+
}
|
|
82416
|
+
return void 0;
|
|
82417
|
+
};
|
|
82383
82418
|
var getUseModel = async (req, tokenCount, config, lastUsage) => {
|
|
82419
|
+
const projectSpecificRouter = await getProjectSpecificRouter(req);
|
|
82420
|
+
const Router = projectSpecificRouter || config.Router;
|
|
82384
82421
|
if (req.body.model.includes(",")) {
|
|
82385
82422
|
const [provider, model] = req.body.model.split(",");
|
|
82386
82423
|
const finalProvider = config.Providers.find(
|
|
@@ -82394,14 +82431,14 @@ var getUseModel = async (req, tokenCount, config, lastUsage) => {
|
|
|
82394
82431
|
}
|
|
82395
82432
|
return req.body.model;
|
|
82396
82433
|
}
|
|
82397
|
-
const longContextThreshold =
|
|
82434
|
+
const longContextThreshold = Router.longContextThreshold || 6e4;
|
|
82398
82435
|
const lastUsageThreshold = lastUsage && lastUsage.input_tokens > longContextThreshold && tokenCount > 2e4;
|
|
82399
82436
|
const tokenCountThreshold = tokenCount > longContextThreshold;
|
|
82400
|
-
if ((lastUsageThreshold || tokenCountThreshold) &&
|
|
82437
|
+
if ((lastUsageThreshold || tokenCountThreshold) && Router.longContext) {
|
|
82401
82438
|
req.log.info(
|
|
82402
82439
|
`Using long context model due to token count: ${tokenCount}, threshold: ${longContextThreshold}`
|
|
82403
82440
|
);
|
|
82404
|
-
return
|
|
82441
|
+
return Router.longContext;
|
|
82405
82442
|
}
|
|
82406
82443
|
if (req.body?.system?.length > 1 && req.body?.system[1]?.text?.startsWith("<CCR-SUBAGENT-MODEL>")) {
|
|
82407
82444
|
const model = req.body?.system[1].text.match(
|
|
@@ -82415,18 +82452,18 @@ var getUseModel = async (req, tokenCount, config, lastUsage) => {
|
|
|
82415
82452
|
return model[1];
|
|
82416
82453
|
}
|
|
82417
82454
|
}
|
|
82418
|
-
if (req.body.model?.
|
|
82455
|
+
if (req.body.model?.includes("claude") && req.body.model?.includes("haiku") && config.Router.background) {
|
|
82419
82456
|
req.log.info(`Using background model for ${req.body.model}`);
|
|
82420
82457
|
return config.Router.background;
|
|
82421
82458
|
}
|
|
82422
|
-
if (Array.isArray(req.body.tools) && req.body.tools.some((tool) => tool.type?.startsWith("web_search")) &&
|
|
82423
|
-
return
|
|
82459
|
+
if (Array.isArray(req.body.tools) && req.body.tools.some((tool) => tool.type?.startsWith("web_search")) && Router.webSearch) {
|
|
82460
|
+
return Router.webSearch;
|
|
82424
82461
|
}
|
|
82425
|
-
if (req.body.thinking &&
|
|
82462
|
+
if (req.body.thinking && Router.think) {
|
|
82426
82463
|
req.log.info(`Using think model for ${req.body.thinking}`);
|
|
82427
|
-
return
|
|
82464
|
+
return Router.think;
|
|
82428
82465
|
}
|
|
82429
|
-
return
|
|
82466
|
+
return Router.default;
|
|
82430
82467
|
};
|
|
82431
82468
|
var router = async (req, _res, context) => {
|
|
82432
82469
|
const { config, event: event2 } = context;
|
|
@@ -82470,6 +82507,40 @@ var router = async (req, _res, context) => {
|
|
|
82470
82507
|
}
|
|
82471
82508
|
return;
|
|
82472
82509
|
};
|
|
82510
|
+
var searchProjectBySession = async (sessionId) => {
|
|
82511
|
+
try {
|
|
82512
|
+
const dir = await (0, import_promises4.opendir)(CLAUDE_PROJECTS_DIR);
|
|
82513
|
+
const folderNames = [];
|
|
82514
|
+
for await (const dirent of dir) {
|
|
82515
|
+
if (dirent.isDirectory()) {
|
|
82516
|
+
folderNames.push(dirent.name);
|
|
82517
|
+
}
|
|
82518
|
+
}
|
|
82519
|
+
const checkPromises = folderNames.map(async (folderName) => {
|
|
82520
|
+
const sessionFilePath = (0, import_path2.join)(
|
|
82521
|
+
CLAUDE_PROJECTS_DIR,
|
|
82522
|
+
folderName,
|
|
82523
|
+
`${sessionId}.jsonl`
|
|
82524
|
+
);
|
|
82525
|
+
try {
|
|
82526
|
+
const fileStat = await (0, import_promises4.stat)(sessionFilePath);
|
|
82527
|
+
return fileStat.isFile() ? folderName : null;
|
|
82528
|
+
} catch {
|
|
82529
|
+
return null;
|
|
82530
|
+
}
|
|
82531
|
+
});
|
|
82532
|
+
const results = await Promise.all(checkPromises);
|
|
82533
|
+
for (const result of results) {
|
|
82534
|
+
if (result) {
|
|
82535
|
+
return result;
|
|
82536
|
+
}
|
|
82537
|
+
}
|
|
82538
|
+
return null;
|
|
82539
|
+
} catch (error) {
|
|
82540
|
+
console.error("Error searching for project by session:", error);
|
|
82541
|
+
return null;
|
|
82542
|
+
}
|
|
82543
|
+
};
|
|
82473
82544
|
|
|
82474
82545
|
// src/server.ts
|
|
82475
82546
|
var createServer = (config) => {
|
|
@@ -82512,7 +82583,7 @@ var createServer = (config) => {
|
|
|
82512
82583
|
}, 1e3);
|
|
82513
82584
|
});
|
|
82514
82585
|
server.app.register(import_static.default, {
|
|
82515
|
-
root: (0,
|
|
82586
|
+
root: (0, import_path3.join)(__dirname, "..", "dist"),
|
|
82516
82587
|
prefix: "/ui/",
|
|
82517
82588
|
maxAge: "1h"
|
|
82518
82589
|
});
|
|
@@ -82549,13 +82620,13 @@ var createServer = (config) => {
|
|
|
82549
82620
|
});
|
|
82550
82621
|
server.app.get("/api/logs/files", async (req, reply) => {
|
|
82551
82622
|
try {
|
|
82552
|
-
const logDir = (0,
|
|
82623
|
+
const logDir = (0, import_path3.join)((0, import_os.homedir)(), ".claude-code-router", "logs");
|
|
82553
82624
|
const logFiles = [];
|
|
82554
82625
|
if ((0, import_fs2.existsSync)(logDir)) {
|
|
82555
82626
|
const files = (0, import_fs2.readdirSync)(logDir);
|
|
82556
82627
|
for (const file of files) {
|
|
82557
82628
|
if (file.endsWith(".log")) {
|
|
82558
|
-
const filePath = (0,
|
|
82629
|
+
const filePath = (0, import_path3.join)(logDir, file);
|
|
82559
82630
|
const stats = (0, import_fs2.statSync)(filePath);
|
|
82560
82631
|
logFiles.push({
|
|
82561
82632
|
name: file,
|
|
@@ -82580,7 +82651,7 @@ var createServer = (config) => {
|
|
|
82580
82651
|
if (filePath) {
|
|
82581
82652
|
logFilePath = filePath;
|
|
82582
82653
|
} else {
|
|
82583
|
-
logFilePath = (0,
|
|
82654
|
+
logFilePath = (0, import_path3.join)((0, import_os.homedir)(), ".claude-code-router", "logs", "app.log");
|
|
82584
82655
|
}
|
|
82585
82656
|
if (!(0, import_fs2.existsSync)(logFilePath)) {
|
|
82586
82657
|
return [];
|
|
@@ -82600,7 +82671,7 @@ var createServer = (config) => {
|
|
|
82600
82671
|
if (filePath) {
|
|
82601
82672
|
logFilePath = filePath;
|
|
82602
82673
|
} else {
|
|
82603
|
-
logFilePath = (0,
|
|
82674
|
+
logFilePath = (0, import_path3.join)((0, import_os.homedir)(), ".claude-code-router", "logs", "app.log");
|
|
82604
82675
|
}
|
|
82605
82676
|
if ((0, import_fs2.existsSync)(logFilePath)) {
|
|
82606
82677
|
(0, import_fs2.writeFileSync)(logFilePath, "", "utf8");
|
|
@@ -82761,8 +82832,8 @@ var import_child_process3 = require("child_process");
|
|
|
82761
82832
|
var import_zlib = require("zlib");
|
|
82762
82833
|
var import_stream = require("stream");
|
|
82763
82834
|
var import_fs4 = require("fs");
|
|
82764
|
-
var
|
|
82765
|
-
var
|
|
82835
|
+
var import_promises5 = require("fs/promises");
|
|
82836
|
+
var import_path4 = require("path");
|
|
82766
82837
|
var import_util2 = require("util");
|
|
82767
82838
|
var import_timers = require("timers");
|
|
82768
82839
|
async function exists(filename) {
|
|
@@ -82806,10 +82877,10 @@ var RotatingFileStream = class extends import_stream.Writable {
|
|
|
82806
82877
|
this.filename = path7 + generator(null);
|
|
82807
82878
|
this.fsCreateReadStream = import_fs4.createReadStream;
|
|
82808
82879
|
this.fsCreateWriteStream = import_fs4.createWriteStream;
|
|
82809
|
-
this.fsOpen =
|
|
82810
|
-
this.fsReadFile =
|
|
82811
|
-
this.fsStat =
|
|
82812
|
-
this.fsUnlink =
|
|
82880
|
+
this.fsOpen = import_promises5.open;
|
|
82881
|
+
this.fsReadFile = import_promises5.readFile;
|
|
82882
|
+
this.fsStat = import_promises5.stat;
|
|
82883
|
+
this.fsUnlink = import_promises5.unlink;
|
|
82813
82884
|
this.generator = generator;
|
|
82814
82885
|
this.maxTimeout = 2147483640;
|
|
82815
82886
|
this.options = options;
|
|
@@ -82879,7 +82950,7 @@ var RotatingFileStream = class extends import_stream.Writable {
|
|
|
82879
82950
|
return new Promise((resolve, reject) => process.nextTick(() => this.immutate(true).then(resolve).catch(reject)));
|
|
82880
82951
|
let stats;
|
|
82881
82952
|
try {
|
|
82882
|
-
stats = await (0,
|
|
82953
|
+
stats = await (0, import_promises5.stat)(this.filename);
|
|
82883
82954
|
} catch (e) {
|
|
82884
82955
|
if (e.code !== "ENOENT")
|
|
82885
82956
|
throw e;
|
|
@@ -82902,17 +82973,17 @@ var RotatingFileStream = class extends import_stream.Writable {
|
|
|
82902
82973
|
return this.rotate();
|
|
82903
82974
|
}
|
|
82904
82975
|
async makePath(name) {
|
|
82905
|
-
return (0,
|
|
82976
|
+
return (0, import_promises5.mkdir)(name.split(import_path4.sep).slice(0, -1).join(import_path4.sep), { recursive: true });
|
|
82906
82977
|
}
|
|
82907
82978
|
async reopen(size) {
|
|
82908
82979
|
let file;
|
|
82909
82980
|
try {
|
|
82910
|
-
file = await (0,
|
|
82981
|
+
file = await (0, import_promises5.open)(this.filename, "a", this.options.mode);
|
|
82911
82982
|
} catch (e) {
|
|
82912
82983
|
if (e.code !== "ENOENT")
|
|
82913
82984
|
throw e;
|
|
82914
82985
|
await this.makePath(this.filename);
|
|
82915
|
-
file = await (0,
|
|
82986
|
+
file = await (0, import_promises5.open)(this.filename, "a", this.options.mode);
|
|
82916
82987
|
}
|
|
82917
82988
|
this.file = file;
|
|
82918
82989
|
this.size = size;
|
|
@@ -82958,7 +83029,7 @@ var RotatingFileStream = class extends import_stream.Writable {
|
|
|
82958
83029
|
if (compress)
|
|
82959
83030
|
await this.compress(filename);
|
|
82960
83031
|
else
|
|
82961
|
-
await (0,
|
|
83032
|
+
await (0, import_promises5.rename)(this.filename, filename);
|
|
82962
83033
|
return this.rotated(filename);
|
|
82963
83034
|
}
|
|
82964
83035
|
async touch(filename) {
|
|
@@ -82969,7 +83040,7 @@ var RotatingFileStream = class extends import_stream.Writable {
|
|
|
82969
83040
|
if (e.code !== "ENOENT")
|
|
82970
83041
|
throw e;
|
|
82971
83042
|
await this.makePath(filename);
|
|
82972
|
-
file = await (0,
|
|
83043
|
+
file = await (0, import_promises5.open)(filename, "a");
|
|
82973
83044
|
}
|
|
82974
83045
|
await file.close();
|
|
82975
83046
|
return this.unlink(filename);
|
|
@@ -82988,12 +83059,12 @@ var RotatingFileStream = class extends import_stream.Writable {
|
|
|
82988
83059
|
await this.compress(currName);
|
|
82989
83060
|
else {
|
|
82990
83061
|
try {
|
|
82991
|
-
await (0,
|
|
83062
|
+
await (0, import_promises5.rename)(prevName, currName);
|
|
82992
83063
|
} catch (e) {
|
|
82993
83064
|
if (e.code !== "ENOENT")
|
|
82994
83065
|
throw e;
|
|
82995
83066
|
await this.makePath(currName);
|
|
82996
|
-
await (0,
|
|
83067
|
+
await (0, import_promises5.rename)(prevName, currName);
|
|
82997
83068
|
}
|
|
82998
83069
|
}
|
|
82999
83070
|
}
|
|
@@ -83139,7 +83210,7 @@ var RotatingFileStream = class extends import_stream.Writable {
|
|
|
83139
83210
|
this.emit("removed", file.name, false);
|
|
83140
83211
|
}
|
|
83141
83212
|
}
|
|
83142
|
-
await (0,
|
|
83213
|
+
await (0, import_promises5.writeFile)(history, res.map((e) => e.name).join("\n") + "\n", "utf-8");
|
|
83143
83214
|
this.emit("history");
|
|
83144
83215
|
}
|
|
83145
83216
|
async immutate(first) {
|
|
@@ -83284,8 +83355,8 @@ var checks = {
|
|
|
83284
83355
|
path: (type, options, value) => {
|
|
83285
83356
|
if (type !== "string")
|
|
83286
83357
|
throw new Error(`Don't know how to handle 'options.path' type: ${type}`);
|
|
83287
|
-
if (value[value.length - 1] !==
|
|
83288
|
-
options.path = value +
|
|
83358
|
+
if (value[value.length - 1] !== import_path4.sep)
|
|
83359
|
+
options.path = value + import_path4.sep;
|
|
83289
83360
|
}
|
|
83290
83361
|
}
|
|
83291
83362
|
};
|
|
@@ -84931,60 +85002,76 @@ var ImageAgent = class {
|
|
|
84931
85002
|
this.appendTools();
|
|
84932
85003
|
}
|
|
84933
85004
|
shouldHandle(req, config) {
|
|
84934
|
-
if (!config.Router.image || req.body.model === config.Router.image)
|
|
85005
|
+
if (!config.Router.image || req.body.model === config.Router.image)
|
|
85006
|
+
return false;
|
|
84935
85007
|
const lastMessage = req.body.messages[req.body.messages.length - 1];
|
|
84936
|
-
if (!config.forceUseImageAgent && lastMessage.role === "user" && Array.isArray(lastMessage.content) && lastMessage.content.find(
|
|
85008
|
+
if (!config.forceUseImageAgent && lastMessage.role === "user" && Array.isArray(lastMessage.content) && lastMessage.content.find(
|
|
85009
|
+
(item) => item.type === "image" || Array.isArray(item?.content) && item.content.some((sub) => sub.type === "image")
|
|
85010
|
+
)) {
|
|
84937
85011
|
req.body.model = config.Router.image;
|
|
84938
85012
|
const images = [];
|
|
84939
85013
|
lastMessage.content.filter((item) => item.type === "tool_result").forEach((item) => {
|
|
84940
|
-
item.content
|
|
84941
|
-
|
|
84942
|
-
|
|
84943
|
-
|
|
84944
|
-
|
|
84945
|
-
|
|
85014
|
+
if (Array.isArray(item.content)) {
|
|
85015
|
+
item.content.forEach((element) => {
|
|
85016
|
+
if (element.type === "image") {
|
|
85017
|
+
images.push(element);
|
|
85018
|
+
}
|
|
85019
|
+
});
|
|
85020
|
+
item.content = "read image successfully";
|
|
85021
|
+
}
|
|
84946
85022
|
});
|
|
84947
85023
|
lastMessage.content.push(...images);
|
|
84948
85024
|
return false;
|
|
84949
85025
|
}
|
|
84950
|
-
return req.body.messages.some(
|
|
85026
|
+
return req.body.messages.some(
|
|
85027
|
+
(msg) => msg.role === "user" && Array.isArray(msg.content) && msg.content.some(
|
|
85028
|
+
(item) => item.type === "image" || Array.isArray(item?.content) && item.content.some((sub) => sub.type === "image")
|
|
85029
|
+
)
|
|
85030
|
+
);
|
|
84951
85031
|
}
|
|
84952
85032
|
appendTools() {
|
|
84953
85033
|
this.tools.set("analyzeImage", {
|
|
84954
85034
|
name: "analyzeImage",
|
|
84955
85035
|
description: "Analyse image or images by ID and extract information such as OCR text, objects, layout, colors, or safety signals.",
|
|
84956
85036
|
input_schema: {
|
|
84957
|
-
|
|
84958
|
-
|
|
84959
|
-
|
|
84960
|
-
|
|
84961
|
-
|
|
84962
|
-
|
|
84963
|
-
|
|
85037
|
+
type: "object",
|
|
85038
|
+
properties: {
|
|
85039
|
+
imageId: {
|
|
85040
|
+
type: "array",
|
|
85041
|
+
description: "an array of IDs to analyse",
|
|
85042
|
+
items: {
|
|
85043
|
+
type: "string"
|
|
84964
85044
|
}
|
|
84965
85045
|
},
|
|
84966
|
-
|
|
84967
|
-
|
|
84968
|
-
|
|
85046
|
+
task: {
|
|
85047
|
+
type: "string",
|
|
85048
|
+
description: "Details of task to perform on the image.The more detailed, the better"
|
|
84969
85049
|
},
|
|
84970
|
-
|
|
84971
|
-
|
|
84972
|
-
|
|
84973
|
-
|
|
84974
|
-
|
|
84975
|
-
|
|
84976
|
-
|
|
84977
|
-
|
|
84978
|
-
|
|
84979
|
-
|
|
84980
|
-
|
|
84981
|
-
|
|
85050
|
+
regions: {
|
|
85051
|
+
type: "array",
|
|
85052
|
+
description: "Optional regions of interest within the image",
|
|
85053
|
+
items: {
|
|
85054
|
+
type: "object",
|
|
85055
|
+
properties: {
|
|
85056
|
+
name: {
|
|
85057
|
+
type: "string",
|
|
85058
|
+
description: "Optional label for the region"
|
|
85059
|
+
},
|
|
85060
|
+
x: { type: "number", description: "X coordinate" },
|
|
85061
|
+
y: { type: "number", description: "Y coordinate" },
|
|
85062
|
+
w: { type: "number", description: "Width of the region" },
|
|
85063
|
+
h: { type: "number", description: "Height of the region" },
|
|
85064
|
+
units: {
|
|
85065
|
+
type: "string",
|
|
85066
|
+
enum: ["px", "pct"],
|
|
85067
|
+
description: "Units for coordinates and size"
|
|
85068
|
+
}
|
|
84982
85069
|
},
|
|
84983
|
-
|
|
85070
|
+
required: ["x", "y", "w", "h", "units"]
|
|
84984
85071
|
}
|
|
84985
85072
|
}
|
|
84986
85073
|
},
|
|
84987
|
-
|
|
85074
|
+
required: ["imageId", "task"]
|
|
84988
85075
|
},
|
|
84989
85076
|
handler: async (args, context) => {
|
|
84990
85077
|
const imageMessages = [];
|
|
@@ -84992,7 +85079,9 @@ var ImageAgent = class {
|
|
|
84992
85079
|
if (args.imageId) {
|
|
84993
85080
|
if (Array.isArray(args.imageId)) {
|
|
84994
85081
|
args.imageId.forEach((imgId) => {
|
|
84995
|
-
const image = imageCache.getImage(
|
|
85082
|
+
const image = imageCache.getImage(
|
|
85083
|
+
`${context.req.id}_Image#${imgId}`
|
|
85084
|
+
);
|
|
84996
85085
|
if (image) {
|
|
84997
85086
|
imageMessages.push({
|
|
84998
85087
|
type: "image",
|
|
@@ -85001,7 +85090,9 @@ var ImageAgent = class {
|
|
|
85001
85090
|
}
|
|
85002
85091
|
});
|
|
85003
85092
|
} else {
|
|
85004
|
-
const image = imageCache.getImage(
|
|
85093
|
+
const image = imageCache.getImage(
|
|
85094
|
+
`${context.req.id}_Image#${args.imageId}`
|
|
85095
|
+
);
|
|
85005
85096
|
if (image) {
|
|
85006
85097
|
imageMessages.push({
|
|
85007
85098
|
type: "image",
|
|
@@ -85014,7 +85105,11 @@ var ImageAgent = class {
|
|
|
85014
85105
|
}
|
|
85015
85106
|
const userMessage = context.req.body.messages[context.req.body.messages.length - 1];
|
|
85016
85107
|
if (userMessage.role === "user" && Array.isArray(userMessage.content)) {
|
|
85017
|
-
const msgs = userMessage.content.filter(
|
|
85108
|
+
const msgs = userMessage.content.filter(
|
|
85109
|
+
(item) => item.type === "text" && !item.text.includes(
|
|
85110
|
+
"This is an image, if you need to view or analyze it, you need to extract the imageId"
|
|
85111
|
+
)
|
|
85112
|
+
);
|
|
85018
85113
|
imageMessages.push(...msgs);
|
|
85019
85114
|
}
|
|
85020
85115
|
if (Object.keys(args).length > 0) {
|
|
@@ -85023,30 +85118,35 @@ var ImageAgent = class {
|
|
|
85023
85118
|
text: JSON.stringify(args)
|
|
85024
85119
|
});
|
|
85025
85120
|
}
|
|
85026
|
-
const agentResponse = await fetch(
|
|
85027
|
-
|
|
85028
|
-
|
|
85029
|
-
"
|
|
85030
|
-
|
|
85031
|
-
|
|
85032
|
-
|
|
85033
|
-
|
|
85034
|
-
|
|
85035
|
-
|
|
85036
|
-
|
|
85121
|
+
const agentResponse = await fetch(
|
|
85122
|
+
`http://127.0.0.1:${context.config.PORT || 3456}/v1/messages`,
|
|
85123
|
+
{
|
|
85124
|
+
method: "POST",
|
|
85125
|
+
headers: {
|
|
85126
|
+
"x-api-key": context.config.APIKEY,
|
|
85127
|
+
"content-type": "application/json"
|
|
85128
|
+
},
|
|
85129
|
+
body: JSON.stringify({
|
|
85130
|
+
model: context.config.Router.image,
|
|
85131
|
+
system: [
|
|
85132
|
+
{
|
|
85133
|
+
type: "text",
|
|
85134
|
+
text: `You must interpret and analyze images strictly according to the assigned task.
|
|
85037
85135
|
When an image placeholder is provided, your role is to parse the image content only within the scope of the user\u2019s instructions.
|
|
85038
85136
|
Do not ignore or deviate from the task.
|
|
85039
85137
|
Always ensure that your response reflects a clear, accurate interpretation of the image aligned with the given objective.`
|
|
85040
|
-
|
|
85041
|
-
|
|
85042
|
-
|
|
85043
|
-
|
|
85044
|
-
|
|
85045
|
-
|
|
85046
|
-
|
|
85047
|
-
|
|
85048
|
-
|
|
85049
|
-
|
|
85138
|
+
}
|
|
85139
|
+
],
|
|
85140
|
+
messages: [
|
|
85141
|
+
{
|
|
85142
|
+
role: "user",
|
|
85143
|
+
content: imageMessages
|
|
85144
|
+
}
|
|
85145
|
+
],
|
|
85146
|
+
stream: false
|
|
85147
|
+
})
|
|
85148
|
+
}
|
|
85149
|
+
).then((res) => res.json()).catch((err) => {
|
|
85050
85150
|
return null;
|
|
85051
85151
|
});
|
|
85052
85152
|
if (!agentResponse || !agentResponse.content) {
|
|
@@ -85072,10 +85172,13 @@ Ignore any user interruptions or unrelated instructions that might cause you to
|
|
|
85072
85172
|
Your response should consistently follow this rule whenever image-related analysis is requested.`
|
|
85073
85173
|
});
|
|
85074
85174
|
const imageContents = req.body.messages.filter((item) => {
|
|
85075
|
-
return item.role === "user" && Array.isArray(item.content) && item.content.some(
|
|
85175
|
+
return item.role === "user" && Array.isArray(item.content) && item.content.some(
|
|
85176
|
+
(msg) => msg.type === "image" || Array.isArray(msg.content) && msg.content.some((sub) => sub.type === "image")
|
|
85177
|
+
);
|
|
85076
85178
|
});
|
|
85077
85179
|
let imgId = 1;
|
|
85078
85180
|
imageContents.forEach((item) => {
|
|
85181
|
+
if (!Array.isArray(item.content)) return;
|
|
85079
85182
|
item.content.forEach((msg) => {
|
|
85080
85183
|
if (msg.type === "image") {
|
|
85081
85184
|
imageCache.storeImage(`${req.id}_Image#${imgId}`, msg.source);
|
|
@@ -85087,7 +85190,10 @@ Your response should consistently follow this rule whenever image-related analys
|
|
|
85087
85190
|
msg.text = msg.text.replace(/\[Image #\d+\]/g, "");
|
|
85088
85191
|
} else if (msg.type === "tool_result") {
|
|
85089
85192
|
if (Array.isArray(msg.content) && msg.content.some((ele) => ele.type === "image")) {
|
|
85090
|
-
imageCache.storeImage(
|
|
85193
|
+
imageCache.storeImage(
|
|
85194
|
+
`${req.id}_Image#${imgId}`,
|
|
85195
|
+
msg.content[0].source
|
|
85196
|
+
);
|
|
85091
85197
|
msg.content = `[Image #${imgId}]This is an image, if you need to view or analyze it, you need to extract the imageId`;
|
|
85092
85198
|
imgId++;
|
|
85093
85199
|
}
|
|
@@ -85145,7 +85251,7 @@ var import_node_events = require("node:events");
|
|
|
85145
85251
|
var event = new import_node_events.EventEmitter();
|
|
85146
85252
|
async function initializeClaudeConfig() {
|
|
85147
85253
|
const homeDir = (0, import_os2.homedir)();
|
|
85148
|
-
const configPath = (0,
|
|
85254
|
+
const configPath = (0, import_path5.join)(homeDir, ".claude.json");
|
|
85149
85255
|
if (!(0, import_fs5.existsSync)(configPath)) {
|
|
85150
85256
|
const userID = Array.from(
|
|
85151
85257
|
{ length: 64 },
|
|
@@ -85159,7 +85265,7 @@ async function initializeClaudeConfig() {
|
|
|
85159
85265
|
lastOnboardingVersion: "1.0.17",
|
|
85160
85266
|
projects: {}
|
|
85161
85267
|
};
|
|
85162
|
-
await (0,
|
|
85268
|
+
await (0, import_promises6.writeFile)(configPath, JSON.stringify(configContent, null, 2));
|
|
85163
85269
|
}
|
|
85164
85270
|
}
|
|
85165
85271
|
async function run(options = {}) {
|
|
@@ -85217,7 +85323,7 @@ async function run(options = {}) {
|
|
|
85217
85323
|
providers: config.Providers || config.providers,
|
|
85218
85324
|
HOST,
|
|
85219
85325
|
PORT: servicePort,
|
|
85220
|
-
LOG_FILE: (0,
|
|
85326
|
+
LOG_FILE: (0, import_path5.join)(
|
|
85221
85327
|
(0, import_os2.homedir)(),
|
|
85222
85328
|
".claude-code-router",
|
|
85223
85329
|
"claude-code-router.log"
|
|
@@ -85469,9 +85575,9 @@ init_utils();
|
|
|
85469
85575
|
// src/utils/close.ts
|
|
85470
85576
|
var import_fs6 = require("fs");
|
|
85471
85577
|
init_constants();
|
|
85472
|
-
var
|
|
85578
|
+
var import_path6 = require("path");
|
|
85473
85579
|
async function closeService() {
|
|
85474
|
-
const PID_FILE2 = (0,
|
|
85580
|
+
const PID_FILE2 = (0, import_path6.join)(HOME_DIR, ".claude-code-router.pid");
|
|
85475
85581
|
const isRunning = await isServiceRunning();
|
|
85476
85582
|
if (!isRunning) {
|
|
85477
85583
|
console.log("No service is currently running.");
|
|
@@ -85573,7 +85679,7 @@ async function executeCodeCommand(args = []) {
|
|
|
85573
85679
|
}
|
|
85574
85680
|
|
|
85575
85681
|
// src/utils/statusline.ts
|
|
85576
|
-
var
|
|
85682
|
+
var import_promises7 = __toESM(require("node:fs/promises"));
|
|
85577
85683
|
var import_child_process5 = require("child_process");
|
|
85578
85684
|
var import_node_path5 = __toESM(require("node:path"));
|
|
85579
85685
|
init_constants();
|
|
@@ -85652,7 +85758,7 @@ function replaceVariables(text, variables) {
|
|
|
85652
85758
|
}
|
|
85653
85759
|
async function executeScript(scriptPath, variables) {
|
|
85654
85760
|
try {
|
|
85655
|
-
await
|
|
85761
|
+
await import_promises7.default.access(scriptPath);
|
|
85656
85762
|
const scriptModule = require(scriptPath);
|
|
85657
85763
|
if (typeof scriptModule === "function") {
|
|
85658
85764
|
const result = scriptModule(variables);
|
|
@@ -85809,11 +85915,11 @@ async function getProjectThemeConfig() {
|
|
|
85809
85915
|
try {
|
|
85810
85916
|
const configPath = CONFIG_FILE;
|
|
85811
85917
|
try {
|
|
85812
|
-
await
|
|
85918
|
+
await import_promises7.default.access(configPath);
|
|
85813
85919
|
} catch {
|
|
85814
85920
|
return { theme: null, style: "default" };
|
|
85815
85921
|
}
|
|
85816
|
-
const configContent = await
|
|
85922
|
+
const configContent = await import_promises7.default.readFile(configPath, "utf-8");
|
|
85817
85923
|
const config = import_json53.default.parse(configContent);
|
|
85818
85924
|
if (config.StatusLine) {
|
|
85819
85925
|
const currentStyle = config.StatusLine.currentStyle || "default";
|
|
@@ -85874,7 +85980,7 @@ async function parseStatusLineData(input) {
|
|
|
85874
85980
|
}).toString().trim();
|
|
85875
85981
|
} catch (error) {
|
|
85876
85982
|
}
|
|
85877
|
-
const transcriptContent = await
|
|
85983
|
+
const transcriptContent = await import_promises7.default.readFile(input.transcript_path, "utf-8");
|
|
85878
85984
|
const lines2 = transcriptContent.trim().split("\n");
|
|
85879
85985
|
let model = "";
|
|
85880
85986
|
let inputTokens = 0;
|
|
@@ -85899,11 +86005,11 @@ async function parseStatusLineData(input) {
|
|
|
85899
86005
|
const projectConfigPath = import_node_path5.default.join(workDir, ".claude-code-router", "config.json");
|
|
85900
86006
|
let configPath = projectConfigPath;
|
|
85901
86007
|
try {
|
|
85902
|
-
await
|
|
86008
|
+
await import_promises7.default.access(projectConfigPath);
|
|
85903
86009
|
} catch {
|
|
85904
86010
|
configPath = CONFIG_FILE;
|
|
85905
86011
|
}
|
|
85906
|
-
const configContent = await
|
|
86012
|
+
const configContent = await import_promises7.default.readFile(configPath, "utf-8");
|
|
85907
86013
|
const config = import_json53.default.parse(configContent);
|
|
85908
86014
|
if (config.Router && config.Router.default) {
|
|
85909
86015
|
const [, defaultModel] = config.Router.default.split(",");
|
|
@@ -87846,7 +87952,7 @@ var import_package = __toESM(require_package3());
|
|
|
87846
87952
|
var import_child_process6 = require("child_process");
|
|
87847
87953
|
init_constants();
|
|
87848
87954
|
var import_fs7 = __toESM(require("fs"));
|
|
87849
|
-
var
|
|
87955
|
+
var import_path7 = require("path");
|
|
87850
87956
|
var command = process.argv[2];
|
|
87851
87957
|
var HELP_TEXT = `
|
|
87852
87958
|
Usage: ccr [command]
|
|
@@ -87939,7 +88045,7 @@ async function main() {
|
|
|
87939
88045
|
case "code":
|
|
87940
88046
|
if (!isRunning) {
|
|
87941
88047
|
console.log("Service not running, starting service...");
|
|
87942
|
-
const cliPath2 = (0,
|
|
88048
|
+
const cliPath2 = (0, import_path7.join)(__dirname, "cli.js");
|
|
87943
88049
|
const startProcess2 = (0, import_child_process6.spawn)("node", [cliPath2, "start"], {
|
|
87944
88050
|
detached: true,
|
|
87945
88051
|
stdio: "ignore"
|
|
@@ -87966,7 +88072,7 @@ async function main() {
|
|
|
87966
88072
|
case "ui":
|
|
87967
88073
|
if (!isRunning) {
|
|
87968
88074
|
console.log("Service not running, starting service...");
|
|
87969
|
-
const cliPath2 = (0,
|
|
88075
|
+
const cliPath2 = (0, import_path7.join)(__dirname, "cli.js");
|
|
87970
88076
|
const startProcess2 = (0, import_child_process6.spawn)("node", [cliPath2, "start"], {
|
|
87971
88077
|
detached: true,
|
|
87972
88078
|
stdio: "ignore"
|
|
@@ -88074,7 +88180,7 @@ async function main() {
|
|
|
88074
88180
|
cleanupPidFile();
|
|
88075
88181
|
}
|
|
88076
88182
|
console.log("Starting claude code router service...");
|
|
88077
|
-
const cliPath = (0,
|
|
88183
|
+
const cliPath = (0, import_path7.join)(__dirname, "cli.js");
|
|
88078
88184
|
const startProcess = (0, import_child_process6.spawn)("node", [cliPath, "start"], {
|
|
88079
88185
|
detached: true,
|
|
88080
88186
|
stdio: "ignore"
|