fix: preserve metadata on voice session touches

This commit is contained in:
Tak Hoffman
2026-03-26 10:23:13 -05:00
parent 65a1afb9df
commit df04ca7da3
2 changed files with 59 additions and 0 deletions

View File

@@ -9,6 +9,9 @@ const buildSessionLookup = (
lastChannel?: string; lastChannel?: string;
lastTo?: string; lastTo?: string;
updatedAt?: number; updatedAt?: number;
label?: string;
spawnedBy?: string;
parentSessionKey?: string;
} = {}, } = {},
): ReturnType<typeof loadSessionEntryType> => ({ ): ReturnType<typeof loadSessionEntryType> => ({
cfg: { session: { mainKey: "agent:main:main" } } as OpenClawConfig, cfg: { session: { mainKey: "agent:main:main" } } as OpenClawConfig,
@@ -19,6 +22,9 @@ const buildSessionLookup = (
updatedAt: entry.updatedAt ?? Date.now(), updatedAt: entry.updatedAt ?? Date.now(),
lastChannel: entry.lastChannel, lastChannel: entry.lastChannel,
lastTo: entry.lastTo, lastTo: entry.lastTo,
label: entry.label,
spawnedBy: entry.spawnedBy,
parentSessionKey: entry.parentSessionKey,
}, },
canonicalKey: sessionKey, canonicalKey: sessionKey,
legacyKey: undefined, legacyKey: undefined,
@@ -460,6 +466,58 @@ describe("voice transcript events", () => {
expect(agentCommandMock).toHaveBeenCalledTimes(1); expect(agentCommandMock).toHaveBeenCalledTimes(1);
expect(warn).toHaveBeenCalledWith(expect.stringContaining("voice session-store update failed")); expect(warn).toHaveBeenCalledWith(expect.stringContaining("voice session-store update failed"));
}); });
it("preserves existing session metadata when touching the store for voice transcripts", async () => {
const ctx = buildCtx();
loadSessionEntryMock.mockImplementation((sessionKey: string) =>
buildSessionLookup(sessionKey, {
sessionId: "sess-preserve",
updatedAt: 10,
label: "existing label",
spawnedBy: "agent:main:parent",
parentSessionKey: "agent:main:parent",
lastChannel: "discord",
lastTo: "thread-1",
}),
);
let updatedStore: Record<string, unknown> | undefined;
updateSessionStoreMock.mockImplementationOnce(async (_storePath, update) => {
const store = {
"voice-preserve-session": {
sessionId: "sess-preserve",
updatedAt: 10,
label: "existing label",
spawnedBy: "agent:main:parent",
parentSessionKey: "agent:main:parent",
lastChannel: "discord",
lastTo: "thread-1",
},
};
update(store);
updatedStore = structuredClone(store);
});
await handleNodeEvent(ctx, "node-v4", {
event: "voice.transcript",
payloadJSON: JSON.stringify({
text: "preserve metadata",
sessionKey: "voice-preserve-session",
}),
});
await Promise.resolve();
expect(updatedStore).toMatchObject({
"voice-preserve-session": {
sessionId: "sess-preserve",
label: "existing label",
spawnedBy: "agent:main:parent",
parentSessionKey: "agent:main:parent",
lastChannel: "discord",
lastTo: "thread-1",
},
});
});
}); });
describe("notifications changed events", () => { describe("notifications changed events", () => {

View File

@@ -154,6 +154,7 @@ async function touchSessionStore(params: {
store, store,
}); });
store[primaryKey] = { store[primaryKey] = {
...store[primaryKey],
sessionId: params.sessionId, sessionId: params.sessionId,
updatedAt: params.now, updatedAt: params.now,
thinkingLevel: params.entry?.thinkingLevel, thinkingLevel: params.entry?.thinkingLevel,