惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
A
About on SuperTechFans
小众软件
小众软件
Hugging Face - Blog
Hugging Face - Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 叶小钗
博客园 - 聂微东
博客园 - Franky
Apple Machine Learning Research
Apple Machine Learning Research
罗磊的独立博客
量子位
博客园 - 三生石上(FineUI控件)
Recent Announcements
Recent Announcements
The GitHub Blog
The GitHub Blog
B
Blog RSS Feed
T
The Blog of Author Tim Ferriss
GbyAI
GbyAI
云风的 BLOG
云风的 BLOG
Last Week in AI
Last Week in AI
宝玉的分享
宝玉的分享
B
Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Stack Overflow Blog
Stack Overflow Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
fix(agents): resolve bound route agent for inbound sessio...
849261680 · 2026-06-23 · via Recent Commits to openclaw:main
Original file line numberDiff line numberDiff line change

@@ -301,25 +301,30 @@ export function resolveSessionAgentIds(params: {

301301

sessionKey?: string;

302302

config?: OpenClawConfig;

303303

agentId?: string;

304+

fallbackAgentId?: string;

304305

}): {

305306

defaultAgentId: string;

306307

sessionAgentId: string;

307308

} {

308309

const defaultAgentId = resolveDefaultAgentId(params.config ?? {});

309310

const explicitAgentIdRaw = normalizeLowercaseStringOrEmpty(params.agentId);

310311

const explicitAgentId = explicitAgentIdRaw ? normalizeAgentId(explicitAgentIdRaw) : null;

312+

const fallbackAgentIdRaw = normalizeLowercaseStringOrEmpty(params.fallbackAgentId);

313+

const fallbackAgentId = fallbackAgentIdRaw ? normalizeAgentId(fallbackAgentIdRaw) : null;

311314

const sessionKey = params.sessionKey?.trim();

312315

const normalizedSessionKey = sessionKey ? normalizeLowercaseStringOrEmpty(sessionKey) : undefined;

313316

const parsed = normalizedSessionKey ? parseAgentSessionKey(normalizedSessionKey) : null;

314317

const sessionAgentId =

315-

explicitAgentId ?? (parsed?.agentId ? normalizeAgentId(parsed.agentId) : defaultAgentId);

318+

explicitAgentId ??

319+

(parsed?.agentId ? normalizeAgentId(parsed.agentId) : (fallbackAgentId ?? defaultAgentId));

316320

return { defaultAgentId, sessionAgentId };

317321

}

318322
319323

export function resolveSessionAgentId(params: {

320324

sessionKey?: string;

321325

config?: OpenClawConfig;

322326

agentId?: string;

327+

fallbackAgentId?: string;

323328

}): string {

324329

return resolveSessionAgentIds(params).sessionAgentId;

325330

}

Original file line numberDiff line numberDiff line change

@@ -68,4 +68,32 @@ describe("resolveSessionAgentIds", () => {

6868

});

6969

expect(sessionAgentId).toBe("main");

7070

});

71+
72+

it("uses fallbackAgentId for unscoped channel session keys", () => {

73+

const { sessionAgentId } = resolveSessionAgentIds({

74+

sessionKey: "feishu:direct:ou_user1",

75+

fallbackAgentId: "main",

76+

config: cfg,

77+

});

78+

expect(sessionAgentId).toBe("main");

79+

});

80+
81+

it("prefers session-key agent over fallbackAgentId", () => {

82+

const { sessionAgentId } = resolveSessionAgentIds({

83+

sessionKey: "agent:beta:feishu:direct:ou_user1",

84+

fallbackAgentId: "main",

85+

config: cfg,

86+

});

87+

expect(sessionAgentId).toBe("beta");

88+

});

89+
90+

it("prefers explicit agentId over fallbackAgentId", () => {

91+

const { sessionAgentId } = resolveSessionAgentIds({

92+

sessionKey: "feishu:direct:ou_user1",

93+

agentId: "beta",

94+

fallbackAgentId: "main",

95+

config: cfg,

96+

});

97+

expect(sessionAgentId).toBe("beta");

98+

});

7199

});

Original file line numberDiff line numberDiff line change

@@ -394,7 +394,7 @@ const resolveSessionStoreLookup = (

394394

if (!sessionKey) {

395395

return {};

396396

}

397-

const agentId = resolveSessionAgentId({ sessionKey, config: cfg, agentId: ctx.AgentId });

397+

const agentId = resolveSessionAgentId({ sessionKey, config: cfg, fallbackAgentId: ctx.AgentId });

398398

const storePath = resolveStorePath(cfg.session?.store, { agentId });

399399

try {

400400

const store = loadSessionStore(storePath);

@@ -1275,7 +1275,7 @@ export async function dispatchReplyFromConfig(

12751275

const sessionAgentId = resolveSessionAgentId({

12761276

sessionKey: acpDispatchSessionKey,

12771277

config: cfg,

1278-

agentId: ctx.AgentId,

1278+

fallbackAgentId: ctx.AgentId,

12791279

});

12801280

const sessionAgentCfg = resolveAgentConfig(cfg, sessionAgentId);

12811281

const verboseProgress = createShouldEmitVerboseProgress({

Original file line numberDiff line numberDiff line change

@@ -284,7 +284,7 @@ export async function getReplyFromConfig(

284284

agentId: resolveSessionAgentId({

285285

sessionKey: resolvedAgentSessionKey,

286286

config: cfg,

287-

agentId: finalized.AgentId,

287+

fallbackAgentId: finalized.AgentId,

288288

}),

289289

};

290290

},

Original file line numberDiff line numberDiff line change

@@ -265,6 +265,7 @@ export async function initSessionState(params: {

265265

const agentId = resolveSessionAgentId({

266266

sessionKey: sessionCtxForState.SessionKey,

267267

config: cfg,

268+

fallbackAgentId: sessionCtxForState.AgentId,

268269

});

269270

const groupResolution = resolveGroupSessionKey(sessionCtxForState) ?? undefined;

270271

const resetTriggers = sessionCfg?.resetTriggers?.length

Original file line numberDiff line numberDiff line change

@@ -137,6 +137,7 @@ describe("buildChannelInboundEventContext", () => {

137137

From: "test:user:u1",

138138

To: "test:room:room-1",

139139

SessionKey: "agent:main:test:group:room-1",

140+

AgentId: "main",

140141

AccountId: "acct",

141142

ParentSessionKey: "agent:main:test:group",

142143

ModelParentSessionKey: "agent:main:test:model",

@@ -211,6 +212,20 @@ describe("buildChannelInboundEventContext", () => {

211212

expect(ctx.CommandAuthorized).toBe(false);

212213

});

213214
215+

it("carries the routed agent for unscoped session keys", async () => {

216+

const ctx = buildChannelInboundEventContext(

217+

createBaseContextParams({

218+

route: {

219+

agentId: "bound-agent",

220+

routeSessionKey: "feishu:direct:ou_user1",

221+

},

222+

}),

223+

);

224+
225+

expect(ctx.AgentId).toBe("bound-agent");

226+

expect(ctx.SessionKey).toBe("feishu:direct:ou_user1");

227+

});

228+
214229

it("carries room event semantics into the finalized context", async () => {

215230

const ctx = buildChannelInboundEventContext(

216231

createBaseContextParams({

Original file line numberDiff line numberDiff line change

@@ -484,6 +484,7 @@ export function buildChannelInboundEventContext(

484484

From: params.from,

485485

To: params.reply.to,

486486

SessionKey: params.route.dispatchSessionKey ?? params.route.routeSessionKey,

487+

AgentId: params.route.agentId,

487488

AccountId: params.route.accountId ?? params.accountId,

488489

ParentSessionKey: params.route.parentSessionKey,

489490

ModelParentSessionKey: params.route.modelParentSessionKey,