dsh-plugin-om 0.0.2 → 0.0.5
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.md +17 -6
- package/cordis.patch.yml +4 -0
- package/dist/compress.d.ts +3 -2
- package/dist/compress.d.ts.map +1 -1
- package/dist/constants.d.ts +2 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +171 -38
- package/dist/summarize.d.ts +12 -4
- package/dist/summarize.d.ts.map +1 -1
- package/dist/types.d.ts +3 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +11 -5
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# dsh-plugin-om
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/dsh-plugin-om)
|
|
4
|
+
|
|
3
5
|
在 DSH 里应用 [Observational Memory](https://mastra.ai/research/observational-memory) 风格的上下文管理策略
|
|
4
6
|
|
|
5
7
|
## 工作原理
|
|
@@ -34,7 +36,7 @@
|
|
|
34
36
|
dsh plugin --profile <profile> add dsh-plugin-om
|
|
35
37
|
```
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
需要重启
|
|
38
40
|
|
|
39
41
|
可以通过`dsh --profile <profile> --dump-config`审查配置是否正确
|
|
40
42
|
|
|
@@ -58,10 +60,13 @@ dsh的"预设"分为两层,`dsh web`等同于`dsh --profile web`,调用的
|
|
|
58
60
|
|
|
59
61
|
而`web-profile`里定义了多个"预设agent"`preset-agent` 这里主要说的是`preset-agent`的问题
|
|
60
62
|
|
|
61
|
-
`preset-agent`配置里自带一个`compaction-basic`。由于配置注入的顺序是层级低的覆盖层级高的,所以`cordis.patch.yml`对`compaction-basic
|
|
63
|
+
`preset-agent`配置里自带一个`compaction-basic`。由于配置注入的顺序是层级低的覆盖层级高的,所以`cordis.patch.yml`对`compaction-basic`的禁用不会生效。
|
|
64
|
+
|
|
65
|
+
此外,这个插件位于`preset-agent`的定义而非额外的安装,也无法通过`dsh plugin`卸载。
|
|
62
66
|
|
|
63
67
|
解决方案:
|
|
64
68
|
|
|
69
|
+
- 直接改`preset-agent`的定义(不推荐)
|
|
65
70
|
- 定义不含`compaction-basic`的`preset-agent`
|
|
66
71
|
- `compaction-basic`压缩阈值是80%上下文窗口,而只需要确保OM的配置中,`thresholdRatio`+`historyMergeRatio`<0.8,理论上没到强制摘要就会被OM压缩了(默认值满足这一条件)
|
|
67
72
|
|
|
@@ -99,15 +104,21 @@ src/
|
|
|
99
104
|
│ └─ ③ 事件接线(仅主会话生效)
|
|
100
105
|
│ └─ ctx.on('agent/pre-step') → compress.ts # maybeCompress:两级压缩阻塞串行(先反思后观察)
|
|
101
106
|
│ ├─ reflectPass → summarize.ts # 摘要 ≥ 窗口 × historyMergeRatio:fork 精简合并 <om-history>
|
|
102
|
-
│
|
|
103
|
-
|
|
107
|
+
│ ├─ observePass → summarize.ts # 未压缩消息 ≥ 窗口 × thresholdRatio:fork 观察日志 → 追加 + 替换
|
|
108
|
+
│ └─ 提交 → compress.ts # compaction/start → summary → 替换消息(checkpoint) → end;usage 归入主会话
|
|
109
|
+
├── constants.ts # 共享常量(PLUGIN_LABEL / HISTORY_TAG / COMPACT_CHECKPOINT_PLUGIN)
|
|
104
110
|
├── types.ts # type-only:宿主类型再导出 + 领域类型(MessageNode / MessageIndex)
|
|
105
111
|
├── config.ts # 配置默认值 / 校验(缺省、null、空串回退默认值)
|
|
106
112
|
├── utils.ts # 零依赖工具函数(配置校验 / 文本渲染 / 主会话判定 / 路由解析)
|
|
107
113
|
├── log-index.ts # 消息索引(message_id → 消息事件;recall 消费)
|
|
108
|
-
├── summarize.ts # 观察/反思 persona + 提示词 + fork
|
|
114
|
+
├── summarize.ts # 观察/反思 persona + 提示词 + fork 摘要子会话(提取子会话 token usage 归入主会话)
|
|
109
115
|
├── recall.ts # recall 工具
|
|
110
|
-
└── compress.ts # 两级自动压缩(测量 / 区间计算 / 中断扫描 / 对照表 /
|
|
116
|
+
└── compress.ts # 两级自动压缩(测量 / 区间计算 / 中断扫描 / 对照表 / compaction/* 生命周期事件 + checkpoint 替换)
|
|
111
117
|
scripts/ # release-archive.mjs(CHANGELOG 归档)
|
|
112
118
|
tests/ # vitest 单元测试(52 例)
|
|
119
|
+
.dsh/skills/ # 项目级 skill(feature-defect-workflow:需求/缺陷完成工作流)
|
|
113
120
|
```
|
|
121
|
+
|
|
122
|
+
## 开发计划
|
|
123
|
+
|
|
124
|
+
- 引入OM消息的语义找回查询
|
package/cordis.patch.yml
ADDED
package/dist/compress.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Agent, Context, PluginConfig, Session } from './types.ts';
|
|
2
|
+
import { type RoutedTarget } from './utils.ts';
|
|
2
3
|
/** 历史文本 token 估算:4 字符 ≈ 1 token(与宿主 dsh-token-meter 启发式一致)。 */
|
|
3
4
|
export declare function estimateTextTokens(text: string): number;
|
|
4
5
|
/** token 估算器的结构类型(仅需 estimateMessage;避免依赖完整 TokenMeter 接口)。 */
|
|
@@ -49,12 +50,12 @@ export declare function buildMessageIdTable(session: Session, shadowedSeqs: read
|
|
|
49
50
|
* 反思:摘要 tokens ≥ 窗口 × historyMergeRatio 时,fork 子会话精简合并摘要,
|
|
50
51
|
* 替换单个 <om-history> 节点。失败不产生部分替换。
|
|
51
52
|
*/
|
|
52
|
-
export declare function reflectPass(ctx: Context, agent: Agent, config: Readonly<PluginConfig>, window: number, signal?: AbortSignal): Promise<void>;
|
|
53
|
+
export declare function reflectPass(ctx: Context, agent: Agent, config: Readonly<PluginConfig>, window: number, target: RoutedTarget, signal?: AbortSignal): Promise<void>;
|
|
53
54
|
/**
|
|
54
55
|
* 观察:未压缩消息 tokens ≥ 窗口 × thresholdRatio 时,fork 子会话把未压缩消息压缩为
|
|
55
56
|
* 观察日志,追加到旧摘要并替换被压缩消息区间。失败不产生部分替换。
|
|
56
57
|
*/
|
|
57
|
-
export declare function observePass(ctx: Context, agent: Agent, config: Readonly<PluginConfig>, window: number, tailCount: number, signal?: AbortSignal): Promise<void>;
|
|
58
|
+
export declare function observePass(ctx: Context, agent: Agent, config: Readonly<PluginConfig>, window: number, tailCount: number, target: RoutedTarget, signal?: AbortSignal): Promise<void>;
|
|
58
59
|
/**
|
|
59
60
|
* 压力检查 + 两级压缩:先反思(压缩过往摘要,有必要才做),后观察(压缩新消息,
|
|
60
61
|
* 有必要才做)。在 pre-step 阻塞串行执行(避免压缩失败或重复压缩)。仅主会话生效。
|
package/dist/compress.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EACV,KAAK,EAEL,OAAO,EACP,YAAY,EACZ,OAAO,EAIR,MAAM,YAAY,CAAC;AACpB,OAAO,EAAgB,KAAK,YAAY,EAAsB,MAAM,YAAY,CAAC;AAEjF,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAYD,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG;IAAE,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAA;CAAE,CAAC;AAE3E;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAYzF;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAS7F;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CA4BxF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAmB5F;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,SAAS,MAAM,EAAE,GAC9B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAS3C;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CA6B/F;AAsGD;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC9B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,YAAY,EACpB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAqEf;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC9B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,EACpB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CA+Ff;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC9B,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAyBf"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
export declare const PLUGIN_LABEL = "dsh-plugin-om";
|
|
6
6
|
/** 压缩日志标签名:<om-history>...</om-history> 包裹观察/反思日志块。 */
|
|
7
7
|
export declare const HISTORY_TAG = "om-history";
|
|
8
|
-
/**
|
|
9
|
-
export declare const
|
|
8
|
+
/** 宿主压缩 checkpoint 标记的 plugin 名(dsh-compaction-basic 的 COMPACT_CHECKPOINT_MARKER.plugin)。 */
|
|
9
|
+
export declare const COMPACT_CHECKPOINT_PLUGIN = "compact";
|
|
10
10
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,uCAAuC;AACvC,eAAO,MAAM,YAAY,kBAAkB,CAAC;AAE5C,uDAAuD;AACvD,eAAO,MAAM,WAAW,eAAe,CAAC;AAExC
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,uCAAuC;AACvC,eAAO,MAAM,YAAY,kBAAkB,CAAC;AAE5C,uDAAuD;AACvD,eAAO,MAAM,WAAW,eAAe,CAAC;AAExC,6FAA6F;AAC7F,eAAO,MAAM,yBAAyB,YAAY,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* 反思(摘要 ≥ 窗口 × historyMergeRatio 时 fork 精简合并 <om-history>)、
|
|
9
9
|
* 观察(未压缩消息 ≥ 窗口 × thresholdRatio 时 fork 压缩为观察日志并追加)
|
|
10
10
|
*
|
|
11
|
-
* 约束:不引入自定义会话事件类型——压缩复用宿主已知的
|
|
11
|
+
* 约束:不引入自定义会话事件类型——压缩复用宿主已知的 compaction/* 生命周期事件
|
|
12
|
+
* (start/summary/end)与 checkpoint 标记,结果写入消息记录与轨迹。
|
|
12
13
|
* 仅主会话生效(subagent 不压缩、recall 拒绝)。
|
|
13
14
|
*/
|
|
14
15
|
import type { Context } from './types.ts';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,6BAA6B;AAC7B,eAAO,MAAM,IAAI,kBAAkB,CAAC;AAEpC,wDAAwD;AACxD,eAAO,MAAM,MAAM,UAA6C,CAAC;AAEjE;;;GAGG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAuB1D"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
//#region src/constants.ts
|
|
3
|
-
/**
|
|
4
|
-
* 共享常量:集中定义插件级魔法字符串与事件名,避免散落各模块。
|
|
5
|
-
*/
|
|
6
|
-
/** 插件标识:压缩消息 source.plugin 取值与日志前缀。 */
|
|
7
|
-
const PLUGIN_LABEL = "dsh-plugin-om";
|
|
8
3
|
/** 压缩日志标签名:<om-history>...</om-history> 包裹观察/反思日志块。 */
|
|
9
4
|
const HISTORY_TAG = "om-history";
|
|
10
|
-
/**
|
|
11
|
-
const
|
|
5
|
+
/** 宿主压缩 checkpoint 标记的 plugin 名(dsh-compaction-basic 的 COMPACT_CHECKPOINT_MARKER.plugin)。 */
|
|
6
|
+
const COMPACT_CHECKPOINT_PLUGIN = "compact";
|
|
12
7
|
//#endregion
|
|
13
8
|
//#region src/log-index.ts
|
|
14
9
|
/**
|
|
@@ -188,8 +183,39 @@ function buildReflectPrompt() {
|
|
|
188
183
|
].join("\n");
|
|
189
184
|
}
|
|
190
185
|
/**
|
|
191
|
-
*
|
|
192
|
-
*
|
|
186
|
+
* 提取 fork 子会话(run.localAgent.session)的 token usage:仅统计子会话自身事件
|
|
187
|
+
* (firstLiveSeq 之后,不含继承的父会话 seed 前缀),按 turn/step 去重(同 step 的
|
|
188
|
+
* usage chunk 与 assistant/message 后写覆盖)后累加四桶;无 usage 返回 undefined。
|
|
189
|
+
*/
|
|
190
|
+
function extractSubagentUsage(agent) {
|
|
191
|
+
if (!agent) return void 0;
|
|
192
|
+
/** 子会话自身事件的起点(构造 seed 长度;缺省回退 0)。 */
|
|
193
|
+
const start = Number.isFinite(agent.session.firstLiveSeq) ? agent.session.firstLiveSeq : 0;
|
|
194
|
+
/** 子会话自身事件(跳过继承的父会话前缀)。 */
|
|
195
|
+
const ownEvents = agent.session.events.slice(start);
|
|
196
|
+
/** turn/step → usage(同 step 后写覆盖,与宿主投影语义一致)。 */
|
|
197
|
+
const perStep = /* @__PURE__ */ new Map();
|
|
198
|
+
for (const event of ownEvents) if (event.type === "assistant/message" && event.data.usage !== void 0) perStep.set(`${event.data.turn}:${event.data.step}`, event.data.usage);
|
|
199
|
+
else if (event.type === "assistant/chunk" && event.data.chunk.type === "usage") perStep.set(`${event.data.turn}:${event.data.step}`, event.data.chunk.usage);
|
|
200
|
+
if (perStep.size === 0) return void 0;
|
|
201
|
+
/** 累加结果(四桶互斥,不重复累加推理 token)。 */
|
|
202
|
+
const total = {
|
|
203
|
+
inputTokens: 0,
|
|
204
|
+
outputTokens: 0,
|
|
205
|
+
cacheReadTokens: 0,
|
|
206
|
+
cacheWriteTokens: 0
|
|
207
|
+
};
|
|
208
|
+
for (const usage of perStep.values()) {
|
|
209
|
+
total.inputTokens += usage.inputTokens;
|
|
210
|
+
total.outputTokens += usage.outputTokens;
|
|
211
|
+
total.cacheReadTokens = (total.cacheReadTokens ?? 0) + (usage.cacheReadTokens ?? 0);
|
|
212
|
+
total.cacheWriteTokens = (total.cacheWriteTokens ?? 0) + (usage.cacheWriteTokens ?? 0);
|
|
213
|
+
}
|
|
214
|
+
return total;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Fork 子会话执行一次摘要(观察或反思),返回文本与可选 token usage;
|
|
218
|
+
* 失败或无法 fork 返回 null。工具被 toolFilter 禁用,输出长度受 maxTokens 限制。
|
|
193
219
|
*/
|
|
194
220
|
async function runSummarySubagent(ctx, agent, persona, prompt, maxTokens, signal) {
|
|
195
221
|
/** subagents 服务(缺失则无法分叉摘要)。 */
|
|
@@ -225,7 +251,12 @@ async function runSummarySubagent(ctx, agent, persona, prompt, maxTokens, signal
|
|
|
225
251
|
ctx.logger.warn("dsh-plugin-om: 摘要未完成(" + (result.stopReason === "completed" ? "无输出" : String(result.stopReason)) + "),忽略本次摘要");
|
|
226
252
|
return null;
|
|
227
253
|
}
|
|
228
|
-
|
|
254
|
+
/** fork 子会话的 token usage(归入主会话记录;无则省略)。 */
|
|
255
|
+
const usage = extractSubagentUsage(run.localAgent);
|
|
256
|
+
return {
|
|
257
|
+
text,
|
|
258
|
+
...usage === void 0 ? {} : { usage }
|
|
259
|
+
};
|
|
229
260
|
} catch (error) {
|
|
230
261
|
/** 错误信息(统一为字符串)。 */
|
|
231
262
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -239,6 +270,26 @@ async function runSummarySubagent(ctx, agent, persona, prompt, maxTokens, signal
|
|
|
239
270
|
}
|
|
240
271
|
//#endregion
|
|
241
272
|
//#region src/compress.ts
|
|
273
|
+
/**
|
|
274
|
+
* 自动压缩(OM 观察/反思两级阈值,思路参考 Mastra Observational Memory):
|
|
275
|
+
* - 观察:未压缩消息 tokens ≥ 窗口 × thresholdRatio → fork 子会话把未压缩消息压缩为
|
|
276
|
+
* 观察日志,追加到旧摘要(<om-history> 原文保留),替换被压缩消息区间;
|
|
277
|
+
* - 反思:摘要 tokens ≥ 窗口 × historyMergeRatio(默认 0.2)→ fork 子会话精简合并摘要,
|
|
278
|
+
* 替换单个 <om-history> 节点。
|
|
279
|
+
* 两级检查在 pre-step 阻塞串行执行(先反思后观察),避免压缩失败或重复压缩。
|
|
280
|
+
*
|
|
281
|
+
* 压缩结果写入宿主 compaction/* 生命周期事件(compaction/start → compaction/summary →
|
|
282
|
+
* 替换 <om-history> 消息 → compaction/end),使消息记录(聊天视图压缩卡片)与轨迹视图
|
|
283
|
+
* 可见;compaction/summary 同时承担影子价格认领(shadowedTokenCount),不再单独发
|
|
284
|
+
* compaction/prune。替换消息的 source 使用宿主 checkpoint 标记(plugin: 'compact' +
|
|
285
|
+
* compactionId),UI 据此关联 summary 与替换消息。生命周期事件在 fork 摘要成功后才写入
|
|
286
|
+
* (失败不产生任何日志变更)。
|
|
287
|
+
*
|
|
288
|
+
* 观察区间:尾部保留 config.tailMessageCount(默认 10)条消息不压缩;
|
|
289
|
+
* 其余全部未压缩消息一次压缩。fork seed 截断于最后一个 turn/end,
|
|
290
|
+
* 故区间表层节点封顶在最后一个已结束 turn 的表层节点(当前 turn 消息留待下次)。
|
|
291
|
+
* 仅主会话生效。
|
|
292
|
+
*/
|
|
242
293
|
/** 历史文本 token 估算:4 字符 ≈ 1 token(与宿主 dsh-token-meter 启发式一致)。 */
|
|
243
294
|
function estimateTextTokens(text) {
|
|
244
295
|
return Math.ceil(text.length / 4);
|
|
@@ -389,13 +440,53 @@ function buildMessageIdTable(session, shadowedSeqs) {
|
|
|
389
440
|
}
|
|
390
441
|
return rows;
|
|
391
442
|
}
|
|
392
|
-
/**
|
|
393
|
-
function
|
|
394
|
-
|
|
443
|
+
/** 当前打开中的 turn 号(最近 turn/start 且未被 turn/end 关闭);无则 null(跨轮次场景)。 */
|
|
444
|
+
function openTurnOf(session) {
|
|
445
|
+
/** 折叠结果(turn/start 打开、turn/end 关闭)。 */
|
|
446
|
+
let turn = null;
|
|
447
|
+
for (const event of session.events) if (event.type === "turn/start") turn = event.data.turn;
|
|
448
|
+
else if (event.type === "turn/end") turn = null;
|
|
449
|
+
return turn;
|
|
450
|
+
}
|
|
451
|
+
/** 生成宿主 compaction 生命周期 id(uuid 按宿主品牌类型 CompactionId 标注)。 */
|
|
452
|
+
function newCompactionId() {
|
|
453
|
+
return uuid();
|
|
395
454
|
}
|
|
396
|
-
/** 追加
|
|
397
|
-
function
|
|
398
|
-
|
|
455
|
+
/** 追加 compaction/start(log-only:仅标记生命周期开始,不进入表层),返回事件 seq。 */
|
|
456
|
+
function appendCompactionStart(session, lifecycle) {
|
|
457
|
+
return session.append("compaction/start", lifecycle).seq;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* 追加 compaction/summary(log-only,承担影子价格认领:紧随其后的替换消息消费 claim)。
|
|
461
|
+
* summary 为完整合并后的 <om-history> 内文;usage 由 fork 子会话提取(无则省略)。
|
|
462
|
+
*/
|
|
463
|
+
function appendCompactionSummary(session, data) {
|
|
464
|
+
return session.append("compaction/summary", {
|
|
465
|
+
compactionId: data.lifecycle.compactionId,
|
|
466
|
+
summary: [{
|
|
467
|
+
type: "text",
|
|
468
|
+
text: data.summary
|
|
469
|
+
}],
|
|
470
|
+
shadowedRange: data.shadowedRange,
|
|
471
|
+
shadowedSeqs: data.shadowedSeqs,
|
|
472
|
+
shadowedTokenCount: data.shadowedTokenCount,
|
|
473
|
+
provider: data.provider,
|
|
474
|
+
model: data.model,
|
|
475
|
+
maxTokens: data.maxTokens,
|
|
476
|
+
...data.usage === void 0 ? {} : { usage: data.usage }
|
|
477
|
+
}).seq;
|
|
478
|
+
}
|
|
479
|
+
/** 追加 compaction/end(log-only,结束生命周期;error 记录失败原因)。 */
|
|
480
|
+
function appendCompactionEnd(session, lifecycle, error) {
|
|
481
|
+
return session.append("compaction/end", {
|
|
482
|
+
compactionId: lifecycle.compactionId,
|
|
483
|
+
turn: lifecycle.turn,
|
|
484
|
+
...error === void 0 ? {} : { error }
|
|
485
|
+
}).seq;
|
|
486
|
+
}
|
|
487
|
+
/** 追加 <om-history> 压缩日志消息(surfaceOp 替换遮蔽区间,source 为宿主 checkpoint 标记)。 */
|
|
488
|
+
function appendHistoryMessage(session, content, sourceEventSeqs, surfaceOp, compactionId) {
|
|
489
|
+
/** 压缩替换消息(<om-history> 包裹摘要,source 标记宿主 checkpoint 供 UI 关联)。 */
|
|
399
490
|
const message = {
|
|
400
491
|
id: uuid(),
|
|
401
492
|
role: "user",
|
|
@@ -411,7 +502,8 @@ function appendHistoryMessage(session, content, sourceEventSeqs, surfaceOp) {
|
|
|
411
502
|
}],
|
|
412
503
|
source: {
|
|
413
504
|
kind: "plugin",
|
|
414
|
-
plugin:
|
|
505
|
+
plugin: COMPACT_CHECKPOINT_PLUGIN,
|
|
506
|
+
compactionId
|
|
415
507
|
}
|
|
416
508
|
};
|
|
417
509
|
session.append("user/message", message, {
|
|
@@ -423,7 +515,7 @@ function appendHistoryMessage(session, content, sourceEventSeqs, surfaceOp) {
|
|
|
423
515
|
* 反思:摘要 tokens ≥ 窗口 × historyMergeRatio 时,fork 子会话精简合并摘要,
|
|
424
516
|
* 替换单个 <om-history> 节点。失败不产生部分替换。
|
|
425
517
|
*/
|
|
426
|
-
async function reflectPass(ctx, agent, config, window, signal) {
|
|
518
|
+
async function reflectPass(ctx, agent, config, window, target, signal) {
|
|
427
519
|
/** 当前会话。 */
|
|
428
520
|
const session = agent.session;
|
|
429
521
|
/** 当前摘要(最后一次 <om-history>;无则跳过)。 */
|
|
@@ -436,32 +528,52 @@ async function reflectPass(ctx, agent, config, window, signal) {
|
|
|
436
528
|
if (tokens < threshold) return;
|
|
437
529
|
/** 摘要节点须仍在表层才可替换。 */
|
|
438
530
|
if (surfaceIndexOf([...session.surface.nodes], history.seq) === -1) return;
|
|
439
|
-
/**
|
|
440
|
-
const
|
|
441
|
-
if (
|
|
531
|
+
/** 反思子会话结果(null 表示失败/跳过)。 */
|
|
532
|
+
const summaryResult = await runSummarySubagent(ctx, agent, REFLECTOR_PERSONA, buildReflectPrompt(), config.compressMaxTokens, signal);
|
|
533
|
+
if (summaryResult === null || summaryResult.text.trim().length === 0) return;
|
|
534
|
+
/** 反思摘要文本。 */
|
|
535
|
+
const report = summaryResult.text;
|
|
536
|
+
/** 本次压缩生命周期(compactionId + 当前轮次;fork 成功后才写入日志)。 */
|
|
537
|
+
const lifecycle = {
|
|
538
|
+
compactionId: newCompactionId(),
|
|
539
|
+
turn: openTurnOf(session)
|
|
540
|
+
};
|
|
442
541
|
try {
|
|
443
|
-
|
|
542
|
+
appendCompactionStart(session, lifecycle);
|
|
543
|
+
appendHistoryMessage(session, report, [appendCompactionSummary(session, {
|
|
544
|
+
lifecycle,
|
|
545
|
+
summary: report,
|
|
444
546
|
shadowedRange: {
|
|
445
547
|
start: history.seq,
|
|
446
548
|
end: history.seq
|
|
447
549
|
},
|
|
448
550
|
shadowedSeqs: [history.seq],
|
|
449
|
-
shadowedTokenCount: tokens
|
|
551
|
+
shadowedTokenCount: tokens,
|
|
552
|
+
provider: target.provider,
|
|
553
|
+
model: target.model,
|
|
554
|
+
maxTokens: config.compressMaxTokens,
|
|
555
|
+
...summaryResult.usage === void 0 ? {} : { usage: summaryResult.usage }
|
|
450
556
|
}), history.seq], {
|
|
451
557
|
op: "replace",
|
|
452
558
|
start: history.seq,
|
|
453
559
|
end: history.seq
|
|
454
|
-
});
|
|
455
|
-
|
|
560
|
+
}, lifecycle.compactionId);
|
|
561
|
+
appendCompactionEnd(session, lifecycle);
|
|
562
|
+
ctx.logger.info(`dsh-plugin-om: 反思完成(摘要 ${tokens} tokens ≥ 阈值 ${threshold},替换摘要节点)`);
|
|
456
563
|
} catch (error) {
|
|
457
|
-
|
|
564
|
+
/** 提交失败信息(统一字符串)。 */
|
|
565
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
566
|
+
ctx.logger.warn(`dsh-plugin-om: 反思提交失败: ${message}`);
|
|
567
|
+
try {
|
|
568
|
+
appendCompactionEnd(session, lifecycle, message);
|
|
569
|
+
} catch {}
|
|
458
570
|
}
|
|
459
571
|
}
|
|
460
572
|
/**
|
|
461
573
|
* 观察:未压缩消息 tokens ≥ 窗口 × thresholdRatio 时,fork 子会话把未压缩消息压缩为
|
|
462
574
|
* 观察日志,追加到旧摘要并替换被压缩消息区间。失败不产生部分替换。
|
|
463
575
|
*/
|
|
464
|
-
async function observePass(ctx, agent, config, window, tailCount, signal) {
|
|
576
|
+
async function observePass(ctx, agent, config, window, tailCount, target, signal) {
|
|
465
577
|
/** 当前会话。 */
|
|
466
578
|
const session = agent.session;
|
|
467
579
|
/** 观察阈值(窗口 × thresholdRatio 向下取整)。 */
|
|
@@ -482,9 +594,11 @@ async function observePass(ctx, agent, config, window, tailCount, signal) {
|
|
|
482
594
|
interruptions,
|
|
483
595
|
hasOldHistory: history !== void 0
|
|
484
596
|
});
|
|
485
|
-
/**
|
|
486
|
-
const
|
|
487
|
-
if (
|
|
597
|
+
/** 观察子会话结果(null 表示失败/跳过)。 */
|
|
598
|
+
const summaryResult = await runSummarySubagent(ctx, agent, OBSERVER_PERSONA, prompt, config.compressMaxTokens, signal);
|
|
599
|
+
if (summaryResult === null || summaryResult.text.trim().length === 0) return;
|
|
600
|
+
/** 观察摘要文本。 */
|
|
601
|
+
const report = summaryResult.text;
|
|
488
602
|
/** 合并后的摘要(旧摘要原文保留,新观察日志追加在末尾)。 */
|
|
489
603
|
const combined = [history?.text, report].filter(Boolean).join("\n");
|
|
490
604
|
/** 被遮蔽表层节点的 token 估算合计。 */
|
|
@@ -495,22 +609,40 @@ async function observePass(ctx, agent, config, window, tailCount, signal) {
|
|
|
495
609
|
const message = event ? session.deriveEventMessage(event) : null;
|
|
496
610
|
return total + (message ? ctx.tokenMeter.estimateMessage(message) : 0);
|
|
497
611
|
}, 0);
|
|
612
|
+
/** 本次压缩生命周期(compactionId + 当前轮次;fork 成功后才写入日志)。 */
|
|
613
|
+
const lifecycle = {
|
|
614
|
+
compactionId: newCompactionId(),
|
|
615
|
+
turn: openTurnOf(session)
|
|
616
|
+
};
|
|
498
617
|
try {
|
|
499
|
-
|
|
618
|
+
appendCompactionStart(session, lifecycle);
|
|
619
|
+
appendHistoryMessage(session, combined, [appendCompactionSummary(session, {
|
|
620
|
+
lifecycle,
|
|
621
|
+
summary: combined,
|
|
500
622
|
shadowedRange: {
|
|
501
623
|
start: range.start,
|
|
502
624
|
end: range.end
|
|
503
625
|
},
|
|
504
626
|
shadowedSeqs: range.shadowedSeqs,
|
|
505
|
-
shadowedTokenCount
|
|
627
|
+
shadowedTokenCount,
|
|
628
|
+
provider: target.provider,
|
|
629
|
+
model: target.model,
|
|
630
|
+
maxTokens: config.compressMaxTokens,
|
|
631
|
+
...summaryResult.usage === void 0 ? {} : { usage: summaryResult.usage }
|
|
506
632
|
}), ...range.shadowedSeqs], {
|
|
507
633
|
op: "replace",
|
|
508
634
|
start: range.start,
|
|
509
635
|
end: range.end
|
|
510
|
-
});
|
|
511
|
-
|
|
636
|
+
}, lifecycle.compactionId);
|
|
637
|
+
appendCompactionEnd(session, lifecycle);
|
|
638
|
+
ctx.logger.info(`dsh-plugin-om: 观察压缩完成(未压缩 ${uncompressedTokens} tokens ≥ 阈值 ${threshold},遮蔽 ${range.shadowedSeqs.length} 个表层节点,约 ${shadowedTokenCount} tokens)`);
|
|
512
639
|
} catch (error) {
|
|
513
|
-
|
|
640
|
+
/** 提交失败信息(统一字符串)。 */
|
|
641
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
642
|
+
ctx.logger.warn(`dsh-plugin-om: 观察压缩提交失败: ${message}`);
|
|
643
|
+
try {
|
|
644
|
+
appendCompactionEnd(session, lifecycle, message);
|
|
645
|
+
} catch {}
|
|
514
646
|
}
|
|
515
647
|
}
|
|
516
648
|
/**
|
|
@@ -536,8 +668,8 @@ async function maybeCompress(ctx, agent, config, signal) {
|
|
|
536
668
|
if (typeof window !== "number" || !Number.isFinite(window) || window <= 0) return;
|
|
537
669
|
/** 尾部保留条数(config.tailMessageCount,缺省 10)。 */
|
|
538
670
|
const tailCount = config.tailMessageCount;
|
|
539
|
-
await reflectPass(ctx, agent, config, window, signal);
|
|
540
|
-
await observePass(ctx, agent, config, window, tailCount, signal);
|
|
671
|
+
await reflectPass(ctx, agent, config, window, target, signal);
|
|
672
|
+
await observePass(ctx, agent, config, window, tailCount, target, signal);
|
|
541
673
|
}
|
|
542
674
|
//#endregion
|
|
543
675
|
//#region src/config.ts
|
|
@@ -749,7 +881,8 @@ function buildRecallTool(getPruner) {
|
|
|
749
881
|
* 反思(摘要 ≥ 窗口 × historyMergeRatio 时 fork 精简合并 <om-history>)、
|
|
750
882
|
* 观察(未压缩消息 ≥ 窗口 × thresholdRatio 时 fork 压缩为观察日志并追加)
|
|
751
883
|
*
|
|
752
|
-
* 约束:不引入自定义会话事件类型——压缩复用宿主已知的
|
|
884
|
+
* 约束:不引入自定义会话事件类型——压缩复用宿主已知的 compaction/* 生命周期事件
|
|
885
|
+
* (start/summary/end)与 checkpoint 标记,结果写入消息记录与轨迹。
|
|
753
886
|
* 仅主会话生效(subagent 不压缩、recall 拒绝)。
|
|
754
887
|
*/
|
|
755
888
|
/** 插件名(Loader 识别入口的稳定标识)。 */
|
package/dist/summarize.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Agent, Context } from './types.ts';
|
|
1
|
+
import type { Agent, Context, TokenUsage } from './types.ts';
|
|
2
2
|
/** 观察者 persona:只针对未压缩消息产出观察日志,不用工具、不展示思考。 */
|
|
3
3
|
export declare const OBSERVER_PERSONA = "\u4F60\u662F dsh-plugin-om \u7684\u4E0A\u4E0B\u6587\u89C2\u5BDF\u8005\uFF08Observer\uFF0C\u673A\u5236\u53C2\u8003 Mastra Observational Memory\uFF09\uFF1A\u628A\u4F1A\u8BDD\u4E2D\u5C1A\u672A\u538B\u7F29\u7684\u6D88\u606F\u538B\u7F29\u4E3A\u4E00\u4EFD\u89C2\u5BDF\u65E5\u5FD7\u3002\u4E0D\u7528\u5DE5\u5177\u3001\u4E0D\u5C55\u793A\u601D\u8003\u3001\u4E0D\u8BC4\u4EF7\u4EE3\u7801\u3001\u4E0D\u8F93\u51FA\u591A\u4F59\u6587\u5B57\u3002";
|
|
4
4
|
/** 反思者 persona:只精简合并当前摘要,不用工具、不展示思考。 */
|
|
@@ -21,8 +21,16 @@ export declare function buildObservePrompt(options: ObservePromptOptions): strin
|
|
|
21
21
|
/** 构建反思提示词:精简合并当前 <om-history>;全文由继承上下文提供。 */
|
|
22
22
|
export declare function buildReflectPrompt(): string;
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
24
|
+
* 摘要子会话结果:文本 + 可选 token usage(fork 子会话自身消耗,随 compaction/summary
|
|
25
|
+
* 归入主会话记录)。
|
|
26
26
|
*/
|
|
27
|
-
export
|
|
27
|
+
export type SummarySubagentResult = {
|
|
28
|
+
text: string;
|
|
29
|
+
usage?: TokenUsage;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Fork 子会话执行一次摘要(观察或反思),返回文本与可选 token usage;
|
|
33
|
+
* 失败或无法 fork 返回 null。工具被 toolFilter 禁用,输出长度受 maxTokens 限制。
|
|
34
|
+
*/
|
|
35
|
+
export declare function runSummarySubagent(ctx: Context, agent: Agent, persona: string, prompt: string, maxTokens: number, signal?: AbortSignal): Promise<SummarySubagentResult | null>;
|
|
28
36
|
//# sourceMappingURL=summarize.d.ts.map
|
package/dist/summarize.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarize.d.ts","sourceRoot":"","sources":["../src/summarize.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAqC,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"summarize.d.ts","sourceRoot":"","sources":["../src/summarize.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAqC,UAAU,EAAE,MAAM,YAAY,CAAC;AAGhG,6CAA6C;AAC7C,eAAO,MAAM,gBAAgB,kbACyF,CAAC;AAEvH,wCAAwC;AACxC,eAAO,MAAM,iBAAiB,6ZACiG,CAAC;AAEhI,+CAA+C;AAC/C,MAAM,MAAM,oBAAoB,GAAG;IACjC,sCAAsC;IACtC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,qCAAqC;IACrC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,iCAAiC;IACjC,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CA4BxE;AAED,8CAA8C;AAC9C,wBAAgB,kBAAkB,IAAI,MAAM,CAc3C;AAED;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB,CAAC;AAuCF;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAyDvC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { Context, EventOptions, Events } from '@deepseek-ai/cordis';
|
|
9
9
|
import type { Agent } from '@deepseek-ai/dsh-agent';
|
|
10
|
+
import type { CompactionId } from '@deepseek-ai/dsh-compaction';
|
|
10
11
|
import type { ToolResultPruner } from '@deepseek-ai/dsh-compaction-tool-result-pruner';
|
|
11
|
-
import type { Message, UserMessage } from '@deepseek-ai/dsh-llm';
|
|
12
|
+
import type { Message, TokenUsage, UserMessage } from '@deepseek-ai/dsh-llm';
|
|
12
13
|
import type { Session, SessionEvent } from '@deepseek-ai/dsh-session';
|
|
13
14
|
import type { SubagentResult, SubagentRun, SubagentStartRequest } from '@deepseek-ai/dsh-subagent';
|
|
14
15
|
import type { SystemPrompt } from '@deepseek-ai/dsh-system-prompt';
|
|
@@ -20,7 +21,7 @@ export type { PluginConfig } from './config.ts';
|
|
|
20
21
|
* 官方包宿主类型再导出:插件 API 与工具签名统一从这里取型,
|
|
21
22
|
* 避免各模块直接依赖不同版本的 dsh-* 包类型面。
|
|
22
23
|
*/
|
|
23
|
-
export type { Agent, Context, EventOptions, Events, Message, Session, SessionEvent, SubagentResult, SubagentRun, SubagentStartRequest, SystemPrompt, TokenMeter, ToolDefinition, ToolResultPruner, ToolRunContext, UserMessage, };
|
|
24
|
+
export type { Agent, CompactionId, Context, EventOptions, Events, Message, Session, SessionEvent, SubagentResult, SubagentRun, SubagentStartRequest, SystemPrompt, TokenMeter, TokenUsage, ToolDefinition, ToolResultPruner, ToolRunContext, UserMessage, };
|
|
24
25
|
/**
|
|
25
26
|
* 一条消息事件(user/assistant/tool-result),带稳定 message_id;
|
|
26
27
|
* 供 recall 按 message_id 定位消息序列下标。
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACnG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7E,gDAAgD;AAChD,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;GAGG;AACH,YAAY,EACV,KAAK,EACL,YAAY,EACZ,OAAO,EACP,YAAY,EACZ,MAAM,EACN,OAAO,EACP,OAAO,EACP,YAAY,EACZ,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,YAAY,EACZ,UAAU,EACV,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,WAAW,GACZ,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,mBAAmB;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,wBAAwB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,IAAI,EAAE,cAAc,GAAG,mBAAmB,GAAG,aAAa,CAAC;CAC5D,CAAC;AAEF,yDAAyD;AACzD,MAAM,MAAM,YAAY,GAAG;IACzB,oBAAoB;IACpB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,kCAAkC;IAClC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-om",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.mjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
"harness",
|
|
12
12
|
"plugin"
|
|
13
13
|
],
|
|
14
|
+
"repository": {
|
|
15
|
+
"url": "https://github.com/FanetheDivine/dsh-plugin-om"
|
|
16
|
+
},
|
|
14
17
|
"exports": {
|
|
15
18
|
".": {
|
|
16
19
|
"types": "./dist/index.d.ts",
|
|
@@ -19,13 +22,15 @@
|
|
|
19
22
|
},
|
|
20
23
|
"files": [
|
|
21
24
|
"dist",
|
|
25
|
+
"cordis.patch.yml",
|
|
22
26
|
"README.md"
|
|
23
27
|
],
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
"dsh": {
|
|
29
|
+
"bundle": {
|
|
30
|
+
"patch": "./cordis.patch.yml"
|
|
31
|
+
}
|
|
28
32
|
},
|
|
33
|
+
"license": "MIT",
|
|
29
34
|
"packageManager": "pnpm@11.7.0",
|
|
30
35
|
"engines": {
|
|
31
36
|
"node": "^22.19.0 || >=24.0.0"
|
|
@@ -48,6 +53,7 @@
|
|
|
48
53
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
49
54
|
"@deepseek-ai/dsh-agent": "^0.1.0-rc.6",
|
|
50
55
|
"@deepseek-ai/dsh-code-runtime": "^0.1.0-rc.6",
|
|
56
|
+
"@deepseek-ai/dsh-compaction": "^0.1.0-rc.6",
|
|
51
57
|
"@deepseek-ai/dsh-compaction-tool-result-pruner": "^0.1.0-rc.6",
|
|
52
58
|
"@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
|
|
53
59
|
"@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
|