@agents-uni/zhenhuan 0.1.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.en.md ADDED
@@ -0,0 +1,547 @@
1
+ <p align="center">
2
+ <h1 align="center">zhenhuan-uni</h1>
3
+ <p align="center">
4
+ <strong>Agent competition system inspired by palace intrigue</strong>
5
+ </p>
6
+ <p align="center">
7
+ You are the Emperor. A horse-race framework where agents compete for your favor, ranked by ELO, driven to improve by competitive pressure. You judge, promote, and banish.
8
+ </p>
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="./README.md">中文</a> &bull;
13
+ <a href="#how-it-works">How It Works</a> &bull;
14
+ <a href="#quick-start">Quick Start</a> &bull;
15
+ <a href="#competition-mechanics">Competition</a> &bull;
16
+ <a href="#palace-system">Palace System</a> &bull;
17
+ <a href="#rest-api">API</a> &bull;
18
+ <a href="./DESIGN.md">Design Doc</a>
19
+ </p>
20
+
21
+ ---
22
+
23
+ ## Why?
24
+
25
+ Traditional multi-agent systems assign fixed roles to agents. This assumes we **already know** which agent is best for each job. We usually don't.
26
+
27
+ **zhenhuan-uni** takes a different approach: **let them compete, and let results decide**.
28
+
29
+ > Don't prescribe who's best. Set up the arena, define the rules, and let the cream rise to the top.
30
+
31
+ Built on [@agents-uni/core](https://github.com/agents-uni/core), it models a competitive hierarchy inspired by the Chinese palace drama "Legend of Zhen Huan" — where agents vie for rank, form alliances, betray rivals, and face elimination. Behind the metaphor is a rigorous competition framework applicable to:
32
+
33
+ - **Model selection** — multiple LLMs compete on the same task, ELO finds the best
34
+ - **Prompt optimization** — different prompt versions race head-to-head
35
+ - **Creative contests** — agents compete on open-ended tasks, judges pick winners
36
+ - **A/B testing** — continuous tournament-style evaluation
37
+ - **Team simulation** — pressure-test agent capabilities under competition
38
+
39
+ ## How It Works
40
+
41
+ ```
42
+ dispatchAndRace()
43
+ |
44
+ ┌────┴──────────────────────────────┐
45
+ │ TaskDispatcher writes TASK.md │
46
+ │ to each agent's OpenClaw workspace│
47
+ └────┬──────────────────────────────┘
48
+ |
49
+ +----+----+----+----+
50
+ | | | | |
51
+ A1 A2 A3 A4 A5 ← agents read TASK.md, execute, write SUBMISSION.md
52
+ | | | | |
53
+ +----+----+----+----+
54
+ |
55
+ ┌────┴───────────────────────┐
56
+ │ Poll & collect SUBMISSION.md│
57
+ └────┬───────────────────────┘
58
+ |
59
+ You (Emperor/User) ← score each submission via Dashboard/API
60
+ |
61
+ ELO Rating Update ← winners gain, losers drop
62
+ |
63
+ Season End?
64
+ yes → Promotion / Relegation / Update SOUL.md
65
+ no → Next Task
66
+ ```
67
+
68
+ ## Quick Start
69
+
70
+ ### Install
71
+
72
+ ```bash
73
+ npm install
74
+ ```
75
+
76
+ ### Start the server
77
+
78
+ ```bash
79
+ npm start
80
+ # or
81
+ npm run zhenhuan serve
82
+ ```
83
+
84
+ On startup, it prints the access URLs:
85
+
86
+ ```
87
+ ╔══════════════════════════════════════╗
88
+ ║ 甄嬛后宫 · Agent 赛马竞技系统 ║
89
+ ╚══════════════════════════════════════╝
90
+
91
+ Homepage: http://localhost:8089
92
+ API: http://localhost:8089/api
93
+ Manage: http://localhost:8089/manage
94
+ ```
95
+
96
+ Open the homepage in your browser to see project intro, deployed agents, relationship graph, and user guide.
97
+
98
+ ### Check palace status
99
+
100
+ ```bash
101
+ npm run zhenhuan status
102
+ ```
103
+
104
+ ### View ELO leaderboard
105
+
106
+ ```bash
107
+ npm run zhenhuan leaderboard
108
+ ```
109
+
110
+ ### Run a horse race (auto-dispatch)
111
+
112
+ ```typescript
113
+ import { PalaceOrchestrator } from 'zhenhuan-uni';
114
+
115
+ const orchestrator = await PalaceOrchestrator.fromSpec('universe.yaml');
116
+
117
+ // One call does it all: dispatch TASK.md → poll SUBMISSION.md → judge → ELO update
118
+ const { dispatch, race } = await orchestrator.dispatchAndRace(
119
+ {
120
+ id: 'task-001',
121
+ title: 'Write a haiku about spring',
122
+ description: 'Compose a haiku following the 5-7-5 syllable pattern',
123
+ criteria: [
124
+ { name: 'quality', weight: 0.4, description: 'Literary quality' },
125
+ { name: 'creativity', weight: 0.3, description: 'Originality' },
126
+ { name: 'speed', weight: 0.3, description: 'Completion speed' },
127
+ ],
128
+ timeoutMs: 60000, // 1 minute timeout
129
+ participants: ['zhenhuan', 'huafei', 'anlingrong'],
130
+ },
131
+ myJudgeFunction
132
+ );
133
+
134
+ console.log('Submitted:', dispatch.submissions.length, 'Timed out:', dispatch.timedOut);
135
+ console.log('Rankings:', race?.rankings); // ['zhenhuan', 'anlingrong', 'huafei']
136
+ console.log('ELO changes:', race?.eloChanges); // Map { 'zhenhuan' => +24, 'huafei' => -18, ... }
137
+ ```
138
+
139
+ **Under the hood**: `TaskDispatcher` writes `TASK.md` to each agent's OpenClaw workspace, polls for `SUBMISSION.md`, then feeds collected outputs to the horse race engine for scoring.
140
+
141
+ ### Manual race (without OpenClaw)
142
+
143
+ If you already have agent outputs, skip dispatch and score directly:
144
+
145
+ ```typescript
146
+ const result = await orchestrator.runHorseRace(
147
+ task,
148
+ [
149
+ { agentId: 'zhenhuan', output: 'Cherry blossoms fall...', completedAt: '...', duration: 5000 },
150
+ { agentId: 'huafei', output: 'Thunder shakes the earth...', completedAt: '...', duration: 3000 },
151
+ ],
152
+ myJudgeFunction
153
+ );
154
+ ```
155
+
156
+ ## Competition Mechanics
157
+
158
+ ### ELO Rating System
159
+
160
+ Every agent starts with a base ELO rating. After each race, ratings update based on actual vs expected performance:
161
+
162
+ | Tier | K-Factor | Description |
163
+ |------|----------|-------------|
164
+ | New (< 10 matches) | 48 | Fast calibration for newcomers |
165
+ | Regular | 32 | Normal volatility |
166
+ | Veteran (ELO > 1400) | 16 | Stable, hard-earned ratings |
167
+
168
+ ELO floor is **100** — no agent drops below this, preventing death spirals.
169
+
170
+ ### Horse Race
171
+
172
+ Multiple agents receive the **same task** simultaneously. You (the Emperor) score each submission across weighted criteria (quality, creativity, speed, collaboration, strategy). ELO updates happen pairwise between all participants.
173
+
174
+ ### Season System
175
+
176
+ Competitions are organized into seasons (default: 30 days):
177
+
178
+ ```
179
+ Season Start --> Multiple Races --> Monthly Court Assembly --> Season End
180
+ |
181
+ +----------+-----------+
182
+ | | |
183
+ Top 20% Middle Bottom 15%
184
+ Promoted Unchanged Relegated
185
+ ```
186
+
187
+ Season rewards:
188
+ - 1st place: 100 favor points
189
+ - 2nd place: 60 favor points
190
+ - 3rd place: 30 favor points
191
+
192
+ ## Palace System
193
+
194
+ The palace metaphor maps to concrete competitive mechanics:
195
+
196
+ ### Rank Hierarchy (8 levels)
197
+
198
+ | Rank | Title | Max Slots | Monthly Stipend | Min ELO |
199
+ |------|-------|-----------|-----------------|---------|
200
+ | 8 | Queen | 1 | 1000 | 1600 |
201
+ | 7 | Imperial Noble Consort | 1 | 800 | 1500 |
202
+ | 6 | Noble Consort | 2 | 400 | 1400 |
203
+ | 5 | Consort | 4 | 200 | 1300 |
204
+ | 4 | Concubine | 6 | 100 | 1200 |
205
+ | 3 | Noble Lady | 6 | 50 | 1100 |
206
+ | 2 | First Attendant | unlimited | 20 | 1000 |
207
+ | 1 | Answering | unlimited | 10 | 0 |
208
+
209
+ **Slot limits create structural scarcity** — high ELO alone isn't enough; you need an opening.
210
+
211
+ ### Resources
212
+
213
+ | Resource | Type | Distribution | Purpose |
214
+ |----------|------|-------------|---------|
215
+ | Imperial Favor | Finite | Competitive | Core influence metric, **decays 5% monthly** |
216
+ | Monthly Stipend | Renewable | By rank | Baseline resource allocation |
217
+ | Palace Assignment | Positional | By rank | Status symbol, 12 total |
218
+ | Attendants | Finite | By merit | 100 total, allocated by performance |
219
+
220
+ Favor decay means **past glory fades** — agents must keep performing to maintain influence.
221
+
222
+ ### Power Dynamics
223
+
224
+ - **Alliances**: agents can ally for mutual influence boost
225
+ - **Betrayals**: allies can turn rival, creating enmity
226
+ - **Factions**: BFS-discovered alliance clusters with collective influence
227
+ - **Influence formula**: `rank + allies * 0.3 + favor * 0.1 - rivals * 5`
228
+
229
+ ### Cold Palace (Elimination Zone)
230
+
231
+ Underperforming agents face banishment:
232
+
233
+ - **Temporary**: serves a sentence, auto-released on expiry
234
+ - **Indefinite**: awaits your pardon
235
+ - **Permanent**: eliminated from competition entirely
236
+
237
+ ## REST API
238
+
239
+ Start the server with `npm start`, then:
240
+
241
+ ```
242
+ GET /api/state # Full palace state
243
+ GET /api/leaderboard # ELO rankings
244
+ GET /api/agents # All agents
245
+ GET /api/agents/:id # Agent profile
246
+
247
+ POST /api/race/dispatch # 🆕 Auto-dispatch race (TASK.md → SUBMISSION.md → judge)
248
+ POST /api/race/evaluate # Manual race evaluation
249
+ GET /api/race/history # Race history
250
+
251
+ POST /api/ceremony/court-assembly # Monthly review
252
+ POST /api/ceremony/selection # 🆕 Selection (one-click agent registration)
253
+ GET /api/ceremony/history # Ceremony history
254
+
255
+ POST /api/agents/register # 🆕 Register agents in openclaw.json
256
+
257
+ POST /api/alliance # Form alliance
258
+ GET /api/factions # View factions
259
+
260
+ POST /api/cold-palace/banish # Banish an agent
261
+ POST /api/cold-palace/rehabilitate # Rehabilitate an agent
262
+ GET /api/cold-palace # Cold palace inmates
263
+
264
+ GET /api/resources/:agentId # Resource summary
265
+ POST /api/resources/favor # Grant favor
266
+
267
+ POST /api/season/start # Start new season
268
+ GET /api/season # View all seasons
269
+ ```
270
+
271
+ ### Example: Auto-dispatch Race
272
+
273
+ ```bash
274
+ curl -X POST http://localhost:8089/api/race/dispatch \
275
+ -H 'Content-Type: application/json' \
276
+ -d '{
277
+ "task": {
278
+ "id": "race-001",
279
+ "title": "Write a strategy essay",
280
+ "description": "Write a 500-word essay on improving team efficiency",
281
+ "criteria": [{"name": "quality", "weight": 0.6, "description": "Depth"}, {"name": "creativity", "weight": 0.4, "description": "Originality"}],
282
+ "timeoutMs": 120000,
283
+ "participants": ["zhenhuan", "huafei", "anlingrong"]
284
+ }
285
+ }'
286
+ ```
287
+
288
+ The server will:
289
+ 1. Write `TASK.md` to each participant's OpenClaw workspace
290
+ 2. Poll for `SUBMISSION.md` until timeout
291
+ 3. Score collected submissions via the built-in judge
292
+ 4. Return rankings and ELO changes
293
+
294
+ ## CLI
295
+
296
+ ```bash
297
+ # Start the server (default port 8089, prints homepage URL on startup)
298
+ npm run zhenhuan serve
299
+
300
+ # View palace status (ranks, ELO, favor)
301
+ npm run zhenhuan status
302
+
303
+ # View ELO leaderboard
304
+ npm run zhenhuan leaderboard
305
+
306
+ # Conduct a court assembly (monthly review)
307
+ npm run zhenhuan court
308
+
309
+ # 🆕 Selection — one-click register a new agent
310
+ npm run zhenhuan select --id new-agent --name "New Consort" --role Answering
311
+
312
+ # Also register in openclaw.json
313
+ npm run zhenhuan select --id new-agent --name "New Consort" --register
314
+ ```
315
+
316
+ ## Roles
317
+
318
+ ### The Emperor (You)
319
+
320
+ You are the Emperor — not an AI agent, but the **user** controlling everything through Dashboard / API / CLI. Your powers:
321
+ - 🏇 **Launch races** — dispatch tasks, let consorts compete
322
+ - ⚖️ **Judge results** — review submissions, assign scores
323
+ - 📈 **Promote / Demote** — adjust ranks at court assemblies
324
+ - 💝 **Grant favor** — reward outstanding consorts
325
+ - 🏚️ **Banish** — send underperformers to the cold palace
326
+ - 🔄 **Pardon** — rehabilitate banished consorts
327
+
328
+ ### Built-in Consorts (AI Agents)
329
+
330
+ | Agent | Role | Personality |
331
+ |-------|------|-------------|
332
+ | **Empress (Yixiu)** | Palace Manager | Deep strategist, controls palace order |
333
+ | **Zhen Huan** | Competitor | Strategic, adaptive, strong at collaboration |
334
+ | **Hua Fei** | Competitor | Aggressive, fast executor, dominant style |
335
+ | **An Lingrong** | Competitor | Detail-oriented, excels in niche tasks |
336
+ | **Shen Meizhuang** | Competitor | Steady, high-quality output, loyal ally |
337
+ | **Qi Fei** | Competitor | Simple, straightforward, maternal drive |
338
+ | **Duan Fei** | Competitor | Patient observer, perceptive |
339
+
340
+ Each consort has a SOUL.md definition in `src/agents/souls/` compatible with OpenClaw.
341
+
342
+ ## OpenClaw Integration
343
+
344
+ zhenhuan-uni integrates with [OpenClaw](https://github.com/anthropics/openclaw) through a **file-based protocol**. Agents communicate via Markdown files in their workspace directories — no HTTP required from the agent side.
345
+
346
+ ### File Protocol
347
+
348
+ ```
349
+ Complete OpenClaw directory structure:
350
+ ~/.openclaw/
351
+ ├── openclaw.json ← agent registry (workspace + agentDir)
352
+ ├── agents/
353
+ │ └── zhenhuan/
354
+ │ ├── agent/ ← runtime config (auth-profiles.json etc.)
355
+ │ └── sessions/ ← session history
356
+ └── workspace-zhenhuan/
357
+ ├── SOUL.md ← deployed once (agent persona)
358
+ ├── TASK.md ← written per race (task description, by TaskDispatcher)
359
+ └── SUBMISSION.md ← written by agent after execution (collected by TaskDispatcher)
360
+ ```
361
+
362
+ - **SOUL.md** — agent identity/personality/relationships, generated by `uni deploy`
363
+ - **TASK.md** — race task description, written by `TaskDispatcher`
364
+ - **SUBMISSION.md** — agent output, written by agent, polled by `TaskDispatcher`
365
+ - **agents/{id}/agent/** — agent runtime config directory, created by `deployToOpenClaw`
366
+ - **agents/{id}/sessions/** — agent session history directory, created by `deployToOpenClaw`
367
+ - **openclaw.json** — agent registry with both `workspace` and `agentDir` path fields
368
+
369
+ ### Full Pipeline
370
+
371
+ ```
372
+ universe.yaml
373
+ │ uni deploy
374
+
375
+ SOUL.md × N → OpenClaw workspaces
376
+
377
+ dispatchAndRace()
378
+
379
+ ├─ 1. TaskDispatcher writes TASK.md to each participant's workspace
380
+
381
+ ├─ 2. Agent reads TASK.md → executes → writes SUBMISSION.md
382
+
383
+ ├─ 3. TaskDispatcher polls SUBMISSION.md until timeout
384
+
385
+ ├─ 4. HorseRaceEngine scores → ELO update → promotion/demotion
386
+
387
+ └─ 5. Regenerate SOUL.md with updated rank info
388
+ ```
389
+
390
+ ### Deploy Agents to OpenClaw
391
+
392
+ ```bash
393
+ # One-command deploy
394
+ npx uni deploy universe.yaml
395
+
396
+ # Custom directory
397
+ npx uni deploy universe.yaml --dir ~/.openclaw
398
+
399
+ # Dry run (preview only)
400
+ npx uni deploy universe.yaml --dry-run
401
+ ```
402
+
403
+ Or use pre-built SOUL.md files (hand-tuned with richer personality descriptions):
404
+
405
+ ```bash
406
+ cp src/agents/souls/zhenhuan.md ~/.openclaw/workspace-zhenhuan/SOUL.md
407
+ cp src/agents/souls/huafei.md ~/.openclaw/workspace-huafei/SOUL.md
408
+ ```
409
+
410
+ ### One-Click Race
411
+
412
+ ```typescript
413
+ import { PalaceOrchestrator } from 'zhenhuan-uni';
414
+
415
+ const orchestrator = await PalaceOrchestrator.fromSpec('universe.yaml');
416
+
417
+ // Auto: write TASK.md → poll SUBMISSION.md → judge → ELO update
418
+ const { dispatch, race } = await orchestrator.dispatchAndRace(
419
+ {
420
+ id: 'race-001',
421
+ title: 'Strategy Essay',
422
+ description: 'Write a 500-word essay on improving collaboration efficiency',
423
+ criteria: [{ name: 'quality', weight: 0.6, description: 'Content depth' }],
424
+ timeoutMs: 120000,
425
+ participants: ['zhenhuan', 'huafei', 'anlingrong'],
426
+ },
427
+ judgeFunction
428
+ );
429
+
430
+ // Or via HTTP API
431
+ // POST /api/race/dispatch
432
+ ```
433
+
434
+ > 📖 Full integration tutorial: [OPENCLAW_INTEGRATION_GUIDE.md](https://github.com/agents-uni/zhenhuan/blob/main/OPENCLAW_INTEGRATION_GUIDE.md)
435
+
436
+ ## Dashboard Integration
437
+
438
+ zhenhuan-uni integrates deeply with the agents-uni-core Dashboard, providing a unified web UI for managing the palace system.
439
+
440
+ ### Auto-Registration
441
+
442
+ `zhenhuan serve` automatically registers the palace universe in `~/.openclaw/uni-registry.json` on startup. The `deploy` command also auto-registers via the `specPath` option.
443
+
444
+ `zhenhuan serve` starts with the agents-uni-core Dashboard built in. Visit `http://localhost:8089` to see:
445
+
446
+ - **Project Intro** — system architecture overview, quick start guide
447
+ - **Deployed Unis** — all registered universe cards, click to view details
448
+ - **Agent List** — each agent's rank, SOUL.md status, task status
449
+ - **Relationship Graph** — superior/competitive/alliance relationships
450
+ - **User Guide** — complete usage guide at `http://localhost:8089/guide`
451
+ - **Management** — reset/cleanup/update operations at `http://localhost:8089/manage`
452
+
453
+ ### Extending the Dashboard
454
+
455
+ On startup, zhenhuan-uni automatically injects palace-specific panels (ELO leaderboard, factions, ranks) into the core Dashboard via the `DashboardExtension` interface:
456
+
457
+ ```typescript
458
+ import { Hono } from 'hono';
459
+ import { startDashboard } from '@agents-uni/core';
460
+ import type { DashboardExtension, PanelDefinition } from '@agents-uni/core';
461
+
462
+ // Create palace extension routes
463
+ const extRoutes = new Hono();
464
+ extRoutes.get('/leaderboard', (c) => c.json(orchestrator.getLeaderboard()));
465
+ extRoutes.get('/factions', (c) => c.json(orchestrator.dynamics.getFactions()));
466
+ extRoutes.get('/state', (c) => c.json(orchestrator.getState()));
467
+
468
+ // Define homepage panels
469
+ const panels: PanelDefinition[] = [
470
+ { title: '🏆 ELO Leaderboard', renderHtml: () => '<table>...</table>' },
471
+ { title: '⚔️ Factions', renderHtml: () => '<div>...</div>' },
472
+ { title: '🏛️ Palace Ranks', renderHtml: () => '<div>...</div>' },
473
+ ];
474
+
475
+ const extension: DashboardExtension = {
476
+ uniId: 'zhenhuan-palace',
477
+ routes: extRoutes, // Mounted at /ext/zhenhuan-palace/
478
+ panels, // Displayed on homepage
479
+ };
480
+
481
+ await startDashboard({ port: 8089, extensions: [extension] });
482
+ ```
483
+
484
+ ## Architecture
485
+
486
+ ```
487
+ +-------------------------------------------------------+
488
+ | PalaceOrchestrator |
489
+ | (Central Coordination) |
490
+ +-----+-------------+-------------+---------------------+
491
+ | | | |
492
+ +-----+------+ +----+------+ +---+--------+ +--+-------------+
493
+ | Competition| | Palace | | Evolution | | OpenClaw Bridge|
494
+ +------------+ +-----------+ +------------+ +----------------+
495
+ | EloArena | | Ranks | | Performance| | TaskDispatcher |
496
+ | HorseRace | | Resources | | Tracker | | FileWorkspaceIO|
497
+ | Season | | Dynamics | | (from core)| | SoulGenerator |
498
+ | | | Ceremonies| | | | |
499
+ | | | ColdPalace| | | | |
500
+ +------------+ +-----------+ +------------+ +----------------+
501
+ | |
502
+ agents-uni-core OpenClaw workspaces
503
+ (Universe / Registry / Graph / (SOUL.md / TASK.md
504
+ StateMachine / EventBus / ...) / SUBMISSION.md)
505
+ ```
506
+
507
+ ## Project Structure
508
+
509
+ ```
510
+ zhenhuan-uni/
511
+ src/
512
+ competition/ # ELO arena, horse race engine, season system
513
+ palace/ # Ranks, resources, dynamics, ceremonies, cold palace
514
+ orchestrator/ # Central coordination engine
515
+ server/ # Hono HTTP API server
516
+ cli/ # Command-line interface
517
+ agents/souls/ # SOUL.md definitions for built-in agents
518
+ universe.yaml # Full palace universe specification
519
+ DESIGN.md # Detailed design document
520
+ ```
521
+
522
+ ## Development
523
+
524
+ ```bash
525
+ # Install dependencies
526
+ npm install
527
+
528
+ # Type check
529
+ npx tsc --noEmit
530
+
531
+ # Run tests
532
+ npm test
533
+
534
+ # Start dev server (watch mode)
535
+ npm run dev
536
+
537
+ # Build
538
+ npm run build
539
+ ```
540
+
541
+ ## Related Projects
542
+
543
+ - [**agents-uni-core**](../agents-uni-core) — The universal protocol layer this project is built on
544
+
545
+ ## License
546
+
547
+ MIT