fix(routing): resolveAgentRoute uses binding.accountId, not agent_id #11
@@ -51,6 +51,30 @@ type FabricMessage = {
|
||||
xType?: string;
|
||||
};
|
||||
|
||||
// Walk cfg.bindings for the entry that ties `agentId` to a fabric account.
|
||||
// Returns the binding's match.accountId (the slot label routing keys on);
|
||||
// returns undefined when the agent has no explicit fabric binding so the
|
||||
// caller can fall back to agentId without changing pre-existing semantics
|
||||
// for agents whose binding accountId == agent_id anyway.
|
||||
function findFabricBindingAccountId(cfg: unknown, agentId: string): string | undefined {
|
||||
const bindings = (cfg as { bindings?: Array<{
|
||||
agentId?: string;
|
||||
match?: { channel?: string; accountId?: string };
|
||||
}> })?.bindings;
|
||||
if (!Array.isArray(bindings)) return undefined;
|
||||
for (const b of bindings) {
|
||||
if (
|
||||
b?.agentId === agentId &&
|
||||
b?.match?.channel === 'fabric' &&
|
||||
typeof b?.match?.accountId === 'string' &&
|
||||
b.match.accountId.length > 0
|
||||
) {
|
||||
return b.match.accountId;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export class FabricInbound {
|
||||
private sockets: Socket[] = [];
|
||||
private seen = new Set<string>();
|
||||
@@ -541,10 +565,22 @@ export class FabricInbound {
|
||||
// (commands-handlers `isDirectMessage` checks ChatType==='direct')
|
||||
// misclassifies the turn.
|
||||
const { peerKind, chatType } = fabricPeerRoutingForXType(m.xType);
|
||||
// resolveAgentRoute needs the *binding* accountId (the channel-side
|
||||
// slot name) — not the openclaw agentId. For most agents the binding
|
||||
// is `{agentId: X, match: {channel: fabric, accountId: X}}` so the
|
||||
// two coincide; but for shared-placeholder cases (e.g. the recruitment
|
||||
// `interviewee` slot bound to multiple agents over its lifetime) the
|
||||
// binding accountId is the slot label ("interviewee", "Neon", …) not
|
||||
// the agent_id. Passing agentId there returned bindings=0 and silently
|
||||
// fell back to `main`, hijacking sub-discussion turns. Look up the
|
||||
// agent's fabric binding accountId here; fall back to agentId when no
|
||||
// explicit binding exists (preserves prior behavior for agents with
|
||||
// no fabric binding declared).
|
||||
const bindingAccountId = findFabricBindingAccountId(this.cfg, agentId) ?? agentId;
|
||||
const route = core.channel.routing.resolveAgentRoute({
|
||||
cfg: this.cfg,
|
||||
channel: 'fabric',
|
||||
accountId: agentId,
|
||||
accountId: bindingAccountId,
|
||||
peer: { kind: peerKind, id: channelId },
|
||||
});
|
||||
const storePath = core.channel.session.resolveStorePath(cfg.session?.store, {
|
||||
|
||||
Reference in New Issue
Block a user