billion-context-dsh 0.2.17 → 0.2.19
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 +18 -9
- package/README.md +15 -9
- package/dist/index.js +98 -66
- package/dist/index.js.map +1 -1
- package/dist/messages.d.ts +2 -2
- package/dist/region.d.ts +13 -1
- package/dist/session-events.d.ts +21 -0
- package/package.json +5 -2
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.19**) 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 ⭐:
|
|
@@ -68,15 +68,24 @@ The command installs the package and automatically layers this package's bundle
|
|
|
68
68
|
|
|
69
69
|
Restart `dsh` afterwards (bundle layers are composed at startup), open a new session, and verify: ask the model to call `acp_status`, or run `/acp status`. Shipped presets (standard / code / cordis) keep their realm-local `compaction-basic` fallback (automatic pressure compression still runs there; the ACP tools and nudge coexist); minimal and presets without a compaction realm use this engine directly.
|
|
70
70
|
|
|
71
|
-
> **DSH version compatibility.** The package declares
|
|
72
|
-
>
|
|
73
|
-
>
|
|
74
|
-
>
|
|
75
|
-
>
|
|
71
|
+
> **DSH version compatibility.** The package declares all four runtime seam
|
|
72
|
+
> packages (`dsh-compaction` / `dsh-session` / `dsh-llm` / `dsh-tools`) as peer
|
|
73
|
+
> dependencies, sharing the range
|
|
74
|
+
> `^0.1.0-rc.6 || ^0.1.1-rc.1 || ^0.1.2-alpha.4`,
|
|
75
|
+
> covering the `0.1.0-rc.x` and `0.1.1-rc.x` release lines (including the current
|
|
76
|
+
> DSH release; the seam's `src/` is unchanged from `0.1.0-rc.6` to `0.1.1-rc.2`, so the public
|
|
77
|
+
> API is identical) and the `0.1.2-alpha.x` line (which removed the
|
|
78
|
+
> `Session.events` getter in favour of `snapshotEvents()` / `eventAt()`; this
|
|
79
|
+
> engine feature-detects both shapes, so one build runs on either seam). The
|
|
80
|
+
> range is multiple `||` clauses **on purpose**: npm
|
|
76
81
|
> (node-semver) only lets a prerelease version satisfy a range that carries a
|
|
77
82
|
> comparator on the SAME `[major, minor, patch]` tuple as the candidate, so a lone
|
|
78
|
-
> `^0.1.0-rc.6` can never match `0.1.1-rc.x` (issue #68)
|
|
79
|
-
> install on DSH 0.1.1-rc.x; upgrade to a
|
|
83
|
+
> `^0.1.0-rc.6` can never match `0.1.1-rc.x` (issue #68) or `0.1.2-alpha.x` —
|
|
84
|
+
> older releases fail to install on DSH 0.1.1-rc.x / 0.1.2-alpha.x; upgrade to a
|
|
85
|
+
> release containing this fix. Declaring all four seam packages as peers (not
|
|
86
|
+
> just `dsh-compaction`) ensures that, even under pnpm's
|
|
87
|
+
> hoisted/linked layout, installations resolve them to the **host's own** copy
|
|
88
|
+
> rather than a stale nested copy inconsistent with the host.
|
|
80
89
|
|
|
81
90
|
**Path B: plain `npm install` (package only — a composition row is required).**
|
|
82
91
|
|
|
@@ -89,7 +98,7 @@ This only installs the package into your project/global store; it does **not** t
|
|
|
89
98
|
**Install from the git source (`github:` spec — the form the plugin store shows).** The prebuilt `dist/` artifacts are committed to this repository, so a git-source install also works out of the box — **no build step needed**, and pnpm 11's default build-script blocking (`allowBuilds`) never applies to this package:
|
|
90
99
|
|
|
91
100
|
```bash
|
|
92
|
-
dsh plugin --profile web add github:Tyan66666/billion-context-dsh#v0.2.
|
|
101
|
+
dsh plugin --profile web add github:Tyan66666/billion-context-dsh#v0.2.19
|
|
93
102
|
```
|
|
94
103
|
|
|
95
104
|
Prefer a `#<tag>` ref to get artifacts identical to that npm release; without a ref you get the latest default-branch build. Only building the repo yourself (`npm run build`) requires approving build scripts. Background and trade-offs: [docs/git-source-install-design.md](docs/git-source-install-design.md) (issue #92).
|
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.19**)仍处于开发中的测试版。[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 本身也处于**公开测试版**阶段。**请勿将两者用于工程化 / 生产环境**——预期会有破坏性变更与粗糙之处。
|
|
7
7
|
|
|
8
8
|
<p align="center">
|
|
9
9
|
<strong>衷心感谢以下项目——请给它们一个 ⭐:</strong>
|
|
@@ -71,14 +71,20 @@ dsh plugin --profile web add billion-context-dsh
|
|
|
71
71
|
|
|
72
72
|
装完**重启 `dsh`**(bundle 层在启动时组合),新开会话即可用——让模型调用 `acp_status` 或执行 `/acp status` 自证。shipped 预设(standard / code / cordis)内部的 realm 级 `compaction-basic` 自动压缩兜底仍然保留(这些模式里"自动摘要"照旧,ACP 工具与 nudge 并存);minimal 等不带 compaction realm 的预设直接使用本引擎。
|
|
73
73
|
|
|
74
|
-
> **与 DSH 版本的兼容性。**
|
|
75
|
-
>
|
|
76
|
-
>
|
|
77
|
-
>
|
|
78
|
-
>
|
|
74
|
+
> **与 DSH 版本的兼容性。** 包把四个运行期 seam 包(`dsh-compaction` /
|
|
75
|
+
> `dsh-session` / `dsh-llm` / `dsh-tools`)都声明为 peer 依赖,共享同一个
|
|
76
|
+
> 范围 `^0.1.0-rc.6 || ^0.1.1-rc.1 || ^0.1.2-alpha.4`,同时覆盖 `0.1.0-rc.x`、
|
|
77
|
+
> `0.1.1-rc.x` 两条 rc 线与 `0.1.2-alpha.x` 线(从 `0.1.0-rc.6` 到 `0.1.1-rc.2`,
|
|
78
|
+
> seam 的 `src/` 源码零改动,公开 API 完全一致;`0.1.2-alpha` 移除了
|
|
79
|
+
> `Session.events` getter,改为 `snapshotEvents()` / `eventAt()`,本引擎对两种
|
|
80
|
+
> 形态做了特性探测,单一构建两端通用)。范围写成多个并集子句是**有意为之**:
|
|
81
|
+
> npm (node-semver)的预发布匹配规则要求 range 里存在与候选版本**相同
|
|
79
82
|
> `[major, minor, patch]` 元组**的比较器,单一 `^0.1.0-rc.6` 永远匹配不了
|
|
80
|
-
> `0.1.1-rc.x`(issue #68
|
|
81
|
-
>
|
|
83
|
+
> `0.1.1-rc.x`(issue #68),也匹配不了 `0.1.2-alpha.x`——因此旧发布的包在
|
|
84
|
+
> DSH 0.1.1-rc.x / 0.1.2-alpha.x 上装不上,升级到含本次修复的新版本即可。
|
|
85
|
+
> 把这四个 seam 包一并声明为 peer(而不只是 `dsh-compaction`),是为了让
|
|
86
|
+
> 安装在 pnpm 的集成/封存布局下仍能把它们解析到**宿主自己的副本**,而不是
|
|
87
|
+
> 某个与宿主不一致的陈旧嵌套副本。
|
|
82
88
|
|
|
83
89
|
**方式二:纯 `npm install`(只装包,需要手写组合行)。**
|
|
84
90
|
|
|
@@ -91,7 +97,7 @@ npm install billion-context-dsh
|
|
|
91
97
|
**git 源安装(`github:` 规格,插件商店展示的形态)。** 预构建产物 `dist/` 已提交到仓库,从 git 源安装同样开箱即用——**无需任何构建步骤**,pnpm 11 默认拦截构建脚本(`allowBuilds`)的机制对这个包不构成障碍:
|
|
92
98
|
|
|
93
99
|
```bash
|
|
94
|
-
dsh plugin --profile web add github:Tyan66666/billion-context-dsh#v0.2.
|
|
100
|
+
dsh plugin --profile web add github:Tyan66666/billion-context-dsh#v0.2.19
|
|
95
101
|
```
|
|
96
102
|
|
|
97
103
|
建议带 `#<tag>` 安装,拿到与对应 npm 版本完全一致的产物;不带 ref 则装默认分支的最新构建。只有 clone 仓库自行从源码构建(`npm run build`)才需要放行构建。背景与方案取舍见 [docs/git-source-install-design.md](docs/git-source-install-design.md)(issue #92)。
|
package/dist/index.js
CHANGED
|
@@ -2645,6 +2645,18 @@ import {
|
|
|
2645
2645
|
} from "@deepseek-ai/dsh-compaction";
|
|
2646
2646
|
import { createAssistantMessage, createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
2647
2647
|
|
|
2648
|
+
// src/session-events.ts
|
|
2649
|
+
function sessionEventsOf(session) {
|
|
2650
|
+
const snapshot = session.snapshotEvents?.();
|
|
2651
|
+
if (snapshot !== void 0) return snapshot;
|
|
2652
|
+
return session.events;
|
|
2653
|
+
}
|
|
2654
|
+
function eventAtOf(session, seq) {
|
|
2655
|
+
const eventAt = session.eventAt;
|
|
2656
|
+
if (typeof eventAt === "function") return eventAt.call(session, seq);
|
|
2657
|
+
return session.events[seq];
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2648
2660
|
// src/messages.ts
|
|
2649
2661
|
function extractText(content) {
|
|
2650
2662
|
if (typeof content === "string") return content;
|
|
@@ -2757,10 +2769,10 @@ function eventsToCoreMessages(events, toolNames) {
|
|
|
2757
2769
|
return out;
|
|
2758
2770
|
}
|
|
2759
2771
|
function surfaceEventsOf(session) {
|
|
2760
|
-
return session.surface.nodes.map((seq) => session
|
|
2772
|
+
return session.surface.nodes.map((seq) => eventAtOf(session, seq)).filter((event) => event !== void 0);
|
|
2761
2773
|
}
|
|
2762
2774
|
function allLogMessages(session) {
|
|
2763
|
-
return eventsToCoreMessages(session
|
|
2775
|
+
return eventsToCoreMessages(sessionEventsOf(session));
|
|
2764
2776
|
}
|
|
2765
2777
|
function extractEventText(event) {
|
|
2766
2778
|
switch (event.type) {
|
|
@@ -2826,7 +2838,7 @@ function hostPriceEvent(event) {
|
|
|
2826
2838
|
function shadowedHostTokens(session, seqs) {
|
|
2827
2839
|
let total = 0;
|
|
2828
2840
|
for (const seq of seqs) {
|
|
2829
|
-
const event = session
|
|
2841
|
+
const event = eventAtOf(session, seq);
|
|
2830
2842
|
if (event !== void 0) total += hostPriceEvent(event);
|
|
2831
2843
|
}
|
|
2832
2844
|
return total;
|
|
@@ -2869,11 +2881,11 @@ function assertNoActiveCompaction(events) {
|
|
|
2869
2881
|
else if (event.type === "compaction/end") active = false;
|
|
2870
2882
|
}
|
|
2871
2883
|
if (active) {
|
|
2872
|
-
|
|
2884
|
+
console.warn("billion-context-dsh: clearing stale compaction flag \u2014 found a compaction/start with no matching compaction/end");
|
|
2873
2885
|
}
|
|
2874
2886
|
}
|
|
2875
2887
|
function hasPlainRef(session, seq) {
|
|
2876
|
-
const event = session
|
|
2888
|
+
const event = eventAtOf(session, seq);
|
|
2877
2889
|
if (event === void 0) return false;
|
|
2878
2890
|
switch (event.type) {
|
|
2879
2891
|
case "user/message":
|
|
@@ -2906,14 +2918,14 @@ var AlreadyCompressedRangeError = class extends Error {
|
|
|
2906
2918
|
coveringBlockIds;
|
|
2907
2919
|
};
|
|
2908
2920
|
function recoverStaleRange(session, start, end) {
|
|
2909
|
-
if (session
|
|
2910
|
-
const failedEdge = session
|
|
2921
|
+
if (eventAtOf(session, start) === void 0 || eventAtOf(session, end) === void 0) {
|
|
2922
|
+
const failedEdge = eventAtOf(session, start) === void 0 ? start : end;
|
|
2911
2923
|
return { kind: "unresolvable", failedEdge };
|
|
2912
2924
|
}
|
|
2913
2925
|
const liveInside = session.surface.nodes.filter((seq) => seq >= start && seq <= end).sort((a, b) => a - b);
|
|
2914
|
-
const plain = liveInside.filter((seq) => !isCheckpointNode(session
|
|
2926
|
+
const plain = liveInside.filter((seq) => !isCheckpointNode(eventAtOf(session, seq)));
|
|
2915
2927
|
if (plain.length === 0) {
|
|
2916
|
-
const coveringBlockIds = rebuildBlockLedger(session
|
|
2928
|
+
const coveringBlockIds = rebuildBlockLedger(sessionEventsOf(session)).filter((entry) => entry.shadowedSeqs.some((seq) => seq >= start && seq <= end)).map((entry) => entry.blockId);
|
|
2917
2929
|
return { kind: "already-compressed", coveringBlockIds };
|
|
2918
2930
|
}
|
|
2919
2931
|
return { kind: "ok", start: plain[0], end: plain[plain.length - 1] };
|
|
@@ -2996,35 +3008,53 @@ function readCompactionSummary(event) {
|
|
|
2996
3008
|
return event.data;
|
|
2997
3009
|
}
|
|
2998
3010
|
function runCompactionTransaction(session, input) {
|
|
2999
|
-
assertNoActiveCompaction(session
|
|
3000
|
-
const turn = findOpenTurn(session
|
|
3011
|
+
assertNoActiveCompaction(sessionEventsOf(session));
|
|
3012
|
+
const turn = findOpenTurn(sessionEventsOf(session));
|
|
3001
3013
|
const compactionId = CompactionId(randomUUID());
|
|
3002
3014
|
const seqs = [];
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3015
|
+
if (input.start > input.end) {
|
|
3016
|
+
throw new Error(`billion-context-dsh: reversed range ${input.start}..${input.end}`);
|
|
3017
|
+
}
|
|
3018
|
+
if (eventAtOf(session, input.start) === void 0 || eventAtOf(session, input.end) === void 0) {
|
|
3019
|
+
const failedEdge = eventAtOf(session, input.start) === void 0 ? input.start : input.end;
|
|
3020
|
+
throw new Error(
|
|
3021
|
+
`billion-context-dsh: seq ${input.start}..${input.end} not in the current surface \u2014 edge seq ${failedEdge} is not in this session's log. Surface seqs are sparse message nodes (only user/message, assistant/message, tool/result events); consult acp_status for the current surface range`
|
|
3022
|
+
);
|
|
3023
|
+
}
|
|
3024
|
+
try {
|
|
3025
|
+
seqs.push(session.append("compaction/start", { compactionId, turn }).seq);
|
|
3026
|
+
seqs.push(session.append("compaction/summary", {
|
|
3027
|
+
compactionId,
|
|
3028
|
+
summary: input.summary,
|
|
3029
|
+
shadowedRange: { start: input.start, end: input.end },
|
|
3030
|
+
shadowedSeqs: [...input.shadowedSeqs],
|
|
3031
|
+
shadowedTokenCount: input.shadowedTokenCount,
|
|
3032
|
+
provider: input.provider,
|
|
3033
|
+
model: input.model,
|
|
3034
|
+
tier: input.tier ?? 1,
|
|
3035
|
+
...input.kernelBlockId === void 0 ? {} : { kernelBlockId: input.kernelBlockId },
|
|
3036
|
+
...input.topic === void 0 ? {} : { topic: input.topic },
|
|
3037
|
+
...input.parentBlockIds === void 0 || input.parentBlockIds.length === 0 ? {} : { parentBlockIds: [...input.parentBlockIds] },
|
|
3038
|
+
...input.directMessageIds === void 0 ? {} : { directMessageIds: [...input.directMessageIds] },
|
|
3039
|
+
...input.effectiveMessageIds === void 0 ? {} : { effectiveMessageIds: [...input.effectiveMessageIds] }
|
|
3040
|
+
}).seq);
|
|
3041
|
+
const message = createUserMessage({
|
|
3042
|
+
content: input.summary,
|
|
3043
|
+
source: compactCheckpointSource(compactionId)
|
|
3044
|
+
});
|
|
3045
|
+
seqs.push(session.append("user/message", message, {
|
|
3046
|
+
surfaceOp: { op: "replace", start: input.start, end: input.end },
|
|
3047
|
+
sourceEventSeqs: [...input.shadowedSeqs]
|
|
3048
|
+
}).seq);
|
|
3049
|
+
seqs.push(session.append("compaction/end", { compactionId, turn }).seq);
|
|
3050
|
+
} catch (error) {
|
|
3051
|
+
try {
|
|
3052
|
+
session.append("compaction/end", { compactionId, turn });
|
|
3053
|
+
} catch (compensateError) {
|
|
3054
|
+
console.warn("billion-context-dsh: failed to write a compensating compaction/end", compensateError);
|
|
3055
|
+
}
|
|
3056
|
+
throw error;
|
|
3057
|
+
}
|
|
3028
3058
|
return { compactionId, seqs };
|
|
3029
3059
|
}
|
|
3030
3060
|
function summarySeqOfCompaction(events, compactionId) {
|
|
@@ -3111,7 +3141,7 @@ function hideSurfaceSeqs(session, seqs, provider, model, text, priceEvent = host
|
|
|
3111
3141
|
const end = seqs[seqs.length - 1];
|
|
3112
3142
|
let shadowedTokenCount = 0;
|
|
3113
3143
|
for (const seq of seqs) {
|
|
3114
|
-
const event = session
|
|
3144
|
+
const event = eventAtOf(session, seq);
|
|
3115
3145
|
if (event !== void 0) shadowedTokenCount += priceEvent(event);
|
|
3116
3146
|
}
|
|
3117
3147
|
session.append("compaction/prune", {
|
|
@@ -3130,7 +3160,7 @@ function hideSurfaceSeqs(session, seqs, provider, model, text, priceEvent = host
|
|
|
3130
3160
|
return;
|
|
3131
3161
|
}
|
|
3132
3162
|
session.append("assistant/message", {
|
|
3133
|
-
turn: findOpenTurn(session
|
|
3163
|
+
turn: findOpenTurn(sessionEventsOf(session)) ?? 0,
|
|
3134
3164
|
step: 0,
|
|
3135
3165
|
message: createAssistantMessage({ content: [], source: { provider, model } })
|
|
3136
3166
|
}, {
|
|
@@ -3140,7 +3170,8 @@ function hideSurfaceSeqs(session, seqs, provider, model, text, priceEvent = host
|
|
|
3140
3170
|
}
|
|
3141
3171
|
function hideCompressToolPair(session, callId, resultSeq) {
|
|
3142
3172
|
let callSeq = null;
|
|
3143
|
-
|
|
3173
|
+
const events = sessionEventsOf(session);
|
|
3174
|
+
for (const event of events) {
|
|
3144
3175
|
if (event.type !== "assistant/message") continue;
|
|
3145
3176
|
if (toolCallIdsOfEvent(event).includes(callId)) {
|
|
3146
3177
|
callSeq = event.seq;
|
|
@@ -3148,11 +3179,11 @@ function hideCompressToolPair(session, callId, resultSeq) {
|
|
|
3148
3179
|
}
|
|
3149
3180
|
}
|
|
3150
3181
|
if (callSeq === null) return false;
|
|
3151
|
-
const callNodeIds = toolCallIdsOfEvent(
|
|
3182
|
+
const callNodeIds = toolCallIdsOfEvent(events[callSeq]);
|
|
3152
3183
|
if (callNodeIds.length !== 1 || callNodeIds[0] !== callId) return false;
|
|
3153
3184
|
let resolvedResultSeq = resultSeq ?? null;
|
|
3154
3185
|
if (resolvedResultSeq === null) {
|
|
3155
|
-
for (const event of
|
|
3186
|
+
for (const event of events) {
|
|
3156
3187
|
if (event.type === "tool/result" && toolCallIdOfResultEvent(event) === callId) {
|
|
3157
3188
|
resolvedResultSeq = event.seq;
|
|
3158
3189
|
break;
|
|
@@ -3164,8 +3195,8 @@ function hideCompressToolPair(session, callId, resultSeq) {
|
|
|
3164
3195
|
const startIdx = nodes.indexOf(callSeq);
|
|
3165
3196
|
const endIdx = nodes.indexOf(resolvedResultSeq);
|
|
3166
3197
|
if (startIdx < 0 || endIdx < 0 || endIdx - startIdx !== 1) return false;
|
|
3167
|
-
const { provider, model } = assistantProviderModel(
|
|
3168
|
-
const resultEvent =
|
|
3198
|
+
const { provider, model } = assistantProviderModel(events[callSeq]);
|
|
3199
|
+
const resultEvent = events[resolvedResultSeq];
|
|
3169
3200
|
const resultText = resultEvent === void 0 ? "" : extractEventText(resultEvent);
|
|
3170
3201
|
hideSurfaceSeqs(session, [callSeq, resolvedResultSeq], provider, model, resultText.trim().length > 0 ? resultText : void 0);
|
|
3171
3202
|
return true;
|
|
@@ -3178,7 +3209,7 @@ function stripOrphanedSurfaceToolMessages(session, inFlightCallIds = /* @__PURE_
|
|
|
3178
3209
|
const brokenResults = /* @__PURE__ */ new Map();
|
|
3179
3210
|
for (let index = 0; index < nodes.length; index += 1) {
|
|
3180
3211
|
const seq = nodes[index];
|
|
3181
|
-
const event = session
|
|
3212
|
+
const event = eventAtOf(session, seq);
|
|
3182
3213
|
if (event === void 0) continue;
|
|
3183
3214
|
if (event.type === "assistant/message") {
|
|
3184
3215
|
const ids = toolCallIdsOfEvent(event);
|
|
@@ -3200,7 +3231,7 @@ function stripOrphanedSurfaceToolMessages(session, inFlightCallIds = /* @__PURE_
|
|
|
3200
3231
|
if (callNodeIds !== void 0) {
|
|
3201
3232
|
adjacent = true;
|
|
3202
3233
|
for (let mid = call.index + 1; mid < index; mid += 1) {
|
|
3203
|
-
const midEvent = session
|
|
3234
|
+
const midEvent = eventAtOf(session, nodes[mid]);
|
|
3204
3235
|
if (midEvent === void 0 || midEvent.type !== "tool/result") {
|
|
3205
3236
|
adjacent = false;
|
|
3206
3237
|
break;
|
|
@@ -3218,7 +3249,7 @@ function stripOrphanedSurfaceToolMessages(session, inFlightCallIds = /* @__PURE_
|
|
|
3218
3249
|
}
|
|
3219
3250
|
const brokenIdsByCallSeq = /* @__PURE__ */ new Map();
|
|
3220
3251
|
for (const [resultSeq, callSeq] of brokenResults) {
|
|
3221
|
-
const id = toolCallIdOfResultEvent(session
|
|
3252
|
+
const id = toolCallIdOfResultEvent(eventAtOf(session, resultSeq));
|
|
3222
3253
|
if (id !== null) {
|
|
3223
3254
|
const list = brokenIdsByCallSeq.get(callSeq) ?? [];
|
|
3224
3255
|
list.push(id);
|
|
@@ -3235,7 +3266,7 @@ function stripOrphanedSurfaceToolMessages(session, inFlightCallIds = /* @__PURE_
|
|
|
3235
3266
|
const hidden = [...hiddenSet].sort((a, b) => a - b);
|
|
3236
3267
|
let count = 0;
|
|
3237
3268
|
for (const seq of hidden) {
|
|
3238
|
-
const event = session
|
|
3269
|
+
const event = eventAtOf(session, seq);
|
|
3239
3270
|
if (event === void 0) continue;
|
|
3240
3271
|
const { provider, model } = assistantProviderModel(event);
|
|
3241
3272
|
hideSurfaceSeqs(session, [seq], provider, model);
|
|
@@ -3246,7 +3277,7 @@ function stripOrphanedSurfaceToolMessages(session, inFlightCallIds = /* @__PURE_
|
|
|
3246
3277
|
function openToolCallIds(session) {
|
|
3247
3278
|
const open = /* @__PURE__ */ new Set();
|
|
3248
3279
|
for (const seq of session.surface.nodes) {
|
|
3249
|
-
const event = session
|
|
3280
|
+
const event = eventAtOf(session, seq);
|
|
3250
3281
|
if (event === void 0) continue;
|
|
3251
3282
|
if (event.type === "assistant/message") {
|
|
3252
3283
|
for (const id of toolCallIdsOfEvent(event)) open.add(id);
|
|
@@ -3275,7 +3306,7 @@ function buildCompressibleSeqRanges(session, opts = {}) {
|
|
|
3275
3306
|
for (const seq of nodes.slice(-preserve)) protectedSeqs.add(seq);
|
|
3276
3307
|
}
|
|
3277
3308
|
for (let index = nodes.length - 1; index >= 0; index -= 1) {
|
|
3278
|
-
const event = session
|
|
3309
|
+
const event = eventAtOf(session, nodes[index]);
|
|
3279
3310
|
if (event?.type === "user/message" && !isCheckpointNode(event)) {
|
|
3280
3311
|
protectedSeqs.add(nodes[index]);
|
|
3281
3312
|
break;
|
|
@@ -3288,7 +3319,7 @@ function buildCompressibleSeqRanges(session, opts = {}) {
|
|
|
3288
3319
|
cur = null;
|
|
3289
3320
|
};
|
|
3290
3321
|
for (const seq of nodes) {
|
|
3291
|
-
const event = session
|
|
3322
|
+
const event = eventAtOf(session, seq);
|
|
3292
3323
|
if (event === void 0 || protectedSeqs.has(seq) || isCheckpointNode(event)) {
|
|
3293
3324
|
flush();
|
|
3294
3325
|
continue;
|
|
@@ -3335,7 +3366,7 @@ function surfaceSummary(session) {
|
|
|
3335
3366
|
return `${nodes.length} nodes, seqs ${first}..${last}`;
|
|
3336
3367
|
}
|
|
3337
3368
|
function blockRegistry(session) {
|
|
3338
|
-
const ledger = rebuildBlockLedger(session
|
|
3369
|
+
const ledger = rebuildBlockLedger(sessionEventsOf(session));
|
|
3339
3370
|
const kernelIdOf = /* @__PURE__ */ new Map();
|
|
3340
3371
|
const raw = [];
|
|
3341
3372
|
let next = 1;
|
|
@@ -3369,7 +3400,7 @@ function blockRegistry(session) {
|
|
|
3369
3400
|
}));
|
|
3370
3401
|
}
|
|
3371
3402
|
function blockRefForSummarySeq(session, seq) {
|
|
3372
|
-
const event = session
|
|
3403
|
+
const event = eventAtOf(session, seq);
|
|
3373
3404
|
if (event?.type !== "user/message") return null;
|
|
3374
3405
|
const source = event.data.source;
|
|
3375
3406
|
if (source?.plugin !== "compact" || source.compactionId === void 0) return null;
|
|
@@ -3399,7 +3430,7 @@ function checkpointBlockIdOf(events, seq) {
|
|
|
3399
3430
|
return source.compactionId;
|
|
3400
3431
|
}
|
|
3401
3432
|
function expandShadowedSeqs(session, blockId) {
|
|
3402
|
-
const ledger = rebuildBlockLedger(session
|
|
3433
|
+
const ledger = rebuildBlockLedger(sessionEventsOf(session));
|
|
3403
3434
|
const byId = new Map(ledger.map((entry) => [entry.blockId, entry]));
|
|
3404
3435
|
const root = byId.get(blockId);
|
|
3405
3436
|
if (root === void 0) return [];
|
|
@@ -3409,7 +3440,7 @@ function expandShadowedSeqs(session, blockId) {
|
|
|
3409
3440
|
if (seen.has(entry.blockId)) return;
|
|
3410
3441
|
seen.add(entry.blockId);
|
|
3411
3442
|
for (const seq of entry.shadowedSeqs) {
|
|
3412
|
-
const childId = checkpointBlockIdOf(session
|
|
3443
|
+
const childId = checkpointBlockIdOf(sessionEventsOf(session), seq);
|
|
3413
3444
|
const child = childId === null ? void 0 : byId.get(childId);
|
|
3414
3445
|
if (child !== void 0) visit(child);
|
|
3415
3446
|
else out.push(seq);
|
|
@@ -3486,9 +3517,10 @@ var AcpStateStore = class {
|
|
|
3486
3517
|
const existing = this.states.get(id);
|
|
3487
3518
|
if (existing !== void 0) return existing;
|
|
3488
3519
|
const state = createInitialState();
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
state.
|
|
3520
|
+
const events = sessionEventsOf(session);
|
|
3521
|
+
if (events.some((event) => event.type === "compaction/summary")) {
|
|
3522
|
+
state.blocks = rebuildKernelBlocks(events);
|
|
3523
|
+
state.nextBlockId = nextBlockIdAfter(events);
|
|
3492
3524
|
}
|
|
3493
3525
|
this.states.set(id, state);
|
|
3494
3526
|
return state;
|
|
@@ -3707,7 +3739,7 @@ function buildNudge(agent, env, lastNudgeTurn) {
|
|
|
3707
3739
|
const nudge = turn.nudge;
|
|
3708
3740
|
if (nudge === void 0 || !nudge.shouldInject) return null;
|
|
3709
3741
|
const emergency = nudge.breakdown?.emergencyOverride === 1;
|
|
3710
|
-
const turnNumber = findOpenTurn(session
|
|
3742
|
+
const turnNumber = findOpenTurn(sessionEventsOf(session)) ?? 0;
|
|
3711
3743
|
const alreadyShown = !emergency && lastNudgeTurn.get(session.id) === turnNumber;
|
|
3712
3744
|
if (alreadyShown) return null;
|
|
3713
3745
|
lastNudgeTurn.set(session.id, turnNumber);
|
|
@@ -4126,7 +4158,7 @@ var decompressParameters = {
|
|
|
4126
4158
|
function resolveBlockId(session, arg) {
|
|
4127
4159
|
const byKernelRef = blockIdOfKernelRef(session, arg);
|
|
4128
4160
|
if (byKernelRef !== null) return byKernelRef;
|
|
4129
|
-
const ledger = rebuildBlockLedger(session
|
|
4161
|
+
const ledger = rebuildBlockLedger(sessionEventsOf(session));
|
|
4130
4162
|
const byPrefix = ledger.find((entry) => entry.blockId.startsWith(arg));
|
|
4131
4163
|
return byPrefix?.blockId ?? null;
|
|
4132
4164
|
}
|
|
@@ -4137,14 +4169,14 @@ function handleDecompress(_env, rawArgs, exec) {
|
|
|
4137
4169
|
if (blockId === null) {
|
|
4138
4170
|
return { text: `decompress: block "${args.blockId}" not found (see acp_status for the block list)` };
|
|
4139
4171
|
}
|
|
4140
|
-
const ledger = rebuildBlockLedger(session
|
|
4172
|
+
const ledger = rebuildBlockLedger(sessionEventsOf(session));
|
|
4141
4173
|
const block = ledger.find((entry) => entry.blockId === blockId);
|
|
4142
4174
|
if (block === void 0) {
|
|
4143
4175
|
return { text: `decompress: block "${args.blockId}" not found (see acp_status for the block list)` };
|
|
4144
4176
|
}
|
|
4145
4177
|
const parts = [];
|
|
4146
4178
|
for (const seq of expandShadowedSeqs(session, block.blockId)) {
|
|
4147
|
-
const event = session
|
|
4179
|
+
const event = eventAtOf(session, seq);
|
|
4148
4180
|
const text = event === void 0 ? "" : extractEventText(event);
|
|
4149
4181
|
if (text.length > 0) parts.push(`[seq ${seq}] ${text}`);
|
|
4150
4182
|
}
|
|
@@ -4172,7 +4204,7 @@ function roleOfEvent(event) {
|
|
|
4172
4204
|
}
|
|
4173
4205
|
}
|
|
4174
4206
|
function buildSearchDocs(session) {
|
|
4175
|
-
const ledger = rebuildBlockLedger(session
|
|
4207
|
+
const ledger = rebuildBlockLedger(sessionEventsOf(session));
|
|
4176
4208
|
const docs = [];
|
|
4177
4209
|
const claimed = /* @__PURE__ */ new Set();
|
|
4178
4210
|
for (const block of ledger) {
|
|
@@ -4188,7 +4220,7 @@ function buildSearchDocs(session) {
|
|
|
4188
4220
|
for (const seq of expandShadowedSeqs(session, block.blockId)) {
|
|
4189
4221
|
if (claimed.has(seq)) continue;
|
|
4190
4222
|
claimed.add(seq);
|
|
4191
|
-
const event = session
|
|
4223
|
+
const event = eventAtOf(session, seq);
|
|
4192
4224
|
if (event === void 0) continue;
|
|
4193
4225
|
const role = roleOfEvent(event);
|
|
4194
4226
|
const text = extractEventText(event);
|
|
@@ -4367,7 +4399,7 @@ async function detectContextWindow(agent, provider, model) {
|
|
|
4367
4399
|
// src/commands.ts
|
|
4368
4400
|
async function statusText(env, agent) {
|
|
4369
4401
|
const session = agent.session;
|
|
4370
|
-
const ledger = rebuildBlockLedger(session
|
|
4402
|
+
const ledger = rebuildBlockLedger(sessionEventsOf(session));
|
|
4371
4403
|
const totalTokens = ledger.reduce((sum, block) => sum + block.shadowedTokenCount, 0);
|
|
4372
4404
|
const coreMessages = allLogMessages(session);
|
|
4373
4405
|
const surfaceMessages = eventsToCoreMessages(surfaceEventsOf(session));
|
|
@@ -4435,10 +4467,10 @@ function decompressText(_env, agent, args) {
|
|
|
4435
4467
|
if (args.length < 1) return "/acp decompress <blockId>";
|
|
4436
4468
|
const session = agent.session;
|
|
4437
4469
|
const blockId = blockIdOfKernelRef(session, args[0]);
|
|
4438
|
-
const ledger = rebuildBlockLedger(session
|
|
4470
|
+
const ledger = rebuildBlockLedger(sessionEventsOf(session));
|
|
4439
4471
|
const block = blockId === null ? ledger.find((entry) => entry.blockId.startsWith(args[0])) : ledger.find((entry) => entry.blockId === blockId);
|
|
4440
4472
|
if (block === void 0) return `block "${args[0]}" not found (see /acp status)`;
|
|
4441
|
-
const parts = expandShadowedSeqs(session, block.blockId).map((seq) => extractEventText(session
|
|
4473
|
+
const parts = expandShadowedSeqs(session, block.blockId).map((seq) => extractEventText(eventAtOf(session, seq))).filter((text) => text.length > 0);
|
|
4442
4474
|
return `Block ${block.blockId} \u2014 ${block.summary}
|
|
4443
4475
|
|
|
4444
4476
|
${parts.join("\n\n") || "(no recoverable content)"}`;
|