@mokuyoaxis/dsh-iris 0.2.6 → 0.3.0-alpha.1

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 (177) hide show
  1. package/CHANGELOG.md +103 -1
  2. package/README.en.md +104 -304
  3. package/README.md +101 -302
  4. package/bin/dsh-iris.js +446 -64
  5. package/docs/AGENT_CORE_QUICKSTART.md +64 -0
  6. package/docs/AGENT_QUICKSTART.md +7 -5
  7. package/docs/ARCHITECTURE.md +20 -4
  8. package/docs/AUDIO_FLOWS.md +71 -0
  9. package/docs/CLI_MANAGEMENT.md +1 -1
  10. package/docs/CONTACT_SHEET.md +62 -0
  11. package/docs/CORE_CONNECTIONS.md +99 -0
  12. package/docs/CORE_QUICKSTART.md +108 -0
  13. package/docs/CORE_RUNTIME_CONTRACT.md +41 -5
  14. package/docs/CORE_SERVICE.md +97 -0
  15. package/docs/CORE_SKILLS.md +94 -0
  16. package/docs/DSH_COMPATIBILITY.md +14 -4
  17. package/docs/DSH_CORE_MIGRATION.md +4 -2
  18. package/docs/DSH_PROVIDER_CONNECTIONS.md +1 -1
  19. package/docs/DSH_RC2_ADAPTATION.md +1 -1
  20. package/docs/DSH_RUNTIME.md +40 -0
  21. package/docs/FUNCTION_MODEL_POOLS.md +1 -1
  22. package/docs/HEADLESS_CLI.md +12 -4
  23. package/docs/HOST_DOCTOR.md +13 -1
  24. package/docs/IMAGE_FLOW.md +75 -0
  25. package/docs/IMAGE_GENERATION.md +127 -0
  26. package/docs/LOCAL_API.md +62 -0
  27. package/docs/LOCAL_API_CONTRACT.md +140 -0
  28. package/docs/LOCAL_CREATION.md +56 -0
  29. package/docs/LOCAL_OPERATIONS.md +46 -0
  30. package/docs/LOCAL_SELECTION.md +57 -0
  31. package/docs/LOCAL_WEB.md +201 -0
  32. package/docs/MCP.md +191 -0
  33. package/docs/MUSIC.md +2 -0
  34. package/docs/PANEL_EXTENSIONS.md +64 -0
  35. package/docs/PLUGINS.md +189 -0
  36. package/docs/PLUGIN_STARTUP.md +100 -0
  37. package/docs/PROVIDER_ADAPTER_CONTRACT.md +1 -1
  38. package/docs/PROVIDER_EXTENSIONS.md +78 -0
  39. package/docs/PROVIDER_HEALTH.md +4 -2
  40. package/docs/PROVIDER_SETTINGS.md +85 -0
  41. package/docs/PROVIDER_SUBMISSION_CONTRACT.md +6 -0
  42. package/docs/ROADMAP.md +28 -6
  43. package/docs/SECURITY.md +9 -1
  44. package/docs/SYNC_DELIVERY_RECOVERY.md +2 -0
  45. package/docs/VISION_CLI.md +2 -2
  46. package/docs/WEB_PROTOTYPE.md +62 -0
  47. package/docs/WEB_RECOVERY.md +46 -0
  48. package/docs/WORKBENCH_LOGIN.md +63 -0
  49. package/docs/assets/screenshots/core-connections-preview.webp +0 -0
  50. package/docs/assets/screenshots/core-model-pools-preview.webp +0 -0
  51. package/docs/assets/screenshots/core-overview-preview.webp +0 -0
  52. package/docs/assets/screenshots/core-spectrum-preview.webp +0 -0
  53. package/docs/assets/screenshots/core-studio-dark-preview.webp +0 -0
  54. package/docs/assets/screenshots/core-studio-mobile-preview.webp +0 -0
  55. package/docs/assets/screenshots/core-studio-preview.webp +0 -0
  56. package/docs/releases/0.2.7.md +62 -0
  57. package/docs/releases/0.3.0-alpha.1.md +51 -0
  58. package/docs/screenshots.md +41 -1
  59. package/lib/actions.js +132 -70
  60. package/lib/adapters.js +20 -11
  61. package/lib/api.js +38 -38
  62. package/lib/application-runtime.js +213 -0
  63. package/lib/audio-flow-input.js +37 -0
  64. package/lib/client.js +434 -55
  65. package/lib/comfyui-adapter.js +94 -0
  66. package/lib/comfyui-client.js +51 -0
  67. package/lib/comfyui-inspection.js +73 -0
  68. package/lib/comfyui-workflow.js +94 -0
  69. package/lib/config.js +36 -1
  70. package/lib/configured-image-runtime.js +50 -0
  71. package/lib/connection-skill.js +89 -0
  72. package/lib/connection-template.js +23 -0
  73. package/lib/core-artifact-store.js +21 -2
  74. package/lib/core-bridge-selection.js +31 -0
  75. package/lib/core-bridge-tools.js +83 -0
  76. package/lib/core-capability-catalog.js +182 -0
  77. package/lib/core-connection-diagnostics.js +49 -0
  78. package/lib/core-connection-store.js +277 -0
  79. package/lib/core-connections.js +225 -0
  80. package/lib/core-maintenance.js +31 -2
  81. package/lib/core-runtime.js +20 -0
  82. package/lib/core-service-client.js +170 -0
  83. package/lib/core-tasks.js +84 -13
  84. package/lib/core-writer-lease.js +16 -0
  85. package/lib/creation-request-store.js +133 -0
  86. package/lib/doctor.js +12 -1
  87. package/lib/dsh-core-adapter.js +666 -572
  88. package/lib/dsh-host-adapter.js +8 -2
  89. package/lib/dsh-service-bridge.js +66 -0
  90. package/lib/execution-ownership.js +43 -0
  91. package/lib/flow-store.js +290 -0
  92. package/lib/generation-input.js +10 -1
  93. package/lib/headless-vision.js +7 -7
  94. package/lib/image-edit-input.js +1 -1
  95. package/lib/image-flow.js +232 -0
  96. package/lib/index.js +94 -68
  97. package/lib/local-api-projection.js +32 -0
  98. package/lib/local-api-token-directory.js +31 -0
  99. package/lib/local-api.js +1083 -0
  100. package/lib/local-creation.js +150 -0
  101. package/lib/local-operations.js +36 -0
  102. package/lib/local-request-root.js +86 -0
  103. package/lib/local-web-assets.js +37 -0
  104. package/lib/mcp-bridge.js +58 -0
  105. package/lib/mcp-check.js +26 -0
  106. package/lib/mcp-config.js +42 -0
  107. package/lib/mcp-delivery.js +46 -0
  108. package/lib/mcp-http.js +101 -0
  109. package/lib/mcp-server.js +47 -0
  110. package/lib/model-directory-service.js +16 -6
  111. package/lib/model-directory.js +3 -3
  112. package/lib/models.js +2 -2
  113. package/lib/music-transport.js +2 -1
  114. package/lib/operation-runner.js +236 -0
  115. package/lib/operation-store.js +216 -0
  116. package/lib/panel-extension.js +36 -0
  117. package/lib/plugin-contract.js +194 -0
  118. package/lib/plugin-execution.js +51 -0
  119. package/lib/plugin-launch.js +86 -0
  120. package/lib/plugin-operation-store.js +101 -0
  121. package/lib/plugin-operations.js +28 -0
  122. package/lib/plugin-registry.js +109 -0
  123. package/lib/plugin-selection.js +15 -0
  124. package/lib/plugin-source-image.js +5 -0
  125. package/lib/plugin-web-assets.js +54 -0
  126. package/lib/plugins.d.ts +288 -0
  127. package/lib/plugins.js +58 -0
  128. package/lib/private-storage.js +12 -0
  129. package/lib/provider-adapter.js +5 -1
  130. package/lib/provider-adapters.js +56 -18
  131. package/lib/provider-catalog.js +40 -29
  132. package/lib/provider-config-service.js +105 -23
  133. package/lib/provider-diagnostics.js +56 -0
  134. package/lib/provider-extensions.js +29 -0
  135. package/lib/provider-health.js +8 -1
  136. package/lib/provider-monitor.js +79 -0
  137. package/lib/provider-protocol.js +70 -20
  138. package/lib/provider-registry.js +118 -0
  139. package/lib/provider-response.js +28 -0
  140. package/lib/provider-settings.js +134 -0
  141. package/lib/provider-task-runner.js +40 -7
  142. package/lib/render-address.js +35 -0
  143. package/lib/render.js +52 -13
  144. package/lib/skill-installation.js +211 -0
  145. package/lib/vision-model-routing.js +3 -0
  146. package/lib/web/app.js +642 -0
  147. package/lib/web/appearance.js +111 -0
  148. package/lib/web/comfyui.js +146 -0
  149. package/lib/web/connections.js +377 -0
  150. package/lib/web/creation.js +355 -0
  151. package/lib/web/flow-view.js +33 -0
  152. package/lib/web/gallery.js +132 -0
  153. package/lib/web/index.html +291 -0
  154. package/lib/web/media-client.js +204 -0
  155. package/lib/web/plugin-panel.js +221 -0
  156. package/lib/web/plugin-surface.css +17 -0
  157. package/lib/web/providers.js +492 -0
  158. package/lib/web/recovery.js +105 -0
  159. package/lib/web/startup.js +18 -0
  160. package/lib/web/styles.css +518 -0
  161. package/lib/web/transport.js +96 -0
  162. package/lib/web/workbench-login.js +165 -0
  163. package/lib/workbench-artifacts.js +1 -2
  164. package/lib/workbench-auth-cli.js +47 -0
  165. package/lib/workbench-auth.js +200 -0
  166. package/lib/workbench-management.js +8 -9
  167. package/package.json +22 -6
  168. package/plugins/contact-sheet/index.d.mts +4 -0
  169. package/plugins/contact-sheet/index.mjs +33 -0
  170. package/plugins/contact-sheet/web/board.css +14 -0
  171. package/plugins/contact-sheet/web/board.mjs +93 -0
  172. package/skills/iris-core/SKILL.md +44 -0
  173. package/skills/iris-core/agents/openai.yaml +4 -0
  174. package/skills/iris-core/references/cli.md +95 -0
  175. package/skills/iris-core/references/comfyui.md +69 -0
  176. package/skills/iris-core/references/tasks.md +60 -0
  177. package/user_guide.md +19 -9
@@ -0,0 +1,75 @@
1
+ # 固定图片流程(0.2.7)
2
+
3
+ 0.3 alpha源码另提供 [image-generate/v0 与 ComfyUI 入口](IMAGE_GENERATION.md),需显式的新 v2 执行根;下文保留 0.2.7 的原固定编辑流程,旧根不自动迁移。
4
+
5
+ 0.3 alpha源码可通过 [Core 执行服务](CORE_SERVICE.md)、正式 MCP 和 DSH 可选共享 Flow 连接消费同一固定流程,另有显式启用的 [owner 持久选择 API](LOCAL_SELECTION.md)。真实 [Core 工作台](LOCAL_WEB.md)已接入创作、执行与选择;本文保留已发布 0.2.7 的 CLI 使用方式。
6
+
7
+ 0.2.7 提供 `image-edit/v0`:导入原图 → 指定模型改图 → 本地像素比较 → 选择原图或新版 → 导出。真实执行入口是独立 CLI 和内部应用运行时,尚未接入 DSH 工作台或真实独立 Web;[Web Demo](WEB_PROTOTYPE.md)仅说明面向 0.3.0 的交互方向。本流程从 npm 0.2.7 起随包分发。
8
+
9
+ 0.2.7 另提供 [默认只读 API](LOCAL_API.md)查看已有流程与图片;新空专用根可主动启用 [本地上传与创建](LOCAL_CREATION.md)。这些 HTTP 入口不执行/继续流程,也不把 CLI 的导出路径暴露给浏览器。
10
+
11
+ ## 初始化与创建
12
+
13
+ 先选择一个新的、空的专用 Core 数据根。`flow init` 不迁移现有 DSH/CLI 数据根;初始化后才向它导入图片。已有有效流程根上再次执行 init 不改变声明。
14
+
15
+ ```bash
16
+ dsh-iris flow init --data-root /absolute/path/flow-core
17
+ dsh-iris artifact import --data-root /absolute/path/flow-core --input '{"image_path":"/absolute/path/source.png"}'
18
+ ```
19
+
20
+ 使用返回的 Artifact ID 编写输入文件,例如:
21
+
22
+ ```json
23
+ {
24
+ "source_artifact_id": "artifact_<返回的24位十六进制ID>",
25
+ "model_ref": "providerId::modelId",
26
+ "prompt": "将背景改成绿色,保留主体",
27
+ "n": 1
28
+ }
29
+ ```
30
+
31
+ 替换示例中的 ID 与模型,保存为 `/absolute/path/edit.json`,再创建流程:
32
+
33
+ ```bash
34
+ dsh-iris flow create --data-root /absolute/path/flow-core --provider-config /absolute/path/providers.json --input-file /absolute/path/edit.json
35
+ dsh-iris flow list --data-root /absolute/path/flow-core
36
+ ```
37
+
38
+ create 只验证原图、模型允许范围与改图协议,保存输入和预留身份,**不提交生成请求**。首版要求明确模型、单张结果 `n=1`,可选 `size`;支持现有聊天图片和原生 Qwen 改图协议。Provider 配置仍按 [功能池](FUNCTION_MODEL_POOLS.md)和 [CLI 配置](HEADLESS_CLI.md)处理。
39
+
40
+ ## 执行、选择与导出
41
+
42
+ 将下方引号内的占位 ID 替换为 create 返回的 Run ID。首次 continue 可能调用指定模型并产生费用:
43
+
44
+ ```bash
45
+ dsh-iris flow continue 'run_<24hex>' --data-root /absolute/path/flow-core --provider-config /absolute/path/providers.json
46
+ dsh-iris flow inspect 'run_<24hex>' --data-root /absolute/path/flow-core
47
+ dsh-iris flow select 'run_<24hex>' --data-root /absolute/path/flow-core --input '{"artifact_id":"artifact_<原图或新版ID>"}'
48
+ dsh-iris flow export 'run_<24hex>' --data-root /absolute/path/flow-core --output /absolute/path/selected.png
49
+ ```
50
+
51
+ continue 对同一 Run 复用预留 Task;已有 Attempt 后不重新 submit,也不按新模型池顺序改绑。已受理任务每次至多观察一次,生成成功但交付中断时恢复原缓存或原远端任务。完成结果不需要 Provider 配置即可继续、查看、选择和导出。连接端点/协议漂移、输入摘要不符或作品缺失会拒绝相应操作;API Key 轮换遵守原 Task 配置规则。
52
+
53
+ | `status` | 含义 |
54
+ |---|---|
55
+ | `not_started` | 尚未提交;再次 continue 可执行首次生成 |
56
+ | `running` | 原任务仍在执行,后续 continue 仅观察原任务 |
57
+ | `needs_attention` | 未知受理、失败、取消或缺少可靠完成事实;不会自动重提 |
58
+ | `delivery_failed` | 生成已成功,本地交付尚未完成 |
59
+ | `needs_comparison` | 原 Task 已交付,流程的本地比较尚未完成 |
60
+ | `awaiting_selection` | 改图和比较完成,等待明确选择 |
61
+ | `selected` | 已选择原图或新版,尚不代表已导出 |
62
+
63
+ 像素比较只描述差异,不证明修改符合创作要求。选择仅接受本流程的原图或新版;重复选择相同作品不改记录。导出路径只用于当次调用,不写入 Run,不自动恢复外部路径写入,也不覆盖现有文件。需要重新生成时应明确新建 Run,原 Run 不自动采用 `task retry` 创建的新任务。
64
+
65
+ ## 持久化与恢复
66
+
67
+ 流程根使用 `flow-store/v0/root.json` 声明,Run 保存在 `flow-store/v0/runs/`。它保存版本、源图 SHA256、创作输入、模型/连接绑定摘要、预留 Task/比较作品 ID、交付引用和选择。**提示词是私有 Run 输入**,`flow inspect` 会返回它,list 只返回摘要;Task 继续不保存提示词、Key、端点或宿主路径。POSIX 下目录/文件沿用 0700/0600;Windows 文件 mode 不等于 ACL。
68
+
69
+ Task 仍使用 schemaVersion 0 / semanticsVersion 2,新增可选 `flowBinding` 记录 Run、步骤和输入摘要。旧 Task 无需改写。步骤意图先落盘,Task 排他建立后再记录检查点,Attempt 必须先于 Provider 调用。已有 Attempt 但没有可靠响应时,即使 `acceptance=none`,也不能推断请求尚未发送。完整缓存可以接回原结果;缺少证据时保留未知。
70
+
71
+ 比较图使用预留 ID、时间和内容证据重入;不会因 Run 完成标记未写入就另建随机比较作品。进程异常留下的写者租约仍按 [显式恢复流程](HEADLESS_CLI.md#异常退出后的写者租约)处理,不抢锁或手动删除租约。
72
+
73
+ Run 引用的原图、结果、比较作品和 Task 均进入现有删除/清理保护;Run 或绑定损坏时管理操作停止。首版不提供 Run 删除、自动 GC 或完整通用 Recipe 编辑器。流程根**不能与旧版 writer 混用或降级写入**:旧版能读 Task 不代表其清理器认识 Run 引用;回退使用原有数据根或只读导出。
74
+
75
+ 当前恢复证据来自隔离根中的进程强杀、受控 Provider 与本地 HTTP。它不保证真实 Provider 的通用 exactly-once、断电持久性、网络/Android 共享文件系统支持或所有平台的实际运行;基础目录应放在支持现有 writer 租约的私有文件系统中。
@@ -0,0 +1,127 @@
1
+ # Core 文生图与 ComfyUI(0.3 alpha)
2
+
3
+ 当前源码支持固定 `image-generate/v0`:无需原图,使用明确的 `provider::model` 和提示词生成一张图片。它与改图共用 Run、Operation、Task、作品、原 Key 恢复和有限执行;生成结果无需像素比较,明确选择后可下载或用作下一次改图的原图。**npm 0.2.7 不包含本页的新流程、页面或 MCP 入口。**
4
+
5
+ ## 新建支持文生图的工作区
6
+
7
+ 在新的专用位置初始化 v2 执行根;不要转换现有数据根:
8
+
9
+ ```bash
10
+ node bin/dsh-iris.js flow init --data-root /absolute/new-image-core
11
+ node bin/dsh-iris.js execution init --data-root /absolute/new-image-core --image-generation
12
+ node bin/dsh-iris.js web serve --data-root /absolute/new-image-core \
13
+ --provider-config /absolute/private-providers.json \
14
+ --token-file /absolute/new-owner-token \
15
+ --allow-execution --allow-selection --allow-provider-management
16
+ ```
17
+
18
+ v2 可同时保存文生图和改图。原 v0/v1 根继续支持原编辑行为,不自动升级、迁移或开启新功能;旧写者拒绝 v2。连接凭据与恢复身份仍绑定各自的 rootId。
19
+
20
+ 在创作设置选择“生成图片”,明确选择模型、填写画面描述,再点击“开始生成”。创建和执行各使用独立 Key,双击合并;创建结果未知时先找回原 Run,不自动开始生成。修改已有输入需新建流程。
21
+
22
+ CLI 也可创建同一流程,创建本身不调用模型:
23
+
24
+ ```bash
25
+ node bin/dsh-iris.js flow create --data-root /absolute/new-image-core \
26
+ --provider-config /absolute/private-providers.json \
27
+ --input '{"model_ref":"my-provider::my-model","prompt":"A violet iris in soft morning light","n":1}'
28
+ node bin/dsh-iris.js flow continue run_REPLACE_WITH_RETURNED_ID \
29
+ --data-root /absolute/new-image-core --provider-config /absolute/private-providers.json
30
+ ```
31
+
32
+ `run_REPLACE_WITH_RETURNED_ID` 须替换为创建实际返回的 Run ID。后续继续、选择和导出见 [图片流程](IMAGE_FLOW.md)。已有 Task 有 Attempt 时只处理原任务;受理未知不重新提交。异步任务每次“查看原任务”只观察一次;“停止等待”不等于远端取消或停止计费。
33
+
34
+ ## ComfyUI 入口
35
+
36
+ 需要你已运行的 ComfyUI HTTP 服务和一份能在该服务上执行的 API 工作流。Iris 不安装 ComfyUI、模型或自定义节点,不启动 GPU 服务;独立网页不嵌入节点编辑器。
37
+
38
+ 1. 供应商页选择“ComfyUI · 已有服务”,填写 Iris Core 能访问的地址;本机通常是 `http://127.0.0.1:8188`。远程 Core 的这个地址指向 Core 所在机器。原生 ComfyUI 可选无需认证,受保护的反向代理可使用 API Key/Bearer;不提供 Comfy Cloud/OAuth 登录适配。
39
+ 2. 在 ComfyUI 使用 **Export (API)** 导出。展开“ComfyUI 工作流”,导入 API 图或完整 Iris v0/v1 模板,最多 40 KiB、256 个节点;参数声明也计入模板大小。普通画布格式不能直接执行。
40
+ 3. 填写稳定的工作流名称,明确正向提示词节点(替换其 `inputs.text`)、图片输出节点和可选尺寸节点(替换 `inputs.width/height`)。展开“开放参数”,勾选已有标量输入、命名并选择整数/小数类型;右侧设置区提供使用时的表单预览。完整 v1 模板保留原参数 ID、类型、范围、选项和顺序。
41
+ 4. 已保存、启用的 ComfyUI 连接可做“只读检查”,不保存草稿、不创建 Task、不入队。点击“加入模型草稿”,同名替换需确认,再“保存设置”。连接地址或密钥尚有编辑时,先保存连接,再重新导入模板检查。
42
+ 5. 创作页选择此工作流,填写提示词及开放参数。LoRA 槽位分别显示模型与 CLIP 权重,更多参数默认折叠;“检查参数并读取选项”取得当前服务的候选,超出 256 项时保留手填。检查不会替换当前参数;修改输入或切换工作流使旧检查结论失效。
43
+ 6. “开始生成”才提交一次工作流,之后明确查看原任务并取回图片。没有绑定尺寸节点时使用模板尺寸,页面禁用尺寸覆盖。首次 v1 提交前后端重新检查实际参数;服务缺少节点/模型或执行失败时,请结合原 ComfyUI 任务检查。
44
+
45
+ “打开 ComfyUI”在浏览器新标签打开所填服务地址;它不为远程服务建立代理或转发。工作流可调用节点自己的外部服务,应只导入你了解的流程。原始图配置保存在私有 Provider 文件及其备份中,普通设置读取只显示摘要和绑定,不回显图正文;不要将账号凭据写入图节点。
46
+
47
+ 参数表单按模板声明显示,不添加 LoRA 节点或安装模型;多个 LoRA 需要原图已有多个槽位。只读检查需 owner 与 `--allow-provider-management`,仅执行连接仍可填写已开放的参数并按原权限生成。生成点击时固定本次参数快照,新 v1 表单保存全部开放参数的取值;草稿不写入 sessionStorage,恢复表仍只保存请求身份。结果的“流程详情”显示 Run 中实际记录的参数 ID 与值,不用最新模板默认值补写历史;未记录的输入仍依赖原模板。真实 GPU 出图、节点级进度和推理预览尚未验收或接入。
48
+
49
+ 运行时使用 `/prompt`、`/history/{prompt_id}`、`/queue` 和 `/view`。历史和队列都找不到的原任务标记未知,不重新排队。取图只接受原服务的图片接口,不读取 ComfyUI 机器上的任意文件路径。工作流摘要进入原 Task 连接绑定;更改工作流后旧任务不会悄悄改用新图恢复。首版不调用共享服务的全局 `/interrupt`。
50
+
51
+ 协议依据:[官方路由](https://docs.comfy.org/development/comfyui-server/comms_routes)、[API 工作流示例](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples/basic_api_example.py)、[原任务与取图示例](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples/websockets_api_example.py)。Iris 仅接入 HTTP 协议,不随包分发 ComfyUI 或其运行依赖。
52
+
53
+ 2026-10-26 已在线复核官网及官方源码提交 [`fe298e4`](https://github.com/Comfy-Org/ComfyUI/tree/fe298e4e20f1ff26d30e8639267bbd0b57811390)。以下是当前适配边界,源码核对与受控测试不代替真实 GPU 验收:
54
+
55
+ - [`POST /prompt`](https://github.com/Comfy-Org/ComfyUI/blob/fe298e4e20f1ff26d30e8639267bbd0b57811390/server.py#L1164) 会验证并入队,不是只读验证接口。Iris 的只读检查只 GET 节点定义;实际生成才提交一次,并以返回的任务 ID 查询历史/队列,取图沿用官方的文件名、子目录和类型参数。
56
+ - [LoRA 官方定义](https://github.com/Comfy-Org/ComfyUI/blob/fe298e4e20f1ff26d30e8639267bbd0b57811390/nodes.py#L714)分别提供模型与 CLIP 权重,多个 LoRA 依靠已有节点串联。候选来自服务端节点定义;Iris 不直接扫描模型目录。
57
+ - 官方当前支持[带任务 ID 的中断](https://github.com/Comfy-Org/ComfyUI/blob/fe298e4e20f1ff26d30e8639267bbd0b57811390/server.py#L1262),但 Iris 首版尚未接入,仍不发送远端 `/interrupt`;停止等待不表示远端已取消。
58
+ - 官方[采样器种子](https://github.com/Comfy-Org/ComfyUI/blob/fe298e4e20f1ff26d30e8639267bbd0b57811390/nodes.py#L1606)支持 unsigned 64-bit;Iris 的整数输入限于 JavaScript 安全范围。API 图中直接填写的越界整数也会拒绝,请将种子调至 `0`–`9007199254740991` 后重新导出,避免静默舍入。
59
+ - Iris 提交整份图,只导入所选输出节点的一张图片;其他输出节点或图内外部服务仍可能执行。[SaveImage](https://github.com/Comfy-Org/ComfyUI/blob/fe298e4e20f1ff26d30e8639267bbd0b57811390/nodes.py#L1669)默认可把图与提示词写入 PNG 元数据,Iris 保留原字节,不自动移除这些元数据。
60
+
61
+ ## DSH 工作台入口(0.3 alpha)
62
+
63
+ 当前源码另在原 DSH 工作台中提供专用区域;**npm 0.2.7 尚不包含以下 ComfyUI 界面**。它使用 DSH 侧原配置和 Core Task,不要求另起独立 Core 服务或创建 v2 Flow 根,也不自动接管独立 Core 面板的配置。
64
+
65
+ 1. “设置 → Iris 工作台 → + 添加供应商”,选择“ComfyUI · 已有服务”。默认地址为 `http://127.0.0.1:8188`,按 DSH 进程可访问的地址修改;可选无需认证或 Bearer。保存连接不探测服务、不生成图片。
66
+ 2. 在该供应商中导入原始 **Export (API)** 图或完整 Iris v0/v1 模板。明确正向提示词、图片输出和可选尺寸节点;展开“公开参数”,勾选已有标量输入。LoRA 名称、模型权重、CLIP 权重可以分别公开;节点连接不可勾选。普通画布 JSON 不支持。
67
+ 3. “只读检查”仅查询已保存服务的节点定义,不保存草稿、不创建 Task、不入队。修正问题后点击“保存工作流”;同名替换另行确认,原摘要不符时拒绝覆盖。保留原 JSON,后续修改模板需再次导入。
68
+ 4. 可明确勾选“保存时将图片功能设为自动池”;首次空配置默认勾选,已有功能池保持原选择。未启用时,到“功能池与调用方式”纳入此工作流。
69
+ 5. 展开“创作工具 → 画图”,选择具体工作流,再展开默认收起的“工作流参数”。“只读检查并读取选项”可取得服务当前公布的 LoRA、采样器等候选;超出 256 项时可手填名称。多个 LoRA 依赖原图已有节点,不会自动插入或安装模型。
70
+ 6. 点击“生成图片”才创建生成 Task。请求前重新核对模板摘要;v1 模板还检查实际参数的节点定义。参数改变会清除旧检查结论,切换模型会清空本卡片的参数覆盖。提交结果未知时先查任务列表,不自动重试或改用另一模型。
71
+
72
+ 地址与认证收在默认折叠的“连接设置”,外观跟随 DSH;进入 ComfyUI 区域有一次短暂鸢尾扫光,遵循减少动画设置。工作台和泡泡常用卡片复用同一画图控件。能力健康中的 ComfyUI 实测转到画图表单,实际生成保留受理/观察/作品事实;静态检查通过不表示真实 GPU 出图通过。
73
+
74
+ ## ComfyUI 参数模板与只读检查(后端)
75
+
76
+ 当前后端支持 `comfyWorkflow.version: 1`,在已有 `graph`、`promptNode`、`outputNode` 和可选 `sizeNode` 上增加明确的 `parameters`。原 v0 模板保持;Core 与 DSH 工作台均支持导入、声明及填写参数。没有开放参数时仍保存 v0 固定模板;v1 完整模板也可通过 CLI `providers add/set` 的 `models[].comfyWorkflow` 保存。
77
+
78
+ 例如,已有图中的 `10` 是 LoRA 节点、`7` 是负面提示词节点、`3` 是采样器,可声明下列参数。此片段只是参数声明,须与原 API 图和输入输出绑定一起保存:
79
+
80
+ ```json
81
+ {
82
+ "parameters": [
83
+ {"id":"lora","label":"LoRA","node":"10","input":"lora_name","type":"string"},
84
+ {"id":"model_weight","node":"10","input":"strength_model","type":"number","min":-2,"max":2},
85
+ {"id":"clip_weight","node":"10","input":"strength_clip","type":"number","min":-2,"max":2},
86
+ {"id":"negative","node":"7","input":"text","type":"string"},
87
+ {"id":"seed","node":"3","input":"seed","type":"integer","min":0},
88
+ {"id":"steps","node":"3","input":"steps","type":"integer","min":1,"max":100}
89
+ ]
90
+ }
91
+ ```
92
+
93
+ 最多开放 32 个已有标量输入,类型为 `string`、`integer`、`number`、`boolean`,可加数值 `min/max` 或有限 `choices`;默认值来自图,且必须符合声明。参数 ID 和目标不能重复,不能覆盖已绑定的正向提示词或尺寸,也不能替换节点连接。LoRA 模型权重和 CLIP 权重分别声明;多个 LoRA 可使用图中不同节点的不同槽位。整数限制在 JavaScript 安全整数范围,不支持完整 unsigned 64-bit seed。
94
+
95
+ 先做一次只读检查,可提供准备使用的参数:
96
+
97
+ ```bash
98
+ node bin/dsh-iris.js models workflow-check comfy::portrait \
99
+ --provider-config /absolute/private-providers.json \
100
+ --input '{"workflow_parameters":{"lora":"portrait.safetensors","model_weight":0.7,"clip_weight":0.4,"seed":42}}'
101
+ ```
102
+
103
+ 检查只 GET 官方 `/object_info/{node_class}`,每类查询一次,整体默认限时 15 秒。它报告缺失节点、必需输入、可判断的连接引用/类型、标量范围和枚举,包括节点公布的 checkpoint/LoRA 文件名。结果的 `ok` 仅表示这些静态条件满足;不执行节点、自定义校验或推理,不验证模型家族、显存与外部服务,不证明真实出图成功。参数的 `value` 是本次检查值;模型目录中的 `default` 仍是原模板默认值。候选参数选项最多返回 256 个,超出会标记截断;不扫描磁盘或安装模型。`ok:false` 的业务检查结果仍作为 JSON 正常返回,应读取 `ok/issues`。
104
+
105
+ v1 模板在每次首次提交前重新检查实际参数与尺寸,检查失败或检查网络中断属于未受理,不发送 `/prompt`;真正 POST 入队后的响应丢失仍保守记为受理未知。v0 固定模板沿用原提交行为,可主动运行上述只读检查。
106
+
107
+ 用 CLI 创建带参数的持久流程:
108
+
109
+ ```bash
110
+ node bin/dsh-iris.js flow create --data-root /absolute/new-image-core \
111
+ --provider-config /absolute/private-providers.json \
112
+ --input '{"model_ref":"comfy::portrait","prompt":"An iris portrait","n":1,"workflow_parameters":{"lora":"portrait.safetensors","model_weight":0.7,"clip_weight":0.4,"negative":"","seed":42}}'
113
+ ```
114
+
115
+ HTTP `POST /api/v0/generations` 和 MCP `iris_core_create_generation` 使用可选 `workflowParameters` 对象;`iris_core_models` 返回已明确开放的参数描述。配置检查需 owner 与 `--allow-provider-management`,通过 `POST /api/v0/provider-management/workflow-check` 发送 `{expectedRevision,modelRef,workflowParameters?}`。未保存的模板可改用 `{expectedRevision,providerId,comfyWorkflow,workflowParameters?}`,仅访问已保存且启用的 ComfyUI 连接,不接受临时地址或凭据;两种选择不能混用。检查不写配置或创建 Task,配置在检查期间变化会拒绝旧结果。普通目录读取仍只列已配置工作流。
116
+
117
+ 单次参数最多 24 KiB,参数化 CLI 输入最多 96 KiB;HTTP 正文仍最多 64 KiB。参数会排序并纳入创建 Key 和 Run 输入摘要;同 Key 不同值冲突,同值不同键顺序可重放。带参数 Run 使用记录版本 2,旧读取者拒绝;无参数 Run、原固定模板和摘要保持,已有根不迁移。这里保存的是请求参数和模板绑定摘要,不保存另一份完整图;原模板改变后仍按原规则拒绝将旧任务重新绑定到新模板,并清除该图片模型的过期实测标记。原 Task 的远端查询不重新检查节点目录或生成。
118
+
119
+ ## MCP 能力选择
120
+
121
+ 连接中心的图片组分别选择“生成图片”和“修改图片”;CLI 对应 `image-generate`、`image-edit`,可逗号组合。文生图新增 `iris_core_create_generation`,参数为原请求 UUID、明确模型、提示词、可选尺寸及明确开放的 ComfyUI `workflowParameters`;创建后通过共享的 `iris_core_continue` 明确执行。
122
+
123
+ 只选择文生图时不注册导入/改图创建工具。原连接默认仍为 image-edit 和原 12 工具,不自动增加能力;两个功能都选且具备全部操作权限时共 13 工具。继续、Run/Operation 和已绑定作品读取都核对流程所属能力;这不是同一用户不同连接之间的租户隔离。配置与传输见 [通用 MCP](MCP.md)。
124
+
125
+ ## 验证范围
126
+
127
+ 定向验证覆盖根版本、稳定步骤/Task、重复 Key、未知受理不重提、原结果恢复、选择/下载、MCP stdio/HTTP 授权和真实 Chromium 操作。ComfyUI HTTP 服务响应为受控夹具,未进行真实 GPU/节点/模型出图验收;没有调用付费媒体。实际服务、反向代理与自定义节点仍需在你的部署上验证。
@@ -0,0 +1,62 @@
1
+ # 只读本地 API(0.2.7 / I4A)
2
+
3
+ 0.3 alpha源码另有 [Core 有限执行与 harness 服务](CORE_SERVICE.md)和 [owner 持久选择](LOCAL_SELECTION.md),需独立显式开启。本文其余内容说明已发布 0.2.7 的默认只读与零生成创建范围;执行实现及连接协议以上述指南为准。[真实 Web](LOCAL_WEB.md)已按权限接入固定图片创作、选择及连接管理,默认仍只读。
4
+
5
+ 0.2.7 增加显式启动的本地 HTTP 入口,默认只提供 GET/HEAD,用来验证无 DSH 环境下的流程查询与图片访问。另有主动启用的 [本地上传与创建](LOCAL_CREATION.md);0.2.7 不含继续、选择和取消接口,开发源码的对应入口见上方指南。安装包不会自动启动本服务。
6
+
7
+ 现有 [Web Demo](WEB_PROTOTYPE.md)继续保留为面向 0.3.0 的交互说明,尚未连接这个 API;界面和交互细节到 0.3.0 阶段统一润色。[完整 API 契约](LOCAL_API_CONTRACT.md)分别说明已发布能力和未发布的执行、选择实现。
8
+
9
+ ## 显式启动与停止
10
+
11
+ 准备一个已经由 `flow init` 初始化的专用根,操作见 [固定图片流程](IMAGE_FLOW.md)。只读服务不会创建缺失的根或转换旧根。
12
+
13
+ ```bash
14
+ dsh-iris api serve --data-root /absolute/path/flow-core --token-file /absolute/private/iris-session-001.token
15
+ ```
16
+
17
+ `token-file` 必须是**新文件的绝对路径**,已有父目录须可写,且该文件位于 Core 根之外。启动时生成新的随机 Token,写入此文件;POSIX 文件权限为 0600。终端只打印服务地址、文件路径和只读说明,不打印 Token;URL 与接口响应也不带 Token。请使用支持私有文件权限的本地目录;Windows 的 mode 不等于 ACL,权限依赖系统账户控制。
18
+
19
+ 服务固定监听 `127.0.0.1`,默认随机端口;可用 `--port 4174` 指定端口,占用时报错。打印的 JSON 中 `origin` 是本次服务地址。`--provider-config /absolute/path/providers.json` 可选:提供时,模型列表只读解析该显式文件,不发现/同步模型、不调用 Provider、不返回 Key 或端点;省略时仍可离线查看流程和已保存图片,模型列表返回 `configured: false`。
20
+
21
+ Ctrl+C 关闭监听和连接,等待读取释放;POSIX 下也支持 SIGTERM。Windows 的进程终止信号行为不同,其优雅停机尚未实际验证。停机后本次 Token 失效;重启使用新的 Token 文件名。旧 Token 文件保留,不覆盖或自动清理,不作为下次启动凭据。启动和关闭均不持有 Core writer,不重启 DSH。
22
+
23
+ ## 身份与访问
24
+
25
+ 每个接口都要求 `Authorization: Bearer <Token>`。Token 从私有文件读取,保持在调用进程内存中,不放进 URL、命令行参数、聊天或共享日志。下面仅把文件路径交给 Node,示例响应不包含 Token;替换实际端口与文件路径后执行:
26
+
27
+ ```bash
28
+ node --input-type=module - http://127.0.0.1:4174 /absolute/private/iris-session-001.token <<'JS'
29
+ import fs from 'node:fs';
30
+ const [origin, tokenFile] = process.argv.slice(2);
31
+ const token = fs.readFileSync(tokenFile, 'utf8').trim();
32
+ const response = await fetch(new URL('/api/v0/session', origin), {
33
+ headers: { Authorization: 'Bearer ' + token }
34
+ });
35
+ console.log(response.status, await response.json());
36
+ JS
37
+ ```
38
+
39
+ Host 必须精确匹配启动地址;带 Origin 时须等于该 origin,跨源、`null` 来源和跨站请求拒绝,不采信转发头,不开放 CORS。所有响应禁止缓存并使用 nosniff;未认证时返回 401,不读取流程或模型配置。Token 文件或浏览器已有 DSH 登录状态不能代替本 API 的 Bearer 请求头。
40
+
41
+ ## 当前接口
42
+
43
+ 以下路径都以 `/api/v0` 开头,支持 GET 和 HEAD;HEAD 完成同样的鉴权与校验,响应无正文。
44
+
45
+ | 路径 | 结果 |
46
+ |---|---|
47
+ | `/session` | 实例标识、只读能力和限额,无根路径或 Token |
48
+ | `/models` | 当前图片候选的模型引用、显示名、`supportsImageEdit`;只是配置事实,不是实测可用性 |
49
+ | `/runs?limit=20&cursor=…` | 最多 30 项摘要,不含 Prompt;`nextCursor` 是下一页使用的最后 Run ID,末页为 null |
50
+ | `/runs/:id` | 白名单 FlowView,含用户创作输入和原 Task 的有限事实;未知状态保持,不自动恢复 |
51
+ | `/artifacts/:id/content` | 已提交图片的原字节,按 ID 读取该根中的作品,不接受本地路径或外部 URL |
52
+ | `/runs/:id/download` | 已选择作品的原字节与固定附件名;尚未选择返回 409,不写服务器输出路径 |
53
+
54
+ 图片访问仅提供 PNG、JPEG、WebP,单份最多 64 MiB;当前使用有界、已核验内容哈希的字节快照。大型媒体的磁盘流式、Range 和音视频访问留到后续,不作为本切片能力。最多两个活动读取,繁忙返回 429。列表使用现有 Flow 存储逐项盘点,页数限制只约束响应数量,尚未建立大型目录索引。
55
+
56
+ 默认只读模式下,非 GET/HEAD 方法返回 405;不支持的路径返回 404,未知/重复查询参数或格式错误的 ID 返回 400。损坏/不一致的记录返回 409,不修复原文件;错误只包含固定代码、说明和关联 ID,不透传堆栈、配置、私有路径或 Provider 错误原文。
57
+
58
+ 详情和图片属于私有创作数据,均需鉴权。列表、查看、HEAD、刷新与下载不会调用 `flow.continue`,不会补交付或重新生成;下载请求成功也不证明浏览器已保存文件。CLI 的本地 `flow export` 仍是单独的显式写操作。
59
+
60
+ ## 后续范围
61
+
62
+ 默认入口保持 I4A 的只读行为。0.2.7 的 [I4B](LOCAL_CREATION.md)另提供新空根请求区与 `--allow-local-writes`:上传和 Run 创建使用持久 Key/预留身份,本地提交后 201、重放 200;不执行生成。有限执行/取消和真实 Web 联调留到后续,不改 Flow/Task/Artifact 格式、不迁移原数据根或冻结公共 SDK。
@@ -0,0 +1,140 @@
1
+ # 独立本地 API 契约(0.3 / I4)
2
+
3
+ 0.2.7实现 **I4A 默认只读**与 **I4B 显式本地创建**:显式本机监听、Bearer/Host/Origin、受控流程/媒体,以及主动启用的上传/创建与持久身份接回,见 [只读 API](LOCAL_API.md)和 [本地创建](LOCAL_CREATION.md)。0.3.0-alpha.1另提供 [有限执行服务](CORE_SERVICE.md)、[连接握手](CORE_CONNECTIONS.md)与 [owner持久选择](LOCAL_SELECTION.md)。本契约尚未冻结为公开SDK;稳定0.2.7只包含上述I4A/I4B入口。
4
+
5
+ 已发布固定流程通过 [CLI](IMAGE_FLOW.md)执行,0.3 alpha源码另有上方 Core 服务;[独立 Web Demo](WEB_PROTOTYPE.md)只消费内存演示,保留到 0.3.0 阶段统一润色。Demo 尚未接入只读 API,也不作为完整服务或写操作已实现的依据。
6
+
7
+ 0.3 alpha源码另有 [Core 工作台](LOCAL_WEB.md),通过显式 `web serve` 同源提供固定静态资源;登录页不包含私有数据,API/图片仍要求 Bearer。默认只读,创建、执行和选择分别显式开启,不要求连接管理;页面按能力接入改图、比较、选择、停止和下载。npm 0.2.7 尚不含,不改变下方已发布 I4A/I4B 的能力边界。
8
+
9
+ 源码另实现 [Operation 存储与版本门禁](LOCAL_OPERATIONS.md),只在新专用根主动初始化;显式 `api serve --allow-execution` 装配 runner、持久接收/查询与本地停止,默认模式与刷新恢复仍只读。v1 根复用零生成创建,写者拒绝损坏记录;具体执行与握手以服务指南为准。
10
+
11
+ 0.3 alpha源码的 [Core 音频流程](AUDIO_FLOWS.md)另在新 v3 根增加 `/audio-models`、`/audio`、`/speeches`、`/transcriptions`、作品 `/audio` 和 `/text`,以及 Run 类别筛选。音频与图片共用原 runner/Task/Key;现有图片 `/content` 保持图片类型限制。播放/下载最多64 MiB音频或1 MiB文本,输入音频最多20 MiB且核对容器/MIME,不接收任意路径/URL。下方 I4A/I4B 表继续描述已发布图片切片,不能据此把音频入口用于旧根。
12
+
13
+ 源码另有 owner 专用只读 `GET/HEAD /api/v0/capabilities`:返回 `contractVersion:0,state,scopeOptions,controlTools,groups,tools,media,plugins,contributions`,装配插件时附 Core 版本及准确贡献依赖。无模型密钥、数据根或可加载脚本路径;无凭据401,连接凭据403,未知查询参数400。此完整目录不表示当前用户授权或媒体健康。连接管理目录复用同一投影并另附 availableScopes/defaults 等服务选项;`session.operations` 由 Core 的 Web 映射和实际根版本、开关、授权交集生成。详情见 [插件目录](PLUGINS.md#core-能力目录与授权),不改变已发布 I4A/I4B 的契约范围。
14
+
15
+ ## 1. 实例与启动
16
+
17
+ 一个服务实例显式绑定一个已初始化的专用 Flow 根和一个 Application Runtime。Provider 配置来源可显式提供,省略时仍可查看已有流程/图片,启用本地写入后也可上传;模型列表返回未配置,不能创建新 Run。由用户主动启动,固定仅监听 `127.0.0.1`;首次不支持远程监听、代理转发或自动扫描 DSH 配置。CLI 的 `flow init` 仍负责初始化新根,浏览器不能指定根路径或初始化旧根。未发布 C3 另以独立开关提供 owner 供应商管理,只操作启动时固定的配置,见 [管理契约](PROVIDER_SETTINGS.md)。
18
+
19
+ API 使用 `/api/v0` 前缀,后续静态页面须与 API 同源。只有 HTTP 适配器负责验证外部输入、生成受控 DTO 和管理请求;不得把 `application.execute(name, input)`、现有 DSH `serveApi` 或 CLI 参数作为通用 HTTP 转发口。模型来自显式配置中允许改图的候选,Flow 继续绑定单一明确模型与 `n=1`。
20
+
21
+ I4B 的上传与 Run 创建均不生成,完成本地提交后返回 201,同 Key 接回返回 200。`api init` 先在空的已初始化 Flow 根建立请求区,`api serve --allow-local-writes` 才开放这两个 POST,不自动转换已有创作根。默认启动仍只读。
22
+
23
+ ## 2. 身份与浏览器边界
24
+
25
+ - `api serve` 每次启动产生32字节随机 owner Token,CLI 通过 `--token-file` 或 `--token-dir` 写入新的根外私有文件(POSIX0600),不打印 Token。服务鉴权使用摘要和等时比较;调用进程读取私有文件,以 `Authorization: Bearer …` 发送,不进入 URL、命令行参数、Run、日志或错误文本。普通 `web serve` 改由根外私有认证存储管理口令与浏览器会话;记住设备时浏览器独立凭据保存在 origin 隔离的 localStorage,普通模式用 sessionStorage,不保存口令或 owner/MCP 密钥。刷新先 GET 验证,不开始生成,见[工作台登录](WORKBENCH_LOGIN.md)。
26
+ - 模型列表、业务状态、媒体与管理 API 均要求 Bearer 身份;owner Token 使用摘要及等时比较。不使用 Cookie,也不建立“同源就已认证”的假设。工作台主动退出经服务确认后撤销当前浏览器会话,401清除失效的客户端登录;口令模式的有效浏览器会话跨正常重启保留,进程 owner 控制令牌仍轮换。
27
+ - 普通 `web serve` 的有限登录入口为 `GET/HEAD /api/v0/workbench/auth`、严格同源 `POST /setup`、`POST /password-login`、`POST /logout`(后三者均在 `/api/v0/workbench` 下),字段和权限见[口令接口](WORKBENCH_LOGIN.md#接口与装配)。首次设置要求启动器交付的随机片段票据,没有10分钟窗口,成功后失效。`POST /setup-link` 与 `/password-reset` 只接受本机 owner 控制令牌,浏览器及 MCP 凭据不可调用。
28
+ - 显式 `--token-file` / `--token-dir` 的旧工作台模式保留 `POST /api/v0/workbench/login`、`/login-link` 和10分钟一次性链接;票据与浏览器身份仅在进程内保留摘要,服务重启失效。口令模式拒绝这两个旧接口。`api serve` 不开放工作台登录入口,MCP仍使用连接专属凭据。
29
+ - `Host` 必须精确匹配实际监听 authority。带 `Origin` 的请求仅允许该页面精确 origin;`Origin: null`、外站 origin 和不匹配 Host 拒绝,不采信 `Forwarded` 或 `X-Forwarded-*`。无 Origin 的本机 CLI 请求仍须通过 Host 与 Token 检查。不同 origin 的 OPTIONS 不开放 CORS。
30
+ - 公开工作台首页允许外站顶层GET导航,以便直接点击登录链接;必须是document/navigate,不把此例外用于iframe、脚本、外站fetch或业务API,Host和已有Origin检查仍保留。
31
+ - 当前 API 响应使用限制性 CSP。未来页面的脚本/样式只从本站加载,无内联脚本、第三方资源、对象、框架嵌入或表单提交;用户内容用文本节点展示,媒体通过带认证的 fetch 获取 Blob 后展示/下载,不将 Token 放入 `<img>` URL。
32
+ - JSON、状态、媒体和错误响应使用 `Cache-Control: no-store`、`X-Content-Type-Options: nosniff`;API 不重定向到 Provider URL。首切片仅为意外服务错误记录净化调用帧与关联 ID。若增加访问日志,只记录方法、固定路由类型、状态、随机关联 ID 与耗时,不记录 Authorization、正文、查询参数或绝对路径。
33
+
34
+ Bearer、Host/Origin 与 CSP 是不同边界,不能相互替代。静态预览器没有凭据或 Core 权限,它的验证不等于这里的认证验收。
35
+
36
+ ## 3. 有限路由
37
+
38
+ 实验性公开插件工作台可通过 `allowedOperations` 开启持久 `plugin.execute`;媒体执行仍独立开关。它增加以下有限路由,逐请求核对 scope/tools/准确依赖,插件处理器只能调用已声明的 Core 子集;不是通用命令转发。
39
+
40
+ | 方法与路径 | 输入 | 语义 |
41
+ |---|---|---|
42
+ | `GET /plugin-operations/catalog` | `offset`、`limit=1..30` | 当前连接选择的业务、准确依赖、输入 Schema、available及现有图片;分页沿用作品库 offset/total,过滤不支持类型及超过8 MiB的图片,nextOffset用于继续读取 |
43
+ | `POST /plugin-operations` | UUIDv4 `Idempotency-Key`,`{operationId,dependency,input}`,正文最多64 KiB | 202持久回执;同 Key 同输入读原记录,变更冲突。需要 execute和plugin_call,接受及Core命令处检查有效授权 |
44
+ | `GET /plugin-operations` | `limit=1..30`、`cursor` | 按当前准确业务选择过滤后分页的持久历史;owner可读全部,不要求插件实现仍安装 |
45
+ | `GET /operations/:id`、`GET /operations?key=…`、`POST /operations/:id/cancel` | 原 ID/UUID;cancel正文 `{}` | 复用原查询/接回/本地停止,按记录的准确依赖鉴权;新业务结果含Core确认的artifactIds |
46
+
47
+ 会话附 `pluginExecution/pluginOperations` 和允许的 plugins.catalog/plugins.execute 等别名。工作台有内建业务记录页,插件缺失仍可查原作品。启动将遗留在途记录标为 interrupted,不自动重做;业务 succeeded 仅表示处理器返回及Core命令完成。详见[真实业务](CONTACT_SHEET.md)。
48
+
49
+ 下列 GET/HEAD 已有实现,Operation 路由需未发布的显式执行模式;I4B 只含 images/runs 两个 POST,执行模式另含 continue/cancel,selection 需独立 `--allow-selection` 且仅限 owner。JSON 响应含 `contractVersion: 0`;列表最多 30 项,摘要不含 Prompt;创建 JSON 上限 64 KiB,执行/选择/连接 JSON 上限 8 KiB。未知/重复查询参数和带正文的只读请求拒绝。
50
+
51
+ | 方法与路径 | 输入 | 语义 |
52
+ |---|---|---|
53
+ | `GET /session` | 无 | 返回实例标识、契约版本、允许的操作与输入上限;owner 会话另有稳定 rootId(无请求区为 null),默认 Panel 显式选中扩展时附 panelContributions(身份、准确依赖、本站资源 URL);连接凭据不获此清单,不返回根路径、Key 或端点 |
54
+ | `GET /creation-requests`(未发布) | `kind=image-import/flow-create`、原 UUIDv4 `key` | 仅 owner;默认只读也可核对已有请求,返回 kind/state 与经核验的结果引用或 null,不补写或生成 |
55
+ | `GET /models` | 无 | 返回当前可选的 `modelRef`、显示名和是否支持改图;不会探测 Provider、同步目录或修改用途 |
56
+ | `POST /images`(I4B) | 原始 PNG/JPEG/WebP 字节、匹配的 Content-Type、Idempotency-Key | 本地提交后返回 201 和 Artifact 引用,同 Key 接回返回 200;不接受文件路径、URL、目录或 SVG |
57
+ | `GET /runs` | `cursor`、`limit`,limit 1–30;0.3 alpha源码另有 `selection=all/selected/unselected` | 已有流程摘要,不含 Prompt;只读,不观察远端。先按选择筛选再计算 total/分页,另有 counts 全部/已选/未选计数 |
58
+ | `POST /runs`(I4B) | `{sourceArtifactId, modelRef, prompt, size?}`、Idempotency-Key | 固定 `image-edit/v0` / `n=1`,只保存输入与身份,零生成请求;本地提交后 201,同 Key 接回 200 |
59
+ | `GET /runs/:id` | 无 | 返回下述 FlowView;只读,不创建 Task、补交付或继续步骤 |
60
+ | `POST /runs/:id/continue`(未发布执行模式) | `{expectedRevision}`、Idempotency-Key | 持久接收后 202,同 Key 200;一次首次提交/观察/补交付/比较,不重提已有 Attempt |
61
+ | `POST /runs/:id/selection`(未发布选择模式) | `{artifactId, expectedRevision}` | 仅 owner;同 writer 核对版本并保存原图/结果选择,返回 200;过期版本 409,不触发生成或下载 |
62
+ | `GET /artifacts/:id/content` | 无 | 按已验证 Artifact ID 和清单读取该根内媒体字节,不接受 path/URL 参数;不写文件 |
63
+ | `GET /runs/:id/download` | 无 | 返回已选择图片的原字节及受控附件名;未选择则冲突,不接受服务器输出路径 |
64
+ | `GET /operations/:id`(未发布执行模式) | 无 | 查询持久状态,不能借此继续操作;原 Key 查询和 Run 列表见服务指南 |
65
+ | `POST /operations/:id/cancel`(未发布执行模式) | 空 JSON | 原 ID 幂等停止本地排队/等待,终态落盘后 200;不代表远端已取消或已退款 |
66
+
67
+ 上传累积读取限制使用现有 `MAX_IMPORT_IMAGE_BYTES = 20 MiB`,不能只相信 Content-Length;最终交给 `readImportImage({imageBytes}, signal)` 检查实际格式和静态图片要求。连接关闭、超量与解析失败不留下临时可服务文件,不把 filename 当服务器路径。并发上传上限 1,超过返回忙;用户显式重试复用原 Key。
68
+
69
+ 上传复用现有图片验证与 Artifact 预留 ID 提交;请求与作品在同一次 writer 内保存。当前图片读取/下载仍限 64 MiB,类型 PNG/JPEG/WebP,先检查清单大小再校验内容哈希,最多两个活动读取。大型媒体磁盘流式、Range 和音视频仍待后续。下载不调用服务器本地 `flow.export(output_path)`;浏览器是否保存成功不属于持久 Run 事实。
70
+
71
+ 未发布 HTTP 列表摘要保留 id/recipe/createdAt/modelRef/source,另投影 updatedAt、revision、output/selection 引用(无值为 null),不附 Prompt、Task、供应商绑定或路径;CLI/MCP 列表保持原语义。省略 selection 等于 all,未知/重复参数或不属于筛选结果的 cursor 返回400。图库封面使用 selection,否则 source。
72
+
73
+ ## 4. FlowView 与操作反馈
74
+
75
+ 浏览器只消费白名单投影,不直接接收磁盘 Run、完整 Task、Attempt、Provider 错误对象或配置。完整详情是用户创作数据,需要认证;摘要不包含 Prompt。
76
+
77
+ ```text
78
+ FlowView {
79
+ contractVersion: 0,
80
+ id, recipe: "image-edit/v0", revision, createdAt, updatedAt,
81
+ status: not_started | running | needs_attention | delivery_failed |
82
+ needs_comparison | awaiting_selection | selected,
83
+ input: { prompt, modelRef, size? },
84
+ source: { artifactId },
85
+ output: { artifactId } | null,
86
+ comparison: { artifactId } | null,
87
+ selection: { artifactId } | null,
88
+ task: { id, acceptance, outcome, deliveryState, attemptCount } | null,
89
+ metrics: { ratio, diffPixels, totalPixels, width, height } | null
90
+ }
91
+ ```
92
+
93
+ ID 继续使用当前 `run_` / `task_` / `artifact_` 加 24 位小写十六进制。DTO 不带绝对路径、端点、绑定摘要、远端任务 ID 或任意媒体 URL。媒体信息如格式/尺寸应由独立受控投影提供,不信任用户文件名。`metrics` 仅来自实际已提交比较作品;像素差异不是质量评分。
94
+
95
+ | `status` | 首要操作与文案边界 |
96
+ |---|---|
97
+ | `not_started` | “开始生成”;可能产生费用,输入已经固定 |
98
+ | `running` | “查看原任务”;每次显式操作至多观察一次,页面不自行调用 continue |
99
+ | `needs_attention` | 显示受理未知/失败/取消等事实;无自动重提。需要新生成时明确新建 Run |
100
+ | `delivery_failed` | “恢复结果”;生成已经成功,恢复原缓存/远端结果,不新生成 |
101
+ | `needs_comparison` | “完成比较”;执行本地步骤,不新生成 |
102
+ | `awaiting_selection` | 选择原图或新版;下载仍禁用 |
103
+ | `selected` | 可下载;不能据此声称文件已经保存到用户设备 |
104
+
105
+ I4B 的上传与创建同步完成本地提交,以 201/200 返回 Artifact/FlowView 和 `idempotentReplay`,不返回持久排队的 202,也不开放 Operation 查询或取消。相同 Key 保证原业务身份与效果;已有 Run 的返回状态可以随真实进度变化,不承诺重放完全相同的响应字节。
106
+
107
+ 未发布执行模式在原子接收后返回 `202 {contractVersion:0, operation, idempotentReplay:false}`;重放返回 200,状态为 `queued | running | succeeded | failed | canceled | interrupted`。GET 不驱动 Provider;每次显式继续至多一次观察。单根最多 8 条 queued/running,同 Run 最多一条;writer 忙时拒绝新接收,不声称已排队。停止直接中止控制器,随后在同 writer 下落盘并返回 200;不伪造远端 Task canceled。此模式不随 I4B 或只读 Web 自动开启。
108
+
109
+ ## 5. 上传与持久创建幂等(I4B)
110
+
111
+ I2 保证相同 Run 使用原 Task;I4B 另保证同 Key 创建请求接回原 Artifact/Run。前端禁用按钮、内存 Map 和“成功后才写 Key → Run 映射”不能代替持久意图。
112
+
113
+ 新空专用根使用 `creation-requests/v0/root.json` 和 `requests/req_<64 hex>.json`,没有数据库或已有创作根迁移;现有 Task/Artifact/Run 格式保持。具体约定为:
114
+
115
+ 1. 客户端每次明确动作使用一个不带引号的小写 UUIDv4 `Idempotency-Key`。请求区保存稳定 rootId;命名空间按 rootId、操作种类和 Key 计算 SHA256,**不使用随重启变化的服务 instanceId、Token、端口或本机路径**。原始 Key 不持久保存或记录。
116
+ 2. 输入摘要来自规范化内容:图片的真实字节摘要、大小与 Content-Type;Run 的来源 ID、模型引用、规范化 Prompt/size、固定 recipe/n。对象键序不影响摘要,不额外改写正文。同 Key 不同内容 409;已发布意图不因模型池或端点变化另选身份。
117
+ 3. 同一个 operation-owned Core writer 内,先校验新输入并**排他发布 prepared 意图与全部预留身份**,再提交 Artifact/Run,最后原子更新 succeeded。不能通过两个独立 writer 或“先创建后补 Key 映射”实现。创建 Run 需内部受控的预留 Run/Task/比较作品 ID,浏览器不能指定它们。
118
+ 4. 已存在的 Run 按原始输入、来源/binding、创建时间和预留身份核对;允许后续 revision、输出或选择已经推进,返回当前事实,绝不覆盖回初始状态。图片复用现有 Artifact 重入提交及内容校验;未完成上传不另存原件,需客户端同 Key 重新提供相同字节。
119
+ 5. 意图发布前的验证失败、busy 或排队取消不消费 Key;发布后的断线不撤销已经接受的本地提交。启动、GET 和刷新不自动修复/重放;显式同 Key POST 才核对或补完。存储损坏或身份冲突保留现场,不能回退成随机新建;不永久缓存通用 500 并把原对象藏起来。
120
+ 6. prepared 引用保护包括预留上传对象、Flow 来源/Task/比较身份;succeeded 保留请求身份和原结果 ID,但不额外禁止显式删除未使用的上传,真实 Run/Task 引用仍保护。成功目标不可用时,同 Key 返回 `409 IRIS_API_RESULT_UNAVAILABLE`,不复活作品或重建 Run。损坏/未知请求阻止误清理,不能当作空引用;首版没有请求删除、TTL 或自动 GC,权限沿用私有约定。
121
+ 7. 新版 writer 和维护入口必须识别请求格式,未知/半初始化请求区拒绝写入。已发布旧程序没有这些新检查,不能靠一个标记保证其拒绝该根;此专用根只支持已验收的 request-aware writer,回退使用完整副本,不删除请求区伪装降级。已提交 Flow/图片仍可只读查看。
122
+ 8. 复用现有原子发布和重入能力,验证范围限进程异常退出/SIGKILL;不据此承诺断电、操作系统崩溃或共享存储下的跨文件事务。请求区本身不触发 Provider 目录刷新、探测、生成或任务观察。
123
+
124
+ 未发布 continue/Operation 使用独立 runner 与持久身份,显式启动只记录遗留中断,**不能自动重放 continue**。I4B 创建证据与执行验收分开;Web 的连接管理写入见 [连接契约](CORE_CONNECTIONS.md)。选择复用 Run 原子提交:当前版本的同目标选择不重写,旧版本即使目标相同也冲突;没有持久 Key/选择收据,响应丢失先 GET 核对,见 [持久选择](LOCAL_SELECTION.md)。源码已实现 [原创建 Key 查询、稳定根身份及浏览器恢复](WEB_RECOVERY.md)和真实创作按钮;刷新或找回创建成功均不自动首次执行。
125
+
126
+ ## 6. 错误与验收
127
+
128
+ 统一错误外形为 `{contractVersion:0, error:{code, message, requestId}}`,不附堆栈、配置或 Provider 原始响应。网络错误只返回已脱敏的有限分类;取消/断线不把未知改写为失败未计费。
129
+
130
+ | HTTP | 类别 |
131
+ |---|---|
132
+ | 400 / 413 / 415 | 输入无效、正文过大、图片格式不支持 |
133
+ | 401 / 403 | 身份无效、Host/Origin 不可信 |
134
+ | 404 | 合法 ID 在该实例不存在 |
135
+ | 409 | Key 输入冲突、原任务状态冲突、根被占用、同一 Run 操作活跃、尚未选择 |
136
+ | 429 | 有界队列/上传已满,显式重试可复用原 Key |
137
+ | 503 | 正在关闭;不再接收新写操作 |
138
+ | 500 | 无法分类的内部错误,保留服务端关联证据并停止相应操作,不静默回退 |
139
+
140
+ I4 必须实际验证:错误 Token/Host/Origin、媒体绕过、超量流式上传/损坏图片/路径参数、双击/不同 Key 并发、同 Key 响应丢失/重启、未知受理不重提、只读重连、取消时序、停机与租约释放。之后才让 [Web 原型](WEB_PROTOTYPE.md)换成真实传输并验收无 DSH 的端到端路径。本稿和静态预览不等于第二个生产 Host 已完成。
@@ -0,0 +1,56 @@
1
+ # 本地上传与流程创建(0.2.7 / I4B)
2
+
3
+ 0.3 alpha源码另支持 [Operation 执行根](LOCAL_OPERATIONS.md)与 [Core 有限执行服务](CORE_SERVICE.md),需在新空 Flow 根显式 `execution init`,执行另主动开启;上传/创建仍不生成。下文说明已发布 0.2.7 的 v0 初始化流程,各种根不自动转换。
4
+
5
+ 新的 `execution init --image-generation` 使用 v2 容器;owner 可通过 POST `/api/v0/generations` 保存 `{modelRef,prompt,size?,workflowParameters?}`,使用独立的 `generation-create` 原 Key 查询与重放,不接受来源图片。`workflowParameters` 仅用于明确开放槽位的 ComfyUI 模板,并纳入原 Key 和 Run 输入摘要;旧 `/runs` 不接受该字段。旧 `/runs` 创建仍必须提供来源,不能借旧编辑工具调用新能力。见 [独立文生图](IMAGE_GENERATION.md)。
6
+
7
+ 0.2.7 在 [只读本地 API](LOCAL_API.md)之上,增加显式启用的图片上传和固定 Run 创建。两者都只提交本地数据,不生成、不观察任务、不调用 Provider。实际生成仍使用 [Flow CLI](IMAGE_FLOW.md);执行/取消 API 与真实 Web 接入留到后续。本功能从 npm 0.2.7 起随包分发。
8
+
9
+ ## 初始化与启用
10
+
11
+ 为这一功能选择新的专用根,先初始化 Flow,再初始化请求区:
12
+
13
+ ```bash
14
+ dsh-iris flow init --data-root /absolute/path/new-flow-core
15
+ dsh-iris api init --data-root /absolute/path/new-flow-core
16
+ dsh-iris api serve --data-root /absolute/path/new-flow-core --token-file /absolute/private/session-001.token --provider-config /absolute/private/providers.json --allow-local-writes
17
+ ```
18
+
19
+ `api init` 只接受空的已初始化 Flow 根,不转换已有创作数据。重复初始化返回原 rootId;半初始化、未知版本或损坏请求区报错并保留现场。省略 `--allow-local-writes` 时仍只读;没有 Provider 配置也可上传或读取已有结果,创建新 Run 需要显式的可改图模型配置。
20
+
21
+ 服务仍固定监听 `127.0.0.1`,默认随机端口;Token 文件与身份、Host/Origin、停止方法沿用 [只读入口](LOCAL_API.md)。Token 和请求 Key 是两件事:每次启动换 Token,同一次创建在网络不确定时保留原 Key。不要通过 URL、命令行参数或共享日志传 Token。
22
+
23
+ ## 两个本地写接口
24
+
25
+ 每次明确的新动作产生一个不带引号的小写 UUIDv4 `Idempotency-Key`,发送单个请求头。该 Key 不代替 Bearer 鉴权。
26
+
27
+ | 路径 | 输入 | 返回 |
28
+ |---|---|---|
29
+ | `POST /api/v0/images` | 原始静态 PNG/JPEG/WebP 字节,匹配的 Content-Type,最多 20 MiB | `{contractVersion:0,idempotentReplay,artifact:{artifactId,mediaType,size,width,height}}` |
30
+ | `POST /api/v0/runs` | UTF-8 JSON `{sourceArtifactId,modelRef,prompt,size?}`,最多 64 KiB | `{contractVersion:0,idempotentReplay,flow:<FlowView>}` |
31
+
32
+ 首次创建在本地提交完成后返回 201;同 Key、同规范化输入接回原身份,返回 200 和 `idempotentReplay: true`。同 Key 不同输入返回 409;新的 Key 表示另一明确创建,不做全局按内容去重。Run 固定 `image-edit/v0`、单一明确模型和 `n=1`,创建不建立实际 Task。模型配置只读解析,不刷新目录或实测能力。
33
+
34
+ 上传不接受路径、URL、文件名、SVG、动画或压缩正文;真实格式必须匹配 Content-Type。累计读取限额不只依赖 Content-Length,同时最多一个上传、最多九个本地创建请求;繁忙返回 429,同物理根有其他 writer 时返回 409,显式重试保留原 Key。
35
+
36
+ 超限返回 `413 IRIS_API_INPUT_TOO_LARGE`,不创建作品或消费 Key。对尚未结束的上传,先发送完整错误响应,再丢弃剩余正文并关闭连接;不继续缓存正文,连接仍受现有请求/空闲超时和服务停止约束。客户端收到拒绝后应停止上传。
37
+
38
+ 已发布 0.2.7 与仅开启 `--allow-local-writes` 时没有 continue、selection、Operation 查询或取消接口。GET、HEAD、页面刷新和启动不自动执行或补完创建;现有 Demo 仍使用演示传输,尚未连接这个 API。
39
+
40
+ ## 重试、删除与中断
41
+
42
+ 0.3 alpha源码增加 owner-only 的原 Key 只读查询和 session 稳定 rootId,v0/v1 请求区均可读取;prepared 不自动补完,默认只读服务也不创建请求区。浏览器刷新先验证标签页保存的登录,再 GET 核对,详见 [工作台请求恢复](WEB_RECOVERY.md)。此查询不在已发布 npm 0.2.7 中。
43
+
44
+ 请求意图、预留身份、业务提交和完成状态共用同一次 Core writer。跨进程重启、端口变化或 Token 轮换后,同 Key 仍绑定原数据根和原输入;已有 Run 后续执行或选择过,重放返回其当前 FlowView,不回退进度。已有意图不因当前 Provider 配置变化另选模型/端点,未来执行仍遵守原 Flow binding。
45
+
46
+ 意图发布前的输入错误、busy、排队取消或断线不消费 Key;发布后断线不撤销本地提交。未完成上传需要重新提供相同字节;显式同 Key POST 才核对或补完,没有自动后台重放。关闭服务会停止接收和等待,并保留未完成证据。
47
+
48
+ 未完成请求引用的来源与预留对象受删除/清理保护。成功上传如果没有其他 Run/Task 引用,仍可通过现有明确动作隔离或删除;之后同 Key 返回 `409 IRIS_API_RESULT_UNAVAILABLE`,不复活作品或新建替代身份。请求记录首版不自动过期、删除或 GC。
49
+
50
+ ## 数据与版本边界
51
+
52
+ 新私有请求区为 `creation-requests/v0`;现有 Run、Task、Artifact 格式保持,未迁移 DSH 日常数据。未知/损坏请求区使新版 writer 和维护操作报错,reader 仍可只读查看已有有效 Flow/图片。
53
+
54
+ 此专用根只支持认识请求格式且通过验收的 writer。旧 binary 没有新检查,不能靠一个新目录保证它拒写;不要用旧版本对该根执行写入。需要回退时使用改动前完整副本,不删除请求区伪装降级。半初始化现场不自动修复,优先另建新空根。
55
+
56
+ 验证范围为进程异常退出与 SIGKILL 下的身份接回;现有文件原语没有显式 fsync,不承诺断电、操作系统崩溃或 Android 共享存储上的跨文件事务。Windows/macOS 与真机使用范围须独立验证。
@@ -0,0 +1,46 @@
1
+ # Operation 存储与版本门禁(0.3 alpha)
2
+
3
+ 持久 Operation 记录一次明确有限调用的意图、原身份和状态。原 `flow.continue` 继续媒体 Run,新增 `plugin.execute` 执行明确选中的真实业务;共用单根 runner、队列、租约、HTTP 202/原 Key 接回和本地停止。默认 API 仍只读;主动开启方式见 [Core 执行服务](CORE_SERVICE.md)及[多图对照板](CONTACT_SHEET.md)。原 CLI 图片流程保持。
4
+
5
+ Operation 表示一次有限调用,Run 表示创作流程,Task/Attempt 表示外部受理与结果。Operation 成功并不等于图片完成;running 是最后保存的本地状态,不证明处理器仍在线。存储 CLI 初始化/查询不执行模型;执行服务启动只标记遗留中断,查询和原 Key 重放不重新生成或观察 Provider。
6
+
7
+ 新增 [文生图](IMAGE_GENERATION.md)使用显式 `execution init --image-generation` 的新 v2 根,runner 和 Operation 语义相同,绑定没有来源/比较作品;首次执行前或停止时作品列表可为空。原 v0/v1 不自动迁移,旧写者拒绝 v2。以下不带开关的初始化仍建立原 v1 编辑执行根。
8
+
9
+ 新增[语音/转写](AUDIO_FLOWS.md)使用显式 `execution init --audio` 新 v3 根,同时支持原图片流程。音频步骤固定为 speak/transcribe,Task、来源和输出的持久绑定仍逐项核对,停止及中断不重提;v0/v1/v2不迁移,旧程序拒绝不支持的请求区版本。
10
+
11
+ ## 显式初始化与查询
12
+
13
+ 以下命令针对0.3 alpha源码;已公开 npm 0.2.7 没有此入口。需要 Node.js ≥22 和项目现有依赖:
14
+
15
+ ```bash
16
+ node bin/dsh-iris.js flow init --data-root /absolute/path/to/new-flow-root
17
+ node bin/dsh-iris.js execution init --data-root /absolute/path/to/new-flow-root
18
+ node bin/dsh-iris.js operation list --data-root /absolute/path/to/new-flow-root
19
+ node bin/dsh-iris.js operation inspect op_REPLACE_WITH_64_HEX --data-root /absolute/path/to/new-flow-root
20
+ ```
21
+
22
+ `execution init` 只接受新的空 Flow 根,建立 `creation-requests/v1/`,包括请求记录、Operation、根声明和预留的空 runner 目录。输出 `executionEnabled: false`。重复初始化同版本根接回原声明,不改写业务和请求记录,但仍通过 writer 检查;不会把现有 v0 请求根升级,也不会降级 v1。缺失的 Flow 根、已有作品/流程的普通根和部分初始化均明确拒绝,不自动清理。
23
+
24
+ 没有 CLI 接收/执行 Operation 的命令;终端开放列表与单项查询,支持 `--run-id`、`--limit 1..30`、`--cursor`。媒体记录投影保持。插件业务通过公开工作台持久接收,投影另含准确依赖、JSON输入、输入摘要和来源作品,不含owner或存储路径;输入属于获授权可读的业务数据。
25
+
26
+ `plugin.execute` 使用有版本的 Operation schema1 分支,原 flow记录/根声明不迁移;旧 Core 遇到未知记录明确拒绝,不承诺降级。输出身份先持久预留,Core 写入后才作为实际作品投影;中断保留已提交部分结果。插件缺失/升级不改变原记录;恢复准确版本也不自动重放。其 succeeded 代表业务处理器及Core命令完成,区别于媒体 Task 完成。
27
+
28
+ ## 身份与状态
29
+
30
+ - 身份按根 UUID 与小写 UUIDv4 Key 派生为 `op_<64 hex>`,不依赖 Token、端口或进程,原 Key 不单独复制。媒体记录不复制 Prompt;插件记录保存其实际JSON输入并纳入摘要,同 Key 改输入/依赖拒绝。
31
+ - 同 Key、同 Run/revision 接回原记录,包含已结束或取消记录;变更输入复用 Key 拒绝。同 Run 最多一条 queued/running,单根活动上限 8;被拒绝的请求不落盘。
32
+ - 接收写入单条完整记录,不双写索引。状态转换按 Operation revision 检查,允许排队、开始及成功/失败/取消/中断的有限转换,结束记录不重新排队。
33
+ - 存储原语只修改 Operation 文件;真实继续与 Abort 由显式 runner 持有 writer 调用。停止不发远端取消,不改写远端 Task 的已知结果。
34
+ - 单纯查询保留原状态;显式启动执行服务取得所有权后将遗留 queued/running 标记 interrupted,但不执行它们。调用方必须明确核对原 Run/Task。未知受理不因存储重放而重新生成。
35
+
36
+ 记录绑定 Run 的私有输入摘要、预留 Task 和来源/比较作品 ID。完成时保存已有 Run revision 与结果引用,不复制 Provider 配置、完整异常或媒体。错误只记录有限类别。所有记录的引用暂继续保留,归档/释放策略另列,不自动 GC 或清除请求身份。
37
+
38
+ ## 版本与维护
39
+
40
+ 原 `creation-requests/v0` 行为与记录格式保持。v1 中的本地图片上传/Run 创建复用现有零生成逻辑与持久 Key;[只读工作台](LOCAL_WEB.md)仍然只读。
41
+
42
+ 新版写者启动时检查请求容器、Operation 结构和原 Run/Task 绑定。未知版本、损坏记录、混合容器、符号链接或未知 runner 内容会阻止写入并保留现场。新根也由已发布 0.2.7 的真实 CLI 验证拒写;更早版本和任意外部程序不在此保证内,不应把实验根交给它们维护。
43
+
44
+ 删除与清理盘点识别 Operation 的 Task/Artifact 引用,结束记录也继续保护引用;请求/Operation 文件及临时证据不在清理白名单内。旧隔离内容恢复仍遵守当前写者门禁和不覆盖规则。
45
+
46
+ 私有目录/文件创建时采用 0700/0600;Windows 的 mode 不替代 ACL。原子提交和进程强杀验证不等于断电耐久,也不等于 Android 共享存储已经验证。当前无个人数据迁移或公开发行。
@@ -0,0 +1,57 @@
1
+ # 本地持久选择(0.3 alpha)
2
+
3
+ 源码的 `api serve` 和 `web serve` 可显式开放选择接口,将已完成图片流程的原图或生成结果保存为当前作品。**npm 0.2.7 尚不包含此接口**;[真实工作台](LOCAL_WEB.md)已接入原图/结果选择,服务确认后才显示已选状态,冲突或回包丢失时读取当前事实。
4
+
5
+ ## 显式开启
6
+
7
+ 在已有专用 Flow 根上启动;不初始化或转换原根,不需要 Provider 配置,也不要求连接管理、创建或执行模式:
8
+
9
+ ```bash
10
+ node bin/dsh-iris.js web serve --data-root /absolute/path/to/flow-root \
11
+ --token-file /absolute/path/to/new-owner-token --allow-selection
12
+ ```
13
+
14
+ 也可换用 `api serve`。默认不开启;`--allow-local-writes`、`--allow-execution` 和 `--allow-connection-management` 均不会隐式开启选择。创建和执行模式仍各自要求已初始化的请求区或 v1 执行根,见 [本地创建](LOCAL_CREATION.md)与 [Core 服务](CORE_SERVICE.md)。
15
+
16
+ Token 文件须为根外新文件,权限沿用本地 API 约定。只有本次服务的 owner Token 能调用选择;连接凭据即使拥有全部 MCP 权限也不能调用,不新增 MCP scope 或工具。Bearer、精确 Host、同源 Origin 和禁止跨站请求的检查保持,见 [访问边界](LOCAL_API.md#身份与访问)。
17
+
18
+ ## 请求与版本门禁
19
+
20
+ 先通过 `GET /api/v0/runs/:id` 读取最新 `revision` 与原图/结果的 Artifact ID,再由用户明确选择:
21
+
22
+ ```http
23
+ POST /api/v0/runs/:id/selection
24
+ Authorization: Bearer <owner-token-from-private-file>
25
+ Content-Type: application/json
26
+
27
+ {"artifactId":"artifact_<24 lowercase hex>","expectedRevision":7}
28
+ ```
29
+
30
+ 正文只接受这两个字段;`expectedRevision` 必须是正安全整数,JSON 上限 8 KiB。原图或结果须属于该 Run,且流程已完成比较。路径、URL、比较图和其他 Run 的作品均不能作为选择目标。
31
+
32
+ 版本核对和选择写入在同一个 Application writer 中完成,复用原子 Run 提交,不新建请求区、Operation 或选择收据,也不改 Run 格式。成功返回 `200` 和当前 FlowView:
33
+
34
+ - 选择改变时,Run 的 `revision` 增加一次。
35
+ - 当前版本重复选择同一作品时,不重写记录、不增加版本。
36
+ - 版本已过期时返回 `409 IRIS_API_RUN_CHANGED`,即使目标恰好与当前选择相同也拒绝,避免旧操作覆盖后来的决定。
37
+ - 本实例有活动或排队写入、runner 操作,或其他写者占根时,返回 `409 IRIS_API_ROOT_BUSY`;不承诺排队。
38
+
39
+ 本接口不提供持久 `Idempotency-Key` 接回。响应丢失后先 GET 当前 Run 核对真实选择;若要改变,使用当前版本再次明确提交,不自动重试旧请求。请求在开始写入前断开会取消未开始项;已经提交的选择保留,不能因客户端未收到响应而回滚。
40
+
41
+ ## 结果与错误
42
+
43
+ 选择不调用 Provider,不创建/观察 Task,不触发生成或下载。之后的 `GET /api/v0/runs/:id/download` 返回已选图片原字节;浏览器保存完成仍以下载记录为准。
44
+
45
+ | 状态 | 含义 |
46
+ |---|---|
47
+ | 400 / 413 | 字段、类型、版本或请求格式无效 / 正文超限 |
48
+ | 401 / 403 | 身份无效 / 访问边界不符或调用方不是 owner |
49
+ | 404 | 合法 Run ID 不存在 |
50
+ | 405 | 未显式开启选择,或方法不支持 |
51
+ | 409 `IRIS_API_RUN_CHANGED` | Run 版本已改变,先读取再决定 |
52
+ | 409 `IRIS_API_RUN_NOT_READY` | 比较尚未完成 |
53
+ | 409 `IRIS_API_SELECTION_INVALID` | 作品不属于该 Run 可选的原图或结果 |
54
+ | 409 `IRIS_API_ROOT_BUSY` | 写者或执行器忙 |
55
+ | 500 | 意外写入错误;不报告成功,响应只提供净化错误与关联 ID |
56
+
57
+ CLI 的 `flow select` 保持原有用法;内部应用调用另支持可选 `expected_revision`。页面按钮、创建身份查询与刷新恢复属于后续切片,不因本接口完成而自动具备。