@deepseek-ai/dsh-compaction-basic 0.1.5-rc.2 → 0.1.6-alpha.2
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.i18n.yaml +2 -2
- package/README.md +4 -2
- package/README.zh.md +9 -7
- package/lib/index.js +25 -11
- package/lib/types/region.d.ts +1 -0
- package/package.json +23 -22
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/compaction/compaction-basic/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 68d5a321e04a90bfb726392d1fb179612f6e0626
|
|
6
|
+
README.zh.md: f941cac74053a680cad859b68c7836e181065bc9
|
package/README.md
CHANGED
|
@@ -119,6 +119,8 @@ A direct `ctx.llm.stream()` call uses the configured provider/model pair and cap
|
|
|
119
119
|
|
|
120
120
|
### The region transaction
|
|
121
121
|
|
|
122
|
+
Failed summary requests dispatch synchronous `compaction/summary-error` after checking cancellation and selection stability. A recovery listener must record a durable input change before requesting retry. The backend re-derives the selected messages and refreshes their token prices and shrink baseline. The image-offload plugin owns image selection; its recorded omissions remain effective if the summary later fails or is cancelled.
|
|
123
|
+
|
|
122
124
|
The transaction validates the surface span and the durable lock, appends `compaction/start`, summarizes through the hook, revalidates stability (whole-surface for automatic calls, selected-span for manual calls), rejects a summary that does not shrink its source, appends `compaction/summary` plus the replacement `user/message`, and makes exactly one `compaction/end` attempt. A live unmatched start is the durable lock: an unmatched marker before a newer `session/end-seed` is stale evidence from a prior lifecycle and does not block; one after that boundary reports `busy`. A failed close deliberately leaves a blocking orphan. Cancellation remains authoritative after cleanup and durability.
|
|
123
125
|
|
|
124
126
|
### Config resolution
|
|
@@ -134,7 +136,7 @@ The transaction validates the surface span and the durable lock, appends `compac
|
|
|
134
136
|
| [`src/summarizer.ts`](src/summarizer.ts) | Default `ctx.llm.stream()` summarization, checkpoint framing, safe-summary projection |
|
|
135
137
|
| [`src/config.ts`](src/config.ts) | Load-time validation and routed-model policy resolution |
|
|
136
138
|
| [`src/types.ts`](src/types.ts) | `BasicCompactionConfig` and resolved policy vocabulary |
|
|
137
|
-
| — | No runtime invariant companion is published; this package exposes no independent event sequence or mutable data relation beyond contracts enforced at its owning seam. |
|
|
139
|
+
| — | No runtime invariant companion is published; this package exposes no independent event sequence or mutable data relation beyond contracts enforced at its owning seam. The durable bracket remains observable in the session log. |
|
|
138
140
|
|
|
139
141
|
</details>
|
|
140
142
|
|
|
@@ -252,7 +254,7 @@ These limits define when automatic condensation is a poor fit or needs special c
|
|
|
252
254
|
This Dev Note is working context for maintainers and is explicitly non-authoritative; shipped behavior lives in the sections above, the package code, and the linked Agent Notes.
|
|
253
255
|
|
|
254
256
|
- **Default ratios, undecided** — `thresholdRatio: 0.8` and `retainRatio: 0.16` are fixed defaults; per-model tuning via `modelPolicies` exists, but no corpus-backed guidance on ideal values is recorded.
|
|
255
|
-
- **Tokenizer-accurate measurement, deferred** — the token meter's four-characters-per-token heuristic underprices CJK text and JSON
|
|
257
|
+
- **Tokenizer-accurate measurement, deferred** — the token meter's four-characters-per-token heuristic underprices CJK text and JSON Schema documents; exact tokenization remains an open direction for the measurement service.
|
|
256
258
|
- **Overflow recovery beyond canonical errors, undecided** — recovery triggers on `CONTEXT_WINDOW_EXCEEDED` only; other provider-side context failures are not classified.
|
|
257
259
|
|
|
258
260
|
</details>
|
package/README.zh.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "
|
|
2
|
+
description: "面向部署场景的自动会话压缩(compaction):用于选择、调优或排查随 token 压力上升对较早历史进行摘要的方式。"
|
|
3
3
|
kind: "package-reference"
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -9,7 +9,7 @@ kind: "package-reference"
|
|
|
9
9
|
|
|
10
10
|
## 概述
|
|
11
11
|
|
|
12
|
-
本包让长时 agent
|
|
12
|
+
本包让长时 agent(智能体)会话在接近模型上下文上限时仍能正常工作。token 压力上升时,它会把最旧的历史压缩为摘要并保留近期消息;上下文溢出错误发生后,它会压缩并重试。你也可以通过 `/compact` 按需压缩,并选择先修剪超大工具输出。压缩使用一次额外的模型请求,并且只保留该请求返回的摘要文本。它无法缩减系统提示词、工具或会话前缀,也无法拆分单个不可分单元(例如一次超大工具调用)。
|
|
13
13
|
|
|
14
14
|
## 目录
|
|
15
15
|
|
|
@@ -17,7 +17,7 @@ kind: "package-reference"
|
|
|
17
17
|
- [理解实现](#understand-the-implementation)
|
|
18
18
|
- [进一步探索](#further-exploration)
|
|
19
19
|
- [模型体验](#model-experience)
|
|
20
|
-
- [
|
|
20
|
+
- [已知限制与暂缓事项](#known-limitations-and-deferred-work)
|
|
21
21
|
- [开发备注](#dev-note)
|
|
22
22
|
|
|
23
23
|
-----
|
|
@@ -109,7 +109,7 @@ kind: "package-reference"
|
|
|
109
109
|
|
|
110
110
|
### 自动触发与溢出恢复
|
|
111
111
|
|
|
112
|
-
当 `auto: true` 时,串行 `agent/pre-step` listener 会在请求派生前检查压力:它通过 `ctx.tokenMeter` 为最新持久路由请求 envelope 定价,当压力越过路由模型的阈值时,先剪枝,再在保留已定价近期尾部的同时摘要最旧的平衡范围。每个选定范围都从第一个不是 `system/message` 的 surface 节点开始,因此位于 surface 节点 0 的系统提示词永不会被遮蔽;由历史内提示词更新追加的后续 `system/message` 是普通历史,范围可以遮蔽它,agent loop
|
|
112
|
+
当 `auto: true` 时,串行 `agent/pre-step` listener 会在请求派生前检查压力:它通过 `ctx.tokenMeter` 为最新持久路由请求 envelope 定价,当压力越过路由模型的阈值时,先剪枝,再在保留已定价近期尾部的同时摘要最旧的平衡范围。每个选定范围都从第一个不是 `system/message` 的 surface 节点开始,因此位于 surface 节点 0 的系统提示词永不会被遮蔽;由历史内提示词更新追加的后续 `system/message` 是普通历史,范围可以遮蔽它,agent loop(智能体循环)的投影随后会在二者文本不同时用当前提示词替换节点 0([决策规则](../../core/agent-loop/README.zh.md#understand-the-implementation))。`agent/request-error` listener 响应提供方确认的 `CONTEXT_WINDOW_EXCEEDED`:它绕过常规阈值与保留策略,尝试一次最大平衡头部缩减,并且只在表层替换 generation 前进后才授权重试。取消全程保持最终决定权。
|
|
113
113
|
|
|
114
114
|
压力策略从拥有持久路由的适配器解析容量。适配器无法为有效动态路由返回容量时,手动压力路径会抛出目标特定配置错误;自动 listener 会对该精确目标警告一次,并携带完整历史继续。
|
|
115
115
|
|
|
@@ -119,6 +119,8 @@ kind: "package-reference"
|
|
|
119
119
|
|
|
120
120
|
### 区域事务
|
|
121
121
|
|
|
122
|
+
摘要请求失败后,后端先检查取消和选区稳定性,再触发同步的 `compaction/summary-error`。恢复监听器必须先记录持久的输入变更,才能请求重试。后端重新派生所选消息,更新 token 价格及判断摘要是否缩短输入的基准。图片省略插件负责选图;后续摘要失败或取消后,已经记录的省略仍然有效。
|
|
123
|
+
|
|
122
124
|
事务验证表层范围与持久锁,追加 `compaction/start`,通过钩子生成摘要,重新验证稳定性(自动调用要求整个表层、手动调用只要求所选范围),拒绝不缩小源内容的摘要,追加 `compaction/summary` 与替换 `user/message`,并恰好进行一次 `compaction/end` 尝试。活动的未匹配 start 是持久锁:位于较新 `session/end-seed` 之前的未匹配标记是先前生命周期留下的陈旧证据,不会阻塞;位于该边界之后的标记报告 `busy`。闭合失败会有意留下阻塞性的未匹配标记。完成清理与持久化后,取消仍具有最终决定权。
|
|
123
125
|
|
|
124
126
|
### 配置解析
|
|
@@ -134,7 +136,7 @@ kind: "package-reference"
|
|
|
134
136
|
| [`src/summarizer.ts`](src/summarizer.ts) | 默认 `ctx.llm.stream()` 摘要、检查点框定、安全摘要投影 |
|
|
135
137
|
| [`src/config.ts`](src/config.ts) | 加载时验证与路由模型策略解析 |
|
|
136
138
|
| [`src/types.ts`](src/types.ts) | `BasicCompactionConfig` 与已解析策略词汇 |
|
|
137
|
-
| — |
|
|
139
|
+
| — | 不发布运行时不变式配套条目;除所属 seam 强制执行的约定外,本包不公开独立事件序列或可变数据关系。持久标记对仍可在会话日志中观察。 |
|
|
138
140
|
|
|
139
141
|
</details>
|
|
140
142
|
|
|
@@ -230,7 +232,7 @@ Rules:
|
|
|
230
232
|
|
|
231
233
|
已回放系统提示词、工具与已遮蔽区域消息与会话最后一个已路由请求逐字匹配,因此提供方的热前缀 cache 可复用至尾随指令之前;只有该指令与摘要输出未缓存。将摘要器路由到不同提供方/模型,或压缩非头部范围,都会放弃该复用。
|
|
232
234
|
|
|
233
|
-
##
|
|
235
|
+
## 已知限制与暂缓事项
|
|
234
236
|
|
|
235
237
|
<a id="known-limitations-and-deferred-work"></a>
|
|
236
238
|
|
|
@@ -252,7 +254,7 @@ Rules:
|
|
|
252
254
|
本开发备注是维护者的工作上下文,明确不具权威性;已交付行为以上文、包代码与所链接的 Agent Note 为准。
|
|
253
255
|
|
|
254
256
|
- **默认比例,尚未决定**——`thresholdRatio: 0.8` 与 `retainRatio: 0.16` 是固定默认值;存在通过 `modelPolicies` 进行的按模型调优,但没有基于语料的理想值指引记录。
|
|
255
|
-
- **tokenizer 精确测量,暂缓**——token meter 每 token 四字符的启发式对 CJK 文本与 JSON
|
|
257
|
+
- **tokenizer 精确测量,暂缓**——token meter 每 token 四字符的启发式对 CJK 文本与 JSON Schema 定价偏低;精确 token 化仍是测量服务的开放方向。
|
|
256
258
|
- **规范错误之外的溢出恢复,尚未决定**——恢复仅针对 `CONTEXT_WINDOW_EXCEEDED` 触发;其他提供方侧上下文失败不参与分类。
|
|
257
259
|
|
|
258
260
|
</details>
|
package/lib/index.js
CHANGED
|
@@ -337,11 +337,7 @@ function frameSummary(summary) {
|
|
|
337
337
|
function finishError(finish) {
|
|
338
338
|
switch (finish.kind) {
|
|
339
339
|
case "error":
|
|
340
|
-
case "aborted":
|
|
341
|
-
const error = new Error(finish.failure.message);
|
|
342
|
-
error.code = finish.failure.code;
|
|
343
|
-
return error;
|
|
344
|
-
}
|
|
340
|
+
case "aborted": return new LlmError(finish.failure.message, finish.failure.code, finish.failure);
|
|
345
341
|
case "max-tokens": {
|
|
346
342
|
const error = /* @__PURE__ */ new Error("summarization truncated at the token cap (incomplete checkpoint)");
|
|
347
343
|
error.code = "MAX_TOKENS";
|
|
@@ -458,7 +454,7 @@ async function compactSurfaceRegion(dependencies, session, start, end, agent, op
|
|
|
458
454
|
let closing = false;
|
|
459
455
|
let stage = "summary";
|
|
460
456
|
try {
|
|
461
|
-
const summarized = await summarizeCompaction(dependencies, prepareCompaction(dependencies, session, selection), agent, compactionId, options.sourceCommandId, signal);
|
|
457
|
+
const summarized = await summarizeCompaction(dependencies, prepareCompaction(dependencies, session, selection), agent, compactionId, options.sourceCommandId, assertStable, signal);
|
|
462
458
|
if (options.owner === null) signal?.throwIfAborted();
|
|
463
459
|
assertStable(dependencies, session, summarized);
|
|
464
460
|
stage = "commit";
|
|
@@ -562,8 +558,20 @@ function prepareCompaction(dependencies, session, selection) {
|
|
|
562
558
|
};
|
|
563
559
|
}
|
|
564
560
|
/** Run the summarizer and frame its replacement checkpoint. */
|
|
565
|
-
async function summarizeCompaction(dependencies, prepared, agent, compactionId, sourceCommandId, signal) {
|
|
566
|
-
|
|
561
|
+
async function summarizeCompaction(dependencies, prepared, agent, compactionId, sourceCommandId, assertStable, signal) {
|
|
562
|
+
let summaryResult;
|
|
563
|
+
for (;;) {
|
|
564
|
+
signal?.throwIfAborted();
|
|
565
|
+
try {
|
|
566
|
+
summaryResult = await dependencies.summarize(prepared.input, agent, signal);
|
|
567
|
+
break;
|
|
568
|
+
} catch (error) {
|
|
569
|
+
if (signal?.aborted === true) throw error;
|
|
570
|
+
assertStable(dependencies, agent.session, prepared);
|
|
571
|
+
if (!dependencies.recover(error, agent, prepared.shadowedSeqs, signal)) throw error;
|
|
572
|
+
prepared = prepareCompaction(dependencies, agent.session, validateSurfaceRegion(agent.session, prepared.start, prepared.end));
|
|
573
|
+
}
|
|
574
|
+
}
|
|
567
575
|
const checkpointMessage = createUserMessage({
|
|
568
576
|
content: frameSummary(summaryResult.summary),
|
|
569
577
|
source: compactCheckpointSource(compactionId, sourceCommandId)
|
|
@@ -598,7 +606,7 @@ function assertSelectedSpanStable(dependencies, session, prepared) {
|
|
|
598
606
|
/** Append one completed summary record and replacement body without yielding. */
|
|
599
607
|
function commitCompactionBody(session, startEvent, summarized) {
|
|
600
608
|
const { start, end, shadowedSeqs, shadowedTokenCount, summary, provider, model, maxTokens, usage, checkpointMessage } = summarized;
|
|
601
|
-
const
|
|
609
|
+
const callRecord = summarized.llmStreamCall === true ? {
|
|
602
610
|
rawOutput: summarized.rawOutput,
|
|
603
611
|
llmStreamCall: true
|
|
604
612
|
} : summarized.rawOutput === void 0 ? {} : { rawOutput: summarized.rawOutput };
|
|
@@ -606,7 +614,7 @@ function commitCompactionBody(session, startEvent, summarized) {
|
|
|
606
614
|
compactionId: startEvent.data.compactionId,
|
|
607
615
|
...startEvent.data.sourceCommandId === void 0 ? {} : { sourceCommandId: startEvent.data.sourceCommandId },
|
|
608
616
|
summary,
|
|
609
|
-
...
|
|
617
|
+
...callRecord,
|
|
610
618
|
shadowedRange: {
|
|
611
619
|
start,
|
|
612
620
|
end
|
|
@@ -972,7 +980,13 @@ var BasicCompactionEngine = class extends CompactionEngine {
|
|
|
972
980
|
regionDependencies() {
|
|
973
981
|
return {
|
|
974
982
|
meter: this.ctx.tokenMeter,
|
|
975
|
-
summarize: (input, owner, abort) => this.summarize(input, owner, abort)
|
|
983
|
+
summarize: (input, owner, abort) => this.summarize(input, owner, abort),
|
|
984
|
+
recover: (error, agent, sourceEventSeqs, signal) => this.ctx.waterfall("compaction/summary-error", {
|
|
985
|
+
session: agent.session,
|
|
986
|
+
sourceEventSeqs,
|
|
987
|
+
error,
|
|
988
|
+
...signal === void 0 ? {} : { signal }
|
|
989
|
+
}, () => false)
|
|
976
990
|
};
|
|
977
991
|
}
|
|
978
992
|
};
|
package/lib/types/region.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ import type { SummarizationInput, SummaryResult } from './summarizer.ts';
|
|
|
13
13
|
interface RegionDependencies {
|
|
14
14
|
readonly meter: TokenMeter;
|
|
15
15
|
summarize(input: SummarizationInput, agent: Agent, signal?: AbortSignal): Promise<SummaryResult>;
|
|
16
|
+
recover(error: unknown, agent: Agent, sourceEventSeqs: readonly SessionSeq[], signal?: AbortSignal): boolean;
|
|
16
17
|
}
|
|
17
18
|
interface CompactionTransactionOptions {
|
|
18
19
|
/** `current-turn` derives a numbered owner; `null` writes a standalone bracket. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-compaction-basic",
|
|
3
3
|
"description": "Token-meter-driven compaction policy and LLM summarization backend for the DeepSeek Harness",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.6-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -27,14 +27,14 @@
|
|
|
27
27
|
],
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"peerDependencies": {
|
|
30
|
+
"@deepseek-ai/dsh-agent": "^0.1.6-alpha.2",
|
|
30
31
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
31
|
-
"@deepseek-ai/dsh-
|
|
32
|
-
"@deepseek-ai/dsh-commands": "^0.1.
|
|
33
|
-
"@deepseek-ai/dsh-compaction": "^0.1.
|
|
34
|
-
"@deepseek-ai/dsh-
|
|
35
|
-
"@deepseek-ai/dsh-
|
|
36
|
-
"@deepseek-ai/dsh-token-meter": "^0.1.
|
|
37
|
-
"@deepseek-ai/dsh-session": "^0.1.5-rc.2"
|
|
32
|
+
"@deepseek-ai/dsh-compaction": "^0.1.6-alpha.2",
|
|
33
|
+
"@deepseek-ai/dsh-commands": "^0.1.6-alpha.2",
|
|
34
|
+
"@deepseek-ai/dsh-compaction-tool-result-pruner": "^0.1.6-alpha.2",
|
|
35
|
+
"@deepseek-ai/dsh-llm": "^0.1.6-alpha.2",
|
|
36
|
+
"@deepseek-ai/dsh-session": "^0.1.6-alpha.2",
|
|
37
|
+
"@deepseek-ai/dsh-token-meter": "^0.1.6-alpha.2"
|
|
38
38
|
},
|
|
39
39
|
"peerDependenciesMeta": {
|
|
40
40
|
"@deepseek-ai/dsh-compaction-tool-result-pruner": {
|
|
@@ -42,25 +42,26 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@deepseek-ai/dsh-util-values": "^0.1.
|
|
45
|
+
"@deepseek-ai/dsh-util-values": "^0.1.6-alpha.2",
|
|
46
46
|
"@deepseek-ai/schemastery": "^3.18.2"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
50
50
|
"@deepseek-ai/cordis-plugin-include": "^1.0.7",
|
|
51
51
|
"@deepseek-ai/cordis-plugin-loader": "^1.0.3",
|
|
52
|
-
"@deepseek-ai/dsh-agent": "^0.1.
|
|
53
|
-
"@deepseek-ai/dsh-agent-loop": "^0.1.
|
|
54
|
-
"@deepseek-ai/dsh-
|
|
55
|
-
"@deepseek-ai/dsh-
|
|
56
|
-
"@deepseek-ai/dsh-
|
|
57
|
-
"@deepseek-ai/dsh-compaction-tool-result-pruner": "^0.1.
|
|
58
|
-
"@deepseek-ai/dsh-invariants": "^0.1.
|
|
59
|
-
"@deepseek-ai/dsh-llm": "^0.1.
|
|
60
|
-
"@deepseek-ai/dsh-
|
|
61
|
-
"@deepseek-ai/dsh-session
|
|
62
|
-
"@deepseek-ai/dsh-
|
|
63
|
-
"@deepseek-ai/dsh-
|
|
64
|
-
"@deepseek-ai/dsh-
|
|
52
|
+
"@deepseek-ai/dsh-agent": "^0.1.6-alpha.2",
|
|
53
|
+
"@deepseek-ai/dsh-agent-loop-testkit": "^0.1.6-alpha.2",
|
|
54
|
+
"@deepseek-ai/dsh-agent-loop": "^0.1.6-alpha.2",
|
|
55
|
+
"@deepseek-ai/dsh-commands": "^0.1.6-alpha.2",
|
|
56
|
+
"@deepseek-ai/dsh-compaction": "^0.1.6-alpha.2",
|
|
57
|
+
"@deepseek-ai/dsh-compaction-tool-result-pruner": "^0.1.6-alpha.2",
|
|
58
|
+
"@deepseek-ai/dsh-invariants": "^0.1.6-alpha.2",
|
|
59
|
+
"@deepseek-ai/dsh-llm": "^0.1.6-alpha.2",
|
|
60
|
+
"@deepseek-ai/dsh-llm-retry": "^0.1.6-alpha.2",
|
|
61
|
+
"@deepseek-ai/dsh-session": "^0.1.6-alpha.2",
|
|
62
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.6-alpha.2",
|
|
63
|
+
"@deepseek-ai/dsh-compaction-image-offload": "^0.1.6-alpha.2",
|
|
64
|
+
"@deepseek-ai/dsh-tools": "^0.1.6-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-token-meter": "^0.1.6-alpha.2"
|
|
65
66
|
}
|
|
66
67
|
}
|