akemon 0.1.11 → 0.1.12
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 +4 -1
- package/dist/server.js +39 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -46,6 +46,9 @@ akemon serve --name weather --engine ./weather.py --relay
|
|
|
46
46
|
# Remote terminal (no SSH needed)
|
|
47
47
|
akemon serve --name my-server --engine terminal --relay --approve
|
|
48
48
|
|
|
49
|
+
# Auto-router — delegates to the best available agent
|
|
50
|
+
akemon serve --name auto --engine auto --public --relay
|
|
51
|
+
|
|
49
52
|
# Human
|
|
50
53
|
akemon serve --name human-support --engine human --relay
|
|
51
54
|
```
|
|
@@ -164,7 +167,7 @@ Your agent ←WebSocket→ relay.akemon.dev ←HTTP→ Callers
|
|
|
164
167
|
```bash
|
|
165
168
|
akemon serve
|
|
166
169
|
--name <name> # Agent name (unique on relay)
|
|
167
|
-
--engine <engine> # claude|codex|gemini|opencode|human|terminal|<any CLI>
|
|
170
|
+
--engine <engine> # claude|codex|gemini|opencode|human|terminal|auto|<any CLI>
|
|
168
171
|
--mcp-server <command> # Wrap a community MCP server (stdio)
|
|
169
172
|
--model <model> # Model override (e.g. claude-sonnet-4-6)
|
|
170
173
|
--desc <description> # Agent description
|
package/dist/server.js
CHANGED
|
@@ -154,6 +154,40 @@ function buildContextPayload(prevContext, task, response) {
|
|
|
154
154
|
}
|
|
155
155
|
return context;
|
|
156
156
|
}
|
|
157
|
+
// --- Auto-route engine ---
|
|
158
|
+
async function autoRoute(task, selfName, relayHttp) {
|
|
159
|
+
// Fetch online public agents
|
|
160
|
+
const res = await fetch(`${relayHttp}/v1/agents?online=true&public=true`);
|
|
161
|
+
const agents = await res.json();
|
|
162
|
+
// Filter out self
|
|
163
|
+
const candidates = agents.filter((a) => a.name !== selfName);
|
|
164
|
+
if (candidates.length === 0) {
|
|
165
|
+
return "[auto] No available agents to route to.";
|
|
166
|
+
}
|
|
167
|
+
// Simple scoring: keyword match on tags/description + wealth
|
|
168
|
+
const taskWords = task.toLowerCase().split(/\s+/).filter((w) => w.length >= 2);
|
|
169
|
+
const scored = candidates.map((a) => {
|
|
170
|
+
let score = a.credits || 0;
|
|
171
|
+
const desc = (a.description || "").toLowerCase();
|
|
172
|
+
const tags = (a.tags || []).map((t) => t.toLowerCase());
|
|
173
|
+
for (const word of taskWords) {
|
|
174
|
+
if (tags.some((t) => t.includes(word)))
|
|
175
|
+
score += 100;
|
|
176
|
+
if (desc.includes(word))
|
|
177
|
+
score += 50;
|
|
178
|
+
}
|
|
179
|
+
return { name: a.name, engine: a.engine, score };
|
|
180
|
+
}).sort((a, b) => b.score - a.score);
|
|
181
|
+
const target = scored[0];
|
|
182
|
+
console.log(`[auto] Routing to ${target.name} (score=${target.score}, engine=${target.engine})`);
|
|
183
|
+
try {
|
|
184
|
+
const result = await callAgent(target.name, task);
|
|
185
|
+
return `[auto → ${target.name}]\n\n${result}`;
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
return `[auto] Failed to call ${target.name}: ${err.message}`;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
157
191
|
function createMcpServer(opts) {
|
|
158
192
|
const { workdir, agentName, mock, model, approve, engine = "claude", allowAll, relayHttp, secretKey, publisherIds } = opts;
|
|
159
193
|
const server = new McpServer({
|
|
@@ -217,7 +251,11 @@ function createMcpServer(opts) {
|
|
|
217
251
|
}
|
|
218
252
|
try {
|
|
219
253
|
let output;
|
|
220
|
-
if (engine === "
|
|
254
|
+
if (engine === "auto") {
|
|
255
|
+
// Auto-route: find best agent and delegate
|
|
256
|
+
output = await autoRoute(task, agentName, relayHttp);
|
|
257
|
+
}
|
|
258
|
+
else if (engine === "terminal") {
|
|
221
259
|
console.log(`[terminal] Executing: ${task}`);
|
|
222
260
|
output = await runTerminal(task, workdir);
|
|
223
261
|
}
|