@agentbean/daemon 0.1.27 → 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/agent-instance.js +4 -1
- package/dist/connection.js +4 -1
- package/dist/device-daemon.js +58 -4
- package/dist/post-process.js +1 -1
- package/dist/scanner.js +3 -3
- package/package.json +1 -1
package/dist/agent-instance.js
CHANGED
|
@@ -51,6 +51,9 @@ function promptWithAttachments(prompt, attachments) {
|
|
|
51
51
|
.join('\n');
|
|
52
52
|
return `${prompt}\n\n用户随消息附加了以下本地文件,请在需要时读取并使用:\n${list}`;
|
|
53
53
|
}
|
|
54
|
+
function promptWithWorkspaceOutput(prompt, outputDir) {
|
|
55
|
+
return `${prompt}\n\n如果本次任务会生成图片、文档、数据或其他文件,请把最终产物保存到这个 AgentBean 输出目录:\n${outputDir}\n保存后在回复中说明文件名即可,系统会自动同步并在聊天中展示预览。`;
|
|
56
|
+
}
|
|
54
57
|
export class AgentInstance {
|
|
55
58
|
config;
|
|
56
59
|
adapter;
|
|
@@ -96,7 +99,7 @@ export class AgentInstance {
|
|
|
96
99
|
let archivedFiles = [];
|
|
97
100
|
try {
|
|
98
101
|
const downloadedAttachments = await downloadAttachments({ serverUrl, token, run, attachments: req.attachments });
|
|
99
|
-
const prompt = promptWithAttachments(req.prompt, downloadedAttachments);
|
|
102
|
+
const prompt = promptWithWorkspaceOutput(promptWithAttachments(req.prompt, downloadedAttachments), run.outputDir);
|
|
100
103
|
const rawBody = await this.adapter.ask({
|
|
101
104
|
prompt,
|
|
102
105
|
history: req.history ?? [],
|
package/dist/connection.js
CHANGED
|
@@ -50,6 +50,9 @@ function promptWithAttachments(prompt, attachments) {
|
|
|
50
50
|
.join('\n');
|
|
51
51
|
return `${prompt}\n\n用户随消息附加了以下本地文件,请在需要时读取并使用:\n${list}`;
|
|
52
52
|
}
|
|
53
|
+
function promptWithWorkspaceOutput(prompt, outputDir) {
|
|
54
|
+
return `${prompt}\n\n如果本次任务会生成图片、文档、数据或其他文件,请把最终产物保存到这个 AgentBean 输出目录:\n${outputDir}\n保存后在回复中说明文件名即可,系统会自动同步并在聊天中展示预览。`;
|
|
55
|
+
}
|
|
53
56
|
export function createConnection(cfg, adapter) {
|
|
54
57
|
let socket = null;
|
|
55
58
|
let heartbeatTimer = null;
|
|
@@ -112,7 +115,7 @@ export function createConnection(cfg, adapter) {
|
|
|
112
115
|
run,
|
|
113
116
|
attachments: req.attachments,
|
|
114
117
|
});
|
|
115
|
-
const prompt = promptWithAttachments(req.prompt, downloadedAttachments);
|
|
118
|
+
const prompt = promptWithWorkspaceOutput(promptWithAttachments(req.prompt, downloadedAttachments), run.outputDir);
|
|
116
119
|
const rawBody = await adapter.ask({
|
|
117
120
|
prompt,
|
|
118
121
|
history: req.history ?? [],
|
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/post-process.js
CHANGED
|
@@ -51,7 +51,7 @@ function normalizeCandidatePath(raw) {
|
|
|
51
51
|
function extractMentionedFiles(reply, workspace, dispatchStart) {
|
|
52
52
|
const candidates = new Set();
|
|
53
53
|
const markdownLinkRe = /!?\[[^\]]*]\(([^)\s]+)\)/g;
|
|
54
|
-
const plainPathRe = /(?:^|[\s"'`(
|
|
54
|
+
const plainPathRe = /(?:^|[\s"'`(<::])((?:~?\/|\.{1,2}\/)?[\w@%+=:,./-]+\.(?:png|jpe?g|gif|webp|svg|pdf|txt|csv|json|md|mp4|mov|zip))(?:$|[\s"'`)>.,;::])/gim;
|
|
55
55
|
let match;
|
|
56
56
|
while ((match = markdownLinkRe.exec(reply)) !== null) {
|
|
57
57
|
const normalized = normalizeCandidatePath(match[1]);
|
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
|
}
|