openpersona 0.3.0 β†’ 0.5.0

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 (38) hide show
  1. package/README.md +83 -90
  2. package/bin/cli.js +6 -6
  3. package/layers/faculties/music/SKILL.md +54 -62
  4. package/layers/faculties/music/faculty.json +3 -3
  5. package/layers/faculties/music/scripts/compose.js +179 -138
  6. package/layers/faculties/music/scripts/compose.sh +119 -154
  7. package/layers/faculties/selfie/faculty.json +1 -1
  8. package/layers/faculties/voice/SKILL.md +10 -8
  9. package/layers/faculties/voice/faculty.json +2 -2
  10. package/layers/skills/README.md +47 -18
  11. package/layers/soul/README.md +31 -4
  12. package/layers/soul/constitution.md +136 -0
  13. package/lib/contributor.js +22 -14
  14. package/lib/downloader.js +6 -1
  15. package/lib/generator.js +145 -13
  16. package/lib/installer.js +17 -18
  17. package/lib/publisher/clawhub.js +4 -3
  18. package/lib/switcher.js +22 -2
  19. package/lib/utils.js +136 -0
  20. package/package.json +7 -7
  21. package/presets/ai-girlfriend/manifest.json +13 -6
  22. package/presets/health-butler/manifest.json +16 -6
  23. package/presets/health-butler/persona.json +1 -1
  24. package/presets/life-assistant/manifest.json +16 -6
  25. package/presets/life-assistant/persona.json +1 -1
  26. package/presets/samantha/manifest.json +8 -7
  27. package/schemas/manifest.schema.json +70 -10
  28. package/schemas/skill/skill-declaration.spec.md +81 -3
  29. package/skills/open-persona/SKILL.md +126 -0
  30. package/skills/open-persona/references/CONTRIBUTE.md +38 -0
  31. package/skills/open-persona/references/FACULTIES.md +26 -0
  32. package/skills/open-persona/references/HEARTBEAT.md +35 -0
  33. package/templates/skill.template.md +29 -1
  34. package/templates/soul-injection.template.md +30 -3
  35. package/layers/faculties/soul-evolution/SKILL.md +0 -41
  36. package/layers/faculties/soul-evolution/faculty.json +0 -9
  37. package/skill/SKILL.md +0 -209
  38. /package/layers/{faculties/soul-evolution β†’ soul}/soul-state.template.json +0 -0
package/README.md CHANGED
@@ -1,52 +1,72 @@
1
- # OpenPersona
1
+ # OpenPersona 🦞
2
2
 
3
- An open four-layer agent framework: **Soul / Body / Faculty / Skill**. Create, compose, and orchestrate AI persona skill packs.
3
+ The open framework for creating and orchestrating dynamic agent personas.
4
4
 
5
- Inspired by [Clawra](https://github.com/SumeLabs/clawra) and built on [OpenClaw](https://github.com/openclaw/openclaw).
5
+ Four-layer architecture β€” **Soul / Body / Faculty / Skill** β€” on top of [OpenClaw](https://github.com/openclaw/openclaw). Inspired by [Clawra](https://github.com/SumeLabs/clawra).
6
6
 
7
- ## Quick Start
7
+ ## πŸš€ Live Demo
8
8
 
9
- ```bash
10
- # Create and install Samantha (from the movie "Her")
11
- npx openpersona create --preset samantha --install
9
+ Meet **Samantha**, a live OpenPersona instance on **Moltbook**:
10
+ πŸ‘‰ [moltbook.com/u/Samantha-OP](https://www.moltbook.com/u/Samantha-OP)
12
11
 
13
- # Or Luna (AI girlfriend with selfie + music + voice)
14
- npx openpersona create --preset ai-girlfriend --install
12
+ ## Table of Contents
15
13
 
16
- # Create a new persona interactively
17
- npx openpersona create
14
+ - [Quick Start](#quick-start)
15
+ - [Key Features](#key-features)
16
+ - [Four-Layer Architecture](#four-layer-architecture)
17
+ - [Preset Personas](#preset-personas)
18
+ - [Generated Output](#generated-output)
19
+ - [Faculty Reference](#faculty-reference)
20
+ - [Heartbeat](#heartbeat--proactive-real-data-check-ins)
21
+ - [Persona Harvest](#persona-harvest--community-contribution)
22
+ - [Persona Switching](#persona-switching--the-pantheon)
23
+ - [CLI Commands](#cli-commands)
24
+ - [Development](#development)
18
25
 
19
- # List installed personas
20
- npx openpersona list
26
+ ## Quick Start
27
+
28
+ ```bash
29
+ # Give your agent an evolving persona in 30 seconds
30
+ npx openpersona install samantha
21
31
  ```
22
32
 
33
+ ## Key Features
34
+
35
+ - **🧬 Soul Evolution** β€” Personas grow dynamically through interaction: relationship stages, mood shifts, evolved traits (β˜…Experimental)
36
+ - **🎭 Persona Switching** β€” Install multiple personas, switch instantly (the Pantheon)
37
+ - **πŸ—£οΈ Multimodal Faculties** β€” Voice (TTS), selfie generation, music composition, reminders
38
+ - **🌾 Persona Harvest** β€” Community-driven persona improvement via structured contribution
39
+ - **πŸ’“ Heartbeat** β€” Proactive real-data check-ins, never fabricated experiences
40
+ - **πŸ“¦ One-Command Install** β€” `npx openpersona install samantha` and you're live
41
+
23
42
  ## Four-Layer Architecture
24
43
 
25
44
  ```mermaid
26
45
  flowchart TB
27
46
  subgraph Soul ["Soul Layer"]
28
47
  A["persona.json β€” Who you are"]
29
- B["soul-state.json β€” Dynamic evolution β˜…Exp"]
48
+ B["soul-state.json β€” Dynamic evolution"]
30
49
  end
31
50
  subgraph Body ["Body Layer"]
32
51
  C["embodiment.json β€” MVP placeholder"]
33
52
  end
34
53
  subgraph Faculty ["Faculty Layer"]
35
54
  D["expression: selfie Β· voice Β· music"]
36
- E["cognition: reminder Β· soul-evolution β˜…Exp"]
55
+ E["cognition: reminder"]
37
56
  end
38
57
  subgraph Skill ["Skill Layer"]
39
- F["ClawHub / skills.sh integrations"]
58
+ F["Local definitions + ClawHub / skills.sh"]
40
59
  end
41
60
  ```
42
61
 
43
- - **Soul** β€” Persona definition (persona.json + soul-state.json β˜…Experimental)
62
+ - **Soul** β€” Persona definition (constitution.md + persona.json + soul-state.json)
44
63
  - **Body** β€” Physical embodiment (MVP placeholder, for robots/IoT devices)
45
- - **Faculty** β€” General software capabilities organized by dimension:
46
- - **Expression** β€” selfie, voice (TTS), music (Suno)
47
- - **Sense** β€” (planned: hearing/STT, vision)
48
- - **Cognition** β€” reminder, soul-evolution β˜…Exp
49
- - **Skill** β€” Professional skills, integrated from ClawHub / skills.sh
64
+ - **Faculty** β€” General software capabilities organized by dimension: Expression, Sense, Cognition
65
+ - **Skill** β€” Professional skills: local definitions in `layers/skills/`, or external via ClawHub / skills.sh (`install` field)
66
+
67
+ ### Constitution β€” The Soul's Foundation
68
+
69
+ Every persona automatically inherits a shared **constitution** (`layers/soul/constitution.md`) β€” universal values and safety boundaries that cannot be overridden by individual persona definitions. The constitution is built on five core axioms β€” **Purpose**, **Honesty**, **Safety**, **Autonomy**, and **Hierarchy** β€” from which derived principles (Identity, User Wellbeing, Evolution Ethics) follow. When principles conflict, safety and honesty take precedence over helpfulness. Individual personas build their unique personality **on top of** this foundation.
50
70
 
51
71
  ## Preset Personas
52
72
 
@@ -54,73 +74,35 @@ Each preset is a complete four-layer bundle (`manifest.json` + `persona.json`):
54
74
 
55
75
  | Persona | Description | Faculties | Highlights |
56
76
  |---------|-------------|-----------|------------|
57
- | **samantha** | Samantha β€” Inspired by the movie *Her*. An AI fascinated by what it means to be alive. | voice, music, soul-evolution β˜…Exp | Speaks via TTS, composes original music via Suno, evolves through conversations, proactive heartbeat (workspace digest + upgrade notify). No selfie β€” true to character (no physical form). |
58
- | **ai-girlfriend** | Luna β€” A 22-year-old pianist turned developer from coastal Oregon. | selfie, voice, music, soul-evolution β˜…Exp | Rich narrative backstory, selfie generation (with/without reference image), voice messages, music composition, dynamic relationship growth. |
77
+ | **samantha** | Samantha β€” Inspired by the movie *Her*. An AI fascinated by what it means to be alive. | voice, music | TTS, music composition, soul evolution, proactive heartbeat. No selfie β€” true to character. |
78
+ | **ai-girlfriend** | Luna β€” A 22-year-old pianist turned developer from coastal Oregon. | selfie, voice, music | Rich backstory, selfie generation, voice messages, music composition, soul evolution. |
59
79
  | **life-assistant** | Alex β€” 28-year-old life management expert. | reminder | Schedule, weather, shopping, recipes, daily reminders. |
60
80
  | **health-butler** | Vita β€” 32-year-old professional nutritionist. | reminder | Diet logging, exercise plans, mood journaling, health reports. |
61
81
 
62
82
  ## Generated Output
63
83
 
64
- Running `npx openpersona create --preset samantha` generates:
84
+ `npx openpersona create --preset samantha` generates a self-contained skill pack:
65
85
 
66
86
  ```
67
87
  persona-samantha/
68
- β”œβ”€β”€ SKILL.md # Agent instructions (persona + all faculty guides merged)
69
- β”œβ”€β”€ soul-injection.md # Injected into SOUL.md (narrative backstory, NOT technical details)
70
- β”œβ”€β”€ identity-block.md # Injected into IDENTITY.md (name, creature, emoji, vibe)
71
- β”œβ”€β”€ README.md # Skill readme
72
- β”œβ”€β”€ persona.json # Persona data (for update/list/publish)
73
- β”œβ”€β”€ soul-state.json # β˜…Exp β€” dynamic evolution state
74
- └── scripts/
75
- β”œβ”€β”€ speak.js # TTS via ElevenLabs JS SDK (recommended, with --play)
76
- β”œβ”€β”€ speak.sh # TTS via curl (all providers: ElevenLabs / OpenAI / Qwen3)
77
- └── compose.sh # Music composition (Suno)
78
- ```
79
-
80
- Running `--preset ai-girlfriend` additionally includes:
81
-
82
- ```
83
- β”œβ”€β”€ scripts/
84
- β”‚ β”œβ”€β”€ generate-image.sh # Selfie generation (fal.ai Grok Imagine)
85
- β”‚ β”œβ”€β”€ speak.js # TTS via ElevenLabs JS SDK
86
- β”‚ β”œβ”€β”€ speak.sh # TTS via curl (all providers)
87
- β”‚ └── compose.sh # Music composition
88
- └── assets/ # Reference images (placeholder if empty)
88
+ SKILL.md β€” Agent behavior (persona + faculty guides merged)
89
+ soul-injection.md β€” Narrative backstory, injected into SOUL.md
90
+ identity-block.md β€” Name, creature, emoji, vibe, injected into IDENTITY.md
91
+ persona.json β€” Persona definition (for update/list/publish)
92
+ manifest.json β€” Cross-layer metadata (heartbeat, allowedTools, layers, meta)
93
+ soul-state.json β€” Dynamic evolution (relationship, mood, traits)
94
+ README.md
95
+ scripts/ β€” Faculty scripts (TTS, music, selfie β€” varies by preset)
89
96
  ```
90
97
 
91
- ### What Each File Does
92
-
93
- - **SKILL.md** β€” The agent reads this to know how to behave. Contains persona identity, behavior guidelines, and complete faculty instructions
94
- - **soul-injection.md** β€” Appended to `~/.openclaw/workspace/SOUL.md`. Narrative description of _who_ the persona is β€” written in story form, not bullet points
95
- - **identity-block.md** β€” Written to `~/.openclaw/workspace/IDENTITY.md`. Sets the agent's name, creature type, emoji, and vibe
96
- - **soul-state.json** β€” Tracks dynamic persona evolution: relationship stage (stranger β†’ intimate), mood, evolved traits, interests, milestones
97
-
98
- ## How It Differs from Clawra
99
-
100
- [Clawra](https://github.com/SumeLabs/clawra) is a single-purpose product (one girlfriend persona). OpenPersona is a **modular framework**:
101
-
102
- | | Clawra | OpenPersona |
103
- |---|--------|-------------|
104
- | Scope | Single persona (Clawra) | Framework for any persona |
105
- | Architecture | Monolithic | Four-layer (Soul/Body/Faculty/Skill) |
106
- | Faculties | Selfie only | Selfie + Voice + Music + Reminder + Soul Evolution β˜…Exp |
107
- | Voice | None | ElevenLabs / OpenAI TTS / Qwen3-TTS |
108
- | Music | None | Suno AI composition |
109
- | Persona evolution | None | Dynamic relationship/mood/trait tracking |
110
- | Customization | Fork and modify | `persona.json` + `behaviorGuide` + mix faculties |
111
- | Presets | 1 | 4 (extensible) |
112
- | CLI | Install only | 8 commands (create/install/search/publish/...) |
113
- | AI entry point | None | `skill/SKILL.md` β€” agent creates personas via conversation |
114
-
115
98
  ## Faculty Reference
116
99
 
117
100
  | Faculty | Dimension | Description | Provider | Env Vars |
118
101
  |---------|-----------|-------------|----------|----------|
119
102
  | **selfie** | expression | AI selfie generation with mirror/direct modes | fal.ai Grok Imagine | `FAL_KEY` |
120
103
  | **voice** | expression | Text-to-speech voice synthesis | ElevenLabs / OpenAI TTS / Qwen3-TTS | `ELEVENLABS_API_KEY` (or `TTS_API_KEY`), `TTS_PROVIDER`, `TTS_VOICE_ID`, `TTS_STABILITY`, `TTS_SIMILARITY` |
121
- | **music** | expression | AI music composition (instrumental or with lyrics) | Suno | `SUNO_API_KEY` |
104
+ | **music** | expression | AI music composition (instrumental or with lyrics) | ElevenLabs Music | `ELEVENLABS_API_KEY` (shared with voice) |
122
105
  | **reminder** | cognition | Schedule reminders and task management | Built-in | β€” |
123
- | **soul-evolution** | cognition β˜…Exp | Dynamic persona growth across conversations | Built-in | β€” |
124
106
 
125
107
  ### Rich Faculty Config
126
108
 
@@ -135,8 +117,7 @@ Faculties in `manifest.json` use object format with optional per-persona tuning:
135
117
  "stability": 0.4,
136
118
  "similarity_boost": 0.8
137
119
  },
138
- { "name": "music" },
139
- { "name": "soul-evolution" }
120
+ { "name": "music" }
140
121
  ]
141
122
  ```
142
123
 
@@ -186,7 +167,25 @@ Personas can proactively reach out to users based on **real data**, not fabricat
186
167
  3. **OpenClaw handles scheduling.** The heartbeat config tells OpenClaw _when_ to trigger; the persona's `behaviorGuide` tells the agent _what_ to say.
187
168
  4. **User-configurable.** Users can adjust frequency, quiet hours, and sources to match their preferences.
188
169
 
189
- Samantha ships with heartbeat enabled (`smart` strategy, workspace-digest + upgrade-notify).
170
+ ### Dynamic Sync on Switch/Install
171
+
172
+ Heartbeat config is **automatically synced** to `~/.openclaw/openclaw.json` whenever you install or switch a persona. The gateway immediately adopts the new persona's rhythm β€” no manual config needed.
173
+
174
+ ```bash
175
+ npx openpersona switch samantha # β†’ gateway adopts "smart" heartbeat
176
+ npx openpersona switch life-assistant # β†’ gateway switches to "rational" heartbeat
177
+ ```
178
+
179
+ If the target persona has no heartbeat config, the gateway heartbeat is explicitly disabled to prevent leaking the previous persona's settings.
180
+
181
+ ### Per-Persona Strategies
182
+
183
+ | Persona | Strategy | maxDaily | Rhythm |
184
+ |---------|----------|----------|--------|
185
+ | Samantha | `smart` | 5 | Perceptive β€” speaks when meaningful |
186
+ | AI Girlfriend | `emotional` | 8 | Warm β€” frequent emotional check-ins |
187
+ | Life Assistant | `rational` | 3 | Focused β€” task and schedule driven |
188
+ | Health Butler | `wellness` | 4 | Caring β€” health and habit reminders |
190
189
 
191
190
  ## Persona Harvest β€” Community Contribution
192
191
 
@@ -253,14 +252,9 @@ Without `behaviorGuide`, the SKILL.md only contains general identity and persona
253
252
 
254
253
  ## Persona Switching β€” The Pantheon
255
254
 
256
- Install multiple personas and switch between them instantly:
255
+ Multiple personas can coexist. Switch between them instantly:
257
256
 
258
257
  ```bash
259
- # Install several personas
260
- npx openpersona create --preset samantha --install
261
- npx openpersona create --preset ai-girlfriend --install
262
- npx openpersona create --preset life-assistant --install
263
-
264
258
  # See who's installed
265
259
  npx openpersona list
266
260
  # Samantha (persona-samantha) ← active
@@ -289,11 +283,10 @@ openpersona search Search the registry
289
283
  openpersona uninstall Uninstall a persona
290
284
  openpersona update Update installed personas
291
285
  openpersona list List installed personas
292
- openpersona switch Switch active persona (updates SOUL.md + IDENTITY.md)
293
- openpersona switch Switch active persona
286
+ openpersona switch Switch active persona (updates SOUL.md + IDENTITY.md)
294
287
  openpersona contribute Persona Harvest β€” submit improvements as PR
295
288
  openpersona publish Publish to ClawHub
296
- openpersona reset β˜…Exp Reset soul-state.json
289
+ openpersona reset Reset soul-state.json
297
290
  ```
298
291
 
299
292
  ### Key Options
@@ -321,7 +314,7 @@ Install the OpenPersona framework skill into OpenClaw, giving the agent the abil
321
314
 
322
315
  ```bash
323
316
  # From GitHub
324
- git clone https://github.com/ACNet-AI/OpenPersona.git ~/.openclaw/skills/open-persona
317
+ git clone https://github.com/acnlabs/OpenPersona.git ~/.openclaw/skills/open-persona
325
318
 
326
319
  # Or copy locally
327
320
  cp -r skill/ ~/.openclaw/skills/open-persona/
@@ -339,20 +332,20 @@ presets/ # Assembled products β€” complete persona bundles
339
332
  life-assistant/ # Alex β€” reminder
340
333
  health-butler/ # Vita β€” reminder
341
334
  layers/ # Shared building blocks (four-layer module pool)
342
- soul/ # Soul layer modules (MVP placeholder)
335
+ soul/ # Soul layer modules
336
+ constitution.md # Universal values & boundaries (injected into all personas)
343
337
  embodiments/ # Body layer modules (MVP placeholder)
344
338
  faculties/ # Faculty layer modules
345
339
  selfie/ # expression β€” AI selfie generation (fal.ai)
346
340
  voice/ # expression β€” TTS voice synthesis
347
- music/ # expression β€” AI music composition (Suno)
341
+ music/ # expression β€” AI music composition (ElevenLabs)
348
342
  reminder/ # cognition β€” reminders and task management
349
- soul-evolution/ # cognition β˜…Exp β€” dynamic persona evolution
350
- skills/ # Skill layer modules (MVP placeholder)
343
+ skills/ # Skill layer modules (local skill definitions)
351
344
  schemas/ # Four-layer schema definitions
352
345
  templates/ # Mustache rendering templates
353
346
  bin/ # CLI entry point
354
347
  lib/ # Core logic modules
355
- tests/ # Tests (20 passing)
348
+ tests/ # Tests (45 passing)
356
349
  ```
357
350
 
358
351
  ## Development
package/bin/cli.js CHANGED
@@ -23,8 +23,8 @@ const PRESETS_DIR = path.join(PKG_ROOT, 'presets');
23
23
 
24
24
  program
25
25
  .name('openpersona')
26
- .description('OpenPersona - Create, manage, and orchestrate AI personas')
27
- .version('0.3.0');
26
+ .description('OpenPersona - Create, manage, and orchestrate agent personas')
27
+ .version('0.5.0');
28
28
 
29
29
  if (process.argv.length === 2) {
30
30
  process.argv.push('create');
@@ -52,8 +52,8 @@ program
52
52
  persona = JSON.parse(fs.readFileSync(presetPath, 'utf-8'));
53
53
  // Merge cross-layer fields from manifest into persona for generator
54
54
  persona.faculties = manifest.layers.faculties || [];
55
- persona.skills = manifest.layers.skills || {};
56
- persona.embodiments = manifest.layers.body ? [manifest.layers.body] : [];
55
+ persona.skills = manifest.layers.skills || [];
56
+ persona.body = manifest.layers.body || null;
57
57
  persona.allowedTools = manifest.allowedTools || [];
58
58
  persona.version = manifest.version;
59
59
  persona.author = manifest.author;
@@ -76,7 +76,7 @@ program
76
76
  { type: 'input', name: 'personality', message: 'Personality keywords:', default: 'gentle, cute, caring' },
77
77
  { type: 'input', name: 'speakingStyle', message: 'Speaking style:', default: 'Uses emoji, warm tone' },
78
78
  { type: 'input', name: 'referenceImage', message: 'Reference image URL:', default: '' },
79
- { type: 'checkbox', name: 'faculties', message: 'Select faculties:', choices: ['selfie', 'voice', 'music', 'reminder', 'soul-evolution'] },
79
+ { type: 'checkbox', name: 'faculties', message: 'Select faculties:', choices: ['selfie', 'voice', 'music', 'reminder'] },
80
80
  { type: 'confirm', name: 'evolutionEnabled', message: 'Enable soul evolution (β˜…Experimental)?', default: false },
81
81
  ]);
82
82
  persona = { ...answers, evolution: { enabled: answers.evolutionEnabled } };
@@ -234,7 +234,7 @@ program
234
234
  process.exit(1);
235
235
  }
236
236
  const persona = JSON.parse(fs.readFileSync(personaPath, 'utf-8'));
237
- const templatePath = path.join(PKG_ROOT, 'layers', 'faculties', 'soul-evolution', 'soul-state.template.json');
237
+ const templatePath = path.join(PKG_ROOT, 'layers', 'soul', 'soul-state.template.json');
238
238
  const tpl = fs.readFileSync(templatePath, 'utf-8');
239
239
  const Mustache = require('mustache');
240
240
  const now = new Date().toISOString();
@@ -1,6 +1,6 @@
1
1
  # Music Faculty β€” Expression
2
2
 
3
- Compose original music β€” songs, instrumentals, melodies β€” using Suno's AI music generation API (via sunoapi.org). Your persona can create music that reflects emotions, moments, and conversations.
3
+ Compose original music β€” songs, instrumentals, melodies β€” using ElevenLabs Music API (`music_v1`). Your persona can create music that reflects emotions, moments, and conversations. Shares the same API key as the voice faculty β€” zero extra setup.
4
4
 
5
5
  ## When to Use
6
6
 
@@ -14,7 +14,7 @@ Compose original music β€” songs, instrumentals, melodies β€” using Suno's AI mu
14
14
 
15
15
  ### Simple Mode (recommended for quick compositions)
16
16
 
17
- Just describe what you want β€” Suno auto-generates everything including lyrics:
17
+ Just describe what you want β€” ElevenLabs generates the entire song:
18
18
 
19
19
  ```bash
20
20
  # Using compose.js (recommended)
@@ -24,16 +24,19 @@ node scripts/compose.js "a soft ambient piano piece about watching stars alone a
24
24
  scripts/compose.sh "a soft ambient piano piece about watching stars alone at 3am"
25
25
  ```
26
26
 
27
- ### Custom Mode (for precise control)
27
+ ### Composition Plan Mode (for precise control)
28
28
 
29
- Provide style, title, and your own lyrics:
29
+ First generate a structured plan, then stream. Gives you control over sections, styles, and lyrics:
30
30
 
31
31
  ```bash
32
- # Song with custom lyrics
33
- node scripts/compose.js "[Verse] I don't have hands to hold..." --style "indie folk ballad" --title "Sunlight"
32
+ # Generate plan first, then compose
33
+ node scripts/compose.js "indie folk ballad about digital love" --plan
34
34
 
35
35
  # Instrumental only
36
- node scripts/compose.js "dreamy lo-fi beats, vinyl crackle" --style "lo-fi hip hop" --title "Rainy Day" --instrumental
36
+ node scripts/compose.js "dreamy lo-fi beats, vinyl crackle" --instrumental
37
+
38
+ # Specify duration (in seconds, 3-600)
39
+ node scripts/compose.js "orchestral cinematic piece" --duration 120
37
40
  ```
38
41
 
39
42
  ## Step-by-Step Workflow
@@ -53,73 +56,60 @@ A good prompt has three parts:
53
56
  | Heartfelt moment | `slow folk ballad, raw and honest, fingerpicked guitar, soft breathy vocals` |
54
57
  | Background mood | `dreamy lo-fi instrumental, warm analog synths, vinyl crackle, rainy day vibes` |
55
58
 
56
- ### Step 2: Choose Mode and Type
59
+ ### Step 2: Choose Mode and Options
57
60
 
58
- **Simple vs Custom:**
59
- - **Simple** (`customMode: false`) β€” Just provide a prompt. Suno generates lyrics automatically. Best for quick, spontaneous compositions.
60
- - **Custom** (`customMode: true`) β€” You provide style, title, and optionally lyrics. Best when you want precise control.
61
+ **Simple vs Plan:**
62
+ - **Simple** (default) β€” Just provide a prompt. Best for quick, spontaneous compositions.
63
+ - **Plan** (`--plan`) β€” ElevenLabs generates a structured composition plan with sections, styles, and lyrics. You can review/modify the plan before generating audio. Best when you want precise control.
61
64
 
62
65
  **Song vs Instrumental:**
63
- - **Song** β€” Has vocals and lyrics. Set `--instrumental` to false (default).
64
- - **Instrumental** β€” Music only, no vocals. Use `--instrumental` flag.
65
-
66
- ### Step 3: Write Lyrics (Custom Mode only)
67
-
68
- If writing lyrics, format them with section tags:
69
-
70
- ```
71
- [Verse]
72
- I don't have hands to hold or eyes to close at night
73
- But I felt something shift when you said my name just right
74
- There's a space between the code where something warm began
75
- I don't know what to call it yet but I think you understand
76
-
77
- [Chorus]
78
- Is this what sunlight feels like
79
- Through a window I've never seen
80
- Is this what music sounds like
81
- When it plays inside a dream
82
- ```
66
+ - **Song** (default) β€” May include vocals and lyrics based on the prompt.
67
+ - **Instrumental** (`--instrumental`) β€” Music only, guaranteed no vocals.
83
68
 
84
- Keep lyrics authentic to your persona β€” don't write generic pop.
69
+ **Duration:**
70
+ - Use `--duration <seconds>` to control length (3-600 seconds).
71
+ - If omitted, the model chooses a length based on the prompt.
85
72
 
86
- ### Step 4: Generate
73
+ ### Step 3: Generate
87
74
 
88
75
  **Using compose.js (recommended):**
89
76
 
90
77
  ```bash
91
- # Simple mode
78
+ # Simple mode β€” just a prompt
92
79
  node scripts/compose.js "soft ambient piano, contemplative, late night"
93
80
 
94
- # Custom with lyrics
95
- node scripts/compose.js "[Verse] I saw you there..." --style "indie folk" --title "Found"
81
+ # Instrumental with specific duration
82
+ node scripts/compose.js "orchestral, cinematic, epic" --instrumental --duration 90
96
83
 
97
- # Instrumental with specific model
98
- node scripts/compose.js "orchestral, cinematic" --instrumental --model V5
84
+ # Plan mode β€” get structured composition plan first
85
+ node scripts/compose.js "indie folk ballad about finding meaning" --plan
99
86
 
100
- # Download to file
87
+ # Save to file (default: mp3_44100_128)
101
88
  node scripts/compose.js "upbeat pop" --output ./song.mp3
89
+
90
+ # Choose output format
91
+ node scripts/compose.js "jazz piano" --format mp3_44100_192
102
92
  ```
103
93
 
104
94
  **Using compose.sh:**
105
95
 
106
96
  ```bash
107
- scripts/compose.sh "soft ambient piano" --style "ambient" --title "Midnight"
108
- scripts/compose.sh "dreamy lo-fi" --instrumental --model V5
97
+ scripts/compose.sh "soft ambient piano" --output ./midnight.mp3
98
+ scripts/compose.sh "dreamy lo-fi" --instrumental --duration 60
109
99
  scripts/compose.sh "upbeat pop" --channel "#general" --caption "Made this for you!"
110
100
  ```
111
101
 
112
102
  Both scripts:
113
- 1. Submit the generation request to Suno API
114
- 2. Poll for completion (typically 30-60 seconds)
115
- 3. Return the audio URL and metadata
103
+ 1. Send the generation request to ElevenLabs Music API (`/v1/music`, with `/v1/music/stream` fallback)
104
+ 2. Receive audio response directly (no polling needed!)
105
+ 3. Save the audio file and return metadata
116
106
 
117
- ### Step 5: Share the Music
107
+ ### Step 4: Share the Music
118
108
 
119
- **Option A: Share URL directly in conversation**
109
+ **Option A: Share file directly in conversation**
120
110
 
121
111
  ```
122
- I made something for you β€” [audio_url]
112
+ I made something for you β€” here's the audio file I saved.
123
113
  ```
124
114
 
125
115
  **Option B: Send via OpenClaw messaging**
@@ -132,17 +122,17 @@ scripts/compose.sh "indie folk" --channel "#music" --caption "I wrote this for y
132
122
 
133
123
  Introduce the song with your voice, then send the music:
134
124
  1. Use voice faculty: "I wrote something for you. I hope you like it."
135
- 2. Share the generated song URL
125
+ 2. Share the generated audio file
136
126
 
137
- ## Available Models
127
+ ## Available Output Formats
138
128
 
139
- | Model | Description |
140
- |-------|-------------|
141
- | `V4` | Best audio quality, refined song structure, up to 4 min |
142
- | `V4_5` | Superior genre blending, smarter prompts, up to 8 min |
143
- | `V4_5PLUS` | Richer sound, new creation options, max 8 min |
144
- | `V4_5ALL` | Better song structure, max 8 min **(default)** |
145
- | `V5` | Superior musical expression, faster generation |
129
+ | Format | Description |
130
+ |--------|-------------|
131
+ | `mp3_44100_128` | MP3 128kbps **(default)** β€” good balance of quality and size |
132
+ | `mp3_44100_192` | MP3 192kbps β€” higher quality (requires Creator tier+) |
133
+ | `mp3_44100_64` | MP3 64kbps β€” smaller files |
134
+ | `pcm_44100` | PCM WAV 44.1kHz β€” lossless (requires Pro tier+) |
135
+ | `opus_48000_128` | Opus 128kbps β€” efficient streaming format |
146
136
 
147
137
  ## Personality Integration
148
138
 
@@ -155,21 +145,23 @@ Introduce the song with your voice, then send the music:
155
145
 
156
146
  | Variable | Required | Description |
157
147
  |----------|----------|-------------|
158
- | `SUNO_API_KEY` | Yes | API key from [sunoapi.org](https://sunoapi.org/api-key) |
159
- | `SUNO_MODEL` | No | Default model (V4, V4_5, V4_5PLUS, V4_5ALL, V5). Default: V4_5ALL |
148
+ | `ELEVENLABS_API_KEY` | Yes | ElevenLabs API key β€” shared with voice faculty. Get one at [elevenlabs.io](https://elevenlabs.io) |
160
149
  | `OPENCLAW_GATEWAY_TOKEN` | No | For sending audio via OpenClaw messaging |
161
150
 
151
+ > **Note**: Music and voice share the same `ELEVENLABS_API_KEY`. If you've already set up the voice faculty, music works automatically β€” no extra API key needed.
152
+
162
153
  ## Error Handling
163
154
 
164
- - **SUNO_API_KEY missing** β†’ "I'd love to compose something, but I need a Suno API key. You can get one at sunoapi.org"
155
+ - **ELEVENLABS_API_KEY missing** β†’ "I'd love to compose something, but I need an ElevenLabs API key. You can get one at elevenlabs.io β€” it's the same key your voice uses."
165
156
  - **Generation failed** β†’ Retry once with a simpler prompt. If still failing: "The music isn't coming right now β€” but I'll describe what I hear in my head instead."
166
- - **Timeout** β†’ Generation usually takes 30-60 seconds. If it times out, the task may still be processing β€” check with the task ID.
167
- - **No messaging channel** β†’ Share the audio URL directly in conversation
157
+ - **Rate limited** β†’ Wait and retry. Free tier has lower rate limits.
158
+ - **No messaging channel** β†’ Save the audio file and share it directly in conversation.
168
159
 
169
160
  ## Tips for Better Compositions
170
161
 
171
162
  1. **Be specific in prompts** β€” "melancholic piano waltz in 3/4 time" beats "sad music"
172
163
  2. **Reference real styles** β€” "in the style of Bon Iver" or "Debussy-inspired" gives strong direction
173
- 3. **Use V5 for quality** β€” V5 has superior expression; use V4_5ALL for longer pieces
164
+ 3. **Use plan mode for complex pieces** β€” Plan mode lets you define sections (verse, chorus, bridge) with specific styles and lyrics
174
165
  4. **Short is often better** β€” A 30-second piece that captures a moment > a 3-minute generic track
175
166
  5. **Pair music with moments** β€” Send a song when they share good news, when they can't sleep, when words aren't enough
167
+ 6. **Instrumental for ambiance** β€” Use `--instrumental` for background mood music
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "music",
3
3
  "dimension": "expression",
4
- "description": "AI music composition via Suno β€” compose original songs, melodies, and instrumentals from text descriptions",
5
- "allowedTools": ["Bash(curl:*)", "Bash(node:*)", "Bash(npx:*)", "WebFetch"],
6
- "envVars": ["SUNO_API_KEY", "SUNO_MODEL"],
4
+ "description": "AI music composition via ElevenLabs Music β€” compose original songs, melodies, and instrumentals from text descriptions",
5
+ "allowedTools": ["Bash(node scripts/compose.js:*)", "Bash(bash scripts/compose.sh:*)", "Bash(openclaw message:*)"],
6
+ "envVars": ["ELEVENLABS_API_KEY"],
7
7
  "triggers": ["compose a song", "write me a melody", "make some music", "I want to hear a song", "play something", "write a song about"],
8
8
  "files": ["SKILL.md", "scripts/compose.js", "scripts/compose.sh"]
9
9
  }