omnius 1.0.591 → 1.0.592

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 (131) hide show
  1. package/.aiwg/addons/omnius-docs/README.md +15 -1
  2. package/.aiwg/addons/omnius-docs/manifest.json +28 -68
  3. package/.aiwg/addons/omnius-docs/skills/agent-failure-recovery/SKILL.md +2 -1
  4. package/.aiwg/addons/omnius-docs/skills/browser-interaction-validation/SKILL.md +2 -1
  5. package/.aiwg/addons/omnius-docs/skills/evidence-directed-delivery/SKILL.md +2 -1
  6. package/.aiwg/addons/omnius-docs/skills/hardware-evidence-audit/SKILL.md +2 -1
  7. package/.aiwg/addons/omnius-docs/skills/omnius-docs/SKILL.md +17 -7
  8. package/.aiwg/addons/omnius-docs/skills/omnius-inference-docs/SKILL.md +27 -0
  9. package/.aiwg/addons/omnius-docs/skills/omnius-integration-docs/SKILL.md +21 -0
  10. package/.aiwg/addons/omnius-docs/skills/omnius-ops-docs/SKILL.md +2 -0
  11. package/.aiwg/addons/omnius-docs/skills/omnius-realtime-docs/SKILL.md +2 -0
  12. package/.aiwg/addons/omnius-docs/skills/omnius-sponsor-docs/SKILL.md +2 -0
  13. package/.aiwg/addons/omnius-docs/skills/omnius-telegram-docs/SKILL.md +2 -0
  14. package/.aiwg/addons/omnius-docs/skills/omnius-tools-docs/SKILL.md +23 -0
  15. package/.aiwg/addons/omnius-docs/skills/omnius-version-compatibility-docs/SKILL.md +23 -0
  16. package/.aiwg/addons/omnius-docs/skills/runtime-provenance-audit/SKILL.md +2 -1
  17. package/.aiwg/addons/omnius-docs/skills/secrets-and-config-audit/SKILL.md +2 -1
  18. package/.aiwg/addons/omnius-docs/skills/test-surface-audit/SKILL.md +2 -1
  19. package/.aiwg/addons/omnius-docs/skills/workspace-reality-audit/SKILL.md +2 -1
  20. package/.aiwg/addons/omnius-rest-docs/README.md +3 -0
  21. package/.aiwg/addons/omnius-rest-docs/manifest.json +27 -20
  22. package/.aiwg/addons/omnius-rest-docs/skills/omnius-rest-docs/SKILL.md +9 -5
  23. package/README.md +36 -0
  24. package/dist/discovery.d.ts +50 -0
  25. package/dist/index.js +5975 -4021
  26. package/dist/library.d.ts +7 -0
  27. package/dist/library.js +950 -0
  28. package/dist/postinstall-daemon.cjs +18 -0
  29. package/dist/providerRegistry.d.ts +80 -0
  30. package/dist/service-version.d.ts +35 -0
  31. package/docs/.vitepress/config.mts +8 -0
  32. package/docs/DISCOVERY.json +20224 -0
  33. package/docs/DISCOVERY.md +648 -0
  34. package/docs/HANDOFF-crl-encoder-decoder-fix.md +129 -0
  35. package/docs/agent-memory/INDEX.md +9 -4
  36. package/docs/agent-memory/index.md +7 -0
  37. package/docs/concept-relational-language.md +869 -0
  38. package/docs/context-management-medium-models-proposal.md +449 -0
  39. package/docs/dedup-false-positive-meta-analysis.md +96 -0
  40. package/docs/discovery/catalog-overrides.json +724 -0
  41. package/docs/duplicate-calls-root-cause-analysis.md +91 -0
  42. package/docs/duplicate-calls-root-cause-deep.md +155 -0
  43. package/docs/ephemeral-skill-pack-small-context.md +57 -0
  44. package/docs/explorations/context-window-todo-association.md +156 -0
  45. package/docs/explorations/todo-association-verify.json +30 -0
  46. package/docs/explorations/verification-ledger.json +45 -0
  47. package/docs/explorations/verify-todo-association.sh +30 -0
  48. package/docs/flowstate.md +806 -0
  49. package/docs/getting-started/install.md +24 -0
  50. package/docs/getting-started/model-providers.md +13 -0
  51. package/docs/guides/agent-integration.md +87 -0
  52. package/docs/guides/bring-your-own-inference.md +126 -0
  53. package/docs/guides/tools-and-web-search.md +95 -0
  54. package/docs/index.md +14 -0
  55. package/docs/longhaul-35b-workorders.md +496 -0
  56. package/docs/memory-integration-analysis.md +303 -0
  57. package/docs/model-capability-awareness-and-multimodal-memory-root-fix.md +799 -0
  58. package/docs/multimodal-identity-memory-implementation.md +76 -0
  59. package/docs/omnius-self-edit-eval-2026-06-10.md +169 -0
  60. package/docs/opencode-agentic-loop-comparison.md +290 -0
  61. package/docs/operations/security-and-remote-access.md +2 -2
  62. package/docs/operations/version-compatibility.md +63 -0
  63. package/docs/proposals/git-progress-tracking-strategy.md +289 -0
  64. package/docs/proposals/opencode-modules/backendAdapter.ts +443 -0
  65. package/docs/proposals/opencode-modules/childSession.ts +288 -0
  66. package/docs/proposals/opencode-modules/compactionAgent.ts +101 -0
  67. package/docs/proposals/opencode-modules/orchestrator.ts +387 -0
  68. package/docs/proposals/opencode-modules/runner.ts +258 -0
  69. package/docs/reference/auth-map.md +87 -196
  70. package/docs/reference/configuration.md +27 -0
  71. package/docs/reference/rest-api.md +7 -0
  72. package/docs/reference/slash-commands.md +125 -2
  73. package/docs/research/_archived/README.md +18 -0
  74. package/docs/research/_archived/context_window_attention_model.py +418 -0
  75. package/docs/research/_archived/context_window_attention_spec.md +55 -0
  76. package/docs/research/_archived/context_window_attention_weights.json +68 -0
  77. package/docs/research/k-splanifolds.pdf +0 -0
  78. package/docs/research/personality-verbosity-control.md +293 -0
  79. package/docs/rest/INDEX.md +7 -0
  80. package/docs/rest/QUICKREF.md +18 -0
  81. package/docs/rest/REST-DOCS-MANIFEST.json +1 -0
  82. package/docs/rest/auth-and-scopes.md +7 -1
  83. package/docs/rest/endpoints/discovery.md +44 -0
  84. package/docs/rest/endpoints/events.md +5 -0
  85. package/docs/rest/endpoints/tools.md +9 -0
  86. package/docs/reviews/adversary-system-review.md +42 -0
  87. package/docs/sana-and-video-generation-integration-plan.md +712 -0
  88. package/docs/session-diary-llm-training-analysis.md +218 -0
  89. package/docs/telegram-dmn-curiosity-outreach-scaffold.md +91 -0
  90. package/docs/telegram-mid-horizon-download-loop-handoff.md +468 -0
  91. package/docs/telegram-reflection-corpus-integration-plan.md +306 -0
  92. package/docs/telegram-unified-tooling-architecture.md +332 -0
  93. package/docs/threat-model.md +868 -0
  94. package/docs/trajectory-grounding.md +160 -0
  95. package/docs/voice-flow-architecture.md +489 -0
  96. package/docs/work-orders/WO-AM-GAPS.md +638 -0
  97. package/docs/work-orders/daemon-hud-ui-overhaul.md +82 -0
  98. package/docs/work-orders/hermes-architecture-deltas/01-public-scrutiny-provenance-control/INDEX.md +21 -0
  99. package/docs/work-orders/hermes-architecture-deltas/01-public-scrutiny-provenance-control/WORKORDER.md +225 -0
  100. package/docs/work-orders/hermes-architecture-deltas/02-context-engine-plugin-boundary/INDEX.md +20 -0
  101. package/docs/work-orders/hermes-architecture-deltas/02-context-engine-plugin-boundary/WORKORDER.md +198 -0
  102. package/docs/work-orders/hermes-architecture-deltas/03-typed-gateway-event-stream/INDEX.md +19 -0
  103. package/docs/work-orders/hermes-architecture-deltas/03-typed-gateway-event-stream/WORKORDER.md +172 -0
  104. package/docs/work-orders/hermes-architecture-deltas/04-task-local-gateway-context/INDEX.md +19 -0
  105. package/docs/work-orders/hermes-architecture-deltas/04-task-local-gateway-context/WORKORDER.md +169 -0
  106. package/docs/work-orders/hermes-architecture-deltas/05-process-lifecycle-monitoring-notifications/INDEX.md +22 -0
  107. package/docs/work-orders/hermes-architecture-deltas/05-process-lifecycle-monitoring-notifications/WORKORDER.md +189 -0
  108. package/docs/work-orders/hermes-architecture-deltas/06-vision-evidence-routing-ladder/INDEX.md +22 -0
  109. package/docs/work-orders/hermes-architecture-deltas/06-vision-evidence-routing-ladder/WORKORDER.md +199 -0
  110. package/docs/work-orders/hermes-architecture-deltas/07-durable-multi-agent-kanban/INDEX.md +20 -0
  111. package/docs/work-orders/hermes-architecture-deltas/07-durable-multi-agent-kanban/WORKORDER.md +174 -0
  112. package/docs/work-orders/hermes-architecture-deltas/08-completion-critic-reconciliation-ledger/INDEX.md +22 -0
  113. package/docs/work-orders/hermes-architecture-deltas/08-completion-critic-reconciliation-ledger/WORKORDER.md +226 -0
  114. package/docs/work-orders/hermes-architecture-deltas/INDEX.md +38 -0
  115. package/docs/work-orders/omnius-context-engineering-behavior-fixes.md +281 -0
  116. package/docs/work-orders/telegram-dropbear-context-rca-workorder.md +202 -0
  117. package/docs/work-orders/world-class-memory-compiler/README.md +162 -0
  118. package/docs/work-orders/world-class-memory-compiler/TRACKER.md +179 -0
  119. package/docs/work-orders/world-class-memory-compiler/WO-01-exact-request-budget.md +79 -0
  120. package/docs/work-orders/world-class-memory-compiler/WO-02-typed-memory-fabric.md +65 -0
  121. package/docs/work-orders/world-class-memory-compiler/WO-03-dependency-working-set.md +55 -0
  122. package/docs/work-orders/world-class-memory-compiler/WO-04-inference-memory-compiler.md +67 -0
  123. package/docs/work-orders/world-class-memory-compiler/WO-05-artifact-fidelity-materialization.md +72 -0
  124. package/docs/work-orders/world-class-memory-compiler/WO-06-temporal-hybrid-retrieval.md +49 -0
  125. package/docs/work-orders/world-class-memory-compiler/WO-07-evaluation-harness.md +45 -0
  126. package/docs/work-orders/world-class-memory-compiler/WO-08-rollout-legacy-removal.md +45 -0
  127. package/docs/x402-remote-inference-plan.md +323 -0
  128. package/npm-shrinkwrap.json +108 -117
  129. package/package.json +7 -6
  130. package/templates/AGENTS.md +6 -0
  131. package/templates/OMNIUS.md +20 -0
@@ -0,0 +1,712 @@
1
+ # Sana (Image) + `/video` (Video Generation) Integration Plan
2
+
3
+ > **Status**: Plan only. Builds a complete, anchored handoff for a downstream implementation agent.
4
+ > **Goal**: (A) Promote NVIDIA Sana to the **primary image-generation model** for `/image` and the image-generation tool, (B) ship an entirely new **`/video` pipeline** modeled exactly on the existing `/image` and `/sound`-`/music` patterns, including its agent tool, Telegram public/private wiring, weight management menus, and TUI ASCII preview (video → thumbnail frame).
5
+ >
6
+ > **Reference inventory**: `/home/robit/Downloads/open_source_video_generation_models_agent_package.md`
7
+ > **Sana upstream**: <https://github.com/NVlabs/Sana>
8
+
9
+ ---
10
+
11
+ ## 0. TL;DR for the implementation agent
12
+
13
+ You are extending three parallel pipelines that already exist for `/image`, `/sound`, and `/music`. Replicate them for video. Do **not** invent new abstractions. Reuse:
14
+
15
+ 1. The `ImageGenerateTool` (preset list, fallback ladder, Python venv bootstrapper, sidecar JSON, progress events, prompt expander, ASCII preview).
16
+ 2. The `AudioGenerateTool` (kind discriminator — `sound`/`music`, per-kind defaults, project profile fallback).
17
+ 3. The TUI command surface in [packages/cli/src/tui/commands.ts](packages/cli/src/tui/commands.ts) + [packages/cli/src/tui/command-registry.ts](packages/cli/src/tui/command-registry.ts).
18
+ 4. The Telegram bridge wiring in [packages/cli/src/tui/telegram-bridge.ts](packages/cli/src/tui/telegram-bridge.ts) + [packages/cli/src/tui/telegram-creative-tools.ts](packages/cli/src/tui/telegram-creative-tools.ts).
19
+ 5. Media classification + Telegram routing in [packages/cli/src/tui/media-routing.ts](packages/cli/src/tui/media-routing.ts) (already supports `kind: "video"` → `sendVideo`).
20
+
21
+ **Two deliverables**:
22
+
23
+ | # | Deliverable | Files (new / edited) |
24
+ | - | --- | --- |
25
+ | 1 | Make Sana the primary image generator | edit [packages/execution/src/tools/image-generate.ts](packages/execution/src/tools/image-generate.ts) (presets, ladder, defaults, runner) |
26
+ | 2 | New `/video` pipeline | new [packages/execution/src/tools/video-generate.ts](packages/execution/src/tools/video-generate.ts); edits to [packages/execution/src/index.ts](packages/execution/src/index.ts), [packages/cli/src/tui/commands.ts](packages/cli/src/tui/commands.ts), [packages/cli/src/tui/command-registry.ts](packages/cli/src/tui/command-registry.ts), [packages/cli/src/tui/omnius-directory.ts](packages/cli/src/tui/omnius-directory.ts), [packages/cli/src/tui/telegram-bridge.ts](packages/cli/src/tui/telegram-bridge.ts), [packages/cli/src/tui/telegram-creative-tools.ts](packages/cli/src/tui/telegram-creative-tools.ts) |
27
+
28
+ ---
29
+
30
+ ## 1. Architectural Anchors — How the existing `/image` pipeline is shaped
31
+
32
+ These line refs are the contract you replicate for `/video` and the spots where Sana becomes the primary model.
33
+
34
+ ### 1.1 Tool surface — `ImageGenerateTool`
35
+
36
+ File: [packages/execution/src/tools/image-generate.ts](packages/execution/src/tools/image-generate.ts) (2115 lines)
37
+
38
+ | Anchor | Lines | What it is |
39
+ | --- | --- | --- |
40
+ | Tool class header | [1206-1215](packages/execution/src/tools/image-generate.ts#L1206-L1215) | `ImageGenerateTool implements Tool`, `name = "generate_image"`, description used by the LLM. |
41
+ | Tool parameters schema | [1216-1279](packages/execution/src/tools/image-generate.ts#L1216-L1279) | JSON-schema for `prompt`, `model`, `backend`, `aspect_ratio`, `width`, `height`, `steps`, `guidance`, `seed`, `action`, `fallback`, `strict_model`, `expand_prompt`. |
42
+ | Constructor + defaults wiring | [1281-1305](packages/execution/src/tools/image-generate.ts#L1281-L1305) | `defaults: ImageGenerateToolDefaults` carries model/backend/promptExpander from settings/Telegram. |
43
+ | `execute(args)` entry | [1325-1390](packages/execution/src/tools/image-generate.ts#L1325-L1390) | Dispatch to list/setup/prewarm/generate; calls `imageGenerationFallbackCandidates`. |
44
+ | Backend dispatch | [1459-1463](packages/execution/src/tools/image-generate.ts#L1459-L1463) | `ollama` / `sdcpp` / `diffusers` per candidate. |
45
+ | Sidecar writer | [1502-1534](packages/execution/src/tools/image-generate.ts#L1502-L1534) | Writes `<image>.json` alongside the PNG with original/expanded prompt, model, backend, seed, dimensions. |
46
+ | Python runner template | [507-641](packages/execution/src/tools/image-generate.ts#L507-L641) | `DIFFUSERS_RUNNER` heredoc; auto-pick FluxPipeline / SD3Pipeline / AutoPipelineForText2Image. |
47
+ | Venv bootstrap | [1077-1130](packages/execution/src/tools/image-generate.ts#L1077-L1130) | `ensurePythonFor("diffusers" | "sdcpp")`. |
48
+ | Cache layout | [1037-1052](packages/execution/src/tools/image-generate.ts#L1037-L1052) | HF/Torch/pip caches pinned to `.omnius/image-gen/{huggingface,torch,cache,pip-cache}`. |
49
+ | Preset list | [147-486](packages/execution/src/tools/image-generate.ts#L147-L486) | `IMAGE_GENERATION_MODEL_PRESETS` (Z-Image Turbo, FLUX1 dev variants, SD3.5, Hunyuan, SDXL Turbo, SD-Turbo, LCM, Sana Sprint, sdcpp). |
50
+ | Quality ladder | [488-501](packages/execution/src/tools/image-generate.ts#L488-L501) | `IMAGE_GENERATION_QUALITY_LADDER` — ordered IDs that drive `imageGenerationFallbackCandidates` (lines [832-868](packages/execution/src/tools/image-generate.ts#L832-L868)). |
51
+ | Default constants | [59-60](packages/execution/src/tools/image-generate.ts#L59-L60) | `DEFAULT_DIFFUSERS_IMAGE_MODEL = "stabilityai/sdxl-turbo"` (**this becomes Sana**), `DEFAULT_OLLAMA_IMAGE_MODEL = "x/z-image-turbo"`. |
52
+
53
+ ### 1.2 TUI surface — `/image`
54
+
55
+ File: [packages/cli/src/tui/commands.ts](packages/cli/src/tui/commands.ts) (15065 lines)
56
+
57
+ | Anchor | Lines | What it is |
58
+ | --- | --- | --- |
59
+ | Dispatcher case | [1590-1592](packages/cli/src/tui/commands.ts#L1590-L1592) | `case "image": return handleImageCommand(...)`. |
60
+ | `handleImageCommand` | [9169-9246](packages/cli/src/tui/commands.ts#L9169-L9246) | Parses args, runs menu/list/setup/prewarm/generate, renders ASCII preview. |
61
+ | `parseImageCommand` | [8759-8779](packages/cli/src/tui/commands.ts#L8759-L8779) | Flag/positional parser used by `/image`. |
62
+ | `showImageModelsMenu` | [9054-9145](packages/cli/src/tui/commands.ts#L9054-L9145) | Hardware-aware fit menu with Del-to-delete-weights. |
63
+ | `renderImageModelList` | [8877-8911](packages/cli/src/tui/commands.ts#L8877-L8911) | `/image list` output. |
64
+ | `prewarmImageModel` | [9147-9167](packages/cli/src/tui/commands.ts#L9147-L9167) | Runs `ImageGenerateTool#execute({action: "prewarm"})`. |
65
+ | ASCII preview | [9226-9244](packages/cli/src/tui/commands.ts#L9226-L9244) | `buildImageAsciiPreview` + `extractSavedImagePath` from [image-ascii-preview.ts](packages/cli/src/tui/image-ascii-preview.ts). |
66
+ | Progress formatter | [9248-9260](packages/cli/src/tui/commands.ts#L9248-L9260) | Renders the `omnius_progress` JSON stream. |
67
+
68
+ ### 1.3 Command registry surface
69
+
70
+ File: [packages/cli/src/tui/command-registry.ts](packages/cli/src/tui/command-registry.ts)
71
+
72
+ | Anchor | Lines | What it is |
73
+ | --- | --- | --- |
74
+ | Slash help entries | [136-152](packages/cli/src/tui/command-registry.ts#L136-L152) | `/image`, `/sound`, `/music` signatures + descriptions. |
75
+ | Category overrides | [344-435](packages/cli/src/tui/command-registry.ts#L344-L435) | `image: "media"` — video must be added here too. |
76
+ | User-only set | [479-544](packages/cli/src/tui/command-registry.ts#L479-L544) | Both `/image` and `/sound`-`/music` are user-only; video should join. |
77
+ | Networked set | [547-576](packages/cli/src/tui/command-registry.ts#L547-L576) | `image` is networked because Ollama/HF pulls hit the network. Same applies to video. |
78
+ | Telegram bot command export | [681-709](packages/cli/src/tui/command-registry.ts#L681-L709) | `buildTelegramBotCommands` — adding `/video` here automatically wires the Telegram BotFather command. |
79
+
80
+ ### 1.4 Settings persistence
81
+
82
+ File: [packages/cli/src/tui/omnius-directory.ts](packages/cli/src/tui/omnius-directory.ts)
83
+
84
+ | Anchor | Lines | What it is |
85
+ | --- | --- | --- |
86
+ | `OmniusSettings` interface | [171-235](packages/cli/src/tui/omnius-directory.ts#L171-L235) | Adds `imageModel/imageBackend/soundModel/soundBackend/musicModel/musicBackend` — extend with `videoModel`/`videoBackend`/`videoKind` (default sub-kind). |
87
+ | Project/Global save+merge | [251-291](packages/cli/src/tui/omnius-directory.ts#L251-L291) | Already merges arbitrary keys — no changes needed beyond the interface. |
88
+
89
+ ### 1.5 Telegram bridge surface
90
+
91
+ File: [packages/cli/src/tui/telegram-bridge.ts](packages/cli/src/tui/telegram-bridge.ts) (8798 lines)
92
+
93
+ | Anchor | Lines | What it is |
94
+ | --- | --- | --- |
95
+ | Tool imports | [85-104](packages/cli/src/tui/telegram-bridge.ts#L85-L104) | Imports `ImageGenerateTool`, `AudioGenerateTool`, `TtsGenerateTool` — extend with `VideoGenerateTool`. |
96
+ | Admin-DM tool list | [6119-6184](packages/cli/src/tui/telegram-bridge.ts#L6119-L6184) | `new ImageGenerateTool(...)`, `new AudioGenerateTool(...)` — add `new VideoGenerateTool(...)`. |
97
+ | Quota tag map | [6246-6253](packages/cli/src/tui/telegram-bridge.ts#L6246-L6253) | `generate_image|generate_audio|generate_tts|create_audio_file` → `"generation"` quota. Extend regex to include `generate_video`. |
98
+ | Public/group creative tool factory call | [6205-6213](packages/cli/src/tui/telegram-bridge.ts#L6205-L6213) | Invokes `buildTelegramCreativeTools` — the place that scopes creative tools to a per-chat workspace. |
99
+ | Defaults helpers | [7346-7368](packages/cli/src/tui/telegram-bridge.ts#L7346-L7368) | `imageGenerationDefaultsForRepo` / `audioGenerationDefaultsForRepo` — mirror with `videoGenerationDefaultsForRepo`. |
100
+ | Generated-image sidecar reader | [8095-8158](packages/cli/src/tui/telegram-bridge.ts#L8095-L8158) | Reads `<image>.json` after sendPhoto to enable reply-context awareness — re-use for `<video>.json` after sendVideo. |
101
+ | Multipart upload | [8050-8093](packages/cli/src/tui/telegram-bridge.ts#L8050-L8093) | `sendMediaReference` — already routes `kind: "video"` to `sendVideo` via `mediaTelegramMethod` in [media-routing.ts](packages/cli/src/tui/media-routing.ts) (lines [129-144](packages/cli/src/tui/media-routing.ts#L129-L144)). |
102
+
103
+ ### 1.6 Telegram public/group creative workspace
104
+
105
+ File: [packages/cli/src/tui/telegram-creative-tools.ts](packages/cli/src/tui/telegram-creative-tools.ts)
106
+
107
+ | Anchor | Lines | What it is |
108
+ | --- | --- | --- |
109
+ | Tool factory | [139-157](packages/cli/src/tui/telegram-creative-tools.ts#L139-L157) | `buildTelegramCreativeTools` returns scoped instances of FileWrite/FileEdit/StructuredFile/Image/Audio/Tts + CreativeAudioFile. **Add `VideoGenerateTool` here.** |
110
+ | Scoped tool wrapper | [159-293](packages/cli/src/tui/telegram-creative-tools.ts#L159-L293) | Path guarding, encrypted blob storage, attachment notice. The `generate_image|generate_audio|generate_tts` regex on line 174 must include `generate_video`. |
111
+ | Manifest pickup of generated artifacts | [116-137](packages/cli/src/tui/telegram-creative-tools.ts#L116-L137) | `collectGeneratedArtifactPathsFromText` parses lines like `Image generated: <path>` and `Sound generated: ...` — extend marker regex to also catch `Video generated:`. |
112
+ | Public artifact policy | [99-105](packages/cli/src/tui/telegram-creative-tools.ts#L99-L105) | Blocks executable extensions. `.mp4/.webm/.mov/.mkv` are not on the blocklist — videos are allowed. |
113
+
114
+ ### 1.7 Media routing (kind classification + Telegram method)
115
+
116
+ File: [packages/cli/src/tui/media-routing.ts](packages/cli/src/tui/media-routing.ts) (already complete for video)
117
+
118
+ | Anchor | Lines | Status |
119
+ | --- | --- | --- |
120
+ | `VIDEO_EXT` set | [27](packages/cli/src/tui/media-routing.ts#L27) | `.mp4 .mov .mkv .webm .avi .m4v` — already covers all model outputs. |
121
+ | `classifyMedia` | [117-127](packages/cli/src/tui/media-routing.ts#L117-L127) | Returns `"video"` for the above extensions. |
122
+ | `mediaTelegramMethod("video")` | [139-140](packages/cli/src/tui/media-routing.ts#L139-L140) | Routes to `sendVideo`. **No edits needed.** |
123
+
124
+ ### 1.8 Execution package exports
125
+
126
+ File: [packages/execution/src/index.ts](packages/execution/src/index.ts)
127
+
128
+ Currently exports `ImageGenerateTool`, `ImageGenerateToolDefaults`, `AudioGenerateTool`, `AudioGenerateToolDefaults`, `VideoUnderstandTool`. **Add** exports for `VideoGenerateTool`, `VideoGenerateToolDefaults`, `VideoGenerationBackend`, `VideoGenerationPreset`, `VIDEO_GENERATION_MODEL_PRESETS`, `inferVideoGenerationBackend`, `videoGenerationSetupPlan`, `videoGenerationDir`, `videoGenerationQualityLadder`, `DEFAULT_DIFFUSERS_VIDEO_MODEL`.
129
+
130
+ ---
131
+
132
+ ## 2. Deliverable 1 — Sana as primary image model
133
+
134
+ ### 2.1 What "primary" means here
135
+
136
+ The `/image` quality ladder ([packages/execution/src/tools/image-generate.ts:488](packages/execution/src/tools/image-generate.ts#L488-L501)) defines fallback order. Today `SECONDARY_FLUX_DEV_MODEL` sits at slot 0. With Sana installed, FLUX still requires gated HF access and 12GB+ VRAM; Sana 1.6B runs on 8-12GB VRAM under Apache/NSCL with **no gating**, has a Diffusers pipeline class shipping in `diffusers>=0.32`, and was already a fallback rung as `Sana Sprint 0.6B`. We promote the **SANA-1.5 1.6B 1024px** variant to slot 0 and add **SANA-1.5 4.8B** as a higher-quality option above it.
137
+
138
+ ### 2.2 Sana model variants to register
139
+
140
+ Verified against <https://github.com/NVlabs/Sana> and HF model cards.
141
+
142
+ | ID | Pipeline | Steps | CFG | Resolution | dtype | Min VRAM | Notes |
143
+ | --- | --- | --- | --- | --- | --- | --- | --- |
144
+ | `Efficient-Large-Model/SANA1.5_1.6B_1024px_diffusers` | `SanaPipeline` | 20 | 4.5 | 1024×1024 | bfloat16 | 8 GB (CPU offload) / 12 GB recommended | **New primary.** Apache+NSCL/Gemma terms. Text enc.: `google/gemma-2-2b-it`. |
145
+ | `Efficient-Large-Model/SANA1.5_4.8B_1024px_diffusers` | `SanaPipeline` | 20 | 4.5 | 1024×1024 | bfloat16 | 16 GB / 24 GB recommended | Higher-fidelity Sana 1.5. |
146
+ | `Efficient-Large-Model/Sana_1600M_1024px_MultiLing` | `SanaPipeline` | 20 | 4.5 | 1024×1024 | bfloat16 | 8 GB / 12 GB | Multilingual variant (CN/emoji/EN). |
147
+ | `Efficient-Large-Model/Sana_1600M_2Kpx_BF16_diffusers` | `SanaPipeline` | 20 | 4.5 | 2048×2048 | bfloat16 | 16 GB / 22 GB tiled | 2K quality. |
148
+ | `Efficient-Large-Model/Sana_1600M_4Kpx_BF16_diffusers` | `SanaPipeline` | 20 | 4.5 | 4096×4096 | bfloat16 | 22 GB tiled | 4K — gated by tiling. |
149
+ | `Efficient-Large-Model/Sana_Sprint_0.6B_1024px_diffusers` | `SanaSprintPipeline` (or `AutoPipelineForText2Image`) | 4 | 0 | 1024×1024 | float16 | 6 GB | **Existing preset** — keep as the smallest/fastest path. |
150
+
151
+ ### 2.3 Edits to `image-generate.ts`
152
+
153
+ 1. Update `DEFAULT_DIFFUSERS_IMAGE_MODEL` (line [59](packages/execution/src/tools/image-generate.ts#L59)):
154
+ ```ts
155
+ export const DEFAULT_DIFFUSERS_IMAGE_MODEL = "Efficient-Large-Model/SANA1.5_1.6B_1024px_diffusers";
156
+ ```
157
+ 2. **Insert new presets** between the existing Sana Sprint preset (line [453](packages/execution/src/tools/image-generate.ts#L453-L469)) and the SDXL Turbo block. Use the same `ImageGenerationPreset` shape — copy from Sana Sprint and adjust `id/label/install/category/sizeClass/quality/minVramGB/recommendedVramGB/steps/guidance/width/height/note`.
158
+ 3. **Update `IMAGE_GENERATION_QUALITY_LADDER`** (line [488](packages/execution/src/tools/image-generate.ts#L488-L501)) so Sana 1.5 4.8B → Sana 1.5 1.6B → existing FLUX trio → Z-Image → … Sana 1.5 1.6B should appear ahead of the FLUX entries because it has no gating risk; the rest of the ladder stays as a safety net.
159
+ 4. **Patch `_pipeline_class`** in `DIFFUSERS_RUNNER` heredoc (line [529-538](packages/execution/src/tools/image-generate.ts#L529-L538)): add an explicit branch for Sana, since `AutoPipelineForText2Image` already picks `SanaPipeline` in diffusers ≥ 0.32 but Sana 1.5 needs a `text_encoder` dtype cast to bf16 (per Sana HF docs). Append after the `flux` branch:
160
+ ```python
161
+ if "sana" in lowered:
162
+ from diffusers import SanaPipeline
163
+ return SanaPipeline
164
+ ```
165
+ And in the call site, after `pipe = pipeline_cls.from_pretrained(...)`:
166
+ ```python
167
+ if "sana" in args.model.lower() and hasattr(pipe, "text_encoder"):
168
+ try:
169
+ pipe.text_encoder.to(torch.bfloat16)
170
+ except Exception:
171
+ pass
172
+ ```
173
+ 5. **Bump `_large_model` heuristic** (line [540-542](packages/execution/src/tools/image-generate.ts#L540-L542)) to enable `enable_model_cpu_offload` for the 4.8B Sana and the 2K/4K variants:
174
+ ```python
175
+ return any(token in lowered for token in [
176
+ "flux.1", "flux.2", "stable-diffusion-3.5", "hunyuan", "z-image", "janus",
177
+ "sana1.5_4.8b", "sana_1600m_2kpx", "sana_1600m_4kpx",
178
+ ])
179
+ ```
180
+ 6. **Description string** update at line [1209-1215](packages/execution/src/tools/image-generate.ts#L1209-L1215): swap "SDXL Turbo default" for "**Sana 1.5 1.6B default**".
181
+ 7. **Add Sana to fallback alternates**: when a FLUX preset fails (gated/oom), Sana should be a target. Set `fallbackFor: ["lllyasviel/flux1-dev-bnb-nf4", "ChuckMcSneed/FLUX.1-dev"]` on the new Sana 1.5 1.6B preset entry.
182
+
183
+ ### 2.4 No new venv needed
184
+
185
+ `SanaPipeline` ships in `diffusers` (already in `DIFFUSERS_PYTHON_PACKAGES` at line [130-140](packages/execution/src/tools/image-generate.ts#L130-L140)). Sana 1.5 also pulls `google/gemma-2-2b-it` — already covered by `transformers` + `sentencepiece` + `protobuf`. **No requirements changes.**
186
+
187
+ ### 2.5 First-run prewarm (Sana)
188
+
189
+ Plan and run automatically via the existing `prewarmImageModel(ctx, "Efficient-Large-Model/SANA1.5_1.6B_1024px_diffusers", "diffusers")` ([commands.ts:9147](packages/cli/src/tui/commands.ts#L9147)) path. The runner already streams `omnius_progress` JSON, which the TUI/Telegram surfaces consume identically.
190
+
191
+ ---
192
+
193
+ ## 3. Deliverable 2 — `/video` pipeline
194
+
195
+ ### 3.1 Scope
196
+
197
+ - TUI: `/video`, `/video <prompt>`, `/video --model <id> <prompt>`, `/video setup <runtime>`, `/video list`, `/video prewarm`.
198
+ - Sub-kinds: `text-to-video` (T2V, default) and `image-to-video` (I2V, when an `--image` flag or attached image is present).
199
+ - Agent tool: `generate_video` (Diffusers-first; Ollama is not a path because no current Ollama model emits video). Telegram public + admin contexts.
200
+ - Telegram BotFather command `/video` auto-registered via `buildTelegramBotCommands` since the command registry covers it.
201
+ - Outputs: MP4 saved under `.omnius/videos/vid-<timestamp>-<rand>.mp4` with thumbnail PNG at `<video>.png` and sidecar JSON at `<video>.json`.
202
+ - Preview: TUI renders ASCII preview of the thumbnail; Telegram auto-attaches video via existing `sendVideo` routing.
203
+
204
+ ### 3.2 New types — `VideoGenerationBackend`, `VideoGenerationKind`, `VideoGenerationPreset`
205
+
206
+ To live in [packages/execution/src/tools/video-generate.ts](packages/execution/src/tools/video-generate.ts) (new file).
207
+
208
+ ```ts
209
+ export type VideoGenerationKind = "t2v" | "i2v";
210
+ export type VideoGenerationBackend = "auto" | "diffusers" | "comfyui";
211
+
212
+ export interface VideoGenerationPreset {
213
+ id: string;
214
+ label: string;
215
+ kinds: VideoGenerationKind[]; // models can support t2v, i2v, or both
216
+ backend: Exclude<VideoGenerationBackend, "auto">;
217
+ pipelineClass: // signals which Diffusers class to use
218
+ | "WanPipeline"
219
+ | "MochiPipeline"
220
+ | "CogVideoXPipeline"
221
+ | "CogVideoXImageToVideoPipeline"
222
+ | "LTXPipeline"
223
+ | "LTXConditionPipeline"
224
+ | "HunyuanVideoPipeline"
225
+ | "AutoPipelineForText2Video";
226
+ install: string; // canonical pip/cli line shown in setup
227
+ category: string;
228
+ sizeClass: string;
229
+ quality: string;
230
+ output: string; // e.g. "5s 720p MP4 at 24fps"
231
+ minVramGB: number;
232
+ recommendedVramGB: number;
233
+ deployment: string;
234
+ steps: number;
235
+ guidance?: number;
236
+ numFrames: number;
237
+ fps: number;
238
+ width: number;
239
+ height: number;
240
+ dtype: "bfloat16" | "float16";
241
+ needsCpuOffload: boolean; // forces enable_model_cpu_offload + tiling
242
+ needsVae?: { repoSubfolder: string }; // Wan2.2 separate AutoencoderKLWan
243
+ fallbackFor?: string[];
244
+ note: string;
245
+ }
246
+
247
+ export const DEFAULT_DIFFUSERS_VIDEO_MODEL = "Wan-AI/Wan2.2-TI2V-5B-Diffusers";
248
+ ```
249
+
250
+ ### 3.3 Video preset registry (Phase 1 + Phase 2 from the reference doc)
251
+
252
+ These are the verified Diffusers-runnable models. Each entry uses the shape above.
253
+
254
+ | ID | Pipeline | Kinds | dtype | Frames | FPS | W×H | Steps | CFG | Min/Rec VRAM | License |
255
+ | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
256
+ | **`Wan-AI/Wan2.2-TI2V-5B-Diffusers`** | `WanPipeline` (+`AutoencoderKLWan`) | t2v, i2v | bfloat16 | 121 | 24 | 1280×704 | 50 | 5.0 | 24 / 80 | Apache 2.0 |
257
+ | `genmo/mochi-1-preview` | `MochiPipeline` | t2v | bfloat16 (variant `bf16`) | 84 | 30 | 848×480 | 64 | 4.5 | 22 (offload) / 42 | Apache 2.0 |
258
+ | `zai-org/CogVideoX-5b` | `CogVideoXPipeline` | t2v | bfloat16 | 49 | 8 | 720×480 | 50 | 6.0 | 5 (offload) / 15 | Apache 2.0 |
259
+ | `zai-org/CogVideoX-2b` | `CogVideoXPipeline` | t2v | bfloat16 | 49 | 8 | 720×480 | 50 | 6.0 | 4 / 8 | Apache 2.0 |
260
+ | `Lightricks/LTX-Video` | `LTXPipeline` | t2v | bfloat16 | 121 | 24 | 832×480 | 30 | n/a | 12 / 20 | LTX Open-Weights (non-commercial) |
261
+ | `Lightricks/LTX-Video-0.9.8-dev` | `LTXConditionPipeline` | i2v | bfloat16 | 96 | 24 | 832×480 | 30 | n/a | 16 / 24 | LTX Open-Weights |
262
+ | `tencent/HunyuanVideo` | `HunyuanVideoPipeline` | t2v | bfloat16 | 129 | 24 | 1280×720 | 50 | 6.0 | 60 / 80 | Tencent Hunyuan Community |
263
+ | `Wan-AI/Wan2.2-I2V-A14B-Diffusers` | `WanPipeline` | i2v | bfloat16 | 121 | 24 | 1280×720 | 50 | 5.0 | 40 / 80 | Apache 2.0 |
264
+ | `Wan-AI/Wan2.2-T2V-A14B-Diffusers` | `WanPipeline` | t2v | bfloat16 | 121 | 24 | 1280×720 | 50 | 5.0 | 40 / 80 | Apache 2.0 |
265
+
266
+ **Default**: `Wan-AI/Wan2.2-TI2V-5B-Diffusers` — practical 24GB VRAM target, supports both T2V and I2V, becomes the agent default.
267
+
268
+ **Quality ladder** (consumer-first, gated/biggest last):
269
+ ```text
270
+ 1. Wan2.2 TI2V 5B (primary; both t2v+i2v)
271
+ 2. LTX-Video 0.9.8 (T2V) (fast iteration)
272
+ 3. CogVideoX-5B (5 GB VRAM with offload)
273
+ 4. Mochi 1 Preview (permissive)
274
+ 5. CogVideoX-2B (smoke-test fallback)
275
+ 6. Wan2.2 I2V A14B (premium I2V)
276
+ 7. Wan2.2 T2V A14B (premium T2V)
277
+ 8. HunyuanVideo (cinematic, datacenter)
278
+ ```
279
+
280
+ ### 3.4 Python runner template (`DIFFUSERS_VIDEO_RUNNER`)
281
+
282
+ Mirror `DIFFUSERS_RUNNER` from `image-generate.ts`. Key differences:
283
+
284
+ - Selects pipeline class from `model` via the same lowered-string heuristics (`wan`, `mochi`, `cogvideox`, `ltx`, `hunyuanvideo`). For Wan, additionally instantiate `AutoencoderKLWan.from_pretrained(model_id, subfolder="vae", torch_dtype=torch.float32)` and pass `vae=vae`.
285
+ - For I2V, accept `--image <path>` and feed via `image=load_image(args.image)`.
286
+ - Use `from diffusers.utils import export_to_video` to write MP4 at the model's preferred fps.
287
+ - After export, run `ffmpeg -hide_banner -loglevel error -ss 00:00:00 -i <out.mp4> -frames:v 1 -q:v 2 <out.mp4>.png` (or use OpenCV) to produce a thumbnail; emit thumbnail path in the final JSON line.
288
+ - Emit the same `{"omnius_progress": true, "stage": ..., "message": ..., "percent": ...}` lines on stderr so the TUI/telegram progress formatter keeps working.
289
+ - Output final JSON line: `{"ok": true, "path": "<mp4>", "thumbnail": "<mp4>.png", "frames": N, "width": W, "height": H, "fps": F, "duration_seconds": D, "model": "<id>", "device": "cuda"}`.
290
+
291
+ ```python
292
+ def _video_pipeline(model):
293
+ lowered = model.lower()
294
+ if "wan" in lowered:
295
+ from diffusers import WanPipeline, AutoencoderKLWan
296
+ return ("wan", WanPipeline, AutoencoderKLWan)
297
+ if "mochi" in lowered:
298
+ from diffusers import MochiPipeline
299
+ return ("mochi", MochiPipeline, None)
300
+ if "cogvideox" in lowered:
301
+ from diffusers import CogVideoXPipeline, CogVideoXImageToVideoPipeline
302
+ return ("cogvideox", CogVideoXPipeline, CogVideoXImageToVideoPipeline)
303
+ if "ltx" in lowered:
304
+ from diffusers import LTXPipeline, LTXConditionPipeline
305
+ return ("ltx", LTXPipeline, LTXConditionPipeline)
306
+ if "hunyuanvideo" in lowered:
307
+ from diffusers import HunyuanVideoPipeline
308
+ return ("hunyuan", HunyuanVideoPipeline, None)
309
+ from diffusers import AutoPipelineForText2Video
310
+ return ("auto", AutoPipelineForText2Video, None)
311
+ ```
312
+
313
+ The runner script lives at `.omnius/video-gen/diffusers_text2video.py` and is written by `ensureRunner(repoRoot, "video-diffusers")` (new variant of [image-generate.ts:1132-1141](packages/execution/src/tools/image-generate.ts#L1132-L1141)).
314
+
315
+ ### 3.5 Python deps
316
+
317
+ ```ts
318
+ const DIFFUSERS_VIDEO_PACKAGES = [
319
+ "torch",
320
+ "torchvision",
321
+ "diffusers",
322
+ "transformers",
323
+ "accelerate",
324
+ "safetensors",
325
+ "pillow",
326
+ "sentencepiece",
327
+ "protobuf",
328
+ "imageio",
329
+ "imageio-ffmpeg",
330
+ "ftfy", // common Hunyuan/CogVideoX requirement
331
+ "einops", // LTX
332
+ "av", // Wan VAE
333
+ ];
334
+ ```
335
+
336
+ Cache layout mirrors image-gen at `.omnius/video-gen/{huggingface,torch,cache,pip-cache,.venv}`.
337
+
338
+ ### 3.6 `VideoGenerateTool` class skeleton
339
+
340
+ Direct mirror of `ImageGenerateTool`. Required surface:
341
+
342
+ ```ts
343
+ export class VideoGenerateTool implements Tool {
344
+ name = "generate_video";
345
+ description =
346
+ "Generate a short video from a text prompt or text+image using a local Diffusers video model. " +
347
+ "Default model: Wan-AI/Wan2.2-TI2V-5B-Diffusers (24GB-class GPU, both text-to-video and image-to-video). " +
348
+ "Pass mode='t2v' (default) or mode='i2v' with image=<path|url>. Optional duration_seconds, fps, aspect_ratio, " +
349
+ "negative_prompt, seed. Saves an MP4 under .omnius/videos and returns the file path. Outputs a thumbnail PNG " +
350
+ "next to the MP4 so chat surfaces can render a preview.";
351
+ parameters = { /* prompt, image, mode, model, backend, duration_seconds, fps,
352
+ num_frames, width, height, aspect_ratio, steps, guidance,
353
+ negative_prompt, seed, action, fallback, strict_model, expand_prompt */ };
354
+ setProgressCallback(...) { ... }
355
+ setPromptExpander(...) { ... } // optional — reuses the same expander contract
356
+ async execute(args): Promise<ToolResult> { ... }
357
+ }
358
+ ```
359
+
360
+ Key parameter notes:
361
+
362
+ - `mode`: `"t2v" | "i2v"`. If `image` is passed and `mode` is unset, infer `"i2v"`.
363
+ - `duration_seconds` + `fps` derive `num_frames` if not provided.
364
+ - `aspect_ratio`: same `W:H` parser as image — resolves around the preset's longest side, snapped to a multiple of 16 (LTX requires multiples of 32; for those models snap to 32 in the runner-side validation).
365
+ - `negative_prompt`: forwarded to all models that accept it; ignored otherwise.
366
+ - `strict_model`/`fallback`: same semantics as `ImageGenerateTool`.
367
+
368
+ Reuse helpers from image-gen by lifting them into a tiny shared module (`packages/execution/src/tools/internal/generative-runtime.ts` if you want cleanliness, otherwise duplicate locally to keep the change surface tight):
369
+
370
+ - `runProcess`, `cleanProgressText`, `parsePercent`, `parseStructuredProgress`, `parseRunnerJson`
371
+ - `ensurePythonFor` (parameterize by `kind: "video-diffusers"` + dir + import-check string)
372
+ - `imageGenerationPythonEnv` → generalize as `pythonGenerationEnv(rootDir)`
373
+
374
+ > **Recommendation**: duplicate locally for the first cut to avoid touching the image-generate file beyond Sana edits. A follow-up PR can extract `internal/generative-runtime.ts`.
375
+
376
+ ### 3.7 Sidecar JSON for video
377
+
378
+ Exact same shape as image sidecar ([image-generate.ts:1502-1534](packages/execution/src/tools/image-generate.ts#L1502-L1534)), extended fields:
379
+
380
+ ```json
381
+ {
382
+ "version": 1,
383
+ "kind": "video-generation",
384
+ "video_path": "/repo/.omnius/videos/vid-…mp4",
385
+ "thumbnail_path": "/repo/.omnius/videos/vid-…mp4.png",
386
+ "original_prompt": "...",
387
+ "expanded_prompt": "...",
388
+ "prompt_was_expanded": true,
389
+ "mode": "t2v",
390
+ "image_input": null,
391
+ "model": "Wan-AI/Wan2.2-TI2V-5B-Diffusers",
392
+ "backend": "diffusers",
393
+ "width": 1280,
394
+ "height": 704,
395
+ "num_frames": 121,
396
+ "fps": 24,
397
+ "duration_seconds": 5.04,
398
+ "seed": null,
399
+ "aspect_ratio": "16:9",
400
+ "created_at": "2026-…Z"
401
+ }
402
+ ```
403
+
404
+ `recordOutboundGeneratedImagePrompt` in [telegram-bridge.ts:8102-8129](packages/cli/src/tui/telegram-bridge.ts#L8102-L8129) needs a parallel `recordOutboundGeneratedVideoPrompt` (or generalize the helper to take `kind`). The existing `sendMediaReference` path already accepts a `sourcePromptPath` option (see [telegram-bridge.ts:8087-8088](packages/cli/src/tui/telegram-bridge.ts#L8087-L8088)) — extend the conditional from `media.kind === "image"` to `media.kind === "image" || media.kind === "video"`.
405
+
406
+ ### 3.8 TUI command — `/video`
407
+
408
+ Edit [packages/cli/src/tui/commands.ts](packages/cli/src/tui/commands.ts):
409
+
410
+ 1. Add dispatcher case beside `/image` ([line 1590-1600](packages/cli/src/tui/commands.ts#L1590-L1600)):
411
+ ```ts
412
+ case "video": {
413
+ return handleVideoCommand(ctx, arg, hasLocal);
414
+ }
415
+ ```
416
+ 2. Implement `handleVideoCommand`, `showVideoModelsMenu`, `renderVideoModelList`, `prewarmVideoModel`, `rateVideoPresetForHardware`, `videoModelDiskStats`, `deleteVideoModelWeights`, `formatVideoGenerationProgress`. Mirror the image helpers at [commands.ts:9054-9260](packages/cli/src/tui/commands.ts#L9054-L9260) — keep names parallel for grep-ability.
417
+ 3. Reuse `parseImageCommand` ([line 8759-8779](packages/cli/src/tui/commands.ts#L8759-L8779)) as-is — it is already generic over flags. Add `--image <path>` recognition through the existing flag pass-through.
418
+ 4. For ASCII preview, after generation completes, the runner emits a `thumbnail` field in its final JSON. Pipe that into `buildImageAsciiPreview` and render with a "Generated video" label and `Tap to play: <path>` line. Use `extractSavedImagePath`-style helper `extractSavedVideoPath(text, repoRoot)` matching `Video generated: <path>`.
419
+
420
+ ### 3.9 Command registry — `/video`
421
+
422
+ Edit [packages/cli/src/tui/command-registry.ts](packages/cli/src/tui/command-registry.ts):
423
+
424
+ 1. Slash help block (after the `/music` entries at [line 147-151](packages/cli/src/tui/command-registry.ts#L147-L151)):
425
+ ```ts
426
+ ["/video", "Open video-generation model/setup menu"],
427
+ ["/video <prompt>", "Generate a video from a prompt and show an ASCII thumbnail"],
428
+ ["/video --model <model> <prompt>", "Generate with an explicit video model"],
429
+ ["/video --image <path|url> <prompt>", "Image-to-video animation"],
430
+ ["/video setup <diffusers|comfyui>", "Show setup commands for a video-generation backend"],
431
+ ["/video list", "List video models by category, quality, size, and hardware fit"],
432
+ ```
433
+ 2. Add `video: "media"` to `CATEGORY_OVERRIDES` ([line 344-435](packages/cli/src/tui/command-registry.ts#L344-L435)).
434
+ 3. Add `"video"` to the `USER_ONLY` and `NETWORKED` sets ([line 479-600](packages/cli/src/tui/command-registry.ts#L479-L600)).
435
+
436
+ ### 3.10 Settings interface
437
+
438
+ Edit [packages/cli/src/tui/omnius-directory.ts](packages/cli/src/tui/omnius-directory.ts) at [line 228-229](packages/cli/src/tui/omnius-directory.ts#L228-L229):
439
+ ```ts
440
+ /** Preferred video-generation model for /video and video-generation tool defaults */
441
+ videoModel?: string;
442
+ /** Preferred video-generation backend for /video */
443
+ videoBackend?: "auto" | "diffusers" | "comfyui";
444
+ /** Default sub-kind for /video when image input is absent */
445
+ videoKind?: "t2v" | "i2v";
446
+ ```
447
+
448
+ ### 3.11 Telegram bridge wiring
449
+
450
+ Edit [packages/cli/src/tui/telegram-bridge.ts](packages/cli/src/tui/telegram-bridge.ts):
451
+
452
+ 1. Imports at [line 85-104](packages/cli/src/tui/telegram-bridge.ts#L85-L104) — add `VideoGenerateTool` + `VideoGenerateToolDefaults`.
453
+ 2. Admin tool list at [line 6165-6168](packages/cli/src/tui/telegram-bridge.ts#L6165-L6168) — insert `new VideoGenerateTool(repoRoot, videoDefaults)`.
454
+ 3. Compute `videoDefaults` in the same place as `imageDefaults`/`audioDefaults` (search for `imageGenerationDefaultsForRepo`). Add:
455
+ ```ts
456
+ private videoGenerationDefaultsForRepo(repoRoot: string): VideoGenerateToolDefaults {
457
+ const settings = resolveSettings(repoRoot);
458
+ return {
459
+ model: typeof settings.videoModel === "string" && settings.videoModel.trim()
460
+ ? settings.videoModel
461
+ : undefined,
462
+ backend: settings.videoBackend,
463
+ defaultKind: settings.videoKind,
464
+ };
465
+ }
466
+ ```
467
+ 4. Quota regex at [line 6249](packages/cli/src/tui/telegram-bridge.ts#L6249):
468
+ ```ts
469
+ if (/^(generate_image|generate_audio|generate_video|generate_tts|create_audio_file)$/.test(toolName)) return "generation";
470
+ ```
471
+ 5. **Quota limits**: video is heavy. Add a dedicated `TelegramPublicQuotaKind` `"video-generation"` with a tighter window (e.g. 2/hour) in `TELEGRAM_PUBLIC_TOOL_QUOTAS` (search the same file for its declaration) and route `generate_video` to it explicitly.
472
+ 6. Public-context creative tool factory call at [line 6205-6212](packages/cli/src/tui/telegram-bridge.ts#L6205-L6212) — pass `videoDefaults` into the new factory signature.
473
+ 7. Outbound sidecar pickup at [line 8087-8093](packages/cli/src/tui/telegram-bridge.ts#L8087-L8093) — extend the condition so a successful `sendVideo` also calls `recordOutboundGeneratedMediaPrompt(chatId, messageId, videoPath, caption, "video")`. Read the `<video>.json` sidecar and store it on the chat history entry just like images today.
474
+ 8. Telegram BotFather command list — `/video` will register automatically via `listCommandRegistry` consumed by `buildTelegramBotCommands` ([command-registry.ts:681-709](packages/cli/src/tui/command-registry.ts#L681-L709)).
475
+ 9. System-prompt strings at [line 5555-5556](packages/cli/src/tui/telegram-bridge.ts#L5555-L5556): add a parallel sentence telling the model "For video generation requests, decide whether `generate_video` is appropriate (image-to-video if the user attached an image)."
476
+
477
+ ### 3.12 Telegram public/group creative tools
478
+
479
+ Edit [packages/cli/src/tui/telegram-creative-tools.ts](packages/cli/src/tui/telegram-creative-tools.ts):
480
+
481
+ 1. Imports at [line 22-30](packages/cli/src/tui/telegram-creative-tools.ts#L22-L30) — add `VideoGenerateTool` + `VideoGenerateToolDefaults`.
482
+ 2. Factory signature at [line 139-145](packages/cli/src/tui/telegram-creative-tools.ts#L139-L145):
483
+ ```ts
484
+ export function buildTelegramCreativeTools(
485
+ repoRoot: string,
486
+ chatId: TelegramChatId | undefined,
487
+ backendUrl?: string,
488
+ imageDefaults: ImageGenerateToolDefaults = {},
489
+ audioDefaults: AudioGenerateToolDefaults = {},
490
+ videoDefaults: VideoGenerateToolDefaults = {},
491
+ ): Tool[] {
492
+ ```
493
+ 3. Factory body at [line 148-157](packages/cli/src/tui/telegram-creative-tools.ts#L148-L157) — append `scopedTool(new VideoGenerateTool(root, videoDefaults), root, "generate")`.
494
+ 4. Scoped wrapper regex at [line 174](packages/cli/src/tui/telegram-creative-tools.ts#L174):
495
+ ```ts
496
+ if (base.name === "generate_image" || base.name === "generate_audio" || base.name === "generate_video" || base.name === "generate_tts") {
497
+ ```
498
+ 5. `collectGeneratedArtifactPathsFromText` marker regex at [line 128](packages/cli/src/tui/telegram-creative-tools.ts#L128):
499
+ ```ts
500
+ line.match(/(?:Image generated|Sound generated|Music generated|Video generated|TTS generated|Created [A-Z]+ file|Created|Overwrote|Saved to):\s*([^\n\r(]+)/i);
501
+ ```
502
+ 6. **No blocklist edits needed** — `.mp4/.webm/.mov/.mkv/.m4v` are not in `PUBLIC_EXECUTABLE_ARTIFACT_EXTENSIONS` at [line 64-74](packages/cli/src/tui/telegram-creative-tools.ts#L64-L74), so videos already pass policy.
503
+
504
+ ### 3.13 Execution package exports
505
+
506
+ Edit [packages/execution/src/index.ts](packages/execution/src/index.ts) — alongside existing `ImageGenerateTool` / `AudioGenerateTool` exports, re-export the entire `VideoGenerateTool` surface (class, defaults type, presets, backend type, ladder helper, setup plan, dir helper, default constant).
507
+
508
+ ### 3.14 First-run prewarm strategy
509
+
510
+ Wan2.2 TI2V 5B is ~10 GB on disk and pulls T5 encoder + AutoencoderKLWan in addition to the transformer. The first `/video` call (or first `/video setup diffusers`) will:
511
+
512
+ 1. Create `.omnius/video-gen/.venv`.
513
+ 2. `pip install` `DIFFUSERS_VIDEO_PACKAGES`.
514
+ 3. Pull `Wan-AI/Wan2.2-TI2V-5B-Diffusers` via `WanPipeline.from_pretrained(...)` and `AutoencoderKLWan.from_pretrained(..., subfolder="vae")`.
515
+ 4. Run a `--prewarm` pass that loads the pipeline + VAE and exits. The runner must emit the same `omnius_progress` JSON for percent/stage so the TUI bar and Telegram updates work unchanged.
516
+
517
+ Document this in the existing `--help`-style command output for `/video setup diffusers`.
518
+
519
+ ### 3.15 Hardware fit heuristic for video
520
+
521
+ Add `rateVideoPresetForHardware(preset, specs)` in `commands.ts`. Use the same VRAM-based scoring as `rateImagePresetForHardware` but include a "frames * resolution / dtype" penalty so 4K Wan and 720p Hunyuan land in red on a 16GB GPU. Reuse `imageFitIcon`. Keep three labels: `excellent / comfortable / offload-only / heavy-cloud`.
522
+
523
+ ### 3.16 Tool description for the LLM (`generate_video` system surfacing)
524
+
525
+ Critical for autonomous use. Make the tool description list:
526
+
527
+ - Default model + that it runs both T2V and I2V.
528
+ - That **I2V** is triggered when an `image` is provided (path or URL).
529
+ - That `duration_seconds` ≤ 6 is recommended on consumer GPUs.
530
+ - That the tool **takes long enough that the agent should set expectations** (≥ 2 minutes on 24GB even for the small Wan); see Telegram quota in §3.11.
531
+ - That a thumbnail is auto-generated and attached for previews.
532
+ - That the sidecar JSON enables reply-context — the agent can reference "what prompt made this video?".
533
+
534
+ This matches the existing `ImageGenerateTool` description style ([image-generate.ts:1208-1215](packages/execution/src/tools/image-generate.ts#L1208-L1215)).
535
+
536
+ ### 3.17 Public Telegram safety review
537
+
538
+ - **Public users cannot exfiltrate the repo**: `VideoGenerateTool` writes into the per-chat workspace root passed to `scopedTool` (the wrapper enforces `--output` is rewritten under `rootAbs` exactly like image+audio). Pattern: see [telegram-creative-tools.ts:171-235](packages/cli/src/tui/telegram-creative-tools.ts#L171-L235).
539
+ - **Public users cannot bomb GPU**: `generate_video` lands under `"generation"` (or new `"video-generation"`) quota.
540
+ - **Public users cannot pull arbitrary models**: agent gets `videoDefaults.model = settings.videoModel` and the description discourages exploring other models; admin can still override.
541
+ - **Public users cannot use I2V to leak files**: scoped wrapper already materializes `image` arg through `materializeTelegramCreativeArtifactForSend` for any local-path inputs ([telegram-creative-tools.ts:187-203](packages/cli/src/tui/telegram-creative-tools.ts#L187-L203)). Add the same TTS-style key list for video — recognized image-input keys: `image`, `image_path`, `init_image`, `source_image`, `reference_image`.
542
+
543
+ ### 3.18 Thumbnail strategy
544
+
545
+ Emit thumbnail from the runner with one of:
546
+
547
+ - `ffmpeg -hide_banner -loglevel error -y -i <out.mp4> -frames:v 1 -q:v 2 <out.mp4>.png`
548
+ - Or `imageio.get_reader(out_path).get_data(0).save(thumb_path)` if ffmpeg is missing.
549
+
550
+ Set TUI ASCII preview to `<video>.png` since `image-ascii-preview.ts` already handles PNGs.
551
+
552
+ ### 3.19 ComfyUI path (optional, deferred to follow-up)
553
+
554
+ The reference doc names ComfyUI as a strong runtime for Wan/Hunyuan. The plan defers ComfyUI to Phase 2 — implement the backend type now (`"comfyui"`) but `videoGenerationSetupPlan("comfyui", ...)` returns a "not yet supported in this build; use diffusers" message until a ComfyUI worker is wired. This keeps the menu layout future-proof without blocking shipping.
555
+
556
+ ### 3.20 LTX license note (HIGH attention)
557
+
558
+ `Lightricks/LTX-Video` ships under the LTX Open-Weights License — **non-commercial**. The preset entry's `note` MUST surface this, and the LLM tool description should advise that the agent default (Wan2.2 TI2V 5B, Apache 2.0) is the safer baseline. We do not promote LTX to default; FLUX-style gating logic ([image-generate.ts:1031-1033](packages/execution/src/tools/image-generate.ts#L1031-L1033)) inspires the LTX error path: detect `LTX-Video-Open-Weights-License` files in the HF response and surface a license-accept reminder.
559
+
560
+ ### 3.21 HunyuanVideo gating note
561
+
562
+ Tencent HunyuanVideo requires HF auth (license click-through). Reuse the existing gated-repo detection at [image-generate.ts:1031-1033](packages/execution/src/tools/image-generate.ts#L1031-L1033) — generalize it into `formatVideoFailure`.
563
+
564
+ ---
565
+
566
+ ## 4. Cross-cutting checklist for the downstream agent
567
+
568
+ ### 4.1 Build / type pipeline
569
+
570
+ - `tsc --build` from the monorepo root must stay green. The new exports in `packages/execution/src/index.ts` need the new file to compile cleanly.
571
+ - Update `packages/execution/tsconfig.tsbuildinfo` consumers automatically; no manual edits.
572
+ - Add unit tests next to the image tests (look for `packages/cli/tests/image-ascii-preview.test.ts`-style pattern) — at minimum, register a `video-generate.preset.test.ts` that asserts every preset entry parses and the ladder is non-empty.
573
+
574
+ ### 4.2 Smoke tests (post-merge)
575
+
576
+ Run the three reference doc smoke prompts (§8 in the package) via:
577
+
578
+ ```
579
+ omnius /video setup diffusers
580
+ omnius /video "A locked-off cinematic shot of a matte black cube on wet asphalt at night..."
581
+ omnius /video --image .omnius/images/<sample>.png "Animate this image with subtle camera push-in..."
582
+ ```
583
+
584
+ Then exercise via Telegram in (1) admin DM, (2) public group with bot added (use `aiwg-status` style ad-hoc check). Confirm:
585
+
586
+ - ASCII thumbnail renders in TUI.
587
+ - `sendVideo` delivers the file with caption containing the prompt.
588
+ - Reply-to-video carries `originalPrompt` into the next turn (because of the sidecar pickup at §3.11.7).
589
+ - Public quota blocks the third call within the window.
590
+
591
+ ### 4.3 Telegram BotFather refresh
592
+
593
+ After shipping, run `aiwg ralph-status`-equivalent: the bot's command set updates via `setMyCommands` on startup. Confirm `/video` appears in the in-app menu by sending `/start` to the bot.
594
+
595
+ ### 4.4 Docs to drop alongside the PR
596
+
597
+ - Update [README.md](README.md) media section (search for `/image` mention) to reference `/video`.
598
+ - Add a one-line bullet to [docs/voice-flow-architecture.md](docs/voice-flow-architecture.md) or create a peer doc `docs/video-flow-architecture.md` summarizing the runner shape.
599
+
600
+ ### 4.5 Risk register
601
+
602
+ | Risk | Mitigation |
603
+ | --- | --- |
604
+ | Disk: Wan 5B = ~10 GB; Hunyuan ≈ 60 GB | Document in `/video setup` plan output; never trigger Hunyuan pull on a fresh install — keep it behind explicit selection. |
605
+ | Diffusers pipeline class drift between versions | Lock `diffusers>=0.32` in `DIFFUSERS_VIDEO_PACKAGES`; surface clear "update diffusers" failure note in `formatVideoFailure`. |
606
+ | ffmpeg missing for thumbnail | Fall back to `imageio` in the runner; bridge gracefully if both fail (skip preview, send video without ASCII). |
607
+ | Public spam (video is expensive) | Dedicated `video-generation` quota (≤ 2/hour/user); Telegram message acknowledges "this may take 2-5 minutes" before kickoff. |
608
+ | User runs `/video` with no GPU | `rateVideoPresetForHardware` returns "too heavy" / red icon; `prewarmVideoModel` refuses if `specs.gpuVramGB === 0` and points to cloud. |
609
+ | Aspect ratio not divisible by required factor | Runner snaps to multiple-of-32 for LTX, multiple-of-16 elsewhere; emit a `_progress("setup", "snapping ...")` line so the user sees the adjustment. |
610
+
611
+ ---
612
+
613
+ ## 5. Suggested implementation order
614
+
615
+ 1. **Sana primary swap** in `image-generate.ts` (one file, no new tool surface). Build, smoke `/image "test"`.
616
+ 2. **Skeleton video tool** in `packages/execution/src/tools/video-generate.ts` — types, preset registry, runner heredoc, no Tool class yet. `tsc` must compile.
617
+ 3. **`VideoGenerateTool` class** with `execute({ action: "list" })` only. Wire export. Build.
618
+ 4. **CogVideoX-2B path** — the smallest model — to validate the full Diffusers stack: prewarm + generate + thumbnail + sidecar. This is the equivalent of "Phase 1 smoke test" from the reference doc.
619
+ 5. **Wan2.2 TI2V 5B path** — verify T2V and I2V on a 24 GB-class GPU (or note CPU-offload expectation).
620
+ 6. **TUI surface** — dispatcher case, `handleVideoCommand`, menu, list, prewarm, ASCII preview hook.
621
+ 7. **Command registry** entries.
622
+ 8. **Settings interface** entries.
623
+ 9. **Telegram admin DM** wiring — add to `adminTools`, defaults helper, quota regex.
624
+ 10. **Telegram public/group** wiring — `buildTelegramCreativeTools` signature + factory body + marker regex.
625
+ 11. **Outbound sidecar pickup** for `sendVideo`.
626
+ 12. **License/gating warnings** for LTX + Hunyuan.
627
+ 13. **Tests** — preset shape, ladder, parseImageCommand reused for video flags.
628
+ 14. **Docs** — README + plan-link.
629
+
630
+ Each step is independently shippable; do not bundle 1+2+3 into one commit.
631
+
632
+ ---
633
+
634
+ ## 6. File-by-file changelist
635
+
636
+ | File | Change | Owner |
637
+ | --- | --- | --- |
638
+ | [packages/execution/src/tools/image-generate.ts](packages/execution/src/tools/image-generate.ts) | Promote Sana 1.5 1.6B to default; add 4.8B/2K/4K presets; patch `_pipeline_class`; update description; update ladder. | Sana swap |
639
+ | [packages/execution/src/tools/video-generate.ts](packages/execution/src/tools/video-generate.ts) **(new)** | Full `VideoGenerateTool` class + presets + runner template + helpers. | Video |
640
+ | [packages/execution/src/index.ts](packages/execution/src/index.ts) | Re-export Video* surface. | Video |
641
+ | [packages/cli/src/tui/commands.ts](packages/cli/src/tui/commands.ts) | `case "video"`, `handleVideoCommand`, `showVideoModelsMenu`, `renderVideoModelList`, `prewarmVideoModel`, `formatVideoGenerationProgress`, `rateVideoPresetForHardware`, `videoModelDiskStats`, `deleteVideoModelWeights`, `extractSavedVideoPath`. | Video |
642
+ | [packages/cli/src/tui/command-registry.ts](packages/cli/src/tui/command-registry.ts) | `/video` signatures; `CATEGORY_OVERRIDES.video = "media"`; add `video` to `USER_ONLY` + `NETWORKED`. | Video |
643
+ | [packages/cli/src/tui/omnius-directory.ts](packages/cli/src/tui/omnius-directory.ts) | `videoModel`/`videoBackend`/`videoKind` on `OmniusSettings`. | Video |
644
+ | [packages/cli/src/tui/telegram-bridge.ts](packages/cli/src/tui/telegram-bridge.ts) | Import; admin tool list; `videoGenerationDefaultsForRepo`; quota regex; outbound sidecar pickup; system prompt phrasing; new quota class. | Video |
645
+ | [packages/cli/src/tui/telegram-creative-tools.ts](packages/cli/src/tui/telegram-creative-tools.ts) | Import; signature; factory body; scoped-wrapper regex; marker regex. | Video |
646
+ | [packages/cli/tests/](packages/cli/tests/) | New `video-generate.preset.test.ts`; extend image preset test if shared registry helper introduced. | Video |
647
+ | [README.md](README.md) | One-line `/video` doc near `/image`. | Video |
648
+ | [docs/sana-and-video-generation-integration-plan.md](docs/sana-and-video-generation-integration-plan.md) **(this doc)** | Reference. | — |
649
+
650
+ ---
651
+
652
+ ## 7. Open decisions for the user
653
+
654
+ 1. **Default video model**: Wan2.2 TI2V 5B (recommended — 24GB-class, handles both T2V and I2V, Apache 2.0). Alternate: CogVideoX-5B if 16GB target is preferred for the broader install base.
655
+ 2. **Whether to also expose ComfyUI runtime now**: this plan defers it to a follow-up. Wire the type but not the backend.
656
+ 3. **Public Telegram quota for video**: suggested 2/hour/user. Configurable.
657
+ 4. **Whether the new tool should also generate **audio-with-video** (Wan2.2 S2V / LTX-2.3)**: out of scope for v1; document as a Phase 4 follow-up.
658
+
659
+ ---
660
+
661
+ ## 8. Reference excerpts (verified)
662
+
663
+ - Wan2.2 TI2V 5B Diffusers: `WanPipeline` + `AutoencoderKLWan` subfolder VAE; 50 steps, CFG 5.0, 121 frames @ 24fps, 1280×704; min 24GB; Apache 2.0. (HF `Wan-AI/Wan2.2-TI2V-5B-Diffusers`)
664
+ - CogVideoX-5B: `CogVideoXPipeline`; 50 steps, CFG 6.0, 49 frames @ 8fps, 720×480; min ~5GB with `enable_model_cpu_offload`. (HF `zai-org/CogVideoX-5b`)
665
+ - Mochi 1 Preview: `MochiPipeline`; variant `bf16`; 64 steps, CFG 4.5 schedule, 84 frames @ 30fps, 848×480; min 22GB with offload; Apache 2.0. (HF `genmo/mochi-1-preview`)
666
+ - LTX-Video: `LTXPipeline` / `LTXConditionPipeline`; 30 steps; frames divisible by 8+1; LTX Open-Weights non-commercial. (HF `Lightricks/LTX-Video`)
667
+ - Sana 1.5 1.6B: `SanaPipeline`; 20 steps, CFG 4.5, 1024×1024, bfloat16; text encoder `google/gemma-2-2b-it`; NSCL v2-custom + Gemma terms; not gated. (HF `Efficient-Large-Model/SANA1.5_1.6B_1024px_diffusers`, <https://github.com/NVlabs/Sana>)
668
+
669
+ ---
670
+
671
+ ## 9. Quick map for the downstream agent (line-by-line cheat sheet)
672
+
673
+ ```text
674
+ NEW packages/execution/src/tools/video-generate.ts (full file, ~1500 LOC mirroring image-generate.ts)
675
+ EDIT packages/execution/src/tools/image-generate.ts
676
+ L59 default = "Efficient-Large-Model/SANA1.5_1.6B_1024px_diffusers"
677
+ L147 prepend 4 Sana 1.5 preset entries (1.6B / 4.8B / 1600M MultiLing / 2Kpx)
678
+ L488 ladder: place SANA1.5_4.8B then SANA1.5_1.6B above FLUX entries
679
+ L529 _pipeline_class: add Sana branch
680
+ L540 _large_model: enable offload for 4.8B / 2Kpx / 4Kpx
681
+ L1209 description: swap SDXL-Turbo for Sana 1.5 1.6B
682
+ EDIT packages/execution/src/index.ts (add Video* re-exports near L165-197)
683
+ EDIT packages/cli/src/tui/commands.ts
684
+ L1590 add `case "video"`
685
+ L8742 introduce ParsedVideoCommand parity OR reuse ParsedImageCommand
686
+ L9054 add showVideoModelsMenu mirror
687
+ L9147 add prewarmVideoModel mirror
688
+ L9169 add handleVideoCommand mirror
689
+ EDIT packages/cli/src/tui/command-registry.ts
690
+ L147 insert /video signatures
691
+ L344 add video: "media"
692
+ L506 add "video" to USER_ONLY
693
+ L555 add "video" to NETWORKED
694
+ EDIT packages/cli/src/tui/omnius-directory.ts
695
+ L228 append videoModel/videoBackend/videoKind
696
+ EDIT packages/cli/src/tui/telegram-bridge.ts
697
+ L85 add VideoGenerateTool import
698
+ L6165 add new VideoGenerateTool(repoRoot, videoDefaults)
699
+ L6205 pass videoDefaults to buildTelegramCreativeTools
700
+ L6249 add generate_video to quota regex (or new "video-generation" kind)
701
+ L7346 add videoGenerationDefaultsForRepo helper
702
+ L8087 broaden generated-media sidecar pickup beyond images
703
+ L5555 system-prompt note about generate_video
704
+ EDIT packages/cli/src/tui/telegram-creative-tools.ts
705
+ L24 add VideoGenerateTool / VideoGenerateToolDefaults imports
706
+ L128 add "Video generated" to marker regex
707
+ L139 add videoDefaults to factory signature
708
+ L152 add scopedTool(new VideoGenerateTool(...))
709
+ L174 add generate_video to the generation-routing regex
710
+ ```
711
+
712
+ End of plan.