Skip to content

Commit

Permalink
add initial voy implementation (langchain-ai#1181)
Browse files Browse the repository at this point in the history
* add initial voy implementation

* update implementation and tests

* add docs and examples

* fix lint

* Rename to avoid conflicts with SDK, add delete

* Mark Voy as optional

* Lint

---------

Co-authored-by: harry_squater <[email protected]>
Co-authored-by: jacoblee93 <[email protected]>
  • Loading branch information
3 people authored Sep 8, 2023
1 parent 570d052 commit 9f9a92a
Show file tree
Hide file tree
Showing 15 changed files with 421 additions and 2 deletions.
12 changes: 12 additions & 0 deletions .yarn/patches/voy-search-npm-0.6.2-d4aca30a0e.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
diff --git a/package.json b/package.json
index 1823128f20579c0c70acfb394d84d5f2997aafb9..663f5b611870e762cf355b1d4810765f9c89b318 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,7 @@
{
"name": "voy-search",
+ "type": "module",
+ "main": "voy_search.js",
"collaborators": [
"Daw-Chih Liou <[email protected]>"
],
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import CodeBlock from "@theme/CodeBlock";

# Voy

[Voy](https://github.com/tantaraio/voy) is a WASM vector similarity search engine written in Rust.
It's supported in non-Node environments like browsers. You can use Voy as a vector store with LangChain.js.

### Install Voy

```bash npm2yarn
npm install voy-search
```

## Usage

import Example from "@examples/indexes/vector_stores/voy.ts";

<CodeBlock language="typescript">{Example}</CodeBlock>
3 changes: 2 additions & 1 deletion examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
],
"scripts": {
"build": "tsc --declaration --outDir dist/",
"start": "tsx -r dotenv/config src/index.ts",
"start": "tsx --experimental-wasm-modules -r dotenv/config src/index.ts",
"postinstall": "prisma generate --schema ./src/indexes/vector_stores/prisma_vectorstore/prisma/schema.prisma",
"start:dist": "yarn build && node -r dotenv/config dist/index.js",
"lint": "eslint src",
Expand Down Expand Up @@ -54,6 +54,7 @@
"typesense": "^1.5.3",
"uuid": "^9.0.0",
"vectordb": "^0.1.4",
"voy-search": "0.6.2",
"weaviate-ts-client": "^1.0.0",
"zod": "^3.21.4",
"zod-to-json-schema": "^3.21.4"
Expand Down
49 changes: 49 additions & 0 deletions examples/src/indexes/vector_stores/voy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { VoyVectorStore } from "langchain/vectorstores/voy";
import { Voy as VoyClient } from "voy-search";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import { Document } from "langchain/document";

// Create Voy client using the library.
const voyClient = new VoyClient();
// Create embeddings
const embeddings = new OpenAIEmbeddings();
// Create the Voy store.
const store = new VoyVectorStore(voyClient, embeddings);

// Add two documents with some metadata.
await store.addDocuments([
new Document({
pageContent: "How has life been treating you?",
metadata: {
foo: "Mike",
},
}),
new Document({
pageContent: "And I took it personally...",
metadata: {
foo: "Testing",
},
}),
]);

const model = new OpenAIEmbeddings();
const query = await model.embedQuery("And I took it personally");

// Perform a similarity search.
const resultsWithScore = await store.similaritySearchVectorWithScore(query, 1);

// Print the results.
console.log(JSON.stringify(resultsWithScore, null, 2));
/*
[
[
{
"pageContent": "And I took it personally...",
"metadata": {
"foo": "Testing"
}
},
0
]
]
*/
3 changes: 3 additions & 0 deletions langchain/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ vectorstores/usearch.d.ts
vectorstores/vectara.cjs
vectorstores/vectara.js
vectorstores/vectara.d.ts
vectorstores/voy.cjs
vectorstores/voy.js
vectorstores/voy.d.ts
vectorstores/xata.cjs
vectorstores/xata.js
vectorstores/xata.d.ts
Expand Down
13 changes: 13 additions & 0 deletions langchain/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@
"vectorstores/vectara.cjs",
"vectorstores/vectara.js",
"vectorstores/vectara.d.ts",
"vectorstores/voy.cjs",
"vectorstores/voy.js",
"vectorstores/voy.d.ts",
"vectorstores/xata.cjs",
"vectorstores/xata.js",
"vectorstores/xata.d.ts",
Expand Down Expand Up @@ -725,6 +728,7 @@
"typesense": "^1.5.3",
"usearch": "^1.1.1",
"vectordb": "^0.1.4",
"voy-search": "0.6.2",
"weaviate-ts-client": "^1.4.0",
"youtube-transcript": "^1.0.6",
"youtubei.js": "^5.8.0"
Expand Down Expand Up @@ -805,6 +809,7 @@
"typesense": "^1.5.3",
"usearch": "^1.1.1",
"vectordb": "^0.1.4",
"voy-search": "0.6.2",
"weaviate-ts-client": "^1.4.0",
"youtube-transcript": "^1.0.6",
"youtubei.js": "^5.8.0"
Expand Down Expand Up @@ -1035,6 +1040,9 @@
"vectordb": {
"optional": true
},
"voy-search": {
"optional": true
},
"weaviate-ts-client": {
"optional": true
},
Expand Down Expand Up @@ -1467,6 +1475,11 @@
"import": "./vectorstores/vectara.js",
"require": "./vectorstores/vectara.cjs"
},
"./vectorstores/voy": {
"types": "./vectorstores/voy.d.ts",
"import": "./vectorstores/voy.js",
"require": "./vectorstores/voy.cjs"
},
"./vectorstores/xata": {
"types": "./vectorstores/xata.d.ts",
"import": "./vectorstores/xata.js",
Expand Down
2 changes: 2 additions & 0 deletions langchain/scripts/create-entrypoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ const entrypoints = {
"vectorstores/tigris": "vectorstores/tigris",
"vectorstores/usearch": "vectorstores/usearch",
"vectorstores/vectara": "vectorstores/vectara",
"vectorstores/voy": "vectorstores/voy",
"vectorstores/xata": "vectorstores/xata",
"vectorstores/zep": "vectorstores/zep",
// text_splitter
Expand Down Expand Up @@ -302,6 +303,7 @@ const requiresOptionalDependency = [
"vectorstores/typesense",
"vectorstores/tigris",
"vectorstores/usearch",
"vectorstores/voy",
"vectorstores/zep",
"memory/zep",
"document_loaders/web/apify_dataset",
Expand Down
1 change: 1 addition & 0 deletions langchain/src/load/import_constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const optionalImportEntrypoints = [
"langchain/vectorstores/singlestore",
"langchain/vectorstores/tigris",
"langchain/vectorstores/usearch",
"langchain/vectorstores/voy",
"langchain/vectorstores/zep",
"langchain/memory/zep",
"langchain/document_loaders/web/apify_dataset",
Expand Down
3 changes: 3 additions & 0 deletions langchain/src/load/import_type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ export interface OptionalImportMap {
"langchain/vectorstores/usearch"?:
| typeof import("../vectorstores/usearch.js")
| Promise<typeof import("../vectorstores/usearch.js")>;
"langchain/vectorstores/voy"?:
| typeof import("../vectorstores/voy.js")
| Promise<typeof import("../vectorstores/voy.js")>;
"langchain/vectorstores/zep"?:
| typeof import("../vectorstores/zep.js")
| Promise<typeof import("../vectorstores/zep.js")>;
Expand Down
49 changes: 49 additions & 0 deletions langchain/src/vectorstores/tests/voy.int.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { expect, test } from "@jest/globals";
import { Voy as VoyOriginClient } from "voy-search";
import { Document } from "../../document.js";
import { OpenAIEmbeddings } from "../../embeddings/openai.js";
import { VoyVectorStore } from "../voy.js";

const client = new VoyOriginClient();

test("it can create index using Voy.from text, add new elements to the index and get queried documents", async () => {
const vectorStore = await VoyVectorStore.fromTexts(
["initial first page", "initial second page"],
[{ id: 1 }, { id: 2 }],
new OpenAIEmbeddings(),
client
);
// the number of dimensions is produced by OpenAI
expect(vectorStore.numDimensions).toBe(1536);
await vectorStore.addDocuments([
new Document({
pageContent: "added first page",
metadata: { id: 5 },
}),
new Document({
pageContent: "added second page",
metadata: { id: 4 },
}),
new Document({
pageContent: "added third page",
metadata: { id: 6 },
}),
]);
expect(vectorStore.docstore.length).toBe(5);
await vectorStore.addDocuments([
new Document({
pageContent: "added another first page",
metadata: { id: 7 },
}),
]);
const results = await vectorStore.similaritySearchWithScore("added first", 6);
expect(results.length).toBe(6);
await vectorStore.delete({
deleteAll: true,
});
const results2 = await vectorStore.similaritySearchWithScore(
"added first",
6
);
expect(results2.length).toBe(0);
});
56 changes: 56 additions & 0 deletions langchain/src/vectorstores/tests/voy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { test, expect } from "@jest/globals";
import { Document } from "../../document.js";
import { FakeEmbeddings } from "../../embeddings/fake.js";
import { VoyVectorStore, VoyClient } from "../voy.js";

const fakeClient: VoyClient = {
index: ({ embeddings }) => embeddings.map((i) => i.id).join(","),
add: (_) => {},
search: () => ({
neighbors: [
{ id: "0", title: "", url: "" },
{ id: "1", title: "", url: "" },
],
}),
clear: () => {},
};

test("it can create index using Voy.from text, add new elements to the index and get queried documents", async () => {
const vectorStore = await VoyVectorStore.fromTexts(
["initial first page", "initial second page"],
[{ id: 1 }, { id: 2 }],
new FakeEmbeddings(),
fakeClient
);

// the number of dimensions is produced by fake embeddings
expect(vectorStore.numDimensions).toBe(4);
await vectorStore.addVectors(
[
[0, 1, 0, 0],
[1, 0, 0, 0],
[0.5, 0.5, 0.5, 0.5],
],
[
new Document({
pageContent: "added first page",
metadata: { id: 5 },
}),
new Document({
pageContent: "added second page",
metadata: { id: 4 },
}),
new Document({
pageContent: "added third page",
metadata: { id: 6 },
}),
]
);
expect(vectorStore.docstore.length).toBe(5);
const results = await vectorStore.similaritySearchVectorWithScore(
[1, 0, 0, 0],
3
);
expect(results[0][0].metadata.id).toBe(1);
expect(results[1][0].metadata.id).toBe(2);
});
Loading

0 comments on commit 9f9a92a

Please sign in to comment.