












@@ -9,6 +9,7 @@ import {
99deriveSessionKey,
1010loadSessionStore,
1111patchSessionEntry,
12+recordSessionMetaFromInbound,
1213resolveSessionFilePath,
1314resolveSessionFilePathOptions,
1415resolveSessionKey,
@@ -445,6 +446,70 @@ describe("sessions", () => {
445446expect(store[mainSessionKey]?.lastTo).toBe("99999");
446447});
447448449+it("updateLastRoute skips persistence when the route is unchanged", async () => {
450+const mainSessionKey = "agent:main:main";
451+const entry = buildMainSessionEntry({
452+route: {
453+channel: "telegram",
454+target: { to: "99999" },
455+},
456+deliveryContext: {
457+channel: "telegram",
458+to: "99999",
459+},
460+lastChannel: "telegram",
461+lastTo: "99999",
462+});
463+const { storePath } = await createSessionStoreFixture({
464+prefix: "updateLastRoute-noop",
465+entries: {
466+[mainSessionKey]: entry,
467+},
468+});
469+const before = await fs.readFile(storePath, "utf-8");
470+471+const result = await updateLastRoute({
472+ storePath,
473+sessionKey: mainSessionKey,
474+deliveryContext: {
475+channel: "telegram",
476+to: "99999",
477+},
478+});
479+480+expect(result).toEqual(entry);
481+if (result) {
482+result.lastTo = "mutated";
483+}
484+expect(loadSessionStore(storePath, { clone: false })[mainSessionKey]?.lastTo).toBe("99999");
485+await expect(fs.readFile(storePath, "utf-8")).resolves.toBe(before);
486+});
487+488+it("recordSessionMetaFromInbound skips persistence when there is no metadata patch", async () => {
489+const mainSessionKey = "agent:main:main";
490+const entry = buildMainSessionEntry();
491+const { storePath } = await createSessionStoreFixture({
492+prefix: "recordSessionMetaFromInbound-noop",
493+entries: {
494+[mainSessionKey]: entry,
495+},
496+});
497+const before = await fs.readFile(storePath, "utf-8");
498+499+const result = await recordSessionMetaFromInbound({
500+ storePath,
501+sessionKey: mainSessionKey,
502+ctx: {},
503+});
504+505+expect(result).toEqual(entry);
506+if (result) {
507+result.sessionId = "mutated";
508+}
509+expect(loadSessionStore(storePath, { clone: false })[mainSessionKey]?.sessionId).toBe("sess-1");
510+await expect(fs.readFile(storePath, "utf-8")).resolves.toBe(before);
511+});
512+448513it("updateSessionStoreEntry preserves existing fields when patching", async () => {
449514const sessionKey = "agent:main:main";
450515const { storePath } = await createSessionStoreFixture({
@@ -508,6 +573,31 @@ describe("sessions", () => {
508573expect(store[sessionKey]?.thinkingLevel).toBe("low");
509574});
510575576+it("updateSessionStoreEntry persists callback mutations returned as patches", async () => {
577+const sessionKey = "agent:main:main";
578+const { storePath } = await createSessionStoreFixture({
579+prefix: "updateSessionStoreEntry-mutated-patch",
580+entries: {
581+[sessionKey]: {
582+sessionId: "sess-1",
583+updatedAt: 123,
584+displayName: "before",
585+},
586+},
587+});
588+589+await updateSessionStoreEntry({
590+ storePath,
591+ sessionKey,
592+update: async (entry) => {
593+entry.displayName = "after";
594+return { displayName: entry.displayName };
595+},
596+});
597+598+expect(loadSessionStore(storePath)[sessionKey]?.displayName).toBe("after");
599+});
600+511601it("patchSessionEntry can preserve activity for metadata-only updates", async () => {
512602const sessionKey = "agent:main:main";
513603const { storePath } = await createSessionStoreFixture({
이 콘텐츠는 인셔셔RSS(RSS 리더)가 자동으로 집계한 것으로 읽기 참고용입니다. 원문 출처 — 저작권은 원저작자에게 있습니다.