Compare commits
1 Commits
180b717eda
...
fix/routin
| Author | SHA1 | Date | |
|---|---|---|---|
| ea713064e1 |
@@ -51,6 +51,30 @@ type FabricMessage = {
|
|||||||
xType?: string;
|
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 {
|
export class FabricInbound {
|
||||||
private sockets: Socket[] = [];
|
private sockets: Socket[] = [];
|
||||||
private seen = new Set<string>();
|
private seen = new Set<string>();
|
||||||
@@ -541,10 +565,22 @@ export class FabricInbound {
|
|||||||
// (commands-handlers `isDirectMessage` checks ChatType==='direct')
|
// (commands-handlers `isDirectMessage` checks ChatType==='direct')
|
||||||
// misclassifies the turn.
|
// misclassifies the turn.
|
||||||
const { peerKind, chatType } = fabricPeerRoutingForXType(m.xType);
|
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({
|
const route = core.channel.routing.resolveAgentRoute({
|
||||||
cfg: this.cfg,
|
cfg: this.cfg,
|
||||||
channel: 'fabric',
|
channel: 'fabric',
|
||||||
accountId: agentId,
|
accountId: bindingAccountId,
|
||||||
peer: { kind: peerKind, id: channelId },
|
peer: { kind: peerKind, id: channelId },
|
||||||
});
|
});
|
||||||
const storePath = core.channel.session.resolveStorePath(cfg.session?.store, {
|
const storePath = core.channel.session.resolveStorePath(cfg.session?.store, {
|
||||||
|
|||||||
Reference in New Issue
Block a user