mirror of
https://fastgit.cc/github.com/openclaw/openclaw
synced 2026-05-01 06:36:23 +08:00
fix(session): clear stale thread route on system events
This commit is contained in:
@@ -2520,6 +2520,76 @@ describe("initSessionState dmScope delivery migration", () => {
|
||||
});
|
||||
|
||||
describe("initSessionState internal channel routing preservation", () => {
|
||||
it("clears stale thread routing on non-thread system-event sessions", async () => {
|
||||
const storePath = await createStorePath("system-event-clears-stale-thread-");
|
||||
const sessionKey = "agent:main:mattermost:channel:chan1";
|
||||
await writeSessionStoreFast(storePath, {
|
||||
[sessionKey]: {
|
||||
sessionId: "sess-system-event-stale-thread",
|
||||
updatedAt: Date.now(),
|
||||
lastChannel: "mattermost",
|
||||
lastTo: "channel:CHAN1",
|
||||
lastAccountId: "default",
|
||||
lastThreadId: "stale-root",
|
||||
deliveryContext: {
|
||||
channel: "mattermost",
|
||||
to: "channel:CHAN1",
|
||||
accountId: "default",
|
||||
threadId: "stale-root",
|
||||
},
|
||||
origin: {
|
||||
provider: "mattermost",
|
||||
to: "channel:CHAN1",
|
||||
accountId: "default",
|
||||
threadId: "stale-root",
|
||||
},
|
||||
},
|
||||
});
|
||||
const cfg = { session: { store: storePath } } as OpenClawConfig;
|
||||
|
||||
const result = await initSessionState({
|
||||
ctx: {
|
||||
Body: "heartbeat tick",
|
||||
SessionKey: sessionKey,
|
||||
Provider: "heartbeat",
|
||||
From: "heartbeat",
|
||||
To: "heartbeat",
|
||||
},
|
||||
cfg,
|
||||
commandAuthorized: true,
|
||||
});
|
||||
|
||||
expect(result.sessionEntry.lastChannel).toBe("mattermost");
|
||||
expect(result.sessionEntry.lastTo).toBe("channel:CHAN1");
|
||||
expect(result.sessionEntry.lastThreadId).toBeUndefined();
|
||||
expect(result.sessionEntry.deliveryContext).toEqual({
|
||||
channel: "mattermost",
|
||||
to: "channel:CHAN1",
|
||||
accountId: "default",
|
||||
});
|
||||
expect(result.sessionEntry.origin).toEqual({
|
||||
provider: "mattermost",
|
||||
to: "channel:CHAN1",
|
||||
accountId: "default",
|
||||
});
|
||||
|
||||
const persisted = JSON.parse(await fs.readFile(storePath, "utf-8")) as Record<
|
||||
string,
|
||||
SessionEntry
|
||||
>;
|
||||
expect(persisted[sessionKey]?.lastThreadId).toBeUndefined();
|
||||
expect(persisted[sessionKey]?.deliveryContext).toEqual({
|
||||
channel: "mattermost",
|
||||
to: "channel:CHAN1",
|
||||
accountId: "default",
|
||||
});
|
||||
expect(persisted[sessionKey]?.origin).toEqual({
|
||||
provider: "mattermost",
|
||||
to: "channel:CHAN1",
|
||||
accountId: "default",
|
||||
});
|
||||
});
|
||||
|
||||
it("does not synthesize heartbeat routing on a session with no external route", async () => {
|
||||
const storePath = await createStorePath("system-event-no-route-");
|
||||
const sessionKey = "agent:main:main";
|
||||
|
||||
@@ -67,6 +67,24 @@ function loadSessionArchiveRuntime() {
|
||||
return sessionArchiveRuntimePromise;
|
||||
}
|
||||
|
||||
function stripThreadIdFromDeliveryContext(
|
||||
context: SessionEntry["deliveryContext"],
|
||||
): SessionEntry["deliveryContext"] {
|
||||
if (!context || context.threadId == null || context.threadId === "") {
|
||||
return context;
|
||||
}
|
||||
const { threadId: _threadId, ...rest } = context;
|
||||
return Object.keys(rest).length > 0 ? rest : undefined;
|
||||
}
|
||||
|
||||
function stripThreadIdFromOrigin(origin: SessionEntry["origin"]): SessionEntry["origin"] {
|
||||
if (!origin || origin.threadId == null || origin.threadId === "") {
|
||||
return origin;
|
||||
}
|
||||
const { threadId: _threadId, ...rest } = origin;
|
||||
return Object.keys(rest).length > 0 ? rest : undefined;
|
||||
}
|
||||
|
||||
function resolveExplicitSessionEndReason(
|
||||
matchedResetTriggerLower?: string,
|
||||
): PluginHookSessionEndReason {
|
||||
@@ -607,6 +625,14 @@ export async function initSessionState(params: {
|
||||
if (metaPatch) {
|
||||
sessionEntry = { ...sessionEntry, ...metaPatch };
|
||||
}
|
||||
if (isSystemEvent && !isThread) {
|
||||
sessionEntry = {
|
||||
...sessionEntry,
|
||||
lastThreadId: undefined,
|
||||
deliveryContext: stripThreadIdFromDeliveryContext(sessionEntry.deliveryContext),
|
||||
origin: stripThreadIdFromOrigin(sessionEntry.origin),
|
||||
};
|
||||
}
|
||||
if (!sessionEntry.chatType) {
|
||||
sessionEntry.chatType = "direct";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user