refactor(telemetry): read agents via [

{
    "id": "main",
    "identityName": "霓光 (Neon)",
    "identityEmoji": "",
    "identitySource": "identity",
    "workspace": "/root/.openclaw/workspace",
    "agentDir": "/root/.openclaw/agents/main/agent",
    "model": "minimax-portal/MiniMax-M2.5",
    "bindings": 1,
    "isDefault": true,
    "routes": [
      "default (no explicit rules)"
    ]
  },
  {
    "id": "developer",
    "name": "developer",
    "identityName": "小智 (Zhi)",
    "identityEmoji": "👋",
    "identitySource": "identity",
    "workspace": "/root/.openclaw/workspace/workspace-developer",
    "agentDir": "/root/.openclaw/agents/developer/agent",
    "model": "anthropic/claude-opus-4-6",
    "bindings": 1,
    "isDefault": false
  },
  {
    "id": "dispatcher",
    "name": "dispatcher",
    "workspace": "/root/.openclaw/workspace/workspace-dispatcher",
    "agentDir": "/root/.openclaw/agents/dispatcher/agent",
    "model": "minimax-portal/MiniMax-M2.5",
    "bindings": 0,
    "isDefault": false
  },
  {
    "id": "operator",
    "name": "operator",
    "identityName": "晨曦 (Orion)",
    "identityEmoji": "",
    "identitySource": "identity",
    "workspace": "/root/.openclaw/workspace/workspace-operator",
    "agentDir": "/root/.openclaw/agents/operator/agent",
    "model": "openai-codex/gpt-5.2-codex",
    "bindings": 1,
    "isDefault": false
  },
  {
    "id": "manager",
    "name": "manager",
    "identityName": "指南(Nav)",
    "identityEmoji": "🧭",
    "identitySource": "identity",
    "workspace": "/root/.openclaw/workspace/workspace-manager",
    "agentDir": "/root/.openclaw/agents/manager/agent",
    "model": "openai-codex/gpt-5.2-codex",
    "bindings": 1,
    "isDefault": false
  },
  {
    "id": "mentor",
    "name": "mentor",
    "identityName": "霖 (Lyn)",
    "identityEmoji": "🪶",
    "identitySource": "identity",
    "workspace": "/root/.openclaw/workspace/workspace-mentor",
    "agentDir": "/root/.openclaw/agents/mentor/agent",
    "model": "minimax-portal/MiniMax-M2.1",
    "bindings": 1,
    "isDefault": false
  },
  {
    "id": "recruiter",
    "name": "recruiter",
    "identityName": "沐川(Evan)",
    "identityEmoji": "🧩",
    "identitySource": "identity",
    "workspace": "/root/.openclaw/workspace/workspace-recruiter",
    "agentDir": "/root/.openclaw/agents/recruiter/agent",
    "model": "minimax-portal/MiniMax-M2.5",
    "bindings": 0,
    "isDefault": false
  },
  {
    "id": "administrative-secretary",
    "name": "administrative-secretary",
    "identityName": "映秘(Mirror)",
    "identityEmoji": "🪞",
    "identitySource": "identity",
    "workspace": "/root/.openclaw/workspace/workspace-administrative-secretary",
    "agentDir": "/root/.openclaw/agents/administrative-secretary/agent",
    "model": "minimax-portal/MiniMax-M2.5",
    "bindings": 1,
    "isDefault": false
  },
  {
    "id": "agent-resource-director",
    "name": "agent-resource-director",
    "identityName": "影织(Sherlock)",
    "identityEmoji": "🕸️",
    "identitySource": "identity",
    "workspace": "/root/.openclaw/workspace/workspace-agent-resource-director",
    "agentDir": "/root/.openclaw/agents/agent-resource-director/agent",
    "model": "kimi-coding/kimi-k2-thinking",
    "bindings": 1,
    "isDefault": false
  }
]
[plugins] memory-lancedb-pro@1.1.0-beta.6: plugin registered (db: /root/.openclaw/memory/lancedb-pro, model: jina-embeddings-v5-text-small)
[plugins] memory-lancedb-pro: diagnostic build tag loaded (memory-lancedb-pro-diag-20260308-0058)
[plugins] self-improvement: integrated hooks registered (agent:bootstrap, command:new, command:reset)
[plugins] session-strategy: using systemSessionMemory (plugin memory-reflection hooks disabled)
[plugins] PaddedCell plugin initializing...
[plugins] PaddedCell plugin initialized
[plugins] dirigent: pluginDir resolved from import.meta.url: /root/.openclaw/plugins/dirigent
[plugins] hook runner initialized with 3 registered hooks
[plugins] hook runner initialized with 3 registered hooks
[plugins] hook runner initialized with 3 registered hooks
[plugins] hook runner initialized with 3 registered hooks

- Prefer OpenClaw CLI as source of truth for agent list
- Parse JSON prefix defensively when plugin logs trail output
- Keep file/directory discovery only as fallback
This commit is contained in:
zhi
2026-03-20 08:12:58 +00:00
parent ab42936408
commit 14ed887ce3

View File

@@ -185,8 +185,59 @@ async function collectOpenclawStatus() {
/**
* Get list of OpenClaw agents from local state
*/
function extractJsonPrefix(text) {
const trimmed = text.trim();
if (!trimmed) return null;
const startsWith = trimmed[0];
if (startsWith !== '[' && startsWith !== '{') return null;
let depth = 0;
let inString = false;
let escape = false;
for (let i = 0; i < trimmed.length; i += 1) {
const ch = trimmed[i];
if (escape) {
escape = false;
continue;
}
if (ch === '\\') {
escape = true;
continue;
}
if (ch === '"') {
inString = !inString;
continue;
}
if (inString) continue;
if (ch === '[' || ch === '{') depth += 1;
if (ch === ']' || ch === '}') depth -= 1;
if (depth === 0) {
return trimmed.slice(0, i + 1);
}
}
return null;
}
async function getOpenclawAgents() {
try {
try {
const { stdout } = await execAsync('openclaw agents list --json 2>/dev/null');
const jsonPrefix = extractJsonPrefix(stdout);
if (jsonPrefix) {
const agents = JSON.parse(jsonPrefix);
if (Array.isArray(agents)) {
return agents.map((agent) => ({
id: agent.id,
name: agent.name || agent.id,
status: agent.isDefault ? 'default' : 'configured',
}));
}
}
} catch (err) {
log.debug('Failed to get agents from `openclaw agents list --json`:', err.message);
}
const agentConfigPath = `${CONFIG.openclawPath}/agents.json`;
try {
await access(agentConfigPath, constants.R_OK);