billion-context-dsh 0.2.14 → 0.2.16

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.en.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [English](./README.en.md) | [中文](./README.md)
4
4
 
5
5
  > **⚠️ Beta notice — not for production use**
6
- > This project (**v0.2.14**) is a work-in-progress beta. The [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) itself is also in **public beta**. **Do not use either in engineering / production environments** — expect breaking changes and rough edges.
6
+ > This project (**v0.2.16**) is a work-in-progress beta. The [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) itself is also in **public beta**. **Do not use either in engineering / production environments** — expect breaking changes and rough edges.
7
7
 
8
8
  <p align="center">
9
9
  <strong>Built with gratitude on top of these projects</strong> — please give them a ⭐:
@@ -199,8 +199,8 @@ This project reuses `acp-kernel`'s compression core and `billion-context-pi`'s d
199
199
 
200
200
  | Key | Default | Meaning |
201
201
  |---|---|---|
202
- | `modelContextLimit` | auto-detected (fallback `128000`) | Context window used for the kernel's pressure decisions; an explicit value wins and skips the probe |
203
- | `autoModelContextLimit` | `true` | Probe the model's real window from the model API (`agent.ctx.llm.resolveModelInfo`); fall back to the default on failure, the `/acp` command shows the window source (the `acp_status` model tool carries no window info). A failed probe is surfaced in the host log and the `/acp` panel (`restart to re-probe`) — the failure is cached like a success, so fixing the gateway requires a restart or an explicit `modelContextLimit` before the probe retries |
202
+ | `modelContextLimit` | auto-detected (fallback `128000`) | Context window used for the kernel's pressure decisions; an explicit value wins and skips detection. When omitted, the host session projection `contextPressure.contextWindow` is read first — the capacity disclosed for the **current real route** (a session that switched models follows automatically, no restart needed) — and the model API is probed only when the projection discloses no window |
203
+ | `autoModelContextLimit` | `true` | Resolve the real context window automatically: the host projection first (`windowFor` → `projectedContextWindow`, `src/window.ts`), then the model API probe (`agent.ctx.llm.resolveModelInfo`); both are skipped when `autoModelContextLimit: false`. On probe failure it falls back to the default, and the `/acp` command shows the window source (the `acp_status` model tool carries no window info). A failed probe is surfaced in the host log and the `/acp` panel (`restart to re-probe`) — the failure is cached like a success, so fixing the gateway requires a restart or an explicit `modelContextLimit` before the probe retries |
204
204
  | `nudgeMinContextLimitPct` | kernel default `0.45` | Nudge window lower bound (usage fraction) — validation only; the growth-driven trigger has no percentage floor — same default as billion-context-pi |
205
205
  | `nudgeMaxContextLimitPct` | engine default `0.70` (kernel/pi default `0.75`) | Over-limit line: above this the nudge fires regardless of growth — deliberately below the host compaction-basic 80% auto-compaction line so the forced nudge fires first; an explicit value wins (a same-name key in `coreOverrides.nudge` outranks it — see below) |
206
206
  | `nudgeEmergencyThresholdPct` | engine default `0.85` (kernel/pi default `0.95`) | Emergency nudge (bypasses the per-turn dedup) — lowered from `0.95`: at 95% the model has no room to act and the 80% auto-compaction line shadows it; an explicit value wins (a same-name key in `coreOverrides.nudge` outranks it — see below) |
@@ -233,7 +233,7 @@ src/
233
233
  ├── nudge.ts # M4: kernel pressure decision → injected advisory nudge
234
234
  ├── system-prompt.ts# M4: one-time ACP guidance section (keeps nudges short)
235
235
  ├── config.ts # kernel config assembly (thresholds + coreOverrides)
236
- ├── window.ts # auto context-window detection (LLM runtime probe, fallback 128000)
236
+ ├── window.ts # auto context-window detection (session projection first, LLM runtime probe fallback, default 128000)
237
237
  └── commands.ts # M4: /acp slash command
238
238
  ```
239
239
 
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [中文](./README.md) | [English](./README.en.md)
4
4
 
5
5
  > **⚠️ 测试版声明——请勿用于生产环境**
6
- > 本项目(**v0.2.14**)仍处于开发中的测试版。[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 本身也处于**公开测试版**阶段。**请勿将两者用于工程化 / 生产环境**——预期会有破坏性变更与粗糙之处。
6
+ > 本项目(**v0.2.16**)仍处于开发中的测试版。[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 本身也处于**公开测试版**阶段。**请勿将两者用于工程化 / 生产环境**——预期会有破坏性变更与粗糙之处。
7
7
 
8
8
  <p align="center">
9
9
  <strong>衷心感谢以下项目——请给它们一个 ⭐:</strong>
@@ -199,8 +199,8 @@ DSH 的每个模型请求都派生自其 append-only 会话日志(*surface*)
199
199
 
200
200
  | 键 | 默认值 | 含义 |
201
201
  |---|---|---|
202
- | `modelContextLimit` | 自动探测(回退 `128000`) | 用于内核压力决策的上下文窗口;显式配置时优先且跳过探测 |
203
- | `autoModelContextLimit` | `true` | 从模型 API 自动探测真实窗口(`agent.ctx.llm.resolveModelInfo`);探测失败回退默认值,`/acp` 命令展示窗口来源(模型工具 `acp_status` 不含窗口信息)。探测失败会在宿主日志与 `/acp` 面板提示(`restart to re-probe`)——失败结果同样被缓存,修复网关后需重启或显式设置 `modelContextLimit` 才会重新探测 |
202
+ | `modelContextLimit` | 自动探测(回退 `128000`) | 用于内核压力决策的上下文窗口;显式配置时优先且跳过探测。省略时优先读宿主会话投影 `contextPressure.contextWindow`(按**当前真实路由**披露的新窗口,切模型会话自动跟随,无需重启),无投影时再从模型 API 探测 |
203
+ | `autoModelContextLimit` | `true` | 从模型 API 自动探测真实窗口(`agent.ctx.llm.resolveModelInfo`);探测失败回退默认值,`/acp` 命令展示窗口来源(模型工具 `acp_status` 不含窗口信息)。省略时窗口先读宿主投影(`windowFor` → `projectedContextWindow`,`src/window.ts`)再走探测;投影与探测在 `autoModelContextLimit: false` 时均跳过。探测失败会在宿主日志与 `/acp` 面板提示(`restart to re-probe`)——失败结果同样被缓存,修复网关后需重启或显式设置 `modelContextLimit` 才会重新探测 |
204
204
  | `nudgeMinContextLimitPct` | 内核默认 `0.45` | Nudge 窗口下界(用量占比)——仅作配置校验,增长路径的触发没有百分比下限——与 billion-context-pi 相同的默认值 |
205
205
  | `nudgeMaxContextLimitPct` | engine 默认 `0.70`(内核/pi 默认 `0.75`) | 过限线:超过此值则无论增长与否都触发 nudge——刻意低于宿主 compaction-basic 的 80% 自动压缩线,保证强制 nudge 先触发;显式配置优先(`coreOverrides.nudge` 同名键优先级更高,见下) |
206
206
  | `nudgeEmergencyThresholdPct` | engine 默认 `0.85`(内核/pi 默认 `0.95`) | 紧急 nudge(绕过每轮去重)——从 `0.95` 下调:95% 时模型已无操作空间且会被 80% 自动压缩线遮蔽;显式配置优先(`coreOverrides.nudge` 同名键优先级更高,见下) |
@@ -233,7 +233,7 @@ src/
233
233
  ├── nudge.ts # M4: 内核压力决策 → 注入的建议式 nudge
234
234
  ├── system-prompt.ts# M4: 一次性 ACP 指引段(让 nudge 保持简短)
235
235
  ├── config.ts # 内核配置组装(阈值 + coreOverrides)
236
- ├── window.ts # 自动上下文窗口探测(LLM 运行时探测,回退 128000)
236
+ ├── window.ts # 自动上下文窗口探测(宿主投影优先,LLM 运行时探测回退,兜底 128000)
237
237
  └── commands.ts # M4: /acp 斜杠命令
238
238
  ```
239
239
 
package/dist/index.d.ts CHANGED
@@ -40,18 +40,20 @@ export { DEFAULT_PROMPTS, DEFAULT_RESOLVED, renderSystemPrompt, renderTemplate,
40
40
  export { makeTools, type ToolEnvironment } from './tools.ts';
41
41
  export { acpCommand } from './commands.ts';
42
42
  export { buildNudge, resolveTokenCount, type NudgeEnvironment, type NudgeOutcome } from './nudge.ts';
43
- export { DEFAULT_CONTEXT_WINDOW, detectContextWindow, windowSourceLabel, type AcpWindow, } from './window.ts';
43
+ export { DEFAULT_CONTEXT_WINDOW, detectContextWindow, projectedContextWindow, windowSourceLabel, type AcpWindow, } from './window.ts';
44
44
  export { AlreadyCompressedRangeError, rebuildBlockLedger, resolveSurfaceRange, runCompactionTransaction, shadowedSeqsOf, findOpenTurn, assertNoActiveCompaction, blockRegistry, blockRefForSummarySeq, compactionIdsOfKernelBlocks, summarySeqOfKernelBlock, expandShadowedSeqs, hideCompressToolPair, stripOrphanedSurfaceToolMessages, type AcpBlockLedgerEntry, type CompactionTransactionInput, type ResolvedSurfaceRange, } from './region.ts';
45
45
  export { eventsToCoreMessages, projectEvent, surfaceEventsOf, extractEventText } from './messages.ts';
46
46
  export interface AcpConfig {
47
47
  /**
48
48
  * The context window used for pressure decisions, in tokens. When omitted,
49
- * `autoModelContextLimit` (default true) probes the model's real window via
49
+ * `autoModelContextLimit` (default true) resolves it automatically: the live
50
+ * host session projection (`contextPressure.contextWindow`) is preferred,
51
+ * then the model's real window is probed via
50
52
  * `agent.ctx.llm.resolveModelInfo(provider, model)`; an explicit value
51
- * always wins and disables the probe.
53
+ * always wins and disables both.
52
54
  */
53
55
  readonly modelContextLimit?: number;
54
- /** Probe the model's real context window from the LLM runtime. Default true. */
56
+ /** Auto-resolve the real context window: host session projection first, then the LLM runtime probe. Default true. */
55
57
  readonly autoModelContextLimit: boolean;
56
58
  /** Nudge window lower bound (usage fraction; validation only — the growth-driven trigger has no percentage floor). Kernel default 0.45 — same as billion-context-pi. */
57
59
  readonly nudgeMinContextLimitPct?: number;
@@ -129,10 +131,14 @@ export declare class AcpCompactionEngine extends CompactionEngine {
129
131
  constructor(ctx: Context, config?: Partial<AcpConfig>);
130
132
  /**
131
133
  * Resolve the effective context window for an agent. An explicitly
132
- * configured `modelContextLimit` always wins (no probe). Otherwise probe the
133
- * model's real window via `agent.ctx.llm.resolveModelInfo` (cached per
134
- * provider/model route, probe failures cached too) and fall back to
135
- * DEFAULT_CONTEXT_WINDOW when auto-detection is disabled or unavailable.
134
+ * configured `modelContextLimit` always wins (no probe). Otherwise the live
135
+ * session projection (`contextPressure.contextWindow`) is preferred when it
136
+ * discloses one it tracks the session's CURRENT route, so a mid-session
137
+ * model switch repairs itself without a restart or config (see
138
+ * projectedContextWindow). Falls back to probing the model's real window
139
+ * via `agent.ctx.llm.resolveModelInfo` (cached per provider/model route,
140
+ * probe failures cached too) and finally to DEFAULT_CONTEXT_WINDOW when
141
+ * auto-detection is disabled or unavailable.
136
142
  */
137
143
  windowFor(agent: Agent): Promise<AcpWindow>;
138
144
  /** ACP is model-driven: automatic pressure policy never summarizes by itself. */
package/dist/index.js CHANGED
@@ -3616,7 +3616,7 @@ var DEFAULT_PROMPTS = {
3616
3616
  footer: "Compress with: compress({ content: [{ startSeq, endSeq, summary }] }) \u2014 content is an array: batch multiple unrelated segments in one call, each entry its own block. Keep ranges disjoint.\nSnapshot taken at nudge time: the seqs go stale once the surface moves (a later compress shadows them), so re-run acp_status for fresh refs before compressing."
3617
3617
  },
3618
3618
  tools: {
3619
- compress: "Replace older conversation ranges with dense summaries you write. Each message seq is a surface reference. Single range: compress({ content: [{ startSeq, endSeq, summary }] }). Batch multiple unrelated ranges in one call (each content entry becomes its own block); keep ranges disjoint. Never compress content the current step is actively using. Compress boundaries are SURFACE SEQS (acp_status Surface: row, latest nudge table) \u2014 NOT the block refs (bN, e.g. b1) that acp_status COMPRESSED BLOCKS shows, which are for decompress only. Drilldown mN refs (e.g. m00306) are ALSO accepted as startSeq/endSeq \u2014 they are auto-mapped to the live surface seq; an unknown mN (never assigned on the current surface) fails with guidance. Seq refs must come from the CURRENT surface (acp_status or the latest nudge): a span whose edges were shadowed by an earlier compress is auto-remapped to its still-live content, a fully compressed span is reported as already compressed, and invented/other-session seqs fail with guidance. Good compression moments: stage or subtask completion, strategy switches, intermediate milestones, and wrapping up failed exploration \u2014 when the details are consumed and no longer critical for the task ahead. When you write a summary, turn dead-end exploration into a conclusion (what was tried, why it failed, the next step) \u2014 not a blow-by-blow; and keep the summary the ONLY record: self-contained, so a later reader (or you, after decompress) can continue without the original.",
3619
+ compress: "Replace older conversation ranges with dense summaries you write. Each message seq is a surface reference. Single range: compress({ content: [{ startSeq, endSeq, summary }] }). Batch multiple unrelated ranges in one call (each content entry becomes its own block); keep ranges disjoint. Never compress content the current step is actively using. Compress boundaries are SURFACE SEQS (acp_status Surface: row, latest nudge table) \u2014 NOT the block refs (bN, e.g. b1) that acp_status COMPRESSED BLOCKS shows, which are for decompress only. Drilldown mN refs (e.g. m00306) are ALSO accepted as startSeq/endSeq \u2014 they are auto-mapped to the live surface seq; an unknown mN (never assigned on the current surface) fails with guidance. Seq refs must come from the CURRENT surface (acp_status or the latest nudge): a span whose edges were shadowed by an earlier compress is auto-remapped to its still-live content, a fully compressed span is reported as already compressed, and invented/other-session seqs fail with guidance. Good compression moments: stage or subtask completion whose details you have fully consumed and will not re-check, strategy switches, intermediate milestones, and wrapping up failed exploration \u2014 when the details are consumed and no longer critical for the task ahead. Before compressing, ask: will I need to re-verify any detail from this range in this task? If yes, keep it live. When you write a summary, turn dead-end exploration into a conclusion (what was tried, why it failed, the next step) \u2014 not a blow-by-blow; and keep the summary the ONLY record: self-contained, so a later reader (or you, after decompress) can continue without the original.",
3620
3620
  decompress: "Recover the original content of a compressed block by its blockId \u2014 the kernel block ref `bN` shown by acp_status (e.g. b1), or a compaction id from search_context (read-only; does not unshadow the range).",
3621
3621
  searchContext: "Search inside compressed blocks (summaries and original content) for information the model no longer sees in context. When a summary lacks a detail you need (exact values, error strings, decisions, verbatim code), SEARCH the compressed blocks FIRST \u2014 never guess or reconstruct from memory: search_context(query) locates the right block, then decompress only that block to recover the original.",
3622
3622
  acpStatus: 'Context status: overview of the current context \u2014 CONTEXT BREAKDOWN (tool/text/summaries token shares of the visible total), COMPRESSED BLOCKS ledger, and the nudge decision. No args = overview. Percentages are shares of the visible content, not the context window. Note: the block refs in COMPRESSED BLOCKS (bN, e.g. b1) are for decompress; compress uses the Surface: seq range, not bN. Drilldown: pass scope:"compressed" for a per-block list, or scope:"uncompressed" with view:"messages" (every visible message) / view:"ranges" (merged ranges); tool filters to one tool name, sort reorders (size/time/tool; age for compressed), limit caps rows (default 30). Drilldown row refs are kernel ids (mN) \u2014 feed them straight to compress as startSeq/endSeq (auto-mapped to the live surface seq); bN is for decompress, Surface: seqs also work in compress.'
@@ -3640,6 +3640,7 @@ WHEN NOT TO COMPRESS:
3640
3640
  - Content the current step is actively reading or reasoning about.
3641
3641
  - Important user messages \u2014 preserve their exact intent, constraints, and acceptance criteria.
3642
3642
  - Protected tool outputs \u2014 hard-excluded from compression ranges, survive intact in visible context.
3643
+ - Content you will still need to cite verbatim \u2014 in review/audit/verification tasks, keep source reads un-compressed until the final report is written. If you compressed it and now need the exact detail, decompress costs a full round-trip; prefer delaying the compress.
3643
3644
 
3644
3645
  {howToCompressRules}
3645
3646
 
@@ -4335,12 +4336,21 @@ function makeTools(env) {
4335
4336
  var DEFAULT_CONTEXT_WINDOW = 128e3;
4336
4337
  function windowSourceLabel(window) {
4337
4338
  if (window.source === "explicit") return "configured";
4339
+ if (window.source === "projection") {
4340
+ return `session projection current route (auto-refreshes on model switch)`;
4341
+ }
4338
4342
  if (window.source === "auto") {
4339
4343
  return `auto-detected from ${window.provider ?? "?"}/${window.model ?? "?"}`;
4340
4344
  }
4341
4345
  if (window.probeFailed === true) return "default (auto-detection failed \u2014 restart to re-probe)";
4342
4346
  return "default (auto-detection unavailable)";
4343
4347
  }
4348
+ function projectedContextWindow(agent) {
4349
+ const projections = agent.ctx?.get?.("sessionProjections");
4350
+ const window = projections?.snapshot?.(agent.session)?.values?.contextPressure?.contextWindow;
4351
+ if (typeof window === "number" && Number.isInteger(window) && window > 0) return window;
4352
+ return null;
4353
+ }
4344
4354
  async function detectContextWindow(agent, provider, model) {
4345
4355
  const llm = agent.ctx?.get?.("llm");
4346
4356
  if (llm?.resolveModelInfo === void 0) return null;
@@ -4599,10 +4609,14 @@ var AcpCompactionEngine = class extends CompactionEngine {
4599
4609
  }
4600
4610
  /**
4601
4611
  * Resolve the effective context window for an agent. An explicitly
4602
- * configured `modelContextLimit` always wins (no probe). Otherwise probe the
4603
- * model's real window via `agent.ctx.llm.resolveModelInfo` (cached per
4604
- * provider/model route, probe failures cached too) and fall back to
4605
- * DEFAULT_CONTEXT_WINDOW when auto-detection is disabled or unavailable.
4612
+ * configured `modelContextLimit` always wins (no probe). Otherwise the live
4613
+ * session projection (`contextPressure.contextWindow`) is preferred when it
4614
+ * discloses one it tracks the session's CURRENT route, so a mid-session
4615
+ * model switch repairs itself without a restart or config (see
4616
+ * projectedContextWindow). Falls back to probing the model's real window
4617
+ * via `agent.ctx.llm.resolveModelInfo` (cached per provider/model route,
4618
+ * probe failures cached too) and finally to DEFAULT_CONTEXT_WINDOW when
4619
+ * auto-detection is disabled or unavailable.
4606
4620
  */
4607
4621
  async windowFor(agent) {
4608
4622
  if (this.config.modelContextLimit !== void 0) {
@@ -4611,6 +4625,12 @@ var AcpCompactionEngine = class extends CompactionEngine {
4611
4625
  const provider = agent.options.provider ?? "";
4612
4626
  const model = agent.options.model ?? "";
4613
4627
  const key = `${provider}\0${model}`;
4628
+ if (this.config.autoModelContextLimit) {
4629
+ const projected = projectedContextWindow(agent);
4630
+ if (projected !== null) {
4631
+ return { limit: projected, source: "projection", provider, model };
4632
+ }
4633
+ }
4614
4634
  const cached = this.windowCache.get(key);
4615
4635
  if (cached !== void 0) return cached;
4616
4636
  let window;
@@ -4679,6 +4699,7 @@ export {
4679
4699
  kernelConfigFor,
4680
4700
  makeTools,
4681
4701
  projectEvent,
4702
+ projectedContextWindow,
4682
4703
  rebuildBlockLedger,
4683
4704
  renderSystemPrompt,
4684
4705
  renderTemplate,