mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
clawdbot-037: add sqlite exact session lookup
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
appendTranscriptEvent,
|
||||
appendTranscriptMessage,
|
||||
listSessionEntries,
|
||||
loadExactSessionEntry,
|
||||
loadSessionEntry,
|
||||
loadTranscriptEvents,
|
||||
patchSessionEntry,
|
||||
@@ -17,6 +18,7 @@ import {
|
||||
replaceSessionEntry,
|
||||
updateSessionEntry,
|
||||
upsertSessionEntry,
|
||||
type ExactSessionEntry,
|
||||
type SessionAccessScope,
|
||||
type SessionEntrySummary,
|
||||
type SessionTranscriptAccessScope,
|
||||
@@ -31,6 +33,7 @@ import {
|
||||
appendSqliteTranscriptEvent,
|
||||
appendSqliteTranscriptMessage,
|
||||
listSqliteSessionEntries,
|
||||
loadExactSqliteSessionEntry,
|
||||
loadSqliteSessionEntry,
|
||||
loadSqliteTranscriptEvents,
|
||||
loadSqliteTranscriptEventsSync,
|
||||
@@ -48,6 +51,7 @@ type AccessorAdapter = {
|
||||
entryScope(paths: TestPaths): SessionAccessScope;
|
||||
transcriptReadScope(paths: TestPaths, id?: string): SessionTranscriptReadScope;
|
||||
transcriptScope(paths: TestPaths, id?: string): SessionTranscriptAccessScope;
|
||||
loadExactSessionEntry(scope: SessionAccessScope): ExactSessionEntry | undefined;
|
||||
loadSessionEntry(scope: SessionAccessScope): SessionEntry | undefined;
|
||||
listSessionEntries(scope: Partial<Omit<SessionAccessScope, "sessionKey">>): SessionEntrySummary[];
|
||||
readSessionUpdatedAt(scope: SessionAccessScope): number | undefined;
|
||||
@@ -106,6 +110,7 @@ const fileBackedAdapter: AccessorAdapter = {
|
||||
storePath: paths.storePath,
|
||||
}),
|
||||
loadSessionEntry,
|
||||
loadExactSessionEntry,
|
||||
listSessionEntries,
|
||||
readSessionUpdatedAt,
|
||||
upsertSessionEntry,
|
||||
@@ -140,6 +145,7 @@ const sqliteAdapter: AccessorAdapter = {
|
||||
storePath: paths.sqlitePath,
|
||||
}),
|
||||
loadSessionEntry: loadSqliteSessionEntry,
|
||||
loadExactSessionEntry: loadExactSqliteSessionEntry,
|
||||
listSessionEntries: listSqliteSessionEntries,
|
||||
readSessionUpdatedAt: readSqliteSessionUpdatedAt,
|
||||
upsertSessionEntry: upsertSqliteSessionEntry,
|
||||
@@ -255,6 +261,30 @@ describe.each([fileBackedAdapter, sqliteAdapter])(
|
||||
});
|
||||
});
|
||||
|
||||
it("conforms for exact persisted-key lookup without canonical alias fallback", async () => {
|
||||
const scope = adapter.entryScope(paths);
|
||||
const mixedCaseScope = { ...scope, sessionKey: "AGENT:MAIN:MAIN" };
|
||||
|
||||
await adapter.upsertSessionEntry(scope, {
|
||||
model: "gpt-5.5",
|
||||
sessionId: "exact-session",
|
||||
updatedAt: 10,
|
||||
});
|
||||
|
||||
expect(adapter.loadSessionEntry(mixedCaseScope)).toMatchObject({
|
||||
model: "gpt-5.5",
|
||||
sessionId: "exact-session",
|
||||
});
|
||||
expect(adapter.loadExactSessionEntry(mixedCaseScope)).toBeUndefined();
|
||||
expect(adapter.loadExactSessionEntry(scope)).toEqual({
|
||||
sessionKey: "agent:main:main",
|
||||
entry: expect.objectContaining({
|
||||
model: "gpt-5.5",
|
||||
sessionId: "exact-session",
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
it("conforms for raw transcript event load and append", async () => {
|
||||
const scope = adapter.transcriptScope(paths);
|
||||
const readScope = adapter.transcriptReadScope(paths);
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
type OpenClawAgentDatabaseOptions,
|
||||
} from "../../state/openclaw-agent-db.js";
|
||||
import type {
|
||||
ExactSessionEntry,
|
||||
SessionAccessScope,
|
||||
SessionEntryPatchContext,
|
||||
SessionEntryPatchOptions,
|
||||
@@ -82,6 +83,20 @@ export function loadSqliteSessionEntry(scope: SessionAccessScope): SessionEntry
|
||||
return readSessionEntryRow(database, resolved.sessionKey)?.entry;
|
||||
}
|
||||
|
||||
/** Loads one exact persisted-key entry from the additive SQLite session store. */
|
||||
export function loadExactSqliteSessionEntry(
|
||||
scope: SessionAccessScope,
|
||||
): ExactSessionEntry | undefined {
|
||||
const sessionKey = scope.sessionKey.trim();
|
||||
if (!sessionKey) {
|
||||
return undefined;
|
||||
}
|
||||
const resolved = resolveSqliteScope(scope);
|
||||
const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved));
|
||||
const row = readExactSessionEntryRow(database, sessionKey);
|
||||
return row ? { sessionKey, entry: row.entry } : undefined;
|
||||
}
|
||||
|
||||
/** Lists session entries from the additive SQLite session store. */
|
||||
export function listSqliteSessionEntries(
|
||||
scope: Partial<Omit<SessionAccessScope, "sessionKey">> = {},
|
||||
@@ -498,14 +513,18 @@ function parseSessionEntryRow(row: Pick<SessionEntryRow, "entry_json">): Session
|
||||
function readSessionEntryRow(
|
||||
database: OpenClawAgentDatabase,
|
||||
sessionKey: string,
|
||||
): { entry: SessionEntry; row: SessionEntryRow } | undefined {
|
||||
return readExactSessionEntryRow(database, normalizeSqliteSessionKey(sessionKey));
|
||||
}
|
||||
|
||||
function readExactSessionEntryRow(
|
||||
database: OpenClawAgentDatabase,
|
||||
sessionKey: string,
|
||||
): { entry: SessionEntry; row: SessionEntryRow } | undefined {
|
||||
const db = getSessionKysely(database.db);
|
||||
const row = executeSqliteQueryTakeFirstSync(
|
||||
database.db,
|
||||
db
|
||||
.selectFrom("session_entries")
|
||||
.selectAll()
|
||||
.where("session_key", "=", normalizeSqliteSessionKey(sessionKey)),
|
||||
db.selectFrom("session_entries").selectAll().where("session_key", "=", sessionKey),
|
||||
);
|
||||
if (!row) {
|
||||
return undefined;
|
||||
|
||||
Reference in New Issue
Block a user