hermes-web-ui 0.4.1 → 0.4.2
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/client/assets/{Add-BpktEZsz.js → Add-COjp_zn3.js} +1 -1
- package/dist/client/assets/{Button-Cnfw-IjX.js → Button-pgPN7RfC.js} +1 -1
- package/dist/client/assets/{ChannelsView-8vPg4mUj.js → ChannelsView-qFMvJ9rS.js} +1 -1
- package/dist/client/assets/ChatView-DVQv3z6i.js +127 -0
- package/dist/client/assets/ChatView-w9DKSiie.css +1 -0
- package/dist/client/assets/{Close-U2JC-gNs.js → Close-CXC76d7R.js} +1 -1
- package/dist/client/assets/{FormItem-hNEKqj3O.js → FormItem-DIcSMjKz.js} +1 -1
- package/dist/client/assets/{GatewaysView-Y-OpJkmm.js → GatewaysView-BeaZvbdd.js} +1 -1
- package/dist/client/assets/{Input-DrKhBiZw.js → Input-CxMM68Q2.js} +1 -1
- package/dist/client/assets/{InputNumber-CpgDdt3i.js → InputNumber-Btyn8bQo.js} +1 -1
- package/dist/client/assets/{JobsView-DPWQMuXD.js → JobsView-DhosFF52.js} +2 -2
- package/dist/client/assets/{LoginView-i8prLGX4.js → LoginView-DrjDX7xD.js} +1 -1
- package/dist/client/assets/{LogsView-DKijLNKW.js → LogsView-BpW_vgEs.js} +1 -1
- package/dist/client/assets/{MarkdownRenderer-DENPDjvG.js → MarkdownRenderer-G4nly1xR.js} +1 -1
- package/dist/client/assets/{MemoryView-FsdXJHO2.js → MemoryView-CP3K8mDG.js} +1 -1
- package/dist/client/assets/{Modal-R2Z6-Zms.js → Modal-rKb1tfQv.js} +1 -1
- package/dist/client/assets/{ModelsView-CUhcDxQn.js → ModelsView-DdQUiiu6.js} +1 -1
- package/dist/client/assets/{Popconfirm-LcqynqV7.js → Popconfirm-DnYCLqNF.js} +1 -1
- package/dist/client/assets/{Popover-BMyFTs0l.js → Popover-DAXLiB78.js} +1 -1
- package/dist/client/assets/{ProfilesView-CeMhWRo4.js → ProfilesView-Bkhqt3QB.js} +1 -1
- package/dist/client/assets/{Select-DuDO62HK.js → Select-CpNY3UGb.js} +1 -1
- package/dist/client/assets/{SettingRow-Dqpk_Y1X.js → SettingRow-B4_BuJSm.js} +1 -1
- package/dist/client/assets/{SettingsView-C3sd8K0e.css → SettingsView-CX312EGG.css} +1 -1
- package/dist/client/assets/{SettingsView-C-Wmo-pf.js → SettingsView-ZwzxJZVc.js} +2 -2
- package/dist/client/assets/{SkillsView--XG2gvdt.js → SkillsView-B3X9y2kZ.js} +1 -1
- package/dist/client/assets/{Spin-CNthlR40.js → Spin-CAOjab_F.js} +1 -1
- package/dist/client/assets/{Suffix-CeHN3ihg.js → Suffix-DQWmhzzW.js} +1 -1
- package/dist/client/assets/{Switch-HUSzpquo.js → Switch-haCJAcVn.js} +1 -1
- package/dist/client/assets/{Tag-bcPrHTQq.js → Tag-CKzgX6hi.js} +1 -1
- package/dist/client/assets/{TerminalView-CxtsiKer.js → TerminalView-CmSON012.js} +1 -1
- package/dist/client/assets/{Tooltip-CsnrCUqC.js → Tooltip-U6DmMv6W.js} +1 -1
- package/dist/client/assets/{UsageView-w5xY3YK-.js → UsageView-rmIKdR1u.js} +1 -1
- package/dist/client/assets/{Warning-B-4ukuIo.js → Warning-B2AD2ulw.js} +1 -1
- package/dist/client/assets/{_plugin-vue_export-helper-DTysiCFw.js → _plugin-vue_export-helper-DXZ6IauR.js} +1 -1
- package/dist/client/assets/{app-Cj6XwFKm.js → app-Du5RZCLa.js} +1 -1
- package/dist/client/assets/app-lD2ZIoa4.js +1 -0
- package/dist/client/assets/{browser-DkMcmggy.js → browser-DcLLT85r.js} +1 -1
- package/dist/client/assets/chat-DJP53-h1.js +6 -0
- package/dist/client/assets/composables-CjmuafMO.js +1 -0
- package/dist/client/assets/{fade-in.cssr-CkQvzPci.js → fade-in.cssr-CkQxIGt5.js} +1 -1
- package/dist/client/assets/index-BqaBjme9.js +284 -0
- package/dist/client/assets/{jobs-B_aJckhl.js → jobs-BnXwbdOs.js} +1 -1
- package/dist/client/assets/{light-B5Gclu7u.js → light-BZfVIZ0W.js} +1 -1
- package/dist/client/assets/{light-UxDRH3KV.js → light-Bdfae2y3.js} +1 -1
- package/dist/client/assets/{light-CZF9XJcN.js → light-Dgzhn0jz.js} +1 -1
- package/dist/client/assets/{light-DSFGnDIn.js → light-Jn66LOmu.js} +1 -1
- package/dist/client/assets/{light-CwhS-d6R.js → light-ZuZhSzix.js} +1 -1
- package/dist/client/assets/{light-ZT7fg6Ar.js → light-ba4gwt1q.js} +1 -1
- package/dist/client/assets/{models-BVMLuhRp.js → models-mCQyOPuV.js} +1 -1
- package/dist/client/assets/{pinia-Cw7gKk_G.js → pinia-Jb4QOAzE.js} +1 -1
- package/dist/client/assets/{profiles-PYziKhyQ.js → profiles-PisKQKsd.js} +1 -1
- package/dist/client/assets/{router-DZ0K5mgk.js → router-qWVkGgap.js} +2 -2
- package/dist/client/assets/session-browser-prefs-Bh1and1f.js +1 -0
- package/dist/client/assets/{sessions-BmGawaJ1.js → sessions-smjenK_5.js} +1 -1
- package/dist/client/assets/{skills-D_FCqgt0.js → skills-BIFy9nXD.js} +1 -1
- package/dist/client/assets/{use-message-Cu2H6Jgg.js → use-message-Do_vF1fs.js} +1 -1
- package/dist/client/assets/{useTheme-CNjnv-8-.js → useTheme-BFm8wMmc.js} +1 -1
- package/dist/client/index.html +27 -27
- package/dist/server/index.js +456 -76
- package/dist/server/index.js.map +4 -4
- package/package.json +1 -1
- package/dist/client/assets/ChatView-BndkT9Ak.js +0 -127
- package/dist/client/assets/ChatView-Bp0GIJ5d.css +0 -1
- package/dist/client/assets/app-BPvkNIt-.js +0 -1
- package/dist/client/assets/chat-CJVCt7tU.js +0 -6
- package/dist/client/assets/composables-BVHKoSa5.js +0 -1
- package/dist/client/assets/index-6U3b19b2.js +0 -284
package/dist/server/index.js
CHANGED
|
@@ -40045,7 +40045,19 @@ function resolveHermesBin() {
|
|
|
40045
40045
|
return "hermes";
|
|
40046
40046
|
}
|
|
40047
40047
|
var HERMES_BIN2 = resolveHermesBin();
|
|
40048
|
-
|
|
40048
|
+
function parseSessionExport(stdout) {
|
|
40049
|
+
const lines = stdout.trim().split("\n").filter(Boolean);
|
|
40050
|
+
const sessions2 = [];
|
|
40051
|
+
for (const line of lines) {
|
|
40052
|
+
try {
|
|
40053
|
+
const raw = JSON.parse(line);
|
|
40054
|
+
sessions2.push(raw);
|
|
40055
|
+
} catch {
|
|
40056
|
+
}
|
|
40057
|
+
}
|
|
40058
|
+
return sessions2;
|
|
40059
|
+
}
|
|
40060
|
+
async function exportSessionsRaw(source) {
|
|
40049
40061
|
const args2 = ["sessions", "export", "-"];
|
|
40050
40062
|
if (source) args2.push("--source", source);
|
|
40051
40063
|
try {
|
|
@@ -40055,53 +40067,52 @@ async function listSessions(source, limit) {
|
|
|
40055
40067
|
timeout: 3e4,
|
|
40056
40068
|
...execOpts
|
|
40057
40069
|
});
|
|
40058
|
-
|
|
40059
|
-
const sessions2 = [];
|
|
40060
|
-
for (const line of lines) {
|
|
40061
|
-
try {
|
|
40062
|
-
const raw = JSON.parse(line);
|
|
40063
|
-
let title = raw.title;
|
|
40064
|
-
if (!title && raw.messages) {
|
|
40065
|
-
const firstUser = raw.messages.find((m) => m.role === "user");
|
|
40066
|
-
if (firstUser?.content) {
|
|
40067
|
-
const t = String(firstUser.content).slice(0, 40);
|
|
40068
|
-
title = t + (String(firstUser.content).length > 40 ? "..." : "");
|
|
40069
|
-
}
|
|
40070
|
-
}
|
|
40071
|
-
sessions2.push({
|
|
40072
|
-
id: raw.id,
|
|
40073
|
-
source: raw.source,
|
|
40074
|
-
user_id: raw.user_id,
|
|
40075
|
-
model: raw.model,
|
|
40076
|
-
title,
|
|
40077
|
-
started_at: raw.started_at,
|
|
40078
|
-
ended_at: raw.ended_at,
|
|
40079
|
-
end_reason: raw.end_reason,
|
|
40080
|
-
message_count: raw.message_count,
|
|
40081
|
-
tool_call_count: raw.tool_call_count,
|
|
40082
|
-
input_tokens: raw.input_tokens,
|
|
40083
|
-
output_tokens: raw.output_tokens,
|
|
40084
|
-
cache_read_tokens: raw.cache_read_tokens || 0,
|
|
40085
|
-
cache_write_tokens: raw.cache_write_tokens || 0,
|
|
40086
|
-
reasoning_tokens: raw.reasoning_tokens || 0,
|
|
40087
|
-
billing_provider: raw.billing_provider,
|
|
40088
|
-
estimated_cost_usd: raw.estimated_cost_usd,
|
|
40089
|
-
actual_cost_usd: raw.actual_cost_usd ?? null,
|
|
40090
|
-
cost_status: raw.cost_status || ""
|
|
40091
|
-
});
|
|
40092
|
-
} catch {
|
|
40093
|
-
}
|
|
40094
|
-
}
|
|
40095
|
-
sessions2.sort((a, b) => b.started_at - a.started_at);
|
|
40096
|
-
if (limit && limit > 0) {
|
|
40097
|
-
return sessions2.slice(0, limit);
|
|
40098
|
-
}
|
|
40099
|
-
return sessions2;
|
|
40070
|
+
return parseSessionExport(stdout);
|
|
40100
40071
|
} catch (err) {
|
|
40101
40072
|
logger.error(err, "Hermes CLI: sessions export failed");
|
|
40102
40073
|
throw new Error(`Failed to list sessions: ${err.message}`);
|
|
40103
40074
|
}
|
|
40104
40075
|
}
|
|
40076
|
+
async function listSessions(source, limit) {
|
|
40077
|
+
const raws = await exportSessionsRaw(source);
|
|
40078
|
+
const sessions2 = [];
|
|
40079
|
+
for (const raw of raws) {
|
|
40080
|
+
let title = raw.title;
|
|
40081
|
+
if (!title && raw.messages) {
|
|
40082
|
+
const firstUser = raw.messages.find((m) => m.role === "user");
|
|
40083
|
+
if (firstUser?.content) {
|
|
40084
|
+
const t = String(firstUser.content).slice(0, 40);
|
|
40085
|
+
title = t + (String(firstUser.content).length > 40 ? "..." : "");
|
|
40086
|
+
}
|
|
40087
|
+
}
|
|
40088
|
+
sessions2.push({
|
|
40089
|
+
id: raw.id,
|
|
40090
|
+
source: raw.source,
|
|
40091
|
+
user_id: raw.user_id,
|
|
40092
|
+
model: raw.model,
|
|
40093
|
+
title,
|
|
40094
|
+
started_at: raw.started_at,
|
|
40095
|
+
ended_at: raw.ended_at,
|
|
40096
|
+
end_reason: raw.end_reason,
|
|
40097
|
+
message_count: raw.message_count,
|
|
40098
|
+
tool_call_count: raw.tool_call_count,
|
|
40099
|
+
input_tokens: raw.input_tokens,
|
|
40100
|
+
output_tokens: raw.output_tokens,
|
|
40101
|
+
cache_read_tokens: raw.cache_read_tokens || 0,
|
|
40102
|
+
cache_write_tokens: raw.cache_write_tokens || 0,
|
|
40103
|
+
reasoning_tokens: raw.reasoning_tokens || 0,
|
|
40104
|
+
billing_provider: raw.billing_provider,
|
|
40105
|
+
estimated_cost_usd: raw.estimated_cost_usd,
|
|
40106
|
+
actual_cost_usd: raw.actual_cost_usd ?? null,
|
|
40107
|
+
cost_status: raw.cost_status || ""
|
|
40108
|
+
});
|
|
40109
|
+
}
|
|
40110
|
+
sessions2.sort((a, b) => b.started_at - a.started_at);
|
|
40111
|
+
if (limit && limit > 0) {
|
|
40112
|
+
return sessions2.slice(0, limit);
|
|
40113
|
+
}
|
|
40114
|
+
return sessions2;
|
|
40115
|
+
}
|
|
40105
40116
|
async function getSession(id) {
|
|
40106
40117
|
const args2 = ["sessions", "export", "-", "--session-id", id];
|
|
40107
40118
|
try {
|
|
@@ -40110,10 +40121,9 @@ async function getSession(id) {
|
|
|
40110
40121
|
timeout: 3e4,
|
|
40111
40122
|
...execOpts
|
|
40112
40123
|
});
|
|
40113
|
-
const
|
|
40114
|
-
if (
|
|
40115
|
-
|
|
40116
|
-
const raw = JSON.parse(lines[0]);
|
|
40124
|
+
const raws = parseSessionExport(stdout);
|
|
40125
|
+
if (raws.length === 0) return null;
|
|
40126
|
+
const raw = raws[0];
|
|
40117
40127
|
return {
|
|
40118
40128
|
id: raw.id,
|
|
40119
40129
|
source: raw.source,
|
|
@@ -40410,7 +40420,7 @@ async function importProfile(archivePath, name) {
|
|
|
40410
40420
|
}
|
|
40411
40421
|
|
|
40412
40422
|
// packages/server/src/controllers/health.ts
|
|
40413
|
-
var LOCAL_VERSION = true ? "0.4.
|
|
40423
|
+
var LOCAL_VERSION = true ? "0.4.2" : (() => {
|
|
40414
40424
|
try {
|
|
40415
40425
|
const { readFileSync: readFileSync8 } = null;
|
|
40416
40426
|
const { resolve: resolve8 } = null;
|
|
@@ -40676,6 +40686,309 @@ async function handleUpdate(ctx) {
|
|
|
40676
40686
|
var updateRoutes = new router_default();
|
|
40677
40687
|
updateRoutes.post("/api/hermes/update", handleUpdate);
|
|
40678
40688
|
|
|
40689
|
+
// packages/server/src/services/hermes/conversations.ts
|
|
40690
|
+
var LINEAGE_TOLERANCE_SECONDS = 3;
|
|
40691
|
+
var LIVE_WINDOW_SECONDS = 300;
|
|
40692
|
+
var EXPORT_CACHE_TTL_MS = 3e4;
|
|
40693
|
+
var DEFAULT_CONVERSATION_LIMIT = 200;
|
|
40694
|
+
var SYNTHETIC_USER_PREFIXES = [
|
|
40695
|
+
"[system:",
|
|
40696
|
+
"you've reached the maximum number of tool-calling iterations allowed.",
|
|
40697
|
+
"you have reached the maximum number of tool-calling iterations allowed."
|
|
40698
|
+
];
|
|
40699
|
+
var exportCache = /* @__PURE__ */ new Map();
|
|
40700
|
+
function cacheKey(source) {
|
|
40701
|
+
return source || "__all__";
|
|
40702
|
+
}
|
|
40703
|
+
function safeText(value) {
|
|
40704
|
+
if (typeof value === "string") return value;
|
|
40705
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
40706
|
+
return "";
|
|
40707
|
+
}
|
|
40708
|
+
function textFromContent(value) {
|
|
40709
|
+
if (typeof value === "string") return value;
|
|
40710
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
40711
|
+
if (Array.isArray(value)) {
|
|
40712
|
+
return value.map((item) => textFromContent(item).trim()).filter(Boolean).join("\n");
|
|
40713
|
+
}
|
|
40714
|
+
if (!value || typeof value !== "object") return "";
|
|
40715
|
+
const record = value;
|
|
40716
|
+
const directKeys = ["text", "content", "value"];
|
|
40717
|
+
for (const key of directKeys) {
|
|
40718
|
+
const direct = record[key];
|
|
40719
|
+
if (typeof direct === "string") return direct;
|
|
40720
|
+
if (Array.isArray(direct)) {
|
|
40721
|
+
const nested = textFromContent(direct);
|
|
40722
|
+
if (nested) return nested;
|
|
40723
|
+
}
|
|
40724
|
+
}
|
|
40725
|
+
const nestedKeys = ["parts", "children", "items"];
|
|
40726
|
+
for (const key of nestedKeys) {
|
|
40727
|
+
if (Array.isArray(record[key])) {
|
|
40728
|
+
const nested = textFromContent(record[key]);
|
|
40729
|
+
if (nested) return nested;
|
|
40730
|
+
}
|
|
40731
|
+
}
|
|
40732
|
+
const flattened = Object.values(record).map((entry) => textFromContent(entry).trim()).filter(Boolean).join("\n");
|
|
40733
|
+
if (flattened) return flattened;
|
|
40734
|
+
try {
|
|
40735
|
+
return JSON.stringify(record);
|
|
40736
|
+
} catch {
|
|
40737
|
+
return "";
|
|
40738
|
+
}
|
|
40739
|
+
}
|
|
40740
|
+
function normalizeText(value) {
|
|
40741
|
+
return textFromContent(value).replace(/\s+/g, " ").trim().toLowerCase();
|
|
40742
|
+
}
|
|
40743
|
+
function excerpt(value, width = 80) {
|
|
40744
|
+
const text = textFromContent(value).replace(/\s+/g, " ").trim();
|
|
40745
|
+
if (!text) return "";
|
|
40746
|
+
return text.length > width ? `${text.slice(0, width)}\u2026` : text;
|
|
40747
|
+
}
|
|
40748
|
+
function isSyntheticUserText(content) {
|
|
40749
|
+
const text = normalizeText(content);
|
|
40750
|
+
return SYNTHETIC_USER_PREFIXES.some((prefix) => text.startsWith(prefix));
|
|
40751
|
+
}
|
|
40752
|
+
function visibleHumanMessage(message2) {
|
|
40753
|
+
const role = safeText(message2.role);
|
|
40754
|
+
const content = textFromContent(message2.content).trim();
|
|
40755
|
+
if (!content) return false;
|
|
40756
|
+
if (role !== "user" && role !== "assistant") return false;
|
|
40757
|
+
if (role === "user" && isSyntheticUserText(content)) return false;
|
|
40758
|
+
return true;
|
|
40759
|
+
}
|
|
40760
|
+
function firstVisibleHumanText(messages) {
|
|
40761
|
+
const firstVisible = messages.find(visibleHumanMessage);
|
|
40762
|
+
return firstVisible ? textFromContent(firstVisible.content).trim() : "";
|
|
40763
|
+
}
|
|
40764
|
+
function maxMessageTimestamp(messages) {
|
|
40765
|
+
return messages.reduce((max, message2) => {
|
|
40766
|
+
const timestamp2 = Number(message2.timestamp || 0);
|
|
40767
|
+
return Number.isFinite(timestamp2) && timestamp2 > max ? timestamp2 : max;
|
|
40768
|
+
}, 0);
|
|
40769
|
+
}
|
|
40770
|
+
function enrichSession(session, nowSeconds) {
|
|
40771
|
+
const messages = Array.isArray(session.messages) ? session.messages : [];
|
|
40772
|
+
const preview = excerpt(firstVisibleHumanText(messages));
|
|
40773
|
+
const lastActive = maxMessageTimestamp(messages) || Number(session.ended_at || session.started_at || 0);
|
|
40774
|
+
const endedAt = session.ended_at ?? null;
|
|
40775
|
+
return {
|
|
40776
|
+
...session,
|
|
40777
|
+
parent_session_id: session.parent_session_id ?? null,
|
|
40778
|
+
preview,
|
|
40779
|
+
last_active: lastActive,
|
|
40780
|
+
is_active: endedAt == null && nowSeconds - lastActive <= LIVE_WINDOW_SECONDS
|
|
40781
|
+
};
|
|
40782
|
+
}
|
|
40783
|
+
function sortByRecency(items) {
|
|
40784
|
+
return [...items].sort((a, b) => {
|
|
40785
|
+
if (b.last_active !== a.last_active) return b.last_active - a.last_active;
|
|
40786
|
+
if (b.started_at !== a.started_at) return b.started_at - a.started_at;
|
|
40787
|
+
return a.id.localeCompare(b.id);
|
|
40788
|
+
});
|
|
40789
|
+
}
|
|
40790
|
+
function timingMatchesParent(parent, child) {
|
|
40791
|
+
if (!parent || !child || parent.ended_at == null) return false;
|
|
40792
|
+
return Math.abs(Number(child.started_at || 0) - Number(parent.ended_at || 0)) <= LINEAGE_TOLERANCE_SECONDS;
|
|
40793
|
+
}
|
|
40794
|
+
function isBranchRoot(session, byId) {
|
|
40795
|
+
if (!session?.parent_session_id) return false;
|
|
40796
|
+
const parent = byId.get(session.parent_session_id);
|
|
40797
|
+
return !!parent && parent.end_reason === "branched" && timingMatchesParent(parent, session);
|
|
40798
|
+
}
|
|
40799
|
+
function isVisibleRoot(session, byId) {
|
|
40800
|
+
if (!session || session.source === "tool") return false;
|
|
40801
|
+
return session.parent_session_id == null || isBranchRoot(session, byId);
|
|
40802
|
+
}
|
|
40803
|
+
function continuationCandidates(parent, byId, childrenByParent) {
|
|
40804
|
+
const childIds = childrenByParent.get(parent.id) || [];
|
|
40805
|
+
return childIds.map((childId) => byId.get(childId)).filter((child) => !!child).filter((child) => child.source !== "tool").filter((child) => child.source === parent.source).filter((child) => timingMatchesParent(parent, child)).sort((a, b) => {
|
|
40806
|
+
const aDelta = Math.abs(Number(a.started_at || 0) - Number(parent.ended_at || 0));
|
|
40807
|
+
const bDelta = Math.abs(Number(b.started_at || 0) - Number(parent.ended_at || 0));
|
|
40808
|
+
if (aDelta !== bDelta) return aDelta - bDelta;
|
|
40809
|
+
return a.id.localeCompare(b.id);
|
|
40810
|
+
});
|
|
40811
|
+
}
|
|
40812
|
+
function nextContinuationChild(parent, byId, childrenByParent) {
|
|
40813
|
+
if (parent.end_reason !== "compression") return null;
|
|
40814
|
+
const candidates = continuationCandidates(parent, byId, childrenByParent);
|
|
40815
|
+
if (candidates.length === 1) return candidates[0];
|
|
40816
|
+
const exactPreviewMatches = candidates.filter((child) => {
|
|
40817
|
+
const childPreview = normalizeText(child.preview);
|
|
40818
|
+
const parentPreview = normalizeText(parent.preview);
|
|
40819
|
+
return !!childPreview && childPreview === parentPreview;
|
|
40820
|
+
});
|
|
40821
|
+
if (exactPreviewMatches.length === 1) return exactPreviewMatches[0];
|
|
40822
|
+
return null;
|
|
40823
|
+
}
|
|
40824
|
+
function collectConversationChain(rootId, byId, childrenByParent) {
|
|
40825
|
+
const chain = [];
|
|
40826
|
+
const seen = /* @__PURE__ */ new Set();
|
|
40827
|
+
let current = byId.get(rootId) || null;
|
|
40828
|
+
while (current && !seen.has(current.id)) {
|
|
40829
|
+
chain.push(current);
|
|
40830
|
+
seen.add(current.id);
|
|
40831
|
+
current = nextContinuationChild(current, byId, childrenByParent);
|
|
40832
|
+
}
|
|
40833
|
+
return chain;
|
|
40834
|
+
}
|
|
40835
|
+
function sessionMessages(session) {
|
|
40836
|
+
return Array.isArray(session.messages) ? session.messages : [];
|
|
40837
|
+
}
|
|
40838
|
+
function normalizeVisibleMessage(message2, session, index) {
|
|
40839
|
+
if (!visibleHumanMessage(message2)) return null;
|
|
40840
|
+
const role = safeText(message2.role);
|
|
40841
|
+
const content = textFromContent(message2.content).trim();
|
|
40842
|
+
if (role !== "user" && role !== "assistant") return null;
|
|
40843
|
+
if (!content) return null;
|
|
40844
|
+
const rawTimestamp = Number(message2.timestamp);
|
|
40845
|
+
const timestamp2 = Number.isFinite(rawTimestamp) && rawTimestamp > 0 ? rawTimestamp : Number(session.ended_at || session.started_at || 0);
|
|
40846
|
+
const id = message2.id ?? `${session.id}:${index}:${timestamp2}`;
|
|
40847
|
+
return {
|
|
40848
|
+
id,
|
|
40849
|
+
session_id: safeText(message2.session_id || session.id),
|
|
40850
|
+
role,
|
|
40851
|
+
content,
|
|
40852
|
+
timestamp: timestamp2
|
|
40853
|
+
};
|
|
40854
|
+
}
|
|
40855
|
+
function visibleMessagesForSessions(sessions2) {
|
|
40856
|
+
return sessions2.flatMap((session) => sessionMessages(session).map((message2, index) => normalizeVisibleMessage({ ...message2, session_id: safeText(message2.session_id || session.id) }, session, index))).filter((message2) => !!message2).sort((a, b) => {
|
|
40857
|
+
if (a.timestamp !== b.timestamp) return a.timestamp - b.timestamp;
|
|
40858
|
+
return String(a.id).localeCompare(String(b.id));
|
|
40859
|
+
});
|
|
40860
|
+
}
|
|
40861
|
+
function hasVisibleHumanMessages(sessions2) {
|
|
40862
|
+
return visibleMessagesForSessions(sessions2).length > 0;
|
|
40863
|
+
}
|
|
40864
|
+
function toSummary(session) {
|
|
40865
|
+
return {
|
|
40866
|
+
id: session.id,
|
|
40867
|
+
source: safeText(session.source),
|
|
40868
|
+
model: safeText(session.model),
|
|
40869
|
+
title: session.title ?? null,
|
|
40870
|
+
started_at: Number(session.started_at || 0),
|
|
40871
|
+
ended_at: session.ended_at ?? null,
|
|
40872
|
+
last_active: session.last_active,
|
|
40873
|
+
message_count: Number(session.message_count || 0),
|
|
40874
|
+
tool_call_count: Number(session.tool_call_count || 0),
|
|
40875
|
+
input_tokens: Number(session.input_tokens || 0),
|
|
40876
|
+
output_tokens: Number(session.output_tokens || 0),
|
|
40877
|
+
cache_read_tokens: Number(session.cache_read_tokens || 0),
|
|
40878
|
+
cache_write_tokens: Number(session.cache_write_tokens || 0),
|
|
40879
|
+
reasoning_tokens: Number(session.reasoning_tokens || 0),
|
|
40880
|
+
billing_provider: session.billing_provider ?? null,
|
|
40881
|
+
estimated_cost_usd: Number(session.estimated_cost_usd || 0),
|
|
40882
|
+
actual_cost_usd: session.actual_cost_usd ?? null,
|
|
40883
|
+
cost_status: safeText(session.cost_status),
|
|
40884
|
+
preview: session.preview,
|
|
40885
|
+
is_active: session.is_active,
|
|
40886
|
+
thread_session_count: 1
|
|
40887
|
+
};
|
|
40888
|
+
}
|
|
40889
|
+
function aggregateSummary(rootId, byId, childrenByParent) {
|
|
40890
|
+
const chain = collectConversationChain(rootId, byId, childrenByParent);
|
|
40891
|
+
if (!chain.length || !hasVisibleHumanMessages(chain)) return null;
|
|
40892
|
+
const root = chain[0];
|
|
40893
|
+
const last = chain[chain.length - 1];
|
|
40894
|
+
const title = root.title || excerpt(firstVisibleHumanText(chain.flatMap(sessionMessages)), 72) || null;
|
|
40895
|
+
const preview = root.preview || excerpt(firstVisibleHumanText(chain.flatMap(sessionMessages)));
|
|
40896
|
+
const costStatuses = Array.from(new Set(chain.map((session) => safeText(session.cost_status)).filter(Boolean)));
|
|
40897
|
+
return {
|
|
40898
|
+
...toSummary(root),
|
|
40899
|
+
title,
|
|
40900
|
+
preview,
|
|
40901
|
+
model: safeText(last?.model || root.model),
|
|
40902
|
+
ended_at: last?.ended_at ?? null,
|
|
40903
|
+
last_active: Math.max(...chain.map((session) => session.last_active)),
|
|
40904
|
+
is_active: chain.some((session) => session.is_active),
|
|
40905
|
+
billing_provider: last?.billing_provider ?? root.billing_provider ?? null,
|
|
40906
|
+
cost_status: costStatuses.length === 1 ? costStatuses[0] : "mixed",
|
|
40907
|
+
thread_session_count: chain.length,
|
|
40908
|
+
message_count: chain.reduce((sum, session) => sum + Number(session.message_count || 0), 0),
|
|
40909
|
+
tool_call_count: chain.reduce((sum, session) => sum + Number(session.tool_call_count || 0), 0),
|
|
40910
|
+
input_tokens: chain.reduce((sum, session) => sum + Number(session.input_tokens || 0), 0),
|
|
40911
|
+
output_tokens: chain.reduce((sum, session) => sum + Number(session.output_tokens || 0), 0),
|
|
40912
|
+
cache_read_tokens: chain.reduce((sum, session) => sum + Number(session.cache_read_tokens || 0), 0),
|
|
40913
|
+
cache_write_tokens: chain.reduce((sum, session) => sum + Number(session.cache_write_tokens || 0), 0),
|
|
40914
|
+
reasoning_tokens: chain.reduce((sum, session) => sum + Number(session.reasoning_tokens || 0), 0),
|
|
40915
|
+
estimated_cost_usd: chain.reduce((sum, session) => sum + Number(session.estimated_cost_usd || 0), 0),
|
|
40916
|
+
actual_cost_usd: chain.reduce((sum, session) => {
|
|
40917
|
+
const actual = session.actual_cost_usd;
|
|
40918
|
+
if (actual == null) return sum;
|
|
40919
|
+
return (sum || 0) + Number(actual);
|
|
40920
|
+
}, null)
|
|
40921
|
+
};
|
|
40922
|
+
}
|
|
40923
|
+
async function loadSessions(source) {
|
|
40924
|
+
const key = cacheKey(source);
|
|
40925
|
+
const nowMs = Date.now();
|
|
40926
|
+
const cached = exportCache.get(key);
|
|
40927
|
+
const raws = cached && cached.expires_at_ms > nowMs ? cached.sessions : await exportSessionsRaw(source);
|
|
40928
|
+
if (!cached || cached.expires_at_ms <= nowMs) {
|
|
40929
|
+
exportCache.set(key, {
|
|
40930
|
+
expires_at_ms: nowMs + EXPORT_CACHE_TTL_MS,
|
|
40931
|
+
sessions: raws
|
|
40932
|
+
});
|
|
40933
|
+
}
|
|
40934
|
+
const nowSeconds = nowMs / 1e3;
|
|
40935
|
+
return raws.map((raw) => enrichSession(raw, nowSeconds));
|
|
40936
|
+
}
|
|
40937
|
+
async function listConversationSummaries(options = {}) {
|
|
40938
|
+
const humanOnly = options.humanOnly !== false;
|
|
40939
|
+
const limit = options.limit && options.limit > 0 ? options.limit : DEFAULT_CONVERSATION_LIMIT;
|
|
40940
|
+
const sessions2 = await loadSessions(options.source);
|
|
40941
|
+
const byId = new Map(sessions2.map((session) => [session.id, session]));
|
|
40942
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
40943
|
+
for (const session of sessions2) {
|
|
40944
|
+
const key = session.parent_session_id ?? null;
|
|
40945
|
+
const siblings = childrenByParent.get(key) || [];
|
|
40946
|
+
siblings.push(session.id);
|
|
40947
|
+
childrenByParent.set(key, siblings);
|
|
40948
|
+
}
|
|
40949
|
+
if (!humanOnly) {
|
|
40950
|
+
return sortByRecency(
|
|
40951
|
+
sessions2.filter((session) => session.source !== "tool").map(toSummary)
|
|
40952
|
+
).slice(0, limit);
|
|
40953
|
+
}
|
|
40954
|
+
const summaries = sessions2.filter((session) => isVisibleRoot(session, byId)).map((session) => aggregateSummary(session.id, byId, childrenByParent)).filter((summary) => !!summary);
|
|
40955
|
+
return sortByRecency(summaries).slice(0, limit);
|
|
40956
|
+
}
|
|
40957
|
+
async function getConversationDetail(sessionId, options = {}) {
|
|
40958
|
+
const humanOnly = options.humanOnly !== false;
|
|
40959
|
+
const sessions2 = await loadSessions(options.source);
|
|
40960
|
+
const byId = new Map(sessions2.map((session) => [session.id, session]));
|
|
40961
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
40962
|
+
for (const session of sessions2) {
|
|
40963
|
+
const key = session.parent_session_id ?? null;
|
|
40964
|
+
const siblings = childrenByParent.get(key) || [];
|
|
40965
|
+
siblings.push(session.id);
|
|
40966
|
+
childrenByParent.set(key, siblings);
|
|
40967
|
+
}
|
|
40968
|
+
if (!humanOnly) {
|
|
40969
|
+
const session = byId.get(sessionId);
|
|
40970
|
+
if (!session || session.source === "tool") return null;
|
|
40971
|
+
const messages2 = visibleMessagesForSessions([session]);
|
|
40972
|
+
return {
|
|
40973
|
+
session_id: sessionId,
|
|
40974
|
+
messages: messages2,
|
|
40975
|
+
visible_count: messages2.length,
|
|
40976
|
+
thread_session_count: 1
|
|
40977
|
+
};
|
|
40978
|
+
}
|
|
40979
|
+
const root = byId.get(sessionId);
|
|
40980
|
+
if (!isVisibleRoot(root, byId)) return null;
|
|
40981
|
+
const chain = collectConversationChain(sessionId, byId, childrenByParent);
|
|
40982
|
+
const messages = visibleMessagesForSessions(chain);
|
|
40983
|
+
if (!messages.length) return null;
|
|
40984
|
+
return {
|
|
40985
|
+
session_id: sessionId,
|
|
40986
|
+
messages,
|
|
40987
|
+
visible_count: messages.length,
|
|
40988
|
+
thread_session_count: chain.length
|
|
40989
|
+
};
|
|
40990
|
+
}
|
|
40991
|
+
|
|
40679
40992
|
// packages/server/src/services/hermes/sessions-db.ts
|
|
40680
40993
|
init_hermes_profile();
|
|
40681
40994
|
var SQLITE_AVAILABLE = (() => {
|
|
@@ -40787,6 +41100,33 @@ async function listSessionSummaries(source, limit = 2e3) {
|
|
|
40787
41100
|
|
|
40788
41101
|
// packages/server/src/controllers/hermes/sessions.ts
|
|
40789
41102
|
init_logger();
|
|
41103
|
+
function parseHumanOnly(value) {
|
|
41104
|
+
if (typeof value !== "string") return true;
|
|
41105
|
+
return value !== "false" && value !== "0";
|
|
41106
|
+
}
|
|
41107
|
+
function parseLimit(value) {
|
|
41108
|
+
if (typeof value !== "string") return void 0;
|
|
41109
|
+
const parsed = parseInt(value, 10);
|
|
41110
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
41111
|
+
}
|
|
41112
|
+
async function listConversations(ctx) {
|
|
41113
|
+
const source = ctx.query.source || void 0;
|
|
41114
|
+
const humanOnly = parseHumanOnly(ctx.query.humanOnly);
|
|
41115
|
+
const limit = parseLimit(ctx.query.limit);
|
|
41116
|
+
const sessions2 = await listConversationSummaries({ source, humanOnly, limit });
|
|
41117
|
+
ctx.body = { sessions: sessions2 };
|
|
41118
|
+
}
|
|
41119
|
+
async function getConversationMessages(ctx) {
|
|
41120
|
+
const source = ctx.query.source || void 0;
|
|
41121
|
+
const humanOnly = parseHumanOnly(ctx.query.humanOnly);
|
|
41122
|
+
const detail = await getConversationDetail(ctx.params.id, { source, humanOnly });
|
|
41123
|
+
if (!detail) {
|
|
41124
|
+
ctx.status = 404;
|
|
41125
|
+
ctx.body = { error: "Conversation not found" };
|
|
41126
|
+
return;
|
|
41127
|
+
}
|
|
41128
|
+
ctx.body = detail;
|
|
41129
|
+
}
|
|
40790
41130
|
async function list(ctx) {
|
|
40791
41131
|
const source = ctx.query.source || void 0;
|
|
40792
41132
|
const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : void 0;
|
|
@@ -40836,6 +41176,8 @@ async function rename(ctx) {
|
|
|
40836
41176
|
|
|
40837
41177
|
// packages/server/src/routes/hermes/sessions.ts
|
|
40838
41178
|
var sessionRoutes = new router_default();
|
|
41179
|
+
sessionRoutes.get("/api/hermes/sessions/conversations", listConversations);
|
|
41180
|
+
sessionRoutes.get("/api/hermes/sessions/conversations/:id/messages", getConversationMessages);
|
|
40839
41181
|
sessionRoutes.get("/api/hermes/sessions", list);
|
|
40840
41182
|
sessionRoutes.get("/api/hermes/sessions/:id", get);
|
|
40841
41183
|
sessionRoutes.delete("/api/hermes/sessions/:id", remove);
|
|
@@ -41073,6 +41415,7 @@ init_hermes_profile();
|
|
|
41073
41415
|
init_logger();
|
|
41074
41416
|
var PROVIDER_ENV_MAP = {
|
|
41075
41417
|
openrouter: { api_key_env: "OPENROUTER_API_KEY", base_url_env: "" },
|
|
41418
|
+
"glm-coding-plan": { api_key_env: "", base_url_env: "" },
|
|
41076
41419
|
zai: { api_key_env: "GLM_API_KEY", base_url_env: "" },
|
|
41077
41420
|
"kimi-coding-cn": { api_key_env: "KIMI_CN_API_KEY", base_url_env: "" },
|
|
41078
41421
|
moonshot: { api_key_env: "MOONSHOT_API_KEY", base_url_env: "" },
|
|
@@ -41459,8 +41802,8 @@ var PROVIDER_PRESETS = [
|
|
|
41459
41802
|
models: ["glm-5.1", "glm-5", "glm-5v-turbo", "glm-5-turbo", "glm-4.7", "glm-4.5", "glm-4.5-flash"]
|
|
41460
41803
|
},
|
|
41461
41804
|
{
|
|
41462
|
-
label: "
|
|
41463
|
-
value: "glm",
|
|
41805
|
+
label: "GLM-Coding-Plan",
|
|
41806
|
+
value: "glm-coding-plan",
|
|
41464
41807
|
builtin: true,
|
|
41465
41808
|
base_url: "https://api.z.ai/api/anthropic",
|
|
41466
41809
|
models: ["glm-5.1", "glm-5", "glm-5-turbo", "glm-4.7", "glm-4.5", "glm-4.5-flash"]
|
|
@@ -41732,7 +42075,9 @@ async function getAvailable(ctx) {
|
|
|
41732
42075
|
if (!cp.base_url) return null;
|
|
41733
42076
|
const providerKey = `custom:${cp.name.trim().toLowerCase().replace(/ /g, "-")}`;
|
|
41734
42077
|
const baseUrl = cp.base_url.replace(/\/+$/, "");
|
|
41735
|
-
|
|
42078
|
+
const bareKey = cp.name.trim().toLowerCase().replace(/ /g, "-");
|
|
42079
|
+
const builtinPreset = PROVIDER_PRESETS.find((p) => p.value === bareKey);
|
|
42080
|
+
let models = builtinPreset?.models?.length ? [...builtinPreset.models] : [cp.model];
|
|
41736
42081
|
if (cp.api_key) {
|
|
41737
42082
|
try {
|
|
41738
42083
|
const fetched = await fetchProviderModels(baseUrl, cp.api_key);
|
|
@@ -41740,7 +42085,9 @@ async function getAvailable(ctx) {
|
|
|
41740
42085
|
} catch {
|
|
41741
42086
|
}
|
|
41742
42087
|
}
|
|
41743
|
-
|
|
42088
|
+
const label = builtinPreset?.label || cp.name;
|
|
42089
|
+
const presetBaseUrl = builtinPreset?.base_url || "";
|
|
42090
|
+
return { providerKey, label, base_url: presetBaseUrl || baseUrl, models, api_key: cp.api_key || "" };
|
|
41744
42091
|
})
|
|
41745
42092
|
);
|
|
41746
42093
|
for (const result of customFetches) {
|
|
@@ -41811,6 +42158,7 @@ init_hermes_profile();
|
|
|
41811
42158
|
init_logger();
|
|
41812
42159
|
async function create2(ctx) {
|
|
41813
42160
|
const { name, base_url, api_key, model, providerKey } = ctx.request.body;
|
|
42161
|
+
console.log(name, base_url, api_key, model, providerKey);
|
|
41814
42162
|
if (!name || !base_url || !model) {
|
|
41815
42163
|
ctx.status = 400;
|
|
41816
42164
|
ctx.body = { error: "Missing name, base_url, or model" };
|
|
@@ -41824,36 +42172,55 @@ async function create2(ctx) {
|
|
|
41824
42172
|
try {
|
|
41825
42173
|
const poolKey = providerKey || `custom:${name.trim().toLowerCase().replace(/ /g, "-")}`;
|
|
41826
42174
|
const isBuiltin = poolKey in PROVIDER_ENV_MAP;
|
|
42175
|
+
const config2 = await readConfigYaml();
|
|
42176
|
+
if (typeof config2.model !== "object" || config2.model === null) {
|
|
42177
|
+
config2.model = {};
|
|
42178
|
+
}
|
|
41827
42179
|
if (!isBuiltin) {
|
|
41828
|
-
|
|
41829
|
-
|
|
41830
|
-
config3.custom_providers = [];
|
|
42180
|
+
if (!Array.isArray(config2.custom_providers)) {
|
|
42181
|
+
config2.custom_providers = [];
|
|
41831
42182
|
}
|
|
41832
|
-
const existing =
|
|
41833
|
-
(e) => `custom:${e.name
|
|
42183
|
+
const existing = config2.custom_providers.find(
|
|
42184
|
+
(e) => `custom:${e.name}` === poolKey
|
|
41834
42185
|
);
|
|
41835
42186
|
if (existing) {
|
|
41836
42187
|
existing.base_url = base_url;
|
|
41837
42188
|
existing.api_key = api_key;
|
|
41838
42189
|
existing.model = model;
|
|
41839
42190
|
} else {
|
|
41840
|
-
|
|
42191
|
+
config2.custom_providers.push({ name: name.trim().toLowerCase().replace(/ /g, "-"), base_url, api_key, model });
|
|
41841
42192
|
}
|
|
41842
|
-
|
|
41843
|
-
|
|
41844
|
-
|
|
41845
|
-
|
|
41846
|
-
|
|
41847
|
-
|
|
41848
|
-
|
|
42193
|
+
config2.model.default = model;
|
|
42194
|
+
config2.model.provider = poolKey;
|
|
42195
|
+
} else {
|
|
42196
|
+
console.log(PROVIDER_ENV_MAP[poolKey]);
|
|
42197
|
+
if (PROVIDER_ENV_MAP[poolKey].api_key_env) {
|
|
42198
|
+
await saveEnvValue(PROVIDER_ENV_MAP[poolKey].api_key_env, api_key);
|
|
42199
|
+
if (PROVIDER_ENV_MAP[poolKey].base_url_env) {
|
|
42200
|
+
await saveEnvValue(PROVIDER_ENV_MAP[poolKey].base_url_env, base_url);
|
|
42201
|
+
}
|
|
42202
|
+
config2.model.default = model;
|
|
42203
|
+
config2.model.provider = poolKey;
|
|
42204
|
+
} else {
|
|
42205
|
+
if (!Array.isArray(config2.custom_providers)) {
|
|
42206
|
+
config2.custom_providers = [];
|
|
42207
|
+
}
|
|
42208
|
+
const existing = config2.custom_providers.find(
|
|
42209
|
+
(e) => `custom:${e.name}` === `custom:${poolKey}`
|
|
42210
|
+
);
|
|
42211
|
+
if (existing) {
|
|
42212
|
+
existing.base_url = base_url;
|
|
42213
|
+
existing.api_key = api_key;
|
|
42214
|
+
existing.model = model;
|
|
42215
|
+
} else {
|
|
42216
|
+
config2.custom_providers.push({ name: poolKey, base_url, api_key, model });
|
|
42217
|
+
}
|
|
42218
|
+
config2.model.default = model;
|
|
42219
|
+
config2.model.provider = `custom:${poolKey}`;
|
|
41849
42220
|
}
|
|
41850
42221
|
}
|
|
41851
|
-
|
|
41852
|
-
|
|
41853
|
-
config2.model = {};
|
|
41854
|
-
}
|
|
41855
|
-
config2.model.default = model;
|
|
41856
|
-
config2.model.provider = poolKey;
|
|
42222
|
+
delete config2.model.base_url;
|
|
42223
|
+
delete config2.model.api_key;
|
|
41857
42224
|
await writeConfigYaml(config2);
|
|
41858
42225
|
try {
|
|
41859
42226
|
await restartGateway();
|
|
@@ -41955,17 +42322,27 @@ async function remove3(ctx) {
|
|
|
41955
42322
|
if (currentProvider === poolKey) {
|
|
41956
42323
|
const freshConfig = await readConfigYaml();
|
|
41957
42324
|
const remaining = Array.isArray(freshConfig.custom_providers) ? freshConfig.custom_providers : [];
|
|
41958
|
-
|
|
41959
|
-
|
|
42325
|
+
if (remaining.length > 0) {
|
|
42326
|
+
const fallbackCp = remaining[0];
|
|
41960
42327
|
const fallbackKey = `custom:${fallbackCp.name.trim().toLowerCase().replace(/ /g, "-")}`;
|
|
41961
42328
|
if (typeof freshConfig.model !== "object" || freshConfig.model === null) {
|
|
41962
42329
|
freshConfig.model = {};
|
|
41963
42330
|
}
|
|
41964
42331
|
freshConfig.model.default = fallbackCp.model;
|
|
41965
42332
|
freshConfig.model.provider = fallbackKey;
|
|
42333
|
+
delete freshConfig.model.base_url;
|
|
42334
|
+
delete freshConfig.model.api_key;
|
|
42335
|
+
await writeConfigYaml(freshConfig);
|
|
42336
|
+
} else {
|
|
42337
|
+
freshConfig.model = {};
|
|
41966
42338
|
await writeConfigYaml(freshConfig);
|
|
41967
42339
|
}
|
|
41968
42340
|
}
|
|
42341
|
+
try {
|
|
42342
|
+
await restartGateway();
|
|
42343
|
+
} catch (e) {
|
|
42344
|
+
logger.error(e, "Gateway restart failed");
|
|
42345
|
+
}
|
|
41969
42346
|
ctx.body = { success: true };
|
|
41970
42347
|
} catch (err) {
|
|
41971
42348
|
ctx.status = 500;
|
|
@@ -46668,14 +47045,17 @@ async function proxy(ctx) {
|
|
|
46668
47045
|
const profile = resolveProfile(ctx);
|
|
46669
47046
|
const upstream = resolveUpstream(ctx);
|
|
46670
47047
|
const upstreamPath = ctx.path.replace(/^\/api\/hermes\/v1/, "/v1").replace(/^\/api\/hermes/, "/api");
|
|
46671
|
-
const
|
|
47048
|
+
const params = new URLSearchParams(ctx.search || "");
|
|
47049
|
+
params.delete("token");
|
|
47050
|
+
const search = params.toString();
|
|
47051
|
+
const url2 = `${upstream}${upstreamPath}${search ? `?${search}` : ""}`;
|
|
46672
47052
|
const headers = {};
|
|
46673
47053
|
for (const [key, value] of Object.entries(ctx.headers)) {
|
|
46674
47054
|
if (value == null) continue;
|
|
46675
47055
|
const lower = key.toLowerCase();
|
|
46676
47056
|
if (lower === "host") {
|
|
46677
47057
|
headers["host"] = new URL(upstream).host;
|
|
46678
|
-
} else if (lower === "origin" || lower === "referer" || lower === "connection") {
|
|
47058
|
+
} else if (lower === "origin" || lower === "referer" || lower === "connection" || lower === "authorization") {
|
|
46679
47059
|
continue;
|
|
46680
47060
|
} else {
|
|
46681
47061
|
const v = Array.isArray(value) ? value[0] : value;
|
|
@@ -46783,7 +47163,7 @@ var import_path13 = require("path");
|
|
|
46783
47163
|
var import_promises13 = require("fs/promises");
|
|
46784
47164
|
var import_fs12 = require("fs");
|
|
46785
47165
|
init_logger();
|
|
46786
|
-
var APP_VERSION = true ? "0.4.
|
|
47166
|
+
var APP_VERSION = true ? "0.4.2" : (() => {
|
|
46787
47167
|
try {
|
|
46788
47168
|
return JSON.parse(readFileSync7((0, import_path13.resolve)(__dirname, "../../package.json"), "utf-8")).version;
|
|
46789
47169
|
} catch {
|