billion-context 0.1.91-pr.615.438 → 0.1.91

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
@@ -43869,9 +43869,6 @@ function refToIndex(ref) {
43869
43869
  function refForRaw(map, rawId) {
43870
43870
  return map.byRaw[rawId] ?? null;
43871
43871
  }
43872
- function rawForRef(map, ref) {
43873
- return map.byRef[ref] ?? null;
43874
- }
43875
43872
  function assignRefs(messages, options) {
43876
43873
  const map = {
43877
43874
  byRaw: { ...options.existing.byRaw },
@@ -44825,34 +44822,6 @@ var ACP_MUTATING_TOOLS = /* @__PURE__ */ new Set([
44825
44822
  COMPRESS_TOOL_NAME,
44826
44823
  DECOMPRESS_TOOL_NAME
44827
44824
  ]);
44828
- var ABSORB_TOOL_DESCRIPTION = "Distill a tool result into a compact summary you write. REQUIRED immediately after a tool result ends with an [ACP absorb] instruction: pass its ref and the distilled essentials (outcome, key values, paths:lines, errors, decisions). The original output is then removed from context; your summary is the durable record.";
44829
- var ABSORB_PARAMETERS = {
44830
- type: "object",
44831
- properties: {
44832
- ref: {
44833
- type: "string",
44834
- description: "mNNNNN ref of the tool result to absorb (from the [ACP absorb] instruction)"
44835
- },
44836
- summary: {
44837
- type: "string",
44838
- description: "Distilled essentials of the tool result \u2014 this replaces the original output in context"
44839
- }
44840
- },
44841
- required: ["ref", "summary"]
44842
- };
44843
- var ABSORB_TOOL = {
44844
- name: ABSORB_TOOL_NAME,
44845
- description: ABSORB_TOOL_DESCRIPTION,
44846
- input_schema: ABSORB_PARAMETERS
44847
- };
44848
- var ABSORB_TOOL_OPENAI = {
44849
- type: "function",
44850
- function: {
44851
- name: ABSORB_TOOL_NAME,
44852
- description: ABSORB_TOOL_DESCRIPTION,
44853
- parameters: ABSORB_PARAMETERS
44854
- }
44855
- };
44856
44825
  var ALWAYS_PROTECTED_TOOLS = ["compress"];
44857
44826
  var NEVER_PRESERVE_RECENT_TOOLS = [
44858
44827
  "decompress",
@@ -44921,11 +44890,6 @@ function formatTokenCount(tokens) {
44921
44890
  function buildAbsorbPrompt(ref, tokens, toolName = ABSORB_TOOL_NAME) {
44922
44891
  return `${ABSORB_PROMPT_MARKER} This tool result (~${formatTokenCount(tokens)} tokens) will be REMOVED from context. Your IMMEDIATE next action: call ${toolName}({ ref: "${ref}", summary: "..." }) \u2014 summary = distilled essentials only (outcome, key values, exact paths:lines, error text verbatim, decisions). Afterwards work from your summary; do NOT re-run this tool. If the result contains nothing you need, call ${toolName} with summary "(nothing needed)".`;
44923
44892
  }
44924
- function buildAbsorbSystemPrompt(toolName = ABSORB_TOOL_NAME) {
44925
- return `INSTANT TOOL-RESULT ABSORPTION (${toolName})
44926
-
44927
- Some tool results end with a ${ABSORB_PROMPT_MARKER} instruction. When you see one, your IMMEDIATE next action must be calling ${toolName}({ ref, summary }) \u2014 distill that tool result's essentials into summary: outcome, key values, exact paths:lines, error text verbatim, decisions. The original output is then removed from context; your ${toolName} summary becomes the only durable record of it, so distill carefully. Never call another tool or answer the user before absorbing a marked result. Do not re-run the original tool afterwards \u2014 work from your summary. ${toolName} calls are ordinary context: the regular compression system may fold them later like any other message.`;
44928
- }
44929
44893
  function isAcpOrConfiguredTool(toolName, cfg) {
44930
44894
  if (!toolName) return false;
44931
44895
  if (toolName === cfg.toolName) return true;
@@ -44980,139 +44944,6 @@ function appendAbsorbPrompts(messages, state, config, tokenCount, countTokens) {
44980
44944
  });
44981
44945
  return { messages: out, promptedCount };
44982
44946
  }
44983
- function parseAbsorbInput(input, callId, onWarn) {
44984
- let obj = null;
44985
- if (typeof input === "string") {
44986
- try {
44987
- const parsed = JSON.parse(input);
44988
- if (parsed && typeof parsed === "object") {
44989
- obj = parsed;
44990
- }
44991
- } catch {
44992
- obj = null;
44993
- }
44994
- } else if (input && typeof input === "object") {
44995
- obj = input;
44996
- }
44997
- if (!obj) {
44998
- onWarn?.(`[acp-absorb-input] rejected: not an object (${typeof input})`);
44999
- return null;
45000
- }
45001
- const ref = pickString(obj, "ref", "messageId", "of");
45002
- const summary = pickString(obj, "summary", "content");
45003
- if (typeof ref !== "string" || typeof summary !== "string") {
45004
- onWarn?.(
45005
- `[acp-absorb-input] rejected: need ref (string) + summary (string); keys: ${Object.keys(obj).join(",")}`
45006
- );
45007
- return null;
45008
- }
45009
- return {
45010
- ref: ref.trim(),
45011
- summary,
45012
- ...callId ? { absorbCallId: callId } : {}
45013
- };
45014
- }
45015
- function pickString(obj, ...keys) {
45016
- for (const key of keys) {
45017
- const value = obj[key];
45018
- if (typeof value === "string") return value;
45019
- }
45020
- return void 0;
45021
- }
45022
- function applyAbsorb(input) {
45023
- const countTokens = input.countTokens ?? ((text) => Math.ceil(text.length / 4));
45024
- const summary = input.summary?.trim() ?? "";
45025
- if (!summary) {
45026
- return {
45027
- state: input.state,
45028
- ok: false,
45029
- resultText: "absorb failed: summary is empty \u2014 provide the distilled key info of the tool result."
45030
- };
45031
- }
45032
- const cfg = resolveAbsorbConfig(input.config);
45033
- const rawId = rawForRef(input.state.messageRefs, input.ref.trim());
45034
- if (!rawId) {
45035
- return {
45036
- state: input.state,
45037
- ok: false,
45038
- resultText: `absorb failed: ref ${input.ref} does not exist in this session (it may be hidden, already compressed, or stale).`
45039
- };
45040
- }
45041
- const existing = (input.state.absorbed ?? []).find(
45042
- (record2) => record2.resultMessageId === rawId
45043
- );
45044
- if (existing) {
45045
- return {
45046
- state: input.state,
45047
- ok: true,
45048
- resultText: `already absorbed (${input.ref}) \u2014 no change.`
45049
- };
45050
- }
45051
- const target = input.messages.find((m2) => m2.id === rawId);
45052
- if (!target) {
45053
- return {
45054
- state: input.state,
45055
- ok: false,
45056
- resultText: `absorb failed: ref ${input.ref} is not visible in this session (hidden or compressed).`
45057
- };
45058
- }
45059
- if (target.contentType !== "tool-result") {
45060
- return {
45061
- state: input.state,
45062
- ok: false,
45063
- resultText: `absorb failed: ref ${input.ref} is a ${target.contentType}, not a tool result.`
45064
- };
45065
- }
45066
- if (isAcpOrConfiguredTool(target.toolName, cfg)) {
45067
- return {
45068
- state: input.state,
45069
- ok: false,
45070
- resultText: `absorb failed: ${target.toolName} is an ACP-managed tool result \u2014 it is not absorbable.`
45071
- };
45072
- }
45073
- if (isMessageProtected(target, input.config)) {
45074
- return {
45075
- state: input.state,
45076
- ok: false,
45077
- resultText: `absorb failed: ${target.toolName} is a protected tool \u2014 its results must stay visible.`
45078
- };
45079
- }
45080
- if (!target.toolCallId) {
45081
- return {
45082
- state: input.state,
45083
- ok: false,
45084
- resultText: `absorb failed: ref ${input.ref} has no tool-call id \u2014 cannot pair it for hiding.`
45085
- };
45086
- }
45087
- const call = input.messages.find(
45088
- (m2) => m2.contentType === "tool-call" && m2.toolCallId === target.toolCallId
45089
- );
45090
- const tokens = countTokens(target.text ?? "");
45091
- const summaryTokens = countTokens(summary);
45092
- const record = {
45093
- toolCallId: target.toolCallId,
45094
- callMessageId: call?.id ?? "",
45095
- resultMessageId: target.id,
45096
- ...input.absorbCallId ? { absorbCallId: input.absorbCallId } : {},
45097
- summary,
45098
- tokensReclaimed: tokens,
45099
- createdAt: Date.now()
45100
- };
45101
- const state = {
45102
- ...input.state,
45103
- absorbed: [...input.state.absorbed ?? [], record],
45104
- stats: {
45105
- ...input.state.stats,
45106
- absorbedTokens: (input.state.stats.absorbedTokens ?? 0) + tokens
45107
- }
45108
- };
45109
- const bloat = summaryTokens >= tokens && tokens > 0 ? ` WARNING: your summary (~${formatTokenCount(summaryTokens)} tokens) is not smaller than the original (~${formatTokenCount(tokens)} tokens) \u2014 distill harder next time.` : "";
45110
- return {
45111
- state,
45112
- ok: true,
45113
- resultText: `absorbed ${input.ref} (~${formatTokenCount(tokens)} tokens \u2192 summary ~${formatTokenCount(summaryTokens)}). The original tool output is now hidden; your summary is the durable record.${bloat}`
45114
- };
45115
- }
45116
44947
  var registry = /* @__PURE__ */ new Map();
45117
44948
  function listMessageFilters() {
45118
44949
  return [...registry.values()];
@@ -48404,51 +48235,6 @@ function parseCompressSettings(v2) {
48404
48235
  if (typeof obj.acknowledgePromptsRisk !== "boolean") ok = false;
48405
48236
  else out.acknowledgePromptsRisk = obj.acknowledgePromptsRisk;
48406
48237
  }
48407
- if ("absorb" in obj && obj.absorb !== void 0) {
48408
- const a = obj.absorb;
48409
- if (!a || typeof a !== "object" || Array.isArray(a)) {
48410
- ok = false;
48411
- } else {
48412
- const ao2 = a;
48413
- const cleaned = {};
48414
- for (const key of ["enabled", "minToolTokens", "contextThresholdPct", "excludeTools", "toolName"]) {
48415
- if (!(key in ao2)) continue;
48416
- const v3 = ao2[key];
48417
- if (key === "enabled") {
48418
- if (typeof v3 !== "boolean") {
48419
- ok = false;
48420
- continue;
48421
- }
48422
- cleaned.enabled = v3;
48423
- } else if (key === "minToolTokens") {
48424
- if (typeof v3 !== "number" || !Number.isFinite(v3)) {
48425
- ok = false;
48426
- continue;
48427
- }
48428
- cleaned.minToolTokens = v3;
48429
- } else if (key === "contextThresholdPct") {
48430
- if (!numberOrPercent(v3)) {
48431
- ok = false;
48432
- continue;
48433
- }
48434
- cleaned.contextThresholdPct = typeof v3 === "string" ? v3.trim() : v3;
48435
- } else if (key === "excludeTools") {
48436
- if (!Array.isArray(v3) || v3.some((x) => typeof x !== "string")) {
48437
- ok = false;
48438
- continue;
48439
- }
48440
- cleaned.excludeTools = [...v3];
48441
- } else {
48442
- if (typeof v3 !== "string" || v3.trim().length === 0) {
48443
- ok = false;
48444
- continue;
48445
- }
48446
- cleaned.toolName = v3.trim();
48447
- }
48448
- }
48449
- if (ok) out.absorb = cleaned;
48450
- }
48451
- }
48452
48238
  if ("prompts" in obj && obj.prompts !== void 0) {
48453
48239
  const prompts = obj.prompts;
48454
48240
  if (!prompts || typeof prompts !== "object" || Array.isArray(prompts)) {
@@ -48499,7 +48285,6 @@ function mergeCompress(global2, provider, model) {
48499
48285
  const pick = (k2) => model?.[k2] ?? provider?.[k2] ?? global2?.[k2];
48500
48286
  const promptLevels = [global2?.prompts, provider?.prompts, model?.prompts].filter(Boolean);
48501
48287
  const rangeOf = (s3) => s3?.minCompressRangeChars ?? s3?.minCompressRange;
48502
- const absorbLevels = [global2?.absorb, provider?.absorb, model?.absorb].filter(Boolean);
48503
48288
  return {
48504
48289
  modelContextLimit: pick("modelContextLimit"),
48505
48290
  maxContextLimit: pick("maxContextLimit"),
@@ -48510,8 +48295,7 @@ function mergeCompress(global2, provider, model) {
48510
48295
  minCompressRangeChars: rangeOf(model) ?? rangeOf(provider) ?? rangeOf(global2),
48511
48296
  tiers: pick("tiers"),
48512
48297
  prompts: promptLevels.length > 0 ? Object.assign({}, ...promptLevels) : void 0,
48513
- acknowledgePromptsRisk: pick("acknowledgePromptsRisk"),
48514
- absorb: absorbLevels.length > 0 ? Object.assign({}, ...absorbLevels) : void 0
48298
+ acknowledgePromptsRisk: pick("acknowledgePromptsRisk")
48515
48299
  };
48516
48300
  }
48517
48301
  function resolveCompress(routes, upstreamUrl, model, global2) {
@@ -48552,17 +48336,6 @@ function applyCompressSettings(base, limit, s3) {
48552
48336
  }
48553
48337
  const tiers = { ...base.tiers };
48554
48338
  if (s3.tiers !== void 0) tiers.enabled = s3.tiers;
48555
- let absorb;
48556
- if (s3.absorb !== void 0) {
48557
- const d = DEFAULT_ABSORB_CONFIG;
48558
- absorb = {
48559
- enabled: s3.absorb.enabled === true,
48560
- toolName: s3.absorb.toolName ?? d.toolName,
48561
- minToolTokens: s3.absorb.minToolTokens ?? d.minToolTokens,
48562
- contextThresholdPct: s3.absorb.contextThresholdPct !== void 0 ? parsePercent(s3.absorb.contextThresholdPct) : d.contextThresholdPct,
48563
- excludeTools: s3.absorb.excludeTools ?? [...d.excludeTools]
48564
- };
48565
- }
48566
48339
  return {
48567
48340
  ...base,
48568
48341
  modelContextLimit: limit,
@@ -48574,8 +48347,7 @@ function applyCompressSettings(base, limit, s3) {
48574
48347
  compress: {
48575
48348
  ...base.compress,
48576
48349
  minCompressRange: s3.minCompressRangeChars ?? s3.minCompressRange ?? base.compress.minCompressRange
48577
- },
48578
- ...absorb !== void 0 ? { absorb } : {}
48350
+ }
48579
48351
  };
48580
48352
  }
48581
48353
  function parsePercent(v2) {
@@ -50269,10 +50041,7 @@ function mergeState(parsed) {
50269
50041
  stats: { ...fresh.stats, ...parsed.stats ?? {} },
50270
50042
  nextBlockId: parsed.nextBlockId ?? fresh.nextBlockId,
50271
50043
  nextRunId: parsed.nextRunId ?? fresh.nextRunId,
50272
- tokenSnapshot: parsed.tokenSnapshot ?? fresh.tokenSnapshot,
50273
- // Without this, a restart re-exposes absorbed tool outputs: state
50274
- // resurrects with absorbed=[] and hideAbsorbedMessages has nothing to hide.
50275
- absorbed: parsed.absorbed ?? fresh.absorbed
50044
+ tokenSnapshot: parsed.tokenSnapshot ?? fresh.tokenSnapshot
50276
50045
  };
50277
50046
  }
50278
50047
  function hostLabel(upstreamOrigin) {
@@ -50875,12 +50644,6 @@ async function flushAllSessions() {
50875
50644
  }
50876
50645
 
50877
50646
  // src/compress-tool.ts
50878
- var ABSORB_TOOL_RESPONSES = {
50879
- type: "function",
50880
- name: ABSORB_TOOL_OPENAI.function.name,
50881
- description: ABSORB_TOOL_OPENAI.function.description,
50882
- parameters: ABSORB_TOOL_OPENAI.function.parameters
50883
- };
50884
50647
  function parseCompressInput(input, callId) {
50885
50648
  const first = parseCompressArgs(input, { callId });
50886
50649
  if (first.ranges.length === 0 || first.diagnostics.invalidItems > 0) {
@@ -50980,72 +50743,6 @@ function withStagedCompressGuidance(text) {
50980
50743
  return text + STAGED_COMPRESS_GUIDANCE;
50981
50744
  }
50982
50745
 
50983
- // src/absorb.ts
50984
- var EFFECTIVE_ABSORB_KEY = "effectiveAbsorb";
50985
- function absorbEnabled(config) {
50986
- return config.absorb?.enabled === true;
50987
- }
50988
- function absorbToolName(config) {
50989
- return config.absorb?.toolName ?? ABSORB_TOOL_NAME;
50990
- }
50991
- function effectiveAbsorbConfig(session, fallback) {
50992
- const meta = session?.metadata[EFFECTIVE_ABSORB_KEY];
50993
- if (meta && typeof meta === "object" && typeof meta.enabled === "boolean") {
50994
- return meta;
50995
- }
50996
- return fallback.absorb;
50997
- }
50998
- function storeEffectiveAbsorb(session, config) {
50999
- session.metadata[EFFECTIVE_ABSORB_KEY] = config.absorb ?? null;
51000
- }
51001
- function isProxyToolFor(name, session, config) {
51002
- if (ACP_TOOL_NAMES.has(name)) return true;
51003
- const absorb = effectiveAbsorbConfig(session, config);
51004
- return absorb?.enabled === true && name === (absorb.toolName ?? ABSORB_TOOL_NAME);
51005
- }
51006
- function applyAbsorbView(messages, state, config, tokenCount) {
51007
- const hidden = hideAbsorbedMessages(messages, state);
51008
- const prompted = appendAbsorbPrompts(hidden, state, config, tokenCount, defaultCountTokens);
51009
- return prompted.messages;
51010
- }
51011
- function executeAbsorb(args, callId, absorb, ctx) {
51012
- const log2 = ctx.log ?? ((msg) => log("info", msg));
51013
- const parsed = parseAbsorbInput(args, callId, (w2) => log2(`[acp-absorb] ${w2}`));
51014
- if (!parsed) {
51015
- return '[absorb FAILED: invalid input \u2014 expected { ref: "mNNNNN", summary: "..." }]';
51016
- }
51017
- const before = ctx.session.state.absorbed?.length ?? 0;
51018
- let outcome;
51019
- try {
51020
- outcome = applyAbsorb({
51021
- ref: parsed.ref,
51022
- summary: parsed.summary,
51023
- absorbCallId: parsed.absorbCallId,
51024
- messages: ctx.messages,
51025
- state: ctx.session.state,
51026
- config: { ...ctx.config, absorb }
51027
- });
51028
- } catch (err2) {
51029
- log2(`[acp-absorb] error: ${String(err2)}`);
51030
- return `[absorb FAILED: ${String(err2)}]`;
51031
- }
51032
- ctx.session.state = outcome.state;
51033
- if (!outcome.ok) {
51034
- log2(`[acp-absorb] ${outcome.resultText}`);
51035
- return `[absorb FAILED: ${outcome.resultText}]`;
51036
- }
51037
- const records = outcome.state.absorbed ?? [];
51038
- const record = records.length > before ? records[records.length - 1] : void 0;
51039
- if (record) {
51040
- ctx.session.stats.compressCreditTokens = (ctx.session.stats.compressCreditTokens ?? 0) + record.tokensReclaimed;
51041
- ctx.session.stats.lastInputTokens = Math.max(0, ctx.session.stats.lastInputTokens - record.tokensReclaimed);
51042
- log2(`[acp-absorb] ${outcome.resultText} (credit -${record.tokensReclaimed} tok)`);
51043
- } else {
51044
- log2(`[acp-absorb] ${outcome.resultText}`);
51045
- }
51046
- return outcome.resultText;
51047
- }
51048
-
51049
50746
  // src/acp-status.ts
51050
50747
  function handleAcpStatus(args, ctx) {
51051
50748
  const scope = typeof args.scope === "string" ? args.scope : void 0;
@@ -51413,10 +51110,6 @@ ${lines.join("\n\n")}`;
51413
51110
  if (toolName === "acp_status") {
51414
51111
  return handleAcpStatus(args, ctx);
51415
51112
  }
51416
- const absorb = effectiveAbsorbConfig(ctx.session, ctx.config);
51417
- if (absorb?.enabled === true && toolName === (absorb.toolName ?? ABSORB_TOOL_NAME)) {
51418
- return executeAbsorb(args, void 0, absorb, ctx);
51419
- }
51420
51113
  return `[Unknown proxy tool: ${toolName}]`;
51421
51114
  }
51422
51115
  function refNum2(ref) {
@@ -51495,7 +51188,7 @@ function rewriteJsonResponse(body, ctx) {
51495
51188
  const newContent = [];
51496
51189
  for (const block of b2.content) {
51497
51190
  const blk = block;
51498
- if (blk.type === "tool_use" && typeof blk.name === "string" && isProxyToolFor(blk.name, ctx.session, ctx.config)) {
51191
+ if (blk.type === "tool_use" && typeof blk.name === "string" && ACP_TOOL_NAMES.has(blk.name)) {
51499
51192
  converted = true;
51500
51193
  const args = blk.input && typeof blk.input === "object" ? blk.input : {};
51501
51194
  newContent.push({ type: "text", text: executeAnthropicProxyTool(blk.name, args, ctx) });
@@ -51712,7 +51405,6 @@ async function preflightCompress(deps, messages) {
51712
51405
  renderTags: "text-only"
51713
51406
  });
51714
51407
  deps.session.state = turn.state;
51715
- turn.messages = applyAbsorbView(turn.messages, turn.state, activeConfig, currentTokens);
51716
51408
  currentTokens = Math.max(deps.session.stats.lastInputTokens, estimateCoreMessages(turn.messages) + (deps.imageFloor ?? 0) + (deps.wireOverhead ?? 0));
51717
51409
  if (!baselineKnown) {
51718
51410
  finalUpper = estimateCoreMessagesUpper(turn.messages) + (deps.imageFloor ?? 0) + (deps.wireOverhead ?? 0);
@@ -52564,8 +52256,7 @@ function buildVisibilityMarker(toolName, result) {
52564
52256
  compress: "\u{1F4E6}",
52565
52257
  decompress: "\u{1F4E4}",
52566
52258
  search_context: "\u{1F50D}",
52567
- acp_status: "\u{1F4CA}",
52568
- absorb: "\u{1FAE7}"
52259
+ acp_status: "\u{1F4CA}"
52569
52260
  };
52570
52261
  const icon = failed ? "\u274C" : icons[toolName] ?? "\u{1F4E6}";
52571
52262
  if (toolName === "acp_status") {
@@ -52893,10 +52584,6 @@ ${lines.join("\n\n")}`;
52893
52584
  if (toolName === "acp_status") {
52894
52585
  return handleAcpStatus(args, ctx);
52895
52586
  }
52896
- const absorb = effectiveAbsorbConfig(ctx.session, ctx.config);
52897
- if (absorb?.enabled === true && toolName === (absorb.toolName ?? ABSORB_TOOL_NAME)) {
52898
- return executeAbsorb(args, callId, absorb, ctx);
52899
- }
52900
52587
  return `[Unknown proxy tool: ${toolName}]`;
52901
52588
  }
52902
52589
  function recordUsage(ctx, usage, round) {
@@ -53064,7 +52751,7 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
53064
52751
  const realToolCalls = [];
53065
52752
  const proxyResults = [];
53066
52753
  for (const call of allCalls) {
53067
- if (isProxyToolFor(call.name, ctx.session, ctx.config)) {
52754
+ if (ACP_TOOL_NAMES.has(call.name)) {
53068
52755
  let parsedArgs;
53069
52756
  try {
53070
52757
  parsedArgs = call.arguments.length > 0 ? JSON.parse(call.arguments) : {};
@@ -53153,11 +52840,7 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
53153
52840
  coreMessages.push(...hidden.messages);
53154
52841
  }
53155
52842
  }
53156
- const absorbName = (() => {
53157
- const a = effectiveAbsorbConfig(ctx.session, ctx.config);
53158
- return a?.enabled === true ? a.toolName ?? ABSORB_TOOL_NAME : void 0;
53159
- })();
53160
- if (ctx.refreshFolded && proxyResults.some((pr2) => (pr2.name === "compress" || pr2.name === absorbName) && !pr2.result.includes("FAILED"))) {
52843
+ if (ctx.refreshFolded && proxyResults.some((pr2) => pr2.name === "compress" && !pr2.result.includes("FAILED"))) {
53161
52844
  try {
53162
52845
  const refreshed = ctx.refreshFolded(coreMessages);
53163
52846
  if (refreshed.length > 0) {
@@ -53499,7 +53182,7 @@ data: ${JSON.stringify({ type: "response.completed", response: resp })}
53499
53182
  "utf8"
53500
53183
  );
53501
53184
  }
53502
- function createResponsesAdapter(textProtocol, projection, absorbName) {
53185
+ function createResponsesAdapter(textProtocol, projection) {
53503
53186
  const suppressTextLifecycle = !!textProtocol;
53504
53187
  let outputIndex = 0;
53505
53188
  let responseObj = null;
@@ -53585,7 +53268,7 @@ data: ${JSON.stringify({ type: "response.created", response: { id: createdRespId
53585
53268
  const item = obj.item;
53586
53269
  if (item?.type === "function_call") {
53587
53270
  const fcName = typeof item.name === "string" ? item.name : "";
53588
- if (ACP_TOOL_NAMES.has(fcName) || fcName === absorbName) {
53271
+ if (ACP_TOOL_NAMES.has(fcName)) {
53589
53272
  const itemId = typeof item.id === "string" ? item.id : "";
53590
53273
  pending.set(itemId, {
53591
53274
  itemId,
@@ -53930,7 +53613,7 @@ function patchUsageChunk(eventStr, parsed, u2, hostCredit) {
53930
53613
  }
53931
53614
  return Buffer.from(eventStr + "\n\n", "utf8");
53932
53615
  }
53933
- function createOpenaiAdapter(requestBody, clientSystem, hostCredit = 0, absorbName) {
53616
+ function createOpenaiAdapter(requestBody, clientSystem, hostCredit = 0) {
53934
53617
  const model = requestBody.model ?? "unknown";
53935
53618
  let responseId = `chatcmpl-proxy-${Date.now()}`;
53936
53619
  let toolIndex = 0;
@@ -54032,7 +53715,7 @@ function createOpenaiAdapter(requestBody, clientSystem, hostCredit = 0, absorbNa
54032
53715
  const settleToolCalls = function* () {
54033
53716
  const realIndexes = /* @__PURE__ */ new Set();
54034
53717
  for (const [idx, tc] of pending) {
54035
- if (tc.name.length > 0 && !PROXY_TOOL_SET.has(tc.name) && tc.name !== absorbName) realIndexes.add(idx);
53718
+ if (tc.name.length > 0 && !PROXY_TOOL_SET.has(tc.name)) realIndexes.add(idx);
54036
53719
  }
54037
53720
  sawRealToolCall = realIndexes.size > 0;
54038
53721
  if (!sawRealToolCall) {
@@ -54624,9 +54307,9 @@ data: ${JSON.stringify({ type: "content_block_stop", index })}
54624
54307
  }
54625
54308
 
54626
54309
  // src/loop/index.ts
54627
- function pickAdapter(protocol, requestBody, textProtocol, responsesProjection, anthropicSystem, openaiSystem, hostCredit = 0, absorbName) {
54628
- if (protocol === "responses") return createResponsesAdapter(textProtocol, responsesProjection, absorbName);
54629
- if (protocol === "openai") return createOpenaiAdapter(requestBody, openaiSystem, hostCredit, absorbName);
54310
+ function pickAdapter(protocol, requestBody, textProtocol, responsesProjection, anthropicSystem, openaiSystem, hostCredit = 0) {
54311
+ if (protocol === "responses") return createResponsesAdapter(textProtocol, responsesProjection);
54312
+ if (protocol === "openai") return createOpenaiAdapter(requestBody, openaiSystem, hostCredit);
54630
54313
  if (protocol === "anthropic") return createAnthropicAdapter(requestBody, anthropicSystem, hostCredit);
54631
54314
  throw new Error(`[acp-loop] unknown protocol: ${protocol}`);
54632
54315
  }
@@ -55911,16 +55594,11 @@ function handlePluginManifest(res) {
55911
55594
  protocolVersion: PLUGIN_PROTOCOL_VERSION,
55912
55595
  proxy: "billion-context",
55913
55596
  version: VERSION,
55914
- // Absorb is advertised alongside the four ACP tools. It is host-
55915
- // registered opt-in (not in the kernel's ACP_TOOL_NAMES), so the
55916
- // manifest must list it explicitly. Per-session enablement is enforced
55917
- // at execution (isProxyToolFor / executeProxyTool), not here — the
55918
- // manifest has no request context to know which route will win.
55919
- toolNames: [...ACP_TOOL_NAMES, ABSORB_TOOL_NAME],
55597
+ toolNames: [...ACP_TOOL_NAMES],
55920
55598
  tools: {
55921
- anthropic: [...ACP_TOOLS_ANTHROPIC, ABSORB_TOOL],
55922
- openai: [...ACP_TOOLS_OPENAI, ABSORB_TOOL_OPENAI],
55923
- responses: [...ACP_TOOLS_RESPONSES, ABSORB_TOOL_RESPONSES]
55599
+ anthropic: ACP_TOOLS_ANTHROPIC,
55600
+ openai: ACP_TOOLS_OPENAI,
55601
+ responses: ACP_TOOLS_RESPONSES
55924
55602
  },
55925
55603
  headers: { agent: PLUGIN_AGENT_HEADER, conversation: PLUGIN_CONVERSATION_HEADER, contextWindow: PLUGIN_CONTEXT_WINDOW_HEADER },
55926
55604
  toolEndpoint: "/__bili/plugin/tool",
@@ -56017,6 +55695,11 @@ async function handlePluginTool(payload, res, deps) {
56017
55695
  res.end(JSON.stringify({ ok: false, error: `conversationId is required (send the same value as the ${PLUGIN_CONVERSATION_HEADER} header)` }));
56018
55696
  return;
56019
55697
  }
55698
+ if (!ACP_TOOL_NAMES.has(tool)) {
55699
+ res.writeHead(400, { "content-type": "application/json" });
55700
+ res.end(JSON.stringify({ ok: false, error: `unknown tool "${tool}" (expected one of: ${[...ACP_TOOL_NAMES].join(", ")})` }));
55701
+ return;
55702
+ }
56020
55703
  const entry = conversations.get(conversationId2);
56021
55704
  const session = entry ? peekSession(entry.sessionId) : void 0;
56022
55705
  if (!entry || !session) {
@@ -56024,14 +55707,6 @@ async function handlePluginTool(payload, res, deps) {
56024
55707
  res.end(JSON.stringify({ ok: false, error: "unknown plugin conversation (no model request has arrived with this conversation id yet)" }));
56025
55708
  return;
56026
55709
  }
56027
- if (!isProxyToolFor(tool, session, deps.config)) {
56028
- const allowed = [...ACP_TOOL_NAMES];
56029
- const absorb = effectiveAbsorbConfig(session, deps.config);
56030
- if (absorb?.enabled === true) allowed.push(absorb.toolName ?? ABSORB_TOOL_NAME);
56031
- res.writeHead(400, { "content-type": "application/json" });
56032
- res.end(JSON.stringify({ ok: false, error: `unknown tool "${tool}" (expected one of: ${allowed.join(", ")})` }));
56033
- return;
56034
- }
56035
55710
  entry.lastSeen = Date.now();
56036
55711
  const args = parsed.args && typeof parsed.args === "object" ? parsed.args : {};
56037
55712
  const callId = `plugin_${Date.now().toString(36)}`;
@@ -59072,13 +58747,9 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
59072
58747
  extractSystem(parsed.system);
59073
58748
  const tokenCount = effectiveTokenCount(session, msgs);
59074
58749
  const activeBefore = new Set(session.state.blocks.filter((b2) => b2.active).map((b2) => b2.blockId));
59075
- const absorbActive = absorbEnabled(config) && opts.compress.injectTool;
59076
- const loopConfig = absorbActive ? config : { ...config, absorb: void 0 };
59077
- const turn = core.processTurn({ messages: msgs, state: session.state, config: loopConfig, tokenCount, renderTags: "text-only" });
58750
+ const turn = core.processTurn({ messages: msgs, state: session.state, config, tokenCount, renderTags: "text-only" });
59078
58751
  session.state = turn.state;
59079
58752
  session.stats.compressCreditTokens = 0;
59080
- storeEffectiveAbsorb(session, loopConfig);
59081
- turn.messages = applyAbsorbView(turn.messages, session.state, loopConfig, tokenCount);
59082
58753
  if (turn.nudge) turn.nudge.compressibleRanges = viableRanges(turn.nudge.compressibleRanges);
59083
58754
  nudge = turn.nudge;
59084
58755
  session.stats.contextTokens = tokenCount;
@@ -59093,9 +58764,9 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
59093
58764
  applyCompactionArchive(session, activeBefore, new Set(msgs.map((m2) => m2.id)), log2);
59094
58765
  reapOrphanBlocks(session, msgs, deactivateBlock);
59095
58766
  rebuiltMessages = coreToAnthropic(processedMessages, cacheControls);
59096
- systemOut = injectSystem(parsed, opts, prompts, loopConfig);
58767
+ systemOut = injectSystem(parsed, opts, prompts);
59097
58768
  if (injectTools) {
59098
- toolsOut = injectTool(parsed.tools, absorbActive ? ABSORB_TOOL : void 0);
58769
+ toolsOut = injectTool(parsed.tools);
59099
58770
  }
59100
58771
  if (willInjectNudge && turn.nudge) {
59101
58772
  try {
@@ -59197,13 +58868,9 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
59197
58868
  originalMessages = msgs;
59198
58869
  const tokenCount = effectiveTokenCount(session, msgs);
59199
58870
  const activeBefore = new Set(session.state.blocks.filter((b2) => b2.active).map((b2) => b2.blockId));
59200
- const absorbActive = absorbEnabled(config) && shouldInject;
59201
- const loopConfig = absorbActive ? config : { ...config, absorb: void 0 };
59202
- const turn = core.processTurn({ messages: msgs, state: session.state, config: loopConfig, tokenCount, renderTags: "text-only" });
58871
+ const turn = core.processTurn({ messages: msgs, state: session.state, config, tokenCount, renderTags: "text-only" });
59203
58872
  session.state = turn.state;
59204
58873
  session.stats.compressCreditTokens = 0;
59205
- storeEffectiveAbsorb(session, loopConfig);
59206
- turn.messages = applyAbsorbView(turn.messages, session.state, loopConfig, tokenCount);
59207
58874
  if (turn.nudge) turn.nudge.compressibleRanges = viableRanges(turn.nudge.compressibleRanges);
59208
58875
  nudge = turn.nudge;
59209
58876
  session.stats.contextTokens = tokenCount;
@@ -59221,11 +58888,10 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
59221
58888
  const sysParts = [];
59222
58889
  if (systemText) sysParts.push(systemText);
59223
58890
  if (shouldInject) sysParts.push(buildCompressSystemPrompt(prompts));
59224
- if (absorbActive) sysParts.push(buildAbsorbSystemPrompt(absorbToolName(config)));
59225
58891
  rebuiltMessages = injectOpenaiSystem(rebuiltMessages, sysParts);
59226
58892
  openaiOutboundSystem = sysParts.join("\n\n");
59227
58893
  if (injectTools) {
59228
- toolsOut = injectOpenaiTool(parsed.tools, absorbActive ? ABSORB_TOOL_OPENAI : void 0);
58894
+ toolsOut = injectOpenaiTool(parsed.tools);
59229
58895
  }
59230
58896
  if (willInjectNudge && turn.nudge) {
59231
58897
  try {
@@ -59306,13 +58972,9 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
59306
58972
  log2("info", `[${sessionId}] input items: ${Array.isArray(parsed.input) ? parsed.input.map((i) => i.type).join(",") : "(string)"}`);
59307
58973
  }
59308
58974
  const tokenCount = effectiveTokenCount(session, msgs);
59309
- const absorbActive = absorbEnabled(config) && shouldInject && !isCompactionTrigger && !responsesTextProtocol;
59310
- const loopConfig = absorbActive ? config : { ...config, absorb: void 0 };
59311
- const turn = core.processTurn({ messages: msgs, state: session.state, config: loopConfig, tokenCount, renderTags });
58975
+ const turn = core.processTurn({ messages: msgs, state: session.state, config, tokenCount, renderTags });
59312
58976
  session.state = turn.state;
59313
58977
  session.stats.compressCreditTokens = 0;
59314
- storeEffectiveAbsorb(session, loopConfig);
59315
- turn.messages = applyAbsorbView(turn.messages, session.state, loopConfig, tokenCount);
59316
58978
  if (turn.nudge) turn.nudge.compressibleRanges = viableRanges(turn.nudge.compressibleRanges);
59317
58979
  nudge = turn.nudge;
59318
58980
  session.stats.contextTokens = tokenCount;
@@ -59329,13 +58991,11 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
59329
58991
  const forgedSummaries = echoReplaced ? [] : session.metadata.codexForgedSummaries ?? [];
59330
58992
  if (shouldInject && !isCompactionTrigger && !process.env.ACP_NO_COMPRESS_PROMPT) {
59331
58993
  const prompt = responsesTextProtocol ? buildCompressHybridSystemPrompt(prompts) : buildCompressSystemPrompt(prompts);
59332
- const devParts = [...projection.systemParts, ...forgedSummaries, prompt];
59333
- if (absorbActive) devParts.push(buildAbsorbSystemPrompt(absorbToolName(config)));
59334
- const devContent = devParts.join("\n\n---\n\n");
58994
+ const devContent = [...projection.systemParts, ...forgedSummaries, prompt].join("\n\n---\n\n");
59335
58995
  responsesDevContent = devContent;
59336
58996
  rebuiltInput = injectResponsesDeveloperMessage(rebuiltInput, devContent);
59337
58997
  if (!process.env.ACP_NO_INJECT_TOOL && injectTools) {
59338
- toolsOut = responsesTextProtocol ? injectResponsesTool(parsed.tools, ACP_READONLY_TOOLS_RESPONSES) : injectResponsesTool(parsed.tools, absorbActive ? [...ACP_TOOLS_RESPONSES, ABSORB_TOOL_RESPONSES] : ACP_TOOLS_RESPONSES);
58998
+ toolsOut = responsesTextProtocol ? injectResponsesTool(parsed.tools, ACP_READONLY_TOOLS_RESPONSES) : injectResponsesTool(parsed.tools);
59339
58999
  }
59340
59000
  } else if (projection.systemParts.length > 0 || forgedSummaries.length > 0) {
59341
59001
  const devContent = [...projection.systemParts, ...forgedSummaries].join("\n\n---\n\n");
@@ -59480,16 +59140,14 @@ function prepareResponsesCompact(body, parsed, session, req, core, config, log2)
59480
59140
  let transformOk = false;
59481
59141
  try {
59482
59142
  const projection = responsesToCore(forgeBody);
59483
- const compactConfig = { ...config, absorb: void 0 };
59484
- const turn = core.processTurn({ messages: projection.msgs, state: session.state, config: compactConfig, tokenCount: session.stats.lastInputTokens, renderTags: process.env.ACP_RENDER_NONE ? "none" : "text-only" });
59143
+ const turn = core.processTurn({ messages: projection.msgs, state: session.state, config, tokenCount: session.stats.lastInputTokens, renderTags: process.env.ACP_RENDER_NONE ? "none" : "text-only" });
59485
59144
  session.state = turn.state;
59486
59145
  transformOk = true;
59487
59146
  if (!codexCompactGate(session, config.modelContextLimit, transformOk)) {
59488
59147
  session.state = prevState;
59489
59148
  return base;
59490
59149
  }
59491
- const viewed = applyAbsorbView(turn.messages, turn.state, compactConfig, session.stats.lastInputTokens);
59492
- const processed = repairResponsesAssistantOrdering(stripKernelSummaries(viewed, turn.state), projection.msgs);
59150
+ const processed = repairResponsesAssistantOrdering(stripKernelSummaries(turn.messages, turn.state), projection.msgs);
59493
59151
  const output = patchResponsesInput(projection, processed);
59494
59152
  if (typeof output === "string") {
59495
59153
  session.state = prevState;
@@ -59525,11 +59183,10 @@ function isAutoModeClassifier(parsed) {
59525
59183
  if (!Array.isArray(stops)) return false;
59526
59184
  return stops.some((s3) => typeof s3 === "string" && AUTO_MODE_CLASSIFIER_STOPS.has(s3));
59527
59185
  }
59528
- function injectSystem(parsed, opts, prompts = defaultPrompts, config) {
59186
+ function injectSystem(parsed, opts, prompts = defaultPrompts) {
59529
59187
  const baseText = extractSystem(parsed.system);
59530
59188
  const parts = [];
59531
59189
  if (opts.compress.injectTool) parts.push(buildCompressSystemPrompt(prompts));
59532
- if (opts.compress.injectTool && absorbEnabled(config)) parts.push(buildAbsorbSystemPrompt(absorbToolName(config)));
59533
59190
  if (parts.length === 0) return parsed.system;
59534
59191
  const full = baseText ? `${baseText}
59535
59192
 
@@ -59538,23 +59195,19 @@ function injectSystem(parsed, opts, prompts = defaultPrompts, config) {
59538
59195
  ${parts.join("\n\n")}` : parts.join("\n\n");
59539
59196
  return buildSystem(full, parsed.system);
59540
59197
  }
59541
- function injectTool(tools, extra) {
59542
- if (!Array.isArray(tools)) return extra ? [...ACP_TOOLS_ANTHROPIC, extra] : [...ACP_TOOLS_ANTHROPIC];
59198
+ function injectTool(tools) {
59199
+ if (!Array.isArray(tools)) return [...ACP_TOOLS_ANTHROPIC];
59543
59200
  const names = new Set(tools.map((t) => t?.name));
59544
59201
  const missing = ACP_TOOLS_ANTHROPIC.filter((t) => !names.has(t.name));
59545
- const extraMissing = extra && !names.has(extra.name);
59546
- if (missing.length === 0 && !extraMissing) return tools;
59547
- return [...tools, ...missing, ...extraMissing ? [extra] : []];
59202
+ return missing.length === 0 ? tools : [...tools, ...missing];
59548
59203
  }
59549
- function injectOpenaiTool(tools, extra) {
59550
- if (!Array.isArray(tools)) return extra ? [...ACP_TOOLS_OPENAI, extra] : [...ACP_TOOLS_OPENAI];
59204
+ function injectOpenaiTool(tools) {
59205
+ if (!Array.isArray(tools)) return [...ACP_TOOLS_OPENAI];
59551
59206
  const present = new Set(
59552
59207
  tools.map((t) => t?.function?.name).filter((n) => typeof n === "string")
59553
59208
  );
59554
59209
  const additions = ACP_TOOLS_OPENAI.filter((t) => !present.has(t.function.name));
59555
- const out = [...tools, ...additions];
59556
- if (extra && !out.some((t) => t?.function?.name === extra.function?.name)) out.push(extra);
59557
- return out;
59210
+ return [...tools, ...additions];
59558
59211
  }
59559
59212
  var FORCE_TEXT_PROTOCOL = process.env.ACP_COMPRESS_PROTOCOL === "text";
59560
59213
  function injectResponsesTool(tools, toolsToAdd = ACP_TOOLS_RESPONSES) {
@@ -60167,27 +59820,19 @@ ${hdrText}
60167
59820
  const parsedReq = JSON.parse(typeof body === "string" ? body : body.toString("utf8"));
60168
59821
  const reqHeaders = buildForwardHeaders(headers);
60169
59822
  const textProtocol = prepared.protocol === "responses" && !!prepared.responsesTextProtocol;
60170
- const absorbActive = absorbEnabled(config) && opts.compress.injectTool && !textProtocol;
60171
- const loopConfig = absorbActive ? config : { ...config, absorb: void 0 };
60172
- const absorbSection = absorbActive ? `
60173
-
60174
- ---
60175
-
60176
- ${buildAbsorbSystemPrompt(absorbToolName(loopConfig))}` : "";
60177
- const systemPrompt = (textProtocol ? buildCompressHybridSystemPrompt(prepared.prompts ?? defaultPrompts) : buildCompressSystemPrompt(prepared.prompts ?? defaultPrompts)) + absorbSection;
60178
- const adapter = pickAdapter(prepared.protocol, parsedReq, textProtocol, prepared.responsesProjection, prepared.anthropicSystem, prepared.openaiSystemText, prepared.session.hostCreditTokens ?? 0, absorbActive ? absorbToolName(loopConfig) : void 0);
59823
+ const systemPrompt = textProtocol ? buildCompressHybridSystemPrompt(prepared.prompts ?? defaultPrompts) : buildCompressSystemPrompt(prepared.prompts ?? defaultPrompts);
59824
+ const adapter = pickAdapter(prepared.protocol, parsedReq, textProtocol, prepared.responsesProjection, prepared.anthropicSystem, prepared.openaiSystemText, prepared.session.hostCreditTokens ?? 0);
60179
59825
  const refreshFolded = (current) => {
60180
59826
  const turn = core.processTurn({
60181
59827
  messages: prepared.originalMessages,
60182
59828
  state: prepared.session.state,
60183
- config: loopConfig,
59829
+ config,
60184
59830
  tokenCount: prepared.session.stats.lastInputTokens,
60185
59831
  renderTags: prepared.renderTags ?? "text-only"
60186
59832
  });
60187
59833
  prepared.session.state = turn.state;
60188
- const viewed = applyAbsorbView(turn.messages, turn.state, loopConfig, prepared.session.stats.lastInputTokens);
60189
59834
  const records = current.filter((m2) => typeof m2.id === "string" && m2.id.startsWith("acp_loop_"));
60190
- return repairResponsesAssistantOrdering(stripKernelSummaries([...viewed, ...records], turn.state), prepared.originalMessages);
59835
+ return repairResponsesAssistantOrdering(stripKernelSummaries([...turn.messages, ...records], turn.state), prepared.originalMessages);
60191
59836
  };
60192
59837
  const loop = runCompressLoop(
60193
59838
  streamToRead,