|
11 | 11 | import { Buffer } from "node:buffer"; |
12 | 12 | import fs from "node:fs/promises"; |
13 | 13 | import path from "node:path"; |
| 14 | +import { Command } from "commander"; |
14 | 15 | import { |
15 | 16 | clearMemoryPluginState, |
16 | 17 | getMemoryCapabilityRegistration, |
@@ -708,6 +709,73 @@ describe("memory plugin e2e", () => { |
708 | 709 | }); |
709 | 710 | }); |
710 | 711 |
|
| 712 | + test("normalizes signed decimal CLI limits through the shared parser", async () => { |
| 713 | + const ensureGlobalUndiciEnvProxyDispatcher = vi.fn(); |
| 714 | + const toArray = vi.fn(async () => []); |
| 715 | + const limit = vi.fn(() => ({ toArray })); |
| 716 | + const select = vi.fn(() => ({ limit, toArray })); |
| 717 | + const query = vi.fn(() => ({ select })); |
| 718 | + const loadLanceDbModule = vi.fn(async () => ({ |
| 719 | + connect: vi.fn(async () => ({ |
| 720 | + tableNames: vi.fn(async () => ["memories"]), |
| 721 | + openTable: vi.fn(async () => ({ |
| 722 | + query, |
| 723 | + countRows: vi.fn(async () => 0), |
| 724 | + add: vi.fn(async () => undefined), |
| 725 | + delete: vi.fn(async () => undefined), |
| 726 | + })), |
| 727 | + })), |
| 728 | + })); |
| 729 | + |
| 730 | + await withMockedOpenAiMemoryPlugin({ |
| 731 | + ensureGlobalUndiciEnvProxyDispatcher, |
| 732 | + loadLanceDbModule, |
| 733 | + run: async (dynamicMemoryPlugin) => { |
| 734 | + const registerCli = vi.fn(); |
| 735 | + const mockApi = { |
| 736 | + id: "memory-lancedb", |
| 737 | + name: "Memory (LanceDB)", |
| 738 | + source: "test", |
| 739 | + config: {}, |
| 740 | + pluginConfig: { |
| 741 | + embedding: { |
| 742 | + apiKey: OPENAI_API_KEY, |
| 743 | + model: "text-embedding-3-small", |
| 744 | + }, |
| 745 | + dbPath: getDbPath(), |
| 746 | + autoCapture: false, |
| 747 | + autoRecall: false, |
| 748 | + }, |
| 749 | + runtime: {}, |
| 750 | + logger: { |
| 751 | + info: vi.fn(), |
| 752 | + warn: vi.fn(), |
| 753 | + error: vi.fn(), |
| 754 | + debug: vi.fn(), |
| 755 | + }, |
| 756 | + registerTool: vi.fn(), |
| 757 | + registerCli, |
| 758 | + registerService: vi.fn(), |
| 759 | + on: vi.fn(), |
| 760 | + resolvePath: (filePath: string) => filePath, |
| 761 | + }; |
| 762 | + const log = vi.spyOn(console, "log").mockImplementation(() => undefined); |
| 763 | + try { |
| 764 | + dynamicMemoryPlugin.register(mockApi as any); |
| 765 | + const registrar = firstMockArg(registerCli as unknown as MockCallSource, "cli registrar"); |
| 766 | + const program = new Command(); |
| 767 | + (registrar as (params: { program: Command }) => void)({ program }); |
| 768 | + |
| 769 | + await program.parseAsync(["node", "openclaw", "ltm", "list", "--limit", "+03"]); |
| 770 | + |
| 771 | + expect(limit).toHaveBeenCalledWith(3); |
| 772 | + } finally { |
| 773 | + log.mockRestore(); |
| 774 | + } |
| 775 | + }, |
| 776 | + }); |
| 777 | + }); |
| 778 | + |
711 | 779 | test("keeps before_prompt_build registered but inert when auto-recall is disabled", async () => { |
712 | 780 | const on = vi.fn(); |
713 | 781 | const mockApi = { |
|
0 commit comments