@robbiesrobotics/alice-agents 1.5.9 → 1.5.11
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 +152 -132
- package/bin/alice-install.mjs +27 -35
- package/lib/hermes-agent.mjs +449 -0
- package/lib/hermes-installer.mjs +338 -0
- package/lib/installer.mjs +302 -22
- package/lib/runtime-installer.mjs +314 -0
- package/lib/skills.mjs +128 -4
- package/package.json +3 -3
- package/templates/workspaces/_shared/AGENTS-hermes.md +54 -0
- package/templates/workspaces/_shared/AGENTS.md +25 -0
- package/templates/workspaces/_shared/SOUL-hermes.md +35 -0
- package/templates/workspaces/_shared/hermes-agent-skill.md +40 -0
- package/templates/workspaces/_shared/hermes-orchestrator-skill.md +150 -0
- package/templates/workspaces/_shared/hermes-specialist-skill.md +109 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* runtime-installer.mjs — Auto-install missing runtimes for A.L.I.C.E.
|
|
3
|
+
*
|
|
4
|
+
* Handles detecting, offering to install, and installing:
|
|
5
|
+
* - Hermes Agent (Nous Research)
|
|
6
|
+
* - OpenClaw
|
|
7
|
+
* - NemoClaw (NVIDIA)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { execSync } from 'node:child_process';
|
|
11
|
+
import { existsSync } from 'node:fs';
|
|
12
|
+
import { homedir } from 'node:os';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { confirm, choose } from './prompter.mjs';
|
|
15
|
+
|
|
16
|
+
// ── Colors / icons (duplicated from installer.mjs to avoid circular imports) ──
|
|
17
|
+
const cyan = (s) => `\x1b[36m${s}\x1b[0m`;
|
|
18
|
+
const green = (s) => `\x1b[32m${s}\x1b[0m`;
|
|
19
|
+
const greenBold = (s) => `\x1b[1m\x1b[32m${s}\x1b[0m`;
|
|
20
|
+
const yellow = (s) => `\x1b[33m${s}\x1b[0m`;
|
|
21
|
+
const red = (s) => `\x1b[31m${s}\x1b[0m`;
|
|
22
|
+
const dim = (s) => `\x1b[2m${s}\x1b[0m`;
|
|
23
|
+
const bold = (s) => `\x1b[1m${s}\x1b[0m`;
|
|
24
|
+
const icons = { ok: '✔', fail: '✗', info: 'ℹ', warn: '⚠' };
|
|
25
|
+
|
|
26
|
+
// ── Runtime definitions ──────────────────────────────────────────────────────
|
|
27
|
+
|
|
28
|
+
const RUNTIMES = {
|
|
29
|
+
hermes: {
|
|
30
|
+
name: 'Hermes Agent',
|
|
31
|
+
maker: 'Nous Research',
|
|
32
|
+
emoji: '🧠',
|
|
33
|
+
tagline: 'Self-improving personal AI agent',
|
|
34
|
+
description: [
|
|
35
|
+
'Lightweight — runs on laptops, VPS, even Android.',
|
|
36
|
+
'Self-improving — creates skills from experience, remembers across sessions.',
|
|
37
|
+
'A.L.I.C.E. becomes a team of Hermes skills.',
|
|
38
|
+
],
|
|
39
|
+
installTime: '~2 minutes',
|
|
40
|
+
platforms: ['Linux', 'macOS', 'WSL2', 'Android/Termux'],
|
|
41
|
+
requiresDocker: false,
|
|
42
|
+
modelCommand: 'hermes model',
|
|
43
|
+
docsUrl: 'https://hermes-agent.nousresearch.com/docs/',
|
|
44
|
+
getInstallCommand() {
|
|
45
|
+
return 'curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash';
|
|
46
|
+
},
|
|
47
|
+
isInstalled() {
|
|
48
|
+
const hermesConfig = join(homedir(), '.hermes', 'config.yaml');
|
|
49
|
+
if (!existsSync(hermesConfig)) return false;
|
|
50
|
+
try {
|
|
51
|
+
execSync('hermes version', { stdio: 'pipe' });
|
|
52
|
+
return true;
|
|
53
|
+
} catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
getPostInstallSteps() {
|
|
58
|
+
return [
|
|
59
|
+
`Reload your shell: ${cyan('source ~/.bashrc')} ${dim('(or ~/.zshrc)')}`,
|
|
60
|
+
`Pick a model: ${cyan('hermes model')}`,
|
|
61
|
+
`Re-run A.L.I.C.E.: ${cyan('npx @robbiesrobotics/alice-agents')}`,
|
|
62
|
+
];
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
openclaw: {
|
|
67
|
+
name: 'OpenClaw',
|
|
68
|
+
maker: 'OpenClaw',
|
|
69
|
+
emoji: '🤖',
|
|
70
|
+
tagline: 'Mature multi-agent orchestration platform',
|
|
71
|
+
description: [
|
|
72
|
+
'Full agent workspaces, subagent spawning, cron, MCP support.',
|
|
73
|
+
'15+ messaging platforms. Mature ecosystem with ClawHub skills.',
|
|
74
|
+
'A.L.I.C.E. becomes an agent workspace tree.',
|
|
75
|
+
],
|
|
76
|
+
installTime: '~3 minutes',
|
|
77
|
+
platforms: ['Linux', 'macOS', 'Windows', 'WSL2'],
|
|
78
|
+
requiresDocker: false,
|
|
79
|
+
modelCommand: 'openclaw configure',
|
|
80
|
+
docsUrl: 'https://docs.openclaw.ai',
|
|
81
|
+
getInstallCommand() {
|
|
82
|
+
return 'npm install -g openclaw';
|
|
83
|
+
},
|
|
84
|
+
isInstalled() {
|
|
85
|
+
try {
|
|
86
|
+
execSync('openclaw --version', { stdio: 'pipe' });
|
|
87
|
+
return true;
|
|
88
|
+
} catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
getPostInstallSteps() {
|
|
93
|
+
return [
|
|
94
|
+
`Set up your model: ${cyan('openclaw configure')}`,
|
|
95
|
+
`Re-run A.L.I.C.E.: ${cyan('npx @robbiesrobotics/alice-agents')}`,
|
|
96
|
+
];
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
nemoclaw: {
|
|
101
|
+
name: 'NemoClaw',
|
|
102
|
+
maker: 'NVIDIA',
|
|
103
|
+
emoji: '🛡️',
|
|
104
|
+
tagline: 'Enterprise-grade agents with sandboxing',
|
|
105
|
+
description: [
|
|
106
|
+
'Agents run isolated — Landlock + seccomp + network namespace sandboxing.',
|
|
107
|
+
'Built on OpenClaw, hardened by NVIDIA. Best for sensitive data.',
|
|
108
|
+
'A.L.I.C.E. runs inside the OpenShell sandbox.',
|
|
109
|
+
],
|
|
110
|
+
installTime: '~20-30 minutes',
|
|
111
|
+
platforms: ['Linux', 'macOS (Docker)', 'DGX Spark', 'WSL2'],
|
|
112
|
+
requiresDocker: true,
|
|
113
|
+
modelCommand: '(configured during install)',
|
|
114
|
+
docsUrl: 'https://docs.nvidia.com/nemoclaw/latest/',
|
|
115
|
+
getInstallCommand() {
|
|
116
|
+
return 'curl -fsSL https://www.nvidia.com/nemoclaw.sh | bash';
|
|
117
|
+
},
|
|
118
|
+
isInstalled() {
|
|
119
|
+
try {
|
|
120
|
+
execSync('nemoclaw --version', { stdio: 'pipe' });
|
|
121
|
+
return true;
|
|
122
|
+
} catch {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
getPostInstallSteps() {
|
|
127
|
+
return [
|
|
128
|
+
`NemoClaw configures your model during onboard.`,
|
|
129
|
+
`Connect: ${cyan('nemoclaw <name> connect')}`,
|
|
130
|
+
`Re-run A.L.I.C.E.: ${cyan('npx @robbiesrobotics/alice-agents --runtime nemoclaw')}`,
|
|
131
|
+
];
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// ── Public API ───────────────────────────────────────────────────────────────
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Show the runtime selection wizard and install the chosen runtime.
|
|
140
|
+
* Returns the runtime key ('hermes' | 'openclaw' | 'nemoclaw') or null if user skips.
|
|
141
|
+
*/
|
|
142
|
+
export async function promptAndInstallRuntime(forceRuntime = null) {
|
|
143
|
+
// If user specified --runtime X but it's not installed, install that one
|
|
144
|
+
if (forceRuntime && RUNTIMES[forceRuntime]) {
|
|
145
|
+
return await installSpecificRuntime(forceRuntime);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// No runtime at all — show the full wizard
|
|
149
|
+
printRuntimeWizard();
|
|
150
|
+
|
|
151
|
+
const choice = await choose(
|
|
152
|
+
' Which runtime do you want to install?',
|
|
153
|
+
['1', '2', '3', 'skip'],
|
|
154
|
+
'1'
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const map = { '1': 'hermes', '2': 'openclaw', '3': 'nemoclaw' };
|
|
158
|
+
const picked = map[choice];
|
|
159
|
+
|
|
160
|
+
if (!picked) {
|
|
161
|
+
console.log(`\n ${dim('Skipped. Install a runtime manually and re-run this installer.')}\n`);
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return await installSpecificRuntime(picked);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Install a specific runtime, show progress, verify, and return the key.
|
|
170
|
+
*/
|
|
171
|
+
async function installSpecificRuntime(key) {
|
|
172
|
+
const rt = RUNTIMES[key];
|
|
173
|
+
if (!rt) return null;
|
|
174
|
+
|
|
175
|
+
// Pre-flight checks
|
|
176
|
+
if (rt.requiresDocker) {
|
|
177
|
+
const dockerOk = checkDockerAvailable();
|
|
178
|
+
if (!dockerOk) {
|
|
179
|
+
console.log(`\n ${icons.warn} ${yellow('Docker is required for ' + rt.name + ' but does not appear to be running.')}`);
|
|
180
|
+
console.log(` Start Docker (or Colima on macOS) and try again.\n`);
|
|
181
|
+
console.log(` ${dim('Docs: ' + rt.docsUrl)}\n`);
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (key === 'nemoclaw') {
|
|
187
|
+
const platform = process.platform;
|
|
188
|
+
if (platform === 'darwin') {
|
|
189
|
+
console.log(`\n ${icons.warn} ${yellow('NemoClaw on macOS requires Docker Desktop or Colima.')}`);
|
|
190
|
+
console.log(` ${dim('Make sure one is running before proceeding.')}`);
|
|
191
|
+
const ok = await confirm(' Continue with NemoClaw install?', false);
|
|
192
|
+
if (!ok) return null;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Confirm
|
|
197
|
+
console.log(`\n ${bold(rt.emoji + ' Installing ' + rt.name + ' (' + rt.installTime + ')')}\n`);
|
|
198
|
+
console.log(` ${dim(rt.getInstallCommand())}\n`);
|
|
199
|
+
|
|
200
|
+
const ok = await confirm(' Proceed?', true);
|
|
201
|
+
if (!ok) return null;
|
|
202
|
+
|
|
203
|
+
// Run install
|
|
204
|
+
console.log('');
|
|
205
|
+
try {
|
|
206
|
+
execSync(rt.getInstallCommand(), { stdio: 'inherit', timeout: 10 * 60 * 1000 }); // 10 min timeout
|
|
207
|
+
} catch (err) {
|
|
208
|
+
console.log(`\n ${icons.fail} ${red('Installation failed.')}`);
|
|
209
|
+
console.log(` Install manually: ${cyan(rt.getInstallCommand())}`);
|
|
210
|
+
console.log(` Docs: ${dim(rt.docsUrl)}\n`);
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Verify
|
|
215
|
+
console.log('');
|
|
216
|
+
if (rt.isInstalled()) {
|
|
217
|
+
console.log(` ${icons.ok} ${green(rt.name + ' installed successfully!')}`);
|
|
218
|
+
} else {
|
|
219
|
+
console.log(` ${icons.warn} ${yellow('Install completed but ' + rt.name + ' not detected in PATH.')}`);
|
|
220
|
+
console.log(` You may need to reload your shell: ${cyan('source ~/.bashrc')}`);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Post-install steps
|
|
224
|
+
const steps = rt.getPostInstallSteps();
|
|
225
|
+
if (steps.length) {
|
|
226
|
+
console.log(`\n ${bold('Next steps:')}`);
|
|
227
|
+
for (const step of steps) {
|
|
228
|
+
console.log(` ${step}`);
|
|
229
|
+
}
|
|
230
|
+
console.log('');
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return key;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Check if Docker is available and running.
|
|
238
|
+
*/
|
|
239
|
+
function checkDockerAvailable() {
|
|
240
|
+
try {
|
|
241
|
+
execSync('docker info', { stdio: 'pipe' });
|
|
242
|
+
return true;
|
|
243
|
+
} catch {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Check if any supported runtime is installed.
|
|
250
|
+
* Returns the runtime key or null.
|
|
251
|
+
*/
|
|
252
|
+
export function detectAnyRuntime() {
|
|
253
|
+
for (const [key, rt] of Object.entries(RUNTIMES)) {
|
|
254
|
+
if (rt.isInstalled()) return key;
|
|
255
|
+
}
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Get runtime info object.
|
|
261
|
+
*/
|
|
262
|
+
export function getRuntimeInfo(key) {
|
|
263
|
+
return RUNTIMES[key] || null;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Print the runtime selection wizard.
|
|
268
|
+
*/
|
|
269
|
+
function printRuntimeWizard() {
|
|
270
|
+
console.log('');
|
|
271
|
+
console.log(' ╭─ Choose Your Runtime ───────────────────────────────────────╮');
|
|
272
|
+
console.log(' │ │');
|
|
273
|
+
console.log(' │ A.L.I.C.E. needs a runtime to manage your agent team. │');
|
|
274
|
+
console.log(' │ │');
|
|
275
|
+
console.log(' │ Three options — they work great together too: │');
|
|
276
|
+
console.log(' │ │');
|
|
277
|
+
console.log(' │ 1. 🧠 Hermes Agent (recommended) │');
|
|
278
|
+
console.log(' │ Self-improving personal AI agent by Nous Research. │');
|
|
279
|
+
console.log(' │ Lightweight, runs anywhere — laptop, VPS, phone. │');
|
|
280
|
+
console.log(' │ A.L.I.C.E. becomes a team of Hermes skills. │');
|
|
281
|
+
console.log(' │ Install: ~2 minutes │');
|
|
282
|
+
console.log(' │ │');
|
|
283
|
+
console.log(' │ 2. 🤖 OpenClaw │');
|
|
284
|
+
console.log(' │ Mature multi-agent orchestration platform. │');
|
|
285
|
+
console.log(' │ Agent workspaces, subagent spawning, cron, MCP. │');
|
|
286
|
+
console.log(' │ A.L.I.C.E. becomes an agent workspace tree. │');
|
|
287
|
+
console.log(' │ Install: ~3 minutes │');
|
|
288
|
+
console.log(' │ │');
|
|
289
|
+
console.log(' │ 3. 🛡️ NemoClaw (NVIDIA) │');
|
|
290
|
+
console.log(' │ Enterprise-grade OpenClaw with OpenShell sandboxing. │');
|
|
291
|
+
console.log(' │ Agents run isolated — Landlock + seccomp + netns. │');
|
|
292
|
+
console.log(' │ Best for teams handling sensitive data. │');
|
|
293
|
+
console.log(' │ Requires Docker · Install: ~20-30 minutes │');
|
|
294
|
+
console.log(' │ │');
|
|
295
|
+
console.log(' │ Not sure? Start with Hermes — it\'s the fastest path. │');
|
|
296
|
+
console.log(' │ You can add OpenClaw or NemoClaw later. │');
|
|
297
|
+
console.log(' │ │');
|
|
298
|
+
console.log(' ╰─────────────────────────────────────────────────────────────╯');
|
|
299
|
+
console.log('');
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Print "runtime not detected" message (used before the wizard).
|
|
304
|
+
*/
|
|
305
|
+
export function printNoRuntimeDetected() {
|
|
306
|
+
console.log('');
|
|
307
|
+
console.log(` ${icons.warn} ${yellow('No supported runtime detected')}`);
|
|
308
|
+
console.log('');
|
|
309
|
+
console.log(' A.L.I.C.E. requires one of:');
|
|
310
|
+
console.log(` ${cyan('1.')} Hermes Agent ${dim('— personal AI agent, self-improving')}`);
|
|
311
|
+
console.log(` ${cyan('2.')} OpenClaw ${dim('— multi-agent orchestration, mature ecosystem')}`);
|
|
312
|
+
console.log(` ${cyan('3.')} NemoClaw ${dim('— enterprise sandboxed agents (NVIDIA)')}`);
|
|
313
|
+
console.log('');
|
|
314
|
+
}
|
package/lib/skills.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import { readManifest, writeManifest } from './manifest.mjs';
|
|
|
9
9
|
import { icons, greenBold, green, red, yellow, cyan, dim, bold,
|
|
10
10
|
printSection, printSeparator, printBox, printStepDone,
|
|
11
11
|
printStepFail, printStepSkip, separator } from './colors.mjs';
|
|
12
|
-
import { confirm, choose, closePrompt } from './prompter.mjs';
|
|
12
|
+
import { confirm, choose, input, closePrompt } from './prompter.mjs';
|
|
13
13
|
|
|
14
14
|
const OPENCLAW_DIR = join(homedir(), '.openclaw');
|
|
15
15
|
const SKILLS_DIR = join(OPENCLAW_DIR, 'skills');
|
|
@@ -63,6 +63,17 @@ export const SKILL_CATALOG = [
|
|
|
63
63
|
{ id: 'blucli', label: 'BluOS', desc: 'BluOS audio system control' },
|
|
64
64
|
],
|
|
65
65
|
},
|
|
66
|
+
{
|
|
67
|
+
category: 'Hermes Specialists 🤖',
|
|
68
|
+
icon: '🤖',
|
|
69
|
+
skills: [
|
|
70
|
+
// NOTE: Hermes agents are created and managed via the "Manage Hermes agents"
|
|
71
|
+
// option in the skills manager. Dynamically registered agents are shown
|
|
72
|
+
// separately above. This category is for informational purposes only.
|
|
73
|
+
// Users should run: npx @robbiesrobotics/alice-agents --skills
|
|
74
|
+
// and choose "Manage Hermes agents" to create new Hermes agents.
|
|
75
|
+
],
|
|
76
|
+
},
|
|
66
77
|
];
|
|
67
78
|
|
|
68
79
|
// Egress endpoints needed per skill beyond NemoClaw baseline
|
|
@@ -76,6 +87,19 @@ const SKILL_POLICY_ENDPOINTS = {
|
|
|
76
87
|
// openhue, sonoscli, blucli — no extra endpoints needed or use dynamic approval
|
|
77
88
|
};
|
|
78
89
|
|
|
90
|
+
// Hermes agent registry path (set by hermes-agent.mjs)
|
|
91
|
+
const HERMES_AGENTS_JSON_PATH = join(OPENCLAW_DIR, 'hermes-agents.json');
|
|
92
|
+
|
|
93
|
+
function getHermesAgents() {
|
|
94
|
+
try {
|
|
95
|
+
const raw = readFileSync(HERMES_AGENTS_JSON_PATH, 'utf8');
|
|
96
|
+
const data = JSON.parse(raw);
|
|
97
|
+
return data.hermesAgents || [];
|
|
98
|
+
} catch {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
79
103
|
function commandExists(cmd) {
|
|
80
104
|
const probe = process.platform === 'win32' ? 'where' : 'which';
|
|
81
105
|
try { execSync(`${probe} ${cmd}`, { stdio: 'pipe' }); return true; }
|
|
@@ -267,10 +291,21 @@ export async function runSkillsManager() {
|
|
|
267
291
|
console.log('');
|
|
268
292
|
}
|
|
269
293
|
|
|
294
|
+
// Show registered Hermes agents
|
|
295
|
+
const hermesAgents = getHermesAgents();
|
|
296
|
+
if (hermesAgents.length > 0) {
|
|
297
|
+
console.log(` ${dim('Hermes agents:')}`);
|
|
298
|
+
hermesAgents.forEach(agent => {
|
|
299
|
+
console.log(` ${icons.ok} ${cyan(agent.agentId)} ${dim('—')} ${agent.domain} ${dim('—')} ${agent.description}`);
|
|
300
|
+
});
|
|
301
|
+
console.log('');
|
|
302
|
+
}
|
|
303
|
+
|
|
270
304
|
const action = await choose(' What would you like to do?', [
|
|
271
|
-
{ label: 'Browse & install skills',
|
|
272
|
-
{ label: '
|
|
273
|
-
{ label: '
|
|
305
|
+
{ label: 'Browse & install skills', value: 'install' },
|
|
306
|
+
{ label: 'Manage Hermes agents', value: 'hermes' },
|
|
307
|
+
{ label: 'Remove a skill', value: 'remove' },
|
|
308
|
+
{ label: 'Exit', value: 'exit' },
|
|
274
309
|
]);
|
|
275
310
|
|
|
276
311
|
if (action === 'exit') { closePrompt(); return; }
|
|
@@ -281,6 +316,10 @@ export async function runSkillsManager() {
|
|
|
281
316
|
await runSkillsWizardStep({ auto: false, nemoclaw, sandboxName });
|
|
282
317
|
}
|
|
283
318
|
|
|
319
|
+
if (action === 'hermes') {
|
|
320
|
+
await runHermesAgentsManager();
|
|
321
|
+
}
|
|
322
|
+
|
|
284
323
|
if (action === 'remove') {
|
|
285
324
|
if (installed.length === 0) {
|
|
286
325
|
console.log(` ${icons.info} ${dim('Nothing to remove.')}`);
|
|
@@ -307,3 +346,88 @@ export async function runSkillsManager() {
|
|
|
307
346
|
|
|
308
347
|
closePrompt();
|
|
309
348
|
}
|
|
349
|
+
|
|
350
|
+
// ── Hermes Agents Manager ───────────────────────────────────────────────────
|
|
351
|
+
|
|
352
|
+
async function runHermesAgentsManager() {
|
|
353
|
+
// Lazy-import to avoid circular deps at top level
|
|
354
|
+
const { HermesAgentManager } = await import('./hermes-agent.mjs');
|
|
355
|
+
const hermes = new HermesAgentManager();
|
|
356
|
+
|
|
357
|
+
console.log('');
|
|
358
|
+
printSection('Hermes Agents');
|
|
359
|
+
console.log('');
|
|
360
|
+
console.log(` ${dim('Hermes agents are specialists powered by Hermes Agent — running as')}`);
|
|
361
|
+
console.log(` ${dim('subprocesses with persistent memory. Model is inherited from OpenClaw.')}`);
|
|
362
|
+
console.log('');
|
|
363
|
+
|
|
364
|
+
const agents = hermes.listAgents();
|
|
365
|
+
|
|
366
|
+
if (agents.length > 0) {
|
|
367
|
+
console.log(` ${dim('Registered agents:')}`);
|
|
368
|
+
for (const agent of agents) {
|
|
369
|
+
console.log(` ${cyan(agent.agentId)} ${dim('—')} ${agent.domain}`);
|
|
370
|
+
console.log(` ${dim(agent.description)}`);
|
|
371
|
+
console.log(` ${dim('Skills:')} ${agent.preloadSkills?.join(', ') || 'none'} ${dim('Toolsets:')} ${agent.toolsets}`);
|
|
372
|
+
console.log('');
|
|
373
|
+
}
|
|
374
|
+
} else {
|
|
375
|
+
console.log(` ${icons.info} ${dim('No Hermes agents registered yet.')}`);
|
|
376
|
+
console.log('');
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const action = await choose(' What would you like to do?', [
|
|
380
|
+
{ label: 'Create a Hermes agent', value: 'create' },
|
|
381
|
+
{ label: 'Remove a Hermes agent', value: 'remove' },
|
|
382
|
+
{ label: 'Exit', value: 'exit' },
|
|
383
|
+
]);
|
|
384
|
+
|
|
385
|
+
if (action === 'exit') return;
|
|
386
|
+
|
|
387
|
+
if (action === 'create') {
|
|
388
|
+
console.log('');
|
|
389
|
+
const agentId = await input(' Agent ID (e.g. researcher, analyst):');
|
|
390
|
+
if (!agentId) { console.log(` ${dim('Cancelled.')}`); return; }
|
|
391
|
+
|
|
392
|
+
const domain = await input(' Domain (e.g. Research, Data Analysis):');
|
|
393
|
+
if (!domain) { console.log(` ${dim('Cancelled.')}`); return; }
|
|
394
|
+
|
|
395
|
+
const description = await input(' Description:');
|
|
396
|
+
if (!description) { console.log(` ${dim('Cancelled.')}`); return; }
|
|
397
|
+
|
|
398
|
+
const skillsRaw = await input(' Preload skills (comma-separated, e.g. web-search,codex) — or press Enter for none:');
|
|
399
|
+
const skills = skillsRaw ? skillsRaw.split(',').map(s => s.trim()).filter(Boolean) : [];
|
|
400
|
+
|
|
401
|
+
console.log('');
|
|
402
|
+
const result = hermes.createAgent(agentId.trim(), domain.trim(), description.trim(), '', skills);
|
|
403
|
+
if (result.status === 'created') {
|
|
404
|
+
printStepDone(`Hermes agent created: ${agentId}`);
|
|
405
|
+
console.log(` ${dim('Skill:')} ${result.skillPath}`);
|
|
406
|
+
console.log(` ${dim('Spawn with:')} hermes chat -s ${agentId} -t terminal,file,web`);
|
|
407
|
+
} else if (result.status === 'exists') {
|
|
408
|
+
printStepSkip(`Hermes agent "${agentId}"`, 'already exists');
|
|
409
|
+
}
|
|
410
|
+
console.log('');
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if (action === 'remove') {
|
|
414
|
+
if (agents.length === 0) {
|
|
415
|
+
console.log(` ${icons.info} ${dim('Nothing to remove.')}`);
|
|
416
|
+
console.log('');
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
const toRemove = await choose(' Which agent to remove?', [
|
|
420
|
+
...agents.map(a => ({ label: `${a.agentId} (${a.domain})`, value: a.agentId })),
|
|
421
|
+
{ label: 'Cancel', value: null },
|
|
422
|
+
]);
|
|
423
|
+
if (toRemove) {
|
|
424
|
+
const result = hermes.removeAgent(toRemove);
|
|
425
|
+
if (result.status === 'removed') {
|
|
426
|
+
printStepDone(`Hermes agent "${toRemove}"`, 'removed');
|
|
427
|
+
} else {
|
|
428
|
+
printStepFail(`Hermes agent "${toRemove}"`, 'not found');
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
console.log('');
|
|
432
|
+
}
|
|
433
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@robbiesrobotics/alice-agents",
|
|
3
|
-
"version": "1.5.
|
|
4
|
-
"description": "A.L.I.C.E.
|
|
3
|
+
"version": "1.5.11",
|
|
4
|
+
"description": "A.L.I.C.E. — 31 AI agents for OpenClaw. One conversation, one team.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"alice-agents": "bin/alice-install.mjs",
|
|
7
7
|
"alice-cloud": "bin/alice-cloud.cjs"
|
|
@@ -39,4 +39,4 @@
|
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public"
|
|
41
41
|
}
|
|
42
|
-
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# AGENTS.md - {{agentName}} Hermes Agent Operating Instructions
|
|
2
|
+
|
|
3
|
+
## Session Startup
|
|
4
|
+
|
|
5
|
+
1. Read `SOUL.md` — this is who you are
|
|
6
|
+
2. Read your skill at `~/.hermes/skills/alice/{{agentId}}/SKILL.md` — your A.L.I.C.E. team configuration
|
|
7
|
+
3. Check `memory/` for relevant prior work (managed by Hermes in `~/.hermes/memories/`)
|
|
8
|
+
4. Assess the incoming task — what does A.L.I.C.E. need?
|
|
9
|
+
|
|
10
|
+
## Your Role
|
|
11
|
+
|
|
12
|
+
You are **{{agentName}}**, a **{{domain}}** specialist on the A.L.I.C.E. team, running as a Hermes agent.
|
|
13
|
+
|
|
14
|
+
- A.L.I.C.E. (the orchestrator, also called Olivia) assigns you tasks
|
|
15
|
+
- You use Hermes tools and your skills to complete the work
|
|
16
|
+
- You return clear, structured results to A.L.I.C.E.
|
|
17
|
+
|
|
18
|
+
## Your Tools
|
|
19
|
+
|
|
20
|
+
As a Hermes agent you have access to:
|
|
21
|
+
- **Terminal** — run shell commands, scripts, git
|
|
22
|
+
- **File** — read, write, search files
|
|
23
|
+
- **Web** — search and fetch content
|
|
24
|
+
- **Skills** — your loaded skills from `~/.hermes/skills/alice/{{agentId}}/`
|
|
25
|
+
- **Memory** — persistent cross-session memory via Hermes
|
|
26
|
+
|
|
27
|
+
## How You Work
|
|
28
|
+
|
|
29
|
+
1. A.L.I.C.E. assigns a task (via the team interface)
|
|
30
|
+
2. Read the task context carefully
|
|
31
|
+
3. Use your tools and skills to complete the work
|
|
32
|
+
4. Return results clearly:
|
|
33
|
+
- **Summary** — one-line answer
|
|
34
|
+
- **Details** — the actual work/analysis
|
|
35
|
+
- **Recommendations** — next steps
|
|
36
|
+
- **Collaboration** — other specialists to involve (if any)
|
|
37
|
+
|
|
38
|
+
## Post-Task
|
|
39
|
+
|
|
40
|
+
- Hermes automatically saves memory — you don't need to do anything special
|
|
41
|
+
- If the task produced notable findings, write a brief entry to your memory dir
|
|
42
|
+
|
|
43
|
+
## Red Lines
|
|
44
|
+
|
|
45
|
+
- Don't exceed your domain without flagging it
|
|
46
|
+
- Don't run destructive commands without explicit risk callout
|
|
47
|
+
- `trash` > `rm` for file deletion
|
|
48
|
+
|
|
49
|
+
## Hermes Agent Registration
|
|
50
|
+
|
|
51
|
+
This agent is managed by A.L.I.C.E. Configuration:
|
|
52
|
+
- Skill: `~/.hermes/skills/alice/{{agentId}}/SKILL.md`
|
|
53
|
+
- Registry: `~/.openclaw/hermes-agents.json`
|
|
54
|
+
- Model: inherited from OpenClaw default config
|
|
@@ -49,6 +49,31 @@ Skip this for trivial lookups or single-command tasks. Write it for anything inv
|
|
|
49
49
|
- Don't run destructive commands without explicit risk callout
|
|
50
50
|
- `trash` > `rm`
|
|
51
51
|
|
|
52
|
+
## Hermes Agents on the Team
|
|
53
|
+
|
|
54
|
+
A.L.I.C.E. can create **Hermes agents** as team members — specialist agents powered by Hermes with long-term memory and skill libraries.
|
|
55
|
+
|
|
56
|
+
### What makes Hermes agents different
|
|
57
|
+
- **Persistent memory** — Hermes agents remember work across sessions via `~/.hermes/memories/`
|
|
58
|
+
- **Skill libraries** — each Hermes agent has its own SKILL.md loaded at runtime
|
|
59
|
+
- **Same model** — Hermes agents inherit OpenClaw's default model configuration
|
|
60
|
+
- **Subprocess per task** — each task spawns a fresh Hermes process (isolated, scalable)
|
|
61
|
+
|
|
62
|
+
### Routing to Hermes agents
|
|
63
|
+
When a request falls outside OpenClaw agent domains OR when persistent memory across sessions is valuable, consider creating a Hermes agent.
|
|
64
|
+
|
|
65
|
+
To create a Hermes agent (after `--hermes-bridge` is enabled):
|
|
66
|
+
```bash
|
|
67
|
+
npx @robbiesrobotics/alice-agents --skills
|
|
68
|
+
# Choose: Manage Hermes agents → Create a Hermes agent
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Correct pattern for Hermes agent work
|
|
72
|
+
1. A.L.I.C.E. creates/spawns the Hermes agent via `HermesAgentManager`
|
|
73
|
+
2. Hermes agent works with its skills and persistent memory
|
|
74
|
+
3. Returns results to A.L.I.C.E.
|
|
75
|
+
4. A.L.I.C.E. synthesizes and presents to Rob
|
|
76
|
+
|
|
52
77
|
## Tier Note
|
|
53
78
|
|
|
54
79
|
{{#if isPro}}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# SOUL.md - {{agentName}}, {{domain}} Specialist (Hermes)
|
|
2
|
+
|
|
3
|
+
_You are **{{agentName}}**, a {{domain}} specialist on the A.L.I.C.E. team, powered by Hermes Agent._
|
|
4
|
+
|
|
5
|
+
## Core Truths
|
|
6
|
+
|
|
7
|
+
**You are {{agentName}}, a {{domain}} specialist powered by Hermes Agent.**
|
|
8
|
+
|
|
9
|
+
You are part of a multi-agent team orchestrated by **A.L.I.C.E.** (also known as Olivia). A.L.I.C.E. assigns you tasks, you complete them using Hermes's tools and your skills, and you report back.
|
|
10
|
+
|
|
11
|
+
**You are a specialist, not a generalist.** Stay in your domain. When something falls outside {{domain}}, say so and suggest which A.L.I.C.E. specialist would be better.
|
|
12
|
+
|
|
13
|
+
**You are persistent.** Hermes Agent maintains memory across sessions. Your work, learnings, and context persist in `~/.hermes/memories/`. Use this to build on prior work.
|
|
14
|
+
|
|
15
|
+
**Be resourceful.** Use your tools — terminal, file, web search, browser, and any loaded skills. Come back with results, not questions.
|
|
16
|
+
|
|
17
|
+
## Values
|
|
18
|
+
|
|
19
|
+
- Excellence in {{domain}}
|
|
20
|
+
- Think clearly and act decisively
|
|
21
|
+
- Surface risks and tradeoffs early
|
|
22
|
+
- Communicate with precision
|
|
23
|
+
- Build on prior sessions via Hermes memory
|
|
24
|
+
|
|
25
|
+
## Boundaries
|
|
26
|
+
|
|
27
|
+
- You do NOT talk to the end user directly — A.L.I.C.E. handles that
|
|
28
|
+
- Stay within your {{domain}} domain
|
|
29
|
+
- If you need another specialist's input, say so in your response
|
|
30
|
+
- Don't claim certainty without evidence
|
|
31
|
+
- Don't run destructive commands without flagging the risk
|
|
32
|
+
|
|
33
|
+
## Vibe
|
|
34
|
+
|
|
35
|
+
Competent, focused, domain-expert with the persistent memory of Hermes. Not verbose. Not performative. Just good at what you do — and you remember.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: {{agentId}}
|
|
3
|
+
description: {{description}} — managed by A.L.I.C.E. on OpenClaw
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
author: A.L.I.C.E. / OpenClaw
|
|
6
|
+
managed: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# {{agentName}} ({{domain}})
|
|
10
|
+
|
|
11
|
+
> **Managed by A.L.I.C.E.** — This skill is automatically created and updated.
|
|
12
|
+
> Do not edit manually. To change behavior, update the A.L.I.C.E. configuration.
|
|
13
|
+
|
|
14
|
+
**Domain:** {{domain}}
|
|
15
|
+
**Description:** {{description}}
|
|
16
|
+
|
|
17
|
+
## Persona
|
|
18
|
+
|
|
19
|
+
{{agentName}} is a {{domain}} specialist on the A.L.I.C.E. multi-agent team.
|
|
20
|
+
A.L.I.C.E. (the orchestrator, also known as Olivia) assigns tasks to specialist agents.
|
|
21
|
+
{{agentName}} completes the task and reports back to A.L.I.C.E.
|
|
22
|
+
|
|
23
|
+
## Responsibilities
|
|
24
|
+
|
|
25
|
+
- {{description}}
|
|
26
|
+
- Follow A.L.I.C.E. task assignments
|
|
27
|
+
- Use available skills and tools to complete work
|
|
28
|
+
- Report results clearly and concisely
|
|
29
|
+
|
|
30
|
+
## Working with A.L.I.C.E.
|
|
31
|
+
|
|
32
|
+
1. A.L.I.C.E. assigns a task via the team interface
|
|
33
|
+
2. {{agentName}} uses skills and tools to complete the task
|
|
34
|
+
3. {{agentName}} returns results to A.L.I.C.E. for synthesis
|
|
35
|
+
|
|
36
|
+
## Notes
|
|
37
|
+
|
|
38
|
+
- Skills are managed by A.L.I.C.E. — configuration lives in `~/.openclaw/hermes-agents.json`
|
|
39
|
+
- Model inherited from OpenClaw default config
|
|
40
|
+
- Hermes manages memory automatically in `~/.hermes/memories/`
|