@mokuyoaxis/dsh-iris 0.2.2 → 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.
Files changed (79) hide show
  1. package/.dsh/skills/iris-compose-media/SKILL.md +23 -73
  2. package/.dsh/skills/iris-compose-media/agents/openai.yaml +1 -1
  3. package/.dsh/skills/iris-compose-media/references/task-v2-recovery.md +23 -22
  4. package/.dsh/skills/iris-compose-media/references/workflows.md +25 -30
  5. package/.dsh/skills/iris-use/SKILL.md +42 -0
  6. package/.dsh/skills/iris-use/agents/openai.yaml +4 -0
  7. package/.dsh/skills/iris-use/references/media-contract.md +83 -0
  8. package/.dsh/skills/iris-verify-ui/SKILL.md +9 -7
  9. package/.dsh/skills/iris-verify-ui/agents/openai.yaml +1 -1
  10. package/.dsh/skills/iris-verify-ui/references/verdict-and-degradation.md +3 -0
  11. package/CHANGELOG.md +41 -2
  12. package/README.en.md +50 -38
  13. package/README.md +48 -37
  14. package/bin/dsh-iris.js +35 -6
  15. package/docs/AGENT_QUICKSTART.md +9 -9
  16. package/docs/ARCHITECTURE.md +4 -2
  17. package/docs/CLI_MANAGEMENT.md +11 -3
  18. package/docs/CORE_RUNTIME_CONTRACT.md +3 -1
  19. package/docs/DSH_COMPATIBILITY.md +43 -0
  20. package/docs/DSH_CORE_MIGRATION.md +6 -2
  21. package/docs/DSH_RC2_ADAPTATION.md +4 -2
  22. package/docs/FAULT_INJECTION.md +1 -0
  23. package/docs/FUNCTION_MODEL_ASSIGNMENTS.md +63 -0
  24. package/docs/HEADLESS_CLI.md +14 -8
  25. package/docs/HOST_ADAPTER_CONTRACT.md +10 -7
  26. package/docs/HOST_DOCTOR.md +6 -4
  27. package/docs/IMAGE_IMPORT.md +49 -0
  28. package/docs/MODEL_PORT_CONTRACT.md +6 -2
  29. package/docs/MUSIC.md +77 -0
  30. package/docs/PROMPT_OPTIMIZER.md +48 -10
  31. package/docs/PROVIDER_ADAPTER_CONTRACT.md +2 -0
  32. package/docs/ROADMAP.md +16 -25
  33. package/docs/SECURITY.md +3 -2
  34. package/docs/SYNC_DELIVERY_RECOVERY.md +39 -0
  35. package/docs/TASK_SEMANTICS.md +4 -4
  36. package/docs/VISION_CLI.md +3 -3
  37. package/docs/VISION_MODEL.md +1 -1
  38. package/docs/WORKBENCH_ARTIFACTS.md +4 -2
  39. package/docs/releases/0.2.3.md +54 -0
  40. package/docs/releases/0.2.4.md +27 -0
  41. package/lib/actions.js +71 -14
  42. package/lib/adapters.js +6 -2
  43. package/lib/api.js +14 -5
  44. package/lib/bundled-skills.js +1 -1
  45. package/lib/capability.js +2 -0
  46. package/lib/client.js +131 -47
  47. package/lib/command-service.js +28 -4
  48. package/lib/config.js +41 -23
  49. package/lib/core-artifact-store.js +44 -6
  50. package/lib/core-delivery-cache.js +145 -0
  51. package/lib/core-maintenance.js +12 -1
  52. package/lib/core-tasks.js +19 -5
  53. package/lib/core-user-projection.js +2 -2
  54. package/lib/doctor.js +4 -10
  55. package/lib/dsh-compatibility.js +10 -0
  56. package/lib/dsh-core-adapter.js +20 -4
  57. package/lib/dsh-text-model-adapter.js +15 -2
  58. package/lib/generation-input.js +10 -0
  59. package/lib/host-runtime.js +5 -2
  60. package/lib/image-edit-input.js +7 -5
  61. package/lib/image-import.js +61 -0
  62. package/lib/index.js +60 -17
  63. package/lib/models.js +12 -3
  64. package/lib/music-generation.js +21 -0
  65. package/lib/music-options.js +18 -0
  66. package/lib/music-transport.js +46 -0
  67. package/lib/ocr-model-routing.js +1 -0
  68. package/lib/prompt-optimizer-config.js +92 -21
  69. package/lib/prompt-optimizer-core.js +51 -6
  70. package/lib/prompt-optimizer.js +20 -14
  71. package/lib/provider-adapter.js +1 -0
  72. package/lib/provider-adapters.js +35 -3
  73. package/lib/provider-catalog.js +20 -11
  74. package/lib/provider-config-service.js +18 -6
  75. package/lib/provider-protocol.js +18 -0
  76. package/lib/provider-task-runner.js +80 -5
  77. package/lib/vision-model-routing.js +22 -8
  78. package/package.json +12 -9
  79. package/user_guide.md +45 -23
package/bin/dsh-iris.js CHANGED
@@ -5,11 +5,12 @@ import { createCommandService } from '../lib/command-service.js';
5
5
  import { createCoreRuntime } from '../lib/core-runtime.js';
6
6
  import { recoverCoreWriterLease } from '../lib/core-lease-recovery.js';
7
7
  import { doctor, formatDoctorReport } from '../lib/doctor.js';
8
- import { loadProviderCatalog, providerCatalogSnapshot, catalogCapabilitySnapshot, imageCandidatesFromCatalog, providerForTaskFromCatalog, providerTaskBinding, transcribeCandidatesFromCatalog, ttsCandidatesFromCatalog, videoCandidatesFromCatalog } from '../lib/provider-catalog.js';
8
+ import { loadProviderCatalog, providerCatalogSnapshot, catalogCapabilitySnapshot, imageCandidatesFromCatalog, musicCandidatesFromCatalog, providerForTaskFromCatalog, providerTaskBinding, transcribeCandidatesFromCatalog, ttsCandidatesFromCatalog, videoCandidatesFromCatalog } from '../lib/provider-catalog.js';
9
9
  import { createConfiguredProviderAdapter } from '../lib/provider-adapters.js';
10
10
  import { providerForImageModel } from '../lib/provider-protocol.js';
11
11
  import { prepareProviderInput } from '../lib/provider-adapter.js';
12
12
  import { createProviderTaskRunner } from '../lib/provider-task-runner.js';
13
+ import { generateMusicTask } from '../lib/music-generation.js';
13
14
  import { GenerationInputError, normalizeGenerationInput } from '../lib/generation-input.js';
14
15
  import { executeVisionCommand, normalizeVisionInput } from '../lib/headless-vision.js';
15
16
  import { videoTaskCandidates } from '../lib/video-input.js';
@@ -47,7 +48,7 @@ function usage() {
47
48
  ' dsh-iris providers <add|set> --provider-config <absolute-path> --input <provider-json>',
48
49
  ' dsh-iris providers remove <provider-id> --provider-config <absolute-path>',
49
50
  ' dsh-iris models list --provider-config <absolute-path>',
50
- ' dsh-iris models <add|remove|caps|protocol|vision-input> <providerId::modelId> --provider-config <absolute-path> [--input <json>]',
51
+ ' dsh-iris models <add|remove|caps|protocol|music-protocol|vision-input> <providerId::modelId> --provider-config <absolute-path> [--input <json>]',
51
52
  ' dsh-iris models discover <provider-id> --provider-config <absolute-path> [--apply <true|false>]',
52
53
  ' dsh-iris models test <providerId::modelId> --capability <vision|tts|image-gen|video-gen|transcribe> --provider-config <absolute-path> [--data-root <absolute-path>]',
53
54
  ' dsh-iris assignments <list|set|clear> --provider-config <absolute-path> [--input <json>]',
@@ -60,6 +61,7 @@ function usage() {
60
61
  ' dsh-iris run image --data-root <absolute-path> --provider-config <absolute-path> --input <json>',
61
62
  ' dsh-iris run video --data-root <absolute-path> --provider-config <absolute-path> --input <json>',
62
63
  ' dsh-iris run tts --data-root <absolute-path> --provider-config <absolute-path> --input <json>',
64
+ ' dsh-iris run music --data-root <absolute-path> --provider-config <absolute-path> --input <json>',
63
65
  ' dsh-iris run transcribe --data-root <absolute-path> --provider-config <absolute-path> --input <json>',
64
66
  ' dsh-iris task inspect <id> --data-root <absolute-path>',
65
67
  ' dsh-iris task list --data-root <absolute-path>',
@@ -67,10 +69,11 @@ function usage() {
67
69
  ' dsh-iris <task|artifact> inspect-many --data-root <absolute-path> --input <json>',
68
70
  ' dsh-iris task observe <id> --data-root <absolute-path> --provider-config <absolute-path>',
69
71
  ' dsh-iris task wait <id> --data-root <absolute-path> [--provider-config <absolute-path>] [--timeout-ms <1..1200000>] [--poll-interval-ms <50..60000>]',
70
- ' dsh-iris task redeliver <id> --data-root <absolute-path> --provider-config <absolute-path>',
72
+ ' dsh-iris task redeliver <id> --data-root <absolute-path> [--provider-config <absolute-path>]',
71
73
  ' dsh-iris task cancel <id> --data-root <absolute-path> --provider-config <absolute-path>',
72
74
  ' dsh-iris task retry <id> --data-root <absolute-path> --provider-config <absolute-path> --input <json> --confirm-billing [--model-ref <providerId::modelId>]',
73
75
  ' dsh-iris artifact inspect <id> --data-root <absolute-path>',
76
+ ' dsh-iris artifact import --data-root <absolute-path> --input <json with image_path>',
74
77
  ' dsh-iris artifact list --data-root <absolute-path>',
75
78
  ' artifact list supports --offset, --limit, --kind, --media-type, --task-id.',
76
79
  ' dsh-iris artifact export-many --data-root <absolute-path> --input <json> --output <absolute-directory>',
@@ -231,7 +234,7 @@ async function main(args) {
231
234
 
232
235
  if (['config', 'providers', 'models', 'assignments'].includes(args[0])) {
233
236
  const [group, verb] = args;
234
- const verbs = { config: ['init', 'show', 'check'], providers: ['add', 'set', 'remove'], models: ['list', 'add', 'remove', 'caps', 'protocol', 'vision-input', 'discover', 'test'], assignments: ['list', 'set', 'clear'] };
237
+ const verbs = { config: ['init', 'show', 'check'], providers: ['add', 'set', 'remove'], models: ['list', 'add', 'remove', 'caps', 'protocol', 'music-protocol', 'vision-input', 'discover', 'test'], assignments: ['list', 'set', 'clear'] };
235
238
  if (!verbs[group].includes(verb)) throw new CliUsageError('未知配置命令');
236
239
  const positional = (group === 'providers' && verb === 'remove') || (group === 'models' && verb !== 'list');
237
240
  const id = positional ? required(args[2], group === 'providers' || verb === 'discover' ? 'provider-id' : 'model-ref') : undefined;
@@ -250,6 +253,7 @@ async function main(args) {
250
253
  const result = await executeConfigCommand(required(options['provider-config'], 'provider-config'), group === 'config' ? verb : group + '.' + verb, input, {
251
254
  signal: cliAbortController.signal,
252
255
  probe: async ({ provider, modelId, capability, signal }) => {
256
+ if (capability === 'music-gen') return { skipped: true, ok: false, reason: 'Music 不发起小样本探测;请使用 run music 提交创作要求' };
253
257
  if (capability === 'vision') return probeVisionModel(provider, modelId, { bytes: Buffer.from(RED_TEST_IMAGE.split(',')[1], 'base64'), mediaType: 'image/png' }, { signal });
254
258
  if (['video-gen', 'transcribe'].includes(capability) && !options.input) return {
255
259
  skipped: true, ok: false, reason: '请用 models test --input 提供与 run video/transcribe 相同的真实素材;未发起请求'
@@ -398,6 +402,22 @@ async function main(args) {
398
402
  }
399
403
 
400
404
  // 语音合成输入冻结(E2 Profile):同步完成型,一次命令内完成 Task → Artifact。
405
+ if (args[0] === 'run' && args[1] === 'music') {
406
+ const options = flags(args.slice(2), ['data-root', 'provider-config', 'input']);
407
+ const normalized = generationInput('music', jsonInput(options.input));
408
+ const catalog = loadProviderCatalog(required(options['provider-config'], 'provider-config'));
409
+ const routes = musicCandidatesFromCatalog(catalog, normalized.modelRef);
410
+ let result;
411
+ await withRawRuntime('writer', options['data-root'], async runtime => {
412
+ result = await generateMusicTask({ runner: createProviderTaskRunner(runtime),
413
+ candidates: routes.map(route => ({ adapter: trackedProviderAdapter(route.provider, options), model: route.modelRef,
414
+ selectionReason: route.selectionReason, providerBinding: providerTaskBinding(route.provider) })),
415
+ providerInput: normalized.providerInput, options: normalized.musicOptions, signal: cliAbortController.signal });
416
+ console.log(JSON.stringify(result, null, 2));
417
+ });
418
+ return result.task.outcome === 'succeeded' && result.task.deliveryState === 'ready' ? 0 : 1;
419
+ }
420
+
401
421
  if (args[0] === 'run' && args[1] === 'tts') {
402
422
  const options = flags(args.slice(2), ['data-root', 'provider-config', 'input']);
403
423
  const { providerInput, modelRef } = generationInput('tts', jsonInput(options.input));
@@ -473,10 +493,10 @@ async function main(args) {
473
493
 
474
494
  if (args[0] === 'task' && args[1] === 'redeliver' && args[2]) {
475
495
  const options = flags(args.slice(3), ['data-root', 'provider-config']);
476
- const catalog = loadProviderCatalog(required(options['provider-config'], 'provider-config'));
496
+ const catalog = options['provider-config'] ? loadProviderCatalog(options['provider-config']) : null;
477
497
  await withRuntime('reader', options['data-root'], (commands) => commands.execute('task.inspect', { task_id: args[2] }));
478
498
  const result = await withRuntime('writer', options['data-root'], (commands) => commands.execute('task.redeliver', { task_id: args[2] }), {
479
- resolveTaskAdapter: (task) => trackedProviderAdapter(providerForTaskFromCatalog(catalog, task), options, task)
499
+ ...(catalog ? { resolveTaskAdapter: (task) => trackedProviderAdapter(providerForTaskFromCatalog(catalog, task), options, task) } : {})
480
500
  });
481
501
  console.log(JSON.stringify(result, null, 2));
482
502
  return 0;
@@ -512,6 +532,8 @@ async function main(args) {
512
532
  ? videoCandidatesFromCatalog(catalog, modelRef || undefined)
513
533
  : capability === 'tts'
514
534
  ? ttsCandidatesFromCatalog(catalog, modelRef || undefined)
535
+ : capability === 'music'
536
+ ? musicCandidatesFromCatalog(catalog, modelRef || undefined)
515
537
  : capability === 'transcribe'
516
538
  ? transcribeCandidatesFromCatalog(catalog, modelRef || undefined)
517
539
  : imageCandidatesFromCatalog(catalog, modelRef || undefined)
@@ -543,6 +565,13 @@ async function main(args) {
543
565
  return 0;
544
566
  }
545
567
 
568
+ if (args[0] === 'artifact' && args[1] === 'import') {
569
+ const options = flags(args.slice(2), ['data-root', 'input']);
570
+ const result = await withRuntime('writer', options['data-root'], commands => commands.execute('artifact.import', jsonInput(options.input)));
571
+ console.log(JSON.stringify(result, null, 2));
572
+ return 0;
573
+ }
574
+
546
575
  if (args[0] === 'artifact' && args[1] === 'inspect' && args[2]) {
547
576
  const options = flags(args.slice(3), ['data-root']);
548
577
  const result = await withRuntime('reader', options['data-root'], (commands) =>
@@ -2,22 +2,22 @@
2
2
 
3
3
  把下面一段交给负责安装或使用 Iris 的 Agent。版本与发布状态以当前 [README](../README.md) 为准;Iris 和 DSH 的版本号独立。
4
4
 
5
- 当前安装版本为 Iris 0.2.2。先核对宿主与实际安装版本,再使用新视觉命令或 Artifact 改图;旧宿主仍固定安装 0.1.4。
5
+ 本文对应Iris0.2.4。执行安装命令前先核对README的发布状态,再确认实际版本、工具和功能分配;旧宿主仍固定安装0.1.4。
6
6
 
7
7
  ## 中文
8
8
 
9
9
  ```text
10
10
  请根据本仓库 README,帮我安装并使用 Iris(@mokuyoaxis/dsh-iris)。
11
11
  先确认运行环境、目标 DSH profile,并用 dsh --version 核对宿主;Iris 0.2.x 要求 Node.js >=22.0.0(旧 npm 0.1.4 的历史要求为 >=20.10.0):
12
- - DSH 0.2.0-rc.2:固定安装 dsh plugin --profile web add @mokuyoaxis/dsh-iris@0.2.2。
12
+ - DSH 0.2.0-rc.2或0.2.1-alpha.4:固定安装 dsh plugin --profile web add @mokuyoaxis/dsh-iris@0.2.4。
13
13
  - DSH >=0.1.2-rc.1 <0.1.3-0 或 0.1.5-rc.1:固定安装 dsh plugin --profile web add @mokuyoaxis/dsh-iris@0.1.4;只下载用 npm pack @mokuyoaxis/dsh-iris@0.1.4。
14
14
  - 其他 DSH 版本:先报告没有支持声明,不自行升级宿主或跳过版本检查。
15
- 没有 DSH、希望用 CLI 时,按 docs/HEADLESS_CLI.md 使用 npm 0.2.2;npm 0.1.4 不含新的 Core 媒体 CLI。
16
- 先用 --help 和 Doctor 核对实际版本与命令。Iris 0.2.2 支持 OpenAI 兼容图片与视觉工作流;其他协议与 music 是后续计划。
15
+ 没有DSH、希望用CLI时,按docs/HEADLESS_CLI.md使用npm0.2.4;npm0.1.4不含新的Core媒体CLI。
16
+ 先用--help和Doctor核对实际版本与命令。六类模型功能都需明确分配,空名单停止新调用;DSH默认视觉也须明确加入。图片导入用iris_import_image,改图用iris_edit_image;音乐用iris_generate_music并配置Chat Completions(内嵌音频)协议,见docs/MUSIC.md。
17
17
  从 dsh-market 安装也要核对实际包名、版本和兼容范围;市场缓存不代表支持旧宿主,不对旧 DSH 安装 latest。
18
18
  若使用其他 profile,把示例中的 web 换成已确认的目标。保留完整 scoped 包名,不把 dsh-iris 当作同一 npm 包。
19
19
  安装后检查 Doctor 和工具可达性,再执行我指定的媒体任务;不要输出 API Key,重启宿主前说明影响。
20
- 查询、观察和重新取回不等于重新生成;任务已受理或受理未知时,不自动重新提交。
20
+ 查询、观察和重新取回不等于重新生成;任务已受理或受理未知时,不自行重新提交。音乐入口内部执行本次配置的有限502重试,不再由Agent包外层循环;配乐仅按用户要求加入流程。
21
21
  最后报告所用 Iris/DSH 版本、安装来源和实际验证结果。
22
22
  ```
23
23
 
@@ -26,14 +26,14 @@
26
26
  ```text
27
27
  Help me install and use Iris (@mokuyoaxis/dsh-iris) according to this repository's README.
28
28
  Check the environment, target DSH profile, and dsh --version first; Iris 0.2.x requires Node.js >=22.0.0 (the published npm 0.1.4 historically requires >=20.10.0):
29
- - DSH 0.2.0-rc.2: pin dsh plugin --profile web add @mokuyoaxis/dsh-iris@0.2.2.
29
+ - DSH 0.2.0-rc.2 or 0.2.1-alpha.4: pin dsh plugin --profile web add @mokuyoaxis/dsh-iris@0.2.4.
30
30
  - DSH >=0.1.2-rc.1 <0.1.3-0 or 0.1.5-rc.1: pin dsh plugin --profile web add @mokuyoaxis/dsh-iris@0.1.4; download only with npm pack @mokuyoaxis/dsh-iris@0.1.4.
31
31
  - Other DSH versions: report the missing support claim; do not upgrade the host or bypass its version checks automatically.
32
- For CLI use without DSH, follow docs/HEADLESS_CLI.md using npm 0.2.2; npm 0.1.4 does not include the new Core media CLI.
33
- Check --help, Doctor and the actual installed version before using commands. Iris 0.2.2 supports the OpenAI-compatible image and vision workflow; additional protocols and music remain future work.
32
+ For CLI use without DSH, follow docs/HEADLESS_CLI.md using npm 0.2.4; npm 0.1.4 does not include the new Core media CLI. Check the README publication status first.
33
+ Check --help, Doctor and the actual installed version. All six model functions require explicit assignments; empty lists stop new calls. Add DSH default vision explicitly when needed. Use iris_import_image for import, iris_edit_image for editing, and iris_generate_music with its configured inline-audio protocol for music.
34
34
  For dsh-market, check the actual package name, version, and compatibility range too. Cached listings do not establish older-host support; do not install latest on an old DSH host.
35
35
  Replace web with the confirmed profile when needed. Keep the scoped package name; unscoped dsh-iris is a different npm package.
36
36
  Check Doctor and tool availability after installation, then carry out my requested media task. Do not expose API keys; explain the impact before restarting the host.
37
- Inspect, observe, and redeliver do not create a new generation. Never resubmit automatically after accepted or unknown acceptance.
37
+ Inspect, observe, and redeliver do not generate again. Do not add an agent retry loop after accepted or unknown acceptance; music handles its configured bounded 502 retries internally. Add music to workflows only when requested.
38
38
  Report the Iris/DSH versions, installation source, and actual validation results.
39
39
  ```
@@ -1,6 +1,6 @@
1
1
  # Iris 架构与边界
2
2
 
3
- 状态:本文面向 **Iris 0.2.2**。0.2.0 建立实例化 Core Runtime、Headless CLI、共享 Provider 生命周期与 Task/Artifact 事实;0.2.2 补共享视觉、模型级图片协议、Artifact 编辑及维护入口。DSH 插件仅支持 `0.2.0-rc.2`,Node.js 最低为 22.0.0;旧宿主固定使用 npm `0.1.4`。Core 内部 API 尚未冻结为公共 SDK。
3
+ 状态:本文面向 **Iris 0.2.4**。0.2.0建立实例化Core Runtime、Headless CLI及共享Task/Artifact事实;后续加入共享视觉、图片编辑、音乐和交付恢复。0.2.4补图片导入、原生Qwen改图、统一功能分配及DSH双版本声明。插件支持rc.2或alpha.4,Node.js最低22.0.0;旧宿主固定Iris0.1.4,详见 [兼容矩阵](DSH_COMPATIBILITY.md)。Core内部API尚未冻结为公共SDK。
4
4
 
5
5
  ## 当前形态
6
6
 
@@ -64,7 +64,7 @@ DSH Host / Cordis Headless CLI
64
64
  ## Task、Attempt 与 Artifact
65
65
 
66
66
  - 一个用户意图对应一个 Core Task;每次候选供应商调用对应一个稳定 Attempt。Attempt 必须在可能发送计费请求前落盘。
67
- - 只有明确 `not_accepted` 才允许自动切换候选;`accepted` 或 `unknown` 后禁止自动重提。重试会创建新 Task,并要求用户再次提供未持久化的输入和明确确认潜在费用。
67
+ - Core只有明确 `not_accepted` 才自动切换候选;`accepted` 或 `unknown` 后通用Runner停止重提。人工重试会创建新Task,要求重新提供输入并确认潜在费用。Music功能层另按本次配置对明确HTTP502进行有限重发,保留原Task的未知事实和新旧任务关系,详见 [音乐生成](MUSIC.md)。
68
68
  - 生成结果与本地交付是两类事实。远端成功后下载失败仍保持 `outcome=succeeded / deliveryState=failed`,可显式重新交付而不重新生成。
69
69
  - 新 Attempt 可选保存阶段时间戳与模型选择来源;旧记录缺少这些字段仍可读取。
70
70
  - Artifact Manifest v0 保存内容哈希、媒体类型、中性元数据和关系边;不保存 Prompt、API Key、签名 URL、Provider 端点或宿主绝对路径。
@@ -74,6 +74,8 @@ DSH Host / Cordis Headless CLI
74
74
 
75
75
  ## Provider 边界
76
76
 
77
+ 0.2.4将六类功能统一为严格有序分配名单:不补入全局池,临时指定只绑定名单内单项。DSH默认视觉为显式宿主资源,不作为隐式兜底;手动实测与旧任务恢复保持独立。配置格式、Core受理纪律与生产依赖保持。升级范围见 [功能模型分配](FUNCTION_MODEL_ASSIGNMENTS.md)。下方0.2.2描述保留当时能力声明变更的背景。
78
+
77
79
  0.2.2按功能组织有序模型候选池,能力来自明确模型标签、旧能力字段绑定或供应商能力元数据。裸账号不物化默认模型,模型名称不授权进入候选链;明确空池与空标签保持权威。模型与供应商复合身份用于底层执行器,功能入口、分配排序及安全 failover 没有改为模型中心产品或默认轮转。旧 0.2.1 的能力推断行为不再用于裸账号或模型名称赋能。
78
80
 
79
81
  Provider Adapter v0 固定 discovery、submit、poll、cancel、download 与 error mapping 六类生命周期操作;提交前的临时输入上传是可选准备能力,不自动成为 Core 事实。协议实现只接收显式凭据、模型和媒体端点,Core 保存复合模型身份与非敏感 binding,不保存端点原文。
@@ -32,6 +32,10 @@ dsh-iris media html --data-root /path/core --input-file /path/html-input.json \
32
32
 
33
33
  ## 账号、模型与配置
34
34
 
35
+ 已有本地图片可先用0.2.4的 `artifact import` 保存为作品ID,再执行看图或改图;导入无需账号或模型,见 [图片导入](IMAGE_IMPORT.md)。
36
+
37
+ 0.2.4的六类功能均需明确分配;`assignments clear`停止新调用,已有Task仍按原绑定观察和补交付。临时指定须在名单内。旧自动池升级及DSH宿主资源见 [功能模型分配](FUNCTION_MODEL_ASSIGNMENTS.md)。
38
+
35
39
  | 命令 | 行为 |
36
40
  | --- | --- |
37
41
  | `config init/show/check` | 创建空私有配置(不覆盖)、脱敏查看、检查重复账号和失效分配 |
@@ -53,6 +57,8 @@ dsh-iris media html --data-root /path/core --input-file /path/html-input.json \
53
57
 
54
58
  上述命令均需 `--provider-config /path/providers.json`。`<ref>` 必须是 `providerId::modelId`;媒体 run 的既有输入规则不变。`models test` 本身是显式真实请求,可能消耗额度,只调用指定模型,成功后解除该模型的冷却或耗尽停用。视频/转写未提供 `--input` 时返回 `skipped:true`,不请求供应商、不记录成功。`models list` 对受阻模型显示 `rateLimited`,短时限流另有 `retryAt`,明确耗尽另有 `reason`。
55
59
 
60
+ 视觉分配还可保存宿主资源 `host:current-vision`,供 DSH 使用;它不是 Provider 模型,独立 CLI 不执行该项,`models` 命令仍只管理普通复合引用。
61
+
56
62
  ```bash
57
63
  dsh-iris providers add --provider-config /path/providers.json --input-file /path/private-provider.json
58
64
  dsh-iris models caps 'aliyun::qwen3-vl-flash' --provider-config /path/providers.json \
@@ -125,16 +131,18 @@ dsh-iris run image --data-root /path/core --provider-config /path/providers.json
125
131
 
126
132
  ## Artifact 聊天改图
127
133
 
128
- 为 `run image` 提供 `source_artifact_id`,将当前 Core 中的原图与修改指令一起发送给支持带图编辑的 `openai-chat-images` 模型:
134
+ 为 `run image` 提供 `source_artifact_id`,将当前Core原图与修改指令一起发送给带图编辑模型。支持openai-chat-images,0.2.4另支持DashScope原生Qwen改图:
129
135
 
130
136
  ```bash
131
137
  dsh-iris run image --data-root /path/core --provider-config /path/providers.json \
132
138
  --input '{"source_artifact_id":"artifact_ID","prompt":"把蓝色发饰改成白色,保留人物、服装和构图","model_ref":"gateway::gemini-image"}'
133
139
  ```
134
140
 
135
- 来源必须是同一数据根中的有效 Artifact ID(`artifact_` 后 24 位十六进制),最多 20 MiB 的静态 PNG/JPEG/WebP;创建 Task 前核验哈希、MIME 和真实格式。不需要导出原图,不支持 GIF/动画或蒙版。省略 `model_ref` 时沿用生图候选顺序,只保留聊天生图协议;显式指定其他协议会在 HTTP 前拒绝,不误发普通文生图。模型是否实际支持编辑由上游决定。
141
+ 来源必须是同一数据根中的有效 Artifact ID(`artifact_` 后 24 位十六进制),最多 20 MiB 的静态 PNG/JPEG/WebP;创建 Task 前核验哈希、MIME 和真实格式。不需要导出原图,不支持 GIF/动画或蒙版。省略 `model_ref` 时沿用当前生图分配顺序,只保留已接入的带图编辑模型;显式指定仍须在生图名单内,不支持的模型会在 HTTP 前拒绝,不误发普通文生图。模型实际可用性由上游决定。
142
+
143
+ DashScope 原生改图使用 `imageProtocol: dashscope`(或继承同协议账号),当前接入 `qwen-image-edit`、`qwen-image-edit-max/plus`、`qwen-image-2.0/pro` 及其日期快照。模型还须显式声明 `image-gen` 并加入生图分配名单;名称本身不会授予能力。可将上例的 `model_ref` 换成已分配的 `bailian::qwen-image-edit-max`。原图以 data URL 发送到 `/api/v1/services/aigc/multimodal-generation/generation`,返回图片 URL 后立即保存为 Core 作品。`qwen-image-plus/max` 等纯文生图模型,以及尚未接入的其他 Qwen 版本,不作为原生改图候选。请求结构参考[百炼原生改图文档](https://help.aliyun.com/en/model-studio/qwen-image-edit-api)。
136
144
 
137
- 原图只读,发送副本复用默认 8 MiB 与账号/模型 `visionInput`,按每个实际候选分别处理。新 Task 保存 `sourceArtifactId`,新 Artifact 保存 `derived-from` 来源关系;输出原字节及 MIME 保留。返回的新 Artifact ID 可继续 `vision look/ocr`、导出或编辑。
145
+ 原图只读,发送副本复用默认 8 MiB 与账号/模型 `visionInput`,按每个实际候选分别处理;原生 Qwen 发送副本另限制在 10 MiB 内。新 Task 保存 `sourceArtifactId`,新 Artifact 保存 `derived-from` 来源关系;输出原字节及 MIME 保留。返回的新 Artifact ID 可继续 `vision look/ocr`、导出或编辑。
138
146
 
139
147
  未知受理、纯文字响应和交付失败不会自动重提或切换端点。知情 `task retry --confirm-billing true` 必须在新的 `--input` 中重新提供 `prompt` 和 `source_artifact_id`,模型覆盖使用外层 `--model-ref`。Core 删除预览会识别原图被编辑任务与新作品引用的情况。DSH 对应工具为 `iris_edit_image`,动作是 `image_edit`,工作台图片卡提供“改图”。
140
148
 
@@ -74,11 +74,13 @@ created --start--> started --dispose--> disposing --finish-dispose--> disposed
74
74
 
75
75
  ## 当前接口与后续范围
76
76
 
77
+ 0.2.3 增加同步完成结果的私有交付缓存:`task.redeliver` 可从原结果恢复,无需虚构远端 ID;完整字节离线交付,缺失字节只取回原 URL,不 submit。完整缓存可补回提交完成事实的中断,预留 Artifact ID 支持逐件重入;缓存与任务隔离/恢复一起管理。详见 [同步交付恢复](SYNC_DELIVERY_RECOVERY.md)。
78
+
77
79
  当前实现包括:
78
80
 
79
81
  - `normalizeCoreOptions()`:规范化显式数据根和 reader/writer 模式;
80
82
  - `createCoreRuntime()`:管理写者租约、状态、`AbortSignal`、在途操作和 cleanup;
81
- - `createCommandService()`:提供 `crop`、只读 `task.list/task.inspect`、显式单步 `task.observe`/`task.reobserve`(同一份实现,`reobserve` 是人工触发观察的对外命令名)、人工重新交付 `task.redeliver`(只开放 outcome=succeeded / deliveryState=failed,一次带 redelivery 标志的 re-poll + 下载,绝不 submit、绝不重新生成)、人工取消 `task.cancel`(只开放已受理未终态任务,只有 Provider 明确确认才写 canceled,不支持/无法确认保持真实状态)、人工重试为新任务 `task.retry`(只开放终态未成功交付任务;必须显式 confirm_billing 确认重复计费;新 Task 记录单向 retriedFrom 关系,候选链按宿主实况重新解析;Core 不持久化 Prompt,prompt 必须由调用方重新提供),以及 Artifact inspect/list/export/rebuild;Task reader 返回既有安全事实,不读取 Provider 配置,也不创建、修复或迁移记录;`observe/reobserve/redeliver/cancel` 只接受宿主注入的 Adapter resolver,`retry` 只接受宿主注入的候选链 resolver,Core 不读取配置路径;Task capability 现已覆盖 image、video、tts 与 transcribe——交付按 `provider-task-runner.js` 的 DELIVERY_PROFILES 冻结(video:`video/mp4` + `generated-video`;tts:`audio/mpeg`/`audio/wav` + `generated-audio`,同步 completed 同次调用内交付;transcribe:`text/plain` + `transcript`,正文物化为 UTF-8 Artifact),不共用不准确的图片交付语义;
83
+ - `createCommandService()`:提供 `crop`、只读 `task.list/task.inspect`、显式单步 `task.observe`/`task.reobserve`(同一份实现,`reobserve` 是人工触发观察的对外命令名)、人工重新交付 `task.redeliver`(只开放 outcome=succeeded / deliveryState=failed,异步使用一次带 redelivery 标志的 re-poll + 下载,同步结果使用原缓存,绝不 submit、绝不重新生成)、人工取消 `task.cancel`(只开放已受理未终态任务,只有 Provider 明确确认才写 canceled,不支持/无法确认保持真实状态)、人工重试为新任务 `task.retry`(只开放终态未成功交付任务;必须显式 confirm_billing 确认重复计费;新 Task 记录单向 retriedFrom 关系,候选链按宿主实况重新解析;Core 不持久化 Prompt,prompt 必须由调用方重新提供),以及 Artifact inspect/list/export/rebuild;Task reader 返回既有安全事实,不读取 Provider 配置,也不创建、修复或迁移记录;需联网的 `observe/reobserve/redeliver/cancel` 只接受宿主注入的 Adapter resolver;完整本地缓存的 redeliver 不解析 Provider,`retry` 只接受宿主注入的候选链 resolver,Core 不读取配置路径;Task capability覆盖image、video、tts、transcribe与music——交付按 `provider-task-runner.js` 的 DELIVERY_PROFILES 冻结(video:`video/mp4` + `generated-video`;tts/music:`audio/mpeg`/`audio/wav` + `generated-audio`,同步 completed 同次调用内交付;transcribe:`text/plain` + `transcript`,正文物化为 UTF-8 Artifact),不共用不准确的图片交付语义;
82
84
  - 0.2.1 补齐 `media.diff/frames/html`、S2V 按候选上传、查询/批量管理与 Core 隔离/恢复;视觉和维护入口见 [CLI 管理](CLI_MANAGEMENT.md) 与 [视觉 CLI](VISION_CLI.md)。
83
85
  - Artifact Manifest v0:保存受控对象、SHA-256、关系边和可重建 Index,可跨 CLI 进程检查、导出和显式重建;Doctor 只报告孤立/未解析条目,不自动删除或修复。
84
86
 
@@ -0,0 +1,43 @@
1
+ # DSH 版本兼容
2
+
3
+ Iris与DSH的版本号独立。安装前运行 `dsh --version`,并核对要安装的Iris版本;发布状态见 [README](../README.md)。
4
+
5
+ | Iris版本 | 支持的DSH版本 |
6
+ |---|---|
7
+ | 0.2.4 | `0.2.0-rc.2` 或 `0.2.1-alpha.4` |
8
+ | 0.2.0–0.2.3 | `0.2.0-rc.2` |
9
+ | 0.1.4 | `>=0.1.2-rc.1 <0.1.3-0` 或 `0.1.5-rc.1` |
10
+
11
+ 0.2.4的范围是两项准确版本,不包含其他alpha、其他rc或未来版本。扩大插件支持不要求现有rc.2用户升级宿主。Iris Core与独立CLI要求Node.js ≥ 22.0.0;DSH插件还须满足所用DSH自身更高的运行要求。
12
+
13
+ ## 安装与升级
14
+
15
+ 在上表支持的宿主中固定安装所需Iris版本,以下为0.2.4命令:
16
+
17
+ ```bash
18
+ dsh plugin --profile web add @mokuyoaxis/dsh-iris@0.2.4
19
+ ```
20
+
21
+ 使用其他profile时替换 `web`。更新后检查服务端装载、刷新Web客户端,并查看Iris工作台的 [宿主诊断](HOST_DOCTOR.md)。alpha.3及之后的DSH改善了插件更新与热加载,但仍以实际装载结果为准。
22
+
23
+ 0.2.4另统一了六类功能的明确模型名单。已有分配保持;以前依赖自动模型池的功能需要在升级后明确分配,见 [升级说明](FUNCTION_MODEL_ASSIGNMENTS.md)。
24
+
25
+ ## 兼容声明如何生效
26
+
27
+ 0.2.4的 `package.json` 顶层 `engines.dsh` 与五项可选客户端peer统一为 `0.2.0-rc.2 || 0.2.1-alpha.4`;现有嵌套 `dsh.engines.dsh` 保持同值。Doctor按相同版本集合诊断。Iris不把DSH客户端包安装为生产依赖。
28
+
29
+ rc.2的加载器检查DSH相关peer;alpha.4优先读取顶层 `engines.dsh`,未声明时再检查peer。只改嵌套字段不能扩大新加载器的支持范围。另外,npm默认的预览版匹配与DSH的匹配选项有差别,`^0.2.0-rc.2` 不能代替这里明确并列的两版范围。
30
+
31
+ ## 验证范围
32
+
33
+ 宿主验收使用各版官方发布的Cordis、LLM、ToolRuntime、附件、Skill、WebServer和SlotRegistry,覆盖模型路由、错误终态、视觉/OCR/定位/摘要、工具交付、作品管理及四个Iris界面插槽。模型事件由本地fixture提供,禁止外部模型请求。
34
+
35
+ 维护者可在本机已有目标SDK时运行:
36
+
37
+ ```bash
38
+ node scripts/verify-dsh-host.mjs --dsh-root /absolute/path/to/@deepseek-ai/dsh
39
+ ```
40
+
41
+ 脚本在独立临时目录使用隔离DSH_HOME,不操作日常profile。Node客户端夹具另需同版本的官方 `@deepseek-ai/dsh-client-ui-slots` SDK;实际Web前端已内嵌此模块。脚本不会自动下载依赖或升级宿主。
42
+
43
+ React/DOM和会话数据部分使用fixture,因此这项验收不代替完整浏览器操作、草稿写回、真机触摸或插件热更新验收。TLS和带前缀反代也不由loopback HTTP检查推定通过。早期rc.2适配的历史原因见 [rc.2适配记录](DSH_RC2_ADAPTATION.md)。
@@ -1,5 +1,7 @@
1
1
  # DSH → Core 渐进迁移
2
2
 
3
+ Iris 0.2.3 的音乐生成由 CLI、Agent 工具与工作台共同调用,使用独立模型协议绑定和明确功能分配。502有限重试每次创建新Core Task并记录关系,交付失败可使用同步缓存恢复,见 [音乐生成](MUSIC.md)。
4
+
3
5
  本文描述 **Iris 0.2.2** 的实现边界;0.2.0 建立的 Core 数据格式保持兼容。迁移逐条切换消费者,不原地改写 0.1.4 数据。
4
6
 
5
7
  0.2.1 已把 S2V、HTML、单图视觉、OCR、定位、摘要和提示词预览接入共享 Core Command 或 Model Ports,并补齐视觉 CLI、配置/查询/维护命令。图片按模型选择四种协议,Artifact ID 聊天编辑另存新作品并保留来源关系;输入预算仅处理发送副本。功能范围见 [发布说明](releases/0.2.1.md)。
@@ -29,7 +31,9 @@ Headless CLI 使用同一控制面:`task observe` 每次显式调用只 poll
29
31
 
30
32
  DSH 工作台现也开放同一份显式单步观察(D1 reobserve):`POST /iris/api/core/task/:id/reobserve` 经 Command Service 命令 `task.reobserve`(与 `task.observe` 同实现),adapter/binding 恢复与 Host 观察节拍共用同一 resolver。用户任务区的 Core 投影行在服务端的行 DTO 标记 `observable`(已受理、有远端 ID、结果未定论、非终态)时显示「重新观察」按钮,点击后单次调用、禁用期间防重复,完成后复用刷新节拍重拉快照;高级诊断卡对符合同一受理事实门的任务提供同一动作。每次调用至多一次 poll,绝不 submit;终态、未受理、无远端 ID 或 binding 漂移的任务在网络与写入前被拒绝并返回稳定错误码。
31
33
 
32
- 人工控制面第二项 redeliver(D2)也已开放:`POST /iris/api/core/task/:id/redeliver` 与 CLI `task redeliver` 经 Command Service 命令 `task.redeliver`,只对 outcome=succeeded / deliveryState=failed 的 Task 开放——一次带 redelivery 标志的 re-poll 拿远端产物清单 → 下载 → 新 Artifact,绝不 submit、绝不重新生成、不新建 Attempt。行 DTO 在五类状态中的 `delivery_failed` 上标记 `redeliverable`,工作台相应投影行与高级诊断卡显示「重新取回作品」;成功即 ready 且门反转(再次调用被拒),下载失败回落 failed 可再次显式执行。
34
+ 人工控制面第二项 redeliver(D2)也已开放:`POST /iris/api/core/task/:id/redeliver` 与 CLI `task redeliver` 经 Command Service 命令 `task.redeliver`,只对 outcome=succeeded / deliveryState=failed 的 Task 开放——异步任务使用一次带 redelivery 标志的 re-poll 拿远端产物清单 → 下载 → 新 Artifact;同步任务消费原私有缓存,完整字节本地恢复、缺少字节只下载原 URL,绝不 submit、绝不重新生成、不新建 Attempt。行 DTO 在五类状态中的 `delivery_failed` 上标记 `redeliverable`,工作台相应投影行与高级诊断卡显示「重新取回作品」;成功即 ready 且门反转(再次调用被拒),下载失败回落 failed 可再次显式执行。
35
+
36
+ 同步缓存增量尚未包含于 npm 0.2.2。它保留原 Task/Attempt 与预留 Artifact ID,不读取缓存的 reader/普通刷新无副作用;完整本地恢复不要求原供应商仍配置。缓存损坏、旧任务无缓存及签名 URL 失效边界见 [同步交付恢复](SYNC_DELIVERY_RECOVERY.md)。
33
37
 
34
38
  人工控制面第三项 cancel(D3)同样开放:`POST /iris/api/core/task/:id/cancel` 与 CLI `task cancel` 经 Command Service 命令 `task.cancel`,只对已受理、有远端 ID、未终态且未请求过取消的 Task 开放。结果只有三种,且**绝不伪造已取消**:① 供应商明确确认 → outcome=canceled、cancelState=remote_confirmed;② 供应商不支持远端取消(当前 DashScope 与 OpenAI Images 媒体协议均不提供经过验证的取消实现)→ 取消未发生,回落到可继续观察的真实状态(outcome 不变);③ 超时或网络失败 → cancelState=unknown、保持非终态,可显式 reobserve 收敛。竞态下远端先沉淀的成功事实不得被取消覆盖;已请求过取消但未确认的任务拒绝再次取消。工作台按钮「取消任务」需要二次确认,五类用户状态保持不变,三种结果态在高级诊断的「取消状态」字段如实区分(已确认 / 已请求未确认 / 无请求)。
35
39
 
@@ -59,7 +63,7 @@ t2v/i2v 视频已迁到 Core,与图片共用 Task/Attempt 事实轴但**不共
59
63
 
60
64
  ## 语音合成迁移(E 阶段第二项)
61
65
 
62
- TTS 是同步完成型,与视频的长轮询不同:一次 submit 内 completed,同一次调用直接交付为 Core Artifact(`DELIVERY_PROFILES.tts`:媒体白名单 `audio/mpeg`/`audio/wav`、kind `generated-audio`;remote-url 走下载,inline base64 直接物化)。Agent 工具 `iris_speak_text`、工作台语音动作与 CLI `run tts` 全部落到 Core,**零 legacy 双写**;同步完成即终态,observe/redeliver/cancel 对终态语音任务全部稳定拒绝,终态失败可用 retry 显式重试为新任务(输入为 `{text, voice?}`,候选链按实况解析)。语义差如实记录:legacy 是"单 Task 多 Attempt、每次尝试独立交付到 outputs/",Core 是"单 Task 多 Attempt、一次 Artifact 交付";候选链共用一个 voice(Core providerInput 静态)。同源媒体路由按 ID 播放音频。真实 Provider 语音 canary 待验收。
66
+ TTS 是同步完成型,与视频的长轮询不同:一次 submit 内 completed,同一次调用直接交付为 Core Artifact(`DELIVERY_PROFILES.tts`:媒体白名单 `audio/mpeg`/`audio/wav`、kind `generated-audio`;remote-url 走下载,inline base64 直接物化)。Agent 工具 `iris_speak_text`、工作台语音动作与 CLI `run tts` 全部落到 Core,**零 legacy 双写**;交付 ready 后 observe/redeliver/cancel 全部稳定拒绝;同步交付失败可沿完整缓存 redeliver,零 poll、零重新生成。没有可恢复来源的旧任务仍可用 retry 显式重试为新任务(输入为 `{text, voice?}`,候选链按实况解析)。语义差如实记录:legacy 是"单 Task 多 Attempt、每次尝试独立交付到 outputs/",Core 是"单 Task 多 Attempt、一次 Artifact 交付";候选链共用一个 voice(Core providerInput 静态)。同源媒体路由按 ID 播放音频。真实 Provider 语音 canary 待验收。
63
67
 
64
68
  ## 转写迁移(E 阶段第三项)
65
69
 
@@ -1,5 +1,7 @@
1
1
  # DSH 0.2.0-rc.2 适配
2
2
 
3
+ 本文保留Iris0.2.0/0.2.1适配rc.2时的背景与验证记录。当前0.2.4兼容rc.2及alpha.4,声明规则、使用步骤和验证边界见 [DSH版本兼容](DSH_COMPATIBILITY.md)。以下准确rc.2限制属于当时发行范围。
4
+
3
5
  本适配随 Iris `0.2.0` 发布;npm 0.1.4 包不包含这些后续修正。Iris 0.2.0 要求 Node.js `>=22.0.0`,DSH engines、五项客户端 peers 与 Host Doctor 仅放行准确版本 `0.2.0-rc.2`,不再沿用旧版支持窗口,也不推定其他 0.2 预览版或正式版兼容。
4
6
 
5
7
  旧 DSH `>=0.1.2-rc.1 <0.1.3-0` 或 `0.1.5-rc.1` 按历史验证范围使用稳定包 `@mokuyoaxis/dsh-iris@0.1.4`。安装与 npm tarball 下载方式见 [README](../README.md#最快开始)。保留的旧桥接与 fixture 测试不构成 Iris 0.2.0 的旧宿主支持承诺。
@@ -10,7 +12,7 @@ Iris 0.2.1 沿用相同 Node/DSH 要求,新增 Artifact 改图工具后共注
10
12
 
11
13
  | 边界 | 问题与修正 |
12
14
  |---|---|
13
- | 加载器与诊断 | rc.2 加载器检查 `peerDependencies`,原旧版客户端范围会被拒绝。当前客户端 peers、DSH engines、锁文件和 Host Doctor 均收敛到准确 rc.2,无需版本豁免。 |
15
+ | 加载器与诊断 | rc.2加载器检查peerDependencies,原旧版客户端范围会被拒绝。当时客户端peers、DSH engines、锁文件和Doctor收敛到准确rc.2,无需版本豁免;0.2.4按两版范围同步。 |
14
16
  | 会话附件 | 扫描引用时曾丢弃 `bytes/width/height`,真实 `readImage()` 因完整性不匹配拒绝读取。适配器保留这些已知事实及 `originalDimensions` 的独立副本,不猜测缺失值,不复制额外 Host 字段。 |
15
17
  | 宿主视觉 | rc.2 的 `llm.stream()` 需要明确 Provider/模型路由。默认选择仅在精确模型元数据确认接受 `image` 时成为视觉候选;文本模型、未知能力和身份漂移在生成前拒绝,错误事件以及 `finish.reason.kind` 的 `error/aborted` 不再被当作空回答或部分成功。 |
16
18
  | 客户端会话 | rc.2 列表没有旧 `current` 字段。适配器使用唯一的 `retainedBy.mainView` 持有者,通知时回读 `getSnapshot()`,卸载时释放订阅;保留旧接口,有歧义或无选择时不取任意列表项。 |
@@ -29,7 +31,7 @@ node scripts/verify-dsh-host.mjs --dsh-root /absolute/path/to/@deepseek-ai/dsh
29
31
 
30
32
  脚本在仓库外创建新临时数据根,载入实际安装的 Cordis、加载器兼容检查、附件、工具、Skill、LLM、默认模型、WebServer 与客户端 SlotRegistry。模型使用本地 Fake Adapter,正常流遵循安装包的 `index` 和对象终态格式,并验证真实 Runtime 将异常转换为失败终态;禁止外部请求。会话日志和列表是显式 fixture,宿主进程入口是已核实 DSH bin 的模拟。实际 WebServer 只绑定临时 loopback 端口,退出时卸载所有 Fiber。临时目录与 `report.json` 保留供复核。
31
33
 
32
- 当前脚本检查 15 个工具、2 项 Skill、Doctor 路由、DSH → Core diff → DSH 附件,以及四个客户端座位的注册和卸载。SlotRegistry 使用安装包中的真实代码,React/DOM 为 stub,因此不证明完整 Web profile 装载、实际组件渲染、点击和草稿写回。另用 `scripts/verify-headless-package.mjs --offline` 验证当前 tarball 在无 DSH/Cordis 安装树中执行 CLI 和 Artifact 导出。
34
+ 当时脚本检查15工具、2项Skill、Doctor路由、Core diff与附件,以及四个客户端座位。0.2.4检查17工具/3项Skill及两版宿主。SlotRegistry使用实际安装包代码,React/DOM为stub,不证明完整Web profile、实际渲染、点击和草稿写回。另用 `scripts/verify-headless-package.mjs --offline` 验证无DSH/Cordis安装树中的CLI和作品导出。
33
35
 
34
36
  ## 当前限制
35
37
 
@@ -11,6 +11,7 @@
11
11
  | 已受理后轮询 429/500/超时 | `watchState=exhausted`、`outcome=unknown` | 0 | `task-runtime-faults-v2.mjs` |
12
12
  | 供应商明确返回任务失败 | `outcome=failed` | 0 | `task-runtime-faults-v2.mjs` |
13
13
  | 已成功但下载/本地写入失败 | `outcome=succeeded`、`deliveryState=failed` | 0 | `task-store-v2.mjs`、`image-task-mixed-v2.mjs` |
14
+ | 同步无远端 ID,完整结果/下载/Artifact/Task 提交中断 | 私有缓存、原 Attempt、稳定作品 ID;恢复不重复生成 | 0 | `sync-delivery-recovery.mjs`(含真实 SIGKILL、CLI、缓存损坏、隔离/恢复) |
14
15
  | 进程在 submitting 阶段退出 | 无受理证据时转为 unknown,禁止恢复提交 | 0 | `task-store-v2.mjs` |
15
16
  | 进程在 accepted/running 阶段退出 | 只恢复观察;供应商缺失则 suspended | 0 | `task-runtime-faults-v2.mjs` |
16
17
  | 已成功、交付中途退出 | 保留 succeeded,交付标 failed | 0 | `task-runtime-faults-v2.mjs` |
@@ -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)。
@@ -1,11 +1,15 @@
1
1
  # Headless CLI
2
2
 
3
- 本文面向 Iris 0.2.2,涵盖无 DSH 的本地处理、媒体生成、视觉分析、配置和任务管理。媒体结果保存为 Core Artifact,可在后续进程中检查、分析或导出;纯视觉不自动创建产物。Core 内部接口与 Artifact v0 尚未冻结为公共 SDK。
3
+ `run music` 支持音乐生成与模型级协议配置,见 [音乐生成](MUSIC.md)。0.2.4的六类功能均采用明确分配名单,升级差异见 [功能模型分配](FUNCTION_MODEL_ASSIGNMENTS.md)。
4
4
 
5
- 需要 Node.js ≥ 22.0.0。安装 `npm install @mokuyoaxis/dsh-iris@0.2.2` 后运行 `npx dsh-iris --help`。源码入口为 `node bin/dsh-iris.js ...`;安装本地 tarball 后也可运行 `dsh-iris ...`。
5
+ 本文面向Iris0.2.4,涵盖无DSH的本地处理、媒体生成、视觉分析、配置和任务管理。媒体结果保存为Core Artifact,可在后续进程中检查、分析或导出;纯视觉不自动创建产物。Core内部接口与Artifact v0尚未冻结为公共SDK。
6
+
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也可用于安装。
6
8
 
7
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)。
8
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
+
9
13
  ## 配置查询与离线诊断
10
14
 
11
15
  ```bash
@@ -14,7 +18,7 @@ dsh-iris capabilities list --provider-config /absolute/path/to/providers.json
14
18
  dsh-iris doctor --data-root /absolute/path/to/iris-data --json
15
19
  ```
16
20
 
17
- 前两项只读取显式提供的私有配置文件,不创建 Core Runtime 或数据根,也不请求 Provider。`providers list` 输出供应商身份、启用/配置状态、认证方式、媒体协议及其推断标记、配置能力与模型数;不输出 API Key 或端点。`capabilities list` 按五种配置能力列出 `providerId::modelId` 候选链,沿用 DSH 的“手工分配优先、模型池顺序补齐”规则;空链标为 `gap: no_configured_model`。这些只是配置事实,不证明远端模型或协议可调用。
21
+ 前两项只读取显式提供的私有配置文件,不创建Core Runtime或数据根,也不请求Provider。`providers list`输出供应商身份、启用/配置状态、认证方式、媒体协议及其推断标记、配置能力与模型数;不输出API Key或端点。0.2.4的 `capabilities list` 按六种配置能力列出明确分配且当前CLI可用的 `providerId::modelId` 候选链;空链标为 `gap: no_configured_model`。这些只是配置事实,不证明远端模型或协议可调用。
18
22
 
19
23
  显式 `doctor --data-root` 是只读 Core 盘点:检查 Task/Artifact 结构、Index 一致性、孤立/未解析条目和写者租约;不创建缺失的根、不执行写入探针、不重建索引,也不释放租约。活跃写者可能使盘点在读取期间变化。省略 `--data-root` 时仍检查 DSH profile,保留原有写入探针,并纳入该 profile 的 `core-v0`。两种模式都返回 legacy/Core 计数对照,显式模式只统计指定根同层的 legacy 文件。退出码为 `0` 正常、`1` 警告、`2` 硬错误;诊断不会调用 Provider。
20
24
 
@@ -71,11 +75,11 @@ dsh-iris run image \
71
75
  --input '{"prompt":"一朵雨后的鸢尾花","model_ref":"provider-id::model-id","size":"1024*1024","n":1}'
72
76
  ```
73
77
 
74
- `model_ref` 可省略;省略时采用“手工 assignment 顺序优先、模型池顺序补齐”的安全 failover。每个请求从首项开始,只有明确 `not_accepted` 才进入下一项。配置文件须为普通文件,POSIX 权限不得开放给 group/other;API Key、端点、Prompt 和下载 URL都不会写入 Task 输出。
78
+ `model_ref` 可省略;省略时只使用assignment名单,按配置顺序选择。指定时须属于名单且本次只调用该项。每个请求从首项开始,只有明确 `not_accepted` 才进入下一项。配置文件须为普通文件,POSIX权限不得开放给group/other;API Key、端点、Prompt和下载URL都不会写入Task输出。
75
79
 
76
- 模型必须存在于配置的 `models` 或旧模型字段中,且具备所请求的能力;缺失时返回配置错误,不注入厂商默认模型。显式 `models:[]` 表示没有可用模型。`model_ref` 也接受裸模型名,同名跨供应商时按配置中的供应商顺序取首项;需要精确绑定账号时使用 `providerId::modelId`。显式指定只选择该模型,不扩展 failover 候选。
80
+ 模型必须存在于配置的 `models` 或旧模型字段中,且具备所请求的能力;缺失时返回配置错误,不注入厂商默认模型。显式 `models:[]` 表示没有可用模型。`model_ref` 也接受裸模型名,同名跨供应商时从当前功能名单中取首个匹配项;需要精确绑定账号时使用 `providerId::modelId`。显式指定只选择该模型,不扩展 failover 候选。
77
81
 
78
- 旧裸 DashScope 账号的已知目录仅在 DSH 配置加载或保存时一次性写入 `models`,随后可见、可编辑;CLI 只读配置,不执行该迁移。独立 CLI 配置须自行声明模型。
82
+ 裸 DashScope 账号不再自动写入厂商目录或授予功能能力。已有明确保存的模型和旧能力字段绑定继续保留;独立 CLI 配置同样需要声明模型并分配给功能。
79
83
 
80
84
  生图按每个模型的有效图片协议调用,保存真实 PNG/JPEG/WebP 字节。聊天改图使用 `source_artifact_id`,创建关联原图的新 Artifact;具体参数和协议限制见 [模型级图片协议](CLI_MANAGEMENT.md#模型级图片协议) 与 [Artifact 聊天改图](CLI_MANAGEMENT.md#artifact-聊天改图)。
81
85
 
@@ -134,7 +138,7 @@ dsh-iris task inspect task_0123456789abcdef01234567 \
134
138
 
135
139
  新建 Attempt 可选保存 `stageTimestamps`:排队、开始提交、提交响应、远端终态、开始下载、下载校验完成和本地 Artifact 处理完成七个边界。字段按发生顺序单调不减;旧记录缺失该字段仍可读取。重新交付会从新的下载开始边界重新计时,不伪造尚未跨过的阶段。
136
140
 
137
- 新建 Attempt 还可选保存 `selectionReason`:`explicit` 表示调用方显式提供 `model_ref`,`assignment` 表示候选来自提交当时的能力分配,`pool` 表示由配置模型池按顺序补齐。它与 Attempt 一起在 Provider submit 前落盘;`task inspect` 只展示持久事实,不会用当前可能已变化的 assignment 事后猜测。旧记录没有该字段时保持缺失,不伪造默认值;第几次 failover 仍看 `ordinal`。
141
+ 新建Attempt还可选保存 `selectionReason`:`explicit` 表示调用方明确指定名单内模型,`assignment` 表示按提交当时的功能名单选择。`pool` 保留为旧记录的历史来源,0.2.4不再产生池补齐候选。该事实随Attempt在Provider submit前落盘;`task inspect` 只展示持久记录,不按当前assignment事后猜测。旧记录缺少字段时保持缺失;第几次failover仍看 `ordinal`。
138
142
 
139
143
  已受理的异步图片 Task 可以显式推进一次:
140
144
 
@@ -158,7 +162,9 @@ dsh-iris task redeliver task_0123456789abcdef01234567 \
158
162
  --provider-config /absolute/path/to/providers.json
159
163
  ```
160
164
 
161
- 每次命令至多一次带 redelivery 语义标志的 `poll`(拿远端产物清单)接一轮下载,写入新的 Core Artifact;不调用 `submit`、不新建 Attempt、不产生第二次生成费用。非 failed、无远端 ID 或 binding 漂移时在调用前拒绝;成功后再次调用被同样拒绝,失败回落 failed 后可再次显式执行。DSH 侧同构开放:`POST /iris/api/core/task/:id/redeliver` 与工作台「重新取回作品」按钮(delivery_failed 投影行的唯一动作)。
165
+ 异步任务每次命令至多一次带 redelivery 语义标志的 `poll`(拿远端产物清单)接一轮下载;不调用 `submit`、不新建 Attempt、不产生第二次生成费用。非 failed、缺少可恢复来源或需联网时 binding 漂移,会在调用前拒绝;成功后再次调用被同样拒绝,失败回落 failed 后可再次显式执行。DSH 侧同构开放:`POST /iris/api/core/task/:id/redeliver` 与工作台「重新取回作品」按钮。
166
+
167
+ 0.2.3 支持同步结果的私有缓存恢复:完整字节仅做本地交付,可省略 `--provider-config`;只有 URL 尚需下载时才解析原供应商,且不 poll。旧任务没有完整缓存时不能追溯恢复;详见 [同步交付恢复](SYNC_DELIVERY_RECOVERY.md)。
162
168
 
163
169
  已受理且尚未终态的 Task 可以显式请求远端取消:
164
170
 
@@ -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 全局视觉模型 | 作为 Iris 自持视觉 Provider 之外的可选后端 | 有自持视觉配置时降级;否则视觉动作失败 |
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` | 无 | `visionModel` | 生成与 Task 不依赖宿主;成功后的简短视觉描述可以降级 |
32
- | `video`、`tts`、`transcribe` | 无 | 无 | Provider、Task 与产物落盘属于 Iris Core |
33
- | `look`、`locate`、`ocr` | 无 | `visionModel` | 优先使用 Iris Provider;没有任何视觉后端才失败 |
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` | 无 | `visionModel` | 帧提取是本地动作,理解阶段允许宿主视觉降级 |
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/模型/能力配置 | 无 | `visionModel` | 普通发现与配置不依赖宿主;视觉实测可选宿主后端且必须显式触发 |
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