fix(sessions): preserve idle reset timestamp on inbound metadata

This commit is contained in:
romeodiaz 2026-03-02 17:21:06 -08:00 committed by Peter Steinberger
parent 3eec79bd6c
commit a467517b2b
2 changed files with 48 additions and 1 deletions

View File

@ -108,4 +108,41 @@ describe("session store key normalization", () => {
expect(store[CANONICAL_KEY]?.sessionId).toBe("legacy-session");
expect(store[MIXED_CASE_KEY]).toBeUndefined();
});
it("preserves updatedAt when recording inbound metadata for an existing session", async () => {
await fs.writeFile(
storePath,
JSON.stringify(
{
[CANONICAL_KEY]: {
sessionId: "existing-session",
updatedAt: 1111,
chatType: "direct",
channel: "webchat",
origin: {
provider: "webchat",
chatType: "direct",
from: "WebChat:User-1",
to: "webchat:user-1",
},
},
},
null,
2,
),
"utf-8",
);
clearSessionStoreCacheForTest();
await recordSessionMetaFromInbound({
storePath,
sessionKey: CANONICAL_KEY,
ctx: createInboundContext(),
});
const store = loadSessionStore(storePath, { skipCache: true });
expect(store[CANONICAL_KEY]?.sessionId).toBe("existing-session");
expect(store[CANONICAL_KEY]?.updatedAt).toBe(1111);
expect(store[CANONICAL_KEY]?.origin?.provider).toBe("webchat");
});
});

View File

@ -1,3 +1,4 @@
import crypto from "node:crypto";
import fs from "node:fs";
import path from "node:path";
import { acquireSessionWriteLock } from "../../agents/session-write-lock.js";
@ -736,7 +737,16 @@ export async function recordSessionMetaFromInbound(params: {
if (!existing && !createIfMissing) {
return null;
}
const next = mergeSessionEntry(existing, patch);
const next = existing
? normalizeSessionRuntimeModelFields({
...existing,
...patch,
// Inbound metadata updates must not refresh activity timestamps;
// idle reset evaluation relies on updatedAt from actual session turns.
sessionId: existing.sessionId ?? crypto.randomUUID(),
updatedAt: existing.updatedAt ?? Date.now(),
})
: mergeSessionEntry(existing, patch);
store[resolved.normalizedKey] = next;
for (const legacyKey of resolved.legacyKeys) {
delete store[legacyKey];