billion-context 0.1.104 → 0.1.105-pr.691.546

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/README.md CHANGED
@@ -24,6 +24,12 @@ Any agent that can set a base URL — <em>zero per-agent adapter code</em>.
24
24
 
25
25
  `billion-context` sits between **any** agent and its model API, rewriting Anthropic/OpenAI streams with [acp-kernel](https://github.com/ranxianglei/acp-kernel) compression. The model decides **when** and **what** to compress into high-fidelity summaries — not a hard truncation limit.
26
26
 
27
+ ## Community
28
+
29
+ Discussion, help, and updates on QQ — one group covers all three projects (`billion-context`, `billion-context-pi`, `opencode-acp`):
30
+
31
+ **QQ Group: 1056132097**
32
+
27
33
  ## Why
28
34
 
29
35
  Long coding sessions blow up context. Each provider charges per token, and once you pass the context window the session degrades or dies. `billion-context` compresses consumed conversation into layered summaries so you can run a single session for days — billions of tokens through one context window.
@@ -466,6 +472,10 @@ Early. Protocol handling and compression work against mock tests (500+ passing).
466
472
 
467
473
  Client-side plugins for pi / omp / opencode ship inside `billion-context` (`dist/agent/*.js`) for the cooperative-proxy path. See the **"Which do I need?"** section above for how `billion-context`, the standalone `billion-context-pi`, and `opencode-acp` relate.
468
474
 
475
+ ## Community
476
+
477
+ QQ group — one shared group for all three projects ([`billion-context`](https://github.com/ranxianglei/billion-context), [`billion-context-pi`](https://github.com/ranxianglei/billion-context-pi), [`opencode-acp`](https://github.com/ranxianglei/opencode-acp)): **1056132097**
478
+
469
479
  ## License
470
480
 
471
481
  MIT
package/README.zh-CN.md CHANGED
@@ -24,6 +24,12 @@ AI 编程助手的<strong>通用上下文压缩代理</strong>
24
24
 
25
25
  `billion-context` 架在**任意**编程助手与其模型 API 之间,用 [acp-kernel](https://github.com/ranxianglei/acp-kernel) 压缩重写 Anthropic/OpenAI 流。何时压缩、压缩什么 —— <strong>由模型决定</strong>,而非硬截断。
26
26
 
27
+ ## 社区
28
+
29
+ 交流、求助与更新都在 QQ——同一个群覆盖三个项目(`billion-context`、`billion-context-pi`、`opencode-acp`):
30
+
31
+ **QQ 群:1056132097**
32
+
27
33
  ## 为什么
28
34
 
29
35
  长编程会话会把上下文撑爆。各家 provider 按 token 计费,一旦超过上下文窗口,会话质量下降甚至崩掉。`billion-context` 把已消耗的对话压缩成分层摘要,让你**一个会话连跑数天** —— 海量 token 穿过同一个上下文窗口。
@@ -287,6 +293,10 @@ Windows 下会自动发现常见 Clash/Mihomo 静态系统代理;Web UI 会显
287
293
 
288
294
  针对 pi / omp / opencode 的客户端插件随 `billion-context` 一起发布(`dist/agent/*.js`),用于协作代理路径。三者(`billion-context`、独立的 `billion-context-pi`、`opencode-acp`)如何取舍,见上文「该选哪个?」一节。
289
295
 
296
+ ## 社区
297
+
298
+ QQ 群 —— 三个项目共用一个群([`billion-context`](https://github.com/ranxianglei/billion-context)、[`billion-context-pi`](https://github.com/ranxianglei/billion-context-pi)、[`opencode-acp`](https://github.com/ranxianglei/opencode-acp)):**1056132097**
299
+
290
300
  ## 许可证
291
301
 
292
302
  MIT
package/dist/index.js CHANGED
@@ -48626,7 +48626,6 @@ function loadOptions(env = process.env) {
48626
48626
  passthrough: passthrough.enabled,
48627
48627
  passthroughSource: passthrough.source,
48628
48628
  autoUpdate: (env.ACP_AUTO_UPDATE ?? (fileConfig.autoUpdate === false ? "0" : "1")) !== "0",
48629
- hostUsageCredit: parseHostUsageCredit(env.BILI_HOST_USAGE_CREDIT ?? fileConfig.hostUsageCredit),
48630
48629
  updateTag: (env.ACP_UPDATE_TAG ?? fileConfig.updateTag ?? "latest").trim() || "latest",
48631
48630
  logFile: env.ACP_LOG_FILE !== void 0 ? env.ACP_LOG_FILE || void 0 : fileConfig.logFile,
48632
48631
  mitm: {
@@ -48704,9 +48703,6 @@ function parsePromptCacheRouting(value) {
48704
48703
  function parseUpstreamProxyMode(value) {
48705
48704
  return value === "manual" || value === "auto" ? value : "direct";
48706
48705
  }
48707
- function parseHostUsageCredit(value) {
48708
- return value === "off" ? "off" : "auto";
48709
- }
48710
48706
  function parseCompressSettings(v2) {
48711
48707
  if (!v2 || typeof v2 !== "object" || Array.isArray(v2)) return void 0;
48712
48708
  const obj = v2;
@@ -51305,8 +51301,6 @@ function resetSessionCompression(session) {
51305
51301
  session.blockContents.clear();
51306
51302
  session.stats.lastInputTokens = 0;
51307
51303
  session.stats.contextTokens = 0;
51308
- session.hostCreditTokens = 0;
51309
- session.hostContextTokens = 0;
51310
51304
  session.metadata.nativeCompactionAt = Date.now();
51311
51305
  markDirty(session);
51312
51306
  }
@@ -53340,23 +53334,6 @@ function promptInputTotal(protocol, input, cached) {
53340
53334
  const splitSemantics = !includesCached || typeof cached === "number" && input < cached;
53341
53335
  return input + (splitSemantics && typeof cached === "number" ? cached : 0);
53342
53336
  }
53343
- function backfillHostUsage(protocol, usage, credit) {
53344
- if (!Number.isFinite(credit) || credit <= 0) return false;
53345
- let patched = false;
53346
- const add = (key) => {
53347
- if (typeof usage[key] === "number" && Number.isFinite(usage[key])) {
53348
- usage[key] = usage[key] + credit;
53349
- patched = true;
53350
- }
53351
- };
53352
- if (protocol === "openai") {
53353
- add("prompt_tokens");
53354
- add("total_tokens");
53355
- } else {
53356
- add("input_tokens");
53357
- }
53358
- return patched;
53359
- }
53360
53337
  var CONTEXT_OVERFLOW_PATTERNS = [
53361
53338
  /context_length_exceeded/i,
53362
53339
  /context_window_exceeded/i,
@@ -53486,7 +53463,6 @@ function recordUsage(ctx, usage, round) {
53486
53463
  const total = promptInputTotal(ctx.protocol, prompt, cached);
53487
53464
  if (total > 0) ctx.session.stats.inputTokens += total;
53488
53465
  ctx.session.stats.lastInputTokens = Math.max(0, total - (ctx.session.stats.compressCreditTokens ?? 0));
53489
- ctx.session.hostContextTokens = total + (ctx.session.hostCreditTokens ?? 0);
53490
53466
  if (typeof cached === "number") {
53491
53467
  ctx.session.stats.cachedTokens += cached;
53492
53468
  ctx.session.stats.cacheSamples += 1;
@@ -53627,10 +53603,6 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
53627
53603
  if (usage.inputTokens !== void 0 || usage.outputTokens !== void 0 || usage.cachedTokens !== void 0) {
53628
53604
  recordUsage(ctx, usage, round);
53629
53605
  }
53630
- const hostCredit = ctx.session.hostCreditTokens ?? 0;
53631
- if (hostCredit > 0 && typeof usage.inputTokens === "number") {
53632
- usage.inputTokens += hostCredit;
53633
- }
53634
53606
  let resolvedText = assistantText;
53635
53607
  let allCalls = calls;
53636
53608
  if (ctx.textProtocol && assistantText.length > 0 && adapter.extractTextTriggers) {
@@ -54527,24 +54499,7 @@ function stripFinishReasonChunk(buf) {
54527
54499
  return buf;
54528
54500
  }
54529
54501
  }
54530
- function patchUsageChunk(eventStr, parsed, u2, hostCredit) {
54531
- const pu = typeof u2.prompt_tokens === "number" ? u2.prompt_tokens : void 0;
54532
- const tu = typeof u2.total_tokens === "number" ? u2.total_tokens : void 0;
54533
- if (hostCredit > 0 && (pu !== void 0 || tu !== void 0)) {
54534
- const patched = {
54535
- ...parsed,
54536
- usage: {
54537
- ...u2,
54538
- ...pu !== void 0 ? { prompt_tokens: pu + hostCredit } : {},
54539
- ...tu !== void 0 ? { total_tokens: tu + hostCredit } : {}
54540
- }
54541
- };
54542
- const out = eventStr.split("\n").map((l) => l.startsWith("data:") ? `data: ${JSON.stringify(patched)}` : l).join("\n");
54543
- return Buffer.from(out + "\n\n", "utf8");
54544
- }
54545
- return Buffer.from(eventStr + "\n\n", "utf8");
54546
- }
54547
- function createOpenaiAdapter(requestBody, clientSystem, hostCredit = 0, absorbName) {
54502
+ function createOpenaiAdapter(requestBody, clientSystem, absorbName) {
54548
54503
  const model = requestBody.model ?? "unknown";
54549
54504
  let responseId = `chatcmpl-proxy-${Date.now()}`;
54550
54505
  let toolIndex = 0;
@@ -54736,7 +54691,7 @@ function createOpenaiAdapter(requestBody, clientSystem, hostCredit = 0, absorbNa
54736
54691
  cachedTokens: typeof pd?.cached_tokens === "number" ? pd.cached_tokens : void 0
54737
54692
  };
54738
54693
  if (sawRealToolCall) {
54739
- yield { kind: "meta", chunk: patchUsageChunk(eventStr, parsed, u2, hostCredit) };
54694
+ yield { kind: "meta", chunk: rawBuf };
54740
54695
  }
54741
54696
  }
54742
54697
  continue;
@@ -54756,7 +54711,7 @@ function createOpenaiAdapter(requestBody, clientSystem, hostCredit = 0, absorbNa
54756
54711
  cachedTokens: typeof pd?.cached_tokens === "number" ? pd.cached_tokens : void 0
54757
54712
  };
54758
54713
  if (sawRealToolCall) {
54759
- const chunk = patchUsageChunk(eventStr, parsed, u2 ?? {}, hostCredit);
54714
+ const chunk = rawBuf;
54760
54715
  yield { kind: "meta", chunk };
54761
54716
  maybeWarnDegenerate(finishReason);
54762
54717
  yield { kind: "done", finishReason, suppressCompletion: true };
@@ -54947,7 +54902,7 @@ data: ${JSON.stringify({ type: "content_block_delta", index, delta: { type: "tex
54947
54902
  "utf8"
54948
54903
  );
54949
54904
  }
54950
- function createAnthropicAdapter(requestBody, originalSystem, hostCredit = 0) {
54905
+ function createAnthropicAdapter(requestBody, originalSystem) {
54951
54906
  const model = requestBody.model ?? void 0;
54952
54907
  let messageId;
54953
54908
  let clientIndex = 0;
@@ -55072,19 +55027,8 @@ ${systemPrompt}` : systemPrompt;
55072
55027
  if (typeof u2.input_tokens === "number") roundInput = u2.input_tokens;
55073
55028
  if (typeof u2.cache_read_input_tokens === "number") roundCached = u2.cache_read_input_tokens;
55074
55029
  if (round === 1) {
55075
- let chunk = rawBuf;
55076
- if (hostCredit > 0 && typeof u2.input_tokens === "number") {
55077
- const patched = structuredClone(data);
55078
- const pmsg = patched["message"];
55079
- const pu = pmsg?.["usage"] ?? {};
55080
- if (typeof pu.input_tokens === "number") {
55081
- pu.input_tokens += hostCredit;
55082
- const out = eventStr.split("\n").map((l) => l.startsWith("data:") ? `data: ${JSON.stringify(patched)}` : l).join("\n");
55083
- chunk = Buffer.from(out + "\n\n", "utf8");
55084
- }
55085
- }
55086
55030
  messageStartForwarded = true;
55087
- yield { kind: "meta", chunk, firstRoundOnly: true };
55031
+ yield { kind: "meta", chunk: rawBuf, firstRoundOnly: true };
55088
55032
  }
55089
55033
  } else if (type === "ping") {
55090
55034
  yield { kind: "meta", chunk: rawBuf };
@@ -55273,10 +55217,10 @@ data: ${JSON.stringify({ type: "content_block_stop", index })}
55273
55217
  }
55274
55218
 
55275
55219
  // src/loop/index.ts
55276
- function pickAdapter(protocol, requestBody, textProtocol, responsesProjection, anthropicSystem, openaiSystem, hostCredit = 0, absorbName) {
55220
+ function pickAdapter(protocol, requestBody, textProtocol, responsesProjection, anthropicSystem, openaiSystem, absorbName) {
55277
55221
  if (protocol === "responses") return createResponsesAdapter(textProtocol, responsesProjection, absorbName);
55278
- if (protocol === "openai") return createOpenaiAdapter(requestBody, openaiSystem, hostCredit, absorbName);
55279
- if (protocol === "anthropic") return createAnthropicAdapter(requestBody, anthropicSystem, hostCredit);
55222
+ if (protocol === "openai") return createOpenaiAdapter(requestBody, openaiSystem, absorbName);
55223
+ if (protocol === "anthropic") return createAnthropicAdapter(requestBody, anthropicSystem);
55280
55224
  throw new Error(`[acp-loop] unknown protocol: ${protocol}`);
55281
55225
  }
55282
55226
 
@@ -56634,7 +56578,7 @@ function handlePluginStatus(conversationId2, res, deps, fallbackLatest = false)
56634
56578
  const systemPromptTokens = typeof sysTokRaw === "number" && Number.isFinite(sysTokRaw) && sysTokRaw > 0 ? sysTokRaw : 0;
56635
56579
  panel = buildStatusPanel({
56636
56580
  version: `billion-context@${PROXY_VERSION}`,
56637
- tokenCount: session.hostContextTokens ?? session.stats.lastInputTokens,
56581
+ tokenCount: session.stats.lastInputTokens,
56638
56582
  systemPromptTokens,
56639
56583
  state: session.state,
56640
56584
  nudge,
@@ -56652,8 +56596,7 @@ function handlePluginStatus(conversationId2, res, deps, fallbackLatest = false)
56652
56596
  label: session.meta.label ?? null,
56653
56597
  pluginAgent: session.metadata.pluginAgent ?? null,
56654
56598
  contextLimit: typeof limit === "number" ? limit : null,
56655
- contextTokens: session.hostContextTokens ?? session.stats.lastInputTokens,
56656
- hostCredit: session.hostCreditTokens ?? 0,
56599
+ contextTokens: session.stats.lastInputTokens,
56657
56600
  inputTokens: session.stats.inputTokens,
56658
56601
  outputTokens: session.stats.outputTokens,
56659
56602
  cachedTokens: session.stats.cachedTokens,
@@ -56775,11 +56718,10 @@ function applyUsageSample(session, sample, protocol) {
56775
56718
  session.stats.inputTokens += total;
56776
56719
  session.stats.lastInputTokens = Math.max(0, total - (session.stats.compressCreditTokens ?? 0));
56777
56720
  warnCacheCollapse(session, total, sample.cachedTokens ?? 0);
56778
- session.hostContextTokens = total + (session.hostCreditTokens ?? 0);
56779
56721
  const hit = sample.cachedTokens === void 0 || total <= 0 ? void 0 : Math.round(100 * (sample.cachedTokens ?? 0) / total);
56780
56722
  const foldNew = session.stats.pendingFoldUsage === true;
56781
56723
  if (foldNew) session.stats.pendingFoldUsage = false;
56782
- log("info", `[${session.id}] [plugin] [acp-usage] input=${total} cached=${sample.cachedTokens ?? "n/a"}${hit === void 0 ? "" : ` (cache hit ${hit}%)`} ctx=${session.hostContextTokens}${foldNew ? " fold=new" : ""}`);
56724
+ log("info", `[${session.id}] [plugin] [acp-usage] input=${total} cached=${sample.cachedTokens ?? "n/a"}${hit === void 0 ? "" : ` (cache hit ${hit}%)`}${foldNew ? " fold=new" : ""}`);
56783
56725
  }
56784
56726
  if (sample.outputTokens !== void 0) session.stats.outputTokens += sample.outputTokens;
56785
56727
  }
@@ -56793,7 +56735,6 @@ async function pipePluginChatWithStrip(stream2, res, protocol, session, log2) {
56793
56735
  const decoder = new TextDecoder("utf-8");
56794
56736
  let buf = "";
56795
56737
  const acc = {};
56796
- const credit = session?.hostCreditTokens ?? 0;
56797
56738
  const onDrop = (snippet) => {
56798
56739
  log("warn", `[tag-echo] stripped model-emitted render tag (plugin passthrough): ${snippet.slice(0, 80).replace(/\n/g, " ")}`);
56799
56740
  log2?.(`[tag-echo] stripped model-emitted render tag from plugin passthrough text`);
@@ -57004,18 +56945,8 @@ data: ${JSON.stringify({ type: "content_block_delta", index, delta: { type: delt
57004
56945
  }
57005
56946
  const sample = usageFromSseEvent(ev);
57006
56947
  if (sample) mergeUsageSample(acc, sample);
57007
- let backfilled = false;
57008
- if (credit > 0 && protocol) {
57009
- const usage = ev["type"] === "message_start" ? ev["message"]?.["usage"] : ev["usage"];
57010
- const deltaEcho = ev["type"] === "message_delta" && (num2(usage?.["input_tokens"]) ?? 0) <= 0;
57011
- if (usage && !deltaEcho && backfillHostUsage(protocol, usage, credit)) backfilled = true;
57012
- }
57013
56948
  const out = protocol === "anthropic" ? processAnthropic(ev, rawEvent) : processOpenai(ev, rawEvent);
57014
- if (backfilled && out === rawEvent + "\n\n") {
57015
- await write(rebuildEvent(rawEvent, ev));
57016
- } else if (out.length > 0) {
57017
- await write(out);
57018
- }
56949
+ if (out.length > 0) await write(out);
57019
56950
  }
57020
56951
  }
57021
56952
  if (res.destroyed || res.writableEnded) break;
@@ -57155,13 +57086,6 @@ async function pipePluginResponsesWithStrip(stream2, res, session, log2) {
57155
57086
  let evOut = ev;
57156
57087
  let rebuild = containsRenderTagText(jsonStr);
57157
57088
  if (rebuild) evOut = stripResponsesText(ev);
57158
- if (type === "response.completed") {
57159
- const credit = session?.hostCreditTokens ?? 0;
57160
- const usage = evOut["response"]?.["usage"];
57161
- if (credit > 0 && usage && backfillHostUsage("responses", usage, credit)) {
57162
- rebuild = true;
57163
- }
57164
- }
57165
57089
  const out = rebuild ? rebuildEvent(rawEvent, evOut) : rawEvent + "\n\n";
57166
57090
  await write(flushTail(out));
57167
57091
  continue;
@@ -57258,10 +57182,6 @@ async function pipePluginJson(stream2, res, session, protocol) {
57258
57182
  cachedTokens: num2(usage["prompt_tokens_details"]?.["cached_tokens"]) ?? num2(usage["input_tokens_details"]?.["cached_tokens"]) ?? num2(usage["cache_read_input_tokens"])
57259
57183
  }, protocol);
57260
57184
  markDirty(session);
57261
- const credit = session.hostCreditTokens ?? 0;
57262
- if (credit > 0 && protocol && backfillHostUsage(protocol, usage, credit)) {
57263
- mutated = true;
57264
- }
57265
57185
  }
57266
57186
  }
57267
57187
  } catch {
@@ -60068,16 +59988,6 @@ function diagNudge(turn, sessionId, tokenCount, limit, model, willInject) {
60068
59988
  const modelTag = model ? ` model=${model}` : "";
60069
59989
  return `[${sessionId}] nudge ${inject}: usage=${pct2} (${tokenCount}/${limit}), growth=${growth}/${floor} (ref=${ref}, interval=${interval}), pendingT1=${pendingT1}/${interval}${modelTag}, reason="${n.reason.slice(0, 120)}"`;
60070
59990
  }
60071
- function armHostUsageCredit(session, originalMessages, processedMessages, headers, hostUsageCredit, log2) {
60072
- session.hostCreditTokens = 0;
60073
- if (hostUsageCredit === "off") return;
60074
- if (session.metadata.pluginAgent === "pi" || session.metadata.pluginAgent === "omp") return;
60075
- if (isCodexClient(headers)) return;
60076
- session.hostCreditTokens = processedMessages.length > 0 ? Math.max(0, estimateCoreMessages(originalMessages) - estimateCoreMessages(processedMessages)) : 0;
60077
- if (session.hostCreditTokens > 0) {
60078
- log2("info", `[${session.id}] host usage backfill armed: +${session.hostCreditTokens} tok (forwarded view is folded); host usage will report the uncompressed baseline`);
60079
- }
60080
- }
60081
59991
  function effectiveTokenCount(session, msgs) {
60082
59992
  if (session.stats.lastInputTokens > 0) return session.stats.lastInputTokens;
60083
59993
  if (!session.metadata.anonymousPrefixAffinity) return 0;
@@ -60087,7 +59997,6 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
60087
59997
  const sessionId = session.id;
60088
59998
  const stream2 = parsed.stream === true;
60089
59999
  ++session.stats.requests;
60090
- session.hostCreditTokens = 0;
60091
60000
  const injectTools = opts.compress.injectTool && !pluginMode;
60092
60001
  const stripReasoning = (msgs) => withReasoningDrop(msgs, reasoning, log2, sessionId, isStrictReasoningEcho(session, upstreamOrigin));
60093
60002
  if (isAutoModeClassifier(parsed)) {
@@ -60154,7 +60063,6 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
60154
60063
  const rebuilt = { ...parsed, messages: rebuiltMessages, system: systemOut, tools: toolsOut };
60155
60064
  warnAnthropicThinkingPairs(rebuiltMessages, log2, sessionId);
60156
60065
  delete rebuilt.prompt_cache_key;
60157
- armHostUsageCredit(session, originalMessages, processedMessages, req.headers, opts.hostUsageCredit, log2);
60158
60066
  return { body: JSON.stringify(rebuilt), session, processedMessages, originalMessages, anthropicSystem: parsed.system, protocol: "anthropic", stream: stream2, compressInjected: injectTools, pluginMode, nudge, prompts, renderTags: "text-only" };
60159
60067
  }
60160
60068
  var OUTPUT_CLAMP_MARGIN_PCT = 0.05;
@@ -60214,7 +60122,6 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
60214
60122
  const sessionId = session.id;
60215
60123
  const stream2 = parsed.stream === true;
60216
60124
  ++session.stats.requests;
60217
- session.hostCreditTokens = 0;
60218
60125
  let openaiSystemText = "";
60219
60126
  const stripReasoning = (msgs) => withReasoningDrop(msgs, reasoning, log2, sessionId, isStrictReasoningEcho(session, upstreamOrigin));
60220
60127
  let openaiOutboundSystem;
@@ -60287,7 +60194,6 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
60287
60194
  if (stream2 && rebuilt.stream_options === void 0) {
60288
60195
  rebuilt.stream_options = { include_usage: true };
60289
60196
  }
60290
- armHostUsageCredit(session, originalMessages, processedMessages, req.headers, opts.hostUsageCredit, log2);
60291
60197
  if (!isTitleGen && openaiOutboundSystem !== void 0) {
60292
60198
  session.metadata.systemPromptTokens = countSystemAndToolsTokens(openaiOutboundSystem, toolsOut);
60293
60199
  }
@@ -60299,7 +60205,6 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
60299
60205
  const sessionId = session.id;
60300
60206
  const stream2 = parsed.stream === true;
60301
60207
  ++session.stats.requests;
60302
- session.hostCreditTokens = 0;
60303
60208
  const stripReasoning = (msgs) => withReasoningDrop(msgs, reasoning, log2, sessionId, isStrictReasoningEcho(session, upstreamOrigin));
60304
60209
  if (reconcileNativeCompactionBoundary(session)) {
60305
60210
  log2("info", `[${sessionId}] reconciled ACP state after native Responses compact boundary`);
@@ -60440,7 +60345,6 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
60440
60345
  });
60441
60346
  log2("info", `[${sessionId}] responses forward tools=[${fwdTools.join(",")}] injectTool=${injectTools}${pluginMode ? " (plugin mode: wire injection suppressed)" : ""} NO_INJECT_TOOL=${!!process.env.ACP_NO_INJECT_TOOL} NO_COMPRESS_PROMPT=${!!process.env.ACP_NO_COMPRESS_PROMPT}`);
60442
60347
  }
60443
- armHostUsageCredit(session, originalMessages, processedMessages, req.headers, opts.hostUsageCredit, log2);
60444
60348
  if (transformOk) {
60445
60349
  session.metadata.systemPromptTokens = countSystemAndToolsTokens(responsesDevContent ?? "", toolsOut);
60446
60350
  }
@@ -61218,7 +61122,7 @@ ${hdrText}
61218
61122
 
61219
61123
  ${buildAbsorbSystemPrompt(absorbToolName(loopConfig))}` : "";
61220
61124
  const systemPrompt = (textProtocol ? buildCompressHybridSystemPrompt(prepared.prompts ?? defaultPrompts) : buildCompressSystemPrompt(prepared.prompts ?? defaultPrompts)) + absorbSection;
61221
- const adapter = pickAdapter(prepared.protocol, parsedReq, textProtocol, prepared.responsesProjection, prepared.anthropicSystem, prepared.openaiSystemText, prepared.session.hostCreditTokens ?? 0, absorbActive ? absorbToolName(loopConfig) : void 0);
61125
+ const adapter = pickAdapter(prepared.protocol, parsedReq, textProtocol, prepared.responsesProjection, prepared.anthropicSystem, prepared.openaiSystemText, absorbActive ? absorbToolName(loopConfig) : void 0);
61222
61126
  const refreshFolded = (current) => {
61223
61127
  const turn = core.processTurn({
61224
61128
  messages: prepared.originalMessages,
@@ -61301,10 +61205,6 @@ ${buildAbsorbSystemPrompt(absorbToolName(loopConfig))}` : "";
61301
61205
  const out = u2.completion_tokens ?? u2.output_tokens;
61302
61206
  if (typeof out === "number") prepared.session.stats.outputTokens += out;
61303
61207
  }
61304
- const credit = prepared.session.hostCreditTokens ?? 0;
61305
- if (credit > 0 && backfillHostUsage(prepared.protocol, u2, credit)) {
61306
- prepared.session.hostContextTokens = (typeof total === "number" ? total : 0) + credit;
61307
- }
61308
61208
  if (prepared.protocol === "openai") {
61309
61209
  rewriteOpenaiJsonResponse(json, ctx);
61310
61210
  } else if (prepared.protocol === "responses") {