@agentbean/daemon 0.1.28 → 0.1.29
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/dist/device-daemon.js +58 -4
- package/dist/scanner.js +3 -3
- package/package.json +1 -1
package/dist/device-daemon.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { io } from 'socket.io-client';
|
|
2
2
|
import { execFile } from 'node:child_process';
|
|
3
3
|
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
4
|
-
import { join } from 'node:path';
|
|
4
|
+
import { basename, isAbsolute, join } from 'node:path';
|
|
5
5
|
import { homedir } from 'node:os';
|
|
6
6
|
import { promisify } from 'node:util';
|
|
7
7
|
import { logger } from './log.js';
|
|
@@ -29,6 +29,50 @@ function agentSlug(name) {
|
|
|
29
29
|
function scannedAgentId(deviceId, name) {
|
|
30
30
|
return `scan-${deviceId}-${agentSlug(name)}`;
|
|
31
31
|
}
|
|
32
|
+
function normalizeAdapterKind(kind) {
|
|
33
|
+
const normalized = (kind ?? '').trim().toLowerCase().replace(/[_\s]+/g, '-');
|
|
34
|
+
if (normalized === 'claude' || normalized === 'claude-code')
|
|
35
|
+
return 'claude-code';
|
|
36
|
+
if (normalized === 'codex' || normalized === 'codex-cli')
|
|
37
|
+
return 'codex';
|
|
38
|
+
if (normalized === 'kimi' || normalized === 'kimi-cli')
|
|
39
|
+
return 'kimi-cli';
|
|
40
|
+
return normalized;
|
|
41
|
+
}
|
|
42
|
+
function runtimeScoreForCustomAgent(runtime, custom) {
|
|
43
|
+
if (!runtime.installed || !runtime.command?.trim())
|
|
44
|
+
return 0;
|
|
45
|
+
const runtimeCommand = runtime.command.trim();
|
|
46
|
+
const customCommand = custom.command?.trim() ?? '';
|
|
47
|
+
if (runtimeCommand && customCommand && runtimeCommand === customCommand)
|
|
48
|
+
return 100;
|
|
49
|
+
const runtimeBase = basename(runtimeCommand).toLowerCase();
|
|
50
|
+
const customBase = customCommand ? basename(customCommand).toLowerCase() : '';
|
|
51
|
+
if (runtimeBase && customBase && runtimeBase === customBase)
|
|
52
|
+
return 90;
|
|
53
|
+
const runtimeKind = normalizeAdapterKind(runtime.adapterKind);
|
|
54
|
+
const customKind = normalizeAdapterKind(custom.adapterKind);
|
|
55
|
+
if (runtimeKind === 'kimi-cli' && customKind === 'codex' && customCommand.toLowerCase().includes('kimi'))
|
|
56
|
+
return 85;
|
|
57
|
+
if (runtimeKind && customKind && runtimeKind === customKind)
|
|
58
|
+
return 70;
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
export function resolveCustomAgentRuntime(custom, runtimes) {
|
|
62
|
+
const configured = custom.command?.trim() ?? '';
|
|
63
|
+
const configuredAbsoluteExists = configured && isAbsolute(configured) && existsSync(configured);
|
|
64
|
+
const bestRuntime = [...runtimes]
|
|
65
|
+
.map((runtime) => ({ runtime, score: runtimeScoreForCustomAgent(runtime, custom) }))
|
|
66
|
+
.filter((candidate) => candidate.score > 0)
|
|
67
|
+
.sort((a, b) => b.score - a.score)[0]?.runtime;
|
|
68
|
+
if (configuredAbsoluteExists) {
|
|
69
|
+
return { command: configured, runtime: bestRuntime };
|
|
70
|
+
}
|
|
71
|
+
if (bestRuntime?.command?.trim()) {
|
|
72
|
+
return { command: bestRuntime.command.trim(), runtime: bestRuntime };
|
|
73
|
+
}
|
|
74
|
+
return { command: configured };
|
|
75
|
+
}
|
|
32
76
|
export function nativeDirectoryPickerCommands(platform = process.platform) {
|
|
33
77
|
if (platform === 'darwin') {
|
|
34
78
|
return [{ command: 'osascript', args: ['-e', 'POSIX path of (choose folder with prompt "选择项目目录")'] }];
|
|
@@ -184,10 +228,12 @@ export function createDeviceDaemon(cfg, agents) {
|
|
|
184
228
|
const httpBase = cfg.server.url.replace(/\/agent$/, '');
|
|
185
229
|
let firstConnect = true;
|
|
186
230
|
const systemInfo = collectSystemInfo();
|
|
231
|
+
let latestRuntimes = [];
|
|
187
232
|
const publicAgents = Array.from(agents.values())
|
|
188
233
|
.filter((a) => a.visibility === 'public')
|
|
189
234
|
.map((a) => a.publicMeta);
|
|
190
235
|
function emitRegister(sock, payload) {
|
|
236
|
+
latestRuntimes = payload.runtimes.filter((runtime) => runtime.installed);
|
|
191
237
|
if (payload.runtimes.length > 0) {
|
|
192
238
|
sock.emit('device:register-runtimes', { runtimes: payload.runtimes }, (ack) => {
|
|
193
239
|
if (!ack?.ok)
|
|
@@ -323,8 +369,9 @@ export function createDeviceDaemon(cfg, agents) {
|
|
|
323
369
|
});
|
|
324
370
|
socket.on('dispatch', (req) => {
|
|
325
371
|
let agent = agents.get(req.agentId);
|
|
326
|
-
if (
|
|
372
|
+
if (req.customAgent) {
|
|
327
373
|
const custom = req.customAgent;
|
|
374
|
+
const resolvedRuntime = resolveCustomAgentRuntime(custom, latestRuntimes);
|
|
328
375
|
const entry = {
|
|
329
376
|
id: custom.id,
|
|
330
377
|
name: custom.name,
|
|
@@ -332,7 +379,7 @@ export function createDeviceDaemon(cfg, agents) {
|
|
|
332
379
|
category: 'executor-hosted',
|
|
333
380
|
adapter: {
|
|
334
381
|
kind: custom.adapterKind,
|
|
335
|
-
command:
|
|
382
|
+
command: resolvedRuntime.command,
|
|
336
383
|
args: custom.args ?? [],
|
|
337
384
|
cwd: custom.cwd ?? undefined,
|
|
338
385
|
workspace: custom.cwd ?? undefined,
|
|
@@ -343,7 +390,14 @@ export function createDeviceDaemon(cfg, agents) {
|
|
|
343
390
|
try {
|
|
344
391
|
agent = new AgentInstance(entry, pickAdapter(entry.adapter));
|
|
345
392
|
agents.set(req.agentId, agent);
|
|
346
|
-
logger.info({
|
|
393
|
+
logger.info({
|
|
394
|
+
agentId: req.agentId,
|
|
395
|
+
kind: entry.adapter.kind,
|
|
396
|
+
command: entry.adapter.command,
|
|
397
|
+
configuredCommand: custom.command,
|
|
398
|
+
runtimeCommand: resolvedRuntime.runtime?.command,
|
|
399
|
+
cwd: entry.adapter.cwd,
|
|
400
|
+
}, 'custom agent instance created for dispatch');
|
|
347
401
|
}
|
|
348
402
|
catch (err) {
|
|
349
403
|
logger.warn({ agentId: req.agentId, err: errorMessage(err) }, 'failed to create custom dispatch agent');
|
package/dist/scanner.js
CHANGED
|
@@ -285,14 +285,14 @@ async function checkOpenClawGateway() {
|
|
|
285
285
|
return null;
|
|
286
286
|
const status = await run(path, ["gateway", "status"]);
|
|
287
287
|
const running = status.includes("running") || status.includes("✓");
|
|
288
|
-
|
|
289
|
-
|
|
288
|
+
const agentId = parseOpenClawAgentId(await run(path, ["agents", "list", "--json"]));
|
|
289
|
+
if (running || agentId) {
|
|
290
290
|
return {
|
|
291
291
|
category: "agentos-hosted",
|
|
292
292
|
name: "OpenClaw-Agent",
|
|
293
293
|
adapterKind: "openclaw",
|
|
294
294
|
command: path,
|
|
295
|
-
args: ["agent", "--agent", agentId],
|
|
295
|
+
args: ["agent", "--agent", agentId ?? "main"],
|
|
296
296
|
source: "gateway",
|
|
297
297
|
};
|
|
298
298
|
}
|