@mokuyoaxis/dsh-iris 0.1.1 → 0.1.3

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 (44) hide show
  1. package/CHANGELOG.md +75 -1
  2. package/README.en.md +259 -0
  3. package/README.md +70 -7
  4. package/bin/dsh-iris.js +23 -0
  5. package/cordis.patch.yml +1 -1
  6. package/docs/ARCHITECTURE.md +81 -0
  7. package/docs/FAULT_INJECTION.md +26 -0
  8. package/docs/PROVIDER_SUBMISSION_CONTRACT.md +60 -0
  9. package/docs/ROADMAP.md +25 -8
  10. package/docs/SECURITY.md +53 -0
  11. package/docs/TASK_SEMANTICS.md +147 -0
  12. package/docs/assets/diagrams/iris-architecture.drawio +1 -0
  13. package/docs/assets/diagrams/iris-architecture.png +0 -0
  14. package/docs/assets/diagrams/iris-architecture.svg +63 -0
  15. package/docs/assets/diagrams/iris-task-lifecycle.drawio +1 -0
  16. package/docs/assets/diagrams/iris-task-lifecycle.png +0 -0
  17. package/docs/assets/diagrams/iris-task-lifecycle.svg +64 -0
  18. package/docs/assets/diagrams/iris-workflow-compose.drawio +1 -0
  19. package/docs/assets/diagrams/iris-workflow-compose.png +0 -0
  20. package/docs/assets/diagrams/iris-workflow-compose.svg +41 -0
  21. package/docs/assets/examples/iris-flower-generated.webp +0 -0
  22. package/docs/assets/screenshots/image-task-succeeded.webp +0 -0
  23. package/docs/assets/screenshots/prompt-general-after.webp +0 -0
  24. package/docs/assets/screenshots/prompt-general-before.webp +0 -0
  25. package/docs/assets/screenshots/prompt-general-preview.webp +0 -0
  26. package/docs/assets/screenshots/prompt-image-before.webp +0 -0
  27. package/docs/assets/screenshots/prompt-image-preview.webp +0 -0
  28. package/docs/releases/0.1.2.md +26 -0
  29. package/docs/releases/0.1.3.md +30 -0
  30. package/docs/screenshots.md +34 -0
  31. package/lib/actions.js +609 -175
  32. package/lib/api.js +122 -18
  33. package/lib/bundled-skills.js +62 -0
  34. package/lib/client.js +460 -22
  35. package/lib/doctor.js +243 -0
  36. package/lib/index.js +57 -46
  37. package/lib/prompt-optimizer-config.js +170 -0
  38. package/lib/prompt-optimizer.js +244 -0
  39. package/lib/provider-contract.js +234 -0
  40. package/lib/task-semantics.js +209 -0
  41. package/lib/tasks.js +473 -29
  42. package/package.json +13 -4
  43. package/screenshots.json +6 -0
  44. package/user_guide.md +84 -3
package/CHANGELOG.md CHANGED
@@ -6,6 +6,78 @@
6
6
 
7
7
  当前没有尚未发布的用户可见变更。
8
8
 
9
+ ## [0.1.3] - 2026-09-08
10
+
11
+ ### Added
12
+
13
+ - 新增公开的 Task/Attempt v2 语义契约,以及零网络纯函数真值表;冻结受理、自动 failover、观察、取消、产物交付、旧状态兼容和移动端用户状态的不可违反规则。
14
+
15
+ - 新增最小 Provider 提交契约、脱敏错误分类、写前持久化 Hook、零网络 Fake Provider 和旧任务纯规范化器;普通提交异常默认归为受理未知,只有明确 `not_accepted` 才能自动切换候选。
16
+
17
+ - 新增 Task v2 复制落盘与单调 revision 原语,并覆盖图片、视频、转写和 TTS:一次用户请求只创建一个 Task,每次候选在 HTTP 请求前写入 Attempt;视频和转写进一步区分上传与提交 stage。明确 4xx 拒绝才允许 failover,5xx、网络异常及缺失必要响应会以受理未知停止。
18
+
19
+ - 新增图片故障注入测试,覆盖 429 后异步/同步混合候选安全切换、500/网络失败/缺远端 ID 后零重复提交、API Key 不落任务文件、同步与异步生成成功后交付失败不重新生成、未知取消及提交中断恢复。
20
+
21
+ - 图片、视频、转写和 TTS Agent 工具开始读取 v2 事实轴:交付失败会明确表述为“生成成功但交付失败”,受理或结果未知会停止等待并要求人工确认。
22
+
23
+ - 新增 Task v2 运行时故障矩阵,覆盖盯守超时、连续轮询异常、远端明确失败、重启恢复、供应商缺失、交付中断、SSE 慢消费者和人工接管;全部使用本地 Fake/fixture,不发送计费请求。
24
+
25
+ - 新增无需安装或启动 DSH 的离线 `doctor()`、`dsh-iris doctor` CLI 与 `--json` 输出;检查运行时、依赖、私有存储、配置、模型、任务、临时文件和产物,使用稳定的 0/1/2 退出码。
26
+
27
+ - 新增公开架构、安全边界和故障注入矩阵文档。
28
+
29
+ ### Changed
30
+
31
+ - 将 v0.1.3 聚焦为“防重复计费与事实可信”:离线 Doctor v0 与最薄 CLI 保留在本版,完整 Host Adapter、Provider conformance 和依赖 DSH 运行时的 Doctor 扩展顺延到 0.1.4。
32
+
33
+ - 工作台、泡泡和任务详情开始消费 v2 派生用户态:排队/运行仍属于活动任务,观察暂停、受理或结果未知、生成成功但交付失败进入独立“需要处理”分区;旧任务继续按原四态显示。
34
+
35
+ - 状态快照新增进程 epoch 与单调 revision,客户端拒绝迟到快照;SSE 对慢消费者只保留最新待发状态。
36
+
37
+ - 任务详情新增重新观察、重新交付与知情重试:前两者禁止新生成提交;知情重试必须确认可能重复计费,并用新旧 Task 关系保留审计线索。
38
+
39
+ - 待处理任务新增“标为已读/恢复提醒”;知情重试创建新任务后自动归档原提醒并展示关联,避免同一异常重复占用泡泡角标。只有明确的 Task v1 才显示“旧任务 · 只读”,热更新字段缺失不再误标新任务。
40
+
41
+ ## [0.1.2] - 2026-09-06
42
+
43
+ ### Changed
44
+
45
+ - 提示词优化器不再默认继承主会话的 High/Low thinking 档位;新增 `generation.reasoningEffort` 策略,默认在模型元数据明确支持时关闭推理,并在面板显示思考策略与输出预算,降低推理 token 挤占正文和意外增费的风险。
46
+
47
+ - 提示词优化器按 DSH `modelSelection.current` 投影读取当前会话模型,避免界面已有选择时仍误回退为“DSH 默认模型”。
48
+
49
+ - 对外展示名使用 “Iris Media for DSH”,npm 包名继续保留为 `@mokuyoaxis/dsh-iris`,安装文档始终使用完整 scoped 名称。
50
+
51
+ ### Added
52
+
53
+ - 新增独立于 Iris 工作台的 DSH 对话框提示词优化器:输入区只保留无边框、无文字的 🫧 入口,进入带背景模糊和柔和光影的半透明玻璃悬浮窗;窄屏自动切换为安全区自适应、可内部滚动的底部面板。支持通用、图片、视频和首尾帧视频目标,默认使用当前会话模型,先预览后写回且绝不自动发送。
54
+
55
+ - 新增独立的 `prompt-optimizer.json` 配置:面板可导入/导出 JSON、固定其他 DSH provider/model、一键恢复 Iris 默认 Prompt,并可单独关闭对话入口;入口关闭后工作台、Agent 工具和任务后台继续运行。
56
+
57
+ - 插件启用时通过 DSH Skill registry 自动注册随包的 `iris-verify-ui` 与 `iris-compose-media`;用户无需克隆本仓库或把会话工作目录切到 Iris。
58
+
59
+ - README 首屏新增一张可追溯到供应商、模型与提示词的真实 Iris 生成图片。
60
+
61
+ - 新增 Android 16 真机截图画廊,记录通用提示词优化、图片 Prompt 优化、写回、任务成功和实际产物;公开副本统一移除 EXIF/XMP/IPTC 元数据。中英文 README 直接展示三张关键截图,根目录 `screenshots.json` 为插件市场声明四张精选素材。
62
+
63
+ - README 新增三张示意图:插件架构总览、生成任务生命周期与受理边界,以及「看图 → 重绘 → 自检」组合工作流示例(附 SVG 与可编辑 drawio 源文件)。
64
+
65
+ - 新增英文版 `README.en.md` 并在两份 README 顶部互设语言切换链接;npm 包清单纳入英文版。
66
+
67
+ - 新增 `scripts/gen-diagrams.mjs`:README 三张示意图由单一脚本再生成,每次运行同步产出 PNG、SVG 与可编辑 drawio 源文件。
68
+
69
+ ### Fixed
70
+
71
+ - 泡泡快捷任务不再混入失败、取消或无产物的旧记录,只显示当前运行任务与最近成功产物;完整历史和错误仍保留在 Iris 工作台。
72
+
73
+ - 常用区与 Iris 工作台的功能状态灯改为挂载后直接读取共享供应商状态:启用的 API 且具备相应能力时常驻绿色,不再要求逐张点开卡片;当前执行报错后立即变暗。
74
+
75
+ - Cordis 运行时行 ID 改为唯一的 `mokuyoaxis-dsh-iris`,避免与另一款 `dsh-iris` 插件同装时按短 ID 相互覆盖;文档说明手动 profile 覆盖的迁移方式。
76
+
77
+ ### Security
78
+
79
+ - 随包 Skill 直接从已安装的 Iris 包读取,不扫描额外项目或用户目录,也不改变默认 filesystem Skill provider 配置。
80
+
9
81
  ## [0.1.1] - 2026-09-05
10
82
 
11
83
  ### Changed
@@ -78,6 +150,8 @@
78
150
  - 上传采用流式限额、临时 `.part` 文件和原子落盘,失败时会清理未完成文件。
79
151
  - 修改状态的路由拒绝明确的跨站请求,媒体文件继续使用随机能力令牌访问。
80
152
 
81
- [Unreleased]: https://github.com/mokuyoaxis/dsh-iris/compare/v0.1.1...HEAD
153
+ [Unreleased]: https://github.com/mokuyoaxis/dsh-iris/compare/v0.1.3...HEAD
154
+ [0.1.3]: https://github.com/mokuyoaxis/dsh-iris/compare/v0.1.2...v0.1.3
155
+ [0.1.2]: https://github.com/mokuyoaxis/dsh-iris/compare/v0.1.1...v0.1.2
82
156
  [0.1.1]: https://github.com/mokuyoaxis/dsh-iris/compare/v0.1.0...v0.1.1
83
157
  [0.1.0]: https://github.com/mokuyoaxis/dsh-iris/releases/tag/v0.1.0
package/README.en.md ADDED
@@ -0,0 +1,259 @@
1
+ <p align="center">
2
+ <sub><a href="README.md">简体中文</a> | English</sub>
3
+ </p>
4
+
5
+ <p align="center">
6
+ <img src="docs/assets/iris-wordmark.svg" width="520" alt="IRIS wordmark">
7
+ </p>
8
+
9
+ <h1 align="center">Iris Media for DSH</h1>
10
+
11
+ <p align="center"><strong>A multimodal media production runtime · currently shipped as a DeepSeek Harness plugin</strong></p>
12
+
13
+ <p align="center">
14
+ <a href="#deepseek-harness-adaptation"><img alt="DeepSeek Harness compatible" src="https://img.shields.io/badge/DeepSeek%20Harness-compatible-4D6BFE.svg?style=flat-square"></a>
15
+ <a href="https://www.npmjs.com/package/@mokuyoaxis/dsh-iris"><img alt="npm version" src="https://img.shields.io/npm/v/%40mokuyoaxis%2Fdsh-iris.svg?style=flat-square"></a>
16
+ <a href="https://nodejs.org/"><img alt="Node.js 20.10 or newer" src="https://img.shields.io/badge/Node.js-%3E%3D20.10-339933.svg?style=flat-square&amp;logo=nodedotjs&amp;logoColor=white"></a>
17
+ <a href="https://github.com/mokuyoaxis/dsh-iris/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/mokuyoaxis/dsh-iris/actions/workflows/ci.yml/badge.svg"></a>
18
+ <a href="LICENSE"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-1689FF.svg?style=flat-square"></a>
19
+ </p>
20
+
21
+ dsh-iris gives agents and the Iris workbench image, video, speech, and visual understanding capabilities, and it can optimize any draft directly in the DSH composer. It connects to Alibaba Cloud DashScope (Bailian) and to OpenAI Images–compatible services. Configuration and task management live in the Iris workbench, and a floating Iris bubble in the bottom-right corner is the quick entry point.
22
+
23
+ ## A real generation example
24
+
25
+ <p align="center">
26
+ <img src="docs/assets/examples/iris-flower-generated.webp" width="720" alt="A violet-blue iris generated from a prompt optimized by Iris">
27
+ </p>
28
+
29
+ > Starting from the two-character draft “鸢尾花”: Iris composer optimization (`deepseek-v4-flash`, thinking `off`) → Alibaba Cloud Bailian `qwen-image-3.0-pro` generation · 2048×2048
30
+
31
+ ## Android 16 live UI
32
+
33
+ These captures come from an Android browser connected to DSH under Termux/PRoot Debian ARM64, using the default DSH skin. Public copies have no EXIF, XMP, or IPTC metadata.
34
+
35
+ | 🫧 in the conversation composer | Optimized draft written back |
36
+ |---|---|
37
+ | ![Iris bubble control in the DSH composer](docs/assets/screenshots/prompt-general-before.webp) | ![Iris writes the optimized prompt back to the DSH composer](docs/assets/screenshots/prompt-general-after.webp) |
38
+
39
+ <p align="center">
40
+ <img src="docs/assets/screenshots/image-task-succeeded.webp" width="520" alt="Succeeded image task in the Iris workbench">
41
+ </p>
42
+
43
+ > [See the complete six-image workflow: before, glass preview panel, write-back, succeeded task, and artifact](docs/screenshots.md)
44
+
45
+ The project is at an early stage; interfaces and configuration formats may still change between releases.
46
+
47
+ Iris's long-term direction is a media production core that can run on its own and plug into different agent hosts. DeepSeek Harness is the first supported host, and the current version still requires DSH — a standalone Core, CLI, and workbench are on the roadmap but not yet available.
48
+
49
+ ## Relationship with ai-paint
50
+
51
+ `ai-paint` is the maintainer's local, unpublished predecessor of Iris. It is not a public dependency, and users never need to download, install, or create it. Without that project, simply configure providers in the Iris workbench as described below.
52
+
53
+ Early versions read models and credentials from the maintainer's local ai-paint configuration — partly to migrate the predecessor project, and partly so the host process could reuse an existing API key locally instead of pasting keys into agent sessions, command-line arguments, or documents. Version 0.1.1 separates the two configurations completely: Iris uses only its own configuration. The old one can be imported exactly once, and only by explicitly setting `IRIS_IMPORT_WORKBENCH_CONFIG` to the absolute path of the local config file. Iris never scans for ai-paint by default and never syncs the two sides. The variable carries a file path, not an API key, and the source file is left untouched. See the [user guide](user_guide.md) for details.
54
+
55
+ ## Quickest start
56
+
57
+ With DeepSeek Harness `0.1.2-rc.1` installed and `pnpm` on your PATH, add Iris to the Web profile:
58
+
59
+ ```bash
60
+ dsh plugin --profile web add @mokuyoaxis/dsh-iris
61
+ dsh web
62
+ ```
63
+
64
+ > The unscoped `dsh-iris` on npm belongs to a different plugin. Always keep the fully scoped name `@mokuyoaxis/dsh-iris` when installing or updating Iris Media.
65
+
66
+ To try it from a source checkout, replace `@mokuyoaxis/dsh-iris` in the first command with `.`. The plugin loads the next time DSH starts; the web UI defaults to `http://127.0.0.1:3080`.
67
+
68
+ After the first start, open "Settings → Iris workbench → + Add provider", enter your DashScope base URL and API key, then click "Discover models". A single provider can start with automatic capability assignment. Full steps, OpenAI Images–compatible configuration, and failover notes are in the [user guide](user_guide.md) (Chinese).
69
+
70
+ Once configured, minimal instructions can be as simple as:
71
+
72
+ ```text
73
+ Use iris_draw_image: draw a white cat sitting by a blue window.
74
+ Summarize the image I just uploaded.
75
+ Summarize /absolute/path/demo.mp4 with Iris, then turn the summary into speech.
76
+ ```
77
+
78
+ DSH profiles and plugin commands follow the [official installation docs](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/user/develop/basic/publish.md). Generating images, videos, or speech may incur provider charges.
79
+
80
+ ## Feature overview
81
+
82
+ ![Iris architecture overview](docs/assets/diagrams/iris-architecture.png)
83
+
84
+ - Image generation, text-to-video, image-to-video, and S2V digital-human video
85
+ - Text-to-speech and audio transcription
86
+ - Visual question answering, long-image OCR, target grounding, cropping, and pixel-diff analysis
87
+ - Video frame extraction and multimodal video summarization
88
+ - Asynchronous task tracking, restart recovery, and token-authorized media playback
89
+ - A multi-provider model pool with per `provider + model` capability assignment
90
+ - Three file sources: browser upload, session attachments, and host paths
91
+ - Workbench-independent composer prompt optimization with current-session and JSON-configured fixed model routing
92
+
93
+ ## Prerequisites
94
+
95
+ - A Node.js version that satisfies your DeepSeek Harness release's requirement; dsh-iris itself requires at least 20.10
96
+ - A working DeepSeek Harness environment with `pnpm` on the PATH
97
+ - At least one supported media or vision provider
98
+ - `ffmpeg` and `ffprobe` on the system, for video frame extraction and video summaries
99
+
100
+ After installing the plugin, add a provider in the Iris workbench and assign models to the capabilities you need. Provider keys are kept in Iris's host-side configuration; on POSIX systems, Iris's own directories and files are tightened to `0700` and `0600` respectively, and neither the UI nor the API ever returns full keys. On Windows, file modes are not equivalent to ACLs — keep relying on your user directory and system account permissions.
101
+
102
+ ## DeepSeek Harness adaptation
103
+
104
+ dsh-iris ships as a native DSH plugin with a server side and a web client. The server registers 14 agent tools and reuses the host's tool, routing, and lifecycle services; the client hooks into the settings page, the conversation input area, and the global floating layer through DSH's module loader. The plugin never starts a separate service or listens on an extra port.
105
+
106
+ Automated tests currently cover plugin loading, tool registration, client seats, and routing behavior. Version 0.1.1 completed host smoke tests on Linux ARM64 — in both a clean and a real web profile — against DSH `0.1.2-rc.1` on Node.js `22.23.2`: the browser startup graph, the full combined bundle, the Iris client factory, and the three UI seats present at that time were verified. The fourth prompt-optimizer seat added in 0.1.2 has now been rendered in a live Android browser; configuration loading, a real session-model optimization with thinking actually `off`, preview write-back, independent disabling and re-enabling, and the loop from a short draft to a succeeded image-generation task are verified. Browser-side cancellation and JSON operations have automated HTTP/configuration coverage; a step-by-step live-device record is still pending. Iris itself keeps Node.js `>=20.10` as its own floor.
107
+
108
+ Iris 0.1.1–0.1.3 explicitly supports DSH `>=0.1.2-rc.1 <0.1.3-0` and no longer works with the legacy client runtime of DSH 0.1.0/0.1.1. DSH is still evolving quickly; later preview versions must pass verification before the supported range widens, and the compatibility badge is not an official certification. If DSH requires a newer Node.js, DSH wins.
109
+
110
+ ## Tools
111
+
112
+ ### Generation, speech, and tasks
113
+
114
+ | Tool | Purpose |
115
+ |---|---|
116
+ | `iris_draw_image` | Generate images from a prompt |
117
+ | `iris_generate_video` | Text-to-video, image-to-video, or S2V digital-human video |
118
+ | `iris_speak_text` | Synthesize speech from text |
119
+ | `iris_transcribe_audio` | Transcribe audio to text |
120
+ | `iris_task_status` | Check the status and outputs of one task or the recent tasks |
121
+
122
+ ### Vision and image processing
123
+
124
+ | Tool | Purpose |
125
+ |---|---|
126
+ | `iris_look_at_image` | Ask a question about an image and get a vision model's answer |
127
+ | `iris_relook_attachment` | Re-inspect an image attachment from the session with a new question |
128
+ | `iris_long_ocr` | Recognize text in tall screenshots or long images, chunk by chunk |
129
+ | `iris_locate` | Ground a target in an image and return pixel coordinates |
130
+ | `iris_crop` | Crop an image by pixel region |
131
+ | `iris_pixel_diff` | Compare two images and produce diff statistics and a heatmap |
132
+ | `iris_html_screenshot` | Render an HTML string to a screenshot in a restricted environment |
133
+
134
+ ### Video processing
135
+
136
+ | Tool | Purpose |
137
+ |---|---|
138
+ | `iris_video_frames` | Extract frames evenly from a video |
139
+ | `iris_media_summarize` | Summarize a video from sampled frames plus optional audio transcription |
140
+
141
+ ## File inputs
142
+
143
+ Iris accepts three file sources, in the recommended order:
144
+
145
+ 1. **Browser upload** — best for local files and cross-environment access; 64 MB per file.
146
+ 2. **Session attachments** — best for reusing media already uploaded or generated in the current session.
147
+ 3. **Host paths** — best for large files the host can read directly. Enter the path as seen by the host process; it is not always the path on the machine your browser runs on.
148
+
149
+ Uploads are stored under `$DSH_HOME/iris/v1/uploads/` and kept for 7 days by default. For path-picking advice on different platforms, see [File access across environments](docs/file-access-across-environments.md) (Chinese).
150
+
151
+ ## Conversation prompt optimization
152
+
153
+ Iris adds a borderless, text-free “🫧” control directly to the DSH composer, so the workbench does not need to be open. It opens a translucent glass panel with background blur and soft depth; on narrow screens and Android browsers it becomes a safe-area-aware, internally scrollable bottom sheet to prevent overlap and overflow. It reads only the current unsent plain-text draft and offers general, image, video, and start-to-end-frame video targets. The result is previewed first and is written back only after confirmation; Iris never sends it automatically. Drafts containing structured `@` or `/` references are left untouched for now so their identities are not lost.
154
+
155
+ By default, the optimizer uses the model selected for the current session and falls back to DSH's default model when the session has none. The request carries no chat history, tools, attachments, or workspace content—only the current draft and target template. To prevent reasoning tokens from exhausting the generation budget before visible text is complete, `generation.reasoningEffort` defaults to `off-if-supported`: reasoning is disabled only when DSH model metadata explicitly advertises such an effort; otherwise the provider default is used, and the session High/Low setting is not inherited. JSON may select `provider-default`, `inherit`, or an exact effort ID advertised by the model. For predictable cost and latency, use a `fixed` route with a lightweight non-reasoning model. You can also export `prompt-optimizer.json`, change `route.mode` to `fixed`, name another `provider` and `model` already registered in DSH, and import it again. “Reset to defaults” restores Iris's built-in prompt, target templates, session-model routing, and generation settings. The composer control can be disabled independently and re-enabled from the Iris workbench; disabling it does not stop the workbench, agent tools, or task runtime. An optimization call may incur charges from the selected text model.
156
+
157
+ ## Model assignment and failover
158
+
159
+ Capability assignment uses `providerId::modelId` as the model identity. The same model name from a different provider or account counts as two independent options.
160
+
161
+ Generation capabilities accept multiple candidate models. Iris tries the next candidate only when the provider explicitly proves that the request was not accepted. A 500 response, timeout, disconnect, missing response, polling failure, or local persistence failure never authorizes automatic resubmission. Once accepted, Iris may only resume observation or delivery.
162
+
163
+ The workbench lists paused observation, unknown acceptance/outcome, and successful generation with failed delivery under “Needs attention.” Re-observe never submits; re-deliver never regenerates; acknowledge/restore only changes the local reminder queue; only an explicitly confirmed informed retry creates a linked new task and may incur duplicate charges. Creating that task archives the original reminder while preserving its unknown facts and audit link. See [Task semantics](docs/TASK_SEMANTICS.md), [Architecture](docs/ARCHITECTURE.md), [Security](docs/SECURITY.md), and the [Fault-injection matrix](docs/FAULT_INJECTION.md).
164
+
165
+ ![Task lifecycle and acceptance boundary](docs/assets/diagrams/iris-task-lifecycle.png)
166
+
167
+ Transcription is a separate `transcribe` capability and does not consume the TTS or vision model configuration.
168
+
169
+ ## Offline diagnostics
170
+
171
+ No DSH installation or running host is required, and no provider request is sent:
172
+
173
+ ```bash
174
+ npx @mokuyoaxis/dsh-iris doctor
175
+ npx @mokuyoaxis/dsh-iris doctor --json
176
+ ```
177
+
178
+ The installed binary is `dsh-iris`. Exit code `0` is healthy, `1` means warnings, and `2` means hard errors. Doctor checks Node.js, sharp, ffmpeg/ffprobe, a real but cleaned-up storage write probe, configuration, models/assignments, task semantics, temporary files, and orphaned or missing artifacts. It cannot verify a running DSH host, browser service, or live provider.
179
+
180
+ ## Composed workflow example
181
+
182
+ Iris ships two agent skills (`iris-verify-ui` and `iris-compose-media`) that chain multiple tools into bounded, reviewable media workflows. The example below is "look → redraw → self-check": understand the source image first, then generate, review against concrete mismatches, and only deliver once the review passes.
183
+
184
+ ![Composed workflow example](docs/assets/diagrams/iris-workflow-compose.png)
185
+
186
+ SVG versions and editable drawio sources of the figures above live in [`docs/assets/diagrams/`](docs/assets/diagrams/). Diagram labels are currently in Chinese.
187
+
188
+ ## Data and tasks
189
+
190
+ Runtime data lives under `$DSH_HOME/iris/v1/` by default:
191
+
192
+ | Location | Contents |
193
+ |---|---|
194
+ | `providers.json` | Providers and capability assignments; file mode 0600 |
195
+ | `prompt-optimizer.json` | Imported optimizer prompt, target templates, model route, and generation settings; file mode 0600 |
196
+ | `tasks.json` | Task metadata and attachment indexes; up to 500 records |
197
+ | `outputs/` | Generated and processed media |
198
+ | `uploads/` | Temporary copies of browser uploads |
199
+
200
+ On first load, 0.1.1 tightens POSIX permissions across an existing `$DSH_HOME/iris/v1/` tree without modifying file contents or following symlinks. Large media downloads stream to a private temporary file and are moved into place atomically, instead of loading a whole video into memory.
201
+
202
+ Asynchronous tasks are polled in the background. After a plugin restart, Iris can re-adopt tasks that are still running remotely. Cancellation signals propagate through local waits and polling; whether the remote computation itself can be cancelled depends on the provider's API.
203
+
204
+ Audio and video are served through Iris media links that carry random capability tokens. Images are, wherever possible, also saved as DSH durable attachments so they stay usable in the conversation.
205
+
206
+ ## Security notes
207
+
208
+ - Provider keys are never returned by status endpoints.
209
+ - The DashScope media protocol only sends keys to official Alibaba Cloud HTTPS domains; any other base URL defaults to the OpenAI Images–compatible protocol.
210
+ - `/iris/*` accepts loopback Host headers only by default; LAN or reverse-proxy deployments must set `IRIS_TRUSTED_HOSTS` explicitly, and state-changing requests are also checked against cross-site origins.
211
+ - `IRIS_TRUSTED_HOSTS` is not an authentication mechanism. When exposing DSH to the public internet or an untrusted network, configure authentication and HTTPS at the reverse proxy or host layer.
212
+ - Paid model probes run one capability at a time and always confirm before a real provider call; video and transcription never submit empty-sample paid probes automatically.
213
+ - HTML screenshots render inside a sandboxed page without same-origin privileges; scripts and external network access are disabled by default.
214
+ - Media links use random capability tokens, and file paths are resolved only from task records.
215
+ - Iris provides no account system of its own; multi-user isolation and access control are the responsibility of the DeepSeek Harness deployment.
216
+
217
+ ## Known limitations
218
+
219
+ - `sharp` bundles native components; glibc Linux, Windows, and macOS are the primary targets. Non-standard environments such as bare Termux may need extra work.
220
+ - Video frame extraction and video summaries require system-installed `ffmpeg` and `ffprobe`.
221
+ - HTML screenshots load no remote scripts, fonts, or images; inline the resources you need first.
222
+ - Under WSL, containers, and remote deployments, browser paths usually cannot be handed to the host directly — prefer uploading files.
223
+ - Provider model lists are candidate sets only; whether a model truly supports a capability is settled by real calls.
224
+
225
+ ## Agent Skills
226
+
227
+ When the plugin is enabled, it automatically registers the two bundled skills through the DSH skill registry:
228
+
229
+ | Skill | When to use |
230
+ |---|---|
231
+ | [`iris-verify-ui`](.dsh/skills/iris-verify-ui/SKILL.md) | Combine screenshots, semantic inspection, element grounding, cropping, and pixel comparison into evidence-based UI acceptance |
232
+ | [`iris-compose-media`](.dsh/skills/iris-compose-media/SKILL.md) | Chain two or more Iris tools into media workflows: inspect-then-draw, image-to-video, video summary with narration, S2V, and more |
233
+
234
+ From 0.1.2, as long as the host provides the DSH skill registry, regular npm installs can discover and load both skills from any project directory — no need to clone this repository or configure a skill search path. When the project directory contains same-name skills, DSH's native precedence keeps using the project versions; if the skill registry is unavailable, the 14 Iris tools still load on their own.
235
+
236
+ ## Development and verification
237
+
238
+ Run in the project directory:
239
+
240
+ npm test
241
+
242
+ Tests cover config merging, model identity, task lifecycle, generation actions, HTTP/SSE routing, client interactions, and security boundaries. The project is pure ES Modules with no build step.
243
+
244
+ The test scheduler runs on Node.js, launching one process per file and stopping at the first failure — no Bash involved. Temporary directories use system APIs and are cleaned up on exit. GitHub Actions defines a Linux/Windows × Node.js 20.10/22 matrix, and a pre-release hook re-runs the full suite. DSH host smoke tests on native Windows/WSL are still pending real-machine verification.
245
+
246
+ Releases are triggered by `v*` tags through `.github/workflows/release.yml`: the full test suite runs first, then the tarball is packaged, a GitHub Release is created with the workflow's built-in `GITHUB_TOKEN` (tarball attached; release notes taken from the matching CHANGELOG section), and npm publish happens when an `NPM_TOKEN` secret is configured. No local GitHub credentials are needed.
247
+
248
+ ## Documentation
249
+
250
+ - [User guide](user_guide.md) (Chinese)
251
+ - [Changelog](CHANGELOG.md) (Chinese)
252
+ - [Roadmap](docs/ROADMAP.md) (Chinese)
253
+ - [File access across environments](docs/file-access-across-environments.md) (Chinese)
254
+ - [Android 16 screenshot gallery](docs/screenshots.md)
255
+ - [Task/Attempt v2 semantics (Chinese)](docs/TASK_SEMANTICS.md)
256
+
257
+ ## License
258
+
259
+ [MIT](LICENSE)
package/README.md CHANGED
@@ -1,8 +1,12 @@
1
+ <p align="center">
2
+ <sub>简体中文 | <a href="README.en.md">English</a></sub>
3
+ </p>
4
+
1
5
  <p align="center">
2
6
  <img src="docs/assets/iris-wordmark.svg" width="520" alt="IRIS 彩色字标">
3
7
  </p>
4
8
 
5
- <h1 align="center">dsh-iris</h1>
9
+ <h1 align="center">Iris Media for DSH</h1>
6
10
 
7
11
  <p align="center"><strong>Iris 多模态生产运行时 · 当前通过 DeepSeek Harness 插件使用</strong></p>
8
12
 
@@ -14,7 +18,29 @@
14
18
  <a href="LICENSE"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-1689FF.svg?style=flat-square"></a>
15
19
  </p>
16
20
 
17
- dsh-iris 为 Agent 和 Iris 工作台提供图像、视频、语音与视觉理解能力。它可以连接 DashScope 百炼及 OpenAI Images 兼容服务;完整配置和任务管理集中在 Iris 工作台,右下角的 Iris 泡泡提供快捷入口。
21
+ dsh-iris 为 Agent 和 Iris 工作台提供图像、视频、语音与视觉理解能力,也能直接优化 DSH 对话框中的任意提示词。它可以连接 DashScope 百炼及 OpenAI Images 兼容服务;完整配置和任务管理集中在 Iris 工作台,右下角的 Iris 泡泡提供快捷入口。
22
+
23
+ ## 实际生成示例
24
+
25
+ <p align="center">
26
+ <img src="docs/assets/examples/iris-flower-generated.webp" width="720" alt="由 Iris 优化提示词并生成的蓝紫色鸢尾花">
27
+ </p>
28
+
29
+ > 从一句“鸢尾花”开始:Iris 对话框优化 Prompt(`deepseek-v4-flash`,thinking `off`)→ 阿里云百炼 `qwen-image-3.0-pro` 生成 · 2048×2048
30
+
31
+ ## Android 16 真机界面
32
+
33
+ 以下截图来自 Android 浏览器连接 Termux/PRoot Debian ARM64 中的 DSH,使用 DSH 默认皮肤;公开图片均已移除 EXIF/XMP/IPTC 元数据。
34
+
35
+ | 对话输入区的 🫧 入口 | 优化结果写回输入框 |
36
+ |---|---|
37
+ | ![DSH 对话输入区中的 Iris 泡泡入口](docs/assets/screenshots/prompt-general-before.webp) | ![Iris 将优化结果写回 DSH 输入框](docs/assets/screenshots/prompt-general-after.webp) |
38
+
39
+ <p align="center">
40
+ <img src="docs/assets/screenshots/image-task-succeeded.webp" width="520" alt="Iris 工作台中的图片任务成功详情">
41
+ </p>
42
+
43
+ > [查看完整六图流程:优化前、玻璃预览窗、写回、任务成功与实际产物](docs/screenshots.md)
18
44
 
19
45
  项目目前处于早期版本,接口和配置格式仍可能随版本迭代调整。
20
46
 
@@ -35,6 +61,8 @@ dsh plugin --profile web add @mokuyoaxis/dsh-iris
35
61
  dsh web
36
62
  ```
37
63
 
64
+ > npm 上无 scope 的 `dsh-iris` 属于另一款插件。安装和更新 Iris Media 时必须保留完整包名 `@mokuyoaxis/dsh-iris`。
65
+
38
66
  从当前源码目录试用时,把第一条命令中的 `@mokuyoaxis/dsh-iris` 换成 `.`。插件会在下一次 DSH 启动时装载,Web UI 默认位于 `http://127.0.0.1:3080`。
39
67
 
40
68
  首次启动后,打开“设置 → Iris 工作台 → + 添加供应商”,填入 DashScope Base URL 和 API Key,再点“发现模型”。单供应商可以先使用自动能力分配。完整步骤、OpenAI Images 兼容配置和故障转移说明见[用户指南](user_guide.md)。
@@ -51,6 +79,8 @@ DSH 的 profile 与插件命令由[官方安装说明](https://github.com/deepse
51
79
 
52
80
  ## 功能概览
53
81
 
82
+ ![Iris 架构总览](docs/assets/diagrams/iris-architecture.png)
83
+
54
84
  - 图像生成、文生视频、图生视频和 S2V 数字人视频
55
85
  - 文本转语音与音频转写
56
86
  - 看图问答、长图 OCR、目标定位、裁剪和像素差异分析
@@ -58,6 +88,7 @@ DSH 的 profile 与插件命令由[官方安装说明](https://github.com/deepse
58
88
  - 异步任务跟踪、重启恢复和带授权令牌的媒体播放
59
89
  - 多供应商模型池,以及按 `供应商 + 模型` 分配能力
60
90
  - 浏览器上传、会话附件和宿主路径三种文件来源
91
+ - 独立于工作台的对话框提示词优化,支持当前会话模型与 JSON 固定模型路由
61
92
 
62
93
  ## 使用前准备
63
94
 
@@ -72,9 +103,9 @@ DSH 的 profile 与插件命令由[官方安装说明](https://github.com/deepse
72
103
 
73
104
  dsh-iris 按 DeepSeek Harness 插件形态提供服务端与 Web 客户端入口:服务端注册 14 个 Agent 工具,并复用宿主的工具、路由和生命周期服务;客户端通过 DSH 模块加载器接入设置页、会话输入区和全局悬浮层。插件不会启动独立服务或额外监听端口。
74
105
 
75
- 当前自动化测试覆盖插件装载、工具注册、客户端槽位和路由行为。0.1.1 已在 Linux ARM64 的干净与真实 Web profile 中,使用 DSH `0.1.2-rc.1`、Node.js `22.23.2` 完成宿主烟测;浏览器启动图、完整组合 bundle、Iris 客户端工厂和三个 UI 座位均已验证。Iris 自身仍以 Node.js `>=20.10` 为最低基线。
106
+ 当前自动化测试覆盖插件装载、工具注册、客户端槽位和路由行为。0.1.1 已在 Linux ARM64 的干净与真实 Web profile 中,使用 DSH `0.1.2-rc.1`、Node.js `22.23.2` 完成宿主烟测;浏览器启动图、完整组合 bundle、Iris 客户端工厂和当时的三个 UI 座位均已验证。0.1.2 新增的第四个提示词优化座位已在 Android 浏览器真机确认渲染,配置读取、真实会话模型优化(实际 thinking `off`)、预览写回、独立关闭与重新启用,以及从短草稿到图片生成任务成功的闭环均已验证;浏览器端取消和 JSON 操作已有自动化 HTTP/配置覆盖,尚待补充真机逐项记录。Iris 自身仍以 Node.js `>=20.10` 为最低基线。
76
107
 
77
- 0.1.1 明确支持 DSH `>=0.1.2-rc.1 <0.1.3-0`,不再兼容 0.1.0/0.1.1 的旧客户端 Runtime。DSH 仍在快速演进,后续预览版须经验证后再扩大范围;兼容徽章不代表官方认证。若 DSH 要求更高 Node 版本,以 DSH 为准。
108
+ Iris 0.1.1–0.1.3 明确支持 DSH `>=0.1.2-rc.1 <0.1.3-0`,不再兼容 0.1.0/0.1.1 的旧客户端 Runtime。DSH 仍在快速演进,后续预览版须经验证后再扩大范围;兼容徽章不代表官方认证。若 DSH 要求更高 Node 版本,以 DSH 为准。
78
109
 
79
110
  ## 工具
80
111
 
@@ -117,14 +148,43 @@ Iris 支持三种文件来源,推荐顺序如下:
117
148
 
118
149
  上传内容保存在 `$DSH_HOME/iris/v1/uploads/`,默认保留 7 天。不同系统下的路径选择建议见[文件访问与跨环境](docs/file-access-across-environments.md)。
119
150
 
151
+ ## 对话框提示词优化
152
+
153
+ Iris 会在 DSH 对话输入区提供一个无边框、无文字的“🫧”入口,不需要打开 Iris 工作台。点击后打开带背景模糊、半透明层次和柔和光影的玻璃悬浮窗;桌面端靠近输入区显示,窄屏与 Android 浏览器自动切换为带安全区和内部滚动的底部面板,避免遮挡、溢出或控件挤叠。它只读取当前未发送的纯文本草稿,并提供通用、图片、视频和首尾帧视频四种目标模板;结果先预览,用户确认后才写回输入框,不会自动发送。含 `@` 或 `/` 结构化引用的草稿暂不改写,以免引用身份丢失。
154
+
155
+ 默认使用当前会话选中的主模型;会话尚未选定模型时回退到 DSH 默认模型。优化请求不携带聊天历史、工具、附件或工作区,只发送当前草稿与目标模板。为避免推理模型在正文前耗尽生成预算,默认 `generation.reasoningEffort` 为 `off-if-supported`:仅在 DSH 模型元数据明确支持关闭 thinking 时禁用推理,否则使用供应商默认值,并且不再继承主会话的 High/Low 档位。可在 JSON 中改为 `provider-default`、`inherit` 或模型声明的具体 effort ID;成本与稳定性优先时,建议使用 `fixed` 路由指定轻量非思考模型。用户也可以导出 `prompt-optimizer.json`,将 `route.mode` 改为 `fixed` 并指定其他已在 DSH 注册的 `provider` 与 `model`,然后从面板重新导入。面板提供“恢复默认”,可还原 Iris 内置 Prompt、目标模板、会话模型路由和生成参数。该对话入口可以单独关闭,并从 Iris 工作台重新启用;关闭不会停用工作台、Agent 工具或任务后台。优化调用可能产生对应文本模型的费用。
156
+
120
157
  ## 模型分配与故障转移
121
158
 
122
159
  能力分配使用 `providerId::modelId` 作为模型身份。同名模型如果来自不同供应商或不同账号,会被视为两个独立选项。
123
160
 
124
- 生成类能力可以配置多个候选模型。Iris 只会在上传、提交或同步生成阶段失败时尝试下一个候选项;远端服务一旦受理任务,就不会自动重新提交,以免产生重复任务或重复计费。已经受理的异步任务由任务系统继续跟踪。
161
+ 生成类能力可以配置多个候选模型。Iris 只有在供应商明确证明未受理时才会尝试下一个候选;500、超时、断网、响应缺失、轮询失败和本地落盘失败都不会授权自动重提。远端服务一旦受理任务,Iris 只会恢复观察或交付,以免产生重复任务或重复计费。
162
+
163
+ 工作台把观察暂停、受理/结果未知和生成成功但交付失败单列为“需要处理”。“重新观察”不会提交;“重新交付”不会重新生成;“标为已读/恢复提醒”只改变本地提醒队列;只有“知情重试”会创建新任务,并要求用户逐次确认潜在重复费用。新任务创建后,原提醒自动归档但保留未知事实和新旧任务关联。任务语义、架构、安全边界与故障证据分别见 [`TASK_SEMANTICS.md`](docs/TASK_SEMANTICS.md)、[`ARCHITECTURE.md`](docs/ARCHITECTURE.md)、[`SECURITY.md`](docs/SECURITY.md) 和 [`FAULT_INJECTION.md`](docs/FAULT_INJECTION.md)。
164
+
165
+ ![生成任务生命周期与受理边界](docs/assets/diagrams/iris-task-lifecycle.png)
125
166
 
126
167
  转写是独立的 `transcribe` 能力,不会占用 TTS 或视觉能力的模型配置。
127
168
 
169
+ ## 离线诊断
170
+
171
+ 无需安装或启动 DSH,也不会发送供应商请求:
172
+
173
+ ```bash
174
+ npx @mokuyoaxis/dsh-iris doctor
175
+ npx @mokuyoaxis/dsh-iris doctor --json
176
+ ```
177
+
178
+ 安装后的二进制名是 `dsh-iris`。退出码 `0` 表示正常、`1` 表示有警告、`2` 表示有硬错误。Doctor 检查 Node、sharp、ffmpeg/ffprobe、数据目录真实写入、配置、模型/分配、任务语义、临时文件和孤儿/缺失产物;它不会判断运行中的 DSH、浏览器或真实 Provider 是否在线。
179
+
180
+ ## 组合工作流示例
181
+
182
+ Iris 自带两个 Agent Skills(`iris-verify-ui` 与 `iris-compose-media`),把多个工具编排成有界、可复核的媒体工作流。下例是「看图 → 重绘 → 自检」:先理解原图,再生成,复核针对具体偏差,只有复核通过才交付。
183
+
184
+ ![组合工作流示例](docs/assets/diagrams/iris-workflow-compose.png)
185
+
186
+ 图的 SVG 版本与可编辑 drawio 源文件位于 [`docs/assets/diagrams/`](docs/assets/diagrams/)。
187
+
128
188
  ## 数据与任务
129
189
 
130
190
  运行数据默认位于 `$DSH_HOME/iris/v1/`:
@@ -132,6 +192,7 @@ Iris 支持三种文件来源,推荐顺序如下:
132
192
  | 位置 | 内容 |
133
193
  |---|---|
134
194
  | `providers.json` | 供应商和能力分配,文件权限为 0600 |
195
+ | `prompt-optimizer.json` | 用户导入的优化 Prompt、目标模板、模型路由和生成参数,文件权限为 0600 |
135
196
  | `tasks.json` | 任务元数据和附件索引,最多保留 500 条 |
136
197
  | `outputs/` | 生成和处理后的媒体文件 |
137
198
  | `uploads/` | 浏览器上传的临时输入副本 |
@@ -163,14 +224,14 @@ Iris 支持三种文件来源,推荐顺序如下:
163
224
 
164
225
  ## Agent Skills
165
226
 
166
- 源码和 npm 包附带两个仓库级预览 Skill:
227
+ 插件启用时会通过 DSH Skill registry 自动注册两个随包 Skill:
167
228
 
168
229
  | Skill | 适用场景 |
169
230
  |---|---|
170
231
  | [`iris-verify-ui`](.dsh/skills/iris-verify-ui/SKILL.md) | 组合截图、语义检查、元素定位、裁剪和像素比较,完成有证据的 UI 验收 |
171
232
  | [`iris-compose-media`](.dsh/skills/iris-compose-media/SKILL.md) | 组合两个以上 Iris 工具,完成看图后绘图、图片转视频、视频总结配旁白或 S2V 等媒体工作流 |
172
233
 
173
- 当 DSH 会话以本仓库为项目目录且启用了文件系统 Skill 服务时,可以直接发现它们。当前版本尚未在插件启用时自动向其他项目注册这些 Skill;14 个 Iris 工具不受影响。
234
+ 从 0.1.2 起,只要宿主提供 DSH Skill registry,普通 npm 安装用户在任意项目目录中都能发现并加载它们,不需要克隆本仓库或另外配置 Skill 搜索目录。项目目录中存在同名 Skill 时,仍按 DSH 原生优先级使用项目版本;Skill registry 不可用时,14 个 Iris 工具仍可独立装载。
174
235
 
175
236
  ## 开发与验证
176
237
 
@@ -190,6 +251,8 @@ Iris 支持三种文件来源,推荐顺序如下:
190
251
  - [变更记录](CHANGELOG.md)
191
252
  - [路线图](docs/ROADMAP.md)
192
253
  - [文件访问与跨环境](docs/file-access-across-environments.md)
254
+ - [Android 16 真机截图画廊](docs/screenshots.md)
255
+ - [Task/Attempt v2 语义契约](docs/TASK_SEMANTICS.md)
193
256
 
194
257
  ## License
195
258
 
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ import { doctor, formatDoctorReport } from '../lib/doctor.js';
3
+
4
+ function usage() {
5
+ return [
6
+ 'Usage: dsh-iris doctor [--json]',
7
+ '',
8
+ 'Runs offline diagnostics only. It does not start DSH or send provider requests.'
9
+ ].join('\n');
10
+ }
11
+
12
+ const args = process.argv.slice(2);
13
+ if (args.includes('--help') || args.includes('-h')) {
14
+ console.log(usage());
15
+ process.exitCode = 0;
16
+ } else if (args[0] !== 'doctor' || args.some((arg, index) => index > 0 && arg !== '--json')) {
17
+ console.error(usage());
18
+ process.exitCode = 2;
19
+ } else {
20
+ const report = await doctor();
21
+ console.log(args.includes('--json') ? JSON.stringify(report, null, 2) : formatDoctorReport(report));
22
+ process.exitCode = report.exitCode;
23
+ }
package/cordis.patch.yml CHANGED
@@ -1,3 +1,3 @@
1
1
  - insert:
2
- - id: dsh-iris
2
+ - id: mokuyoaxis-dsh-iris
3
3
  name: '@mokuyoaxis/dsh-iris'
@@ -0,0 +1,81 @@
1
+ # Iris 架构与边界
2
+
3
+ 状态:v0.1.3 当前实现。本文描述已经存在的代码边界,不把 0.2+ 规划写成现成功能。
4
+
5
+ ## 当前形态
6
+
7
+ Iris 目前以 DeepSeek Harness 插件运行。DSH 提供 Agent 工具注册、会话附件、浏览器和 Web UI 插槽;Iris 自己负责供应商配置、媒体动作、可信任务、产物落盘、媒体授权路由和工作台投影。
8
+
9
+ ```text
10
+ DSH Host / Cordis
11
+ ├─ Agent tools ───────────────┐
12
+ ├─ Web slots / browser │
13
+ └─ attachment/session ports │
14
+ ▼
15
+ actions.runAction
16
+ ├─ provider adapters
17
+ ├─ Task / Attempt v2
18
+ ├─ media delivery
19
+ └─ vision / local media tools
20
+ │
21
+ ▼
22
+ $DSH_HOME/iris/v1
23
+ providers.json · tasks.json
24
+ outputs/ · uploads/
25
+ ```
26
+
27
+ `lib/index.js` 是 DSH Host Adapter 的当前集中入口;`lib/client.js` 只消费同源 API 与 DSH UI Slot。`lib/api.js` 是工作台 HTTP 投影,不是真相来源。Task 的持久事实由 `lib/tasks.js` 管理。
28
+
29
+ ## 已稳定的核心候选
30
+
31
+ | 模块 | 职责 | DSH 运行时依赖 |
32
+ |---|---|---:|
33
+ | `task-semantics.js` | Task v2 枚举、旧状态与用户状态派生、自洽校验 | 无 |
34
+ | `provider-contract.js` | 提交结果、受理边界、错误脱敏、候选调度 | 无 |
35
+ | `tasks.js` | Task/Attempt 持久化、观察、恢复与交付状态 | 无;数据根仍沿用 `DSH_HOME` |
36
+ | `doctor.js` | 零网络离线环境与数据诊断 | 无 |
37
+ | `actions.js` | GUI 与 Agent 共用动作 | 有宿主上下文参数,部分动作依赖 Browser/会话能力 |
38
+ | `index.js` | DSH 工具、路由、Skill 与生命周期注册 | 有 |
39
+ | `client.js` | DSH Web Slot、工作台、泡泡和提示词入口 | 有 |
40
+
41
+ 0.1.3 不声称已有完整独立 Core 或 Local Host Adapter。完整 Command Service、Host Port 接口和非 DSH 运行入口属于后续版本;本版先保证任务语义与离线 Doctor 不依赖 DSH 包即可执行。
42
+
43
+ ## Task、Attempt 与 Artifact
44
+
45
+ - 一个用户意图对应一个 Task;每个候选供应商调用对应一个稳定 Attempt。
46
+ - Attempt 必须在可能发送计费请求前落盘。只有明确 `not_accepted` 才允许自动 failover。
47
+ - 生成结果与本地交付是两类事实。生成成功后下载失败仍保持 `outcome=succeeded`。
48
+ - 当前 Artifact 仍由任务中的文件、媒体令牌和附件记录表示;正式 Artifact Manifest、内容哈希和谱系属于 0.2.0。
49
+ - 每次 v2 任务变更递增 Task `revision`;完整状态快照另带进程 `stateEpoch/stateRevision`,客户端拒绝同一 epoch 中迟到的旧快照。
50
+
51
+ 详细状态机见 [Task/Attempt v2 语义契约](TASK_SEMANTICS.md),故障证据见 [故障注入矩阵](FAULT_INJECTION.md)。
52
+
53
+ ## Provider 边界
54
+
55
+ 现有 DashScope 与 OpenAI Images 兼容分支仍位于 `adapters.js`,尚未宣称完整 Provider SDK。0.1.3 已冻结供应商提交所需的最小契约:复合模型身份、写前 Hook、四类提交结果、受理证据和安全错误。新增 Provider 不应绕过该契约直接在失败时切换候选。
56
+
57
+ 完整接口与 conformance runner 延后到 0.1.4+,见 [Provider 提交契约 v0](PROVIDER_SUBMISSION_CONTRACT.md)。
58
+
59
+ ## Host Port 清单
60
+
61
+ | 能力 | 当前来源 | 缺失时行为 |
62
+ |---|---|---|
63
+ | 工具注册与 Fiber 生命周期 | DSH `ctx.tools` / `ctx.effect` | 对应工具不注册;其余能力继续装载 |
64
+ | Web 路由 | DSH `webServer` 或 `httpServer` | 工作台 API、媒体链接和 HTML 渲染不可用 |
65
+ | UI Slot | DSH Web Client | 不影响 Host 侧任务与离线 Doctor |
66
+ | Browser | DSH browser service | 仅 HTML 截图不可用 |
67
+ | 会话附件与输入草稿 | DSH session/input ports | 退化为 Iris 自有产物或浏览器上传 |
68
+ | Skills registry | DSH skills service | 随包 Skill 不自动注册;核心动作仍可用 |
69
+
70
+ 这些依赖目前由 `index.js` 的可选注入和守卫集中处理。0.1.4 将把它们转成正式 Host Adapter 接口并增加 Local Host fixture。
71
+
72
+ ## 事件与 UI
73
+
74
+ 任务和配置写入会触发节流 SSE 快照。每份快照都有进程 epoch 与单调序号;慢消费者进入背压后只保留最新快照,重连仍通过持久化全量状态收敛。工作台只展示稳定人类状态,内部事实轴保留在 API 详情中供诊断和人工动作判断。
75
+
76
+ ## 非目标
77
+
78
+ - 不在 0.1.3 启动独立常驻服务或复制 DSH 聊天界面。
79
+ - 不迁移到 SQLite/JSONL,不破坏旧任务读取。
80
+ - 不新增 Gemini、Fal 或 Replicate 分支。
81
+ - 不把离线 Doctor 的成功等同于 DSH Host、浏览器或真实供应商已可用。