billion-context 0.1.75-pr.489.307 → 0.1.75-pr.489.309

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;
@@ -51110,7 +51119,7 @@ async function saveProviders(){const button=byId("save-providers");busy(button,t
51110
51119
  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
51120
  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
51121
  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}}
51122
+ 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
51123
  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
51124
  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
51125
  Promise.all([loadConfig(),loadUpstream()]).catch((error)=>toast(String(error),true));setInterval(()=>{if(byId("page-sessions").classList.contains("active"))loadSessions().catch(()=>{})},5000);
@@ -51120,7 +51129,7 @@ Promise.all([loadConfig(),loadUpstream()]).catch((error)=>toast(String(error),tr
51120
51129
  var WEB_STYLES = `
51121
51130
  :root{--bg:#0f1115;--panel:#171a21;--panel2:#1e222c;--line:#2b313d;--text:#e7eaf0;--muted:#8f98a8;--blue:#6ea8fe;--green:#55c98b;--yellow:#e9b949;--red:#ef6b73;--radius:10px}
51122
51131
  *{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}
51132
+ .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
51133
  @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
51134
  `;
51126
51135
 
@@ -54436,10 +54445,14 @@ function handlePluginStatus(conversationId2, res, fallbackLatest = false) {
54436
54445
  let session = entry ? peekSession(entry.sessionId) : void 0;
54437
54446
  let viaFallback = false;
54438
54447
  if ((!entry || !session) && fallbackLatest) {
54439
- const latest = listSessions().filter((s3) => typeof s3.lastSeen === "number").sort((a, b2) => (b2.lastSeen ?? 0) - (a.lastSeen ?? 0))[0];
54448
+ const latest = listSessions().filter((s3) => s3.restored !== true).sort((a, b2) => (b2.lastSeen ?? 0) - (a.lastSeen ?? 0))[0];
54440
54449
  if (latest) {
54441
54450
  session = latest;
54442
54451
  viaFallback = true;
54452
+ } else {
54453
+ res.writeHead(404, { "content-type": "application/json" });
54454
+ res.end(JSON.stringify({ ok: false, error: "no session with activity since boot \u2014 issue a model request or pass the conversation id" }));
54455
+ return;
54443
54456
  }
54444
54457
  }
54445
54458
  if (!session) {
@@ -57294,7 +57307,7 @@ function emergencyNudge(nudge, escalationPct = EMERGENCY_NUDGE_ESCALATION_PCT) {
57294
57307
  function clampOutgoingOutput(rebuilt, field, ctx, sessionId, log2) {
57295
57308
  const raw = rebuilt[field];
57296
57309
  if (typeof raw !== "number") return;
57297
- const inputEstimate = estimateInputTokens(ctx.processedMessages, ctx.systemText, ctx.tools, ctx.lastInputTokens);
57310
+ const inputEstimate = estimateInputTokens(ctx.processedMessages, ctx.systemText, ctx.tools, ctx.lastInputTokens) + ctx.imageTokens;
57298
57311
  const capped = clampOutputBudget(raw, inputEstimate, ctx.nativeWindow);
57299
57312
  if (capped !== void 0) {
57300
57313
  rebuilt[field] = capped;
@@ -57359,7 +57372,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
57359
57372
  processedMessages = [];
57360
57373
  }
57361
57374
  const rebuilt = { ...parsed, messages: rebuiltMessages, tools: toolsOut };
57362
- clampOutgoingOutput(rebuilt, typeof parsed.max_completion_tokens === "number" ? "max_completion_tokens" : "max_tokens", { systemText: openaiSystemText, tools: toolsOut, processedMessages, lastInputTokens: session.stats.lastInputTokens, nativeWindow }, sessionId, log2);
57375
+ clampOutgoingOutput(rebuilt, typeof parsed.max_completion_tokens === "number" ? "max_completion_tokens" : "max_tokens", { systemText: openaiSystemText, tools: toolsOut, processedMessages, lastInputTokens: session.stats.lastInputTokens, nativeWindow, imageTokens: imageTokensInParsedBody("openai", rebuilt) }, sessionId, log2);
57363
57376
  delete rebuilt.prompt_cache_retention;
57364
57377
  if (stream2 && rebuilt.stream_options === void 0) {
57365
57378
  rebuilt.stream_options = { include_usage: true };
@@ -57477,7 +57490,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
57477
57490
  }
57478
57491
  const rebuilt = { ...parsed, input: rebuiltInput, tools: toolsOut };
57479
57492
  if (!isCompactionTrigger) {
57480
- clampOutgoingOutput(rebuilt, "max_output_tokens", { systemText: (responsesProjection?.systemParts ?? []).join("\n"), tools: toolsOut, processedMessages, lastInputTokens: session.stats.lastInputTokens, nativeWindow }, sessionId, log2);
57493
+ clampOutgoingOutput(rebuilt, "max_output_tokens", { systemText: (responsesProjection?.systemParts ?? []).join("\n"), tools: toolsOut, processedMessages, lastInputTokens: session.stats.lastInputTokens, nativeWindow, imageTokens: imageTokensInParsedBody("responses", rebuilt) }, sessionId, log2);
57481
57494
  }
57482
57495
  const promptCacheKey = resolvePromptCacheKey(
57483
57496
  rebuilt.prompt_cache_key,
@@ -58310,7 +58323,8 @@ function sendStats(res) {
58310
58323
  outputTokens: s3.stats.outputTokens,
58311
58324
  cacheSamples: s3.stats.cacheSamples,
58312
58325
  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()
58326
+ lastSeen: new Date(s3.lastSeen).toISOString(),
58327
+ restored: s3.restored === true
58314
58328
  }));
58315
58329
  res.writeHead(200, { "content-type": "application/json" });
58316
58330
  res.end(JSON.stringify({ sessions: sessions2 }, null, 2));