billion-context 0.1.75-pr.489.307 → 0.1.75-pr.490.308
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/index.js +46 -101
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -47856,7 +47856,7 @@ function parseCompressSettings(v2) {
|
|
|
47856
47856
|
}
|
|
47857
47857
|
out[key] = typeof obj[key] === "string" ? obj[key].trim() : obj[key];
|
|
47858
47858
|
}
|
|
47859
|
-
for (const key of ["nudgeGrowthTokens", "preserveRecentMessages", "preserveRecentTokens", "minCompressRange"]) {
|
|
47859
|
+
for (const key of ["nudgeGrowthTokens", "preserveRecentMessages", "preserveRecentTokens", "minCompressRange", "minCompressRangeChars"]) {
|
|
47860
47860
|
takeNumber(key);
|
|
47861
47861
|
}
|
|
47862
47862
|
if ("tiers" in obj) {
|
|
@@ -47922,6 +47922,7 @@ function resolveContextLimitValue(raw, nativeLimit) {
|
|
|
47922
47922
|
function mergeCompress(global2, provider, model) {
|
|
47923
47923
|
const pick = (k2) => model?.[k2] ?? provider?.[k2] ?? global2?.[k2];
|
|
47924
47924
|
const promptLevels = [global2?.prompts, provider?.prompts, model?.prompts].filter(Boolean);
|
|
47925
|
+
const rangeOf = (s3) => s3?.minCompressRangeChars ?? s3?.minCompressRange;
|
|
47925
47926
|
return {
|
|
47926
47927
|
modelContextLimit: pick("modelContextLimit"),
|
|
47927
47928
|
maxContextLimit: pick("maxContextLimit"),
|
|
@@ -47929,7 +47930,7 @@ function mergeCompress(global2, provider, model) {
|
|
|
47929
47930
|
nudgeGrowthTokens: pick("nudgeGrowthTokens"),
|
|
47930
47931
|
preserveRecentMessages: pick("preserveRecentMessages"),
|
|
47931
47932
|
preserveRecentTokens: pick("preserveRecentTokens"),
|
|
47932
|
-
|
|
47933
|
+
minCompressRangeChars: rangeOf(model) ?? rangeOf(provider) ?? rangeOf(global2),
|
|
47933
47934
|
tiers: pick("tiers"),
|
|
47934
47935
|
prompts: promptLevels.length > 0 ? Object.assign({}, ...promptLevels) : void 0,
|
|
47935
47936
|
acknowledgePromptsRisk: pick("acknowledgePromptsRisk")
|
|
@@ -47983,7 +47984,7 @@ function applyCompressSettings(base, limit, s3) {
|
|
|
47983
47984
|
preserveRecentTokens: s3.preserveRecentTokens ?? base.preserveRecentTokens,
|
|
47984
47985
|
compress: {
|
|
47985
47986
|
...base.compress,
|
|
47986
|
-
minCompressRange: s3.minCompressRange ?? base.compress.minCompressRange
|
|
47987
|
+
minCompressRange: s3.minCompressRangeChars ?? s3.minCompressRange ?? base.compress.minCompressRange
|
|
47987
47988
|
}
|
|
47988
47989
|
};
|
|
47989
47990
|
}
|
|
@@ -48165,6 +48166,7 @@ var CACHE_FILE = path3.join(cacheDir(), "models-dev.json");
|
|
|
48165
48166
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
48166
48167
|
var cache2 = null;
|
|
48167
48168
|
var loading = null;
|
|
48169
|
+
var warnedConflicts = /* @__PURE__ */ new Set();
|
|
48168
48170
|
var snapshotReg = null;
|
|
48169
48171
|
var snapshotMs = 0;
|
|
48170
48172
|
function bundledSnapshotRegistry() {
|
|
@@ -48337,15 +48339,22 @@ function registryLookup(reg, model, host) {
|
|
|
48337
48339
|
}
|
|
48338
48340
|
if (provider === void 0) {
|
|
48339
48341
|
const suffix = `/${model}`;
|
|
48340
|
-
let
|
|
48342
|
+
let max;
|
|
48343
|
+
const distinct = /* @__PURE__ */ new Set();
|
|
48344
|
+
const parts = [];
|
|
48341
48345
|
for (const key of Object.keys(reg)) {
|
|
48342
48346
|
if (!key.endsWith(suffix)) continue;
|
|
48343
48347
|
const ctx = reg[key].limit?.context;
|
|
48344
48348
|
if (typeof ctx !== "number" || ctx <= 0) continue;
|
|
48345
|
-
if (
|
|
48346
|
-
|
|
48349
|
+
if (max === void 0 || ctx > max) max = ctx;
|
|
48350
|
+
distinct.add(ctx);
|
|
48351
|
+
parts.push(`${key}=${ctx}`);
|
|
48352
|
+
}
|
|
48353
|
+
if (max !== void 0 && distinct.size > 1 && !warnedConflicts.has(model)) {
|
|
48354
|
+
warnedConflicts.add(model);
|
|
48355
|
+
log("warn", `[acp-registry] conflicting context windows for "${model}" (${parts.join(", ")}) \u2014 using max ${max}`);
|
|
48347
48356
|
}
|
|
48348
|
-
return
|
|
48357
|
+
return max;
|
|
48349
48358
|
}
|
|
48350
48359
|
return void 0;
|
|
48351
48360
|
}
|
|
@@ -49951,7 +49960,13 @@ function buildSession(parsed) {
|
|
|
49951
49960
|
metadata: parsed.metadata ?? {},
|
|
49952
49961
|
state: mergeState(parsed.state),
|
|
49953
49962
|
createdAt: parsed.createdAt ?? Date.now(),
|
|
49954
|
-
|
|
49963
|
+
// #404: lastSeen reflects the on-disk savedAt (the last real
|
|
49964
|
+
// activity), NOT the restore moment — a restart must not fabricate
|
|
49965
|
+
// activity for every session (broke fallback=latest ties, panel
|
|
49966
|
+
// freshness, and eviction ordering). Consumers that need "has this
|
|
49967
|
+
// session been used since boot" read the restored flag.
|
|
49968
|
+
lastSeen: parsed.savedAt ?? Date.now(),
|
|
49969
|
+
restored: true,
|
|
49955
49970
|
blockContents,
|
|
49956
49971
|
lastMessages: Array.isArray(parsed.messages) ? parsed.messages : void 0,
|
|
49957
49972
|
inFlight: 0,
|
|
@@ -50006,7 +50021,8 @@ async function initSessions() {
|
|
|
50006
50021
|
await store.migrateLegacyIds();
|
|
50007
50022
|
const loaded = await store.loadAll();
|
|
50008
50023
|
if (loaded.size > MAX_SESSIONS) {
|
|
50009
|
-
const
|
|
50024
|
+
const freshness = (s3) => Math.max(s3.createdAt ?? 0, s3.lastSeen ?? 0);
|
|
50025
|
+
const entries = [...loaded.entries()].sort((a, b2) => freshness(b2[1]) - freshness(a[1]));
|
|
50010
50026
|
for (const [id, s3] of entries) {
|
|
50011
50027
|
if (sessions.size >= MAX_SESSIONS) break;
|
|
50012
50028
|
sessions.set(id, s3);
|
|
@@ -50019,6 +50035,7 @@ function getSession(id, meta) {
|
|
|
50019
50035
|
const existing = sessions.get(id);
|
|
50020
50036
|
if (existing) {
|
|
50021
50037
|
existing.lastSeen = Date.now();
|
|
50038
|
+
existing.restored = false;
|
|
50022
50039
|
if (meta?.protocol && !existing.meta.protocol) existing.meta.protocol = meta.protocol;
|
|
50023
50040
|
if (meta?.upstreamOrigin && !existing.meta.upstreamOrigin) existing.meta.upstreamOrigin = meta.upstreamOrigin;
|
|
50024
50041
|
if (meta?.label && !existing.meta.label) existing.meta.label = meta.label;
|
|
@@ -50028,6 +50045,7 @@ function getSession(id, meta) {
|
|
|
50028
50045
|
const reloaded = store.loadSync(id, meta);
|
|
50029
50046
|
if (reloaded) {
|
|
50030
50047
|
reloaded.lastSeen = Date.now();
|
|
50048
|
+
reloaded.restored = false;
|
|
50031
50049
|
reloaded.persisted = true;
|
|
50032
50050
|
sessions.set(id, reloaded);
|
|
50033
50051
|
return reloaded;
|
|
@@ -50696,7 +50714,7 @@ function summaryPayload(protocol, model, system, content) {
|
|
|
50696
50714
|
if (protocol === "openai") {
|
|
50697
50715
|
return { model, max_tokens: MAX_SUMMARY_OUTPUT_TOKENS, messages: [{ role: "system", content: system }, { role: "user", content }], stream: false };
|
|
50698
50716
|
}
|
|
50699
|
-
return { model, max_output_tokens: MAX_SUMMARY_OUTPUT_TOKENS, instructions: system, input: [{ role: "user", content }], stream: false
|
|
50717
|
+
return { model, max_output_tokens: MAX_SUMMARY_OUTPUT_TOKENS, instructions: system, input: [{ role: "user", content }], stream: false };
|
|
50700
50718
|
}
|
|
50701
50719
|
function extractSummaryText(protocol, json) {
|
|
50702
50720
|
if (protocol === "anthropic") {
|
|
@@ -50762,7 +50780,7 @@ TASK: The conversation segment below (messages ${startRef}\u2013${endRef}) must
|
|
|
50762
50780
|
var ABORTED_FAILURE = { kind: "aborted", detail: "the client disconnected during preflight compression" };
|
|
50763
50781
|
async function preflightCompress(deps, messages) {
|
|
50764
50782
|
const limit = deps.config.modelContextLimit;
|
|
50765
|
-
const result = { compressedRanges: 0, savedTokens: 0, payloadEstimate: estimateCoreMessages(messages)
|
|
50783
|
+
const result = { compressedRanges: 0, savedTokens: 0, payloadEstimate: estimateCoreMessages(messages) };
|
|
50766
50784
|
if (limit <= 0) return result;
|
|
50767
50785
|
const budget = Math.max(MIN_CHUNK_TOKENS, Math.floor(limit * CHUNK_FRACTION));
|
|
50768
50786
|
const minChars = deps.config.compress.minCompressRange;
|
|
@@ -50782,8 +50800,8 @@ async function preflightCompress(deps, messages) {
|
|
|
50782
50800
|
renderTags: "text-only"
|
|
50783
50801
|
});
|
|
50784
50802
|
deps.session.state = turn.state;
|
|
50785
|
-
currentTokens = Math.max(deps.session.stats.lastInputTokens, estimateCoreMessages(turn.messages)
|
|
50786
|
-
result.payloadEstimate = estimateCoreMessages(turn.messages)
|
|
50803
|
+
currentTokens = Math.max(deps.session.stats.lastInputTokens, estimateCoreMessages(turn.messages));
|
|
50804
|
+
result.payloadEstimate = estimateCoreMessages(turn.messages);
|
|
50787
50805
|
if (startTokens < 0) startTokens = currentTokens;
|
|
50788
50806
|
if (currentTokens < limit) break;
|
|
50789
50807
|
const ranges = viableRanges(turn.nudge?.compressibleRanges ?? []);
|
|
@@ -50869,78 +50887,6 @@ async function preflightCompress(deps, messages) {
|
|
|
50869
50887
|
return result;
|
|
50870
50888
|
}
|
|
50871
50889
|
|
|
50872
|
-
// src/image-tokens.ts
|
|
50873
|
-
var REMOTE_IMAGE_TOKENS = 4096;
|
|
50874
|
-
function imageTokenCap() {
|
|
50875
|
-
const v2 = Number(process.env.BILI_IMAGE_TOKEN_CAP ?? "");
|
|
50876
|
-
return Number.isInteger(v2) && v2 > 0 ? v2 : 0;
|
|
50877
|
-
}
|
|
50878
|
-
function applyCap(cost) {
|
|
50879
|
-
const cap = imageTokenCap();
|
|
50880
|
-
return cap > 0 ? Math.min(cost, cap) : cost;
|
|
50881
|
-
}
|
|
50882
|
-
function costForUrl(url) {
|
|
50883
|
-
if (url.startsWith("data:")) {
|
|
50884
|
-
const i = url.indexOf("base64,");
|
|
50885
|
-
if (i >= 0) return applyCap(Math.ceil((url.length - i - "base64,".length) / 4));
|
|
50886
|
-
}
|
|
50887
|
-
return applyCap(REMOTE_IMAGE_TOKENS);
|
|
50888
|
-
}
|
|
50889
|
-
function isObj(v2) {
|
|
50890
|
-
return typeof v2 === "object" && v2 !== null;
|
|
50891
|
-
}
|
|
50892
|
-
function urlOf(v2) {
|
|
50893
|
-
if (typeof v2 === "string") return v2;
|
|
50894
|
-
if (isObj(v2) && typeof v2.url === "string") return v2.url;
|
|
50895
|
-
return void 0;
|
|
50896
|
-
}
|
|
50897
|
-
function imageTokensInParsedBody(protocol, body) {
|
|
50898
|
-
if (!isObj(body)) return 0;
|
|
50899
|
-
let total = 0;
|
|
50900
|
-
if (protocol === "responses") {
|
|
50901
|
-
const input = body.input;
|
|
50902
|
-
if (!Array.isArray(input)) return 0;
|
|
50903
|
-
for (const item of input) {
|
|
50904
|
-
if (!isObj(item) || !Array.isArray(item.content)) continue;
|
|
50905
|
-
for (const part of item.content) {
|
|
50906
|
-
if (!isObj(part) || part.type !== "input_image") continue;
|
|
50907
|
-
const url = urlOf(part.image_url);
|
|
50908
|
-
if (url) total += costForUrl(url);
|
|
50909
|
-
}
|
|
50910
|
-
}
|
|
50911
|
-
return total;
|
|
50912
|
-
}
|
|
50913
|
-
const messages = body.messages;
|
|
50914
|
-
if (!Array.isArray(messages)) return 0;
|
|
50915
|
-
for (const m2 of messages) {
|
|
50916
|
-
if (!isObj(m2) || !Array.isArray(m2.content)) continue;
|
|
50917
|
-
for (const part of m2.content) {
|
|
50918
|
-
if (!isObj(part)) continue;
|
|
50919
|
-
if (protocol === "openai") {
|
|
50920
|
-
if (part.type !== "image_url") continue;
|
|
50921
|
-
const url = urlOf(part.image_url);
|
|
50922
|
-
if (url) total += costForUrl(url);
|
|
50923
|
-
} else {
|
|
50924
|
-
if (part.type !== "image") continue;
|
|
50925
|
-
const src = part.source;
|
|
50926
|
-
if (isObj(src) && src.type === "base64" && typeof src.data === "string") total += applyCap(Math.ceil(src.data.length / 4));
|
|
50927
|
-
else if (isObj(src) && src.type === "url" && typeof src.url === "string") total += costForUrl(src.url);
|
|
50928
|
-
}
|
|
50929
|
-
}
|
|
50930
|
-
}
|
|
50931
|
-
return total;
|
|
50932
|
-
}
|
|
50933
|
-
function imageTokensInRawBody(protocol, raw) {
|
|
50934
|
-
const s3 = typeof raw === "string" ? raw : raw.toString("utf8");
|
|
50935
|
-
const probe = protocol === "responses" ? s3.includes("input_image") : protocol === "openai" ? s3.includes("image_url") : s3.includes('"type":"image"') || s3.includes('"type": "image"');
|
|
50936
|
-
if (!probe) return 0;
|
|
50937
|
-
try {
|
|
50938
|
-
return imageTokensInParsedBody(protocol, JSON.parse(s3));
|
|
50939
|
-
} catch {
|
|
50940
|
-
return 0;
|
|
50941
|
-
}
|
|
50942
|
-
}
|
|
50943
|
-
|
|
50944
50890
|
// src/web/index.ts
|
|
50945
50891
|
import { readFileSync as readFileSync3 } from "fs";
|
|
50946
50892
|
import { dirname as dirname4, join as join3 } from "path";
|
|
@@ -51110,7 +51056,7 @@ async function saveProviders(){const button=byId("save-providers");busy(button,t
|
|
|
51110
51056
|
async function saveCompress(){const button=byId("save-compress");busy(button,true,"\u4FDD\u5B58\u4E2D\u2026");try{const text=byId("compress-json").value.trim();const compress=text?JSON.parse(text):null;await json("/__bili/config",{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify({compress})});toast("\u538B\u7F29\u53C2\u6570\u5DF2\u70ED\u66F4\u65B0")}catch(error){toast(String(error),true)}finally{busy(button,false)}}
|
|
51111
51057
|
async function loadOverrides(){try{const data=await loadConfig();const providers=data.providers||{};const box=byId("upstream-overrides");const entries=Object.entries(providers);if(entries.length===0){box.innerHTML='<p class="status">\u6682\u65E0 Provider\u3002\u5728"\u9AD8\u7EA7\u8BBE\u7F6E"\u9875\u6DFB\u52A0 Provider \u540E\u53EF\u5728\u6B64\u6309 URL \u914D\u7F6E\u4EE3\u7406\u3002</p>';return}box.innerHTML='<table><thead><tr><th>Provider URL</th><th>\u4E0A\u6E38\u4EE3\u7406\uFF08\u7A7A=\u7EE7\u627F\u5168\u5C40\uFF09</th></tr></thead><tbody>'+entries.map(([url,route])=>'<tr><td class="mono">'+escapeHtml(url)+'</td><td><input class="mono override-proxy" data-url="'+escapeHtml(url)+'" value="'+escapeHtml((route&&route.proxy)||"")+'" placeholder="\u7EE7\u627F\u5168\u5C40"></td></tr>').join("")+'</tbody></table>'}catch(error){byId("upstream-overrides").textContent=String(error)}}
|
|
51112
51058
|
async function saveOverrides(){const button=byId("save-overrides");busy(button,true,"\u4FDD\u5B58\u4E2D\u2026");try{const data=await loadConfig();const providers=data.providers||{};document.querySelectorAll(".override-proxy").forEach((input)=>{const url=input.dataset.url;if(!url)return;if(!providers[url])providers[url]={};const val=input.value.trim();if(val)providers[url].proxy=val;else delete providers[url].proxy});await json("/__bili/config",{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify({providers})});await json("/__bili/config/reload",{method:"POST"});toast("\u6309 URL \u8986\u76D6\u5DF2\u70ED\u66F4\u65B0");await loadOverrides()}catch(error){toast(String(error),true)}finally{busy(button,false)}}
|
|
51113
|
-
async function loadSessions(){try{const data=await json("/__bili/stats");const rows=(data.sessions||[]).map((item)=>"<tr><td>"+escapeHtml(item.title||"\u2014")+"</td><td>"+escapeHtml(item.protocol||"\u2014")+"</td><td class=mono>"+escapeHtml(item.label||"\u2014")+"</td><td>"+escapeHtml(item.requests)+"</td><td>"+escapeHtml(item.contextTokens)+"</td><td>"+escapeHtml(new Date(item.lastSeen).toLocaleString())+"</td></tr>").join("");byId("sessions-body").innerHTML=rows||'<tr><td colspan="6">\u6682\u65E0\u4F1A\u8BDD</td></tr>'}catch(error){toast(String(error),true);throw error}}
|
|
51059
|
+
async function loadSessions(){try{const data=await json("/__bili/stats");const rows=(data.sessions||[]).map((item)=>"<tr><td>"+escapeHtml(item.title||"\u2014")+"</td><td>"+escapeHtml(item.protocol||"\u2014")+"</td><td class=mono>"+escapeHtml(item.label||"\u2014")+"</td><td>"+escapeHtml(item.requests)+"</td><td>"+escapeHtml(item.contextTokens)+"</td><td>"+escapeHtml(new Date(item.lastSeen).toLocaleString())+(item.restored?" <span class=muted>(\u6062\u590D\uFF0C\u5F00\u673A\u540E\u672A\u6D3B\u52A8)</span>":"")+"</td></tr>").join("");byId("sessions-body").innerHTML=rows||'<tr><td colspan="6">\u6682\u65E0\u4F1A\u8BDD</td></tr>'}catch(error){toast(String(error),true);throw error}}
|
|
51114
51060
|
async function refreshSessions(){const button=byId("refresh-sessions");busy(button,true,"\u5237\u65B0\u4E2D\u2026");try{await loadSessions();toast("\u4F1A\u8BDD\u5217\u8868\u5DF2\u5237\u65B0")}catch{}finally{busy(button,false)}}
|
|
51115
51061
|
document.querySelectorAll(".copy-btn").forEach((btn)=>btn.addEventListener("click",async()=>{busy(btn,true,"\u590D\u5236\u4E2D\u2026");try{await navigator.clipboard.writeText(btn.dataset.copy||"");toast("\u5DF2\u590D\u5236")}catch(e){toast(String(e),true)}finally{busy(btn,false)}}));byId("save-upstream").addEventListener("click",saveUpstream);byId("test-upstream").addEventListener("click",testUpstream);byId("save-providers").addEventListener("click",saveProviders);byId("save-compress").addEventListener("click",saveCompress);byId("save-overrides").addEventListener("click",saveOverrides);byId("refresh-sessions").addEventListener("click",refreshSessions);
|
|
51116
51062
|
Promise.all([loadConfig(),loadUpstream()]).catch((error)=>toast(String(error),true));setInterval(()=>{if(byId("page-sessions").classList.contains("active"))loadSessions().catch(()=>{})},5000);
|
|
@@ -51120,7 +51066,7 @@ Promise.all([loadConfig(),loadUpstream()]).catch((error)=>toast(String(error),tr
|
|
|
51120
51066
|
var WEB_STYLES = `
|
|
51121
51067
|
:root{--bg:#0f1115;--panel:#171a21;--panel2:#1e222c;--line:#2b313d;--text:#e7eaf0;--muted:#8f98a8;--blue:#6ea8fe;--green:#55c98b;--yellow:#e9b949;--red:#ef6b73;--radius:10px}
|
|
51122
51068
|
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text);font:14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;min-height:100vh}.app{display:grid;grid-template-columns:220px 1fr;min-height:100vh}.sidebar{border-right:1px solid var(--line);padding:22px 14px;background:#12151b;position:sticky;top:0;height:100vh}.brand{font-size:18px;font-weight:700;padding:0 10px 22px}.brand span{color:var(--blue)}.version{display:block;color:var(--muted);font-size:11px;font-weight:400;margin-top:2px}.nav{display:grid;gap:4px}.nav button{appearance:none;border:0;background:transparent;color:var(--muted);text-align:left;padding:10px 12px;border-radius:7px;cursor:pointer;font:inherit}.nav button:hover,.nav button.active{background:var(--panel2);color:var(--text)}.main{padding:32px;max-width:1050px;width:100%}.page{display:none}.page.active{display:block}h1{font-size:23px;margin:0 0 4px}h2{font-size:15px;margin:0}.lead{color:var(--muted);margin:0 0 24px}.grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:18px;margin-bottom:14px}.card-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.badge{border-radius:99px;padding:3px 9px;font-size:12px;background:var(--panel2);color:var(--muted)}.badge.ok{color:var(--green)}.badge.warn{color:var(--yellow)}.badge.err{color:var(--red)}.kv{display:grid;grid-template-columns:135px 1fr;gap:10px 14px;margin:0}.kv dt{color:var(--muted)}.kv dd{margin:0;word-break:break-all}.mono{font-family:"Cascadia Code",Consolas,monospace;font-size:12px}.actions{display:flex;gap:9px;flex-wrap:wrap;margin-top:18px}.btn{border:1px solid var(--line);background:var(--panel2);color:var(--text);border-radius:7px;padding:8px 13px;cursor:pointer;font:inherit}.btn:hover{border-color:#4b5668}.btn.primary{background:var(--blue);border-color:var(--blue);color:#0b1220;font-weight:600}.btn.danger{color:var(--red)}.btn:disabled{opacity:.55;cursor:wait}.field{display:grid;gap:6px;margin:12px 0}.field label{color:var(--muted);font-size:12px}input,textarea,select{width:100%;background:#101319;color:var(--text);border:1px solid var(--line);border-radius:7px;padding:9px 10px;font:inherit}textarea{min-height:250px;font-family:"Cascadia Code",Consolas,monospace;font-size:12px;resize:vertical}.modes{display:flex;gap:18px;margin:12px 0}.modes label{display:flex;gap:7px;align-items:center;color:var(--muted)}.modes input{width:auto}.notice{border-left:3px solid var(--yellow);padding:10px 12px;background:rgba(233,185,73,.08);color:#d8c185;margin-top:14px}.status{color:var(--muted);white-space:pre-wrap}.status.ok{color:var(--green)}.status.err{color:var(--red)}table{width:100%;border-collapse:collapse}th,td{text-align:left;border-bottom:1px solid var(--line);padding:9px 8px;font-size:12px}th{color:var(--muted);font-weight:500}.toast{position:fixed;right:24px;bottom:24px;background:var(--green);color:#07140d;padding:10px 15px;border-radius:8px;opacity:0;transform:translateY(8px);transition:.2s;pointer-events:none}.toast.show{opacity:1;transform:none}.toast.err{background:var(--red);color:#1b0608}
|
|
51123
|
-
.section-title{font-size:17px;margin:28px 0 4px}.hint{color:var(--muted);margin:0 0 14px;font-size:13px}.btn.small{padding:4px 10px;font-size:12px}.config-block{background:var(--panel2);border:1px solid var(--line);border-radius:6px;padding:10px 14px;margin:8px 0 12px;overflow-x:auto;font-size:13px}.config-block code{font-family:"Cascadia Code",Consolas,monospace;color:var(--text)}.fork-ribbon{position:fixed;top:0;right:0;background:#1a1a2e;color:#fff;padding:6px 16px;font-size:12px;text-decoration:none;border-radius:0 0 0 8px;z-index:100;opacity:.8;transition:.2s}.fork-ribbon:hover{opacity:1}
|
|
51069
|
+
.section-title{font-size:17px;margin:28px 0 4px}.hint{color:var(--muted);margin:0 0 14px;font-size:13px}.muted{color:var(--muted);font-size:11px}.btn.small{padding:4px 10px;font-size:12px}.config-block{background:var(--panel2);border:1px solid var(--line);border-radius:6px;padding:10px 14px;margin:8px 0 12px;overflow-x:auto;font-size:13px}.config-block code{font-family:"Cascadia Code",Consolas,monospace;color:var(--text)}.fork-ribbon{position:fixed;top:0;right:0;background:#1a1a2e;color:#fff;padding:6px 16px;font-size:12px;text-decoration:none;border-radius:0 0 0 8px;z-index:100;opacity:.8;transition:.2s}.fork-ribbon:hover{opacity:1}
|
|
51124
51070
|
@media(max-width:760px){.app{grid-template-columns:1fr}.sidebar{height:auto;position:static;border-right:0;border-bottom:1px solid var(--line)}.nav{display:flex;overflow:auto}.main{padding:20px}.grid{grid-template-columns:1fr}.kv{grid-template-columns:110px 1fr}}
|
|
51125
51071
|
`;
|
|
51126
51072
|
|
|
@@ -51149,7 +51095,7 @@ function renderPage(origin, version2) {
|
|
|
51149
51095
|
<div class="card"><div class="card-head"><h2>ZCode\uFF08\u7F16\u7A0B\u5957\u9910\uFF09</h2><span class="badge">MITM</span><button class="btn small copy-btn" data-copy="${caPathEsc}">\u590D\u5236 CA \u8DEF\u5F84</button></div><dl class="kv"><dt>\u65B9\u5F0F</dt><dd>MITM \u900F\u660E\u4EE3\u7406</dd><dt>\u8BBE\u7F6E</dt><dd>Settings \u2192 Network \u2192 HTTP Proxy = <span class="mono">${origin}</span></dd><dt>CA \u8BC1\u4E66</dt><dd class="mono">${caPathEsc}${caReady ? "" : "\uFF08\u5C1A\u672A\u751F\u6210\uFF0C\u542F\u52A8\u4EE3\u7406\u540E\u81EA\u52A8\u521B\u5EFA\uFF09"}</dd></dl><p class="hint">CA \u8DEF\u5F84\u662F\u672C\u673A bili \u5B9E\u9645\u751F\u6210\u7684\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u70B9"\u590D\u5236 CA \u8DEF\u5F84"\u540E\u76F4\u63A5\u7C98\u8D34\u8FDB ZCode\u3002\u26A0\uFE0F Windows \u4E0A ZCode \u4E0D\u4F1A\u5C55\u5F00 <span class="mono">~</span>\uFF0C\u8BF7\u52FF\u624B\u586B <span class="mono">~/\u2026</span> \u5F62\u5F0F\u7684\u8DEF\u5F84\u3002</p></div></section>
|
|
51150
51096
|
<section id="page-upstream" class="page"><h1>\u4E0A\u6E38\u7F51\u7EDC</h1><p class="lead">\u63A7\u5236 bili \u5982\u4F55\u8BBF\u95EE\u771F\u5B9E Provider\uFF0C\u4E0D\u4F1A\u6539\u53D8\u5BA2\u6237\u7AEF\u7684\u672C\u5730\u8DEF\u7531\u5730\u5740\u3002</p><div class="card"><div class="card-head"><h2>\u5168\u5C40\u4EE3\u7406</h2></div><div class="modes"><label><input type="radio" name="proxy-mode" value="direct" checked>\u76F4\u8FDE\uFF08\u9ED8\u8BA4\uFF09</label><label><input type="radio" name="proxy-mode" value="manual">\u624B\u52A8\u4EE3\u7406</label><label><input type="radio" name="proxy-mode" value="auto">\u81EA\u52A8\uFF08\u8DDF\u968F\u7CFB\u7EDF\uFF09</label></div><div class="field"><label>HTTP / HTTPS Proxy</label><input id="proxy-url" class="mono" placeholder="http://127.0.0.1:7897"></div><dl class="kv"><dt>\u5F53\u524D\u6765\u6E90</dt><dd id="upstream-source">\u76F4\u8FDE</dd><dt>\u6709\u6548\u4EE3\u7406</dt><dd id="upstream-effective" class="mono">direct</dd><dt>\u7CFB\u7EDF PAC</dt><dd id="upstream-pac" class="mono">\u2014</dd><dt>\u72B6\u6001</dt><dd id="upstream-state" class="status">\u5C1A\u672A\u6D4B\u8BD5</dd></dl><div class="actions"><button id="save-upstream" class="btn primary">\u4FDD\u5B58\u5E76\u70ED\u66F4\u65B0</button><button id="test-upstream" class="btn">\u6D4B\u8BD5\u8FDE\u63A5</button></div></div><div class="card"><div class="card-head"><h2>\u6309 URL \u8986\u76D6</h2></div><p class="status">\u4E3A\u7279\u5B9A Provider \u5355\u72EC\u8BBE\u7F6E\u4E0A\u6E38\u4EE3\u7406\uFF0C\u8986\u76D6\u5168\u5C40\u8BBE\u7F6E\u3002\u7559\u7A7A = \u7EE7\u627F\u5168\u5C40\u3002</p><div id="upstream-overrides" class="status">\u52A0\u8F7D\u4E2D</div><div class="actions"><button id="save-overrides" class="btn primary">\u4FDD\u5B58\u8986\u76D6\u5E76\u70ED\u66F4\u65B0</button></div></div></section>
|
|
51151
51097
|
<section id="page-sessions" class="page"><div class="card-head"><div><h1>\u4F1A\u8BDD</h1><p class="lead">ACP \u538B\u7F29\u72B6\u6001\u4E0E\u4E0A\u6E38\u7528\u91CF\u3002</p></div><button id="refresh-sessions" class="btn">\u5237\u65B0</button></div><div class="card"><table><thead><tr><th>\u6807\u9898</th><th>\u534F\u8BAE</th><th>\u6807\u8BC6</th><th>\u8BF7\u6C42</th><th>\u4E0A\u4E0B\u6587</th><th>\u6700\u540E\u6D3B\u52A8</th></tr></thead><tbody id="sessions-body"></tbody></table></div></section>
|
|
51152
|
-
<section id="page-settings" class="page"><h1>\u9AD8\u7EA7\u8BBE\u7F6E</h1><p class="lead">\u76F4\u63A5\u7F16\u8F91 providers JSON\uFF08\u6DFB\u52A0\u65B0 Provider\u3001\u914D\u7F6E\u6A21\u578B\u4E0A\u4E0B\u6587\u7A97\u53E3\u3001\u6309 URL \u4EE3\u7406\u7B49\uFF09\uFF1B\u4FDD\u5B58\u540E\u7ACB\u5373\u70ED\u66F4\u65B0\u3002</p><div class="card"><div class="field"><label>providers JSON</label><textarea id="providers-json">{}</textarea></div><div class="actions"><button id="save-providers" class="btn primary">\u4FDD\u5B58\u5E76\u5E94\u7528</button></div></div><div class="card"><div class="card-head"><h2>\u538B\u7F29\u53C2\u6570\uFF08\u5168\u5C40\uFF09</h2></div><p class="status">\u5168\u5C40 compress \u914D\u7F6E\uFF08modelContextLimit / maxContextLimit / emergencyThresholdPercent / nudgeGrowthTokens / preserveRecentMessages / preserveRecentTokens / minCompressRange / tiers / injectTool / injectNudge\uFF09\u3002\u4FDD\u5B58\u540E\u70ED\u66F4\u65B0\uFF0C\u65E0\u9700\u91CD\u542F\u3002\u7F6E\u7A7A = \u6062\u590D\u9ED8\u8BA4\u3002</p><div class="field"><label>compress JSON</label><textarea id="compress-json" placeholder='{"modelContextLimit": 200000}'></textarea></div><div class="actions"><button id="save-compress" class="btn primary">\u4FDD\u5B58\u5E76\u70ED\u66F4\u65B0</button></div></div></section></main></div><div id="toast" class="toast"></div><script>${WEB_CLIENT}</script></body></html>`;
|
|
51098
|
+
<section id="page-settings" class="page"><h1>\u9AD8\u7EA7\u8BBE\u7F6E</h1><p class="lead">\u76F4\u63A5\u7F16\u8F91 providers JSON\uFF08\u6DFB\u52A0\u65B0 Provider\u3001\u914D\u7F6E\u6A21\u578B\u4E0A\u4E0B\u6587\u7A97\u53E3\u3001\u6309 URL \u4EE3\u7406\u7B49\uFF09\uFF1B\u4FDD\u5B58\u540E\u7ACB\u5373\u70ED\u66F4\u65B0\u3002</p><div class="card"><div class="field"><label>providers JSON</label><textarea id="providers-json">{}</textarea></div><div class="actions"><button id="save-providers" class="btn primary">\u4FDD\u5B58\u5E76\u5E94\u7528</button></div></div><div class="card"><div class="card-head"><h2>\u538B\u7F29\u53C2\u6570\uFF08\u5168\u5C40\uFF09</h2></div><p class="status">\u5168\u5C40 compress \u914D\u7F6E\uFF08modelContextLimit / maxContextLimit / emergencyThresholdPercent / nudgeGrowthTokens / preserveRecentMessages / preserveRecentTokens / minCompressRangeChars\uFF08\u5355\u4F4D\uFF1A\u5B57\u7B26\uFF0C\u65E7\u540D minCompressRange \u517C\u5BB9\uFF09 / tiers / injectTool / injectNudge\uFF09\u3002\u4FDD\u5B58\u540E\u70ED\u66F4\u65B0\uFF0C\u65E0\u9700\u91CD\u542F\u3002\u7F6E\u7A7A = \u6062\u590D\u9ED8\u8BA4\u3002</p><div class="field"><label>compress JSON</label><textarea id="compress-json" placeholder='{"modelContextLimit": 200000}'></textarea></div><div class="actions"><button id="save-compress" class="btn primary">\u4FDD\u5B58\u5E76\u70ED\u66F4\u65B0</button></div></div></section></main></div><div id="toast" class="toast"></div><script>${WEB_CLIENT}</script></body></html>`;
|
|
51153
51099
|
}
|
|
51154
51100
|
|
|
51155
51101
|
// src/web/api.ts
|
|
@@ -54436,10 +54382,14 @@ function handlePluginStatus(conversationId2, res, fallbackLatest = false) {
|
|
|
54436
54382
|
let session = entry ? peekSession(entry.sessionId) : void 0;
|
|
54437
54383
|
let viaFallback = false;
|
|
54438
54384
|
if ((!entry || !session) && fallbackLatest) {
|
|
54439
|
-
const latest = listSessions().filter((s3) =>
|
|
54385
|
+
const latest = listSessions().filter((s3) => s3.restored !== true).sort((a, b2) => (b2.lastSeen ?? 0) - (a.lastSeen ?? 0))[0];
|
|
54440
54386
|
if (latest) {
|
|
54441
54387
|
session = latest;
|
|
54442
54388
|
viaFallback = true;
|
|
54389
|
+
} else {
|
|
54390
|
+
res.writeHead(404, { "content-type": "application/json" });
|
|
54391
|
+
res.end(JSON.stringify({ ok: false, error: "no session with activity since boot \u2014 issue a model request or pass the conversation id" }));
|
|
54392
|
+
return;
|
|
54443
54393
|
}
|
|
54444
54394
|
}
|
|
54445
54395
|
if (!session) {
|
|
@@ -57702,13 +57652,11 @@ function isPreflightFailFast(outcome) {
|
|
|
57702
57652
|
async function preflightCompressIfNeeded(prepared, runPrepare, req, res, opts, core, config, model, route, affinity, log2, instanceId) {
|
|
57703
57653
|
const session = prepared.session;
|
|
57704
57654
|
const limit = config.modelContextLimit;
|
|
57705
|
-
const
|
|
57706
|
-
const payloadEstimate = estimateCoreMessages(prepared.processedMessages) + imageTokens;
|
|
57655
|
+
const payloadEstimate = estimateCoreMessages(prepared.processedMessages);
|
|
57707
57656
|
const tokenCount = Math.max(session.stats.lastInputTokens, payloadEstimate);
|
|
57708
57657
|
if (limit <= 0 || !model || tokenCount < limit) return prepared;
|
|
57709
57658
|
const failFast = (status2, detail, retryable) => {
|
|
57710
|
-
const
|
|
57711
|
-
const message = `context ~${tokenCount} tokens exceeds the model window ${limit} (model=${model}) and preflight compression could not bring it under: ${detail}.` + imageNote + ` The over-window payload was NOT forwarded.`;
|
|
57659
|
+
const message = `context ~${tokenCount} tokens exceeds the model window ${limit} (model=${model}) and preflight compression could not bring it under: ${detail}. The over-window payload was NOT forwarded.`;
|
|
57712
57660
|
log2("error", `[${session.id}] preflight fail-fast ${status2} (retryable=${retryable}): ${message}`);
|
|
57713
57661
|
return { failFast: true, status: status2, message, retryable, respond: !res.writableEnded };
|
|
57714
57662
|
};
|
|
@@ -57738,8 +57686,7 @@ async function preflightCompressIfNeeded(prepared, runPrepare, req, res, opts, c
|
|
|
57738
57686
|
model,
|
|
57739
57687
|
proxyUrl,
|
|
57740
57688
|
signal: clientAbort.signal,
|
|
57741
|
-
log: log2
|
|
57742
|
-
imageFloor: imageTokens
|
|
57689
|
+
log: log2
|
|
57743
57690
|
},
|
|
57744
57691
|
prepared.originalMessages
|
|
57745
57692
|
);
|
|
@@ -57908,12 +57855,9 @@ ${hdrText}
|
|
|
57908
57855
|
const info = inspectContextOverflow(upstream.status, errBody.toString("utf8"));
|
|
57909
57856
|
if (info.isOverflow) {
|
|
57910
57857
|
let reqModel;
|
|
57911
|
-
let rejectedImageTokens = 0;
|
|
57912
57858
|
try {
|
|
57913
57859
|
const rawBody = typeof prepared.body === "string" ? prepared.body : prepared.body.toString("utf8");
|
|
57914
|
-
|
|
57915
|
-
reqModel = typeof parsedBody.model === "string" ? parsedBody.model : void 0;
|
|
57916
|
-
rejectedImageTokens = imageTokensInParsedBody(prepared.protocol, parsedBody);
|
|
57860
|
+
reqModel = JSON.parse(rawBody).model;
|
|
57917
57861
|
} catch {
|
|
57918
57862
|
reqModel = void 0;
|
|
57919
57863
|
}
|
|
@@ -57925,7 +57869,7 @@ ${hdrText}
|
|
|
57925
57869
|
s3.metadata.learnedContextLimits = learnedMap;
|
|
57926
57870
|
log2("warn", `[${s3.id}] upstream context overflow \u2014 learned real window ${info.window} for ${reqModel ?? "(unknown model)"} (was ${prev ?? "unset"}); arming emergency shrink`);
|
|
57927
57871
|
} else {
|
|
57928
|
-
const payloadEstimate = estimateCoreMessages(prepared.processedMessages)
|
|
57872
|
+
const payloadEstimate = estimateCoreMessages(prepared.processedMessages);
|
|
57929
57873
|
const prev = (reqModel ? learnedMap[reqModel] : void 0) ?? s3.metadata.learnedContextLimit;
|
|
57930
57874
|
if (payloadEstimate >= 1e3 && (prev === void 0 || payloadEstimate < prev)) {
|
|
57931
57875
|
if (reqModel) learnedMap[reqModel] = payloadEstimate;
|
|
@@ -58310,7 +58254,8 @@ function sendStats(res) {
|
|
|
58310
58254
|
outputTokens: s3.stats.outputTokens,
|
|
58311
58255
|
cacheSamples: s3.stats.cacheSamples,
|
|
58312
58256
|
cacheHitPct: s3.stats.cacheSamples > 0 && s3.stats.inputTokens > 0 ? Math.round(s3.stats.cachedTokens / s3.stats.inputTokens * 100) : null,
|
|
58313
|
-
lastSeen: new Date(s3.lastSeen).toISOString()
|
|
58257
|
+
lastSeen: new Date(s3.lastSeen).toISOString(),
|
|
58258
|
+
restored: s3.restored === true
|
|
58314
58259
|
}));
|
|
58315
58260
|
res.writeHead(200, { "content-type": "application/json" });
|
|
58316
58261
|
res.end(JSON.stringify({ sessions: sessions2 }, null, 2));
|