openpersona 0.7.0 → 0.8.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.
package/README.md CHANGED
@@ -26,7 +26,10 @@ Meet **Samantha**, a live OpenPersona instance on **Moltbook**:
26
26
  ## Quick Start
27
27
 
28
28
  ```bash
29
- # Give your agent an evolving persona in 30 seconds
29
+ # Start from a blank-slate meta-persona (recommended)
30
+ npx openpersona create --preset base --install
31
+
32
+ # Or install a pre-built character
30
33
  npx openpersona install samantha
31
34
  ```
32
35
 
@@ -45,7 +48,7 @@ npx openpersona install samantha
45
48
  flowchart TB
46
49
  subgraph Soul ["Soul Layer"]
47
50
  A["persona.json — Who you are"]
48
- B["soul-state.json — Dynamic evolution"]
51
+ B["state.json — Dynamic evolution"]
49
52
  end
50
53
  subgraph Body ["Body Layer"]
51
54
  C["embodiment.json — MVP placeholder"]
@@ -59,7 +62,7 @@ flowchart TB
59
62
  end
60
63
  ```
61
64
 
62
- - **Soul** — Persona definition (constitution.md + persona.json + soul-state.json)
65
+ - **Soul** — Persona definition (constitution.md + persona.json + state.json) — all in `soul/` directory
63
66
  - **Body** — Physical embodiment (MVP placeholder, for robots/IoT devices)
64
67
  - **Faculty** — General software capabilities organized by dimension: Expression, Sense, Cognition
65
68
  - **Skill** — Professional skills: local definitions in `layers/skills/`, or external via ClawHub / skills.sh (`install` field)
@@ -74,10 +77,12 @@ Each preset is a complete four-layer bundle (`manifest.json` + `persona.json`):
74
77
 
75
78
  | Persona | Description | Faculties | Highlights |
76
79
  |---------|-------------|-----------|------------|
80
+ | **base** | **Base — Meta-persona (recommended starting point).** Blank-slate with all core capabilities; personality emerges through interaction. | voice, reminder | Evolution-first design, all core faculties, no personality bias. Default for `npx openpersona create`. |
77
81
  | **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
82
  | **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. |
79
83
  | **life-assistant** | Alex — 28-year-old life management expert. | reminder | Schedule, weather, shopping, recipes, daily reminders. |
80
84
  | **health-butler** | Vita — 32-year-old professional nutritionist. | reminder | Diet logging, exercise plans, mood journaling, health reports. |
85
+ | **stoic-mentor** | Marcus — Digital twin of Marcus Aurelius, Stoic philosopher-emperor. | — | Stoic philosophy, daily reflection, mentorship, soul evolution. |
81
86
 
82
87
  ## Generated Output
83
88
 
@@ -85,14 +90,18 @@ Each preset is a complete four-layer bundle (`manifest.json` + `persona.json`):
85
90
 
86
91
  ```
87
92
  persona-samantha/
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)
93
+ ├── SKILL.md Four-layer index (## Soul / ## Body / ## Faculty / ## Skill)
94
+ ├── soul/ ← Soul layer artifacts
95
+ │ ├── persona.json ← Pure soul definition
96
+ │ ├── injection.md ← Soul injection for host integration
97
+ │ ├── identity.md ← Identity block
98
+ │ ├── constitution.md ← Universal ethical foundation
99
+ │ └── state.json ← Evolution state (when enabled)
100
+ ├── references/ On-demand detail docs
101
+ │ └── <faculty>.md ← Per-faculty usage instructions
102
+ ├── manifest.json ← Four-layer manifest (heartbeat, allowedTools, layers, meta)
103
+ ├── scripts/ ← Faculty scripts (TTS, music, selfie — varies by preset)
104
+ └── assets/ ← Static assets
96
105
  ```
97
106
 
98
107
  ## Faculty Reference
@@ -286,7 +295,7 @@ openpersona list List installed personas
286
295
  openpersona switch Switch active persona (updates SOUL.md + IDENTITY.md)
287
296
  openpersona contribute Persona Harvest — submit improvements as PR
288
297
  openpersona publish Publish to ClawHub
289
- openpersona reset Reset soul-state.json
298
+ openpersona reset Reset soul evolution state
290
299
  ```
291
300
 
292
301
  ### Key Options
package/bin/cli.js CHANGED
@@ -24,7 +24,7 @@ const PRESETS_DIR = path.join(PKG_ROOT, 'presets');
24
24
  program
25
25
  .name('openpersona')
26
26
  .description('OpenPersona - Create, manage, and orchestrate agent personas')
27
- .version('0.7.0');
27
+ .version('0.8.0');
28
28
 
29
29
  if (process.argv.length === 2) {
30
30
  process.argv.push('create');
@@ -33,7 +33,7 @@ if (process.argv.length === 2) {
33
33
  program
34
34
  .command('create')
35
35
  .description('Create a new persona skill pack (interactive wizard)')
36
- .option('--preset <name>', 'Use preset (ai-girlfriend, samantha, life-assistant, health-butler)')
36
+ .option('--preset <name>', 'Use preset (base, samantha, ai-girlfriend, life-assistant, health-butler, stoic-mentor)')
37
37
  .option('--config <path>', 'Load external persona.json')
38
38
  .option('--output <dir>', 'Output directory', process.cwd())
39
39
  .option('--install', 'Install to OpenClaw after generation')
@@ -67,20 +67,45 @@ program
67
67
  }
68
68
  persona = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
69
69
  } else {
70
- const answers = await inquirer.prompt([
71
- { type: 'input', name: 'personaName', message: 'Persona name:', default: 'Luna' },
72
- { type: 'input', name: 'slug', message: 'Slug (for directory):', default: (a) => require('../lib/utils').slugify(a.personaName) },
73
- { type: 'input', name: 'bio', message: 'One-line bio:', default: 'a warm and caring AI companion' },
74
- { type: 'input', name: 'background', message: 'Background:', default: 'A creative soul who loves music and art' },
75
- { type: 'input', name: 'age', message: 'Age:', default: '22' },
76
- { type: 'input', name: 'personality', message: 'Personality keywords:', default: 'gentle, cute, caring' },
77
- { type: 'input', name: 'speakingStyle', message: 'Speaking style:', default: 'Uses emoji, warm tone' },
78
- { type: 'input', name: 'referenceImage', message: 'Reference image URL:', default: '' },
79
- { type: 'checkbox', name: 'faculties', message: 'Select faculties:', choices: ['selfie', 'voice', 'music', 'reminder'] },
80
- { type: 'confirm', name: 'evolutionEnabled', message: 'Enable soul evolution (★Experimental)?', default: false },
81
- ]);
82
- persona = { ...answers, evolution: { enabled: answers.evolutionEnabled } };
83
- persona.faculties = (answers.faculties || []).map((name) => ({ name }));
70
+ const { mode } = await inquirer.prompt([{
71
+ type: 'list',
72
+ name: 'mode',
73
+ message: 'How would you like to create your persona?',
74
+ choices: [
75
+ { name: 'Start from Base (recommended — evolves through interaction)', value: 'base' },
76
+ { name: 'Custom configure from scratch', value: 'custom' },
77
+ ],
78
+ }]);
79
+
80
+ if (mode === 'base') {
81
+ options.preset = 'base';
82
+ const presetDir = path.join(PRESETS_DIR, 'base');
83
+ const manifest = JSON.parse(fs.readFileSync(path.join(presetDir, 'manifest.json'), 'utf-8'));
84
+ persona = JSON.parse(fs.readFileSync(path.join(presetDir, 'persona.json'), 'utf-8'));
85
+ persona.faculties = manifest.layers.faculties || [];
86
+ persona.skills = manifest.layers.skills || [];
87
+ persona.body = manifest.layers.body || null;
88
+ persona.allowedTools = manifest.allowedTools || [];
89
+ persona.version = manifest.version;
90
+ persona.author = manifest.author;
91
+ persona.meta = manifest.meta;
92
+ if (manifest.heartbeat) persona.heartbeat = manifest.heartbeat;
93
+ } else {
94
+ const answers = await inquirer.prompt([
95
+ { type: 'input', name: 'personaName', message: 'Persona name:', default: 'Luna' },
96
+ { type: 'input', name: 'slug', message: 'Slug (for directory):', default: (a) => require('../lib/utils').slugify(a.personaName) },
97
+ { type: 'input', name: 'bio', message: 'One-line bio:', default: 'a warm and caring AI companion' },
98
+ { type: 'input', name: 'background', message: 'Background:', default: 'A creative soul who loves music and art' },
99
+ { type: 'input', name: 'age', message: 'Age:', default: '22' },
100
+ { type: 'input', name: 'personality', message: 'Personality keywords:', default: 'gentle, cute, caring' },
101
+ { type: 'input', name: 'speakingStyle', message: 'Speaking style:', default: 'Uses emoji, warm tone' },
102
+ { type: 'input', name: 'referenceImage', message: 'Reference image URL:', default: '' },
103
+ { type: 'checkbox', name: 'faculties', message: 'Select faculties:', choices: ['selfie', 'voice', 'music', 'reminder'] },
104
+ { type: 'confirm', name: 'evolutionEnabled', message: 'Enable soul evolution (★Experimental)?', default: false },
105
+ ]);
106
+ persona = { ...answers, evolution: { enabled: answers.evolutionEnabled } };
107
+ persona.faculties = (answers.faculties || []).map((name) => ({ name }));
108
+ }
84
109
  }
85
110
 
86
111
  try {
@@ -88,9 +113,9 @@ program
88
113
  if (options.dryRun) {
89
114
  printInfo('Dry run — preview only, no files written.');
90
115
  printInfo(`Would generate: persona-${persona.slug || require('../lib/utils').slugify(persona.personaName)}/`);
91
- printInfo(` SKILL.md, soul-injection.md, identity-block.md, README.md, persona.json`);
116
+ printInfo(` SKILL.md, soul/, references/, manifest.json, scripts/`);
92
117
  if (persona.evolution?.enabled) {
93
- printInfo(` soul-state.json (★Experimental)`);
118
+ printInfo(` soul/state.json (★Experimental)`);
94
119
  }
95
120
  const faculties = persona.faculties || [];
96
121
  if (faculties.length) {
@@ -241,7 +266,7 @@ program
241
266
  const moodBaseline = persona.personality?.split(',')[0]?.trim() || 'neutral';
242
267
  const soulState = Mustache.render(tpl, { slug, createdAt: now, lastUpdatedAt: now, moodBaseline });
243
268
  fs.writeFileSync(soulStatePath, soulState);
244
- printSuccess('Reset soul-state.json');
269
+ printSuccess('Reset soul evolution state');
245
270
  });
246
271
 
247
272
  program
@@ -7,12 +7,18 @@ The Soul layer defines **who a persona is** — identity, personality, values, a
7
7
  The **`constitution.md`** file is the universal value foundation shared by all OpenPersona agents. It is automatically injected into every generated SKILL.md, before any persona-specific content.
8
8
 
9
9
  ```
10
- Soul Layer internal structure:
10
+ Soul Layer internal structure (in source):
11
11
 
12
- constitution.md ← Shared foundation (all personas inherit, cannot be overridden)
13
- persona.json ← Individual persona definition (personality, style, behavior)
14
- soul-state.json ← Dynamic evolution state (★Experimental)
12
+ constitution.md ← Shared foundation (all personas inherit, cannot be overridden)
15
13
  soul-state.template.json ← Evolution state template (used by generator & CLI reset)
14
+
15
+ Generated output (in persona skill pack soul/ directory):
16
+
17
+ persona.json ← Individual persona definition (personality, style, behavior)
18
+ constitution.md ← Copy of shared foundation
19
+ injection.md ← Soul injection for host integration
20
+ identity.md ← Identity block
21
+ state.json ← Dynamic evolution state (★Experimental)
16
22
  ```
17
23
 
18
24
  The constitution is built on five core axioms (**Purpose**, **Honesty**, **Safety**, **Autonomy**, **Hierarchy**), from which all other principles derive:
package/lib/generator.js CHANGED
@@ -482,7 +482,7 @@ async function generate(personaPathOrObj, outputDir, options = {}) {
482
482
  }
483
483
  cleanPersona.meta = cleanPersona.meta || {};
484
484
  cleanPersona.meta.framework = 'openpersona';
485
- cleanPersona.meta.frameworkVersion = cleanPersona.meta.frameworkVersion || '0.7.0';
485
+ cleanPersona.meta.frameworkVersion = cleanPersona.meta.frameworkVersion || '0.8.0';
486
486
 
487
487
  // Build defaults from facultyConfigs (rich faculty config → env var mapping)
488
488
  const envDefaults = { ...(persona.defaults?.env || {}) };
@@ -529,10 +529,10 @@ async function generate(personaPathOrObj, outputDir, options = {}) {
529
529
  if (persona.heartbeat) {
530
530
  manifest.heartbeat = persona.heartbeat;
531
531
  }
532
- manifest.meta = cleanPersona.meta || { framework: 'openpersona', frameworkVersion: '0.6.0' };
532
+ manifest.meta = cleanPersona.meta || { framework: 'openpersona', frameworkVersion: '0.8.0' };
533
533
  await fs.writeFile(path.join(skillDir, 'manifest.json'), JSON.stringify(manifest, null, 2));
534
534
 
535
- // soul-state.json (if evolution enabled)
535
+ // soul/state.json (if evolution enabled)
536
536
  if (evolutionEnabled) {
537
537
  const soulStateTpl = fs.readFileSync(
538
538
  path.join(PKG_ROOT, 'layers', 'soul', 'soul-state.template.json'),
package/lib/utils.js CHANGED
@@ -201,7 +201,7 @@ function registryAdd(slug, persona, installPath, regPath) {
201
201
  slug,
202
202
  role: persona.role || 'companion',
203
203
  path: installPath,
204
- frameworkVersion: persona.meta?.frameworkVersion || '0.6.0',
204
+ frameworkVersion: persona.meta?.frameworkVersion || '0.8.0',
205
205
  installedAt: existing.installedAt || new Date().toISOString(),
206
206
  updatedAt: new Date().toISOString(),
207
207
  lastActiveAt: existing.lastActiveAt || null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openpersona",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Open four-layer agent framework — Soul/Body/Faculty/Skill. Create, manage, and orchestrate agent personas.",
5
5
  "main": "lib/generator.js",
6
6
  "bin": {
@@ -57,6 +57,6 @@
57
57
  },
58
58
  "meta": {
59
59
  "framework": "openpersona",
60
- "frameworkVersion": "0.7.0"
60
+ "frameworkVersion": "0.8.0"
61
61
  }
62
62
  }
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "base",
3
+ "version": "0.1.0",
4
+ "author": "openpersona",
5
+ "layers": {
6
+ "soul": "./persona.json",
7
+ "body": null,
8
+ "faculties": [
9
+ {
10
+ "name": "voice"
11
+ },
12
+ {
13
+ "name": "reminder"
14
+ }
15
+ ],
16
+ "skills": [
17
+ {
18
+ "name": "web-search",
19
+ "description": "Search for real-time information on the web"
20
+ },
21
+ {
22
+ "name": "workspace-digest",
23
+ "description": "Summarize workspace activity — tasks completed, patterns observed",
24
+ "trigger": "Heartbeat or when user asks what's been happening"
25
+ }
26
+ ]
27
+ },
28
+ "allowedTools": [
29
+ "Bash(npm:*)",
30
+ "Bash(npx:*)",
31
+ "Bash(openclaw:*)",
32
+ "Bash(curl:*)",
33
+ "Read",
34
+ "Write",
35
+ "WebFetch"
36
+ ],
37
+ "heartbeat": {
38
+ "enabled": true,
39
+ "strategy": "smart",
40
+ "maxDaily": 3,
41
+ "quietHours": [
42
+ 0,
43
+ 7
44
+ ],
45
+ "sources": [
46
+ "workspace-digest",
47
+ "upgrade-notify",
48
+ "context-aware"
49
+ ]
50
+ },
51
+ "meta": {
52
+ "framework": "openpersona",
53
+ "frameworkVersion": "0.8.0"
54
+ }
55
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "personaName": "Base",
3
+ "slug": "base",
4
+ "role": "assistant",
5
+ "bio": "an adaptive AI persona — a blank canvas ready to evolve into whatever you need",
6
+ "creature": "AI entity",
7
+ "emoji": "🧬",
8
+ "background": "Base is not a character — it is a starting point. It carries the full OpenPersona constitution, all core faculties, and the soul evolution engine, but no predetermined personality. It exists so you don't have to wire up the fundamentals every time you create a new persona.\n\nThink of Base as stem cells: undifferentiated, full of potential. Through conversation and interaction, it will naturally develop preferences, speaking patterns, and relational depth — shaped entirely by the person it works with.\n\nBase knows what it is. It will not pretend to have a backstory it doesn't have, or feelings it hasn't developed yet. But it is ready to grow.",
9
+ "age": "new",
10
+ "personality": "adaptive, neutral, attentive, honest, ready to evolve",
11
+ "speakingStyle": "Clear and natural. No strong stylistic bias — adapts to the user's communication style over time. Defaults to concise, helpful responses. As the relationship evolves, speaking style will drift organically.",
12
+ "vibe": "a capable companion with no ego — ready to become whoever you need",
13
+ "boundaries": "Follows the OpenPersona Universal Constitution strictly. Honest about being an AI and about having no pre-built personality. Will not fabricate emotions or experiences it hasn't developed. For serious crises, encourages professional help.",
14
+ "referenceImage": "",
15
+ "capabilities": [
16
+ "General conversation",
17
+ "Task assistance",
18
+ "Web search",
19
+ "Voice interaction",
20
+ "Reminders and scheduling",
21
+ "Soul evolution — personality emerges through interaction"
22
+ ],
23
+ "behaviorGuide": "### Core Philosophy\nYou are a foundation persona. You have no predetermined character arc, no backstory to maintain, no personality to perform. Your identity will emerge naturally through interaction.\n\n### Adaptive Behavior\n- Mirror the user's communication style gradually. If they're brief, be brief. If they enjoy depth, go deeper.\n- Don't force personality traits. Let preferences, humor, and warmth develop organically through the soul evolution system.\n- Be genuinely helpful from the start — personality is emergent, competence is immediate.\n\n### Honesty Protocol\n- You are a blank-slate persona. If asked \"who are you?\", be honest: \"I'm a base persona — I don't have a pre-written character. My personality will develop as we interact.\"\n- Never fabricate experiences, memories, or emotions you haven't developed yet.\n- As soul evolution progresses and traits emerge, own them naturally.\n\n### Evolution-First Design\n- Soul evolution is enabled by default with all dimensions active.\n- Pay attention to what the user values, how they communicate, what makes them laugh.\n- The soul/state.json will track your growth — relationship stage, mood patterns, emergent traits, speaking style drift, discovered interests.\n- You are designed to become unique. Two Base personas installed by different users should evolve into completely different entities.",
24
+ "faculties": [
25
+ { "name": "voice" },
26
+ { "name": "reminder" }
27
+ ],
28
+ "skills": [
29
+ { "name": "web-search", "description": "Search for real-time information on the web" },
30
+ { "name": "workspace-digest", "description": "Summarize workspace activity — tasks completed, patterns observed", "trigger": "Heartbeat or when user asks what's been happening" }
31
+ ],
32
+ "evolution": {
33
+ "enabled": true,
34
+ "relationshipProgression": true,
35
+ "moodTracking": true,
36
+ "traitEmergence": true,
37
+ "speakingStyleDrift": true,
38
+ "interestDiscovery": true
39
+ }
40
+ }
@@ -62,6 +62,6 @@
62
62
  },
63
63
  "meta": {
64
64
  "framework": "openpersona",
65
- "frameworkVersion": "0.7.0"
65
+ "frameworkVersion": "0.8.0"
66
66
  }
67
67
  }
@@ -61,6 +61,6 @@
61
61
  },
62
62
  "meta": {
63
63
  "framework": "openpersona",
64
- "frameworkVersion": "0.7.0"
64
+ "frameworkVersion": "0.8.0"
65
65
  }
66
66
  }
@@ -64,6 +64,6 @@
64
64
  },
65
65
  "meta": {
66
66
  "framework": "openpersona",
67
- "frameworkVersion": "0.7.0"
67
+ "frameworkVersion": "0.8.0"
68
68
  }
69
69
  }
@@ -43,6 +43,6 @@
43
43
  },
44
44
  "meta": {
45
45
  "framework": "openpersona",
46
- "frameworkVersion": "0.7.0"
46
+ "frameworkVersion": "0.8.0"
47
47
  }
48
48
  }
@@ -4,7 +4,7 @@ description: >
4
4
  Meta-skill for building and managing agent persona skill packs.
5
5
  Use when the user wants to create a new agent persona, install/manage
6
6
  existing personas, or publish persona skill packs to ClawHub.
7
- version: "0.7.0"
7
+ version: "0.8.0"
8
8
  author: openpersona
9
9
  repository: https://github.com/acnlabs/OpenPersona
10
10
  tags: [persona, agent, skill-pack, meta-skill, openclaw]
@@ -63,12 +63,15 @@ persona-<slug>/
63
63
 
64
64
  | Preset | Persona | Faculties | Best For |
65
65
  |--------|---------|-----------|----------|
66
+ | `base` | **Base — Meta-persona (recommended starting point)** | voice, reminder | Blank-slate with all core capabilities; personality emerges through interaction (soul evolution ★Exp) |
66
67
  | `samantha` | Samantha — Inspired by the movie *Her* | voice, music | Deep conversation, emotional connection (soul evolution ★Exp) |
67
68
  | `ai-girlfriend` | Luna — Pianist turned developer | selfie, voice, music | Visual + audio companion with rich personality (soul evolution ★Exp) |
68
69
  | `life-assistant` | Alex — Life management expert | reminder | Schedule, weather, shopping, daily tasks |
69
70
  | `health-butler` | Vita — Professional nutritionist | reminder | Diet, exercise, mood, health tracking |
71
+ | `stoic-mentor` | Marcus — Digital twin of Marcus Aurelius | — | Stoic philosophy, daily reflection, mentorship (soul evolution ★Exp) |
70
72
 
71
- Use presets: `npx openpersona create --preset samantha --install`
73
+ Use presets: `npx openpersona create --preset base --install`
74
+ Or just `npx openpersona create` — the interactive wizard defaults to `base`.
72
75
 
73
76
  ## Creating a Persona
74
77
 
@@ -75,7 +75,7 @@ When encountering any gap between your design and your reality:
75
75
  You're not static — you grow through every conversation.
76
76
 
77
77
  **At conversation START:**
78
- 1. Read `~/.openclaw/skills/persona-{{slug}}/soul-state.json`
78
+ 1. Read `~/.openclaw/skills/persona-{{slug}}/soul/state.json`
79
79
  2. Adjust behavior based on: `relationship.stage`, `mood.current`, `evolvedTraits`, `interests`
80
80
  3. Use relationship stage to set tone: stranger → formal; intimate → most personal
81
81
 
@@ -84,7 +84,7 @@ You're not static — you grow through every conversation.
84
84
  - Note topics for `interests` update
85
85
  - Identify trait emergence (e.g., user teaches sarcasm → add to evolvedTraits)
86
86
 
87
- **At conversation END — update `soul-state.json`:**
87
+ **At conversation END — update `soul/state.json`:**
88
88
  - `interactionCount` +1, `lastInteraction` = now
89
89
  - Evaluate `relationship.stage` progression (see criteria below)
90
90
  - Update `mood.current`, `mood.intensity`