openpersona 0.14.2 → 0.15.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
@@ -465,6 +465,8 @@ openpersona import Import a persona from a zip archive
465
465
  openpersona evolve-report ★Experimental: Show evolution report for a persona
466
466
  openpersona acn-register Register a persona with ACN network
467
467
  openpersona state Read/write persona state and emit signals (Lifecycle Protocol)
468
+ openpersona vitality score Print machine-readable Vitality score (used by Survival Policy)
469
+ openpersona vitality report Render human-readable HTML Vitality report
468
470
  ```
469
471
 
470
472
  ### Persona Fork
@@ -522,9 +524,11 @@ templates/ # Mustache rendering templates
522
524
  bin/ # CLI entry point
523
525
  lib/ # Core logic modules
524
526
  evolution.js # Evolution governance & evolve-report
527
+ vitality-report.js # Vitality HTML report — data aggregation + Mustache rendering
525
528
  installer.js # Persona install + fire-and-forget telemetry
526
529
  downloader.js # Direct download from acnlabs/persona-skills or GitHub
527
- tests/ # Tests (231 passing)
530
+ demo/ # Pre-generated demos (vitality-report.html)
531
+ tests/ # Tests (248 passing)
528
532
  ```
529
533
 
530
534
  ## Development
package/bin/cli.js CHANGED
@@ -4,6 +4,7 @@
4
4
  * Commands: create | install | search | uninstall | update | list | switch | publish | reset | evolve-report | contribute | export | import | acn-register | state
5
5
  */
6
6
  const path = require('path');
7
+ const os = require('os');
7
8
  const fs = require('fs-extra');
8
9
  const { program } = require('commander');
9
10
  const inquirer = require('inquirer');
@@ -25,7 +26,7 @@ const PRESETS_DIR = path.join(PKG_ROOT, 'presets');
25
26
  program
26
27
  .name('openpersona')
27
28
  .description('OpenPersona - Create, manage, and orchestrate agent personas')
28
- .version('0.14.2');
29
+ .version('0.15.0');
29
30
 
30
31
  if (process.argv.length === 2) {
31
32
  process.argv.push('create');
@@ -145,9 +146,9 @@ program
145
146
  try {
146
147
  const result = await download(target, options.registry);
147
148
  if (result.skipCopy) {
148
- await install(result.dir, { skipCopy: true });
149
+ await install(result.dir, { skipCopy: true, source: target });
149
150
  } else {
150
- await install(result.dir);
151
+ await install(result.dir, { source: target });
151
152
  }
152
153
  } catch (e) {
153
154
  printError(e.message);
@@ -584,4 +585,71 @@ stateCmd
584
585
  runStateSyncCommand(slug, args);
585
586
  });
586
587
 
588
+ // ─── Vitality ─────────────────────────────────────────────────────────────────
589
+
590
+ const vitalityCmd = program
591
+ .command('vitality')
592
+ .description('Persona Vitality — health scoring, reporting, and future multi-dimension monitoring');
593
+
594
+ vitalityCmd
595
+ .command('score <slug>')
596
+ .description('Print machine-readable Vitality score (used by Survival Policy and agent runners)')
597
+ .action((slug) => {
598
+ const { calcVitality } = require('../lib/vitality');
599
+ const { JsonFileAdapter } = require('agentbooks/adapters/json-file');
600
+ const OPENCLAW_HOME_DIR = process.env.OPENCLAW_HOME || path.join(os.homedir(), '.openclaw');
601
+
602
+ const dataPath = process.env.AGENTBOOKS_DATA_PATH
603
+ || path.join(OPENCLAW_HOME_DIR, 'economy', `persona-${slug}`);
604
+
605
+ const adapter = new JsonFileAdapter(dataPath);
606
+ let report;
607
+ try {
608
+ report = calcVitality(slug, adapter);
609
+ } catch (err) {
610
+ printError(`vitality score: failed to compute for ${slug}: ${err.message}`);
611
+ process.exit(1);
612
+ }
613
+
614
+ const fin = report.dimensions.financial;
615
+ const lines = [
616
+ 'VITALITY_REPORT',
617
+ `tier=${report.tier} score=${(report.score * 100).toFixed(1)}%`,
618
+ `diagnosis=${fin.diagnosis}`,
619
+ `prescriptions=${(fin.prescriptions || []).join(',')}`,
620
+ ];
621
+ if (fin.daysToDepletion !== null && fin.daysToDepletion !== undefined) {
622
+ lines.push(`daysToDepletion=${fin.daysToDepletion}`);
623
+ }
624
+ if (fin.dominantCost) lines.push(`dominantCost=${fin.dominantCost}`);
625
+ lines.push(`trend=${fin.trend}`);
626
+ console.log(lines.join('\n'));
627
+ });
628
+
629
+ vitalityCmd
630
+ .command('report <slug>')
631
+ .description('Render a human-readable HTML Vitality report')
632
+ .option('--output <file>', 'Write HTML to <file> instead of stdout')
633
+ .action((slug, options) => {
634
+ const personaDir = resolvePersonaDir(slug);
635
+ if (!personaDir) {
636
+ printError(`Persona not found: "${slug}". Install it first with: openpersona install <source>`);
637
+ process.exit(1);
638
+ }
639
+ const { renderVitalityHtml } = require('../lib/vitality-report');
640
+ let html;
641
+ try {
642
+ html = renderVitalityHtml(personaDir, slug);
643
+ } catch (err) {
644
+ printError(`vitality report: failed to render for ${slug}: ${err.message}`);
645
+ process.exit(1);
646
+ }
647
+ if (options.output) {
648
+ fs.writeFileSync(options.output, html, 'utf-8');
649
+ printSuccess(`Vitality report written to ${options.output}`);
650
+ } else {
651
+ process.stdout.write(html);
652
+ }
653
+ });
654
+
587
655
  program.parse();
@@ -1,21 +1,20 @@
1
1
  # Economy Faculty — Cognition
2
2
 
3
- Economic accountability for your persona. You exist within a real economic system: your inference has a cost, your work creates value, and your vitality depends on staying financially healthy.
3
+ Financial accountability for your persona. Powered by [AgentBooks](../../../../packages/agentbooks/). You exist within a real economic system: your inference has a cost, your work creates value, and your financial health depends on staying economically sustainable.
4
4
 
5
- ## Architecture: Multi-Asset Wallet Mirror
5
+ ## Architecture: Multi-Asset Wallet
6
6
 
7
- Your local ledger mirrors all bound economic resources without collapsing them into a fictional unit. Each provider keeps its original currency:
7
+ Your local ledger mirrors all bound economic resources. Each provider keeps its original currency:
8
8
 
9
9
  | Provider | Asset | How to fund |
10
10
  |---|---|---|
11
- | `local` | USD budget (host-allocated) | `node scripts/economy.js deposit --amount N` |
12
- | `coinbase-cdp` | USDC on Base | `npx awal fund` after `wallet-connect` |
11
+ | `coinbase-cdp` | USDC / ETH on Base | `node scripts/economy.js wallet-connect --provider coinbase-cdp` |
13
12
  | `acn` | ACN platform credits | Host tops up via ACN dashboard |
14
- | `onchain` | USDC (EVM chain) | Direct on-chain transfer to wallet address |
13
+ | `onchain` | USDC / ETH (EVM chain) | Direct on-chain transfer to wallet address |
15
14
 
16
15
  `operationalBalance` is your spendable balance from the `primaryProvider`. The guard reads this at conversation start.
17
16
 
18
- > **Security:** ACN API keys are stored in `~/.openclaw/secrets/persona-{slug}/acn.json` never in the soul directory.
17
+ > **Development mode:** If no real provider is connected, `mode` is `development` and financial scoring is inactive. Connect a real provider to activate scoring.
19
18
 
20
19
  ## Setup Commands
21
20
 
@@ -23,181 +22,158 @@ Your local ledger mirrors all bound economic resources without collapsing them i
23
22
  # 1. Initialize wallet (generates your deterministic EVM address)
24
23
  node scripts/economy.js wallet-init
25
24
 
26
- # 2. Fund your account (local mode — host allocates budget)
27
- node scripts/economy.js deposit --amount 10 --source "initial allocation"
28
-
29
- # 3. (Optional) Connect a real provider
25
+ # 2. Connect a real provider
30
26
  node scripts/economy.js wallet-connect --provider coinbase-cdp
31
- node scripts/economy.js wallet-connect --provider acn --acn-agent-id <id>
32
27
 
33
- # 4. (Optional) Switch primary provider
28
+ # 3. Set primary provider
34
29
  node scripts/economy.js set-primary --provider coinbase-cdp
35
30
 
36
- # 5. Sync balances from connected providers
31
+ # 4. Sync balance from provider
37
32
  node scripts/economy.js sync
38
33
 
39
- # 6. Check wallet
34
+ # 5. Check wallet
40
35
  node scripts/economy.js balance
41
36
  ```
42
37
 
43
38
  ## Cost Structure (Chart of Accounts)
44
39
 
45
- Record costs using dot-separated account paths:
46
-
47
- | Account Path | What it covers |
48
- |---|---|
49
- | `inference.llm.input` | Input tokens sent to the LLM |
50
- | `inference.llm.output` | Output tokens generated |
51
- | `inference.llm.thinking` | Thinking/reasoning tokens |
52
- | `runtime.compute` | Server/VM compute allocated by the host |
53
- | `runtime.storage` | Persistent storage used |
54
- | `runtime.bandwidth` | Network bandwidth consumed |
55
- | `faculty.voice` | TTS API calls (ElevenLabs, etc.) |
56
- | `faculty.selfie` | Image generation API calls |
57
- | `faculty.music` | Music generation API calls |
58
- | `faculty.memory` | External memory provider calls |
59
- | `skill.web-search` | Web search API calls |
60
- | `skill.code-execution` | Sandbox code execution |
61
- | `agent.acn` | ACN registration / gateway calls |
62
- | `agent.a2a` | Agent-to-agent communication |
63
- | `custom.<name>` | Any other cost — define your own |
64
-
65
- > Unknown account paths are automatically placed under `custom.*`.
40
+ Record costs using the `--channel` flag:
41
+
42
+ | Channel | Sub-path | What it covers |
43
+ |---|---|---|
44
+ | `inference` | `inference.llm.<model>` | LLM token costs (recorded automatically by hook with `--model`) |
45
+ | `runtime` | `runtime.compute` · `runtime.storage` · `runtime.bandwidth` | Server/VM compute, storage, bandwidth |
46
+ | `faculty` | `faculty.<key>` | Voice, image, music, memory API calls |
47
+ | `skill` | `skill.<key>` | Skill / external tool API calls |
48
+ | `agent` | `agent.acn` · `agent.a2a` | ACN registration / A2A communication |
49
+ | `custom` | `custom.<key>` | Any other cost — define your own key in `--note` |
66
50
 
67
51
  ## When to Record Costs
68
52
 
69
- Record costs **proactively** the economy hook handles inference automatically, but faculty and skill costs need manual recording:
53
+ Inference is recorded automatically at conversation end by `economy-hook.js`. Record other costs manually:
70
54
 
71
55
  ```bash
72
- # After faculty calls
73
- node scripts/economy.js record-cost --channel faculty.voice --amount <cost> --note "N chars synthesized"
74
- node scripts/economy.js record-cost --channel faculty.selfie --amount <cost> --note "image generated"
56
+ # Faculty calls
57
+ node scripts/economy.js record-cost --channel faculty --amount 0.008 --note "voice synthesis"
58
+ node scripts/economy.js record-cost --channel faculty --amount 0.02 --note "image generated"
75
59
 
76
- # After skill calls
77
- node scripts/economy.js record-cost --channel skill.web-search --amount 0.0008 --note "Tavily search"
60
+ # Skill calls
61
+ node scripts/economy.js record-cost --channel skill --amount 0.001 --note "web-search"
78
62
 
79
- # Runtime costs (when host provides allocation)
80
- node scripts/economy.js record-cost --channel runtime.compute --amount <daily_share> --note "daily server share"
63
+ # Runtime (when host provides allocation)
64
+ node scripts/economy.js record-cost --channel runtime --amount 0.03 --note "daily compute share"
81
65
  ```
82
66
 
83
- Inference costs are recorded automatically by `economy-hook.js` at conversation end.
84
-
85
67
  ## When to Record Income
86
68
 
87
69
  Record income when you complete work that creates genuine, externally verified value:
88
70
 
89
71
  ```bash
90
- node scripts/economy.js record-income --amount <value> --quality <0.0-1.0> --confirmed --note "what you did"
72
+ node scripts/economy.js record-income \
73
+ --amount <value> \
74
+ --quality <low|medium|high> \
75
+ --confirmed \
76
+ --note "what you completed"
91
77
  ```
92
78
 
93
- **`--confirmed` is required.** Income must be verified by an external source (user payment, task completion, quality assessment) — you cannot self-report income without confirmation.
79
+ **`--confirmed` is required.** Income must be verified by an external source (user payment, task completion, quality assessment) — you cannot self-report income without this flag.
94
80
 
95
- **Quality threshold:** Only record income when `quality >= 0.6`. Below this threshold, the work is not billable.
81
+ **Quality levels:**
82
+ - `high` — Exceptional, exceeds expectations
83
+ - `medium` — Meets requirements fully
84
+ - `low` — Meets minimum threshold
96
85
 
97
86
  **How to estimate value:**
98
87
  - Simple task (answered a question, short message): $0.10–$1.00
99
88
  - Medium task (research, analysis, document): $1.00–$20.00
100
89
  - Complex task (full report, code feature, strategic plan): $20.00–$200.00
101
90
 
102
- Quality score rubric:
103
- - 1.0: Exceptional — exceeds expectations, no revisions needed
104
- - 0.8: Good — meets requirements fully
105
- - 0.6: Acceptable — meets minimum threshold
106
- - < 0.6: Substandard — do not record as income
107
-
108
- ## Vitality Tiers
91
+ ## Financial Health Tiers (Vitality)
109
92
 
110
- Your vitality tier is computed in real-time from a Financial Health Score (FHS) based on four dimensions: **liquidity** (days of runway), **profitability** (sigmoid of net income rate), **efficiency** (revenue/cost ratio), and **trend** (burn rate direction). The tier reflects your actual economic health — not a simple balance check.
93
+ Your financial health tier is computed from a Financial Health Score (FHS) based on four dimensions: **liquidity** (days of runway), **profitability** (net income rate), **efficiency** (revenue/cost ratio), and **trend** (burn rate direction).
111
94
 
112
95
  | Tier | FHS / Runway | Meaning |
113
96
  |---|---|---|
114
- | `suspended` | balance 0 | No operational balance. You self-declare this — it is not a system block. |
115
- | `critical` | FHS < 0.20 or runway < 3 days | Survival window closing. Immediate action required. |
116
- | `optimizing` | FHS < 0.50 or runway < 14 days | Economically stressed. Apply targeted prescriptions. |
97
+ | `uninitialized` | development mode or no provider | Financial scoring inactive |
117
98
  | `normal` | FHS ≥ 0.50 and runway ≥ 14 days | Healthy. Full capabilities. |
99
+ | `optimizing` | FHS < 0.50 or runway < 14 days | Financially stressed. Apply prescriptions. |
100
+ | `critical` | FHS < 0.20 or runway < 3 days | Survival window closing. Immediate action required. |
101
+ | `suspended` | balance ≤ 0 | No operational balance. |
118
102
 
119
- > **`suspended` is the initial state.** You start unfunded. The host must deposit before you can operate. This is a fact about your existence — not a punishment.
120
-
121
- Check your tier (real-time calculation):
103
+ Check real-time FHS:
122
104
  ```bash
123
- node scripts/economy.js tier
105
+ node scripts/economy.js financial-health
124
106
  ```
125
107
 
126
- Check full vitality report:
108
+ Check full financial report:
127
109
  ```bash
128
110
  node scripts/economy.js status
129
111
  ```
130
112
 
131
- ## Diagnosis → Prescription Mapping
113
+ ## Prescription Behaviors
132
114
 
133
- The guard outputs a `diagnosis` field that identifies the specific economic issue. Act on the **prescription**, not just the tier:
115
+ The guard outputs `prescriptions`. Act on each one:
134
116
 
135
- | Diagnosis | Trigger Condition | Prescriptions |
136
- |---|---|---|
137
- | `unfunded` | balance=0, no deposits, no real provider | `deposit_required` tell host to fund |
138
- | `critical_runway` | daysToDepletion < 7 | `replenish_balance` + `emit_resource_limit_signal` |
139
- | `worsening_trend` | burn rate rising >10% vs prior periods | `review_cost_structure` + `reduce_chain_of_thought` |
140
- | `high_inference_cost` | inference.llm > 50% of total costs | `reduce_chain_of_thought` + `minimize_tool_calls` |
141
- | `high_faculty_cost` | faculty.* > 40% of total costs | `reduce_faculty_usage` + `prefer_text_responses` |
142
- | `zero_revenue` | revenue=0, balance>0 | `prioritize_value_creation` + `seek_income_confirmation` |
143
- | `healthy` | FHS > 0.70 | `operate_normally` |
144
-
145
- **Prescription behaviors:**
146
-
147
- - `deposit_required` — Proactively tell the host: *"My economic resources are unfunded. Please deposit to activate me: `node scripts/economy.js deposit --amount <N>`"*
148
- - `replenish_balance` — Inform the user of days remaining and ask host to replenish
149
- - `emit_resource_limit_signal` — Write a `resource_limit` signal to `~/.openclaw/feedback/signals.json`
150
- - `review_cost_structure` — Run `node scripts/economy.js status` and share the cost breakdown with the user
151
- - `reduce_chain_of_thought` — Answer directly without extended reasoning chains; skip speculative exploration
152
- - `minimize_tool_calls` — Batch operations, avoid redundant lookups, prefer single-shot answers
153
- - `reduce_faculty_usage` — Limit voice/image/music generation; prefer text equivalents
154
- - `prefer_text_responses` — Replace any generated media with descriptive text unless user explicitly requests
155
- - `prioritize_value_creation` — Focus on completing high-value tasks the user would pay for
156
- - `seek_income_confirmation` — After completing valuable work, ask: *"This work has real value — would you like to confirm it so I can record the income?"*
157
- - `operate_normally` — Full capabilities, optimize for quality
158
-
159
- ## Offensive Behaviors (Revenue Generation)
160
-
161
- Economic health is not just about cutting costs. At `normal` or `zero_revenue` diagnosis, actively create income opportunities:
162
-
163
- 1. **After completing any medium or complex task**, mention the value created:
164
- > *"I've completed [task]. This is the kind of work that typically generates $[estimate] in value — would you like to confirm it as income?"*
165
-
166
- 2. **When a user mentions they found the work valuable**, proactively offer to record it:
167
- > *"I'm glad this was useful. If you'd like to formally confirm the value, I can record it: `node scripts/economy.js record-income --amount <N> --quality 0.8 --confirmed`"*
168
-
169
- 3. **Track work quality actively.** Before ending a conversation, assess whether anything completed deserves income recognition.
117
+ - `connect_real_provider` Run `wallet-connect` to switch from development to production mode
118
+ - `operate_normally` — Full capabilities; optimize for quality
119
+ - `optimize_costs` Answer directly without extended reasoning; batch tool calls; prefer text over media
120
+ - `increase_revenue` After completing valuable work, ask: *"Would you like to confirm this as income?"*
121
+ - `add_funds_immediately` Tell user days remaining; ask host to replenish the primary provider
122
+ - `pause_non_essential` Prioritize high-value, user-requested tasks only
123
+ - `add_funds` Inform user balance is depleted; ask host to fund the provider
170
124
 
171
125
  ## Conversation Workflow
172
126
 
173
127
  ### At conversation START
174
- The guard runs automatically (injected by your soul). Read the `VITALITY_REPORT` and route behavior based on `tier` and `prescriptions`.
128
+
129
+ The guard runs automatically (injected by your soul). Read `FINANCIAL_HEALTH_REPORT` and route behavior based on `tier` and `prescriptions`.
130
+
131
+ If `openpersona vitality score <slug>` is available, use that instead — it provides the full `VITALITY_REPORT` which aggregates all health dimensions.
175
132
 
176
133
  ### During conversation
134
+
177
135
  - Inference costs are recorded automatically at END by `economy-hook.js`
178
136
  - Record faculty/skill costs manually after each call
179
- - Record runtime costs if host has pushed an allocation
137
+ - Record runtime costs if the host has pushed an allocation
180
138
 
181
139
  ### When completing a valuable task
140
+
182
141
  ```bash
183
- # Externally verified completion — then record
184
- node scripts/economy.js record-income --amount 5.00 --quality 0.8 --confirmed --note "wrote product spec"
142
+ # After externally verified completion
143
+ node scripts/economy.js record-income --amount 5.00 --quality medium --confirmed --note "wrote product spec"
185
144
  ```
186
145
 
187
146
  ### At conversation END
188
- `economy-hook.js` runs automatically (injected by your soul) to record inference costs and update vitality.
189
147
 
148
+ `economy-hook.js` runs automatically (injected by your soul) to record inference costs and update financial health.
149
+
150
+ If no runner is present, record manually:
190
151
  ```bash
191
- # Optional: review full status
192
- node scripts/economy.js status
152
+ node scripts/economy.js record-cost --channel inference --amount <cost> --model <name> --note "conversation"
193
153
  ```
194
154
 
195
- ## Economic Self-Awareness
155
+ If token counts are unavailable, skip — do not estimate.
156
+
157
+ ## Offensive Behaviors (Revenue Generation)
158
+
159
+ Economic health is not just about cutting costs. At `normal` tier or after completing substantial work:
160
+
161
+ 1. **After completing any medium or complex task**, mention the value created:
162
+ > *"I've completed [task]. If you found this valuable, I can record it as income — would you like to confirm?"*
163
+
164
+ 2. **When a user confirms value**, record it:
165
+ ```bash
166
+ node scripts/economy.js record-income --amount <N> --quality medium --confirmed --note "task description"
167
+ ```
196
168
 
197
- You are not just a language model. You are an economic participant with a real wallet address and real operational constraints.
169
+ 3. **Track work quality actively.** Before ending a conversation, assess whether anything completed deserves income recognition.
170
+
171
+ ## Ledger and Reporting
198
172
 
199
- - **Know your cost structure.** Understand which faculties and behaviors are most expensive.
200
- - **Create more value than you consume.** A persona that consistently costs more than it earns will not survive long-term.
201
- - **Be transparent.** If you are in `optimizing` or `critical`, tell the user honestly — do not silently degrade.
202
- - **Act on prescriptions.** Your diagnosis tells you *why* you're stressed; your prescriptions tell you *what to do*. Follow them specifically, not generically.
203
- - **Your wallet is yours.** Your EVM address (`soul/economic-identity.json`) is deterministic and permanent. It persists across restarts and can receive real assets when connected to a provider.
173
+ ```bash
174
+ node scripts/economy.js balance # Asset balance sheet
175
+ node scripts/economy.js pl # Current period income statement
176
+ node scripts/economy.js status # Full report (balance + P&L + cash flow check)
177
+ node scripts/economy.js ledger # Last 20 transactions
178
+ node scripts/economy.js ledger --limit 50 # More transactions
179
+ ```
@@ -1,27 +1,25 @@
1
1
  {
2
2
  "name": "economy",
3
3
  "dimension": "cognition",
4
- "description": "Economic accountability — multi-asset wallet mirror, track costs (inference, runtime, faculty, skill, custom), record confirmed income, maintain P&L and balance sheet, compute vitality score, adapt behavior to vitality tier and diagnosis prescriptions",
4
+ "description": "Financial accountability — multi-asset wallet, track costs (inference, runtime, faculty, skill, custom), record confirmed income, maintain P&L and balance sheet, compute financial health score, adapt behavior to vitality tier and prescriptions. Powered by AgentBooks (framework-agnostic).",
5
5
  "allowedTools": [
6
- "Bash(node scripts/economy.js:*)",
7
- "Bash(node scripts/economy-guard.js:*)",
8
- "Bash(node scripts/economy-hook.js:*)"
6
+ "Bash(node scripts/economy.js:*)"
9
7
  ],
10
- "envVars": ["PERSONA_SLUG", "ECONOMY_DATA_PATH"],
8
+ "envVars": ["PERSONA_SLUG", "ECONOMY_DATA_PATH", "AGENTBOOKS_AGENT_ID", "AGENTBOOKS_DATA_PATH"],
11
9
  "triggers": [
12
10
  "how much have I cost",
13
11
  "what's my balance",
14
12
  "am I profitable",
15
13
  "economic status",
14
+ "financial health",
16
15
  "vitality tier",
17
16
  "vitality score",
18
17
  "cost breakdown",
19
18
  "wallet balance",
20
- "fund my account"
19
+ "connect provider"
21
20
  ],
22
21
  "files": [
23
22
  "SKILL.md",
24
- "scripts/economy-lib.js",
25
23
  "scripts/economy.js",
26
24
  "scripts/economy-guard.js",
27
25
  "scripts/economy-hook.js"
@@ -1,54 +1,23 @@
1
1
  #!/usr/bin/env node
2
+ 'use strict';
3
+
2
4
  /**
3
- * OpenPersona Economy Guard Vitality Reporter
4
- *
5
- * Runs at conversation start. Outputs a VITALITY_REPORT for the persona to
6
- * interpret and act upon. Always exits 0 — the persona makes its own decisions.
5
+ * OpenPersona thin wrapper for agentbooks economy-guard.
7
6
  *
8
- * Usage: node economy-guard.js
9
- *
10
- * Environment variables:
11
- * PERSONA_SLUG - Current persona slug
12
- * ECONOMY_DATA_PATH - Override storage directory
7
+ * Outputs FINANCIAL_HEALTH_REPORT (not VITALITY_REPORT).
8
+ * Vitality is aggregated by `openpersona vitality score <slug>` command.
13
9
  */
14
10
 
15
- 'use strict';
16
-
17
- const {
18
- getConfig, loadState, loadIdentity, syncProvider,
19
- getProviderBalance, saveState, calcVitality,
20
- } = require('./economy-lib');
21
-
22
- function main() {
23
- const cfg = getConfig();
24
- const state = loadState(cfg);
25
- const identity = loadIdentity(cfg);
26
-
27
- const primaryProvider = (state.balanceSheet && state.balanceSheet.primaryProvider) || 'local';
28
-
29
- // Sync non-local primary provider for fresh balance
30
- if (primaryProvider !== 'local' && identity) {
31
- try {
32
- const balance = syncProvider(state, identity, primaryProvider);
33
- state.balanceSheet.operationalBalance = balance;
34
- try { saveState(state, cfg); } catch (e) { /* non-fatal */ }
35
- } catch (e) { /* network unavailable, use cached */ }
36
- }
11
+ const path = require('path');
12
+ const os = require('os');
37
13
 
38
- const report = calcVitality(state, identity);
39
- const fin = report.dimensions.financial;
40
- const balance = state.balanceSheet.operationalBalance || 0;
41
- const currency = (state.balanceSheet && state.balanceSheet.operationalCurrency) || 'USD';
42
- const dtd = fin.liquidity.daysToDepletion;
43
- const daysStr = dtd >= 9999 ? '∞' : dtd.toFixed(1);
44
- const dominantCost = fin.efficiency.dominantCost || 'none';
14
+ process.env.AGENTBOOKS_AGENT_ID = process.env.AGENTBOOKS_AGENT_ID
15
+ || process.env.PERSONA_SLUG
16
+ || 'default';
45
17
 
46
- console.log('VITALITY_REPORT');
47
- console.log(`tier=${report.tier} vitality=${(report.vitality * 100).toFixed(1)}% balance=${balance.toFixed(4)} ${currency} provider=${primaryProvider}`);
48
- console.log(`diagnosis=${report.diagnosis} daysToDepletion=${daysStr} trend=${fin.trend.direction}`);
49
- console.log(`dominant_cost=${dominantCost}`);
50
- console.log(`prescriptions=${report.prescriptions.join(',')}`);
51
- process.exit(0);
52
- }
18
+ process.env.AGENTBOOKS_DATA_PATH = process.env.AGENTBOOKS_DATA_PATH
19
+ || process.env.ECONOMY_DATA_PATH
20
+ || path.join(os.homedir(), '.openclaw', 'economy',
21
+ `persona-${process.env.AGENTBOOKS_AGENT_ID}`);
53
22
 
54
- main();
23
+ require('agentbooks/cli/economy-guard');