mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 21:07:01 -06:00
fix(memory): report indexed SQLite sessions (#124834)
* fix(memory): report indexed SQLite sessions * refactor(memory): remove unused state path export
This commit is contained in:
committed by
GitHub
parent
eec67fd67b
commit
d23246770a
@@ -459,7 +459,7 @@ Index session transcripts and surface them via `memory_search`:
|
||||
| `sources` | `string[]` | `["memory"]` | Add `"sessions"` to include transcripts |
|
||||
|
||||
<Warning>
|
||||
Session indexing is opt-in and runs asynchronously. Results can be slightly stale. Session logs live on disk, so treat filesystem access as the trust boundary.
|
||||
Session indexing is opt-in and runs asynchronously. Results can be slightly stale. Active transcripts live in the agent's SQLite database, while retained transcript artifacts can live on disk. Treat access to both as part of the same trust boundary.
|
||||
</Warning>
|
||||
|
||||
<Note>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { resolveMemorySearchStaleness } from "openclaw/plugin-sdk/memory-core-host-engine-storage";
|
||||
import { resolveMemoryDreamingConfig } from "openclaw/plugin-sdk/memory-core-host-status";
|
||||
@@ -14,7 +13,6 @@ import {
|
||||
import {
|
||||
defaultRuntime,
|
||||
formatErrorMessage,
|
||||
resolveStateDir,
|
||||
setVerbose,
|
||||
shortenHomeInString,
|
||||
shortenHomePath,
|
||||
@@ -39,17 +37,14 @@ import {
|
||||
resolveShortTermRecallStorePath,
|
||||
} from "./short-term-promotion.js";
|
||||
const { accent, heading, info, muted, success, warn } = theme;
|
||||
function formatSourceLabel(source: string, workspaceDir: string, agentId: string): string {
|
||||
function formatSourceLabel(source: string, workspaceDir: string): string {
|
||||
if (source === "memory") {
|
||||
return shortenHomeInString(
|
||||
`memory (MEMORY.md + ${path.join(workspaceDir, "memory")}${path.sep}*.md)`,
|
||||
);
|
||||
}
|
||||
if (source === "sessions") {
|
||||
const stateDir = resolveStateDir(process.env, os.homedir);
|
||||
return shortenHomeInString(
|
||||
`sessions (${path.join(stateDir, "agents", agentId, "sessions")}${path.sep}*.jsonl)`,
|
||||
);
|
||||
return "sessions (current transcripts + retained transcript artifacts)";
|
||||
}
|
||||
return source;
|
||||
}
|
||||
@@ -71,7 +66,7 @@ export async function runMemoryIndex(
|
||||
const status = manager.status();
|
||||
const label = (text: string) => muted(`${text}:`);
|
||||
const sourceLabels = (status.sources ?? []).map((source) =>
|
||||
formatSourceLabel(source, status.workspaceDir ?? "", agentId),
|
||||
formatSourceLabel(source, status.workspaceDir ?? ""),
|
||||
);
|
||||
const extraPaths = status.workspaceDir
|
||||
? formatExtraPaths(status.workspaceDir, status.extraPaths ?? [])
|
||||
|
||||
@@ -394,10 +394,10 @@ export function formatMemoryIndexOutcome(
|
||||
scan: MemorySourceScan | undefined,
|
||||
agentId: string,
|
||||
): string {
|
||||
if (status.workspaceDir && scan?.totalFiles === 0) {
|
||||
const indexedFiles = status.files ?? 0;
|
||||
if (indexedFiles === 0 && status.workspaceDir && scan?.totalFiles === 0) {
|
||||
return `No memory files found in ${shortenHomePath(status.workspaceDir)}; nothing indexed (${agentId}).`;
|
||||
}
|
||||
const indexedFiles = status.files ?? 0;
|
||||
const fileLabel = indexedFiles === 1 ? "file" : "files";
|
||||
return `Memory index updated (${agentId}): ${indexedFiles} ${fileLabel} indexed.`;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ export {
|
||||
getRuntimeConfig,
|
||||
resolveDefaultAgentId,
|
||||
resolveSessionTranscriptsDirForAgent,
|
||||
resolveStateDir,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/memory-core-host-runtime-core";
|
||||
export {
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
spyRuntimeLogs,
|
||||
} from "openclaw/plugin-sdk/test-fixtures";
|
||||
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { formatMemoryIndexOutcome } from "./cli-runtime-common.js";
|
||||
import { openMemoryCoreStateStore } from "./dreaming-state.js";
|
||||
import { readShortTermRecallEntries, recordShortTermRecalls } from "./short-term-promotion.js";
|
||||
import {
|
||||
@@ -188,7 +189,7 @@ describe("memory cli", () => {
|
||||
|
||||
function makeMemoryStatus(overrides: Record<string, unknown> = {}) {
|
||||
return {
|
||||
backend: "builtin",
|
||||
backend: "builtin" as const,
|
||||
files: 0,
|
||||
chunks: 0,
|
||||
dirty: false,
|
||||
@@ -230,6 +231,27 @@ describe("memory cli", () => {
|
||||
);
|
||||
}
|
||||
|
||||
it.each([
|
||||
{
|
||||
name: "reports indexed SQLite session rows when the physical-file scan is empty",
|
||||
files: 2,
|
||||
expected: "Memory index updated (main): 2 files indexed.",
|
||||
},
|
||||
{
|
||||
name: "keeps the genuine empty-index result as a no-op",
|
||||
files: 0,
|
||||
expected: `No memory files found in /tmp/openclaw; nothing indexed (main).`,
|
||||
},
|
||||
])("$name", ({ files, expected }) => {
|
||||
expect(
|
||||
formatMemoryIndexOutcome(
|
||||
makeMemoryStatus({ files }),
|
||||
{ sources: [], totalFiles: 0, issues: [] },
|
||||
"main",
|
||||
),
|
||||
).toBe(expected);
|
||||
});
|
||||
|
||||
function stripAnsi(value: string) {
|
||||
let output = "";
|
||||
for (let index = 0; index < value.length; index += 1) {
|
||||
@@ -1423,6 +1445,26 @@ describe("memory cli", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("describes session index sources without implying active JSONL storage", async () => {
|
||||
await withTempWorkspace(async (workspaceDir) => {
|
||||
const close = vi.fn(async () => {});
|
||||
const sync = vi.fn(async () => {});
|
||||
mockManager({
|
||||
sync,
|
||||
status: () => makeMemoryStatus({ workspaceDir, sources: ["sessions"], files: 1 }),
|
||||
close,
|
||||
});
|
||||
|
||||
const log = spyRuntimeLogs(defaultRuntime);
|
||||
await runMemoryCli(["index", "--verbose"]);
|
||||
|
||||
expectLogged(log, "sessions (current transcripts + retained transcript artifacts)");
|
||||
expectNotLogged(log, "*.jsonl");
|
||||
expectLogged(log, "Memory index updated (main): 1 file indexed.");
|
||||
expect(close).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it("warns on stderr when index completes without sqlite-vec embeddings", async () => {
|
||||
const close = vi.fn(async () => {});
|
||||
const sync = vi.fn(async () => {});
|
||||
|
||||
Reference in New Issue
Block a user