billion-context 0.1.27 → 0.1.28
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 +1 -0
- package/README.zh-CN.md +1 -0
- package/dist/index.js +66 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -303,6 +303,7 @@ with no file at all).
|
|
|
303
303
|
| `ACP_SESSION_HEADER` | `x-acp-session` | Conversation-id header name |
|
|
304
304
|
| `ACP_COMPRESS_TOOL` | `1` | Set `0` to disable injecting the compress tool |
|
|
305
305
|
| `ACP_COMPRESS_NUDGE` | `1` | Set `0` to disable compression nudges |
|
|
306
|
+
| `ACP_REASONING_KEEP` | *(default)* | Responses API only: set `none` to drop all reasoning items. Default routes reasoning through the compression pipeline so it is hidden automatically once its turn is summarized (prevents the unbounded accumulation that broke Codex's prompt-cache prefix). |
|
|
306
307
|
| `ACP_DEBUG` | `0` | Set `1` for verbose logging |
|
|
307
308
|
| `ACP_PASSTHROUGH` | `0` | Set `1` to forward without compression |
|
|
308
309
|
| `ACP_AUTO_UPDATE` | `1` | Set `0` to disable background self-update |
|
package/README.zh-CN.md
CHANGED
|
@@ -253,6 +253,7 @@ bili --no-auto-update # 本次启动禁用自动更新
|
|
|
253
253
|
| `ACP_SESSION_HEADER` | `x-acp-session` | 会话标识 header 名 |
|
|
254
254
|
| `ACP_COMPRESS_TOOL` | `1` | 设 `0` 禁止注入 compress 工具 |
|
|
255
255
|
| `ACP_COMPRESS_NUDGE` | `1` | 设 `0` 禁止压缩 nudge |
|
|
256
|
+
| `ACP_REASONING_KEEP` | *(默认)* | 仅 Responses API:设 `none` 丢弃全部 reasoning。默认走压缩管线,turn 被压缩时自动隐藏(防止 reasoning 无限累积撑爆 Codex 的 prompt-cache 前缀)。 |
|
|
256
257
|
| `ACP_DEBUG` | `0` | 设 `1` 打开详细日志 |
|
|
257
258
|
| `ACP_PASSTHROUGH` | `0` | 设 `1` 不压缩直接转发 |
|
|
258
259
|
| `ACP_AUTO_UPDATE` | `1` | 设 `0` 禁用后台自动更新 |
|
package/dist/index.js
CHANGED
|
@@ -46647,7 +46647,6 @@ function firstImagePart(content) {
|
|
|
46647
46647
|
// src/responses.ts
|
|
46648
46648
|
var OPAQUE_ITEM_TYPES = /* @__PURE__ */ new Set([
|
|
46649
46649
|
"additional_tools",
|
|
46650
|
-
"reasoning",
|
|
46651
46650
|
"computer_call",
|
|
46652
46651
|
"computer_call_output",
|
|
46653
46652
|
"file_search_call",
|
|
@@ -46660,6 +46659,9 @@ var OPAQUE_ITEM_TYPES = /* @__PURE__ */ new Set([
|
|
|
46660
46659
|
function isOpaqueItem(it2) {
|
|
46661
46660
|
return OPAQUE_ITEM_TYPES.has(it2.type);
|
|
46662
46661
|
}
|
|
46662
|
+
function shouldDropAllReasoning() {
|
|
46663
|
+
return (process.env.ACP_REASONING_KEEP ?? "").trim().toLowerCase() === "none";
|
|
46664
|
+
}
|
|
46663
46665
|
function partText(p2) {
|
|
46664
46666
|
if (p2.type === "input_text" || p2.type === "output_text") {
|
|
46665
46667
|
const t = p2.text;
|
|
@@ -46691,6 +46693,7 @@ function responsesToCore(body) {
|
|
|
46691
46693
|
const systemParts = [];
|
|
46692
46694
|
const preamble = [];
|
|
46693
46695
|
const customToolCallIds = /* @__PURE__ */ new Set();
|
|
46696
|
+
let droppedReasoning = 0;
|
|
46694
46697
|
if (typeof body.instructions === "string" && body.instructions.trim()) {
|
|
46695
46698
|
systemParts.push(body.instructions);
|
|
46696
46699
|
}
|
|
@@ -46701,7 +46704,7 @@ function responsesToCore(body) {
|
|
|
46701
46704
|
const base = deriveMessageId("user", "text", body.input);
|
|
46702
46705
|
msgs.push({ id: clusters.next(base), role: "user", contentType: "text", text: body.input });
|
|
46703
46706
|
idx++;
|
|
46704
|
-
return { msgs, systemParts, preamble, customToolCallIds };
|
|
46707
|
+
return { msgs, systemParts, preamble, customToolCallIds, droppedReasoning };
|
|
46705
46708
|
}
|
|
46706
46709
|
for (const it2 of items) {
|
|
46707
46710
|
if (isOpaqueItem(it2)) {
|
|
@@ -46709,6 +46712,23 @@ function responsesToCore(body) {
|
|
|
46709
46712
|
continue;
|
|
46710
46713
|
}
|
|
46711
46714
|
switch (it2.type) {
|
|
46715
|
+
case "reasoning": {
|
|
46716
|
+
if (shouldDropAllReasoning()) {
|
|
46717
|
+
droppedReasoning++;
|
|
46718
|
+
break;
|
|
46719
|
+
}
|
|
46720
|
+
const rid = typeof it2.id === "string" ? String(it2.id) : hashId(JSON.stringify(it2));
|
|
46721
|
+
const base = deriveMessageId("assistant", "reasoning", rid);
|
|
46722
|
+
msgs.push({
|
|
46723
|
+
id: clusters.next(base),
|
|
46724
|
+
role: "assistant",
|
|
46725
|
+
contentType: "reasoning",
|
|
46726
|
+
text: rid,
|
|
46727
|
+
rawResponsesItem: it2
|
|
46728
|
+
});
|
|
46729
|
+
idx++;
|
|
46730
|
+
break;
|
|
46731
|
+
}
|
|
46712
46732
|
case "message": {
|
|
46713
46733
|
const m2 = it2;
|
|
46714
46734
|
const text = messageContent(m2.content);
|
|
@@ -46809,7 +46829,7 @@ function responsesToCore(body) {
|
|
|
46809
46829
|
break;
|
|
46810
46830
|
}
|
|
46811
46831
|
}
|
|
46812
|
-
return { msgs, systemParts, preamble, customToolCallIds };
|
|
46832
|
+
return { msgs, systemParts, preamble, customToolCallIds, droppedReasoning };
|
|
46813
46833
|
}
|
|
46814
46834
|
function coreToResponses(messages, customToolCallIds = /* @__PURE__ */ new Set()) {
|
|
46815
46835
|
const out = [];
|
|
@@ -46843,6 +46863,10 @@ function coreToResponses(messages, customToolCallIds = /* @__PURE__ */ new Set()
|
|
|
46843
46863
|
arguments: m2.text ?? ""
|
|
46844
46864
|
});
|
|
46845
46865
|
}
|
|
46866
|
+
} else if (m2.contentType === "reasoning") {
|
|
46867
|
+
if (m2.rawResponsesItem) {
|
|
46868
|
+
out.push(m2.rawResponsesItem);
|
|
46869
|
+
}
|
|
46846
46870
|
}
|
|
46847
46871
|
} else if (m2.role === "tool") {
|
|
46848
46872
|
const callId = m2.toolCallId ?? "";
|
|
@@ -49796,7 +49820,8 @@ async function handle(req, res, opts, core, config, log2) {
|
|
|
49796
49820
|
}
|
|
49797
49821
|
const url = req.url ?? "";
|
|
49798
49822
|
const urlPath = url.split("?", 2)[0];
|
|
49799
|
-
const
|
|
49823
|
+
const countTokens = isCountTokensRequest(req.method ?? "GET", urlPath, bodyBuffer.length > 0);
|
|
49824
|
+
const protocol = req.method === "POST" && bodyBuffer.length > 0 ? urlPath.endsWith("/chat/completions") ? "openai" : urlPath.endsWith("/v1/messages") || urlPath.endsWith("/messages") ? "anthropic" : urlPath.endsWith("/responses") ? "responses" : countTokens ? "anthropic" : null : null;
|
|
49800
49825
|
const route = resolveUpstream(opts, req.url ?? "", req);
|
|
49801
49826
|
const upstreamOrigin = route ? route.upstream : opts.upstream;
|
|
49802
49827
|
let parsed = null;
|
|
@@ -49839,7 +49864,7 @@ async function handle(req, res, opts, core, config, log2) {
|
|
|
49839
49864
|
const clientLabel = clientConversationHeader(req.headers);
|
|
49840
49865
|
const session = getSession(sessionId, { protocol, upstreamOrigin, label: clientLabel ?? void 0 });
|
|
49841
49866
|
await withSessionLock(session, async () => {
|
|
49842
|
-
prepared = protocol === "anthropic" ? prepareAnthropic(parsed, req, opts, core, reqConfig, log2, session) : protocol === "openai" ? prepareOpenai(parsed, req, opts, core, reqConfig, log2, session) : prepareResponses(parsed, req, opts, core, reqConfig, log2, session);
|
|
49867
|
+
prepared = countTokens ? prepareCountTokens(parsed, core, reqConfig, log2, session) : protocol === "anthropic" ? prepareAnthropic(parsed, req, opts, core, reqConfig, log2, session) : protocol === "openai" ? prepareOpenai(parsed, req, opts, core, reqConfig, log2, session) : prepareResponses(parsed, req, opts, core, reqConfig, log2, session);
|
|
49843
49868
|
acquireInFlight(session);
|
|
49844
49869
|
try {
|
|
49845
49870
|
await forward(req, res, opts, prepared.body, prepared, core, reqConfig, log2, route, affinity);
|
|
@@ -49880,6 +49905,42 @@ function diagNudge(turn, sessionId, tokenCount, limit) {
|
|
|
49880
49905
|
const inject = n.shouldInject ? `INJECT T${n.tier ?? "?"}` : "idle";
|
|
49881
49906
|
return `[${sessionId}] nudge ${inject}: usage=${pct2} (${tokenCount}/${limit}), growth=${growth}/${floor} (ref=${ref}, interval=${interval}), pendingT1=${pendingT1}/${interval}, reason="${n.reason.slice(0, 120)}"`;
|
|
49882
49907
|
}
|
|
49908
|
+
function isCountTokensRequest(method, urlPath, hasBody) {
|
|
49909
|
+
return method === "POST" && hasBody && process.env.ACP_COUNT_TOKENS_PASSTHROUGH !== "1" && urlPath.endsWith("/messages/count_tokens");
|
|
49910
|
+
}
|
|
49911
|
+
function prepareCountTokens(parsed, core, config, log2, session) {
|
|
49912
|
+
const sessionId = session.id;
|
|
49913
|
+
try {
|
|
49914
|
+
const { msgs, cacheControls } = anthropicToCore(parsed);
|
|
49915
|
+
const turn = core.processTurn({ messages: msgs, state: session.state, config, tokenCount: session.stats.lastInputTokens, renderTags: "text-only" });
|
|
49916
|
+
const rebuiltMessages = coreToAnthropic(turn.messages, cacheControls);
|
|
49917
|
+
log2("info", `[${sessionId}] count_tokens pruned: ${msgs.length} \u2192 ${turn.messages.length} msgs`);
|
|
49918
|
+
return {
|
|
49919
|
+
body: JSON.stringify({ ...parsed, messages: rebuiltMessages }),
|
|
49920
|
+
session,
|
|
49921
|
+
processedMessages: [],
|
|
49922
|
+
originalMessages: msgs,
|
|
49923
|
+
protocol: "anthropic",
|
|
49924
|
+
stream: false,
|
|
49925
|
+
// MUST stay false + empty processedMessages: keeps forward() on
|
|
49926
|
+
// plain-pipeThrough so usage-capture/markDirty stays unreachable
|
|
49927
|
+
// (else it poisons lastInputTokens with the compressed count and
|
|
49928
|
+
// suppresses the proxy's own nudges).
|
|
49929
|
+
compressInjected: false
|
|
49930
|
+
};
|
|
49931
|
+
} catch (err) {
|
|
49932
|
+
log2("warn", `[${sessionId}] count_tokens prune failed, forwarding unchanged: ${String(err)}`);
|
|
49933
|
+
return {
|
|
49934
|
+
body: JSON.stringify(parsed),
|
|
49935
|
+
session,
|
|
49936
|
+
processedMessages: [],
|
|
49937
|
+
originalMessages: [],
|
|
49938
|
+
protocol: "anthropic",
|
|
49939
|
+
stream: false,
|
|
49940
|
+
compressInjected: false
|
|
49941
|
+
};
|
|
49942
|
+
}
|
|
49943
|
+
}
|
|
49883
49944
|
function prepareAnthropic(parsed, req, opts, core, config, log2, session) {
|
|
49884
49945
|
const sessionId = session.id;
|
|
49885
49946
|
const stream2 = parsed.stream === true;
|