From c49fcba15735c191f4414cd65a0d35c1ea646160 Mon Sep 17 00:00:00 2001 From: chendelian <116870791@qq.com> Date: Mon, 28 Sep 2026 11:56:12 +0800 Subject: [PATCH] Docs: precipitate Action Lookup skill_cli contract (v1.0.119) --- CHANGELOG.md | 6 ++ SKILL.md | 2 +- assets/examples/README.md | 3 +- assets/examples/lookup-action.example.json | 2 +- .../lookup-skill-cli.action.example.json | 51 ++++++++++ assets/schemas/skill-actions.schema.json | 97 +++++++++++++++++-- development/ACCOUNT_MANAGER.md | 11 +++ development/CHECKLIST.md | 2 +- references/ACTIONS.md | 89 +++++++++++++++-- references/SCHEMA.md | 2 + scripts/util/constants.py | 2 +- tests/test_docs_standards.py | 21 +++- 12 files changed, 264 insertions(+), 24 deletions(-) create mode 100644 assets/examples/lookup-skill-cli.action.example.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b2821a..9cb3d76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ - 小节正文写用户能看懂的变化(新能力、修复、注意事项),避免堆砌内部实现细节 - 打 tag 前**必须**为即将发布的版本新增一节;找不到匹配小节时,本次发布不会更新 changelog 字段 +## 1.0.119 + +- 沉淀匠厂宿主 **Action Lookup 三源**:`local_sql`(同库)/ **`skill_cli`(兄弟技能 CLI JSON)** / `external_api`(预留) +- 明确列 Lookup 仍仅 `local_sql`;跨技能账号列表用 `skill_cli`,**禁止**本库镜像缓存表 +- 更新 `ACTIONS.md` / `SCHEMA.md` / `skill-actions.schema.json` / CHECKLIST A4-6 / `ACCOUNT_MANAGER.md`;新增 `lookup-skill-cli.action.example.json` + ## 1.0.118 - 沉淀浏览器 RPA 窗口/viewport 最佳实践(`RPA.md` §1.2.1):`no_viewport=True` + `--start-maximized`,禁止 `viewport=None` 与 CDP/JS 中途改窗 diff --git a/SKILL.md b/SKILL.md index dc67ce7..610f280 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,7 +1,7 @@ --- name: 技能开发模板(通用业务版) description: "OpenClaw 通用业务技能开发模板,供复制后定制新业务 skill。定制步骤见 development/DEVELOPMENT.md。" -version: 1.0.118 +version: 1.0.119 author: 深圳匠厂科技有限公司 metadata: openclaw: diff --git a/assets/examples/README.md b/assets/examples/README.md index cbf4fa3..40dd30e 100644 --- a/assets/examples/README.md +++ b/assets/examples/README.md @@ -6,7 +6,8 @@ - `skill-cell-presentation.example.json`:数据管理单元格呈现文档形状参考(见 `references/CELL_PRESENTATION.md`)。 - `skill-grid-presentation.example.json`:数据管理整行 / 整列 / 区域呈现文档形状参考(见 `references/CELL_PRESENTATION.md`)。 - `render-html.action.example.json`:HTML 报告「重新生成」Action 形状参考(固定 id `render-html`;见 `references/ACTIONS.md`)。 -- `lookup-action.example.json`:Action 内联 Lookup 形状参考(单选 + `multiple: true` 多选并列;跨表引用勿填编号;见 `references/ACTIONS.md`「跨表引用:Lookup」)。 +- `lookup-action.example.json`:Action 内联 Lookup(**local_sql**)形状参考(单选 + `multiple: true`;同库跨表勿填编号;见 `references/ACTIONS.md`「跨表引用:Lookup」)。 +- `lookup-skill-cli.action.example.json`:Action Lookup **`skill_cli`** 形状参考(打开表单时宿主调兄弟技能 CLI 抽 JSON 选项;跨技能账号列表勿再造本库缓存表;见同节)。 - `year-month-action.example.json`:Action / CRUD 账期月份字段 `display_type: year_month` 形状参考(见 `references/ACTIONS.md`「表单字段类型对照」)。 - `visible-when-action.example.json`:Action 参数字段条件显隐 `visibleWhen` 形状参考(互斥模式联动;见 `references/ACTIONS.md`「字段条件显隐」;≠ Policy L3)。 - `selection-label-column.action.example.json`:选择摘要 `bind.labelColumn` 形状参考(见 `references/ACTIONS.md`「选择摘要」)。 diff --git a/assets/examples/lookup-action.example.json b/assets/examples/lookup-action.example.json index 9757f3b..456d1ca 100644 --- a/assets/examples/lookup-action.example.json +++ b/assets/examples/lookup-action.example.json @@ -1,5 +1,5 @@ { - "_comment": "形状参考:Action 参数引用同库另一张表时用 Lookup。单选与多选同一 lookup 对象,多选只加 multiple:true。完整契约见 references/ACTIONS.md「跨表引用:Lookup」与 references/SCHEMA.md。", + "_comment": "形状参考:Action 参数引用同库另一张表时用 Lookup(local_sql)。单选与多选同一 lookup 对象,多选只加 multiple:true。跨技能列表见 lookup-skill-cli.action.example.json。完整契约见 references/ACTIONS.md「跨表引用:Lookup」。", "schemaVersion": 1, "skill": "your-skill-slug", "actions": [ diff --git a/assets/examples/lookup-skill-cli.action.example.json b/assets/examples/lookup-skill-cli.action.example.json new file mode 100644 index 0000000..766bb7e --- /dev/null +++ b/assets/examples/lookup-skill-cli.action.example.json @@ -0,0 +1,51 @@ +{ + "_comment": "形状参考:Action Lookup 的 skill_cli 源——打开表单时宿主 sync 调用兄弟技能 CLI,从 stdout JSON 抽选项。完整契约见 references/ACTIONS.md「跨表引用:Lookup」。本例对标 account-manager 遗留 list-json(stdout 为账号数组,字段 id / account_label);其它依赖技能请核对自己的命令与 JSON 形状。", + "schemaVersion": 1, + "skill": "your-skill-slug", + "actions": [ + { + "id": "publish-with-account", + "label": "发布(示例)", + "description": "演示跨技能选账号:skill_cli 调 account-manager,勿在本技能维护账号缓存表。", + "placements": ["toolbar", "cron"], + "executionProfile": "async", + "interaction": "form", + "bind": { + "tables": ["articles"], + "selectionMode": "none" + }, + "entrypoint": { + "type": "cli", + "command": "run", + "args": ["--account-id", "{{accountId}}", "--pick", "{{pickCount}}"] + }, + "inputSchema": { + "type": "object", + "required": ["pickCount"], + "properties": { + "pickCount": { + "type": "number", + "title": "发布数量", + "description": "从未发布队列领取的条数", + "default": 1, + "minimum": 1 + }, + "accountId": { + "type": "string", + "title": "发布账号", + "description": "不选则由系统自动分配;选定后本次全部使用该号。", + "display_type": "lookup", + "lookup": { + "source": "skill_cli", + "skill": "account-manager", + "command": "list-json", + "args": ["toutiao"], + "value_column": "id", + "label_column": "account_label" + } + } + } + } + } + ] +} diff --git a/assets/schemas/skill-actions.schema.json b/assets/schemas/skill-actions.schema.json index d56ca83..833a58d 100644 --- a/assets/schemas/skill-actions.schema.json +++ b/assets/schemas/skill-actions.schema.json @@ -139,7 +139,7 @@ }, "lookup": { "$ref": "#/$defs/lookupConfig", - "description": "可选。内联同库表关联 Lookup(与列 options_json lookup 对象同构)。用于当前表没有对应列时;推荐同时设 display_type=lookup。见 ACTIONS.md「跨表引用:Lookup」。" + "description": "可选。Action 内联 Lookup:local_sql(同库表)/ skill_cli(兄弟技能 CLI JSON)/ external_api(预留)。打开表单时由宿主解析。推荐同时设 display_type=lookup。见 ACTIONS.md「跨表引用:Lookup」。" }, "visibleWhen": { "description": "可选。表单字段条件显隐。宿主在数据管理/定时任务参数表单中:规则不满足则隐藏该字段、提交时省略、且不校验 required。支持 {field,equals} / {field,in:[...]},或单键简写 {collectMode:\"按关键词采集\"} / {collectMode:[\"a\",\"b\"]}。Agent/CLI 无 UI 时同样按当前 input 求值后剥离隐藏字段。", @@ -187,26 +187,35 @@ }, "lookupConfig": { "type": "object", - "required": ["ref_table", "value_column", "label_column"], "additionalProperties": false, "properties": { + "source": { + "type": "string", + "enum": ["local_sql", "skill_cli", "external_api"], + "description": "可选。显式数据源;省略时:有 ref_table→local_sql,有 skill→skill_cli,有 url→external_api。" + }, + "lookup_source": { + "type": "string", + "enum": ["local_sql", "skill_cli", "external_api"], + "description": "可选。source 别名。" + }, "ref_table": { "type": "string", "minLength": 1, "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$", - "description": "同库被引用表名" + "description": "local_sql:同库被引用表名" }, "value_column": { "type": "string", "minLength": 1, "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$", - "description": "提交值列(编号 / 外键)" + "description": "提交值列;local_sql 必填;skill_cli/external_api 默认可为 id" }, "label_column": { "type": "string", "minLength": 1, "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$", - "description": "主文案列" + "description": "主文案列;local_sql 必填;skill_cli 默认可为 display_label" }, "extra_column": { "type": "string", @@ -218,18 +227,90 @@ "type": "string", "minLength": 1, "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$", - "description": "可选。等值过滤列" + "description": "可选。local_sql 等值过滤列" }, "filter_value": { "type": ["string", "number", "boolean", "null"], "description": "可选。与 filter_column 配对的等值" }, + "skill": { + "type": "string", + "minLength": 1, + "description": "skill_cli:兄弟/依赖技能 slug" + }, + "skill_slug": { + "type": "string", + "minLength": 1, + "description": "skill_cli:skill 别名" + }, + "command": { + "type": "string", + "minLength": 1, + "description": "skill_cli:CLI 子命令(argv[0])" + }, + "cli_command": { + "type": "string", + "minLength": 1, + "description": "skill_cli:command 别名" + }, + "args": { + "oneOf": [ + { + "type": "array", + "items": { "type": "string" } + }, + { "type": "string" } + ], + "description": "skill_cli:追加 argv;数组或逗号分隔串" + }, + "items_path": { + "type": "string", + "minLength": 1, + "description": "skill_cli / external_api:stdout JSON 内选项数组点路径,默认 items" + }, + "url": { + "type": "string", + "minLength": 1, + "description": "external_api(预留):HTTP URL" + }, + "endpoint": { + "type": "string", + "minLength": 1, + "description": "external_api:url 别名" + }, + "method": { + "type": "string", + "enum": ["GET", "POST"], + "description": "external_api:HTTP 方法,默认 GET" + }, "multiple": { "type": "boolean", - "description": "可选。true=多选 Lookup(存/提交 TEXT 逗号分隔 id);省略或 false=单选(默认)。与 CRUD options_json lookup 同构。" + "description": "可选。true=多选 Lookup(存/提交 TEXT 逗号分隔 id);省略或 false=单选(默认)。" } }, - "description": "同库 FK 式 Lookup。展示:value · label;有 extra 时 value · label(extra)。multiple 时多选。宿主亦接受 camelCase 键名。" + "oneOf": [ + { + "required": ["ref_table", "value_column", "label_column"], + "description": "local_sql(同库表)" + }, + { + "anyOf": [ + { "required": ["skill", "command"] }, + { "required": ["skill", "cli_command"] }, + { "required": ["skill_slug", "command"] }, + { "required": ["skill_slug", "cli_command"] } + ], + "description": "skill_cli(兄弟技能 CLI JSON)" + }, + { + "anyOf": [ + { "required": ["url"] }, + { "required": ["endpoint"] } + ], + "description": "external_api(预留)" + } + ], + "description": "Action Lookup:local_sql / skill_cli / external_api。展示:value · label;有 extra 时 value · label(extra)。宿主亦接受 camelCase。列 Lookup 仅 local_sql,见 SCHEMA.md。" }, "inputSchema": { "type": "object", diff --git a/development/ACCOUNT_MANAGER.md b/development/ACCOUNT_MANAGER.md index 1824e15..719f8de 100644 --- a/development/ACCOUNT_MANAGER.md +++ b/development/ACCOUNT_MANAGER.md @@ -93,6 +93,17 @@ finally: ## 5. 账号选择与多账号 +### 5.0 数据管理 / 定时任务表单选账号(Action Lookup) + +若 Action 参数需要用户**点选账号**(而非手填编号): + +- 在 `actions.json` 用 **`display_type: lookup` + `lookup.source: skill_cli`**,指向 `account-manager` 能吐 JSON 选项列表的 CLI(字段名 / `items_path` 以 account-manager 文档与实际 stdout 为准)。 +- **禁止**在本技能库再建「账号选项缓存表」再 `local_sql`——易过期,且定时任务等入口容易空下拉。 +- 契约与示例见 [`references/ACTIONS.md`](../references/ACTIONS.md)「跨表引用:Lookup」、`assets/examples/lookup-skill-cli.action.example.json`。 + +表单 Lookup **只负责填参数**;真正开浏览器前的 ensure / pick / 租约仍按下文与 `account_client` 执行,二者不要混成「打开表单就 pick-web」。 + +### 5.1 运行时选择顺序 选择优先级: 1. 用户明确指定纯数字 `DEFAULT_ACCOUNT_ID`:先确认账号存在且平台一致,再通过可定位该账号的 pick 流程取得租约;不得只 `get` 后返回空租约。 diff --git a/development/CHECKLIST.md b/development/CHECKLIST.md index 6420319..ad66874 100644 --- a/development/CHECKLIST.md +++ b/development/CHECKLIST.md @@ -108,7 +108,7 @@ checklist_version: 1.0 - [ ] A4-3 **P0** 异步任务在任务中心能看到进行中与结束状态;结束有成功或失败结论 - [ ] A4-4 **P1** 进行中的进度/步骤信息对用户可理解 - [ ] A4-5 **P1** 已对外暴露的动作参数覆盖主路径关键输入(无“命令行能做、动作入口不能做”的关键缺口) -- [ ] A4-6 **P0** 若 Action 需引用同库另一张业务表(话术/平台/账号等):参数为 Lookup 下拉(内联 `lookup` 或绑列),**不是**手填内部编号;可选「自动」可留空提交 +- [ ] A4-6 **P0** 若 Action 需引用业务行(话术/平台/账号等):参数为 Lookup 下拉(**不是**手填内部编号);同库用 `local_sql`(内联或绑列),跨技能用 **`skill_cli`**(勿在本库造镜像缓存表);可选「自动」可留空提交(见 `references/ACTIONS.md`) - [ ] A4-7 **P1** 若 Action 有互斥采集/操作模式(如「按关键词 / 按主页」):用 `inputSchema` 字段级 **`visibleWhen`** 联动显隐,勿只靠 `description` 灰字说明「仅某某时填写」(见 `references/ACTIONS.md`;勿与 Policy L3 行态 `visibleWhen` 混淆) - [ ] A4-8 **P1** 行内/勾选打开的 `form`:有「已选择」时参数区不应再重复映射主键(`inputMapping` + `readOnly`);需要强制露出时用 `revealInForm`,**禁止**用 `visibleWhen` 藏主键(会不提交) - [ ] A4-9 **P1** 若同一能力既支持「勾选处理」又支持「按数量从队列领取」:用一个 Action + `bind.selectionMode: "optional"`(勿拆两个同义顶栏按钮);无勾选可点、有勾选显示「已选择」、空选数量字段用 `pickCount` 等约定名(见 `references/ACTIONS.md`) diff --git a/references/ACTIONS.md b/references/ACTIONS.md index a256671..e7c5fca 100644 --- a/references/ACTIONS.md +++ b/references/ACTIONS.md @@ -910,14 +910,37 @@ const data = await jiangchang.call("方法名", { date: "2026-09-19" }); ### 跨表引用:Lookup(宿主已支持;勿让用户填编号) -当 Action 参数要引用**同库另一张业务表**的一行(话术模板、平台、账号等)时,必须用 Lookup 下拉,**禁止**做成「请填写编号」的数字框(用户记不住内部 id,体验差)。 +当 Action 参数要引用**一行业务实体**(话术模板、平台、账号等)时,必须用 Lookup 下拉,**禁止**做成「请填写编号」的数字框(用户记不住内部 id,体验差)。 -| 场景 | 怎么配 | 说明 | -|------|--------|------| -| 当前表已有同含义列,且列上已是 CRUD lookup | `column` / `bind.columnMapping`,或属性名 = 列名 | toolbar/batch 弹窗与 create/update 抽屉都会复用该列已解析的选项 | -| 当前表没有该列(如在「潜客」表上选「话术模板」) | `display_type: "lookup"` + 字段内联 `lookup` 对象 | 打开表单时宿主按当前技能库解析选项 | +#### 两种 Lookup 入口(勿混) -内联 `lookup` 与列元数据 `options_json` **同构**(见 [`SCHEMA.md`](SCHEMA.md)「跨表引用 lookup」): +| 种类 | 声明位置 | 何时解析 | 允许的数据源 | +|------|----------|----------|--------------| +| **列 Lookup** | `_jiangchang_columns.display_type = lookup` + `options_json` 对象 | 拉表 schema 时 | **仅** `local_sql`(同库表) | +| **Action Lookup** | `inputSchema.properties.*.lookup`(推荐同时 `display_type: lookup`) | **打开动作表单** / 字段因 `visibleWhen` 变为可见时 | `local_sql` / **`skill_cli`** / `external_api`(预留) | + +固定小枚举仍用 `options_json` **数组**或 Action `enum`,**不走** Lookup 解析器。 + +#### Action Lookup 三种 source(匠厂宿主已统一) + +| `source` | 何时用 | 核心字段 | 推断(可省略显式 `source`) | +|----------|--------|----------|------------------------------| +| `local_sql` | 选项在**本技能库**另一张表 | `ref_table` + `value_column` + `label_column` | 有 `ref_table` | +| `skill_cli` | 选项在**兄弟/依赖技能**(如 account-manager 账号列表) | `skill` + `command`;可选 `args` / `items_path` / `value_column` / `label_column` | 有 `skill` / `skill_slug` | +| `external_api` | 第三方 HTTP(预留) | `url`(或 `endpoint`) | 有 `url` / `endpoint` | + +**选型:** + +| 场景 | 怎么配 | +|------|--------| +| 当前表已有同含义列,且列上已是 CRUD lookup | `column` / `bind.columnMapping`,或属性名 = 列名(复用列上已解析的 **local_sql** 选项) | +| 同库另一张表、当前表没有对应列 | Action 内联 `lookup` → `local_sql`(可只写 `ref_table`…) | +| 跨技能列表(账号、批次、其它技能业务行) | Action 内联 `lookup` → **`skill_cli`**(`skill` + `command`) | +| 固定三五个状态 | `enum` / 列 `options_json` 数组,**不要** Lookup | + +**反模式(跨技能):** 在本技能再造一张「账号选项缓存表」再 `local_sql`——选项会过期,定时任务等入口也容易空下拉。应直接 `skill_cli` 调依赖技能。 + +#### `local_sql`(同库;与列 `options_json` 对象同构) ```json { @@ -954,14 +977,56 @@ const data = await jiangchang.call("方法名", { date: "2026-09-19" }); | 字段 | 必填 | 说明 | |------|------|------| -| `ref_table` | 是 | 同库被引用表 | +| `ref_table` | 是(local_sql) | 同库被引用表 | | `value_column` | 是 | 提交给 CLI 的值(业务 id / 编号) | | `label_column` | 是 | 主文案列 | | `extra_column` | 否 | 第三展示列(任意列名,不限「备注」) | | `filter_column` / `filter_value` | 否 | 等值过滤 | | `multiple` | 否 | `true` = 多选;省略/`false` = 单选(默认) | -**下拉/选项展示(宿主统一,技能只配列):** 单选为 `{value} · {label}`;有非空 `extra_column` 时为 `{value} · {label}({extra})`。例:`2 · 通用私信-留资`、`2 · 通用私信-留资(dm)`。 +列 Lookup 字段表与加载时机见 [`SCHEMA.md`](SCHEMA.md)「跨表引用 lookup」(**仅 local_sql**)。 + +#### `skill_cli`(兄弟/依赖技能 CLI) + +打开表单时,宿主对声明的技能执行一次 **sync** CLI,从 **stdout JSON** 抽出选项列表(默认路径 `items`)。 + +```json +{ + "accountId": { + "type": "string", + "title": "发布账号", + "description": "不选则由系统自动分配。", + "display_type": "lookup", + "lookup": { + "source": "skill_cli", + "skill": "account-manager", + "command": "list-json", + "args": ["toutiao"], + "value_column": "id", + "label_column": "account_label" + } + } +} +``` + +| 字段 | 必填 | 说明 | +|------|------|------| +| `skill` / `skill_slug` | 是(二选一) | 兄弟技能 slug | +| `command` / `cli_command` | 是(二选一) | CLI 子命令(argv 第一段) | +| `args` | 否 | 追加参数;数组或逗号串 | +| `value_column` | 否 | 默认 `id` | +| `label_column` | 否 | 默认 `display_label` | +| `extra_column` | 否 | 第三展示列 | +| `items_path` | 否 | JSON 内数组点路径,默认 `items`;若 stdout 本身就是数组可省略 | +| `multiple` | 否 | 同 local_sql | + +**依赖技能侧约定:** 该命令须成功退出并打印可解析 JSON;宿主接受**顶层数组**,或对象内由 `items_path`(默认 `items`)指向的数组。元素须含 value/label 列。具体子命令与字段名以依赖技能文档为准(上例对标 account-manager 遗留 `list-json `,字段为 `id` / `account_label`;其它技能请核对 stdout)。 + +**与运行时分流:** 表单选账号用 `skill_cli` Lookup;真正开浏览器 / 占租约仍走本技能 `account_client`(见 [`development/ACCOUNT_MANAGER.md`](../development/ACCOUNT_MANAGER.md)),二者不要混成「表单打开就 pick-web」。 + +#### 展示、多选与可选空 + +**下拉/选项展示(宿主统一,技能只配列):** 单选为 `{value} · {label}`;有非空 `extra_column` 时为 `{value} · {label}({extra})`。列表/详情单元格优先 `listLabel`(不带 id 前缀)。例:`2 · 通用私信-留资`。 **多选存值与模板:** Action / CRUD 存 **`TEXT` 逗号分隔 id**(如 `1,2,5`);`{{engineIds}}` 原样替换进 CLI。多选字段在 `inputSchema` 里用 `type: "string"`(逗号串),不要用尚未稳定的 JSON array 当业务控件。 @@ -969,14 +1034,18 @@ const data = await jiangchang.call("方法名", { date: "2026-09-19" }); **可选「自动」(单选常见):** 字段不要放进 `required`;不要用 `minimum: 1` 卡死留空。宿主会省略空的可选数字参数,避免「提交的数据无效」。 +**解析失败:** 单字段 Lookup 失败时该字段选项为空,表单仍可开(可留空提交的场景不受阻)。 + **反模式(勿做):** - 标题写成「某某编号」,说明里教用户去左侧表抄 id - 用静态 `enum` 罗列会增长/变更的业务行(会过期) - 在技能里自己拼假 label 列代替宿主统一格式(难维护) - 另造 `lookup_multi` / 第二套 display_type(应只加 `multiple: true`) +- 为跨技能列表在本库维护镜像缓存表再 `local_sql`(应用 `skill_cli`) +- 在列 `options_json` 上声明 `skill_cli`(列 Lookup **只**支持同库) -形状参考:[`assets/examples/lookup-action.example.json`](../assets/examples/lookup-action.example.json)。 +形状参考:[`assets/examples/lookup-action.example.json`](../assets/examples/lookup-action.example.json)、[`assets/examples/lookup-skill-cli.action.example.json`](../assets/examples/lookup-skill-cli.action.example.json)。 ### 表单字段类型对照(须与 CRUD 对称) @@ -990,7 +1059,7 @@ Skill Action 弹窗与数据管理「新增 / 编辑」使用**同一套控件 | 数字 | `type: number` | `display_type: number` 或 INT/REAL/NUMERIC | | 开关 | `type: boolean` | `display_type: boolean` | | 枚举下拉 | `enum: [...]` | `options_json` 数组 | -| 关联下拉(Lookup) | 内联 `display_type: lookup` + `lookup`(可选 `multiple`),或绑列 | 同左;多选存 `TEXT` 逗号分隔 id | +| 关联下拉(Lookup) | 内联 `display_type: lookup` + `lookup`(`local_sql` / `skill_cli` / `external_api`;可选 `multiple`),或绑列 | 列侧仅同库 `local_sql`;多选存 `TEXT` 逗号分隔 id | | 密码 | `sensitive: true` | 列 `sensitive` | | 年份 | `display_type` 或 `format`: `year` | `display_type: year` → 存 `YYYY` | | 年月 | `display_type` 或 `format`: `year_month`(别名 `month`) | `display_type: year_month` → 存 `YYYY-MM` | diff --git a/references/SCHEMA.md b/references/SCHEMA.md index d0ca2f9..bd02e78 100644 --- a/references/SCHEMA.md +++ b/references/SCHEMA.md @@ -728,6 +728,8 @@ CREATE TABLE demo_items ( 宿主在加载表 schema 时查询 `ref_table`,把结果展开成 `{value,label}` 选项列表。 +> **列 Lookup 仅支持同库 `local_sql`。** Action 表单若要从兄弟技能拉选项(如 account-manager 账号列表),须在 `actions.json` 的 `inputSchema.lookup` 使用 **`skill_cli`**,见 [`ACTIONS.md`](ACTIONS.md)「跨表引用:Lookup」。不要在列 `options_json` 上声明 `skill` / `command`。 + **存库约定:** | 模式 | 物理列建议 | 存什么 | diff --git a/scripts/util/constants.py b/scripts/util/constants.py index ffe74c0..6d521fb 100644 --- a/scripts/util/constants.py +++ b/scripts/util/constants.py @@ -1,6 +1,6 @@ """技能标识、版本与平台公共库约束(复制后请修改 slug/version/logger)。""" SKILL_SLUG = "your-skill-slug" -SKILL_VERSION = "1.0.118" +SKILL_VERSION = "1.0.119" LOG_LOGGER_NAME = "openclaw.skill.your_skill_slug" PLATFORM_KIT_MIN_VERSION = "1.2.11" diff --git a/tests/test_docs_standards.py b/tests/test_docs_standards.py index 3aa8868..2cd7262 100644 --- a/tests/test_docs_standards.py +++ b/tests/test_docs_standards.py @@ -413,9 +413,13 @@ class TestDocsStandards(unittest.TestCase): "inputSchema 与参数表单", "表单字段类型对照(须与 CRUD 对称)", "跨表引用:Lookup", - "display_type: \"lookup\"", + '"display_type": "lookup"', "extra_column", "multiple", + "skill_cli", + "local_sql", + "external_api", + "items_path", "数据管理新增/编辑", "_jiangchang_columns.description", "datetime_unix_seconds", @@ -427,6 +431,21 @@ class TestDocsStandards(unittest.TestCase): "列筛选", ): self.assertIn(marker, text, msg=f"ACTIONS.md missing {marker!r}") + self.assertTrue( + os.path.isfile( + os.path.join(get_skill_root(), "assets/examples/lookup-skill-cli.action.example.json") + ), + msg="lookup-skill-cli.action.example.json missing", + ) + checklist = self._read("development/CHECKLIST.md") + self.assertIn("skill_cli", checklist) + account_mgr = self._read("development/ACCOUNT_MANAGER.md") + self.assertIn("skill_cli", account_mgr) + schema = self._read("references/SCHEMA.md") + self.assertIn("skill_cli", schema) + schema_json = self._read("assets/schemas/skill-actions.schema.json") + self.assertIn("skill_cli", schema_json) + self.assertIn('"skill"', schema_json) def test_actions_md_disambiguates_visible_when_from_policy(self) -> None: actions = self._read("references/ACTIONS.md")