billion-context-pi 0.1.76-pr.512.330 → 0.1.76

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
@@ -253,11 +253,12 @@ The model receives detailed guidance (in its system prompt) on **when** to compr
253
253
 
254
254
  ### What gets protected
255
255
 
256
- billion-context protects three categories of content from compression:
256
+ billion-context protects four categories of content from compression:
257
257
 
258
258
  1. **Always-protected tools** — `compress` calls are hard-protected (they're load-bearing metadata; compressing them breaks decompress and the "summary is historical" contract).
259
259
  2. **Soft recent-zone** — the last N messages (default 5) and last ~5K tokens are soft-protected so the model keeps its working set. Tool results from `decompress`, `search_context`, `read`, and `bash` are **excluded** from this zone: they're large and meant to be compressible once consumed, so they don't eat the protected budget.
260
260
  3. **Last user message** — always protected (user intent must survive).
261
+ 4. **User-configured tool protection** — `protectedTools` / `protectedLatestTools` in `acp.json` hard-exclude matched tool calls+results (full history vs. latest-only; see [CONFIGURATION.md](./CONFIGURATION.md)).
261
262
 
262
263
  ## Session storage & migration
263
264
 
package/README.zh-CN.md CHANGED
@@ -242,11 +242,12 @@ grep '\[error\]' ~/.pi/acp.log # 汇总所有记录的失败
242
242
 
243
243
  ### 哪些内容会被保护
244
244
 
245
- billion-context 保护三类内容不被压缩:
245
+ billion-context 保护四类内容不被压缩:
246
246
 
247
247
  1. **永久保护的工具** — `compress` 调用被硬保护(它们是承载关键元数据的;压缩它们会破坏 decompress 和"摘要是历史"的契约)。
248
248
  2. **软近期区** — 最后 N 条消息(默认 5)和最后约 5K token 被软保护,让模型保留工作集。来自 `decompress`、`search_context`、`read`、`bash` 的工具结果被**排除**出此区:它们体量大、消费后就该能压缩,所以不该占用保护预算。
249
249
  3. **最后一条用户消息** — 始终保护(用户意图必须存活)。
250
+ 4. **用户配置的工具保护** — `acp.json` 中的 `protectedTools` / `protectedLatestTools` 硬排除匹配的工具 call+result(全历史 vs 仅最近一次;见 [CONFIGURATION.zh-CN.md](./CONFIGURATION.zh-CN.md))。
250
251
 
251
252
  ## 会话存储与迁移
252
253
 
package/dist/config.d.ts CHANGED
@@ -216,7 +216,18 @@ export interface AdapterConfig {
216
216
  /** When omitted, the adapter reads `ctx.model.contextWindow` live each turn.
217
217
  * Set explicitly for tests/headless runs. */
218
218
  modelContextLimit?: number;
219
+ /** Tool-name patterns (glob suffix allowed) whose EVERY call+result pair is
220
+ * hard-excluded from compression — matching refs render as BLOCKED in every
221
+ * view. Default: none. Intended for low-frequency high-value tools whose
222
+ * outputs are independent content (e.g. skill loads); do NOT use for chatty
223
+ * tools — protecting every instance grows context unboundedly (#639
224
+ * rationale). Settable via acp.json since #499. */
219
225
  protectedTools?: string[];
226
+ /** Tool-name patterns (glob suffix allowed) whose LATEST call+result pair is
227
+ * hard-excluded from compression; older pairs remain compressible. Default:
228
+ * none. Intended for cumulative-snapshot tools where each call supersedes
229
+ * the last. Settable via acp.json since #499. */
230
+ protectedLatestTools?: string[];
220
231
  preserveRecentMessages?: number;
221
232
  /** Check npm for a newer billion-context-pi on startup and auto-install it. Default: true.
222
233
  * Disable via `autoUpdate: false` or env `ACP_AUTO_UPDATE=0` to avoid all
package/dist/index.js CHANGED
@@ -170,6 +170,8 @@ var KNOWN = /* @__PURE__ */ new Set([
170
170
  "debug",
171
171
  "autoUpdate",
172
172
  "modelContextLimit",
173
+ "protectedTools",
174
+ "protectedLatestTools",
173
175
  "toolBashDefaultTimeout",
174
176
  "toolOutputMaxBytes",
175
177
  "delegate",
@@ -195,13 +197,27 @@ function pickKnown(parsed) {
195
197
  return out;
196
198
  }
197
199
  function applyUserConfig(adapter, user) {
198
- return {
200
+ const result = {
199
201
  ...adapter,
200
202
  ...user,
201
203
  coreOverrides: adapter.coreOverrides,
202
- protectedTools: adapter.protectedTools,
203
204
  preserveRecentMessages: adapter.preserveRecentMessages
204
205
  };
206
+ for (const key of ["protectedTools", "protectedLatestTools"]) {
207
+ if (!(key in user)) continue;
208
+ const cleaned = cleanProtectionList(key, user[key]);
209
+ if (cleaned !== void 0) result[key] = cleaned;
210
+ else if (adapter[key] !== void 0) result[key] = adapter[key];
211
+ else delete result[key];
212
+ }
213
+ return result;
214
+ }
215
+ function cleanProtectionList(key, value) {
216
+ if (!Array.isArray(value) || value.length === 0 || !value.every((v2) => typeof v2 === "string" && v2.trim() !== "")) {
217
+ console.warn(`[bcp] acp.json "${key}" must be a non-empty array of non-empty strings \u2014 ignoring the value`);
218
+ return void 0;
219
+ }
220
+ return value.map((v2) => v2.trim());
205
221
  }
206
222
 
207
223
  // src/index.ts
@@ -5680,6 +5696,7 @@ function resolveConfig(adapter, liveContextLimit, provider, modelId) {
5680
5696
  const limit = !Number.isNaN(envLimitNum) && envLimitNum > 0 ? envLimitNum : adapter.modelContextLimit && adapter.modelContextLimit > 0 ? adapter.modelContextLimit : liveContextLimit > 0 ? liveContextLimit : FALLBACK_LIMIT;
5681
5697
  const config = defaultConfig(limit, {
5682
5698
  protectedTools: adapter.protectedTools ?? [],
5699
+ protectedLatestTools: adapter.protectedLatestTools ?? [],
5683
5700
  preserveRecentMessages: adapter.preserveRecentMessages ?? 5,
5684
5701
  ...adapter.coreOverrides
5685
5702
  });