dsh-plugin-om 0.0.25 → 0.0.27

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 CHANGED
@@ -2,35 +2,33 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/dsh-plugin-om.svg)](https://www.npmjs.com/package/dsh-plugin-om)
4
4
 
5
- 在 DSH 里应用 [Observational Memory](https://mastra.ai/research/observational-memory) 风格的上下文管理策略:自动把历史消息压缩为摘要,并提供工具回看原始内容。
5
+ 在 DSH 里应用 [Observational Memory](https://mastra.ai/research/observational-memory) 风格的上下文管理:自动把历史消息压缩为摘要并提供工具回看原始内容。
6
6
 
7
7
  ## 功能
8
8
 
9
- - **自动压缩**(仅主会话,`agent/pre-step` 时阻塞串行执行):
10
- - **观察**:净压力(上下文压力 − 已压缩 `<history>` token 估算合计 − 系统提示词 token 估算 − 工具定义 token 估算)≥ `observeThresholdTokens` 时,摘要未压缩消息并追加为新 `<history>` 块,精确替换被压缩的消息区间(旧块保留)
11
- - **反思**:全部 `<history>` token 合计 `reflectThresholdTokens` 时,把多个摘要块合并为一条更紧凑的摘要
12
- - **输出容错**:摘要输出按首个 `<history>` 开标签到最后一个 `</history>` 定位;整块 XML 非法时按条目标签模糊提取并重建为合法块,再校验无 reasoning 与 index 连续
13
- - **失败中断**:摘要尝试全部耗尽后拒绝当前 step(当前 turn 以 blocked 结束,不再继续 AI 会话;signal 中止除外),最后一次尝试的实际报错写入日志与 `compaction/end` error
14
- - **降级容错**:挂载失败类问题(systemPrompt 服务缺失、tokenMeter 服务异常)不阻塞压缩——systemPrompt 按 0 计、tokenMeter 计价按 0 计或跳过观察;问题始终 `console.warn` 输出到宿主进程外部,并写入 log-only `om/warning` 会话事件(同会话同一问题至多一条)。系统提示词/工具定义估算的普通运行时报错仅记日志,同样按 0 计
15
- - **recall 工具**:按完整消息 index 区间回看原始会话(含被压缩内容;命中消息中的图片附件随结果保留)
16
- - **recall-semantic 工具**:本地嵌入模型(paraphrase-multilingual-MiniLM-L12-v2)按语义检索全部完整消息(只匹配文本,纯图片消息不进候选池)
17
- - **压缩卡片**:浏览器客户端在消息列表渲染折叠式「已压缩」卡片、「正在压缩上下文(观察/反思)…」提示行与可展开的「上下文压缩失败」错误行
18
- - **降级警告行**:浏览器客户端把 `om/warning` 事件渲染为可展开的「上下文压缩功能降级」警告行(折叠摘要 + 完整说明展开)
9
+ - **自动压缩**:仅主会话,在 agent/pre-step 阻塞串行执行。净压力达到 `observeThresholdTokens` 后再累计 `tailMessageCount` 条完整消息时,把触发点前的全部消息摘要为新 `<history>` 块并精确替换对应消息区间;全部 `<history>` 块 token 合计达到 `reflectThresholdTokens` 时把全部块内文拼合为单个 `<history>` 块送入摘要,合并为一条更紧凑的摘要。待定标记以 log-only 会话事件持久化,重启后从日志恢复
10
+ - **输出容错**:摘要输出按 `<history>` 标签定位,整块非法时按条目标签模糊提取并重建为合法块。重试全部耗尽后拒绝当前 step;每次实际发出的摘要调用无论成功失败都把完整提示词与模型原始输出即时落盘为 one-shot 诊断子会话
11
+ - **降级容错**:systemPrompt tokenMeter 服务异常时按 0 计继续压缩,问题通过 console 输出与 log-only `om/warning` 会话事件上报,同会话同一问题至多一条
12
+ - **recall 工具**:按完整消息 index 区间回看原始会话,含被压缩内容,图片附件随结果保留
13
+ - **recall-semantic 工具**:本地嵌入模型 paraphrase-multilingual-MiniLM-L12-v2 按语义检索全部完整消息,只匹配文本,纯图片消息不进候选池
14
+ - **压缩卡片**:浏览器客户端渲染折叠式已压缩卡片、压缩中提示行与可展开的失败错误行
15
+ - **降级警告行**:浏览器客户端把 `om/warning` 事件渲染为可展开的警告行
19
16
 
20
17
  ## 安装与启用
21
18
 
22
- - `$DSH_HOME` 缺省为 `~/.dsh`;*profile* 描述 dsh 进程的启动模式(官方启动命令即名为 `web` 的 profile)
19
+ `$DSH_HOME` 缺省为 `~/.dsh`,profile 描述 dsh 进程的启动模式。
23
20
 
24
21
  ```sh
25
22
  dsh plugin --profile <profile> add dsh-plugin-om
26
23
  ```
27
24
 
28
- 安装完成后重启 dsh;可用 `dsh --profile <profile> --dump-config` 审查配置。
25
+ 安装完成后重启 dsh,可用 `dsh --profile <profile> --dump-config` 审查配置。
29
26
 
30
- > pnpm 11+ 默认禁止依赖构建脚本,安装失败时把 `$DSH_HOME/profiles/<profile>/pnpm-workspace.yaml` 的 `allowBuilds` 改为 `true`,或使用
31
- > `dsh plugin --profile <profile> add dsh-plugin-om --allow-build=onnxruntime-node --allow-build=protobufjs --allow-build=sharp`
27
+ > pnpm 11+ 默认禁止依赖构建脚本,安装失败时把 `$DSH_HOME/profiles/<profile>/pnpm-workspace.yaml` 的 `allowBuilds` 改为 `true`,或安装时追加 `--allow-build=onnxruntime-node --allow-build=protobufjs --allow-build=sharp`
32
28
 
33
- 覆盖默认配置:编辑 `$DSH_HOME/profiles/<profile>/cordis.patch.yml`,删除空数组并加入(可热更新):
29
+ ### 配置覆盖
30
+
31
+ 编辑 `$DSH_HOME/profiles/<profile>/cordis.patch.yml`,删除空数组并加入,可热更新:
34
32
 
35
33
  ```yaml
36
34
  - id: dsh-plugin-om
@@ -40,7 +38,7 @@ dsh plugin --profile <profile> add dsh-plugin-om
40
38
 
41
39
  ### 开发插件
42
40
 
43
- 运行 `pnpm dev` 构建(本地嵌入模型运行时自动下载,也可 `pnpm run download:model` 预下载),在 `cordis.patch.yml` 加入(可热重载):
41
+ 运行 `pnpm dev` 构建,本地嵌入模型运行时自动下载,也可 `pnpm run download:model` 预下载。在 `cordis.patch.yml` 加入,可热重载:
44
42
 
45
43
  ```yaml
46
44
  - insert:
@@ -50,26 +48,29 @@ dsh plugin --profile <profile> add dsh-plugin-om
50
48
 
51
49
  ### 与 compaction-basic 的关系
52
50
 
53
- preset-agent 自带 `compaction-basic` 压缩,也会压缩上下文,其压缩阈值为 80% 上下文窗口,一般会先用om进行压缩。
51
+ preset-agent 自带 compaction-basic 压缩,阈值为上下文窗口的 80%,一般先用 om 进行压缩。
54
52
 
55
53
  ## 插件配置项
56
54
 
57
55
  | 键 | 默认 | 含义 |
58
56
  | --- | --- | --- |
59
- | `observeThresholdTokens` | `45000` | 观察阈值(tokens):净压力(上下文压力 − 已压缩块 − 系统提示词估算 − 工具定义估算)≥ 该值时触发观察压缩 |
60
- | `reflectThresholdTokens` | `120000` | 反思阈值(tokens):全部 `<history>` 块 token 合计 ≥ 该值时触发合并 |
61
- | `compressMaxTokens` | 不设置 | 单次摘要生成上限(不设置时由模型适配器默认值决定) |
62
- | `rateLimitWaitMs` | `60000` | 遇 429 限流后下一次摘要请求前的等待毫秒数(全局冷却期;`0` 不限流) |
63
- | `tailMessageCount` | `5` | 尾部保留的不压缩消息条数 |
64
- | `compressRetryCount` | `5` | 摘要失败后的最大重试次数(不含首次) |
65
- | `modelDir` | 共享目录 | recall-semantic 嵌入模型目录(默认 `$DSH_HOME/plugin-data/dsh-plugin-om/models/<id>`,onnx 缺失且启用语义召回时运行时自动下载) |
66
- | `omEnabled` | `true` | 是否启用自动压缩(`false` 时关闭,recall 工具不受影响) |
67
- | `debug` | dev | 步骤级日志开关(缺省按 `NODE_ENV !== 'production'` 判定;每次压缩尝试的结果/报错与失败日志始终输出) |
57
+ | `observeThresholdTokens` | `45000` | 净压力达到该值时触发观察压缩 |
58
+ | `reflectThresholdTokens` | `120000` | 全部 `<history>` 块 token 合计达到该值时触发反思合并 |
59
+ | `compressMaxTokens` | 不设置 | 单次摘要生成上限,不设置时由模型适配器默认值决定 |
60
+ | `rateLimitWaitMs` | `60000` | 遇 429 限流后下一次摘要请求前的等待毫秒数,`0` 不限流 |
61
+ | `tailMessageCount` | `5` | 观察触发后等待新增完整消息达到该条数才执行压缩,`0` 表示触发当轮立即执行 |
62
+ | `compressRetryCount` | `5` | 摘要失败后的最大重试次数,不含首次 |
63
+ | `compressSkipReasoning` | `true` | 观察压缩请求是否携带被压缩 assistant 消息的 reasoning 思考文本,`true` 时不携带 `<reasoning>` 参考条目,压缩指令同步省略对应说明 |
64
+ | `modelDir` | 共享目录 | recall-semantic 嵌入模型目录,默认 `$DSH_HOME/plugin-data/dsh-plugin-om/models/<id>`,onnx 缺失且启用语义召回时运行时自动下载 |
65
+ | `omEnabled` | `true` | 是否启用自动压缩,关闭后 recall 工具不受影响 |
66
+ | `debug` | dev | 步骤级日志开关,缺省按 `NODE_ENV` 非 production 判定,压缩尝试结果与失败日志始终输出 |
68
67
  | `recallEnabled` | `true` | 是否注册 `recall` 工具 |
69
- | `semanticRecallEnabled` | `true` | 是否注册 `recall-semantic` 工具(`false` 时不注册、不触发模型下载) |
68
+ | `semanticRecallEnabled` | `true` | 是否注册 `recall-semantic` 工具,关闭时不触发模型下载 |
70
69
 
71
70
  > 不建议把观察阈值设置得过高:越早压缩收益越高,且机制依赖模型对消息计数,过多消息会导致历史混乱。
72
71
 
72
+ > 想直观理解机制并估算不同参数下的 token 成本,可打开交互式[机制说明与成本计算器](https://fanethedivine.github.io/dsh-plugin-om/),部署在 GitHub Pages,不随插件包分发。
73
+
73
74
  ## npm 命令
74
75
 
75
76
  | 命令 | 作用 |
@@ -78,40 +79,45 @@ preset-agent 自带 `compaction-basic` 压缩,也会压缩上下文,其压
78
79
  | `pnpm typecheck` | TypeScript 类型检查 |
79
80
  | `pnpm lint` / `pnpm format` | 代码检查 / 格式化 |
80
81
  | `pnpm test` | vitest 单元测试 |
81
- | `pnpm run download:model` | 手动预下载嵌入模型(已存在跳过,`--force` 重下) |
82
+ | `pnpm run download:model` | 手动预下载嵌入模型,已存在跳过,`--force` 重下 |
82
83
  | `pnpm build` / `pnpm dev` | 构建 / 自动打包 |
83
84
  | `pnpm run release` | check → CHANGELOG 归档 → 版本号更新 → 打 tag 推送 |
84
85
 
85
86
  ## 文件地图
86
87
 
87
88
  ```
88
- cordis.patch.yml # bundle patchdsh plugin add 后作为组合层插入插件行
89
+ cordis.patch.yml # bundle patchdsh plugin add 后作为组合层插入插件行
89
90
  src/
90
- ├── index.ts # 打包入口:注册 recall 工具 + 接线 pre-step 自动压缩
91
- ├── config.ts # 配置默认值与宽松合并(未知键忽略、非法值回退默认)
92
- ├── constants.ts # 共享常量(插件标识 / history 标签 / 完整消息定义)
93
- ├── degrade.ts # 挂载失败降级上报(console 外部输出 + om/warning 会话事件,每会话去重)
94
- ├── types.ts # type-only:宿主类型再导出 + 领域类型
95
- ├── utils.ts # 零依赖工具函数(文本渲染 / 主会话判定 / 路由解析)
96
- ├── logger.ts # 插件日志门面(step debug 开关过滤)
97
- ├── rate-limit.ts # 全局 429 限流冷却门(进程级共享状态)
98
- ├── log-index.ts # 完整消息索引与渲染(recall 与摘要共用同一套编号)
99
- ├── recall.ts # recall 工具:按完整消息 index 区间回看
100
- ├── recall-output.ts # recall 输出契约:{ text, images } 与 render 投影
101
- ├── semantic-recall.ts # recall-semantic 工具:本地嵌入语义检索
102
- ├── embedding.ts # 本地 ONNX 嵌入(懒加载 / 批量 / 运行时按需下载编排)
103
- ├── model-download.ts # 模型下载原语(URL / 跳过判定 / 原子落盘)
104
- ├── summarize.ts # 共享压缩提示词 + <history> 块渲染与输出校验 + 摘要调用
105
- ├── compress.ts # 两级自动压缩(观察/反思)、失败中断传播与 compaction 生命周期事件
106
- └── client/ # 浏览器客户端 bundle(压缩卡片)
107
- ├── index.ts # 客户端入口:注册卡片定义与渲染器
108
- ├── definition.ts # 压缩卡片业务定义(认领生命周期事件、替换检查点与 om/warning)
109
- ├── OmCompactionCard.tsx # 折叠卡片渲染器(统计标题 + summary/失败报错展开)
110
- ├── OmWarningCard.tsx # 功能降级警告行渲染器(折叠摘要 + 完整说明展开)
111
- ├── format.ts # 统计数字紧凑格式化(k/w/M)
112
- └── locales.ts # om-compaction 文案字典(zh/en)
113
- models/ # 嵌入模型目录(小文件随包分发;onnx 运行时按需下载,不进 git)
114
- scripts/ # release-archive.mjs(CHANGELOG 归档)/ download-model.mjs(预下载 CLI)
115
- tests/ # vitest 测试(服务端各模块 + tests/client/ 客户端卡片 + 整条链路集成测试)
91
+ ├── index.ts # 打包入口:注册 recall 工具并接线 pre-step 自动压缩
92
+ ├── config.ts # 配置默认值与宽松合并,未知键忽略、非法值回退默认
93
+ ├── constants.ts # 共享常量:插件标识、history 标签、完整消息定义
94
+ ├── degrade.ts # 挂载失败降级上报:console 外部输出与 om/warning 会话事件
95
+ ├── types.ts # type-only:宿主类型再导出与领域类型
96
+ ├── utils.ts # 零依赖工具函数:文本渲染、主会话判定、路由解析
97
+ ├── json-schema.ts # zod schema 到工具 wire 参数 JSON Schema 的转换
98
+ ├── logger.ts # 插件日志门面,step debug 开关过滤
99
+ ├── rate-limit.ts # 全局 429 限流冷却门,进程级共享状态
100
+ ├── log-index.ts # 完整消息索引与渲染,recall 与摘要共用同一套编号
101
+ ├── recall.ts # recall 工具:按完整消息 index 区间回看
102
+ ├── recall-output.ts # recall 输出契约:{ text, images } 与 render 投影
103
+ ├── semantic-recall.ts # recall-semantic 工具:本地嵌入语义检索
104
+ ├── embedding.ts # 本地 ONNX 嵌入:懒加载、批量、运行时按需下载编排
105
+ ├── model-download.ts # 模型下载原语:URL、跳过判定、原子落盘
106
+ ├── summarize.ts # 共享压缩提示词、history 块渲染与输出校验、摘要调用
107
+ ├── compaction-log.ts # 压缩日志落盘:诊断子会话创建与单次尝试原样消息组
108
+ ├── compress.ts # 两级自动压缩:观察与反思、失败中断传播、compaction 生命周期事件
109
+ └── client/ # 浏览器客户端 bundle:压缩卡片
110
+ ├── index.ts # 客户端入口:注册卡片定义与渲染器
111
+ ├── definition.ts # 压缩卡片业务定义:认领生命周期事件、检查点替换与 om/warning
112
+ ├── OmCompactionCard.tsx # 折叠卡片渲染器:统计标题与 summary、失败报错展开
113
+ ├── OmWarningCard.tsx # 功能降级警告行渲染器:折叠摘要与完整说明展开
114
+ ├── format.ts # 统计数字紧凑格式化:k、w、M
115
+ └── locales.ts # om-compaction 文案字典:zh en
116
+ models/ # 嵌入模型目录:小文件随包分发,onnx 运行时按需下载,不进 git
117
+ scripts/ # release-archive.mjs 为 CHANGELOG 归档脚本,download-model.mjs 为预下载 CLI
118
+ tests/ # vitest 测试:服务端各模块、客户端卡片、成本模型与整条链路集成测试
119
+ web/ # 机制说明与成本计算器站点:独立 Vite + React + Tailwind CSS + shadcn/ui 工程,发布到 GitHub Pages,不随插件包分发
120
+ ├── src/model.ts # 成本模型纯函数:om 开关全会话模拟与三类 token 计价
121
+ └── src/components/ # 机制简述、侧边栏参数面板、合并单元格成本表、shadcn/ui 原语
122
+ .github/workflows/web-deploy.yml # web/ 变更合入 main 时构建并部署 GitHub Pages
116
123
  ```
117
-
@@ -0,0 +1,43 @@
1
+ /**
2
+ * 压缩调用日志落盘:摘要 run 的每次 LLM 调用(每次尝试,无论成功失败)完成后,
3
+ * 把该次尝试的完整提示词与模型原始输出原样落盘为一个 one-shot 诊断子会话
4
+ * (header origin 'subagent' + 首事件 subagent/descriptor),使其以 subagent 形式
5
+ * 出现在宿主子代理列表中,便于查验每次调用的完整会话。导出 recordCompactionAttempt /
6
+ * SummaryAttemptRecord / compactionLogLabel / COMPACTION_LOG_PROVIDER。
7
+ *
8
+ * - 子会话内容零加工:一对 user/message(实际提示词全文,含 <history> 块)
9
+ * + assistant/message(模型原始输出全文,异常/中止时为已收集的部分输出),
10
+ * 不插入任何额外消息;成败与原因不进子会话,由调用方写入主会话日志并关联子会话 id
11
+ * - 落盘自身绝不抛错:任何失败仅 logger.warn 并返回 undefined,不影响压缩流程
12
+ */
13
+ import type { Context, Session } from './types.ts';
14
+ import { type RoutedTarget } from './utils.ts';
15
+ /** 诊断子会话的 descriptor provider(宿主子代理列表识别用)。 */
16
+ export declare const COMPACTION_LOG_PROVIDER = "om-compaction-log";
17
+ /** 一次摘要尝试的完整记录:prompt=实际提示词全文(含 <history> 块),rawOutput=模型原始输出全文。 */
18
+ export type SummaryAttemptRecord = {
19
+ prompt: string;
20
+ rawOutput: string;
21
+ };
22
+ /** 诊断子会话 label:含压缩阶段与尝试序号。 */
23
+ export declare function compactionLogLabel(phase: 'observe' | 'reflect' | undefined, attemptNo: number): string;
24
+ /**
25
+ * 把一次摘要尝试落盘为诊断子会话:ctx.sessions.create 创建子会话(header origin
26
+ * 'subagent'、parentSession 指向主会话、delegationDepth = 父 + 1、cwd 继承主会话),
27
+ * 追加 one-shot descriptor(provider om-compaction-log,label 含压缩阶段与尝试序号),
28
+ * 原样追加「提示词 + 原始输出」消息组,flush 持久化检查点,返回子会话 id。落盘自身
29
+ * 绝不抛错:任何失败仅 logger.warn 并返回 undefined(不影响压缩流程)。
30
+ */
31
+ export declare function recordCompactionAttempt(ctx: Context, parentSession: Session, options: {
32
+ /** 压缩 pass(诊断子会话 label 用)。 */
33
+ phase: 'observe' | 'reflect' | undefined;
34
+ /** 摘要调用的路由目标(assistant/message 的 model 来源标记)。 */
35
+ target: RoutedTarget;
36
+ /** 本次尝试的完整记录(提示词 + 原始输出)。 */
37
+ attempt: SummaryAttemptRecord;
38
+ /** 尝试序号(1 起,label 与消息 step 标注用)。 */
39
+ attemptNo: number;
40
+ /** 插件 debug 开关(落盘失败的 warn 是否带步骤细节)。 */
41
+ debug: boolean;
42
+ }): Promise<string | undefined>;
43
+ //# sourceMappingURL=compaction-log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compaction-log.d.ts","sourceRoot":"","sources":["../src/compaction-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,KAAK,YAAY,EAAQ,MAAM,YAAY,CAAC;AAErD,8CAA8C;AAC9C,eAAO,MAAM,uBAAuB,sBAAsB,CAAC;AAE3D,oEAAoE;AACpE,MAAM,MAAM,oBAAoB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AASzE,8BAA8B;AAC9B,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,EACxC,SAAS,EAAE,MAAM,GAChB,MAAM,CAER;AA8BD;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,OAAO,EACZ,aAAa,EAAE,OAAO,EACtB,OAAO,EAAE;IACP,8BAA8B;IAC9B,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IACzC,iDAAiD;IACjD,MAAM,EAAE,YAAY,CAAC;IACrB,6BAA6B;IAC7B,OAAO,EAAE,oBAAoB,CAAC;IAC9B,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,KAAK,EAAE,OAAO,CAAC;CAChB,GACA,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA+B7B"}
@@ -1,12 +1,17 @@
1
1
  import type { Agent, Context, PluginConfig, Session } from './types.ts';
2
2
  import { type RoutedTarget } from './utils.ts';
3
- /** 压缩 pass 结果:failed=false 表示无需中断(成功、跳过或非摘要耗尽的局部失败);failed=true 携带最后一次尝试的实际报错与是否因 signal 中止。 */
3
+ /**
4
+ * 压缩 pass 结果:failed=false 表示无需中断(成功、跳过或非摘要耗尽的局部失败);
5
+ * failed=true 携带最后一次尝试的实际报错、是否因 signal 中止与诊断子会话 id
6
+ * (最终失败时每次尝试的完整提示词与模型原始输出落盘为诊断子会话;落盘失败时缺失)。
7
+ */
4
8
  export type CompressPassResult = {
5
9
  failed: false;
6
10
  } | {
7
11
  failed: true;
8
12
  error: string;
9
13
  aborted: boolean;
14
+ diagnosticSessionId?: string;
10
15
  };
11
16
  /** 历史文本 token 估算:4 字符 ≈ 1 token(与宿主 dsh-token-meter 启发式一致)。 */
12
17
  export declare function estimateTextTokens(text: string): number;
@@ -16,11 +21,12 @@ export declare function estimateTextTokens(text: string): number;
16
21
  */
17
22
  export declare function isPairBalancedAfter(session: Session, seq: number): boolean;
18
23
  /**
19
- * 观察压缩区间:压缩边界后的首个表层节点 → 表层长度-1-tailCount(尾部保留 tailCount
20
- * 条不压缩);区间终点回退到 tool-call/result 配对平衡点(不切段)。无可行区间返回
21
- * undefined。返回区间起止表层 seq 与被遮蔽 seq 列表。
24
+ * 观察压缩区间:压缩边界后的首个表层节点 → 触发点完整消息(endMessageIndex)对应的
25
+ * 表层终点(取该完整消息最后一个事件 seq 在表层中的位置);区间终点回退到
26
+ * tool-call/result 配对平衡点(不切段)。触发点完整消息不存在或其事件已不在表层
27
+ * (被后续压缩遮蔽)时返回 undefined。返回区间起止表层 seq 与被遮蔽 seq 列表。
22
28
  */
23
- export declare function computeCompressRange(session: Session, tailCount: number): {
29
+ export declare function computeCompressRange(session: Session, endMessageIndex: number): {
24
30
  start: number;
25
31
  end: number;
26
32
  shadowedSeqs: number[];
@@ -39,18 +45,32 @@ export declare function historySection(session: Session): {
39
45
  boundarySeq: number | undefined;
40
46
  };
41
47
  /**
42
- * 反思:全部 <history> 块 token 合计 ≥ reflectThresholdTokens 时,摘要调用把整个块
43
- * 区段合并替换为一条更紧凑的摘要。失败不产生部分替换;摘要尝试全部耗尽返回
44
- * 失败结果(error = 最后一次尝试的实际报错/具体问题)。
48
+ * 查找当前活跃的观察压缩待定标记:按日志顺序取最后一条 om/observe-pending,其后须无
49
+ * 引用它的 om/observe-invalidate(已失效),且其后的压缩边界 seq 不大于标记 seq(边界
50
+ * 后移说明标记期间已发生过压缩,标记过期——兜底「执行成功但失效标记未写出」的崩溃
51
+ * 窗口)。无活跃标记返回 undefined。
52
+ */
53
+ export declare function findObservePending(session: Session): {
54
+ seq: number;
55
+ triggerMessageIndex: number;
56
+ } | undefined;
57
+ /**
58
+ * 反思:全部 <history> 块 token 合计 ≥ reflectThresholdTokens 时,全部块内文拼合为
59
+ * 单个 <history> 块送入摘要调用,整个块区段合并替换为一条更紧凑的摘要。失败不产生
60
+ * 部分替换;摘要尝试全部耗尽返回失败结果(error = 最后一次尝试的实际报错/具体问题)。
45
61
  */
46
62
  export declare function reflectPass(ctx: Context, agent: Agent, config: Readonly<PluginConfig>, target: RoutedTarget, signal?: AbortSignal): Promise<CompressPassResult>;
47
63
  /**
48
- * 观察:净压力 tokens(上下文压力 已压缩 <history> token 合计 系统提示词
49
- * token 估算 − 工具定义 token 估算)≥ observeThresholdTokens 时,摘要调用把未压缩
50
- * 消息压缩为观察日志,追加到旧摘要并替换被压缩消息区间。失败不产生部分替换;
51
- * 摘要尝试全部耗尽返回失败结果(error = 最后一次尝试的实际报错/具体问题)。
64
+ * 观察(触发 待定 延迟执行):无活跃待定标记时测净压力 tokens(上下文压力已压缩
65
+ * <history> 块 token 合计 − 系统提示词 token 估算 − 工具定义 token 估算),首次
66
+ * observeThresholdTokens 时记录待定标记(触发点 = 当时的最后一条完整消息 index),本次
67
+ * 不压缩(tailMessageCount=0 当轮直接执行,不落待定标记);已有待定标记时按新增完整
68
+ * 消息数 ≥ tailMessageCount 决定执行,压缩区间截至触发点(新增消息成为新未压缩尾部,
69
+ * 延迟窗口内压力允许短暂超阈值)。执行成功(或无可行区间)后写待定失效标记;摘要
70
+ * 失败保留待定,下个 pre-step 直接重试执行。摘要尝试全部耗尽返回失败结果
71
+ * (error = 最后一次尝试的实际报错/具体问题)。
52
72
  */
53
- export declare function observePass(ctx: Context, agent: Agent, config: Readonly<PluginConfig>, tailCount: number, target: RoutedTarget, signal?: AbortSignal): Promise<CompressPassResult>;
73
+ export declare function observePass(ctx: Context, agent: Agent, config: Readonly<PluginConfig>, waitCount: number, target: RoutedTarget, signal?: AbortSignal): Promise<CompressPassResult>;
54
74
  /**
55
75
  * 压力检查 + 两级压缩入口:先反思后观察,pre-step 阻塞串行执行;仅主会话生效。
56
76
  * 反思摘要耗尽失败时直接返回失败结果(观察无需继续,本轮将被拒绝);观察失败同样
@@ -1 +1 @@
1
- {"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EACV,KAAK,EAIL,OAAO,EACP,YAAY,EACZ,OAAO,EAIR,MAAM,YAAY,CAAC;AACpB,OAAO,EAAgB,KAAK,YAAY,EAAqC,MAAM,YAAY,CAAC;AAEhG,gGAAgG;AAChG,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,KAAK,CAAA;CAAE,GACjB;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtD,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AA4CD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAY1E;AAED;;;;GAIG;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,CAAA;CAAE,GAAG,SAAS,CAqBpE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG;IAChD,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7C,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC,CAUA;AA0GD;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC9B,MAAM,EAAE,YAAY,EACpB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,kBAAkB,CAAC,CAiH7B;AAwED;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC9B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,EACpB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,kBAAkB,CAAC,CA0J7B;AAED;;;;GAIG;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,kBAAkB,CAAC,CAwB7B"}
1
+ {"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EACV,KAAK,EAKL,OAAO,EACP,YAAY,EACZ,OAAO,EAIR,MAAM,YAAY,CAAC;AACpB,OAAO,EAAgB,KAAK,YAAY,EAAqC,MAAM,YAAY,CAAC;AAEhG;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,KAAK,CAAA;CAAE,GACjB;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpF,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAuDD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAY1E;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,eAAe,EAAE,MAAM,GACtB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,CA8BpE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG;IAChD,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7C,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC,CAUA;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,GACf;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAmB1D;AA0HD;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC9B,MAAM,EAAE,YAAY,EACpB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,kBAAkB,CAAC,CAgI7B;AAwED;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC9B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,EACpB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,kBAAkB,CAAC,CAwO7B;AAED;;;;GAIG;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,kBAAkB,CAAC,CAwB7B"}
package/dist/config.d.ts CHANGED
@@ -8,10 +8,12 @@ export type PluginConfig = {
8
8
  compressMaxTokens: number | undefined;
9
9
  /** 遇 429 限流后下一次摘要请求前的等待毫秒数(全局冷却期)。 */
10
10
  rateLimitWaitMs: number;
11
- /** 尾部保留的不压缩消息条数。 */
11
+ /** 观察触发后延迟执行的等待完整消息条数(新增完整消息数达到该值才执行压缩;0 表示触发当轮立即执行)。 */
12
12
  tailMessageCount: number;
13
13
  /** 摘要失败后的最大重试次数(不含首次)。 */
14
14
  compressRetryCount: number;
15
+ /** 压缩输入是否携带被压缩消息的 reasoning 思考文本(true 时压缩请求不含 <reasoning> 参考条目,压缩提示词也省略其说明)。 */
16
+ compressSkipReasoning: boolean;
15
17
  /** 是否启用自动压缩(观察/反思)。 */
16
18
  omEnabled: boolean;
17
19
  /** 步骤级日志开关(缺省按 NODE_ENV !== 'production' 判定)。 */
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAQA,kCAAkC;AAClC,MAAM,MAAM,YAAY,GAAG;IACzB,oCAAoC;IACpC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,wDAAwD;IACxD,sBAAsB,EAAE,MAAM,CAAC;IAC/B,2DAA2D;IAC3D,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,sCAAsC;IACtC,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,0BAA0B;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,uBAAuB;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,iDAAiD;IACjD,KAAK,EAAE,OAAO,CAAC;IACf,sBAAsB;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,+CAA+C;IAC/C,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kBAAkB;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,YAAY,CAYhD,CAAC;AAqCH,wCAAwC;AACxC,wBAAgB,aAAa,CAAC,GAAG,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC,YAAY,CAAC,CAoBnE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAQA,kCAAkC;AAClC,MAAM,MAAM,YAAY,GAAG;IACzB,oCAAoC;IACpC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,wDAAwD;IACxD,sBAAsB,EAAE,MAAM,CAAC;IAC/B,2DAA2D;IAC3D,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,sCAAsC;IACtC,eAAe,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,gBAAgB,EAAE,MAAM,CAAC;IACzB,0BAA0B;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gFAAgF;IAChF,qBAAqB,EAAE,OAAO,CAAC;IAC/B,uBAAuB;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,iDAAiD;IACjD,KAAK,EAAE,OAAO,CAAC;IACf,sBAAsB;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,+CAA+C;IAC/C,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kBAAkB;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,YAAY,CAahD,CAAC;AAqCH,wCAAwC;AACxC,wBAAgB,aAAa,CAAC,GAAG,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC,YAAY,CAAC,CAqBnE"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,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,yCAAyC;AACzC,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAoD1D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,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,yCAAyC;AACzC,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAwD1D"}