billion-context-pi 0.1.68 → 0.1.69-pr.428.229

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
@@ -10,6 +10,16 @@ The model decides <em>when</em> and <em>what</em> to compress — not a hard lim
10
10
 
11
11
  ---
12
12
 
13
+ ## 📄 Paper / Preprint
14
+
15
+ - **[Model-Driven Incremental Hierarchical Compression: Training-Free Multi-Generational Context Management for Long-Lived Coding Agents](./paper/model-driven-incremental-hierarchical-compression-training-free-multi-generational-context-management-for-long-lived-coding-agents.md)** (English, v0.2)
16
+
17
+ > 📝 **The paper itself is open-sourced under the MIT License as part of the codebase (`paper/`). It is a living document — anyone may edit it; improvements are welcome via pull request.**
18
+
19
+ A production-scale longitudinal study: 4.5 months, three hosts, 174,327 model calls, 18.76B cumulative input tokens (~24.7B across all hosts), zero window violations on 204,800-token models, marathon sessions of 8,584–12,049 calls.
20
+
21
+ ---
22
+
13
23
  <p align="center">
14
24
  <a href="https://www.npmjs.com/package/billion-context-pi"><img src="https://img.shields.io/npm/v/billion-context-pi.svg?style=flat-square" alt="npm"></a>
15
25
  <a href="https://github.com/ranxianglei/billion-context-pi/blob/master/LICENSE"><img src="https://img.shields.io/npm/l/billion-context-pi.svg?style=flat-square" alt="license"></a>
@@ -66,10 +76,9 @@ pi install npm:billion-context-pi
66
76
 
67
77
  That's it. The extension auto-loads on next Pi startup. No configuration needed — it reads your model's context window automatically.
68
78
 
69
- > **Uninstall `pi-subagents` first (optional, recommended).** billion-context-pi ships its own `acp_delegate` sub-agent tool (see below) that replaces pi-subagents at a fraction of the context cost (~600 tok vs ~7K tok/turn). If you have pi-subagents installed, remove it to avoid duplicate delegation tools:
70
- > ```bash
71
- > pi remove npm:pi-subagents
72
- > ```
79
+ > **Using another sub-agent extension?** billion-context-pi ships its own `acp_delegate` sub-agent tool (see below) at a fraction of the context cost (~600 tok vs ~7K tok/turn). Two delegation tools in one session only make the model's choice noisier, so pick one:
80
+ > - **Use ACP's delegate** — remove the other extension: `pi remove npm:pi-subagents`
81
+ > - **Keep your own sub-agent** — turn ACP's delegate off in `acp.json`: `{ "delegate": false }` (see *Using your own sub-agent instead* below)
73
82
 
74
83
  ## How it works
75
84
 
@@ -123,6 +132,8 @@ billion-context-pi is built for the **Pi** coding agent (`@earendil-works/pi-cod
123
132
  | `acp_delegate_wait` | Block until a delegate run finishes (returns its result; times out otherwise) |
124
133
  | `acp_delegate_cancel` | Cancel a running delegate by runId |
125
134
 
135
+ The four `acp_delegate*` tools are optional: if you bring your own sub-agent extension, disable them with one `acp.json` key — see *Using your own sub-agent instead* below.
136
+
126
137
  ### acp_delegate — clean-context delegation
127
138
 
128
139
  Hand a self-contained task to a fresh pi process running in a clean context. Five built-in roles, each with a system prompt and a **soft tool guardrail**:
@@ -147,6 +158,20 @@ The full delegate result is saved to a file (`/tmp/acp-delegate/<runId>.out`); t
147
158
 
148
159
  In the **interactive TUI**, async runs also show a live status widget below the editor (agent, elapsed seconds, task preview), so you always know what's running and for how long. Disabled automatically in RPC/print/JSON.
149
160
 
161
+ #### Using your own sub-agent instead
162
+
163
+ If you already run another sub-agent extension (pi-subagents, pi-lens, …), turn ACP's delegate off so the model is offered only one way to delegate. In `~/.pi/acp.json` (global) or `<project>/.pi/acp.json` (per project):
164
+
165
+ ```json
166
+ { "delegate": false }
167
+ ```
168
+
169
+ - Equivalent object form: `{ "delegate": { "enabled": false } }`.
170
+ - **What it removes:** the `acp_delegate`, `acp_delegate_wait` and `acp_delegate_cancel` tools, the `ACP_DELEGATE NOTIFICATIONS` system-prompt section, and the `ctrl+alt+f` fleet shortcut (`/acp-fleet` then reports that delegate is off). Compression is unaffected — `compress`, `decompress`, `search_context` and `acp_status` stay.
171
+ - **When it applies:** the three tools are registered at session start, so a change needs a **new session** (or a Pi restart). The system-prompt section is resolved live on every turn, so it can disappear mid-session before the tools do.
172
+ - Want to drop only the prompt section and keep the tools? Set `{ "delegatePrompt": null }`.
173
+ - Pi's `--exclude-tools acp_delegate,acp_delegate_wait,acp_delegate_cancel` is **not** a substitute: it hides the tools but the model still receives the `ACP_DELEGATE NOTIFICATIONS` section describing tools it cannot call. Use `delegate: false`.
174
+
150
175
  ## `/acp` command
151
176
 
152
177
  Rich status display for the user:
package/README.zh-CN.md CHANGED
@@ -8,6 +8,16 @@
8
8
 
9
9
  ---
10
10
 
11
+ ## 📄 论文 / 预印本
12
+
13
+ - **[模型驱动的分层增量压缩:面向长寿命编码 Agent 的免训练多代上下文管理](./paper/模型驱动的分层增量压缩-免训练多代上下文管理.md)**(中文版,v0.2)
14
+
15
+ > 📝 **论文本身与代码一同以 MIT 许可开源(位于 `paper/` 目录),是代码库的一部分 —— 这是一份活文档,任何人都可以编辑,欢迎提 PR 改进。**
16
+
17
+ 生产规模纵向研究:四个半月、三宿主、174,327 次模型调用、187.6 亿累计输入 token(三宿主合计约 247 亿),204,800-token 窗口零违规,马拉松会话 8,584–12,049 次调用。
18
+
19
+ ---
20
+
11
21
  <p align="center">
12
22
  <a href="https://www.npmjs.com/package/billion-context-pi"><img src="https://img.shields.io/npm/v/billion-context-pi.svg?style=flat-square" alt="npm"></a>
13
23
  <a href="https://github.com/ranxianglei/billion-context-pi/blob/master/LICENSE"><img src="https://img.shields.io/npm/l/billion-context-pi.svg?style=flat-square" alt="license"></a>
@@ -65,10 +75,9 @@ pi install npm:billion-context-pi
65
75
 
66
76
  完成。扩展在下次 Pi 启动时自动加载。无需配置 —— 它会自动读取模型的上下文窗口。
67
77
 
68
- > **建议先卸载 `pi-subagents`(可选,推荐)。** billion-context-pi 自带 `acp_delegate` 子代理工具(见下文),以极低的上下文成本(~600 tok vs ~7K tok/轮)替代 pi-subagents。如果你已安装 pi-subagents,卸载它以避免重复的委派工具:
69
- > ```bash
70
- > pi remove npm:pi-subagents
71
- > ```
78
+ > **你另有子代理扩展?** billion-context-pi 自带 `acp_delegate` 子代理工具(见下文),上下文成本极低(~600 tok vs ~7K tok/轮)。同一会话里两套委派工具只会让模型的选择更混乱,二选一:
79
+ > - **用 ACP 的 delegate** —— 卸载另一个扩展:`pi remove npm:pi-subagents`
80
+ > - **保留你自己的子代理** —— 在 `acp.json` 里关掉 ACP 的 delegate:`{ "delegate": false }`(见下文*改用你自己的子代理*)
72
81
 
73
82
  ## 工作原理
74
83
 
@@ -122,6 +131,8 @@ billion-context-pi 面向 **Pi** 编码代理(`@earendil-works/pi-coding-agent`)
122
131
  | `acp_delegate_wait` | 阻塞等待委派任务完成(返回结果,否则超时) |
123
132
  | `acp_delegate_cancel` | 按 runId 取消正在运行的委派任务 |
124
133
 
134
+ `acp_delegate*` 四个工具是可选的:如果你自带子代理扩展,一个 `acp.json` 键即可关闭 —— 见下文*改用你自己的子代理*。
135
+
125
136
  ### acp_delegate — 干净上下文委派
126
137
 
127
138
  把一个自包含的任务交给一个运行在干净上下文中的新 pi 进程。五个内置角色,各自有系统提示和**软工具护栏**:
@@ -145,6 +156,20 @@ Worker 运行在 Pi 的完整默认工具集上 - 不应用 `--tools` 白名单,
145
156
 
146
157
  在**交互 TUI** 中,异步运行还会在编辑器下方显示一个实时状态 widget(角色、已运行秒数、任务预览),让你随时知道什么在跑、跑了多久。RPC/print/JSON 模式自动禁用。
147
158
 
159
+ #### 改用你自己的子代理
160
+
161
+ 如果你已经在用别的子代理扩展(pi-subagents、pi-lens 等),关掉 ACP 的 delegate,让模型只有一条委派路径。在 `~/.pi/acp.json`(全局)或 `<项目>/.pi/acp.json`(项目级):
162
+
163
+ ```json
164
+ { "delegate": false }
165
+ ```
166
+
167
+ - 等价对象写法:`{ "delegate": { "enabled": false } }`。
168
+ - **关掉的是什么:**`acp_delegate`、`acp_delegate_wait`、`acp_delegate_cancel` 三个工具,`ACP_DELEGATE NOTIFICATIONS` 系统提示段,以及 `ctrl+alt+f` 快捷键(此时 `/acp-fleet` 会提示 delegate 未启用)。压缩本身不受影响 —— `compress`、`decompress`、`search_context`、`acp_status` 全部保留。
169
+ - **生效时机:**三个工具在会话启动时注册,因此需要**新会话**(或重启 Pi)。系统提示段每回合实时解析,可能在工具之前先消失。
170
+ - 只想去掉提示段、保留工具?设 `{ "delegatePrompt": null }`。
171
+ - Pi 原生的 `--exclude-tools acp_delegate,acp_delegate_wait,acp_delegate_cancel` **不能**替代:它藏起工具,但模型仍会收到描述这些工具的 `ACP_DELEGATE NOTIFICATIONS` 段。请用 `delegate: false`。
172
+
148
173
  ## `/acp` 命令
149
174
 
150
175
  为用户提供丰富的状态显示:
@@ -1,6 +1,7 @@
1
1
  import { Type, type Static } from "typebox";
2
2
  import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
3
3
  import type { AcpRuntime } from "./runtime.js";
4
+ import { type ToolPromptOverrides } from "./surface.js";
4
5
  import { type CompressionBlock, type CompressionState } from "acp-kernel";
5
6
  declare const RangeSpec: Type.TObject<{
6
7
  startId: Type.TString;
@@ -19,7 +20,7 @@ declare const CompressParams: Type.TObject<{
19
20
  summaryMaxChars: Type.TOptional<Type.TNumber>;
20
21
  }>;
21
22
  type CompressArgs = Static<typeof CompressParams>;
22
- export declare function makeCompressTool(runtime: AcpRuntime): ToolDefinition<typeof CompressParams>;
23
+ export declare function makeCompressTool(runtime: AcpRuntime, overrides?: ToolPromptOverrides): ToolDefinition<typeof CompressParams>;
23
24
  type RangeEntry = Static<typeof RangeSpec>;
24
25
  export declare function normalizeRanges(args: CompressArgs): RangeEntry[] | string;
25
26
  export declare function tailRepair(s: string): string | undefined;
package/dist/config.d.ts CHANGED
@@ -2,6 +2,12 @@ import { type Config, type Prompts } from "acp-kernel";
2
2
  import type { CompressReasoningConfig } from "./reasoning-drop.js";
3
3
  import type { DegenerationGuardConfig } from "./degeneration.js";
4
4
  import type { ThrottleRetryConfig } from "./throttle-retry.js";
5
+ import type { PiPromptSections } from "./system-prompt.js";
6
+ import type { NudgeSectionsConfig, ToolPromptsConfig } from "./surface.js";
7
+ /** Default TUI shortcut for the acp_delegate fleet inspector. Moved off
8
+ * "ctrl+alt+f" (also claimed by pi-subagents) to avoid a cross-extension
9
+ * conflict Pi's loader only warns about — last-loaded silently wins (#412). */
10
+ export declare const DEFAULT_FLEET_SHORTCUT = "ctrl+alt+d";
5
11
  /** Per-role delegate defaults. Lets long-lived automation pin a cheaper or
6
12
  * more capable model and a thinking level per delegate role, so the main
7
13
  * agent doesn't have to fill them in on every `acp_delegate()` call. */
@@ -70,6 +76,13 @@ export interface DelegateConfig {
70
76
  * saw the result, so re-injecting it would only waste context.
71
77
  * "always" — always inject the notification (previous behavior). */
72
78
  notifyIfRead?: "skip" | "always";
79
+ /** Keybinding for the interactive TUI shortcut that opens the acp_delegate
80
+ * fleet inspector (live list + transcript). Default: "ctrl+alt+d". Set to
81
+ * "" (empty string) to disable keyboard registration entirely — the
82
+ * inspector stays reachable via /acp-fleet. Moved off the previous hardcoded
83
+ * "ctrl+alt+f" because pi-subagents also claims ctrl+alt+f, and Pi's loader
84
+ * only warns + last-loaded-wins on cross-extension conflicts (#412). */
85
+ fleetShortcut?: string;
73
86
  }
74
87
  /** Resolved delegate policy: what actually takes effect after merging acp.json,
75
88
  * env overrides and defaults. Timeout fields are milliseconds; null means the
@@ -90,6 +103,8 @@ export interface DelegatePolicy {
90
103
  /** Whether to suppress the completion notification when the model already
91
104
  * read the result file after the run finished. Always resolved ("skip" default). */
92
105
  notifyIfRead: "skip" | "always";
106
+ /** Resolved TUI shortcut for the fleet inspector ("" = registration disabled). */
107
+ fleetShortcut: string;
93
108
  }
94
109
  export declare const DEFAULT_DELEGATE_POLICY: DelegatePolicy;
95
110
  /** Compression tuning fields, shared by all three levels (global, provider,
@@ -120,6 +135,13 @@ export interface CompressSettings {
120
135
  * tool calls — see CompressReasoningConfig in src/reasoning-drop.ts.
121
136
  * Merged field-wise (drop, threshold) across the three levels. */
122
137
  reasoning?: CompressReasoningConfig;
138
+ /** Active prompt pack name (see CONFIGURATION.md “Prompt packs”). Base
139
+ * level; override per provider/model via `providers`. "default" or unset =
140
+ * built-in defaults. Resolved per request against the live model, so
141
+ * switching models mid-session switches the pack. Packs ship text-level
142
+ * overrides only; a pack's `toolPrompts` follow the base selection (tool
143
+ * definitions freeze at extension load, before the model is known). */
144
+ promptPack?: string;
123
145
  }
124
146
  /** Per-provider compression overrides. Carries the same tuning fields as the
125
147
  * global level, plus an optional per-model map keyed by model id. */
@@ -193,13 +215,13 @@ export interface AdapterConfig {
193
215
  * unbounded behavior). */
194
216
  toolBashDefaultTimeout?: number;
195
217
  /** Hard byte cap applied to tool result text via the `tool_result` hook.
196
- * Default: 200000 (~200KB, roughly 5000 lines at ~40 bytes/line) — a
197
- * generous ceiling that stops runaway output. Pi already caps bash/read/grep
198
- * at 50KB/2000 lines (bash full output is saved to a temp file), so this
199
- * default mainly caps tools Pi doesn't cap. Set lower (e.g. 8192) for a
200
- * tighter context budget, or 0 to disable. When capped, oversized text is
201
- * head-truncated with a notice telling the model how to see the full output
202
- * (bash: read BashToolDetails.fullOutputPath). */
218
+ * Default: 50000 (~50KB) — aligned with Pi's own bash/read/grep cap so
219
+ * every tool path lands under one ceiling; the net still catches runaway
220
+ * output from tools Pi does not cap (MCP/custom). Set higher for large
221
+ * MCP outputs, lower (e.g. 8192) for a tighter context budget, or 0 to
222
+ * disable. When capped, oversized text is head-truncated with a notice
223
+ * telling the model how to see the full output (bash: read
224
+ * BashToolDetails.fullOutputPath). */
203
225
  toolOutputMaxBytes?: number;
204
226
  /** Delegate sub-agent config. Accepts a boolean shorthand (`true` →
205
227
  * `{ enabled: true }`, `false` → `{ enabled: false }`) or a DelegateConfig
@@ -252,10 +274,25 @@ export interface AdapterConfig {
252
274
  * replacing the kernel's tuned compression rules may reduce summary quality
253
275
  * (lost paths/signatures/decisions → worse retrieval). */
254
276
  acknowledgePromptsRisk?: boolean;
277
+ /** Override structural sections of the ACP system prompt (ACP TAGS, TOOLS,
278
+ * WHEN TO COMPRESS, ...). Tri-state per section: string = replace, null =
279
+ * remove, omitted = default. Not risk-gated — these are documentation
280
+ * sections, not compression rules. Set via acp.json. */
281
+ promptSections?: Partial<PiPromptSections>;
282
+ /** Override guidance-class nudge texts (efficiencyNote, emergencyHeader,
283
+ * t2Guidance, t3Guidance). Same tri-state semantics. Not risk-gated. */
284
+ nudgeSections?: NudgeSectionsConfig;
285
+ /** Override the four ACP tool definitions' LLM-facing text (description,
286
+ * paramDescriptions, promptSnippet, promptGuidelines). Read synchronously
287
+ * at extension load — tool defs are frozen at registration time. */
288
+ toolPrompts?: ToolPromptsConfig;
289
+ /** Replace (string) or remove (null) the ACP_DELEGATE_NOTIFICATIONS appendix
290
+ * injected when the delegate tool is enabled. */
291
+ delegatePrompt?: string | null;
255
292
  coreOverrides?: Partial<Config>;
256
293
  }
257
294
  export declare const DEFAULT_TOOL_BASH_TIMEOUT = 60;
258
- export declare const DEFAULT_TOOL_OUTPUT_MAX_BYTES = 200000;
295
+ export declare const DEFAULT_TOOL_OUTPUT_MAX_BYTES = 50000;
259
296
  /** Resolve delegate config from the adapter, handling the boolean shorthand
260
297
  * and the legacy flat `displayUsage` alias. Precedence: env > acp.json >
261
298
  * default (same convention as ACP_MODEL_CONTEXT_LIMIT). Invalid values fall
@@ -1,11 +1,12 @@
1
1
  import { Type } from "typebox";
2
2
  import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
3
3
  import type { AcpRuntime } from "./runtime.js";
4
+ import { type ToolPromptOverrides } from "./surface.js";
4
5
  declare const DecompressParams: Type.TObject<{
5
6
  blockId: Type.TString;
6
7
  full: Type.TOptional<Type.TBoolean>;
7
8
  toFile: Type.TOptional<Type.TString>;
8
9
  inline: Type.TOptional<Type.TBoolean>;
9
10
  }>;
10
- export declare function makeDecompressTool(runtime: AcpRuntime): ToolDefinition<typeof DecompressParams>;
11
+ export declare function makeDecompressTool(runtime: AcpRuntime, overrides?: ToolPromptOverrides): ToolDefinition<typeof DecompressParams>;
11
12
  export {};
@@ -6,8 +6,9 @@ interface WidgetRun {
6
6
  startedAt: number;
7
7
  }
8
8
  type RunsSnapshot = () => WidgetRun[];
9
+ export declare function formatShortcutLabel(shortcut: string): string;
9
10
  export declare const delegateStatusWidget: {
10
- setContext(ctx: ExtensionContext, snapshot: RunsSnapshot): void;
11
+ setContext(ctx: ExtensionContext, snapshot: RunsSnapshot, shortcut?: string): void;
11
12
  dispose(): void;
12
13
  poke(): void;
13
14
  };