billion-context 0.1.67-pr.398.237 → 0.1.67-pr.415.239

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
@@ -46991,10 +46991,116 @@ var registry2 = /* @__PURE__ */ new Map();
46991
46991
  function registerSearchAlgorithm(algo) {
46992
46992
  registry2.set(algo.name, algo);
46993
46993
  }
46994
+ function getSearchAlgorithm(name) {
46995
+ return registry2.get(name);
46996
+ }
46994
46997
  registerSearchAlgorithm(substringAlgorithm);
46995
46998
  registerSearchAlgorithm(bm25Algorithm);
46996
46999
  registerSearchAlgorithm(fuzzyAlgorithm);
46997
47000
  registerSearchAlgorithm(hybridAlgorithm);
47001
+ var DEFAULT_ROLE_WEIGHTS = {
47002
+ user: 1.5,
47003
+ assistant: 1,
47004
+ tool: 0.6,
47005
+ block: 1
47006
+ };
47007
+ var DEFAULT_ALGORITHM = "hybrid";
47008
+ function blockDocs(state) {
47009
+ return state.blocks.map((b2) => ({
47010
+ kind: "block",
47011
+ ref: b2.blockId,
47012
+ text: `${b2.topic ?? ""} ${b2.summary ?? ""}`,
47013
+ title: b2.topic ?? b2.blockId,
47014
+ blockId: b2.blockId,
47015
+ tier: b2.tier ?? 1,
47016
+ tokens: b2.compressedTokens
47017
+ }));
47018
+ }
47019
+ function messageDocs(msgs) {
47020
+ return msgs.map((m2) => ({
47021
+ kind: "message",
47022
+ ref: m2.ref,
47023
+ text: m2.text,
47024
+ title: `${m2.role}: ${m2.text.slice(0, 60)}`,
47025
+ role: m2.role,
47026
+ blockId: m2.blockId,
47027
+ tier: m2.tier,
47028
+ tokens: m2.tokens
47029
+ }));
47030
+ }
47031
+ function applyRoleWeight(scored, docs, rw) {
47032
+ if (docs.length === 0) return scored;
47033
+ const docByRef = new Map(docs.map((d) => [d.ref, d]));
47034
+ return scored.map((s3) => {
47035
+ const doc = docByRef.get(s3.ref);
47036
+ if (!doc) return s3;
47037
+ const w2 = doc.kind === "message" ? doc.role === "user" ? rw.user : doc.role === "assistant" ? rw.assistant : rw.tool : rw.block;
47038
+ return { ref: s3.ref, score: s3.score * w2 };
47039
+ });
47040
+ }
47041
+ function runSearch(docs, query, options) {
47042
+ const limit = options.limit ?? 10;
47043
+ const previewLength = options.previewLength ?? 200;
47044
+ const minScore = options.minScore ?? 0.01;
47045
+ const algoName = options.algorithm ?? DEFAULT_ALGORITHM;
47046
+ const rw = { ...DEFAULT_ROLE_WEIGHTS, ...options.roleWeights };
47047
+ const algo = getSearchAlgorithm(algoName);
47048
+ if (!algo) return [];
47049
+ if (docs.length === 0) return [];
47050
+ const scoredOrPromise = algo.score(docs, query);
47051
+ const buildResults = (weighted) => {
47052
+ const byRef = new Map(docs.map((d) => [d.ref, d]));
47053
+ return weighted.map((s3) => {
47054
+ const doc = byRef.get(s3.ref);
47055
+ if (!doc) return null;
47056
+ return {
47057
+ kind: doc.kind,
47058
+ ref: doc.ref,
47059
+ blockId: doc.blockId,
47060
+ tier: doc.tier ?? 1,
47061
+ score: s3.score,
47062
+ title: doc.title,
47063
+ preview: makePreview(doc.text, query, previewLength),
47064
+ role: doc.role,
47065
+ tokens: doc.tokens
47066
+ };
47067
+ }).filter((r) => r !== null && r.score >= minScore).sort((a, b2) => b2.score - a.score).slice(0, limit);
47068
+ };
47069
+ if (scoredOrPromise instanceof Promise) {
47070
+ return scoredOrPromise.then((raw) => buildResults(applyRoleWeight(raw, docs, rw)));
47071
+ }
47072
+ return buildResults(applyRoleWeight(scoredOrPromise, docs, rw));
47073
+ }
47074
+ function searchBlocks(docs, query, options = {}) {
47075
+ const result = runSearch(docs, query, options);
47076
+ if (result instanceof Promise) {
47077
+ throw new Error(
47078
+ `searchBlocks: algorithm "${options.algorithm ?? DEFAULT_ALGORITHM}" is async (e.g. semantic). Use searchBlocksAsync() instead.`
47079
+ );
47080
+ }
47081
+ return result;
47082
+ }
47083
+ function makePreview(text, query, len) {
47084
+ if (!text) return "";
47085
+ const terms = query.toLowerCase().trim().split(/\s+/).filter((t) => t.length > 1);
47086
+ if (terms.length === 0) return text.slice(0, len);
47087
+ const lower = text.toLowerCase();
47088
+ let hitIdx = -1;
47089
+ for (const term of terms) {
47090
+ const idx = lower.indexOf(term);
47091
+ if (idx >= 0) {
47092
+ hitIdx = idx;
47093
+ break;
47094
+ }
47095
+ }
47096
+ if (hitIdx < 0) return text.slice(0, len);
47097
+ const half = Math.max(0, Math.floor(len / 2) - 10);
47098
+ const start = Math.max(0, hitIdx - half);
47099
+ const end = Math.min(text.length, start + len);
47100
+ const prefix = start > 0 ? "\u2026" : "";
47101
+ const suffix = end < text.length ? "\u2026" : "";
47102
+ return prefix + text.slice(start, end).trim() + suffix;
47103
+ }
46998
47104
 
46999
47105
  // src/config.ts
47000
47106
  import { readFileSync, existsSync, mkdirSync as mkdirSync2, writeFileSync } from "fs";
@@ -50097,6 +50203,25 @@ async function flushAllSessions() {
50097
50203
  }
50098
50204
 
50099
50205
  // src/compress-tool.ts
50206
+ var SEARCH_CONTEXT_DESCRIPTION = "Searches compressed block summaries AND visible conversation messages by keyword (English + Chinese/CJK). Use BEFORE decompressing to find the right block, or to locate content still in context.";
50207
+ var SEARCH_CONTEXT_TOOL2 = { ...SEARCH_CONTEXT_TOOL, description: SEARCH_CONTEXT_DESCRIPTION };
50208
+ var SEARCH_CONTEXT_TOOL_OPENAI2 = {
50209
+ ...SEARCH_CONTEXT_TOOL_OPENAI,
50210
+ function: { ...SEARCH_CONTEXT_TOOL_OPENAI.function, description: SEARCH_CONTEXT_DESCRIPTION }
50211
+ };
50212
+ var SEARCH_CONTEXT_TOOL_RESPONSES2 = { ...SEARCH_CONTEXT_TOOL_RESPONSES, description: SEARCH_CONTEXT_DESCRIPTION };
50213
+ var ACP_TOOLS_OPENAI2 = ACP_TOOLS_OPENAI.map(
50214
+ (t) => t.function.name === SEARCH_CONTEXT_TOOL_NAME ? { ...t, function: { ...t.function, description: SEARCH_CONTEXT_DESCRIPTION } } : t
50215
+ );
50216
+ var ACP_TOOLS_ANTHROPIC2 = ACP_TOOLS_ANTHROPIC.map(
50217
+ (t) => t.name === SEARCH_CONTEXT_TOOL_NAME ? { ...t, description: SEARCH_CONTEXT_DESCRIPTION } : t
50218
+ );
50219
+ var ACP_TOOLS_RESPONSES2 = ACP_TOOLS_RESPONSES.map(
50220
+ (t) => t.name === SEARCH_CONTEXT_TOOL_NAME ? { ...t, description: SEARCH_CONTEXT_DESCRIPTION } : t
50221
+ );
50222
+ var ACP_READONLY_TOOLS_RESPONSES2 = ACP_READONLY_TOOLS_RESPONSES.map(
50223
+ (t) => t.name === SEARCH_CONTEXT_TOOL_NAME ? { ...t, description: SEARCH_CONTEXT_DESCRIPTION } : t
50224
+ );
50100
50225
  function parseCompressInput(input, callId) {
50101
50226
  const { ranges, diagnostics } = parseCompressArgs(input, { callId });
50102
50227
  if (!diagnostics.ok && diagnostics.kind !== "ok") {
@@ -50188,6 +50313,56 @@ ${body.slice(0, 4e3)}...`;
50188
50313
  ${body}`;
50189
50314
  }
50190
50315
 
50316
+ // src/search-context.ts
50317
+ function parseSearchContextArgs(args) {
50318
+ const query = typeof args.query === "string" ? args.query : "";
50319
+ const limit = typeof args.limit === "number" && args.limit > 0 ? Math.floor(args.limit) : 5;
50320
+ return { query, limit };
50321
+ }
50322
+ function visibleMessageInputs(state, messages) {
50323
+ const byRaw = state.messageRefs.byRaw;
50324
+ const out = [];
50325
+ for (const m2 of messages) {
50326
+ const ref = byRaw[m2.id];
50327
+ if (typeof ref !== "string" || ref.length === 0) continue;
50328
+ if (m2.role === "system") continue;
50329
+ const text = m2.text ?? "";
50330
+ if (text.length === 0) continue;
50331
+ const role = m2.role === "tool" || m2.contentType === "tool-call" || m2.contentType === "tool-result" ? "tool" : m2.role;
50332
+ out.push({ ref, role, text });
50333
+ }
50334
+ return out;
50335
+ }
50336
+ function handleSearchContext(args, state, messages) {
50337
+ const { query, limit } = parseSearchContextArgs(args);
50338
+ if (query.length === 0) return "[search_context FAILED: query is required]";
50339
+ const activeBlockIds = new Set(state.blocks.filter((b2) => b2.active).map((b2) => b2.blockId));
50340
+ const blockCorpus = blockDocs(state).filter((d) => activeBlockIds.has(d.ref));
50341
+ const messageInputs = visibleMessageInputs(state, messages);
50342
+ const results = searchBlocks([...blockCorpus, ...messageDocs(messageInputs)], query, { limit });
50343
+ if (results.length === 0) {
50344
+ return `[No matches for "${query}" \u2014 searched ${blockCorpus.length} block(s) and ${messageInputs.length} visible message(s). Compressed content is searchable only through its summary; try a broader term, or decompress the block you suspect holds it.]`;
50345
+ }
50346
+ const lines = results.map((r) => {
50347
+ if (r.kind === "block") {
50348
+ const topic = r.title === r.ref ? "(no topic)" : r.title;
50349
+ return `${r.ref} (T${r.tier}) "${topic}"
50350
+ ${r.preview}`;
50351
+ }
50352
+ return `${r.ref} (${r.role ?? "message"})
50353
+ ${r.preview}`;
50354
+ });
50355
+ const blockHits = results.filter((r) => r.kind === "block").length;
50356
+ const messageHits = results.length - blockHits;
50357
+ const what = [
50358
+ blockHits > 0 ? `${blockHits} block(s)` : "",
50359
+ messageHits > 0 ? `${messageHits} message(s)` : ""
50360
+ ].filter(Boolean).join(", ");
50361
+ return `Found ${what} for "${query}":
50362
+
50363
+ ${lines.join("\n\n")}`;
50364
+ }
50365
+
50191
50366
  // src/sse-util.ts
50192
50367
  function normalizeSseLineEndings(buf) {
50193
50368
  if (buf.indexOf("\r") === -1) return buf;
@@ -50374,20 +50549,7 @@ function executeAnthropicProxyTool(toolName, args, ctx) {
50374
50549
  return resolveDecompress(args, ctx);
50375
50550
  }
50376
50551
  if (toolName === "search_context") {
50377
- const query = typeof args.query === "string" ? args.query : "";
50378
- if (query.length === 0) return "[search_context FAILED: query is required]";
50379
- const limit = typeof args.limit === "number" && args.limit > 0 ? Math.floor(args.limit) : 5;
50380
- const blocks = ctx.core.search(query, ctx.session.state).slice(0, limit);
50381
- if (blocks.length === 0) return `[No blocks matched "${query}"]`;
50382
- const lines = blocks.map((b2) => {
50383
- const topic = b2.topic ?? "(no topic)";
50384
- const preview = b2.summary.length > 200 ? b2.summary.slice(0, 200) + "..." : b2.summary;
50385
- return `${b2.blockId} (T${b2.tier}) "${topic}"
50386
- ${preview}`;
50387
- });
50388
- return `Found ${blocks.length} block(s) for "${query}":
50389
-
50390
- ${lines.join("\n\n")}`;
50552
+ return handleSearchContext(args, ctx.session.state, ctx.messages);
50391
50553
  }
50392
50554
  if (toolName === "acp_status") {
50393
50555
  return buildStatusReport(ctx.session.state, ctx.messages, estimateTokensFast);
@@ -51192,20 +51354,7 @@ function executeProxyTool(toolName, args, ctx, callId) {
51192
51354
  return resolveDecompress(args, ctx);
51193
51355
  }
51194
51356
  if (toolName === "search_context") {
51195
- const query = typeof args.query === "string" ? args.query : "";
51196
- if (query.length === 0) return "[search_context FAILED: query is required]";
51197
- const limit = typeof args.limit === "number" && args.limit > 0 ? Math.floor(args.limit) : 5;
51198
- const blocks = ctx.core.search(query, ctx.session.state).slice(0, limit);
51199
- if (blocks.length === 0) return `[No blocks matched "${query}"]`;
51200
- const lines = blocks.map((b2) => {
51201
- const topic = b2.topic ?? "(no topic)";
51202
- const preview = b2.summary.length > 200 ? b2.summary.slice(0, 200) + "..." : b2.summary;
51203
- return `${b2.blockId} (T${b2.tier}) "${topic}"
51204
- ${preview}`;
51205
- });
51206
- return `Found ${blocks.length} block(s) for "${query}":
51207
-
51208
- ${lines.join("\n\n")}`;
51357
+ return handleSearchContext(args, ctx.session.state, ctx.messages);
51209
51358
  }
51210
51359
  if (toolName === "acp_status") {
51211
51360
  return handleAcpStatus(args, ctx);
@@ -52885,20 +53034,7 @@ function executeProxyTool2(toolName, args, ctx) {
52885
53034
  return resolveDecompress(args, ctx);
52886
53035
  }
52887
53036
  if (toolName === "search_context") {
52888
- const query = typeof args.query === "string" ? args.query : "";
52889
- if (query.length === 0) return "[search_context FAILED: query is required]";
52890
- const limit = typeof args.limit === "number" && args.limit > 0 ? Math.floor(args.limit) : 5;
52891
- const blocks = ctx.core.search(query, ctx.session.state).slice(0, limit);
52892
- if (blocks.length === 0) return `[No blocks matched "${query}"]`;
52893
- const lines = blocks.map((b2) => {
52894
- const topic = b2.topic ?? "(no topic)";
52895
- const preview = b2.summary.length > 200 ? b2.summary.slice(0, 200) + "..." : b2.summary;
52896
- return `${b2.blockId} (T${b2.tier}) "${topic}"
52897
- ${preview}`;
52898
- });
52899
- return `Found ${blocks.length} block(s) for "${query}":
52900
-
52901
- ${lines.join("\n\n")}`;
53037
+ return handleSearchContext(args, ctx.session.state, ctx.messages);
52902
53038
  }
52903
53039
  if (toolName === "acp_status") {
52904
53040
  return buildStatusReport(ctx.session.state, ctx.messages, estimateTokensFast);
@@ -53796,9 +53932,9 @@ function handlePluginManifest(res) {
53796
53932
  version: VERSION,
53797
53933
  toolNames: [...ACP_TOOL_NAMES],
53798
53934
  tools: {
53799
- anthropic: ACP_TOOLS_ANTHROPIC,
53800
- openai: ACP_TOOLS_OPENAI,
53801
- responses: ACP_TOOLS_RESPONSES
53935
+ anthropic: ACP_TOOLS_ANTHROPIC2,
53936
+ openai: ACP_TOOLS_OPENAI2,
53937
+ responses: ACP_TOOLS_RESPONSES2
53802
53938
  },
53803
53939
  headers: { agent: PLUGIN_AGENT_HEADER, conversation: PLUGIN_CONVERSATION_HEADER, contextWindow: PLUGIN_CONTEXT_WINDOW_HEADER },
53804
53940
  toolEndpoint: "/__bili/plugin/tool",
@@ -55775,13 +55911,6 @@ Content-Length: ${Buffer.byteLength(body)}\r
55775
55911
  }
55776
55912
  return server;
55777
55913
  }
55778
- var SIDE_REQUEST_MAX_TOKENS = 200;
55779
- function isSideRequest(parsed) {
55780
- if (!parsed || typeof parsed !== "object") return false;
55781
- const p2 = parsed;
55782
- const raw = p2.max_tokens ?? p2.max_completion_tokens ?? p2.max_output_tokens;
55783
- return typeof raw === "number" && raw > 0 && raw <= SIDE_REQUEST_MAX_TOKENS;
55784
- }
55785
55914
  function isTrustedAdminOrigin(origin, host, trustedHosts) {
55786
55915
  if (!host || !trustedHosts.has(host.toLowerCase())) return false;
55787
55916
  if (!origin) return true;
@@ -56143,11 +56272,6 @@ ${bodyBuffer.toString("utf8")}`);
56143
56272
  }
56144
56273
  }
56145
56274
  const pluginMode = pluginAgent !== void 0;
56146
- if (!countTokens && !responsesCompact && protocol !== null && isSideRequest(parsed)) {
56147
- log2("info", `[${session.id}] side request (max_tokens<=${SIDE_REQUEST_MAX_TOKENS}) \u2192 pure passthrough, kernel state untouched`);
56148
- await forward(req, res, opts, bodyBuffer, null, core, reqConfig, log2, route, instanceId, affinity);
56149
- return;
56150
- }
56151
56275
  const reqModel = parsed.model;
56152
56276
  const learnedMap = session.metadata.learnedContextLimits;
56153
56277
  const learnedLimit = (reqModel && learnedMap ? learnedMap[reqModel] : void 0) ?? session.metadata.learnedContextLimit;
@@ -56446,7 +56570,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
56446
56570
  const devContent = [...projection.systemParts, ...forgedSummaries, prompt].join("\n\n---\n\n");
56447
56571
  rebuiltInput = injectResponsesDeveloperMessage(rebuiltInput, devContent);
56448
56572
  if (!process.env.ACP_NO_INJECT_TOOL && injectTools) {
56449
- toolsOut = responsesTextProtocol ? injectResponsesTool(parsed.tools, ACP_READONLY_TOOLS_RESPONSES) : injectResponsesTool(parsed.tools);
56573
+ toolsOut = responsesTextProtocol ? injectResponsesTool(parsed.tools, ACP_READONLY_TOOLS_RESPONSES2) : injectResponsesTool(parsed.tools);
56450
56574
  }
56451
56575
  } else if (projection.systemParts.length > 0 || forgedSummaries.length > 0) {
56452
56576
  const devContent = [...projection.systemParts, ...forgedSummaries].join("\n\n---\n\n");
@@ -56638,21 +56762,21 @@ ${parts.join("\n\n")}` : parts.join("\n\n");
56638
56762
  return buildSystem(full, parsed.system);
56639
56763
  }
56640
56764
  function injectTool(tools) {
56641
- if (!Array.isArray(tools)) return [...ACP_TOOLS_ANTHROPIC];
56765
+ if (!Array.isArray(tools)) return [...ACP_TOOLS_ANTHROPIC2];
56642
56766
  const names = new Set(tools.map((t) => t?.name));
56643
- const missing = ACP_TOOLS_ANTHROPIC.filter((t) => !names.has(t.name));
56767
+ const missing = ACP_TOOLS_ANTHROPIC2.filter((t) => !names.has(t.name));
56644
56768
  return missing.length === 0 ? tools : [...tools, ...missing];
56645
56769
  }
56646
56770
  function injectOpenaiTool(tools) {
56647
- if (!Array.isArray(tools)) return [...ACP_TOOLS_OPENAI];
56771
+ if (!Array.isArray(tools)) return [...ACP_TOOLS_OPENAI2];
56648
56772
  const present = new Set(
56649
56773
  tools.map((t) => t?.function?.name).filter((n) => typeof n === "string")
56650
56774
  );
56651
- const additions = ACP_TOOLS_OPENAI.filter((t) => !present.has(t.function.name));
56775
+ const additions = ACP_TOOLS_OPENAI2.filter((t) => !present.has(t.function.name));
56652
56776
  return [...tools, ...additions];
56653
56777
  }
56654
56778
  var FORCE_TEXT_PROTOCOL = process.env.ACP_COMPRESS_PROTOCOL === "text";
56655
- function injectResponsesTool(tools, toolsToAdd = ACP_TOOLS_RESPONSES) {
56779
+ function injectResponsesTool(tools, toolsToAdd = ACP_TOOLS_RESPONSES2) {
56656
56780
  if (!Array.isArray(tools)) return [...toolsToAdd];
56657
56781
  const present = new Set(
56658
56782
  tools.map((t) => t?.name).filter((n) => typeof n === "string")