Release v1.0.127: document executionProfile stream for HTML token streaming
All checks were successful
技能自动化发布 / release (push) Successful in 6s

This commit is contained in:
2026-10-25 18:22:25 +08:00
parent 8a8fa3cb0c
commit d911bd28cd
14 changed files with 141 additions and 63 deletions

View File

@@ -83,11 +83,11 @@ Action 是否提供、挂哪些 `placements`,由本技能 **入口定位表**
| 字段 / 层 | 只决定什么 | 不决定什么 |
|-----------|------------|------------|
| **`placements`** | Action **出现在哪里**(toolbar / row / batch / cron / agent / skill-detail;`row`=行级入口,壳由宿主呈现) | 不决定 sync/async,不决定点了是否弹窗,不决定行级用操作列还是右键,不决定谁能点 |
| **`placements`** | Action **出现在哪里**(toolbar / row / batch / cron / agent / skill-detail;`row`=行级入口,壳由宿主呈现) | 不决定 sync/async/stream,不决定点了是否弹窗,不决定行级用操作列还是右键,不决定谁能点 |
| **`replaces`** | **可选**:接管数据管理默认「新增 / 编辑 / 删除 / **导入**」 | 不强制;无配置时宿主仍直写**已注册数据源**(默认本地 SQLite);**import 时 UI 仍用宿主「导入数据」面板** |
| **`bind.tables`** | 数据管理里出现在**哪些业务表** | 不决定业务实现 |
| **`executionProfile`** | 宿主是**同步等待**还是**异步 Job** | 不限制可展示入口,不决定是否弹窗 |
| **`interaction`** | 可点击入口(数据管理 toolbar/row/batch、默认 CRUD 接管、未来 skill-detail)**点了怎么交互** | 不决定 sync/async;**cron 触发与 agent 忽略** |
| **`interaction`** | 可点击入口(数据管理 toolbar/row/batch、默认 CRUD 接管、未来 skill-detail)**点了怎么交互** | 不决定 sync/async/stream;**cron 触发与 agent 忽略** |
| **`hoverHint`** | **可选**:数据管理**工具栏悬停**文案 | 不决定短按钮名;不决定点下去弹不弹窗;**不回退** `description` / `confirmation.message`;省略 = 不显示悬停。当前宿主实现为顶栏技能按钮 |
| **`inputSchema.visibleWhen`** | **可选**:Action **参数表单**字段条件显隐(先选模式再出对应参数) | **不是** Data Policy L3 行态 `visibleWhen`;不决定 placements;旧宿主忽略则字段平铺全显 |
| **`hostEffects` / `steps`** | **可选**:数据管理交互跑完前后,宿主要不要刷新表 / 清选区 / 级联删等 | 不决定业务写什么;**省略 = 宿主不额外改 UI**(≥2.8.5 起不再硬编码 mutation 后刷新);cron/agent 忽略 |
@@ -115,7 +115,7 @@ Action 是否提供、挂哪些 `placements`,由本技能 **入口定位表**
| **hoverHint** | 可选字符串。数据管理**工具栏悬停**文案;与 `description` / `confirmation.message` **独立**。省略则不显示悬停,不回退。短名已够懂时不要写。需宿主已支持该字段;当前实现为顶栏技能按钮,不含宿主内置删除/刷新/新增/导入/导出 |
| **visibleWhen** | 可选。写在 **property** 上(非 action 顶层):依赖同表单其它字段值决定是否展示;隐藏字段不提交、不校验 `required`。**勿与** [`POLICY.md`](POLICY.md) L3 行态 `visibleWhen` 混淆;也**勿**用它藏「已选择」已表达的映射主键(见「选择摘要」) |
| **revealInForm** | 可选。写在 **property** 上:有「已选择」时仍强制画出该 `readOnly` 字段;省略 = 映射只读字段默认不占参数区(仍提交) |
| **executionProfile** | `"sync"` \| `"async"`(**必须显式写出**,禁止依赖缺省) |
| **executionProfile** | `"sync"` \| `"async"` \| `"stream"`(**必须显式写出**,禁止依赖缺省) |
| **interaction** | `"auto"` \| `"direct"` \| `"confirm"` \| `"form"`(可选;省略≈`auto`) |
| **interactionByPlacement** | 可选;按 placement 覆盖为 `direct`/`confirm`/`form`(不可写 `auto`) |
| **hostEffects** | 可选;`onSuccess` / `onFailure` → `reloadTable` \| `refreshCatalog` \| `clearSelection`(匠厂宿主 ≥2.8.5) |
@@ -734,20 +734,29 @@ python {skill_root}/scripts/main.py <command> <args...>
完整子命令定义见 [`scripts/cli/app.py`](../scripts/cli/app.py)。
### `executionProfile`(仅 sync / async)
### `executionProfile`(sync / async / stream)
**心智**:多数 Action 按 **sync**(短调用、不进任务中心);只有长耗时 / RPA / 需进度控制时才标 **async**。匠厂宿主若**省略**该字段,按 **sync** 处理;模板与新技能仍要求**每个 Action 显式写出** `sync` 或 `async`,禁止发明 `auto` / `background` / `deferred`,也禁止赌省略行为。
**心智**:多数 Action 按 **sync**(短调用、不进任务中心);长耗时 / RPA / 需任务中心进度·取消时标 **async**;HTML 页内 LLM / 长生成要 **token 流式**时标 **stream**(建 Job,但**不**进任务中心主路径)。匠厂宿主若**省略**该字段,按 **sync** 处理;模板与新技能仍要求**每个 Action 显式写出**三者之一,禁止发明 `auto` / `background` / `deferred`,也禁止赌省略行为。
| 值 | 宿主行为 | 任务中心 |
|----|----------|----------|
| `sync`(或省略时的宿主缺省) | 调用方等待结束,直接返回结构化结果或结构化错误;**不**创建后台 Job | 不进 |
| `async`(须显式声明) | 宿主创建后台 Job,立即返回 `jobId`;用 `emit` / `checkpoint` / `finish` 报告进度与终态 | **进入** |
| `stream`(须显式声明) | 宿主创建 Job 供页内增量;技能用 kit `stream_channel` → Journal `stream_delta`;HTML 用 `jiangchang.stream` 收 delta;终态仍走 `finish` / `finish_success` | **不进**(静默 Job;侧栏角标不因 stream 涨) |
合法组合(全部允许):`sync|async` × `toolbar|row|batch|cron|agent|skill-detail`。
合法组合(全部允许):`sync|async|stream` × `toolbar|row|batch|cron|agent|skill-detail`。
经验建议(**不是** placement 硬限制):耗时不可预测、需要暂停/停止/进度展示的任务,用 `async`;其余默认写 `sync`。
**选型(不是 placement 硬限制):**
直接执行短 CLI 时,终端自然等待进程结束。宿主通过 Action 调用同一 CLI 时,再按 `executionProfile` 决定同步等待还是建 Job。技能**不得**自行实现第二套任务中心或后台队列。
| 场景 | 建议 |
|------|------|
| `health` / `version` / 秒级查询 / 短写入 | `sync` |
| 浏览器 RPA / 长下载 / 要任务中心进度·暂停·停止 | `async` |
| 数据管理 HTML 内问答 / 长文生成,要边出边看 | `stream`(页面用 `jiangchang.stream`,勿用 `call` 假流式) |
`stream` 依赖:宿主已支持 `executionProfile: stream` + 预览桥 `jiangchang.stream`;技能侧 `jiangchang-platform-kit>=1.2.14`(`activity.stream_channel`)。未达版本时不要声明 `stream`。形状参考见 [`../assets/examples/stream-ask.action.example.json`](../assets/examples/stream-ask.action.example.json)。
直接执行短 CLI 时,终端自然等待进程结束。宿主通过 Action 调用同一 CLI 时,再按 `executionProfile` 分流。技能**不得**自行实现第二套任务中心或后台队列。
### CLI 输出契约
@@ -885,23 +894,34 @@ HINT: <next step>
### 页面调用
宿主在数据管理预览里注入 `jiangchang.call`。页面脚本把它当成普通函数调用;宿主只在**当前技能** `actions.json` 已声明的方法里查找,命中后走和表按钮同一条 Python CLI,把 CLI 打出的 JSON 交回。
宿主在数据管理预览里注入 `jiangchang.call`(以及可选的 `jiangchang.stream`)。页面脚本把它当成普通函数调用;宿主只在**当前技能** `actions.json` 已声明的方法里查找,命中后走和表按钮同一条 Python CLI。
**同步结果(`executionProfile: sync`,或只需最终 JSON):**
```javascript
const data = await jiangchang.call("方法名", { date: "2026-09-19" });
```
**页内流式(`executionProfile: stream`):** 用 `jiangchang.stream`,不要用 `call` 假装流式。技能侧在 CLI 里用 `stream_channel(...).delta(...)` 推增量;页面 `onDelta` 拼接并渲染;Promise resolve 为终态 JSON(与 `call` 相同形状)。
```javascript
const data = await jiangchang.stream("ask", { question: "..." }, {
onDelta: (piece) => { /* 追加文本并重绘 */ },
onEvent: (ev) => { /* 可选:检索中等中文提示 */ },
});
```
| 项 | 约定 |
|----|------|
| 方法名 | `actions.json` 里该条的 `id`。没声明则调用失败。不能传任意命令,也不能调别的技能 |
| 参数 | 一个 JSON 对象,字段必须落在该条 `inputSchema` 里 |
| 入口 | 可以不挂 `toolbar`。页面调用不要求表按钮。`placements` 仍不能为空(例如只挂 `agent`) |
| 成功 | CLI 退出码 0,并打印**一个** JSON 对象。页面拿到的就是这个对象 |
| 失败 | 退出码非 0,JSON 里带可读的 `message`(`type` 为 `result`、`status` 为 `failed` 时宿主会把 `message` 交给页面) |
| 范围 | 只在数据管理预览里有这个函数。用浏览器单独打开该文件时没有,页面应说明「请在数据管理中打开」 |
异步命令当场只返回任务号,不在这一节展开。写入和只读是同一种调用,差在技能声明了哪条命令。
| 入口 | 可以不挂 `toolbar`。页面调用不要求表按钮。`placements` 仍不能为空(例如只挂 `agent` / `skill-detail`) |
| 成功(call) | CLI 退出码 0,并打印**一个** JSON 对象。页面拿到的就是这个对象 |
| 成功(stream) | 过程中多次 `stream_delta`;结束后仍须结构化终态(含完整 `answer`/`message` 等),供页面定稿 |
| 失败 | 退出码非 0,JSON 里带可读的 **中文** `message`(`type` 为 `result`、`status` 为 `failed` 时宿主会把 `message` 交给页面) |
| 范围 | 只在数据管理预览里有这些函数。用浏览器单独打开该文件时没有,页面应说明「请在数据管理中打开」;缺 `jiangchang.stream` 时提示升级宿主 |
`async` 命令经 `call` 当场只返回任务号,进度看任务中心,不在这一节展开。写入和只读是同一种调用,差在技能声明了哪条命令。
### Action:`render-html`(固定 id)
宿主「重新生成」**硬编码**查找 Action id `render-html`(见 `service.html_page_service.HOST_HTML_RENDER_ACTION_ID`)。技能未提供该 id → 提示「该技能未提供生成 HTML」。