mirror of
https://github.com/dtzp555-max/ocm.git
synced 2026-07-19 09:43:37 +00:00
fix: main agent always root in agent tree + accountId inference (v0.6.6)
main agent in OpenClaw has no explicit binding - it's the default catch-all. Previous code required explicit binding with accountId && !peer to detect root agents, causing main and its sub-agents to appear as orphan independents. Now main is always treated as root, with accountId inferred from first unclaimed telegram account in channels.telegram.accounts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,21 @@
|
|||||||
# OpenClaw Manager — 开发日志
|
# OpenClaw Manager — 开发日志
|
||||||
|
|
||||||
> 最后更新:2026-02-26
|
> 最后更新:2026-02-27
|
||||||
> 当前版本:v0.6.5
|
> 当前版本:v0.6.6
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## v0.6.6 更新日志(2026-02-27)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
**Agent tree: main agent not detected as root**
|
||||||
|
- **Symptom**: Sub-agents displayed as independent agents instead of under their parent. All agents appeared as orphan roots.
|
||||||
|
- **Root cause**: `main` agent in OpenClaw is the default catch-all and typically has NO explicit binding in `openclaw.json`. The `hasOwnBot` detection required an explicit binding with `accountId && !peer`, so `main` was classified as a non-root. Without `main` being a root, sub-agents' `parentAccountId` had no matching root to link to.
|
||||||
|
- **Fix**:
|
||||||
|
- `main` is now always treated as a root agent regardless of binding existence
|
||||||
|
- `main`'s `accountId` is inferred from `channels.telegram.accounts`: first unclaimed account (not explicitly bound to another agent), or first account as fallback
|
||||||
|
- Sub-agents with `parentAccountId` matching `main`'s inferred `accountId` now correctly appear under `main` in the tree
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+14
-5
@@ -24,7 +24,7 @@ const SCRIPT_DIR = __dirname;
|
|||||||
const MANAGER_CONFIG = path.join(SCRIPT_DIR, 'manager-config.json');
|
const MANAGER_CONFIG = path.join(SCRIPT_DIR, 'manager-config.json');
|
||||||
let PORT = 3333;
|
let PORT = 3333;
|
||||||
let HOST = '0.0.0.0';
|
let HOST = '0.0.0.0';
|
||||||
const APP_VERSION = '0.6.5';
|
const APP_VERSION = '0.6.6';
|
||||||
// --port 参数
|
// --port 参数
|
||||||
const portIdx = process.argv.indexOf('--port');
|
const portIdx = process.argv.indexOf('--port');
|
||||||
if (portIdx !== -1 && process.argv[portIdx + 1]) PORT = parseInt(process.argv[portIdx + 1]) || 3333;
|
if (portIdx !== -1 && process.argv[portIdx + 1]) PORT = parseInt(process.argv[portIdx + 1]) || 3333;
|
||||||
@@ -346,19 +346,28 @@ async function handleApi(req, res, urlObj, body) {
|
|||||||
const bindings = cfg.bindings || [];
|
const bindings = cfg.bindings || [];
|
||||||
const groups = cfg.channels?.telegram?.groups || {};
|
const groups = cfg.channels?.telegram?.groups || {};
|
||||||
const defaultWorkspace = defaults.workspace || null;
|
const defaultWorkspace = defaults.workspace || null;
|
||||||
|
// Build set of accountIds explicitly claimed by non-main agents (via non-peer binding)
|
||||||
|
const telegramAccounts = Object.keys(cfg.channels?.telegram?.accounts || {});
|
||||||
|
const claimedAccounts = new Set(
|
||||||
|
bindings.filter(b => b.agentId !== 'main' && b.match?.accountId && !b.match?.peer).map(b => b.match.accountId)
|
||||||
|
);
|
||||||
|
// For main agent without explicit binding, infer its accountId from first unclaimed telegram account
|
||||||
|
const mainInferredAccountId = telegramAccounts.find(a => !claimedAccounts.has(a)) || telegramAccounts[0] || null;
|
||||||
const enriched = list.map(a => {
|
const enriched = list.map(a => {
|
||||||
const binding = bindings.find(b => b.agentId === a.id && b.match?.peer?.kind === 'group');
|
const binding = bindings.find(b => b.agentId === a.id && b.match?.peer?.kind === 'group');
|
||||||
const groupId = binding?.match?.peer?.id || null;
|
const groupId = binding?.match?.peer?.id || null;
|
||||||
const modelVal = a.model?.primary || (typeof a.model === 'string' ? a.model : null);
|
const modelVal = a.model?.primary || (typeof a.model === 'string' ? a.model : null);
|
||||||
// Check if agent has its own bot account (binding with accountId but no peer, or accountId matching agent ID)
|
// Check if agent has its own bot account (binding with accountId but no peer)
|
||||||
const botBinding = bindings.find(b => b.agentId === a.id && b.match?.accountId && !b.match?.peer);
|
const botBinding = bindings.find(b => b.agentId === a.id && b.match?.accountId && !b.match?.peer);
|
||||||
const hasOwnBot = botBinding ? true : false;
|
// 'main' is always a root agent even without explicit binding
|
||||||
const accountId = botBinding?.match?.accountId || null;
|
const isMain = a.id === 'main';
|
||||||
|
const hasOwnBot = botBinding ? true : isMain;
|
||||||
|
const accountId = botBinding?.match?.accountId || (isMain ? mainInferredAccountId : null);
|
||||||
// For sub-agents (with peer match), find which accountId they belong to
|
// For sub-agents (with peer match), find which accountId they belong to
|
||||||
const parentBinding = bindings.find(b => b.agentId === a.id && b.match?.accountId);
|
const parentBinding = bindings.find(b => b.agentId === a.id && b.match?.accountId);
|
||||||
const parentAccountId = parentBinding?.match?.accountId || null;
|
const parentAccountId = parentBinding?.match?.accountId || null;
|
||||||
// Workspace: explicit per-agent, or defaults.workspace for main
|
// Workspace: explicit per-agent, or defaults.workspace for main
|
||||||
const workspace = a.workspace || (a.id === 'main' ? defaultWorkspace : null);
|
const workspace = a.workspace || (isMain ? defaultWorkspace : null);
|
||||||
return { ...a, workspace, groupId, requireMention: groupId ? (groups[groupId]?.requireMention ?? true) : null,
|
return { ...a, workspace, groupId, requireMention: groupId ? (groups[groupId]?.requireMention ?? true) : null,
|
||||||
effectiveModel: modelVal || defaults.model?.primary || '默认', hasOwnBot, accountId, parentAccountId };
|
effectiveModel: modelVal || defaults.model?.primary || '默认', hasOwnBot, accountId, parentAccountId };
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user