@mokuyoaxis/dsh-iris 0.2.1 → 0.2.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 (76) 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 +41 -0
  6. package/.dsh/skills/iris-use/agents/openai.yaml +4 -0
  7. package/.dsh/skills/iris-use/references/media-contract.md +73 -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 +48 -2
  12. package/README.en.md +47 -40
  13. package/README.md +45 -39
  14. package/bin/dsh-iris.js +27 -6
  15. package/docs/AGENT_QUICKSTART.md +9 -9
  16. package/docs/ARCHITECTURE.md +11 -3
  17. package/docs/ARTIFACT_LIBRARY.md +1 -1
  18. package/docs/CLI_MANAGEMENT.md +5 -3
  19. package/docs/COMPOSITE_VISION.md +1 -1
  20. package/docs/CORE_RUNTIME_CONTRACT.md +12 -2
  21. package/docs/DSH_CORE_MIGRATION.md +7 -3
  22. package/docs/FAULT_INJECTION.md +11 -1
  23. package/docs/HEADLESS_CLI.md +10 -4
  24. package/docs/HOST_ADAPTER_CONTRACT.md +1 -1
  25. package/docs/HOST_DOCTOR.md +3 -3
  26. package/docs/MODEL_PORT_CONTRACT.md +9 -3
  27. package/docs/MUSIC.md +77 -0
  28. package/docs/OCR_MODEL.md +1 -1
  29. package/docs/PROMPT_OPTIMIZER.md +74 -6
  30. package/docs/PROVIDER_ADAPTER_CONTRACT.md +12 -2
  31. package/docs/PROVIDER_HEALTH.md +1 -1
  32. package/docs/ROADMAP.md +15 -18
  33. package/docs/SECURITY.md +4 -3
  34. package/docs/SYNC_DELIVERY_RECOVERY.md +39 -0
  35. package/docs/TASK_SEMANTICS.md +5 -5
  36. package/docs/VISION_CLI.md +1 -1
  37. package/docs/VISION_MODEL.md +1 -1
  38. package/docs/WORKBENCH_ARTIFACTS.md +1 -1
  39. package/docs/releases/0.2.2.md +31 -0
  40. package/docs/releases/0.2.3.md +54 -0
  41. package/lib/actions.js +52 -19
  42. package/lib/adapters.js +89 -24
  43. package/lib/api.js +14 -5
  44. package/lib/bundled-skills.js +1 -1
  45. package/lib/capability.js +25 -16
  46. package/lib/client.js +374 -43
  47. package/lib/command-service.js +12 -3
  48. package/lib/config.js +39 -6
  49. package/lib/core-artifact-store.js +44 -6
  50. package/lib/core-delivery-cache.js +145 -0
  51. package/lib/core-lease-recovery.js +64 -92
  52. package/lib/core-maintenance.js +12 -1
  53. package/lib/core-runtime.js +45 -47
  54. package/lib/core-tasks.js +19 -5
  55. package/lib/core-user-projection.js +2 -2
  56. package/lib/core-writer-lease.js +134 -0
  57. package/lib/dsh-core-adapter.js +14 -4
  58. package/lib/dsh-text-model-adapter.js +15 -2
  59. package/lib/generation-input.js +10 -0
  60. package/lib/host-runtime.js +4 -2
  61. package/lib/index.js +23 -4
  62. package/lib/models.js +23 -38
  63. package/lib/music-generation.js +21 -0
  64. package/lib/music-options.js +18 -0
  65. package/lib/music-transport.js +46 -0
  66. package/lib/prompt-optimizer-config.js +111 -30
  67. package/lib/prompt-optimizer-core.js +183 -12
  68. package/lib/prompt-optimizer.js +20 -14
  69. package/lib/provider-adapter.js +1 -0
  70. package/lib/provider-adapters.js +26 -2
  71. package/lib/provider-catalog.js +18 -7
  72. package/lib/provider-config-service.js +16 -5
  73. package/lib/provider-protocol.js +73 -0
  74. package/lib/provider-task-runner.js +86 -9
  75. package/package.json +4 -2
  76. package/user_guide.md +52 -24
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,7 +69,7 @@ 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>',
@@ -231,7 +233,7 @@ async function main(args) {
231
233
 
232
234
  if (['config', 'providers', 'models', 'assignments'].includes(args[0])) {
233
235
  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'] };
236
+ 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
237
  if (!verbs[group].includes(verb)) throw new CliUsageError('未知配置命令');
236
238
  const positional = (group === 'providers' && verb === 'remove') || (group === 'models' && verb !== 'list');
237
239
  const id = positional ? required(args[2], group === 'providers' || verb === 'discover' ? 'provider-id' : 'model-ref') : undefined;
@@ -250,6 +252,7 @@ async function main(args) {
250
252
  const result = await executeConfigCommand(required(options['provider-config'], 'provider-config'), group === 'config' ? verb : group + '.' + verb, input, {
251
253
  signal: cliAbortController.signal,
252
254
  probe: async ({ provider, modelId, capability, signal }) => {
255
+ if (capability === 'music-gen') return { skipped: true, ok: false, reason: 'Music 不发起小样本探测;请使用 run music 提交创作要求' };
253
256
  if (capability === 'vision') return probeVisionModel(provider, modelId, { bytes: Buffer.from(RED_TEST_IMAGE.split(',')[1], 'base64'), mediaType: 'image/png' }, { signal });
254
257
  if (['video-gen', 'transcribe'].includes(capability) && !options.input) return {
255
258
  skipped: true, ok: false, reason: '请用 models test --input 提供与 run video/transcribe 相同的真实素材;未发起请求'
@@ -398,6 +401,22 @@ async function main(args) {
398
401
  }
399
402
 
400
403
  // 语音合成输入冻结(E2 Profile):同步完成型,一次命令内完成 Task → Artifact。
404
+ if (args[0] === 'run' && args[1] === 'music') {
405
+ const options = flags(args.slice(2), ['data-root', 'provider-config', 'input']);
406
+ const normalized = generationInput('music', jsonInput(options.input));
407
+ const catalog = loadProviderCatalog(required(options['provider-config'], 'provider-config'));
408
+ const routes = musicCandidatesFromCatalog(catalog, normalized.modelRef);
409
+ let result;
410
+ await withRawRuntime('writer', options['data-root'], async runtime => {
411
+ result = await generateMusicTask({ runner: createProviderTaskRunner(runtime),
412
+ candidates: routes.map(route => ({ adapter: trackedProviderAdapter(route.provider, options), model: route.modelRef,
413
+ selectionReason: route.selectionReason, providerBinding: providerTaskBinding(route.provider) })),
414
+ providerInput: normalized.providerInput, options: normalized.musicOptions, signal: cliAbortController.signal });
415
+ console.log(JSON.stringify(result, null, 2));
416
+ });
417
+ return result.task.outcome === 'succeeded' && result.task.deliveryState === 'ready' ? 0 : 1;
418
+ }
419
+
401
420
  if (args[0] === 'run' && args[1] === 'tts') {
402
421
  const options = flags(args.slice(2), ['data-root', 'provider-config', 'input']);
403
422
  const { providerInput, modelRef } = generationInput('tts', jsonInput(options.input));
@@ -473,10 +492,10 @@ async function main(args) {
473
492
 
474
493
  if (args[0] === 'task' && args[1] === 'redeliver' && args[2]) {
475
494
  const options = flags(args.slice(3), ['data-root', 'provider-config']);
476
- const catalog = loadProviderCatalog(required(options['provider-config'], 'provider-config'));
495
+ const catalog = options['provider-config'] ? loadProviderCatalog(options['provider-config']) : null;
477
496
  await withRuntime('reader', options['data-root'], (commands) => commands.execute('task.inspect', { task_id: args[2] }));
478
497
  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)
498
+ ...(catalog ? { resolveTaskAdapter: (task) => trackedProviderAdapter(providerForTaskFromCatalog(catalog, task), options, task) } : {})
480
499
  });
481
500
  console.log(JSON.stringify(result, null, 2));
482
501
  return 0;
@@ -512,6 +531,8 @@ async function main(args) {
512
531
  ? videoCandidatesFromCatalog(catalog, modelRef || undefined)
513
532
  : capability === 'tts'
514
533
  ? ttsCandidatesFromCatalog(catalog, modelRef || undefined)
534
+ : capability === 'music'
535
+ ? musicCandidatesFromCatalog(catalog, modelRef || undefined)
515
536
  : capability === 'transcribe'
516
537
  ? transcribeCandidatesFromCatalog(catalog, modelRef || undefined)
517
538
  : imageCandidatesFromCatalog(catalog, modelRef || undefined)
@@ -2,22 +2,22 @@
2
2
 
3
3
  把下面一段交给负责安装或使用 Iris 的 Agent。版本与发布状态以当前 [README](../README.md) 为准;Iris 和 DSH 的版本号独立。
4
4
 
5
- 当前安装版本为 Iris 0.2.1。先核对宿主与实际安装版本,再使用新视觉命令或 Artifact 改图;旧宿主仍固定安装 0.1.4。
5
+ 本文对应 Iris 0.2.3。使用时先核对实际版本、可用工具和功能分配;旧宿主仍固定安装 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.1。
12
+ - DSH 0.2.0-rc.2:固定安装 dsh plugin --profile web add @mokuyoaxis/dsh-iris@0.2.3。
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.1;npm 0.1.4 不含新的 Core 媒体 CLI。
16
- 先用 --help 和 Doctor 核对实际版本与命令。Iris 0.2.1 支持 OpenAI 兼容图片与视觉工作流;其他协议与 music 是后续计划。
15
+ 没有 DSH、希望用 CLI 时,按 docs/HEADLESS_CLI.md 使用 npm 0.2.3;npm 0.1.4 不含新的 Core 媒体 CLI。
16
+ 先用 --help 和 Doctor 核对实际版本与命令。Iris 0.2.3 支持图片、视频、语音、视觉与音乐入口。音乐需明确分配模型并选择 Chat Completions(内嵌音频)协议,详见 docs/MUSIC.md;使用 iris_generate_music。
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.1.
29
+ - DSH 0.2.0-rc.2: pin dsh plugin --profile web add @mokuyoaxis/dsh-iris@0.2.3.
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.1; 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.1 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.3; 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.3 offers image, video, speech, vision, and music operations. Music requires explicit model assignment and the Chat Completions inline-audio protocol described in docs/MUSIC.md; use iris_generate_music for music generation.
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.1**。0.2.0 建立实例化 Core Runtime、Headless CLI、共享 Provider 生命周期与 Task/Artifact 事实;0.2.1 补共享视觉、模型级图片协议、Artifact 编辑及维护入口。DSH 插件仅支持 `0.2.0-rc.2`,Node.js 最低为 22.0.0;旧宿主固定使用 npm `0.1.4`。Core 内部 API 尚未冻结为公共 SDK。
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。
4
4
 
5
5
  ## 当前形态
6
6
 
@@ -41,7 +41,7 @@ DSH Host / Cordis Headless CLI
41
41
 
42
42
  | 模块 | 职责 | DSH 运行时依赖 |
43
43
  |---|---|---:|
44
- | `core-contract.js` / `core-runtime.js` | 显式数据根、reader/writer 权限、单写者租约、取消与释放 | 无 |
44
+ | `core-contract.js` / `core-runtime.js` / `core-writer-lease.js`(0.2.2) | 显式数据根、reader/writer 权限、单写者租约、取消与释放 | 无 |
45
45
  | `command-service.js` | 本地媒体命令、Task 控制面和 Artifact 查询/导出 | 无 |
46
46
  | `generation-input.js` | CLI、DSH 与重试共用的生成参数校验和 Provider 字段转换 | 无 |
47
47
  | `model-port-contract.js` / `model-invoker.js` | Text/Vision 内部契约、有限调用预算与取消 | 无 |
@@ -59,10 +59,12 @@ DSH Host / Cordis Headless CLI
59
59
 
60
60
  完整规则见 [Core Runtime v0](CORE_RUNTIME_CONTRACT.md)、[Artifact Manifest v0](ARTIFACT_MANIFEST.md)、[Provider Adapter v0](PROVIDER_ADAPTER_CONTRACT.md) 与 [DSH → Core 渐进迁移](DSH_CORE_MIGRATION.md)。这些仍是内部契约,不是第三方 SDK 兼容承诺。
61
61
 
62
+ 0.2.2 的 Core writer 在创建目录前发布完整 owner 意图,释放和显式恢复通过整体退役保留证据;普通启动不抢占。非图片 staging 复用文件复制接收与分块哈希,图片格式验证和 inline 解码仍可能使用完整 Buffer,不声称端到端流式传输。
63
+
62
64
  ## Task、Attempt 与 Artifact
63
65
 
64
66
  - 一个用户意图对应一个 Core Task;每次候选供应商调用对应一个稳定 Attempt。Attempt 必须在可能发送计费请求前落盘。
65
- - 只有明确 `not_accepted` 才允许自动切换候选;`accepted` 或 `unknown` 后禁止自动重提。重试会创建新 Task,并要求用户再次提供未持久化的输入和明确确认潜在费用。
67
+ - Core只有明确 `not_accepted` 才自动切换候选;`accepted` 或 `unknown` 后通用Runner停止重提。人工重试会创建新Task,要求重新提供输入并确认潜在费用。Music功能层另按本次配置对明确HTTP502进行有限重发,保留原Task的未知事实和新旧任务关系,详见 [音乐生成](MUSIC.md)。
66
68
  - 生成结果与本地交付是两类事实。远端成功后下载失败仍保持 `outcome=succeeded / deliveryState=failed`,可显式重新交付而不重新生成。
67
69
  - 新 Attempt 可选保存阶段时间戳与模型选择来源;旧记录缺少这些字段仍可读取。
68
70
  - Artifact Manifest v0 保存内容哈希、媒体类型、中性元数据和关系边;不保存 Prompt、API Key、签名 URL、Provider 端点或宿主绝对路径。
@@ -72,8 +74,12 @@ DSH Host / Cordis Headless CLI
72
74
 
73
75
  ## Provider 边界
74
76
 
77
+ 0.2.2按功能组织有序模型候选池,能力来自明确模型标签、旧能力字段绑定或供应商能力元数据。裸账号不物化默认模型,模型名称不授权进入候选链;明确空池与空标签保持权威。模型与供应商复合身份用于底层执行器,功能入口、分配排序及安全 failover 没有改为模型中心产品或默认轮转。旧 0.2.1 的能力推断行为不再用于裸账号或模型名称赋能。
78
+
75
79
  Provider Adapter v0 固定 discovery、submit、poll、cancel、download 与 error mapping 六类生命周期操作;提交前的临时输入上传是可选准备能力,不自动成为 Core 事实。协议实现只接收显式凭据、模型和媒体端点,Core 保存复合模型身份与非敏感 binding,不保存端点原文。
76
80
 
81
+ 0.2.2 的生图错误将 HTTP 前的尺寸拒绝明确记为未受理,网络异常保留实际请求/正文阶段及可用错误码,原生取消/超时保留原分类。错误诊断不改变受理门,网络超时或正文丢失仍不能触发自动重提。
82
+
77
83
  Core Runner 不拥有后台 timer。Headless `task observe` 每次最多 poll 一次,`task wait` 仅在本次命令内有界观察;DSH 的有界自动观察属于 Host,插件释放时停止 timer 并中止在途观察,但不会把“停止本地观察”写成“远端已取消”。端点或协议 binding 漂移时恢复在联网前拒绝。
78
84
 
79
85
  每个操作必须明确声明 supported 或 unsupported。当前 DashScope 与 OpenAI Images 媒体协议没有经过验证的远端取消实现,因此取消请求如实返回 not-supported,而不是伪造 canceled。完整受理与错误规则见 [Provider 提交契约 v0](PROVIDER_SUBMISSION_CONTRACT.md)。
@@ -84,6 +90,8 @@ Core Runner 不拥有后台 timer。Headless `task observe` 每次最多 poll
84
90
 
85
91
  0.2.1通过 `prompt-optimizer-core.js` → `model-invoker.js` → `dsh-text-model-adapter.js` 接入首个提示词消费者;`prompt-optimizer.js` 继续拥有 v1 配置、模型选择、reasoning 策略和 Host 投影。共享核心不读取 Host/配置/Store,不取得 writer,也不创建媒体 Task/Attempt/Artifact。规则与预览见 [提示词优化系统](PROMPT_OPTIMIZER.md)。
86
92
 
93
+ 0.2.2 的一般提示词功能在这个共享消费者上增加 faithful / rewrite / suggestions 策略:忠实正文由原稿片段按原顺序拼回,建议独立返回并要求明确采纳。五用途和折叠预览属于 DSH UI,不自动进入生图模型池,也不新增自持文本目录、CLI 或公共 SDK。
94
+
87
95
  单图视觉将 Agent/工作台 look/relook 和显式视觉实测接入 `vision-core.js` 与 HTTP/DSH Vision Port:共享 120 秒整体预算、完整终态与候选策略,图片桥接核验原图与实际附件,接受合法宿主规范化。DSH 附件保存属于宿主副作用,不是 Core Artifact;rc.2 保存不可取消的限制如实保留。见 [单图视觉调用](VISION_MODEL.md)。视觉 CLI 复用这些业务;可选 `visionInput` 在入口层控制发送副本。未新增公共 SDK export,自持文本目录和独立提示词入口另行安排。
88
96
 
89
97
  OCR 切片通过 `ocr-model-routing.js` 在入口解引用前建立整体 operation,`ocr.js` 仅接收图片字节和模型端口,使用现有 Sharp 做有限分块;全部块复用 `completeVision`,没有每块重置计时或调用额度。普通块失败可以产生明确部分结果,取消/超时终止整次操作;不取得 Core writer 或写入 Task/Artifact。见 [长图 OCR](OCR_MODEL.md)。
@@ -1,6 +1,6 @@
1
1
  # Iris legacy 作品库 v0
2
2
 
3
- 状态:自 v0.1.4 实现,Iris 0.2.1 保留兼容。本文只描述旧 `outputs/` 与最小索引;当前工作台同时展示 Core Artifact,分页、过滤、批量下载与可恢复隔离见 [工作台作品管理](WORKBENCH_ARTIFACTS.md)。
3
+ 状态:自 v0.1.4 实现,Iris 0.2.2 保留兼容。本文只描述旧 `outputs/` 与最小索引;当前工作台同时展示 Core Artifact,分页、过滤、批量下载与可恢复隔离见 [工作台作品管理](WORKBENCH_ARTIFACTS.md)。
4
4
 
5
5
  作品库解决“清除任务历史后仍能看到本地作品”的问题。任务记录描述执行过程;作品记录只负责本地媒体的发现、展示和访问。两者生命周期彼此独立。
6
6
 
@@ -1,9 +1,11 @@
1
1
  # CLI 配置与任务管理
2
2
 
3
- 本文面向 Iris 0.2.1,沿用 `dsh-iris` 入口,无需启动 DSH,未新增生产依赖。安装 `npm install @mokuyoaxis/dsh-iris@0.2.1` 后运行 `npx dsh-iris ...`;也可从源码或本地 tarball 使用同一入口。视觉命令见 [视觉 CLI](VISION_CLI.md),基础媒体链路见 [Headless CLI](HEADLESS_CLI.md)。
3
+ 本文面向 Iris 0.2.2,沿用 `dsh-iris` 入口,无需启动 DSH,未新增生产依赖。安装 `npm install @mokuyoaxis/dsh-iris@0.2.2` 后运行 `npx dsh-iris ...`;也可从源码或本地 tarball 使用同一入口。视觉命令见 [视觉 CLI](VISION_CLI.md),基础媒体链路见 [Headless CLI](HEADLESS_CLI.md)。
4
4
 
5
5
  所有需要 JSON 的命令均支持 `--input '<json>'`、`--input-file /path/input.json` 或 `--input -`(stdin),只能选择一种,输入最多 2 MiB。私有配置必须是普通文件、绝对路径,POSIX 权限为 `0600`。真实请求只由显式执行生成、发现、实测或观察命令触发。
6
6
 
7
+ 能力配置规则已同步Iris 0.2.2:能力来自明确配置或供应商元数据,裸账号和模型名称不自动赋能。现有功能入口、按功能分配的有序候选池和安全切换规则保持。
8
+
7
9
  ## S2V 数字人视频
8
10
 
9
11
  ```bash
@@ -37,13 +39,13 @@ dsh-iris media html --data-root /path/core --input-file /path/html-input.json \
37
39
  | `providers add/set --input-file ...` | 添加/局部更新账号;JSON 是 provider 对象,必须包含 id |
38
40
  | `providers remove <id>` | 移除指定账号,剪去失效分配 |
39
41
  | `models list` | 模型复合引用、能力和实测事实 |
40
- | `models add <ref> [--input ...]` | 添加模型;可给 capabilities,省略则按现有名称规则推断 |
42
+ | `models add <ref> [--input ...]` | 添加模型;可给 capabilities,省略或空数组则保持未标注 |
41
43
  | `models caps <ref> --input ...` | 手动能力标签(允许空数组) |
42
44
  | `models protocol <ref> --input ...` | 单模型图片协议;`auto` 恢复账号默认 |
43
45
  | `models vision-input <ref> --input ...` | 模型视觉输入预算;`null` 恢复账号继承 |
44
46
  | `models remove <ref>` | 移除模型,剪去失效分配 |
45
47
  | `models discover <provider-id>` | 请求发现,仅预览,不修改配置 |
46
- | `models discover <provider-id> --apply true` | 合并发现结果,保留手工能力标签和已有实测记录 |
48
+ | `models discover <provider-id> --apply true` | 合并明确能力元数据,保留未标注条目、已有明确标签和实测记录 |
47
49
  | `models test <ref> --capability vision` | 一次红图视觉实测,严格绑定该模型,记录 verified |
48
50
  | `models test <ref> --capability image-gen/tts --data-root ...` | 实际生成测试,结果保存为 Core Task/Artifact,图片最多等待 60 秒 |
49
51
  | `models test <ref> --capability video-gen/transcribe --data-root ... --input ...` | 使用真实素材单独实测,输入格式同 `run video/transcribe`,最多等待 60 秒;成功才恢复停用模型 |
@@ -1,6 +1,6 @@
1
1
  # 定位、视频摘要与图片自述
2
2
 
3
- 状态:**Iris 0.2.1**。长图分块另见 [OCR](OCR_MODEL.md)。
3
+ 状态:**Iris 0.2.2**。长图分块另见 [OCR](OCR_MODEL.md)。
4
4
 
5
5
  ## 使用与变化
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Core Runtime v0 内部契约
2
2
 
3
- 本文定义 Iris 0.2.1 沿用的 Core Runtime 内部接口,初版在 0.2.0 实现。内部接口在后续版本仍可能调整,npm 包不把它作为公开 API 导出;现有 `config.js`、`tasks.js` 和 `artifacts.js` 也尚未迁移。
3
+ 本文定义 Iris 0.2.2 沿用的 Core Runtime 内部接口,初版在 0.2.0 实现。内部接口在后续版本仍可能调整,npm 包不把它作为公开 API 导出;现有 `config.js`、`tasks.js` 和 `artifacts.js` 也尚未迁移。
4
4
 
5
5
  ## 目标与范围
6
6
 
@@ -19,6 +19,14 @@ Core Runtime 由调用方显式创建、启动和释放。数据根、操作权
19
19
 
20
20
  初版租约优先使用 Node 标准库和本地文件系统能力,不新增生产依赖。Android 共享存储、网络文件系统和异常退出后的恢复只有拿到真实证据后才声明支持;实现不得假设 systemd 或常驻 daemon 存在。
21
21
 
22
+ 0.2.2在原 v0 租约目录旁增加 `.iris-runtime-writer-v0.owner.json` 意图证据:完整私有 owner 先准备,再通过排他 hard link 原子发布,随后创建目录并链接 `owner.json`。新写者同时尊重目录和意图;创建中断仍保留完整 PID。文件系统不支持 hard link 时安全失败,不回退到可能半写的锁。Task、Artifact、配置格式和 CLI 参数不变,既有完整 v0 目录仍可诊断与显式恢复。
23
+
24
+ 正常释放先整体 rename 非空目录为本实例 UUID 的退役目录,最后撤下意图;不会先在占位目录里删除 owner。退役目录本身不占有固定租约,但若撤下意图前中断,剩余意图仍阻止普通 writer,需要在 owner 已退出且证据完整时显式恢复。意图撤下后的清理只涉及本实例退役证据,清理失败不阻止新 writer;遗留退役目录不会在下次启动时自动删除。
25
+
26
+ 恢复使用数据根中按前驱 UUID 排他发布的完整记录,保留原 owner,不替换或删除旧恢复步骤。Doctor 的 `phase` 可为 `owned`、`pending`、`recovering`;恢复再次中断时回显最新报告中的 PID,并复核链中每个 PID 均为 missing。并发恢复与旧观察被新 writer 接替均拒绝,不向新租约目录写入陈旧 claim。无 PID 的旧空目录、仅剩 `.owner.stale-*` 而缺少恢复 owner 的旧现场、未知文件、损坏或符号链接证据仍拒绝并保留。
27
+
28
+ 私有审计先记录退役授权和完整恢复链,再整体移走租约到审计记录指定的 `evidenceDirectory`。审计 JSON 的存在本身不证明最终解除成功:命令成功结果和退役目录是相应完成证据。异常退出的准备文件、退役目录与根中的未归档恢复记录保留,普通启动不清理。当前证据来自本机私有文件系统的进程 SIGKILL 与 I/O 故障注入,不承诺断电持久性或 Android 共享/网络文件系统支持;混用旧版本 writer 不纳入这些新增保证。
29
+
22
30
  ## 访问模式和操作分类
23
31
 
24
32
  | 模式 | `inspect` | `execute` | `recover` |
@@ -66,11 +74,13 @@ created --start--> started --dispose--> disposing --finish-dispose--> disposed
66
74
 
67
75
  ## 当前接口与后续范围
68
76
 
77
+ 0.2.3 增加同步完成结果的私有交付缓存:`task.redeliver` 可从原结果恢复,无需虚构远端 ID;完整字节离线交付,缺失字节只取回原 URL,不 submit。完整缓存可补回提交完成事实的中断,预留 Artifact ID 支持逐件重入;缓存与任务隔离/恢复一起管理。详见 [同步交付恢复](SYNC_DELIVERY_RECOVERY.md)。
78
+
69
79
  当前实现包括:
70
80
 
71
81
  - `normalizeCoreOptions()`:规范化显式数据根和 reader/writer 模式;
72
82
  - `createCoreRuntime()`:管理写者租约、状态、`AbortSignal`、在途操作和 cleanup;
73
- - `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),不共用不准确的图片交付语义;
74
84
  - 0.2.1 补齐 `media.diff/frames/html`、S2V 按候选上传、查询/批量管理与 Core 隔离/恢复;视觉和维护入口见 [CLI 管理](CLI_MANAGEMENT.md) 与 [视觉 CLI](VISION_CLI.md)。
75
85
  - Artifact Manifest v0:保存受控对象、SHA-256、关系边和可重建 Index,可跨 CLI 进程检查、导出和显式重建;Doctor 只报告孤立/未解析条目,不自动删除或修复。
76
86
 
@@ -1,6 +1,8 @@
1
1
  # DSH → Core 渐进迁移
2
2
 
3
- 本文描述 **Iris 0.2.1** 的实现边界;0.2.0 建立的 Core 数据格式保持兼容。迁移逐条切换消费者,不原地改写 0.1.4 数据。
3
+ Iris 0.2.3 的音乐生成由 CLI、Agent 工具与工作台共同调用,使用独立模型协议绑定和明确功能分配。502有限重试每次创建新Core Task并记录关系,交付失败可使用同步缓存恢复,见 [音乐生成](MUSIC.md)。
4
+
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)。
6
8
 
@@ -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,6 +1,6 @@
1
1
  # 故障注入矩阵
2
2
 
3
- 状态:本矩阵使用本地 fixture、Fake Provider、Mock Fetch 或临时目录,不发送真实供应商请求。前表记录 legacy Task v2 的受理与恢复语义;后表补充 Iris 0.2.1 的 Core、图片协议与视觉边界。
3
+ 状态:本矩阵使用本地 fixture、Fake Provider、Mock Fetch 或临时目录,不发送真实供应商请求。前表记录 legacy Task v2 的受理与恢复语义;后表补充 Iris 0.2.2 的 Core、图片协议与视觉边界。
4
4
 
5
5
  | 场景 | 预期事实 | 自动重复提交 | 证据 |
6
6
  |---|---|---:|---|
@@ -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` |
@@ -33,4 +34,13 @@
33
34
  | Artifact 来源缺失/损坏或编辑失败 | 生成前核验;来源保持原样,已受理未知不重提 | 0 | `chat-image-edit.mjs`、`chat-image-edit-cli.mjs` |
34
35
  | Core 删除引用保护、隔离与恢复冲突 | 拒绝删除仍被引用的作品;可恢复隔离,冲突不覆盖 | 0 | `core-deletion-boundary.mjs`、`workbench-management.mjs` |
35
36
 
37
+ ## 0.2.2 新增边界
38
+
39
+ | 场景 | 预期事实 | 自动重复提交 | 证据 |
40
+ |---|---|---:|---|
41
+ | writer 创建/释放/恢复在关键操作后强杀、恢复竞争 | 保留完整 owner/恢复证据;陈旧现场仅显式恢复,普通 writer 不抢占 | 0 | `core-lease-interruptions.mjs`、`runtime-recover.mjs` |
42
+ | 16 MiB 视频/音频/文本文件接收或复制失败 | staging 不整文件读取;失败保持远端 succeeded,显式重交付不 submit | 0 | `provider-file-delivery.mjs` |
43
+ | 忠实整理遗漏/重复/调换原文片段、建议或媒体混入 | 协议失败不交付成功预览;建议默认不进入正文,无隐藏第二次调用 | 0 | `prompt-optimizer-boundary.mjs`、`prompt-optimizer-api.mjs`、`prompt-optimizer-client.mjs` |
44
+ | 生图本地尺寸拒绝、DNS/TLS/网络超时、HTTP 200 后正文中断 | 本地校验 not_accepted 且 fetch=0;传输失败 unknown,保留分类/阶段/可用错误码 | 0 | `image-transport-errors.mjs`、`image-task-acceptance-unknown.mjs` |
45
+
36
46
  矩阵的硬性规则是:只要已有 `accepted` 或 `unknown` 事实,任何自动路径的生成提交次数增量必须为 **0**。人工重试不属于自动恢复;它必须由用户逐次确认,并在数据中保留新旧 Task 的关系。
@@ -1,8 +1,10 @@
1
1
  # Headless CLI
2
2
 
3
- 本文面向 Iris 0.2.1,涵盖无 DSH 的本地处理、媒体生成、视觉分析、配置和任务管理。媒体结果保存为 Core Artifact,可在后续进程中检查、分析或导出;纯视觉不自动创建产物。Core 内部接口与 Artifact v0 尚未冻结为公共 SDK。
3
+ `run music` 支持音乐生成与模型级协议配置,见 [音乐生成](MUSIC.md)。音乐使用明确分配名单;其余生成能力保留分配优先加池序补齐。
4
4
 
5
- 需要 Node.js ≥ 22.0.0。安装 `npm install @mokuyoaxis/dsh-iris@0.2.1` 后运行 `npx dsh-iris --help`。源码入口为 `node bin/dsh-iris.js ...`;安装本地 tarball 后也可运行 `dsh-iris ...`。
5
+ 本文面向 Iris 0.2.3,涵盖无 DSH 的本地处理、媒体生成、视觉分析、配置和任务管理。媒体结果保存为 Core Artifact,可在后续进程中检查、分析或导出;纯视觉不自动创建产物。Core 内部接口与 Artifact v0 尚未冻结为公共 SDK。
6
+
7
+ 需要 Node.js ≥ 22.0.0。安装 `npm install @mokuyoaxis/dsh-iris@0.2.3` 后运行 `npx dsh-iris --help`。源码入口为 `node bin/dsh-iris.js ...`;安装本地 tarball 后也可运行 `dsh-iris ...`。
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
 
@@ -14,7 +16,7 @@ dsh-iris capabilities list --provider-config /absolute/path/to/providers.json
14
16
  dsh-iris doctor --data-root /absolute/path/to/iris-data --json
15
17
  ```
16
18
 
17
- 前两项只读取显式提供的私有配置文件,不创建 Core Runtime 或数据根,也不请求 Provider。`providers list` 输出供应商身份、启用/配置状态、认证方式、媒体协议及其推断标记、配置能力与模型数;不输出 API Key 或端点。`capabilities list` 按五种配置能力列出 `providerId::modelId` 候选链,沿用 DSH 的“手工分配优先、模型池顺序补齐”规则;空链标为 `gap: no_configured_model`。这些只是配置事实,不证明远端模型或协议可调用。
19
+ 前两项只读取显式提供的私有配置文件,不创建 Core Runtime 或数据根,也不请求 Provider。`providers list` 输出供应商身份、启用/配置状态、认证方式、媒体协议及其推断标记、配置能力与模型数;不输出 API Key 或端点。`capabilities list` 按六种配置能力列出 `providerId::modelId` 候选链,音乐只使用明确分配名单,其余能力采用“手工分配优先、模型池顺序补齐”规则;空链标为 `gap: no_configured_model`。这些只是配置事实,不证明远端模型或协议可调用。
18
20
 
19
21
  显式 `doctor --data-root` 是只读 Core 盘点:检查 Task/Artifact 结构、Index 一致性、孤立/未解析条目和写者租约;不创建缺失的根、不执行写入探针、不重建索引,也不释放租约。活跃写者可能使盘点在读取期间变化。省略 `--data-root` 时仍检查 DSH profile,保留原有写入探针,并纳入该 profile 的 `core-v0`。两种模式都返回 legacy/Core 计数对照,显式模式只统计指定根同层的 legacy 文件。退出码为 `0` 正常、`1` 警告、`2` 硬错误;诊断不会调用 Provider。
20
22
 
@@ -28,6 +30,8 @@ dsh-iris runtime recover --data-root /absolute/path/to/iris-data --confirm-stale
28
30
 
29
31
  此命令会再次核对租约证据和 PID,写入私有恢复审计记录后释放陈旧租约;活跃、无法确认、损坏或 PID 不匹配时拒绝。它不是 Doctor 的自动副作用,也不会修复 Task/Artifact。不要手动删除 `.iris-runtime-writer-v0` 或把“PID 不存在”单独当作安全证明。
30
32
 
33
+ 0.2.2保留创建/释放意图和恢复步骤证据。Doctor 可报告 `phase: pending` 或 `recovering`;恢复本身被强杀后重新运行 Doctor,回显最新 PID,不沿用旧确认。只有完整证据且所有相关 PID 已退出才可继续;无 owner 的旧空目录及仅剩旧 `.owner.stale-*` 的现场仍拒绝。恢复审计保留完整退役目录,普通启动不删除它们。需要支持 hard link 的私有文件系统;参数、Task/Artifact/配置版本不变。细节与验证边界见 [Core Runtime 契约](CORE_RUNTIME_CONTRACT.md)。
34
+
31
35
  媒体与视觉路由会持久记录短时 429 冷却或明确额度/预算耗尽,后续候选跳过受阻模型。冷却到期不发起请求;持续停用需 `models test` 成功恢复。状态及私有配置写入规则见 [Provider 健康](PROVIDER_HEALTH.md) 与 [CLI 管理命令](CLI_MANAGEMENT.md)。
32
36
 
33
37
  ## 裁剪并保存 Artifact
@@ -156,7 +160,9 @@ dsh-iris task redeliver task_0123456789abcdef01234567 \
156
160
  --provider-config /absolute/path/to/providers.json
157
161
  ```
158
162
 
159
- 每次命令至多一次带 redelivery 语义标志的 `poll`(拿远端产物清单)接一轮下载,写入新的 Core Artifact;不调用 `submit`、不新建 Attempt、不产生第二次生成费用。非 failed、无远端 ID 或 binding 漂移时在调用前拒绝;成功后再次调用被同样拒绝,失败回落 failed 后可再次显式执行。DSH 侧同构开放:`POST /iris/api/core/task/:id/redeliver` 与工作台「重新取回作品」按钮(delivery_failed 投影行的唯一动作)。
163
+ 异步任务每次命令至多一次带 redelivery 语义标志的 `poll`(拿远端产物清单)接一轮下载;不调用 `submit`、不新建 Attempt、不产生第二次生成费用。非 failed、缺少可恢复来源或需联网时 binding 漂移,会在调用前拒绝;成功后再次调用被同样拒绝,失败回落 failed 后可再次显式执行。DSH 侧同构开放:`POST /iris/api/core/task/:id/redeliver` 与工作台「重新取回作品」按钮。
164
+
165
+ 0.2.3 支持同步结果的私有缓存恢复:完整字节仅做本地交付,可省略 `--provider-config`;只有 URL 尚需下载时才解析原供应商,且不 poll。旧任务没有完整缓存时不能追溯恢复;详见 [同步交付恢复](SYNC_DELIVERY_RECOVERY.md)。
160
166
 
161
167
  已受理且尚未终态的 Task 可以显式请求远端取消:
162
168
 
@@ -1,6 +1,6 @@
1
1
  # Host Adapter v0 契约
2
2
 
3
- 状态:**v0.1.4 内部契约与渐进迁移已完成,并通过真实 DSH 隔离 canary。** 本文固定真实消费者所需的最小边界;0.2.1 已提供独立 Core/CLI,但未冻结公开 Host SDK,也未实现完整 Local Host。
3
+ 状态:**v0.1.4 内部契约与渐进迁移已完成,并通过真实 DSH 隔离 canary。** 本文固定真实消费者所需的最小边界;0.2.2 已提供独立 Core/CLI,但未冻结公开 Host SDK,也未实现完整 Local Host。
4
4
 
5
5
  ## 目标
6
6
 
@@ -5,7 +5,7 @@ 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、插件装载、当前工具(0.2.1为 15 个)、2 项 Skill、4 组路由、Browser/附件/模型能力、客户端版本与 4 个 UI Slot |
8
+ | `host` | 已认证 DSH 中的 `GET /iris/api/doctor` | DSH与Host Port、插件、当前工具/Skill、4组路由、Browser/附件/模型、客户端版本和4个UI Slot;Iris 0.2.3 检查16工具/3项Skill |
9
9
 
10
10
  两种模式都默认零网络、零计费。Host Doctor 不调用任何 Host Port,不打开 Browser,不读取附件或会话,不调用文本/视觉模型,也不向 Provider 发送请求。它只读取:
11
11
 
@@ -36,8 +36,8 @@ Iris `0.2.x` 仅支持 DSH `0.2.0-rc.2`,版本检查与 package 的 DSH engine
36
36
  服务端只登记成功完成的注册:
37
37
 
38
38
  - 插件身份与 npm 版本;
39
- - Iris Agent 工具名(0.2.1包含 `iris_edit_image`,共 15 个);
40
- - `iris-verify-ui`、`iris-compose-media`;
39
+ - Iris Agent工具名(含改图与音乐,共16个);
40
+ - 随包的 `iris-use`、`iris-compose-media`、`iris-verify-ui`,缺失iris-use明确报告;
41
41
  - `/iris/media`、`/iris/api`、`/iris/api/actions`、`/iris/render` 四组逻辑路由。
42
42
 
43
43
  客户端通过 `POST /iris/api/host-client` 回报插件 ID、静态客户端版本、协议版本和已执行的 Slot 名单。接口拒绝额外字段、未知 Slot、错误插件身份、空版本和无效协议号;同一前端版本的并发报告只做 Slot 单调并集,避免乱序请求把完整证据覆盖成部分证据。报告只保存在内存,不参与认证、任务执行或能力授权,也不接收 API Key、草稿、会话、附件或 Provider 数据。
@@ -1,6 +1,10 @@
1
1
  # Text/Vision Model Port v0 契约设计
2
2
 
3
- 状态:**Iris 0.2.1。** 0.2.0 已包含 M1 契约;0.2.1 接入 DSH 文本适配器与共享优化消费者、HTTP/DSH Vision Port,以及 look/relook、OCR、定位、拼图摘要和图片自述。端口仍为内部契约,不增加公开 export 或生产依赖,不改变 [Host Adapter v0](HOST_ADAPTER_CONTRACT.md) 的现有方法。新增按次规则与 UI 见 [提示词优化系统](PROMPT_OPTIMIZER.md),单图预算与宿主附件副作用见 [单图视觉调用](VISION_MODEL.md),复合操作见 [长图 OCR](OCR_MODEL.md) 和 [定位与摘要](COMPOSITE_VISION.md)。
3
+ 状态:**Iris 0.2.3。** 0.2.0 已包含 M1 契约;0.2.2 接入 DSH 文本适配器与共享优化消费者、HTTP/DSH Vision Port,以及 look/relook、OCR、定位、拼图摘要和图片自述。端口仍为内部契约,不增加公开 export 或生产依赖,不改变 [Host Adapter v0](HOST_ADAPTER_CONTRACT.md) 的现有方法。新增按次规则与 UI 见 [提示词优化系统](PROMPT_OPTIMIZER.md),单图预算与宿主附件副作用见 [单图视觉调用](VISION_MODEL.md),复合操作见 [长图 OCR](OCR_MODEL.md) 和 [定位与摘要](COMPOSITE_VISION.md)。
4
+
5
+ DSH Text 绑定按精确元数据检查文本输入声明;明确不接受 text、身份漂移或非法模态字段在生成前拒绝。没有声明时保持 unknown,已有元数据查询失败则返回准备阶段 unavailable,不再吞掉错误继续生成。查询与生成共用取消/预算,Vision 仍由独立桥接检查 image 输入,不借用 Text 的 text 检查。改写格式与路由原因见 [提示词优化系统](PROMPT_OPTIMIZER.md)。
6
+
7
+ 提示词核心为单片段 faithful 提供程序返回路径,在模型绑定/元数据/生成前短路;输入、规则、输出限额和取消仍检查。已调用的提示词结果提供 `processing.request` 完整指令快照,未调用不伪造请求;这是业务响应扩展,不改变 Model Port v0 请求/完成协议或公共 exports。
4
8
 
5
9
  0.2.1 还提供 [视觉 CLI](VISION_CLI.md)、可选账号/模型 `visionInput` 和设置命令,见 [看图输入预算](CLI_MANAGEMENT.md#看图输入预算);不改变请求/完成 DTO、契约版本或公开 exports。该设置用于看图、OCR 分块、定位和聊天改图的发送副本,不是供应商能力上限声明;聊天改图的媒体任务语义仍由 Core Runner 管理。
6
10
 
@@ -28,7 +32,7 @@ flowchart TD
28
32
  VISION --> FA
29
33
  ```
30
34
 
31
- 图中是目标结构。独立文本 Provider 与新 Headless 命令不在本轮范围;当前自持 Provider 目录尚无 `text` 能力。
35
+ 图中是目标结构。独立文本 Provider 与提示词 Headless 命令尚未提供;当前自持 Provider 目录尚无 `text` 能力。
32
36
 
33
37
  ## 职责归属
34
38
 
@@ -254,9 +258,11 @@ Host 引用、session ID 与 source metadata 可存在于 DSH 适配器闭包,
254
258
 
255
259
  提示词优化仍由 DSH 边界读取 v1 配置、解析固定/会话/默认模型,返回选择来源供 UI 展示。共享核心只接收选定端口与模板;保留原草稿、预览后写回和不携带会话历史的行为。Provider 健康反馈由入口消费安全结果/错误,模型端口不导入健康 Store。
256
260
 
261
+ 0.2.2 的一般功能在既有消费者上增加 faithful / rewrite / suggestions 策略;忠实整理校验原文片段覆盖和顺序,独立建议不自动加入正文。新策略与五用途不改变 Model Port 的单次调用契约,不新增自持文本能力、独立提示词 CLI 或公开 SDK;具体输出协议和旧调用兼容见 [提示词优化系统](PROMPT_OPTIMIZER.md)。
262
+
257
263
  ## 实现切片与退出条件
258
264
 
259
- 0.2.0 包含 M1;0.2.1 包含 M2/M3/M4 和 M5 独立视觉 CLI,详见 [视觉 CLI](VISION_CLI.md);提示词优化后续由用户另行安排。
265
+ 0.2.0 包含 M1;0.2.1 包含 M2/M3/M4 和 M5 独立视觉 CLI,详见 [视觉 CLI](VISION_CLI.md)。一般提示词功能的新增编辑策略属于 0.2.2,特殊功能及独立提示词入口后续安排。
260
266
 
261
267
  | 切片 | 范围 | 退出条件 |
262
268
  |---|---|---|
package/docs/MUSIC.md ADDED
@@ -0,0 +1,77 @@
1
+ # 音乐生成
2
+
3
+ Iris 0.2.3 提供独立音乐生成能力。配置音乐模型后,可以通过 DSH 对话、工作台或 CLI 生成 MP3/WAV,试听、下载并导出同一作品。音乐与文本转语音分别配置,组合创作时按需加入配乐。
4
+
5
+ ## 支持的接口
6
+
7
+ 选择 **Chat Completions(内嵌音频)**:服务接收 OpenAI 风格的 `/chat/completions` 请求,并在 `choices[].message.content` 文本中返回 MP3/WAV 的 `data:audio/...;base64,...` 链接。
8
+
9
+ 接口支持取决于请求和返回格式,不取决于供应商名称或模型 ID。仅声明“OpenAI 兼容”的服务不一定支持这种音频输出;纯文字、远程音频 URL 或其他音频字段不能通过当前接口交付。Google 原生音乐 API 需要独立适配,目前不在支持范围内。
10
+
11
+ ## 工作台配置
12
+
13
+ 1. 添加音乐服务的供应商,填写实际 Base URL 和 API Key;Base URL 应包含服务要求的 API 前缀,例如 `/v1`。
14
+ 2. 发现或手动添加实际模型,为它设置“音乐”功能标签。
15
+ 3. 在模型的“音乐协议”中选择“Chat Completions(内嵌音频)”。
16
+ 4. 在“能力分配”中将该模型加入音乐名单。
17
+
18
+ 音乐仅使用明确分配的名单;未分配时会提示配置缺失。发现模型、添加标签或修改协议不会提交生成请求。音乐协议独立于账号和模型的图片协议。
19
+
20
+ 配置文件中的 `musicProtocol` 使用现有标识 `gemini-web-music`,以兼容已有配置;这个标识不要求供应商或模型必须命名为 Gemini。
21
+
22
+ ## 通过 DSH 或工作台生成
23
+
24
+ 在 DSH 中可以直接描述需求:
25
+
26
+ ```text
27
+ 用 Iris 生成一首复古摇滚配乐,电吉他和鼓为主,期望约30秒,无人声。
28
+ ```
29
+
30
+ 也可以明确选择 `/iris-use` 或工具 `iris_generate_music`。工作台的音乐卡片提供描述输入、模型选择、生成、试听与下载。结果保存为 Core 音频作品,可继续查询或导出。
31
+
32
+ 曲长、人声、歌词、语言和节拍通过描述表达,由实际模型决定;当前没有保证精确控制这些属性的独立参数。输入或响应格式不符时会明确失败。
33
+
34
+ ## CLI 配置与生成
35
+
36
+ 下面的 `music-provider::music-model` 是示例,请替换为实际供应商 ID 和模型 ID。配置路径与数据根均使用绝对路径。
37
+
38
+ ```bash
39
+ dsh-iris models add music-provider::music-model \
40
+ --provider-config /absolute/path/providers.json \
41
+ --input '{"capabilities":["music-gen"],"musicProtocol":"gemini-web-music"}'
42
+
43
+ dsh-iris assignments set \
44
+ --provider-config /absolute/path/providers.json \
45
+ --input '{"capability":"music-gen","model_refs":["music-provider::music-model"]}'
46
+
47
+ dsh-iris run music \
48
+ --data-root /absolute/path/iris-data \
49
+ --provider-config /absolute/path/providers.json \
50
+ --input '{"prompt":"轻快钢琴配乐,期望约30秒,无人声","retry_502":2,"retry_delay_ms":5000,"timeout_ms":300000}'
51
+ ```
52
+
53
+ 已有模型可用 `models caps` 设置功能标签,并用 `models music-protocol` 设置 `musicProtocol`。这些命令只修改指定配置并保留私有备份,不请求生成。
54
+
55
+ 生成输入为 `prompt`,可选 `model_ref` 指定名单中的模型。成功退出码为 0,最终失败为 1;JSON 输出包含最终 Task、Artifact ID、本次 Task ID 列表与重试次数。后续进程可用 `artifact inspect` 和 `artifact export` 导出同一作品,见 [Headless CLI](HEADLESS_CLI.md)。
56
+
57
+ ## 超时、重试与失败恢复
58
+
59
+ | 参数 | 默认值 | 含义 |
60
+ |---|---:|---|
61
+ | `timeout_ms` | 300000 | 单次请求上限,范围 1–3600000 毫秒;不是音乐时长 |
62
+ | `retry_502` | 2 | HTTP 502 后额外生成次数,范围 0–5;0 关闭,默认最多提交3次 |
63
+ | `retry_delay_ms` | 5000 | 502 后等待时间,范围 0–60000 毫秒 |
64
+
65
+ 仅收到 HTTP 502 时按本次参数重试,同一失败模型重新生成,不自动切换来源。每次重发创建关联的新 Task;上游可能已经生成音乐,因此重试可能消耗额外额度。超时、其他 HTTP 状态、文字响应和交付失败不触发这项重试。供应商配额以其实际政策为准。
66
+
67
+ 完整音频已缓存但本地交付失败时,使用工作台“重新取回作品”或 `task redeliver` 恢复,不重新生成。手动 `task retry` 是一次新的知情生成,需要重新提供描述;不要在 Agent 外层再增加重试循环。
68
+
69
+ 取消会停止本地等待和后续重试,无法据此确认上游生成已经撤销。逐模型 `models test --capability music-gen` 会跳过音乐测试;需要验证服务时,明确提交所需作品。
70
+
71
+ ## 接口与产物
72
+
73
+ - 模型能力标签为 `music-gen`,Core Task 能力为 `music`,产物类型为 `generated-audio`。
74
+ - DSH 工具和工作台使用 `POST /iris/api/actions/music`;工具/Action 的模型字段是 `model`,CLI 使用 `model_ref`。
75
+ - 当前只交付 MP3/WAV,按响应媒体类型保存,不转换格式。音频作品可复用作品库筛选、播放和导出。
76
+
77
+ 交付失败的详细恢复步骤见 [同步交付恢复](SYNC_DELIVERY_RECOVERY.md)。
package/docs/OCR_MODEL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # 长图 OCR
2
2
 
3
- 状态:**Iris 0.2.1**。定位、拼图摘要及自述见 [复合视觉调用](COMPOSITE_VISION.md)。
3
+ 状态:**Iris 0.2.2**。定位、拼图摘要及自述见 [复合视觉调用](COMPOSITE_VISION.md)。
4
4
 
5
5
  Agent 的 `iris_long_ocr` 与工作台 OCR 使用相同分块业务和共享 Vision Ports。工具接受 `image_path`、`artifact_id` 或 `attachment_id` 三选一;工作台动作接受 `image_path` 或 `artifact_id` 二选一,现有表单继续输入文件路径。Core ID 读取当前 profile 的既有图片,核验内容哈希和 MIME,不依赖原文件、不导出临时图片、不写入 Core。工具文字保留 Core ID,动作 JSON 带 `artifactId`;CLI `vision ocr` 同样支持,详见 [视觉 CLI](VISION_CLI.md)。复用可选的账号/模型输入预算,不新增公开 SDK export 或生产依赖。
6
6