@lakphy/local-router 0.5.6 → 0.5.7
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/config.schema.json +2 -2
- package/dist/cli.js +525 -293
- package/dist/entry.js +360 -232
- package/dist/web/assets/index-D1WTE7QU.js +192 -0
- package/dist/web/assets/index-DrH6dT5r.css +2 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/web/assets/index-0-b0NcMV.js +0 -192
- package/dist/web/assets/index-_8dgANhJ.css +0 -2
package/dist/cli.js
CHANGED
|
@@ -9179,257 +9179,6 @@ var init_output = __esm(() => {
|
|
|
9179
9179
|
init_global_flags();
|
|
9180
9180
|
});
|
|
9181
9181
|
|
|
9182
|
-
// src/cli/runtime.ts
|
|
9183
|
-
import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync4, rmSync, writeFileSync as writeFileSync3 } from "fs";
|
|
9184
|
-
import { homedir as homedir2 } from "os";
|
|
9185
|
-
import { join as join3, resolve as resolve2 } from "path";
|
|
9186
|
-
function getRuntimeDirs() {
|
|
9187
|
-
const override = process.env.LOCAL_ROUTER_RUNTIME_DIR;
|
|
9188
|
-
const root = override?.trim() ? override.trim() : join3(homedir2(), ".local-router");
|
|
9189
|
-
return {
|
|
9190
|
-
root,
|
|
9191
|
-
run: join3(root, "run"),
|
|
9192
|
-
logs: join3(root, "logs")
|
|
9193
|
-
};
|
|
9194
|
-
}
|
|
9195
|
-
function getRuntimeFiles() {
|
|
9196
|
-
const dirs = getRuntimeDirs();
|
|
9197
|
-
return {
|
|
9198
|
-
pid: join3(dirs.run, "local-router.pid"),
|
|
9199
|
-
state: join3(dirs.run, "status.json"),
|
|
9200
|
-
daemonLog: join3(dirs.logs, "daemon.log")
|
|
9201
|
-
};
|
|
9202
|
-
}
|
|
9203
|
-
function ensureRuntimeDirs() {
|
|
9204
|
-
const dirs = getRuntimeDirs();
|
|
9205
|
-
mkdirSync3(dirs.root, { recursive: true });
|
|
9206
|
-
mkdirSync3(dirs.run, { recursive: true });
|
|
9207
|
-
mkdirSync3(dirs.logs, { recursive: true });
|
|
9208
|
-
}
|
|
9209
|
-
function writeRuntimeState(state) {
|
|
9210
|
-
ensureRuntimeDirs();
|
|
9211
|
-
const files = getRuntimeFiles();
|
|
9212
|
-
writeFileSync3(files.pid, `${state.pid}
|
|
9213
|
-
`, "utf-8");
|
|
9214
|
-
writeFileSync3(files.state, JSON.stringify(state, null, 2), "utf-8");
|
|
9215
|
-
}
|
|
9216
|
-
function readRuntimeState() {
|
|
9217
|
-
const files = getRuntimeFiles();
|
|
9218
|
-
if (!existsSync2(files.state)) {
|
|
9219
|
-
return null;
|
|
9220
|
-
}
|
|
9221
|
-
try {
|
|
9222
|
-
return JSON.parse(readFileSync4(files.state, "utf-8"));
|
|
9223
|
-
} catch {
|
|
9224
|
-
return null;
|
|
9225
|
-
}
|
|
9226
|
-
}
|
|
9227
|
-
function clearRuntimeFiles() {
|
|
9228
|
-
const files = getRuntimeFiles();
|
|
9229
|
-
rmSync(files.pid, { force: true });
|
|
9230
|
-
rmSync(files.state, { force: true });
|
|
9231
|
-
}
|
|
9232
|
-
function resolveConfigArgPath(pathValue) {
|
|
9233
|
-
return resolve2(pathValue);
|
|
9234
|
-
}
|
|
9235
|
-
var init_runtime = () => {};
|
|
9236
|
-
|
|
9237
|
-
// src/cli/autostart.ts
|
|
9238
|
-
import { execSync } from "child_process";
|
|
9239
|
-
import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync5, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
9240
|
-
import { homedir as homedir3, platform } from "os";
|
|
9241
|
-
import { dirname as dirname2, join as join4 } from "path";
|
|
9242
|
-
function getDaemonLogPath() {
|
|
9243
|
-
return getRuntimeDirs().logs + "/daemon.log";
|
|
9244
|
-
}
|
|
9245
|
-
function getLaunchAgentPath() {
|
|
9246
|
-
return join4(homedir3(), "Library", "LaunchAgents", `${LABEL}.plist`);
|
|
9247
|
-
}
|
|
9248
|
-
function buildPlist(opts) {
|
|
9249
|
-
const logPath = getDaemonLogPath();
|
|
9250
|
-
const args = [opts.execPath, ...opts.args].map((a) => ` <string>${escapeXml(a)}</string>`).join(`
|
|
9251
|
-
`);
|
|
9252
|
-
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
9253
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
9254
|
-
<plist version="1.0">
|
|
9255
|
-
<dict>
|
|
9256
|
-
<key>Label</key>
|
|
9257
|
-
<string>${escapeXml(opts.label)}</string>
|
|
9258
|
-
<key>ProgramArguments</key>
|
|
9259
|
-
<array>
|
|
9260
|
-
${args}
|
|
9261
|
-
</array>
|
|
9262
|
-
<key>RunAtLoad</key>
|
|
9263
|
-
<true/>
|
|
9264
|
-
<key>KeepAlive</key>
|
|
9265
|
-
<false/>
|
|
9266
|
-
<key>StandardOutPath</key>
|
|
9267
|
-
<string>${escapeXml(logPath)}</string>
|
|
9268
|
-
<key>StandardErrorPath</key>
|
|
9269
|
-
<string>${escapeXml(logPath)}</string>
|
|
9270
|
-
</dict>
|
|
9271
|
-
</plist>
|
|
9272
|
-
`;
|
|
9273
|
-
}
|
|
9274
|
-
function escapeXml(s) {
|
|
9275
|
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
9276
|
-
}
|
|
9277
|
-
function createMacosManager() {
|
|
9278
|
-
const plistPath = getLaunchAgentPath();
|
|
9279
|
-
return {
|
|
9280
|
-
platform: "macos",
|
|
9281
|
-
async isInstalled() {
|
|
9282
|
-
return existsSync3(plistPath);
|
|
9283
|
-
},
|
|
9284
|
-
async install(opts) {
|
|
9285
|
-
const dir = dirname2(plistPath);
|
|
9286
|
-
if (!existsSync3(dir))
|
|
9287
|
-
mkdirSync4(dir, { recursive: true });
|
|
9288
|
-
writeFileSync4(plistPath, buildPlist(opts), "utf-8");
|
|
9289
|
-
try {
|
|
9290
|
-
execSync(`launchctl bootout gui/$(id -u) ${plistPath} 2>/dev/null`, { stdio: "ignore" });
|
|
9291
|
-
} catch {}
|
|
9292
|
-
execSync(`launchctl bootstrap gui/$(id -u) ${plistPath}`, { stdio: "ignore" });
|
|
9293
|
-
},
|
|
9294
|
-
async uninstall() {
|
|
9295
|
-
if (!existsSync3(plistPath))
|
|
9296
|
-
return;
|
|
9297
|
-
try {
|
|
9298
|
-
execSync(`launchctl bootout gui/$(id -u) ${plistPath}`, { stdio: "ignore" });
|
|
9299
|
-
} catch {}
|
|
9300
|
-
rmSync2(plistPath, { force: true });
|
|
9301
|
-
},
|
|
9302
|
-
getServicePath() {
|
|
9303
|
-
return plistPath;
|
|
9304
|
-
}
|
|
9305
|
-
};
|
|
9306
|
-
}
|
|
9307
|
-
function getSystemdUnitPath() {
|
|
9308
|
-
return join4(homedir3(), ".config", "systemd", "user", "local-router.service");
|
|
9309
|
-
}
|
|
9310
|
-
function buildUnit(opts) {
|
|
9311
|
-
const logPath = getDaemonLogPath();
|
|
9312
|
-
const execStart = [opts.execPath, ...opts.args].join(" ");
|
|
9313
|
-
return `[Unit]
|
|
9314
|
-
Description=Local Router API Gateway
|
|
9315
|
-
After=network-online.target
|
|
9316
|
-
|
|
9317
|
-
[Service]
|
|
9318
|
-
Type=simple
|
|
9319
|
-
ExecStart=${execStart}
|
|
9320
|
-
Restart=on-failure
|
|
9321
|
-
RestartSec=5
|
|
9322
|
-
StandardOutput=append:${logPath}
|
|
9323
|
-
StandardError=append:${logPath}
|
|
9324
|
-
|
|
9325
|
-
[Install]
|
|
9326
|
-
WantedBy=default.target
|
|
9327
|
-
`;
|
|
9328
|
-
}
|
|
9329
|
-
function createLinuxManager() {
|
|
9330
|
-
const unitPath = getSystemdUnitPath();
|
|
9331
|
-
return {
|
|
9332
|
-
platform: "linux",
|
|
9333
|
-
async isInstalled() {
|
|
9334
|
-
if (!existsSync3(unitPath))
|
|
9335
|
-
return false;
|
|
9336
|
-
try {
|
|
9337
|
-
const out = execSync("systemctl --user is-enabled local-router 2>/dev/null", {
|
|
9338
|
-
encoding: "utf-8"
|
|
9339
|
-
}).trim();
|
|
9340
|
-
return out === "enabled";
|
|
9341
|
-
} catch {
|
|
9342
|
-
return false;
|
|
9343
|
-
}
|
|
9344
|
-
},
|
|
9345
|
-
async install(opts) {
|
|
9346
|
-
const dir = dirname2(unitPath);
|
|
9347
|
-
if (!existsSync3(dir))
|
|
9348
|
-
mkdirSync4(dir, { recursive: true });
|
|
9349
|
-
writeFileSync4(unitPath, buildUnit(opts), "utf-8");
|
|
9350
|
-
execSync("systemctl --user daemon-reload", { stdio: "ignore" });
|
|
9351
|
-
execSync("systemctl --user enable local-router", { stdio: "ignore" });
|
|
9352
|
-
},
|
|
9353
|
-
async uninstall() {
|
|
9354
|
-
try {
|
|
9355
|
-
execSync("systemctl --user disable local-router", { stdio: "ignore" });
|
|
9356
|
-
} catch {}
|
|
9357
|
-
rmSync2(unitPath, { force: true });
|
|
9358
|
-
try {
|
|
9359
|
-
execSync("systemctl --user daemon-reload", { stdio: "ignore" });
|
|
9360
|
-
} catch {}
|
|
9361
|
-
},
|
|
9362
|
-
getServicePath() {
|
|
9363
|
-
return unitPath;
|
|
9364
|
-
}
|
|
9365
|
-
};
|
|
9366
|
-
}
|
|
9367
|
-
function createWindowsManager() {
|
|
9368
|
-
return {
|
|
9369
|
-
platform: "windows",
|
|
9370
|
-
async isInstalled() {
|
|
9371
|
-
try {
|
|
9372
|
-
execSync(`reg query "${WIN_REG_KEY}" /v ${WIN_REG_VALUE}`, { stdio: "ignore" });
|
|
9373
|
-
return true;
|
|
9374
|
-
} catch {
|
|
9375
|
-
return false;
|
|
9376
|
-
}
|
|
9377
|
-
},
|
|
9378
|
-
async install(opts) {
|
|
9379
|
-
const cmd = [opts.execPath, ...opts.args].map((a) => `"${a}"`).join(" ");
|
|
9380
|
-
execSync(`reg add "${WIN_REG_KEY}" /v ${WIN_REG_VALUE} /t REG_SZ /d "${cmd}" /f`, {
|
|
9381
|
-
stdio: "ignore"
|
|
9382
|
-
});
|
|
9383
|
-
},
|
|
9384
|
-
async uninstall() {
|
|
9385
|
-
try {
|
|
9386
|
-
execSync(`reg delete "${WIN_REG_KEY}" /v ${WIN_REG_VALUE} /f`, { stdio: "ignore" });
|
|
9387
|
-
} catch {}
|
|
9388
|
-
},
|
|
9389
|
-
getServicePath() {
|
|
9390
|
-
return `${WIN_REG_KEY}\\${WIN_REG_VALUE}`;
|
|
9391
|
-
}
|
|
9392
|
-
};
|
|
9393
|
-
}
|
|
9394
|
-
function createUnsupportedManager() {
|
|
9395
|
-
return {
|
|
9396
|
-
platform: "unsupported",
|
|
9397
|
-
async isInstalled() {
|
|
9398
|
-
return false;
|
|
9399
|
-
},
|
|
9400
|
-
async install() {
|
|
9401
|
-
throw new Error("\u5F53\u524D\u5E73\u53F0\u4E0D\u652F\u6301\u81EA\u542F\u52A8");
|
|
9402
|
-
},
|
|
9403
|
-
async uninstall() {
|
|
9404
|
-
throw new Error("\u5F53\u524D\u5E73\u53F0\u4E0D\u652F\u6301\u81EA\u542F\u52A8");
|
|
9405
|
-
},
|
|
9406
|
-
getServicePath() {
|
|
9407
|
-
return "";
|
|
9408
|
-
}
|
|
9409
|
-
};
|
|
9410
|
-
}
|
|
9411
|
-
function createAutostartManager() {
|
|
9412
|
-
const p = platform();
|
|
9413
|
-
if (p === "darwin")
|
|
9414
|
-
return createMacosManager();
|
|
9415
|
-
if (p === "linux")
|
|
9416
|
-
return createLinuxManager();
|
|
9417
|
-
if (p === "win32")
|
|
9418
|
-
return createWindowsManager();
|
|
9419
|
-
return createUnsupportedManager();
|
|
9420
|
-
}
|
|
9421
|
-
function getAutostartExecArgs() {
|
|
9422
|
-
const script = process.argv[1] ?? "dist/cli.js";
|
|
9423
|
-
return {
|
|
9424
|
-
execPath: process.execPath,
|
|
9425
|
-
args: [script, "__run-server", "--mode", "daemon"]
|
|
9426
|
-
};
|
|
9427
|
-
}
|
|
9428
|
-
var LABEL = "com.lakphy.local-router", WIN_REG_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", WIN_REG_VALUE = "LocalRouter";
|
|
9429
|
-
var init_autostart = __esm(() => {
|
|
9430
|
-
init_runtime();
|
|
9431
|
-
});
|
|
9432
|
-
|
|
9433
9182
|
// node_modules/.bun/@ai-sdk+provider@3.0.8/node_modules/@ai-sdk/provider/dist/index.mjs
|
|
9434
9183
|
function getErrorMessage(error) {
|
|
9435
9184
|
if (error == null) {
|
|
@@ -27547,14 +27296,14 @@ async function delay(delayInMs, options) {
|
|
|
27547
27296
|
return Promise.resolve();
|
|
27548
27297
|
}
|
|
27549
27298
|
const signal = options == null ? undefined : options.abortSignal;
|
|
27550
|
-
return new Promise((
|
|
27299
|
+
return new Promise((resolve2, reject) => {
|
|
27551
27300
|
if (signal == null ? undefined : signal.aborted) {
|
|
27552
27301
|
reject(createAbortError());
|
|
27553
27302
|
return;
|
|
27554
27303
|
}
|
|
27555
27304
|
const timeoutId = setTimeout(() => {
|
|
27556
27305
|
cleanup();
|
|
27557
|
-
|
|
27306
|
+
resolve2();
|
|
27558
27307
|
}, delayInMs);
|
|
27559
27308
|
const cleanup = () => {
|
|
27560
27309
|
clearTimeout(timeoutId);
|
|
@@ -29012,7 +28761,7 @@ function createProviderToolFactoryWithOutputSchema({
|
|
|
29012
28761
|
supportsDeferredResults
|
|
29013
28762
|
});
|
|
29014
28763
|
}
|
|
29015
|
-
async function
|
|
28764
|
+
async function resolve2(value) {
|
|
29016
28765
|
if (typeof value === "function") {
|
|
29017
28766
|
value = value();
|
|
29018
28767
|
}
|
|
@@ -29051,13 +28800,13 @@ var DelayedPromise = class {
|
|
|
29051
28800
|
if (this._promise) {
|
|
29052
28801
|
return this._promise;
|
|
29053
28802
|
}
|
|
29054
|
-
this._promise = new Promise((
|
|
28803
|
+
this._promise = new Promise((resolve2, reject) => {
|
|
29055
28804
|
if (this.status.type === "resolved") {
|
|
29056
|
-
|
|
28805
|
+
resolve2(this.status.value);
|
|
29057
28806
|
} else if (this.status.type === "rejected") {
|
|
29058
28807
|
reject(this.status.error);
|
|
29059
28808
|
}
|
|
29060
|
-
this._resolve =
|
|
28809
|
+
this._resolve = resolve2;
|
|
29061
28810
|
this._reject = reject;
|
|
29062
28811
|
});
|
|
29063
28812
|
return this._promise;
|
|
@@ -31515,11 +31264,11 @@ var VERSION2 = "3.0.58", anthropicErrorDataSchema, anthropicFailedResponseHandle
|
|
|
31515
31264
|
betas,
|
|
31516
31265
|
headers
|
|
31517
31266
|
}) {
|
|
31518
|
-
return combineHeaders(await
|
|
31267
|
+
return combineHeaders(await resolve2(this.config.headers), headers, betas.size > 0 ? { "anthropic-beta": Array.from(betas).join(",") } : {});
|
|
31519
31268
|
}
|
|
31520
31269
|
async getBetasFromHeaders(requestHeaders) {
|
|
31521
31270
|
var _a16, _b16;
|
|
31522
|
-
const configHeaders = await
|
|
31271
|
+
const configHeaders = await resolve2(this.config.headers);
|
|
31523
31272
|
const configBetaHeader = (_a16 = configHeaders["anthropic-beta"]) != null ? _a16 : "";
|
|
31524
31273
|
const requestBetaHeader = (_b16 = requestHeaders == null ? undefined : requestHeaders["anthropic-beta"]) != null ? _b16 : "";
|
|
31525
31274
|
return new Set([
|
|
@@ -42350,7 +42099,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
|
|
|
42350
42099
|
try {
|
|
42351
42100
|
const { value } = await getFromApi({
|
|
42352
42101
|
url: `${this.config.baseURL}/config`,
|
|
42353
|
-
headers: await
|
|
42102
|
+
headers: await resolve2(this.config.headers()),
|
|
42354
42103
|
successfulResponseHandler: createJsonResponseHandler(gatewayAvailableModelsResponseSchema),
|
|
42355
42104
|
failedResponseHandler: createJsonErrorResponseHandler({
|
|
42356
42105
|
errorSchema: exports_external.any(),
|
|
@@ -42368,7 +42117,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
|
|
|
42368
42117
|
const baseUrl = new URL(this.config.baseURL);
|
|
42369
42118
|
const { value } = await getFromApi({
|
|
42370
42119
|
url: `${baseUrl.origin}/v1/credits`,
|
|
42371
|
-
headers: await
|
|
42120
|
+
headers: await resolve2(this.config.headers()),
|
|
42372
42121
|
successfulResponseHandler: createJsonResponseHandler(gatewayCreditsResponseSchema),
|
|
42373
42122
|
failedResponseHandler: createJsonErrorResponseHandler({
|
|
42374
42123
|
errorSchema: exports_external.any(),
|
|
@@ -42401,7 +42150,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
|
|
|
42401
42150
|
async doGenerate(options) {
|
|
42402
42151
|
const { args, warnings } = await this.getArgs(options);
|
|
42403
42152
|
const { abortSignal } = options;
|
|
42404
|
-
const resolvedHeaders = await
|
|
42153
|
+
const resolvedHeaders = await resolve2(this.config.headers());
|
|
42405
42154
|
try {
|
|
42406
42155
|
const {
|
|
42407
42156
|
responseHeaders,
|
|
@@ -42409,7 +42158,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
|
|
|
42409
42158
|
rawValue: rawResponse
|
|
42410
42159
|
} = await postJsonToApi({
|
|
42411
42160
|
url: this.getUrl(),
|
|
42412
|
-
headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, false), await
|
|
42161
|
+
headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, false), await resolve2(this.config.o11yHeaders)),
|
|
42413
42162
|
body: args,
|
|
42414
42163
|
successfulResponseHandler: createJsonResponseHandler(exports_external.any()),
|
|
42415
42164
|
failedResponseHandler: createJsonErrorResponseHandler({
|
|
@@ -42432,11 +42181,11 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
|
|
|
42432
42181
|
async doStream(options) {
|
|
42433
42182
|
const { args, warnings } = await this.getArgs(options);
|
|
42434
42183
|
const { abortSignal } = options;
|
|
42435
|
-
const resolvedHeaders = await
|
|
42184
|
+
const resolvedHeaders = await resolve2(this.config.headers());
|
|
42436
42185
|
try {
|
|
42437
42186
|
const { value: response, responseHeaders } = await postJsonToApi({
|
|
42438
42187
|
url: this.getUrl(),
|
|
42439
|
-
headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, true), await
|
|
42188
|
+
headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, true), await resolve2(this.config.o11yHeaders)),
|
|
42440
42189
|
body: args,
|
|
42441
42190
|
successfulResponseHandler: createEventSourceResponseHandler(exports_external.any()),
|
|
42442
42191
|
failedResponseHandler: createJsonErrorResponseHandler({
|
|
@@ -42521,7 +42270,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
|
|
|
42521
42270
|
providerOptions
|
|
42522
42271
|
}) {
|
|
42523
42272
|
var _a92;
|
|
42524
|
-
const resolvedHeaders = await
|
|
42273
|
+
const resolvedHeaders = await resolve2(this.config.headers());
|
|
42525
42274
|
try {
|
|
42526
42275
|
const {
|
|
42527
42276
|
responseHeaders,
|
|
@@ -42529,7 +42278,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
|
|
|
42529
42278
|
rawValue
|
|
42530
42279
|
} = await postJsonToApi({
|
|
42531
42280
|
url: this.getUrl(),
|
|
42532
|
-
headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await
|
|
42281
|
+
headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve2(this.config.o11yHeaders)),
|
|
42533
42282
|
body: {
|
|
42534
42283
|
values,
|
|
42535
42284
|
...providerOptions ? { providerOptions } : {}
|
|
@@ -42585,7 +42334,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
|
|
|
42585
42334
|
abortSignal
|
|
42586
42335
|
}) {
|
|
42587
42336
|
var _a92, _b92, _c, _d;
|
|
42588
|
-
const resolvedHeaders = await
|
|
42337
|
+
const resolvedHeaders = await resolve2(this.config.headers());
|
|
42589
42338
|
try {
|
|
42590
42339
|
const {
|
|
42591
42340
|
responseHeaders,
|
|
@@ -42593,7 +42342,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
|
|
|
42593
42342
|
rawValue
|
|
42594
42343
|
} = await postJsonToApi({
|
|
42595
42344
|
url: this.getUrl(),
|
|
42596
|
-
headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await
|
|
42345
|
+
headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve2(this.config.o11yHeaders)),
|
|
42597
42346
|
body: {
|
|
42598
42347
|
prompt,
|
|
42599
42348
|
n,
|
|
@@ -42668,11 +42417,11 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
|
|
|
42668
42417
|
abortSignal
|
|
42669
42418
|
}) {
|
|
42670
42419
|
var _a92;
|
|
42671
|
-
const resolvedHeaders = await
|
|
42420
|
+
const resolvedHeaders = await resolve2(this.config.headers());
|
|
42672
42421
|
try {
|
|
42673
42422
|
const { responseHeaders, value: responseBody } = await postJsonToApi({
|
|
42674
42423
|
url: this.getUrl(),
|
|
42675
|
-
headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await
|
|
42424
|
+
headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve2(this.config.o11yHeaders), { accept: "text/event-stream" }),
|
|
42676
42425
|
body: {
|
|
42677
42426
|
prompt,
|
|
42678
42427
|
n,
|
|
@@ -46662,8 +46411,8 @@ function writeToServerResponse({
|
|
|
46662
46411
|
break;
|
|
46663
46412
|
const canContinue = response.write(value);
|
|
46664
46413
|
if (!canContinue) {
|
|
46665
|
-
await new Promise((
|
|
46666
|
-
response.once("drain",
|
|
46414
|
+
await new Promise((resolve3) => {
|
|
46415
|
+
response.once("drain", resolve3);
|
|
46667
46416
|
});
|
|
46668
46417
|
}
|
|
46669
46418
|
}
|
|
@@ -47424,15 +47173,15 @@ async function consumeStream({
|
|
|
47424
47173
|
}
|
|
47425
47174
|
}
|
|
47426
47175
|
function createResolvablePromise() {
|
|
47427
|
-
let
|
|
47176
|
+
let resolve3;
|
|
47428
47177
|
let reject;
|
|
47429
47178
|
const promise2 = new Promise((res, rej) => {
|
|
47430
|
-
|
|
47179
|
+
resolve3 = res;
|
|
47431
47180
|
reject = rej;
|
|
47432
47181
|
});
|
|
47433
47182
|
return {
|
|
47434
47183
|
promise: promise2,
|
|
47435
|
-
resolve:
|
|
47184
|
+
resolve: resolve3,
|
|
47436
47185
|
reject
|
|
47437
47186
|
};
|
|
47438
47187
|
}
|
|
@@ -48014,7 +47763,7 @@ var import_api, import_api2, __defProp2, __export2 = (target, all) => {
|
|
|
48014
47763
|
const schema = asSchema(inputSchema);
|
|
48015
47764
|
return {
|
|
48016
47765
|
name: "object",
|
|
48017
|
-
responseFormat:
|
|
47766
|
+
responseFormat: resolve2(schema.jsonSchema).then((jsonSchema2) => ({
|
|
48018
47767
|
type: "json",
|
|
48019
47768
|
schema: jsonSchema2,
|
|
48020
47769
|
...name21 != null && { name: name21 },
|
|
@@ -48075,7 +47824,7 @@ var import_api, import_api2, __defProp2, __export2 = (target, all) => {
|
|
|
48075
47824
|
const elementSchema = asSchema(inputElementSchema);
|
|
48076
47825
|
return {
|
|
48077
47826
|
name: "array",
|
|
48078
|
-
responseFormat:
|
|
47827
|
+
responseFormat: resolve2(elementSchema.jsonSchema).then((jsonSchema2) => {
|
|
48079
47828
|
const { $schema, ...itemSchema } = jsonSchema2;
|
|
48080
47829
|
return {
|
|
48081
47830
|
type: "json",
|
|
@@ -52573,7 +52322,7 @@ var init_path = () => {};
|
|
|
52573
52322
|
var ENCODINGS, ENCODINGS_ORDERED_KEYS, DEFAULT_DOCUMENT = "index.html", serveStatic = (options) => {
|
|
52574
52323
|
const root = options.root ?? "./";
|
|
52575
52324
|
const optionPath = options.path;
|
|
52576
|
-
const
|
|
52325
|
+
const join3 = options.join ?? defaultJoin;
|
|
52577
52326
|
return async (c, next) => {
|
|
52578
52327
|
if (c.finalized) {
|
|
52579
52328
|
return next();
|
|
@@ -52592,9 +52341,9 @@ var ENCODINGS, ENCODINGS_ORDERED_KEYS, DEFAULT_DOCUMENT = "index.html", serveSta
|
|
|
52592
52341
|
return next();
|
|
52593
52342
|
}
|
|
52594
52343
|
}
|
|
52595
|
-
let path =
|
|
52344
|
+
let path = join3(root, !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename);
|
|
52596
52345
|
if (options.isDir && await options.isDir(path)) {
|
|
52597
|
-
path =
|
|
52346
|
+
path = join3(path, DEFAULT_DOCUMENT);
|
|
52598
52347
|
}
|
|
52599
52348
|
const getContent = options.getContent;
|
|
52600
52349
|
let content = await getContent(path, c);
|
|
@@ -52642,7 +52391,7 @@ var init_serve_static = __esm(() => {
|
|
|
52642
52391
|
|
|
52643
52392
|
// node_modules/.bun/hono@4.12.5/node_modules/hono/dist/adapter/bun/serve-static.js
|
|
52644
52393
|
import { stat } from "fs/promises";
|
|
52645
|
-
import { join as
|
|
52394
|
+
import { join as join3 } from "path";
|
|
52646
52395
|
var serveStatic2 = (options) => {
|
|
52647
52396
|
return async function serveStatic22(c, next) {
|
|
52648
52397
|
const getContent = async (path) => {
|
|
@@ -52660,7 +52409,7 @@ var serveStatic2 = (options) => {
|
|
|
52660
52409
|
return serveStatic({
|
|
52661
52410
|
...options,
|
|
52662
52411
|
getContent,
|
|
52663
|
-
join:
|
|
52412
|
+
join: join3,
|
|
52664
52413
|
isDir
|
|
52665
52414
|
})(c, next);
|
|
52666
52415
|
};
|
|
@@ -52826,6 +52575,257 @@ var init_bun = __esm(() => {
|
|
|
52826
52575
|
init_server();
|
|
52827
52576
|
});
|
|
52828
52577
|
|
|
52578
|
+
// src/cli/runtime.ts
|
|
52579
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync4, rmSync, writeFileSync as writeFileSync3 } from "fs";
|
|
52580
|
+
import { homedir as homedir2 } from "os";
|
|
52581
|
+
import { join as join4, resolve as resolve3 } from "path";
|
|
52582
|
+
function getRuntimeDirs() {
|
|
52583
|
+
const override = process.env.LOCAL_ROUTER_RUNTIME_DIR;
|
|
52584
|
+
const root = override?.trim() ? override.trim() : join4(homedir2(), ".local-router");
|
|
52585
|
+
return {
|
|
52586
|
+
root,
|
|
52587
|
+
run: join4(root, "run"),
|
|
52588
|
+
logs: join4(root, "logs")
|
|
52589
|
+
};
|
|
52590
|
+
}
|
|
52591
|
+
function getRuntimeFiles() {
|
|
52592
|
+
const dirs = getRuntimeDirs();
|
|
52593
|
+
return {
|
|
52594
|
+
pid: join4(dirs.run, "local-router.pid"),
|
|
52595
|
+
state: join4(dirs.run, "status.json"),
|
|
52596
|
+
daemonLog: join4(dirs.logs, "daemon.log")
|
|
52597
|
+
};
|
|
52598
|
+
}
|
|
52599
|
+
function ensureRuntimeDirs() {
|
|
52600
|
+
const dirs = getRuntimeDirs();
|
|
52601
|
+
mkdirSync3(dirs.root, { recursive: true });
|
|
52602
|
+
mkdirSync3(dirs.run, { recursive: true });
|
|
52603
|
+
mkdirSync3(dirs.logs, { recursive: true });
|
|
52604
|
+
}
|
|
52605
|
+
function writeRuntimeState(state) {
|
|
52606
|
+
ensureRuntimeDirs();
|
|
52607
|
+
const files = getRuntimeFiles();
|
|
52608
|
+
writeFileSync3(files.pid, `${state.pid}
|
|
52609
|
+
`, "utf-8");
|
|
52610
|
+
writeFileSync3(files.state, JSON.stringify(state, null, 2), "utf-8");
|
|
52611
|
+
}
|
|
52612
|
+
function readRuntimeState() {
|
|
52613
|
+
const files = getRuntimeFiles();
|
|
52614
|
+
if (!existsSync2(files.state)) {
|
|
52615
|
+
return null;
|
|
52616
|
+
}
|
|
52617
|
+
try {
|
|
52618
|
+
return JSON.parse(readFileSync4(files.state, "utf-8"));
|
|
52619
|
+
} catch {
|
|
52620
|
+
return null;
|
|
52621
|
+
}
|
|
52622
|
+
}
|
|
52623
|
+
function clearRuntimeFiles() {
|
|
52624
|
+
const files = getRuntimeFiles();
|
|
52625
|
+
rmSync(files.pid, { force: true });
|
|
52626
|
+
rmSync(files.state, { force: true });
|
|
52627
|
+
}
|
|
52628
|
+
function resolveConfigArgPath(pathValue) {
|
|
52629
|
+
return resolve3(pathValue);
|
|
52630
|
+
}
|
|
52631
|
+
var init_runtime = () => {};
|
|
52632
|
+
|
|
52633
|
+
// src/cli/autostart.ts
|
|
52634
|
+
import { execSync } from "child_process";
|
|
52635
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync5, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
52636
|
+
import { homedir as homedir3, platform } from "os";
|
|
52637
|
+
import { dirname as dirname3, join as join5 } from "path";
|
|
52638
|
+
function getDaemonLogPath() {
|
|
52639
|
+
return getRuntimeDirs().logs + "/daemon.log";
|
|
52640
|
+
}
|
|
52641
|
+
function getLaunchAgentPath() {
|
|
52642
|
+
return join5(homedir3(), "Library", "LaunchAgents", `${LABEL}.plist`);
|
|
52643
|
+
}
|
|
52644
|
+
function buildPlist(opts) {
|
|
52645
|
+
const logPath = getDaemonLogPath();
|
|
52646
|
+
const args = [opts.execPath, ...opts.args].map((a) => ` <string>${escapeXml(a)}</string>`).join(`
|
|
52647
|
+
`);
|
|
52648
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
52649
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
52650
|
+
<plist version="1.0">
|
|
52651
|
+
<dict>
|
|
52652
|
+
<key>Label</key>
|
|
52653
|
+
<string>${escapeXml(opts.label)}</string>
|
|
52654
|
+
<key>ProgramArguments</key>
|
|
52655
|
+
<array>
|
|
52656
|
+
${args}
|
|
52657
|
+
</array>
|
|
52658
|
+
<key>RunAtLoad</key>
|
|
52659
|
+
<true/>
|
|
52660
|
+
<key>KeepAlive</key>
|
|
52661
|
+
<false/>
|
|
52662
|
+
<key>StandardOutPath</key>
|
|
52663
|
+
<string>${escapeXml(logPath)}</string>
|
|
52664
|
+
<key>StandardErrorPath</key>
|
|
52665
|
+
<string>${escapeXml(logPath)}</string>
|
|
52666
|
+
</dict>
|
|
52667
|
+
</plist>
|
|
52668
|
+
`;
|
|
52669
|
+
}
|
|
52670
|
+
function escapeXml(s) {
|
|
52671
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
52672
|
+
}
|
|
52673
|
+
function createMacosManager() {
|
|
52674
|
+
const plistPath = getLaunchAgentPath();
|
|
52675
|
+
return {
|
|
52676
|
+
platform: "macos",
|
|
52677
|
+
async isInstalled() {
|
|
52678
|
+
return existsSync3(plistPath);
|
|
52679
|
+
},
|
|
52680
|
+
async install(opts) {
|
|
52681
|
+
const dir = dirname3(plistPath);
|
|
52682
|
+
if (!existsSync3(dir))
|
|
52683
|
+
mkdirSync4(dir, { recursive: true });
|
|
52684
|
+
writeFileSync4(plistPath, buildPlist(opts), "utf-8");
|
|
52685
|
+
try {
|
|
52686
|
+
execSync(`launchctl bootout gui/$(id -u) ${plistPath} 2>/dev/null`, { stdio: "ignore" });
|
|
52687
|
+
} catch {}
|
|
52688
|
+
execSync(`launchctl bootstrap gui/$(id -u) ${plistPath}`, { stdio: "ignore" });
|
|
52689
|
+
},
|
|
52690
|
+
async uninstall() {
|
|
52691
|
+
if (!existsSync3(plistPath))
|
|
52692
|
+
return;
|
|
52693
|
+
try {
|
|
52694
|
+
execSync(`launchctl bootout gui/$(id -u) ${plistPath}`, { stdio: "ignore" });
|
|
52695
|
+
} catch {}
|
|
52696
|
+
rmSync2(plistPath, { force: true });
|
|
52697
|
+
},
|
|
52698
|
+
getServicePath() {
|
|
52699
|
+
return plistPath;
|
|
52700
|
+
}
|
|
52701
|
+
};
|
|
52702
|
+
}
|
|
52703
|
+
function getSystemdUnitPath() {
|
|
52704
|
+
return join5(homedir3(), ".config", "systemd", "user", "local-router.service");
|
|
52705
|
+
}
|
|
52706
|
+
function buildUnit(opts) {
|
|
52707
|
+
const logPath = getDaemonLogPath();
|
|
52708
|
+
const execStart = [opts.execPath, ...opts.args].join(" ");
|
|
52709
|
+
return `[Unit]
|
|
52710
|
+
Description=Local Router API Gateway
|
|
52711
|
+
After=network-online.target
|
|
52712
|
+
|
|
52713
|
+
[Service]
|
|
52714
|
+
Type=simple
|
|
52715
|
+
ExecStart=${execStart}
|
|
52716
|
+
Restart=on-failure
|
|
52717
|
+
RestartSec=5
|
|
52718
|
+
StandardOutput=append:${logPath}
|
|
52719
|
+
StandardError=append:${logPath}
|
|
52720
|
+
|
|
52721
|
+
[Install]
|
|
52722
|
+
WantedBy=default.target
|
|
52723
|
+
`;
|
|
52724
|
+
}
|
|
52725
|
+
function createLinuxManager() {
|
|
52726
|
+
const unitPath = getSystemdUnitPath();
|
|
52727
|
+
return {
|
|
52728
|
+
platform: "linux",
|
|
52729
|
+
async isInstalled() {
|
|
52730
|
+
if (!existsSync3(unitPath))
|
|
52731
|
+
return false;
|
|
52732
|
+
try {
|
|
52733
|
+
const out = execSync("systemctl --user is-enabled local-router 2>/dev/null", {
|
|
52734
|
+
encoding: "utf-8"
|
|
52735
|
+
}).trim();
|
|
52736
|
+
return out === "enabled";
|
|
52737
|
+
} catch {
|
|
52738
|
+
return false;
|
|
52739
|
+
}
|
|
52740
|
+
},
|
|
52741
|
+
async install(opts) {
|
|
52742
|
+
const dir = dirname3(unitPath);
|
|
52743
|
+
if (!existsSync3(dir))
|
|
52744
|
+
mkdirSync4(dir, { recursive: true });
|
|
52745
|
+
writeFileSync4(unitPath, buildUnit(opts), "utf-8");
|
|
52746
|
+
execSync("systemctl --user daemon-reload", { stdio: "ignore" });
|
|
52747
|
+
execSync("systemctl --user enable local-router", { stdio: "ignore" });
|
|
52748
|
+
},
|
|
52749
|
+
async uninstall() {
|
|
52750
|
+
try {
|
|
52751
|
+
execSync("systemctl --user disable local-router", { stdio: "ignore" });
|
|
52752
|
+
} catch {}
|
|
52753
|
+
rmSync2(unitPath, { force: true });
|
|
52754
|
+
try {
|
|
52755
|
+
execSync("systemctl --user daemon-reload", { stdio: "ignore" });
|
|
52756
|
+
} catch {}
|
|
52757
|
+
},
|
|
52758
|
+
getServicePath() {
|
|
52759
|
+
return unitPath;
|
|
52760
|
+
}
|
|
52761
|
+
};
|
|
52762
|
+
}
|
|
52763
|
+
function createWindowsManager() {
|
|
52764
|
+
return {
|
|
52765
|
+
platform: "windows",
|
|
52766
|
+
async isInstalled() {
|
|
52767
|
+
try {
|
|
52768
|
+
execSync(`reg query "${WIN_REG_KEY}" /v ${WIN_REG_VALUE}`, { stdio: "ignore" });
|
|
52769
|
+
return true;
|
|
52770
|
+
} catch {
|
|
52771
|
+
return false;
|
|
52772
|
+
}
|
|
52773
|
+
},
|
|
52774
|
+
async install(opts) {
|
|
52775
|
+
const cmd = [opts.execPath, ...opts.args].map((a) => `"${a}"`).join(" ");
|
|
52776
|
+
execSync(`reg add "${WIN_REG_KEY}" /v ${WIN_REG_VALUE} /t REG_SZ /d "${cmd}" /f`, {
|
|
52777
|
+
stdio: "ignore"
|
|
52778
|
+
});
|
|
52779
|
+
},
|
|
52780
|
+
async uninstall() {
|
|
52781
|
+
try {
|
|
52782
|
+
execSync(`reg delete "${WIN_REG_KEY}" /v ${WIN_REG_VALUE} /f`, { stdio: "ignore" });
|
|
52783
|
+
} catch {}
|
|
52784
|
+
},
|
|
52785
|
+
getServicePath() {
|
|
52786
|
+
return `${WIN_REG_KEY}\\${WIN_REG_VALUE}`;
|
|
52787
|
+
}
|
|
52788
|
+
};
|
|
52789
|
+
}
|
|
52790
|
+
function createUnsupportedManager() {
|
|
52791
|
+
return {
|
|
52792
|
+
platform: "unsupported",
|
|
52793
|
+
async isInstalled() {
|
|
52794
|
+
return false;
|
|
52795
|
+
},
|
|
52796
|
+
async install() {
|
|
52797
|
+
throw new Error("\u5F53\u524D\u5E73\u53F0\u4E0D\u652F\u6301\u81EA\u542F\u52A8");
|
|
52798
|
+
},
|
|
52799
|
+
async uninstall() {
|
|
52800
|
+
throw new Error("\u5F53\u524D\u5E73\u53F0\u4E0D\u652F\u6301\u81EA\u542F\u52A8");
|
|
52801
|
+
},
|
|
52802
|
+
getServicePath() {
|
|
52803
|
+
return "";
|
|
52804
|
+
}
|
|
52805
|
+
};
|
|
52806
|
+
}
|
|
52807
|
+
function createAutostartManager() {
|
|
52808
|
+
const p = platform();
|
|
52809
|
+
if (p === "darwin")
|
|
52810
|
+
return createMacosManager();
|
|
52811
|
+
if (p === "linux")
|
|
52812
|
+
return createLinuxManager();
|
|
52813
|
+
if (p === "win32")
|
|
52814
|
+
return createWindowsManager();
|
|
52815
|
+
return createUnsupportedManager();
|
|
52816
|
+
}
|
|
52817
|
+
function getAutostartExecArgs() {
|
|
52818
|
+
const script = process.argv[1] ?? "dist/cli.js";
|
|
52819
|
+
return {
|
|
52820
|
+
execPath: process.execPath,
|
|
52821
|
+
args: [script, "__run-server", "--mode", "daemon"]
|
|
52822
|
+
};
|
|
52823
|
+
}
|
|
52824
|
+
var LABEL = "com.lakphy.local-router", WIN_REG_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", WIN_REG_VALUE = "LocalRouter";
|
|
52825
|
+
var init_autostart = __esm(() => {
|
|
52826
|
+
init_runtime();
|
|
52827
|
+
});
|
|
52828
|
+
|
|
52829
52829
|
// src/config-store.ts
|
|
52830
52830
|
import { writeFileSync as writeFileSync5 } from "fs";
|
|
52831
52831
|
import { resolve as resolve4 } from "path";
|
|
@@ -57455,6 +57455,97 @@ var init_openapi = __esm(() => {
|
|
|
57455
57455
|
}
|
|
57456
57456
|
}
|
|
57457
57457
|
},
|
|
57458
|
+
"/api/models": {
|
|
57459
|
+
get: {
|
|
57460
|
+
tags: ["Health"],
|
|
57461
|
+
summary: "\u55C5\u63A2\u53EF\u7528\u6A21\u578B\u8DEF\u7531",
|
|
57462
|
+
description: "\u8FD4\u56DE\u672C\u673A\u6307\u5B9A\u534F\u8BAE\u4E0B\u53EF\u7528\u7684\u6A21\u578B\u8DEF\u7531\u522B\u540D\uFF08routes[protocol] \u7684 key\uFF0C\u6392\u9664 * \u901A\u914D\uFF09\u3002\u4F9B\u5C40\u57DF\u7F51\u5185\u5176\u4ED6 local-router \u63A2\u6D4B\u4F7F\u7528\u3002",
|
|
57463
|
+
parameters: [
|
|
57464
|
+
{
|
|
57465
|
+
name: "protocol",
|
|
57466
|
+
in: "query",
|
|
57467
|
+
required: true,
|
|
57468
|
+
schema: {
|
|
57469
|
+
type: "string",
|
|
57470
|
+
enum: ["openai-completions", "openai-responses", "anthropic-messages"]
|
|
57471
|
+
},
|
|
57472
|
+
description: "\u534F\u8BAE\u7C7B\u578B"
|
|
57473
|
+
}
|
|
57474
|
+
],
|
|
57475
|
+
responses: {
|
|
57476
|
+
"200": {
|
|
57477
|
+
description: "\u53EF\u7528\u6A21\u578B\u8DEF\u7531\u5217\u8868",
|
|
57478
|
+
content: {
|
|
57479
|
+
"application/json": {
|
|
57480
|
+
schema: {
|
|
57481
|
+
type: "object",
|
|
57482
|
+
properties: {
|
|
57483
|
+
protocol: { type: "string", example: "anthropic-messages" },
|
|
57484
|
+
models: {
|
|
57485
|
+
type: "array",
|
|
57486
|
+
items: { type: "string" },
|
|
57487
|
+
example: ["claude-3-5-sonnet", "claude-3-opus"]
|
|
57488
|
+
}
|
|
57489
|
+
}
|
|
57490
|
+
}
|
|
57491
|
+
}
|
|
57492
|
+
}
|
|
57493
|
+
},
|
|
57494
|
+
"400": { description: "\u534F\u8BAE\u53C2\u6570\u7F3A\u5931\u6216\u65E0\u6548" }
|
|
57495
|
+
}
|
|
57496
|
+
}
|
|
57497
|
+
},
|
|
57498
|
+
"/api/providers/discover": {
|
|
57499
|
+
get: {
|
|
57500
|
+
tags: ["Health"],
|
|
57501
|
+
summary: "\u53D1\u73B0\u5C40\u57DF\u7F51 local-router \u7684\u6A21\u578B",
|
|
57502
|
+
description: "\u7531\u672C\u673A server \u4EE3\u4E3A\u8BF7\u6C42\u5BF9\u7AEF local-router \u7684 /api/models\uFF08\u89C4\u907F\u6D4F\u89C8\u5668\u8DE8\u57DF\uFF09\uFF0C\u8FD4\u56DE\u5BF9\u7AEF\u67D0\u534F\u8BAE\u4E0B\u7684\u53EF\u7528\u6A21\u578B\u8DEF\u7531\u3002",
|
|
57503
|
+
parameters: [
|
|
57504
|
+
{
|
|
57505
|
+
name: "ip",
|
|
57506
|
+
in: "query",
|
|
57507
|
+
required: true,
|
|
57508
|
+
schema: { type: "string" },
|
|
57509
|
+
description: "\u5BF9\u7AEF IP"
|
|
57510
|
+
},
|
|
57511
|
+
{
|
|
57512
|
+
name: "port",
|
|
57513
|
+
in: "query",
|
|
57514
|
+
required: false,
|
|
57515
|
+
schema: { type: "string", default: "4099" },
|
|
57516
|
+
description: "\u5BF9\u7AEF\u7AEF\u53E3\uFF0C\u9ED8\u8BA4 4099"
|
|
57517
|
+
},
|
|
57518
|
+
{
|
|
57519
|
+
name: "protocol",
|
|
57520
|
+
in: "query",
|
|
57521
|
+
required: true,
|
|
57522
|
+
schema: {
|
|
57523
|
+
type: "string",
|
|
57524
|
+
enum: ["openai-completions", "openai-responses", "anthropic-messages"]
|
|
57525
|
+
},
|
|
57526
|
+
description: "\u534F\u8BAE\u7C7B\u578B"
|
|
57527
|
+
}
|
|
57528
|
+
],
|
|
57529
|
+
responses: {
|
|
57530
|
+
"200": {
|
|
57531
|
+
description: "\u5BF9\u7AEF\u53EF\u7528\u6A21\u578B\u8DEF\u7531\u5217\u8868",
|
|
57532
|
+
content: {
|
|
57533
|
+
"application/json": {
|
|
57534
|
+
schema: {
|
|
57535
|
+
type: "object",
|
|
57536
|
+
properties: {
|
|
57537
|
+
protocol: { type: "string", example: "anthropic-messages" },
|
|
57538
|
+
models: { type: "array", items: { type: "string" } }
|
|
57539
|
+
}
|
|
57540
|
+
}
|
|
57541
|
+
}
|
|
57542
|
+
}
|
|
57543
|
+
},
|
|
57544
|
+
"400": { description: "\u53C2\u6570\u7F3A\u5931" },
|
|
57545
|
+
"502": { description: "\u65E0\u6CD5\u8FDE\u63A5\u5BF9\u7AEF\u6216\u5BF9\u7AEF\u8FD4\u56DE\u9519\u8BEF" }
|
|
57546
|
+
}
|
|
57547
|
+
}
|
|
57548
|
+
},
|
|
57458
57549
|
"/api/metrics/logs": {
|
|
57459
57550
|
get: {
|
|
57460
57551
|
tags: ["Health"],
|
|
@@ -59452,6 +59543,43 @@ function createAdminApiRoutes(store, pluginManager, registerCleanup) {
|
|
|
59452
59543
|
routeTypes: Object.keys(ROUTE_REGISTRY)
|
|
59453
59544
|
});
|
|
59454
59545
|
});
|
|
59546
|
+
api2.get("/models", (c) => {
|
|
59547
|
+
const protocol = c.req.query("protocol");
|
|
59548
|
+
const routeTypes = Object.keys(ROUTE_REGISTRY);
|
|
59549
|
+
if (!protocol || !routeTypes.includes(protocol)) {
|
|
59550
|
+
return c.json({ error: "invalid or missing protocol", routeTypes }, 400);
|
|
59551
|
+
}
|
|
59552
|
+
const routes = store.get().routes[protocol] ?? {};
|
|
59553
|
+
const models = Object.keys(routes).filter((k) => k !== "*");
|
|
59554
|
+
return c.json({ protocol, models });
|
|
59555
|
+
});
|
|
59556
|
+
api2.get("/providers/discover", async (c) => {
|
|
59557
|
+
const ip = c.req.query("ip");
|
|
59558
|
+
const portStr = c.req.query("port") ?? "4099";
|
|
59559
|
+
const protocol = c.req.query("protocol");
|
|
59560
|
+
if (!ip || !protocol) {
|
|
59561
|
+
return c.json({ error: "ip and protocol are required" }, 400);
|
|
59562
|
+
}
|
|
59563
|
+
const port = Number(portStr);
|
|
59564
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
59565
|
+
return c.json({ error: "\u7AEF\u53E3\u65E0\u6548\uFF0C\u5FC5\u987B\u662F 1-65535 \u7684\u6574\u6570" }, 400);
|
|
59566
|
+
}
|
|
59567
|
+
if (!isLoopbackAddress(ip) && !isLanAddress(ip)) {
|
|
59568
|
+
return c.json({ error: "\u4EC5\u652F\u6301\u5C40\u57DF\u7F51\u6216\u672C\u673A IP \u5730\u5740" }, 400);
|
|
59569
|
+
}
|
|
59570
|
+
const url2 = `http://${ip}:${port}/api/models?protocol=${encodeURIComponent(protocol)}`;
|
|
59571
|
+
try {
|
|
59572
|
+
const res = await fetch(url2, { signal: AbortSignal.timeout(5000) });
|
|
59573
|
+
if (!res.ok) {
|
|
59574
|
+
const body = await res.json().catch(() => ({}));
|
|
59575
|
+
return c.json({ error: body.error ?? `remote returned ${res.status}` }, 502);
|
|
59576
|
+
}
|
|
59577
|
+
const data = await res.json();
|
|
59578
|
+
return c.json(data);
|
|
59579
|
+
} catch (err) {
|
|
59580
|
+
return c.json({ error: `\u65E0\u6CD5\u8FDE\u63A5\u5BF9\u7AEF local-router: ${err instanceof Error ? err.message : err}` }, 502);
|
|
59581
|
+
}
|
|
59582
|
+
});
|
|
59455
59583
|
api2.get("/config/schema", (c) => {
|
|
59456
59584
|
try {
|
|
59457
59585
|
return c.json(schemaJson);
|
|
@@ -60035,7 +60163,6 @@ async function createAppRuntimeFromConfigPath(configPath, listen) {
|
|
|
60035
60163
|
}
|
|
60036
60164
|
var ROUTE_REGISTRY;
|
|
60037
60165
|
var init_src = __esm(() => {
|
|
60038
|
-
init_autostart();
|
|
60039
60166
|
init_dist4();
|
|
60040
60167
|
init_dist5();
|
|
60041
60168
|
init_dist6();
|
|
@@ -60043,6 +60170,7 @@ var init_src = __esm(() => {
|
|
|
60043
60170
|
init_dist9();
|
|
60044
60171
|
init_dist10();
|
|
60045
60172
|
init_bun();
|
|
60173
|
+
init_autostart();
|
|
60046
60174
|
init_config();
|
|
60047
60175
|
init_config_store();
|
|
60048
60176
|
init_config_validate();
|
|
@@ -61537,6 +61665,7 @@ Commands:
|
|
|
61537
61665
|
config provider list [--json] [--config <path>]
|
|
61538
61666
|
config provider show <name> [--show-secrets] [--config <path>]
|
|
61539
61667
|
config provider add <name> --type <type> --base <url> --api-key <key> --model <name> [--image-input] [--reasoning] [--proxy <url>] [--dry-run] [--config <path>]
|
|
61668
|
+
config provider add-lan <ip> --type <protocol> [--port 4099] [--dry-run] [--config <path>]
|
|
61540
61669
|
config provider set <name> [--base <url>] [--api-key <key>] [--proxy <url>] [--dry-run] [--config <path>]
|
|
61541
61670
|
config provider remove <name> [--force] [--dry-run] [--config <path>]
|
|
61542
61671
|
config provider model list <provider> [--config <path>]
|
|
@@ -61716,6 +61845,89 @@ async function handleProviderAdd(args, flags) {
|
|
|
61716
61845
|
}
|
|
61717
61846
|
});
|
|
61718
61847
|
}
|
|
61848
|
+
async function handleProviderAddLan(args, flags) {
|
|
61849
|
+
return runCommand({
|
|
61850
|
+
command: "config.provider.add-lan",
|
|
61851
|
+
flags,
|
|
61852
|
+
fn: async (ctx) => {
|
|
61853
|
+
const [ip, ...flagArgs] = args;
|
|
61854
|
+
ensureNoFlag("ip", ip);
|
|
61855
|
+
if (!ip) {
|
|
61856
|
+
throw new CliError("USAGE_ERROR", "ip \u5FC5\u586B", {
|
|
61857
|
+
hint: "\u7528\u6CD5: config provider add-lan <ip> --type <protocol> [--port 4099]"
|
|
61858
|
+
});
|
|
61859
|
+
}
|
|
61860
|
+
const parsed = parseArgs3({
|
|
61861
|
+
args: flagArgs,
|
|
61862
|
+
options: {
|
|
61863
|
+
type: { type: "string" },
|
|
61864
|
+
port: { type: "string", default: "4099" },
|
|
61865
|
+
"dry-run": { type: "boolean", default: false },
|
|
61866
|
+
config: { type: "string" }
|
|
61867
|
+
},
|
|
61868
|
+
allowPositionals: true,
|
|
61869
|
+
strict: false
|
|
61870
|
+
});
|
|
61871
|
+
const type = parsed.values.type;
|
|
61872
|
+
if (!type || !providerTypes().includes(type)) {
|
|
61873
|
+
throw new CliError("USAGE_ERROR", "type \u5FC5\u586B\u4E14\u5FC5\u987B\u662F openai-completions/openai-responses/anthropic-messages", { details: { acceptable: providerTypes() } });
|
|
61874
|
+
}
|
|
61875
|
+
const portStr = parsed.values.port ?? "4099";
|
|
61876
|
+
const port = Number(portStr);
|
|
61877
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
61878
|
+
throw new CliError("USAGE_ERROR", `\u7AEF\u53E3\u65E0\u6548: ${portStr}\uFF08\u5FC5\u987B\u662F 1-65535 \u7684\u6574\u6570\uFF09`);
|
|
61879
|
+
}
|
|
61880
|
+
const name21 = `${ip}-${type}`;
|
|
61881
|
+
const { path, config: config2 } = readConfig(parsed.values.config);
|
|
61882
|
+
if (config2.providers[name21]) {
|
|
61883
|
+
throw new CliError("PROVIDER_EXISTS", `provider \u5DF2\u5B58\u5728: ${name21}`, {
|
|
61884
|
+
hint: "\u4F7F\u7528 `config provider set` \u4FEE\u6539\u5B57\u6BB5"
|
|
61885
|
+
});
|
|
61886
|
+
}
|
|
61887
|
+
const url2 = `http://${ip}:${port}/api/models?protocol=${encodeURIComponent(type)}`;
|
|
61888
|
+
let models;
|
|
61889
|
+
try {
|
|
61890
|
+
const res = await fetch(url2, { signal: AbortSignal.timeout(5000) });
|
|
61891
|
+
if (!res.ok) {
|
|
61892
|
+
const body = await res.json().catch(() => ({}));
|
|
61893
|
+
throw new CliError("UPSTREAM_UNREACHABLE", `\u5BF9\u7AEF\u8FD4\u56DE\u9519\u8BEF: ${body.error ?? res.status}`, {
|
|
61894
|
+
details: { url: url2 }
|
|
61895
|
+
});
|
|
61896
|
+
}
|
|
61897
|
+
const data = await res.json();
|
|
61898
|
+
models = Array.isArray(data.models) ? data.models : [];
|
|
61899
|
+
} catch (err) {
|
|
61900
|
+
if (err instanceof CliError)
|
|
61901
|
+
throw err;
|
|
61902
|
+
throw new CliError("UPSTREAM_UNREACHABLE", `\u65E0\u6CD5\u8FDE\u63A5\u5BF9\u7AEF local-router: ${err instanceof Error ? err.message : err}`, { details: { url: url2 } });
|
|
61903
|
+
}
|
|
61904
|
+
if (models.length === 0) {
|
|
61905
|
+
throw new CliError("USAGE_ERROR", `\u5BF9\u7AEF\u5728\u534F\u8BAE "${type}" \u4E0B\u6CA1\u6709\u53EF\u7528\u7684\u6A21\u578B\u8DEF\u7531\uFF0C\u65E0\u6CD5\u521B\u5EFA provider`, { hint: "\u786E\u8BA4\u5BF9\u7AEF\u5DF2\u4E3A\u8BE5\u534F\u8BAE\u914D\u7F6E\u4E86\u5177\u4F53\u6A21\u578B\u8DEF\u7531\uFF08\u800C\u975E\u4EC5 * \u515C\u5E95\uFF09" });
|
|
61906
|
+
}
|
|
61907
|
+
const modelMap = {};
|
|
61908
|
+
for (const m of models) {
|
|
61909
|
+
modelMap[m] = { "image-input": false, reasoning: false };
|
|
61910
|
+
}
|
|
61911
|
+
config2.providers[name21] = {
|
|
61912
|
+
type,
|
|
61913
|
+
base: `http://${ip}:${port}/${type}`,
|
|
61914
|
+
apiKey: "no_key",
|
|
61915
|
+
models: modelMap
|
|
61916
|
+
};
|
|
61917
|
+
const result = applyConfigChange(path, config2, { dryRun: parsed.values["dry-run"] });
|
|
61918
|
+
emitResult(ctx, {
|
|
61919
|
+
command: "config.provider.add-lan",
|
|
61920
|
+
data: { provider: name21, models: models.length, ...result },
|
|
61921
|
+
md: {
|
|
61922
|
+
heading: `config.provider.add-lan \xB7 ${name21} \xB7 ${result.written ? "\u2713" : "dry-run"}`,
|
|
61923
|
+
data: applyResultToMd(result, `provider ${name21} (${models.length} \u4E2A\u6A21\u578B)`),
|
|
61924
|
+
hints: result.written ? ["\u70ED\u52A0\u8F7D: `local-router config apply`"] : ["\u6267\u884C\u5199\u5165: \u53BB\u6389 `--dry-run`"]
|
|
61925
|
+
},
|
|
61926
|
+
text: result.written ? `\u5DF2\u6DFB\u52A0 provider: ${name21}\uFF08\u55C5\u63A2\u5230 ${models.length} \u4E2A\u6A21\u578B\uFF09` : applyResultToText(result)
|
|
61927
|
+
});
|
|
61928
|
+
}
|
|
61929
|
+
});
|
|
61930
|
+
}
|
|
61719
61931
|
async function handleProviderSet(args, flags) {
|
|
61720
61932
|
return runCommand({
|
|
61721
61933
|
command: "config.provider.set",
|
|
@@ -62338,6 +62550,8 @@ async function handleProvider(args, flags) {
|
|
|
62338
62550
|
return handleProviderShow(rest, flags);
|
|
62339
62551
|
case "add":
|
|
62340
62552
|
return handleProviderAdd(rest, flags);
|
|
62553
|
+
case "add-lan":
|
|
62554
|
+
return handleProviderAddLan(rest, flags);
|
|
62341
62555
|
case "set":
|
|
62342
62556
|
return handleProviderSet(rest, flags);
|
|
62343
62557
|
case "remove":
|
|
@@ -62445,7 +62659,11 @@ async function dispatchConfig(group, rest, flags) {
|
|
|
62445
62659
|
init_registry();
|
|
62446
62660
|
var PROVIDER_TYPE_ENUM = ["openai-completions", "openai-responses", "anthropic-messages"];
|
|
62447
62661
|
var COMMON_CONFIG_FLAG = { name: "config", type: "string", description: "\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84" };
|
|
62448
|
-
var DRY_RUN_FLAG = {
|
|
62662
|
+
var DRY_RUN_FLAG = {
|
|
62663
|
+
name: "dry-run",
|
|
62664
|
+
type: "boolean",
|
|
62665
|
+
description: "\u53EA\u9884\u89C8 diff\uFF0C\u4E0D\u5199\u5165"
|
|
62666
|
+
};
|
|
62449
62667
|
function forward(prefix) {
|
|
62450
62668
|
return async (args, flags) => cmdConfig([...prefix, ...args], flags);
|
|
62451
62669
|
}
|
|
@@ -62462,10 +62680,7 @@ defineCommand({
|
|
|
62462
62680
|
defineCommand({
|
|
62463
62681
|
name: "config diff",
|
|
62464
62682
|
summary: "\u4E0E\u5907\u4EFD\u6216\u6307\u5B9A\u6587\u4EF6\u5BF9\u6BD4",
|
|
62465
|
-
flags: [
|
|
62466
|
-
{ name: "against", type: "string", description: "\u5907\u4EFD id \u6216\u8DEF\u5F84" },
|
|
62467
|
-
COMMON_CONFIG_FLAG
|
|
62468
|
-
],
|
|
62683
|
+
flags: [{ name: "against", type: "string", description: "\u5907\u4EFD id \u6216\u8DEF\u5F84" }, COMMON_CONFIG_FLAG],
|
|
62469
62684
|
supportsJson: true,
|
|
62470
62685
|
handler: forward(["diff"])
|
|
62471
62686
|
});
|
|
@@ -62579,6 +62794,26 @@ defineCommand({
|
|
|
62579
62794
|
supportsJson: true,
|
|
62580
62795
|
handler: forward(["provider", "add"])
|
|
62581
62796
|
});
|
|
62797
|
+
defineCommand({
|
|
62798
|
+
name: "config provider add-lan",
|
|
62799
|
+
summary: "\u4ECE\u5C40\u57DF\u7F51\u5185\u5176\u4ED6 local-router \u55C5\u63A2\u5E76\u65B0\u589E provider",
|
|
62800
|
+
positionals: [{ name: "ip", required: true, description: "\u5BF9\u7AEF IP" }],
|
|
62801
|
+
flags: [
|
|
62802
|
+
{
|
|
62803
|
+
name: "type",
|
|
62804
|
+
type: "enum",
|
|
62805
|
+
enum: [...PROVIDER_TYPE_ENUM],
|
|
62806
|
+
required: true,
|
|
62807
|
+
description: "\u534F\u8BAE\u7C7B\u578B"
|
|
62808
|
+
},
|
|
62809
|
+
{ name: "port", type: "string", description: "\u5BF9\u7AEF\u7AEF\u53E3\uFF08\u9ED8\u8BA4 4099\uFF09" },
|
|
62810
|
+
DRY_RUN_FLAG,
|
|
62811
|
+
COMMON_CONFIG_FLAG
|
|
62812
|
+
],
|
|
62813
|
+
mutates: true,
|
|
62814
|
+
supportsJson: true,
|
|
62815
|
+
handler: forward(["provider", "add-lan"])
|
|
62816
|
+
});
|
|
62582
62817
|
defineCommand({
|
|
62583
62818
|
name: "config provider set",
|
|
62584
62819
|
summary: "\u4FEE\u6539 provider \u5B57\u6BB5",
|
|
@@ -62664,10 +62899,7 @@ defineCommand({
|
|
|
62664
62899
|
defineCommand({
|
|
62665
62900
|
name: "config route list",
|
|
62666
62901
|
summary: "\u5217\u51FA\u6240\u6709\u8DEF\u7531",
|
|
62667
|
-
flags: [
|
|
62668
|
-
{ name: "entry", type: "string", description: "\u53EA\u770B\u67D0\u5165\u53E3" },
|
|
62669
|
-
COMMON_CONFIG_FLAG
|
|
62670
|
-
],
|
|
62902
|
+
flags: [{ name: "entry", type: "string", description: "\u53EA\u770B\u67D0\u5165\u53E3" }, COMMON_CONFIG_FLAG],
|
|
62671
62903
|
supportsJson: true,
|
|
62672
62904
|
handler: forward(["route", "list"])
|
|
62673
62905
|
});
|