@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/DESIGN.md +198 -0
- package/LICENSE +21 -0
- package/README.en.md +547 -0
- package/README.md +549 -0
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.js +253 -0
- package/dist/competition/elo.d.ts +62 -0
- package/dist/competition/elo.js +146 -0
- package/dist/competition/horse-race.d.ts +72 -0
- package/dist/competition/horse-race.js +110 -0
- package/dist/competition/index.d.ts +6 -0
- package/dist/competition/index.js +3 -0
- package/dist/competition/season.d.ts +68 -0
- package/dist/competition/season.js +150 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +21 -0
- package/dist/orchestrator/index.d.ts +142 -0
- package/dist/orchestrator/index.js +268 -0
- package/dist/palace/ceremonies.d.ts +55 -0
- package/dist/palace/ceremonies.js +263 -0
- package/dist/palace/cold-palace.d.ts +41 -0
- package/dist/palace/cold-palace.js +106 -0
- package/dist/palace/dynamics.d.ts +52 -0
- package/dist/palace/dynamics.js +192 -0
- package/dist/palace/ranks.d.ts +31 -0
- package/dist/palace/ranks.js +46 -0
- package/dist/palace/resources.d.ts +55 -0
- package/dist/palace/resources.js +146 -0
- package/dist/server/index.d.ts +14 -0
- package/dist/server/index.js +202 -0
- package/dist/server/routes/index.d.ts +6 -0
- package/dist/server/routes/index.js +287 -0
- package/package.json +66 -0
- package/universe.yaml +365 -0
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> •
|
|
13
|
+
<a href="#how-it-works">How It Works</a> •
|
|
14
|
+
<a href="#quick-start">Quick Start</a> •
|
|
15
|
+
<a href="#competition-mechanics">Competition</a> •
|
|
16
|
+
<a href="#palace-system">Palace System</a> •
|
|
17
|
+
<a href="#rest-api">API</a> •
|
|
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
|