mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:20:43 +00:00
fix(active-memory): skip colon-containing session-store channels to prevent crash with QQ c2c agent IDs (#77402)
Summary: - The PR filters colon-containing store-derived Active Memory channel values before embedded recall resolution, adds a QQ c2c regression test, and records the user-facing changelog entry. - Reproducibility: yes. Source inspection on current main shows a stored colon-containing `lastChannel` or `ch ... come the strong embedded recall channel, and the downstream bundled-plugin directory validator rejects `:`. Automerge notes: - PR branch already contained follow-up commit before automerge: fixup! fix(active-memory): add changelog contributor credit (clawswee… - PR branch already contained follow-up commit before automerge: fix(active-memory): skip colon-containing session-store channels Validation: - ClawSweeper review passed for head4bf00dd6ac. - Required merge gates passed before the squash merge. Prepared head SHA:4bf00dd6acReview: https://github.com/openclaw/openclaw/pull/77402#issuecomment-4372618783 Co-authored-by: HCL <chenglunhu@gmail.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
This commit is contained in:
@@ -2753,6 +2753,33 @@ describe("active-memory plugin", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("skips colon-containing session-store channels for embedded recall (#77396)", async () => {
|
||||
hoisted.sessionStore["agent:main:qqbot:direct:12345"] = {
|
||||
sessionId: "session-a",
|
||||
updatedAt: 25,
|
||||
channel: "c2c:10D4F7C2",
|
||||
origin: {
|
||||
provider: "qqbot",
|
||||
},
|
||||
};
|
||||
|
||||
await hooks.before_prompt_build(
|
||||
{ prompt: "what wings should i order? scoped stored channel", messages: [] },
|
||||
{
|
||||
agentId: "main",
|
||||
trigger: "user",
|
||||
sessionKey: "agent:main:qqbot:direct:12345",
|
||||
messageProvider: "qqbot",
|
||||
channelId: "qqbot",
|
||||
},
|
||||
);
|
||||
|
||||
expect(runEmbeddedPiAgent.mock.calls.at(-1)?.[0]).toMatchObject({
|
||||
messageChannel: "qqbot",
|
||||
messageProvider: "qqbot",
|
||||
});
|
||||
});
|
||||
|
||||
it("preserves an explicit real channel hint over a stale stored wrapper channel", async () => {
|
||||
hoisted.sessionStore["agent:main:telegram:direct:12345"] = {
|
||||
sessionId: "session-a",
|
||||
|
||||
@@ -560,9 +560,17 @@ function resolveRecallRunChannelContext(params: {
|
||||
store,
|
||||
sessionKey: resolvedSessionKey,
|
||||
}).existing;
|
||||
const strongEntryChannel =
|
||||
const rawStrongEntryChannel =
|
||||
normalizeOptionalString(sessionEntry?.lastChannel) ??
|
||||
normalizeOptionalString(sessionEntry?.channel);
|
||||
// Channel IDs containing ":" are scoped conversation IDs (e.g. QQ c2c
|
||||
// "c2c:10D4F7C2..."), not runnable channel names. The same guard that
|
||||
// applies to explicit channelId (#76704) must also apply to channels
|
||||
// read from the session store (#77396).
|
||||
const strongEntryChannel =
|
||||
rawStrongEntryChannel && !rawStrongEntryChannel.includes(":")
|
||||
? rawStrongEntryChannel
|
||||
: undefined;
|
||||
const weakEntryChannel = normalizeOptionalString(sessionEntry?.origin?.provider);
|
||||
return resolveReturnValue({
|
||||
resolvedChannel: strongEntryChannel ?? weakEntryChannel,
|
||||
|
||||
Reference in New Issue
Block a user