feat: populate monitor agents from openclaw list
This commit is contained in:
85
plugin/core/openclaw-agents.ts
Normal file
85
plugin/core/openclaw-agents.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { execFile } from 'child_process';
|
||||
import { promisify } from 'util';
|
||||
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
export interface OpenClawAgentInfo {
|
||||
name: string;
|
||||
isDefault?: boolean;
|
||||
identity?: string;
|
||||
workspace?: string;
|
||||
agentDir?: string;
|
||||
model?: string;
|
||||
routingRules?: number;
|
||||
routing?: string;
|
||||
}
|
||||
|
||||
export async function listOpenClawAgents(logger?: { debug?: (...args: any[]) => void; warn?: (...args: any[]) => void }): Promise<OpenClawAgentInfo[]> {
|
||||
try {
|
||||
const { stdout } = await execFileAsync('openclaw', ['agents', 'list'], {
|
||||
timeout: 15000,
|
||||
maxBuffer: 1024 * 1024,
|
||||
});
|
||||
return parseOpenClawAgents(stdout);
|
||||
} catch (err) {
|
||||
logger?.warn?.('Failed to run `openclaw agents list`', err);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export function parseOpenClawAgents(text: string): OpenClawAgentInfo[] {
|
||||
const lines = text.split(/\r?\n/);
|
||||
const out: OpenClawAgentInfo[] = [];
|
||||
let current: OpenClawAgentInfo | null = null;
|
||||
|
||||
const push = () => {
|
||||
if (current) out.push(current);
|
||||
current = null;
|
||||
};
|
||||
|
||||
for (const raw of lines) {
|
||||
const line = raw.trimEnd();
|
||||
if (!line.trim() || line.startsWith('Agents:') || line.startsWith('Routing rules map') || line.startsWith('Channel status reflects')) continue;
|
||||
if (line.startsWith('- ')) {
|
||||
push();
|
||||
const m = line.match(/^-\s+(.+?)(?:\s+\((default)\))?$/);
|
||||
current = {
|
||||
name: m?.[1] || line.slice(2).trim(),
|
||||
isDefault: m?.[2] === 'default',
|
||||
};
|
||||
continue;
|
||||
}
|
||||
if (!current) continue;
|
||||
const trimmed = line.trim();
|
||||
const idx = trimmed.indexOf(':');
|
||||
if (idx === -1) continue;
|
||||
const key = trimmed.slice(0, idx).trim();
|
||||
const value = trimmed.slice(idx + 1).trim();
|
||||
switch (key) {
|
||||
case 'Identity':
|
||||
current.identity = value;
|
||||
break;
|
||||
case 'Workspace':
|
||||
current.workspace = value;
|
||||
break;
|
||||
case 'Agent dir':
|
||||
current.agentDir = value;
|
||||
break;
|
||||
case 'Model':
|
||||
current.model = value;
|
||||
break;
|
||||
case 'Routing rules': {
|
||||
const n = Number(value);
|
||||
current.routingRules = Number.isFinite(n) ? n : undefined;
|
||||
break;
|
||||
}
|
||||
case 'Routing':
|
||||
current.routing = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
push();
|
||||
return out;
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
import { hostname, freemem, totalmem, uptime, loadavg, platform } from 'os';
|
||||
import { getPluginConfig } from './core/config';
|
||||
import { MonitorBridgeClient, type OpenClawMeta } from './core/monitor-bridge';
|
||||
import { listOpenClawAgents } from './core/openclaw-agents';
|
||||
import { registerGatewayStartHook } from './hooks/gateway-start';
|
||||
import { registerGatewayStopHook } from './hooks/gateway-stop';
|
||||
import {
|
||||
@@ -120,7 +121,7 @@ export default {
|
||||
const meta: OpenClawMeta = {
|
||||
version: api.version || 'unknown',
|
||||
plugin_version: '0.3.1',
|
||||
agents: [], // TODO: populate from api agent list when available
|
||||
agents: await listOpenClawAgents(logger),
|
||||
};
|
||||
|
||||
const ok = await bridgeClient.pushOpenClawMeta(meta);
|
||||
|
||||
Reference in New Issue
Block a user