Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 917df04712 | |||
| b016b3b411 |
@@ -5,7 +5,8 @@ description: "用用户能理解的方式说明这个技能能做什么、适合
|
|||||||
> **模板说明(复制后删除本段)**
|
> **模板说明(复制后删除本段)**
|
||||||
> 本文是技能市场详情与普通用户说明,**不是** Agent 参考索引、CLI 契约或开发文档。
|
> 本文是技能市场详情与普通用户说明,**不是** Agent 参考索引、CLI 契约或开发文档。
|
||||||
> frontmatter 的 `description` 必须是用户能看懂的一句话能力描述;**不得**写成 CLI、schema、references、development、契约、数据结构、开发规范或 Agent 参考索引。
|
> frontmatter 的 `description` 必须是用户能看懂的一句话能力描述;**不得**写成 CLI、schema、references、development、契约、数据结构、开发规范或 Agent 参考索引。
|
||||||
> 正文只回答用户关心的问题,**不要**把 Playwright、DOM、Python、RPA、references、development、schema 等作为面向用户的主说明内容;若业务上必须出现技术词,须用用户能理解的方式解释,且不能喧宾夺主。
|
> 正文只回答用户关心的问题,**不要**把 Playwright、DOM、Python、RPA、references、development、schema 等作为面向用户的主说明内容;若业务上必须出现技术词,须用用户能理解的方式解释,且不能喧宾夺主。
|
||||||
|
> **复制后验收章节(标题可微调,建议保留):**「能帮你做什么」「适合什么场景」「使用前需要准备什么」「你可以这样告诉 Agent」「执行后你会得到什么」「注意事项」「常见问题」。
|
||||||
|
|
||||||
# 【技能名称】
|
# 【技能名称】
|
||||||
|
|
||||||
|
|||||||
44
SKILL.md
44
SKILL.md
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: 技能开发模板(通用业务版)
|
name: 技能开发模板(通用业务版)
|
||||||
description: "OpenClaw 通用业务技能开发模板,供复制后定制新业务 skill。定制步骤见 development/DEVELOPMENT.md。"
|
description: "OpenClaw 通用业务技能开发模板,供复制后定制新业务 skill。定制步骤见 development/DEVELOPMENT.md。"
|
||||||
version: 1.0.43
|
version: 1.0.45
|
||||||
author: 深圳匠厂科技有限公司
|
author: 深圳匠厂科技有限公司
|
||||||
metadata:
|
metadata:
|
||||||
openclaw:
|
openclaw:
|
||||||
@@ -29,15 +29,28 @@ allowed-tools:
|
|||||||
- **`bind.tables`**:只决定数据管理出现在哪些表;含 `toolbar` 时**必须**显式非空绑定。
|
- **`bind.tables`**:只决定数据管理出现在哪些表;含 `toolbar` 时**必须**显式非空绑定。
|
||||||
- **`executionProfile`**:只决定执行方式——`sync` 当场返回结果,`async` 进**任务中心**。与 placements / 入口**无关**;每个 Action **必须**显式写 `sync` 或 `async`。
|
- **`executionProfile`**:只决定执行方式——`sync` 当场返回结果,`async` 进**任务中心**。与 placements / 入口**无关**;每个 Action **必须**显式写 `sync` 或 `async`。
|
||||||
- **同步数据**写技能本地库、不生成导出文件;**导出当前表**由宿主数据管理负责;特殊业务报告才另做 `export-*`。
|
- **同步数据**写技能本地库、不生成导出文件;**导出当前表**由宿主数据管理负责;特殊业务报告才另做 `export-*`。
|
||||||
|
- **准备 vs 执行(适用则拆)**:若技能存在「先写入/准备本地数据」与「再对外产生副作用」两段,Agent 必须能分开触发;禁止默认绑成不可拆的一步。一键无准备态的技能可跳过本条。
|
||||||
|
|
||||||
### 如何触发(决策树)
|
### 如何触发(能力类型)
|
||||||
|
|
||||||
| 你要做什么 | Agent 怎么做 | 进任务中心? |
|
| 你要做什么 | Agent 怎么做 | 进任务中心? |
|
||||||
|------------|--------------|--------------|
|
|------------|--------------|--------------|
|
||||||
| 短查询 / 只读 / 秒级(`health` / `version` / `stats` / `list` / `get` / `logs` 等) | OpenClaw bash/exec + **共享 Python** 跑 CLI(见下方「共享 Python」) | 否(CLI 当场结束) |
|
| 短查询 / 只读 / 秒级(`health` / `version` / `stats` / `list` / `get` / `logs` 等) | OpenClaw bash/exec + **共享 Python** 跑 CLI(见下方「共享 Python」) | 否(CLI 当场结束) |
|
||||||
| 已在 `actions.json` 声明且 `executionProfile: "sync"` 的能力 | 可用 `run_skill_action`,或同等效果的短 CLI(同一内核) | 否 |
|
| 已在 `actions.json` 声明且 `executionProfile: "sync"` 的能力 | 可用 `run_skill_action`,或同等效果的短 CLI(同一内核) | 否 |
|
||||||
| 长耗时 / RPA / 浏览器 / 需要进度或取消;或 `executionProfile: "async"` | **必须** `run_skill_action`(先 `list_skill_actions` / `get_skill_action`) | **是**(仅因为该 Action 是 async) |
|
| 长耗时 / RPA / 浏览器 / 需要进度或取消;或 `executionProfile: "async"` | **必须** `run_skill_action`(先 `list_skill_actions` / `get_skill_action`) | **是**(仅因为该 Action 是 async) |
|
||||||
| 用户只问用法 / 能做什么 | 读根目录 `README.md`;技术细节读 `references/` | — |
|
| 用户只问用法 / 能做什么 | 读根目录 `README.md`;**不要**为答用法去列目录或默认打开 `references/` | — |
|
||||||
|
|
||||||
|
### 用户意图路由表(业务技能复制后必改)
|
||||||
|
|
||||||
|
复制为业务技能后,**必须**用本技能真实意图改写下表(保留三列结构)。格子写清:短 CLI 子命令,或 `run_skill_action` → **具体 action id**(及主要 `input`)。勿留模板占位语上线。
|
||||||
|
|
||||||
|
| 用户意图(本技能自填) | Agent 怎么做 | 进任务中心? |
|
||||||
|
|------------------------|--------------|--------------|
|
||||||
|
| (例)查询 / 统计 / 列表 | 短 CLI:`<your-read-commands>` | 否 |
|
||||||
|
| (例)写入 / 导入 / 改本地状态 | 短 CLI:`<your-prep-commands>` | 否 |
|
||||||
|
| (例)长副作用 / RPA / 需进度 | `run_skill_action` → `<your-async-action-id>`,`input.…` | 是(因该 Action 为 async) |
|
||||||
|
|
||||||
|
有长任务 / RPA 时:上表至少一行指向真实的 async action id,且该 id 须出现在 `assets/actions.json`;细节分流见 `references/CLI.md`。
|
||||||
|
|
||||||
**硬规则:**
|
**硬规则:**
|
||||||
|
|
||||||
@@ -46,24 +59,21 @@ allowed-tools:
|
|||||||
3. **禁止** Agent 自行 `pip install`。
|
3. **禁止** Agent 自行 `pip install`。
|
||||||
4. Action **可选**:无数据管理 / 定时 / Agent 结构化调用需求时可不提供 `actions.json`;有长任务 / RPA 时**必须**提供至少一条 `executionProfile: "async"` 且 `placements` 含 `agent` 的 Action。
|
4. Action **可选**:无数据管理 / 定时 / Agent 结构化调用需求时可不提供 `actions.json`;有长任务 / RPA 时**必须**提供至少一条 `executionProfile: "async"` 且 `placements` 含 `agent` 的 Action。
|
||||||
5. **一个业务能力一个 Action**,用多个 `placements` 挂入口;底层仍是同一 `scripts/main.py` CLI。
|
5. **一个业务能力一个 Action**,用多个 `placements` 挂入口;底层仍是同一 `scripts/main.py` CLI。
|
||||||
|
6. 是否进任务中心**只**看该 Action 的 `executionProfile`,与数据管理 / 定时 / Agent 入口无关。
|
||||||
|
|
||||||
Agent 执行契约细节:`references/CLI.md`、`references/ACTIONS.md`、`references/SCHEMA.md`(不要把 `development/` 当 Agent 主读路径)。
|
Agent 执行契约细节:`references/CLI.md`、`references/ACTIONS.md`、`references/SCHEMA.md`(不要把 `development/` 当 Agent 主读路径)。
|
||||||
|
|
||||||
## 共享 Python(必读)
|
## 共享 Python(必读)
|
||||||
|
|
||||||
宿主把共享 runtime 注入进程环境:`JIANGCHANG_PYTHON_EXE`、`VIRTUAL_ENV`,并把 venv 的 `bin`/`Scripts` 前置到 `PATH`。
|
宿主共享 runtime 在 `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv`,并已前置到 PATH(同时设 `VIRTUAL_ENV`)。短 CLI 一条命令直接跑:
|
||||||
|
|
||||||
**推荐调用式(Agent):**
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py health
|
python {baseDir}/scripts/main.py health
|
||||||
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py version
|
python {baseDir}/scripts/main.py version
|
||||||
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py config-path
|
python {baseDir}/scripts/main.py config-path
|
||||||
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py init-db
|
python {baseDir}/scripts/main.py init-db
|
||||||
```
|
```
|
||||||
|
|
||||||
Windows cmd 可用 `"%JIANGCHANG_PYTHON_EXE%"`。若环境已注入共享 venv,也可写 `python {baseDir}/scripts/main.py …`(须确认不是系统/临时解释器)。
|
|
||||||
|
|
||||||
- 公共库来自共享 venv 的 `jiangchang-platform-kit>=1.2.0`(包名路径 `jiangchang_skill_core`);**不要 vendor** `scripts/jiangchang_skill_core/`。
|
- 公共库来自共享 venv 的 `jiangchang-platform-kit>=1.2.0`(包名路径 `jiangchang_skill_core`);**不要 vendor** `scripts/jiangchang_skill_core/`。
|
||||||
- 根目录 `requirements.txt` **只声明技能特有**依赖;不要写 `jiangchang-platform-kit` / `playwright`。
|
- 根目录 `requirements.txt` **只声明技能特有**依赖;不要写 `jiangchang-platform-kit` / `playwright`。
|
||||||
- `metadata.openclaw.platform_kit_min_version` 是宿主兼容声明,**不是** pip 依赖。
|
- `metadata.openclaw.platform_kit_min_version` 是宿主兼容声明,**不是** pip 依赖。
|
||||||
@@ -85,10 +95,18 @@ Windows cmd 可用 `"%JIANGCHANG_PYTHON_EXE%"`。若环境已注入共享 venv
|
|||||||
- 执行后会得到什么
|
- 执行后会得到什么
|
||||||
- 能不能帮我完成某个业务任务
|
- 能不能帮我完成某个业务任务
|
||||||
|
|
||||||
|
**回答「怎么用 / 能做什么」时的要求:**
|
||||||
|
|
||||||
|
1. 以 `README.md` 的「能帮你做什么」「你可以这样告诉 Agent」「常见问题」等章节为主组织回答。
|
||||||
|
2. **禁止**在回答中粘贴 `python …/scripts/main.py …` 或其它命令行(除非用户明确索要命令,或自称技术人员/开发者)。
|
||||||
|
3. **禁止**为答用法而去 `dir` / `ls` / 列技能目录,或默认打开 `references/`、`development/`;仅当用户明确问命令、参数、集成或排错时再读 `references/`。
|
||||||
|
4. **不要**向普通用户暴露 Playwright、DOM、Python、RPA、库表名、`error_code` 等实现细节,除非用户明确询问技术实现。
|
||||||
|
|
||||||
|
**文档读取边界:**
|
||||||
|
|
||||||
- **不要**把 `SKILL.md`、`references/`、`development/` 中的技术细节直接作为用户回答。
|
- **不要**把 `SKILL.md`、`references/`、`development/` 中的技术细节直接作为用户回答。
|
||||||
- **只有当**用户明确询问命令、参数、输出结构、开发、调试、集成或排错时,才读取 `references/`;`development/` 主要给开发者 / 编码助手,对话 Agent **不必**默认打开。
|
- **只有当**用户明确询问命令、参数、输出结构、开发、调试、集成或排错时,才读取 `references/`;`development/` 主要给开发者 / 编码助手,对话 Agent **不必**默认打开。
|
||||||
- 若 `README.md` 与 `SKILL.md` / `references` 表述冲突:对用户展示与市场说明以 `README.md` 为准;对执行契约以 `SKILL.md` / `references` 为准。
|
- 若 `README.md` 与 `SKILL.md` / `references` 表述冲突:对用户展示与市场说明以 `README.md` 为准;对执行契约以 `SKILL.md` / `references` 为准。
|
||||||
- 回答用户时**不要**暴露 Playwright、DOM、Python、RPA 等实现细节,除非用户明确询问技术实现。
|
|
||||||
- 用户未问技术实现时,**不要**讨论 slug 命名规则;开发者问命名或 slug 时,读取 `development/NAMING.md`。
|
- 用户未问技术实现时,**不要**讨论 slug 命名规则;开发者问命名或 slug 时,读取 `development/NAMING.md`。
|
||||||
|
|
||||||
## 文档分工
|
## 文档分工
|
||||||
|
|||||||
@@ -631,11 +631,11 @@ cmd_stats() # 只读 sync:JSON,无 job_context
|
|||||||
本地验证请优先使用宿主共享 Python(与 Agent CLI 相同契约),例如:
|
本地验证请优先使用宿主共享 Python(与 Agent CLI 相同契约),例如:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
"$JIANGCHANG_PYTHON_EXE" scripts/main.py health
|
python scripts/main.py health
|
||||||
"$JIANGCHANG_PYTHON_EXE" scripts/main.py version
|
python scripts/main.py version
|
||||||
```
|
```
|
||||||
|
|
||||||
若环境已将共享 venv 置于 PATH,也可用 `python scripts/main.py …`。**禁止**对技能脚本使用 `uv run python`。
|
**禁止**对技能脚本使用 `uv run python`。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python scripts/main.py -h
|
python scripts/main.py -h
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
| POLICY-STRUCTURE-001 | 标准 `scripts/` 分层:`main.py`、`cli/`、`service/`、`db/`、`util/` 必须存在 | development/DEVELOPMENT.md §2 新 skill 的标准目录结构;development/RUNTIME.md §目录结构 | hard | 目录存在性检查 | `tests/test_development_policy_guard.py::TestPolicyStructure001` |
|
| POLICY-STRUCTURE-001 | 标准 `scripts/` 分层:`main.py`、`cli/`、`service/`、`db/`、`util/` 必须存在 | development/DEVELOPMENT.md §2 新 skill 的标准目录结构;development/RUNTIME.md §目录结构 | hard | 目录存在性检查 | `tests/test_development_policy_guard.py::TestPolicyStructure001` |
|
||||||
| POLICY-RUNTIME-001 | 不得 vendored `scripts/jiangchang_skill_core/` | development/RUNTIME.md §共享 Python Runtime、§明确禁止 | hard | 目录不存在检查 | `tests/test_development_policy_guard.py::TestPolicyRuntime001`(另见 `tests/test_platform_import.py`) |
|
| POLICY-RUNTIME-001 | 不得 vendored `scripts/jiangchang_skill_core/` | development/RUNTIME.md §共享 Python Runtime、§明确禁止 | hard | 目录不存在检查 | `tests/test_development_policy_guard.py::TestPolicyRuntime001`(另见 `tests/test_platform_import.py`) |
|
||||||
| POLICY-RUNTIME-002 | `requirements.txt` 非注释依赖行不得声明 `jiangchang-platform-kit` / `playwright` | development/RUNTIME.md §共享 Python Runtime;development/DEVELOPMENT.md §3.1 requirements.txt 依赖规范 | hard | 解析依赖行 | `tests/test_development_policy_guard.py::TestPolicyRuntime002`(另见 `tests/test_platform_import.py`) |
|
| POLICY-RUNTIME-002 | `requirements.txt` 非注释依赖行不得声明 `jiangchang-platform-kit` / `playwright` | development/RUNTIME.md §共享 Python Runtime;development/DEVELOPMENT.md §3.1 requirements.txt 依赖规范 | hard | 解析依赖行 | `tests/test_development_policy_guard.py::TestPolicyRuntime002`(另见 `tests/test_platform_import.py`) |
|
||||||
| POLICY-RUNTIME-003 | Agent/CLI 文档须要求共享 Python(`JIANGCHANG_PYTHON_EXE` / python-runtime);须明确**禁止**对技能脚本使用 `uv run python` | development/RUNTIME.md;references/CLI.md;SKILL.md | hard | 文档标记扫描 | `tests/test_docs_standards.py::test_cli_md_requires_shared_python_not_uv_run`;`tests/test_docs_standards.py::test_skill_md_requires_shared_python_not_uv_run` |
|
| POLICY-RUNTIME-003 | Agent/CLI 文档须要求共享 Python(python-runtime / PATH 上的 `python` + `{baseDir}`);须明确**禁止**对技能脚本使用 `uv run python` | development/RUNTIME.md;references/CLI.md;SKILL.md | hard | 文档标记扫描 | `tests/test_docs_standards.py::test_cli_md_requires_shared_python_not_uv_run`;`tests/test_docs_standards.py::test_skill_md_requires_shared_python_not_uv_run` |
|
||||||
|
| POLICY-AGENT-001 | `SKILL.md` 须含「用户意图路由表」结构;`CLI.md` 须含短 CLI 白名单 / Action 强制黑名单表;用法回答须禁止无故粘贴 CLI、禁止为答用法列目录挖 references | SKILL.md;references/CLI.md | hard | 文档标记扫描 | `tests/test_docs_standards.py::test_skill_md_has_intent_routing_table`;`tests/test_docs_standards.py::test_cli_md_has_agent_routing_tables`;`tests/test_docs_standards.py::test_skill_md_how_to_forbids_cli_paste` |
|
||||||
| POLICY-INSTALL-001 | 交付执行文件不得含 `pip install` / `python -m pip install` / `uv pip install` / `playwright install` | development/RUNTIME.md §共享 Python Runtime;development/RPA.md §1.4 Playwright 与安装边界;development/DEVELOPMENT.md §3.1 | hard | 扫描 `scripts/**/*.py`、`*.ps1`、`*.sh`、`requirements.txt`、`.github/workflows/*`(不扫 `development/*.md`) | `tests/test_development_policy_guard.py::TestPolicyInstall001` |
|
| POLICY-INSTALL-001 | 交付执行文件不得含 `pip install` / `python -m pip install` / `uv pip install` / `playwright install` | development/RUNTIME.md §共享 Python Runtime;development/RPA.md §1.4 Playwright 与安装边界;development/DEVELOPMENT.md §3.1 | hard | 扫描 `scripts/**/*.py`、`*.ps1`、`*.sh`、`requirements.txt`、`.github/workflows/*`(不扫 `development/*.md`) | `tests/test_development_policy_guard.py::TestPolicyInstall001` |
|
||||||
| POLICY-CONFIG-001 | 仓库根目录必须存在 `.env.example` | development/CONFIG.md §核心原则、§标准配置项 | hard | 文件存在性 | `tests/test_development_policy_guard.py::TestPolicyConfig001` |
|
| POLICY-CONFIG-001 | 仓库根目录必须存在 `.env.example` | development/CONFIG.md §核心原则、§标准配置项 | hard | 文件存在性 | `tests/test_development_policy_guard.py::TestPolicyConfig001` |
|
||||||
| POLICY-CONFIG-002 | `.gitignore` 必须忽略 `.env` 与 `*.env.local` | development/CONFIG.md §红线:敏感信息不进 .env | hard | 解析 `.gitignore` 行 | `tests/test_development_policy_guard.py::TestPolicyConfig002` |
|
| POLICY-CONFIG-002 | `.gitignore` 必须忽略 `.env` 与 `*.env.local` | development/CONFIG.md §红线:敏感信息不进 .env | hard | 解析 `.gitignore` 行 | `tests/test_development_policy_guard.py::TestPolicyConfig002` |
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
| 场景 | 推荐做法 |
|
| 场景 | 推荐做法 |
|
||||||
|------|----------|
|
|------|----------|
|
||||||
| 日常运行(宿主 / Agent) | 使用 `JIANGCHANG_PYTHON_EXE` 或 PATH 已指向的共享 venv `python` |
|
| 日常运行(宿主 / Agent) | 使用 PATH 上的共享 venv `python`(`{JIANGCHANG_DATA_ROOT}/python-runtime/.venv`) |
|
||||||
| 手工排查 / 测试机(环境未注入时) | `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv/.../python` 执行 `scripts/main.py` |
|
| 手工排查 / 测试机(环境未注入时) | `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv/.../python` 执行 `scripts/main.py` |
|
||||||
| **禁止** | 在技能目录内 `uv run python …` — 会创建临时 venv,加载不到宿主共享 runtime |
|
| **禁止** | 在技能目录内 `uv run python …` — 会创建临时 venv,加载不到宿主共享 runtime |
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
推荐(已注入环境时):
|
推荐(已注入环境时):
|
||||||
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py health
|
python {baseDir}/scripts/main.py health
|
||||||
|
|
||||||
Windows(未注入时):
|
Windows(未注入时):
|
||||||
{JIANGCHANG_DATA_ROOT}\python-runtime\.venv\Scripts\python.exe {baseDir}\scripts\main.py health
|
{JIANGCHANG_DATA_ROOT}\python-runtime\.venv\Scripts\python.exe {baseDir}\scripts\main.py health
|
||||||
@@ -25,7 +25,7 @@ Unix(未注入时):
|
|||||||
{JIANGCHANG_DATA_ROOT}/python-runtime/.venv/bin/python3 {baseDir}/scripts/main.py health
|
{JIANGCHANG_DATA_ROOT}/python-runtime/.venv/bin/python3 {baseDir}/scripts/main.py health
|
||||||
```
|
```
|
||||||
|
|
||||||
`<shared-python>` / `JIANGCHANG_PYTHON_EXE` 通常指向 `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv`。数据根由宿主注入(见 `jiangchang_skill_core.runtime_env`)。
|
共享解释器通常位于 `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv`。数据根由宿主注入(见 `jiangchang_skill_core.runtime_env`)。
|
||||||
|
|
||||||
## Runtime 诊断(platform-kit 1.2.0+)
|
## Runtime 诊断(platform-kit 1.2.0+)
|
||||||
|
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ cmd_stats() # 只读 sync:JSON stdout,无 job_context
|
|||||||
|
|
||||||
业务技能 `SKILL.md` / `references/` 应明确(Agent 主读,勿只写在本文):
|
业务技能 `SKILL.md` / `references/` 应明确(Agent 主读,勿只写在本文):
|
||||||
|
|
||||||
1. 短查询:共享 Python(`JIANGCHANG_PYTHON_EXE`)跑 CLI;**禁止** `uv run`。
|
1. 短查询:共享 Python(PATH 上的 `python`)跑 CLI;**禁止** `uv run`。
|
||||||
2. 长任务 / RPA / async Action:必须通过宿主 **Skill Action**(`run_skill_action`);**禁止** `exec` + `process poll`。
|
2. 长任务 / RPA / async Action:必须通过宿主 **Skill Action**(`run_skill_action`);**禁止** `exec` + `process poll`。
|
||||||
3. 单条 vs 批量 action id 与参数(如 `url` / `pickCount`)。
|
3. 单条 vs 批量 action id 与参数(如 `url` / `pickCount`)。
|
||||||
4. `executionProfile: async` → 进度看**任务中心** / Skill Run Card;`sync` → 当场结果。与入口无关。
|
4. `executionProfile: async` → 进度看**任务中心** / Skill Run Card;`sync` → 当场结果。与入口无关。
|
||||||
|
|||||||
@@ -18,6 +18,23 @@
|
|||||||
|
|
||||||
禁止对长任务 `exec`/`bash` + `process poll` 干等 CLI。禁止 `uv run python` 跑技能脚本。
|
禁止对长任务 `exec`/`bash` + `process poll` 干等 CLI。禁止 `uv run python` 跑技能脚本。
|
||||||
|
|
||||||
|
## async 副作用 Action 最小组合(复制验收 checklist)
|
||||||
|
|
||||||
|
对每个「会开浏览器 / 长耗时 / 需进度或取消」的 Action,声明时建议同时满足:
|
||||||
|
|
||||||
|
1. `executionProfile: "async"`(进入任务中心)
|
||||||
|
2. 若要让 Agent 触发:`placements` **含** `agent`
|
||||||
|
3. 有可感知副作用时:提供 `confirmation.message`
|
||||||
|
4. 需要用户/Agent 入参时:简单 `inputSchema` + entrypoint 中的 `{{fieldName}}`
|
||||||
|
5. `SKILL.md`「用户意图路由表」与 `CLI.md`「Action 强制黑名单」**出现同一 action id / 命令**
|
||||||
|
|
||||||
|
默认模板 `assets/actions.json` 仅含诊断类 sync Action,**不要**为通过本 checklist 而塞假业务 Action;业务技能按需添加。完整字段见下文 Phase 1。
|
||||||
|
|
||||||
|
## 可选:域前缀 CLI(嵌套子命令)
|
||||||
|
|
||||||
|
小技能可继续扁平:`entrypoint.command = "run"`。
|
||||||
|
命令变多时,可采用**域前缀**:`command` 为域(如 `<domain>`),业务动词与参数放在 `args` 数组(如 `["<verb>", "--flag", "{{field}}"]`)。与扁平入口等价,须仍指向同一 domain service。
|
||||||
|
|
||||||
## 模板严格规范 vs 宿主向后兼容
|
## 模板严格规范 vs 宿主向后兼容
|
||||||
|
|
||||||
| 角色 | 定位 |
|
| 角色 | 定位 |
|
||||||
@@ -129,10 +146,10 @@ Action 是**可选能力**:
|
|||||||
|
|
||||||
## 执行模型
|
## 执行模型
|
||||||
|
|
||||||
宿主将 action 转为 argv,再用**共享 Python** 执行(与 Agent CLI 同一解释器契约):
|
宿主将 action 转为 argv,再用**共享 Python**(用户数据目录下 `python-runtime/.venv`)执行:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
{JIANGCHANG_PYTHON_EXE} {skill_root}/scripts/main.py <command> <args...>
|
python {skill_root}/scripts/main.py <command> <args...>
|
||||||
```
|
```
|
||||||
|
|
||||||
- `entrypoint.type` 当前只支持 `cli`
|
- `entrypoint.type` 当前只支持 `cli`
|
||||||
|
|||||||
@@ -4,27 +4,38 @@
|
|||||||
|
|
||||||
## 解释器(必读)
|
## 解释器(必读)
|
||||||
|
|
||||||
必须使用宿主**共享 Python runtime**,不要用系统 Python / 临时 venv。
|
必须使用宿主**共享 Python runtime**(`{JIANGCHANG_DATA_ROOT}/python-runtime/.venv`,已在 PATH / `VIRTUAL_ENV`)。一条命令直接跑,不要先探系统 Python。
|
||||||
|
|
||||||
| 优先级 | 写法 |
|
```bash
|
||||||
|--------|------|
|
python {baseDir}/scripts/main.py <command> …
|
||||||
| **推荐(Agent)** | `"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py <command> …` |
|
```
|
||||||
| Windows cmd | `"%JIANGCHANG_PYTHON_EXE%" {baseDir}/scripts/main.py <command> …` |
|
|
||||||
| 等价(PATH 已指向共享 venv) | `python {baseDir}/scripts/main.py <command> …` |
|
| 场景 | 写法 |
|
||||||
| 手工排查(未注入环境时) | `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv/Scripts/python.exe`(Windows)或 `…/.venv/bin/python3`(Unix) |
|
|------|------|
|
||||||
|
| **推荐(Agent)** | `python {baseDir}/scripts/main.py <command> …` |
|
||||||
|
| 手工排查(环境未注入时) | `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv/Scripts/python.exe`(Windows)或 `…/.venv/bin/python3`(Unix) |
|
||||||
|
|
||||||
**禁止**对技能脚本使用 `uv run python …`(会创建临时环境,加载不到 `jiangchang-platform-kit` / `jiangchang_skill_core`)。
|
**禁止**对技能脚本使用 `uv run python …`(会创建临时环境,加载不到 `jiangchang-platform-kit` / `jiangchang_skill_core`)。
|
||||||
**禁止** Agent 自行 `pip install` / `uv pip install` 往临时环境塞依赖。
|
**禁止** Agent 自行 `pip install` / `uv pip install` 往临时环境塞依赖。
|
||||||
|
|
||||||
下文示例里的 `python` **均指**上述共享解释器(优先写成 `$JIANGCHANG_PYTHON_EXE`)。
|
## Agent 分流(业务技能复制后必改)
|
||||||
|
|
||||||
|
用本表列出**本技能**哪些子命令可走短 CLI,哪些必须走 Skill Action。默认:短查询/只读写本地可用短 CLI;长耗时 / RPA / 需进度取消进**黑名单**。有 async/RPA 的技能:**黑名单不得为空**,且黑名单命令须映射到 `actions.json` 中的 async Action。
|
||||||
|
|
||||||
|
| 类型 | 本技能命令(自填) | Agent |
|
||||||
|
|------|--------------------|-------|
|
||||||
|
| **短 CLI 白名单** | (例)`health` / `version` / `logs` / `<your-read-or-prep>` | 可用 bash/exec + 共享 `python` |
|
||||||
|
| **Action 强制黑名单** | (例)`<your-long-or-rpa-command>` | **禁止** bash + `process poll`;必须 `run_skill_action` |
|
||||||
|
|
||||||
|
细节与 Action 清单见 [`ACTIONS.md`](ACTIONS.md)。
|
||||||
|
|
||||||
## 最小命令
|
## 最小命令
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py health
|
python {baseDir}/scripts/main.py health
|
||||||
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py config-path
|
python {baseDir}/scripts/main.py config-path
|
||||||
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py version
|
python {baseDir}/scripts/main.py version
|
||||||
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py init-db
|
python {baseDir}/scripts/main.py init-db
|
||||||
```
|
```
|
||||||
|
|
||||||
## 标准行为
|
## 标准行为
|
||||||
@@ -36,8 +47,8 @@
|
|||||||
- **`init-db`**:幂等创建/迁移本地 SQLite(含 `_jiangchang_*` 展示元数据)。成功输出一行 JSON(`ok` / `skill` / `db_path`),退出码 `0`。宿主可在技能安装或更新成功后静默调用;不要并入 `health`。
|
- **`init-db`**:幂等创建/迁移本地 SQLite(含 `_jiangchang_*` 展示元数据)。成功输出一行 JSON(`ok` / `skill` / `db_path`),退出码 `0`。宿主可在技能安装或更新成功后静默调用;不要并入 `health`。
|
||||||
- **`run` / RPA / 长任务**:CLI 仍是同一内核;**Agent 禁止**用 bash 干等长任务结束。须走宿主 Skill Action(`run_skill_action`),且该 Action 一般为 `executionProfile: "async"` → **任务中心**。长时间无 stdout **不代表卡死**;进度看任务中心 / Run Journal。
|
- **`run` / RPA / 长任务**:CLI 仍是同一内核;**Agent 禁止**用 bash 干等长任务结束。须走宿主 Skill Action(`run_skill_action`),且该 Action 一般为 `executionProfile: "async"` → **任务中心**。长时间无 stdout **不代表卡死**;进度看任务中心 / Run Journal。
|
||||||
- **排查顺序**(由快到慢):
|
- **排查顺序**(由快到慢):
|
||||||
1. `"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py logs`
|
1. `python {baseDir}/scripts/main.py logs`
|
||||||
2. `"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py log-get <log_id>`
|
2. `python {baseDir}/scripts/main.py log-get <log_id>`
|
||||||
3. 统一日志文件 `{JIANGCHANG_DATA_ROOT}/{JIANGCHANG_USER_ID}/logs/jiangchang.log`(含 `trace_id`、`task_failed` 等)
|
3. 统一日志文件 `{JIANGCHANG_DATA_ROOT}/{JIANGCHANG_USER_ID}/logs/jiangchang.log`(含 `trace_id`、`task_failed` 等)
|
||||||
4. Run Journal `{JIANGCHANG_DATA_ROOT}/.jiangchang/runs/{job_id}.jsonl`
|
4. Run Journal `{JIANGCHANG_DATA_ROOT}/.jiangchang/runs/{job_id}.jsonl`
|
||||||
5. RPA artifacts / `video_log` / 失败截图(开发规范见 `development/RPA.md`);未开启录屏时可能只有截图或日志
|
5. RPA artifacts / `video_log` / 失败截图(开发规范见 `development/RPA.md`);未开启录屏时可能只有截图或日志
|
||||||
@@ -68,30 +79,14 @@
|
|||||||
## 通用业务命令骨架
|
## 通用业务命令骨架
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py run
|
python {baseDir}/scripts/main.py run
|
||||||
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py run -t <target> -i <input_id>
|
python {baseDir}/scripts/main.py run -t <target> -i <input_id>
|
||||||
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py logs
|
python {baseDir}/scripts/main.py logs
|
||||||
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py logs --task-type demo --status failed
|
python {baseDir}/scripts/main.py logs --task-type demo --status failed
|
||||||
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py log-get <log_id>
|
python {baseDir}/scripts/main.py log-get <log_id>
|
||||||
```
|
```
|
||||||
|
|
||||||
| 命令 | 用途 | Agent 注意 |
|
| 命令 | 用途 | Agent 注意 |
|
||||||
|------|------|------------|
|
|------|------|------------|
|
||||||
| `run` | 执行一次任务(常为长任务 / RPA) | **走 `run_skill_action`**,不要 bash poll |
|
| `run` | 执行一次任务(常为长任务 / RPA) | **走 `run_skill_action`**,不要 bash poll |
|
||||||
| `logs` | 列出最近 N 条任务日志 | 可用短 CLI |
|
| `logs` / `log-get` | 查任务日志 | 可用短 CLI |
|
||||||
| `log-get` | 按 log_id 查看单条任务日志(JSON) | 可用短 CLI |
|
|
||||||
|
|
||||||
## 查询/导出类(可选)
|
|
||||||
|
|
||||||
复制后按需增加,例如:`contacts`、`contact-get`、`export` 或业务等价命令。短查询用共享 Python CLI;需挂数据管理/定时/Agent 结构化入口时再写进 `assets/actions.json`。
|
|
||||||
|
|
||||||
## 若你的技能依赖兄弟技能
|
|
||||||
|
|
||||||
使用 `service.sibling_bridge.call_sibling_json(skill_slug, args)`,不要硬编码兄弟技能名到 `sibling_bridge.py` 自身;并在 `SKILL.md` 声明 `dependencies.required`。兄弟进程继承当前解释器(须已是共享 runtime)。
|
|
||||||
|
|
||||||
## 模板约定
|
|
||||||
|
|
||||||
- 最小模板至少保留 `health` / `config-path` / `version`
|
|
||||||
- 通用业务技能建议使用 `run` / `logs` / `log-get`
|
|
||||||
- 不要再用旧模板的 `publish` / `--account-id` / `--article-id` 命名
|
|
||||||
- Skill Action 与任务中心契约见 [`ACTIONS.md`](ACTIONS.md)
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""技能标识、版本与平台公共库约束(复制后请修改 slug/version/logger)。"""
|
"""技能标识、版本与平台公共库约束(复制后请修改 slug/version/logger)。"""
|
||||||
|
|
||||||
SKILL_SLUG = "your-skill-slug"
|
SKILL_SLUG = "your-skill-slug"
|
||||||
SKILL_VERSION = "1.0.43"
|
SKILL_VERSION = "1.0.45"
|
||||||
LOG_LOGGER_NAME = "openclaw.skill.your_skill_slug"
|
LOG_LOGGER_NAME = "openclaw.skill.your_skill_slug"
|
||||||
PLATFORM_KIT_MIN_VERSION = "1.2.0"
|
PLATFORM_KIT_MIN_VERSION = "1.2.0"
|
||||||
|
|||||||
@@ -305,7 +305,8 @@ class TestDocsStandards(unittest.TestCase):
|
|||||||
def test_cli_md_requires_shared_python_not_uv_run(self) -> None:
|
def test_cli_md_requires_shared_python_not_uv_run(self) -> None:
|
||||||
text = self._read("references/CLI.md")
|
text = self._read("references/CLI.md")
|
||||||
self.assertIn("python-runtime", text)
|
self.assertIn("python-runtime", text)
|
||||||
self.assertIn("JIANGCHANG_PYTHON_EXE", text)
|
self.assertIn("python {baseDir}/scripts/main.py", text)
|
||||||
|
self.assertNotIn("JIANGCHANG_PYTHON_EXE", text)
|
||||||
self.assertIn("禁止", text)
|
self.assertIn("禁止", text)
|
||||||
self.assertIn("uv run python", text)
|
self.assertIn("uv run python", text)
|
||||||
self.assertNotRegex(
|
self.assertNotRegex(
|
||||||
@@ -314,9 +315,16 @@ class TestDocsStandards(unittest.TestCase):
|
|||||||
msg="CLI.md must not recommend uv run for skill scripts",
|
msg="CLI.md must not recommend uv run for skill scripts",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_cli_md_has_agent_routing_tables(self) -> None:
|
||||||
|
text = self._read("references/CLI.md")
|
||||||
|
self.assertIn("短 CLI 白名单", text)
|
||||||
|
self.assertIn("Action 强制黑名单", text)
|
||||||
|
self.assertIn("run_skill_action", text)
|
||||||
|
|
||||||
def test_skill_md_requires_shared_python_not_uv_run(self) -> None:
|
def test_skill_md_requires_shared_python_not_uv_run(self) -> None:
|
||||||
text = self._read("SKILL.md")
|
text = self._read("SKILL.md")
|
||||||
self.assertIn("JIANGCHANG_PYTHON_EXE", text)
|
self.assertIn("python {baseDir}/scripts/main.py", text)
|
||||||
|
self.assertNotIn("JIANGCHANG_PYTHON_EXE", text)
|
||||||
self.assertIn("uv run python", text)
|
self.assertIn("uv run python", text)
|
||||||
self.assertIn("禁止", text)
|
self.assertIn("禁止", text)
|
||||||
self.assertIn("run_skill_action", text)
|
self.assertIn("run_skill_action", text)
|
||||||
@@ -326,6 +334,31 @@ class TestDocsStandards(unittest.TestCase):
|
|||||||
msg="SKILL.md must state Task Center is independent of entry point",
|
msg="SKILL.md must state Task Center is independent of entry point",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_skill_md_has_intent_routing_table(self) -> None:
|
||||||
|
text = self._read("SKILL.md")
|
||||||
|
self.assertIn("用户意图路由表", text)
|
||||||
|
self.assertIn("用户意图", text)
|
||||||
|
self.assertIn("准备 vs 执行", text)
|
||||||
|
|
||||||
|
def test_skill_md_how_to_forbids_cli_paste(self) -> None:
|
||||||
|
text = self._read("SKILL.md")
|
||||||
|
self.assertIn("回答「怎么用", text)
|
||||||
|
self.assertIn("禁止", text)
|
||||||
|
self.assertTrue(
|
||||||
|
"粘贴" in text and "python" in text,
|
||||||
|
msg="SKILL.md must forbid pasting python CLI when answering how-to",
|
||||||
|
)
|
||||||
|
self.assertTrue(
|
||||||
|
"dir" in text or "列" in text,
|
||||||
|
msg="SKILL.md must discourage directory probing for how-to answers",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_actions_md_has_async_side_effect_checklist(self) -> None:
|
||||||
|
text = self._read("references/ACTIONS.md")
|
||||||
|
self.assertIn("最小组合", text)
|
||||||
|
self.assertIn("confirmation.message", text)
|
||||||
|
self.assertIn("用户意图路由表", text)
|
||||||
|
|
||||||
def test_actions_md_states_profile_not_entry_for_task_center(self) -> None:
|
def test_actions_md_states_profile_not_entry_for_task_center(self) -> None:
|
||||||
text = self._read("references/ACTIONS.md")
|
text = self._read("references/ACTIONS.md")
|
||||||
self.assertIn("executionProfile", text)
|
self.assertIn("executionProfile", text)
|
||||||
|
|||||||
Reference in New Issue
Block a user