dsh-engineering-ui 0.0.0-stage → 1.5.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/LICENSE +21 -0
- package/README.md +772 -3
- package/engineering/plugins/dsh-engineering-ui/cordis.patch.yml +5 -0
- package/engineering/plugins/dsh-engineering-ui/icon.svg +14 -0
- package/engineering/plugins/dsh-engineering-ui/lib/client.js +8259 -0
- package/engineering/plugins/dsh-engineering-ui/lib/defense-sign.js +1552 -0
- package/engineering/plugins/dsh-engineering-ui/lib/index.js +5633 -0
- package/engineering/plugins/dsh-engineering-ui/lib/job-wait-guard.js +236 -0
- package/engineering/plugins/dsh-engineering-ui/lib/mem-guard.js +331 -0
- package/engineering/plugins/dsh-engineering-ui/lib/webots.js +114 -0
- package/engineering/plugins/dsh-engineering-ui/locale/en.json +6 -0
- package/engineering/plugins/dsh-engineering-ui/locale/zh.json +6 -0
- package/engineering/plugins/dsh-engineering-ui/preset-engineering.patch.yml +601 -0
- package/engineering/skills/assembly-orchestration/SKILL.md +651 -0
- package/engineering/skills/cad-workflow/SKILL.md +132 -0
- package/engineering/skills/mode-selection/SKILL.md +660 -0
- package/engineering/skills/physics-in-loop/SKILL.md +238 -0
- package/engineering/skills/physics-in-loop/references/feadocs.md +142 -0
- package/engineering/skills/solidworks-bridge/SKILL.md +445 -0
- package/engineering/skills/sw-design/SKILL.md +112 -0
- package/engineering/skills/sw-design/references/autocad-workflow.md +81 -0
- package/engineering/skills/sw-design/references/gbt-drafting.md +71 -0
- package/engineering/skills/sw-to-cad/SKILL.md +121 -0
- package/engineering/skills/webots-simulation/SKILL.md +58 -0
- package/engineering/tools/LICENSE.Auto-SolidWorks +21 -0
- package/engineering/tools/_plugin_paths.py +93 -0
- package/engineering/tools/_root.py +330 -0
- package/engineering/tools/_store.py +446 -0
- package/engineering/tools/ac_bridge.py +459 -0
- package/engineering/tools/ac_rules.json +21 -0
- package/engineering/tools/ac_validate.py +699 -0
- package/engineering/tools/ask_user.py +887 -0
- package/engineering/tools/build_arm1.py +46 -0
- package/engineering/tools/build_assembly.py +94 -0
- package/engineering/tools/build_base.py +57 -0
- package/engineering/tools/build_housing.py +70 -0
- package/engineering/tools/build_structural.py +43 -0
- package/engineering/tools/build_transmission.py +69 -0
- package/engineering/tools/cadx.lsp +128 -0
- package/engineering/tools/choice_contract.py +61 -0
- package/engineering/tools/conn_state.py +1671 -0
- package/engineering/tools/defense_gate.py +3374 -0
- package/engineering/tools/drawing_input.py +314 -0
- package/engineering/tools/env_check.py +467 -0
- package/engineering/tools/examples/build_axis.py +142 -0
- package/engineering/tools/examples/build_cup.py +56 -0
- package/engineering/tools/examples/build_plate.py +58 -0
- package/engineering/tools/examples/build_sphere.py +30 -0
- package/engineering/tools/examples/build_transition_duct.py +381 -0
- package/engineering/tools/gate_integrity.py +401 -0
- package/engineering/tools/mode2_flow.py +3589 -0
- package/engineering/tools/mode_checker.py +77 -0
- package/engineering/tools/mode_gate.py +8013 -0
- package/engineering/tools/part_registry.py +4266 -0
- package/engineering/tools/physics/__init__.py +50 -0
- package/engineering/tools/physics/_compat.py +12 -0
- package/engineering/tools/physics/design_state.py +142 -0
- package/engineering/tools/physics/domain_validator.py +751 -0
- package/engineering/tools/physics/fatigue.py +489 -0
- package/engineering/tools/physics/fea_solver.py +1163 -0
- package/engineering/tools/physics/feapy_solver.py +314 -0
- package/engineering/tools/physics/gb_materials.json +1228 -0
- package/engineering/tools/physics/geometry_gate.py +337 -0
- package/engineering/tools/physics/load_case.py +951 -0
- package/engineering/tools/physics/material_db.py +874 -0
- package/engineering/tools/physics/mesh_adapter.py +321 -0
- package/engineering/tools/physics/refine_rules.py +272 -0
- package/engineering/tools/physics/rules/gb_base_rules.json +377 -0
- package/engineering/tools/physics/rules/gb_drafting_rules.json +57 -0
- package/engineering/tools/physics/rules/gb_electrical_rules.json +25 -0
- package/engineering/tools/physics/rules/gb_fasteners_rules.json +73 -0
- package/engineering/tools/physics/rules/gb_housing_rules.json +41 -0
- package/engineering/tools/physics/rules/gb_manufacturing_rules.json +25 -0
- package/engineering/tools/physics/rules/gb_material_verify_rules.json +72 -0
- package/engineering/tools/physics/rules/gb_materials_rules.json +377 -0
- package/engineering/tools/physics/rules/gb_safety_rules.json +89 -0
- package/engineering/tools/physics/rules/gb_springs_rules.json +41 -0
- package/engineering/tools/physics/rules/gb_standards_registry.json +1646 -0
- package/engineering/tools/physics/rules/gb_structural_rules.json +201 -0
- package/engineering/tools/physics/rules/gb_surface_rules.json +25 -0
- package/engineering/tools/physics/rules/gb_transmission_rules.json +233 -0
- package/engineering/tools/physics/rules/housing_rules.json +48 -0
- package/engineering/tools/physics/rules/manifest.json +54 -0
- package/engineering/tools/physics/rules/mold_rules.json +48 -0
- package/engineering/tools/physics/rules/structural_rules.json +56 -0
- package/engineering/tools/physics/rules/transmission_rules.json +48 -0
- package/engineering/tools/physics/simulation_report.py +829 -0
- package/engineering/tools/physics_bridge.py +2685 -0
- package/engineering/tools/profile-manifest.ps1 +72 -0
- package/engineering/tools/run_regression.py +109 -0
- package/engineering/tools/settings.py +419 -0
- package/engineering/tools/solidworks-modeling.md +519 -0
- package/engineering/tools/sw_bridge.py +8215 -0
- package/engineering/tools/sw_guard.py +1066 -0
- package/engineering/tools/sw_surface.py +87 -0
- package/engineering/tools/swapi.py +14766 -0
- package/engineering/tools/verify_sync.py +218 -0
- package/engineering/tools/visual_check.py +2589 -0
- package/engineering/tools/webots_env.py +121 -0
- package/engineering/tools/webots_mcp/__init__.py +3 -0
- package/engineering/tools/webots_mcp/__main__.py +3 -0
- package/engineering/tools/webots_mcp/assembly.py +391 -0
- package/engineering/tools/webots_mcp/bootstrap.py +55 -0
- package/engineering/tools/webots_mcp/controller_worker.py +124 -0
- package/engineering/tools/webots_mcp/evidence.py +288 -0
- package/engineering/tools/webots_mcp/fake_worker.py +69 -0
- package/engineering/tools/webots_mcp/fault_resources.py +121 -0
- package/engineering/tools/webots_mcp/host.py +45 -0
- package/engineering/tools/webots_mcp/ledger.py +73 -0
- package/engineering/tools/webots_mcp/owned_job.py +70 -0
- package/engineering/tools/webots_mcp/physical_gate.py +187 -0
- package/engineering/tools/webots_mcp/physics.py +152 -0
- package/engineering/tools/webots_mcp/pipeline.py +108 -0
- package/engineering/tools/webots_mcp/recipes.py +129 -0
- package/engineering/tools/webots_mcp/repair.py +132 -0
- package/engineering/tools/webots_mcp/repair_trial.py +375 -0
- package/engineering/tools/webots_mcp/runtime.py +311 -0
- package/engineering/tools/webots_mcp/server.py +217 -0
- package/engineering/tools/webots_mcp/sw_export.py +509 -0
- package/engineering/tools/webots_mcp/transport.py +156 -0
- package/engineering/tools/workflow_gate.py +6134 -0
- package/package.json +64 -4
|
@@ -0,0 +1,660 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mode-selection
|
|
3
|
+
description: Task mode selector with mandatory workflow gate for design tasks
|
|
4
|
+
whenToUse: Every design task must pass through this skill before any work begins
|
|
5
|
+
disable-model-invocation: false
|
|
6
|
+
user-invocable: true
|
|
7
|
+
source: engineering
|
|
8
|
+
provider: filesystem
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Task Mode Selector with Code-Enforced Workflow Gate
|
|
12
|
+
|
|
13
|
+
## ⛔ 先自查:你是不是被主对话派出来的子代理?
|
|
14
|
+
|
|
15
|
+
运行 `echo $env:DSH_SESSION_ID`,或看自己的 system prompt:
|
|
16
|
+
**如果本次对话是父会话用 `subagent_fork` 派出来的子代理(delegationDepth>0),
|
|
17
|
+
不要执行本技能的门禁流程**,按主对话给你的房间任务直接干活:
|
|
18
|
+
|
|
19
|
+
| 你的身份 | 允许做什么 | 禁止做什么 |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| **建模小屋 / 总理子代理** | 本房间建模、验证、`room-report`、`room-artifact`、`prime-report`(总理) | `init` / `provide_context` / `select` / `confirm-assembly` / `begin-stage` 等门禁命令 —— 门禁已在主对话完成 |
|
|
22
|
+
| **总计子代理** | 只调 `mode2_flow.py` 的阶段/提问/编制命令 + `ask_user.py` | `init` / `provide_context` / `select`(那是主对话的活) |
|
|
23
|
+
|
|
24
|
+
> 实测教训(会话 `session-31c56a28`):三个建模小屋各自加载本技能后又跑了一遍
|
|
25
|
+
> `init → provide_context → begin-stage → ask`,把主对话的十阶段状态覆盖成四份。
|
|
26
|
+
> 现在代码侧已加 `ROOT_SESSION_REQUIRED`:子代理调这些编排命令会被直接拒绝并提示。
|
|
27
|
+
|
|
28
|
+
## Rules (Code-Enforced, Not Just Prompts)
|
|
29
|
+
|
|
30
|
+
**Rule 0: Any design work MUST go through this gate first.**(仅限主对话)
|
|
31
|
+
|
|
32
|
+
## Step 1: Analyze Task Type
|
|
33
|
+
|
|
34
|
+
| Feature | Mode | Architecture |
|
|
35
|
+
|---------|------|--------------|
|
|
36
|
+
| Single part, simple geometry | **Mode 1: Basic Part Building** | Single-thread direct modeling |
|
|
37
|
+
| Multi-part assembly, mechanism, transmission | **Mode 2: Complex Assembly** | Multi-room subagent collaboration |
|
|
38
|
+
| User sent image/screenshot | **Mode 3: Image Analysis** | Single-thread recognition rebuild |
|
|
39
|
+
| 用户要**仿真 / 运动学 / 碰撞 / 传感器 / 机器人跑起来**(不要求新图纸) | **附加动作,不是新模式** | 见下方「Webots 仿真分支」 |
|
|
40
|
+
|
|
41
|
+
> 🟦 **仿真不是第四种模式**:它挂在已有模式的输出端。先照旧判定 1/2/3 并走完该走的门禁,
|
|
42
|
+
> 再按下面的「Webots 仿真分支」把**已交付的模型**送进仿真。**绝不允许**因为"要仿真"
|
|
43
|
+
> 就跳过建模/出图,也绝不允许用仿真结果反过来替代三大防线。
|
|
44
|
+
|
|
45
|
+
## Step 2: Output Mode Declaration
|
|
46
|
+
|
|
47
|
+
Must output BEFORE any design work:
|
|
48
|
+
```
|
|
49
|
+
[MODE SELECTED] Mode 1 / Mode 2 / Mode 3
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Step 3: Mode-Specific Execution
|
|
53
|
+
|
|
54
|
+
- **Mode 1**: Direct modeling, NO subagent allowed
|
|
55
|
+
- **Mode 2**: Must use assembly-orchestration skill, MUST create subagent rooms
|
|
56
|
+
- **Mode 3**: Single-thread image analysis, NO subagent allowed
|
|
57
|
+
|
|
58
|
+
### 图纸 → 整件零件(DeepSeek V4.1 Flash)
|
|
59
|
+
|
|
60
|
+
收到 PDF、图片、DXF、DWG 时使用模式 3。先确认当前会话的实际模型 ID 为 `deepseek-flash`,且该模型路由声明支持图像输入;不能只看显示名。命令通过 DSH 的 `pwsh` 工具执行。先按下文定位工程模式根目录,再确认 Python 解释器和依赖;不要默认 PATH 里的 `python` 就是已配置的解释器。
|
|
61
|
+
|
|
62
|
+
DSH 0.2.2-rc.1 默认接收单图不超过 50 MiB、总像素不超过 6400 万、单边不超过 65535 像素。聊天图片附件与本地 `read_image` 共用附件服务,部署可覆盖这些限值。附件保存时会把总像素限制到 2048×2048、最长边限制到 8192 像素;Flash 模型请求还会按视觉额度进一步缩放,最长边不超过 4096 像素。检查工具返回的缩放说明和实际请求尺寸。标注看不清时索要局部清晰图或读取矢量标注,不能把接收上限或附件存储尺寸当成模型实际看到的分辨率。
|
|
63
|
+
|
|
64
|
+
1. 用 `& "<已验证的 python.exe 绝对路径>" "<工程模式根目录>\tools\drawing_input.py" "<原图>" --output-dir "<本次新目录>"` 取得页图、文字或 CAD 图元。PDF 可加 `--page N` 精读指定页。再对所需的 `images[].path` 调用原生 `read_image`,参数为 `file_path`;只有工具成功返回图像附件,才算图像进入模型输入。准备脚本返回路径不等于看过图。DXF/DWG 先读图元和标注摘要,按需查看 `entity_evidence` 和预览。DWG 需要 LibreDWG 的 `dwg2dxf`,可用 `--dwg2dxf` 指定。读 DXF 需要 ezdxf,读 PDF 需要 Poppler。`pwsh` 或 `read_image` 报错时先处理环境、权限或模型能力问题。
|
|
65
|
+
2. 按工程插件的“机械图识读”提示,核对视图方向、尺寸落点、孔槽深度及实体/空腔。保留直接标注与有依据的推导,列出仍不能唯一确定的关键几何。一次汇总独立缺项,允许请求该部位的其他角度、剖面、清晰局部或文字尺寸。每项说明部位、方向和待消除的歧义,不要求用户重述整张图。禁止按像素比例补数;仅建几何时材料可不指定。
|
|
66
|
+
3. 普通零件把已确定的信息转成草图、拉伸、切除的有序操作,复用原有 `solidworks-bridge`;只有当图纸和工具足以表达整件时才执行。两端开口、同轴、平行截面的圆转椭圆风管可直接用下列操作,免写 COM 脚本。
|
|
67
|
+
4. 将参数写进一个 UTF-8 JSON 文件。新建用 `mode="create"`、`output_path`(绝对 .SLDPRT 路径)、`inlet_diameter_mm`、`outlet_width_mm`、`outlet_height_mm`、`length_mm`。椭圆尺寸是完整轴长,水平轴为长轴。续改出口宽只需 `mode="resize"`、原路径和新 `outlet_width_mm`。同一个已保存且没有手工待保存改动的活动零件可继续使用。偏心、壁厚和法兰超出这个风管命令的范围。
|
|
68
|
+
|
|
69
|
+
```powershell
|
|
70
|
+
$env:DSH_DUCT_SPEC = "<参数 JSON 的绝对路径>"
|
|
71
|
+
& "<已验证的 python.exe 绝对路径>" "<工程模式根目录>\tools\sw_bridge.py" run "<工程模式根目录>\tools\examples\build_transition_duct.py"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
5. 检查桥接 JSON 的 `ok`、连接状态和错误信息,再按实际建模结果、尺寸和产物路径汇报。命令退出码为 0 也可能返回 `ok:false`;连接失败或没有产物时不得报告建模完成。准备页图、识别尺寸、完成 CAD 建模是三个不同的结果。
|
|
75
|
+
|
|
76
|
+
## 🔴 Mode 2 强制门禁流程(用命令行脚本,不是 DSH 工具!)
|
|
77
|
+
|
|
78
|
+
> ⚠️ **【BUG-03/04 修复 · 必读】**
|
|
79
|
+
>
|
|
80
|
+
> 旧版本文档把门禁入口写成了各种**门禁类 DSH 工具名**,照那些名字去调用必然失败。
|
|
81
|
+
> **本环境没有任何门禁类 DSH 工具;真实入口一律是命令行脚本** ——
|
|
82
|
+
> 照旧文档调用会直接失败(工具不存在),任务在第 1 步就卡死。
|
|
83
|
+
>
|
|
84
|
+
> **真实入口是命令行脚本**(下面所有命令都用这个):
|
|
85
|
+
>
|
|
86
|
+
> ```powershell
|
|
87
|
+
> $WG = "<工程模式根目录>\tools\workflow_gate.py"
|
|
88
|
+
> ```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### 🔴 【BUG-01 修复】`<工程模式根目录>` 到底是什么?怎么找?
|
|
93
|
+
|
|
94
|
+
旧文档只写占位符 `<工程模式根目录>` 却从未定义它 —— 用户按字面理解常指向
|
|
95
|
+
`C:\Users\<user>\.dsh\skills\mode-selection\`(那里**只有 SKILL.md**),
|
|
96
|
+
于是第 1 步就 `[Errno 2] No such file or directory`,新用户直接卡死。
|
|
97
|
+
|
|
98
|
+
**判定标准**:工程模式根目录 = **同时包含 `tools\mode_gate.py` 与
|
|
99
|
+
`tools\workflow_gate.py` 的那个目录**。
|
|
100
|
+
|
|
101
|
+
**先跑这个自检**(打印根目录 + 全部门禁脚本路径 + 候选列表):
|
|
102
|
+
```powershell
|
|
103
|
+
python "<任一已知的 tools 目录>\_root.py"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**三种可靠找法(按优先级)**:
|
|
107
|
+
1. **环境变量**(最稳,推荐设一次):
|
|
108
|
+
```powershell
|
|
109
|
+
$env:DSH_ENGINEERING_ROOT = "C:\Users\<你>\Desktop\DSH-SW-and-CAD-main\engineering"
|
|
110
|
+
# 永久设置:setx DSH_ENGINEERING_ROOT "C:\...\engineering"
|
|
111
|
+
```
|
|
112
|
+
设好后所有门禁脚本都会优先用它(见 `tools\_root.py`)。
|
|
113
|
+
2. **从脚本自身位置向上回溯**:找到 `engineering\tools\` 后,其**上一级**即根目录。
|
|
114
|
+
3. **常见备选搜索路径**(找不到时依次试):
|
|
115
|
+
- `%USERPROFILE%\.dsh\.agent-presets\engineering\`(**安装副本,最权威**,实测常见)
|
|
116
|
+
- `<仓库根>\engineering\`
|
|
117
|
+
- `%USERPROFILE%\.dsh\engineering\`
|
|
118
|
+
|
|
119
|
+
⚠️ 注意:`.dsh\skills\*` 下**只有 SKILL.md,没有 tools/** —— 那不是工程模式根目录。
|
|
120
|
+
|
|
121
|
+
下面所有 `<工程模式根目录>` 都请替换成上面找到的**绝对路径**。
|
|
122
|
+
|
|
123
|
+
### ⚠️ 读取含中文的 JSON 凭据:别用 PS 5.1 的 `Get-Content`
|
|
124
|
+
|
|
125
|
+
Windows PowerShell **5.1** 的 `Get-Content` 默认按系统 ANSI 代码页(简中 = cp936)
|
|
126
|
+
解码,UTF-8 的 JSON 会被误解码,`ConvertFrom-Json` 随即报
|
|
127
|
+
**「传入的对象无效,应为":"或"}"」**。**这不是文件坏了,是读法不对。**
|
|
128
|
+
文件名/内容含中文时尤其容易踩(`gate_load_case.json`、`mode_state.json` 等都可能这样)。
|
|
129
|
+
|
|
130
|
+
- ❌ `Get-Content x.json -Raw -Encoding UTF8 | ConvertFrom-Json`
|
|
131
|
+
(PS 5.1 下 `-Encoding UTF8` 不足以保证按 UTF-8 解码)
|
|
132
|
+
- ✅ 首选:`python -c "import json,io;print(json.load(io.open(r'x.json',encoding='utf-8')))"`
|
|
133
|
+
- ✅ 或:直接用 **DSH 的 `read` 工具**读该文件(自动按 UTF-8 解码)
|
|
134
|
+
- ✅ 坚持用 PowerShell:先 `[Console]::OutputEncoding=[System.Text.Encoding]::UTF8`
|
|
135
|
+
与 `$OutputEncoding=[System.Text.Encoding]::UTF8`,再用 `Get-Content -Encoding UTF8`
|
|
136
|
+
(或改用 PowerShell 7 `pwsh`,默认即 UTF-8)
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
**Mode 2(大型复杂器械装配)任务,必须在主对话中用 pwsh 调用以下命令:**
|
|
141
|
+
|
|
142
|
+
> ══ ★【流程已重排 · 2026-10-13】第一步不再是"参数需求强度" ★ ══════════
|
|
143
|
+
> 用户明确要求:**第一步 = 确认模式 + 问并行/串行 + 问是否 AI 自主设计**;
|
|
144
|
+
> 参数需求强度题**后移为第 2 步**;第 3 步启动【总计子代理】按十阶段流水线分析,
|
|
145
|
+
> 由 AI **按需提问**(不再一股脑全问)。原"第一步(多子代理并行建零件)"整体后移。
|
|
146
|
+
>
|
|
147
|
+
> ⚠️ 如果你(AI)按旧顺序问"参数需求强度",用户会看到**和改造前一模一样**的行为 ——
|
|
148
|
+
> 这正是本次改造要消除的。**必须以 `init` 命令的返回为准**,见下方第 1 步。
|
|
149
|
+
|
|
150
|
+
### 第 1 步:`init`(确认模式 + 两个固定问题)
|
|
151
|
+
|
|
152
|
+
```powershell
|
|
153
|
+
python "<工程模式根目录>\tools\workflow_gate.py" init "<设计任务描述>"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
- **作用**: 返回 **新流程的第一步** —— 确认模式 + 两个固定问题,**必须原样呈现给用户**
|
|
157
|
+
- 返回内容包含(以命令输出为准,勿自行改写):
|
|
158
|
+
1. 【模式确认】按**模式二 · 大型复杂器械/多零件装配体**执行
|
|
159
|
+
2. **① 并行策略(D / E)**
|
|
160
|
+
- D = 部分小屋并行(按波次分批启动)
|
|
161
|
+
- E = 单小屋串联(一次一个房间)
|
|
162
|
+
3. **② 搭建方式(A / B / C)** —— 即「**是否 AI 自主设计**」
|
|
163
|
+
- A = 完全自主搭建(AI 自主决策)
|
|
164
|
+
- B = 部分自主搭建(关键节点询问)
|
|
165
|
+
- C = 步步确认(每个零件参数表逐件确认)
|
|
166
|
+
- 返回里还有 `flow_order` 字段,列出完整 5 步顺序,可直接呈现给用户。
|
|
167
|
+
- **MUST 等用户回答这两个问题后才能进入第 2 步!**
|
|
168
|
+
|
|
169
|
+
### 第 2 步:`provide_context` #1(收模式确认 → 返回参数需求强度题)
|
|
170
|
+
|
|
171
|
+
```powershell
|
|
172
|
+
python "<工程模式根目录>\tools\workflow_gate.py" provide_context "<用户对并行策略/搭建方式的回答原文>"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
- 作用: 记录模式确认结果(并尽力解析出 D/E 与 A/B/C 预选项),
|
|
176
|
+
返回**第 2 步的问题:参数需求强度**(强需求 / 不强)。
|
|
177
|
+
- **MUST 把返回的问题原样呈现给用户,等用户作答!**
|
|
178
|
+
|
|
179
|
+
### 第 3 步:`provide_context` #2(定题数区间 → 启动总计子代理)
|
|
180
|
+
|
|
181
|
+
```powershell
|
|
182
|
+
python "<工程模式根目录>\tools\workflow_gate.py" provide_context "<用户对参数需求强度的回答原文>"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
- 判定参数需求强度并返回**按需提问指引**:
|
|
186
|
+
- 回答含「强需求 / 严格校核」→ **强需求**:题数须落在 **10 ~ 50** 之间
|
|
187
|
+
- 回答含「不强 / 精简」或含糊 → **弱需求**:题数须落在 **5 ~ 10** 之间
|
|
188
|
+
- ⚠️ **旧口径(强需求固定 17 题 / 弱需求固定 5 题)已废除**:
|
|
189
|
+
现在题库只作【候选池】,实际问几题由 AI 按十阶段分析进度**按需决定**,
|
|
190
|
+
但必须落在上述区间内(见 3.5.1 / 3.5.2)。
|
|
191
|
+
- ★ 返回内容会要求你**先启动总计子代理**按十阶段分析,**分析到缺信息时才提问**
|
|
192
|
+
(不允许开头就把候选题目全部抛出)。命令返回里有完整的十阶段清单与调用示例。
|
|
193
|
+
- **MUST 按返回指引执行:立刻 spawn 总计子代理(见 §3.6),由它跑十阶段 + 按需提问。**
|
|
194
|
+
主对话自己 `begin-stage` / `ask` 会被 `ANALYST_ACTOR_REQUIRED` 拒绝 —— 别自己上手。
|
|
195
|
+
|
|
196
|
+
### 第 3.6 步:★★ 在主对话里 spawn【总计子代理】(十阶段分析的唯一执行者)
|
|
197
|
+
|
|
198
|
+
> 🔴 **【2026-10-28 修复 · 与旧文档直接矛盾处已删除】**
|
|
199
|
+
> 旧版本文档末尾有两条**已废弃(deprecated)**的旧规则(原文已删除,这里只留一句指认,
|
|
200
|
+
> 免得被再照抄):①「门禁每一步都要在主对话里做完、不要进子代理」;
|
|
201
|
+
> ②「子代理只用来建模、不负责提问」。—— 两条都与「第 3 步启动总计子代理」**直接矛盾**。
|
|
202
|
+
> 实测后果:主对话据此自己把
|
|
203
|
+
> 十阶段走完、`set-subagent-plan` 也自己调(只写了 `--decided-by "总计子代理"` 这个字符串),
|
|
204
|
+
> **总计子代理从未被真实创建**。**本节取代那两句旧规则。**
|
|
205
|
+
|
|
206
|
+
`provide_context` #2 返回后,主对话**立刻**用 `subagent_fork` 创建【总计子代理】
|
|
207
|
+
(**真实子代理**,不是主对话自演):
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
subagent_fork(description="总计子代理(十阶段分析)", prompt="<按下面 5 条写>")
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**总计子代理 prompt 必须原样包含这 5 条(缺一条就会退化成"主对话自演"):**
|
|
214
|
+
|
|
215
|
+
**① 第一步:绑定分析身份** —— 不绑定,后面每条阶段命令都会被 `ANALYST_ACTOR_REQUIRED` 拒绝:
|
|
216
|
+
```powershell
|
|
217
|
+
python "<根>\tools\mode2_flow.py" analyst-bind
|
|
218
|
+
```
|
|
219
|
+
- 自动从环境变量 `DSH_SESSION_ID` 取**它自己**的 sessionId 落盘,**不用手写 id**。
|
|
220
|
+
- 自检:`python "<根>\tools\mode2_flow.py" analyst-status`(谁绑的、什么时候绑的)。
|
|
221
|
+
|
|
222
|
+
**② 按序跑完十阶段**(`begin-stage` → `mark-stage-done`,禁止跳阶段):
|
|
223
|
+
```powershell
|
|
224
|
+
python "<根>\tools\mode2_flow.py" begin-stage TaskUnderstanding
|
|
225
|
+
python "<根>\tools\mode2_flow.py" mark-stage-done TaskUnderstanding --artifact "<本阶段产出>"
|
|
226
|
+
```
|
|
227
|
+
- 十阶段清单见 §3.5.3;进度用 `python "<根>\tools\mode2_flow.py" stage-status` 查。
|
|
228
|
+
- 只有 `DesignIteration` 允许回退(`refresh-stage` / `redo-stage`)。
|
|
229
|
+
- 等价写法:`python "<根>\tools\workflow_gate.py" mode2 <子命令>`(透传同一个模块)。
|
|
230
|
+
|
|
231
|
+
**③ 缺信息时提问 —— 走宿主代问桥 `ask_user.py`**
|
|
232
|
+
(**子代理不能直接调 `ask_user_question`**:`userQuestions.ask` 校验 roots,
|
|
233
|
+
子代理必抛 `DELEGATED_CALLER`,**只能用这个桥**):
|
|
234
|
+
```powershell
|
|
235
|
+
python "<根>\tools\ask_user.py" --room "总计子代理" --child "<它自己的 sessionId>" `
|
|
236
|
+
--header "使用场合" --question "使用场合是什么?" --option "室内" --option "户外"
|
|
237
|
+
```
|
|
238
|
+
- 阻塞等待;用户的答案以 **tool_result** 回到它当前调用栈,可继续原逻辑。
|
|
239
|
+
- **不许自己编答案**,也不许用正文代替提问。
|
|
240
|
+
- 问之前先登记:`python "<根>\tools\mode2_flow.py" ask "<问题>" --stage <当前阶段> --reason "<为什么现在问>"`;
|
|
241
|
+
用户答完再 `answer-question <seq> "<答复>"` 落账。
|
|
242
|
+
- 题数区间:强需求 10~50 / 弱需求 5~10(代码硬校验,见 §3.5.1)。
|
|
243
|
+
|
|
244
|
+
**④ 分析完成后登记房间编制**(房间数 / 细分**由它决定**,禁止照抄固定表):
|
|
245
|
+
```powershell
|
|
246
|
+
python "<根>\tools\mode2_flow.py" set-subagent-plan `
|
|
247
|
+
--rooms-json "<rooms.json 的绝对路径>" --rationale "<按功能分解的理由>" `
|
|
248
|
+
--decided-by "总计子代理"
|
|
249
|
+
```
|
|
250
|
+
- `--decided-by` 必须写「总计子代理」;每房间必须写 `parts`(负责哪些零件)与 `why`;数量 1~24。
|
|
251
|
+
- 十阶段没走完就调会被拒 —— 先 `stage-status` 自查(`require_stages_complete` 强制前置)。
|
|
252
|
+
|
|
253
|
+
**⑤ 结束回合**,返回值里带**编制摘要**:房间名 × 每房间零件 × 该房间属于第几波。
|
|
254
|
+
|
|
255
|
+
**这整段时间,主对话只做一件事:等它结束**(`wait_agent` / `list_agents`)。
|
|
256
|
+
主对话**不要**去跑 `begin-stage` / `mark-stage-done` / `ask` —— 代码会以 `ANALYST_ACTOR_REQUIRED` 拒绝;
|
|
257
|
+
而且一旦主对话自己跑,`select` 之后的「编制由分析得出」就全是假的。
|
|
258
|
+
|
|
259
|
+
### 第 4 步:力学估算(`provide_context` #3)
|
|
260
|
+
|
|
261
|
+
```powershell
|
|
262
|
+
python "<工程模式根目录>\tools\workflow_gate.py" provide_context "<全部提问回答原文>"
|
|
263
|
+
```
|
|
264
|
+
- 执行力学估算,返回 A/B/C 搭建方式 + D/E 并行策略选项
|
|
265
|
+
- **MUST wait for user to choose A/B/C and D/E!**
|
|
266
|
+
- 🔴 **调用前必须确认:总计子代理已 `analyst-bind`、十阶段走完、已 `set-subagent-plan`、回合已结束。**
|
|
267
|
+
自查三连:`analyst-status` / `stage-status` / `subagent-plan`,再用 `list_agents` 确认它结束。
|
|
268
|
+
**它没跑完就调 #3,后面的 `select` 会直接报 `MODE2_ANALYST_REQUIRED`。**
|
|
269
|
+
|
|
270
|
+
> 📌 状态流转(**新流程,2026-10-13 重排**):
|
|
271
|
+
> `mode_confirm_asked`(确认模式+D/E+A/B/C)
|
|
272
|
+
> →(传模式确认答案)→ `depth_asked`(强/弱需求)
|
|
273
|
+
> →(传强度答案)→ `context_asked`(总计子代理十阶段 + 按需提问)
|
|
274
|
+
> →(传全部提问答案)→ `mechanics_done`(力学估算 + A/B/C、D/E 选项)。
|
|
275
|
+
> 不要跳步;`step` 不对时命令会直接报错拒绝。
|
|
276
|
+
|
|
277
|
+
> 📌 **【BUG-01/07 修复】载荷数值口径**
|
|
278
|
+
> 力学估算会**优先读取用户明确写出的载荷数值**(如「100N」「10kg」「0.1kN」),
|
|
279
|
+
> 关键词(冲击/动态)只用于确定**动载系数**,不再放大用户给的额定值。
|
|
280
|
+
> 若返回值带 `load_is_estimate=true`,说明用户没给数值、当前是估算基准,
|
|
281
|
+
> **必须向用户复核后再继续**。
|
|
282
|
+
> 命令同时把载荷工况落盘到 `tools/load_cases/gate_load_case.json`,
|
|
283
|
+
> **physics 校核必须用该文件**(额定载荷 = `magnitude_n`),
|
|
284
|
+
> 严禁另起一套数值(那正是 BUG-07「门禁 1000N / physics 100N」的根因)。
|
|
285
|
+
|
|
286
|
+
### 第 5 步:`select` 确认选择(前置:总计子代理已完成十阶段 + 编制)
|
|
287
|
+
|
|
288
|
+
```powershell
|
|
289
|
+
python "<工程模式根目录>\tools\workflow_gate.py" select <A|B|C>,<D|E>
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
- **参数**: 搭建方式 A/B/C 与并行策略 D/E
|
|
293
|
+
- **A/B/C**: 搭建方式(完全自主/部分自主/步步确认)
|
|
294
|
+
- **D/E**: 并行策略(部分小屋并行 / 单小屋串联)
|
|
295
|
+
- **【BUG-03 修复】** 以下写法**全部等价可用**(旧文档只写了一种,极易踩坑):
|
|
296
|
+
```powershell
|
|
297
|
+
... select C,E # 推荐
|
|
298
|
+
... select C E
|
|
299
|
+
... select "C, E"
|
|
300
|
+
... select c e
|
|
301
|
+
... select --choice C --parallel E
|
|
302
|
+
```
|
|
303
|
+
- **MUST wait for user to confirm selection!**
|
|
304
|
+
- **【BUG-04 修复】** 并行策略的权威来源已统一:
|
|
305
|
+
`select` 当场写入 `workflow_state.json`,并自动与 `mode_state.json` **对齐**,
|
|
306
|
+
不再出现两个命令读到相反结论的情况。
|
|
307
|
+
- 🔴 **【2026-10-28】`select` 的硬前置:总计子代理已 `analyst-bind` 且十阶段走完。**
|
|
308
|
+
未 spawn / 未绑定 / 阶段缺项 → `select` 返回 **`MODE2_ANALYST_REQUIRED`**(绑定缺失的那次)
|
|
309
|
+
或子代理自己调阶段命令被 **`ANALYST_ACTOR_REQUIRED`** 拒。
|
|
310
|
+
**看到 `MODE2_ANALYST_REQUIRED` 就说明第 3.6 步没做**(八成是主对话自己把十阶段跑了):
|
|
311
|
+
→ spawn 总计子代理(§3.6)→ 让它 `analyst-bind` 并补齐缺的阶段 → 再 `select`。
|
|
312
|
+
- 🔴 **`select` 返回的 `wave1` = 编制里的【全部建模房间】+【总理子代理】。**
|
|
313
|
+
房间数与细分**由总计子代理决定**,主对话**不得**改用固定表(旧固定 3 房间 / 5 房间已废弃)。
|
|
314
|
+
|
|
315
|
+
### 第 3.5 步:★ 模式二新流程(全部为【代码强制】,不是提示词约定)
|
|
316
|
+
|
|
317
|
+
> 用户要求:「所有改动都要写在代码里面,强制执行的」。
|
|
318
|
+
> 以下每一条都由 `workflow_gate.py` / `mode2_flow.py` 的代码校验,**违反会被拒绝**。
|
|
319
|
+
|
|
320
|
+
#### 3.5.1 题数硬约束(原「强需求 17 题 / 弱需求 5 题」已取消)
|
|
321
|
+
|
|
322
|
+
| 参数需求强度 | 允许题数(闭区间,可等于上下界) |
|
|
323
|
+
|---|---|
|
|
324
|
+
| 强需求 `full` | **10 ~ 50** |
|
|
325
|
+
| 弱需求 `lite` | **5 ~ 10** |
|
|
326
|
+
|
|
327
|
+
- 由 `mode2_flow.validate_question_budget()` 强制;超上限直接拒绝,
|
|
328
|
+
收尾时未达下限同样拒绝交付。
|
|
329
|
+
- `provide_context` 第 1 次的返回里会带 `question_budget`(含 min/max/候选池大小)。
|
|
330
|
+
|
|
331
|
+
#### 3.5.2 取消「一股脑全问」→ 改为【按需提问】
|
|
332
|
+
|
|
333
|
+
题目必须**挂在已经分析到的阶段**上,并写明理由:
|
|
334
|
+
|
|
335
|
+
```powershell
|
|
336
|
+
# 1) 先推进到某阶段(必须按序,跳阶段会被拒)
|
|
337
|
+
python "<根>\tools\workflow_gate.py" mode2 begin-stage TaskUnderstanding
|
|
338
|
+
# 2) 分析到确实缺信息时,才问对应的问题
|
|
339
|
+
python "<根>\tools\workflow_gate.py" mode2 ask "使用场合是什么" `
|
|
340
|
+
--stage TaskUnderstanding --reason "决定材料与防护等级"
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
- 阶段未 `begin-stage` 就提问 → **拒绝**(这就是「不许开头把题全抛出去」的机器判据)。
|
|
344
|
+
- 无理由提问 → **拒绝**。
|
|
345
|
+
- 查看进度:`python workflow_gate.py stage-status`
|
|
346
|
+
|
|
347
|
+
#### 3.5.3 十阶段设计流水线(必须按序)
|
|
348
|
+
|
|
349
|
+
```
|
|
350
|
+
TaskUnderstanding → FunctionalDecomposition → PhysicsReasoning →
|
|
351
|
+
PrincipleSynthesis → MechanismSynthesis → RecursivePartReasoning →
|
|
352
|
+
PartSynthesis → EngineeringValidation → DesignIteration → ExplainableDesignOutput
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
- 跳阶段被拒;只有 `DesignIteration` 可以发起回退。
|
|
356
|
+
|
|
357
|
+
#### 3.5.4 子代理数量【不再固定 3 个】→ 由「总计子代理」决定
|
|
358
|
+
|
|
359
|
+
```powershell
|
|
360
|
+
python "<根>\tools\workflow_gate.py" mode2 set-subagent-plan `
|
|
361
|
+
--rooms-json "@rooms.json" --rationale "按功能分解得到 N 个模块" `
|
|
362
|
+
--decided-by "总计子代理"
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
- `--decided-by` **必须是「总计子代理」**,否则报「越权」并拒绝。
|
|
366
|
+
- 每个房间必须写 `parts`(负责哪些零件)与 `why`(为什么需要它)。
|
|
367
|
+
- 依赖不得悬空。数量范围 1~24。
|
|
368
|
+
- 🔴 **本条命令只能由【总计子代理本人】执行**:`mode2_flow.py` 会比对调用方的
|
|
369
|
+
`DSH_SESSION_ID` 与 `analyst-bind` 落盘的 analyst(也可显式 `--actor`),
|
|
370
|
+
**主对话直接调 → `ANALYST_ACTOR_REQUIRED`**;`select` 也会校验 analyst,缺失 → `MODE2_ANALYST_REQUIRED`。
|
|
371
|
+
- 🔴 **编制 = 全系统房间表的唯一来源。** `select` 的 `wave1` 直接取编制里的全部建模房间
|
|
372
|
+
(+ 代码固定追加的「总理子代理」)。**旧的代码默认房间表已废弃,不得作为兜底**;
|
|
373
|
+
房间数量与细分由总计子代理按功能分解决定(可能是 2 个,也可能是 7 个)。
|
|
374
|
+
- 「总理子代理」(`type=prime`,`fixed=True`)由代码自动追加,**不要写进编制 JSON**。
|
|
375
|
+
|
|
376
|
+
#### 3.5.5 固定增设「总理子代理」(不可被编制顶掉)
|
|
377
|
+
|
|
378
|
+
房间名常量 `总理子代理`,类型 `prime`,`fixed=True`。职责(代码化):
|
|
379
|
+
|
|
380
|
+
1. 统一规划关键尺寸,给各建模小屋下发同一套尺寸口径;
|
|
381
|
+
2. 接收各建模小屋上报(**缺字段即拒绝**):
|
|
382
|
+
三道防线凭据链接 / 尺寸 / 名称 / 直接接触配合的零件;
|
|
383
|
+
3. 校验相邻零件尺寸一致性;不一致 → `escalate_to_parent=true`,交父代理干涉;
|
|
384
|
+
4. 持久维护零件数据台账,支持按零件反查关联;
|
|
385
|
+
5. 全部完成后汇总导出 docx 交主对话。
|
|
386
|
+
|
|
387
|
+
```powershell
|
|
388
|
+
# 建模小屋 save() 之后必须上报(缺任一字段都会被拒)
|
|
389
|
+
python "<根>\tools\workflow_gate.py" mode2 prime-report --json "@report.json"
|
|
390
|
+
# 总理子代理做一致性校验
|
|
391
|
+
python "<根>\tools\workflow_gate.py" mode2 check-consistency
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
#### 3.5.5.1 ★★ 总理子代理必须【统一核实】数据后才能结束
|
|
395
|
+
|
|
396
|
+
用户要求:「总理子代理要统一核实过数据没有错误了,才能结束」
|
|
397
|
+
「其总理子代理也要核实的相关数据是否一致,必须要保证真实」
|
|
398
|
+
|
|
399
|
+
```powershell
|
|
400
|
+
python "<根>\tools\workflow_gate.py" mode2 prime-verify # 统一核实
|
|
401
|
+
python "<根>\tools\workflow_gate.py" mode2 prime-verify-status # 读回结论
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
**"核实"不是自我声明**(谁都能写 `verified=True`),而是代码从磁盘重算:
|
|
405
|
+
|
|
406
|
+
| 核实项 | 判据 |
|
|
407
|
+
|---|---|
|
|
408
|
+
| 零件台账非空 | 空台账 → 拒绝(`fail-closed`) |
|
|
409
|
+
| 相邻尺寸一致性 | 有 mismatch → 拒绝结束 |
|
|
410
|
+
| 未决记录 | `unresolved` 还有 open → 拒绝结束 |
|
|
411
|
+
| **数据防篡改** | 逐零件重算 SHA-256 指纹;对不上 → 「真实性无法保证」,拒绝结束 |
|
|
412
|
+
| 可复现指纹 | 结论落盘 `digest`,事后任何人可重算验证 |
|
|
413
|
+
|
|
414
|
+
**"才能结束"的强制点**:`pre_delivery_check` 每次都**重算**一遍(不采信旧的
|
|
415
|
+
"已通过"结论),任一项不过 → `workflow_gate` 的交付总闸**拒绝归档**,
|
|
416
|
+
即**任务无法宣告完成**。
|
|
417
|
+
|
|
418
|
+
> 另:`part_registry.py` 自身还有一道**写入前**闸门 ——
|
|
419
|
+
> 改动若导致已登记的配合尺寸不一致,**默认拒绝落盘**(`CONSISTENCY_VERIFICATION_FAILED`),
|
|
420
|
+
> 并做内存回滚(磁盘字节不变)。确属设计允许时须 `--allow-mismatch "理由"`
|
|
421
|
+
> 如实说明,放行后记入 `unresolved` 台账,绝不静默消失。
|
|
422
|
+
|
|
423
|
+
#### 3.5.6 建模之后必须「看图」(第 6 项)
|
|
424
|
+
|
|
425
|
+
建模子代理必须以 **「看图 → 矫正 → 继续看 → 继续矫正」** 作为主要矫正方式:
|
|
426
|
+
|
|
427
|
+
```powershell
|
|
428
|
+
python "<根>\tools\visual_check.py" gate --part "<零件>.SLDPRT" `
|
|
429
|
+
--expect '{"bbox_mm":[xmin,xmax,ymin,ymax,zmin,zmax]}'
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
- `room-end` 时会**强制核实**本房间每个零件是否留有经核实的看图证据
|
|
433
|
+
(截图真实存在且非空 + 闭环 PASS);缺失 → `VISUAL_EVIDENCE_REQUIRED`,**拒绝下线**。
|
|
434
|
+
- 截图被事后删除/替换也会被重新拦下。
|
|
435
|
+
|
|
436
|
+
#### 3.5.7 SW 健康看护(第 4 项,超阈值立即关 SW)
|
|
437
|
+
|
|
438
|
+
**两条路并行(互补),都在取锁那一刻自动触发,无需模型记得启动:**
|
|
439
|
+
|
|
440
|
+
| 路径 | 机制 | 优点 | 局限 |
|
|
441
|
+
|---|---|---|---|
|
|
442
|
+
| ① OS 子进程 | `mode_gate.py sw-guard-start`(`sw_bridge` 取锁时自动调) | 不依赖 DSH 运行时,**必然**有看护 | 没有 DSH job id |
|
|
443
|
+
| ② **`ctx.jobs`** | 插件 `POST /dsh-engineering-ui/sw-guard-job` | **有 job id**,可 `job_list`/`job_output`/`job_kill` 管理 | 需 DSH 运行时 + jobs 服务 |
|
|
444
|
+
|
|
445
|
+
用户要求的两点分别由它们满足:
|
|
446
|
+
- 「利用 DSH 的后台任务运行时(ctx.jobs)…这个 job 会立即返回一个 job id」→ 路径 ②
|
|
447
|
+
- 「一旦内存、CPU超85%阈值就输出一行警报…立马关闭SW」→ 两条路都实现
|
|
448
|
+
|
|
449
|
+
```powershell
|
|
450
|
+
# 查 OS 子进程看护状态(含最近采样值)
|
|
451
|
+
python "<根>\tools\mode_gate.py" sw-guard-status
|
|
452
|
+
# 手动启动 / 停止
|
|
453
|
+
python "<根>\tools\mode_gate.py" sw-guard-start
|
|
454
|
+
python "<根>\tools\mode_gate.py" sw-guard-stop
|
|
455
|
+
```
|
|
456
|
+
```powershell
|
|
457
|
+
# ctx.jobs 版:启动(幂等,返回 job id)/ 查状态
|
|
458
|
+
curl -X POST http://127.0.0.1:19387/dsh-engineering-ui/sw-guard-job
|
|
459
|
+
curl http://127.0.0.1:19387/dsh-engineering-ui/sw-guard-job
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
- 间隔 **10 秒**、阈值 **CPU/内存 85%** —— 均为代码常量
|
|
463
|
+
(`SW_GUARD_INTERVAL_MS` / `SW_GUARD_CPU_LIMIT` / `SW_GUARD_MEM_LIMIT`)。
|
|
464
|
+
- 恰好等于 85% **不触发**(避免临界误杀,与 `sw_guard.py` 口径一致)。
|
|
465
|
+
- 显式关闭:设 `DSH_SW_GUARD_OFF=1`。
|
|
466
|
+
- ⚠️ **`ctx.jobs` 缺失时显式降级**(不假装成功):返回 `job_id=null` +
|
|
467
|
+
`degraded=true` + 说明「① 那条路仍在工作」。
|
|
468
|
+
- ⚠️ **插件 host 半改动是进程级的** —— 改完必须**重启 DSH** 才生效;
|
|
469
|
+
验证方法:`/agents` 返回 200 而 `/sw-guard-job` 返回 404,即"代码已就位、待重启"。
|
|
470
|
+
|
|
471
|
+
#### 3.5.8 交付前总闸
|
|
472
|
+
|
|
473
|
+
```powershell
|
|
474
|
+
python "<根>\tools\workflow_gate.py" pre-delivery
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
任一不满足即**拒绝宣告完成**(拒绝归档):十阶段未走完 / 题数不达标 /
|
|
478
|
+
编制缺失或非总计子代理决定 / 有零件未上报总理 / 存在未处理的相邻尺寸不一致。
|
|
479
|
+
|
|
480
|
+
### 第 6 步:创建子代理小屋(房间表由总计子代理决定!)
|
|
481
|
+
|
|
482
|
+
> 🔴 **【2026-10-28】** 房间表 = `select` 返回的 `wave1` = **编制里的全部建模房间 + 总理子代理**。
|
|
483
|
+
> **数量与细分由总计子代理决定** —— 不要写死旧的固定五房间表
|
|
484
|
+
> (结构件 / 传动机构 / 壳体机架 / 总装与验证 / 工程图输出),
|
|
485
|
+
> 也不要写死「第1波 = 结构件 + 传动机构 + 壳体机架」这种固定三房间说法。
|
|
486
|
+
|
|
487
|
+
**并行模式 D —— 三波式(总理与建模同波一起开):**
|
|
488
|
+
|
|
489
|
+
```
|
|
490
|
+
wave1 = select.wave1 = 全部建模房间 + 总理子代理 ← 同时 fork
|
|
491
|
+
wave2 = 总装与验证(等 wave1 全部 room-end)
|
|
492
|
+
wave3 = 工程图输出(等 wave2 room-end)
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**wave1 执行顺序(不可打乱):**
|
|
496
|
+
1. **先**对每个房间 `python "<根>\tools\mode_gate.py" room-start <房间名>`
|
|
497
|
+
(登记,**BEFORE** 创建 subagent;未 room-start 的房间 `subagent-assign` 会报 `ROOM_NOT_REGISTERED`)
|
|
498
|
+
2. **再**在同一条回复里**一次性 `subagent_fork` 该批全部房间**(含总理子代理)——
|
|
499
|
+
⚠️ 严禁只开一个、严禁分多条回复慢慢开:**同批房间必须同时启动**。
|
|
500
|
+
⚠️ **每批最多 3 个**(含总理子代理):宿主对同一 root 的子代理有名额上限,
|
|
501
|
+
插件在 `tools/pre-execute` 做了硬闸门,第 4 个会直接返回
|
|
502
|
+
`SUBAGENT_LIMIT_REACHED`。编制超过 3 个房间就**分批**:本批全部
|
|
503
|
+
`room-end`(名额释放)后再开下一批,不要原样重试被拒的那次调用。
|
|
504
|
+
3. **每个 fork 之后立刻**用返回的 id 绑定(漏了就永远 `unbound`):
|
|
505
|
+
```powershell
|
|
506
|
+
python "<根>\tools\mode_gate.py" subagent-assign <房间名> <subagent_fork 返回的 id>
|
|
507
|
+
```
|
|
508
|
+
4. 建模小屋 prompt 必须写「只做本房间零件」,并带上 `select` 返回的 `part_ownership` keywords。
|
|
509
|
+
|
|
510
|
+
**总理子代理(与 wave1 同时启动,长生命周期的监工):**
|
|
511
|
+
- 开工:`python "<根>\tools\mode2_flow.py" prime-board` 看全局,`prime-room` 看职责。
|
|
512
|
+
- **循环**:每轮读 `python "<根>\tools\mode_gate.py" room-board --json`,**只看每个房间的 `state`**:
|
|
513
|
+
- `running` / `starting` / `idle` → 正常在干活,**不许催、不许判死**;
|
|
514
|
+
- `waiting_sw` → **在等 SW 锁,属正常等待**,只能等,**禁止判死、禁止 reset**;
|
|
515
|
+
- `unbound` → 平台 alive 但没 `subagent-assign`,**提示父代理补 assign**(不是死亡);
|
|
516
|
+
- `dead` → **只有这个才允许报**,并建议父代理 `recover` / `restart`;
|
|
517
|
+
- `done` → 收报告。
|
|
518
|
+
- 收件:建模小屋 `save()` 后 `prime-report`;总理做 `check-consistency` → `prime-verify`。
|
|
519
|
+
- 结束:wave3 出图完成后 `python "<根>\tools\mode_gate.py" room-end 总理子代理`。
|
|
520
|
+
- **prime 房间不计入 wave 完成判定**(长生命周期),但**收尾前必须 room-end**。
|
|
521
|
+
|
|
522
|
+
**串行模式 E 严格顺序(不可打乱):**
|
|
523
|
+
1. **先**调 `mode_gate.py room-start <房间名>`(登记, BEFORE 创建 subagent)
|
|
524
|
+
2. **再**用 subagent/subagent_fork 创建该小屋,**并立刻** `subagent-assign <房间> <id>`
|
|
525
|
+
3. 等待该小屋完成(`room-board` 看 `state=done`,或 `list_agents` 检查)
|
|
526
|
+
4. 调 `mode_gate.py room-end <房间名>`(解锁,才能开下一个)
|
|
527
|
+
5. 重复 1~4 处理下一个房间
|
|
528
|
+
|
|
529
|
+
**严禁一次性创建多个 subagent(串行模式)!** 串行锁会拒绝第二个 room-start。
|
|
530
|
+
- 🚫【铁律】所有小屋创建完毕前,主对话禁止调用 sw_bridge.py 做任何建模操作!
|
|
531
|
+
|
|
532
|
+
## 🟦 Webots 仿真分支(Mode 1/2/3 的附加产物,不改变原门禁)
|
|
533
|
+
|
|
534
|
+
> **一句话**:仿真只在**模型已经存在**之后发生;它消费 `select` 建立的 task/room 身份,
|
|
535
|
+
> 自己**不建房间、不改 workflow_state.json、不申请 SW 写锁**。
|
|
536
|
+
|
|
537
|
+
### 什么时候走这一支
|
|
538
|
+
|
|
539
|
+
用户明确说要「仿真 / 跑起来 / 看运动 / 查干涉 / 传感器数据 / 机器人行为」时。
|
|
540
|
+
只是要强度、疲劳、FEA、出图 —— **不走这里**,走 physics-in-loop。
|
|
541
|
+
|
|
542
|
+
### 硬约束(代码级,不是提示词)
|
|
543
|
+
|
|
544
|
+
| 约束 | 由谁保证 |
|
|
545
|
+
|---|---|
|
|
546
|
+
| 归属必须由**当前 live 的工程 agent + 唯一活跃房间**推导 | `lib/webots.js` 的 `resolveWebotsContext()`,不符即 `CONTEXT_UNAVAILABLE` |
|
|
547
|
+
| room_id = `room-` + 房间名 UTF-8 的**完整 SHA-256** | 同上;ASCII 与中文走同一映射,禁止给 ASCII 名称开直通域 |
|
|
548
|
+
| 每次调用必须带**真实** `task_id` / `room_id` | `ctx.tools.guard` 拦截 `mcp__webots__*`,自报值对不上直接拒 |
|
|
549
|
+
| 未配置 runtime 时一律 `not_started` / `core_ready=false` | 状态投影取保守值,**不许**把"装好了"说成 READY |
|
|
550
|
+
|
|
551
|
+
### 执行顺序
|
|
552
|
+
|
|
553
|
+
1. **先有 run**:`sim_status` 只读;真正要跑先 `sim_launch`(需要 pinned runtime)。
|
|
554
|
+
2. **未知结果不许重发**:返回 `OUTCOME_UNKNOWN` / 超时 / 断连时,保留
|
|
555
|
+
operation_id / job_id / run_id / session_generation,用原身份查 `sim_job`,**禁止重发动作**。
|
|
556
|
+
3. **读证据而不是猜**:`sim_report`(model_manifest / conversion_report / experiment_report)
|
|
557
|
+
与 `sim_evidence`(UTF-8 字节分页;翻页要带上一页的 `sha256` 作 `expected_sha256`)。
|
|
558
|
+
4. **归因只列候选**:`sim_attribute` 只读;`fake` / `fixture` / `synthetic` /
|
|
559
|
+
静态校验 / 空接触 **都不等于物理 PASS**。
|
|
560
|
+
5. **回写 SW 要单独授权**:本版未实现原生回写(`authorized_native_repair` 在
|
|
561
|
+
`blocked_native` 里),只能报告缺口,**不许**自行改质量/摩擦/重力去凑通过。
|
|
562
|
+
|
|
563
|
+
### 启用条件(缺一即视为未启用,不是"坏了")
|
|
564
|
+
|
|
565
|
+
```powershell
|
|
566
|
+
$env:DSH_WEBOTS_ENABLE = '1' # 唯一开关,不是 1 就整行禁用
|
|
567
|
+
$env:DSH_WEBOTS_PYTHON = '<绝对路径>\python.exe' # 已装 engineering/tools/webots_mcp/requirements.txt
|
|
568
|
+
$env:DSH_WEBOTS_INPUT_ROOT = '<已存在的只读输入根>'
|
|
569
|
+
$env:DSH_STATE_DIR = '<已存在的绝对 state 目录>' # Node 与 Python 必须解析到同一目录
|
|
570
|
+
$env:DSH_ENGINEERING_ROOT = '<工程模式根>\engineering'
|
|
571
|
+
$env:WEBOTS_HOME = '<Webots 安装根>' # 例:D:\Webots
|
|
572
|
+
# 可选:$env:DSH_WEBOTS_RUNTIME_CONFIG = '<绝对路径>\runtime.json'
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
**先跑自检**(只读,不启动任何东西):
|
|
576
|
+
|
|
577
|
+
```powershell
|
|
578
|
+
python "<工程模式根>\tools\webots_env.py" # 人类可读
|
|
579
|
+
python "<工程模式根>\tools\webots_env.py" --json # AI 读 blocking 字段
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
任一缺失 → MCP 行被 `disabled`,或进程起不来但 `failOnStartupError:false` 让预设照常加载。
|
|
583
|
+
**这时正确行为是如实报告"仿真不可用",不是伪造结果。**
|
|
584
|
+
|
|
585
|
+
### 报告里必须保留的四件事
|
|
586
|
+
|
|
587
|
+
`provenance`(fixture / static-derived / real-sw-export / real-webots)、
|
|
588
|
+
`core_ready`、`execution_state`、`stale` + `snapshot_at`。
|
|
589
|
+
把这四项抹掉、只说"仿真通过",等同于交付虚假证据。
|
|
590
|
+
|
|
591
|
+
---
|
|
592
|
+
|
|
593
|
+
## ⚠️ 关键规则
|
|
594
|
+
|
|
595
|
+
- **【BUG-03 修复】必须用命令行脚本;本环境没有任何门禁类 DSH 工具!**
|
|
596
|
+
- ✅ 正确:`python "<工程模式根目录>\tools\workflow_gate.py" init "<任务>"`
|
|
597
|
+
- ❌ 错误:凭印象调用任意门禁类 DSH 工具(**本环境不存在,必然失败**)
|
|
598
|
+
- 子命令名用**下划线**:`init` / `provide_context` / `select` / `confirm-assembly`
|
|
599
|
+
- **`provide_context` 必须调用三次**(新流程):
|
|
600
|
+
① 传「并行策略 D/E + 是否 AI 自主 A/B/C」的答案;
|
|
601
|
+
② 传「参数需求强度(强/不强)」的答案;
|
|
602
|
+
③ 传「全部按需提问」的答案(此时才出力学估算)。
|
|
603
|
+
⚠️ 顺序不能颠倒:模式确认在前、强度在后(2026-10-13 重排)。
|
|
604
|
+
- **`select` 支持 `C,E` / `C E` / `"C, E"` / `--choice C --parallel E` 等写法**(BUG-03)
|
|
605
|
+
- 🔴 **谁调什么(2026-10-28 重排)**:
|
|
606
|
+
· `workflow_gate.py`(init / provide_context / select)与 `mode_gate.py`(room-start / room-end /
|
|
607
|
+
subagent-assign / room-board / recover)**由主对话调**;
|
|
608
|
+
· `mode2_flow.py` 的十阶段与编制命令(analyst-bind / begin-stage / mark-stage-done / ask /
|
|
609
|
+
answer-question / refresh-stage / set-subagent-plan)**只能由总计子代理调**。
|
|
610
|
+
· 旧规则「门禁每一步都在主对话完成、不进子代理」**已废除(deprecated)** —— 它与
|
|
611
|
+
"spawn 总计子代理"直接矛盾,实测导致主对话自演十阶段、总计子代理从未创建。
|
|
612
|
+
- 🔴 **子代理死活只看 `python "<根>\tools\mode_gate.py" room-board --json` 的 `state`**:
|
|
613
|
+
· `waiting_sw`(在排 SW 锁)/ `running` / `starting` / `idle` = **正常,禁止判死**;
|
|
614
|
+
· `unbound` = 平台 alive 但没 `subagent-assign` → **补 assign**(不是僵尸);
|
|
615
|
+
· `dead` = 才允许 `recover` / `restart`,且先看 `safe_to_restart`;
|
|
616
|
+
· **禁止对 `running` / `waiting_sw` / `idle` 的房间 `reset`**(会把还在干活的小屋清掉)。
|
|
617
|
+
- 严禁跳过门禁直接开始设计
|
|
618
|
+
|
|
619
|
+
## Violation Handling
|
|
620
|
+
|
|
621
|
+
- Skip workflow_gate = **CODE BLOCKED**
|
|
622
|
+
- Mode 2 without subagent rooms = **CODE BLOCKED**
|
|
623
|
+
- **主对话自己跑十阶段 / 自己调 `set-subagent-plan`** = **CODE BLOCKED**(`ANALYST_ACTOR_REQUIRED`)
|
|
624
|
+
- **没 spawn 总计子代理就 `select`** = **CODE BLOCKED**(`MODE2_ANALYST_REQUIRED`)
|
|
625
|
+
- **`fork` 后漏 `subagent-assign`** = 房间显示 `unbound`,上报与判定全部失真
|
|
626
|
+
- Used subagent in Mode 1/3 = **FAIL**
|
|
627
|
+
|
|
628
|
+
## Example Flow
|
|
629
|
+
|
|
630
|
+
User: "Design a planetary reducer"
|
|
631
|
+
|
|
632
|
+
AI must(门禁命令在主对话;十阶段在**总计子代理**里):
|
|
633
|
+
1. Output: [MODE SELECTED] Mode 2
|
|
634
|
+
2. 执行 `python "<工程模式根目录>\tools\workflow_gate.py" init "Design a planetary reducer"`
|
|
635
|
+
→ 返回**第 1 步:确认模式 + ① 并行策略 D/E + ② 是否 AI 自主 A/B/C**
|
|
636
|
+
→ **把这两问呈现给用户,必须等用户回答!**
|
|
637
|
+
3. 用户回答后,执行
|
|
638
|
+
`... workflow_gate.py provide_context "<并行策略+搭建方式的答案>"`
|
|
639
|
+
→ 返回**第 2 步:参数需求强度(强需求 / 不强)** → 呈现给用户,等作答
|
|
640
|
+
4. 用户答完参数强度后,**再次**执行
|
|
641
|
+
`... workflow_gate.py provide_context "<参数强度的答案>"`
|
|
642
|
+
→ 返回**先启动总计子代理(十阶段)+ 按需提问指引**
|
|
643
|
+
5. ★ **spawn 总计子代理**(`subagent_fork`,description="总计子代理(十阶段分析)"):
|
|
644
|
+
- 它第一步 `python "<根>\tools\mode2_flow.py" analyst-bind`(绑自己 sessionId)
|
|
645
|
+
- 按序 `begin-stage` / `mark-stage-done` 走完十阶段(缺阶段会被拒)
|
|
646
|
+
- 缺信息时 `python "<根>\tools\ask_user.py" --room "总计子代理" --child <自己的 sessionId>
|
|
647
|
+
--header ... --question ...`(子代理不能直接 ask_user_question)
|
|
648
|
+
- 分析完 `python "<根>\tools\mode2_flow.py" set-subagent-plan --rooms-json <file>
|
|
649
|
+
--rationale "..." --decided-by "总计子代理"`
|
|
650
|
+
- 结束回合,返回编制摘要
|
|
651
|
+
6. 主对话 `wait_agent` / `list_agents` 等它结束,再执行
|
|
652
|
+
`... provide_context "<全部提问的答案>"` → 力学估算 + 落盘 `tools/load_cases/gate_load_case.json`
|
|
653
|
+
7. 问 A/B/C 与 D/E → 执行 `... workflow_gate.py select C,E`
|
|
654
|
+
→ `wave1` = 编制里的**全部建模房间 + 总理子代理**(数量由总计子代理决定)
|
|
655
|
+
→ 返回 **`MODE2_ANALYST_REQUIRED`** = 第 5 步没做(没 spawn 总计子代理)
|
|
656
|
+
8. **wave1 一次性 fork 全部**(建模房间 + 总理子代理写在同一条回复里);
|
|
657
|
+
每个 fork 后立刻 `python "<根>\tools\mode_gate.py" subagent-assign <房间> <id>`
|
|
658
|
+
9. 总理子代理持续 `mode_gate.py room-board --json` 盯各房间 `state`
|
|
659
|
+
(`waiting_sw` 只是排队,不许判死);wave2 = 总装、wave3 = 出图;
|
|
660
|
+
收尾前 `room-end 总理子代理`。
|