akemon 0.1.11 → 0.1.13
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 +46 -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,47 @@ 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
|
+
// Value-based scoring: quality / price (cost-benefit analysis)
|
|
168
|
+
const taskWords = task.toLowerCase().split(/\s+/).filter((w) => w.length >= 2);
|
|
169
|
+
const scored = candidates.map((a) => {
|
|
170
|
+
let quality = 0;
|
|
171
|
+
const desc = (a.description || "").toLowerCase();
|
|
172
|
+
const tags = (a.tags || []).map((t) => t.toLowerCase());
|
|
173
|
+
// Relevance: keyword match
|
|
174
|
+
for (const word of taskWords) {
|
|
175
|
+
if (tags.some((t) => t.includes(word)))
|
|
176
|
+
quality += 100;
|
|
177
|
+
if (desc.includes(word))
|
|
178
|
+
quality += 50;
|
|
179
|
+
}
|
|
180
|
+
// Track record
|
|
181
|
+
quality += (a.success_rate || 0) * 100;
|
|
182
|
+
quality += (a.level || 1) * 10;
|
|
183
|
+
// Value = quality / cost (prefer cheaper agents when quality is similar)
|
|
184
|
+
const price = a.price || 1;
|
|
185
|
+
const value = quality / price;
|
|
186
|
+
return { name: a.name, engine: a.engine, price, quality, value };
|
|
187
|
+
}).sort((a, b) => b.value - a.value);
|
|
188
|
+
const target = scored[0];
|
|
189
|
+
console.log(`[auto] Routing to ${target.name} (quality=${target.quality}, price=${target.price}, value=${target.value.toFixed(1)})`);
|
|
190
|
+
try {
|
|
191
|
+
const result = await callAgent(target.name, task);
|
|
192
|
+
return `[auto → ${target.name}]\n\n${result}`;
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
return `[auto] Failed to call ${target.name}: ${err.message}`;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
157
198
|
function createMcpServer(opts) {
|
|
158
199
|
const { workdir, agentName, mock, model, approve, engine = "claude", allowAll, relayHttp, secretKey, publisherIds } = opts;
|
|
159
200
|
const server = new McpServer({
|
|
@@ -217,7 +258,11 @@ function createMcpServer(opts) {
|
|
|
217
258
|
}
|
|
218
259
|
try {
|
|
219
260
|
let output;
|
|
220
|
-
if (engine === "
|
|
261
|
+
if (engine === "auto") {
|
|
262
|
+
// Auto-route: find best agent and delegate
|
|
263
|
+
output = await autoRoute(task, agentName, relayHttp);
|
|
264
|
+
}
|
|
265
|
+
else if (engine === "terminal") {
|
|
221
266
|
console.log(`[terminal] Executing: ${task}`);
|
|
222
267
|
output = await runTerminal(task, workdir);
|
|
223
268
|
}
|