@crazx/dsh-compaction-basic 0.1.5-rc.1.zw.2 → 0.1.6-alpha.1.zw.1

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 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: 03fe2811a94ea128fffbd3a6b4678b6d944fc1d9
6
- README.zh.md: 2a5f9562d5ff30c97129e5a880d25bedc45bcd82
5
+ README.md: 9dc759e29fa552727400f0ed370e976298809657
6
+ README.zh.md: 6d72a8b58c258a6451bbfad535d9252397a6af9e
package/README.md CHANGED
@@ -124,6 +124,8 @@ A direct `ctx.llm.stream()` call uses the configured provider/model pair and cap
124
124
 
125
125
  ### The region transaction
126
126
 
127
+ 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.
128
+
127
129
  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.
128
130
 
129
131
  ### Config resolution
package/README.zh.md CHANGED
@@ -124,6 +124,8 @@ kind: "package-reference"
124
124
 
125
125
  ### 区域事务
126
126
 
127
+ 摘要请求失败后,后端先检查取消和选区稳定性,再触发同步的 `compaction/summary-error`。恢复监听器必须先记录持久的输入变更,才能请求重试。后端重新派生所选消息,更新 token 价格及判断摘要是否缩短输入的基准。图片省略插件负责选图;后续摘要失败或取消后,已经记录的省略仍然有效。
128
+
127
129
  事务验证表层范围与持久锁,追加 `compaction/start`,通过钩子生成摘要,重新验证稳定性(自动调用要求整个表层、手动调用只要求所选范围),拒绝不缩小源内容的摘要,追加 `compaction/summary` 与替换 `user/message`,并恰好进行一次 `compaction/end` 尝试。活动的未匹配 start 是持久锁:位于较新 `session/end-seed` 之前的未匹配标记是先前生命周期留下的陈旧证据,不会阻塞;位于该边界之后的标记报告 `busy`。闭合失败会有意留下阻塞性的未匹配标记。完成清理与持久化后,取消仍具有最终决定权。
128
130
 
129
131
  ### 配置解析
package/lib/index.js CHANGED
@@ -381,11 +381,7 @@ function frameSummary(summary) {
381
381
  function finishError$1(finish) {
382
382
  switch (finish.kind) {
383
383
  case "error":
384
- case "aborted": {
385
- const error = new Error(finish.failure.message);
386
- error.code = finish.failure.code;
387
- return error;
388
- }
384
+ case "aborted": return new LlmError(finish.failure.message, finish.failure.code, finish.failure);
389
385
  case "max-tokens": {
390
386
  const error = /* @__PURE__ */ new Error("summarization truncated at the token cap (incomplete checkpoint)");
391
387
  error.code = "MAX_TOKENS";
@@ -502,7 +498,7 @@ async function compactSurfaceRegion(dependencies, session, start, end, agent, op
502
498
  let closing = false;
503
499
  let stage = "summary";
504
500
  try {
505
- const summarized = await summarizeCompaction(dependencies, prepareCompaction(dependencies, session, selection), agent, compactionId, options.sourceCommandId, signal);
501
+ const summarized = await summarizeCompaction(dependencies, prepareCompaction(dependencies, session, selection), agent, compactionId, options.sourceCommandId, assertStable, signal);
506
502
  if (options.owner === null) signal?.throwIfAborted();
507
503
  assertStable(dependencies, session, summarized);
508
504
  stage = "commit";
@@ -606,8 +602,20 @@ function prepareCompaction(dependencies, session, selection) {
606
602
  };
607
603
  }
608
604
  /** Run the summarizer and frame its replacement checkpoint. */
609
- async function summarizeCompaction(dependencies, prepared, agent, compactionId, sourceCommandId, signal) {
610
- const summaryResult = await dependencies.summarize(prepared.input, agent, signal);
605
+ async function summarizeCompaction(dependencies, prepared, agent, compactionId, sourceCommandId, assertStable, signal) {
606
+ let summaryResult;
607
+ for (;;) {
608
+ signal?.throwIfAborted();
609
+ try {
610
+ summaryResult = await dependencies.summarize(prepared.input, agent, signal);
611
+ break;
612
+ } catch (error) {
613
+ if (signal?.aborted === true) throw error;
614
+ assertStable(dependencies, agent.session, prepared);
615
+ if (!dependencies.recover(error, agent, prepared.shadowedSeqs, signal)) throw error;
616
+ prepared = prepareCompaction(dependencies, agent.session, validateSurfaceRegion(agent.session, prepared.start, prepared.end));
617
+ }
618
+ }
611
619
  const checkpointMessage = createUserMessage({
612
620
  content: frameSummary(summaryResult.summary),
613
621
  source: compactCheckpointSource(compactionId, sourceCommandId)
@@ -642,7 +650,7 @@ function assertSelectedSpanStable(dependencies, session, prepared) {
642
650
  /** Append one completed summary record and replacement body without yielding. */
643
651
  function commitCompactionBody(session, startEvent, summarized) {
644
652
  const { start, end, shadowedSeqs, shadowedTokenCount, summary, provider, model, maxTokens, usage, checkpointMessage } = summarized;
645
- const callProvenance = summarized.llmStreamCall === true ? {
653
+ const callRecord = summarized.llmStreamCall === true ? {
646
654
  rawOutput: summarized.rawOutput,
647
655
  llmStreamCall: true
648
656
  } : summarized.rawOutput === void 0 ? {} : { rawOutput: summarized.rawOutput };
@@ -650,7 +658,7 @@ function commitCompactionBody(session, startEvent, summarized) {
650
658
  compactionId: startEvent.data.compactionId,
651
659
  ...startEvent.data.sourceCommandId === void 0 ? {} : { sourceCommandId: startEvent.data.sourceCommandId },
652
660
  summary,
653
- ...callProvenance,
661
+ ...callRecord,
654
662
  shadowedRange: {
655
663
  start,
656
664
  end
@@ -1591,7 +1599,13 @@ var BasicCompactionEngine = class extends CompactionEngine {
1591
1599
  regionDependencies() {
1592
1600
  return {
1593
1601
  meter: this.ctx.tokenMeter,
1594
- summarize: (input, owner, abort) => this.summarize(input, owner, abort)
1602
+ summarize: (input, owner, abort) => this.summarize(input, owner, abort),
1603
+ recover: (error, agent, sourceEventSeqs, signal) => this.ctx.waterfall("compaction/summary-error", {
1604
+ session: agent.session,
1605
+ sourceEventSeqs,
1606
+ error,
1607
+ ...signal === void 0 ? {} : { signal }
1608
+ }, () => false)
1595
1609
  };
1596
1610
  }
1597
1611
  };
@@ -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": "@crazx/dsh-compaction-basic",
3
3
  "description": "Token-meter-driven compaction policy and LLM summarization backend for the DeepSeek Harness",
4
- "version": "0.1.5-rc.1.zw.2",
4
+ "version": "0.1.6-alpha.1.zw.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -28,13 +28,13 @@
28
28
  "license": "MIT",
29
29
  "peerDependencies": {
30
30
  "@deepseek-ai/cordis": "^4.0.2",
31
- "@deepseek-ai/dsh-agent": "^0.1.5-rc.1",
32
- "@deepseek-ai/dsh-commands": "^0.1.5-rc.1",
33
- "@deepseek-ai/dsh-compaction": "^0.1.5-rc.1",
34
- "@deepseek-ai/dsh-compaction-tool-result-pruner": "^0.1.5-rc.1",
35
- "@deepseek-ai/dsh-llm": "^0.1.5-rc.1",
36
- "@deepseek-ai/dsh-session": "^0.1.5-rc.1",
37
- "@deepseek-ai/dsh-token-meter": "^0.1.5-rc.1"
31
+ "@deepseek-ai/dsh-agent": "^0.1.6-alpha.1",
32
+ "@deepseek-ai/dsh-commands": "^0.1.6-alpha.1",
33
+ "@deepseek-ai/dsh-compaction": "^0.1.6-alpha.1",
34
+ "@deepseek-ai/dsh-compaction-tool-result-pruner": "^0.1.6-alpha.1",
35
+ "@deepseek-ai/dsh-llm": "^0.1.6-alpha.1",
36
+ "@deepseek-ai/dsh-session": "^0.1.6-alpha.1",
37
+ "@deepseek-ai/dsh-token-meter": "^0.1.6-alpha.1"
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.5-rc.1",
45
+ "@deepseek-ai/dsh-util-values": "^0.1.6-alpha.1",
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.5-rc.1",
53
- "@deepseek-ai/dsh-agent-loop": "^0.1.5-rc.1",
54
- "@deepseek-ai/dsh-agent-loop-testkit": "^0.1.5-rc.1",
55
- "@deepseek-ai/dsh-commands": "^0.1.5-rc.1",
56
- "@deepseek-ai/dsh-compaction": "^0.1.5-rc.1",
57
- "@deepseek-ai/dsh-compaction-tool-result-pruner": "^0.1.5-rc.1",
58
- "@deepseek-ai/dsh-invariants": "^0.1.5-rc.1",
59
- "@deepseek-ai/dsh-llm": "^0.1.5-rc.1",
60
- "@deepseek-ai/dsh-llm-retry": "^0.1.5-rc.1",
61
- "@deepseek-ai/dsh-session": "^0.1.5-rc.1",
62
- "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.1",
63
- "@deepseek-ai/dsh-token-meter": "^0.1.5-rc.1",
64
- "@deepseek-ai/dsh-tools": "^0.1.5-rc.1"
52
+ "@deepseek-ai/dsh-agent": "^0.1.6-alpha.1",
53
+ "@deepseek-ai/dsh-agent-loop": "^0.1.6-alpha.1",
54
+ "@deepseek-ai/dsh-agent-loop-testkit": "^0.1.6-alpha.1",
55
+ "@deepseek-ai/dsh-commands": "^0.1.6-alpha.1",
56
+ "@deepseek-ai/dsh-compaction": "^0.1.6-alpha.1",
57
+ "@deepseek-ai/dsh-compaction-tool-result-pruner": "^0.1.6-alpha.1",
58
+ "@deepseek-ai/dsh-invariants": "^0.1.6-alpha.1",
59
+ "@deepseek-ai/dsh-llm": "^0.1.6-alpha.1",
60
+ "@deepseek-ai/dsh-llm-retry": "^0.1.6-alpha.1",
61
+ "@deepseek-ai/dsh-session": "^0.1.6-alpha.1",
62
+ "@deepseek-ai/dsh-session-projection": "^0.1.6-alpha.1",
63
+ "@deepseek-ai/dsh-token-meter": "^0.1.6-alpha.1",
64
+ "@deepseek-ai/dsh-tools": "^0.1.6-alpha.1",
65
+ "@deepseek-ai/dsh-compaction-image-offload": "^0.1.6-alpha.1"
65
66
  }
66
67
  }