dsh-plugin-om 0.0.22 → 0.0.24
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 +16 -11
- package/dist/client/OmCompactionCard.d.ts +1 -0
- package/dist/client/OmCompactionCard.d.ts.map +1 -1
- package/dist/client/OmWarningCard.d.ts +15 -0
- package/dist/client/OmWarningCard.d.ts.map +1 -0
- package/dist/client/definition.d.ts +27 -6
- package/dist/client/definition.d.ts.map +1 -1
- package/dist/client/index.d.ts +5 -4
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/locales.d.ts +4 -0
- package/dist/client/locales.d.ts.map +1 -1
- package/dist/client.js +151 -8
- package/dist/client.js.map +1 -1
- package/dist/compress.d.ts +22 -8
- package/dist/compress.d.ts.map +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +7 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/degrade.d.ts +18 -0
- package/dist/degrade.d.ts.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +276 -98
- package/dist/semantic-recall.d.ts.map +1 -1
- package/dist/summarize.d.ts +35 -11
- package/dist/summarize.d.ts.map +1 -1
- package/dist/types.d.ts +15 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,12 +7,15 @@
|
|
|
7
7
|
## 功能
|
|
8
8
|
|
|
9
9
|
- **自动压缩**(仅主会话,`agent/pre-step` 时阻塞串行执行):
|
|
10
|
-
- **观察**:净压力(上下文压力 − 已压缩 `<history>` 块 token
|
|
10
|
+
- **观察**:净压力(上下文压力 − 已压缩 `<history>` 块 token 估算合计 − 系统提示词 token 估算 − 工具定义 token 估算)≥ `observeThresholdTokens` 时,摘要未压缩消息并追加为新 `<history>` 块,精确替换被压缩的消息区间(旧块保留)
|
|
11
11
|
- **反思**:全部 `<history>` 块 token 合计 ≥ `reflectThresholdTokens` 时,把多个摘要块合并为一条更紧凑的摘要
|
|
12
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 计
|
|
13
15
|
- **recall 工具**:按完整消息 index 区间回看原始会话(含被压缩内容;命中消息中的图片附件随结果保留)
|
|
14
16
|
- **recall-semantic 工具**:本地嵌入模型(paraphrase-multilingual-MiniLM-L12-v2)按语义检索全部完整消息(只匹配文本,纯图片消息不进候选池)
|
|
15
|
-
-
|
|
17
|
+
- **压缩卡片**:浏览器客户端在消息列表渲染折叠式「已压缩」卡片、「正在压缩上下文(观察/反思)…」提示行与可展开的「上下文压缩失败」错误行
|
|
18
|
+
- **降级警告行**:浏览器客户端把 `om/warning` 事件渲染为可展开的「上下文压缩功能降级」警告行(折叠摘要 + 完整说明展开)
|
|
16
19
|
|
|
17
20
|
## 安装与启用
|
|
18
21
|
|
|
@@ -32,7 +35,7 @@ dsh plugin --profile <profile> add dsh-plugin-om
|
|
|
32
35
|
```yaml
|
|
33
36
|
- id: dsh-plugin-om
|
|
34
37
|
config:
|
|
35
|
-
observeThresholdTokens:
|
|
38
|
+
observeThresholdTokens: 45000
|
|
36
39
|
```
|
|
37
40
|
|
|
38
41
|
### 开发插件
|
|
@@ -53,15 +56,15 @@ preset-agent 自带 `compaction-basic` 压缩,也会压缩上下文,其压
|
|
|
53
56
|
|
|
54
57
|
| 键 | 默认 | 含义 |
|
|
55
58
|
| --- | --- | --- |
|
|
56
|
-
| `observeThresholdTokens` | `
|
|
57
|
-
| `reflectThresholdTokens` | `
|
|
58
|
-
| `compressMaxTokens` |
|
|
59
|
+
| `observeThresholdTokens` | `45000` | 观察阈值(tokens):净压力(上下文压力 − 已压缩块 − 系统提示词估算 − 工具定义估算)≥ 该值时触发观察压缩 |
|
|
60
|
+
| `reflectThresholdTokens` | `120000` | 反思阈值(tokens):全部 `<history>` 块 token 合计 ≥ 该值时触发合并 |
|
|
61
|
+
| `compressMaxTokens` | 不设置 | 单次摘要生成上限(不设置时由模型适配器默认值决定) |
|
|
59
62
|
| `rateLimitWaitMs` | `60000` | 遇 429 限流后下一次摘要请求前的等待毫秒数(全局冷却期;`0` 不限流) |
|
|
60
63
|
| `tailMessageCount` | `5` | 尾部保留的不压缩消息条数 |
|
|
61
64
|
| `compressRetryCount` | `5` | 摘要失败后的最大重试次数(不含首次) |
|
|
62
65
|
| `modelDir` | 共享目录 | recall-semantic 嵌入模型目录(默认 `$DSH_HOME/plugin-data/dsh-plugin-om/models/<id>`,onnx 缺失且启用语义召回时运行时自动下载) |
|
|
63
66
|
| `omEnabled` | `true` | 是否启用自动压缩(`false` 时关闭,recall 工具不受影响) |
|
|
64
|
-
| `debug` | dev | 步骤级日志开关(缺省按 `NODE_ENV !== 'production'`
|
|
67
|
+
| `debug` | dev | 步骤级日志开关(缺省按 `NODE_ENV !== 'production'` 判定;每次压缩尝试的结果/报错与失败日志始终输出) |
|
|
65
68
|
| `recallEnabled` | `true` | 是否注册 `recall` 工具 |
|
|
66
69
|
| `semanticRecallEnabled` | `true` | 是否注册 `recall-semantic` 工具(`false` 时不注册、不触发模型下载) |
|
|
67
70
|
|
|
@@ -87,6 +90,7 @@ src/
|
|
|
87
90
|
├── index.ts # 打包入口:注册 recall 工具 + 接线 pre-step 自动压缩
|
|
88
91
|
├── config.ts # 配置默认值与宽松合并(未知键忽略、非法值回退默认)
|
|
89
92
|
├── constants.ts # 共享常量(插件标识 / history 标签 / 完整消息定义)
|
|
93
|
+
├── degrade.ts # 挂载失败降级上报(console 外部输出 + om/warning 会话事件,每会话去重)
|
|
90
94
|
├── types.ts # type-only:宿主类型再导出 + 领域类型
|
|
91
95
|
├── utils.ts # 零依赖工具函数(文本渲染 / 主会话判定 / 路由解析)
|
|
92
96
|
├── logger.ts # 插件日志门面(step 按 debug 开关过滤)
|
|
@@ -98,15 +102,16 @@ src/
|
|
|
98
102
|
├── embedding.ts # 本地 ONNX 嵌入(懒加载 / 批量 / 运行时按需下载编排)
|
|
99
103
|
├── model-download.ts # 模型下载原语(URL / 跳过判定 / 原子落盘)
|
|
100
104
|
├── summarize.ts # 共享压缩提示词 + <history> 块渲染与输出校验 + 摘要调用
|
|
101
|
-
├── compress.ts #
|
|
105
|
+
├── compress.ts # 两级自动压缩(观察/反思)、失败中断传播与 compaction 生命周期事件
|
|
102
106
|
└── client/ # 浏览器客户端 bundle(压缩卡片)
|
|
103
107
|
├── index.ts # 客户端入口:注册卡片定义与渲染器
|
|
104
|
-
├── definition.ts #
|
|
105
|
-
├── OmCompactionCard.tsx # 折叠卡片渲染器(统计标题 + summary
|
|
108
|
+
├── definition.ts # 压缩卡片业务定义(认领生命周期事件、替换检查点与 om/warning)
|
|
109
|
+
├── OmCompactionCard.tsx # 折叠卡片渲染器(统计标题 + summary/失败报错展开)
|
|
110
|
+
├── OmWarningCard.tsx # 功能降级警告行渲染器(折叠摘要 + 完整说明展开)
|
|
106
111
|
├── format.ts # 统计数字紧凑格式化(k/w/M)
|
|
107
112
|
└── locales.ts # om-compaction 文案字典(zh/en)
|
|
108
113
|
models/ # 嵌入模型目录(小文件随包分发;onnx 运行时按需下载,不进 git)
|
|
109
114
|
scripts/ # release-archive.mjs(CHANGELOG 归档)/ download-model.mjs(预下载 CLI)
|
|
110
|
-
tests/ # vitest
|
|
115
|
+
tests/ # vitest 测试(服务端各模块 + tests/client/ 客户端卡片 + 整条链路集成测试)
|
|
111
116
|
```
|
|
112
117
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* 复用平台原语 DisclosureRow;行内统计与展开体样式按宿主 ContextInjectionRow 的规则
|
|
4
4
|
* 注入 <style>(宿主该卡片样式是编译期哈希的 CSS Module,插件 bundle 无法引用其类名)。
|
|
5
5
|
* 卡片报告模型从何处起不再看到那段历史;summary 留在加载窗口外时行不可展开。
|
|
6
|
+
* 压缩失败节点渲染为可展开的错误行:折叠行显示错误摘要,展开体显示完整报错。
|
|
6
7
|
*/
|
|
7
8
|
import type { ChatNode } from '@deepseek-ai/dsh-client-ui-conversation/client';
|
|
8
9
|
import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OmCompactionCard.d.ts","sourceRoot":"","sources":["../../src/client/OmCompactionCard.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"OmCompactionCard.d.ts","sourceRoot":"","sources":["../../src/client/OmCompactionCard.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gDAAgD,CAAC;AAE/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAKpE,0EAA0E;AAC1E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IACzC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,eAAe,CAAC,CAAC;CAC1C;AAgCD,yCAAyC;AACzC,eAAO,MAAM,gBAAgB,oDAA+C,qBAAqB,iCA2H/F,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 功能降级警告行渲染器:与压缩卡片同款的折叠行。
|
|
3
|
+
* 折叠行显示降级说明摘要,展开体显示完整说明;数据来自 om/warning 事件载荷,
|
|
4
|
+
* 服务端按会话同问题去重后追加(每会话同一问题至多一行)。
|
|
5
|
+
*/
|
|
6
|
+
import type { ChatNode } from '@deepseek-ai/dsh-client-ui-conversation/client';
|
|
7
|
+
import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
|
|
8
|
+
/** Keyed renderer props: 装配好的警告行节点 + 绑定 `om-compaction` 命名空间的 locale 座。 */
|
|
9
|
+
export interface OmWarningCardProps {
|
|
10
|
+
readonly node: ChatNode<'om-warning'>;
|
|
11
|
+
readonly t: TranslateNS<'om-compaction'>;
|
|
12
|
+
}
|
|
13
|
+
/** 折叠式功能降级警告行(降级说明摘要行 + 完整说明展开)。 */
|
|
14
|
+
export declare const OmWarningCard: import("react").MemoExoticComponent<({ node, t }: OmWarningCardProps) => import("react").JSX.Element>;
|
|
15
|
+
//# sourceMappingURL=OmWarningCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OmWarningCard.d.ts","sourceRoot":"","sources":["../../src/client/OmWarningCard.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gDAAgD,CAAC;AAE/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAIpE,2EAA2E;AAC3E,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;IACtC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,eAAe,CAAC,CAAC;CAC1C;AAED,oCAAoC;AACpC,eAAO,MAAM,aAAa,oDAA4C,kBAAkB,iCAqCtF,CAAC"}
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 压缩卡片业务定义:认领插件自产的压缩生命周期事件(compaction/start|summary|end)
|
|
3
|
-
* 与替换检查点(source.plugin = 'dsh-plugin-om'
|
|
3
|
+
* 与替换检查点(source.plugin = 'dsh-plugin-om'),聚合出可渲染的摘要卡片节点;
|
|
4
|
+
* 并认领 om/warning 功能降级警告事件渲染为警告行。
|
|
4
5
|
* 导出 COMPACTION_CARD_KIND / OmCompactionChatData / checkpointCompactionId /
|
|
5
|
-
* omCompactionDefinition
|
|
6
|
+
* omCompactionDefinition / OM_WARNING_CARD_KIND / OmWarningChatData / omWarningDefinition。
|
|
7
|
+
* 宿主的 'compact' 检查点由宿主自己渲染,本定义不认领
|
|
6
8
|
* (双方共存无视觉冲突:宿主无检查点证据时不产出节点)。
|
|
7
9
|
*/
|
|
8
10
|
import type { ConversationMatch, ConversationNodeDefinition } from '@deepseek-ai/dsh-client-runtime/client';
|
|
9
11
|
import type { SessionEvent } from '@deepseek-ai/dsh-session/types';
|
|
10
12
|
/** 压缩卡片渲染器分发键(合并进 ChatNodeDataMap)。 */
|
|
11
13
|
export declare const COMPACTION_CARD_KIND = "om-compaction";
|
|
14
|
+
/** 功能降级警告行渲染器分发键(合并进 ChatNodeDataMap)。 */
|
|
15
|
+
export declare const OM_WARNING_CARD_KIND = "om-warning";
|
|
12
16
|
declare module '@deepseek-ai/dsh-client-ui-conversation/client' {
|
|
13
17
|
interface ChatNodeDataMap {
|
|
14
18
|
/** dsh-plugin-om 压缩替换检查点渲染的摘要卡片数据。 */
|
|
15
19
|
'om-compaction': OmCompactionChatData;
|
|
20
|
+
/** dsh-plugin-om 功能降级警告行数据。 */
|
|
21
|
+
'om-warning': OmWarningChatData;
|
|
16
22
|
}
|
|
17
23
|
}
|
|
18
24
|
/** 压缩卡片载荷:摘要文本与遮蔽统计。 */
|
|
@@ -37,12 +43,14 @@ export interface OmCompactionChatData {
|
|
|
37
43
|
readonly summaryTokenCount: number | null;
|
|
38
44
|
/** 摘要调用重试次数,载荷缺失或非法时为 null。 */
|
|
39
45
|
readonly retryCount: number | null;
|
|
46
|
+
/** 压缩失败的错误文案(来自 compaction/end 载荷 error);非失败节点为 null。 */
|
|
47
|
+
readonly error: string | null;
|
|
40
48
|
}
|
|
41
49
|
/** 压缩生命周期关联状态:summary / checkpoint / end 事件证据。 */
|
|
42
50
|
interface OmCompactionState {
|
|
43
51
|
readonly summary?: ConversationMatch;
|
|
44
52
|
readonly checkpoint?: ConversationMatch;
|
|
45
|
-
/** compaction/end(成功与失败都会到达;无 checkpoint 的 end
|
|
53
|
+
/** compaction/end(成功与失败都会到达;无 checkpoint 的 end 表示压缩失败或中止)。 */
|
|
46
54
|
readonly end?: ConversationMatch;
|
|
47
55
|
}
|
|
48
56
|
/**
|
|
@@ -52,10 +60,23 @@ interface OmCompactionState {
|
|
|
52
60
|
export declare function checkpointCompactionId(event: SessionEvent): string | undefined;
|
|
53
61
|
/**
|
|
54
62
|
* 插件压缩生命周期定义:compaction/start 开启上下文,summary / 替换检查点 / end
|
|
55
|
-
* 作为 update
|
|
56
|
-
*
|
|
57
|
-
*
|
|
63
|
+
* 作为 update 折叠证据。有检查点时产出摘要卡片;end 已到且无检查点时,error 为
|
|
64
|
+
* 非中止报错则产出可见失败行,error 为中止标识或缺失则以 hidden 撤回进行中提示行
|
|
65
|
+
* (已物化节点以 hidden visibility 保留同一 key);仅 start 时渲染「正在压缩上下文…」
|
|
66
|
+
* 提示行。
|
|
58
67
|
*/
|
|
59
68
|
export declare const omCompactionDefinition: ConversationNodeDefinition<OmCompactionState>;
|
|
69
|
+
/** 功能降级警告行载荷:降级问题标识与面向用户的说明(载荷非法时为 null)。 */
|
|
70
|
+
export interface OmWarningChatData {
|
|
71
|
+
/** 降级问题标识(om/warning 载荷 problem)。 */
|
|
72
|
+
readonly problem: string | null;
|
|
73
|
+
/** 面向用户的降级说明(om/warning 载荷 message)。 */
|
|
74
|
+
readonly message: string | null;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* 插件功能降级警告定义:每条 om/warning 事件独立成节点(id 含 seq),渲染为可展开的
|
|
78
|
+
* 「功能降级」警告行。服务端按会话同问题去重后追加,每会话同一问题至多一行。
|
|
79
|
+
*/
|
|
80
|
+
export declare const omWarningDefinition: ConversationNodeDefinition;
|
|
60
81
|
export {};
|
|
61
82
|
//# sourceMappingURL=definition.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/client/definition.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/client/definition.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,iBAAiB,EAEjB,0BAA0B,EAC3B,MAAM,wCAAwC,CAAC;AAGhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAInE,uCAAuC;AACvC,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AAEpD,0CAA0C;AAC1C,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAEjD,OAAO,QAAQ,gDAAgD,CAAC;IAC9D,UAAU,eAAe;QACvB,sCAAsC;QACtC,eAAe,EAAE,oBAAoB,CAAC;QACtC,+BAA+B;QAC/B,YAAY,EAAE,iBAAiB,CAAC;KACjC;CACF;AAED,wBAAwB;AACxB,MAAM,WAAW,oBAAoB;IACnC,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,IAAI,CAAC;IAC7C,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,gDAAgD;IAChD,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,0CAA0C;IAC1C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,4CAA4C;IAC5C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,8BAA8B;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,6CAA6C;IAC7C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,4DAA4D;IAC5D,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,+BAA+B;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,yDAAyD;IACzD,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,kDAAkD;AAClD,UAAU,iBAAiB;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,iBAAiB,CAAC;IACxC,8DAA8D;IAC9D,QAAQ,CAAC,GAAG,CAAC,EAAE,iBAAiB,CAAC;CAClC;AAgBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAe9E;AAuID;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,EAAE,0BAA0B,CAAC,iBAAiB,CAqEhF,CAAC;AAEF,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAChC,qCAAqC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,wCAAwC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,0BAkBjC,CAAC"}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 浏览器客户端入口(exports["./client"] → dist/client.js
|
|
3
|
-
* locale 字典、conversation 业务定义与 keyed 渲染器。宿主 conversation UI
|
|
4
|
-
*
|
|
5
|
-
* 由本 bundle
|
|
2
|
+
* 浏览器客户端入口(exports["./client"] → dist/client.js):注册压缩卡片与功能降级
|
|
3
|
+
* 警告行的 locale 字典、conversation 业务定义与 keyed 渲染器。宿主 conversation UI 只
|
|
4
|
+
* 识别内置 'compact' 检查点,插件自产的压缩检查点(source.plugin = 'dsh-plugin-om')
|
|
5
|
+
* 由本 bundle 认领并在消息列表渲染「已压缩」卡片;om/warning 事件渲染为「功能降级」
|
|
6
|
+
* 警告行。
|
|
6
7
|
*/
|
|
7
8
|
import type { Context } from '@deepseek-ai/cordis';
|
|
8
9
|
/** Required services: 聊天节点槽、会话事件注册表与 locale 服务。 */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAYnD,mDAAmD;AACnD,eAAO,MAAM,MAAM,UAA4C,CAAC;AAEhE,2DAA2D;AAC3D,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAyBxC"}
|
package/dist/client/locales.d.ts
CHANGED
|
@@ -14,7 +14,11 @@ export declare const zh: {
|
|
|
14
14
|
readonly 'compaction.running': "正在压缩上下文…";
|
|
15
15
|
readonly 'compaction.running.observe': "正在压缩上下文(观察)…";
|
|
16
16
|
readonly 'compaction.running.reflect': "正在压缩上下文(反思)…";
|
|
17
|
+
readonly 'compaction.failed': "上下文压缩失败";
|
|
18
|
+
readonly 'compaction.failed.observe': "上下文压缩失败(观察)";
|
|
19
|
+
readonly 'compaction.failed.reflect': "上下文压缩失败(反思)";
|
|
17
20
|
readonly 'compaction.retries': "重试 {count} 次";
|
|
21
|
+
readonly warning: "上下文压缩功能降级";
|
|
18
22
|
};
|
|
19
23
|
/** English dictionary(键集与 zh 一致)。 */
|
|
20
24
|
export declare const en: Record<keyof typeof zh, string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../src/client/locales.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,iDAAiD;AACjD,eAAO,MAAM,EAAE,kBAAkB,CAAC;AAElC,mEAAmE;AACnE,eAAO,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../src/client/locales.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,iDAAiD;AACjD,eAAO,MAAM,EAAE,kBAAkB,CAAC;AAElC,mEAAmE;AACnE,eAAO,MAAM,EAAE;;;;;;;;;;;;;;CAeL,CAAC;AAEX,qCAAqC;AACrC,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,OAAO,EAAE,EAAE,MAAM,CAe9C,CAAC;AAEF,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,kBAAkB;QAC1B,mDAAmD;QACnD,eAAe,EAAE,MAAM,OAAO,EAAE,CAAC;KAClC;CACF"}
|
package/dist/client.js
CHANGED
|
@@ -11,6 +11,8 @@ window.__ModuleLoader__.load({
|
|
|
11
11
|
//#region src/client/definition.ts
|
|
12
12
|
/** 压缩卡片渲染器分发键(合并进 ChatNodeDataMap)。 */
|
|
13
13
|
const COMPACTION_CARD_KIND = "om-compaction";
|
|
14
|
+
/** 功能降级警告行渲染器分发键(合并进 ChatNodeDataMap)。 */
|
|
15
|
+
const OM_WARNING_CARD_KIND = "om-warning";
|
|
14
16
|
/**
|
|
15
17
|
* replace-surface 判定:surfaceOp 为 { op: 'replace' } 对象(与宿主 runtime 的
|
|
16
18
|
* isReplacementSurfaceEvent 同义;宿主该助手位于浏览器 bundle,node 端测试无法求值,
|
|
@@ -51,6 +53,7 @@ window.__ModuleLoader__.load({
|
|
|
51
53
|
return {
|
|
52
54
|
running: false,
|
|
53
55
|
phase: null,
|
|
56
|
+
error: null,
|
|
54
57
|
summary,
|
|
55
58
|
summaryEventSeq: summaryMatch?.event.seq ?? null,
|
|
56
59
|
shadowedItemCount,
|
|
@@ -61,12 +64,38 @@ window.__ModuleLoader__.load({
|
|
|
61
64
|
retryCount
|
|
62
65
|
};
|
|
63
66
|
}
|
|
67
|
+
/** 从 compaction/start 载荷读取压缩 pass(observe/reflect;缺失或非法时回落 null)。 */
|
|
68
|
+
function startPhase(start) {
|
|
69
|
+
const data = start?.event.data;
|
|
70
|
+
return data?.phase === "observe" || data?.phase === "reflect" ? data.phase : null;
|
|
71
|
+
}
|
|
64
72
|
/** 压缩进行中提示行的载荷(统计未就绪,全部为 null)。 */
|
|
65
73
|
function runningData(start) {
|
|
66
|
-
const data = start?.event.data;
|
|
67
74
|
return {
|
|
68
75
|
running: true,
|
|
69
|
-
phase:
|
|
76
|
+
phase: startPhase(start),
|
|
77
|
+
error: null,
|
|
78
|
+
summary: null,
|
|
79
|
+
summaryEventSeq: null,
|
|
80
|
+
shadowedItemCount: null,
|
|
81
|
+
shadowedTokenCount: null,
|
|
82
|
+
shadowedCharCount: null,
|
|
83
|
+
summaryCharCount: null,
|
|
84
|
+
summaryTokenCount: null,
|
|
85
|
+
retryCount: null
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* 压缩失败节点的载荷:end 已到且带非中止 error、无检查点时使用。
|
|
90
|
+
* error 取 compaction/end 载荷中的实际报错文案(非字符串或为空时回落 null);
|
|
91
|
+
* 摘要与统计字段全部为 null。
|
|
92
|
+
*/
|
|
93
|
+
function failureData(start, end) {
|
|
94
|
+
const data = end.event.data;
|
|
95
|
+
return {
|
|
96
|
+
running: false,
|
|
97
|
+
phase: startPhase(start),
|
|
98
|
+
error: typeof data?.error === "string" && data.error !== "" ? data.error : null,
|
|
70
99
|
summary: null,
|
|
71
100
|
summaryEventSeq: null,
|
|
72
101
|
shadowedItemCount: null,
|
|
@@ -103,9 +132,10 @@ window.__ModuleLoader__.load({
|
|
|
103
132
|
}
|
|
104
133
|
/**
|
|
105
134
|
* 插件压缩生命周期定义:compaction/start 开启上下文,summary / 替换检查点 / end
|
|
106
|
-
* 作为 update
|
|
107
|
-
*
|
|
108
|
-
*
|
|
135
|
+
* 作为 update 折叠证据。有检查点时产出摘要卡片;end 已到且无检查点时,error 为
|
|
136
|
+
* 非中止报错则产出可见失败行,error 为中止标识或缺失则以 hidden 撤回进行中提示行
|
|
137
|
+
* (已物化节点以 hidden visibility 保留同一 key);仅 start 时渲染「正在压缩上下文…」
|
|
138
|
+
* 提示行。
|
|
109
139
|
*/
|
|
110
140
|
const omCompactionDefinition = {
|
|
111
141
|
kind: COMPACTION_CARD_KIND,
|
|
@@ -150,12 +180,43 @@ window.__ModuleLoader__.load({
|
|
|
150
180
|
}
|
|
151
181
|
if (state.end !== void 0) {
|
|
152
182
|
const anchorSeq = context.start?.event.seq ?? state.end.event.seq;
|
|
183
|
+
const endData = state.end.event.data;
|
|
184
|
+
if (typeof endData?.error === "string" && endData.error !== "" && !endData.error.startsWith("压缩已中止(signal aborted)")) return chatNode(context, COMPACTION_CARD_KIND, anchorSeq, failureData(context.start, state.end));
|
|
153
185
|
return chatNode(context, COMPACTION_CARD_KIND, anchorSeq, runningData(context.start), "hidden");
|
|
154
186
|
}
|
|
155
187
|
if (context.start !== void 0) return chatNode(context, COMPACTION_CARD_KIND, context.start.event.seq, runningData(context.start));
|
|
156
188
|
return null;
|
|
157
189
|
}
|
|
158
190
|
};
|
|
191
|
+
/**
|
|
192
|
+
* 插件功能降级警告定义:每条 om/warning 事件独立成节点(id 含 seq),渲染为可展开的
|
|
193
|
+
* 「功能降级」警告行。服务端按会话同问题去重后追加,每会话同一问题至多一行。
|
|
194
|
+
*/
|
|
195
|
+
const omWarningDefinition = {
|
|
196
|
+
kind: OM_WARNING_CARD_KIND,
|
|
197
|
+
target: "chat",
|
|
198
|
+
match: (event) => {
|
|
199
|
+
if (event.type !== "om/warning") return null;
|
|
200
|
+
return {
|
|
201
|
+
id: `om-warning:${event.seq}`,
|
|
202
|
+
role: "start"
|
|
203
|
+
};
|
|
204
|
+
},
|
|
205
|
+
start: () => ({}),
|
|
206
|
+
update: (context) => context.state,
|
|
207
|
+
buildViewNode: (context) => {
|
|
208
|
+
const start = context.start;
|
|
209
|
+
if (start === void 0) return null;
|
|
210
|
+
const data = start.event.data;
|
|
211
|
+
const problem = typeof data?.problem === "string" && data.problem !== "" ? data.problem : null;
|
|
212
|
+
const message = typeof data?.message === "string" && data.message !== "" ? data.message : null;
|
|
213
|
+
if (problem === null && message === null) return null;
|
|
214
|
+
return chatNode(context, OM_WARNING_CARD_KIND, start.event.seq, {
|
|
215
|
+
problem,
|
|
216
|
+
message
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
};
|
|
159
220
|
//#endregion
|
|
160
221
|
//#region src/client/locales.ts
|
|
161
222
|
/**
|
|
@@ -174,7 +235,11 @@ window.__ModuleLoader__.load({
|
|
|
174
235
|
"compaction.running": "正在压缩上下文…",
|
|
175
236
|
"compaction.running.observe": "正在压缩上下文(观察)…",
|
|
176
237
|
"compaction.running.reflect": "正在压缩上下文(反思)…",
|
|
177
|
-
"compaction.
|
|
238
|
+
"compaction.failed": "上下文压缩失败",
|
|
239
|
+
"compaction.failed.observe": "上下文压缩失败(观察)",
|
|
240
|
+
"compaction.failed.reflect": "上下文压缩失败(反思)",
|
|
241
|
+
"compaction.retries": "重试 {count} 次",
|
|
242
|
+
warning: "上下文压缩功能降级"
|
|
178
243
|
};
|
|
179
244
|
/** English dictionary(键集与 zh 一致)。 */
|
|
180
245
|
const en = {
|
|
@@ -186,7 +251,11 @@ window.__ModuleLoader__.load({
|
|
|
186
251
|
"compaction.running": "Compressing context…",
|
|
187
252
|
"compaction.running.observe": "Compressing context (observation)…",
|
|
188
253
|
"compaction.running.reflect": "Compressing context (reflection)…",
|
|
189
|
-
"compaction.
|
|
254
|
+
"compaction.failed": "Context compaction failed",
|
|
255
|
+
"compaction.failed.observe": "Context compaction failed (observation)",
|
|
256
|
+
"compaction.failed.reflect": "Context compaction failed (reflection)",
|
|
257
|
+
"compaction.retries": "Retried {count} times",
|
|
258
|
+
warning: "Context compaction degraded"
|
|
190
259
|
};
|
|
191
260
|
//#endregion
|
|
192
261
|
//#region src/client/format.ts
|
|
@@ -248,6 +317,38 @@ window.__ModuleLoader__.load({
|
|
|
248
317
|
})
|
|
249
318
|
});
|
|
250
319
|
}
|
|
320
|
+
if (data.error !== null) {
|
|
321
|
+
const failedLabel = data.phase === "observe" ? t("compaction.failed.observe") : data.phase === "reflect" ? t("compaction.failed.reflect") : t("compaction.failed");
|
|
322
|
+
const errorSummary = data.error.length > 80 ? `${data.error.slice(0, 80)}…` : data.error;
|
|
323
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
324
|
+
style: styles.row,
|
|
325
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.DisclosureRow, {
|
|
326
|
+
className: css.root,
|
|
327
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBrowseOutline16, { size: 14 }),
|
|
328
|
+
chevronClassName: css.chevron,
|
|
329
|
+
title: failedLabel,
|
|
330
|
+
collapsedContent: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
331
|
+
className: css.sep,
|
|
332
|
+
"aria-hidden": true
|
|
333
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
334
|
+
className: css.summary,
|
|
335
|
+
children: errorSummary
|
|
336
|
+
})] }),
|
|
337
|
+
keepContentWhenOpen: true,
|
|
338
|
+
expandable: true,
|
|
339
|
+
expandOnRowClick: true,
|
|
340
|
+
open: expanded,
|
|
341
|
+
onToggle: () => {
|
|
342
|
+
setExpanded((value) => !value);
|
|
343
|
+
},
|
|
344
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
345
|
+
className: css.body,
|
|
346
|
+
style: styles.body,
|
|
347
|
+
children: data.error
|
|
348
|
+
})
|
|
349
|
+
})
|
|
350
|
+
});
|
|
351
|
+
}
|
|
251
352
|
const expandable = data.summary !== null;
|
|
252
353
|
const open = expandable && expanded;
|
|
253
354
|
const stats = data.shadowedItemCount !== null && data.shadowedCharCount !== null && data.shadowedTokenCount !== null && data.summaryCharCount !== null && data.summaryTokenCount !== null ? t("compaction.stats", {
|
|
@@ -293,10 +394,46 @@ window.__ModuleLoader__.load({
|
|
|
293
394
|
});
|
|
294
395
|
const styles = {
|
|
295
396
|
row: {},
|
|
296
|
-
/**
|
|
397
|
+
/** 摘要与失败报错为多行文本,保留换行。 */
|
|
297
398
|
body: { whiteSpace: "pre-wrap" }
|
|
298
399
|
};
|
|
299
400
|
//#endregion
|
|
401
|
+
//#region src/client/OmWarningCard.tsx
|
|
402
|
+
/** 折叠式功能降级警告行(降级说明摘要行 + 完整说明展开)。 */
|
|
403
|
+
const OmWarningCard = (0, react.memo)(function OmWarningCard({ node, t }) {
|
|
404
|
+
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
405
|
+
const { data } = node;
|
|
406
|
+
const message = data.message ?? (data.problem !== null ? data.problem : "");
|
|
407
|
+
const expandable = message !== "";
|
|
408
|
+
const messageSummary = message.length > 80 ? `${message.slice(0, 80)}…` : message;
|
|
409
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.DisclosureRow, {
|
|
410
|
+
className: "om-compaction-root",
|
|
411
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBrowseOutline16, { size: 14 }),
|
|
412
|
+
chevronClassName: "om-compaction-chevron",
|
|
413
|
+
title: t("warning"),
|
|
414
|
+
collapsedContent: expandable ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
415
|
+
className: "om-compaction-sep",
|
|
416
|
+
"aria-hidden": true
|
|
417
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
418
|
+
className: "om-compaction-summary",
|
|
419
|
+
children: messageSummary
|
|
420
|
+
})] }) : void 0,
|
|
421
|
+
keepContentWhenOpen: true,
|
|
422
|
+
expandable,
|
|
423
|
+
expandOnRowClick: true,
|
|
424
|
+
open: expandable && expanded,
|
|
425
|
+
onToggle: () => {
|
|
426
|
+
if (expandable) setExpanded((value) => !value);
|
|
427
|
+
},
|
|
428
|
+
children: expandable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
429
|
+
className: "om-compaction-body",
|
|
430
|
+
style: bodyStyle,
|
|
431
|
+
children: message
|
|
432
|
+
})
|
|
433
|
+
}) });
|
|
434
|
+
});
|
|
435
|
+
const bodyStyle = { whiteSpace: "pre-wrap" };
|
|
436
|
+
//#endregion
|
|
300
437
|
//#region src/client/index.ts
|
|
301
438
|
/** Required services: 聊天节点槽、会话事件注册表与 locale 服务。 */
|
|
302
439
|
const inject = [
|
|
@@ -311,11 +448,17 @@ window.__ModuleLoader__.load({
|
|
|
311
448
|
en
|
|
312
449
|
}), "dsh-plugin-om: compaction card dictionaries");
|
|
313
450
|
ctx.effect(() => ctx.conversationEvents.register(omCompactionDefinition), "dsh-plugin-om: compaction definition");
|
|
451
|
+
ctx.effect(() => ctx.conversationEvents.register(omWarningDefinition), "dsh-plugin-om: om/warning definition");
|
|
314
452
|
ctx.slots.inject("conversation.chat.node", () => ctx.slots.register({
|
|
315
453
|
name: "conversation.chat.node",
|
|
316
454
|
key: "om-compaction",
|
|
317
455
|
locale: NS
|
|
318
456
|
}, OmCompactionCard));
|
|
457
|
+
ctx.slots.inject("conversation.chat.node", () => ctx.slots.register({
|
|
458
|
+
name: "conversation.chat.node",
|
|
459
|
+
key: "om-warning",
|
|
460
|
+
locale: NS
|
|
461
|
+
}, OmWarningCard));
|
|
319
462
|
}
|
|
320
463
|
//#endregion
|
|
321
464
|
exports.apply = apply;
|