dsh-plugin-om 0.0.26 → 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 +62 -64
- package/dist/compaction-log.d.ts +21 -21
- package/dist/compaction-log.d.ts.map +1 -1
- package/dist/compress.d.ts +3 -3
- package/dist/compress.d.ts.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/index.mjs +115 -83
- package/dist/summarize.d.ts +24 -13
- package/dist/summarize.d.ts.map +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,36 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
[](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
|
-
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- **recall 工具**:按完整消息 index 区间回看原始会话(含被压缩内容;命中消息中的图片附件随结果保留)
|
|
17
|
-
- **recall-semantic 工具**:本地嵌入模型(paraphrase-multilingual-MiniLM-L12-v2)按语义检索全部完整消息(只匹配文本,纯图片消息不进候选池)
|
|
18
|
-
- **压缩卡片**:浏览器客户端在消息列表渲染折叠式「已压缩」卡片、「正在压缩上下文(观察/反思)…」提示行与可展开的「上下文压缩失败」错误行
|
|
19
|
-
- **降级警告行**:浏览器客户端把 `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` 事件渲染为可展开的警告行
|
|
20
16
|
|
|
21
17
|
## 安装与启用
|
|
22
18
|
|
|
23
|
-
|
|
19
|
+
`$DSH_HOME` 缺省为 `~/.dsh`,profile 描述 dsh 进程的启动模式。
|
|
24
20
|
|
|
25
21
|
```sh
|
|
26
22
|
dsh plugin --profile <profile> add dsh-plugin-om
|
|
27
23
|
```
|
|
28
24
|
|
|
29
|
-
安装完成后重启 dsh
|
|
25
|
+
安装完成后重启 dsh,可用 `dsh --profile <profile> --dump-config` 审查配置。
|
|
30
26
|
|
|
31
|
-
> pnpm 11+ 默认禁止依赖构建脚本,安装失败时把 `$DSH_HOME/profiles/<profile>/pnpm-workspace.yaml` 的 `allowBuilds` 改为 `true
|
|
32
|
-
> `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`
|
|
33
28
|
|
|
34
|
-
|
|
29
|
+
### 配置覆盖
|
|
30
|
+
|
|
31
|
+
编辑 `$DSH_HOME/profiles/<profile>/cordis.patch.yml`,删除空数组并加入,可热更新:
|
|
35
32
|
|
|
36
33
|
```yaml
|
|
37
34
|
- id: dsh-plugin-om
|
|
@@ -41,7 +38,7 @@ dsh plugin --profile <profile> add dsh-plugin-om
|
|
|
41
38
|
|
|
42
39
|
### 开发插件
|
|
43
40
|
|
|
44
|
-
运行 `pnpm dev`
|
|
41
|
+
运行 `pnpm dev` 构建,本地嵌入模型运行时自动下载,也可 `pnpm run download:model` 预下载。在 `cordis.patch.yml` 加入,可热重载:
|
|
45
42
|
|
|
46
43
|
```yaml
|
|
47
44
|
- insert:
|
|
@@ -51,27 +48,28 @@ dsh plugin --profile <profile> add dsh-plugin-om
|
|
|
51
48
|
|
|
52
49
|
### 与 compaction-basic 的关系
|
|
53
50
|
|
|
54
|
-
preset-agent 自带
|
|
51
|
+
preset-agent 自带 compaction-basic 压缩,阈值为上下文窗口的 80%,一般先用 om 进行压缩。
|
|
55
52
|
|
|
56
53
|
## 插件配置项
|
|
57
54
|
|
|
58
55
|
| 键 | 默认 | 含义 |
|
|
59
56
|
| --- | --- | --- |
|
|
60
|
-
| `observeThresholdTokens` | `45000` |
|
|
61
|
-
| `reflectThresholdTokens` | `120000` |
|
|
62
|
-
| `compressMaxTokens` | 不设置 |
|
|
63
|
-
| `rateLimitWaitMs` | `60000` | 遇 429
|
|
64
|
-
| `tailMessageCount` | `5` |
|
|
65
|
-
| `compressRetryCount` | `5` |
|
|
66
|
-
| `
|
|
67
|
-
| `
|
|
68
|
-
| `
|
|
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 判定,压缩尝试结果与失败日志始终输出 |
|
|
69
67
|
| `recallEnabled` | `true` | 是否注册 `recall` 工具 |
|
|
70
|
-
| `semanticRecallEnabled` | `true` | 是否注册 `recall-semantic`
|
|
68
|
+
| `semanticRecallEnabled` | `true` | 是否注册 `recall-semantic` 工具,关闭时不触发模型下载 |
|
|
71
69
|
|
|
72
70
|
> 不建议把观察阈值设置得过高:越早压缩收益越高,且机制依赖模型对消息计数,过多消息会导致历史混乱。
|
|
73
71
|
|
|
74
|
-
> 想直观理解机制并估算不同参数下的 token 成本,可打开交互式[机制说明与成本计算器](https://fanethedivine.github.io/dsh-plugin-om/)
|
|
72
|
+
> 想直观理解机制并估算不同参数下的 token 成本,可打开交互式[机制说明与成本计算器](https://fanethedivine.github.io/dsh-plugin-om/),部署在 GitHub Pages,不随插件包分发。
|
|
75
73
|
|
|
76
74
|
## npm 命令
|
|
77
75
|
|
|
@@ -81,45 +79,45 @@ preset-agent 自带 `compaction-basic` 压缩,也会压缩上下文,其压
|
|
|
81
79
|
| `pnpm typecheck` | TypeScript 类型检查 |
|
|
82
80
|
| `pnpm lint` / `pnpm format` | 代码检查 / 格式化 |
|
|
83
81
|
| `pnpm test` | vitest 单元测试 |
|
|
84
|
-
| `pnpm run download:model` |
|
|
82
|
+
| `pnpm run download:model` | 手动预下载嵌入模型,已存在跳过,`--force` 重下 |
|
|
85
83
|
| `pnpm build` / `pnpm dev` | 构建 / 自动打包 |
|
|
86
84
|
| `pnpm run release` | check → CHANGELOG 归档 → 版本号更新 → 打 tag 推送 |
|
|
87
85
|
|
|
88
86
|
## 文件地图
|
|
89
87
|
|
|
90
88
|
```
|
|
91
|
-
cordis.patch.yml
|
|
89
|
+
cordis.patch.yml # bundle patch,dsh plugin add 后作为组合层插入插件行
|
|
92
90
|
src/
|
|
93
|
-
├── index.ts
|
|
94
|
-
├── config.ts
|
|
95
|
-
├── constants.ts
|
|
96
|
-
├── degrade.ts
|
|
97
|
-
├── types.ts
|
|
98
|
-
├── utils.ts
|
|
99
|
-
├──
|
|
100
|
-
├──
|
|
101
|
-
├──
|
|
102
|
-
├──
|
|
103
|
-
├── recall
|
|
104
|
-
├──
|
|
105
|
-
├──
|
|
106
|
-
├──
|
|
107
|
-
├──
|
|
108
|
-
├──
|
|
109
|
-
├──
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
├──
|
|
113
|
-
├──
|
|
114
|
-
├──
|
|
115
|
-
├──
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
|
124
123
|
```
|
|
125
|
-
|
package/dist/compaction-log.d.ts
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* subagent/descriptor),使其以 subagent
|
|
5
|
-
*
|
|
6
|
-
* compactionLogLabel / COMPACTION_LOG_PROVIDER。
|
|
2
|
+
* 压缩调用日志落盘:摘要 run 的每次 LLM 调用(每次尝试,无论成功失败)完成后,
|
|
3
|
+
* 把该次尝试的完整提示词与模型原始输出原样落盘为一个 one-shot 诊断子会话
|
|
4
|
+
* (header origin 'subagent' + 首事件 subagent/descriptor),使其以 subagent 形式
|
|
5
|
+
* 出现在宿主子代理列表中,便于查验每次调用的完整会话。导出 recordCompactionAttempt /
|
|
6
|
+
* SummaryAttemptRecord / compactionLogLabel / COMPACTION_LOG_PROVIDER。
|
|
7
7
|
*
|
|
8
|
-
* -
|
|
8
|
+
* - 子会话内容零加工:一对 user/message(实际提示词全文,含 <history> 块)
|
|
9
9
|
* + assistant/message(模型原始输出全文,异常/中止时为已收集的部分输出),
|
|
10
|
-
*
|
|
11
|
-
* -
|
|
12
|
-
* - 落盘自身绝不抛错:任何失败仅 logger.warn 并返回 undefined,不影响压缩失败流程
|
|
10
|
+
* 不插入任何额外消息;成败与原因不进子会话,由调用方写入主会话日志并关联子会话 id
|
|
11
|
+
* - 落盘自身绝不抛错:任何失败仅 logger.warn 并返回 undefined,不影响压缩流程
|
|
13
12
|
*/
|
|
14
13
|
import type { Context, Session } from './types.ts';
|
|
15
14
|
import { type RoutedTarget } from './utils.ts';
|
|
16
15
|
/** 诊断子会话的 descriptor provider(宿主子代理列表识别用)。 */
|
|
17
16
|
export declare const COMPACTION_LOG_PROVIDER = "om-compaction-log";
|
|
18
|
-
/**
|
|
17
|
+
/** 一次摘要尝试的完整记录:prompt=实际提示词全文(含 <history> 块),rawOutput=模型原始输出全文。 */
|
|
19
18
|
export type SummaryAttemptRecord = {
|
|
20
19
|
prompt: string;
|
|
21
20
|
rawOutput: string;
|
|
22
21
|
};
|
|
23
|
-
/** 诊断子会话 label
|
|
24
|
-
export declare function compactionLogLabel(phase: 'observe' | 'reflect' | undefined,
|
|
22
|
+
/** 诊断子会话 label:含压缩阶段与尝试序号。 */
|
|
23
|
+
export declare function compactionLogLabel(phase: 'observe' | 'reflect' | undefined, attemptNo: number): string;
|
|
25
24
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* undefined(不影响压缩失败流程)。
|
|
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(不影响压缩流程)。
|
|
32
30
|
*/
|
|
33
|
-
export declare function
|
|
31
|
+
export declare function recordCompactionAttempt(ctx: Context, parentSession: Session, options: {
|
|
34
32
|
/** 压缩 pass(诊断子会话 label 用)。 */
|
|
35
33
|
phase: 'observe' | 'reflect' | undefined;
|
|
36
34
|
/** 摘要调用的路由目标(assistant/message 的 model 来源标记)。 */
|
|
37
35
|
target: RoutedTarget;
|
|
38
|
-
/**
|
|
39
|
-
|
|
36
|
+
/** 本次尝试的完整记录(提示词 + 原始输出)。 */
|
|
37
|
+
attempt: SummaryAttemptRecord;
|
|
38
|
+
/** 尝试序号(1 起,label 与消息 step 标注用)。 */
|
|
39
|
+
attemptNo: number;
|
|
40
40
|
/** 插件 debug 开关(落盘失败的 warn 是否带步骤细节)。 */
|
|
41
41
|
debug: boolean;
|
|
42
42
|
}): Promise<string | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compaction-log.d.ts","sourceRoot":"","sources":["../src/compaction-log.ts"],"names":[],"mappings":"AAAA
|
|
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"}
|
package/dist/compress.d.ts
CHANGED
|
@@ -55,9 +55,9 @@ export declare function findObservePending(session: Session): {
|
|
|
55
55
|
triggerMessageIndex: number;
|
|
56
56
|
} | undefined;
|
|
57
57
|
/**
|
|
58
|
-
* 反思:全部 <history> 块 token 合计 ≥ reflectThresholdTokens
|
|
59
|
-
*
|
|
60
|
-
*
|
|
58
|
+
* 反思:全部 <history> 块 token 合计 ≥ reflectThresholdTokens 时,全部块内文拼合为
|
|
59
|
+
* 单个 <history> 块送入摘要调用,整个块区段合并替换为一条更紧凑的摘要。失败不产生
|
|
60
|
+
* 部分替换;摘要尝试全部耗尽返回失败结果(error = 最后一次尝试的实际报错/具体问题)。
|
|
61
61
|
*/
|
|
62
62
|
export declare function reflectPass(ctx: Context, agent: Agent, config: Readonly<PluginConfig>, target: RoutedTarget, signal?: AbortSignal): Promise<CompressPassResult>;
|
|
63
63
|
/**
|
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":"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
|
@@ -12,6 +12,8 @@ export type PluginConfig = {
|
|
|
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' 判定)。 */
|
package/dist/config.d.ts.map
CHANGED
|
@@ -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,yDAAyD;IACzD,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,
|
|
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"}
|
package/dist/index.mjs
CHANGED
|
@@ -7482,9 +7482,9 @@ function phaseLabel(phase) {
|
|
|
7482
7482
|
if (phase === "reflect") return "反思";
|
|
7483
7483
|
return "压缩";
|
|
7484
7484
|
}
|
|
7485
|
-
/** 诊断子会话 label
|
|
7486
|
-
function compactionLogLabel(phase,
|
|
7487
|
-
return `OM
|
|
7485
|
+
/** 诊断子会话 label:含压缩阶段与尝试序号。 */
|
|
7486
|
+
function compactionLogLabel(phase, attemptNo) {
|
|
7487
|
+
return `OM 压缩日志(${phaseLabel(phase)} · 第 ${attemptNo} 次尝试)`;
|
|
7488
7488
|
}
|
|
7489
7489
|
/** 追加一次尝试的「提示词 → 原始输出」消息组(surfaceOp append;id 为品牌类型,session.append 运行时校验)。 */
|
|
7490
7490
|
function appendAttemptMessages(child, attempt, step, target) {
|
|
@@ -7521,14 +7521,13 @@ function appendAttemptMessages(child, attempt, step, target) {
|
|
|
7521
7521
|
}, { surfaceOp: "append" });
|
|
7522
7522
|
}
|
|
7523
7523
|
/**
|
|
7524
|
-
*
|
|
7525
|
-
*
|
|
7526
|
-
*
|
|
7527
|
-
*
|
|
7528
|
-
*
|
|
7529
|
-
* undefined(不影响压缩失败流程)。
|
|
7524
|
+
* 把一次摘要尝试落盘为诊断子会话:ctx.sessions.create 创建子会话(header origin
|
|
7525
|
+
* 'subagent'、parentSession 指向主会话、delegationDepth = 父 + 1、cwd 继承主会话),
|
|
7526
|
+
* 追加 one-shot descriptor(provider om-compaction-log,label 含压缩阶段与尝试序号),
|
|
7527
|
+
* 原样追加「提示词 + 原始输出」消息组,flush 持久化检查点,返回子会话 id。落盘自身
|
|
7528
|
+
* 绝不抛错:任何失败仅 logger.warn 并返回 undefined(不影响压缩流程)。
|
|
7530
7529
|
*/
|
|
7531
|
-
async function
|
|
7530
|
+
async function recordCompactionAttempt(ctx, parentSession, options) {
|
|
7532
7531
|
const logger = makeLogger(ctx, options.debug);
|
|
7533
7532
|
try {
|
|
7534
7533
|
const header = parentSession.header;
|
|
@@ -7542,23 +7541,19 @@ async function recordCompactionFailure(ctx, parentSession, options) {
|
|
|
7542
7541
|
version: SUBAGENT_DESCRIPTOR_VERSION,
|
|
7543
7542
|
mode: "one-shot",
|
|
7544
7543
|
provider: COMPACTION_LOG_PROVIDER,
|
|
7545
|
-
label: compactionLogLabel(options.phase, options.
|
|
7544
|
+
label: compactionLogLabel(options.phase, options.attemptNo)
|
|
7546
7545
|
});
|
|
7547
|
-
|
|
7548
|
-
const attempt = options.attempts[i];
|
|
7549
|
-
if (attempt === void 0) continue;
|
|
7550
|
-
appendAttemptMessages(child, attempt, i + 1, options.target);
|
|
7551
|
-
}
|
|
7546
|
+
appendAttemptMessages(child, options.attempt, 1, options.target);
|
|
7552
7547
|
try {
|
|
7553
7548
|
await ctx.sessions.flush(child);
|
|
7554
7549
|
} catch (error) {
|
|
7555
7550
|
const message = error instanceof Error ? error.message : String(error);
|
|
7556
|
-
logger.warn(
|
|
7551
|
+
logger.warn(`压缩日志子会话 flush 失败(子会话 ${child.id} 已创建): ${message}`);
|
|
7557
7552
|
}
|
|
7558
7553
|
return child.id;
|
|
7559
7554
|
} catch (error) {
|
|
7560
7555
|
const message = error instanceof Error ? error.message : String(error);
|
|
7561
|
-
logger.warn(
|
|
7556
|
+
logger.warn(`压缩日志子会话落盘失败(第 ${options.attemptNo} 次尝试): ${message}`);
|
|
7562
7557
|
return;
|
|
7563
7558
|
}
|
|
7564
7559
|
}
|
|
@@ -7621,8 +7616,10 @@ async function gateRateLimit(waitMs, signal) {
|
|
|
7621
7616
|
/**
|
|
7622
7617
|
* 共享压缩提示词(观察/反思同一套):定义 history 块(模型消息 + index 的表达形式)、
|
|
7623
7618
|
* 完整消息定义、压缩要求、输出格式与数据源说明。
|
|
7619
|
+
* skipReasoning=true(默认,与 compressSkipReasoning 默认一致)时压缩输入不含
|
|
7620
|
+
* <reasoning> 参考条目,提示词相应省略 <reasoning> 的说明两行。
|
|
7624
7621
|
*/
|
|
7625
|
-
function buildHistoryPrompt() {
|
|
7622
|
+
function buildHistoryPrompt(skipReasoning = true) {
|
|
7626
7623
|
return [
|
|
7627
7624
|
"压缩 <history> 消息记录。你应当输出**单个**合法的 <history> 块。",
|
|
7628
7625
|
"",
|
|
@@ -7630,17 +7627,18 @@ function buildHistoryPrompt() {
|
|
|
7630
7627
|
"- <history> 是历史消息的记录块。",
|
|
7631
7628
|
"- <user_message index=\"N\">:用户消息条目。",
|
|
7632
7629
|
"- <sys type=\"(kind)\" index=\"N\">:系统消息条目。",
|
|
7633
|
-
"- <reasoning>:模型的思考过程,仅作压缩参考,产物中不要出现。",
|
|
7630
|
+
...skipReasoning ? [] : ["- <reasoning>:模型的思考过程,仅作压缩参考,产物中不要出现。"],
|
|
7634
7631
|
"- <assistant index=\"N\">:单条完整消息(模型输出文本,或 toolcall 及其 result)。",
|
|
7635
7632
|
"- <assistant start=\"A\" end=\"B\">:多条连续完整消息聚合的模块(A/B 为模块首尾完整消息的 index)。",
|
|
7636
7633
|
"",
|
|
7637
7634
|
"【压缩要求】",
|
|
7638
7635
|
"- <user_message> <sys> 条目从输入中逐条保留,不做任何处理。",
|
|
7639
|
-
"- <reasoning> 只作参考,输出产物中不包含 <reasoning> 块。",
|
|
7640
|
-
"- 将具有关联性的 <assistant> 消息按内在逻辑连贯性划分为连续模块,聚合为 <assistant start=\"\" end=\"\">
|
|
7641
|
-
"- 单条重要的完整消息以 <assistant index=\"\">
|
|
7636
|
+
...skipReasoning ? [] : ["- <reasoning> 只作参考,输出产物中不包含 <reasoning> 块。"],
|
|
7637
|
+
"- 将具有关联性的 <assistant> 消息按内在逻辑连贯性划分为连续模块,聚合为 <assistant start=\"\" end=\"\"> 块",
|
|
7638
|
+
"- 单条重要的完整消息以 <assistant index=\"\"> 单独呈现",
|
|
7639
|
+
"- 压缩后的 <assistant> 块内,应当描述**行为逻辑**,强调关键的**结论、产出和任务**;涉及到的具体文件保留完整路径",
|
|
7642
7640
|
"- 加载的 skill 属于**关键信息**:应当产出独立块且不过多省略。",
|
|
7643
|
-
"-
|
|
7641
|
+
"- 压缩后的消息,区间边界与输入的消息必须完全相同,内部 index/start/end 必须连续,相邻区间的左右界必须相邻,",
|
|
7644
7642
|
"",
|
|
7645
7643
|
"【摘要粒度】",
|
|
7646
7644
|
"- 越往后越细:靠近末尾(最近)的完整消息保留更多细节(关键文件、改动与结论),开头(较早)的完整消息可适当从简。",
|
|
@@ -7697,14 +7695,15 @@ function renderUserEntry(doc, session, cm) {
|
|
|
7697
7695
|
}
|
|
7698
7696
|
/**
|
|
7699
7697
|
* 渲染完整消息记录(观察输入):输出一个合法的 <history> 块——
|
|
7700
|
-
* user → <user_message>(文本原样、图片注释)、sys → <sys> 空块、
|
|
7701
|
-
*
|
|
7698
|
+
* user → <user_message>(文本原样、图片注释)、sys → <sys> 空块、
|
|
7699
|
+
* assistant/toolcall → <assistant>(原样文本);skipReasoning=false 时另把
|
|
7700
|
+
* assistant 的 reasoning → <reasoning>(参考条目)。
|
|
7702
7701
|
* 文本经 XML 序列化自动转义;仅渲染 seqs 全部落在给定集合内的完整消息。
|
|
7703
7702
|
*/
|
|
7704
|
-
function renderMessages(session, seqs) {
|
|
7703
|
+
function renderMessages(session, seqs, skipReasoning = true) {
|
|
7705
7704
|
const shadowed = new Set(seqs);
|
|
7706
7705
|
const reasoningBySeq = /* @__PURE__ */ new Map();
|
|
7707
|
-
for (const seq of seqs) {
|
|
7706
|
+
if (!skipReasoning) for (const seq of seqs) {
|
|
7708
7707
|
const event = session.events[seq];
|
|
7709
7708
|
if (event?.type !== "assistant/message") continue;
|
|
7710
7709
|
const message = event.data.message;
|
|
@@ -7733,7 +7732,7 @@ function renderMessages(session, seqs) {
|
|
|
7733
7732
|
} else {
|
|
7734
7733
|
const callSeq = cm.seqs[0];
|
|
7735
7734
|
const reasonings = callSeq === void 0 ? void 0 : reasoningBySeq.get(callSeq);
|
|
7736
|
-
if (callSeq !== void 0 && reasonings !== void 0 && !emittedReasoning.has(callSeq)) {
|
|
7735
|
+
if (!skipReasoning && callSeq !== void 0 && reasonings !== void 0 && !emittedReasoning.has(callSeq)) {
|
|
7737
7736
|
emittedReasoning.add(callSeq);
|
|
7738
7737
|
for (const text of reasonings) {
|
|
7739
7738
|
const re = doc.createElement("reasoning");
|
|
@@ -7815,6 +7814,14 @@ function buildSummaryOptions(session, instruction, contextText, maxTokens, targe
|
|
|
7815
7814
|
}
|
|
7816
7815
|
/** 产出日志后插入首个 <history> 后的格式说明(XML 注释,完整消息定义 + 条目标签语义)。 */
|
|
7817
7816
|
const HISTORY_FORMAT_NOTE = `<!-- 完整消息:${COMPLETE_MESSAGE_DEFINITION} <TAG index="N">表示单条完整消息,<TAG start="A" end="B"> 表示连续模块,start/end 是首尾完整消息的 index;<sys type="KIND" index="N"> 表示被压缩的系统消息,块中为空 -->`;
|
|
7817
|
+
/**
|
|
7818
|
+
* 剥离 <history> 块内文块首的格式说明注释(HISTORY_FORMAT_NOTE 整体精确匹配,仅块首
|
|
7819
|
+
* 一处);正文条目内出现的同名注释串不动。非块首或不匹配时原样返回。
|
|
7820
|
+
*/
|
|
7821
|
+
function stripLeadingFormatNote(inner) {
|
|
7822
|
+
if (!inner.startsWith(HISTORY_FORMAT_NOTE)) return inner;
|
|
7823
|
+
return inner.slice(HISTORY_FORMAT_NOTE.length).replace(/^\s+/, "");
|
|
7824
|
+
}
|
|
7818
7825
|
/** 读取元素整数属性(非负整数;缺失 / 非数字返回 undefined)。 */
|
|
7819
7826
|
function intAttr(el, name) {
|
|
7820
7827
|
const raw = el.getAttribute(name);
|
|
@@ -7886,7 +7893,7 @@ function parseHistoryBlock(xml) {
|
|
|
7886
7893
|
};
|
|
7887
7894
|
}
|
|
7888
7895
|
/**
|
|
7889
|
-
* 解析文本中全部 <history>
|
|
7896
|
+
* 解析文本中全部 <history> 块内的条目(逐块解析提取,兼容多块拼接文本)。
|
|
7890
7897
|
* 非法块跳过;仅提取不校验顺序(连续性由 historyContinuity 校验)。
|
|
7891
7898
|
*/
|
|
7892
7899
|
function parseHistoryEntries(text) {
|
|
@@ -8031,95 +8038,109 @@ function extractSummaryDetailed(raw, expected) {
|
|
|
8031
8038
|
}
|
|
8032
8039
|
/**
|
|
8033
8040
|
* 直连 LLM 执行一次摘要(观察或反思),返回文本与可选 token usage。
|
|
8034
|
-
*
|
|
8035
|
-
*
|
|
8036
|
-
*
|
|
8037
|
-
*
|
|
8038
|
-
*
|
|
8039
|
-
*
|
|
8041
|
+
* 每次实际发出的 LLM 调用(无论成功、校验不通过、非 stop 结束还是异常)完成后,
|
|
8042
|
+
* 立即把该次尝试的完整提示词与模型原始输出原样落盘为诊断子会话(phase 标注观察
|
|
8043
|
+
* 或反思),子会话 id 写入该次尝试的主会话日志;请求发出前被中止的尝试(无实际
|
|
8044
|
+
* 调用)不落盘。失败(抛异常 / 空输出 / 非 stop 结束 / 校验不通过)记录日志并重试;
|
|
8045
|
+
* 全部尝试耗尽返回失败结果(携带最后一次尝试的实际报错/具体问题与其诊断子会话 id)。
|
|
8046
|
+
* signal 中止(含限流等待被中止)立即放弃并标记 aborted。每次请求发出前先过全局
|
|
8047
|
+
* 限流等待门。
|
|
8040
8048
|
*/
|
|
8041
8049
|
async function runSummarySubagent(ctx, agent, instruction, contextText, maxTokens, target, debug, signal, options) {
|
|
8042
8050
|
const session = agent.session;
|
|
8043
8051
|
const logger = makeLogger(ctx, debug);
|
|
8044
8052
|
const maxAttempts = options?.maxAttempts ?? 11;
|
|
8045
8053
|
let lastFailure = {};
|
|
8046
|
-
/** 逐尝试的完整记录(提示词 + 原始输出原样收集,仅最终失败时落盘)。 */
|
|
8047
|
-
const attempts = [];
|
|
8048
|
-
/** 最终失败的统一出口:落盘诊断子会话并携带其 id 返回。 */
|
|
8049
|
-
const finishFailure = async (error, aborted) => {
|
|
8050
|
-
const diagnosticSessionId = await recordCompactionFailure(ctx, session, {
|
|
8051
|
-
phase: options?.phase,
|
|
8052
|
-
target,
|
|
8053
|
-
attempts,
|
|
8054
|
-
debug
|
|
8055
|
-
});
|
|
8056
|
-
return {
|
|
8057
|
-
ok: false,
|
|
8058
|
-
error,
|
|
8059
|
-
aborted,
|
|
8060
|
-
...diagnosticSessionId === void 0 ? {} : { diagnosticSessionId }
|
|
8061
|
-
};
|
|
8062
|
-
};
|
|
8063
8054
|
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
8064
8055
|
if (signal?.aborted) {
|
|
8065
8056
|
logger.warn(`摘要调用中止(第 ${attempt}/${maxAttempts} 次尝试前 signal 已中止),放弃本次压缩`);
|
|
8066
|
-
return
|
|
8057
|
+
return {
|
|
8058
|
+
ok: false,
|
|
8059
|
+
error: COMPACTION_ABORTED_ERROR,
|
|
8060
|
+
aborted: true,
|
|
8061
|
+
...lastFailure.diagnosticSessionId === void 0 ? {} : { diagnosticSessionId: lastFailure.diagnosticSessionId }
|
|
8062
|
+
};
|
|
8067
8063
|
}
|
|
8068
8064
|
const rateLimitWaitMs = options?.rateLimitWaitMs ?? 6e4;
|
|
8069
8065
|
if (!await gateRateLimit(rateLimitWaitMs, signal)) {
|
|
8070
8066
|
logger.warn(`摘要调用中止(第 ${attempt}/${maxAttempts} 次尝试前限流等待被 signal 中止),放弃本次压缩`);
|
|
8071
|
-
return
|
|
8067
|
+
return {
|
|
8068
|
+
ok: false,
|
|
8069
|
+
error: COMPACTION_ABORTED_ERROR,
|
|
8070
|
+
aborted: true,
|
|
8071
|
+
...lastFailure.diagnosticSessionId === void 0 ? {} : { diagnosticSessionId: lastFailure.diagnosticSessionId }
|
|
8072
|
+
};
|
|
8072
8073
|
}
|
|
8073
8074
|
logger.step(`摘要调用开始(第 ${attempt}/${maxAttempts} 次,provider ${target.provider},model ${target.model},maxTokens ${maxTokens === void 0 ? "未设置" : String(maxTokens)})`);
|
|
8074
8075
|
const prompt = `${instruction}\n\n${contextText ?? ""}`;
|
|
8075
8076
|
const collector = new StreamCollector();
|
|
8076
8077
|
let streamCompleted = false;
|
|
8078
|
+
/** 本次尝试的诊断子会话 id(调用完成后立即落盘;落盘失败时缺失)。 */
|
|
8079
|
+
const logAttempt = async () => recordCompactionAttempt(ctx, session, {
|
|
8080
|
+
phase: options?.phase,
|
|
8081
|
+
target,
|
|
8082
|
+
attempt: {
|
|
8083
|
+
prompt,
|
|
8084
|
+
rawOutput: collector.text
|
|
8085
|
+
},
|
|
8086
|
+
attemptNo: attempt,
|
|
8087
|
+
debug
|
|
8088
|
+
});
|
|
8077
8089
|
try {
|
|
8078
8090
|
const requestOptions = buildSummaryOptions(session, instruction, contextText, maxTokens, target, signal);
|
|
8079
8091
|
for await (const chunk of ctx.llm.stream(requestOptions)) collector.push(chunk);
|
|
8080
8092
|
streamCompleted = true;
|
|
8081
|
-
|
|
8082
|
-
prompt,
|
|
8083
|
-
rawOutput: collector.text
|
|
8084
|
-
});
|
|
8093
|
+
const diagnosticSessionId = await logAttempt();
|
|
8085
8094
|
const extracted = extractSummaryDetailed(collector.text, options?.expected);
|
|
8086
8095
|
const finish = collector.finish;
|
|
8087
8096
|
if (finish.kind !== "stop") {
|
|
8088
|
-
lastFailure = {
|
|
8089
|
-
|
|
8097
|
+
lastFailure = {
|
|
8098
|
+
reason: `摘要流以 ${String(finish.kind)} 结束(非正常完成)`,
|
|
8099
|
+
...diagnosticSessionId === void 0 ? {} : { diagnosticSessionId }
|
|
8100
|
+
};
|
|
8101
|
+
logger.warn(`摘要未完成(第 ${attempt}/${maxAttempts} 次,${lastFailure.reason},子会话 ${diagnosticSessionId ?? "未落盘"})` + (attempt < maxAttempts ? ",将重试" : ",重试耗尽,放弃本次压缩"));
|
|
8090
8102
|
continue;
|
|
8091
8103
|
}
|
|
8092
8104
|
if ("error" in extracted) {
|
|
8093
|
-
lastFailure = {
|
|
8094
|
-
|
|
8105
|
+
lastFailure = {
|
|
8106
|
+
reason: extracted.error,
|
|
8107
|
+
...diagnosticSessionId === void 0 ? {} : { diagnosticSessionId }
|
|
8108
|
+
};
|
|
8109
|
+
logger.warn(`摘要输出未通过校验(第 ${attempt}/${maxAttempts} 次,${extracted.error},子会话 ${diagnosticSessionId ?? "未落盘"})` + (attempt < maxAttempts ? ",将重试" : ",重试耗尽,放弃本次压缩"));
|
|
8095
8110
|
continue;
|
|
8096
8111
|
}
|
|
8097
8112
|
const text = extracted.log;
|
|
8098
8113
|
const usage = collector.usage;
|
|
8099
|
-
logger.info(`摘要调用成功(第 ${attempt}/${maxAttempts} 次,输出 ${text.length} 字符` + (usage === void 0 ? "" : `,input ${String(usage.inputTokens ?? "?")} / output ${String(usage.outputTokens ?? "?")} tokens`) + "
|
|
8114
|
+
logger.info(`摘要调用成功(第 ${attempt}/${maxAttempts} 次,输出 ${text.length} 字符` + (usage === void 0 ? "" : `,input ${String(usage.inputTokens ?? "?")} / output ${String(usage.outputTokens ?? "?")} tokens`) + `,子会话 ${diagnosticSessionId ?? "未落盘"})`);
|
|
8100
8115
|
return {
|
|
8101
8116
|
ok: true,
|
|
8102
8117
|
text,
|
|
8103
8118
|
attemptCount: attempt,
|
|
8104
|
-
...usage === void 0 ? {} : { usage }
|
|
8119
|
+
...usage === void 0 ? {} : { usage },
|
|
8120
|
+
...diagnosticSessionId === void 0 ? {} : { diagnosticSessionId }
|
|
8105
8121
|
};
|
|
8106
8122
|
} catch (error) {
|
|
8107
|
-
|
|
8108
|
-
prompt,
|
|
8109
|
-
rawOutput: collector.text
|
|
8110
|
-
});
|
|
8123
|
+
const diagnosticSessionId = streamCompleted ? void 0 : await logAttempt();
|
|
8111
8124
|
const message = error instanceof Error ? error.message : String(error);
|
|
8112
8125
|
if (isRateLimitError(message)) {
|
|
8113
8126
|
noteRateLimit();
|
|
8114
8127
|
logger.warn(`摘要调用触发限流(429,第 ${attempt}/${maxAttempts} 次),下一次请求前至少等待 ${rateLimitWaitMs}ms`);
|
|
8115
8128
|
}
|
|
8116
|
-
lastFailure = {
|
|
8117
|
-
|
|
8129
|
+
lastFailure = {
|
|
8130
|
+
error: message,
|
|
8131
|
+
...diagnosticSessionId === void 0 ? {} : { diagnosticSessionId }
|
|
8132
|
+
};
|
|
8133
|
+
logger.warn(`摘要调用失败(第 ${attempt}/${maxAttempts} 次,${message},子会话 ${diagnosticSessionId ?? "未落盘"})` + (attempt < maxAttempts ? ",将重试" : ",重试耗尽,放弃本次压缩"));
|
|
8118
8134
|
}
|
|
8119
8135
|
}
|
|
8120
8136
|
const lastError = lastFailure.error ?? lastFailure.reason ?? "未知原因";
|
|
8121
8137
|
logger.warn(`摘要调用最终失败(已尝试 ${maxAttempts} 次,最后错误:${lastError}),拒绝放行本轮 step`);
|
|
8122
|
-
return
|
|
8138
|
+
return {
|
|
8139
|
+
ok: false,
|
|
8140
|
+
error: lastError,
|
|
8141
|
+
aborted: false,
|
|
8142
|
+
...lastFailure.diagnosticSessionId === void 0 ? {} : { diagnosticSessionId: lastFailure.diagnosticSessionId }
|
|
8143
|
+
};
|
|
8123
8144
|
}
|
|
8124
8145
|
//#endregion
|
|
8125
8146
|
//#region src/compress.ts
|
|
@@ -8128,7 +8149,8 @@ async function runSummarySubagent(ctx, agent, instruction, contextText, maxToken
|
|
|
8128
8149
|
* 导出 estimateTextTokens / isPairBalancedAfter / computeCompressRange / historySection /
|
|
8129
8150
|
* findObservePending / reflectPass / observePass / maybeCompress。
|
|
8130
8151
|
*
|
|
8131
|
-
* - 反思:全部 <history> 块 token 合计 ≥ reflectThresholdTokens
|
|
8152
|
+
* - 反思:全部 <history> 块 token 合计 ≥ reflectThresholdTokens 时,块内文拼合为单个
|
|
8153
|
+
* <history> 块输入摘要,合并为一条
|
|
8132
8154
|
* - 观察(触发 → 待定 → 延迟执行):净压力(上下文压力 − 已压缩块 token 合计 − 系统提示词
|
|
8133
8155
|
* token 估算 − 工具定义 token 估算)首次 ≥ observeThresholdTokens 时记录待定标记
|
|
8134
8156
|
* (触发点 = 当时的最后一条完整消息 index),本次不压缩;待定后新增完整消息数 ≥
|
|
@@ -8192,6 +8214,14 @@ function historyInnerText(text) {
|
|
|
8192
8214
|
return text.slice(gt + 1, close).trim();
|
|
8193
8215
|
}
|
|
8194
8216
|
/**
|
|
8217
|
+
* 反思输入拼合:全部块内文(historyInnerText 去掉开标签属性,块首格式说明注释剥离)
|
|
8218
|
+
* 按序合并进单个 <history> 块。正文条目内出现的属性/注释同名串原样保留。
|
|
8219
|
+
*/
|
|
8220
|
+
function mergeHistoryBlocks(blocks) {
|
|
8221
|
+
const inner = blocks.map((block) => stripLeadingFormatNote(historyInnerText(block.text))).join("\n");
|
|
8222
|
+
return `<${HISTORY_TAG}>\n${inner}\n</${HISTORY_TAG}>`;
|
|
8223
|
+
}
|
|
8224
|
+
/**
|
|
8195
8225
|
* 判定表层节点 seq 之后的切点是否 tool-call/result 配对平衡:按表层顺序折叠未闭合的
|
|
8196
8226
|
* 工具调用数,处理到 seq 后计数为 0 即平衡(防止把 tool-call 与其结果切到两侧)。
|
|
8197
8227
|
*/
|
|
@@ -8346,7 +8376,7 @@ function appendCompactionSummary(session, data) {
|
|
|
8346
8376
|
}
|
|
8347
8377
|
/**
|
|
8348
8378
|
* 追加 compaction/end(log-only,结束生命周期;error 记录失败原因,
|
|
8349
|
-
* diagnosticSessionId
|
|
8379
|
+
* diagnosticSessionId 记录最后一次摘要尝试(无论成功或失败)的诊断子会话 id)。
|
|
8350
8380
|
*/
|
|
8351
8381
|
function appendCompactionEnd(session, lifecycle, error, diagnosticSessionId) {
|
|
8352
8382
|
const payload = {
|
|
@@ -8378,9 +8408,9 @@ function appendHistoryMessage(session, content, sourceEventSeqs, surfaceOp, comp
|
|
|
8378
8408
|
});
|
|
8379
8409
|
}
|
|
8380
8410
|
/**
|
|
8381
|
-
* 反思:全部 <history> 块 token 合计 ≥ reflectThresholdTokens
|
|
8382
|
-
*
|
|
8383
|
-
*
|
|
8411
|
+
* 反思:全部 <history> 块 token 合计 ≥ reflectThresholdTokens 时,全部块内文拼合为
|
|
8412
|
+
* 单个 <history> 块送入摘要调用,整个块区段合并替换为一条更紧凑的摘要。失败不产生
|
|
8413
|
+
* 部分替换;摘要尝试全部耗尽返回失败结果(error = 最后一次尝试的实际报错/具体问题)。
|
|
8384
8414
|
*/
|
|
8385
8415
|
async function reflectPass(ctx, agent, config, target, signal) {
|
|
8386
8416
|
const session = agent.session;
|
|
@@ -8406,8 +8436,8 @@ async function reflectPass(ctx, agent, config, target, signal) {
|
|
|
8406
8436
|
return { failed: false };
|
|
8407
8437
|
}
|
|
8408
8438
|
const blockSeqs = blocks.map((block) => block.seq);
|
|
8409
|
-
const instruction = buildHistoryPrompt();
|
|
8410
|
-
const contextText = blocks
|
|
8439
|
+
const instruction = buildHistoryPrompt(config.compressSkipReasoning);
|
|
8440
|
+
const contextText = mergeHistoryBlocks(blocks);
|
|
8411
8441
|
const expectedEnd = reflectExpectedEnd(contextText);
|
|
8412
8442
|
const lifecycle = {
|
|
8413
8443
|
compactionId: newCompactionId(),
|
|
@@ -8468,7 +8498,7 @@ async function reflectPass(ctx, agent, config, target, signal) {
|
|
|
8468
8498
|
end: last.seq
|
|
8469
8499
|
}, lifecycle.compactionId);
|
|
8470
8500
|
logger.step("反思提交:追加 compaction/end");
|
|
8471
|
-
appendCompactionEnd(session, lifecycle);
|
|
8501
|
+
appendCompactionEnd(session, lifecycle, void 0, summaryResult.diagnosticSessionId);
|
|
8472
8502
|
logger.info(`反思完成(摘要 ${tokens} tokens ≥ 阈值 ${threshold},合并 ${blocks.length} 个块为一条)`);
|
|
8473
8503
|
return { failed: false };
|
|
8474
8504
|
} catch (error) {
|
|
@@ -8631,8 +8661,8 @@ async function observePass(ctx, agent, config, waitCount, target, signal) {
|
|
|
8631
8661
|
const startIndex = inRangeCms[0]?.index ?? 0;
|
|
8632
8662
|
const endIndex = inRangeCms[inRangeCms.length - 1]?.index ?? startIndex;
|
|
8633
8663
|
logger.step(`观察:保留旧块 ${blocks.length} 条,替换 [${replaceStart}..${range.end}](${replaceSeqs.length} 个表层节点,压缩至${triggerNote}),新消息 index ${startIndex}..${endIndex}`);
|
|
8634
|
-
const instruction = buildHistoryPrompt();
|
|
8635
|
-
const contextText = renderMessages(session, replaceSeqs);
|
|
8664
|
+
const instruction = buildHistoryPrompt(config.compressSkipReasoning);
|
|
8665
|
+
const contextText = renderMessages(session, replaceSeqs, config.compressSkipReasoning);
|
|
8636
8666
|
const lifecycle = {
|
|
8637
8667
|
compactionId: newCompactionId(),
|
|
8638
8668
|
turn: openTurnOf(session)
|
|
@@ -8710,7 +8740,7 @@ async function observePass(ctx, agent, config, waitCount, target, signal) {
|
|
|
8710
8740
|
end: range.end
|
|
8711
8741
|
}, lifecycle.compactionId);
|
|
8712
8742
|
logger.step("观察提交:追加 compaction/end");
|
|
8713
|
-
appendCompactionEnd(session, lifecycle);
|
|
8743
|
+
appendCompactionEnd(session, lifecycle, void 0, summaryResult.diagnosticSessionId);
|
|
8714
8744
|
clearPending();
|
|
8715
8745
|
logger.info(`观察压缩完成(替换 ${replaceSeqs.length} 个表层节点,约 ${shadowedTokenCount} tokens,压缩至${triggerNote})`);
|
|
8716
8746
|
return { failed: false };
|
|
@@ -8968,6 +8998,7 @@ const DEFAULT_CONFIG = Object.freeze({
|
|
|
8968
8998
|
rateLimitWaitMs: 6e4,
|
|
8969
8999
|
tailMessageCount: 5,
|
|
8970
9000
|
compressRetryCount: 5,
|
|
9001
|
+
compressSkipReasoning: true,
|
|
8971
9002
|
omEnabled: true,
|
|
8972
9003
|
debug: false,
|
|
8973
9004
|
recallEnabled: true,
|
|
@@ -9009,6 +9040,7 @@ function resolveConfig(raw) {
|
|
|
9009
9040
|
if (integer && !Number.isInteger(value)) continue;
|
|
9010
9041
|
config[key] = value;
|
|
9011
9042
|
}
|
|
9043
|
+
config.compressSkipReasoning = resolveBoolean(input.compressSkipReasoning, true);
|
|
9012
9044
|
config.omEnabled = resolveBoolean(input.omEnabled, true);
|
|
9013
9045
|
config.debug = resolveBoolean(input.debug, process.env.NODE_ENV !== "production");
|
|
9014
9046
|
config.recallEnabled = resolveBoolean(input.recallEnabled, true);
|
package/dist/summarize.d.ts
CHANGED
|
@@ -17,22 +17,27 @@ import { type RoutedTarget } from './utils.ts';
|
|
|
17
17
|
/**
|
|
18
18
|
* 共享压缩提示词(观察/反思同一套):定义 history 块(模型消息 + index 的表达形式)、
|
|
19
19
|
* 完整消息定义、压缩要求、输出格式与数据源说明。
|
|
20
|
+
* skipReasoning=true(默认,与 compressSkipReasoning 默认一致)时压缩输入不含
|
|
21
|
+
* <reasoning> 参考条目,提示词相应省略 <reasoning> 的说明两行。
|
|
20
22
|
*/
|
|
21
|
-
export declare function buildHistoryPrompt(): string;
|
|
23
|
+
export declare function buildHistoryPrompt(skipReasoning?: boolean): string;
|
|
22
24
|
/**
|
|
23
25
|
* 渲染完整消息记录(观察输入):输出一个合法的 <history> 块——
|
|
24
|
-
* user → <user_message>(文本原样、图片注释)、sys → <sys> 空块、
|
|
25
|
-
*
|
|
26
|
+
* user → <user_message>(文本原样、图片注释)、sys → <sys> 空块、
|
|
27
|
+
* assistant/toolcall → <assistant>(原样文本);skipReasoning=false 时另把
|
|
28
|
+
* assistant 的 reasoning → <reasoning>(参考条目)。
|
|
26
29
|
* 文本经 XML 序列化自动转义;仅渲染 seqs 全部落在给定集合内的完整消息。
|
|
27
30
|
*/
|
|
28
|
-
export declare function renderMessages(session: Session, seqs: readonly number[]): string;
|
|
29
|
-
/** 摘要调用成功结果:文本 + 可选 token usage +
|
|
31
|
+
export declare function renderMessages(session: Session, seqs: readonly number[], skipReasoning?: boolean): string;
|
|
32
|
+
/** 摘要调用成功结果:文本 + 可选 token usage + 尝试次数 + 诊断子会话 id。 */
|
|
30
33
|
export type SummarySuccess = {
|
|
31
34
|
ok: true;
|
|
32
35
|
text: string;
|
|
33
36
|
usage?: TokenUsage;
|
|
34
37
|
/** 成功时的尝试次数(1 起;载荷层换算为重试次数 = 该值 - 1)。 */
|
|
35
38
|
attemptCount: number;
|
|
39
|
+
/** 本次成功尝试落盘的诊断子会话 id(落盘失败时缺失)。 */
|
|
40
|
+
diagnosticSessionId?: string;
|
|
36
41
|
};
|
|
37
42
|
/** 摘要调用失败结果:最后一次尝试的实际报错/具体问题 + 是否因 signal 中止 + 诊断子会话 id。 */
|
|
38
43
|
export type SummaryFailure = {
|
|
@@ -41,7 +46,7 @@ export type SummaryFailure = {
|
|
|
41
46
|
error: string;
|
|
42
47
|
/** 因 signal 中止(含限流等待被中止)而放弃;此时 error 为 COMPACTION_ABORTED_ERROR。 */
|
|
43
48
|
aborted: boolean;
|
|
44
|
-
/**
|
|
49
|
+
/** 最后一次尝试落盘的诊断子会话 id(每次尝试各自落盘;该次未发出请求或落盘失败时缺失)。 */
|
|
45
50
|
diagnosticSessionId?: string;
|
|
46
51
|
};
|
|
47
52
|
/** 摘要调用结果(成功/失败二选一)。 */
|
|
@@ -50,6 +55,11 @@ export type SummaryOutcome = SummarySuccess | SummaryFailure;
|
|
|
50
55
|
export declare const MIN_HISTORY_LENGTH = 10;
|
|
51
56
|
/** 产出日志后插入首个 <history> 后的格式说明(XML 注释,完整消息定义 + 条目标签语义)。 */
|
|
52
57
|
export declare const HISTORY_FORMAT_NOTE = "<!-- \u5B8C\u6574\u6D88\u606F\uFF1A`\u5B8C\u6574\u6D88\u606F`\u6307\u4E00\u6761`\u7528\u6237\u6D88\u606F`\u3001`\u7CFB\u7EDF\u6D88\u606F`\u3001`\u6A21\u578B\u8F93\u51FA\u6587\u672C`\u6216`\u5177\u6709result\u7684toolcall`\uFF1B\u9996\u6761 index \u4E3A 0\uFF0C\u6309\u4F1A\u8BDD\u987A\u5E8F\u9012\u589E\u3002 <TAG index=\"N\">\u8868\u793A\u5355\u6761\u5B8C\u6574\u6D88\u606F\uFF0C<TAG start=\"A\" end=\"B\"> \u8868\u793A\u8FDE\u7EED\u6A21\u5757\uFF0Cstart/end \u662F\u9996\u5C3E\u5B8C\u6574\u6D88\u606F\u7684 index\uFF1B<sys type=\"KIND\" index=\"N\"> \u8868\u793A\u88AB\u538B\u7F29\u7684\u7CFB\u7EDF\u6D88\u606F\uFF0C\u5757\u4E2D\u4E3A\u7A7A -->";
|
|
58
|
+
/**
|
|
59
|
+
* 剥离 <history> 块内文块首的格式说明注释(HISTORY_FORMAT_NOTE 整体精确匹配,仅块首
|
|
60
|
+
* 一处);正文条目内出现的同名注释串不动。非块首或不匹配时原样返回。
|
|
61
|
+
*/
|
|
62
|
+
export declare function stripLeadingFormatNote(inner: string): string;
|
|
53
63
|
/** history 块内条目(单条 index 或模块 start/end)。 */
|
|
54
64
|
export type HistoryEntryRange = {
|
|
55
65
|
kind: 'user' | 'assistant' | 'sys';
|
|
@@ -58,7 +68,7 @@ export type HistoryEntryRange = {
|
|
|
58
68
|
end?: number;
|
|
59
69
|
};
|
|
60
70
|
/**
|
|
61
|
-
* 解析文本中全部 <history>
|
|
71
|
+
* 解析文本中全部 <history> 块内的条目(逐块解析提取,兼容多块拼接文本)。
|
|
62
72
|
* 非法块跳过;仅提取不校验顺序(连续性由 historyContinuity 校验)。
|
|
63
73
|
*/
|
|
64
74
|
export declare function parseHistoryEntries(text: string): HistoryEntryRange[];
|
|
@@ -97,12 +107,13 @@ export declare function extractSummaryLog(raw: string, expected?: SummaryValidat
|
|
|
97
107
|
export declare const SUMMARY_DEFAULT_MAX_ATTEMPTS = 11;
|
|
98
108
|
/**
|
|
99
109
|
* 直连 LLM 执行一次摘要(观察或反思),返回文本与可选 token usage。
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
110
|
+
* 每次实际发出的 LLM 调用(无论成功、校验不通过、非 stop 结束还是异常)完成后,
|
|
111
|
+
* 立即把该次尝试的完整提示词与模型原始输出原样落盘为诊断子会话(phase 标注观察
|
|
112
|
+
* 或反思),子会话 id 写入该次尝试的主会话日志;请求发出前被中止的尝试(无实际
|
|
113
|
+
* 调用)不落盘。失败(抛异常 / 空输出 / 非 stop 结束 / 校验不通过)记录日志并重试;
|
|
114
|
+
* 全部尝试耗尽返回失败结果(携带最后一次尝试的实际报错/具体问题与其诊断子会话 id)。
|
|
115
|
+
* signal 中止(含限流等待被中止)立即放弃并标记 aborted。每次请求发出前先过全局
|
|
116
|
+
* 限流等待门。
|
|
106
117
|
*/
|
|
107
118
|
export declare function runSummarySubagent(ctx: Context, agent: Agent, instruction: string, contextText: string | undefined, maxTokens: number | undefined, target: RoutedTarget, debug: boolean, signal?: AbortSignal, options?: {
|
|
108
119
|
maxAttempts?: number;
|
package/dist/summarize.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarize.d.ts","sourceRoot":"","sources":["../src/summarize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAqBH,OAAO,KAAK,EAAE,KAAK,EAAmB,OAAO,EAAE,OAAO,EAAE,UAAU,EAAe,MAAM,YAAY,CAAC;AACpG,OAAO,EAAE,KAAK,YAAY,EAAQ,MAAM,YAAY,CAAC;AAErD
|
|
1
|
+
{"version":3,"file":"summarize.d.ts","sourceRoot":"","sources":["../src/summarize.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -101,12 +101,12 @@ export type CompactionSummaryPayload = SessionEventMap['compaction/summary'] & {
|
|
|
101
101
|
attemptCount?: number;
|
|
102
102
|
};
|
|
103
103
|
/**
|
|
104
|
-
* 插件扩展的 compaction/end 载荷:宿主类型 + diagnosticSessionId
|
|
105
|
-
*
|
|
104
|
+
* 插件扩展的 compaction/end 载荷:宿主类型 + diagnosticSessionId(最后一次摘要尝试
|
|
105
|
+
* 无论成功或失败时落盘的诊断子会话 id)。宿主 append 不做 schema 剥离,扩展字段原样持久化;
|
|
106
106
|
* 客户端读取时按可选处理(UI 渲染行为不变)。
|
|
107
107
|
*/
|
|
108
108
|
export type CompactionEndPayload = SessionEventMap['compaction/end'] & {
|
|
109
|
-
/**
|
|
109
|
+
/** 最后一次摘要尝试(成功或失败)落盘的诊断子会话 id(未发出请求或落盘失败时缺失)。 */
|
|
110
110
|
diagnosticSessionId?: string;
|
|
111
111
|
};
|
|
112
112
|
/**
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|