@mokuyoaxis/dsh-iris 0.1.4 → 0.2.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 (110) hide show
  1. package/.dsh/skills/iris-compose-media/SKILL.md +10 -5
  2. package/.dsh/skills/iris-compose-media/references/workflows.md +7 -1
  3. package/.dsh/skills/iris-verify-ui/SKILL.md +2 -1
  4. package/CHANGELOG.md +99 -1
  5. package/README.en.md +124 -31
  6. package/README.md +124 -31
  7. package/bin/dsh-iris.js +593 -13
  8. package/docs/AGENT_QUICKSTART.md +39 -0
  9. package/docs/ARCHITECTURE.md +87 -64
  10. package/docs/ARTIFACT_LIBRARY.md +5 -5
  11. package/docs/ARTIFACT_MANIFEST.md +60 -0
  12. package/docs/CLI_MANAGEMENT.md +181 -0
  13. package/docs/COMPOSITE_VISION.md +35 -0
  14. package/docs/CORE_RUNTIME_CONTRACT.md +84 -0
  15. package/docs/DSH_CORE_MIGRATION.md +135 -0
  16. package/docs/DSH_RC2_ADAPTATION.md +38 -0
  17. package/docs/FAULT_INJECTION.md +12 -2
  18. package/docs/HEADLESS_CLI.md +223 -0
  19. package/docs/HOST_ADAPTER_CONTRACT.md +36 -17
  20. package/docs/HOST_DOCTOR.md +4 -2
  21. package/docs/MODEL_PORT_CONTRACT.md +305 -0
  22. package/docs/OCR_MODEL.md +39 -0
  23. package/docs/PROMPT_OPTIMIZER.md +47 -0
  24. package/docs/PROVIDER_ADAPTER_CONTRACT.md +53 -10
  25. package/docs/PROVIDER_HEALTH.md +22 -5
  26. package/docs/PROVIDER_RUNTIME_HARNESS.md +33 -0
  27. package/docs/PROVIDER_SUBMISSION_CONTRACT.md +2 -2
  28. package/docs/ROADMAP.md +49 -83
  29. package/docs/SECURITY.md +8 -7
  30. package/docs/TASK_SEMANTICS.md +2 -2
  31. package/docs/VISION_CLI.md +132 -0
  32. package/docs/VISION_MODEL.md +51 -0
  33. package/docs/WORKBENCH_ARTIFACTS.md +67 -0
  34. package/docs/assets/logo/README.md +55 -0
  35. package/docs/assets/logo/iris-bubble-concept.svg +67 -0
  36. package/docs/assets/logo/iris-bubble.svg +14 -0
  37. package/docs/assets/logo/iris-interim-flower.png +0 -0
  38. package/docs/assets/logo/iris-logo-mono-inverse.svg +78 -0
  39. package/docs/assets/logo/iris-logo-mono.svg +78 -0
  40. package/docs/assets/logo/iris-logo.svg +78 -0
  41. package/docs/assets/logo/iris-mark-mono-inverse.svg +42 -0
  42. package/docs/assets/logo/iris-mark-mono.svg +42 -0
  43. package/docs/assets/logo/iris-mark.svg +42 -0
  44. package/docs/file-access-across-environments.md +8 -5
  45. package/docs/releases/0.2.0.md +48 -0
  46. package/docs/releases/0.2.1.md +56 -0
  47. package/lib/actions.js +520 -591
  48. package/lib/adapters.js +184 -36
  49. package/lib/api.js +200 -11
  50. package/lib/chromium-browser.js +117 -0
  51. package/lib/client.js +1390 -105
  52. package/lib/command-service.js +534 -0
  53. package/lib/composite-vision-routing.js +42 -0
  54. package/lib/config.js +143 -51
  55. package/lib/core-artifact-store.js +630 -0
  56. package/lib/core-artifacts.js +4 -0
  57. package/lib/core-attention.js +103 -0
  58. package/lib/core-contract.js +105 -0
  59. package/lib/core-doctor.js +41 -0
  60. package/lib/core-lease-recovery.js +170 -0
  61. package/lib/core-maintenance.js +213 -0
  62. package/lib/core-runtime.js +232 -0
  63. package/lib/core-tasks.js +567 -0
  64. package/lib/core-user-projection.js +193 -0
  65. package/lib/doctor.js +92 -33
  66. package/lib/dsh-core-adapter.js +653 -0
  67. package/lib/dsh-host-adapter.js +58 -7
  68. package/lib/dsh-text-model-adapter.js +222 -0
  69. package/lib/dsh-vision-model-adapter.js +75 -0
  70. package/lib/generation-input.js +126 -0
  71. package/lib/guard.js +3 -3
  72. package/lib/headless-vision.js +181 -0
  73. package/lib/host-runtime.js +1 -0
  74. package/lib/http-vision-model-adapter.js +187 -0
  75. package/lib/image-edit-input.js +34 -0
  76. package/lib/index.js +323 -188
  77. package/lib/locate.js +86 -28
  78. package/lib/media-probe.js +2 -1
  79. package/lib/model-call-runtime.js +45 -0
  80. package/lib/model-invoker.js +220 -0
  81. package/lib/model-port-contract.js +341 -0
  82. package/lib/models.js +105 -14
  83. package/lib/ocr-model-routing.js +26 -0
  84. package/lib/ocr.js +110 -64
  85. package/lib/prompt-optimizer-config.js +2 -1
  86. package/lib/prompt-optimizer-core.js +121 -0
  87. package/lib/prompt-optimizer.js +37 -193
  88. package/lib/provider-adapter.js +49 -23
  89. package/lib/provider-adapters.js +165 -26
  90. package/lib/provider-catalog.js +183 -0
  91. package/lib/provider-config-service.js +236 -0
  92. package/lib/provider-contract.js +74 -4
  93. package/lib/provider-health.js +80 -1
  94. package/lib/provider-protocol.js +74 -2
  95. package/lib/provider-task-runner.js +370 -0
  96. package/lib/summarize.js +31 -20
  97. package/lib/summary-input.js +52 -0
  98. package/lib/task-wait.js +40 -0
  99. package/lib/tasks.js +16 -4
  100. package/lib/video-input.js +30 -0
  101. package/lib/vision-core.js +42 -0
  102. package/lib/vision-image-input.js +83 -0
  103. package/lib/vision-input.js +31 -0
  104. package/lib/vision-model-routing.js +180 -0
  105. package/lib/vision.js +31 -9
  106. package/lib/workbench-artifacts.js +52 -0
  107. package/lib/workbench-management.js +151 -0
  108. package/lib/workbench-zip.js +39 -0
  109. package/package.json +8 -8
  110. package/user_guide.md +71 -26
@@ -1,6 +1,6 @@
1
1
  # Provider Adapter v0 生命周期契约
2
2
 
3
- 状态:**v0.1.4 内部契约已实现。** 这是 Iris Core 候选模块与供应商协议实现之间的稳定边界,不是面向第三方承诺兼容性的公开 SDK。当前 DashScope 与 OpenAI Images 兼容实现已经通过同一套零网络 conformance runner。
3
+ 状态:**Iris 0.2.1;沿用 v0 生命周期内部契约。** 0.1.4 建立六操作契约,0.2.0 增加可选输入准备能力,0.2.1 增加聊天/Responses 生图及模型级协议覆盖。 这是 Iris Core 模块与供应商协议实现之间的内部边界,尚未冻结为第三方公开 SDK。DashScope 与 OpenAI Images 兼容实现通过同一套零网络 conformance runner;聊天/Responses 图片协议另有提交、交付与 CLI 回归。
4
4
 
5
5
  ## 目标与依赖方向
6
6
 
@@ -18,11 +18,17 @@ Action / Task watcher / recovery / model discovery
18
18
 
19
19
  - Action、Task 恢复、重新交付、模型发现和能力实测不得直接调用供应商生命周期 HTTP 方法。
20
20
  - Provider Adapter 不创建或修改 Iris Task,不读取 DSH `ctx`,也不承担工作台展示。
21
- - `adapters.js` 保留为协议级 HTTP transport;凭据和 `baseUrl` 仅由具体 Adapter 的操作闭包捕获。
21
+ - `adapters.js` 保留为协议级 HTTP transport;凭据和实际媒体端点仅由具体 Adapter 的操作闭包捕获。配置可用 `mediaBaseUrl` 分离媒体与普通/视觉端点,空值沿用 `baseUrl`。
22
22
  - Adapter 快照只包含稳定身份、协议、能力与 supported/unsupported 事实,不包含 API Key、Authorization、私有 URL、配置对象或 live transport。
23
23
 
24
24
  ## 描述结构
25
25
 
26
+ 协议工厂由内部注册表选择;0.2.0 基线提供 `dashscope` 和 `openai-images`,0.2.1 另有 `openai-chat-images` 与 `openai-responses-images`,不提供公开注册 API。生图模型可通过可选 `imageProtocol` 覆盖账号默认;选择、实测与 Task binding 共用有效协议,详见 [模型级图片协议](CLI_MANAGEMENT.md#模型级图片协议)。未知的显式 `mediaProtocol` 保留原值,调用时以 `IRIS_PROVIDER_PROTOCOL_UNSUPPORTED` 在联网前拒绝;错误只包含合法协议标识,不回显端点或凭据。
27
+
28
+ 未配置协议或选择 `auto` 时,官方端点可识别为对应协议;其他端点继续使用 OpenAI Images 兼容路径,并标记 `protocolInferred:true`。该标记表示尚待用户确认兼容性,不代表已经验证成功。显式选择协议会清除标记;旧记录中已保存的明确协议不追溯猜测其来源。CLI 与 DSH 共用选择逻辑,Task binding 绑定最终实际协议与端点。
29
+
30
+ 视觉理解的 `type` 使用独立注册表,目前只有 `openai` 实现。导入保留显式类型;未支持类型在该后端调用前返回 `IRIS_VISION_PROTOCOL_UNSUPPORTED`,不会被静默改写为另一种协议。错误保留在后端链的 `errors` 中,既有宿主视觉降级仍可继续。`auth:'none'` 不发送认证头,缺省认证方式仍为 `bearer`。
31
+
26
32
  `defineProviderAdapter()` 只接受以下顶层字段:
27
33
 
28
34
  ```js
@@ -32,12 +38,16 @@ Action / Task watcher / recovery / model discovery
32
38
  protocol: 'dashscope',
33
39
  capabilities: ['image', 'video', 'tts', 'transcribe'],
34
40
  operations: { discover, submit, poll, download, mapError },
35
- unsupported: { cancel: '经过验证的原因' }
41
+ unsupported: { cancel: '经过验证的原因' },
42
+ // 可选扩展:prepareInput 或 unsupportedPreparation,二者不能同时声明
43
+ prepareInput: async ({ model, filePath, signal, timeoutMs }) => ({ url: '临时地址' })
36
44
  }
37
45
  ```
38
46
 
39
47
  六个操作必须**恰好**出现在 `operations` 或 `unsupported` 之一。方法缺失不能被解释为临时故障;调用显式不支持的方法会得到稳定的 `IRIS_PROVIDER_OPERATION_UNSUPPORTED`。v0 要求所有 Adapter 实现 `submit` 与 `mapError`,其余操作可根据协议事实显式声明不支持。
40
48
 
49
+ `prepareInput` 不属于这六个生命周期操作。未提供该扩展的旧 Adapter 仍有效,能力快照中的 `inputPreparation` 会标为 unsupported;具体协议也可以用 `unsupportedPreparation` 给出受控原因。快照不包含凭据、端点或临时地址。
50
+
41
51
  ## 生命周期操作
42
52
 
43
53
  | 操作 | 输入职责 | canonical 结果 |
@@ -46,10 +56,12 @@ Action / Task watcher / recovery / model discovery
46
56
  | `submit` | capability、model、规范化 input、signal | `completed / accepted / not_accepted / acceptance_unknown` |
47
57
  | `poll` | capability、remoteTaskId、signal | `pending / succeeded / failed / canceled / unknown` |
48
58
  | `cancel` | remoteTaskId、signal | `canceled / not_supported / unknown` |
49
- | `download` | remote-url artifact、目标路径、signal | `{ bytes }` |
59
+ | `download` | 可物化 artifact、目标路径、signal | `{ bytes }` |
50
60
  | `mapError` | 原始错误与 stage/acceptance 上下文 | 可持久化的脱敏错误记录 |
51
61
 
52
- `accepted` 不是独立网络操作,而是异步 `submit` 的受理结果。它必须携带非空远端任务 ID;同步成功使用 `completed`。四态提交和自动 failover 规则继续以 [Provider 提交契约 v0](PROVIDER_SUBMISSION_CONTRACT.md) 为准。
62
+ Core Attempt 持久化 `providerId::modelId` 复合身份,具体 Provider Adapter 的 `submit.model` 只接收供应商原始模型 ID;复合引用不得穿透到 HTTP。
63
+
64
+ `accepted` 不是独立网络操作,而是异步 `submit` 的受理结果。它必须携带非空远端任务 ID;同步成功使用 `completed`,并提供 canonical `artifacts`。迁移期仍保留可直接读取但不随 JSON 序列化的旧 `value`,供 0.1.4 调用方使用。四态提交和自动 failover 规则继续以 [Provider 提交契约 v0](PROVIDER_SUBMISSION_CONTRACT.md) 为准。
53
65
 
54
66
  ## poll、cancel 与交付事实
55
67
 
@@ -58,11 +70,17 @@ Action / Task watcher / recovery / model discovery
58
70
  - `failed` 需要供应商明确的失败证据;
59
71
  - `canceled` 需要远端确认,Task 才能写入 `cancelState=remote_confirmed`;
60
72
  - `unknown` 只停止当前盯守并保留 `acceptance=accepted`,不得伪造失败或重提;
61
- - `succeeded` 可以携带 remote-url artifacts 或文本 value,生成成功先于本地下载事实落盘。
73
+ - `succeeded` 和图片 `completed` 使用同一可物化描述:`remote-url` 或 `inline-base64`;文本任务仍可使用 text value。生成成功先于本地物化事实落盘。
74
+
75
+ `download` 物化已经确认成功的产物:`remote-url` 执行下载,`inline-base64` 直接写入私有 staging。inline 正文只作为 non-enumerable 的短生命周期字段传给 Runner,不进入 JSON、Task 或 Manifest。生图产物按真实字节校验 PNG/JPEG/WebP,保留字节、MIME、后缀和哈希。物化失败只能改变交付状态,不能触发生成重提。OpenAI Images、聊天生图与当前 Responses 生图切片均同步返回图片,所以 `poll` 与 `cancel` 显式 unsupported;Responses 纯文字、缺图或未完成结果保留受理未知,不扫描其他接口。DashScope 当前没有经过验证的远端取消接口,因此 `cancel` 同样显式 unsupported,而不是伪装取消成功。
76
+
77
+ 聊天改图仍使用 `capability:image`:Runner 从当前 Core 校验并读取来源 Artifact,短生命周期 `input.image:{bytes,mediaType}` 与 `prompt` 交给聊天适配器。适配器按实际模型 `visionInput` 准备副本,HTTP 用户消息使用 `text` 与 `image_url` data URL。普通 Images/Responses 不接受此输入,编辑候选链预先过滤协议。Task 仅保存可选 `sourceArtifactId`,用于未知/失败任务的来源保护和交付时写入新 Artifact 的 `derived-from`;旧记录无需迁移,重试仍重新提供输入。来源或编辑输入预算失败发生在 HTTP 之前。
62
78
 
63
- `download` 只交付已经确认成功的远端产物。下载失败只能改变交付状态,不能触发生成重提。OpenAI Images 当前同步返回图片,所以 `poll` 与 `cancel` 显式 unsupported;DashScope 当前没有经过验证的远端取消接口,因此 `cancel` 同样显式 unsupported,而不是伪装取消成功。
79
+ ## 可选输入准备与上传边界
64
80
 
65
- 上传临时输入仍属于提交前准备阶段,不是 v0 六操作之一。上传失败必须记录为 `stage=upload / acceptance=not_accepted`;只有随后真正调用 `submit` 才跨越可能计费的受理边界。未来如出现第二种上传协议,再以真实调用方证据决定是否扩展契约。
81
+ Host 和 CLI 通过 `prepareProviderInput(adapter, { model, filePath, signal?, timeoutMs? })` 调用可选准备能力,不能自行绕过 Adapter 上传。DashScope 的 Adapter 闭包持有实际凭据与媒体端点并实现临时上传;OpenAI Images 明确不支持。未实现时在网络调用前抛 `IRIS_PROVIDER_INPUT_PREPARATION_UNSUPPORTED`。返回的 `{url}` 只供紧随其后的提交读取,属性不参与 JSON 序列化,不能进入 Task、日志或能力快照。
82
+
83
+ 上传错误经 Adapter 映射与脱敏,固定为 `stage=upload / acceptance=not_accepted`;这组字段属于返回调用方的安全错误分类,**不等于已持久化的 Core Attempt stage**。上传属于 Host/CLI 输入准备,只有随后真正调用 `submit` 才跨越可能计费的受理边界。S2V 已迁入 Core:先持久化 Attempt,再按实际候选账号上传首帧和音频,上传失败可写入该 Attempt,且不调用生成 submit;Core 转写的 `audio_path` 在创建 Task 前上传,失败会直接返回且不创建 Core Task,也不会调用 submit。这是 D-12 当前采用的路径 B;若未来要求把准备失败纳入 Core 事实,须另行评审路径 A,不能由错误字段反推已经落盘。
66
84
 
67
85
  ## 错误与取消传播
68
86
 
@@ -78,13 +96,35 @@ Action / Task watcher / recovery / model discovery
78
96
 
79
97
  | 协议 | discover | submit | poll | cancel | download | mapError |
80
98
  |---|---:|---:|---:|---:|---:|---:|
81
- | DashScope | 支持 | 图片/视频/TTS/转写 | 图片/视频/转写 | 显式不支持 | 支持 | 支持 |
99
+ | DashScope | 支持(`/api/v1/models` 分页与能力元数据) | 图片/视频/TTS/转写 | 图片/视频/转写 | 显式不支持 | 支持 | 支持 |
82
100
  | OpenAI Images 兼容 | 支持 | 同步图片 | 显式不支持 | 显式不支持 | 支持 | 支持 |
83
101
 
84
102
  本表只描述协议生命周期,不扩大 0.1.4 的供应商范围。Gemini、Fal 与 Replicate 仍在 0.2.x 路线中。
85
103
 
86
104
  ## conformance runner
87
105
 
106
+ ### 协议 Transport 接口
107
+
108
+ `provider-adapters.js` 的构造器接受可选 `transport`,默认使用 `adapters.js`。它是内部协议实现与测试 fixture 的注入边界,不是 Core API。除独立下载方法外,网络方法接收 `key`、`baseUrl`、可选 `signal`/`timeoutMs`;只有适用方法接收 `model` 或 `remoteTaskId`。
109
+
110
+ | 方法 | 额外输入 | 返回值 |
111
+ |---|---|---|
112
+ | `listModels` | 无 | 模型条目数组,保留能力元数据 |
113
+ | `dashscopeImageMode` | 原始模型名(位置参数) | `legacy-async` 或 `multimodal-sync`,本地判断 |
114
+ | `submitImage` | `prompt/size/n` | 远端任务 ID |
115
+ | `generateImageMultimodal` | `prompt/size/n` | 图片 URL 数组 |
116
+ | `openAiGenerateImage` | `prompt/size/n` | URL 或 base64 图片条目数组 |
117
+ | `submitVideo` | `prompt/imgDataUrl/size/duration/audioUrl/resolution` | 远端任务 ID |
118
+ | `submitTranscription` | `audioUrl` | 远端任务 ID |
119
+ | `synthesizeTts` | `text/voice` | `{audioUrl}` 或 `{audioB64}` |
120
+ | `pollTask/pollTranscriptionTask` | `remoteTaskId` | 协议结果,由 Adapter 归一化为 canonical poll 结果 |
121
+ | `uploadTempFile` | `model/filePath` | 临时输入 URL;仅由支持该扩展的协议 Adapter 调用 |
122
+ | `downloadTo` | URL、目标路径、选项(位置参数) | 写入字节数 |
123
+
124
+ transport 抛出的原始错误必须经 Adapter 的错误映射;提交异常不能直接授权重提。`uploadTempFile` 经过 `prepareProviderInput` 归一化错误,但仍不属于六个 canonical 操作。
125
+
126
+ ### 验证方式
127
+
88
128
  零网络 runner 位于 `tests/fixtures/provider-conformance.mjs`,并由 `tests/provider-adapters-conformance.mjs` 对内置实现执行。它验证:
89
129
 
90
130
  1. 快照可序列化且不含凭据;
@@ -92,6 +132,9 @@ Action / Task watcher / recovery / model discovery
92
132
  3. 每个 supported 操作都有 fixture 场景;
93
133
  4. unsupported 调用返回稳定错误;
94
134
  5. mapError 会清除 synthetic secret 与本地路径;
95
- 6. 提交四态、轮询五态、下载字节数和协议特定能力符合契约。
135
+ 6. 提交四态、轮询五态、URL/inline 物化字节数和协议特定能力符合契约;
136
+ 7. 同步多图片进入同一 Core Task,坏同步响应保持受理未知并停止 failover。
96
137
 
97
138
  runner 本身不访问网络;具体 Adapter 构造时注入 fake transport。新增 Provider 前,必须先通过同一 runner,再进行用户明确授权的真实供应商短验。0.1.4 不发布 Provider SDK,也不把测试 runner 当成第三方兼容性承诺。
139
+
140
+ 可选准备能力另由 `tests/provider-input-preparation.mjs` 和调用方的转写/s2v 测试覆盖:包括未支持协议零网络拒绝、临时 URL 不序列化、上传错误脱敏及上传前后受理边界。
@@ -1,6 +1,6 @@
1
1
  # Provider 与能力健康状态
2
2
 
3
- 状态:v0.1.4 候选契约。
3
+ 状态:**Iris 0.2.1**。新增短时限流冷却与明确额度/预算耗尽停用,沿用既有持久健康证据。
4
4
 
5
5
  Iris 用持久化证据描述“当前配置是否存在、最近是否实际成功、是否出现明确凭据失败”。它不是后台监控,也不等同于 Host Doctor。
6
6
 
@@ -11,15 +11,32 @@ Iris 用持久化证据描述“当前配置是否存在、最近是否实际成
11
11
  | `unconfigured` | 灰色 | 当前能力没有启用且带凭据的候选模型 |
12
12
  | `configured` | 蓝色 | 已配置,但没有 7 天内的成功证据;旧证据过期后也回到此状态 |
13
13
  | `verified` | 绿色 | 该 Provider × Model × Capability 在 7 天内通过显式实测或真实任务成功 |
14
- | `failed` | 暗红色 | 最近的决定性证据是 401、403 或明确的认证/权限失败 |
14
+ | `failed` | 暗红色或红色 | 明确认证/权限失败,或已确认额度/预算耗尽;短时限流另以琥珀色显示 |
15
15
 
16
16
  状态按 `Provider × Model × Capability` 记录,不因同名模型而合并。模型、Key、Base URL、协议或能力模型等关键配置变化会清空相关旧证据;移除模型或能力标签也会移除不再成立的记录。
17
17
 
18
+ 模型可单独设置 `imageProtocol`,未设置或 `auto` 时继承账号默认。改变有效图片协议只使该模型的生图验证失效;同模型的视觉验证、其他模型及冷却/额度停用均保留。再次选择同一有效协议不清空验证。设置入口见 [CLI 管理命令](CLI_MANAGEMENT.md),DSH 模型池的生图模型行也可修改。
19
+
18
20
  ## 什么会改变状态
19
21
 
20
22
  显式“模型实测”和正常用户任务都会产生证据。视觉、图片和 TTS 可从模型池逐项实测;视频与转写不会发送空样本探针,应使用真实的视频生成或音频转写任务验证。成功受理、同步完成或视觉成功会刷新绿色及其成功时间。
21
23
 
22
- Iris 不做定时后台探测,也不会为了让图标变绿而产生隐形请求或费用。429/额度限制、网络错误、5xx、内容安全、用户取消和受理未知属于临时或不确定事实:它们可以记录为最近观察,但不会把 7 天内的绿色覆盖成红色。只有明确认证或权限失败才会变暗红;移除 API Key 后回到灰色。
24
+ Iris 不做定时后台探测,也不会为了让图标变绿而产生隐形请求或费用。网络错误、5xx、内容安全、用户取消和受理未知不会覆盖近期成功证据。移除 API Key 后回到灰色。
25
+
26
+ ## 限流与耗尽的区别
27
+
28
+ HTTP 状态、供应商错误码和明确错误说明一起决定路由规则,不凭 `quota` 或 `limit` 字样推断额度耗尽。百炼的 `Throttling.AllocationQuota` 也可能表示 TPS/TPM 限制。分类依据见[阿里云错误码说明](https://www.alibabacloud.com/help/zh/model-studio/error-code)。
29
+
30
+ | 响应 | 路由与显示 |
31
+ |---|---|
32
+ | 短时或无法进一步确定的 429,包括频率、并发、服务忙 | 琥珀色“429 冷却中”,暂时跳过;优先遵从 `Retry-After` 秒数或 HTTP 日期,缺失或无效时默认 60 秒 |
33
+ | 403 `AllocationQuota.FreeTierOnly`,或 403/429 明确表示免费额度耗尽 | 红色“额度耗尽已停用”,手动实测成功后才恢复 |
34
+ | 429 `BudgetLimitExceeded` | 红色“预算耗尽已停用”,手动实测成功后才恢复 |
35
+ | 普通 401/403 认证或权限失败 | 保留认证失败语义,不套用额度耗尽停用 |
36
+
37
+ 冷却与停用按 Provider × Model 记录,对同账号该模型的所有能力生效;其他账号的同名模型不受影响。状态持久保存,重启后继续遵守。正常路由、显式生成和 OCR 后续切片都会跳过受阻模型;已受理 Task 仍可观察原远端任务,绝不因此自动重提。
38
+
39
+ 模型池显示原因及冷却恢复时间,实测按钮保持可用。冷却到期只恢复候选资格,不触发验证请求;颜色按原有证据返回蓝色或绿色。发现、修改分配、改 Key/端点、移除再添加同名模型,以及旧任务成功,都不能解除明确耗尽的停用。显式实测只调用指定模型,失败不恢复,成功解除该账号该模型的冷却或停用。视频/转写实测须用 CLI `models test --input` 明确提供真实素材,未提供时跳过,见 [CLI 管理命令](CLI_MANAGEMENT.md)。
23
40
 
24
41
  ## failover 与泡泡汇总
25
42
 
@@ -27,7 +44,7 @@ Iris 不做定时后台探测,也不会为了让图标变绿而产生隐形请
27
44
 
28
45
  1. 任一路候选为绿色,能力为绿色;
29
46
  2. 否则任一路为蓝色,能力为蓝色;
30
- 3. 只有所有已配置候选都为暗红时,能力才为暗红;
47
+ 3. 所有已配置候选均受阻时显示调用受阻;若全部只是冷却,显示琥珀色及最早恢复时间;
31
48
  4. 没有候选时为灰色。
32
49
 
33
50
  主泡泡再按五项能力使用同一保守规则汇总。汇总证据时间只从决定汇总颜色的候选中选择,例如绿色不会显示另一条较新蓝色临时观察的时间。界面同时显示文字和证据时间,不要求用户只凭颜色判断。
@@ -36,4 +53,4 @@ Iris 不做定时后台探测,也不会为了让图标变绿而产生隐形请
36
53
 
37
54
  Host Doctor 只检查 DSH、Iris 注册、Host Port、客户端版本和 UI Slot 是否装载;它零网络、零计费,不能证明 API Key 或具体模型可用。Provider 健康来自模型实测和真实业务请求,才回答供应商侧是否近期成功。离线 `dsh-iris doctor` 则检查本地运行时、配置、存储与任务一致性,三者不能互相替代。
38
55
 
39
- 健康事实保存在 `$DSH_HOME/iris/v1/providers.json`,状态 API 仅返回脱敏标量。错误说明会移除 Authorization、Key、签名参数、私有路径和已配置的完整 API Key。
56
+ 健康事实保存在 `$DSH_HOME/iris/v1/providers.json`;可选 `health.rateLimits` 保存模型、时间、来源、HTTP 状态、冷却截止时间或耗尽原因,沿用 v1 配置,不要求迁移。状态 API 仅返回脱敏标量。错误说明会移除 Authorization、Key、签名参数、私有路径和已配置的完整 API Key。
@@ -0,0 +1,33 @@
1
+ # FakeProvider 生命周期验收器
2
+
3
+ FakeProvider harness 是 Core 的零网络生命周期验收器,不是可配置的正式供应商,也不会出现在用户模型列表中。它以脚本化 fixture 驱动真实 Provider Adapter v0、Core Runtime、Task/Attempt v0 和 Artifact v0,验证远端任务边界而不产生 API 请求或费用。
4
+
5
+ ## 覆盖链路
6
+
7
+ ```text
8
+ Task → 写前 Attempt → submit → accepted → poll
9
+ ├─ pending → 重启 → poll
10
+ ├─ succeeded → download → Artifact
11
+ ├─ failed / unknown / canceled
12
+ └─ cancel → confirmed / unknown
13
+ ```
14
+
15
+ - `submit` 前必须先持久化稳定 Attempt ID;写前失败时 Provider 调用次数为零。
16
+ - 只有明确 `not_accepted` 才能进入下一候选;`accepted` 或 `acceptance_unknown` 后禁止自动重提。
17
+ - 已落盘 `remoteTaskId` 的任务可由新 Runtime 恢复观察;停在 `submitting` 且没有受理结果的记录只能恢复为 `unknown`。
18
+ - Provider 成功与本地交付是两个事实。下载失败保留 `outcome=succeeded`、`deliveryState=failed`;重新交付只执行 `poll/download`。
19
+ - 只有 Provider 明确返回 `canceled` 才记录 `remote_confirmed`;不支持或结果未知均保持 `outcome=unknown`。
20
+ - 取消响应落盘前中断会恢复为未知;待交付或下载中断保留远端成功并标记交付失败,不自动重新生成。
21
+ - 下载 URL 只在单次调用内存中传递,不写入 Task。成功文件进入 Core Artifact,Host URL、DSH attachment 和会话展示不属于 Core 事实。
22
+
23
+ ## 当前限制
24
+
25
+ 每次 `observe` 只轮询一次,不拥有后台 timer;同一 Runtime 内同一 Task 的并发操作以 `IRIS_PROVIDER_TASK_BUSY` 拒绝。该基础 harness 的交付 fixture 只使用一个 `image/png` 产物,不代表产品格式上限;0.2.1 的图片交付支持 PNG/JPEG/WebP,视频、音频和转写使用各自的 Profile 回归。重新交付需有持久化的远端任务 ID。Task v0 尚未迁移 0.1.4 的任务文件,也未形成公开 package export。[Artifact Manifest v0](ARTIFACT_MANIFEST.md) 已实现内容哈希、关系边、索引重建及多产物;Doctor 报告孤立对象,显式清理走可恢复隔离,永久 purge 留待后续。
26
+
27
+ 运行单项验收:
28
+
29
+ ```bash
30
+ node tests/provider-task-runner.mjs
31
+ ```
32
+
33
+ 完整回归仍使用 `npm test` 和 `npm run lint`。
@@ -53,8 +53,8 @@ Provider `submit()` 必须返回以下四种结构之一:
53
53
 
54
54
  ## 当前接入边界
55
55
 
56
- `lib/provider-contract.js`、Task v2 复制落盘原语和零网络 Fake Provider 已冻结本契约。完整图片能力现在都会在请求前写入 Attempt:DashScope 旧异步返回远端 ID 后进入观察;DashScope 新同步与 OpenAI Images 的成功响应记为 `completed/accepted`,随后独立推进本地产物交付。异步与同步候选可以在同一个 Task 中安全切换。
56
+ `lib/provider-contract.js`、Task v2 复制落盘原语和零网络 Fake Provider 已冻结本契约。完整图片能力现在都会在请求前写入 Attempt:DashScope 旧异步返回远端 ID 后进入观察;DashScope 新同步、OpenAI Images、聊天生图与 Responses 生图的有效成功响应记为 `completed/accepted`,随后独立推进本地产物交付。异步与同步候选可以在同一个 Task 中安全切换。
57
57
 
58
58
  429 等可证明未创建任务的明确 4xx 拒绝可进入下一候选;408、409、425、499、5xx、网络异常、超时和成功响应缺少必要结果一律停止并记录 `acceptance=unknown`。同步生成已经成功后,下载或落盘失败记录为 `outcome=succeeded / deliveryState=failed`,不会重新生成。
59
59
 
60
- 视频、转写与 TTS 也使用相同边界:视频和转写分别持久化 `prepare/upload/submit` stage,上传失败只表示生成请求未受理;TTS 同步成功则先记 `completed/accepted` 再交付音频。工作台消费稳定的人类状态,并提供重新观察、重新交付、提醒已读/恢复和需确认费用的知情重试。v0.1.4 已将 discovery、submit、poll、cancel、download 与 error mapping 收口到统一 Adapter,并由零网络 conformance runner 覆盖现有 DashScope/OpenAI Images 路径。
60
+ 视频、转写与 TTS 使用同一受理边界,但提交前输入准备不自动成为 Core 事实。0.2.1 的 S2V 先持久化 Core Attempt,再按实际候选账号上传首帧和音频;上传失败保存安全错误,零生成 submit。Core 转写的 `audio_path` 在 Host/CLI 边界先上传,失败以脱敏的 `stage=upload / acceptance=not_accepted` 返回调用方,零 submit、零 Core Task。准备成功后才创建 Core Task/Attempt 并进入写前 submit;TTS 同步成功则先记 `completed/accepted` 再交付音频。工作台消费稳定的人类状态,并提供重新观察、重新交付、提醒已读/恢复和需确认费用的知情重试。v0.1.4 已将 discovery、submit、poll、cancel、download 与 error mapping 收口到统一 Adapter,并由零网络 conformance runner 覆盖现有 DashScope/OpenAI Images 路径。
package/docs/ROADMAP.md CHANGED
@@ -1,110 +1,76 @@
1
1
  # 路线图
2
2
 
3
- dsh-iris 已具备媒体生成、视觉处理和任务管理主流程。长期方向是宿主无关的多模态生产运行时,DSH 是首个受支持宿主。当前仍通过 DSH 插件使用,独立 Core、CLI 和工作台尚未实现。
4
-
5
- 变更详情见[变更记录](../CHANGELOG.md),完整工具清单见[README](../README.md)。
3
+ Iris 正从 DSH 媒体插件演进为可独立运行、可接入不同 Agent 宿主的媒体生产核心。本文列当前状态与后续方向;版本变化见 [变更记录](../CHANGELOG.md)。
6
4
 
7
5
  ## 当前状态
8
6
 
9
- 现有功能包括:
10
-
11
- - 图像、视频、语音生成和音频转写
12
- - 看图问答、OCR、定位、裁剪与像素比较
13
- - 视频抽帧和多模态摘要
14
- - 多供应商模型池与复合模型身份
15
- - 浏览器上传、会话附件和宿主路径输入
16
- - 异步任务恢复、取消传播、SSE 状态更新和授权媒体链接
17
- - 独立作品库 v0:清任务历史后仍可浏览媒体,并可重新索引旧 `outputs/`
18
- - 面向 Agent 与用户的统一视频生成实现
19
- - 两个随包 Agent Skills:UI 视觉验收与多步骤媒体编排;0.1.2 会在插件启用时自动注册
20
-
21
- 当前发布版本为 `v0.1.3`。0.1.1 完成配置独立、安全与工程收口,并把 Web loader 适配固定到已验证的 DSH `0.1.2-rc.1` 接口;0.1.4 把已验证支持窗口扩展为 `>=0.1.2-rc.1 <0.1.3-0` 与 `0.1.5-rc.1`,其余预览版在进入支持范围前仍需重新运行宿主 canary。
7
+ 当前版本为 **Iris 0.2.1**。包名保持 `@mokuyoaxis/dsh-iris`,同时提供 DSH 插件与无 DSH 的 Headless CLI。功能范围见 [0.2.1 发布说明](releases/0.2.1.md)。
22
8
 
23
- ## 已完成:0.1.1
9
+ 0.2.1 的更新重点是 **完成 OpenAI 兼容图片与视觉工作流**:生成图片 → Core Artifact → 按 ID 看图/OCR → 聊天改图 → 新 Artifact,CLI 与 DSH 工作台共用同一链路。本版已实现以下能力:
24
10
 
25
- ### 配置独立与工程收口
11
+ - 图片生成按模型选择 DashScope、OpenAI Images、聊天生图或 Responses 协议,PNG/JPEG/WebP 按真实字节交付;
12
+ - Artifact ID 看图、OCR、定位,以及“来源 Artifact → 聊天改图 → 新 Artifact”的关系与引用保护;
13
+ - 共享视觉预算、长图分块、取消与完整终态检查;账号/模型输入预算只处理发送副本,定位坐标映射回原图;
14
+ - 图片、视频、S2V、语音、转写与本地处理的 Core 任务链,独立视觉 CLI、HTML 截图及完整配置/查询/维护命令;
15
+ - 工作台统一 Core/旧版全媒体分页过滤,跨页选择、ZIP 下载、详情及 Core 可恢复隔离/恢复;
16
+ - 短时 429 琥珀冷却、明确额度或预算耗尽红色停用,以及既有提示词泡泡的按次规则和可编辑预览。
26
17
 
27
- - 对齐公开文档和已发布标签,明确当前能力与未来方向。
28
- - Iris 独立保存配置;ai-paint 仅作为维护者未公开的本地前身和可选迁移来源,不是用户依赖。停止默认读取,仅保留显式指定本地来源的一次性安全导入。
29
- - 用 Node.js 调度测试,去除对 POSIX Shell 循环的依赖。
30
- - 绑定供应商凭据与协议端点,统一私有存储权限和流式原子落盘,并验证损坏配置恢复。
31
- - 将付费能力实测改为单项显式确认,视频与转写不做空样本自动探针。
32
- - 默认将 Iris HTTP 路由限制在回环 Host,为反代提供显式信任列表和认证部署说明。
33
- - 增加 Linux/Windows 与 Node.js 20.10/22 CI 矩阵、发布前测试护栏,并以当前 DSH 预览版完成宿主烟测。
34
- - 核对打包清单,记录真实环境和未验证平台。
18
+ CLI 与 DSH 共用 Task、Attempt、Artifact 和 Command Service;Host 负责会话、附件、浏览器与 UI。纯视觉和提示词预览消费共享 Model Ports,不自动创建媒体 Task/Artifact。受理未知不会自动重提,同一数据根只允许一个 writer。Core 与 Model Port 内部接口尚未冻结为公共 SDK,详见 [Core 迁移](DSH_CORE_MIGRATION.md)、[CLI](HEADLESS_CLI.md) 和 [Artifact Manifest](ARTIFACT_MANIFEST.md)。
35
19
 
36
- ## 已完成:0.1.2
20
+ Node.js 最低版本保持 22.0.0,DSH 插件只声明支持准确的 `0.2.0-rc.2`。旧 DSH `>=0.1.2-rc.1 <0.1.3-0` 或 `0.1.5-rc.1` 继续固定安装 Iris `0.1.4`;其他宿主版本需独立验收。第二个真实 Host Adapter 完成并验收后再安排仓库与 npm 包更名,CLI、测试 fixture 与媒体 Provider 不算第二个 Host Adapter。
37
21
 
38
- ### 可见、可达与唯一身份
22
+ ## 近期优先:真实使用验收
39
23
 
40
- - 保留 npm 包名 `@mokuyoaxis/dsh-iris`,以 “Iris Media for DSH” 作为展示名,并使用唯一 Cordis 行 ID 避免与另一款 `dsh-iris` 同装冲突。
41
- - 插件启用时自动注册两项随包 Skill,不要求用户克隆仓库、切换 cwd 或修改默认 Skill 搜索目录。
42
- - 中英文 README 直接展示已脱敏的 Android 真机截图与代表性生成图,完整流程保留独立画廊;根目录 `screenshots.json` 控制插件市场展示顺序。
43
- - 在 DSH 对话输入框提供可独立关闭的无框 🫧 提示词优化入口:使用半透明玻璃悬浮窗和窄屏底部面板,支持当前会话/固定模型路由、独立 thinking 策略与保守输出预算、预览写回,以及 JSON 导入导出和恢复默认。
44
- - 泡泡快捷历史只展示运行中任务与成功产物;功能状态灯不再依赖用户逐张点开卡片。
45
- - 本版不新增供应商分支,也不声称已完成独立 Core、任务语义 v2 或离线诊断。
24
+ 0.2.1 的发布检查覆盖完整测试、lint、实际 tarball、敏感信息、仓库外安装与跨平台 CI。服务层与包安装验收之外,近期优先补齐真实浏览器/移动端及异步重启使用证据。
46
25
 
47
- ## 下一步
26
+ 工作台两轮功能已实现;第三轮仍需补浏览器/移动端的筛选、分页、跨页选择、识别、改图、下载及回收区使用验收,以及真实异步任务重启后的 CLI 接管。已有真实图片生成、按 ID 看图和聊天改图链路验证,完整会话与重启范围继续以 [验证说明](DSH_CORE_MIGRATION.md#验证证据与限制) 为准。提示词优化系统的后续设计单独安排,不扩入本次发布。
48
27
 
49
- ### 已完成:0.1.3 可信任务
28
+ DSH 工作台与 Headless CLI 均复用 Core 的引用保护、可恢复隔离和恢复命令;legacy `outputs/` 的永久删除仍由旧工作台处理。两种删除语义与已实现的作品管理见 [工作台作品管理](WORKBENCH_ARTIFACTS.md)。
50
29
 
51
- - 图片、视频、转写与 TTS 已接入 Task/Attempt v2;只有明确未受理才允许自动 failover。
52
- - 零网络故障矩阵已覆盖受理未知、轮询耗尽、取消、重启、交付、SSE 与人工接管。
53
- - 提供重新观察、重新交付、提醒已读/恢复和知情重试,并防止重复提醒与错误旧任务标记。
54
- - 提供零网络离线 Doctor、公开任务/架构/安全契约,以及 Linux/Windows CI 与 Android 真机短验。
30
+ ## 后续功能方向
55
31
 
56
- ### 当前开发:0.1.4 适配边界与 Agent 易用性
32
+ ### 后续 0.2.x
57
33
 
58
- - 冻结 [Host Adapter v0](HOST_ADAPTER_CONTRACT.md) 与 Command × Host Port 矩阵,提供无 DSH 的 Local Host fixture;DSH Adapter 已收口工具、路由、附件、会话、Browser、模型、Skill 与客户端 Slot 消费者,并通过 `0.1.2-rc.1` 隔离 canary 与 `0.1.5-rc.1` 日常宿主实测。
59
- - 已实现 [Provider Adapter v0 完整生命周期](PROVIDER_ADAPTER_CONTRACT.md) 和零网络 conformance runner;现有 DashScope/OpenAI Images 兼容实现、Task 恢复与重新交付均消费统一契约,本版不新增 Provider。
60
- - 已实现 [Host Doctor](HOST_DOCTOR.md):观察插件、14 个工具、2 项 Skill、4 组路由、Browser/附件/模型能力、客户端版本与 UI Slot;只读取安全快照和注册证据,默认零网络、零计费。
61
- - 已实现 [Provider 与能力健康状态](PROVIDER_HEALTH.md):按 Provider × Model × Capability 持久化实测/真实任务证据,以灰、蓝、绿、暗红四色及时间呈现,并按当前 failover 候选保守汇总;不增加后台探测。
62
- - 深化现有 `iris-verify-ui`、`iris-compose-media` 两项 Skill:对齐 Task v2、增加显式调用示例、渐进资源与行为 eval;不以增加 Skill 数量为目标。
63
- - 增加最小作品库索引,但继续采用渐进迁移;本版不引入完整 Artifact Manifest、standalone 服务、完整 headless 命令集或大规模目录重写。
34
+ - 适配其他协议,包括原生 Gemini、Fal 和后续 Replicate;网关兼容接口与原生协议接入分别验证;
35
+ - Music 音乐生成:接入音乐生成模型,复用 Core 任务、Artifact 和作品管理;具体协议、模型与入口后续确定,不纳入 0.2.1;
36
+ - 收藏、标签与工作台搜索(CLI 及工作台过滤、分页、显式选择/批量下载已完成);
37
+ - Artifact 关系边冻结 `retried-from` 类型,补全重试谱系(0.2.0 仅有 Task 级 `retriedFrom`);
38
+ - Core 隔离内容的永久 purge(0.2.1 已开放可恢复隔离/恢复,legacy 永久删除保持原行为);
39
+ - 鸢尾花与泡泡视觉身份;
40
+ - 有可用接口与实际需求后,补 Images 编辑、mask、多参考图或连续编辑;
41
+ - 将提示词优化收口为 Core Prompt Engine 与共享 `prompt.optimize` Command,由 CLI 和 DSH 入口共同消费;DSH 只负责草稿读取、预览和写回;
42
+ - 冻结中立 TextModel Port,把 Ollama、兼容文本端点及其他文本模型后端与媒体 Provider Catalog 分离,避免通用文本模型淹没 Iris 媒体模型界面;
43
+ - 接入 ComfyUI、本地 TTS 等本地媒体 Provider,并补齐 `auth: none`、`billing: none`、同步完成语义和本地/远程 UI 区分;
44
+ - 有可信价格来源后的成本与策略展示。
64
45
 
65
- ### 0.2.0:独立 Core 与产物记录
46
+ ### 0.3 及以后
66
47
 
67
- - 统一 Agent、工作台与 CLI 的命令执行核心,将 DSH 集成集中到宿主适配器。
68
- - 将作品库 v0 升级为经安全评审的 Artifact Manifest,为产物保存内容哈希、来源和派生关系,支持检查与导出。
69
- - 在完整 Manifest 上增加收藏、标签、搜索、筛选和批量导出,不把这些字段塞回任务历史。
70
- - 在未安装 DSH 的干净环境完成本地动作和供应商任务验收。
71
- - 建立 Iris 正式产品视觉身份:以简约鸢尾花和泡泡为核心母题,完成可缩放 Logo、图标、单色版与深浅色适配,并替换临时字标。
72
- - 在统一 Provider Adapter 与 conformance 测试稳定后,依次接入 Gemini、Fal,并把 Replicate 排入后续 0.2.x。
73
-
74
- ### 后续方向
75
-
76
- - 0.3:有界、可恢复的媒体工作流,以及用户显式启动的本地 API 和最小独立工作台。
77
- - 0.4:根据真实消费者需要开放供应商和宿主适配契约。
78
- - 1.0:冻结经过验证的公共契约和升级策略。版本表示目标聚合点,不代表发布日期承诺。
48
+ - `0.3`:Recipe、可恢复 Flow、显式启动的本地 API 和最小独立工作台;
49
+ - `0.4`:在有真实消费者后公开 Provider/Host SDK;
50
+ - `1.0`:冻结经过多宿主和升级验证的公共契约。
79
51
 
80
52
  ## 兼容性与限制
81
53
 
82
- - Node.js 最低版本为 20.10。
83
- - 图片处理依赖 `sharp`,非标准 libc 或移动终端环境可能没有可用的预编译包。
84
- - 视频抽帧与视频摘要依赖 `ffmpeg` 和 `ffprobe`。
85
- - WSL、远程浏览器和容器部署应优先使用上传或会话附件,避免混淆浏览器路径与宿主路径。
86
- - HTML 截图运行在离线沙箱中,远程资源和页面脚本不可用。
87
- - 模型发现只能列出候选项,具体能力需要通过实际请求确认。
88
- - Node 测试调度器不依赖 Bash,Linux/Windows × Node.js 20.10/22 自动化矩阵已经通过;原生 Windows/WSL 的 DSH 宿主实机冒烟仍待补充。
54
+ - Iris 0.2.x 的 Node.js 最低版本为 22.0.0;DSH 要求更高版本时以 DSH 为准。
55
+ - 图片处理依赖 `sharp`;视频文件抽帧依赖 `ffmpeg`、`ffprobe`,摘要复用既有 Core 帧时无需这两个工具。独立 HTML 截图需要显式提供 Chromium。
56
+ - DSH 仍处于快速演进期。单个 Host Port 可以降级,但 DSH 若改变插件加载协议,仍需更新 DSH Adapter。
57
+ - 模型发现只列出候选项;真实能力必须由用户显式验证。
58
+ - 原生 Windows/WSL 的完整 DSH 宿主冒烟仍待补充。
59
+ - Headless CLI 的媒体、视觉、S2V、HTML、配置、查询、批量、有界等待与 Core 隔离/恢复见 [CLI 管理](CLI_MANAGEMENT.md)。需要存储时显式指定绝对数据根,观察和等待不重新提交;Core 永久 purge 尚未开放。
60
+ - Responses 只支持同步单图;聊天改图只支持一张静态来源图片,输出尺寸与编辑精度由模型决定。
89
61
 
90
62
  ## 质量要求
91
63
 
92
- 计划中的改动应满足以下条件:
93
-
94
- - `npm test` 通过,并为新增行为补充有针对性的测试。
95
- - 不泄露供应商密钥、宿主绝对路径或未授权媒体内容。
96
- - 不在远端任务受理后自动重提生成请求。
97
- - 不让局部配置更新覆盖未修改字段。
98
- - 在支持的平台上保持 Agent 工具与工作台行为一致。
99
- - 发布前检查 npm 包内容和公开文档中的相对链接。
64
+ - 已受理或受理未知的远端任务不得自动重提。
65
+ - 同一数据根不得出现两个写者;reader 不产生隐式写入。
66
+ - Core/CLI 在 DSH/Cordis 不可解析时仍能装载和运行本地动作。
67
+ - Task、Attempt 和 Artifact 不保存凭据、私有 URL 或不必要的宿主绝对路径。
68
+ - 每项新增行为需有失败路径测试;发布前执行打包、敏感信息和仓库外安装检查。
100
69
 
101
70
  ## 暂不计划
102
71
 
103
- - 在插件内实现账号、权限或多租户系统。
104
- - 接管 DeepSeek Harness 的通用聊天模型配置。
105
- - 由 DSH 插件隐式启动独立后台服务或额外监听端口。
106
- - 在本地工作台阶段建设公网 SaaS、组织账号和多租户系统。
107
- - 自动探测全部模型能力并触发可能计费的请求。
108
- - 仅为未来可能使用的供应商预建没有调用方的适配层。
109
- - 为 0.1.2 临时接入尚无统一契约与测试基线的新供应商。
110
- - 为展示效果伪造实机截图、生成结果或短视频证据。
72
+ - 在插件中建设账号、多租户、计费或公网 SaaS;
73
+ - 由 DSH 插件隐式启动 daemon 或额外监听端口;
74
+ - 自动探测全部模型并产生不可见费用;
75
+ - 为没有真实调用方的 Provider 或 Host 预建空适配器;
76
+ - 在 Core 稳定前拆分多个 npm 包或重写技术栈。
package/docs/SECURITY.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Iris 安全边界
2
2
 
3
- 状态:v0.1.4 候选实现。安全目标是避免凭据泄露、路径越权、跨站写入和因错误重试造成重复计费;Iris 与 DSH 仍是本机同一信任域内的预览软件,不构成多租户安全边界。
3
+ 状态:Iris 0.2.1 安全边界。安全目标是避免凭据泄露、路径越权、跨站写入和因错误重试造成重复计费;Iris 与 DSH 仍是本机同一信任域内的预览软件,不构成多租户安全边界。
4
4
 
5
5
  ## 信任模型
6
6
 
@@ -28,15 +28,16 @@ API、SSE 和 Doctor 只返回凭据存在性或掩码提示。Provider 错误
28
28
  - “知情重试”必须单独确认可能重复任务或重复计费,并创建带 `retryOf/manualRetries` 关系的新 Task。创建后只归档原提醒,不改写原任务的未知事实;当前只对能从安全记录无损重建的文生图和文生视频开放,文件型输入和截断文本要求用户从原始输入重新发起。
29
29
  - “标为已读/恢复提醒”只操作有界的本地 `attentionEvents` 审计元数据,不发送网络请求,也不把用户处置等同于供应商已经受理。
30
30
  - Iris 当前没有凭空假设 DashScope 的远端取消协议。停止本地观察后若远端结果无法确认,状态保持 unknown。
31
- - Provider 健康不做后台探测。只有 401、403 或明确认证/权限分类可变为暗红;429、网络、5xx、内容安全、取消与未知受理不得覆盖近期成功或授权自动重提。
31
+ - Provider 健康不做后台探测。普通认证/权限失败为暗红;短时 429 以琥珀色冷却,优先遵从 `Retry-After`,默认 60 秒,到期只恢复候选资格。明确免费额度或预算耗尽以红色持续停用至手动实测成功,记录按账号和模型隔离。网络、5xx、内容安全、取消与未知受理不覆盖近期成功;任何健康变化均不授权自动重提已受理任务。
32
32
 
33
33
  ## 文件、上传与媒体访问
34
34
 
35
35
  - 浏览器上传使用大小上限、随机文件名、`.part` 临时文件和完成后的原子改名;中断时清理临时文件,过期副本按 TTL 回收。
36
36
  - 输出文件名由 Iris 生成或通过 `basename` 收口,API 不返回宿主绝对路径。
37
- - 媒体播放链接使用随机能力令牌。令牌应视为临时访问凭据,不应发布到公网。
38
- - 清理任务元数据默认不删除作品;独立作品索引不保存 Prompt、Provider、Model 或任务关系。
39
- - 删除单件作品、清空作品库或删除真正的孤儿文件都需要独立确认。作品删除会保留任务历史,但旧媒体链接将失效。
37
+ - legacy 任务与独立作品的媒体链接使用随机 128-bit 能力令牌。令牌应视为临时访问凭据,不应发布到公网。
38
+ - Core 媒体路由 `/iris/api/core/artifact/<artifact_id>/media` **没有独立 token**。它使用随机 96-bit Artifact ID 作为不可猜测的持有者标识,并叠加默认回环/显式 trusted Host、浏览器 `Origin`/`Sec-Fetch-Site` 拒绝跨站、`Cross-Origin-Resource-Policy: same-origin`、`Referrer-Policy: no-referrer` 与每次 SHA-256 校验。任何能访问受信 Host 且持有 Artifact ID 的客户端都能读取对应媒体;`IRIS_TRUSTED_HOSTS` 不是身份认证。不要把 Core Artifact ID 或媒体 URL 发布到不受信任位置。
39
+ - 清理任务元数据默认不删除作品;legacy 独立作品索引不保存 Prompt、Provider、Model 或任务关系;Core Manifest 保存中性元数据、SHA-256 和来源/派生关系,不保存凭据或私有下载 URL。
40
+ - legacy 删除单件作品、清空作品库或删除真正的孤儿文件都需要独立确认,会保留任务历史,但旧媒体链接将失效。0.2.1 Core 删除使用可恢复隔离,任务/产物引用会阻止删除;同时移除关联的已结束任务记录需要明确选择和确认,恢复不会覆盖冲突文件。见 [工作台作品管理](WORKBENCH_ARTIFACTS.md)。
40
41
  - 符号链接不会被私有树权限收紧逻辑跟随。Doctor 会把 Iris 数据根为符号链接视为硬错误。
41
42
 
42
43
  ## Web 与渲染
@@ -48,9 +49,9 @@ API、SSE 和 Doctor 只返回凭据存在性或掩码提示。Provider 错误
48
49
 
49
50
  ## 离线 Doctor
50
51
 
51
- `dsh-iris doctor` 不启动 DSH,不发送供应商或计费请求,也不打印 API Key。它会在 Iris 数据目录或最近可写父目录创建一个随机小文件并立即删除,用于验证真实写权限。`--json` 与文本输出使用同一结果模型,退出码为:`0` 正常、`1` 有警告、`2` 有硬错误。
52
+ `dsh-iris doctor` 不启动 DSH,不发送供应商或计费请求,也不打印 API Key。默认 DSH 模式会在 Iris 数据目录或最近可写父目录创建一个随机小文件并立即删除,用于验证真实写权限;显式 `--data-root <abs>` Core 模式只读检查指定根的结构、索引、任务和租约,不做写探针,也不自动释放租约。`--json` 与文本输出使用同一结果模型,退出码为:`0` 正常、`1` 有警告、`2` 有硬错误。
52
53
 
53
- Doctor 不能证明 DSH 工具注册、浏览器、附件服务、客户端资源或真实 Provider 在线;这些属于后续 Host 扩展诊断。
54
+ Doctor 不能证明 DSH 工具注册、浏览器、附件服务、客户端资源或真实 Provider 在线;这些仍需各自验证。
54
55
 
55
56
  ## 报告问题
56
57
 
@@ -1,6 +1,6 @@
1
1
  # Iris Task/Attempt v2 语义契约
2
2
 
3
- 状态:**v0.1.3 已实现;v0.1.4 Host/Provider Adapter、Host Doctor 与作品库 v0 已接入。** Task v2 已覆盖图片、视频、转写与 TTS,包括同步/异步、上传/提交、混合协议候选、工作台稳定用户态、状态流防倒退、重新观察、重新交付、提醒已读/恢复和知情人工重试。作品库 v0 只分离本地作品生命周期;正式 Artifact Manifest 仍属于后续工作。
3
+ 状态:**v0.1.3 已实现;v0.1.4 Host/Provider Adapter、Host Doctor 与作品库 v0 已接入。** Task v2 已覆盖图片、视频、转写与 TTS,包括同步/异步、上传/提交、混合协议候选、工作台稳定用户态、状态流防倒退、重新观察、重新交付、提醒已读/恢复和知情人工重试。本文的 Task v2 字段描述 legacy 任务,不等同于 Core DTO。作品库 v0 分离旧本地作品生命周期;0.2.0 已实现 Core Task/Attempt 与 Artifact Manifest,0.2.1 的媒体、聊天改图和维护入口共享 Core 事实,见 [Core Runtime](CORE_RUNTIME_CONTRACT.md)。
4
4
 
5
5
  ## 1. 为什么需要 v2
6
6
 
@@ -144,5 +144,5 @@ Task v2 至少包含以下事实轴;字段值采用可序列化的 snake_case
144
144
 
145
145
  - 不在语义冻结阶段重写全部任务存储或 UI。
146
146
  - 不新增 Gemini、Fal、Replicate 等供应商分支。
147
- - v0.1.3 包含零网络、可独立运行的离线 Doctor v0 与最薄 CLI;v0.1.4 已接入 Host/Provider Adapter、Host Doctor 和不含谱系的作品库 v0。完整 Artifact Manifest 仍属于后续版本。
147
+ - v0.1.3 包含零网络、可独立运行的离线 Doctor v0 与最薄 CLI;v0.1.4 已接入 Host/Provider Adapter、Host Doctor 和不含谱系的作品库 v0。0.2.0 已实现 [Core Artifact Manifest](ARTIFACT_MANIFEST.md),0.2.1 补齐共享 CLI/DSH 消费与编辑关系;两种存储保持独立。
148
148
  - 不用更多自动重试换取表面成功率。
@@ -0,0 +1,132 @@
1
+ # 独立视觉 CLI
2
+
3
+ 状态:**Iris 0.2.1**。安装 `npm install @mokuyoaxis/dsh-iris@0.2.1` 后运行 `npx dsh-iris ...`,或从源码运行 `node bin/dsh-iris.js ...`。需要 Node.js ≥ 22、已有依赖 Sharp;从视频文件抽帧还需要 PATH 中的 ffmpeg、ffprobe,复用既有 Core 帧不需要。
4
+
5
+ ## 四个命令
6
+
7
+ 所有命令必须显式提供私有配置文件,媒体文件使用绝对路径;看图/定位/OCR 也可指定 Core 图片 ID,摘要可指定 Core 帧 ID,并提供数据根。下面假设配置位于 `/absolute/path/providers.json`,图片和视频路径也需替换:
8
+
9
+ ```bash
10
+ dsh-iris vision look \
11
+ --provider-config /absolute/path/providers.json \
12
+ --input '{"image_path":"/absolute/path/image.png","question":"画面中有什么?"}'
13
+
14
+ dsh-iris vision locate \
15
+ --provider-config /absolute/path/providers.json \
16
+ --model-ref 'aliyun::qwen3-vl-flash' \
17
+ --input '{"image_path":"/absolute/path/image.png","target":"红色方块"}'
18
+
19
+ dsh-iris vision ocr \
20
+ --provider-config /absolute/path/providers.json \
21
+ --input '{"image_path":"/absolute/path/screenshot.png","chunk_height":1200,"overlap":120}' \
22
+ --format text --output ./recognized.txt
23
+
24
+ dsh-iris vision summarize \
25
+ --provider-config /absolute/path/providers.json \
26
+ --input '{"video_path":"/absolute/path/clip.mp4","max_frames":8,"question":"总结视频内容"}' \
27
+ --output ./summary.json --sheet-output ./contact-sheet.png
28
+ ```
29
+
30
+ `look` 的 `question` 可省略,默认用中文描述画面。`locate` 要求非空 `target`,返回原图像素 `bbox` 或 `{found:false}`,同时提供原图尺寸和 `input` 图片事实。模型被明确要求使用 0–1000 归一化坐标;返回结果已换算、处理 EXIF 方向并向外取整,可直接用于原图裁剪。定位结果取决于模型判断。
31
+
32
+ `ocr` 默认块高 1200、重叠 120、最大宽度 2048,可用 `chunk_height`、`overlap`、`max_dimension`、`max_invocations` 调整;沿用 [OCR](OCR_MODEL.md) 的限制,最多 32 块和 64 次生成。各切片再应用实际模型的 `visionInput`。返回 `complete` / `partial` / `failed`、成功/失败/未处理块数、每块状态与 `fullText`,保留原段号;成功块的 `input.source/sent` 记录切片与实际发送图的宽高、字节数和 MIME。文本格式会提示缩小导致的细字风险;失败块正文不会混入识别全文。
33
+
34
+ `summarize` 默认均匀取 8 帧,`max_frames` 最多 20;`target_width` 默认 640,按源图比例缩放。每次视觉候选调用只发送一张带时间戳的 PNG 拼图,`--sheet-output` 保存的就是该图片。JSON 仅包含拼图尺寸、MIME 和 SHA-256,不包含图片 base64 或本机路径。
35
+
36
+ ## 直接使用 Core 图片
37
+
38
+ `look`、`locate`、`ocr` 均接受 `artifact_id`,与 `image_path` 二选一。ID 可来自生成图片、裁剪、HTML 截图、视频抽帧等 Core 产物;用 `artifact list --data-root ... --media-type image/png` 查找,或从已有命令结果取得真实 ID。
39
+
40
+ ```bash
41
+ dsh-iris vision look \
42
+ --provider-config /absolute/path/providers.json \
43
+ --data-root /absolute/path/iris-core \
44
+ --input '{"artifact_id":"artifact_0123456789abcdef01234567","question":"画面中有什么?"}'
45
+
46
+ dsh-iris vision locate \
47
+ --provider-config /absolute/path/providers.json \
48
+ --data-root /absolute/path/iris-core \
49
+ --input '{"artifact_id":"artifact_0123456789abcdef01234567","target":"发送按钮"}'
50
+
51
+ dsh-iris vision ocr \
52
+ --provider-config /absolute/path/providers.json \
53
+ --data-root /absolute/path/iris-core \
54
+ --input '{"artifact_id":"artifact_0123456789abcdef01234567","chunk_height":1200,"overlap":120}' \
55
+ --format text --output ./recognized.txt
56
+ ```
57
+
58
+ 示例 ID 需替换成实际 ID。读取核验 Core 内容哈希,使用 Manifest 的 MIME 和图片原字节,支持最多 20 MiB 的 PNG/JPEG/WebP/GIF,不限制图片的 `kind`。看图、OCR 每块和定位按实际账号/模型准备发送副本,默认 8 MiB;超预算 PNG/JPEG/WebP 等比缩小并保留格式,原图及下载字节不变。可配置大小与最长边,见 [视觉输入预算](CLI_MANAGEMENT.md#看图输入预算)。定位返回原像素坐标;OCR 保留单帧、像素/分块上限与部分完成语义。JSON 结果(含 OCR 部分结果)附 `artifactId`。
59
+
60
+ 这三个命令只以 reader 打开显式数据根,不需要原图片文件、不导出临时图片、不创建 Task/Artifact,也不取得 writer 租约。缺失、损坏、非图片或超限 Artifact 在调用模型前拒绝;缺失的数据根不会被创建。文件输入用法不变。
61
+
62
+ ## 复用已保存的 Core 帧
63
+
64
+ 先用 `media frames --data-root ... --input ...` 抽帧,从结果的 `artifacts[].id` 取 ID;也可用 `artifact list --data-root ... --kind video-frame` 查找。将同一视频中要分析的帧直接传给摘要:
65
+
66
+ ```bash
67
+ dsh-iris vision summarize \
68
+ --provider-config /absolute/path/providers.json \
69
+ --data-root /absolute/path/iris-core \
70
+ --input '{"frame_artifact_ids":["artifact_0123456789abcdef01234567","artifact_89abcdef0123456789abcdef"],"question":"总结这些片段"}' \
71
+ --output ./summary.json --sheet-output ./contact-sheet.png
72
+ ```
73
+
74
+ 示例 ID 需替换成实际 ID。`video_path` 与 `frame_artifact_ids` 必须二选一;帧 ID 数组为 1–20 个不同的 `video-frame` Artifact,读取时核对其内容哈希、帧序号、时间戳和尺寸,按 `atSec`、`frameIndex` 排序。可以只选择部分帧,结果 `frames[]` 保留实际使用的 `artifactId`、原 `frameIndex`、`atSec`、尺寸;`meta.source` 为 `core-artifacts`,`startSec` / `endSec` 是所选帧覆盖的时间范围,不代表完整视频时长。
75
+
76
+ 此模式只读 Core,不要求原视频或 ffmpeg,不导出临时副本、不新增 Task/Artifact;其他进程持有 writer 租约时仍可读取。`max_frames`、`target_width` 只用于视频文件模式,已有帧需直接选择 ID。已有帧不自动提取音轨,可用 `transcribe_text` 提供已有文字;`transcribe:true` 需要视频文件模式。
77
+
78
+ ## 配置和模型选择
79
+
80
+ 配置沿用 Iris Provider 文件,不执行配置迁移或模型发现。文件必须为普通文件,POSIX 权限限制为当前用户可读写(例如 `chmod 600 providers.json`)。可以直接只读使用已有 Iris 配置;不会推断 DSH_HOME、HOME 或当前目录。
81
+
82
+ 最小结构如下,`apiKey` 由你在私有文件中设置,不放在命令参数中:
83
+
84
+ ```json
85
+ {
86
+ "providers": [{
87
+ "id": "aliyun",
88
+ "type": "openai",
89
+ "enabled": true,
90
+ "baseUrl": "https://dashscope.aliyuncs.com/compatible-mode/v1",
91
+ "apiKey": "你的密钥",
92
+ "models": [{"id": "qwen3-vl-flash", "capabilities": ["vision"]}]
93
+ }],
94
+ "assignments": {"vision": ["aliyun::qwen3-vl-flash"]}
95
+ }
96
+ ```
97
+
98
+ 省略 `--model-ref` 时按 `assignments.vision` 排序,再以配置模型池补齐。只有本地不可用、明确拒绝或正常空正文才允许下一候选;截断、未知终态、收到正文后的失败、取消和超时停止调用。显式 `--model-ref providerId::modelId` 严格只绑定该账号与模型,失败不会替换;新视觉命令不接受裸模型名。模型需启用并声明 `vision` 能力,未配置时直接失败。当前自持视觉端口支持 OpenAI-compatible Chat Completions SSE,不追加 DSH 宿主候选。
99
+
100
+ 成功 JSON 携带实际 `modelRef`、`selectionReason`(`explicit` / `assignment` / `pool`)、模型身份、正常终态及可用的 usage。OCR 的实际选择保留在每个成功块上。配置凭据、端点和原始错误响应不会出现在诊断中;模型回答和 OCR 正文是用户内容。
101
+
102
+ ## 输出、预算与退出码
103
+
104
+ 默认 `--format json`,`--format text` 输出看图/摘要正文、定位 bbox JSON 或带完成状态的 OCR 文本。stdout 始终返回相同格式,`--output` 同时保存该结果。输出文件允许相对路径,父目录必须存在;已有文件不会覆盖。仅摘要支持 `--sheet-output`。两份文件逐个排他写入,不提供多文件事务;若第二份保存失败,第一份可能已经保存。
105
+
106
+ 默认一次操作共用 120 秒,`--timeout-ms 1..120000` 可缩短。预算覆盖文件读取、图像准备、抽帧、可选转写等待与全部视觉候选。Sharp 原生操作和同步 ffprobe 无法强制中断,取消后不会继续消费结果生成;可取消的网络请求与 ffmpeg 会收到信号。每次视觉正文上限 6000 字、输入图片最多 20 MiB,沿用共享端口的正常终态检查。
107
+
108
+ 退出码:成功为 `0`;模型、配置、输入错误或 OCR 部分完成/失败为 `1`;命令参数/输出路径错误为 `2`;SIGINT / SIGTERM 为 `130` / `143`。OCR 部分完成仍输出结构化结果,脚本应同时检查退出码与 `status`。
109
+
110
+ ## 摘要中的音轨
111
+
112
+ 默认只分析画面,不自动转写。已有转写可用 `transcribe_text` 显式提供,不产生任务:
113
+
114
+ ```bash
115
+ dsh-iris vision summarize \
116
+ --provider-config /absolute/path/providers.json \
117
+ --input '{"video_path":"/absolute/path/clip.mp4","transcribe_text":"这里是已获得的转写文字"}'
118
+ ```
119
+
120
+ 主动上传并转写音轨需设置 `transcribe:true` 和显式数据根;视觉与转写模型分别选择:
121
+
122
+ ```bash
123
+ dsh-iris vision summarize \
124
+ --provider-config /absolute/path/providers.json \
125
+ --data-root /absolute/path/iris-core \
126
+ --model-ref 'aliyun::qwen3-vl-flash' \
127
+ --input '{"video_path":"/absolute/path/clip.mp4","transcribe":true,"transcribe_model_ref":"aliyun::qwen-audio-3.0-asr-flash-filetrans"}'
128
+ ```
129
+
130
+ 配置需声明 `transcribe` 模型,并使用既有上传型转写协议(当前 DashScope)。省略 `transcribe_model_ref` 时沿用转写 assignment/模型池,显式指定时只使用该项;不能同时提供 `transcribe_text`。本次命令观察已受理的同一 Core Task,读取成功的文本 Artifact 后摘要;普通转写失败则返回画面摘要并将 `transcription.status` 标为 `failed`。无音轨标为 `no_audio`;取消/超时直接终止摘要,已经提交的转写任务保留事实,可按 [Headless CLI](HEADLESS_CLI.md) 的任务命令继续检查、观察或重新取回,不会自动重提。
131
+
132
+ 文件输入的纯视觉命令不要求数据根,不创建 Core Runtime、Task 或 Artifact;使用图片/帧 Artifact ID 时只使用显式数据根的 reader,主动音轨转写时才持有 writer 租约。独立提示词优化入口不属于本次交付。