billion-context-pi 0.1.67 → 0.1.68-pr.208.191

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
@@ -24,6 +24,12 @@ The model decides <em>when</em> and <em>what</em> to compress — not a hard lim
24
24
 
25
25
  > **Host support:** this plugin is for **Pi**. It does **not** support **OMP (oh-my-pi)** — on an OMP host it refuses to run. OMP users: use [billion-context](https://github.com/ranxianglei/billion-context) instead (`bili omp`, built-in plugin). Full client → package table: see [Which do I need?](#which-do-i-need); OMP details: [docs/omp.md](./docs/omp.md).
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
  When conversations get long, the model runs out of context. Most tools hard-truncate — silently dropping earlier messages. **billion-context** gives the model a `compress` tool: the LLM decides **when** and **what** to compress into high-fidelity summaries, preserving critical details (file paths, decisions, error strings) while reclaiming context space.
package/README.zh-CN.md CHANGED
@@ -22,6 +22,12 @@
22
22
 
23
23
  > **宿主支持:** 本插件面向 **Pi**。它**不支持 OMP(oh-my-pi)** —— 在 OMP 宿主上会拒绝运行。OMP 用户请直接改用 [billion-context](https://github.com/ranxianglei/billion-context)(启动命令 bili omp);其他客户端的完整对照见[该选哪个?](#该选哪个)。OMP 详细说明:[docs/omp.zh-CN.md](./docs/omp.zh-CN.md)。
24
24
 
25
+ ## 社区
26
+
27
+ 交流、求助与更新都在 QQ——同一个群覆盖三个项目(`billion-context`、`billion-context-pi`、`opencode-acp`):
28
+
29
+ **QQ 群:1056132097**
30
+
25
31
  ## 为什么选择 billion-context
26
32
 
27
33
  当对话变长,模型的上下文会耗尽。多数工具采用硬截断 —— 静默丢弃早期消息。**billion-context** 把 `compress` 工具交给模型:由 LLM 决定**何时**压缩、压缩**什么**,将内容压缩成高保真摘要,在回收上下文空间的同时保留关键细节(文件路径、决策、错误字符串)。
@@ -0,0 +1,10 @@
1
+ import { Type } from "typebox";
2
+ import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
3
+ import type { AcpRuntime } from "./runtime.js";
4
+ import { type ToolPromptOverrides } from "./surface.js";
5
+ declare const AbsorbParams: Type.TObject<{
6
+ ref: Type.TString;
7
+ summary: Type.TString;
8
+ }>;
9
+ export declare function makeAbsorbTool(runtime: AcpRuntime, name?: string, overrides?: ToolPromptOverrides): ToolDefinition<typeof AbsorbParams>;
10
+ export {};
@@ -1,6 +1,8 @@
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";
5
+ import { type CompressionBlock, type CompressionState } from "acp-kernel";
4
6
  declare const RangeSpec: Type.TObject<{
5
7
  startId: Type.TString;
6
8
  endId: Type.TString;
@@ -18,10 +20,14 @@ declare const CompressParams: Type.TObject<{
18
20
  summaryMaxChars: Type.TOptional<Type.TNumber>;
19
21
  }>;
20
22
  type CompressArgs = Static<typeof CompressParams>;
21
- export declare function makeCompressTool(runtime: AcpRuntime): ToolDefinition<typeof CompressParams>;
23
+ export declare function makeCompressTool(runtime: AcpRuntime, overrides?: ToolPromptOverrides): ToolDefinition<typeof CompressParams>;
22
24
  type RangeEntry = Static<typeof RangeSpec>;
23
25
  export declare function normalizeRanges(args: CompressArgs): RangeEntry[] | string;
24
26
  export declare function tailRepair(s: string): string | undefined;
27
+ /** Panel block count, or -1 for non-panels. Accepts BOTH the legacy
28
+ * "… B blocks)" form (0-block runs; historical transcripts replayed by
29
+ * index/floor-stale) and the #376 "… blocks: b3=m00044–m00097*, …" form. */
30
+ export declare function compressPanelBlocks(text: string): number;
25
31
  /** Success = completed run that created >= 1 block (partial range errors
26
32
  * still count: progress was made). A 0-block panel must NOT be success —
27
33
  * it would reset the retry counter while the emergency nudge re-fires,
@@ -31,4 +37,5 @@ export declare function isCompressSuccessText(text: string): boolean;
31
37
  * range skipped). Counted as a FAILED attempt by noteCompressOutcomes so
32
38
  * the retry cap applies. Non-panels ("No ranges provided.") stay neutral. */
33
39
  export declare function isCompressNoopText(text: string): boolean;
40
+ export declare function blockSpanLabel(block: CompressionBlock, state: CompressionState): string;
34
41
  export {};
@@ -0,0 +1 @@
1
+ export declare const CONFIG_DIR_NAME: string;
package/dist/config.d.ts CHANGED
@@ -2,6 +2,8 @@ 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";
5
7
  /** Per-role delegate defaults. Lets long-lived automation pin a cheaper or
6
8
  * more capable model and a thinking level per delegate role, so the main
7
9
  * agent doesn't have to fill them in on every `acp_delegate()` call. */
@@ -18,6 +20,27 @@ export interface DelegateRoleConfig {
18
20
  * value is ignored with a warning (never fails). */
19
21
  thinkingLevel?: string;
20
22
  }
23
+ /** Instant tool-result absorption settings (small-context mode). Mirrors
24
+ * acp-kernel's absorb feature: when enabled, every eligible large tool
25
+ * result gets a forced [ACP absorb] prompt and the model must distill it
26
+ * via the absorb tool; the original tool-call + tool-result pair is then
27
+ * hidden from subsequent turns. */
28
+ export interface AbsorbSettings {
29
+ /** Enable instant absorption. Default: false. */
30
+ enabled?: boolean;
31
+ /** Registered name of the absorb tool. Default: "absorb". */
32
+ toolName?: string;
33
+ /** Minimum estimated tokens of a tool result before it demands
34
+ * absorption. Smaller results stay as-is. Default: 1000. */
35
+ minToolTokens?: number;
36
+ /** Context usage percentage (ratio 0.3 or percent string "30%") above
37
+ * which absorption prompts fire. 0 = fire on size alone regardless of
38
+ * usage. Default: 0. */
39
+ contextThresholdPct?: number | string;
40
+ /** Tool names whose results are never absorb-prompted (in addition to
41
+ * ACP's own tools and protectedTools). */
42
+ excludeTools?: string[];
43
+ }
21
44
  /** Delegate sub-agent configuration. */
22
45
  export interface DelegateConfig {
23
46
  /** Enable acp_delegate tools (delegate/wait/cancel) and their system-prompt
@@ -120,6 +143,13 @@ export interface CompressSettings {
120
143
  * tool calls — see CompressReasoningConfig in src/reasoning-drop.ts.
121
144
  * Merged field-wise (drop, threshold) across the three levels. */
122
145
  reasoning?: CompressReasoningConfig;
146
+ /** Active prompt pack name (see CONFIGURATION.md “Prompt packs”). Base
147
+ * level; override per provider/model via `providers`. "default" or unset =
148
+ * built-in defaults. Resolved per request against the live model, so
149
+ * switching models mid-session switches the pack. Packs ship text-level
150
+ * overrides only; a pack's `toolPrompts` follow the base selection (tool
151
+ * definitions freeze at extension load, before the model is known). */
152
+ promptPack?: string;
123
153
  }
124
154
  /** Per-provider compression overrides. Carries the same tuning fields as the
125
155
  * global level, plus an optional per-model map keyed by model id. */
@@ -207,6 +237,10 @@ export interface AdapterConfig {
207
237
  delegate?: boolean | DelegateConfig;
208
238
  /** Compression tuning. */
209
239
  compress?: CompressConfig;
240
+ /** Instant tool-result absorption (small-context mode). Accepts a boolean
241
+ * shorthand (`true` → enabled with defaults) or an AbsorbSettings object.
242
+ * Default: disabled. */
243
+ absorb?: boolean | AbsorbSettings;
210
244
  /** Provider token-throttle (Bedrock "Too many tokens, please wait before
211
245
  * trying again.") auto-retry. Accepts a boolean shorthand (`false`
212
246
  * disables) or a ThrottleRetryConfig object. Default: enabled, 10 retries,
@@ -232,6 +266,14 @@ export interface AdapterConfig {
232
266
  * boolean shorthand (`false` disables) or an object. Default: enabled,
233
267
  * minRun=200. */
234
268
  degenerationGuard?: boolean | DegenerationGuardConfig;
269
+ /** Host multi-session turn-boundary policy (#364). Accepts a boolean
270
+ * shorthand (`true` → count host-injected custom_message entries as turn
271
+ * boundaries) or a HostSessionConfig object. Default: off — pi-native
272
+ * behavior where only genuine user-role messages start a turn, so existing
273
+ * single-session users' nudge cadence is unchanged. Enable for inline
274
+ * multi-session hosts (Prime RLM & co.) whose injected agent messages must
275
+ * delimit real turns. See docs/host-adapter.md. */
276
+ hostSession?: boolean | HostSessionConfig;
235
277
  /** Legacy flat alias for `delegate.displayUsage`. Kept for backward
236
278
  * compatibility with existing acp.json files. Prefer `delegate.displayUsage`. */
237
279
  displayUsage?: "merged" | "separate";
@@ -244,6 +286,21 @@ export interface AdapterConfig {
244
286
  * replacing the kernel's tuned compression rules may reduce summary quality
245
287
  * (lost paths/signatures/decisions → worse retrieval). */
246
288
  acknowledgePromptsRisk?: boolean;
289
+ /** Override structural sections of the ACP system prompt (ACP TAGS, TOOLS,
290
+ * WHEN TO COMPRESS, ...). Tri-state per section: string = replace, null =
291
+ * remove, omitted = default. Not risk-gated — these are documentation
292
+ * sections, not compression rules. Set via acp.json. */
293
+ promptSections?: Partial<PiPromptSections>;
294
+ /** Override guidance-class nudge texts (efficiencyNote, emergencyHeader,
295
+ * t2Guidance, t3Guidance). Same tri-state semantics. Not risk-gated. */
296
+ nudgeSections?: NudgeSectionsConfig;
297
+ /** Override the four ACP tool definitions' LLM-facing text (description,
298
+ * paramDescriptions, promptSnippet, promptGuidelines). Read synchronously
299
+ * at extension load — tool defs are frozen at registration time. */
300
+ toolPrompts?: ToolPromptsConfig;
301
+ /** Replace (string) or remove (null) the ACP_DELEGATE_NOTIFICATIONS appendix
302
+ * injected when the delegate tool is enabled. */
303
+ delegatePrompt?: string | null;
247
304
  coreOverrides?: Partial<Config>;
248
305
  }
249
306
  export declare const DEFAULT_TOOL_BASH_TIMEOUT = 60;
@@ -267,6 +324,21 @@ export declare function resolveRepetitionGuard(adapter: AdapterConfig): {
267
324
  warn: number;
268
325
  abort: number;
269
326
  };
327
+ /** Host multi-session turn-boundary policy (#364). See TurnBoundaryPolicy in
328
+ * src/turn-boundary.ts for the semantics this resolves. */
329
+ export interface HostSessionConfig {
330
+ /** Count host-injected custom_message entries (agent_message) as turn
331
+ * boundaries. Default: false (pi-native behavior). */
332
+ countCustomMessages?: boolean;
333
+ }
334
+ export interface ResolvedHostSession {
335
+ countCustomMessages: boolean;
336
+ }
337
+ /** Resolve the host-session turn-boundary policy from the adapter, handling
338
+ * the boolean shorthand (`true` enables countCustomMessages). Invalid values
339
+ * fall back to the pi-native default (off) with a logged warning — they never
340
+ * fail the session. */
341
+ export declare function resolveHostSession(adapter: AdapterConfig): ResolvedHostSession;
270
342
  /** Per-field deepest-wins merge of the three compression levels (global →
271
343
  * provider → model). An undefined field at a deeper level does NOT clear a
272
344
  * value set at a shallower level — only a defined value overrides. */
@@ -277,5 +349,14 @@ export declare function mergeCompress(global?: CompressSettings, provider?: Comp
277
349
  * at any level. The Pi adapter keys providers by name (ctx.model.provider),
278
350
  * not URL — it never sees the upstream URL the way the proxy does. */
279
351
  export declare function resolveCompress(compress: CompressConfig | undefined, provider: string | undefined, modelId: string | undefined): CompressSettings;
352
+ /** Resolve absorb settings from the adapter config, handling the boolean
353
+ * shorthand. contextThresholdPct is parsed to a ratio when provided. */
354
+ export declare function resolveAbsorb(adapter: AdapterConfig): {
355
+ enabled: boolean;
356
+ toolName?: string;
357
+ minToolTokens?: number;
358
+ contextThresholdPct?: number;
359
+ excludeTools?: string[];
360
+ };
280
361
  export declare function resolveConfig(adapter: AdapterConfig, liveContextLimit: number, provider?: string, modelId?: string): Config;
281
362
  export declare function parsePercent(v: number | string): number;
@@ -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 {};
@@ -0,0 +1,20 @@
1
+ export interface ExportOptions {
2
+ output?: string;
3
+ full?: boolean;
4
+ }
5
+ export interface SessionSummary {
6
+ id: string;
7
+ title?: string;
8
+ label?: string;
9
+ savedAt?: number;
10
+ contextTokens?: number;
11
+ blocks: number;
12
+ }
13
+ export declare function listSessions(sessionDir: string): Promise<SessionSummary[]>;
14
+ export declare function exportSession(selector: string | undefined, opts: ExportOptions, sessionDir: string): Promise<string>;
15
+ export declare function parseExportArgs(args: string): {
16
+ selector?: string;
17
+ full: boolean;
18
+ output?: string;
19
+ error?: string;
20
+ };
package/dist/host.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
+ /** Which session-entry source API the host exposes (same precedence as readContextEntries). */
3
+ export type EntrySourceKind = "buildContextEntries" | "getBranch";
4
+ export declare function entrySourceOf(sm: ExtensionContext["sessionManager"]): EntrySourceKind | null;
5
+ /**
6
+ * Whether the host declared itself a Pi-compatible fork via environment.
7
+ *
8
+ * The SessionManager shape alone cannot distinguish e.g. Prime from OMP — both are
9
+ * Pi forks exposing `getBranch()` but not `buildContextEntries()` — so an
10
+ * unsupported shape requires an explicit declaration before the adapter runs.
11
+ * Read at call time so hosts can set it per-launch. See docs/host-adapter.md.
12
+ */
13
+ export declare function isDeclaredForkHost(): boolean;
14
+ /** Unsupported host: not Pi-shaped and not declared as a fork. OMP stays blocked by default. */
15
+ export declare function isUnsupportedHost(sm: ExtensionContext["sessionManager"]): boolean;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  import type { ExtensionFactory } from "@earendil-works/pi-coding-agent";
2
2
  import { type AdapterConfig } from "./config.js";
3
+ export { createRuntime } from "./runtime.js";
4
+ export type { AcpRuntime, SessionRef } from "./runtime.js";
5
+ export { deriveChildState } from "./state.js";
3
6
  export declare function createAcpExtension(adapter?: AdapterConfig): ExtensionFactory;
4
7
  declare const _default: ExtensionFactory;
5
8
  export default _default;