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 +10 -0
- package/README.zh-CN.md +10 -0
- package/dist/index.js +13 -113
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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
|
|
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:
|
|
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 =
|
|
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
|
|
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,
|
|
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,
|
|
55279
|
-
if (protocol === "anthropic") return createAnthropicAdapter(requestBody, anthropicSystem
|
|
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.
|
|
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.
|
|
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}%)`}
|
|
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 (
|
|
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,
|
|
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") {
|