@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/dist/entry.js CHANGED
@@ -9287,216 +9287,6 @@ var require_dist2 = __commonJS((exports, module) => {
9287
9287
  import { readFileSync as readFileSync6 } from "fs";
9288
9288
  import { dirname as dirname3, resolve as resolve8 } from "path";
9289
9289
 
9290
- // src/cli/autostart.ts
9291
- import { execSync } from "child_process";
9292
- import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
9293
- import { homedir as homedir2, platform } from "os";
9294
- import { dirname, join as join2 } from "path";
9295
-
9296
- // src/cli/runtime.ts
9297
- import { homedir } from "os";
9298
- import { join, resolve } from "path";
9299
- function getRuntimeDirs() {
9300
- const override = process.env.LOCAL_ROUTER_RUNTIME_DIR;
9301
- const root = override?.trim() ? override.trim() : join(homedir(), ".local-router");
9302
- return {
9303
- root,
9304
- run: join(root, "run"),
9305
- logs: join(root, "logs")
9306
- };
9307
- }
9308
-
9309
- // src/cli/autostart.ts
9310
- var LABEL = "com.lakphy.local-router";
9311
- function getDaemonLogPath() {
9312
- return getRuntimeDirs().logs + "/daemon.log";
9313
- }
9314
- function getLaunchAgentPath() {
9315
- return join2(homedir2(), "Library", "LaunchAgents", `${LABEL}.plist`);
9316
- }
9317
- function buildPlist(opts) {
9318
- const logPath = getDaemonLogPath();
9319
- const args = [opts.execPath, ...opts.args].map((a) => ` <string>${escapeXml(a)}</string>`).join(`
9320
- `);
9321
- return `<?xml version="1.0" encoding="UTF-8"?>
9322
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
9323
- <plist version="1.0">
9324
- <dict>
9325
- <key>Label</key>
9326
- <string>${escapeXml(opts.label)}</string>
9327
- <key>ProgramArguments</key>
9328
- <array>
9329
- ${args}
9330
- </array>
9331
- <key>RunAtLoad</key>
9332
- <true/>
9333
- <key>KeepAlive</key>
9334
- <false/>
9335
- <key>StandardOutPath</key>
9336
- <string>${escapeXml(logPath)}</string>
9337
- <key>StandardErrorPath</key>
9338
- <string>${escapeXml(logPath)}</string>
9339
- </dict>
9340
- </plist>
9341
- `;
9342
- }
9343
- function escapeXml(s) {
9344
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
9345
- }
9346
- function createMacosManager() {
9347
- const plistPath = getLaunchAgentPath();
9348
- return {
9349
- platform: "macos",
9350
- async isInstalled() {
9351
- return existsSync(plistPath);
9352
- },
9353
- async install(opts) {
9354
- const dir = dirname(plistPath);
9355
- if (!existsSync(dir))
9356
- mkdirSync(dir, { recursive: true });
9357
- writeFileSync(plistPath, buildPlist(opts), "utf-8");
9358
- try {
9359
- execSync(`launchctl bootout gui/$(id -u) ${plistPath} 2>/dev/null`, { stdio: "ignore" });
9360
- } catch {}
9361
- execSync(`launchctl bootstrap gui/$(id -u) ${plistPath}`, { stdio: "ignore" });
9362
- },
9363
- async uninstall() {
9364
- if (!existsSync(plistPath))
9365
- return;
9366
- try {
9367
- execSync(`launchctl bootout gui/$(id -u) ${plistPath}`, { stdio: "ignore" });
9368
- } catch {}
9369
- rmSync(plistPath, { force: true });
9370
- },
9371
- getServicePath() {
9372
- return plistPath;
9373
- }
9374
- };
9375
- }
9376
- function getSystemdUnitPath() {
9377
- return join2(homedir2(), ".config", "systemd", "user", "local-router.service");
9378
- }
9379
- function buildUnit(opts) {
9380
- const logPath = getDaemonLogPath();
9381
- const execStart = [opts.execPath, ...opts.args].join(" ");
9382
- return `[Unit]
9383
- Description=Local Router API Gateway
9384
- After=network-online.target
9385
-
9386
- [Service]
9387
- Type=simple
9388
- ExecStart=${execStart}
9389
- Restart=on-failure
9390
- RestartSec=5
9391
- StandardOutput=append:${logPath}
9392
- StandardError=append:${logPath}
9393
-
9394
- [Install]
9395
- WantedBy=default.target
9396
- `;
9397
- }
9398
- function createLinuxManager() {
9399
- const unitPath = getSystemdUnitPath();
9400
- return {
9401
- platform: "linux",
9402
- async isInstalled() {
9403
- if (!existsSync(unitPath))
9404
- return false;
9405
- try {
9406
- const out = execSync("systemctl --user is-enabled local-router 2>/dev/null", {
9407
- encoding: "utf-8"
9408
- }).trim();
9409
- return out === "enabled";
9410
- } catch {
9411
- return false;
9412
- }
9413
- },
9414
- async install(opts) {
9415
- const dir = dirname(unitPath);
9416
- if (!existsSync(dir))
9417
- mkdirSync(dir, { recursive: true });
9418
- writeFileSync(unitPath, buildUnit(opts), "utf-8");
9419
- execSync("systemctl --user daemon-reload", { stdio: "ignore" });
9420
- execSync("systemctl --user enable local-router", { stdio: "ignore" });
9421
- },
9422
- async uninstall() {
9423
- try {
9424
- execSync("systemctl --user disable local-router", { stdio: "ignore" });
9425
- } catch {}
9426
- rmSync(unitPath, { force: true });
9427
- try {
9428
- execSync("systemctl --user daemon-reload", { stdio: "ignore" });
9429
- } catch {}
9430
- },
9431
- getServicePath() {
9432
- return unitPath;
9433
- }
9434
- };
9435
- }
9436
- var WIN_REG_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";
9437
- var WIN_REG_VALUE = "LocalRouter";
9438
- function createWindowsManager() {
9439
- return {
9440
- platform: "windows",
9441
- async isInstalled() {
9442
- try {
9443
- execSync(`reg query "${WIN_REG_KEY}" /v ${WIN_REG_VALUE}`, { stdio: "ignore" });
9444
- return true;
9445
- } catch {
9446
- return false;
9447
- }
9448
- },
9449
- async install(opts) {
9450
- const cmd = [opts.execPath, ...opts.args].map((a) => `"${a}"`).join(" ");
9451
- execSync(`reg add "${WIN_REG_KEY}" /v ${WIN_REG_VALUE} /t REG_SZ /d "${cmd}" /f`, {
9452
- stdio: "ignore"
9453
- });
9454
- },
9455
- async uninstall() {
9456
- try {
9457
- execSync(`reg delete "${WIN_REG_KEY}" /v ${WIN_REG_VALUE} /f`, { stdio: "ignore" });
9458
- } catch {}
9459
- },
9460
- getServicePath() {
9461
- return `${WIN_REG_KEY}\\${WIN_REG_VALUE}`;
9462
- }
9463
- };
9464
- }
9465
- function createUnsupportedManager() {
9466
- return {
9467
- platform: "unsupported",
9468
- async isInstalled() {
9469
- return false;
9470
- },
9471
- async install() {
9472
- throw new Error("\u5F53\u524D\u5E73\u53F0\u4E0D\u652F\u6301\u81EA\u542F\u52A8");
9473
- },
9474
- async uninstall() {
9475
- throw new Error("\u5F53\u524D\u5E73\u53F0\u4E0D\u652F\u6301\u81EA\u542F\u52A8");
9476
- },
9477
- getServicePath() {
9478
- return "";
9479
- }
9480
- };
9481
- }
9482
- function createAutostartManager() {
9483
- const p = platform();
9484
- if (p === "darwin")
9485
- return createMacosManager();
9486
- if (p === "linux")
9487
- return createLinuxManager();
9488
- if (p === "win32")
9489
- return createWindowsManager();
9490
- return createUnsupportedManager();
9491
- }
9492
- function getAutostartExecArgs() {
9493
- const script = process.argv[1] ?? "dist/cli.js";
9494
- return {
9495
- execPath: process.execPath,
9496
- args: [script, "__run-server", "--mode", "daemon"]
9497
- };
9498
- }
9499
-
9500
9290
  // node_modules/.bun/@ai-sdk+provider@3.0.8/node_modules/@ai-sdk/provider/dist/index.mjs
9501
9291
  var marker = "vercel.ai.error";
9502
9292
  var symbol = Symbol.for(marker);
@@ -29343,7 +29133,7 @@ function createProviderToolFactoryWithOutputSchema({
29343
29133
  supportsDeferredResults
29344
29134
  });
29345
29135
  }
29346
- async function resolve2(value) {
29136
+ async function resolve(value) {
29347
29137
  if (typeof value === "function") {
29348
29138
  value = value();
29349
29139
  }
@@ -32288,11 +32078,11 @@ var AnthropicMessagesLanguageModel = class {
32288
32078
  betas,
32289
32079
  headers
32290
32080
  }) {
32291
- return combineHeaders(await resolve2(this.config.headers), headers, betas.size > 0 ? { "anthropic-beta": Array.from(betas).join(",") } : {});
32081
+ return combineHeaders(await resolve(this.config.headers), headers, betas.size > 0 ? { "anthropic-beta": Array.from(betas).join(",") } : {});
32292
32082
  }
32293
32083
  async getBetasFromHeaders(requestHeaders) {
32294
32084
  var _a16, _b16;
32295
- const configHeaders = await resolve2(this.config.headers);
32085
+ const configHeaders = await resolve(this.config.headers);
32296
32086
  const configBetaHeader = (_a16 = configHeaders["anthropic-beta"]) != null ? _a16 : "";
32297
32087
  const requestBetaHeader = (_b16 = requestHeaders == null ? undefined : requestHeaders["anthropic-beta"]) != null ? _b16 : "";
32298
32088
  return new Set([
@@ -41477,7 +41267,7 @@ var GatewayFetchMetadata = class {
41477
41267
  try {
41478
41268
  const { value } = await getFromApi({
41479
41269
  url: `${this.config.baseURL}/config`,
41480
- headers: await resolve2(this.config.headers()),
41270
+ headers: await resolve(this.config.headers()),
41481
41271
  successfulResponseHandler: createJsonResponseHandler(gatewayAvailableModelsResponseSchema),
41482
41272
  failedResponseHandler: createJsonErrorResponseHandler({
41483
41273
  errorSchema: exports_external.any(),
@@ -41495,7 +41285,7 @@ var GatewayFetchMetadata = class {
41495
41285
  const baseUrl = new URL(this.config.baseURL);
41496
41286
  const { value } = await getFromApi({
41497
41287
  url: `${baseUrl.origin}/v1/credits`,
41498
- headers: await resolve2(this.config.headers()),
41288
+ headers: await resolve(this.config.headers()),
41499
41289
  successfulResponseHandler: createJsonResponseHandler(gatewayCreditsResponseSchema),
41500
41290
  failedResponseHandler: createJsonErrorResponseHandler({
41501
41291
  errorSchema: exports_external.any(),
@@ -41560,7 +41350,7 @@ var GatewayLanguageModel = class {
41560
41350
  async doGenerate(options) {
41561
41351
  const { args, warnings } = await this.getArgs(options);
41562
41352
  const { abortSignal } = options;
41563
- const resolvedHeaders = await resolve2(this.config.headers());
41353
+ const resolvedHeaders = await resolve(this.config.headers());
41564
41354
  try {
41565
41355
  const {
41566
41356
  responseHeaders,
@@ -41568,7 +41358,7 @@ var GatewayLanguageModel = class {
41568
41358
  rawValue: rawResponse
41569
41359
  } = await postJsonToApi({
41570
41360
  url: this.getUrl(),
41571
- headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, false), await resolve2(this.config.o11yHeaders)),
41361
+ headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, false), await resolve(this.config.o11yHeaders)),
41572
41362
  body: args,
41573
41363
  successfulResponseHandler: createJsonResponseHandler(exports_external.any()),
41574
41364
  failedResponseHandler: createJsonErrorResponseHandler({
@@ -41591,11 +41381,11 @@ var GatewayLanguageModel = class {
41591
41381
  async doStream(options) {
41592
41382
  const { args, warnings } = await this.getArgs(options);
41593
41383
  const { abortSignal } = options;
41594
- const resolvedHeaders = await resolve2(this.config.headers());
41384
+ const resolvedHeaders = await resolve(this.config.headers());
41595
41385
  try {
41596
41386
  const { value: response, responseHeaders } = await postJsonToApi({
41597
41387
  url: this.getUrl(),
41598
- headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, true), await resolve2(this.config.o11yHeaders)),
41388
+ headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, true), await resolve(this.config.o11yHeaders)),
41599
41389
  body: args,
41600
41390
  successfulResponseHandler: createEventSourceResponseHandler(exports_external.any()),
41601
41391
  failedResponseHandler: createJsonErrorResponseHandler({
@@ -41681,7 +41471,7 @@ var GatewayEmbeddingModel = class {
41681
41471
  providerOptions
41682
41472
  }) {
41683
41473
  var _a92;
41684
- const resolvedHeaders = await resolve2(this.config.headers());
41474
+ const resolvedHeaders = await resolve(this.config.headers());
41685
41475
  try {
41686
41476
  const {
41687
41477
  responseHeaders,
@@ -41689,7 +41479,7 @@ var GatewayEmbeddingModel = class {
41689
41479
  rawValue
41690
41480
  } = await postJsonToApi({
41691
41481
  url: this.getUrl(),
41692
- headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve2(this.config.o11yHeaders)),
41482
+ headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve(this.config.o11yHeaders)),
41693
41483
  body: {
41694
41484
  values,
41695
41485
  ...providerOptions ? { providerOptions } : {}
@@ -41751,7 +41541,7 @@ var GatewayImageModel = class {
41751
41541
  abortSignal
41752
41542
  }) {
41753
41543
  var _a92, _b92, _c, _d;
41754
- const resolvedHeaders = await resolve2(this.config.headers());
41544
+ const resolvedHeaders = await resolve(this.config.headers());
41755
41545
  try {
41756
41546
  const {
41757
41547
  responseHeaders,
@@ -41759,7 +41549,7 @@ var GatewayImageModel = class {
41759
41549
  rawValue
41760
41550
  } = await postJsonToApi({
41761
41551
  url: this.getUrl(),
41762
- headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve2(this.config.o11yHeaders)),
41552
+ headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve(this.config.o11yHeaders)),
41763
41553
  body: {
41764
41554
  prompt,
41765
41555
  n,
@@ -41874,11 +41664,11 @@ var GatewayVideoModel = class {
41874
41664
  abortSignal
41875
41665
  }) {
41876
41666
  var _a92;
41877
- const resolvedHeaders = await resolve2(this.config.headers());
41667
+ const resolvedHeaders = await resolve(this.config.headers());
41878
41668
  try {
41879
41669
  const { responseHeaders, value: responseBody } = await postJsonToApi({
41880
41670
  url: this.getUrl(),
41881
- headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve2(this.config.o11yHeaders), { accept: "text/event-stream" }),
41671
+ headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve(this.config.o11yHeaders), { accept: "text/event-stream" }),
41882
41672
  body: {
41883
41673
  prompt,
41884
41674
  n,
@@ -44749,7 +44539,7 @@ var object2 = ({
44749
44539
  const schema = asSchema(inputSchema);
44750
44540
  return {
44751
44541
  name: "object",
44752
- responseFormat: resolve2(schema.jsonSchema).then((jsonSchema2) => ({
44542
+ responseFormat: resolve(schema.jsonSchema).then((jsonSchema2) => ({
44753
44543
  type: "json",
44754
44544
  schema: jsonSchema2,
44755
44545
  ...name21 != null && { name: name21 },
@@ -44811,7 +44601,7 @@ var array2 = ({
44811
44601
  const elementSchema = asSchema(inputElementSchema);
44812
44602
  return {
44813
44603
  name: "array",
44814
- responseFormat: resolve2(elementSchema.jsonSchema).then((jsonSchema2) => {
44604
+ responseFormat: resolve(elementSchema.jsonSchema).then((jsonSchema2) => {
44815
44605
  const { $schema, ...itemSchema } = jsonSchema2;
44816
44606
  return {
44817
44607
  type: "json",
@@ -50070,7 +49860,7 @@ var Hono2 = class extends Hono {
50070
49860
 
50071
49861
  // node_modules/.bun/hono@4.12.5/node_modules/hono/dist/adapter/bun/serve-static.js
50072
49862
  import { stat } from "fs/promises";
50073
- import { join as join3 } from "path";
49863
+ import { join } from "path";
50074
49864
 
50075
49865
  // node_modules/.bun/hono@4.12.5/node_modules/hono/dist/utils/compress.js
50076
49866
  var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/(?!event-stream(?:[;\s]|$))[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
@@ -50175,7 +49965,7 @@ var DEFAULT_DOCUMENT = "index.html";
50175
49965
  var serveStatic = (options) => {
50176
49966
  const root = options.root ?? "./";
50177
49967
  const optionPath = options.path;
50178
- const join3 = options.join ?? defaultJoin;
49968
+ const join = options.join ?? defaultJoin;
50179
49969
  return async (c, next) => {
50180
49970
  if (c.finalized) {
50181
49971
  return next();
@@ -50194,9 +49984,9 @@ var serveStatic = (options) => {
50194
49984
  return next();
50195
49985
  }
50196
49986
  }
50197
- let path = join3(root, !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename);
49987
+ let path = join(root, !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename);
50198
49988
  if (options.isDir && await options.isDir(path)) {
50199
- path = join3(path, DEFAULT_DOCUMENT);
49989
+ path = join(path, DEFAULT_DOCUMENT);
50200
49990
  }
50201
49991
  const getContent = options.getContent;
50202
49992
  let content = await getContent(path, c);
@@ -50248,7 +50038,7 @@ var serveStatic2 = (options) => {
50248
50038
  return serveStatic({
50249
50039
  ...options,
50250
50040
  getContent,
50251
- join: join3,
50041
+ join,
50252
50042
  isDir
50253
50043
  })(c, next);
50254
50044
  };
@@ -50339,6 +50129,216 @@ var upgradeWebSocket = defineWebSocketHelper((c, events) => {
50339
50129
  return;
50340
50130
  });
50341
50131
 
50132
+ // src/cli/autostart.ts
50133
+ import { execSync } from "child_process";
50134
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
50135
+ import { homedir as homedir2, platform } from "os";
50136
+ import { dirname as dirname2, join as join3 } from "path";
50137
+
50138
+ // src/cli/runtime.ts
50139
+ import { homedir } from "os";
50140
+ import { join as join2, resolve as resolve2 } from "path";
50141
+ function getRuntimeDirs() {
50142
+ const override = process.env.LOCAL_ROUTER_RUNTIME_DIR;
50143
+ const root = override?.trim() ? override.trim() : join2(homedir(), ".local-router");
50144
+ return {
50145
+ root,
50146
+ run: join2(root, "run"),
50147
+ logs: join2(root, "logs")
50148
+ };
50149
+ }
50150
+
50151
+ // src/cli/autostart.ts
50152
+ var LABEL = "com.lakphy.local-router";
50153
+ function getDaemonLogPath() {
50154
+ return getRuntimeDirs().logs + "/daemon.log";
50155
+ }
50156
+ function getLaunchAgentPath() {
50157
+ return join3(homedir2(), "Library", "LaunchAgents", `${LABEL}.plist`);
50158
+ }
50159
+ function buildPlist(opts) {
50160
+ const logPath = getDaemonLogPath();
50161
+ const args = [opts.execPath, ...opts.args].map((a) => ` <string>${escapeXml(a)}</string>`).join(`
50162
+ `);
50163
+ return `<?xml version="1.0" encoding="UTF-8"?>
50164
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
50165
+ <plist version="1.0">
50166
+ <dict>
50167
+ <key>Label</key>
50168
+ <string>${escapeXml(opts.label)}</string>
50169
+ <key>ProgramArguments</key>
50170
+ <array>
50171
+ ${args}
50172
+ </array>
50173
+ <key>RunAtLoad</key>
50174
+ <true/>
50175
+ <key>KeepAlive</key>
50176
+ <false/>
50177
+ <key>StandardOutPath</key>
50178
+ <string>${escapeXml(logPath)}</string>
50179
+ <key>StandardErrorPath</key>
50180
+ <string>${escapeXml(logPath)}</string>
50181
+ </dict>
50182
+ </plist>
50183
+ `;
50184
+ }
50185
+ function escapeXml(s) {
50186
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
50187
+ }
50188
+ function createMacosManager() {
50189
+ const plistPath = getLaunchAgentPath();
50190
+ return {
50191
+ platform: "macos",
50192
+ async isInstalled() {
50193
+ return existsSync(plistPath);
50194
+ },
50195
+ async install(opts) {
50196
+ const dir = dirname2(plistPath);
50197
+ if (!existsSync(dir))
50198
+ mkdirSync(dir, { recursive: true });
50199
+ writeFileSync(plistPath, buildPlist(opts), "utf-8");
50200
+ try {
50201
+ execSync(`launchctl bootout gui/$(id -u) ${plistPath} 2>/dev/null`, { stdio: "ignore" });
50202
+ } catch {}
50203
+ execSync(`launchctl bootstrap gui/$(id -u) ${plistPath}`, { stdio: "ignore" });
50204
+ },
50205
+ async uninstall() {
50206
+ if (!existsSync(plistPath))
50207
+ return;
50208
+ try {
50209
+ execSync(`launchctl bootout gui/$(id -u) ${plistPath}`, { stdio: "ignore" });
50210
+ } catch {}
50211
+ rmSync(plistPath, { force: true });
50212
+ },
50213
+ getServicePath() {
50214
+ return plistPath;
50215
+ }
50216
+ };
50217
+ }
50218
+ function getSystemdUnitPath() {
50219
+ return join3(homedir2(), ".config", "systemd", "user", "local-router.service");
50220
+ }
50221
+ function buildUnit(opts) {
50222
+ const logPath = getDaemonLogPath();
50223
+ const execStart = [opts.execPath, ...opts.args].join(" ");
50224
+ return `[Unit]
50225
+ Description=Local Router API Gateway
50226
+ After=network-online.target
50227
+
50228
+ [Service]
50229
+ Type=simple
50230
+ ExecStart=${execStart}
50231
+ Restart=on-failure
50232
+ RestartSec=5
50233
+ StandardOutput=append:${logPath}
50234
+ StandardError=append:${logPath}
50235
+
50236
+ [Install]
50237
+ WantedBy=default.target
50238
+ `;
50239
+ }
50240
+ function createLinuxManager() {
50241
+ const unitPath = getSystemdUnitPath();
50242
+ return {
50243
+ platform: "linux",
50244
+ async isInstalled() {
50245
+ if (!existsSync(unitPath))
50246
+ return false;
50247
+ try {
50248
+ const out = execSync("systemctl --user is-enabled local-router 2>/dev/null", {
50249
+ encoding: "utf-8"
50250
+ }).trim();
50251
+ return out === "enabled";
50252
+ } catch {
50253
+ return false;
50254
+ }
50255
+ },
50256
+ async install(opts) {
50257
+ const dir = dirname2(unitPath);
50258
+ if (!existsSync(dir))
50259
+ mkdirSync(dir, { recursive: true });
50260
+ writeFileSync(unitPath, buildUnit(opts), "utf-8");
50261
+ execSync("systemctl --user daemon-reload", { stdio: "ignore" });
50262
+ execSync("systemctl --user enable local-router", { stdio: "ignore" });
50263
+ },
50264
+ async uninstall() {
50265
+ try {
50266
+ execSync("systemctl --user disable local-router", { stdio: "ignore" });
50267
+ } catch {}
50268
+ rmSync(unitPath, { force: true });
50269
+ try {
50270
+ execSync("systemctl --user daemon-reload", { stdio: "ignore" });
50271
+ } catch {}
50272
+ },
50273
+ getServicePath() {
50274
+ return unitPath;
50275
+ }
50276
+ };
50277
+ }
50278
+ var WIN_REG_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";
50279
+ var WIN_REG_VALUE = "LocalRouter";
50280
+ function createWindowsManager() {
50281
+ return {
50282
+ platform: "windows",
50283
+ async isInstalled() {
50284
+ try {
50285
+ execSync(`reg query "${WIN_REG_KEY}" /v ${WIN_REG_VALUE}`, { stdio: "ignore" });
50286
+ return true;
50287
+ } catch {
50288
+ return false;
50289
+ }
50290
+ },
50291
+ async install(opts) {
50292
+ const cmd = [opts.execPath, ...opts.args].map((a) => `"${a}"`).join(" ");
50293
+ execSync(`reg add "${WIN_REG_KEY}" /v ${WIN_REG_VALUE} /t REG_SZ /d "${cmd}" /f`, {
50294
+ stdio: "ignore"
50295
+ });
50296
+ },
50297
+ async uninstall() {
50298
+ try {
50299
+ execSync(`reg delete "${WIN_REG_KEY}" /v ${WIN_REG_VALUE} /f`, { stdio: "ignore" });
50300
+ } catch {}
50301
+ },
50302
+ getServicePath() {
50303
+ return `${WIN_REG_KEY}\\${WIN_REG_VALUE}`;
50304
+ }
50305
+ };
50306
+ }
50307
+ function createUnsupportedManager() {
50308
+ return {
50309
+ platform: "unsupported",
50310
+ async isInstalled() {
50311
+ return false;
50312
+ },
50313
+ async install() {
50314
+ throw new Error("\u5F53\u524D\u5E73\u53F0\u4E0D\u652F\u6301\u81EA\u542F\u52A8");
50315
+ },
50316
+ async uninstall() {
50317
+ throw new Error("\u5F53\u524D\u5E73\u53F0\u4E0D\u652F\u6301\u81EA\u542F\u52A8");
50318
+ },
50319
+ getServicePath() {
50320
+ return "";
50321
+ }
50322
+ };
50323
+ }
50324
+ function createAutostartManager() {
50325
+ const p = platform();
50326
+ if (p === "darwin")
50327
+ return createMacosManager();
50328
+ if (p === "linux")
50329
+ return createLinuxManager();
50330
+ if (p === "win32")
50331
+ return createWindowsManager();
50332
+ return createUnsupportedManager();
50333
+ }
50334
+ function getAutostartExecArgs() {
50335
+ const script = process.argv[1] ?? "dist/cli.js";
50336
+ return {
50337
+ execPath: process.execPath,
50338
+ args: [script, "__run-server", "--mode", "daemon"]
50339
+ };
50340
+ }
50341
+
50342
50342
  // src/config.ts
50343
50343
  import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
50344
50344
  import { homedir as homedir3 } from "os";
@@ -56217,6 +56217,97 @@ var openAPISpec = {
56217
56217
  }
56218
56218
  }
56219
56219
  },
56220
+ "/api/models": {
56221
+ get: {
56222
+ tags: ["Health"],
56223
+ summary: "\u55C5\u63A2\u53EF\u7528\u6A21\u578B\u8DEF\u7531",
56224
+ 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",
56225
+ parameters: [
56226
+ {
56227
+ name: "protocol",
56228
+ in: "query",
56229
+ required: true,
56230
+ schema: {
56231
+ type: "string",
56232
+ enum: ["openai-completions", "openai-responses", "anthropic-messages"]
56233
+ },
56234
+ description: "\u534F\u8BAE\u7C7B\u578B"
56235
+ }
56236
+ ],
56237
+ responses: {
56238
+ "200": {
56239
+ description: "\u53EF\u7528\u6A21\u578B\u8DEF\u7531\u5217\u8868",
56240
+ content: {
56241
+ "application/json": {
56242
+ schema: {
56243
+ type: "object",
56244
+ properties: {
56245
+ protocol: { type: "string", example: "anthropic-messages" },
56246
+ models: {
56247
+ type: "array",
56248
+ items: { type: "string" },
56249
+ example: ["claude-3-5-sonnet", "claude-3-opus"]
56250
+ }
56251
+ }
56252
+ }
56253
+ }
56254
+ }
56255
+ },
56256
+ "400": { description: "\u534F\u8BAE\u53C2\u6570\u7F3A\u5931\u6216\u65E0\u6548" }
56257
+ }
56258
+ }
56259
+ },
56260
+ "/api/providers/discover": {
56261
+ get: {
56262
+ tags: ["Health"],
56263
+ summary: "\u53D1\u73B0\u5C40\u57DF\u7F51 local-router \u7684\u6A21\u578B",
56264
+ 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",
56265
+ parameters: [
56266
+ {
56267
+ name: "ip",
56268
+ in: "query",
56269
+ required: true,
56270
+ schema: { type: "string" },
56271
+ description: "\u5BF9\u7AEF IP"
56272
+ },
56273
+ {
56274
+ name: "port",
56275
+ in: "query",
56276
+ required: false,
56277
+ schema: { type: "string", default: "4099" },
56278
+ description: "\u5BF9\u7AEF\u7AEF\u53E3\uFF0C\u9ED8\u8BA4 4099"
56279
+ },
56280
+ {
56281
+ name: "protocol",
56282
+ in: "query",
56283
+ required: true,
56284
+ schema: {
56285
+ type: "string",
56286
+ enum: ["openai-completions", "openai-responses", "anthropic-messages"]
56287
+ },
56288
+ description: "\u534F\u8BAE\u7C7B\u578B"
56289
+ }
56290
+ ],
56291
+ responses: {
56292
+ "200": {
56293
+ description: "\u5BF9\u7AEF\u53EF\u7528\u6A21\u578B\u8DEF\u7531\u5217\u8868",
56294
+ content: {
56295
+ "application/json": {
56296
+ schema: {
56297
+ type: "object",
56298
+ properties: {
56299
+ protocol: { type: "string", example: "anthropic-messages" },
56300
+ models: { type: "array", items: { type: "string" } }
56301
+ }
56302
+ }
56303
+ }
56304
+ }
56305
+ },
56306
+ "400": { description: "\u53C2\u6570\u7F3A\u5931" },
56307
+ "502": { description: "\u65E0\u6CD5\u8FDE\u63A5\u5BF9\u7AEF\u6216\u5BF9\u7AEF\u8FD4\u56DE\u9519\u8BEF" }
56308
+ }
56309
+ }
56310
+ },
56220
56311
  "/api/metrics/logs": {
56221
56312
  get: {
56222
56313
  tags: ["Health"],
@@ -58226,6 +58317,43 @@ function createAdminApiRoutes(store, pluginManager, registerCleanup) {
58226
58317
  routeTypes: Object.keys(ROUTE_REGISTRY)
58227
58318
  });
58228
58319
  });
58320
+ api2.get("/models", (c2) => {
58321
+ const protocol = c2.req.query("protocol");
58322
+ const routeTypes = Object.keys(ROUTE_REGISTRY);
58323
+ if (!protocol || !routeTypes.includes(protocol)) {
58324
+ return c2.json({ error: "invalid or missing protocol", routeTypes }, 400);
58325
+ }
58326
+ const routes = store.get().routes[protocol] ?? {};
58327
+ const models = Object.keys(routes).filter((k) => k !== "*");
58328
+ return c2.json({ protocol, models });
58329
+ });
58330
+ api2.get("/providers/discover", async (c2) => {
58331
+ const ip = c2.req.query("ip");
58332
+ const portStr = c2.req.query("port") ?? "4099";
58333
+ const protocol = c2.req.query("protocol");
58334
+ if (!ip || !protocol) {
58335
+ return c2.json({ error: "ip and protocol are required" }, 400);
58336
+ }
58337
+ const port = Number(portStr);
58338
+ if (!Number.isInteger(port) || port < 1 || port > 65535) {
58339
+ return c2.json({ error: "\u7AEF\u53E3\u65E0\u6548\uFF0C\u5FC5\u987B\u662F 1-65535 \u7684\u6574\u6570" }, 400);
58340
+ }
58341
+ if (!isLoopbackAddress(ip) && !isLanAddress(ip)) {
58342
+ return c2.json({ error: "\u4EC5\u652F\u6301\u5C40\u57DF\u7F51\u6216\u672C\u673A IP \u5730\u5740" }, 400);
58343
+ }
58344
+ const url2 = `http://${ip}:${port}/api/models?protocol=${encodeURIComponent(protocol)}`;
58345
+ try {
58346
+ const res = await fetch(url2, { signal: AbortSignal.timeout(5000) });
58347
+ if (!res.ok) {
58348
+ const body = await res.json().catch(() => ({}));
58349
+ return c2.json({ error: body.error ?? `remote returned ${res.status}` }, 502);
58350
+ }
58351
+ const data = await res.json();
58352
+ return c2.json(data);
58353
+ } catch (err) {
58354
+ return c2.json({ error: `\u65E0\u6CD5\u8FDE\u63A5\u5BF9\u7AEF local-router: ${err instanceof Error ? err.message : err}` }, 502);
58355
+ }
58356
+ });
58229
58357
  api2.get("/config/schema", (c2) => {
58230
58358
  try {
58231
58359
  return c2.json(schemaJson);