@fuxi-ailabs/dsh-ecat 0.0.0-stage → 0.1.0-alpha.2

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.
Files changed (37) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +168 -2
  3. package/assets/skills/ecat-refine/SKILL.md +126 -0
  4. package/assets/skills/ecat-refine/config.claudecode.yaml +101 -0
  5. package/assets/skills/ecat-refine/config.deveco.yaml +109 -0
  6. package/assets/skills/ecat-refine/config.dsh.yaml +104 -0
  7. package/assets/skills/ecat-refine/config.opencode.yaml +115 -0
  8. package/assets/skills/ecat-refine/scripts/_cli_path.py +119 -0
  9. package/assets/skills/ecat-refine/scripts/_proc.py +82 -0
  10. package/assets/skills/ecat-refine/scripts/preflight.py +372 -0
  11. package/assets/skills/ecat-refine/scripts/start.py +136 -0
  12. package/assets/skills/ecat-refine/scripts/stop.py +65 -0
  13. package/assets/skills/ecat-refine/scripts/watch.py +267 -0
  14. package/assets/skills/ecat-setup/SKILL.md +220 -0
  15. package/assets/skills/ecat-setup/references/plugin-design.md +111 -0
  16. package/assets/skills/ecat-setup/scripts/_profile.py +104 -0
  17. package/assets/skills/ecat-setup/scripts/check.py +394 -0
  18. package/assets/skills/ecat-setup/scripts/plugins.py +478 -0
  19. package/assets/skills/ecat-setup/scripts/seeds.py +244 -0
  20. package/assets/skills/ecat-setup/scripts/setup.py +543 -0
  21. package/assets/wheels/ecat-0.1.0-py3-none-any.whl +0 -0
  22. package/cordis.patch.yml +12 -0
  23. package/icon.svg +6 -0
  24. package/locale/en.json +6 -0
  25. package/locale/zh.json +6 -0
  26. package/package.json +58 -6
  27. package/src/client.js +102 -0
  28. package/src/ecat.js +212 -0
  29. package/src/plugin.js +375 -0
  30. package/src/probe_deps.py +128 -0
  31. package/src/proc.js +64 -0
  32. package/src/skills.js +108 -0
  33. package/src/venv.js +117 -0
  34. package/src/web-app.css +224 -0
  35. package/src/web-app.js +476 -0
  36. package/src/web-page.html +13 -0
  37. package/src/web.js +723 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Fuxi AI Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,169 @@
1
- # Temporary Holding Version
1
+ # dsh-ecat
2
+
3
+ Two DSH commands over the ECAT refinement loop.
4
+
5
+ | Command | What it does |
6
+ |---|---|
7
+ | `/ecat-setup` | Hands a prompt to the agent, which runs the `ecat-setup` skill: interview, profile, scoring plugins |
8
+ | `/ecat-refine` | Runs the `ecat-refine` scripts directly: `status`, `open`, `preflight`, `start`, `stop` |
9
+
10
+ `/ecat-setup` never writes files itself — every write goes through the agent, so the normal
11
+ approval and sandbox rules apply. `/ecat-refine` only executes fixed subcommands with an
12
+ argv array; the raw input is never passed to a shell.
13
+
14
+ ## Install
15
+
16
+ ```
17
+ dsh plugin --profile <profile> add dsh-ecat
18
+ ```
19
+
20
+ Or add the market index source and install from the discovers page. The package is MIT
21
+ licensed; its full contents are the two skills, the ECAT wheel, and the command code.
22
+
23
+ ## Requirements
24
+
25
+ - DSH `^0.2.1-rc.2`
26
+ - Python 3.11+ somewhere on the host (`python3`, `python`, or the `py` launcher)
27
+
28
+ ECAT itself is not a prerequisite: the package ships `assets/wheels/ecat-*.whl` and
29
+ `/ecat-setup` creates `~/.dsh/ecat-venv`, installs the wheel into it with `uv pip`
30
+ (falling back to `python -m venv` + `pip`), and points every later command at that
31
+ interpreter. Dependencies are resolved from the network on that first run, which is why
32
+ the installation lives in setup rather than in the loop commands: configuration is the
33
+ point where a missing environment should surface, not the first status check.
34
+
35
+ If the environment cannot be prepared, `/ecat-setup` fails before asking any questions
36
+ and reports the uv and pip errors; `/ecat-refine` has no install step of its own.
37
+
38
+ If you already installed ECAT globally (`uv tool install --editable <repo>`), the plugin
39
+ uses that interpreter instead and never creates a venv.
40
+
41
+ ## Configuration
42
+
43
+ | Key | Default | Meaning |
44
+ |---|---|---|
45
+ | `pythonPath` | auto | Interpreter to use. When set it always wins, broken or not. |
46
+ | `ecatPath` | `ecat` | The CLI, used only for preflight's availability check. |
47
+ | `workspaceRoot` | empty | Fixed ECAT workspace; otherwise the hand-off file or session cwd. |
48
+ | `uvPath` | `uv` | Used by `/ecat-setup` to build the venv. Falls back to `python -m venv`. |
49
+
50
+ `ECAT_VENV_DIR` relocates the managed environment; tests and multi-user machines use it.
51
+
52
+ ## Usage
53
+
54
+ ```
55
+ /ecat-setup
56
+ /ecat-setup help
57
+ /ecat-refine status
58
+ /ecat-refine preflight
59
+ /ecat-refine start
60
+ /ecat-refine open
61
+ /ecat-refine stop
62
+ ```
63
+
64
+ Both commands advertise their arguments in the composer hint as soon as you type the
65
+ name: `/ecat-setup [help | <task description>]` and
66
+ `/ecat-refine [help | status | open | start | stop | preflight] [workspace]`.
67
+
68
+ `/ecat-refine` with no subcommand prints the same list as `/ecat-refine help`.
69
+ `/ecat-refine run` starts the runtime-selection conversation explicitly.
70
+
71
+ Help output is echoed back through one agent turn. DSH's chat view treats a session
72
+ whose only nodes are commands as blank and shows the welcome screen, so a command
73
+ that merely returns text stays invisible until something creates a conversation turn.
74
+
75
+ ### Worked example — `/ecat-setup help`
76
+
77
+ The environment check lives here, not on `/ecat-refine`, because that is where you go
78
+ when you want to know whether the Python side is usable and where a short wait is
79
+ expected. Real output, DSH `0.2.1-rc.2`, plugin `0.1.0-alpha.1`, Windows:
80
+
81
+ ```
82
+ Usage: /ecat-setup [help | <task description>]
83
+ no argument interview me about the task, then write profile and plugins
84
+ <text> same, reusing what this message already says about the task
85
+ help this text, plus whether every ECAT dependency is usable
86
+
87
+ interpreter: C:\Users\me\.dsh\ecat-venv\Scripts\python.exe
88
+ python: 3.11.13
89
+ environment: ready — all 13 runtime dependencies usable
90
+ anthropic 2.1.0
91
+ typer 0.27.3
92
+ ...
93
+ ecat: C:\Users\me\.dsh\ecat-venv\Lib\site-packages\ecat\__init__.py
94
+ ```
95
+
96
+ The list is not hard-coded: `src/probe_deps.py` reads the installed wheel's own
97
+ `Requires-Dist` entries through `importlib.metadata`, so a dependency added to
98
+ `pyproject.toml` is covered the next time the wheel is built. Each entry is
99
+ checked for presence, for the version range the wheel asks for, and for a
100
+ resolvable top-level module. A failure names the package and how to fix it:
101
+
102
+ ```
103
+ environment: NOT ready — 2 of 13 dependencies failed
104
+ openpyxl is not installed
105
+ pydantic has version 2.6.1, needs pydantic>=2.7
106
+ fix with: <interpreter> -m pip install openpyxl
107
+ ```
108
+
109
+ This is deliberately not `import ecat`: `ecat/__init__.py` is a version string,
110
+ so importing it succeeds with every third-party package missing. `resolvePython`
111
+ uses the same probe when it chooses an interpreter, so a half-installed
112
+ environment is never picked for `status`, `start`, or anything else.
113
+
114
+ Before the first setup it reads `environment: NOT ready — <venv> does not exist.` and
115
+ tells you to run `/ecat-setup` with no argument. Nothing is installed and no interview
116
+ starts from `help`.
117
+
118
+ ### Worked example — `/ecat-refine help`
119
+
120
+ ```
121
+ Usage: /ecat-refine [status|open|start|stop|preflight] [workspace]
122
+ status latest run: H, iterations, worst dimension (default)
123
+ ...
124
+ No subcommand runs the loop: the agent picks the runtime with you first.
125
+ Check the environment with /ecat-setup help; /ecat-refine has no install step.
126
+ ```
127
+
128
+ This is synchronous — it does not spawn Python, so it answers immediately even when
129
+ no interpreter can import ECAT.
130
+
131
+ ### Worked example — a common failure
132
+
133
+ `/ecat-refine status` with no workspace configured and no hand-off file:
134
+
135
+ ```
136
+ kind: error
137
+ No ECAT workspace found. Run /ecat-setup first, pass it explicitly
138
+ (/ecat-refine status <workspace>), or set workspaceRoot in the plugin config.
139
+ ```
140
+
141
+ This is the path a first-time user hits; it names all three ways to resolve it rather
142
+ than silently reading the session's cwd, which could start the loop on the wrong tree.
143
+
144
+ ## Failure modes
145
+
146
+ | Symptom | Cause |
147
+ |---|---|
148
+ | `No ECAT workspace found` | `/ecat-setup` has not run and no workspace was passed |
149
+ | `spawn failed: ENOENT` | `pythonPath` does not exist on the DSH host |
150
+ | preflight `exit 15` | `ecat` is not on the host PATH |
151
+ | preflight `exit 13` | the variable named by `api_key_env` has no value in `<ws>/.env` |
2
152
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
153
+ ## Releasing the npm package
154
+
155
+ Everything needed to build and publish ships on the `dsh-plugin` branch: `src/`,
156
+ the two skills under `assets/skills/`, and the ECAT wheel under `assets/wheels/`.
157
+ The `ECAT_core` branch is not required for a release (refresh the wheel only when
158
+ core behaviour that the plugin relies on changed).
159
+
160
+ 1. `git checkout dsh-plugin` and make sure the tree is clean.
161
+ 2. `node integrations/dsh/scripts/sync-skills.mjs` — keeps `assets/skills` identical to `./skills`.
162
+ 3. If ECAT core changed: build a wheel from that revision (`uv build`) and replace `assets/wheels/ecat-*.whl`.
163
+ 4. Bump the version: `npm version prerelease --preid=alpha --no-git-tag-version`.
164
+ 5. `cd integrations/dsh && npm pack --dry-run` — expect the same 37 files, including `src/client.js`.
165
+ 6. `npm publish --tag alpha`.
166
+ 7. `git push origin dsh-plugin`.
167
+
168
+ Keep `name` in `package.json` and the `insert` entry in `cordis.patch.yml`
169
+ identical (`@fuxi-ailabs/dsh-ecat`); a mismatch makes the plugin fail to import.
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: ecat-refine
3
+ description: 启动、监控、停止 ECAT 的 Android→HarmonyOS 对抗式迁移循环(ecat refine)。当用户说"跑一下 ECAT""继续优化鸿蒙仓""跑迁移修复循环""ECAT 跑到哪了""看看熵降到多少了""停掉 ECAT"时触发。也用于跑之前检查 ECAT 配置是否符合预期。这是小时级后台任务,本 skill 只负责启停与查询,不会同步等待。
4
+ ---
5
+
6
+ # ecat-refine
7
+
8
+ 驱动 ECAT:生成器改鸿蒙代码、判别器打分算熵(H),逐轮对抗直到收敛。
9
+
10
+ ## 这是长任务,绝不要同步等
11
+
12
+ 一轮的耗时由 target 规模、维度数量和模型速度决定,从几分钟到几十分钟不等;轮次上限默认 300。启动脚本后台跑并立即返回;之后每次想知道进展就调一次 `watch.py`,它秒回。
13
+
14
+ **永远不要**用 `ecat refine` 直接前台跑,也不要在等待循环里反复 sleep。
15
+
16
+ ## 第零步:先问用户跑哪个 runtime,打印 config 路径让用户确认
17
+
18
+ **先分清两份配置**:`ecat-setup` 写的是 `<WS>/ecat.config.yaml`(你的 profile、插件集、
19
+ 权重、路径),四份 `config.*.yaml` 只是 **runtime preset**(决定用哪个 CLI、endpoint 怎么走)。
20
+ `preflight.py` / `start.py` **默认读 workspace 那份**;只有第一次在某台机器上试跑、或
21
+ workspace 里还没有 `ecat.config.yaml` 时才用 preset。
22
+
23
+ 如果 workspace 里已有 `ecat.config.yaml` 而你又显式传了 preset,preflight 会 WARN 并
24
+ 列出被忽略的键(`profile` / `entropy.plugin_set` / `paths.target`)——看到这条就别继续。
25
+
26
+ 1. **问用户用哪个 runtime**(四选一,列出来让用户选):
27
+
28
+ | 选项 | preset | 说明 |
29
+ |---|---|---|
30
+ | Claude Code | `config.claudecode.yaml` | 走 `claude` CLI + DeepSeek 的 Anthropic 兼容层。可观测性完整(stream-json 事件流、会话续跑、多目录访问) |
31
+ | opencode | `config.opencode.yaml` | 走 `opencode` CLI + OpenAI 兼容端点。**已知降级**:`generator_compact_interval` 无效;附加目录靠公共祖先合并成单个 `--dir` |
32
+ | deveco | `config.deveco.yaml` | 走 `deveco` CLI(npm `@deveco/deveco-code`,opencode 的 fork)+ OpenAI 兼容端点。配置 schema / 事件流 / 429 软中止与 opencode 同构;**已知降级**:同 opencode(`generator_compact_interval` 无效) |
33
+ | DeepSeek Harness | `config.dsh.yaml` | 走 `dsh --profile headless` 的一次性模式(npm `@deepseek-ai/dsh`)。**两处特殊**:`base_url` 必须留空(端点由 dsh 的 profile 决定,配了会被 ECAT 拒绝);模型靠每次调用的临时 patch 指定。**已知降级**:`generator_compact_interval` 无效(无会话内压缩),改由 dsh 自带的 compaction-basic 接管;`.ecat/agents/*/agents/*.md` 不会被加载,judge 的 rubric 走派发提示词 |
34
+
35
+ 2. **打印实际会用的 config 绝对路径**,念给用户确认:workspace 有 `ecat.config.yaml` 时
36
+ 就是它;没有时才念所选 preset 的路径。
37
+
38
+ 3. **用户确认后**才执行 preflight(体检)+ start(启动)。未确认/用户选别的,不要擅自跑。
39
+
40
+ 四份 preset 的差异只在 runtime / base_url / api_key_env / model(deveco 与 opencode
41
+ 同构,仅 runtime 字段和命令名不同),其余调参完全一致。**`ecat-setup` 已把这些键写进
42
+ `<WS>/ecat.config.yaml`,不要用 preset 覆盖它。**
43
+
44
+ > 选 `dsh` 时额外确认两件事:`dsh` 在 PATH 上(`npm i -g @deepseek-ai/dsh`),以及 `.env` 里有 `DEEPSEEK_API_KEY`。首次运行会在 `.ecat/agents/<role>/` 下自动生成 DSH 的 profile 和 `AGENTS.md`——preflight 会提示"尚未生成",那是正常的。
45
+
46
+ > 确认依据:跑 `preflight.py` 会打印「── 确认 ──」段(runtime + config 绝对路径),**把它念给用户确认后再执行 start.py**。preflight 不是确认,它只是体检;发车前的确认以用户点头为准。
47
+
48
+ ## 四步
49
+
50
+ 全部是 Python 脚本(Windows / Linux / macOS 通用,不需要 bash)。
51
+ `S` = 本 skill 目录,`WS` = ECAT 工作区根目录。
52
+
53
+ ```
54
+ # CFG = config.claudecode.yaml / config.opencode.yaml / config.deveco.yaml / config.dsh.yaml(第零步问出来的)
55
+
56
+ # 1. 体检(必做)—— 摊开"实际会怎么跑",逐项对现实核验
57
+ python <S>/scripts/preflight.py --config <S>/<CFG> --workspace <WS>
58
+
59
+ # 2. 启动(体检 exit 0 之后)
60
+ python <S>/scripts/start.py --config <S>/<CFG> --workspace <WS>
61
+
62
+ # 3. 查进度(随时,秒回)
63
+ python <S>/scripts/watch.py --workspace <WS>
64
+ # 想让用户看曲线:加 --open 用默认浏览器打开 charts/entropy.html
65
+ python <S>/scripts/watch.py --workspace <WS> --open
66
+
67
+ # 4. 停止
68
+ python <S>/scripts/stop.py --workspace <WS>
69
+ ```
70
+
71
+ 解释器名按平台取 `python` 或 `python3`。脚本只用标准库 + `pyyaml`,
72
+ 进程操作可选依赖 `psutil`(ECAT 本身已依赖;缺失时自动退化到 tasklist/kill)。
73
+
74
+ `<WS>` = ECAT 工作区根目录(含 `.ecat/`、鸿蒙仓、安卓源码那个目录)。必须由用户给出,不要猜。
75
+
76
+ 不传 `<WS>` 时,脚本和 `/ecat-refine` 命令按 `~/.ecat/active-workspace.json` 解析——那是**最近一次 `ecat-setup` 的 `check.py` 通过时**写入的指针,所以换项目只要重跑 setup,裸命令会自动跟随。命令行显式给的 `<WS>` 永远优先;指针指向的目录被删掉时会跳过它,退回插件配置/会话 cwd。
77
+
78
+ ## 配置就在这个 skill 里
79
+
80
+ 两份 config 都随 skill 分发。**每次启动前先跑 preflight**,它会打印这份配置实际指向什么,末尾单列一块「项目相关配置」。
81
+
82
+ 配置分两类,处理方式不同:
83
+
84
+ | | 字段 | 怎么做 |
85
+ |---|---|---|
86
+ | **项目相关**(每次调用都可能变) | `project`、`paths.android`、`paths.harmony`、`paths.spec`、`paths.feature_checklist` | 把 preflight 末尾那一块念给用户确认;不对就改所选的 config 重跑 |
87
+ | **策略/调参**(ECAT 的经验值) | `loop.*` 阈值、`entropy.weights`、`judge_max_issues`、`timeout_s`、模型与 endpoint | **不要动**。用户明确要求才改,改完说明改了什么 |
88
+
89
+ `paths.spec` 与 `paths.feature_checklist` 是选填:spec 缺失时生成器退化为按文件名匹配安卓源码;feature_checklist 未配置时该熵维度自动跳过(`skipped: no_feature_checklist_configured`),都不会报错。但**配了却指向不存在的文件**是 FAIL——那是写错了,不是没配。
90
+
91
+ ## 退出码
92
+
93
+ `preflight.py`
94
+
95
+ | 码 | 含义 | 怎么办 |
96
+ |---|---|---|
97
+ | 0 | 就绪 | 可以启动 |
98
+ | 10 | 配置本身有问题 | 改所选的 config;若报 endpoint 不匹配,多半是两份 config 用混了 |
99
+ | 11 | 路径对不上现实 | 改 `config.yaml` 的 `paths.*`;harmony 不是 git 仓要先 `git init` |
100
+ | 12 | 运行时缺失 | 装/加 PATH:`claude` 或 `opencode`(按所选 runtime) |
101
+ | 13 | 凭据缺失 | 往 `<WS>/.env` 里补 `api_key_env` 指名的变量 |
102
+ | 14 | workspace 未初始化 | 在 `<WS>` 跑 `ecat init` |
103
+ | 15 | `ecat` 不在 PATH | `uv tool install --editable <ECAT 仓>` |
104
+
105
+ `start.py`:0=已启动 / 1=参数或路径错 / 2=已有 run 在跑 / 3=启动失败(看打印的 boot log 末尾)
106
+
107
+ `watch.py`:0=正在跑 / 1=已结束 / 2=异常终止 / 3=没有任何 run
108
+
109
+ `stop.py`:0=已停 / 3=没有在跑的 run
110
+
111
+ ## 怎么读 watch 的输出
112
+
113
+ - **H 曲线**是主信号,逐轮下降说明生成器在真的修东西;长期不动说明卡住了
114
+ - **维度分数**指出当前最差的一维(`worst:`),生成器下一轮主要修它
115
+ - **清单行**(配了功能清单时)显示 `OK/ISSUE/TODO` 与上轮推进量——推进量远低于目标说明判别器在敷衍
116
+ - 异常终止(exit 2)时看 `.ecat/skill-refine.boot.log` 和 `runs_*/run.log` 末尾
117
+
118
+ `--open` 打开的是 `runs_*/charts/entropy.html`:每轮判别完成后重写、页面每 30 秒自刷新,
119
+ 所以停在浏览器里即可,不必反复 `watch`。首轮判别完成前这个文件还不存在,脚本会直接说明。
120
+ 只想确认路径、不想弹浏览器时用 `--open --dry-run`。
121
+
122
+ ## 边界
123
+
124
+ - 一个 workspace 同时只允许一个 refine(两个会互相 revert 同一个 git 仓)。`start.py` 会拦。
125
+ - 本 skill 不改鸿蒙代码、不改熵插件、不动 `.ecat/agents/`——那些是 ECAT 自己的事。
126
+ - 跑起来之后 ECAT 会自行 commit 每轮改动到鸿蒙仓;`stop.py` 不回滚已提交的内容。
@@ -0,0 +1,101 @@
1
+ # ─── Identity ────────────────────────────────────────────────────────────────
2
+ project: my-android-app
3
+ work_dir: .
4
+
5
+ # ─── Source / Target paths ───────────────────────────────────────────────────
6
+ # `target` is required; `source` is optional (single-tree tasks omit it).
7
+ paths:
8
+ source: ./Android_code/AIPPT
9
+ target: ./aippt_cc_glm_0705
10
+
11
+
12
+ # ─── Agents ──────────────────────────────────────────────────────────────────
13
+ # Each agent can use a different runtime, provider, model, and base_url.
14
+ # base_url: set to your provider's OpenAI-compatible endpoint, or null for default.
15
+ # api_key_env: the NAME of the env var in .env (not the key itself).
16
+
17
+ generator:
18
+ runtime: claude_code # claude_code | opencode | deveco_code | dsh
19
+ model: deepseek-v4-flash[1m] # any model your provider supports
20
+ provider: deepseek
21
+ base_url: https://api.deepseek.com/anthropic # e.g. https://api.deepseek.com/v1
22
+ api_key_env: ANTHROPIC_AUTH_TOKEN
23
+ config_dir: .ecat/agents/generator
24
+ timeout_s: 5400
25
+ extra_args: []
26
+ resume_session: true
27
+
28
+ discriminator:
29
+ runtime: claude_code
30
+ model: deepseek-v4-flash[1m]
31
+ provider: deepseek
32
+ base_url: https://api.deepseek.com/anthropic
33
+ api_key_env: ANTHROPIC_AUTH_TOKEN
34
+ config_dir: .ecat/agents/discriminator
35
+ timeout_s: 3600
36
+ extra_args: []
37
+ evolution_write_paths:
38
+ - .ecat/agents/generator/skills
39
+ - .ecat/agents/generator/memory
40
+
41
+ # ─── Adversarial loop ────────────────────────────────────────────────────────
42
+ loop:
43
+ max_iterations: 300
44
+ entropy_threshold: 0.01
45
+ # stable_iters_to_stop: H 需连续 N 轮低于 entropy_threshold 才提前退出(防单轮"安静"过早收敛)。默认 2。
46
+ stable_iters_to_stop: 2
47
+ # regression_tolerance: 相邻两轮之间的回归容忍度。
48
+ # 如果本轮 H 比上轮 H 增加超过此值,判定为"回归"(代码质量变差)。
49
+ # revert_on_regression=true 时会 git checkout 撤销本轮 Generator 的改动。
50
+ # 作用:防止单次迭代引入破坏性变更。
51
+ regression_tolerance: 0.1
52
+ revert_on_regression: true
53
+
54
+ # oscillation_guard: 检测循环是否陷入"震荡"(反复修改同一问题无法收敛)。
55
+ # window: 回看最近 N 轮的 H 值序列。
56
+ # min_delta: 如果最近 window 轮中相邻两轮的 H 变化绝对值都 < min_delta,
57
+ # 说明 Generator 在原地打转,触发提前终止。
58
+ # 作用:避免浪费 token 在无效迭代上。
59
+ oscillation_guard:
60
+ enabled: true
61
+ window: 5
62
+ min_delta: 0.02
63
+
64
+ generator_compact_interval: 15
65
+ # max_items_per_iter: 每轮传给生成器的 work-list 最大条目数。
66
+ # 调小可缩短每轮耗时但需更多轮次收敛;调大每轮改动更多但速度变慢。默认 25。
67
+ max_items_per_iter: 50
68
+
69
+ # ─── Entropy plugin set ───────────────────────────────────────────────────────
70
+ # Every dimension listed in weights must be registered by a plugin in the
71
+ # selected set; a weight with no plugin is silently ignored, so the dimension
72
+ # never scores and the Generator never gets work for it.
73
+ entropy:
74
+ plugin_set: example
75
+ # judge_max_issues: 每个 agentic judge 子代理最多上报的问题数。
76
+ # 调小让 judge 更早停止探索文件,加快判别器;调大获取更多细节。默认 10。
77
+ judge_max_issues: 20
78
+ weights:
79
+ compile: 0.30
80
+ feature_parity: 0.35
81
+
82
+ # ─── Retry ────────────────────────────────────────────────────────────────────
83
+ retry:
84
+ max_attempts: 3
85
+ base_delay_s: 2
86
+ max_delay_s: 30
87
+ jitter: true
88
+
89
+ # ─── Phase gates ─────────────────────────────────────────────────────────────
90
+ features:
91
+ memory_evolution: true
92
+ skill_evolution: false
93
+ multi_discriminator: false
94
+ in_loop_intervention: false
95
+
96
+ # ─── Reporting ───────────────────────────────────────────────────────────────
97
+ reporting:
98
+ chart_format: png
99
+ chart_on_each_iter: true
100
+ keep_run_artifacts: -1
101
+ log_level: info
@@ -0,0 +1,109 @@
1
+ # ─── deveco_code 变体 ────────────────────────────────────────────────────────
2
+ # 与 config.opencode.yaml 的差异只在 runtime:deveco 是 opencode 的 fork
3
+ # (npm @deveco/deveco-code),配置 schema / 事件流 / 429 软中止与 opencode 同构,
4
+ # 只是命令名为 `deveco`、自动批准用 `--auto`、配置目录环境变量是 DEVECO_CONFIG_DIR、
5
+ # 配置文件名是 deveco.jsonc。ECAT 引擎由 DevecoCodeRunner(继承 OpencodeRunner)驱动。
6
+ #
7
+ # runtime claude_code → deveco_code
8
+ # 其余(base_url / api_key_env / model / provider)与 opencode 变体一致:
9
+ # * 走 @ai-sdk/openai-compatible 裸 OpenAI 端点(不要 /anthropic 后缀)
10
+ # * api_key_env 用 DEEPSEEK_API_KEY 之类标准 AI SDK 槽位(同 opencode)
11
+ # ─── Identity ────────────────────────────────────────────────────────────────
12
+ project: my-android-app
13
+ work_dir: .
14
+
15
+ # ─── Source / Target paths ───────────────────────────────────────────────────
16
+ # `target` is required; `source` is optional (single-tree tasks omit it).
17
+ paths:
18
+ source: ./Android_code/AIPPT
19
+ target: ./ai_ppt_ecat_deveco_skill0910
20
+
21
+
22
+ # ─── Agents ──────────────────────────────────────────────────────────────────
23
+ # Each agent can use a different runtime, provider, model, and base_url.
24
+ # base_url: set to your provider's OpenAI-compatible endpoint, or null for default.
25
+ # api_key_env: the NAME of the env var in .env (not the key itself).
26
+
27
+ generator:
28
+ runtime: deveco_code # claude_code | opencode | deveco_code | dsh
29
+ model: glm-5.3-flash # 干净模型名(不带 provider 前缀;deveco runner 会拼成 zhipu/glm-5.3-flash)
30
+ provider: zhipu
31
+ base_url: https://open.bigmodel.cn/api/coding/paas/v4
32
+ api_key_env: GLM_API_KEY_YQ
33
+ config_dir: .ecat/agents/generator
34
+ timeout_s: 5400
35
+ extra_args: []
36
+ resume_session: true
37
+
38
+ discriminator:
39
+ runtime: deveco_code
40
+ model: glm-5.3-flash
41
+ provider: zhipu
42
+ base_url: https://open.bigmodel.cn/api/coding/paas/v4
43
+ api_key_env: GLM_API_KEY_YQ
44
+ config_dir: .ecat/agents/discriminator
45
+ timeout_s: 3600
46
+ extra_args: []
47
+ evolution_write_paths:
48
+ - .ecat/agents/generator/skills
49
+ - .ecat/agents/generator/memory
50
+
51
+ # ─── Adversarial loop ────────────────────────────────────────────────────────
52
+ loop:
53
+ max_iterations: 100
54
+ entropy_threshold: 0.01
55
+ stable_iters_to_stop: 2
56
+ regression_tolerance: 0.1
57
+ revert_on_regression: true
58
+ oscillation_guard:
59
+ enabled: true
60
+ window: 5
61
+ min_delta: 0.02
62
+ generator_compact_interval: 15
63
+ max_items_per_iter: 50
64
+
65
+ # ─── Entropy plugin set ───────────────────────────────────────────────────────
66
+ # Every dimension listed in weights must be registered by a plugin in the
67
+ # selected set; a weight with no plugin is silently ignored, so the dimension
68
+ # never scores and the Generator never gets work for it.
69
+ entropy:
70
+ plugin_set: example
71
+ # judge_max_issues: 每个 agentic judge 子代理最多上报的问题数。
72
+ # 调小让 judge 更早停止探索文件,加快判别器;调大获取更多细节。默认 10。
73
+ judge_max_issues: 20
74
+ weights:
75
+ compile: 0.30
76
+ feature_parity: 0.35
77
+
78
+ # entry_nav: 0.10
79
+ # feature_check: 0.30
80
+ # page_audit: 0.10
81
+ # confidence: 0.10
82
+ # spec_coverage: 0.10
83
+ # source_parity: 0.10
84
+ # hallucination: 0.10
85
+
86
+ # node_align: 0.0
87
+ # ui_align: 0.0
88
+ # runtime_liveness: 0.0
89
+
90
+ # ─── Retry ────────────────────────────────────────────────────────────────────
91
+ retry:
92
+ max_attempts: 3
93
+ base_delay_s: 2
94
+ max_delay_s: 30
95
+ jitter: true
96
+
97
+ # ─── Phase gates ─────────────────────────────────────────────────────────────
98
+ features:
99
+ memory_evolution: false
100
+ skill_evolution: false
101
+ multi_discriminator: false
102
+ in_loop_intervention: false
103
+
104
+ # ─── Reporting ───────────────────────────────────────────────────────────────
105
+ reporting:
106
+ chart_format: png
107
+ chart_on_each_iter: true
108
+ keep_run_artifacts: -1
109
+ log_level: info
@@ -0,0 +1,104 @@
1
+ # ECAT — DeepSeek Harness (dsh) runtime, headless one-shot mode.
2
+ #
3
+ # Differences from the claude_code config:
4
+ # * no base_url — dsh owns its endpoint (official route or DEEPSEEK_BASE_URL);
5
+ # ECAT rejects base_url for this runtime rather than silently ignoring it.
6
+ # * model is written into a per-call patch, because headless has no --model.
7
+ # * api_key_env defaults to DEEPSEEK_API_KEY; the runner exports the resolved
8
+ # value under that name whatever variable the config points at.
9
+ # * each role gets its own DSH_HOME under .ecat/agents/<role>/ (profile +
10
+ # AGENTS.md), created automatically on the first run.
11
+ #
12
+ # Verify with: python <skill>/scripts/preflight.py --config <this file> --workspace <WS>
13
+
14
+ # ─── Identity ────────────────────────────────────────────────────────────────
15
+ project: my-project
16
+ work_dir: .
17
+
18
+ # ─── Prompt profile ──────────────────────────────────────────────────────────
19
+ # Domain fragment under ecat/prompts/profiles/<name>/. "a2h" ships with the
20
+ # repo; create your own with the ecat-setup skill.
21
+ profile: a2h
22
+
23
+ # ─── Source / Target paths ───────────────────────────────────────────────────
24
+ paths:
25
+ # source: ./reference # optional: only for a task with a ground-truth tree
26
+ target: ./target # required, must exist
27
+
28
+ # ─── Agents ──────────────────────────────────────────────────────────────────
29
+ generator:
30
+ runtime: dsh
31
+ model: deepseek-flash
32
+ provider: deepseek
33
+ base_url: null # must stay null for dsh
34
+ api_key_env: DEEPSEEK_API_KEY
35
+ config_dir: .ecat/agents/generator
36
+ timeout_s: 5400
37
+ extra_args: []
38
+ # Continue the same dsh session across iterations (--session-id). Saves
39
+ # cache reads; context grows, so pair it with the loop's compaction setting.
40
+ resume_session: true
41
+
42
+ discriminator:
43
+ runtime: dsh
44
+ model: deepseek-flash
45
+ provider: deepseek
46
+ base_url: null
47
+ api_key_env: DEEPSEEK_API_KEY
48
+ config_dir: .ecat/agents/discriminator
49
+ timeout_s: 3600
50
+ extra_args: []
51
+ evolution_write_paths:
52
+ - .ecat/agents/generator/skills
53
+ - .ecat/agents/generator/memory
54
+
55
+ # ─── Adversarial loop ────────────────────────────────────────────────────────
56
+ loop:
57
+ max_iterations: 100
58
+ entropy_threshold: 0.01
59
+ stable_iters_to_stop: 2
60
+ regression_tolerance: 0.1
61
+ revert_on_regression: true
62
+ oscillation_guard:
63
+ enabled: true
64
+ window: 5
65
+ min_delta: 0.02
66
+ # dsh runs one process per call and has no in-session /compact, so this knob
67
+ # is a no-op here. Context growth is handled by dsh's own compaction-basic
68
+ # (threshold 0.8 of the model window) inside each resumed session.
69
+ generator_compact_interval: 0
70
+ max_items_per_iter: 25
71
+
72
+ # ─── Entropy plugin set ──────────────────────────────────────────────────────
73
+ # `example` ships with the repo. Replace with the set you build; every
74
+ # dimension listed in weights must be registered by some plugin.
75
+ entropy:
76
+ plugin_set: example
77
+ judge_max_issues: 10
78
+ weights:
79
+ compile: 0.30
80
+ feature_parity: 0.35
81
+
82
+ # ─── Retry ────────────────────────────────────────────────────────────────────
83
+ # dsh retries transient provider failures inside the turn (dsh-llm-retry).
84
+ # Keep this modest so an upstream outage surfaces as a failed iteration rather
85
+ # than hours of silent retrying.
86
+ retry:
87
+ max_attempts: 2
88
+ base_delay_s: 2
89
+ max_delay_s: 30
90
+ jitter: true
91
+
92
+ # ─── Phase gates ─────────────────────────────────────────────────────────────
93
+ features:
94
+ memory_evolution: false
95
+ skill_evolution: false
96
+ multi_discriminator: false
97
+ in_loop_intervention: false
98
+
99
+ # ─── Reporting ───────────────────────────────────────────────────────────────
100
+ reporting:
101
+ chart_format: png
102
+ chart_on_each_iter: true
103
+ keep_run_artifacts: -1
104
+ log_level: info