dsh-mcmp 2.2.3 → 3.0.0
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 +81 -60
- package/lib/client.js +63 -18
- package/lib/index.js +111 -541
- package/lib/pipeline.js +882 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,50 +1,57 @@
|
|
|
1
|
-
# dsh-mcmp ·
|
|
1
|
+
# dsh-mcmp · 数学建模竞赛自动化论文撰写系统(v3)
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/dsh-mcmp)
|
|
4
4
|
|
|
5
5
|
DeepSeek Harness **持久化 Cordis 插件**:面向全国大学生数学建模竞赛论文撰写的全自动流水线。
|
|
6
|
-
粘贴赛题 → 发送一条以 `/loopbegin` 开头的消息 → 插件按
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
粘贴赛题 → 发送一条以 `/loopbegin` 开头的消息 → 插件按 **中控台 + 五阶段流水线**(阶段零初始化 →
|
|
7
|
+
阶段一 EDA → 阶段二建模 → 阶段三撰写 → 阶段四排版,共 22 个子阶段)自动完成论文撰写,
|
|
8
|
+
每个子阶段由专家子智能体执行,再经**中控台双重质疑**(扫描验证模块 + 评审决策模块)验证,
|
|
9
|
+
问题按 P0-P3 评级处置(P0/P1/P2 阶段级回滚并持久化教训,P3 精确定点修改),
|
|
10
|
+
成果全部落盘,右下角浮动面板实时显示阶段/子阶段/中控台/回滚进度。
|
|
11
|
+
**无论流水线正常完成、出错还是被中止,最终都会生成一版完整、干净的 Markdown 论文(`Final_Paper.md`)。**
|
|
12
|
+
|
|
13
|
+
> 完整设计见仓库内两份设计文档:
|
|
14
|
+
> **`架构.md`**(v3.17,流程架构设计书:中控台、五阶段、评级/回滚/教训机制)与
|
|
15
|
+
> **`提示词.md`**(v3.4,全部子智能体 Prompt 模板,主循环提示词由其逐段生成)。
|
|
9
16
|
|
|
10
17
|
## 功能特性
|
|
11
18
|
|
|
12
19
|
- **消息触发**:输入文本以 `/loopbegin` 开头即自动运行(兼容斜杠命令路径)
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
|
29
|
-
|
|
30
|
-
|
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
>
|
|
20
|
+
- **五阶段 × 22 子阶段**:阶段零(初始化 4)→ 阶段一(EDA 3)→ 阶段二(建模 5)→ 阶段三(撰写 7)→ 阶段四(排版 3),每遍 22 个子阶段,`--round=N` 控制外循环遍数(默认 1,上限 10)
|
|
21
|
+
- **中控台双重质疑**:执行Agent自检与中控台扫描验证执行**同一套六维度质疑标准**(逻辑自洽性/模型合理性/数据敏感性/视觉合理性/规范符合性/教训对照);扫描通过→索引 `VALIDATED`,发现问题→转交评审决策模块
|
|
22
|
+
- **唯一评级机构**:中控台评审决策模块按 **P0-P3** 评级——P0/P1/P2 经 DEPENDENCIES 链追溯根源阶段,阶段级回滚(物理移入 `deprecated/`、索引 `OBSOLETE`、写入教训文件、重跑);P3 精确定点修改(≤3 行代码/≤1 个句子/≤3 个参数,STAGING→VALIDATED)
|
|
23
|
+
- **教训持久化**:每次回滚(<10 次)写入 `ROLLBACK_LESSONS.yaml`(查重去重),所有执行Agent启动时必须完整读取(ACTIVE+RESOLVED)
|
|
24
|
+
- **防崩溃优先**:同一阶段回滚 ≥10 次强制 `FORCED_FINAL` 锁定、通知人工,问题降级为 P3 处理,保证必然产出
|
|
25
|
+
- **执行失败处理**:非质量问题重试 3 次指数退避(5s/10s/20s),全失败暂停人工介入(不计入回滚计数器),失败日志写入 `transactions.log`
|
|
26
|
+
- **索引导航**:`FILE_INDEX.yaml` 记录全部产出物的位置/状态(STAGING/VALIDATED/OBSOLETE/FORCED_FINAL)/依赖,上游状态跨阶段读取有权限校验
|
|
27
|
+
- **视觉模块集成**:涉及图表的子阶段(1.3/2.4/2.5/3.3/3.4/4.2/4.3)按两阶段流程调用视觉模块(详实描述→系统性质疑);不可用时标记"待人工确认"
|
|
28
|
+
- **论文兜底定稿**:4.3 产出 `Final_Paper.md`;即使流水线提前出错或中止,也会追加一次兜底定稿
|
|
29
|
+
- **实时进度面板**:浮动窗口显示总体进度、五阶段打点、当前子阶段、中控台模块、回滚计数与 P0-P3 评级、强制锁定提示、日志、产出文件,支持中止/重置
|
|
30
|
+
- **断点续跑与重置**:中断/关闭窗口不丢进度,再次 `/loopbegin` 自动续跑;`/loopreset` 或面板「重置(全新开始)」清空续跑记录
|
|
31
|
+
- **原生工作流卡片**:聊天区实时显示每个子智能体的运行状态(执行/扫描/评审/兜底)
|
|
32
|
+
|
|
33
|
+
## 五阶段流水线(每遍 22 个子阶段)
|
|
34
|
+
|
|
35
|
+
| 阶段 | 子阶段 | 核心产出 |
|
|
36
|
+
|------|--------|----------|
|
|
37
|
+
| 阶段零 初始化 | 0.1 创建目录 · 0.2 加载数据 · 0.3 初始化索引 · 0.4 初始化教训文件 | `config/`、`raw_data/`、`FILE_INDEX.yaml`、`ROLLBACK_LESSONS.yaml` |
|
|
38
|
+
| 阶段一 EDA | 1.1 清洗 · 1.2 特征工程 · 1.3 EDA可视化 | 清洗/变换后数据、EDA 图表与报告 |
|
|
39
|
+
| 阶段二 建模 | 2.1 模型筛选 · 2.2 模型建立 · 2.3 模型求解 · 2.4 图表生成 · 2.5 检验与质疑 | 假设/公式、`code/` 求解代码、模型图表、检验质疑报告 |
|
|
40
|
+
| 阶段三 撰写 | 3.1 重述与背景 · 3.2 假设与符号 · 3.3 建模与求解章节 · 3.4 结果分析 · 3.5 摘要 · 3.6 参考文献 · 3.7 附录代码 | `stage_03_outputs/01~07` 各章节 |
|
|
41
|
+
| 阶段四 排版 | 4.1 合并 · 4.2 修正路径 · 4.3 最终产出 | `merged_draft.md`、`merged_with_figures.md`、**`Final_Paper.md`** |
|
|
42
|
+
|
|
43
|
+
> 每个子阶段完成后:执行Agent按 3.3 六维度自检并写入 `_report.yaml`(SUCCESS/HAS_ISSUES/NEEDS_REVIEW)→
|
|
44
|
+
> 中控台扫描验证(SUCCESS 时)或评审决策(HAS_ISSUES/NEEDS_REVIEW 时)→ 通过后推进下一子阶段。
|
|
38
45
|
|
|
39
46
|
## 使用方法
|
|
40
47
|
|
|
41
48
|
1. **发送赛题**:把数学建模竞赛题目完整粘贴到对话框并发送;
|
|
42
49
|
2. **触发插件**:发送一条以 `/loopbegin` 开头的消息:
|
|
43
|
-
- `/loopbegin` —— 默认 1
|
|
44
|
-
- `/loopbegin --round=3` —— 3
|
|
45
|
-
- `/loopbegin --from 题目.txt` —— 从文件读取赛题(
|
|
46
|
-
- `/loopbegin --model glm-vision/glm-4.7-Flash` —— 可选显式覆盖(也可用 `--provider 提供商 --model 模型` 分拆形式)。**默认不需要此参数**:流水线子任务的模型**强制跟随你在对话右下角选择的模型**(每次启动时读取当前选择)
|
|
47
|
-
3. **查看进度**:右下角浮动面板(
|
|
50
|
+
- `/loopbegin` —— 默认 1 遍(22 个子阶段)
|
|
51
|
+
- `/loopbegin --round=3` —— 3 遍外循环(上限 10)
|
|
52
|
+
- `/loopbegin --from 题目.txt` —— 从文件读取赛题(支持含空格/中文的文件名,也可用 `--from=文件` 形式)
|
|
53
|
+
- `/loopbegin --model glm-vision/glm-4.7-Flash` —— 可选显式覆盖(也可用 `--provider 提供商 --model 模型` 分拆形式)。**默认不需要此参数**:流水线子任务的模型**强制跟随你在对话右下角选择的模型**(每次启动时读取当前选择);若无法读取,兜底使用 `deepseek-official/deepseek-v4-flash`
|
|
54
|
+
3. **查看进度**:右下角浮动面板(阶段打点、中控台、回滚、日志、文件)+ 聊天区工作流卡片。
|
|
48
55
|
|
|
49
56
|
辅助命令:`/loopstatus`(查看进度)、`/loopabort`(中止,已产出成果保留)、`/loopreset`(清空状态与断点续跑记录,下次 `/loopbegin` 从头全新开始;等价于面板「重置(全新开始)」按钮)。
|
|
50
57
|
|
|
@@ -67,9 +74,6 @@ DeepSeek Harness **持久化 Cordis 插件**:面向全国大学生数学建模
|
|
|
67
74
|
```powershell
|
|
68
75
|
# 一条命令完成:安装包 + 自动注册(通过 bundle 机制)
|
|
69
76
|
pnpm dsh plugin --profile web add dsh-mcmp
|
|
70
|
-
# 等价调用形式:
|
|
71
|
-
# dsh plugin --profile web add dsh-mcmp
|
|
72
|
-
# npx @deepseek-ai/dsh plugin --profile web add dsh-mcmp
|
|
73
77
|
|
|
74
78
|
# 然后重启:
|
|
75
79
|
# 重启 pnpm dsh web → 刷新网页
|
|
@@ -92,35 +96,49 @@ pnpm dsh plugin --profile web remove dsh-mcmp
|
|
|
92
96
|
|
|
93
97
|
```
|
|
94
98
|
数学建模流水线/
|
|
95
|
-
├──
|
|
96
|
-
├──
|
|
97
|
-
├──
|
|
98
|
-
├──
|
|
99
|
-
├──
|
|
100
|
-
|
|
101
|
-
├──
|
|
102
|
-
|
|
99
|
+
├── config/ # 项目配置(Project_Config.yaml 等)
|
|
100
|
+
├── raw_data/ # 原始数据
|
|
101
|
+
├── FILE_INDEX.yaml # ★ 索引文件:全部产出物的位置/状态/依赖(STAGING/VALIDATED/OBSOLETE/FORCED_FINAL)
|
|
102
|
+
├── ROLLBACK_LESSONS.yaml # ★ 教训文件:回滚教训持久化,执行Agent启动必读
|
|
103
|
+
├── transactions.log # 事务日志:执行失败、强制锁定、DAG 阻断等
|
|
104
|
+
├── stage_00_outputs/ # 阶段零产出(含 _report.yaml 上报文件)
|
|
105
|
+
├── stage_01_outputs/ # 阶段一产出(清洗/特征/EDA 图表与报告)
|
|
106
|
+
├── stage_02_outputs/ # 阶段二产出(建模文档、code 求解代码、figures 图表)
|
|
107
|
+
├── stage_03_outputs/ # 阶段三产出(01~07 各章节 Markdown)
|
|
108
|
+
├── stage_04_outputs/ # 阶段四产出(合并稿、修正稿)
|
|
109
|
+
├── code/ # 建模求解核心代码(附录代码来源)
|
|
110
|
+
├── figures/ # 全部图表
|
|
111
|
+
├── deprecated/ # 回滚废弃文件(物理移入,不删除;建议每场比赛结束后人工清理)
|
|
112
|
+
└── Final_Paper.md # ★ 最终交付:完整、干净的 Markdown 论文(无论成败都会生成)
|
|
103
113
|
```
|
|
104
114
|
|
|
105
115
|
## 架构
|
|
106
116
|
|
|
117
|
+
> 插件按职责拆分为三个模块,主循环按《架构.md》v3 实现。
|
|
118
|
+
|
|
107
119
|
```
|
|
108
120
|
用户消息(/loopbegin 开头)
|
|
109
121
|
│ session/event 全局监听(或 commands 斜杠命令)
|
|
110
122
|
▼
|
|
111
|
-
|
|
112
|
-
├─
|
|
113
|
-
├─
|
|
114
|
-
├─
|
|
115
|
-
├─
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
123
|
+
程序入口模块(lib/index.js)
|
|
124
|
+
├─ 输入框内检测:斜杠命令注册 + 消息触发监听 + systemPrompt 模型侧提示
|
|
125
|
+
├─ 模型选择:父对话当前选择 / --model 显式覆盖 / 兜底 DeepSeek V4 Flash
|
|
126
|
+
├─ 题目检测:提取赛题(对话文本或 --from 文件)
|
|
127
|
+
├─ 识图能力探测(宿主服务/工具注册表扫描;子智能体以自身工具列表为准)
|
|
128
|
+
└─ 启动解析与校验(--round/--fresh/--model/--from)→ 委托主循环模块启动
|
|
129
|
+
▼
|
|
130
|
+
论文写作主循环模块(lib/pipeline.js,createPipeline 实例)
|
|
131
|
+
├─ 五阶段 × 22 子阶段:每个子阶段启动执行Agent(提示词由 提示词.md 2.1/2.2 + 三 生成)
|
|
132
|
+
├─ 中控台·扫描验证模块:执行Agent上报 SUCCESS 后按 3.3 六维度扫描(提示词.md 4.1)
|
|
133
|
+
├─ 中控台·评审决策模块:P0-P3 评级、根源定位、回滚裁定与 P3 定点修改(提示词.md 5.1)
|
|
134
|
+
├─ 代码逻辑:回滚计数器、阶段级删除调度、强制锁定(FORCED_FINAL)、重跑、断点续跑
|
|
135
|
+
├─ 执行失败重试(3 次指数退避)+ 事务日志 transactions.log
|
|
136
|
+
└─ 兜底定稿:不论成败补一版 Final_Paper.md
|
|
137
|
+
▼
|
|
138
|
+
显示界面模块(lib/client.js,标准 __ModuleLoader__ bundle)
|
|
122
139
|
├─ shell.overlay 浮动面板,每 1.2s fetch('/mcmp-api/state') 轮询
|
|
123
|
-
└─
|
|
140
|
+
└─ 五阶段打点/子阶段/中控台模块/回滚计数/P0-P3 评级/强制锁定提示/日志/文件/中止重置按钮
|
|
141
|
+
(面板 API 路由 /mcmp-api/{state,abort,reset} 由程序入口模块注册并转发)
|
|
124
142
|
```
|
|
125
143
|
|
|
126
144
|
## 文件说明
|
|
@@ -131,9 +149,12 @@ Client 插件(dsh-mcmp,标准 __ModuleLoader__ bundle)
|
|
|
131
149
|
| --- | --- |
|
|
132
150
|
| `package.json` | 插件包清单:`dsh.bundle` 补丁声明、`dsh.client` 声明、`exports` 入口(`.` → Host,`./client` → 面板 bundle) |
|
|
133
151
|
| `cordis.patch.yml` | **bundle 补丁**:安装时自动注册插件行(`insert: mcmp`),无需手动编辑配置 |
|
|
134
|
-
| `
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
152
|
+
| `架构.md` | **流程架构设计书 v3.17**:中控台双模块、五阶段、评级/回滚/教训/索引机制与约束 |
|
|
153
|
+
| `提示词.md` | **Prompt 设计 v3.4**:执行Agent/扫描验证模块/评审决策模块的全部提示词模板(主循环按此生成) |
|
|
154
|
+
| `lib/index.js` | **程序入口模块**:输入框内检测、模型选择、题目检测、识图能力探测、启动参数解析与校验、`/mcmp-api` 面板路由注册 |
|
|
155
|
+
| `lib/pipeline.js` | **论文写作主循环模块**:五阶段元数据与提示词构造、中控台扫描/评审调度、回滚与锁定、断点续跑、运行状态与进度快照、中止/重置 |
|
|
156
|
+
| `lib/client.js` | **显示界面模块**:浮动进度面板(标准 `__ModuleLoader__` bundle,`fetch` 轮询、显示与交互) |
|
|
157
|
+
| `tests/smoke.mjs` | **冒烟测试**:伪造 Cordis ctx 驱动插件,验证启动/扫描评审路由/回滚与强制锁定/P3 定点修改/失败重试/断点续跑/中止/兜底/`--from`/识图探测/`--model` 等路径,`node tests/smoke.mjs`(不随 npm 包发布) |
|
|
137
158
|
|
|
138
159
|
## License
|
|
139
160
|
|
package/lib/client.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* dsh-mcmp · Client
|
|
3
|
-
*
|
|
2
|
+
* dsh-mcmp · 显示界面模块(Client 半,标准 __ModuleLoader__ 客户端 bundle)
|
|
3
|
+
* 小浮窗的显示与交互:每 1.2s 通过 fetch('/mcmp-api/state') 轮询 Host 状态,
|
|
4
4
|
* 中止/重置通过 POST /mcmp-api/abort|reset。拖拽仅绑定标题文字。
|
|
5
|
+
* 按《架构.md》v3 目标架构渲染:五阶段(阶段零~四)子阶段进度、中控台模块、
|
|
6
|
+
* 回滚计数与强制锁定、P0-P3 问题评级;主循环重写前,快照无 stages 字段时
|
|
7
|
+
* 自动回退到旧 S1-S8 步骤渲染(见 index.js 中的 v3 快照契约)。
|
|
8
|
+
* (程序入口模块见 lib/index.js,论文写作主循环模块见 lib/pipeline.js)
|
|
5
9
|
*/
|
|
6
10
|
window.__ModuleLoader__.load({
|
|
7
11
|
id: "dsh-mcmp",
|
|
@@ -44,6 +48,8 @@ window.__ModuleLoader__.load({
|
|
|
44
48
|
'.mcmp-actions { display: flex; gap: 8px; justify-content: flex-end; }',
|
|
45
49
|
'.mcmp-actions .mcmp-btn { border: 1px solid var(--dsw-alias-border-l1); padding: 4px 12px; font-size: 12px; }',
|
|
46
50
|
'.mcmp-abort { color: var(--dsw-alias-state-error-primary, #dc2626); border-color: var(--dsw-alias-state-error-primary, #dc2626); }',
|
|
51
|
+
'.mcmp-super { color: var(--dsw-alias-brand-primary, #2563eb); font-weight: 600; }',
|
|
52
|
+
'.mcmp-lock { color: var(--dsw-alias-state-error-primary, #dc2626); font-weight: 600; }',
|
|
47
53
|
].join('\n')
|
|
48
54
|
|
|
49
55
|
const h = react.createElement
|
|
@@ -76,6 +82,8 @@ window.__ModuleLoader__.load({
|
|
|
76
82
|
if (!snap || snap.status === 'idle' || dismissedRun === snap.runId) return null
|
|
77
83
|
const st = snap.status
|
|
78
84
|
const pct = snap.pct
|
|
85
|
+
// v3 架构(架构.md):快照含 stages(五阶段)时走新渲染;当前主循环(旧 S1-S8)缺失该字段,回退旧渲染
|
|
86
|
+
const isV3 = Array.isArray(snap.stages) && snap.stages.length > 0
|
|
79
87
|
|
|
80
88
|
// 拖拽只绑定在标题文字上,避免指针捕获吞掉同栏按钮的点击
|
|
81
89
|
const onTitleDown = (e) => {
|
|
@@ -106,27 +114,42 @@ window.__ModuleLoader__.load({
|
|
|
106
114
|
const ss = Math.floor((elapsed % 60000) / 1000)
|
|
107
115
|
const elapsedText = mm > 0 ? mm + '分' + (ss < 10 ? '0' : '') + ss + '秒' : ss + '秒'
|
|
108
116
|
|
|
109
|
-
const stepRows =
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
const stepRows = isV3
|
|
118
|
+
? (snap.stages || []).map((stage) => {
|
|
119
|
+
let dots = ''
|
|
120
|
+
for (let k = 0; k < stage.subTotal; k++) {
|
|
121
|
+
dots += k < stage.done ? '●' : '○'
|
|
122
|
+
}
|
|
123
|
+
const name = h('span', { className: 'mname' }, stage.key + ' ' + stage.name)
|
|
124
|
+
const dotEl = h('span', { className: 'mcmp-dots ' + (stage.done > 0 ? 'mcmp-done-dot' : '') }, dots)
|
|
125
|
+
const cnt = h('span', { className: 'mcmp-label' }, stage.done + '/' + stage.subTotal)
|
|
126
|
+
return h('div', { key: stage.key, className: 'mcmp-step' + (stage.active ? ' active' : '') }, name, dotEl, cnt)
|
|
127
|
+
})
|
|
128
|
+
: (snap.steps || []).map((step) => {
|
|
129
|
+
let dots = ''
|
|
130
|
+
for (let k = 0; k < step.iterTotal; k++) {
|
|
131
|
+
dots += k < step.done ? '●' : '○'
|
|
132
|
+
}
|
|
133
|
+
const name = h('span', { className: 'mname' }, step.key + ' ' + step.name)
|
|
134
|
+
const dotEl = h('span', { className: 'mcmp-dots ' + (step.done > 0 ? 'mcmp-done-dot' : '') }, dots)
|
|
135
|
+
const cnt = h('span', { className: 'mcmp-label' }, step.done + '/' + step.iterTotal)
|
|
136
|
+
return h('div', { key: step.key, className: 'mcmp-step' + (step.active ? ' active' : '') }, name, dotEl, cnt)
|
|
137
|
+
})
|
|
119
138
|
|
|
120
139
|
const logLines = (snap.logs || []).map((l, i) => l.t + ' ' + l.m).join('\n')
|
|
121
140
|
const fileRows = (snap.files || []).map((f, i) => h('div', { key: 'f' + i, className: 'mcmp-file' }, (f.type === 'dir' ? '📁 ' : '📄 ') + f.name))
|
|
122
141
|
|
|
123
|
-
const curLine =
|
|
124
|
-
?
|
|
125
|
-
|
|
142
|
+
const curLine = isV3
|
|
143
|
+
? (snap.cur
|
|
144
|
+
? snap.cur.stageKey + ' ' + snap.cur.stageName + ' · 子阶段 ' + (snap.cur.subIdx + 1) + '/' + snap.cur.subTotal + ' 「' + snap.cur.subName + '」'
|
|
145
|
+
: st === 'completed' ? '🎉 全部子阶段已完成' : '等待中…')
|
|
146
|
+
: (snap.cur
|
|
147
|
+
? snap.cur.stepKey + ' ' + snap.cur.stepName + ' · 迭代 ' + (snap.cur.iterIdx + 1) + '/' + snap.cur.iterTotal + ' 「' + snap.cur.iterName + '」'
|
|
148
|
+
: st === 'completed' ? '🎉 全部迭代已完成' : '等待中…')
|
|
126
149
|
|
|
127
150
|
const children = []
|
|
128
151
|
children.push(h('div', { key: 'head', className: 'mcmp-head' },
|
|
129
|
-
h('span', { className: 'mcmp-title', title: '按住拖动面板', onPointerDown: onTitleDown }, '
|
|
152
|
+
h('span', { className: 'mcmp-title', title: '按住拖动面板', onPointerDown: onTitleDown }, '数学建模论文撰写系统'),
|
|
130
153
|
h('span', { className: 'mcmp-chip mcmp-chip-' + (STATUS_CLASS[st] || '') }, STATUS_TEXT[st] || st),
|
|
131
154
|
h('button', { key: 'min', className: 'mcmp-btn', title: minimized ? '展开面板' : '最小化面板', onClick: () => setMinimized(!minimized) }, minimized ? '□' : '—'),
|
|
132
155
|
h('button', { key: 'close', className: 'mcmp-btn', title: '关闭面板', onClick: () => setDismissedRun(snap.runId) }, '×'),
|
|
@@ -141,10 +164,32 @@ window.__ModuleLoader__.load({
|
|
|
141
164
|
h('div', { className: 'mcmp-fill', style: { width: pct + '%' } }),
|
|
142
165
|
))
|
|
143
166
|
body.push(h('div', { key: 'meta', className: 'mcmp-row' },
|
|
144
|
-
h('span', { className: 'mcmp-label' },
|
|
167
|
+
h('span', { className: 'mcmp-label' }, isV3
|
|
168
|
+
? '已完成 ' + snap.done + '/' + snap.total + ' 个子阶段 · ' + elapsedText
|
|
169
|
+
: '第 ' + snap.round + '/' + snap.rounds + ' 轮 · ' + snap.done + '/' + snap.total + ' 次迭代 · ' + elapsedText),
|
|
145
170
|
h('span', { className: 'mcmp-label' }, '已完成'),
|
|
146
171
|
))
|
|
147
172
|
body.push(h('div', { key: 'cur', className: 'mcmp-cur' }, curLine))
|
|
173
|
+
if (isV3 && snap.supervisor) {
|
|
174
|
+
const sup = snap.supervisor
|
|
175
|
+
if (sup.module) {
|
|
176
|
+
body.push(h('div', { key: 'super', className: 'mcmp-row' },
|
|
177
|
+
h('span', { className: 'mcmp-label' }, '中控台'),
|
|
178
|
+
h('span', { className: 'mcmp-super' }, sup.module),
|
|
179
|
+
))
|
|
180
|
+
}
|
|
181
|
+
const rb = '回滚 ' + (Number.isSafeInteger(sup.rollbackCount) ? sup.rollbackCount : 0)
|
|
182
|
+
+ '/' + (Number.isSafeInteger(sup.rollbackLimit) ? sup.rollbackLimit : 10) + ' 次'
|
|
183
|
+
const q = sup.issues || {}
|
|
184
|
+
const iss = 'P0 ' + (q.P0 || 0) + ' · P1 ' + (q.P1 || 0) + ' · P2 ' + (q.P2 || 0) + ' · P3 ' + (q.P3 || 0)
|
|
185
|
+
body.push(h('div', { key: 'rb', className: 'mcmp-row' },
|
|
186
|
+
h('span', { className: 'mcmp-label' }, rb),
|
|
187
|
+
h('span', { className: 'mcmp-label' }, iss),
|
|
188
|
+
))
|
|
189
|
+
if (sup.forcedFinal) {
|
|
190
|
+
body.push(h('div', { key: 'lock', className: 'mcmp-lock' }, '🔒 回滚已达上限,流水线已强制锁定(请人工介入)'))
|
|
191
|
+
}
|
|
192
|
+
}
|
|
148
193
|
if (snap.agentLabel && st === 'running') {
|
|
149
194
|
body.push(h('div', { key: 'agent', className: 'mcmp-label' }, '子任务: ' + snap.agentLabel))
|
|
150
195
|
}
|
|
@@ -182,7 +227,7 @@ window.__ModuleLoader__.load({
|
|
|
182
227
|
document.head.appendChild(tag)
|
|
183
228
|
}
|
|
184
229
|
ctx.slots.inject('shell.overlay', () => ctx.slots.register(
|
|
185
|
-
{ name: 'shell.overlay', id: 'mcmp-pipeline-panel', order: 50, label: '
|
|
230
|
+
{ name: 'shell.overlay', id: 'mcmp-pipeline-panel', order: 50, label: '数学建模论文撰写系统进度面板' },
|
|
186
231
|
() => h(Panel),
|
|
187
232
|
))
|
|
188
233
|
}
|