ellm-proxy 0.0.11 → 0.0.13
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/cli.js +11 -58
- package/dist/server.js +9 -23
- package/dist/web-ui/assets/{DashboardView-BWPFis7P.js → DashboardView-C_UXsKRa.js} +1 -1
- package/dist/web-ui/assets/{LayoutView-BkUJgLW2.js → LayoutView-VF0751s6.js} +1 -1
- package/dist/web-ui/assets/{LoginView-C8E6nJw2.js → LoginView-9pRN4_jz.js} +1 -1
- package/dist/web-ui/assets/{LogsView-CtRfyOCZ.js → LogsView-Ddiqpn27.js} +1 -1
- package/dist/web-ui/assets/{ProvidersView-B6fm2FPQ.js → ProvidersView-BisIWeCb.js} +2 -2
- package/dist/web-ui/assets/{SettingsView-BHuXlGS1.js → SettingsView-2J7lJg6I.js} +1 -1
- package/dist/web-ui/assets/{SetupView-Oau3EJgh.js → SetupView-ByC3ZfGq.js} +1 -1
- package/dist/web-ui/assets/{config-CHaFDQC7.js → config-CFGI6BQU.js} +1 -1
- package/dist/web-ui/assets/{index-BmtcBnoW.js → index-DzBTME5Z.js} +2 -2
- package/dist/web-ui/assets/{providers-Aw7T7j0r.js → providers-DN-6AbdJ.js} +1 -1
- package/dist/web-ui/assets/{useManagerApi-PldAaNYo.js → useManagerApi-C3X3JX66.js} +1 -1
- package/dist/web-ui/assets/{useToast-C9BTyaBD.js → useToast-BIVFyGJl.js} +1 -1
- package/dist/web-ui/index.html +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -20915,8 +20915,7 @@ function absolutize(opts) {
|
|
|
20915
20915
|
}
|
|
20916
20916
|
|
|
20917
20917
|
// ../server/src/cli/service.ts
|
|
20918
|
-
import {
|
|
20919
|
-
import { homedir as homedir3 } from "node:os";
|
|
20918
|
+
import { readFileSync as readFileSync6 } from "node:fs";
|
|
20920
20919
|
import { join as join7 } from "node:path";
|
|
20921
20920
|
|
|
20922
20921
|
// ../server/src/proc/index.ts
|
|
@@ -35172,7 +35171,7 @@ var AUTOSTART_CMD = "ellm-proxy-autostart.cmd";
|
|
|
35172
35171
|
var PLIST_LABEL = "com.ellm-proxy.autostart";
|
|
35173
35172
|
var LINUX_UNIT = "ellm-proxy.service";
|
|
35174
35173
|
var OPT_OUT_FILE = "autostart.opt-out";
|
|
35175
|
-
var MARKER = "ellm-proxy-
|
|
35174
|
+
var MARKER = "ellm-proxy-v3";
|
|
35176
35175
|
var ENV_WHITELIST_PREFIX = "ELLM_";
|
|
35177
35176
|
var ENV_WHITELIST_KEYS = /* @__PURE__ */ new Set(["WEBUI_USERNAME", "WEBUI_PASSWORD"]);
|
|
35178
35177
|
function collectAutostartEnv(env10 = process.env) {
|
|
@@ -35214,6 +35213,8 @@ function windowsBody(nodePath, target) {
|
|
|
35214
35213
|
const logPath = join6(target.appDir, "logs", "autostart.log");
|
|
35215
35214
|
const lines = [
|
|
35216
35215
|
"@echo off",
|
|
35216
|
+
// echo 按 OEM 代码页(GBK)写重定向,node 按 UTF-8 写——不切页日志会两种编码混写必然一半乱码
|
|
35217
|
+
"chcp 65001 >nul",
|
|
35217
35218
|
`rem Auto-generated by "ellm-proxy autostart on" (${MARKER}). Disable with "ellm-proxy autostart off".`,
|
|
35218
35219
|
...Object.entries(target.env).map(([k, v]) => `set "${k}=${v}"`),
|
|
35219
35220
|
`>> "${logPath}" echo [%date% %time%] autostart launching.`,
|
|
@@ -35236,7 +35237,7 @@ function darwinBody(nodePath, target) {
|
|
|
35236
35237
|
return [
|
|
35237
35238
|
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
35238
35239
|
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
|
|
35239
|
-
|
|
35240
|
+
`<!-- ${MARKER}: launch service directly -->`,
|
|
35240
35241
|
'<plist version="1.0">',
|
|
35241
35242
|
"<dict>",
|
|
35242
35243
|
` <key>Label</key><string>${PLIST_LABEL}</string>`,
|
|
@@ -35260,8 +35261,8 @@ function darwinBody(nodePath, target) {
|
|
|
35260
35261
|
function linuxBody(nodePath, target) {
|
|
35261
35262
|
const envLines = Object.entries(target.env).map(([k, v]) => `Environment="${k}=${v.replace(/"/g, '\\"')}"`).join("\n");
|
|
35262
35263
|
return [
|
|
35263
|
-
|
|
35264
|
-
|
|
35264
|
+
`[Unit]`,
|
|
35265
|
+
`Description=ellm-proxy autostart (${MARKER}, direct service start)`,
|
|
35265
35266
|
"After=default.target",
|
|
35266
35267
|
"",
|
|
35267
35268
|
"[Service]",
|
|
@@ -35282,7 +35283,6 @@ async function windowsOn(nodePath, target) {
|
|
|
35282
35283
|
const cmdPath = join6(target.appDir, AUTOSTART_CMD);
|
|
35283
35284
|
writeFileSync3(cmdPath, windowsBody(nodePath, target), "utf-8");
|
|
35284
35285
|
writeFileSync3(join6(startupDir, AUTOSTART_VBS), `\uFEFF${windowsVbsBody(cmdPath)}`, "utf16le");
|
|
35285
|
-
rmSync2(join6(startupDir, AUTOSTART_CMD), { force: true });
|
|
35286
35286
|
return join6(startupDir, AUTOSTART_VBS);
|
|
35287
35287
|
}
|
|
35288
35288
|
async function darwinOn(nodePath, target) {
|
|
@@ -35315,12 +35315,9 @@ async function linuxOn(nodePath, target) {
|
|
|
35315
35315
|
return itemPath;
|
|
35316
35316
|
}
|
|
35317
35317
|
async function windowsOff() {
|
|
35318
|
-
const
|
|
35319
|
-
const
|
|
35320
|
-
const legacyCmd = join6(startupDir, AUTOSTART_CMD);
|
|
35321
|
-
const existed = existsSync2(vbsPath) || existsSync2(legacyCmd);
|
|
35318
|
+
const vbsPath = join6(windowsStartupDir(), AUTOSTART_VBS);
|
|
35319
|
+
const existed = existsSync2(vbsPath);
|
|
35322
35320
|
rmSync2(vbsPath, { force: true });
|
|
35323
|
-
rmSync2(legacyCmd, { force: true });
|
|
35324
35321
|
return existed;
|
|
35325
35322
|
}
|
|
35326
35323
|
async function darwinOff() {
|
|
@@ -35346,27 +35343,15 @@ function readTextDetectingBom(path7) {
|
|
|
35346
35343
|
function autostartStatus(appDir) {
|
|
35347
35344
|
const itemPath = platformItemPath();
|
|
35348
35345
|
let enabled = false;
|
|
35349
|
-
let outdated = false;
|
|
35350
35346
|
if (itemPath && existsSync2(itemPath)) {
|
|
35351
35347
|
try {
|
|
35352
|
-
|
|
35353
|
-
else outdated = true;
|
|
35348
|
+
enabled = readTextDetectingBom(itemPath).includes(MARKER);
|
|
35354
35349
|
} catch {
|
|
35355
35350
|
}
|
|
35356
35351
|
}
|
|
35357
|
-
if (platform8() === "win32" && !enabled) {
|
|
35358
|
-
const legacyCmd = join6(windowsStartupDir(), AUTOSTART_CMD);
|
|
35359
|
-
if (existsSync2(legacyCmd)) {
|
|
35360
|
-
try {
|
|
35361
|
-
if (readTextDetectingBom(legacyCmd).includes(MARKER)) outdated = true;
|
|
35362
|
-
} catch {
|
|
35363
|
-
}
|
|
35364
|
-
}
|
|
35365
|
-
}
|
|
35366
35352
|
return {
|
|
35367
35353
|
platform: platform8(),
|
|
35368
35354
|
enabled,
|
|
35369
|
-
outdated,
|
|
35370
35355
|
itemPath,
|
|
35371
35356
|
optOut: existsSync2(optOutPath(appDir))
|
|
35372
35357
|
};
|
|
@@ -35400,7 +35385,7 @@ async function ensureAutostartOnStart(target) {
|
|
|
35400
35385
|
if (status.enabled) return;
|
|
35401
35386
|
if (status.optOut) return;
|
|
35402
35387
|
const { itemPath } = await enableAutostart(target);
|
|
35403
|
-
console.log(
|
|
35388
|
+
console.log(`\u5DF2\u81EA\u52A8\u6CE8\u518C\u5F00\u673A\u81EA\u542F: ${itemPath}`);
|
|
35404
35389
|
console.log("\u7981\u7528\u65B9\u5F0F: ellm-proxy autostart off \u6216\u7BA1\u7406\u53F0\u8BBE\u7F6E\u9875\u3002");
|
|
35405
35390
|
} catch (err) {
|
|
35406
35391
|
console.warn(`\u5F00\u673A\u81EA\u542F\u6CE8\u518C\u5931\u8D25\uFF08\u4E0D\u5F71\u54CD\u672C\u6B21\u542F\u52A8\uFF09: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -35502,36 +35487,6 @@ function resolvePort(portEnv, configFile) {
|
|
|
35502
35487
|
}
|
|
35503
35488
|
return port;
|
|
35504
35489
|
}
|
|
35505
|
-
var LEGACY_PM2_APPS = /* @__PURE__ */ new Set(["ellm-proxy", "ellm-proxy-manager"]);
|
|
35506
|
-
async function cleanupLegacyPm2() {
|
|
35507
|
-
const pm2Home = process.env["PM2_HOME"] || join7(homedir3(), ".pm2");
|
|
35508
|
-
const pidsDir = join7(pm2Home, "pids");
|
|
35509
|
-
const daemonPidFile = join7(pm2Home, "pm2.pid");
|
|
35510
|
-
if (!existsSync3(daemonPidFile)) return false;
|
|
35511
|
-
try {
|
|
35512
|
-
const candidates = [];
|
|
35513
|
-
for (const file of existsSync3(pidsDir) ? readdirSync(pidsDir) : []) {
|
|
35514
|
-
const match = /^(.+)-(\d+)\.pid$/.exec(file);
|
|
35515
|
-
if (!match) continue;
|
|
35516
|
-
const pid = Number(readFileSync6(join7(pidsDir, file), "utf-8").trim()) || 0;
|
|
35517
|
-
if (pid && isPidAlive(pid)) candidates.push({ name: match[1] ?? "", pid });
|
|
35518
|
-
}
|
|
35519
|
-
const ours = candidates.filter((c3) => LEGACY_PM2_APPS.has(c3.name));
|
|
35520
|
-
if (ours.length === 0) return false;
|
|
35521
|
-
for (const item of ours) await killTree(item.pid);
|
|
35522
|
-
const othersAlive = candidates.filter((c3) => !LEGACY_PM2_APPS.has(c3.name));
|
|
35523
|
-
if (othersAlive.length === 0) {
|
|
35524
|
-
const daemonPid = Number(readFileSync6(daemonPidFile, "utf-8").trim()) || 0;
|
|
35525
|
-
if (daemonPid && isPidAlive(daemonPid)) await killTree(daemonPid);
|
|
35526
|
-
say("\u5DF2\u6E05\u7406\u65E7\u7248 pm2 \u6258\u7BA1\u8FDB\u7A0B\u4E0E\u5B88\u62A4\uFF08\u672C\u6B21\u5347\u7EA7\u8D77\u670D\u52A1\u7531\u5185\u7F6E\u8FDB\u7A0B\u7BA1\u7406\u6258\u7BA1\uFF09\u3002", ICONS2.skip);
|
|
35527
|
-
} else {
|
|
35528
|
-
warn("\u68C0\u6D4B\u5230 pm2 \u5B88\u62A4\u8FDB\u7A0B\u4ECD\u5728\u8FD0\u884C\uFF08\u8FD8\u6709\u5176\u4ED6\u5E94\u7528\uFF09\u3002\u65E7\u7248 ellm-proxy \u5DF2\u505C\u6B62\uFF0C\u82E5\u5B83\u88AB pm2 \u81EA\u52A8\u62C9\u56DE\uFF0C\u8BF7\u6267\u884C: npx pm2 delete ellm-proxy ellm-proxy-manager");
|
|
35529
|
-
}
|
|
35530
|
-
return true;
|
|
35531
|
-
} catch {
|
|
35532
|
-
return false;
|
|
35533
|
-
}
|
|
35534
|
-
}
|
|
35535
35490
|
async function waitServiceOnline(appDir, timeoutMs = 15e3) {
|
|
35536
35491
|
const deadline = Date.now() + timeoutMs;
|
|
35537
35492
|
let lastError = "";
|
|
@@ -35553,7 +35508,6 @@ async function doStart(opts) {
|
|
|
35553
35508
|
say("\u6B63\u5728\u542F\u52A8 ellm-proxy\uFF08\u5185\u7F6E\u8FDB\u7A0B\u7BA1\u7406\uFF0C\u540E\u53F0\u5E38\u9A7B\uFF09...", ICONS2.rocket);
|
|
35554
35509
|
const appDir = resolveAppDir(opts.workingDir);
|
|
35555
35510
|
const config = ensureConfig(opts.config, appDir);
|
|
35556
|
-
await cleanupLegacyPm2();
|
|
35557
35511
|
const existing = readRunInfo(appDir);
|
|
35558
35512
|
if (existing && isPidAlive(existing.pid)) {
|
|
35559
35513
|
throw new Error(`\u5DF2\u5728\u8FD0\u884C\uFF08pid ${String(existing.pid)}\uFF09\u3002\u8BF7\u5148\u505C\u6B62: ellm-proxy stop`);
|
|
@@ -35596,7 +35550,6 @@ async function doStart(opts) {
|
|
|
35596
35550
|
}
|
|
35597
35551
|
async function doStop() {
|
|
35598
35552
|
const appDir = resolveAppDir();
|
|
35599
|
-
await cleanupLegacyPm2();
|
|
35600
35553
|
const info = readRunInfo(appDir);
|
|
35601
35554
|
if (info && isPidAlive(info.pid)) {
|
|
35602
35555
|
begin(`\u505C\u6B62\u670D\u52A1 (pid ${String(info.pid)}) `);
|
package/dist/server.js
CHANGED
|
@@ -20591,7 +20591,7 @@ var AUTOSTART_CMD = "ellm-proxy-autostart.cmd";
|
|
|
20591
20591
|
var PLIST_LABEL = "com.ellm-proxy.autostart";
|
|
20592
20592
|
var LINUX_UNIT = "ellm-proxy.service";
|
|
20593
20593
|
var OPT_OUT_FILE = "autostart.opt-out";
|
|
20594
|
-
var MARKER = "ellm-proxy-
|
|
20594
|
+
var MARKER = "ellm-proxy-v3";
|
|
20595
20595
|
var ENV_WHITELIST_PREFIX = "ELLM_";
|
|
20596
20596
|
var ENV_WHITELIST_KEYS = /* @__PURE__ */ new Set(["WEBUI_USERNAME", "WEBUI_PASSWORD"]);
|
|
20597
20597
|
function collectAutostartEnv(env = process.env) {
|
|
@@ -20633,6 +20633,8 @@ function windowsBody(nodePath, target) {
|
|
|
20633
20633
|
const logPath = join5(target.appDir, "logs", "autostart.log");
|
|
20634
20634
|
const lines = [
|
|
20635
20635
|
"@echo off",
|
|
20636
|
+
// echo 按 OEM 代码页(GBK)写重定向,node 按 UTF-8 写——不切页日志会两种编码混写必然一半乱码
|
|
20637
|
+
"chcp 65001 >nul",
|
|
20636
20638
|
`rem Auto-generated by "ellm-proxy autostart on" (${MARKER}). Disable with "ellm-proxy autostart off".`,
|
|
20637
20639
|
...Object.entries(target.env).map(([k, v]) => `set "${k}=${v}"`),
|
|
20638
20640
|
`>> "${logPath}" echo [%date% %time%] autostart launching.`,
|
|
@@ -20655,7 +20657,7 @@ function darwinBody(nodePath, target) {
|
|
|
20655
20657
|
return [
|
|
20656
20658
|
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
20657
20659
|
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
|
|
20658
|
-
|
|
20660
|
+
`<!-- ${MARKER}: launch service directly -->`,
|
|
20659
20661
|
'<plist version="1.0">',
|
|
20660
20662
|
"<dict>",
|
|
20661
20663
|
` <key>Label</key><string>${PLIST_LABEL}</string>`,
|
|
@@ -20679,8 +20681,8 @@ function darwinBody(nodePath, target) {
|
|
|
20679
20681
|
function linuxBody(nodePath, target) {
|
|
20680
20682
|
const envLines = Object.entries(target.env).map(([k, v]) => `Environment="${k}=${v.replace(/"/g, '\\"')}"`).join("\n");
|
|
20681
20683
|
return [
|
|
20682
|
-
|
|
20683
|
-
|
|
20684
|
+
`[Unit]`,
|
|
20685
|
+
`Description=ellm-proxy autostart (${MARKER}, direct service start)`,
|
|
20684
20686
|
"After=default.target",
|
|
20685
20687
|
"",
|
|
20686
20688
|
"[Service]",
|
|
@@ -20701,7 +20703,6 @@ async function windowsOn(nodePath, target) {
|
|
|
20701
20703
|
const cmdPath = join5(target.appDir, AUTOSTART_CMD);
|
|
20702
20704
|
writeFileSync5(cmdPath, windowsBody(nodePath, target), "utf-8");
|
|
20703
20705
|
writeFileSync5(join5(startupDir, AUTOSTART_VBS), `\uFEFF${windowsVbsBody(cmdPath)}`, "utf16le");
|
|
20704
|
-
rmSync2(join5(startupDir, AUTOSTART_CMD), { force: true });
|
|
20705
20706
|
return join5(startupDir, AUTOSTART_VBS);
|
|
20706
20707
|
}
|
|
20707
20708
|
async function darwinOn(nodePath, target) {
|
|
@@ -20734,12 +20735,9 @@ async function linuxOn(nodePath, target) {
|
|
|
20734
20735
|
return itemPath;
|
|
20735
20736
|
}
|
|
20736
20737
|
async function windowsOff() {
|
|
20737
|
-
const
|
|
20738
|
-
const
|
|
20739
|
-
const legacyCmd = join5(startupDir, AUTOSTART_CMD);
|
|
20740
|
-
const existed = existsSync7(vbsPath) || existsSync7(legacyCmd);
|
|
20738
|
+
const vbsPath = join5(windowsStartupDir(), AUTOSTART_VBS);
|
|
20739
|
+
const existed = existsSync7(vbsPath);
|
|
20741
20740
|
rmSync2(vbsPath, { force: true });
|
|
20742
|
-
rmSync2(legacyCmd, { force: true });
|
|
20743
20741
|
return existed;
|
|
20744
20742
|
}
|
|
20745
20743
|
async function darwinOff() {
|
|
@@ -20765,27 +20763,15 @@ function readTextDetectingBom(path) {
|
|
|
20765
20763
|
function autostartStatus(appDir) {
|
|
20766
20764
|
const itemPath = platformItemPath();
|
|
20767
20765
|
let enabled = false;
|
|
20768
|
-
let outdated = false;
|
|
20769
20766
|
if (itemPath && existsSync7(itemPath)) {
|
|
20770
20767
|
try {
|
|
20771
|
-
|
|
20772
|
-
else outdated = true;
|
|
20768
|
+
enabled = readTextDetectingBom(itemPath).includes(MARKER);
|
|
20773
20769
|
} catch {
|
|
20774
20770
|
}
|
|
20775
20771
|
}
|
|
20776
|
-
if (platform() === "win32" && !enabled) {
|
|
20777
|
-
const legacyCmd = join5(windowsStartupDir(), AUTOSTART_CMD);
|
|
20778
|
-
if (existsSync7(legacyCmd)) {
|
|
20779
|
-
try {
|
|
20780
|
-
if (readTextDetectingBom(legacyCmd).includes(MARKER)) outdated = true;
|
|
20781
|
-
} catch {
|
|
20782
|
-
}
|
|
20783
|
-
}
|
|
20784
|
-
}
|
|
20785
20772
|
return {
|
|
20786
20773
|
platform: platform(),
|
|
20787
20774
|
enabled,
|
|
20788
|
-
outdated,
|
|
20789
20775
|
itemPath,
|
|
20790
20776
|
optOut: existsSync7(optOutPath(appDir))
|
|
20791
20777
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as te,k as ae,q as le,e as w,g as o,w as s,c as S,i as U,r as p,A as V,a as m,j as oe,o as c,b as se,t as r,f as l,h as _,F as ne,v as ue,m as $,_ as re}from"./index-
|
|
1
|
+
import{d as te,k as ae,q as le,e as w,g as o,w as s,c as S,i as U,r as p,A as V,a as m,j as oe,o as c,b as se,t as r,f as l,h as _,F as ne,v as ue,m as $,_ as re}from"./index-DzBTME5Z.js";import{m as de}from"./useManagerApi-C3X3JX66.js";import{u as ie}from"./providers-DN-6AbdJ.js";import{u as ce}from"./useToast-BIVFyGJl.js";import"./config-CFGI6BQU.js";const ve={class:"flex-col-gap"},pe=["onClick"],me={key:1},_e={class:"flex-between"},ge={class:"flex-gap-8"},fe={class:"usage-grid"},he={class:"usage-cell"},ye={class:"usage-num orange"},we={class:"usage-cell"},be={class:"usage-num blue"},ke={class:"usage-cell"},De={class:"usage-num green"},xe={class:"usage-cell"},Ce={class:"usage-num purple"},Me={class:"usage-cell"},Se={class:"usage-num purple"},Ve={key:0,class:"usage-cell"},Pe={class:"usage-num gray"},$e={key:0},Te=["onClick"],Ae=te({__name:"DashboardView",setup(Be){const D=ie(),{toast:P}=ce(),d=p(null),b=p(!0),x=p(""),v=p(null),k=p("today"),C=t=>{const e=t.getFullYear(),a=String(t.getMonth()+1).padStart(2,"0"),i=String(t.getDate()).padStart(2,"0");return`${e}-${a}-${i}`},R=t=>{const e=new Date;let a,i=e;if(t==="today")a=e;else if(t==="yesterday")a=new Date(e),a.setDate(e.getDate()-1),i=a;else if(t==="beforeYesterday")a=new Date(e),a.setDate(e.getDate()-2),i=a;else if(t==="last3days")a=new Date(e),a.setDate(e.getDate()-2);else if(t==="week"){a=new Date(e);const f=(e.getDay()+6)%7;a.setDate(e.getDate()-f)}else if(t==="month")a=new Date(e.getFullYear(),e.getMonth(),1);else return;k.value=t,v.value=[C(a),C(i)],y()},K=t=>{t?R(t):(k.value="",v.value=null,y())},L=()=>{k.value="",y()},j=$(()=>{var e;const t=new Set;for(const a of D.suppliers)for(const i of a.models)t.add(i.modelName);if((e=d.value)!=null&&e.models)for(const a of d.value.models)t.add(a.model);return[...t].sort()}),y=async()=>{var t;b.value=!0;try{const e=new URLSearchParams;x.value&&e.set("model",x.value),((t=v.value)==null?void 0:t.length)===2&&(e.set("startDate",v.value[0]),e.set("endDate",v.value[1]));const a=e.toString();d.value=await V.get(`/api/usage${a?`?${a}`:""}`)}catch(e){console.error(e)}finally{b.value=!1}},q=async()=>{var t;try{const[e]=await Promise.all([V.get("/api/usage"),D.loadProviders(),V.get("/api/status").then(a=>M.value=a.listenPort).catch(()=>M.value)]);if(d.value=e,!((t=v.value)!=null&&t.length)){const a=new Date;v.value=[C(a),C(a)],await y()}}catch(e){console.error(e)}finally{b.value=!1}},E=window.location.hostname,M=p(Number(window.location.port)||null),O=$(()=>`http://${E}${M.value?`:${M.value}`:""}`),T=p(null),A=p(null),B=p(Date.now()),I=async()=>{try{const[t,e]=await Promise.all([de.processes(),V.get("/api/config").catch(()=>null)]);T.value=t[0]??null,A.value=(e==null?void 0:e.masterKey)??"",B.value=Date.now()}catch{}},z=t=>{if(!t.startedAt)return"-";let e=Math.max(0,Math.floor((B.value-t.startedAt)/1e3));const a=Math.floor(e/86400);e-=a*86400;const i=Math.floor(e/3600);e-=i*3600;const f=Math.floor(e/60);return e-=f*60,[a?`${a}天`:"",i?`${i}时`:"",f?`${f}分`:"",`${e}秒`].filter(Boolean).join(" ")},G=t=>t?t>=1024**3?(t/1024**3).toFixed(1)+"G":t>=1024**2?(t/1024**2).toFixed(1)+"M":Math.round(t/1024)+"K":"-",H=$(()=>{const t=[{key:"API 地址",value:O.value},{key:"API 密钥",value:A.value||"未设置(/v1 免鉴权)"},{key:"供应商数量",value:String(D.providerCount)},{key:"模型总数",value:String(D.totalModelCount)}],e=T.value;return e&&t.push({key:"运行状态",value:e.status==="online"?"运行中":e.status==="errored"?"异常":"已停止"},{key:"PID",value:String(e.pid??"-")},{key:"运行时长",value:z(e)},{key:"内存占用",value:G(e.memory)}),t});let Y;const g=t=>t.toLocaleString(),J=t=>t==null||t<=0?"-":t>=1e3?(t/1e3).toFixed(2)+"s":Math.round(t)+"ms",F=async t=>{try{await navigator.clipboard.writeText(t),P("已复制到剪贴板","success")}catch{const e=document.createElement("textarea");e.value=t,e.style.position="fixed",e.style.opacity="0",document.body.appendChild(e),e.select();try{document.execCommand("copy"),P("已复制到剪贴板","success")}catch{P("复制失败","error")}document.body.removeChild(e)}};return ae(()=>{q(),I(),Y=window.setInterval(I,1e4)}),le(()=>window.clearInterval(Y)),(t,e)=>{const a=m("el-table-column"),i=m("el-table"),f=m("el-card"),h=m("el-option"),N=m("el-select"),Q=m("el-date-picker"),W=m("el-button"),X=m("el-tag"),Z=m("el-empty"),ee=oe("loading");return c(),w("div",ve,[o(f,{shadow:"never"},{header:s(()=>[...e[3]||(e[3]=[l("span",{class:"fw-600"},"服务信息",-1)])]),default:s(()=>[se((c(),S(i,{border:"",data:H.value,"show-header":!1,class:"full-width"},{default:s(()=>[o(a,{prop:"key",width:"160"}),o(a,null,{default:s(({row:n})=>[n.key==="API 地址"||n.key==="API 密钥"?(c(),w("span",{key:0,class:"copy-text",onClick:u=>F(n.value)},r(n.value),9,pe)):(c(),w("span",me,r(n.value),1))]),_:1})]),_:1},8,["data"])),[[ee,b.value]])]),_:1}),d.value?(c(),S(f,{key:0,shadow:"never"},{header:s(()=>[l("div",_e,[e[5]||(e[5]=l("span",{class:"fw-600"},"用量统计",-1)),l("div",ge,[o(N,{modelValue:x.value,"onUpdate:modelValue":e[0]||(e[0]=n=>x.value=n),placeholder:"全部模型",clearable:"",filterable:"",style:{width:"220px"},onChange:y},{default:s(()=>[(c(!0),w(ne,null,ue(j.value,n=>(c(),S(h,{key:n,label:n,value:n},null,8,["label","value"]))),128))]),_:1},8,["modelValue"]),o(N,{modelValue:k.value,"onUpdate:modelValue":e[1]||(e[1]=n=>k.value=n),placeholder:"时间范围",clearable:"",style:{width:"130px"},onChange:K},{default:s(()=>[o(h,{label:"今天",value:"today"}),o(h,{label:"昨天",value:"yesterday"}),o(h,{label:"前天",value:"beforeYesterday"}),o(h,{label:"近三天",value:"last3days"}),o(h,{label:"本周",value:"week"}),o(h,{label:"本月",value:"month"})]),_:1},8,["modelValue"]),o(Q,{modelValue:v.value,"onUpdate:modelValue":e[2]||(e[2]=n=>v.value=n),type:"daterange","range-separator":"至","start-placeholder":"开始日期","end-placeholder":"结束日期","value-format":"YYYY-MM-DD",style:{width:"260px"},onChange:L},null,8,["modelValue"]),o(W,{loading:b.value,onClick:y},{default:s(()=>[...e[4]||(e[4]=[_("刷新",-1)])]),_:1},8,["loading"])]),o(X,{type:"info"},{default:s(()=>[_(r(d.value.total.calls)+" 次调用",1)]),_:1})])]),default:s(()=>{var n;return[l("div",fe,[l("div",he,[l("div",ye,r(g(d.value.total.total_tokens)),1),e[6]||(e[6]=l("div",{class:"usage-label"},"总 Token",-1))]),l("div",we,[l("div",be,r(g(d.value.total.input_tokens)),1),e[7]||(e[7]=l("div",{class:"usage-label"},"输入 Token",-1))]),l("div",ke,[l("div",De,r(g(d.value.total.output_tokens)),1),e[8]||(e[8]=l("div",{class:"usage-label"},"输出 Token",-1))]),l("div",xe,[l("div",Ce,r(g(d.value.total.cache_read_tokens)),1),e[9]||(e[9]=l("div",{class:"usage-label"},"缓存读取",-1))]),l("div",Me,[l("div",Se,r(d.value.total.cache_rate!=null?d.value.total.cache_rate+"%":"-"),1),e[10]||(e[10]=l("div",{class:"usage-label"},"缓存命中率",-1))]),d.value.logStorageMB!=null?(c(),w("div",Ve,[l("div",Pe,r(d.value.logStorageMB),1),e[11]||(e[11]=l("div",{class:"usage-label"},"日志占用 (MB)",-1))])):U("",!0)]),(n=d.value.models)!=null&&n.length?(c(),w("div",$e,[e[12]||(e[12]=l("div",{class:"section-title"},"模型用量",-1)),o(i,{data:d.value.models,border:"",stripe:"",class:"full-width"},{default:s(()=>[o(a,{prop:"model",label:"模型","min-width":"200"},{default:s(({row:u})=>[l("span",{class:"copy-text",onClick:Ie=>F(u.model)},r(u.model),9,Te)]),_:1}),o(a,{label:"调用次数",width:"90",align:"center"},{default:s(({row:u})=>[_(r(u.calls),1)]),_:1}),o(a,{label:"平均耗时",width:"110",align:"center"},{default:s(({row:u})=>[_(r(J(u.avg_duration)),1)]),_:1}),o(a,{label:"总 Token",width:"140",align:"center"},{default:s(({row:u})=>[_(r(g(u.total_tokens)),1)]),_:1}),o(a,{label:"输入 Token",width:"140",align:"center"},{default:s(({row:u})=>[_(r(g(u.input_tokens)),1)]),_:1}),o(a,{label:"输出 Token",width:"140",align:"center"},{default:s(({row:u})=>[_(r(g(u.output_tokens)),1)]),_:1}),o(a,{label:"缓存读取",width:"130",align:"center"},{default:s(({row:u})=>[_(r(g(u.cache_read_tokens)),1)]),_:1}),o(a,{label:"缓存命中率",width:"110",align:"center"},{default:s(({row:u})=>[_(r(u.cache_rate!=null?u.cache_rate+"%":"-"),1)]),_:1})]),_:1},8,["data"])])):(c(),S(Z,{key:1,description:"暂无调用记录","image-size":60}))]}),_:1})):U("",!0)])}}}),Ke=re(Ae,[["__scopeId","data-v-ff795a0a"]]);export{Ke as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as T,u as R,c as k,w as o,r as g,a as r,o as v,b as z,e as B,F,f as c,g as l,h as u,t as $,i as x,E as I,j as L,_ as W,k as q,l as j,m as A,n as O,p as G,s as H}from"./index-
|
|
1
|
+
import{d as T,u as R,c as k,w as o,r as g,a as r,o as v,b as z,e as B,F,f as c,g as l,h as u,t as $,i as x,E as I,j as L,_ as W,k as q,l as j,m as A,n as O,p as G,s as H}from"./index-DzBTME5Z.js";import{m as D,w as J}from"./useManagerApi-C3X3JX66.js";import{u as K}from"./useToast-BIVFyGJl.js";const P={class:"check-body"},Q={class:"version-row"},X={class:"version-row"},Y=T({__name:"UpdateCheckDialog",props:{modelValue:{type:Boolean,default:!1},modelModifiers:{}},emits:["update:modelValue"],setup(S){const{toast:w}=K(),y=R(S,"modelValue"),p=g(!1),m=g(!1),a=g(null),f=g(null),i=g(null),h=async()=>{a.value=null,f.value=null,i.value=null,p.value=!0;try{a.value=await D.checkUpdate()}catch(e){f.value=e.message||"检查更新失败"}finally{p.value=!1}},n=async()=>{var e;if(a.value){try{await I.confirm(`确定更新到 ${a.value.latestVersion}?服务将自动重启并在启动时安装新版本(期间界面请求会短暂失败,属正常现象)。`,"更新确认",{confirmButtonText:"立即更新",cancelButtonText:"取消",type:"warning"})}catch{return}m.value=!0;try{const t=await D.update(),d=await D.applyUpdate();if(!d.updated){i.value=`已是最新版本 ${d.toVersion}`,a.value={hasUpdate:!1,currentVersion:d.toVersion,latestVersion:d.toVersion,checkedAt:Date.now()};return}i.value=`正在重启服务并安装 ${d.toVersion},请稍候(预计 1~3 分钟)...`;const s=await J({targetVersion:d.toVersion,sinceAppliedAt:((e=t.lastApply)==null?void 0:e.appliedAt)??null});s&&!s.error?(w(`已更新到 ${s.toVersion}`,"success"),i.value=`已更新 ${s.fromVersion} → ${s.toVersion}`,a.value={hasUpdate:!1,currentVersion:s.toVersion,latestVersion:s.toVersion,checkedAt:Date.now()}):s!=null&&s.error?(w(`更新失败:${s.error}`,"error"),i.value=`更新失败:${s.error}(服务已恢复旧版本)`):i.value="更新耗时较长,请稍后刷新页面查看结果"}catch(t){w(t.message||"更新失败","error")}finally{m.value=!1}}};return(e,t)=>{const d=r("el-tag"),s=r("el-alert"),V=r("el-button"),U=r("el-empty"),b=r("el-dialog"),C=L("loading");return v(),k(b,{modelValue:y.value,"onUpdate:modelValue":t[2]||(t[2]=_=>y.value=_),title:"检查更新",width:"420px","close-on-click-modal":!m.value,onOpen:h},{footer:o(()=>{var _;return[(_=a.value)!=null&&_.hasUpdate?(v(),k(V,{key:0,type:"primary",loading:m.value,onClick:n},{default:o(()=>[u($(m.value?"更新中...":"立即更新"),1)]),_:1},8,["loading"])):x("",!0),l(V,{onClick:t[1]||(t[1]=M=>y.value=!1)},{default:o(()=>[...t[6]||(t[6]=[u("关闭",-1)])]),_:1})]}),default:o(()=>[z((v(),B("div",P,[a.value?(v(),B(F,{key:0},[c("div",Q,[t[3]||(t[3]=c("span",{class:"version-label"},"当前版本",-1)),l(d,{size:"small"},{default:o(()=>[u($(a.value.currentVersion),1)]),_:1})]),c("div",X,[t[4]||(t[4]=c("span",{class:"version-label"},"最新版本",-1)),l(d,{type:a.value.hasUpdate?"warning":"success",size:"small","disable-transitions":""},{default:o(()=>[u($(a.value.latestVersion),1)]),_:1},8,["type"])]),l(s,{title:a.value.hasUpdate?`发现新版本 ${a.value.latestVersion}`:"已是最新版本",type:a.value.hasUpdate?"warning":"success","show-icon":"",closable:!1,class:"mt-12"},null,8,["title","type"])],64)):!p.value&&f.value?(v(),k(U,{key:1,description:f.value},{default:o(()=>[l(V,{type:"primary",onClick:h},{default:o(()=>[...t[5]||(t[5]=[u("重试",-1)])]),_:1})]),_:1},8,["description"])):x("",!0)])),[[C,p.value]]),i.value?(v(),k(s,{key:0,title:i.value,type:"info","show-icon":"",class:"mt-12",onClose:t[0]||(t[0]=_=>i.value=null)},null,8,["title"])):x("",!0)]),_:1},8,["modelValue","close-on-click-modal"])}}}),Z=W(Y,[["__scopeId","data-v-eaed444e"]]),ee={class:"layout"},te={class:"header-nav"},oe={class:"header-actions"},le={class:"main"},se={class:"page"},ue=T({__name:"LayoutView",setup(S){const w=G(),y=O(),p=g(!1);q(()=>{j()});const m=A(()=>{var n;return((n=H.value)==null?void 0:n.authRequired)!==!1}),a=A(()=>{if(!m.value)return"免登录";const n=localStorage.getItem("webui_token")||"";try{return atob(n).split(":")[0]||"用户"}catch{return"用户"}}),f=A(()=>{const n=w.path;return n==="/"?"/":n.startsWith("/providers")?"/providers":n.startsWith("/settings")?"/settings":n.startsWith("/logs")?"/logs":"/"}),i=()=>{localStorage.removeItem("webui_token"),y.push("/login")},h=n=>{n==="logout"&&i(),n==="check-update"&&(p.value=!0)};return(n,e)=>{const t=r("el-menu-item"),d=r("el-menu"),s=r("ArrowDown"),V=r("el-icon"),U=r("el-button"),b=r("el-dropdown-item"),C=r("el-dropdown-menu"),_=r("el-dropdown"),M=r("el-header"),E=r("router-view");return v(),B("div",ee,[l(M,{class:"header"},{default:o(()=>[e[7]||(e[7]=c("h1",null,[c("span",null,"E"),u("LLM")],-1)),c("nav",te,[l(d,{mode:"horizontal","default-active":f.value,ellipsis:!1,router:"",class:"header-menu"},{default:o(()=>[l(t,{index:"/"},{default:o(()=>[...e[1]||(e[1]=[u("首页",-1)])]),_:1}),l(t,{index:"/providers"},{default:o(()=>[...e[2]||(e[2]=[u("供应商管理",-1)])]),_:1}),l(t,{index:"/logs"},{default:o(()=>[...e[3]||(e[3]=[u("日志",-1)])]),_:1}),l(t,{index:"/settings"},{default:o(()=>[...e[4]||(e[4]=[u("设置",-1)])]),_:1})]),_:1},8,["default-active"])]),c("div",oe,[l(_,{trigger:"click",onCommand:h,class:"ml-12"},{dropdown:o(()=>[l(C,null,{default:o(()=>[l(b,{command:"check-update"},{default:o(()=>[...e[5]||(e[5]=[u("检查更新",-1)])]),_:1}),m.value?(v(),k(b,{key:0,command:"logout",divided:""},{default:o(()=>[...e[6]||(e[6]=[u("退出",-1)])]),_:1})):x("",!0)]),_:1})]),default:o(()=>[l(U,null,{default:o(()=>[u($(a.value)+" ",1),l(V,{class:"el-icon--right"},{default:o(()=>[l(s)]),_:1})]),_:1})]),_:1})])]),_:1}),c("main",le,[c("div",se,[l(E)])]),l(Z,{modelValue:p.value,"onUpdate:modelValue":e[0]||(e[0]=N=>p.value=N)},null,8,["modelValue"])])}}});export{ue as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as h,e as b,g as o,w as l,a,o as _,f as k,a0 as x,a6 as f,c as C,i as L,h as B,r as i,A as N,n as I,_ as K}from"./index-
|
|
1
|
+
import{d as h,e as b,g as o,w as l,a,o as _,f as k,a0 as x,a6 as f,c as C,i as L,h as B,r as i,A as N,n as I,_ as K}from"./index-DzBTME5Z.js";const A={class:"login-wrap"},E=h({__name:"LoginView",setup(M){const v=I(),n=i(""),s=i(""),t=i(""),d=i(!1);async function r(){if(!n.value){t.value="请输入用户名";return}if(!s.value){t.value="请输入密码";return}d.value=!0,t.value="";try{const u=await N.post("/api/auth/login",{username:n.value.trim(),password:s.value});localStorage.setItem("webui_token",u.token),v.push("/")}catch(u){t.value=u.message||"登录失败"}finally{d.value=!1}}return(u,e)=>{const p=a("el-input"),m=a("el-form-item"),w=a("el-alert"),g=a("el-button"),V=a("el-form"),y=a("el-card");return _(),b("div",A,[o(y,{shadow:"hover",class:"login-card"},{default:l(()=>[e[3]||(e[3]=k("h2",{class:"login-title"},"ELLM",-1)),o(V,{"label-position":"top",onSubmit:x(r,["prevent"])},{default:l(()=>[o(m,{label:"用户名"},{default:l(()=>[o(p,{modelValue:n.value,"onUpdate:modelValue":e[0]||(e[0]=c=>n.value=c),placeholder:"请输入用户名",onKeyup:f(r,["enter"])},null,8,["modelValue"])]),_:1}),o(m,{label:"密码"},{default:l(()=>[o(p,{modelValue:s.value,"onUpdate:modelValue":e[1]||(e[1]=c=>s.value=c),type:"password",placeholder:"请输入密码","show-password":"",onKeyup:f(r,["enter"])},null,8,["modelValue"])]),_:1}),t.value?(_(),C(w,{key:0,title:t.value,type:"error","show-icon":"",class:"mb-16"},null,8,["title"])):L("",!0),o(g,{type:"primary",class:"full-width",loading:d.value,onClick:r},{default:l(()=>[...e[2]||(e[2]=[B(" 登录 ",-1)])]),_:1},8,["loading"])]),_:1})]),_:1})])}}}),U=K(E,[["__scopeId","data-v-c944978e"]]);export{U as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{d as G,a as b,j as H,o as _,c as q,w as a,e as g,g as e,h as i,t as u,a2 as m,b as Q,F as P,f as d,i as j,r as y,A,_ as X,k as pe,v as ce,a6 as _e,m as ve}from"./index-
|
|
1
|
+
import{d as G,a as b,j as H,o as _,c as q,w as a,e as g,g as e,h as i,t as u,a2 as m,b as Q,F as P,f as d,i as j,r as y,A,_ as X,k as pe,v as ce,a6 as _e,m as ve}from"./index-DzBTME5Z.js";import{u as me}from"./providers-DN-6AbdJ.js";import{u as Z}from"./useToast-BIVFyGJl.js";import"./config-CFGI6BQU.js";async function ee(p){try{if(navigator.clipboard&&window.isSecureContext)return await navigator.clipboard.writeText(p),!0}catch{}try{const f=document.createElement("textarea");f.value=p,f.style.position="fixed",f.style.opacity="0",document.body.appendChild(f),f.select();const k=document.execCommand("copy");return document.body.removeChild(f),k}catch{return!1}}const te=p=>{if(!p)return"-";const f=new Date(p),k=w=>String(w).padStart(2,"0");return`${f.getFullYear()}-${k(f.getMonth()+1)}-${k(f.getDate())} ${k(f.getHours())}:${k(f.getMinutes())}:${k(f.getSeconds())}`},V=p=>p?typeof p=="string"?p:JSON.stringify(p,null,2):"-",fe=p=>{if(!p)return"-";try{return JSON.stringify(JSON.parse(p),null,2)}catch{return p}},T=p=>p.toLocaleString(),le=p=>p==null||p<=0?"-":p>=1e3?(p/1e3).toFixed(2)+"s":Math.round(p)+"ms",ae=p=>{const f=p.input_tokens||0,k=p.cache_read_tokens||0;return f<=0?"-":(k/f*100).toFixed(1)+"%"},be={key:0,class:"detail-content"},ge={key:0,class:"ip-link"},ye={class:"ip-pop"},ke={class:"ip-pop-row"},he={key:0,class:"ip-pop-row"},xe={key:1,class:"ip-pop-error"},we={key:2},De=["href"],Ce={key:1},$e={key:1},Ve={class:"error-text"},Se={class:"pane-bar"},Ie={class:"json-block"},qe={class:"pane-bar"},ze={class:"json-block"},Re={class:"pane-bar"},Ue={class:"json-block"},je={class:"pane-bar"},Te={class:"json-block"},Ne={class:"pane-bar"},Le={class:"json-block"},Me={class:"pane-bar"},Ye={class:"json-block"},Ee={class:"pane-bar"},Pe={class:"json-block"},Fe={class:"pane-bar"},Be={class:"json-block"},Je=G({__name:"LogDetailDialog",setup(p,{expose:f}){const{toast:k}=Z(),w=y(!1),t=y(null),S=y("info"),I=y(!1);f({open:async v=>{w.value=!0,t.value=null,S.value="info";try{const l=v.id?`?id=${v.id}`:`?_file=${encodeURIComponent(v._file)}`,c=await A.get("/api/logs/detail"+l);c&&c.detail?t.value={...c.detail,...c.meta}:t.value=c}catch(l){console.error(l)}}});const h=async v=>{await ee(v)?k("已复制到剪贴板","success"):k("复制失败","error")},N=async v=>{if(!(v._ipInfo||v._ipInfoError)){I.value=!0;try{const l=await A.get(`/api/logs/ipinfo?ip=${encodeURIComponent(v.ip)}`);l.error?v._ipInfoError=l.error:v._ipInfo=l}catch{v._ipInfoError="查询失败"}finally{I.value=!1}}},M=v=>[v.country,v.region,v.city].filter(Boolean).join(" · ")||"-";return(v,l)=>{const c=b("el-descriptions-item"),Y=b("el-tag"),F=b("el-divider"),B=b("el-popover"),J=b("el-descriptions"),E=b("el-alert"),x=b("el-tab-pane"),D=b("el-button"),K=b("el-tabs"),L=b("el-dialog"),C=H("loading");return _(),q(L,{modelValue:w.value,"onUpdate:modelValue":l[11]||(l[11]=z=>w.value=z),title:"日志详情",width:"80%",top:"5vh","destroy-on-close":""},{default:a(()=>[t.value?(_(),g("div",be,[e(K,{modelValue:S.value,"onUpdate:modelValue":l[10]||(l[10]=z=>S.value=z)},{default:a(()=>{var z,r,s;return[e(x,{label:"基本信息",name:"info"},{default:a(()=>{var n;return[e(J,{column:2,border:""},{default:a(()=>[e(c,{label:"时间"},{default:a(()=>[i(u(m(te)(t.value.time)),1)]),_:1}),e(c,{label:"模型"},{default:a(()=>[i(u(t.value.model),1)]),_:1}),e(c,{label:"方法"},{default:a(()=>[i(u(t.value.method),1)]),_:1}),e(c,{label:"路径"},{default:a(()=>[i(u(t.value.path),1)]),_:1}),e(c,{label:"状态码"},{default:a(()=>[i(u(t.value.status),1)]),_:1}),e(c,{label:"流式"},{default:a(()=>[e(Y,{type:t.value.stream?"warning":"info"},{default:a(()=>[i(u(t.value.stream?"是":"否"),1)]),_:1},8,["type"])]),_:1}),e(c,{label:"IP"},{default:a(()=>[t.value.ip?(_(),g("span",ge,[e(B,{placement:"right",width:"240",trigger:"click",onShow:l[0]||(l[0]=R=>N(t.value))},{reference:a(()=>[d("span",null,u(t.value.ip),1)]),default:a(()=>[Q((_(),g("div",ye,[t.value._ipInfo?(_(),g(P,{key:0},[d("div",ke,[l[12]||(l[12]=d("span",{class:"ip-pop-label"},"归属地",-1)),d("span",null,u(M(t.value._ipInfo)),1)]),t.value._ipInfo.isp?(_(),g("div",he,[l[13]||(l[13]=d("span",{class:"ip-pop-label"},"运营商",-1)),d("span",null,u(t.value._ipInfo.isp),1)])):j("",!0)],64)):t.value._ipInfoError?(_(),g("div",xe,u(t.value._ipInfoError),1)):(_(),g("span",we,"查询中...")),e(F,{style:{margin:"8px 0"}}),d("a",{class:"ip-pop-link",href:`https://m.ip138.com/iplookup.php?ip=${encodeURIComponent(t.value.ip)}`,target:"_blank"},"在 ip138 查看",8,De)])),[[C,I.value]])]),_:1})])):(_(),g("span",Ce,"-"))]),_:1}),e(c,{label:"Session"},{default:a(()=>[i(u(t.value.session_id||"-"),1)]),_:1}),e(c,{label:"Request ID"},{default:a(()=>[t.value.request_id?(_(),g("span",{key:0,class:"request-id",title:"点击复制(可用于关联控制台日志与检索)",onClick:l[1]||(l[1]=R=>h(t.value.request_id))},u(t.value.request_id),1)):(_(),g("span",$e,"-"))]),_:1}),e(c,{label:"输入 Token(含缓存读取)"},{default:a(()=>[i(u(m(T)(t.value.input_tokens??0)),1)]),_:1}),e(c,{label:"输出 Token"},{default:a(()=>[i(u(m(T)(t.value.output_tokens??0)),1)]),_:1}),e(c,{label:"缓存读取"},{default:a(()=>[i(u(m(T)(t.value.cache_read_tokens??0)),1)]),_:1}),e(c,{label:"请求耗时"},{default:a(()=>[i(u(m(le)(t.value.duration)),1)]),_:1}),e(c,{label:"缓存命中率"},{default:a(()=>[i(u(m(ae)(t.value)),1)]),_:1}),t.value.error?(_(),q(c,{key:0,label:"错误",span:2},{default:a(()=>[d("span",Ve,u(t.value.error),1)]),_:1})):j("",!0)]),_:1}),(n=t.value.response)!=null&&n.truncated?(_(),q(E,{key:0,class:"mt-16",type:"warning",closable:!1,title:"内容超过单请求捕获上限,已截断"})):j("",!0)]}),_:1}),(z=t.value.response)!=null&&z._capture?(_(),g(P,{key:0},[e(x,{label:"客户端请求",name:"inbound"},{default:a(()=>[d("div",Se,[e(D,{size:"small",class:"copy-btn",onClick:l[2]||(l[2]=n=>h(m(V)(t.value.response.inbound_request)))},{default:a(()=>[...l[14]||(l[14]=[i(" 复制 ",-1)])]),_:1})]),d("pre",Ie,u(m(V)(t.value.response.inbound_request)),1)]),_:1}),e(x,{label:"转发上游的请求",name:"upstreamReq"},{default:a(()=>[d("div",qe,[e(D,{size:"small",class:"copy-btn",onClick:l[3]||(l[3]=n=>h(m(V)(t.value.response.upstream_request)))},{default:a(()=>[...l[15]||(l[15]=[i(" 复制 ",-1)])]),_:1})]),d("pre",ze,u(m(V)(t.value.response.upstream_request)),1)]),_:1}),t.value.response.upstream_response_text?(_(),q(x,{key:0,label:"上游响应(原始)",name:"upstreamRes"},{default:a(()=>[d("div",Re,[e(D,{size:"small",class:"copy-btn",onClick:l[4]||(l[4]=n=>h(t.value.response.upstream_response_text))},{default:a(()=>[...l[16]||(l[16]=[i(" 复制 ",-1)])]),_:1})]),d("pre",Ue,u(m(fe)(t.value.response.upstream_response_text)),1)]),_:1})):(r=t.value.response.upstream_stream_frames)!=null&&r.length?(_(),q(x,{key:1,label:`上游响应(原始流,${t.value.response.upstream_stream_frames.length} 帧)`,name:"upstreamStream"},{default:a(()=>[d("div",je,[e(D,{size:"small",class:"copy-btn",onClick:l[5]||(l[5]=n=>h(t.value.response.upstream_stream_frames.join(`
|
|
2
2
|
|
|
3
3
|
`)))},{default:a(()=>[...l[17]||(l[17]=[i(" 复制 ",-1)])]),_:1})]),d("pre",Te,u(t.value.response.upstream_stream_frames.join(`
|
|
4
4
|
|