





















11// Memory schema tests cover canonical table creation and shipped-name migration.
2+import fs from "node:fs";
3+import os from "node:os";
4+import path from "node:path";
25import { DatabaseSync } from "node:sqlite";
36import { describe, expect, it } from "vitest";
47import { ensureMemoryIndexSchema } from "./memory-schema.js";
@@ -87,6 +90,79 @@ describe("memory index schema", () => {
8790}
8891});
899293+it("does not import a legacy sidecar memory database during schema startup", () => {
94+const rootDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-memory-sidecar-"));
95+const legacyPath = path.join(rootDir, "memory", "main.sqlite");
96+const agentPath = path.join(rootDir, "agents", "main", "agent", "openclaw-agent.sqlite");
97+fs.mkdirSync(path.dirname(legacyPath), { recursive: true });
98+fs.mkdirSync(path.dirname(agentPath), { recursive: true });
99+const legacyDb = new DatabaseSync(legacyPath);
100+try {
101+legacyDb.exec(`
102+ CREATE TABLE meta (key TEXT PRIMARY KEY, value TEXT NOT NULL);
103+ CREATE TABLE files (
104+ path TEXT PRIMARY KEY,
105+ source TEXT NOT NULL DEFAULT 'memory',
106+ hash TEXT NOT NULL,
107+ mtime INTEGER NOT NULL,
108+ size INTEGER NOT NULL
109+ );
110+ CREATE TABLE chunks (
111+ id TEXT PRIMARY KEY,
112+ path TEXT NOT NULL,
113+ source TEXT NOT NULL DEFAULT 'memory',
114+ start_line INTEGER NOT NULL,
115+ end_line INTEGER NOT NULL,
116+ hash TEXT NOT NULL,
117+ model TEXT NOT NULL,
118+ text TEXT NOT NULL,
119+ embedding TEXT NOT NULL,
120+ updated_at INTEGER NOT NULL
121+ );
122+ CREATE TABLE embedding_cache (
123+ provider TEXT NOT NULL,
124+ model TEXT NOT NULL,
125+ provider_key TEXT NOT NULL,
126+ hash TEXT NOT NULL,
127+ embedding TEXT NOT NULL,
128+ dims INTEGER,
129+ updated_at INTEGER NOT NULL,
130+ PRIMARY KEY (provider, model, provider_key, hash)
131+ );
132+ INSERT INTO meta VALUES ('memory_index_meta_v1', '{"vectorDims":3}');
133+ INSERT INTO files VALUES ('MEMORY.md', 'memory', 'file-hash', 10, 20);
134+ INSERT INTO chunks VALUES (
135+ 'chunk-1', 'MEMORY.md', 'memory', 1, 2, 'chunk-hash', 'embed-model',
136+ 'remember this', '[1,0,0]', 30
137+ );
138+ INSERT INTO embedding_cache VALUES (
139+ 'openai', 'embed-model', 'key', 'chunk-hash', '[1,0,0]', 3, 40
140+ );
141+ `);
142+} finally {
143+legacyDb.close();
144+}
145+146+const db = new DatabaseSync(agentPath);
147+try {
148+const result = ensureMemoryIndexSchema({
149+ db,
150+cacheEnabled: true,
151+ftsEnabled: true,
152+});
153+154+expect(result.ftsAvailable).toBe(true);
155+expect(db.prepare("SELECT * FROM memory_index_sources").all()).toEqual([]);
156+expect(db.prepare("SELECT id, text FROM memory_index_chunks").all()).toEqual([]);
157+expect(db.prepare("SELECT id, text FROM memory_index_chunks_fts").all()).toEqual([]);
158+expect(db.prepare("SELECT provider, hash FROM memory_embedding_cache").all()).toEqual([]);
159+expect(fs.existsSync(legacyPath)).toBe(true);
160+} finally {
161+db.close();
162+fs.rmSync(rootDir, { recursive: true, force: true });
163+}
164+});
165+90166it("stores source records with the same path in separate sources", () => {
91167const db = new DatabaseSync(":memory:");
92168try {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。