@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.
@@ -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 (!agent && req.customAgent) {
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: custom.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({ agentId: req.agentId, kind: entry.adapter.kind, cwd: entry.adapter.cwd }, 'custom agent instance created for dispatch');
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
- if (running) {
289
- const agentId = parseOpenClawAgentId(await run(path, ["agents", "list", "--json"])) ?? "main";
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
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agentbean/daemon",
3
3
  "private": false,
4
- "version": "0.1.28",
4
+ "version": "0.1.29",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "bin": {