billion-context 0.1.75-pr.485.304 → 0.1.75-pr.487.306

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 CHANGED
@@ -49951,7 +49951,13 @@ function buildSession(parsed) {
49951
49951
  metadata: parsed.metadata ?? {},
49952
49952
  state: mergeState(parsed.state),
49953
49953
  createdAt: parsed.createdAt ?? Date.now(),
49954
- lastSeen: Date.now(),
49954
+ // #404: lastSeen reflects the on-disk savedAt (the last real
49955
+ // activity), NOT the restore moment — a restart must not fabricate
49956
+ // activity for every session (broke fallback=latest ties, panel
49957
+ // freshness, and eviction ordering). Consumers that need "has this
49958
+ // session been used since boot" read the restored flag.
49959
+ lastSeen: parsed.savedAt ?? Date.now(),
49960
+ restored: true,
49955
49961
  blockContents,
49956
49962
  lastMessages: Array.isArray(parsed.messages) ? parsed.messages : void 0,
49957
49963
  inFlight: 0,
@@ -50006,7 +50012,8 @@ async function initSessions() {
50006
50012
  await store.migrateLegacyIds();
50007
50013
  const loaded = await store.loadAll();
50008
50014
  if (loaded.size > MAX_SESSIONS) {
50009
- const entries = [...loaded.entries()].sort((a, b2) => (b2[1].createdAt ?? 0) - (a[1].createdAt ?? 0));
50015
+ const freshness = (s3) => Math.max(s3.createdAt ?? 0, s3.lastSeen ?? 0);
50016
+ const entries = [...loaded.entries()].sort((a, b2) => freshness(b2[1]) - freshness(a[1]));
50010
50017
  for (const [id, s3] of entries) {
50011
50018
  if (sessions.size >= MAX_SESSIONS) break;
50012
50019
  sessions.set(id, s3);
@@ -50019,6 +50026,7 @@ function getSession(id, meta) {
50019
50026
  const existing = sessions.get(id);
50020
50027
  if (existing) {
50021
50028
  existing.lastSeen = Date.now();
50029
+ existing.restored = false;
50022
50030
  if (meta?.protocol && !existing.meta.protocol) existing.meta.protocol = meta.protocol;
50023
50031
  if (meta?.upstreamOrigin && !existing.meta.upstreamOrigin) existing.meta.upstreamOrigin = meta.upstreamOrigin;
50024
50032
  if (meta?.label && !existing.meta.label) existing.meta.label = meta.label;
@@ -50028,6 +50036,7 @@ function getSession(id, meta) {
50028
50036
  const reloaded = store.loadSync(id, meta);
50029
50037
  if (reloaded) {
50030
50038
  reloaded.lastSeen = Date.now();
50039
+ reloaded.restored = false;
50031
50040
  reloaded.persisted = true;
50032
50041
  sessions.set(id, reloaded);
50033
50042
  return reloaded;
@@ -51038,7 +51047,7 @@ async function saveProviders(){const button=byId("save-providers");busy(button,t
51038
51047
  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)}}
51039
51048
  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)}}
51040
51049
  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)}}
51041
- 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}}
51050
+ 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}}
51042
51051
  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)}}
51043
51052
  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);
51044
51053
  Promise.all([loadConfig(),loadUpstream()]).catch((error)=>toast(String(error),true));setInterval(()=>{if(byId("page-sessions").classList.contains("active"))loadSessions().catch(()=>{})},5000);
@@ -51048,7 +51057,7 @@ Promise.all([loadConfig(),loadUpstream()]).catch((error)=>toast(String(error),tr
51048
51057
  var WEB_STYLES = `
51049
51058
  :root{--bg:#0f1115;--panel:#171a21;--panel2:#1e222c;--line:#2b313d;--text:#e7eaf0;--muted:#8f98a8;--blue:#6ea8fe;--green:#55c98b;--yellow:#e9b949;--red:#ef6b73;--radius:10px}
51050
51059
  *{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}
51051
- .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}
51060
+ .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}
51052
51061
  @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}}
51053
51062
  `;
51054
51063
 
@@ -54364,10 +54373,14 @@ function handlePluginStatus(conversationId2, res, fallbackLatest = false) {
54364
54373
  let session = entry ? peekSession(entry.sessionId) : void 0;
54365
54374
  let viaFallback = false;
54366
54375
  if ((!entry || !session) && fallbackLatest) {
54367
- const latest = listSessions().filter((s3) => typeof s3.lastSeen === "number").sort((a, b2) => (b2.lastSeen ?? 0) - (a.lastSeen ?? 0))[0];
54376
+ const latest = listSessions().filter((s3) => s3.restored !== true).sort((a, b2) => (b2.lastSeen ?? 0) - (a.lastSeen ?? 0))[0];
54368
54377
  if (latest) {
54369
54378
  session = latest;
54370
54379
  viaFallback = true;
54380
+ } else {
54381
+ res.writeHead(404, { "content-type": "application/json" });
54382
+ res.end(JSON.stringify({ ok: false, error: "no session with activity since boot \u2014 issue a model request or pass the conversation id" }));
54383
+ return;
54371
54384
  }
54372
54385
  }
54373
54386
  if (!session) {
@@ -57890,14 +57903,28 @@ ${hdrText}
57890
57903
  }
57891
57904
  if (prepared?.pluginMode) {
57892
57905
  try {
57906
+ let pluginBody = upstream.body;
57907
+ if (prepared.stream && maxFakeCompletionRetries() > 0) {
57908
+ const resolvedBuf = await resolveFakeCompletion(pluginBody, {
57909
+ protocol: prepared.protocol,
57910
+ body,
57911
+ upstreamUrl,
57912
+ reqHeaders: buildForwardHeaders(headers),
57913
+ proxyUrl,
57914
+ signal: clientAbort.signal,
57915
+ session: prepared.session,
57916
+ log: log2
57917
+ });
57918
+ pluginBody = bufferToStream(resolvedBuf);
57919
+ }
57893
57920
  if (prepared.stream) {
57894
57921
  if (prepared.protocol === "responses") {
57895
- await pipePluginResponsesWithStrip(upstream.body, res, prepared.session, (msg) => log2("info", `[${prepared.session.id}] ${msg}`));
57922
+ await pipePluginResponsesWithStrip(pluginBody, res, prepared.session, (msg) => log2("info", `[${prepared.session.id}] ${msg}`));
57896
57923
  } else {
57897
- await pipePluginChatWithStrip(upstream.body, res, prepared.protocol, prepared.session, (msg) => log2("info", `[${prepared.session.id}] ${msg}`));
57924
+ await pipePluginChatWithStrip(pluginBody, res, prepared.protocol, prepared.session, (msg) => log2("info", `[${prepared.session.id}] ${msg}`));
57898
57925
  }
57899
57926
  } else {
57900
- await pipePluginJson(upstream.body, res, prepared.session, prepared.protocol);
57927
+ await pipePluginJson(pluginBody, res, prepared.session, prepared.protocol);
57901
57928
  }
57902
57929
  } finally {
57903
57930
  clearUpstreamTimer();
@@ -58218,7 +58245,8 @@ function sendStats(res) {
58218
58245
  outputTokens: s3.stats.outputTokens,
58219
58246
  cacheSamples: s3.stats.cacheSamples,
58220
58247
  cacheHitPct: s3.stats.cacheSamples > 0 && s3.stats.inputTokens > 0 ? Math.round(s3.stats.cachedTokens / s3.stats.inputTokens * 100) : null,
58221
- lastSeen: new Date(s3.lastSeen).toISOString()
58248
+ lastSeen: new Date(s3.lastSeen).toISOString(),
58249
+ restored: s3.restored === true
58222
58250
  }));
58223
58251
  res.writeHead(200, { "content-type": "application/json" });
58224
58252
  res.end(JSON.stringify({ sessions: sessions2 }, null, 2));