clawdbot-55f: route sdk session patch through seam

This commit is contained in:
Josh Lehman
2026-06-01 07:05:30 -07:00
parent a61602995b
commit 3c7b433fbb
5 changed files with 97 additions and 4 deletions

View File

@@ -8,6 +8,7 @@ import { loadSessionStore as loadSessionStoreImpl } from "../config/sessions/sto
export {
getSessionEntry,
listSessionEntries,
patchSessionEntry,
updateSessionStoreEntry,
upsertSessionEntry,
} from "./session-store-runtime.js";
@@ -147,7 +148,6 @@ export type {
} from "../config/types.js";
export {
clearSessionStoreCacheForTest,
patchSessionEntry,
readSessionUpdatedAt,
recordSessionMetaFromInbound,
saveSessionStore,

View File

@@ -5,6 +5,7 @@ import { afterEach, beforeEach, describe, expect, it } from "vitest";
import {
getSessionEntry,
listSessionEntries,
patchSessionEntry,
updateSessionStoreEntry,
upsertSessionEntry,
} from "./session-store-runtime.js";
@@ -80,6 +81,19 @@ describe("session-store-runtime compatibility surface", () => {
updatedAt: 10,
},
});
const beforePatch = getSessionEntry({ sessionKey, storePath });
await expect(
patchSessionEntry({
sessionKey,
storePath,
preserveActivity: true,
update: () => ({ providerOverride: "openai", updatedAt: 20 }),
}),
).resolves.toMatchObject({
providerOverride: "openai",
sessionId: "session-1",
updatedAt: beforePatch?.updatedAt,
});
await expect(
updateSessionStoreEntry({
sessionKey,

View File

@@ -3,6 +3,7 @@
import {
listSessionEntries as listAccessorSessionEntries,
loadSessionEntry,
patchSessionEntry as patchAccessorSessionEntry,
replaceSessionEntry,
updateSessionEntry,
} from "../config/sessions/session-accessor.js";
@@ -28,6 +29,18 @@ type SessionStoreEntryUpdate = (
entry: SessionEntry,
) => Promise<Partial<SessionEntry> | null> | Partial<SessionEntry> | null;
type SessionStoreEntryPatch = (
entry: SessionEntry,
context: { existingEntry?: SessionEntry },
) => Promise<Partial<SessionEntry> | null> | Partial<SessionEntry> | null;
type PatchSessionEntryParams = SessionStoreReadParams & {
fallbackEntry?: SessionEntry;
preserveActivity?: boolean;
replaceEntry?: boolean;
update: SessionStoreEntryPatch;
};
type UpdateSessionStoreEntryParams = {
storePath: string;
sessionKey: string;
@@ -70,6 +83,27 @@ export function listSessionEntries(
});
}
/** Patches one session entry through the accessor seam. */
export async function patchSessionEntry(
params: PatchSessionEntryParams,
): Promise<SessionEntry | null> {
return await patchAccessorSessionEntry(
{
agentId: params.agentId,
env: params.env,
hydrateSkillPromptRefs: params.hydrateSkillPromptRefs,
sessionKey: params.sessionKey,
storePath: params.storePath,
},
params.update,
{
fallbackEntry: params.fallbackEntry,
preserveActivity: params.preserveActivity,
replaceEntry: params.replaceEntry,
},
);
}
/** Updates an existing session entry through the accessor seam. */
export async function updateSessionStoreEntry(
params: UpdateSessionStoreEntryParams,
@@ -114,7 +148,6 @@ export { resolveGroupSessionKey } from "../config/sessions/group.js";
export { canonicalizeMainSessionAlias } from "../config/sessions/main-session.js";
export {
clearSessionStoreCacheForTest,
patchSessionEntry,
readSessionUpdatedAt,
recordSessionMetaFromInbound,
saveSessionStore,

View File

@@ -13,12 +13,12 @@ import { resolveSessionFilePath, resolveStorePath } from "../../config/sessions/
import {
listSessionEntries as listAccessorSessionEntries,
loadSessionEntry,
patchSessionEntry as patchAccessorSessionEntry,
replaceSessionEntry,
updateSessionEntry,
} from "../../config/sessions/session-accessor.js";
import {
loadSessionStore,
patchSessionEntry,
saveSessionStore,
updateSessionStore,
} from "../../config/sessions/store.js";
@@ -52,6 +52,16 @@ type RuntimeSessionStoreEntryUpdateParams = {
takeCacheOwnership?: boolean;
};
type RuntimeSessionStoreEntryPatchParams = RuntimeSessionStoreReadParams & {
fallbackEntry?: SessionEntry;
preserveActivity?: boolean;
replaceEntry?: boolean;
update: (
entry: SessionEntry,
context: { existingEntry?: SessionEntry },
) => Promise<Partial<SessionEntry> | null> | Partial<SessionEntry> | null;
};
type RuntimeUpsertSessionEntryParams = RuntimeSessionStoreReadParams & {
entry: SessionEntry;
};
@@ -91,6 +101,26 @@ function listSessionEntries(
});
}
async function patchSessionEntry(
params: RuntimeSessionStoreEntryPatchParams,
): Promise<SessionEntry | null> {
return await patchAccessorSessionEntry(
{
agentId: params.agentId,
env: params.env,
hydrateSkillPromptRefs: params.hydrateSkillPromptRefs,
sessionKey: params.sessionKey,
storePath: params.storePath,
},
params.update,
{
fallbackEntry: params.fallbackEntry,
preserveActivity: params.preserveActivity,
replaceEntry: params.replaceEntry,
},
);
}
async function updateSessionStoreEntry(
params: RuntimeSessionStoreEntryUpdateParams,
): Promise<SessionEntry | null> {

View File

@@ -222,7 +222,23 @@ export type PluginRuntimeCore = {
sessionKey: string;
entry: import("../../config/sessions/types.js").SessionEntry;
}>;
patchSessionEntry: typeof import("../../config/sessions/store.js").patchSessionEntry;
patchSessionEntry: (params: {
agentId?: string;
env?: NodeJS.ProcessEnv;
fallbackEntry?: import("../../config/sessions/types.js").SessionEntry;
hydrateSkillPromptRefs?: boolean;
preserveActivity?: boolean;
replaceEntry?: boolean;
sessionKey: string;
storePath?: string;
update: (
entry: import("../../config/sessions/types.js").SessionEntry,
context: { existingEntry?: import("../../config/sessions/types.js").SessionEntry },
) =>
| Promise<Partial<import("../../config/sessions/types.js").SessionEntry> | null>
| Partial<import("../../config/sessions/types.js").SessionEntry>
| null;
}) => Promise<import("../../config/sessions/types.js").SessionEntry | null>;
upsertSessionEntry: (params: {
agentId?: string;
env?: NodeJS.ProcessEnv;