billion-context-dsh 0.2.9 → 0.2.10
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 +3 -3
- package/README.md +3 -3
- package/dist/index.js +15 -7
- package/dist/index.js.map +1 -1
- package/dist/prompts.d.ts +1 -1
- package/package.json +1 -1
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.
|
|
6
|
+
> This project (**v0.2.10**) 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 ⭐:
|
|
@@ -130,7 +130,7 @@ DSH derives every model request from its append-only session log (the *surface*)
|
|
|
130
130
|
| nudge ("efficiency note — compress early and keep context lean") | injected at `agent/pre-step` by the kernel's pressure decision — efficiency note + context breakdown + compression rules, tone aligned with kernel/pi; never an order |
|
|
131
131
|
| `decompress` | read-only recovery of shadowed originals from the log |
|
|
132
132
|
| `search_context` | scores a unified doc set (block summaries + shadowed originals) rebuilt from the log via acp-kernel `searchBlocks` (hybrid: stemming + CJK bigrams + char n-gram fuzzy); hits link back to the owning block |
|
|
133
|
-
| `acp_status` | CONTEXT BREAKDOWN (tool/text/summaries shares of the visible total) + compressed-block ledger + nudge decision line; no context-window rows; scope/view/tool/sort/limit drilldown supported |
|
|
133
|
+
| `acp_status` | CONTEXT BREAKDOWN (tool/text/summaries shares of the visible total) + compressed-block ledger + nudge decision line + a `Checkpoint seqs` row mapping each ACTIVE block's kernel ref (`bN`) to its checkpoint summary seq — compressing a checkpoint seq distills that block (issue #60); no context-window rows; scope/view/tool/sort/limit drilldown supported |
|
|
134
134
|
| block state | in-memory kernel state + **log-rebuilt ledger** (no sidecar files) |
|
|
135
135
|
| tiered distillation (T2/T3) | re-compressing a block's summary node distills that block (tier 2); distilling a tier-2 block yields tier 3. Tier + kernel block ids are persisted to the log, so kernel state rehydrates from the log after a restart and stays distillable |
|
|
136
136
|
| compression accounting (shadow price) | `shadowedTokenCount` (what the host occupancy display deducts) is priced in the **host token-meter's vocabulary** (`ctx.tokenMeter.measure` preferred; exact mirror in `src/host-tokens.ts` as fallback) — never the plugin's internal CJK-aware estimate (that is display currency; mixing it into the host ledger can drive `messageTokens` negative and brick a CJK-heavy session, issue #54) |
|
|
@@ -150,7 +150,7 @@ A walkthrough of the ACP philosophy this project inherits — how active context
|
|
|
150
150
|
| `compress` | Replace a seq range with a dense summary you write (edges auto-balanced to tool-pair boundaries); re-compressing a block's summary node distills it (tier 2/3) |
|
|
151
151
|
| `decompress` | Restore a previously compressed block's original content (read-only); accepts the `bN` ref shown by acp_status or a compaction id |
|
|
152
152
|
| `search_context` | Search compressed block summaries and originals by keyword (acp-kernel hybrid retrieval: stemming + CJK bigrams + fuzzy); hits link back to the owning block |
|
|
153
|
-
| `acp_status` | CONTEXT BREAKDOWN (tool/text/summaries shares of the visible total) + compressed-block ledger + nudge decision line; no context-window rows. Drilldown supported: `scope:"compressed"` per block, `scope:"uncompressed"` + `view:"messages"`/`"ranges"` per message/range, with `tool` filter, `sort` order and `limit` cap. Drilldown row refs are kernel ids (mN) — feed them straight to `compress` as `startSeq`/`endSeq` (auto-mapped to the live surface seq); `Surface:` seqs work too |
|
|
153
|
+
| `acp_status` | CONTEXT BREAKDOWN (tool/text/summaries shares of the visible total) + compressed-block ledger + nudge decision line + a `Checkpoint seqs` row mapping each ACTIVE block's kernel ref (`bN`) to its checkpoint summary seq (the distill entry point, issue #60); no context-window rows. Drilldown supported: `scope:"compressed"` per block, `scope:"uncompressed"` + `view:"messages"`/`"ranges"` per message/range, with `tool` filter, `sort` order and `limit` cap. Drilldown row refs are kernel ids (mN) — feed them straight to `compress` as `startSeq`/`endSeq` (auto-mapped to the live surface seq); `Surface:` seqs work too |
|
|
154
154
|
| `/acp` | status / compress / decompress from the command bar; status also shows human-side window info (estimated context, window source, compressed-block ledger, and **nudge arbitration** — `nudge: idle/ACTIVE — reason` plus how many tokens remain until the next nudge, decided by the same kernel turn as the nudge path) |
|
|
155
155
|
|
|
156
156
|
## Upstream & credits
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[中文](./README.md) | [English](./README.en.md)
|
|
4
4
|
|
|
5
5
|
> **⚠️ 测试版声明——请勿用于生产环境**
|
|
6
|
-
> 本项目(**v0.2.
|
|
6
|
+
> 本项目(**v0.2.10**)仍处于开发中的测试版。[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 本身也处于**公开测试版**阶段。**请勿将两者用于工程化 / 生产环境**——预期会有破坏性变更与粗糙之处。
|
|
7
7
|
|
|
8
8
|
<p align="center">
|
|
9
9
|
<strong>衷心感谢以下项目——请给它们一个 ⭐:</strong>
|
|
@@ -131,7 +131,7 @@ DSH 的每个模型请求都派生自其 append-only 会话日志(*surface*)
|
|
|
131
131
|
| nudge("效率提示——尽早压缩保持精简") | 由内核的压力决策在 `agent/pre-step` 注入——效率通知 + 上下文分解 + 压缩规则,语气对齐 kernel/pi;绝非命令 |
|
|
132
132
|
| `decompress` | 从日志只读恢复被遮蔽的原文 |
|
|
133
133
|
| `search_context` | 从日志重建块摘要 + 被遮蔽原文的统一文档集,交 acp-kernel `searchBlocks`(hybrid:词干化 + CJK bigram + 字符 n-gram 模糊)打分;命中回链所属块 |
|
|
134
|
-
| `acp_status` | CONTEXT BREAKDOWN(tool/text/summaries 占可见总量)+ 压缩块账本 + nudge
|
|
134
|
+
| `acp_status` | CONTEXT BREAKDOWN(tool/text/summaries 占可见总量)+ 压缩块账本 + nudge 决策行 + `Checkpoint seqs` 行(active 块的 `bN → seq` 映射——压缩某个 checkpoint seq 即蒸馏该块,issue #60);不含上下文窗口;支持 scope/view/tool/sort/limit 钻取 |
|
|
135
135
|
| 块状态 | 内存内核状态 + **日志重建账本**(无旁车文件) |
|
|
136
136
|
| 分层蒸馏(T2/T3) | 再次压缩某块的摘要节点 = 蒸馏该块(tier 2),蒸馏 tier-2 块得 tier 3;tier 与内核块 id 持久化进日志,重启后内核状态从日志再水合、可继续蒸馏 |
|
|
137
137
|
| 压缩记账(影子价格) | `shadowedTokenCount`(宿主占用率据此扣减)**用宿主 token-meter 的词汇计价**(`ctx.tokenMeter.measure` 优先,`src/host-tokens.ts` 精确镜像兜底)——绝不混用插件内部的 CJK 感知估算(那是展示货币,混用会把宿主账本扣成负数、卡死中文会话,issue #54) |
|
|
@@ -151,7 +151,7 @@ DSH 的每个模型请求都派生自其 append-only 会话日志(*surface*)
|
|
|
151
151
|
| `compress` | 用你书写的紧凑摘要替换 seq 范围(边界自动平衡到 tool-call/result 配对点);对某块的摘要节点再次压缩 = 分层蒸馏(tier 2/3) |
|
|
152
152
|
| `decompress` | 恢复已压缩块的原始内容(只读);接受 acp_status 显示的 `bN` 或 compaction id |
|
|
153
153
|
| `search_context` | 按关键词搜索压缩块摘要与原文(acp-kernel hybrid 检索:词干化 + CJK bigram + 模糊);命中回链所属块 |
|
|
154
|
-
| `acp_status` | CONTEXT BREAKDOWN(tool/text/summaries 占可见总量)+ 压缩块账本 + nudge
|
|
154
|
+
| `acp_status` | CONTEXT BREAKDOWN(tool/text/summaries 占可见总量)+ 压缩块账本 + nudge 决策行 + `Checkpoint seqs` 行(active 块的 `bN → seq` 蒸馏入口,issue #60);不含上下文窗口。支持钻取:`scope:"compressed"` 逐块、`scope:"uncompressed"` + `view:"messages"`/`"ranges"` 逐消息/区间,`tool` 过滤、`sort` 排序、`limit` 截断。钻取行 ref 是内核 mN——可直接作为 `compress` 的 `startSeq`/`endSeq`(自动映射为 live surface seq);`Surface:` 的 seq 同样可用 |
|
|
155
155
|
| `/acp` | 从命令栏执行 status / compress / decompress;status 额外展示 human-side 窗口信息(estimated context、context window 来源、压缩账本、**nudge 仲裁**——`nudge: idle/ACTIVE — reason` 及距下一次 nudge 还差多少 token,与 nudge 路径同一内核判定) |
|
|
156
156
|
|
|
157
157
|
## 上游项目与致谢
|
package/dist/index.js
CHANGED
|
@@ -3525,7 +3525,7 @@ var NUDGE_ALLOWED = {
|
|
|
3525
3525
|
normal: /* @__PURE__ */ new Set(["pct", "philosophy"]),
|
|
3526
3526
|
emergency: /* @__PURE__ */ new Set(["pct", "philosophy"]),
|
|
3527
3527
|
guidance: /* @__PURE__ */ new Set(),
|
|
3528
|
-
tier: /* @__PURE__ */ new Set(["tier", "count", "prevTier", "tokens", "seqs"]),
|
|
3528
|
+
tier: /* @__PURE__ */ new Set(["tier", "count", "prevTier", "tokens", "seqs", "firstSeq", "lastSeq"]),
|
|
3529
3529
|
breakdown: /* @__PURE__ */ new Set(["system", "tool", "summaries", "code", "text"]),
|
|
3530
3530
|
growth: /* @__PURE__ */ new Set(["growth"]),
|
|
3531
3531
|
tip: /* @__PURE__ */ new Set()
|
|
@@ -3600,7 +3600,7 @@ var DEFAULT_PROMPTS = {
|
|
|
3600
3600
|
normal: "This is an efficiency nudge to compress early and keep context lean \u2014 not an overflow warning. A separate, stronger alert will appear if the context is actually full.\n\n{philosophy}",
|
|
3601
3601
|
emergency: "\u26A0\uFE0F Context limit reached \u2014 compress now. Prioritize consumed tool outputs.\n\n{philosophy}",
|
|
3602
3602
|
guidance: HOW_TO_COMPRESS_RULES,
|
|
3603
|
-
tier: "Tier {tier}: {count} tier-{prevTier} block(s) distillable ({tokens} tokens) \u2014
|
|
3603
|
+
tier: "Tier {tier}: {count} tier-{prevTier} block(s) distillable ({tokens} tokens) \u2014 distill them by compressing their checkpoint seq(s) [seqs {seqs}] as one range: compress({ content: [{ startSeq: {firstSeq}, endSeq: {lastSeq}, summary }] }).",
|
|
3604
3604
|
breakdown: "Context breakdown: {system}K system | {tool}K tool | {summaries}K summaries | {code}K code | {text}K text",
|
|
3605
3605
|
growth: "+{growth}K since last nudge",
|
|
3606
3606
|
tip: "\u{1F4A1} Compress all ranges in one call (pass multiple content entries: `content: [{...}, {...}]`)."
|
|
@@ -3749,7 +3749,7 @@ function replaceTierTrigger(text, nudge, session, prompts) {
|
|
|
3749
3749
|
const next = rest.match(/\n\nHOW TO COMPRESS/);
|
|
3750
3750
|
const end = next !== null ? start + 2 + next.index : text.length;
|
|
3751
3751
|
const targets = nudge.tierTargetBlocks;
|
|
3752
|
-
const summarySeqs = targets.map((block) => summarySeqOfKernelBlock(session, block.blockId)).filter((seq) => seq !== null);
|
|
3752
|
+
const summarySeqs = targets.map((block) => summarySeqOfKernelBlock(session, block.blockId)).filter((seq) => seq !== null).sort((a, b) => a - b);
|
|
3753
3753
|
const pending = nudge.tier === 2 ? nudge.breakdown?.pendingT2 : nudge.breakdown?.pendingT3;
|
|
3754
3754
|
const tokens = typeof pending === "number" ? pending : 0;
|
|
3755
3755
|
const tierValue = nudge.tier === null ? 2 : nudge.tier;
|
|
@@ -3758,7 +3758,9 @@ function replaceTierTrigger(text, nudge, session, prompts) {
|
|
|
3758
3758
|
count: targets.length,
|
|
3759
3759
|
prevTier: tierValue - 1,
|
|
3760
3760
|
tokens,
|
|
3761
|
-
seqs: summarySeqs.join(", ")
|
|
3761
|
+
seqs: summarySeqs.join(", "),
|
|
3762
|
+
firstSeq: summarySeqs[0] ?? "n/a",
|
|
3763
|
+
lastSeq: summarySeqs[summarySeqs.length - 1] ?? "n/a"
|
|
3762
3764
|
});
|
|
3763
3765
|
return text.slice(0, start) + "\n\n" + tierLine + text.slice(end);
|
|
3764
3766
|
}
|
|
@@ -3795,7 +3797,7 @@ function renderNudgeFromTemplates(nudge, emergency, session, prompts) {
|
|
|
3795
3797
|
if (prompts.nudge.guidance !== "") parts.push("", prompts.nudge.guidance);
|
|
3796
3798
|
if ((nudge.tier === 2 || nudge.tier === 3) && (nudge.tierTargetBlocks?.length ?? 0) > 0) {
|
|
3797
3799
|
const targets = nudge.tierTargetBlocks;
|
|
3798
|
-
const summarySeqs = targets.map((block) => summarySeqOfKernelBlock(session, block.blockId)).filter((seq) => seq !== null);
|
|
3800
|
+
const summarySeqs = targets.map((block) => summarySeqOfKernelBlock(session, block.blockId)).filter((seq) => seq !== null).sort((a, b) => a - b);
|
|
3799
3801
|
const pending = nudge.tier === 2 ? nudge.breakdown?.pendingT2 : nudge.breakdown?.pendingT3;
|
|
3800
3802
|
const tokens = typeof pending === "number" ? pending : 0;
|
|
3801
3803
|
const tierLine = renderTemplate(prompts.nudge.tier, {
|
|
@@ -3803,7 +3805,9 @@ function renderNudgeFromTemplates(nudge, emergency, session, prompts) {
|
|
|
3803
3805
|
count: targets.length,
|
|
3804
3806
|
prevTier: nudge.tier - 1,
|
|
3805
3807
|
tokens,
|
|
3806
|
-
seqs: summarySeqs.join(", ")
|
|
3808
|
+
seqs: summarySeqs.join(", "),
|
|
3809
|
+
firstSeq: summarySeqs[0] ?? "n/a",
|
|
3810
|
+
lastSeq: summarySeqs[summarySeqs.length - 1] ?? "n/a"
|
|
3807
3811
|
});
|
|
3808
3812
|
if (tierLine !== "") parts.push(tierLine);
|
|
3809
3813
|
const tierRules = nudge.tier === 2 ? TIER2_DISTILL_RULES : TIER3_CONDENSE_RULES;
|
|
@@ -4068,7 +4072,7 @@ async function handleCompress(env, args, exec) {
|
|
|
4068
4072
|
effectiveMessageIds: block.effectiveMessageIds
|
|
4069
4073
|
});
|
|
4070
4074
|
const adjusted = start !== range.startSeq || end !== range.endSeq;
|
|
4071
|
-
const tierLabel2 =
|
|
4075
|
+
const tierLabel2 = `, tier ${tier}`;
|
|
4072
4076
|
const note = range.recovered === true ? ` (seqs ${range.startSeq}..${range.endSeq} were already shadowed \u2014 compressed the live remainder ${start}..${end})` : adjusted ? ` (adjusted from ${range.startSeq}..${range.endSeq} to balanced edges)` : "";
|
|
4073
4077
|
lines.push(
|
|
4074
4078
|
` block ${compactionId.slice(0, 8)}: seqs ${start}..${end}, ${shadowed.length} messages shadowed${tierLabel2}${note}`
|
|
@@ -4240,6 +4244,10 @@ async function handleStatus(env, rawArgs, exec) {
|
|
|
4240
4244
|
if (nudge !== void 0) {
|
|
4241
4245
|
lines.push("", `Nudge: ${nudge.shouldInject ? "ACTIVE" : "idle"} \u2014 ${nudge.reason}`);
|
|
4242
4246
|
}
|
|
4247
|
+
const checkpointRows = blockRegistry(session).filter((entry) => entry.active && entry.summarySeq !== null).map((entry) => `${entry.kernelBlockId} \u2192 seq ${entry.summarySeq}`);
|
|
4248
|
+
if (checkpointRows.length > 0) {
|
|
4249
|
+
lines.push("", `Checkpoint seqs (active blocks \u2014 compress a checkpoint seq to distill it): ${checkpointRows.join(", ")}`);
|
|
4250
|
+
}
|
|
4243
4251
|
}
|
|
4244
4252
|
lines.push("", `Surface: ${surfaceSummary(session)}`);
|
|
4245
4253
|
if (args.scope === "uncompressed") {
|