diff --git a/packages/agentdb/package-lock.json b/packages/agentdb/package-lock.json index 57719e419..50402d8d4 100644 --- a/packages/agentdb/package-lock.json +++ b/packages/agentdb/package-lock.json @@ -1,12 +1,12 @@ { "name": "agentdb", - "version": "2.0.0-alpha.2.11", + "version": "2.0.0-alpha.2.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "agentdb", - "version": "2.0.0-alpha.2.11", + "version": "2.0.0-alpha.2.12", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -25,7 +25,7 @@ "inquirer": "^9.3.8", "marked-terminal": "^6.0.0", "ora": "^7.0.0", - "ruvector": "^0.1.24", + "ruvector": "^0.1.99", "ruvector-attention-wasm": "^0.1.0", "sql.js": "^1.13.0", "sqlite": "^5.1.1", @@ -40,7 +40,7 @@ "esbuild": "^0.25.11", "tsx": "^4.19.2", "typescript": "^5.7.2", - "vitest": "^2.1.8" + "vitest": "^2.1.9" }, "engines": { "node": ">=18.0.0" @@ -944,92 +944,113 @@ ] }, "node_modules/@ruvector/attention": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@ruvector/attention/-/attention-0.1.1.tgz", - "integrity": "sha512-Bm2w96E4T6oVkUT/dNDdb79BebamuIJIbRnA9mCc23YpLumkb59QqiiQ6Quf7bgot9X2j8QsuGnl4UK601qrdA==", - "engines": { - "node": ">= 10" - }, + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/@ruvector/attention/-/attention-0.1.31.tgz", + "integrity": "sha512-xZC1EKuR8dop64LGy0wDyiMmMnxZtTalvIy3hZSCQglM8jxV+zlj1xPDiAQVl/aZZJ59K1UaGq3J1U552EOSxA==", "optionalDependencies": { - "@ruvector/attention-darwin-x64": "0.1.1", - "@ruvector/attention-linux-x64-gnu": "0.1.1", - "@ruvector/attention-win32-x64-msvc": "0.1.1" + "@ruvector/attention-darwin-arm64": "0.1.31", + "@ruvector/attention-darwin-x64": "0.1.31", + "@ruvector/attention-linux-arm64-gnu": "0.1.31", + "@ruvector/attention-linux-x64-gnu": "0.1.31", + "@ruvector/attention-win32-x64-msvc": "0.1.31" } }, + "node_modules/@ruvector/attention-darwin-arm64": { + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/@ruvector/attention-darwin-arm64/-/attention-darwin-arm64-0.1.31.tgz", + "integrity": "sha512-9gOug/T0q5OCR65g1AKxWaJSTqTMa7kSAFH1sH2VeoNzqWr++EEOTE68vtajYSpNvM+r8788ehApCqjVW5mhHA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, "node_modules/@ruvector/attention-darwin-x64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@ruvector/attention-darwin-x64/-/attention-darwin-x64-0.1.1.tgz", - "integrity": "sha512-knMCHiTT5VbDaX5BdbRO1kiVC0x+oqoJBB+M02FTXjBJhQ1tqhirhJGGYgXjkhP+ZCzCgNFthPkgJzbSv3IUbg==", + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/@ruvector/attention-darwin-x64/-/attention-darwin-x64-0.1.31.tgz", + "integrity": "sha512-nBxQYRPU3+Z3Q8Qq4BFr/NTgw9QKjoh04vqYzECfJQJyyleIpDPWJpCwU3nhDy+4yMLdBQpQa8HYr2/C9rHCnQ==", "cpu": [ "x64" ], "optional": true, "os": [ "darwin" + ] + }, + "node_modules/@ruvector/attention-linux-arm64-gnu": { + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/@ruvector/attention-linux-arm64-gnu/-/attention-linux-arm64-gnu-0.1.31.tgz", + "integrity": "sha512-2Via10Rlfg+wzKANHsBZN01JXlONeTclPJxlYSpdsJPQ7UNlEEQ69/6y1R8sz+Ym1AE7whG0h5YWrqEyhhNcKg==", + "cpu": [ + "arm64" ], - "engines": { - "node": ">= 10" - } + "optional": true, + "os": [ + "linux" + ] }, "node_modules/@ruvector/attention-linux-x64-gnu": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@ruvector/attention-linux-x64-gnu/-/attention-linux-x64-gnu-0.1.1.tgz", - "integrity": "sha512-yY7qIyDVC1kdQYDmCGTIiFIOPQcm+DWelpWqXONgfpfCi9sdVNeBcJdBz1aETzROfBMaZyq43C7l7l8e3m3unw==", + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/@ruvector/attention-linux-x64-gnu/-/attention-linux-x64-gnu-0.1.31.tgz", + "integrity": "sha512-IXUZeS1g6V6+KYUOCy0IlVom19262stsNnoajfpUPct7udtHmD/wr3yJ6XbWxivZ2pNV7Na+z21R0oMiCGk+jA==", "cpu": [ "x64" ], "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">= 10" - } + ] }, "node_modules/@ruvector/attention-win32-x64-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@ruvector/attention-win32-x64-msvc/-/attention-win32-x64-msvc-0.1.1.tgz", - "integrity": "sha512-Byxx145kOrOKSZ2/cLzwwWcVgWMgUAcc9U/6x8zShYKSD7xpLLQe6FBORU4VKuxzZYbUBNp3lBAQTws57DSIgg==", + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/@ruvector/attention-win32-x64-msvc/-/attention-win32-x64-msvc-0.1.31.tgz", + "integrity": "sha512-eRtFASeJhWCiYC+Lcyg1pwQV+ky6PciVj+o56BchpA+36SLEvYPziIAaJ8KYaMp3zVAFadNiM3DYCmvjxB/n6A==", "cpu": [ "x64" ], "optional": true, "os": [ "win32" - ], - "engines": { - "node": ">= 10" - } + ] }, "node_modules/@ruvector/core": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/@ruvector/core/-/core-0.1.15.tgz", - "integrity": "sha512-KbSxeJmeXZBnPguOPU8MYiWJJZnqQVcN7bn7BzXVxIuOlkMjVqbHByZmbkL3N88m+T3nSDO7L7uX6ENyTxrjAg==", + "version": "0.1.30", + "resolved": "https://registry.npmjs.org/@ruvector/core/-/core-0.1.30.tgz", + "integrity": "sha512-pMeh4G3OkX2BLQZ2XUnTD8FlipRDqgvAVQlR02TTgo8/Ri2u4WmDZUHROOsKLKF7IbPLKL6G81zebiFCfC9SMA==", "engines": { - "node": ">= 18" + "node": ">=18.0.0" + }, + "optionalDependencies": { + "ruvector-core-darwin-arm64": "0.1.29", + "ruvector-core-darwin-x64": "0.1.29", + "ruvector-core-linux-arm64-gnu": "0.1.29", + "ruvector-core-linux-x64-gnu": "0.1.29", + "ruvector-core-win32-x64-msvc": "0.1.29" } }, "node_modules/@ruvector/gnn": { - "version": "0.1.19", - "resolved": "https://registry.npmjs.org/@ruvector/gnn/-/gnn-0.1.19.tgz", - "integrity": "sha512-xHdUerOT2/h0JDyBmecp2qwsUykgYRlJ8Wa2QNbjJ6Nm07/iXNernTO/kPjmUxiyZGRK2z39dUlMMXuDZJ+XdA==", + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/@ruvector/gnn/-/gnn-0.1.23.tgz", + "integrity": "sha512-LayUtIcpgLQ48O9T1J+ssk5oeGGrHO82aSPWFpzHhnUJd7Jk9jX91d9bCmnGqLGPwsiwkOfh4mZ4rKJ5YAm3CQ==", "engines": { "node": ">= 10" }, "optionalDependencies": { - "@ruvector/gnn-darwin-arm64": "0.1.19", - "@ruvector/gnn-darwin-x64": "0.1.19", - "@ruvector/gnn-linux-arm64-gnu": "0.1.19", - "@ruvector/gnn-linux-arm64-musl": "0.1.19", - "@ruvector/gnn-linux-x64-gnu": "0.1.19", - "@ruvector/gnn-linux-x64-musl": "0.1.19", - "@ruvector/gnn-win32-x64-msvc": "0.1.19" + "@ruvector/gnn-darwin-arm64": "0.1.23", + "@ruvector/gnn-darwin-x64": "0.1.23", + "@ruvector/gnn-linux-arm64-gnu": "0.1.23", + "@ruvector/gnn-linux-arm64-musl": "0.1.23", + "@ruvector/gnn-linux-x64-gnu": "0.1.23", + "@ruvector/gnn-linux-x64-musl": "0.1.23", + "@ruvector/gnn-win32-x64-msvc": "0.1.23" } }, "node_modules/@ruvector/gnn-darwin-arm64": { - "version": "0.1.19", - "resolved": "https://registry.npmjs.org/@ruvector/gnn-darwin-arm64/-/gnn-darwin-arm64-0.1.19.tgz", - "integrity": "sha512-UJ39xt0lm69451x0qrnFvXusfkJb76OOwh9IAc011B90uGWVHeutq9ep34nZdJX2rKHPPQDAVEFPHjfiVjgU7w==", + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/@ruvector/gnn-darwin-arm64/-/gnn-darwin-arm64-0.1.23.tgz", + "integrity": "sha512-ZighfK0ysK/JQk23ZfbudsYMLiluIkZecXOh1dVA9JzhJdWsJv0JDZDWdJoqtg3kFpkUfeK3bkW7qE4xH1bA/Q==", "cpu": [ "arm64" ], @@ -1042,9 +1063,9 @@ } }, "node_modules/@ruvector/gnn-darwin-x64": { - "version": "0.1.19", - "resolved": "https://registry.npmjs.org/@ruvector/gnn-darwin-x64/-/gnn-darwin-x64-0.1.19.tgz", - "integrity": "sha512-pYa5xE1qrNQrDJKZFzbYS7Tk+kL+pQtC1HeClMgULDb/tAT66FqLViHX3Qe0rNHdy5MhiCb91qzOYhVCXNA81w==", + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/@ruvector/gnn-darwin-x64/-/gnn-darwin-x64-0.1.23.tgz", + "integrity": "sha512-ZVwYx2ASfvZWDExVfPV4fPCU9VwtfxXumr5UQnkuC61rt8SCU0M7lGwQhLh08nzeQNBHvAXXlz6PV2R7aHzskg==", "cpu": [ "x64" ], @@ -1057,9 +1078,24 @@ } }, "node_modules/@ruvector/gnn-linux-arm64-gnu": { - "version": "0.1.19", - "resolved": "https://registry.npmjs.org/@ruvector/gnn-linux-arm64-gnu/-/gnn-linux-arm64-gnu-0.1.19.tgz", - "integrity": "sha512-fwg73ShQqwSDqGQ0ZllxV7GdSC8zLVmoUEh2BhnVuC6z8QVjj6rAca73Mk6d7FtKDq7rSwbmZ6fhc5quXASYgQ==", + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/@ruvector/gnn-linux-arm64-gnu/-/gnn-linux-arm64-gnu-0.1.23.tgz", + "integrity": "sha512-zwqBVvb1bvnaeLr28lsFdo5KAZ7ajssNYeTlqXj9DskyBFPe1NpWb5/wL6Q3pg/9D3tlutGMeYex3sIg1AqkgQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 18" + } + }, + "node_modules/@ruvector/gnn-linux-arm64-musl": { + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/@ruvector/gnn-linux-arm64-musl/-/gnn-linux-arm64-musl-0.1.23.tgz", + "integrity": "sha512-k1UMWvI4nq0B1NpoK6BdPaFtyD7tX1NnHK+z689+N6xNGBAdobw/E1D4cmZQULXg4E75NVX++7NypPqmrj2PPg==", "cpu": [ "arm64" ], @@ -1072,9 +1108,24 @@ } }, "node_modules/@ruvector/gnn-linux-x64-gnu": { - "version": "0.1.19", - "resolved": "https://registry.npmjs.org/@ruvector/gnn-linux-x64-gnu/-/gnn-linux-x64-gnu-0.1.19.tgz", - "integrity": "sha512-PQjR64d8Dh3wF6bXX/MlUnmryPaN83ZEvk+ecvSrkKRoYa2nmtoMlNimRa7SnjeCznLlvuhF/escW3dQiq7Dmw==", + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/@ruvector/gnn-linux-x64-gnu/-/gnn-linux-x64-gnu-0.1.23.tgz", + "integrity": "sha512-q4PaqwVW0LIDHfqL05z8KV+0+uFZRI10/82fTCKnQutZNJkCITl2oetBbmtOuA5JxEp3hQJgsOnZOe0eXdw2uQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ruvector/gnn-linux-x64-musl": { + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/@ruvector/gnn-linux-x64-musl/-/gnn-linux-x64-musl-0.1.23.tgz", + "integrity": "sha512-cxw3HleWD8i2hQpvoXuARuDyZiwksOp3eGdaxEjJUf9GiMi7edL5PsSTiXATy4wCvprM04IUJir2ave/ar/zPg==", "cpu": [ "x64" ], @@ -1087,9 +1138,9 @@ } }, "node_modules/@ruvector/gnn-win32-x64-msvc": { - "version": "0.1.19", - "resolved": "https://registry.npmjs.org/@ruvector/gnn-win32-x64-msvc/-/gnn-win32-x64-msvc-0.1.19.tgz", - "integrity": "sha512-FyEVfD60G6L7O88RDYPo7mqyc8/P4li5KMsNqwj4GBH5W+vv6cbwR9pnJuByj131/SM8XLiyqWAcHqqwtopl0A==", + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/@ruvector/gnn-win32-x64-msvc/-/gnn-win32-x64-msvc-0.1.23.tgz", + "integrity": "sha512-p1Mj4fFzb7jvgX+Gzj1wPYJfKTQ0TquAXKse2RlMFBM5rcVDs2WLImOrIA6pBpm3wamJpCGAaDIHwc9m7fZQiw==", "cpu": [ "x64" ], @@ -1221,6 +1272,208 @@ "node": ">=18.0.0" } }, + "node_modules/@ruvector/rvf": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@ruvector/rvf/-/rvf-0.1.9.tgz", + "integrity": "sha512-W40NLeSj/+FwIHT0+v3soFrtk4pnAZL5Ghx93qAsZkuwriNw2y6vGPnsapflQyp34WgMN362syIRiACXx3KW8g==", + "optional": true, + "dependencies": { + "@ruvector/rvf-node": "^0.1.7" + }, + "optionalDependencies": { + "@ruvector/rvf-solver": "^0.1.0", + "@ruvector/rvf-wasm": "^0.1.5" + } + }, + "node_modules/@ruvector/rvf-node": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@ruvector/rvf-node/-/rvf-node-0.1.7.tgz", + "integrity": "sha512-VHfEKBew62gNpi3lST0bxMw+ynRTM1xDdqca2d5A1qyW6jSCyTFJ9TAYP00uzfnTKKxezNcrzEkyQWj+gs/Pzw==", + "optional": true, + "engines": { + "node": ">= 16" + }, + "optionalDependencies": { + "@ruvector/rvf-node-darwin-arm64": "0.1.7", + "@ruvector/rvf-node-darwin-x64": "0.1.7", + "@ruvector/rvf-node-linux-arm64-gnu": "0.1.7", + "@ruvector/rvf-node-linux-x64-gnu": "0.1.7", + "@ruvector/rvf-node-win32-x64-msvc": "0.1.7" + } + }, + "node_modules/@ruvector/rvf-node-darwin-arm64": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@ruvector/rvf-node-darwin-arm64/-/rvf-node-darwin-arm64-0.1.7.tgz", + "integrity": "sha512-vll3WJwDn3oOfy1PB10IG7/f3zBpFiMNHL2/2tdJmeRR8La/rSPJ0ZH5MDIsfleiVtaWzh9bvVCtVkZ6uo2jeg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@ruvector/rvf-node-darwin-x64": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@ruvector/rvf-node-darwin-x64/-/rvf-node-darwin-x64-0.1.7.tgz", + "integrity": "sha512-Qi/l2bVuVz5YQ2RcYPYF0LNZVkytiIZHzvWhS71+Tt5GEIrsToauHQIcnJQmDNypvwxO8wYk+EeT2xcHR3ZSQQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@ruvector/rvf-node-linux-arm64-gnu": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@ruvector/rvf-node-linux-arm64-gnu/-/rvf-node-linux-arm64-gnu-0.1.7.tgz", + "integrity": "sha512-oZwrtfs7XqRVaDP6iiw6G52l7+NdP3NbTwR2iM+EP8r8X4e1+p4opwV2Ig+lyT7wAz72wcyOpkzpu1MlbK4NKA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ruvector/rvf-node-linux-x64-gnu": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@ruvector/rvf-node-linux-x64-gnu/-/rvf-node-linux-x64-gnu-0.1.7.tgz", + "integrity": "sha512-CRq9nc7dIj8QbcY9sSXvVau7cr1ESh3VnYUPp1IodzZ4SegN0H3oeieF5nUMNYyq+43MkBR4yrEwFgDBZ00QHQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ruvector/rvf-node-win32-x64-msvc": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@ruvector/rvf-node-win32-x64-msvc/-/rvf-node-win32-x64-msvc-0.1.7.tgz", + "integrity": "sha512-sgnoNphOnbD4d3+YyQ83MlGO7sX4kbcDwsFNz7p2mlTaDR8coQXoudSaPrMeMpeUojFUqoxeDvVly/un3jADig==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@ruvector/rvf-solver": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@ruvector/rvf-solver/-/rvf-solver-0.1.7.tgz", + "integrity": "sha512-wJvw+0deGnaVpsPxGNIy/QzQN47oPkFKD4koHJGVTMHgPAe8eRbzp5g8t9cB8qbHd8K6NRAAd4hr/VYEA3QHVw==", + "optional": true + }, + "node_modules/@ruvector/rvf-wasm": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@ruvector/rvf-wasm/-/rvf-wasm-0.1.6.tgz", + "integrity": "sha512-hdxRgMJqqDR5jsYBepYrdc0odGGjlwE7QsKOfKlrIWN3kC/pNulCppqKwropJsME0/ZzlLBF90YmWmSXw1AXkg==", + "optional": true + }, + "node_modules/@ruvector/sona": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@ruvector/sona/-/sona-0.1.5.tgz", + "integrity": "sha512-XHQbphnWsRzWRWGK/HxK+RreY6OdlggMrOvrfkWlEq8EctHVy2ASwps7hk25Somx8Umj7+CkNuyQEbHcNcl/oQ==", + "engines": { + "node": ">= 16" + }, + "optionalDependencies": { + "@ruvector/sona-darwin-arm64": "0.1.5", + "@ruvector/sona-darwin-x64": "0.1.5", + "@ruvector/sona-linux-arm64-gnu": "0.1.5", + "@ruvector/sona-linux-x64-gnu": "0.1.5", + "@ruvector/sona-linux-x64-musl": "0.1.5", + "@ruvector/sona-win32-arm64-msvc": "0.1.5", + "@ruvector/sona-win32-x64-msvc": "0.1.5" + } + }, + "node_modules/@ruvector/sona-darwin-arm64": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@ruvector/sona-darwin-arm64/-/sona-darwin-arm64-0.1.5.tgz", + "integrity": "sha512-+bXB7+WdbkiNbcw0Xh5VENNILgDVpuma7fyx8NwGylWaYRe1niM03k/rezdM3zbpf4qGSqp6fVKIIDU8/H9lHw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@ruvector/sona-darwin-x64": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@ruvector/sona-darwin-x64/-/sona-darwin-x64-0.1.5.tgz", + "integrity": "sha512-wnr1oxeZqaHomjRevdqvciy8BSLyxF9pjkcZ7G5rszmmNNQf+YcM9IUUEbxno4b4MXj1HJC/ZtS602PBNvf5PA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@ruvector/sona-linux-arm64-gnu": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@ruvector/sona-linux-arm64-gnu/-/sona-linux-arm64-gnu-0.1.5.tgz", + "integrity": "sha512-Kp895NJC52HfRlSjg+vZ32/8+v9eIDSbJXKMrjZNdA7aep4tsFTcE5bQG2Iru+zoIeFi+jcx0AVeqDPBS/9HHA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ruvector/sona-linux-x64-gnu": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@ruvector/sona-linux-x64-gnu/-/sona-linux-x64-gnu-0.1.5.tgz", + "integrity": "sha512-fmYlrJx9IQBHxeNX2Tu0ihHr3xsb3NwhgMmasOTOHBv/42fnxuuYrwhfHtMA6J6JtjyVxoBw1XLD6QJy4Y9BsA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ruvector/sona-linux-x64-musl": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@ruvector/sona-linux-x64-musl/-/sona-linux-x64-musl-0.1.5.tgz", + "integrity": "sha512-q0hzfilUUCQNsx2QTZ0H07FKuwdfaxh7mNuv01oq5fGCC/0beBENiL5UKxm0YHtTmMPNze83Vwp1fGT9ObOQ3g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ruvector/sona-win32-arm64-msvc": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@ruvector/sona-win32-arm64-msvc/-/sona-win32-arm64-msvc-0.1.5.tgz", + "integrity": "sha512-kk7aiedLw/Z8Xogv+sQfoYQp8Y+om7/X4Ycbl830RSNpVBXEKkQpI7vMbK55eaQ9zjBbqjtgcoZNWXzGUmbTeA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@ruvector/sona-win32-x64-msvc": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@ruvector/sona-win32-x64-msvc/-/sona-win32-x64-msvc-0.1.5.tgz", + "integrity": "sha512-ifB2meo3GeguivC5Dcq50UZEupc+F/yFZ1+cg2mVgUpoqNN9lzJ+k3IdGgdYyMu7YAM8CrgTswfp/krUwx8BLQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -4066,12 +4319,15 @@ } }, "node_modules/ruvector": { - "version": "0.1.24", - "resolved": "https://registry.npmjs.org/ruvector/-/ruvector-0.1.24.tgz", - "integrity": "sha512-upjo5+yMxMmfnrVWPbBEwQMcQQvneHhU6BLXx9rDRoCwcYK9uX0A8ZFrKV/ZpT1oqclsk/ibfYQT5X5LiGe33A==", - "dependencies": { - "@ruvector/core": "^0.1.15", - "@ruvector/gnn": "^0.1.15", + "version": "0.1.99", + "resolved": "https://registry.npmjs.org/ruvector/-/ruvector-0.1.99.tgz", + "integrity": "sha512-aYr88JDXHSs/sdvySJlQDsyS0dd8XR9Z6wMavgZgJyzvRFuRW8IPuOMgVVFtdSvPQk+5kTz2E0nQ9TZ7rcmVfg==", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0", + "@ruvector/attention": "^0.1.3", + "@ruvector/core": "^0.1.25", + "@ruvector/gnn": "^0.1.22", + "@ruvector/sona": "^0.1.4", "chalk": "^4.1.2", "commander": "^11.1.0", "ora": "^5.4.1" @@ -4081,6 +4337,9 @@ }, "engines": { "node": ">=14.0.0" + }, + "optionalDependencies": { + "@ruvector/rvf": "^0.1.0" } }, "node_modules/ruvector-attention-wasm": { @@ -4088,6 +4347,66 @@ "resolved": "https://registry.npmjs.org/ruvector-attention-wasm/-/ruvector-attention-wasm-0.1.0.tgz", "integrity": "sha512-kYdKs5fH2LkUz2TmBbSjN3m/0ZtmaOihiyPeDYDq8bwHTc3bCVxAw3bPZoY/OQvsDy34uhE/EDnqMxnpU4TWoA==" }, + "node_modules/ruvector-core-darwin-arm64": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/ruvector-core-darwin-arm64/-/ruvector-core-darwin-arm64-0.1.29.tgz", + "integrity": "sha512-gjZ1/J/0Nh9Mn74VdifIIkPLP/M4FqD/g+QVxWcfWcNFWhHVz+zHyxGjc6gJgrfYBquiMyP5jLfvyR3TffLanQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/ruvector-core-darwin-x64": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/ruvector-core-darwin-x64/-/ruvector-core-darwin-x64-0.1.29.tgz", + "integrity": "sha512-SNq2DrIBWM53qG3YSYcNV/BnBbAoJouafAADOjG3PkM8+RPrIucTeUDBavf148DNo5ZI337IS8TK1/0HpJEwFg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/ruvector-core-linux-arm64-gnu": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/ruvector-core-linux-arm64-gnu/-/ruvector-core-linux-arm64-gnu-0.1.29.tgz", + "integrity": "sha512-gcA2qSQD9nEeHR8pIXr5SKpQAiHMxu4EyBUwUSG4UnWOxVQnnU0l2kA/Z2NZ6B+JWLrb5+nhkkv7AaSmb8YAsg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/ruvector-core-linux-x64-gnu": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/ruvector-core-linux-x64-gnu/-/ruvector-core-linux-x64-gnu-0.1.29.tgz", + "integrity": "sha512-GcYCVNRbAmiXmEaMNvVnA78ZIM469H0VwP2JFGfibwiSASBgWGX3BT+mqflX+gtBynbtQqslj8XcqVdDxEkEBg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/ruvector-core-win32-x64-msvc": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/ruvector-core-win32-x64-msvc/-/ruvector-core-win32-x64-msvc-0.1.29.tgz", + "integrity": "sha512-nqHrlUAKpTreGO87jQLtFVrQUBT/7J/dBsPD5/mV9Fet/shncN0QMij7YqBTrlhR9qtQ2gAUGrG0zw69T60AiQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/ruvector/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", diff --git a/packages/agentdb/package.json b/packages/agentdb/package.json index d4ad35938..dc7c05713 100644 --- a/packages/agentdb/package.json +++ b/packages/agentdb/package.json @@ -1,6 +1,6 @@ { "name": "agentdb", - "version": "2.0.0-alpha.2.11", + "version": "2.0.0-alpha.2.21", "description": "AgentDB v2 - RuVector-powered graph database with Cypher queries, hyperedges, and ACID persistence. 150x faster than SQLite with integrated vector search, GNN learning, semantic routing, and comprehensive memory patterns. Includes reflexion memory, skill library, causal reasoning, and MCP integration.", "type": "module", "main": "dist/src/index.js", @@ -101,7 +101,7 @@ "inquirer": "^9.3.8", "marked-terminal": "^6.0.0", "ora": "^7.0.0", - "ruvector": "^0.1.24", + "ruvector": "^0.1.99", "ruvector-attention-wasm": "^0.1.0", "sql.js": "^1.13.0", "sqlite": "^5.1.1", @@ -113,7 +113,7 @@ "esbuild": "^0.25.11", "tsx": "^4.19.2", "typescript": "^5.7.2", - "vitest": "^2.1.8" + "vitest": "^2.1.9" }, "engines": { "node": ">=18.0.0" diff --git a/packages/agentdb/src/backends/ruvector/RuVectorBackend.ts b/packages/agentdb/src/backends/ruvector/RuVectorBackend.ts index 4f95ca912..fc85917d7 100644 --- a/packages/agentdb/src/backends/ruvector/RuVectorBackend.ts +++ b/packages/agentdb/src/backends/ruvector/RuVectorBackend.ts @@ -21,6 +21,11 @@ export class RuVectorBackend implements VectorBackend { private metadata: Map> = new Map(); private initialized = false; + // String ID <-> Numeric Label mappings (N-API layer requires numeric IDs) + private idToLabel: Map = new Map(); + private labelToId: Map = new Map(); + private nextLabel: number = 1; // RuVector uses 1-based labels + constructor(config: VectorConfig) { // Handle both dimension and dimensions for backward compatibility const dimension = config.dimension ?? config.dimensions; @@ -94,12 +99,24 @@ export class RuVectorBackend implements VectorBackend { /** * Insert single vector with optional metadata + * + * Maps string IDs to numeric labels before passing to the N-API layer, + * which internally requires i64 IDs. Without this mapping, non-numeric + * string IDs (e.g. UUIDs) would be silently dropped. */ insert(id: string, embedding: Float32Array, metadata?: Record): void { this.ensureInitialized(); - // RuVector expects regular arrays - this.db.insert(id, Array.from(embedding)); + // Assign or reuse a numeric label for this string ID + let label = this.idToLabel.get(id); + if (label === undefined) { + label = this.nextLabel++; + this.idToLabel.set(id, label); + this.labelToId.set(label, id); + } + + // Pass numeric label (as string) to the N-API layer + this.db.insert(String(label), Array.from(embedding)); if (metadata) { this.metadata.set(id, metadata); @@ -131,14 +148,18 @@ export class RuVectorBackend implements VectorBackend { // Perform vector search const results = this.db.search(Array.from(query), k); - // Convert results and apply filtering + // Convert results: map numeric labels back to original string IDs return results - .map((r: { id: string; distance: number }) => ({ - id: r.id, - distance: r.distance, - similarity: this.distanceToSimilarity(r.distance), - metadata: this.metadata.get(r.id) - })) + .map((r: { id: string; distance: number }) => { + const numericLabel = Number(r.id); + const originalId = this.labelToId.get(numericLabel) ?? r.id; + return { + id: originalId, + distance: r.distance, + similarity: this.distanceToSimilarity(r.distance), + metadata: this.metadata.get(originalId) + }; + }) .filter((r: SearchResult) => { // Apply similarity threshold if (options?.threshold && r.similarity < options.threshold) { @@ -162,10 +183,17 @@ export class RuVectorBackend implements VectorBackend { remove(id: string): boolean { this.ensureInitialized(); + const label = this.idToLabel.get(id); + if (label === undefined) { + return false; + } + this.metadata.delete(id); + this.idToLabel.delete(id); + this.labelToId.delete(label); try { - return this.db.remove(id); + return this.db.remove(String(label)); } catch { return false; } @@ -187,7 +215,7 @@ export class RuVectorBackend implements VectorBackend { } /** - * Save index and metadata to disk + * Save index, metadata, and ID mappings to disk */ async save(path: string): Promise { this.ensureInitialized(); @@ -195,17 +223,22 @@ export class RuVectorBackend implements VectorBackend { // Save vector index this.db.save(path); - // Save metadata separately as JSON + // Save metadata and ID mappings as a single sidecar JSON file const metadataPath = path + '.meta.json'; const fs = await import('fs/promises'); - await fs.writeFile( - metadataPath, - JSON.stringify(Object.fromEntries(this.metadata), null, 2) - ); + const savedData = { + metadata: Object.fromEntries(this.metadata), + idToLabel: Object.fromEntries(this.idToLabel), + labelToId: Object.fromEntries( + Array.from(this.labelToId.entries()).map(([k, v]) => [String(k), v]) + ), + nextLabel: this.nextLabel, + }; + await fs.writeFile(metadataPath, JSON.stringify(savedData, null, 2)); } /** - * Load index and metadata from disk + * Load index, metadata, and ID mappings from disk */ async load(path: string): Promise { this.ensureInitialized(); @@ -213,12 +246,29 @@ export class RuVectorBackend implements VectorBackend { // Load vector index this.db.load(path); - // Load metadata + // Load metadata and ID mappings const metadataPath = path + '.meta.json'; try { const fs = await import('fs/promises'); - const data = await fs.readFile(metadataPath, 'utf-8'); - this.metadata = new Map(Object.entries(JSON.parse(data))); + const raw = await fs.readFile(metadataPath, 'utf-8'); + const data = JSON.parse(raw); + + // Support both new format (with mappings) and legacy format (metadata-only) + if (data.idToLabel) { + // New format: includes ID mappings + this.metadata = new Map(Object.entries(data.metadata || {})); + this.idToLabel = new Map(Object.entries(data.idToLabel).map( + ([k, v]) => [k, v as number] + )); + this.labelToId = new Map(Object.entries(data.labelToId).map( + ([k, v]) => [Number(k), v as string] + )); + this.nextLabel = data.nextLabel || 1; + } else { + // Legacy format: only metadata, no mappings + this.metadata = new Map(Object.entries(data)); + console.debug('[RuVectorBackend] Loaded legacy metadata format (no ID mappings)'); + } } catch { // No metadata file - this is okay for backward compatibility console.debug(`[RuVectorBackend] No metadata file found at ${metadataPath}`); @@ -229,8 +279,10 @@ export class RuVectorBackend implements VectorBackend { * Close and cleanup resources */ close(): void { - // RuVector cleanup if needed this.metadata.clear(); + this.idToLabel.clear(); + this.labelToId.clear(); + this.nextLabel = 1; } /** diff --git a/packages/agentdb/tests/backends/ruvector-id-mapping.test.ts b/packages/agentdb/tests/backends/ruvector-id-mapping.test.ts new file mode 100644 index 000000000..cbe2508b0 --- /dev/null +++ b/packages/agentdb/tests/backends/ruvector-id-mapping.test.ts @@ -0,0 +1,324 @@ +/** + * RuVectorBackend ID Mapping Tests + * + * Validates fix for: https://github.com/ruvnet/agentic-flow/issues/114 + * RvfBackend silently drops vectors with non-numeric string IDs. + * + * The underlying @ruvector/core N-API layer converts IDs via Number(), + * which returns NaN for non-numeric strings (UUIDs, hex hashes, etc.). + * The fix adds idToLabel/labelToId mappings in the AgentDB layer. + */ + +import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { RuVectorBackend } from '../../src/backends/ruvector/RuVectorBackend.js'; + +// Mock VectorDB to simulate the N-API layer behavior +class MockVectorDB { + private vectors = new Map(); + private efSearch = 100; + + insert(id: string, embedding: number[]): void { + const numericId = Number(id); + // Simulate N-API behavior: NaN IDs are silently dropped + if (isNaN(numericId)) { + return; // Silent drop — this is the bug we're fixing + } + this.vectors.set(numericId, embedding); + } + + search(query: number[], k: number): Array<{ id: string; distance: number }> { + // Simple brute-force search for testing + const results: Array<{ id: number; distance: number }> = []; + for (const [id, vec] of this.vectors.entries()) { + const distance = this.cosineDistance(query, vec); + results.push({ id, distance }); + } + results.sort((a, b) => a.distance - b.distance); + return results.slice(0, k).map(r => ({ id: String(r.id), distance: r.distance })); + } + + remove(id: string): boolean { + const numericId = Number(id); + if (isNaN(numericId)) return false; + return this.vectors.delete(numericId); + } + + count(): number { + return this.vectors.size; + } + + setEfSearch(ef: number): void { + this.efSearch = ef; + } + + save(_path: string): void {} + load(_path: string): void {} + memoryUsage(): number { return 0; } + + private cosineDistance(a: number[], b: number[]): number { + let dot = 0, normA = 0, normB = 0; + for (let i = 0; i < a.length; i++) { + dot += a[i] * b[i]; + normA += a[i] * a[i]; + normB += b[i] * b[i]; + } + const denom = Math.sqrt(normA) * Math.sqrt(normB); + if (denom === 0) return 1; + return 1 - dot / denom; + } +} + +function createBackendWithMock(): RuVectorBackend { + const backend = new RuVectorBackend({ + dimension: 4, + metric: 'cosine', + maxElements: 1000, + }); + + // Inject mock DB and mark as initialized + (backend as any).db = new MockVectorDB(); + (backend as any).initialized = true; + + return backend; +} + +function randomVector(dim: number): Float32Array { + const vec = new Float32Array(dim); + for (let i = 0; i < dim; i++) vec[i] = Math.random() * 2 - 1; + return vec; +} + +describe('RuVectorBackend ID Mapping (Issue #114)', () => { + let backend: RuVectorBackend; + + beforeEach(() => { + backend = createBackendWithMock(); + }); + + afterEach(() => { + backend.close(); + }); + + describe('Non-numeric string ID support', () => { + it('should insert and retrieve vectors with UUID-style IDs', () => { + const ids = [ + 'da003664-2b0f-6ff3-747e-abcdef123456', + 'f47ac10b-58cc-4372-a567-0e02b2c3d479', + 'a1b2c3d4-e5f6-7890-abcd-ef1234567890', + ]; + + for (const id of ids) { + backend.insert(id, randomVector(4), { source: id }); + } + + const stats = backend.getStats(); + expect(stats.count).toBe(3); + }); + + it('should insert and retrieve vectors with prefix-style IDs', () => { + const ids = ['chunk_0', 'chunk_1', 'chunk_2', 'doc_abc', 'node_xyz']; + + for (const id of ids) { + backend.insert(id, randomVector(4)); + } + + expect(backend.getStats().count).toBe(5); + }); + + it('should insert and retrieve vectors with hex hash IDs', () => { + const ids = ['da003664_2b0f6ff3747e', 'abc123def456', '0xdeadbeef']; + + for (const id of ids) { + backend.insert(id, randomVector(4)); + } + + expect(backend.getStats().count).toBe(3); + }); + + it('should still work with numeric string IDs', () => { + for (let i = 1; i <= 10; i++) { + backend.insert(String(i), randomVector(4)); + } + + expect(backend.getStats().count).toBe(10); + }); + + it('should handle mixed numeric and non-numeric IDs', () => { + const ids = ['1', 'chunk_a', '42', 'uuid-xyz', '100']; + + for (const id of ids) { + backend.insert(id, randomVector(4)); + } + + expect(backend.getStats().count).toBe(5); + }); + }); + + describe('Search returns original string IDs', () => { + it('should return original non-numeric IDs in search results', () => { + const targetVec = new Float32Array([1, 0, 0, 0]); + + backend.insert('my-document-uuid', targetVec, { title: 'target' }); + backend.insert('other-doc-1', new Float32Array([0, 1, 0, 0])); + backend.insert('other-doc-2', new Float32Array([0, 0, 1, 0])); + + const results = backend.search(targetVec, 3); + + expect(results.length).toBeGreaterThan(0); + expect(results[0].id).toBe('my-document-uuid'); + expect(results[0].metadata).toEqual({ title: 'target' }); + }); + + it('should return correct metadata for string IDs in search', () => { + backend.insert('doc_alpha', randomVector(4), { category: 'alpha' }); + backend.insert('doc_beta', randomVector(4), { category: 'beta' }); + backend.insert('doc_gamma', randomVector(4), { category: 'gamma' }); + + const results = backend.search(randomVector(4), 3); + + for (const result of results) { + expect(result.id).toMatch(/^doc_/); + expect(result.metadata).toBeDefined(); + expect(result.metadata!.category).toBeDefined(); + } + }); + }); + + describe('Remove with string IDs', () => { + it('should remove vectors by non-numeric string ID', () => { + backend.insert('keep-me', randomVector(4)); + backend.insert('remove-me', randomVector(4)); + backend.insert('also-keep', randomVector(4)); + + expect(backend.getStats().count).toBe(3); + + const removed = backend.remove('remove-me'); + expect(removed).toBe(true); + expect(backend.getStats().count).toBe(2); + }); + + it('should return false for removing non-existent ID', () => { + backend.insert('exists', randomVector(4)); + + const removed = backend.remove('does-not-exist'); + expect(removed).toBe(false); + }); + }); + + describe('Batch insert with string IDs', () => { + it('should batch insert vectors with non-numeric IDs', () => { + const items = Array.from({ length: 20 }, (_, i) => ({ + id: `batch-item-${i}`, + embedding: randomVector(4), + metadata: { index: i }, + })); + + backend.insertBatch(items); + + expect(backend.getStats().count).toBe(20); + }); + }); + + describe('ID mapping persistence', () => { + it('should persist and restore ID mappings via save/load', async () => { + const fs = await import('fs/promises'); + const os = await import('os'); + const path = await import('path'); + const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'ruvector-test-')); + const savePath = path.join(tmpDir, 'test.rvf'); + + // Insert with non-numeric IDs + backend.insert('uuid-aaa', new Float32Array([1, 0, 0, 0]), { name: 'aaa' }); + backend.insert('uuid-bbb', new Float32Array([0, 1, 0, 0]), { name: 'bbb' }); + backend.insert('uuid-ccc', new Float32Array([0, 0, 1, 0]), { name: 'ccc' }); + + // Save + await backend.save(savePath); + + // Verify sidecar file contains mappings + const metaContent = JSON.parse(await fs.readFile(savePath + '.meta.json', 'utf-8')); + expect(metaContent.idToLabel).toBeDefined(); + expect(metaContent.labelToId).toBeDefined(); + expect(metaContent.nextLabel).toBe(4); // 3 items + next=4 + expect(metaContent.idToLabel['uuid-aaa']).toBeDefined(); + expect(metaContent.idToLabel['uuid-bbb']).toBeDefined(); + expect(metaContent.idToLabel['uuid-ccc']).toBeDefined(); + expect(metaContent.metadata['uuid-aaa']).toEqual({ name: 'aaa' }); + + // Create fresh backend and load + const backend2 = createBackendWithMock(); + await backend2.load(savePath); + + // Verify mappings are restored + expect((backend2 as any).idToLabel.get('uuid-aaa')).toBeDefined(); + expect((backend2 as any).idToLabel.get('uuid-bbb')).toBeDefined(); + expect((backend2 as any).idToLabel.get('uuid-ccc')).toBeDefined(); + expect((backend2 as any).nextLabel).toBe(4); + + // Cleanup + backend2.close(); + await fs.rm(tmpDir, { recursive: true, force: true }); + }); + + it('should load legacy metadata format without mappings', async () => { + const fs = await import('fs/promises'); + const os = await import('os'); + const path = await import('path'); + const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'ruvector-legacy-')); + const savePath = path.join(tmpDir, 'test.rvf'); + + // Write legacy format (metadata-only, no idToLabel) + const legacyMeta = { + 'some-id': { name: 'legacy' }, + }; + await fs.writeFile(savePath + '.meta.json', JSON.stringify(legacyMeta)); + + // Mock the save file too (load calls db.load) + await fs.writeFile(savePath, ''); + + const backend2 = createBackendWithMock(); + await backend2.load(savePath); + + // Should load metadata without crashing + expect((backend2 as any).metadata.get('some-id')).toEqual({ name: 'legacy' }); + + backend2.close(); + await fs.rm(tmpDir, { recursive: true, force: true }); + }); + }); + + describe('Re-insert same ID', () => { + it('should reuse existing label for duplicate ID', () => { + const vec1 = new Float32Array([1, 0, 0, 0]); + const vec2 = new Float32Array([0, 1, 0, 0]); + + backend.insert('my-id', vec1, { version: 1 }); + const labelAfterFirst = (backend as any).idToLabel.get('my-id'); + + backend.insert('my-id', vec2, { version: 2 }); + const labelAfterSecond = (backend as any).idToLabel.get('my-id'); + + // Should reuse the same numeric label + expect(labelAfterSecond).toBe(labelAfterFirst); + // Metadata should be updated + expect((backend as any).metadata.get('my-id')).toEqual({ version: 2 }); + }); + }); + + describe('Close resets state', () => { + it('should clear all mappings on close', () => { + backend.insert('id-1', randomVector(4)); + backend.insert('id-2', randomVector(4)); + + expect((backend as any).idToLabel.size).toBe(2); + expect((backend as any).labelToId.size).toBe(2); + + backend.close(); + + expect((backend as any).idToLabel.size).toBe(0); + expect((backend as any).labelToId.size).toBe(0); + expect((backend as any).metadata.size).toBe(0); + expect((backend as any).nextLabel).toBe(1); + }); + }); +});