Skip to content

Commit ed55b63

Browse files
committed
fix: add regression for memory-lancedb dimensions pass-through (#32036) (thanks @scotthuang)
1 parent 31bc2cc commit ed55b63

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Docs: https://docs.openclaw.ai
4747

4848
### Fixes
4949

50+
- Memory/LanceDB embeddings: forward configured `embedding.dimensions` into OpenAI embeddings requests so vector size and API output dimensions stay aligned when dimensions are explicitly configured. (#32036) Thanks @scotthuang.
5051
- Mentions/Slack formatting hardening: add null-safe guards for runtime text normalization paths so malformed/undefined text payloads do not crash mention stripping or mrkdwn conversion. (#31865) Thanks @stone-jin.
5152
- Failover/error classification: treat HTTP `529` (provider overloaded, common with Anthropic-compatible APIs) as `rate_limit` so model failover can engage instead of misclassifying the error path. (#31854) Thanks @bugkill3r.
5253
- Voice-call/webhook routing: require exact webhook path matches (instead of prefix matches) so lookalike paths cannot reach provider verification/dispatch logic. (#31930) Thanks @afurm.

extensions/memory-lancedb/index.test.ts

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import fs from "node:fs/promises";
1212
import os from "node:os";
1313
import path from "node:path";
14-
import { describe, test, expect, beforeEach, afterEach } from "vitest";
14+
import { describe, test, expect, beforeEach, afterEach, vi } from "vitest";
1515

1616
const OPENAI_API_KEY = process.env.OPENAI_API_KEY ?? "test-key";
1717
const HAS_OPENAI_KEY = Boolean(process.env.OPENAI_API_KEY);
@@ -135,6 +135,89 @@ describe("memory plugin e2e", () => {
135135
expect(config?.autoRecall).toBe(true);
136136
});
137137

138+
test("passes configured dimensions to OpenAI embeddings API", async () => {
139+
const embeddingsCreate = vi.fn(async () => ({
140+
data: [{ embedding: [0.1, 0.2, 0.3] }],
141+
}));
142+
const toArray = vi.fn(async () => []);
143+
const limit = vi.fn(() => ({ toArray }));
144+
const vectorSearch = vi.fn(() => ({ limit }));
145+
146+
vi.resetModules();
147+
vi.doMock("openai", () => ({
148+
default: class MockOpenAI {
149+
embeddings = { create: embeddingsCreate };
150+
},
151+
}));
152+
vi.doMock("@lancedb/lancedb", () => ({
153+
connect: vi.fn(async () => ({
154+
tableNames: vi.fn(async () => ["memories"]),
155+
openTable: vi.fn(async () => ({
156+
vectorSearch,
157+
countRows: vi.fn(async () => 0),
158+
add: vi.fn(async () => undefined),
159+
delete: vi.fn(async () => undefined),
160+
})),
161+
})),
162+
}));
163+
164+
try {
165+
const { default: memoryPlugin } = await import("./index.js");
166+
// oxlint-disable-next-line typescript/no-explicit-any
167+
const registeredTools: any[] = [];
168+
const mockApi = {
169+
id: "memory-lancedb",
170+
name: "Memory (LanceDB)",
171+
source: "test",
172+
config: {},
173+
pluginConfig: {
174+
embedding: {
175+
apiKey: OPENAI_API_KEY,
176+
model: "text-embedding-3-small",
177+
dimensions: 1024,
178+
},
179+
dbPath,
180+
autoCapture: false,
181+
autoRecall: false,
182+
},
183+
runtime: {},
184+
logger: {
185+
info: vi.fn(),
186+
warn: vi.fn(),
187+
error: vi.fn(),
188+
debug: vi.fn(),
189+
},
190+
// oxlint-disable-next-line typescript/no-explicit-any
191+
registerTool: (tool: any, opts: any) => {
192+
registeredTools.push({ tool, opts });
193+
},
194+
// oxlint-disable-next-line typescript/no-explicit-any
195+
registerCli: vi.fn(),
196+
// oxlint-disable-next-line typescript/no-explicit-any
197+
registerService: vi.fn(),
198+
// oxlint-disable-next-line typescript/no-explicit-any
199+
on: vi.fn(),
200+
resolvePath: (p: string) => p,
201+
};
202+
203+
// oxlint-disable-next-line typescript/no-explicit-any
204+
memoryPlugin.register(mockApi as any);
205+
const recallTool = registeredTools.find((t) => t.opts?.name === "memory_recall")?.tool;
206+
expect(recallTool).toBeDefined();
207+
await recallTool.execute("test-call-dims", { query: "hello dimensions" });
208+
209+
expect(embeddingsCreate).toHaveBeenCalledWith({
210+
model: "text-embedding-3-small",
211+
input: "hello dimensions",
212+
dimensions: 1024,
213+
});
214+
} finally {
215+
vi.doUnmock("openai");
216+
vi.doUnmock("@lancedb/lancedb");
217+
vi.resetModules();
218+
}
219+
});
220+
138221
test("shouldCapture applies real capture rules", async () => {
139222
const { shouldCapture } = await import("./index.js");
140223

0 commit comments

Comments
 (0)