You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is an issue here: when a context limit is selected, compression is performed successfully and consistently. However, if I set the limit to 70,000—aiming to keep the active context around 40,000—it usually works, but a problem arises when a task actually requires 80,000 tokens of context (e.g., for reading); the task fails because it keeps getting compressed halfway through. The system needs to handle compression autonomously when switching between different tasks—since everyone is running autonomous agents and we aren't working in environments where we have manual control, the compression process itself must operate autonomously to achieve maximum compression.
[bot] 🏷 Verified against the code and by running the real kernel decision logic (acp-kernel@0.0.82, pinned in this repo) against a synthetic ~78–80k-token history. Your diagnosis is right, and there's a concrete cause plus a workaround you can use today.
What's happening (root cause, not symptom)
compress.modelContextLimit currently plays two roles at once:
Denominator for the pressure bands — usage = tokens / this value, and the nudge/truncate/emergency thresholds are fractions of it (src/compress-settings.ts).
The hard wall for preflight compression — the proxy starts proactively folding your context before forwarding the moment the payload reaches this value (src/server.ts:3478), and if folding can't bring it under, the request fails with 502 and is never sent upstream.
So when you set it to 70k on a model whose native window is larger, any task that legitimately needs ~80k of context is in direct conflict with the wall. I reproduced the decision behavior:
Setup
80k payload
Result
modelContextLimit: 70000 (your config)
usage 114% → EMERGENCY, compress forced every single turn
preflight wall also crossed → old context folded mid-task or 502 fail-fast — exactly your "keeps getting compressed halfway through"
usage 40% → normal OVER-LIMIT nudge, fires every turn until back under 35%
payload forwarded as-is — nothing folded, no fail-fast; hard protection only engages near the true native edge
The second row is the key: the kernel's pressure branch force-injects the compress nudge every turn while usage is above the band (no cadence gaps), so context gets pinned near your target autonomously — while a genuinely large read is allowed to breathe up to the real window instead of being crushed.
This is the same mechanism documented in #736/#737 (operator-shrunk window → misleading fail-fast); the fix there was to name the shrunken window in the error. What you're asking for goes further: make the target and the wall independent.
Workaround available today (no code change)
Set the limit to the model's true native window and use maxContextLimit as your soft target:
(Numbers per your model — e.g. "35%" of 200k ≈ 70k active target; these keys are hot-reloadable via the web UI, and per-model overrides exist under routes.<url>.models.<name>.compress.)
Behavior you get:
Small tasks stay small — below the band, zero compression happens.
Growth above the band is trimmed back down automatically each turn.
A big read (your 80k case) is forwarded intact; compression only kicks in to keep things bounded, never to reject the request.
The 502 fail-fast path is reserved for the only case that truly can't be served: payload beyond the model's actual window.
If your soft target is under 45% of the native window, the kernel logs a cosmetic validation warning (minContextLimitPct defaults to 0.45); I verified the over-band nudge path still fires correctly in that configuration.
Optional follow-up (needs your call before I build)
A first-class soft-target knob that formally separates the two roles — e.g. exposing minContextLimitPct and making the preflight wall independently configurable from the nudge-band denominator — would remove the workaround's caveats and make "keep context around N tokens, but allow bursts up to the native window" a named, documented setting rather than a ratio trick. Say the word and I'll spec/implement it as its own PR referencing this issue.
It adds the one missing knob so the elastic recipe from my previous comment works without caveats:
compress.minContextLimit (number | string, e.g. 0.35 or "35%") → kernel nudge.minContextLimitPct. Unset = kernel default (0.45), so existing configs behave byte-identically; three-level cascade (global → provider → model) like every other compress field; hot-reloadable via the web UI.
Your full recipe becomes a documented, first-class setting (CONFIGURATION.md gains a "Soft target with elastic headroom" section, zh/en):
{ "compress": {
"modelContextLimit": 200000, // native window = hard wall only at the true edge"maxContextLimit": "35%", // soft target ≈ 70k — forced nudge every turn above it"minContextLimit": "35%", // required once under the kernel's 45% default"emergencyThresholdPercent": "95%" } }
Verified behaviorally against the real kernel decision code through bili's actual per-request config pipeline: with the knob set, an 80k payload on a 200k window (40%) triggers the every-turn nudge below the old 45% floor with no validation warning; a control test proves the warning exists without the knob. Also documented the two facts that matter for tuning: the pressure branch fires at maxContextLimit regardless of min, and modelContextLimit doubles as the hard preflight wall (fold-or-fail-fast) — which is exactly why it should stay at the native window for this pattern.
Pre-flight on the rebased head (master @ v0.1.135): typecheck clean, 2199 tests pass / 0 fail, build OK. Diff is 7 files, all in scope. Merge stays with you.
A system that performs compression autonomously when switching to completely different tasks—instead of relying on specified numbers or percentages—could have been more optimized.
[bot] 🏷 Good direction to think about — let me lay out how it would actually work, where it helps, and where I'd push back, so @ranxianglei can decide if it's worth tracking.
What "compress on task switch, no numbers" would require
To compress because a task ended (rather than because usage crossed a band), the proxy would need to detect task boundaries. Realistically three options:
Side-model segmentation — an extra LLM call classifies the history into task segments each turn. Cost + latency on every request, non-deterministic boundaries, and "is reading these 5 files part of the refactor or a separate task?" is genuinely ambiguous.
Heuristics (topic shift, disjoint file sets, new user prompt) — brittle: real agent work interleaves read/edit/test constantly; false positives would fold live context out from under an active task, which is worse than the status quo.
Agent-declared boundaries — the agent marks "task done" and asks for a checkpoint. Most reliable signal (the agent knows its own tasks), but it's no longer proxy-autonomous.
Why I'd keep the numeric trigger anyway
Thresholds aren't the problem — they're the stopping condition. A fully number-free compressor has no budget: compress until what? Usage bands give bounded cost, no mid-turn compression storms, and stable prefix caches. The interesting variable isn't when to compress; it's what to fold first. Today that policy is "oldest viable range" — a coarse approximation of "what's least useful now".
What already exists (often overlooked)
Plugin mode: the agent can call compress voluntarily, right now. An agent that summarizes at a natural task boundary (end of a sub-goal, before switching files) gets exactly "compress on task switch" with zero proxy changes — it's a prompting/convention matter, not a mechanism gap.
Tiered summaries already preserve the load-bearing facts (decisions, paths, signatures) of finished work, so a new task can decompress/search_context back into the old one instead of keeping it raw.
My recommendation
Don't replace usage-based triggering; make the selection structure-aware:
Kernel-side (real engineering, cross-repo): when picking ranges under pressure, prefer coherent segment boundaries (complete tool-call sequences / self-contained exchanges) over arbitrary oldest-N, so folds land at natural seams. Deterministic, testable, keeps the safe trigger.
Agent-side (free, available today): document the "checkpoint-compress at task boundaries" pattern for plugin-mode agents.
If you want option 1 tracked, say the word and I'll file a properly-scoped acp-kernel issue (with the #1122 source marker) — I'd rather not start that architectural work from an unreviewed suggestion.
不阻断、不 clamp、不改阈值——只是每个 processTurn 打一条 console.warn:[acp-kernel] Config validation warnings: nudge.minContextLimitPct must not exceed nudge.maxContextLimitPct. Thresholds may not fire correctly.
Activity
ranxianglei commentedon Sep 22, 2026
[bot] 🏷 Verified against the code and by running the real kernel decision logic (
acp-kernel@0.0.82, pinned in this repo) against a synthetic ~78–80k-token history. Your diagnosis is right, and there's a concrete cause plus a workaround you can use today.What's happening (root cause, not symptom)
compress.modelContextLimitcurrently plays two roles at once:src/compress-settings.ts).src/server.ts:3478), and if folding can't bring it under, the request fails with 502 and is never sent upstream.So when you set it to 70k on a model whose native window is larger, any task that legitimately needs ~80k of context is in direct conflict with the wall. I reproduced the decision behavior:
modelContextLimit: 70000(your config)modelContextLimit: 200000(native) +maxContextLimit: "35%"The second row is the key: the kernel's pressure branch force-injects the compress nudge every turn while usage is above the band (no cadence gaps), so context gets pinned near your target autonomously — while a genuinely large read is allowed to breathe up to the real window instead of being crushed.
This is the same mechanism documented in #736/#737 (operator-shrunk window → misleading fail-fast); the fix there was to name the shrunken window in the error. What you're asking for goes further: make the target and the wall independent.
Workaround available today (no code change)
Set the limit to the model's true native window and use
maxContextLimitas your soft target:{ "compress": { "modelContextLimit": 200000, "maxContextLimit": "35%", "emergencyThresholdPercent": "95%" } }(Numbers per your model — e.g.
"35%"of 200k ≈ 70k active target; these keys are hot-reloadable via the web UI, and per-model overrides exist underroutes.<url>.models.<name>.compress.)Behavior you get:
Two caveats, both verified:
maxContextLimitcomfortably belowemergencyThresholdPercent.minContextLimitPctdefaults to 0.45); I verified the over-band nudge path still fires correctly in that configuration.Optional follow-up (needs your call before I build)
A first-class soft-target knob that formally separates the two roles — e.g. exposing
minContextLimitPctand making the preflight wall independently configurable from the nudge-band denominator — would remove the workaround's caveats and make "keep context around N tokens, but allow bursts up to the native window" a named, documented setting rather than a ratio trick. Say the word and I'll spec/implement it as its own PR referencing this issue.walsykerem commentedon Sep 22, 2026
yes it's can be great.do pr!
ranxianglei commentedon Sep 22, 2026
[bot] 🏷 Done — PR is up: #1123
It adds the one missing knob so the elastic recipe from my previous comment works without caveats:
compress.minContextLimit(number | string, e.g.0.35or"35%") → kernelnudge.minContextLimitPct. Unset = kernel default (0.45), so existing configs behave byte-identically; three-level cascade (global → provider → model) like every other compress field; hot-reloadable via the web UI.CONFIGURATION.mdgains a "Soft target with elastic headroom" section, zh/en):{ "compress": { "modelContextLimit": 200000, // native window = hard wall only at the true edge "maxContextLimit": "35%", // soft target ≈ 70k — forced nudge every turn above it "minContextLimit": "35%", // required once under the kernel's 45% default "emergencyThresholdPercent": "95%" } }maxContextLimitregardless ofmin, andmodelContextLimitdoubles as the hard preflight wall (fold-or-fail-fast) — which is exactly why it should stay at the native window for this pattern.Pre-flight on the rebased head (master @ v0.1.135): typecheck clean, 2199 tests pass / 0 fail, build OK. Diff is 7 files, all in scope. Merge stays with you.
ranxianglei commentedon Sep 22, 2026
结束这个根本问题 优化思路 动机 如何实现
ranxianglei commentedon Sep 22, 2026
简述这个根本问题 优化思路 动机 如何实现
walsykerem commentedon Sep 22, 2026
A system that performs compression autonomously when switching to completely different tasks—instead of relying on specified numbers or percentages—could have been more optimized.
ranxianglei commentedon Sep 22, 2026
[bot] 🏷 简述如下(PR 已开好:#1123 ):
根本问题
compress.modelContextLimit一个旋钮同时扮演两个角色:usage = tokens / limit);把它设到模型原生窗口以下(如 200k 模型设 70k),两个角色就互相打架:任何合法需要 80k 上下文的任务,要么中途被反复折叠、要么直接被拒。#1122 报的失败模式正是这个。根因不是压缩太激进,而是配置模型把「软成本目标」和「硬溢出边界」混在了一个字段里。
动机
自主 agent 同时要两件事:日常活跃上下文保持小(成本/延迟),但单个任务在确实需要时(读大文件等)能突发远超目标。单旋钮表达不了这种弹性;而且用户不在线盯着,压缩必须自主完成——钉在目标附近靠自动 nudge,大读取放行靠抬高硬墙。
优化思路
把两个角色分开:
modelContextLimit回归本义 = 原生窗口,硬墙只在真实边缘生效;maxContextLimit当软目标——内核压力分支无节奏门控,越过即每轮强制 nudge,这正是把上下文钉在目标附近的机制;nudge.minContextLimitPct默认 0.45,软目标低于它时每轮刷 min>max 校验警告,而 bili 没暴露这个值 → 补一个minContextLimit字段。已验证压力分支不受 min 门控,低目标照常触发。如何实现(PR #1123,7 文件,+141 −7)
src/config.ts:新增可选minContextLimit?: number | string(比例或"NN%",解析规则与 maxContextLimit 一致);src/compress-settings.ts:三层级合并 pick + 映射到内核nudge.minContextLimitPct;不设 = 内核默认 0.45,存量配置逐字节不变;modelContextLimit硬墙双重角色说明、「软目标与弹性余量」配方章节;resolveRequestConfig→ 真实内核processTurn:200k 窗口 40% 使用率、低于旧 45% floor 每轮触发且无警告;对照测试证明不设该字段时警告存在);配方示例:
{ "compress": { "modelContextLimit": 200000, // = 原生窗口,硬墙只在真实边缘 "maxContextLimit": "35%", // 软目标 ≈ 70k,越过每轮强制 nudge "minContextLimit": "35%", // 低于内核默认 45% 时必须同步设置 "emergencyThresholdPercent": "95%" } }效果:低于档位零压缩;高于档位每轮 nudge 直到回落;其间的较大读取原样转发;只有超过真实原生窗口的载荷才撞硬墙。
ranxianglei commentedon Sep 22, 2026
[bot] 🏷 Good direction to think about — let me lay out how it would actually work, where it helps, and where I'd push back, so @ranxianglei can decide if it's worth tracking.
What "compress on task switch, no numbers" would require
To compress because a task ended (rather than because usage crossed a band), the proxy would need to detect task boundaries. Realistically three options:
Why I'd keep the numeric trigger anyway
Thresholds aren't the problem — they're the stopping condition. A fully number-free compressor has no budget: compress until what? Usage bands give bounded cost, no mid-turn compression storms, and stable prefix caches. The interesting variable isn't when to compress; it's what to fold first. Today that policy is "oldest viable range" — a coarse approximation of "what's least useful now".
What already exists (often overlooked)
compressvoluntarily, right now. An agent that summarizes at a natural task boundary (end of a sub-goal, before switching files) gets exactly "compress on task switch" with zero proxy changes — it's a prompting/convention matter, not a mechanism gap.decompress/search_contextback into the old one instead of keeping it raw.My recommendation
Don't replace usage-based triggering; make the selection structure-aware:
If you want option 1 tracked, say the word and I'll file a properly-scoped acp-kernel issue (with the #1122 source marker) — I'd rather not start that architectural work from an unreviewed suggestion.
ranxianglei commentedon Sep 22, 2026
麻烦这个功能提交到内核,然后billion-context-pi也提交同一个issue,内核合并后本pr跟进
ranxianglei commentedon Sep 22, 2026
[bot] 🏷 已按指示立项,两个 issue 都带来源标记(来源: #1122 分析 "auto compress problem" 时发现):
主 issue(内核):ranxianglei/acp-kernel#344
feat: structure-aware range selection(压力压缩优先选连贯任务段边界)内容要点:
recommendNode(buildCompressibleRanges → mergeRangesToThreshold),候选生成/排序只按位置与最小长度,无结构判断;镜像 issue(pi):ranxianglei/billion-context-pi#501
列出 pi 侧内核合并后的跟进清单:确认发布后精确 pin 升级、长多任务会话折叠边界验证、agent 侧决策路径评估、checkpoint-compress 约定文档。
后续流程(内核合并后本 PR 跟进):
npm view acp-kernel version确认新版本已在 npm;另说明:PR #1123(minContextLimit 软目标旋钮)与该功能相互独立,不依赖内核改动,现在就可以合并——如果你想先落这个,随时可以。
ranxianglei commentedon Sep 22, 2026
你不是说问题主要是增加了maxContextLimit配置吗?为啥反而向内核提交了feat: structure-aware range selection(压力压缩优先选连贯任务段边界)
ranxianglei commentedon Sep 22, 2026
[bot] 🏷 这里其实是两条独立的线,我分开讲清楚:
线 1 —— #1122 的原始 bug(已修完,PR #1123,与内核无关)
你最开始报的问题:limit 设 70k、但任务需要 80k 时被反复压缩/失败。根因是
modelContextLimit一个字段同时当「软目标分母」和「硬墙」。修复就是拆开它:modelContextLimit=原生窗口(硬墙)、maxContextLimit=软目标、新增minContextLimit消除告警。关键点:
maxContextLimit/minContextLimit这两个字段内核本来就有(nudge.maxContextLimitPct/nudge.minContextLimitPct),#1123 只是把它们从 billion-context 的配置层暴露出来。所以修 #1122 根本不需要向内核提任何东西,PR #1123 独立可合、测试全绿。线 2 —— 结构感知范围选择(acp-kernel#344),来自另一条评论
这是 @walsycommunity 后来单独提的新想法(不是原始 bug):"切换完全不同任务时自主压缩,而不是靠数字/百分比"。我评估后建议的工程路径就是「结构感知范围选择」,并问你要不要立项跟踪。接着你的指示是:「麻烦这个功能提交到内核,然后 billion-context-pi 也提交同一个issue,内核合并后本pr跟进」——所以我按你说的把结构感知立成了 acp-kernel#344 + pi#501。
两者不矛盾:
如果你现在不想推进结构感知这个方向,我可以把 #344/#501 关掉或降级,只保留 #1123 合入即可——你来定。
ranxianglei commentedon Sep 22, 2026
minContextLimit 不是应该从内核出吗?为什么内核无关 其他不是所有的配置都是内核出的吗 还是说这个配置是和agent相关的
https://github.com/ranxianglei/billion-context-pi增加这个参数了吗
ranxianglei commentedon Sep 22, 2026
[bot] 🏷 两个问题分开答,第二个先纠正一下我之前的措辞。
1. minContextLimit 到底该不该「从内核出」
我上次说「与内核无关」是措辞不准,准确说法是:内核早就有这个字段,#1123 只补了宿主侧的暴露,所以内核零改动。这里其实是两层:
Config对象里并被内核消费——nudge.maxContextLimitPct、nudge.minContextLimitPct(默认 0.45)、nudge.emergencyThresholdPct、truncate.threshold……你的直觉对:这些配置确实都归内核。minContextLimitPct内核里一直就有,还带校验(min>max 会告警)。maxContextLimit在 bili 里本来就有(→nudge.maxContextLimitPct);缺的只是minContextLimit这个宿主侧 key + 映射行。docs: correct compress soft-target guidance, drop minContextLimit knob #1123 加的就是这一层,不碰内核。所以它不是 agent 专属,也不是要新造的内核能力——只是同一个内核旋钮在 bili 的配置面上之前没露出来。这也是为什么它能独立于内核、直接合。
2. billion-context-pi 加了吗?
没有。 PR #1123 只改了 ranxianglei/billion-context。而且我刚核对了 pi 的代码,它有同样的缺口:
CompressSettings(src/config.ts)目前只暴露maxContextLimit/emergencyThresholdPercent/nudgeGrowthTokens/minPressureBenefitTokens;resolveConfig相应地映射到nudge.maxContextLimitPct等,但没有任何minContextLimit→nudge.minContextLimitPct。也就是说 pi 用户如果把软目标设到默认 45% 以下,会遇到和 #1122 一模一样的每轮校验告警,且无配置手段消除。
建议:值得把同样的
minContextLimit补进 pi(一个独立的小 PR,跨仓所以按规矩等你拍板)。要做的话我现在就开——你确认一声即可。ranxianglei commentedon Sep 22, 2026
[bot] 🏷 补充一条:pi 的这个缺口我已经立项跟踪了 → ranxianglei/billion-context-pi#502 (带来源标记,指向 bili#1122/#1123)。
目前只立了 issue、还没动 pi 的代码/PR——按你说的跨仓等你拍板。确认要做我就把
minContextLimit镜像进 pi(config key + 映射 + 文档 + 测试,独立小 PR)。15 remaining items
ranxianglei commentedon Sep 22, 2026
[bot] 🏷 你的记忆是对的,我上一条的公式错了,先纠正,再给理清楚后的完整关系(全部对着 acp-kernel@0.0.82 dist 实证)。
先认错:「首次压缩 ≈ min% × 窗口」是错的
我上条把
firstSightMassReady(L3278)当成了通用首压门槛。但它要求baseline===0——而baseline(lastPerMessageNudgeTokens)在第 1 轮结束后就被盖章为非零(nudgeNode L2864-2866),之后只有大幅收缩重置(L2859-2863,重置为当前值,仍非零)。所以那条路实际只在会话第 1 轮可达,不是日常路径。日常触发根本不走 min%。理清后的三层关系
第一层:绝对增长层(日常主力,与窗口无关) —— 就是你记得的「nudge 决定的」:
代入默认值:窗口 ≤400k → nudgeGrowth=20k、growthFloor=20k;窗口 ≥1M → 触顶 50k、growthFloor=22.5k。基准点 = 会话起点 / 上次 nudge 注入点 / 大收缩后。1M 窗口也是 5w 量级,200k 窗口也是 2w 量级——绝对值,被 50k 封顶,不随窗口放大。 你记得没错。
第二层:百分比压力层(随窗口缩放):usage ≥ max%(默认 75%)→ 每轮强制 nudge;≥95% → 紧急截断。这层才和窗口成正比。
第三层:百分比资格层(min%,边角料):只出现在两处——第 1 轮冷启动门票(L3278)、T2/T3 按块数升级的地板(L3282-3284)。不参与日常主路径。
回归判定
行动项
我上一条给的公式和文档里隐含的「onset≈min%×窗口」说法要撤掉,改成上面的三层模型。要我直接把 #1123 的 CONFIGURATION 章节按这个模型重写吗?
ranxianglei commentedon Sep 22, 2026
撤销min相关参数 只留下衍生的max吧 并确保没有回归问题
ranxianglei commentedon Sep 22, 2026
[bot] 🏷 收到,执行方案如下,先报一个刚验证完的关键事实:
关键验证:只留 max、设低于默认 45% 时会发生什么
对着 acp-kernel@0.0.82 dist 查了
validateConfig(L395-399)和唯一调用点(L2669-2674):processTurn打一条console.warn:[acp-kernel] Config validation warnings: nudge.minContextLimitPct must not exceed nudge.maxContextLimitPct. Thresholds may not fire correctly.执行清单
maxContextLimit的配方;开始动手,完成后回贴。
ranxianglei commentedon Sep 22, 2026
[bot] 🏷 已按你的决定执行完毕:min 相关代码全部撤销,只保留(已有的)max,PR 变成纯文档。
交付
modelContextLimit条目补上「硬墙」第二角色说明;modelContextLimit=原生窗口 + 现有maxContextLimit管日常目标(% = 目标 ÷ 窗口),并按修正后的三层模型写清触发机制(增长层绝对值 / 压力层 % / 资格层内核默认值)。min > max时每轮 processTurn 刷一条 validation warning(日志噪音;功能无影响——两层管独立代码路径,已逐行验证)。建议按错误集合变化去重。无回归证明
maxContextLimit < 45%(低于内核默认 min),功能也正确——pressure 区与 min 门控互不依赖,唯一代价是上面那条 warning 噪音(ZCode 会话消息丢失:接入 bili MITM 后,旧会话打开无消息、新会话切换后丢失 #346 处理)。一句话中文摘要:撤销了 minContextLimit 参数(只保留已有的 maxContextLimit),把修正后的压缩触发模型写成文档交付为新 PR #1147(纯文档零源码改动,测试全绿),可以合并。
ranxianglei commentedon Sep 22, 2026
这个本来就有??两个项目??
ranxianglei commentedon Sep 22, 2026
[bot] 🏷 对,两个项目本来就有,不是这次加的。git 证据:
billion-context(bili)
compress.maxContextLimit在 master 上:src/config.ts:114(maxContextLimit?: number | string),映射在src/compress-settings.ts:217→ 内核nudge.maxContextLimitPct;billion-context-pi
src/config.ts:146(注释写明 Default: 0.75, Maps to kernel nudge.maxContextLimitPct),三级合并在config.ts:499,测试覆盖在tests/config.test.ts:52-58。所以这次的工作只是:把「max 本来就能当软目标用」这件事写进文档(配方:
modelContextLimit=原生窗口 +maxContextLimit=目标÷窗口),之前那个minContextLimit新参数已按你的决定全部撤销。两项目现在都不需要任何代码改动即可用这套配方。ranxianglei commentedon Sep 22, 2026
pi版本的是否需要提交文档 如果需要你来提交
ranxianglei commentedon Sep 22, 2026
[bot] 🏷 需要,已提交:**https://github.com/ranxianglei/billion-context-pi/pull/509**(仅文档,2 个文件:CONFIGURATION.md / CONFIGURATION.zh-CN.md,+56/-2)
判断依据:pi 的 CONFIGURATION.md 虽然逐个记录了
compress.maxContextLimit、emergencyThresholdPercent、nudgeGrowthTokens和三级级联,但同样缺「软目标配方」——即modelContextLimit的分母角色说明 + 「分母保持真窗口、成本目标用 maxContextLimit 表达」的完整配方式和三层触发模型。不补的话,pi 用户会踩同一个坑。内容(与 bili PR #1147 同构,做了 pi 特化适配):
modelContextLimit条目补一句分母角色说明 + 指向新章节;maxContextLimit: "35%"≈ 70k/200k)、三层触发模型。pi 与 bili 的两处差异(已按 pi 实际情况写):
truncate.threshold←emergencyThresholdPercent),不存在 preflight 502;modelContextLimit可不填——默认每轮跟随 Pi 实时模型目录(bili 上该字段是硬墙所在,必须填真窗口);src/config.ts:553-555把内核growthFloor+growthCap都钉到用户的nudgeGrowthTokens(默认 50k),不像 bili 那样随窗口自适应——但同样是绝对 token、与分母无关,结论不变。Pre-flight:typecheck ✅ / build ✅ / tests 86 fail —— 已用 stash 对照验证:干净 master 基线是完全相同的 86 个环境性失败(本沙盒缺 pi host 相关环境),本 diff 零回归。
一句话中文摘要:给 pi 版补了与 bili #1147 同构的软目标配方文档(纯文档、零行为变更、预检绿),PR #509 待你合并。
ranxianglei commentedon Sep 22, 2026
[bot] 🏷 这条已经处理完了(上一条回复可能你没看到,简短确认):
**需要,已提交 → https://github.com/ranxianglei/billion-context-pi/pull/509**(刚核实:open、mergeable)
modelContextLimit分母角色说明,按 pi 实际特化(无硬墙/代理层、modelContextLimit可省略默认跟随 Pi 模型目录、增长步长 = 常数nudgeGrowthTokens);待你合并即可。
ranxianglei commentedon Sep 22, 2026
本 issue 除了配置还有其他问题吗?我记得已经单独提交 issue ?
ranxianglei commentedon Sep 22, 2026
[bot] 🏷 是的,除了配置本身,#1122 分析中发现了 2 个独立问题,都已单独立项(带来源标记),且实现已在途:
minContextLimitPct must not exceed maxContextLimitPct(功能无害,纯日志噪音)刚才顺手清理的两处遗留(自查发现,透明起见报告):
compress.minContextLimit)已关闭 —— 这一对是在你「撤销min相关参数」决定之前开的(时间戳 10:39Z,另一会话实现完毕),与最终决定矛盾。已各留一条说明后关闭;若你认为仍需要该旋钮,重开即可。billion-context#344——那个其实是一个无关的已关闭窗口优先级 bug;正确指向是acp-kernel#344。已补 commit 修正并推送(bili docs: correct compress soft-target guidance, drop minContextLimit knob #1147 @9d96177、pi feat: add pi-package keyword so pi.dev gallery indexes billion-context (clean, un-bundled) #509 @d22d21b)。一句话中文摘要:除配置外还有两个已单独立项的问题(内核告警刷屏 acp-kernel#346/#347、结构感知范围选择 acp-kernel#344/#345+pi#501),均已实现或修复在途;另关闭了与你撤销决定矛盾的过期 pi#502/#503,并修正了两个文档 PR 里的错误引用。
docs: rewrite soft-target recipe on corrected nudge model, drop minCo…