@mokuyoaxis/dsh-iris 0.2.3 → 0.2.4
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.
- package/.dsh/skills/iris-compose-media/references/workflows.md +1 -1
- package/.dsh/skills/iris-use/SKILL.md +2 -1
- package/.dsh/skills/iris-use/references/media-contract.md +12 -2
- package/CHANGELOG.md +16 -1
- package/README.en.md +28 -23
- package/README.md +28 -23
- package/bin/dsh-iris.js +8 -0
- package/docs/AGENT_QUICKSTART.md +7 -7
- package/docs/ARCHITECTURE.md +3 -1
- package/docs/CLI_MANAGEMENT.md +11 -3
- package/docs/DSH_COMPATIBILITY.md +43 -0
- package/docs/DSH_RC2_ADAPTATION.md +4 -2
- package/docs/FUNCTION_MODEL_ASSIGNMENTS.md +63 -0
- package/docs/HEADLESS_CLI.md +10 -8
- package/docs/HOST_ADAPTER_CONTRACT.md +10 -7
- package/docs/HOST_DOCTOR.md +5 -3
- package/docs/IMAGE_IMPORT.md +49 -0
- package/docs/ROADMAP.md +4 -2
- package/docs/VISION_CLI.md +3 -3
- package/docs/VISION_MODEL.md +1 -1
- package/docs/WORKBENCH_ARTIFACTS.md +4 -2
- package/docs/releases/0.2.4.md +27 -0
- package/lib/actions.js +32 -12
- package/lib/adapters.js +5 -2
- package/lib/client.js +28 -29
- package/lib/command-service.js +16 -1
- package/lib/config.js +16 -22
- package/lib/doctor.js +4 -10
- package/lib/dsh-compatibility.js +10 -0
- package/lib/dsh-core-adapter.js +7 -1
- package/lib/host-runtime.js +1 -0
- package/lib/image-edit-input.js +7 -5
- package/lib/image-import.js +61 -0
- package/lib/index.js +39 -15
- package/lib/models.js +9 -3
- package/lib/ocr-model-routing.js +1 -0
- package/lib/provider-adapters.js +11 -2
- package/lib/provider-catalog.js +6 -8
- package/lib/provider-config-service.js +5 -5
- package/lib/provider-protocol.js +6 -0
- package/lib/vision-model-routing.js +22 -8
- package/package.json +9 -8
- package/user_guide.md +25 -17
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# 功能模型分配
|
|
2
|
+
|
|
3
|
+
版本要求:Iris0.2.4。0.2.3只有Music采用严格名单;本页说明升级后的统一规则,发布状态见 [README](../README.md)。
|
|
4
|
+
|
|
5
|
+
在“功能分配(调用顺序)”中为图片、视频、语音、音乐、转写和视觉分别选择模型。模型池登记资源、能力、协议和健康;只有加入功能名单的模型参与该功能的新请求。普通模型使用 `providerId::modelId` 复合引用,同名模型的不同账号独立选择。
|
|
6
|
+
|
|
7
|
+
每次请求按名单顺序选择。已停用、缺少配置、已知冷却或不支持本次模式的项可跳过;名单之外的模型不会补入。临时指定模型也必须属于名单,且本次只调用指定项;失败不会改用其他模型。没有分配或名单全部不可用时明确失败。
|
|
8
|
+
|
|
9
|
+
“清空分配”停止该功能的新调用,保留供应商、模型池、任务和作品。修改名单影响后续请求;原任务的观察和补交付仍绑定原模型和协议,不按新名单重新生成。原供应商停用、移除或绑定漂移时,仍可能无法恢复。
|
|
10
|
+
|
|
11
|
+
## 功能范围
|
|
12
|
+
|
|
13
|
+
- 图片生成与改图共用图片名单;改图只保留支持编辑协议的候选。
|
|
14
|
+
- 视频与S2V共用视频名单,按实际首帧/音频输入筛选。
|
|
15
|
+
- 看图、OCR、定位和视觉摘要共用视觉名单。
|
|
16
|
+
- TTS、Music和转写各自分配;本地裁剪、抽帧等不需要模型。
|
|
17
|
+
- 提示词优化继续使用独立文本路由,不随媒体分配改变。
|
|
18
|
+
|
|
19
|
+
媒体生成仍只在明确未受理时切换候选。已受理或未知状态停止自动换模型;Vision沿用已有有限候选策略。Music的显式有限502重试维持原规则,可能消耗额外额度,每次创建关联新任务。
|
|
20
|
+
|
|
21
|
+
## DSH宿主视觉
|
|
22
|
+
|
|
23
|
+
视觉名单可加入并排序“DSH 当前默认模型”,引用为 `host:current-vision`。它通过宿主默认选择及精确元数据绑定,只有声明支持图片输入才调用;不宣称使用当前对话所选模型。一轮OCR或其他复合操作复用已绑定的实际模型,默认设置变化影响下一次操作。
|
|
24
|
+
|
|
25
|
+
宿主视觉只有明确加入名单才参与,不自动放在自持模型之后。临时指定该项时也只使用该项。独立CLI没有DSH宿主,不能执行此资源;需分配可由CLI直接调用的Provider模型。
|
|
26
|
+
|
|
27
|
+
## 从旧行为升级
|
|
28
|
+
|
|
29
|
+
原来依赖“自动按模型池顺序选择”的功能需要明确分配。已有明确名单及顺序继续保留,升级不自动复制整个模型池、不修改个人配置。未填写和空名单均表示未分配;模型停用后仍可在分配页看到原选项及不可用状态。
|
|
30
|
+
|
|
31
|
+
已有手动模型实测独立于生产名单,按既有确认与支持范围执行;实测成功更新健康状态,不自动分配。发现模型、查看状态和编辑标签不会发起生成。
|
|
32
|
+
|
|
33
|
+
Headless配置示例:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"providers": [
|
|
38
|
+
{
|
|
39
|
+
"id": "provider-a",
|
|
40
|
+
"auth": "none",
|
|
41
|
+
"baseUrl": "http://127.0.0.1:8080/v1",
|
|
42
|
+
"mediaProtocol": "openai-images",
|
|
43
|
+
"models": [
|
|
44
|
+
{"id": "image-a", "capabilities": ["image-gen"]},
|
|
45
|
+
{"id": "vision-a", "capabilities": ["vision"]}
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "provider-b",
|
|
50
|
+
"auth": "none",
|
|
51
|
+
"baseUrl": "http://127.0.0.1:8081/v1",
|
|
52
|
+
"mediaProtocol": "openai-images",
|
|
53
|
+
"models": [{"id": "image-b", "capabilities": ["image-gen"]}]
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
"assignments": {
|
|
57
|
+
"image-gen": ["provider-a::image-a", "provider-b::image-b"],
|
|
58
|
+
"vision": ["provider-a::vision-a"]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
示例引用的账号和模型必须实际存在、启用并声明对应能力。配置操作与参数见 [CLI管理](CLI_MANAGEMENT.md)。
|
package/docs/HEADLESS_CLI.md
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# Headless CLI
|
|
2
2
|
|
|
3
|
-
`run music` 支持音乐生成与模型级协议配置,见 [音乐生成](MUSIC.md)
|
|
3
|
+
`run music` 支持音乐生成与模型级协议配置,见 [音乐生成](MUSIC.md)。0.2.4的六类功能均采用明确分配名单,升级差异见 [功能模型分配](FUNCTION_MODEL_ASSIGNMENTS.md)。
|
|
4
4
|
|
|
5
|
-
本文面向
|
|
5
|
+
本文面向Iris0.2.4,涵盖无DSH的本地处理、媒体生成、视觉分析、配置和任务管理。媒体结果保存为Core Artifact,可在后续进程中检查、分析或导出;纯视觉不自动创建产物。Core内部接口与Artifact v0尚未冻结为公共SDK。
|
|
6
6
|
|
|
7
|
-
需要
|
|
7
|
+
需要Node.js ≥ 22.0.0。按 [README](../README.md) 核对发布状态,安装 `npm install @mokuyoaxis/dsh-iris@0.2.4` 后运行 `npx dsh-iris --help`。源码入口为 `node bin/dsh-iris.js ...`;本地tarball也可用于安装。
|
|
8
8
|
|
|
9
9
|
0.2.1 提供 `vision look / locate / ocr / summarize`。文件输入的纯视觉不需要数据根,支持显式模型覆盖、JSON/文本、结果和拼图文件;图片/帧 Artifact ID 输入需显式数据根,以 reader 读取既有 Core 产物,只有主动音轨转写才创建 Core Task/Artifact。完整命令与输出规则见 [独立视觉 CLI](VISION_CLI.md);S2V、HTML、配置、等待及批量管理见 [CLI 管理](CLI_MANAGEMENT.md)。
|
|
10
10
|
|
|
11
|
+
0.2.4新增 `artifact import --data-root /absolute/path/core --input '{"image_path":"/absolute/path/source.png"}'`,将本地图片保存为持久作品,不调用模型;详见 [图片导入](IMAGE_IMPORT.md)。npm0.2.3不包含此命令。
|
|
12
|
+
|
|
11
13
|
## 配置查询与离线诊断
|
|
12
14
|
|
|
13
15
|
```bash
|
|
@@ -16,7 +18,7 @@ dsh-iris capabilities list --provider-config /absolute/path/to/providers.json
|
|
|
16
18
|
dsh-iris doctor --data-root /absolute/path/to/iris-data --json
|
|
17
19
|
```
|
|
18
20
|
|
|
19
|
-
前两项只读取显式提供的私有配置文件,不创建
|
|
21
|
+
前两项只读取显式提供的私有配置文件,不创建Core Runtime或数据根,也不请求Provider。`providers list`输出供应商身份、启用/配置状态、认证方式、媒体协议及其推断标记、配置能力与模型数;不输出API Key或端点。0.2.4的 `capabilities list` 按六种配置能力列出明确分配且当前CLI可用的 `providerId::modelId` 候选链;空链标为 `gap: no_configured_model`。这些只是配置事实,不证明远端模型或协议可调用。
|
|
20
22
|
|
|
21
23
|
显式 `doctor --data-root` 是只读 Core 盘点:检查 Task/Artifact 结构、Index 一致性、孤立/未解析条目和写者租约;不创建缺失的根、不执行写入探针、不重建索引,也不释放租约。活跃写者可能使盘点在读取期间变化。省略 `--data-root` 时仍检查 DSH profile,保留原有写入探针,并纳入该 profile 的 `core-v0`。两种模式都返回 legacy/Core 计数对照,显式模式只统计指定根同层的 legacy 文件。退出码为 `0` 正常、`1` 警告、`2` 硬错误;诊断不会调用 Provider。
|
|
22
24
|
|
|
@@ -73,11 +75,11 @@ dsh-iris run image \
|
|
|
73
75
|
--input '{"prompt":"一朵雨后的鸢尾花","model_ref":"provider-id::model-id","size":"1024*1024","n":1}'
|
|
74
76
|
```
|
|
75
77
|
|
|
76
|
-
`model_ref`
|
|
78
|
+
`model_ref` 可省略;省略时只使用assignment名单,按配置顺序选择。指定时须属于名单且本次只调用该项。每个请求从首项开始,只有明确 `not_accepted` 才进入下一项。配置文件须为普通文件,POSIX权限不得开放给group/other;API Key、端点、Prompt和下载URL都不会写入Task输出。
|
|
77
79
|
|
|
78
|
-
模型必须存在于配置的 `models` 或旧模型字段中,且具备所请求的能力;缺失时返回配置错误,不注入厂商默认模型。显式 `models:[]` 表示没有可用模型。`model_ref`
|
|
80
|
+
模型必须存在于配置的 `models` 或旧模型字段中,且具备所请求的能力;缺失时返回配置错误,不注入厂商默认模型。显式 `models:[]` 表示没有可用模型。`model_ref` 也接受裸模型名,同名跨供应商时从当前功能名单中取首个匹配项;需要精确绑定账号时使用 `providerId::modelId`。显式指定只选择该模型,不扩展 failover 候选。
|
|
79
81
|
|
|
80
|
-
|
|
82
|
+
裸 DashScope 账号不再自动写入厂商目录或授予功能能力。已有明确保存的模型和旧能力字段绑定继续保留;独立 CLI 配置同样需要声明模型并分配给功能。
|
|
81
83
|
|
|
82
84
|
生图按每个模型的有效图片协议调用,保存真实 PNG/JPEG/WebP 字节。聊天改图使用 `source_artifact_id`,创建关联原图的新 Artifact;具体参数和协议限制见 [模型级图片协议](CLI_MANAGEMENT.md#模型级图片协议) 与 [Artifact 聊天改图](CLI_MANAGEMENT.md#artifact-聊天改图)。
|
|
83
85
|
|
|
@@ -136,7 +138,7 @@ dsh-iris task inspect task_0123456789abcdef01234567 \
|
|
|
136
138
|
|
|
137
139
|
新建 Attempt 可选保存 `stageTimestamps`:排队、开始提交、提交响应、远端终态、开始下载、下载校验完成和本地 Artifact 处理完成七个边界。字段按发生顺序单调不减;旧记录缺失该字段仍可读取。重新交付会从新的下载开始边界重新计时,不伪造尚未跨过的阶段。
|
|
138
140
|
|
|
139
|
-
新建
|
|
141
|
+
新建Attempt还可选保存 `selectionReason`:`explicit` 表示调用方明确指定名单内模型,`assignment` 表示按提交当时的功能名单选择。`pool` 保留为旧记录的历史来源,0.2.4不再产生池补齐候选。该事实随Attempt在Provider submit前落盘;`task inspect` 只展示持久记录,不按当前assignment事后猜测。旧记录缺少字段时保持缺失;第几次failover仍看 `ordinal`。
|
|
140
142
|
|
|
141
143
|
已受理的异步图片 Task 可以显式推进一次:
|
|
142
144
|
|
|
@@ -19,8 +19,8 @@ Host Adapter 只负责把一个宿主的工具、路由、客户端、附件、
|
|
|
19
19
|
| `attachments` | `ctx.get('attachments')` | 保存/读取图片字节,返回 Iris 自有引用 DTO | DSH 图片投影或会话图片读取不可用 |
|
|
20
20
|
| `sessions` | `ctx.get('sessionQuery')` / Client sessions | 列出当前会话的受支持附件和最小模型选择信息 | 只使用 Iris 自有产物或显式上传 |
|
|
21
21
|
| `browser` | `ctx.get('browser')` | 将受限 HTML 渲染为图片;不向 Command 暴露 DSH page/session 对象 | HTML 截图不可用 |
|
|
22
|
-
| `textModel` | DSH LLM/default-model 服务 |
|
|
23
|
-
| `visionModel` | DSH
|
|
22
|
+
| `textModel` | DSH LLM/default-model 服务 | 文本生成及精确模型元数据;当前宿主视觉也由此绑定默认选择 | 宿主文本/视觉不可用,自持 Provider 按各功能名单执行 |
|
|
23
|
+
| `visionModel` | DSH 旧视觉桥接 | 保留 `analyze()` 兼容入口;当前视觉共享端口经 `textModel` 与附件桥接执行 | 旧桥接不可用,不自动授予视觉功能调用资格 |
|
|
24
24
|
|
|
25
25
|
`ports` 只包含真实可调用的方法对象。缺失或版本不兼容的能力进入 `unavailable`,并提供 `kind` 与人类可读 `reason`;Doctor 与运行错误必须消费同一份事实。
|
|
26
26
|
|
|
@@ -28,21 +28,23 @@ Host Adapter 只负责把一个宿主的工具、路由、客户端、附件、
|
|
|
28
28
|
|
|
29
29
|
| Command/入口 | 必需端口 | 可选端口 | 说明 |
|
|
30
30
|
|---|---|---|---|
|
|
31
|
-
| `image` | 无 | `
|
|
32
|
-
| `video`、`tts`、`transcribe` | 无 | 无 | Provider、Task 与产物落盘属于 Iris Core |
|
|
33
|
-
| `look`、`locate`、`ocr` | 无 | `
|
|
31
|
+
| `image` | 无 | `textModel` + `attachments` | 生图按图片名单执行;成功后可选描述按视觉名单执行,不影响生成事实 |
|
|
32
|
+
| `video`、`tts`、`music`、`transcribe` | 无 | 无 | Provider、Task 与产物落盘属于 Iris Core,分别使用功能名单 |
|
|
33
|
+
| `look`、`locate`、`ocr` | 无 | `textModel` + `attachments` | 只按视觉名单尝试自持或显式宿主资源,无可用项时失败 |
|
|
34
34
|
| `crop`、`diff`、`video_frames` | 无 | 无 | 确定性本地动作 |
|
|
35
|
-
| `media_summarize` | 无 | `
|
|
35
|
+
| `media_summarize` | 无 | `textModel` + `attachments` | 帧提取是本地动作,理解阶段只使用视觉名单 |
|
|
36
36
|
| `html` | `browser` | 无 | Command 只调用语义级 `renderHtml` |
|
|
37
37
|
| `relook` | 条件必需 `attachments` + `sessions` | 无 | Iris 自有附件可直接解析;会话附件必须走宿主端口 |
|
|
38
38
|
| `attachments_list`、`attachment_export` | 条件必需 `attachments` + `sessions` | 无 | Iris 自有产物不依赖宿主;会话来源不得读取宿主私有文件 |
|
|
39
39
|
| Task 查询、观察、交付、提醒和知情重试 | 无 | 无 | 事实、费用确认和新旧 Task 关系归 Iris 所有 |
|
|
40
|
-
| Provider/模型/能力配置 | 无 |
|
|
40
|
+
| Provider/模型/能力配置 | 无 | 无 | 普通发现与配置不依赖宿主;手动实测只调用指定Provider,不按生产名单或回退宿主 |
|
|
41
41
|
| Prompt Optimize | `textModel` | `sessions` | 客户端可显式传模型;否则从宿主获取当前/默认选择 |
|
|
42
42
|
| DSH 工具结果投影 | `tools` | `attachments` | 注册与结果转为 DSH attachment 属于 DSH Adapter,不进入 Command |
|
|
43
43
|
| Workbench/API/媒体路由 | `routes` | `clientSlots` | HTTP/UI 只是投影,不是真相来源 |
|
|
44
44
|
| 随包 Skill | `skills` | 无 | Skill 不得绕过 Command、Task 或费用边界 |
|
|
45
45
|
|
|
46
|
+
开发树中的宿主视觉必须以 `host:current-vision` 加入视觉名单并排序;读取的是DSH当前默认选择,不是当前对话选择。不自动追加宿主候选,临时指定失败也不回退。升级规则见 [功能模型分配](FUNCTION_MODEL_ASSIGNMENTS.md)。
|
|
47
|
+
|
|
46
48
|
## 不可违反规则
|
|
47
49
|
|
|
48
50
|
1. Core、Command、Task 和 Provider 模块不得导入 DSH/Cordis 运行时,也不得通过任意字段重新取得原始 `ctx`。
|
|
@@ -89,6 +91,7 @@ Iris 继续作为普通 DSH/Cordis 插件装载:`cordis.patch.yml` 只把 npm
|
|
|
89
91
|
- Host Doctor 对服务端注册账本、客户端版本和 Slot 握手分别给出结果;
|
|
90
92
|
- 已发布 Iris `0.1.4` 在 DSH `0.1.2-rc.1` 与 `0.1.5-rc.1` 上有历史宿主验证记录,不继承为当前版本的支持声明。
|
|
91
93
|
- Iris `0.2.1` 只声明 DSH `0.2.0-rc.2`,已通过真实安装服务隔离验收,保留附件完整引用、绑定明确图片模型路由并适配客户端主视图选择;边界与尚未完成的浏览器实机检查见 [rc.2 适配说明](DSH_RC2_ADAPTATION.md)。
|
|
94
|
+
- Iris0.2.4扩大为rc.2与alpha.4两项准确版本,顶层engines.dsh、嵌套字段、五项可选peer及Doctor同步;Core/Provider契约保持。当前范围和服务/浏览器验证区别见 [DSH版本兼容](DSH_COMPATIBILITY.md)。
|
|
92
95
|
|
|
93
96
|
Local Host 不模拟 Browser、会话或附件。测试需要这些能力时必须显式注入,缺失行为也属于契约。
|
|
94
97
|
|
package/docs/HOST_DOCTOR.md
CHANGED
|
@@ -5,7 +5,9 @@ Host Doctor 是 Iris 在运行中的 DSH 实例内提供的兼容性诊断。它
|
|
|
5
5
|
| 模式 | 入口 | 观察范围 |
|
|
6
6
|
|---|---|---|
|
|
7
7
|
| `offline` | `dsh-iris doctor [--json]` | Node、依赖、私有存储、配置、Task 与产物;不要求 DSH |
|
|
8
|
-
| `host` | 已认证 DSH 中的 `GET /iris/api/doctor` | DSH与Host Port、插件、当前工具/Skill、4组路由、Browser/附件/模型、客户端版本和4个UI Slot;Iris 0.2.
|
|
8
|
+
| `host` | 已认证 DSH 中的 `GET /iris/api/doctor` | DSH与Host Port、插件、当前工具/Skill、4组路由、Browser/附件/模型、客户端版本和4个UI Slot;Iris 0.2.4检查17工具/3项Skill |
|
|
9
|
+
|
|
10
|
+
0.2.4新增 `iris_import_image`,图片导入自身不调用模型。0.2.3检查16工具/3项Skill,发布状态见 [README](../README.md)。
|
|
9
11
|
|
|
10
12
|
两种模式都默认零网络、零计费。Host Doctor 不调用任何 Host Port,不打开 Browser,不读取附件或会话,不调用文本/视觉模型,也不向 Provider 发送请求。它只读取:
|
|
11
13
|
|
|
@@ -29,14 +31,14 @@ Host Doctor 是 Iris 在运行中的 DSH 实例内提供的兼容性诊断。它
|
|
|
29
31
|
|
|
30
32
|
如果刚安装、热更新或强制刷新,先等 Web 页面完成装载,再刷新诊断。未收到客户端握手时,Host Doctor 只报告警告,不会把“服务端已装载”冒充成“UI 已装载”。
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
Iris0.2.4支持DSH `0.2.0-rc.2` 或 `0.2.1-alpha.4`,Doctor与package顶层/嵌套DSH engines及客户端peer保持同一范围。0.2.0–0.2.3仅支持rc.2。旧DSH0.1.2线或0.1.5-rc.1返回版本错误,并提示固定Iris0.1.4;无DSH的CLI/离线诊断不受宿主版本限制。见 [兼容矩阵](DSH_COMPATIBILITY.md)。
|
|
33
35
|
|
|
34
36
|
## 运行时证据
|
|
35
37
|
|
|
36
38
|
服务端只登记成功完成的注册:
|
|
37
39
|
|
|
38
40
|
- 插件身份与 npm 版本;
|
|
39
|
-
- Iris Agent
|
|
41
|
+
- Iris Agent工具名(0.2.4为17个,0.2.3为16个);
|
|
40
42
|
- 随包的 `iris-use`、`iris-compose-media`、`iris-verify-ui`,缺失iris-use明确报告;
|
|
41
43
|
- `/iris/media`、`/iris/api`、`/iris/api/actions`、`/iris/render` 四组逻辑路由。
|
|
42
44
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# 图片导入
|
|
2
|
+
|
|
3
|
+
版本要求:Iris0.2.4;npm0.2.3没有本页的导入命令和工具。发布状态见 [README](../README.md)。
|
|
4
|
+
|
|
5
|
+
把上传图片、会话图片或宿主本地图片保存为Iris作品,获得后续看图、改图、裁剪和导出可复用的作品ID。导入只在本地保存副本,不调用模型、不创建生成任务,原文件保持。
|
|
6
|
+
|
|
7
|
+
支持单张静态PNG、JPEG、WebP,最多20 MiB。格式和尺寸按真实内容识别,保留原始字节;不会按文件名转码,不支持动画、网络URL或`content://`路径。相册中的图片请通过浏览器上传。
|
|
8
|
+
|
|
9
|
+
## 工作台
|
|
10
|
+
|
|
11
|
+
1. 打开作品区,展开“导入图片”。
|
|
12
|
+
2. 用“上传文件”选择图片,也可选当前会话附件;宿主本地文件可通过“高级 · 宿主路径”输入。
|
|
13
|
+
3. 点击“保存到作品”。完成后显示图片,作品区刷新;导入作品标为“导入图片”。
|
|
14
|
+
|
|
15
|
+
单纯上传仍是临时输入副本,既有上传保留期为七天;“保存到作品”成功后,作品与上传副本独立保存,不随该保留期过期。上传或输入格式错误时,按错误提示修正后重新导入。
|
|
16
|
+
|
|
17
|
+
## Agent
|
|
18
|
+
|
|
19
|
+
使用实际已装载的 `iris_import_image`,二选一:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{"image_path":"/absolute/path/source.png"}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{"attachment_id":"current-session-image-id"}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
附件只能来自当前会话或Iris已有的受支持图片引用,不能猜测其他会话附件ID。结果给出作品ID与图片链接。需要修改时,把返回ID交给 `iris_edit_image` 的 `source_artifact_id`;已经是Core图片的作品可直接使用,不必重复导入。
|
|
30
|
+
|
|
31
|
+
## CLI
|
|
32
|
+
|
|
33
|
+
无需DSH或供应商配置,使用明确的数据根和宿主可读绝对路径:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
dsh-iris artifact import --data-root /absolute/path/iris-core \
|
|
37
|
+
--input '{"image_path":"/absolute/path/source.png"}'
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
返回JSON中的 `artifact.id` 是稳定作品ID,`artifact.kind` 为 `imported-image`,并包含媒体类型、尺寸与内容哈希。原路径和文件名不写入作品记录。该命令使用既有Core单写者约束;同一数据根已有其他写者时按现有规则拒绝。
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
dsh-iris artifact export artifact_ID --data-root /absolute/path/iris-core \
|
|
44
|
+
--output /absolute/path/export.png
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
导出保留原字节,输出路径不能覆盖已有文件。看图与改图另按对应功能分配调用模型,见 [视觉CLI](VISION_CLI.md)、[聊天改图](CLI_MANAGEMENT.md#artifact-聊天改图) 和 [功能模型分配](FUNCTION_MODEL_ASSIGNMENTS.md)。
|
|
48
|
+
|
|
49
|
+
本步只提供持久导入与已有操作衔接;原图/新版并排对比、版本选择和配乐关联仍是后续工作。
|
package/docs/ROADMAP.md
CHANGED
|
@@ -4,15 +4,16 @@ Iris 的方向是本地优先、Agent 可调用的多模态创作工作台。用
|
|
|
4
4
|
|
|
5
5
|
## 当前状态
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
本文对应 **Iris0.2.4**,发布状态见 [README](../README.md)。包名为 `@mokuyoaxis/dsh-iris`,同时提供DSH插件与独立CLI,详见 [0.2.4发布说明](releases/0.2.4.md)。
|
|
8
8
|
|
|
9
9
|
- 图片生成、Artifact ID 看图/OCR/定位和聊天改图,支持按模型配置图片协议。
|
|
10
|
+
- 持久图片导入与原生Qwen改图,六类功能统一严格分配及显式宿主视觉;支持DSH rc.2和alpha.4。见 [0.2.4发布说明](releases/0.2.4.md)。
|
|
10
11
|
- 视频、S2V、TTS、转写与音乐生成,共用任务、音频/视频作品和导出入口;音乐使用明确分配名单。
|
|
11
12
|
- 三项 Agent Skills 分别指导单步操作、多步骤创作和界面验收;配乐与检查按用户目标加入。
|
|
12
13
|
- 提示词的忠实整理、明确改写、可选建议与预览;完整同步媒体结果缓存后的交付恢复。
|
|
13
14
|
- 工作台全媒体筛选、分页、跨页选择和下载,CLI 的配置、查询与可恢复维护。
|
|
14
15
|
|
|
15
|
-
DSH与CLI共用Task和Artifact,同一数据根只允许一个写者。纯视觉和提示词预览不自动创建媒体任务;Core与Model Port仍是内部契约。Node.js最低22.0.0,
|
|
16
|
+
DSH与CLI共用Task和Artifact,同一数据根只允许一个写者。纯视觉和提示词预览不自动创建媒体任务;Core与Model Port仍是内部契约。Node.js最低22.0.0,Iris0.2.4支持DSH rc.2或alpha.4,旧宿主固定Iris0.1.4,见 [兼容矩阵](DSH_COMPATIBILITY.md)。
|
|
16
17
|
|
|
17
18
|
## 近期优先:真实使用验收
|
|
18
19
|
|
|
@@ -28,6 +29,7 @@ DSH 工作台与 Headless CLI 共用 Core 的可恢复隔离和恢复入口,
|
|
|
28
29
|
|
|
29
30
|
### 后续 0.2.x
|
|
30
31
|
|
|
32
|
+
- 图片创作的原图/新版并排对比与版本选择;0.2.4已提供持久图片导入和原生Qwen改图。
|
|
31
33
|
- 适配其他协议,包括原生 Gemini、Fal 和后续 Replicate;网关兼容接口与原生协议接入分别验证;
|
|
32
34
|
- 按实际需求增加音乐来源、可控参数和音视频衔接;已有音乐生成入口见 [音乐生成](MUSIC.md);
|
|
33
35
|
- 收藏、标签与工作台搜索(CLI 及工作台过滤、分页、显式选择/批量下载已完成);
|
package/docs/VISION_CLI.md
CHANGED
|
@@ -95,9 +95,9 @@ dsh-iris vision summarize \
|
|
|
95
95
|
}
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
省略 `--model-ref`
|
|
98
|
+
0.2.4省略 `--model-ref` 时仅按 `assignments.vision` 名单排序,不补入模型池。只有本地不可用、明确拒绝或正常空正文才允许下一候选;截断、未知终态、收到正文后的失败、取消和超时停止调用。显式 `--model-ref providerId::modelId` 须已分配且只绑定该账号与模型,失败不会替换;新视觉命令不接受裸模型名。模型需启用并声明vision能力,未配置时直接失败。自持视觉支持OpenAI-compatible Chat Completions SSE;CLI不能执行DSH宿主视觉资源。见 [功能模型分配](FUNCTION_MODEL_ASSIGNMENTS.md)。
|
|
99
99
|
|
|
100
|
-
成功
|
|
100
|
+
成功JSON携带实际`modelRef`、`selectionReason`(`explicit` / `assignment`)、模型身份、正常终态及可用usage;旧记录的`pool`来源仍可读取。OCR实际选择保留在每个成功块上。配置凭据、端点和原始错误响应不会出现在诊断中;模型回答和OCR正文是用户内容。
|
|
101
101
|
|
|
102
102
|
## 输出、预算与退出码
|
|
103
103
|
|
|
@@ -127,6 +127,6 @@ dsh-iris vision summarize \
|
|
|
127
127
|
--input '{"video_path":"/absolute/path/clip.mp4","transcribe":true,"transcribe_model_ref":"aliyun::qwen-audio-3.0-asr-flash-filetrans"}'
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
配置需声明并分配`transcribe`模型,使用既有上传型转写协议(当前DashScope)。省略`transcribe_model_ref`时只使用转写名单,显式指定须属于名单且只使用该项;不能同时提供`transcribe_text`。本次命令观察已受理的同一Core Task,读取成功的文本Artifact后摘要;普通转写失败则返回画面摘要并将`transcription.status`标为`failed`。无音轨标为`no_audio`;取消/超时直接终止摘要,已提交任务保留事实,可按 [Headless CLI](HEADLESS_CLI.md) 继续检查、观察或补交付,不会自动重提。
|
|
131
131
|
|
|
132
132
|
文件输入的纯视觉命令不要求数据根,不创建 Core Runtime、Task 或 Artifact;使用图片/帧 Artifact ID 时只使用显式数据根的 reader,主动音轨转写时才持有 writer 租约。独立提示词优化入口不属于本次交付。
|
package/docs/VISION_MODEL.md
CHANGED
|
@@ -8,7 +8,7 @@ Agent 的 `iris_look_at_image` / `iris_relook_attachment`、工作台的看图/
|
|
|
8
8
|
|
|
9
9
|
`iris_look_at_image` 与看图动作现可用 `artifact_id` 代替 `image_path`,直接读取当前 DSH profile 的 Core 图片,二者必须二选一。图片的 MIME、原字节和内容哈希由共享读取器核对,不要求原文件或临时导出、不写入 Core;生成图片、HTML 截图、裁剪、视频帧均可使用。自持模型成功时无需为 Core 输入另存 DSH 附件;DSH 候选仍通过既有附件桥接。工具文字保留 Core ID,动作 JSON 带 `artifactId`。工作台原表单继续输入文件路径,动作 API 可直接传 ID。独立 CLI 的同一用法见 [视觉 CLI](VISION_CLI.md)。
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
0.2.4按视觉分配名单选择后端,不补入模型池。DSH当前默认模型须作为 `host:current-vision` 明确加入并排序,不再自动追加;临时指定只调用该项。DSH必须明确提供Provider、模型及图片输入能力;默认文本模型、未知元数据和身份漂移在生成前拒绝。自持成功时不查询DSH元数据或额外保存附件。升级变化见 [功能模型分配](FUNCTION_MODEL_ASSIGNMENTS.md)。
|
|
12
12
|
|
|
13
13
|
只有明确认证/权限拒绝、速率/额度拒绝、正常完成但正文为空,以及本地能力不可用,才允许进入下一个候选。已收到部分正文、截断、工具调用、内容阻断、网络/协议错误、取消或超时都会停止操作。正常空结果后的切换可能已经产生上一模型的费用。
|
|
14
14
|
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
状态:**Iris 0.2.2**。
|
|
4
4
|
|
|
5
|
+
0.2.4新增 [图片导入](IMAGE_IMPORT.md):作品区展开“导入图片”,选择文件后点击“保存到作品”。导入图片保留原字节,标为“导入图片”,可直接看图、改图或下载;单纯上传的临时副本与保存后的作品分开。
|
|
6
|
+
|
|
5
7
|
Iris 工作台的作品库统一展示 Core 和旧版作品,包括图片、视频、音频和文本。默认按时间倒序排列,每页 24 个;使用上一页、下一页浏览全部作品。媒体类型、作品来源和产物类型可组合筛选,匹配总数与 Core/旧版计数均按当前筛选计算。切换筛选回到第一页,刷新保留页码和筛选;尾页因作品数量减少而超界时,回到最后一页。
|
|
6
8
|
|
|
7
9
|
Core 的原始输入 `host-input` 不出现在作品库。不可读取的 Core 条目局部跳过并提示;Core 整体暂时不可用时仍可浏览旧版作品,此时计数只含可读取来源。图片提供预览,视频、音频提供播放器,文本可以打开原文件。
|
|
@@ -22,9 +24,9 @@ Core 图片卡的“看图”“OCR”按钮直接读取原 Artifact。点击即
|
|
|
22
24
|
|
|
23
25
|
## 从图片卡改图
|
|
24
26
|
|
|
25
|
-
Core
|
|
27
|
+
Core静态PNG/JPEG/WebP图片卡提供“改图”。填写修改指令,可选择已分配的带图编辑模型,或按当前生图名单顺序选择。面板只读取配置,不自动实测;列出openai-chat-images及0.2.4接入的DashScope Qwen原生改图模型,冷却/额度耗尽项不可选择。具体型号见 [CLI改图](CLI_MANAGEMENT.md#artifact-聊天改图)。
|
|
26
28
|
|
|
27
|
-
点击“生成修改版”才调用模型,原图保留,修改版作为关联原图的新 Core 作品显示。成功后提供新 Artifact 链接、刷新作品库,保留筛选和页码;新作品可继续看图/OCR、编辑、下载和管理。来源最多 20 MiB
|
|
29
|
+
点击“生成修改版”才调用模型,原图保留,修改版作为关联原图的新 Core 作品显示。成功后提供新 Artifact 链接、刷新作品库,保留筛选和页码;新作品可继续看图/OCR、编辑、下载和管理。来源最多 20 MiB;大图只处理发送副本,预算设置也可在支持改图的模型行编辑。
|
|
28
30
|
|
|
29
31
|
“停止等待”、关闭面板或切换分析会中止在途等待,迟到响应不覆盖新面板。远端可能已受理,须在任务区查看结果,不会自动再次生成。编辑任务的手动重试要求重新输入修改指令并确认原图 ID;只支持一次带图请求,不保存聊天历史或提供蒙版。详见 [CLI 改图](CLI_MANAGEMENT.md#artifact-聊天改图)。
|
|
30
32
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Iris 0.2.4:图片续作、统一分配与新版宿主兼容
|
|
2
|
+
|
|
3
|
+
0.2.4让已有图片可以直接进入作品库并继续编辑,统一六类功能的模型选择规则,同时支持DSH rc.2与alpha.4。
|
|
4
|
+
|
|
5
|
+
## 升级前检查功能分配
|
|
6
|
+
|
|
7
|
+
图片、视频、TTS、Music、转写和视觉只使用各自明确分配的有序名单。名单为空时停止新调用,临时指定的模型也必须已分配,且只调用该项。以前依赖自动补入模型池的功能,需要在升级后明确分配模型。
|
|
8
|
+
|
|
9
|
+
供应商、模型池和已有名单保留,不自动迁移个人配置。旧任务仍绑定原模型查询和补交付;手动模型实测独立于生产名单。DSH默认视觉改为需要明确加入名单的“DSH 当前默认模型”,独立CLI不能调用该宿主资源。见 [完整升级说明](../FUNCTION_MODEL_ASSIGNMENTS.md)。
|
|
10
|
+
|
|
11
|
+
## 图片导入与原生Qwen改图
|
|
12
|
+
|
|
13
|
+
工作台“导入图片”、`iris_import_image` 和CLI `artifact import` 保存静态PNG/JPEG/WebP图片,最多20 MiB,返回持久作品ID。保留原字节和源文件,不调用模型;已有Core作品无需重复导入。见 [图片导入](../IMAGE_IMPORT.md)。
|
|
14
|
+
|
|
15
|
+
`iris_edit_image`、CLI和工作台改图支持DashScope原生Qwen edit/max/plus、2.0/pro系列及日期快照,继续支持聊天生图协议。模型还须具备image-gen能力并加入生图名单,具体账号与地域是否可用由服务端决定。`qwen-image-2.0-pro` 已通过真实CLI带图生成、取回与保存来源关系的实测。
|
|
16
|
+
|
|
17
|
+
原图只读,发送副本按账号/模型预算处理;修改版保存为独立作品并关联来源。原生Qwen输入副本另受10 MiB上限约束。编辑精度、输出尺寸由模型决定,不提供蒙版、多参考图或像素级保真保证。见 [Artifact改图](../CLI_MANAGEMENT.md#artifact-聊天改图)。
|
|
18
|
+
|
|
19
|
+
## DSH双版本兼容
|
|
20
|
+
|
|
21
|
+
支持准确版本 `0.2.0-rc.2` 和 `0.2.1-alpha.4`,manifest、可选客户端peer及Doctor同步。不要求已有rc.2用户升级宿主,也不据此支持整个0.2.x。Iris最低Node.js为22.0.0;DSH若要求更高,以宿主为准。见 [兼容矩阵与验证范围](../DSH_COMPATIBILITY.md)。
|
|
22
|
+
|
|
23
|
+
## 使用与验证范围
|
|
24
|
+
|
|
25
|
+
Agent工具增至17项,三项Skills的共享说明包含图片导入、严格分配和Qwen改图。Music仍是可选功能,本版未更换音乐来源或增加新的音乐协议。
|
|
26
|
+
|
|
27
|
+
宿主隔离验收覆盖实际官方SDK服务、工具/附件交付、HTTP与界面插槽;React/DOM和部分会话数据使用fixture,完整浏览器/移动端交互与热更新仍需实际使用验证。未增加Core数据格式迁移或生产依赖。
|
package/lib/actions.js
CHANGED
|
@@ -23,7 +23,7 @@ import { registerMedia, mediaLinksOf, webBase } from './media.js';
|
|
|
23
23
|
import { RED_TEST_IMAGE } from './vision.js';
|
|
24
24
|
import { runVisionRequest, readVisionImageFile, probeVisionModel, visionImageFromDataUrl } from './vision-model-routing.js';
|
|
25
25
|
import { HOST_CONTRACT_VERSION, HOST_PORTS, defineHostAdapter, hasHostPort, requireHostPort } from './host-contract.js';
|
|
26
|
-
import { coreSnapshotForDsh, cropForDsh, diffForDsh, framesForDsh, summaryFramesForDsh, visionImageForDsh, htmlForDsh, inspectProviderTaskForDsh, submitMusicForDsh, submitProviderTaskForDsh, watchProviderTaskForDsh } from './dsh-core-adapter.js';
|
|
26
|
+
import { coreSnapshotForDsh, importImageForDsh, cropForDsh, diffForDsh, framesForDsh, summaryFramesForDsh, visionImageForDsh, htmlForDsh, inspectProviderTaskForDsh, submitMusicForDsh, submitProviderTaskForDsh, watchProviderTaskForDsh } from './dsh-core-adapter.js';
|
|
27
27
|
import { runLocateRequest, runSummaryRequest } from './composite-vision-routing.js';
|
|
28
28
|
import { normalizeSummarySource, summaryFrameRecords, summaryTimelineLabel } from './summary-input.js';
|
|
29
29
|
import { normalizeVisionImageSource } from './vision-input.js';
|
|
@@ -31,7 +31,7 @@ import { formatOcrResult } from './ocr.js';
|
|
|
31
31
|
import { runOcrRequest } from './ocr-model-routing.js';
|
|
32
32
|
import { ffmpegAvailable, extractFrames, probeVideo } from './media-probe.js';
|
|
33
33
|
import { ensurePrivateDir, writePrivateFile } from './private-storage.js';
|
|
34
|
-
import { selectMediaProtocol, selectImageProtocol, providerForImageModel } from './provider-protocol.js';
|
|
34
|
+
import { selectMediaProtocol, selectImageProtocol, providerForImageModel, supportsImageEdit } from './provider-protocol.js';
|
|
35
35
|
import { musicCandidatesFromCatalog, providerTaskBinding } from './provider-catalog.js';
|
|
36
36
|
import { invokeProviderOperation, providerPollTaskView, prepareProviderInput } from './provider-adapter.js';
|
|
37
37
|
import { createConfiguredProviderAdapter as createProviderAdapter } from './provider-adapters.js';
|
|
@@ -49,6 +49,11 @@ function createConfiguredProviderAdapter(provider, options = {}) {
|
|
|
49
49
|
onRateLimit: options.allowRateLimited ? undefined : store.recordRateLimit });
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
function imageRoutingForModel(provider, modelId) {
|
|
53
|
+
const routing = selectImageProtocol(provider, modelId);
|
|
54
|
+
return { ...routing, editSupported: supportsImageEdit(routing.mediaProtocol, modelId) };
|
|
55
|
+
}
|
|
56
|
+
|
|
52
57
|
const EMPTY_ACTION_HOST = defineHostAdapter({
|
|
53
58
|
id: 'iris-hostless',
|
|
54
59
|
ports: {},
|
|
@@ -90,7 +95,7 @@ function selectProviders(capability, label, requestedModelRef) {
|
|
|
90
95
|
let providers = store.pickAllFor(capability);
|
|
91
96
|
const requested = String(requestedModelRef || '').trim();
|
|
92
97
|
if (requested) {
|
|
93
|
-
const pool = models.modelPool(store.providers());
|
|
98
|
+
const pool = models.orderedModels(models.modelPool(store.providers()), capability, store.assignments()[capability], { includeRateLimited: true });
|
|
94
99
|
const selected = models.resolvePoolModel(pool, requested, capability);
|
|
95
100
|
if (selected?.rateLimited) throw Object.assign(new Error(store.modelHealth(selected.providerId, selected.id, capability).retryAt
|
|
96
101
|
? 'iris: 指定模型正在限流冷却,请稍后使用或手动实测'
|
|
@@ -99,7 +104,7 @@ function selectProviders(capability, label, requestedModelRef) {
|
|
|
99
104
|
});
|
|
100
105
|
const field = models.CAP_FIELD[capability];
|
|
101
106
|
providers = selected ? providers.filter((p) => p.id === selected.providerId && p[field] === selected.id) : [];
|
|
102
|
-
if (!providers.length) throw new Error('iris:
|
|
107
|
+
if (!providers.length) throw new Error('iris: 指定模型未分配给该功能、不可用或不具备' + label + '能力');
|
|
103
108
|
}
|
|
104
109
|
if (!providers.length) throw new Error('iris: 没有可用' + label + '供应商——先在 Iris 设置里添加、标注并分配模型');
|
|
105
110
|
return providers;
|
|
@@ -462,6 +467,15 @@ export async function runAction(host, name, args, { signal } = {}) {
|
|
|
462
467
|
|
|
463
468
|
/* ============ 动作实现 ============ */
|
|
464
469
|
|
|
470
|
+
register('image_import', async (_host, args, { signal }) => {
|
|
471
|
+
if (args.image_path !== undefined && args.image_bytes !== undefined) throw new Error('图片导入只能选择一个来源');
|
|
472
|
+
const { artifact } = await importImageForDsh({ imagePath: args.image_path, imageBytes: args.image_bytes, signal });
|
|
473
|
+
const imageUrl = '/iris/api/core/artifact/' + artifact.id + '/media';
|
|
474
|
+
const text = `已导入图片(${artifact.metadata.width}×${artifact.metadata.height}),原文件保留。\n作品ID:${artifact.id}`;
|
|
475
|
+
return { ok: true, storage: 'core', artifact, artifactId: artifact.id, artifactIds: [artifact.id], imageUrl, text,
|
|
476
|
+
blocks: [{ type: 'text', text: text + `\n图片:${imageUrl}` }] };
|
|
477
|
+
});
|
|
478
|
+
|
|
465
479
|
/* ---------- 🖼️ 画图 ---------- */
|
|
466
480
|
async function imageAction(host, args, { signal }, editing = false) {
|
|
467
481
|
if (editing && !args.source_artifact_id) throw new Error('iris: 改图必须提供 source_artifact_id');
|
|
@@ -1038,7 +1052,7 @@ register('providers_list', async (host, args) => {
|
|
|
1038
1052
|
...(m.musicProtocol !== undefined ? { musicProtocol: m.musicProtocol } : {}),
|
|
1039
1053
|
...(m.visionInput !== undefined ? { visionInput: m.visionInput } : {}),
|
|
1040
1054
|
...(m.capabilities.includes(cap.CAPABILITIES.VISION) ? { visionInputEffective: visionInputLimits(p, m.id) } : {}),
|
|
1041
|
-
...(m.capabilities.includes(cap.CAPABILITIES.IMAGE) ? { imageRouting:
|
|
1055
|
+
...(m.capabilities.includes(cap.CAPABILITIES.IMAGE) ? { imageRouting: imageRoutingForModel(p, m.id) } : {}),
|
|
1042
1056
|
verified: m.verified || null,
|
|
1043
1057
|
health: Object.fromEntries(m.capabilities.map((capability) => [
|
|
1044
1058
|
capability, store.modelHealth(p.id, m.id, capability)
|
|
@@ -1103,11 +1117,11 @@ register('providers_discover', async (host, args, { signal }) => {
|
|
|
1103
1117
|
register('providers_test_vision', async (host, args, { signal }) => {
|
|
1104
1118
|
const p = store.providerById(String(args.id || ''));
|
|
1105
1119
|
if (!p) throw new Error('iris: 供应商不存在');
|
|
1106
|
-
const
|
|
1107
|
-
if (!
|
|
1108
|
-
const model =
|
|
1120
|
+
const vision = models.providerModels(p).find(m => m.capabilities.includes(cap.CAPABILITIES.VISION));
|
|
1121
|
+
if (!vision) return { ok: true, tested: false, text: '该供应商未配置 vision 模型,跳过' };
|
|
1122
|
+
const model = vision.id;
|
|
1109
1123
|
if (args.confirm_paid !== true) throw new Error('iris: 视觉实测会发起真实供应商请求,请先明确确认');
|
|
1110
|
-
const r = await probeVisionModel(
|
|
1124
|
+
const r = await probeVisionModel(p, model, visionImageFromDataUrl(RED_TEST_IMAGE), { timeoutMs: 15000, signal });
|
|
1111
1125
|
store.setModelVerified(p.id, model, cap.CAPABILITIES.VISION, {
|
|
1112
1126
|
ok: r.ok,
|
|
1113
1127
|
note: r.ok ? '认出红色测试图' : (r.error || '未识别出红色'),
|
|
@@ -1287,17 +1301,23 @@ register('providers_test_model', async (host, args, { signal }) => {
|
|
|
1287
1301
|
|
|
1288
1302
|
/** 查询:全部分配 + 每个能力可用的模型池(client 渲染下拉/排序) */
|
|
1289
1303
|
register('assignments_get', async (host, args) => {
|
|
1290
|
-
const
|
|
1304
|
+
const providers = store.allProviders();
|
|
1305
|
+
const configured = new Set(store.providers().map(provider => provider.id));
|
|
1306
|
+
const pool = models.modelPool(providers, { includeHostVision: true });
|
|
1291
1307
|
const byCap = {};
|
|
1292
1308
|
for (const m of pool) {
|
|
1293
1309
|
for (const c of m.capabilities) {
|
|
1294
1310
|
if (!byCap[c]) byCap[c] = [];
|
|
1295
|
-
|
|
1311
|
+
const provider = providers.find(provider => provider.id === m.providerId);
|
|
1312
|
+
byCap[c].push({ ref: m.ref, id: m.id, providerId: m.providerId,
|
|
1313
|
+
label: m.ref === models.HOST_VISION_REF ? 'DSH 当前默认模型' : m.id + ' · ' + m.providerId,
|
|
1314
|
+
unavailable: m.ref !== models.HOST_VISION_REF && (!configured.has(m.providerId) || m.rateLimited === true),
|
|
1315
|
+
...(c === cap.CAPABILITIES.IMAGE && provider ? { imageRouting: imageRoutingForModel(provider, m.id) } : {}) });
|
|
1296
1316
|
}
|
|
1297
1317
|
}
|
|
1298
1318
|
// order:归一化的有序分配列表(GUI 直接渲染 failover 顺序,无需处理单字符串旧格式)
|
|
1299
1319
|
const order = {};
|
|
1300
|
-
for (const c of Object.
|
|
1320
|
+
for (const c of Object.values(cap.CAPABILITIES)) order[c] = store.assignmentOrder(c);
|
|
1301
1321
|
return { ok: true, assignments: store.assignments(), order, poolByCapability: byCap };
|
|
1302
1322
|
});
|
|
1303
1323
|
|
package/lib/adapters.js
CHANGED
|
@@ -189,7 +189,7 @@ export function applyImageSize({ protocol, mode, size }) {
|
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
/** 新版多模态同步协议:响应中直接返回图片 URL。 */
|
|
192
|
-
export async function generateImageMultimodal({ key, baseUrl, model, prompt, size, n = 1, timeoutMs = T_SYNC_GEN, signal }) {
|
|
192
|
+
export async function generateImageMultimodal({ key, baseUrl, model, prompt, image, size, n = 1, timeoutMs = T_SYNC_GEN, signal }) {
|
|
193
193
|
const apiBase = dashscopeApiBase(baseUrl);
|
|
194
194
|
const requestSize = applyImageSize({ protocol: 'dashscope', mode: 'multimodal-sync', size });
|
|
195
195
|
const { res, body } = await fetchImageJson(`${apiBase}/services/aigc/multimodal-generation/generation`, {
|
|
@@ -198,7 +198,10 @@ export async function generateImageMultimodal({ key, baseUrl, model, prompt, siz
|
|
|
198
198
|
signal: timeoutSignal(timeoutMs, signal),
|
|
199
199
|
body: JSON.stringify({
|
|
200
200
|
model,
|
|
201
|
-
input: { messages: [{ role: 'user', content: [
|
|
201
|
+
input: { messages: [{ role: 'user', content: [
|
|
202
|
+
...(image ? [{ image: 'data:' + image.mediaType + ';base64,' + Buffer.from(image.bytes).toString('base64') }] : []),
|
|
203
|
+
{ text: prompt }
|
|
204
|
+
] }] },
|
|
202
205
|
parameters: { ...(requestSize ? { size: requestSize } : {}), n: Number(n) || 1 }
|
|
203
206
|
})
|
|
204
207
|
});
|