Files
pftom 976a6eadf2 feat(media): add image/video/audio project kinds via od media generate
Introduce non-web media surfaces (image, video, audio) as first-class
project kinds. The unifying contract is "skill workflow + project
metadata tell the agent WHAT to make; one shell command — od media
generate — is HOW bytes are produced", so any code-agent CLI with
shell access can drive it without bespoke tools.

- Frontend: New Project panel gains Image/Video/Audio tabs with model
  picker, aspect/length/duration controls, and audio kind/voice
  selection. Examples and Design Systems tabs gain layered sections.
  FileViewer renders the generated image/video/audio files.
- Shared registry: src/media/models.ts is the single source of truth
  for image/video/audio model IDs, aspects, and defaults — consumed
  by the picker AND the daemon dispatcher.
- Prompts: media-contract.ts is pinned LAST in the system prompt for
  media surfaces so its hard rules (call od media generate, don't
  emit binary in <artifact>, allowed model IDs) win over softer
  earlier wording.
- Daemon: new media.js dispatcher + media-models.js JSON view of the
  registry; cli.js gets the `od media generate` subcommand wired up
  via server.js / projects.js so the daemon writes files back into
  the project dir.
- Skills: audio-jingle, image-poster, video-shortform seed examples
  for the three surfaces.

Made-with: Cursor
2026-04-28 22:41:14 +08:00

122 lines
3.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: audio-jingle
description: |
Audio generation skill — jingles, beds, voiceover, and sound effects.
Routes music requests to Suno V5 / Udio / Lyria, speech to MiniMax
TTS / FishAudio / ElevenLabs V3, and SFX to ElevenLabs SFX or
AudioCraft. Output is one MP3/WAV file saved to the project folder.
triggers:
- "music"
- "jingle"
- "bed"
- "voiceover"
- "tts"
- "sound effect"
- "音乐"
- "配音"
- "音效"
od:
mode: audio
surface: audio
scenario: marketing
preview:
type: html
entry: example.html
design_system:
requires: false
example_prompt: |
A 30-second upbeat indie-pop jingle for a coffee shop launch — warm
electric piano lead, brushed drums, gentle bass, a single sun-soaked
"ahhh" choir on the chorus. No vocals. Loop-friendly tail.
---
# Audio Jingle Skill
Three sub-modes. The active project's `audioKind` decides which one
runs:
| `audioKind` | Models we route to | Plan focus |
|---|---|---|
| `music` | Suno V5 (default), Udio, Lyria 2 | genre + tempo + instrumentation |
| `speech` | MiniMax TTS (default), Fish, ElevenLabs V3 | script + voice + pacing |
| `sfx` | ElevenLabs SFX (default), AudioCraft | texture + impact + duration |
## Resource map
```
audio-jingle/
├── SKILL.md
└── example.html
```
## Workflow
### Step 0 — Read the project metadata
`audioKind`, `audioModel`, `audioDuration` (seconds), and (for speech)
`voice`. Branch by `audioKind` and use the values verbatim — no
clarifying form unless something is marked `(unknown — ask)`.
### Step 1 — Plan
**Music**
- Genre + reference artists (1-2)
- Tempo (BPM) + key
- Instrumentation (3-5 instruments max)
- Vocals: yes / no / hummed / choir
- Mood arc (intro → chorus → outro)
**Speech**
- Script (final, not draft — TTS runs verbatim)
- Voice description (warmth, age, accent, pacing)
- Pronunciation hints for proper nouns / acronyms
**SFX**
- Texture (impact / whoosh / ambience / foley)
- Duration + envelope (sharp attack vs. gentle swell)
- Layering note (single hit vs. stacked)
State the plan in 2-3 sentences before dispatching.
### Step 2 — Compose the prompt
Use the format the upstream model prefers. Bind `audioDuration` to the
API parameter directly; never put "make it 30 seconds" in prose.
### Step 3 — Dispatch via the media contract
Use the unified dispatcher — do **not** call provider APIs by hand:
```bash
node "$OD_BIN" media generate \
--project "$OD_PROJECT_ID" \
--surface audio \
--audio-kind "<music|speech|sfx>" \
--model "<audioModel from metadata>" \
--duration <audioDuration seconds> \
--voice "<voice (speech only)>" \
--output "<short-slug>-<duration>s.mp3" \
--prompt "<assembled prompt from Step 2 — for speech, the literal script>"
```
The command prints one line of JSON: `{"file": {"name": "...", ...}}`.
The bytes land in the project; the FileViewer renders the audio
transport controls automatically.
### Step 4 — Hand off
Reply with: plan summary, the filename returned by the dispatcher, and
one sentence on what to try if the user wants a variation (e.g. "swap
tempo from 92 to 108 BPM" rather than "make it different").
## Hard rules
- TTS runs your script **literally**. Proof it before dispatching —
even one stray comma changes the cadence.
- Music: under 30s = single section; 3090s = intro + body; 90s+ =
full arc. Don't try to fit a 3-act song into 15 seconds.
- SFX: prefer one well-described layer over a paragraph of "make it
cool" — generators reward specific texture words.
- Save the file every turn. The audio viewer shows transport controls
the moment the file lands.