billion-context 0.1.59 → 0.1.60-pr.312.163

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
@@ -30021,9 +30021,9 @@ var require_sha256 = __commonJS({
30021
30021
  var forge2 = require_forge();
30022
30022
  require_md();
30023
30023
  require_util7();
30024
- var sha256 = module.exports = forge2.sha256 = forge2.sha256 || {};
30025
- forge2.md.sha256 = forge2.md.algorithms.sha256 = sha256;
30026
- sha256.create = function() {
30024
+ var sha2562 = module.exports = forge2.sha256 = forge2.sha256 || {};
30025
+ forge2.md.sha256 = forge2.md.algorithms.sha256 = sha2562;
30026
+ sha2562.create = function() {
30027
30027
  if (!_initialized) {
30028
30028
  _init();
30029
30029
  }
@@ -49830,15 +49830,17 @@ function normalizeSseLineEndings(buf) {
49830
49830
  }
49831
49831
 
49832
49832
  // src/loop/tag-echo-filter.ts
49833
- var PAIRED = /\x3cacp\s[^<>]*>([^<>]{0,64})<\/acp>/;
49834
- var LONE = /<\/?acp(?=[\s>])[^<>]*>/;
49833
+ var PAIRED = /\x3cacp\s[^<>]{0,256}>([^<>]{0,64})<\/acp>/;
49834
+ var LONE_OPEN = /\x3cacp(?:\s[^<>]{0,256})?>/;
49835
+ var LONE_CLOSE = /<\/acp(?=[\s>])[^<>]{0,32}>/;
49835
49836
  var PARTIAL_TAIL = /(\x3cacp\s[^<>]*|<\/?a?c?p?)$/;
49836
- var TRUNCATED_TAG = /\x3cacp\s[^<>]*tokens\s*=\s*"[^<>"]*"[^<>]*$/;
49837
+ var TRUNC_OPEN = /\x3cacp\s[^<>]*$/;
49837
49838
  var CLOSE_TAG = "</acp";
49838
49839
  var HOLD_LIMIT = 128;
49840
+ var TAG_OPEN_CAP = 4096;
49839
49841
  var SWALLOW_CAP = 80;
49840
49842
  function stripAcpTags(text) {
49841
- return text.replace(new RegExp(PAIRED.source, "g"), "").replace(new RegExp(LONE.source, "g"), "").replace(new RegExp(TRUNCATED_TAG.source), "");
49843
+ return text.replace(new RegExp(PAIRED.source, "g"), "").replace(new RegExp(LONE_OPEN.source, "g"), "").replace(new RegExp(LONE_CLOSE.source, "g"), "").replace(new RegExp(TRUNC_OPEN.source), "");
49842
49844
  }
49843
49845
  function containsRenderTagText(s3) {
49844
49846
  return /\x3c\/?acp(?=[\s>])/.test(s3) || /\\u003c\/?acp(?=[\s>\\])/.test(s3);
@@ -49881,15 +49883,26 @@ function createTagEchoFilter(onDrop) {
49881
49883
  return out;
49882
49884
  }
49883
49885
  const p2 = PAIRED.exec(buf);
49884
- const l = LONE.exec(buf);
49885
- let m2;
49886
- if (p2 && l) m2 = p2.index <= l.index ? p2 : l;
49887
- else m2 = p2 ?? l;
49886
+ const o = LONE_OPEN.exec(buf);
49887
+ const c = LONE_CLOSE.exec(buf);
49888
+ let m2 = null;
49889
+ for (const cand of [p2, o, c]) {
49890
+ if (cand && (m2 === null || cand.index < m2.index)) m2 = cand;
49891
+ }
49888
49892
  if (!m2) {
49889
49893
  const t = PARTIAL_TAIL.exec(buf);
49890
- if (t && t[0].length <= HOLD_LIMIT) {
49891
- held = t[0];
49892
- out += buf.slice(0, buf.length - t[0].length);
49894
+ if (t) {
49895
+ const definite = /^\x3cacp\s/.test(t[0]);
49896
+ const cap = definite ? TAG_OPEN_CAP : HOLD_LIMIT;
49897
+ if (t[0].length <= cap) {
49898
+ held = t[0];
49899
+ out += buf.slice(0, buf.length - t[0].length);
49900
+ } else if (definite) {
49901
+ drop(t[0]);
49902
+ out += buf.slice(0, buf.length - t[0].length);
49903
+ } else {
49904
+ out += buf;
49905
+ }
49893
49906
  } else {
49894
49907
  out += buf;
49895
49908
  }
@@ -49898,8 +49911,7 @@ function createTagEchoFilter(onDrop) {
49898
49911
  drop(m2[0]);
49899
49912
  out += buf.slice(0, m2.index);
49900
49913
  buf = buf.slice(m2.index + m2[0].length);
49901
- const wasPaired = m2 === p2;
49902
- if (!wasPaired && /^\x3cacp\s/.test(m2[0])) {
49914
+ if (m2 === o && /^\x3cacp\s/.test(m2[0])) {
49903
49915
  swallowUntilClose = true;
49904
49916
  swallowed = "";
49905
49917
  }
@@ -49913,14 +49925,19 @@ function createTagEchoFilter(onDrop) {
49913
49925
  return process2(chunk);
49914
49926
  },
49915
49927
  flush() {
49916
- let rest = swallowed + held;
49928
+ const rest = swallowed + held;
49929
+ const wasSwallowing = swallowUntilClose;
49917
49930
  swallowed = "";
49918
49931
  held = "";
49919
49932
  swallowUntilClose = false;
49920
- const t = new RegExp(TRUNCATED_TAG.source).exec(rest);
49933
+ if (wasSwallowing) {
49934
+ if (rest.length > 0) drop(rest);
49935
+ return "";
49936
+ }
49937
+ const t = new RegExp(TRUNC_OPEN.source).exec(rest);
49921
49938
  if (t) {
49922
49939
  drop(t[0]);
49923
- rest = rest.slice(0, t.index);
49940
+ return rest.slice(0, t.index);
49924
49941
  }
49925
49942
  return rest;
49926
49943
  },
@@ -52566,6 +52583,102 @@ function preferPromptCacheKeyIdentity(identity, body) {
52566
52583
  return { ...identity, value: pck, source: "prompt-cache-key", clientProvided: true };
52567
52584
  }
52568
52585
 
52586
+ // src/prefix-affinity.ts
52587
+ import { createHash as createHash5 } from "crypto";
52588
+ var MIN_CANONICAL_BYTES = 24;
52589
+ var MAX_TRACKED_SESSIONS = 256;
52590
+ var TTL_MS2 = 7 * 24 * 60 * 60 * 1e3;
52591
+ function stableStringify(value) {
52592
+ return JSON.stringify(sortKeys(value));
52593
+ }
52594
+ function sortKeys(value) {
52595
+ if (Array.isArray(value)) return value.map(sortKeys);
52596
+ if (value && typeof value === "object") {
52597
+ const record = value;
52598
+ const out = {};
52599
+ for (const key of Object.keys(record).sort()) out[key] = sortKeys(record[key]);
52600
+ return out;
52601
+ }
52602
+ return value;
52603
+ }
52604
+ function sha256(text) {
52605
+ return createHash5("sha256").update(text, "utf8").digest("hex");
52606
+ }
52607
+ function hasUserMessage(messages) {
52608
+ return messages.some((m2) => !!m2 && typeof m2 === "object" && m2.role === "user");
52609
+ }
52610
+ function chainHashes(messages) {
52611
+ const hashes = [];
52612
+ let prev = "";
52613
+ let bytes = 0;
52614
+ for (const message of messages) {
52615
+ const canonical = stableStringify(message);
52616
+ bytes += canonical.length;
52617
+ prev = sha256(`${prev}\0${canonical}`);
52618
+ hashes.push(prev);
52619
+ }
52620
+ return bytes >= MIN_CANONICAL_BYTES ? hashes : [];
52621
+ }
52622
+ var PrefixAffinityResolver = class {
52623
+ trackedChains = /* @__PURE__ */ new Map();
52624
+ /**
52625
+ * Resolve an anonymous request to a session id.
52626
+ * Returns null when the request carries no usable conversation signal
52627
+ * (caller keeps the #286 explicit 400).
52628
+ */
52629
+ resolve(messages) {
52630
+ const hashes = chainHashes(messages);
52631
+ if (hashes.length === 0 || !hasUserMessage(messages)) return null;
52632
+ const tailHash = hashes[hashes.length - 1];
52633
+ const tracked = this.trackedChains;
52634
+ this.expire(tracked);
52635
+ let best;
52636
+ for (const entry of tracked.values()) {
52637
+ if (entry.depth > hashes.length) continue;
52638
+ if (hashes[entry.depth - 1] !== entry.tailHash) continue;
52639
+ if (!best || entry.depth > best.depth || entry.depth === best.depth && entry.lastSeen > best.lastSeen) best = entry;
52640
+ }
52641
+ if (best) {
52642
+ return {
52643
+ sessionId: best.sessionId,
52644
+ matchedDepth: best.depth,
52645
+ storedDepth: best.depth,
52646
+ incomingDepth: hashes.length,
52647
+ tailHash
52648
+ };
52649
+ }
52650
+ const sessionId = `pfa-${sha256(`${tailHash}\0${hashes.length}`).slice(0, 16)}`;
52651
+ return { sessionId, matchedDepth: 0, storedDepth: 0, incomingDepth: hashes.length, tailHash };
52652
+ }
52653
+ /** Record the chain of a session (on creation and after every anonymous
52654
+ * request — the incoming history is the truth, appends extend it). */
52655
+ note(sessionId, depth, tailHash) {
52656
+ const tracked = this.trackedChains;
52657
+ tracked.delete(sessionId);
52658
+ tracked.set(sessionId, { sessionId, depth, tailHash, lastSeen: Date.now() });
52659
+ while (tracked.size > MAX_TRACKED_SESSIONS) {
52660
+ const oldest = [...tracked.values()].sort((a, b2) => a.lastSeen - b2.lastSeen)[0];
52661
+ if (!oldest) break;
52662
+ tracked.delete(oldest.sessionId);
52663
+ }
52664
+ }
52665
+ /** Drop tracking for a removed session. */
52666
+ forget(sessionId) {
52667
+ this.trackedChains.delete(sessionId);
52668
+ }
52669
+ trackedSessionIds() {
52670
+ return [...this.trackedChains.keys()];
52671
+ }
52672
+ expire(tracked) {
52673
+ if (tracked.size === 0) return;
52674
+ const now = Date.now();
52675
+ for (const [id, entry] of tracked) {
52676
+ if (now - entry.lastSeen > TTL_MS2) tracked.delete(id);
52677
+ }
52678
+ }
52679
+ };
52680
+ var prefixAffinity = new PrefixAffinityResolver();
52681
+
52569
52682
  // node_modules/acp-kernel/dist/panel/index.js
52570
52683
  function topicFallback(summary) {
52571
52684
  const first = summary.split(/[.\n]/)[0] ?? "";
@@ -53791,7 +53904,7 @@ function collectModelWindows(config) {
53791
53904
  }
53792
53905
 
53793
53906
  // src/discover.ts
53794
- var TTL_MS2 = 2e3;
53907
+ var TTL_MS3 = 2e3;
53795
53908
  function unwrapUpstream(url) {
53796
53909
  const idx = url.indexOf("/bili/");
53797
53910
  return idx >= 0 ? url.slice(idx + "/bili/".length) : url;
@@ -53859,7 +53972,7 @@ function mtimesEqual(a, b2) {
53859
53972
  var cache3 = null;
53860
53973
  function discoverMitmDomains(env = process.env) {
53861
53974
  const now = Date.now();
53862
- if (cache3 && now - cache3.checkedAt < TTL_MS2) {
53975
+ if (cache3 && now - cache3.checkedAt < TTL_MS3) {
53863
53976
  return cache3.domains;
53864
53977
  }
53865
53978
  const paths = configFilePaths(env);
@@ -54742,7 +54855,7 @@ function launcherContextWindow(model) {
54742
54855
  function safeSessionId(id) {
54743
54856
  return (id ?? "unknown").replace(/[^a-zA-Z0-9._-]/g, "_");
54744
54857
  }
54745
- var NO_IDENTITY_MESSAGE = "Missing stable conversation identity. Send one of the headers: x-session-id, x-session-affinity, x-acp-session, x-opencode-session, x-claude-code-session-id, session-id \u2014 or body session_id / prompt_cache_key (responses/openai). Content-fingerprint sessions are disabled (#286).";
54858
+ var NO_IDENTITY_MESSAGE = "Missing stable conversation identity. Send one of the headers: x-session-id, x-session-affinity, x-acp-session, x-opencode-session, x-claude-code-session-id, session-id \u2014 or body session_id / prompt_cache_key (responses/openai). Requests replaying a conversation history are matched by content prefix affinity (#309); this one carries no usable history signal.";
54746
54859
  var UPSTREAM_HOP_HEADERS = /* @__PURE__ */ new Set([
54747
54860
  "host",
54748
54861
  "content-length",
@@ -55194,13 +55307,25 @@ ${bodyBuffer.toString("utf8")}`);
55194
55307
  parsed.instructions
55195
55308
  );
55196
55309
  const clientProvided = protocol === "responses" ? responsesIdentity?.clientProvided ?? false : protocol === "openai" ? openaiIdentity?.clientProvided ?? false : !!convHeader;
55310
+ let anonAffinity = null;
55197
55311
  if (!clientProvided) {
55198
- log2("warn", `400: no stable conversation identity on ${protocol} request \u2192 ${upstreamOrigin}; refusing to create a content-fingerprint session (#286)`);
55199
- res.writeHead(400, { "content-type": "application/json" });
55200
- res.end(JSON.stringify(protocol === "anthropic" ? { type: "error", error: { type: "invalid_request_error", message: NO_IDENTITY_MESSAGE } } : { error: { type: "invalid_request_error", message: NO_IDENTITY_MESSAGE } }));
55201
- return;
55312
+ const anonMessages = protocol === "responses" ? parsed.input ?? [] : parsed.messages ?? [];
55313
+ anonAffinity = prefixAffinity.resolve(Array.isArray(anonMessages) ? anonMessages : []);
55314
+ if (!anonAffinity) {
55315
+ log2("warn", `400: no stable conversation identity on ${protocol} request \u2192 ${upstreamOrigin}; refusing to create a content-fingerprint session (#286)`);
55316
+ res.writeHead(400, { "content-type": "application/json" });
55317
+ res.end(JSON.stringify(protocol === "anthropic" ? { type: "error", error: { type: "invalid_request_error", message: NO_IDENTITY_MESSAGE } } : { error: { type: "invalid_request_error", message: NO_IDENTITY_MESSAGE } }));
55318
+ return;
55319
+ }
55320
+ if (anonAffinity.matchedDepth > 0) {
55321
+ log2("info", `[prefix-affinity] anonymous ${protocol} request \u2192 session ${anonAffinity.sessionId} (prefix match depth=${anonAffinity.matchedDepth}/${anonAffinity.incomingDepth}, tail=${anonAffinity.tailHash.slice(0, 8)}; fork semantics: diverged histories split on their next request)`);
55322
+ log("info", `[prefix-affinity] session ${anonAffinity.sessionId} matched at depth ${anonAffinity.matchedDepth}/${anonAffinity.incomingDepth} (tail=${anonAffinity.tailHash.slice(0, 8)})`);
55323
+ } else {
55324
+ log2("info", `[prefix-affinity] new anonymous session ${anonAffinity.sessionId} (depth=${anonAffinity.incomingDepth}, tail=${anonAffinity.tailHash.slice(0, 8)})`);
55325
+ log("info", `[prefix-affinity] new session ${anonAffinity.sessionId} at depth ${anonAffinity.incomingDepth} (tail=${anonAffinity.tailHash.slice(0, 8)})`);
55326
+ }
55202
55327
  }
55203
- const sessionId = conversation;
55328
+ const sessionId = anonAffinity ? anonAffinity.sessionId : conversation;
55204
55329
  const bodyIdentity = responsesIdentity ?? openaiIdentity;
55205
55330
  const affinity = affinityToken(bodyIdentity ?? {
55206
55331
  value: clientConv ?? conversation,
@@ -55208,8 +55333,15 @@ ${bodyBuffer.toString("utf8")}`);
55208
55333
  clientProvided: !!clientConv
55209
55334
  });
55210
55335
  const clientLabel = bodyIdentity?.clientProvided ? bodyIdentity.value : clientConversationHeader(req.headers);
55211
- const session = getSession(sessionId, { protocol, upstreamOrigin, label: clientLabel ?? void 0 });
55212
- if (!pluginAgent) {
55336
+ const session = getSession(sessionId, { protocol, upstreamOrigin, label: clientLabel ?? (anonAffinity ? "prefix-affinity" : void 0) });
55337
+ if (anonAffinity) {
55338
+ prefixAffinity.note(sessionId, anonAffinity.incomingDepth, anonAffinity.tailHash);
55339
+ session.metadata.anonymousPrefixAffinity = {
55340
+ depth: anonAffinity.incomingDepth,
55341
+ tailHash: anonAffinity.tailHash
55342
+ };
55343
+ }
55344
+ if (!pluginAgent && !anonAffinity) {
55213
55345
  const identityAgent = consumePluginRegisterFor(clientConv ?? conversation);
55214
55346
  if (identityAgent) {
55215
55347
  pluginAgent = identityAgent;