Compare commits

...

4 Commits

Author SHA1 Message Date
github-actions[bot] 28b877e31f Release 0.5.25 (#1182)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-11 12:08:39 -07:00
Alex Yang 4389b80a52 docs: update README.md (#1183) 2024-09-11 11:07:00 -07:00
Alex Yang d3bc663951 fix: vector store cleanup (#1175) 2024-09-11 10:20:55 -07:00
Kieran Simkin 4810364788 fix: handle RouterQueryEngine with string query (#1181) 2024-09-11 10:19:59 -07:00
58 changed files with 487 additions and 116 deletions
+15
View File
@@ -19,6 +19,11 @@ jobs:
matrix:
node-version: [18.x, 20.x, 22.x]
name: E2E on Node.js ${{ matrix.node-version }}
env: POSTGRES_DB=vectordb
POSTGRES_USER=testuser
POSTGRES_PASSWORD=testpwd
POSTGRES_HOST_AUTH_METHOD=trust
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -45,6 +50,16 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: ankane/setup-postgres@v1
with:
database: llamaindex_node_test
dev-files: true
- run: |
cd /tmp
git clone --branch v0.7.0 https://github.com/pgvector/pgvector.git
cd pgvector
make
sudo make install
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
+36 -1
View File
@@ -36,9 +36,44 @@ For now, browser support is limited due to the lack of support for [AsyncLocalSt
npm install llamaindex
pnpm install llamaindex
yarn add llamaindex
jsr install @llamaindex/core
```
### Setup TypeScript
```json5
{
compilerOptions: {
// ⬇️ add this line to your tsconfig.json
moduleResolution: "bundler", // or "node16"
},
}
```
<details>
<summary>Why?</summary>
We are shipping both ESM and CJS module, and compatible with Vercel Edge, Cloudflare Workers, and other serverless platforms.
So we are using [conditional exports](https://nodejs.org/api/packages.html#conditional-exports) to support all environments.
This is a kind of modern way of shipping packages, but might cause TypeScript type check to fail because of legacy module resolution.
Imaging you put output file into `/dist/openai.js` but you are importing `llamaindex/openai` in your code, and set `package.json` like this:
```json
{
"exports": {
"./openai": "./dist/openai.js"
}
}
```
In old module resolution, TypeScript will not be able to find the module because it is not follow the file structure, even you run `node index.js` successfully. (on Node.js >=16)
See more about [moduleResolution](https://www.typescriptlang.org/docs/handbook/modules/theory.html#module-resolution) or
[TypeScript 5.0 blog](https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/#--moduleresolution-bundler7).
</details>
### Node.js
```ts
+8
View File
@@ -1,5 +1,13 @@
# docs
## 0.0.66
### Patch Changes
- Updated dependencies [4810364]
- Updated dependencies [d3bc663]
- llamaindex@0.5.25
## 0.0.65
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "docs",
"version": "0.0.65",
"version": "0.0.66",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
@@ -1,5 +1,14 @@
# @llamaindex/autotool-01-node-example
## 0.0.6
### Patch Changes
- Updated dependencies [4810364]
- Updated dependencies [d3bc663]
- llamaindex@0.5.25
- @llamaindex/autotool@2.0.1
## 0.0.5
### Patch Changes
@@ -13,5 +13,5 @@
"scripts": {
"start": "node --import tsx --import @llamaindex/autotool/node ./src/index.ts"
},
"version": "0.0.5"
"version": "0.0.6"
}
@@ -1,5 +1,14 @@
# @llamaindex/autotool-02-next-example
## 0.1.50
### Patch Changes
- Updated dependencies [4810364]
- Updated dependencies [d3bc663]
- llamaindex@0.5.25
- @llamaindex/autotool@2.0.1
## 0.1.49
### Patch Changes
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/autotool-02-next-example",
"private": true,
"version": "0.1.49",
"version": "0.1.50",
"scripts": {
"dev": "next dev",
"build": "next build",
+1 -1
View File
@@ -51,7 +51,7 @@
"unplugin": "^1.12.2"
},
"peerDependencies": {
"llamaindex": "^0.5.24",
"llamaindex": "^0.5.25",
"openai": "^4",
"typescript": "^4"
},
+6
View File
@@ -1,5 +1,11 @@
# @llamaindex/cloud
## 0.2.4
### Patch Changes
- 4810364: fix: bump version
## 0.2.3
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/cloud",
"version": "0.2.3",
"version": "0.2.4",
"type": "module",
"license": "MIT",
"scripts": {
+8
View File
@@ -1,5 +1,13 @@
# @llamaindex/experimental
## 0.0.75
### Patch Changes
- Updated dependencies [4810364]
- Updated dependencies [d3bc663]
- llamaindex@0.5.25
## 0.0.74
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/experimental",
"description": "Experimental package for LlamaIndexTS",
"version": "0.0.74",
"version": "0.0.75",
"type": "module",
"types": "dist/type/index.d.ts",
"main": "dist/cjs/index.js",
+12
View File
@@ -1,5 +1,17 @@
# llamaindex
## 0.5.25
### Patch Changes
- 4810364: fix: handle `RouterQueryEngine` with string query
- d3bc663: refactor: export vector store only in nodejs environment on top level
If you see some missing modules error, please change vector store related imports to `llamaindex/vector-store`
- Updated dependencies [4810364]
- @llamaindex/cloud@0.2.4
## 0.5.24
### Patch Changes
@@ -1,5 +1,13 @@
# @llamaindex/cloudflare-worker-agent-test
## 0.0.59
### Patch Changes
- Updated dependencies [4810364]
- Updated dependencies [d3bc663]
- llamaindex@0.5.25
## 0.0.58
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/cloudflare-worker-agent-test",
"version": "0.0.58",
"version": "0.0.59",
"type": "module",
"private": true,
"scripts": {
@@ -1,5 +1,13 @@
# @llamaindex/next-agent-test
## 0.1.59
### Patch Changes
- Updated dependencies [4810364]
- Updated dependencies [d3bc663]
- llamaindex@0.5.25
## 0.1.58
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/next-agent-test",
"version": "0.1.58",
"version": "0.1.59",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,5 +1,13 @@
# test-edge-runtime
## 0.1.58
### Patch Changes
- Updated dependencies [4810364]
- Updated dependencies [d3bc663]
- llamaindex@0.5.25
## 0.1.57
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/nextjs-edge-runtime-test",
"version": "0.1.57",
"version": "0.1.58",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,5 +1,13 @@
# @llamaindex/next-node-runtime
## 0.0.40
### Patch Changes
- Updated dependencies [4810364]
- Updated dependencies [d3bc663]
- llamaindex@0.5.25
## 0.0.39
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/next-node-runtime-test",
"version": "0.0.39",
"version": "0.0.40",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,5 +1,13 @@
# @llamaindex/waku-query-engine-test
## 0.0.59
### Patch Changes
- Updated dependencies [4810364]
- Updated dependencies [d3bc663]
- llamaindex@0.5.25
## 0.0.58
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/waku-query-engine-test",
"version": "0.0.58",
"version": "0.0.59",
"type": "module",
"private": true,
"scripts": {
+67
View File
@@ -0,0 +1,67 @@
import { LLMSingleSelector, Settings } from "llamaindex";
import assert from "node:assert";
import { test } from "node:test";
import { mockLLMEvent } from "./utils.js";
await test("#1177", async (t) => {
await mockLLMEvent(t, "#1177");
await t.test(async () => {
const selector = new LLMSingleSelector({
llm: Settings.llm,
});
{
const result = await selector.select(
[
{
description: "Math calculation",
},
{
description: "Search from google",
},
],
"calculate 2 + 2",
);
assert.equal(result.selections.length, 1);
assert.equal(result.selections.at(0)!.index, 0);
}
{
const result = await selector.select(
[
{
description: "Math calculation",
},
{
description: "Search from google",
},
],
{
query: "calculate 2 + 2",
},
);
assert.equal(result.selections.length, 1);
assert.equal(result.selections.at(0)!.index, 0);
}
{
const result = await selector.select(
[
{
description: "Math calculation",
},
{
description: "Search from google",
},
],
{
query: [
{
type: "text",
text: "calculate 2 + 2",
},
],
},
);
assert.equal(result.selections.length, 1);
assert.equal(result.selections.at(0)!.index, 0);
}
});
});
@@ -0,0 +1,67 @@
{
"llmEventStart": [
{
"id": "PRESERVE_0",
"messages": [
{
"content": "Some choices are given below. It is provided in a numbered list (1 to 42), where each item in the list corresponds to a summary.\n---------------------\n(1) Math calculation(2) Search from google\n---------------------\nUsing only the choices above and not prior knowledge, return the choice that is most relevant to the question: 'calculate 2 + 2'\n\n\nThe output should be ONLY JSON formatted as a JSON instance.\n\nHere is an example:\n[\n {\n \"choice\": 1,\n \"reason\": \"<insert reason for choice>\"\n },\n ...\n]\n",
"role": "user"
}
]
},
{
"id": "PRESERVE_1",
"messages": [
{
"content": "Some choices are given below. It is provided in a numbered list (1 to 42), where each item in the list corresponds to a summary.\n---------------------\n(1) Math calculation(2) Search from google\n---------------------\nUsing only the choices above and not prior knowledge, return the choice that is most relevant to the question: 'calculate 2 + 2'\n\n\nThe output should be ONLY JSON formatted as a JSON instance.\n\nHere is an example:\n[\n {\n \"choice\": 1,\n \"reason\": \"<insert reason for choice>\"\n },\n ...\n]\n",
"role": "user"
}
]
},
{
"id": "PRESERVE_2",
"messages": [
{
"content": "Some choices are given below. It is provided in a numbered list (1 to 42), where each item in the list corresponds to a summary.\n---------------------\n(1) Math calculation(2) Search from google\n---------------------\nUsing only the choices above and not prior knowledge, return the choice that is most relevant to the question: 'calculate 2 + 2'\n\n\nThe output should be ONLY JSON formatted as a JSON instance.\n\nHere is an example:\n[\n {\n \"choice\": 1,\n \"reason\": \"<insert reason for choice>\"\n },\n ...\n]\n",
"role": "user"
}
]
}
],
"llmEventEnd": [
{
"id": "PRESERVE_0",
"response": {
"raw": null,
"message": {
"content": "[\n {\n \"choice\": 1,\n \"reason\": \"The question 'calculate 2 + 2' is directly asking for a math calculation, which corresponds to choice 1.\"\n }\n]",
"role": "assistant",
"options": {}
}
}
},
{
"id": "PRESERVE_1",
"response": {
"raw": null,
"message": {
"content": "[\n {\n \"choice\": 1,\n \"reason\": \"The question 'calculate 2 + 2' is asking for a mathematical calculation, which directly corresponds to choice 1: Math calculation.\"\n }\n]",
"role": "assistant",
"options": {}
}
}
},
{
"id": "PRESERVE_2",
"response": {
"raw": null,
"message": {
"content": "[\n {\n \"choice\": 1,\n \"reason\": \"The question 'calculate 2 + 2' is asking for a mathematical calculation, which directly corresponds to choice 1: Math calculation.\"\n }\n]",
"role": "assistant",
"options": {}
}
}
}
],
"llmEventStream": []
}
+12 -4
View File
@@ -1,6 +1,6 @@
{
"name": "llamaindex",
"version": "0.5.24",
"version": "0.5.25",
"license": "MIT",
"type": "module",
"keywords": [
@@ -59,8 +59,6 @@
"openai": "^4.57.0",
"papaparse": "^5.4.1",
"pathe": "^1.1.2",
"pg": "^8.12.0",
"pgvector": "^0.2.0",
"portkey-ai": "0.1.16",
"rake-modified": "^1.0.8",
"string-strip-html": "^13.4.8",
@@ -72,11 +70,19 @@
"zod": "^3.23.8"
},
"peerDependencies": {
"@notionhq/client": "^2.2.15"
"@notionhq/client": "^2.2.15",
"pg": "^8.12.0",
"pgvector": "0.2.0"
},
"peerDependenciesMeta": {
"@notionhq/client": {
"optional": true
},
"pg": {
"optional": true
},
"pgvector": {
"optional": true
}
},
"devDependencies": {
@@ -85,6 +91,8 @@
"@swc/core": "^1.7.22",
"concurrently": "^8.2.2",
"glob": "^11.0.0",
"pg": "^8.12.0",
"pgvector": "0.2.0",
"typescript": "^5.5.4"
},
"engines": {
+4 -2
View File
@@ -59,10 +59,12 @@ class GlobalSettings implements Config {
}
get llm(): LLM {
if (CoreSettings.llm === null) {
// fixme: we might need check internal error instead of try-catch here
try {
CoreSettings.llm;
} catch (error) {
CoreSettings.llm = new OpenAI();
}
return CoreSettings.llm;
}
+4
View File
@@ -17,3 +17,7 @@ export { GeminiVertexSession } from "./llm/gemini/vertex.js";
// Expose AzureDynamicSessionTool for node.js runtime only
export { JinaAIEmbedding } from "./embeddings/JinaAIEmbedding.js";
export { AzureDynamicSessionTool } from "./tools/AzureDynamicSessionTool.node.js";
// Don't export vector store modules for non-node.js runtime on top level,
// as we cannot guarantee that they will work in other environments
export * from "./vector-store.js";
@@ -29,16 +29,16 @@ import {
import type { BaseNodePostprocessor } from "../../postprocessors/types.js";
import type { StorageContext } from "../../storage/StorageContext.js";
import { storageContextFromDefaults } from "../../storage/StorageContext.js";
import type { BaseIndexStore } from "../../storage/indexStore/types.js";
import type { BaseSynthesizer } from "../../synthesizers/types.js";
import type { QueryEngine } from "../../types.js";
import type {
MetadataFilters,
VectorStore,
VectorStoreByType,
VectorStoreQueryResult,
} from "../../storage/index.js";
import type { BaseIndexStore } from "../../storage/indexStore/types.js";
import { VectorStoreQueryMode } from "../../storage/vectorStore/types.js";
import type { BaseSynthesizer } from "../../synthesizers/types.js";
import type { QueryEngine } from "../../types.js";
} from "../../vector-store/index.js";
import { VectorStoreQueryMode } from "../../vector-store/types.js";
import type { BaseIndexInit } from "../BaseIndex.js";
import { BaseIndex } from "../BaseIndex.js";
import { IndexDict, IndexStructType } from "../json-to-index-struct.js";
@@ -7,10 +7,7 @@ import {
type Metadata,
} from "@llamaindex/core/schema";
import type { BaseDocumentStore } from "../storage/docStore/types.js";
import type {
VectorStore,
VectorStoreByType,
} from "../storage/vectorStore/types.js";
import type { VectorStore, VectorStoreByType } from "../vector-store/types.js";
import { IngestionCache, getTransformationHash } from "./IngestionCache.js";
import {
DocStoreStrategy,
@@ -1,6 +1,6 @@
import { BaseNode, TransformComponent } from "@llamaindex/core/schema";
import type { BaseDocumentStore } from "../../storage/docStore/types.js";
import type { VectorStore } from "../../storage/vectorStore/types.js";
import type { VectorStore } from "../../vector-store/types.js";
import { classify } from "./classify.js";
/**
@@ -1,6 +1,6 @@
import { BaseNode, TransformComponent } from "@llamaindex/core/schema";
import type { BaseDocumentStore } from "../../storage/docStore/types.js";
import type { VectorStore } from "../../storage/vectorStore/types.js";
import type { VectorStore } from "../../vector-store/types.js";
import { classify } from "./classify.js";
/**
@@ -1,6 +1,6 @@
import { TransformComponent } from "@llamaindex/core/schema";
import type { BaseDocumentStore } from "../../storage/docStore/types.js";
import type { VectorStore } from "../../storage/vectorStore/types.js";
import type { VectorStore } from "../../vector-store/types.js";
import { DuplicatesStrategy } from "./DuplicatesStrategy.js";
import { UpsertsAndDeleteStrategy } from "./UpsertsAndDeleteStrategy.js";
import { UpsertsStrategy } from "./UpsertsStrategy.js";
@@ -12,8 +12,8 @@ const formatStr = `The output should be ONLY JSON formatted as a JSON instance.
Here is an example:
[
{
choice: 1,
reason: "<insert reason for choice>"
"choice": 1,
"reason": "<insert reason for choice>"
},
...
]
@@ -159,7 +159,7 @@ export class LLMSingleSelector extends BaseSelector {
const prompt = this.prompt.format({
numChoices: `${choicesText.length}`,
context: choicesText,
query: extractText(query.query),
query: extractText(query),
});
const formattedPrompt = this.outputParser.format(prompt);
@@ -5,12 +5,12 @@ import {
import { ModalityType, ObjectType } from "@llamaindex/core/schema";
import { path } from "@llamaindex/env";
import { getImageEmbedModel } from "../internal/settings/image-embed-model.js";
import { SimpleVectorStore } from "../vector-store/SimpleVectorStore.js";
import type { VectorStore, VectorStoreByType } from "../vector-store/types.js";
import { SimpleDocumentStore } from "./docStore/SimpleDocumentStore.js";
import type { BaseDocumentStore } from "./docStore/types.js";
import { SimpleIndexStore } from "./indexStore/SimpleIndexStore.js";
import type { BaseIndexStore } from "./indexStore/types.js";
import { SimpleVectorStore } from "./vectorStore/SimpleVectorStore.js";
import type { VectorStore, VectorStoreByType } from "./vectorStore/types.js";
export interface StorageContext {
docStore: BaseDocumentStore;
-10
View File
@@ -8,13 +8,3 @@ export * from "./indexStore/types.js";
export { SimpleKVStore } from "./kvStore/SimpleKVStore.js";
export * from "./kvStore/types.js";
export * from "./StorageContext.js";
export { AstraDBVectorStore } from "./vectorStore/AstraDBVectorStore.js";
export { ChromaVectorStore } from "./vectorStore/ChromaVectorStore.js";
export { MilvusVectorStore } from "./vectorStore/MilvusVectorStore.js";
export { MongoDBAtlasVectorSearch } from "./vectorStore/MongoDBAtlasVectorStore.js";
export { PGVectorStore } from "./vectorStore/PGVectorStore.js";
export { PineconeVectorStore } from "./vectorStore/PineconeVectorStore.js";
export { QdrantVectorStore } from "./vectorStore/QdrantVectorStore.js";
export { SimpleVectorStore } from "./vectorStore/SimpleVectorStore.js";
export * from "./vectorStore/types.js";
export { WeaviateVectorStore } from "./vectorStore/WeaviateVectorStore.js";
+1
View File
@@ -0,0 +1 @@
export * from "./vector-store/index.js";
@@ -3,10 +3,9 @@ import type pg from "pg";
import {
FilterCondition,
FilterOperator,
VectorStoreBase,
type IEmbedModel,
type MetadataFilter,
type MetadataFilterValue,
VectorStoreBase,
type VectorStoreNoEmbedModel,
type VectorStoreQuery,
type VectorStoreQueryResult,
@@ -14,12 +13,22 @@ import {
import { escapeLikeString } from "./utils.js";
import type { BaseEmbedding } from "@llamaindex/core/embeddings";
import type { BaseNode, Metadata } from "@llamaindex/core/schema";
import { Document, MetadataMode } from "@llamaindex/core/schema";
export const PGVECTOR_SCHEMA = "public";
export const PGVECTOR_TABLE = "llamaindex_embedding";
export type PGVectorStoreConfig = {
schemaName?: string | undefined;
tableName?: string | undefined;
database?: string | undefined;
connectionString?: string | undefined;
dimensions?: number | undefined;
embedModel?: BaseEmbedding | undefined;
};
/**
* Provides support for writing and querying vector data in Postgres.
* Note: Can't be used with data created using the Python version of the vector store (https://docs.llamaindex.ai/en/stable/examples/vector_stores/postgres.html)
@@ -33,10 +42,12 @@ export class PGVectorStore
private collection: string = "";
private schemaName: string = PGVECTOR_SCHEMA;
private tableName: string = PGVECTOR_TABLE;
private database: string | undefined = undefined;
private connectionString: string | undefined = undefined;
private dimensions: number = 1536;
private db?: pg.Client;
private db?: pg.ClientBase;
/**
* Constructs a new instance of the PGVectorStore
@@ -48,26 +59,27 @@ export class PGVectorStore
* PGPASSWORD=your database password
* PGDATABASE=your database name
* PGPORT=your database port
*
* @param {object} config - The configuration settings for the instance.
* @param {string} config.schemaName - The name of the schema (optional). Defaults to PGVECTOR_SCHEMA.
* @param {string} config.tableName - The name of the table (optional). Defaults to PGVECTOR_TABLE.
* @param {string} config.connectionString - The connection string (optional).
* @param {number} config.dimensions - The dimensions of the embedding model.
*/
constructor(
config?: {
schemaName?: string;
tableName?: string;
connectionString?: string;
dimensions?: number;
} & Partial<IEmbedModel>,
) {
super(config?.embedModel);
this.schemaName = config?.schemaName ?? PGVECTOR_SCHEMA;
this.tableName = config?.tableName ?? PGVECTOR_TABLE;
this.connectionString = config?.connectionString;
this.dimensions = config?.dimensions ?? 1536;
constructor(configOrClient?: PGVectorStoreConfig | pg.ClientBase) {
// We cannot import pg from top level, it might have side effects
// so we only check if the config.connect function exists
if (
configOrClient &&
"connect" in configOrClient &&
typeof configOrClient.connect === "function"
) {
const db = configOrClient as pg.ClientBase;
super();
this.db = db;
} else {
const config = configOrClient as PGVectorStoreConfig;
super(config?.embedModel);
this.schemaName = config?.schemaName ?? PGVECTOR_SCHEMA;
this.tableName = config?.tableName ?? PGVECTOR_TABLE;
this.database = config?.database;
this.connectionString = config?.connectionString;
this.dimensions = config?.dimensions ?? 1536;
}
}
/**
@@ -92,7 +104,7 @@ export class PGVectorStore
return this.collection;
}
private async getDb(): Promise<pg.Client> {
private async getDb(): Promise<pg.ClientBase> {
if (!this.db) {
try {
const pg = await import("pg");
@@ -102,6 +114,7 @@ export class PGVectorStore
// Create DB connection
// Read connection params from env - see comment block above
const db = new Client({
database: this.database,
connectionString: this.connectionString,
});
await db.connect();
@@ -110,9 +123,6 @@ export class PGVectorStore
await db.query("CREATE EXTENSION IF NOT EXISTS vector");
await registerType(db);
// Check schema, table(s), index(es)
await this.checkSchema(db);
// All good? Keep the connection reference
this.db = db;
} catch (err) {
@@ -121,10 +131,15 @@ export class PGVectorStore
}
}
const db = this.db;
// Check schema, table(s), index(es)
await this.checkSchema(db);
return Promise.resolve(this.db);
}
private async checkSchema(db: pg.Client) {
private async checkSchema(db: pg.ClientBase) {
await db.query(`CREATE SCHEMA IF NOT EXISTS ${this.schemaName}`);
const tbl = `CREATE TABLE IF NOT EXISTS ${this.schemaName}.${this.tableName}(
@@ -171,26 +186,22 @@ export class PGVectorStore
}
private getDataToInsert(embeddingResults: BaseNode<Metadata>[]) {
const result = [];
for (let index = 0; index < embeddingResults.length; index++) {
const row = embeddingResults[index]!;
return embeddingResults.map((node) => {
const id: any = node.id_.length ? node.id_ : null;
const meta = node.metadata || {};
if (!meta.create_date) {
meta.create_date = new Date();
}
const id: any = row.id_.length ? row.id_ : null;
const meta = row.metadata || {};
meta.create_date = new Date();
const params = [
return [
id,
"",
this.collection,
row.getContent(MetadataMode.EMBED),
node.getContent(MetadataMode.NONE),
meta,
"[" + row.getEmbedding().join(",") + "]",
"[" + node.getEmbedding().join(",") + "]",
];
result.push(params);
}
return result;
});
}
/**
@@ -201,7 +212,7 @@ export class PGVectorStore
*/
async add(embeddingResults: BaseNode<Metadata>[]): Promise<string[]> {
if (embeddingResults.length === 0) {
console.debug("Empty list sent to PGVectorStore::add");
console.warn("Empty list sent to PGVectorStore::add");
return [];
}
@@ -2,11 +2,8 @@ import type { BaseEmbedding } from "@llamaindex/core/embeddings";
import { DEFAULT_PERSIST_DIR } from "@llamaindex/core/global";
import type { BaseNode } from "@llamaindex/core/schema";
import { fs, path } from "@llamaindex/env";
import {
getTopKEmbeddings,
getTopKMMREmbeddings,
} from "../../internal/utils.js";
import { exists } from "../FileSystem.js";
import { getTopKEmbeddings, getTopKMMREmbeddings } from "../internal/utils.js";
import { exists } from "../storage/FileSystem.js";
import {
FilterOperator,
VectorStoreBase,
@@ -0,0 +1,10 @@
export * from "./AstraDBVectorStore.js";
export * from "./ChromaVectorStore.js";
export * from "./MilvusVectorStore.js";
export * from "./MongoDBAtlasVectorStore.js";
export * from "./PGVectorStore.js";
export * from "./PineconeVectorStore.js";
export * from "./QdrantVectorStore.js";
export * from "./SimpleVectorStore.js";
export * from "./types.js";
export * from "./WeaviateVectorStore.js";
@@ -1,6 +1,6 @@
import type { BaseEmbedding } from "@llamaindex/core/embeddings";
import type { BaseNode, ModalityType } from "@llamaindex/core/schema";
import { getEmbeddedModel } from "../../internal/settings/EmbedModel.js";
import { getEmbeddedModel } from "../internal/settings/EmbedModel.js";
export interface VectorStoreQueryResult {
nodes?: BaseNode[];
@@ -2,7 +2,7 @@ import { Document, MetadataMode } from "@llamaindex/core/schema";
import {
metadataDictToNode,
nodeToMetadata,
} from "llamaindex/storage/vectorStore/utils";
} from "llamaindex/vector-store/utils";
import { beforeEach, describe, expect, test } from "vitest";
describe("Testing VectorStore utils", () => {
@@ -1,5 +1,5 @@
import type { BaseNode } from "@llamaindex/core/schema";
import { QdrantVectorStore } from "llamaindex/storage/index";
import { QdrantVectorStore } from "llamaindex/vector-store";
export class TestableQdrantVectorStore extends QdrantVectorStore {
public nodes: BaseNode[] = [];
@@ -4,7 +4,7 @@ import type { Mocked } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { QdrantClient } from "@qdrant/js-client-rest";
import { VectorStoreQueryMode } from "llamaindex/storage/index";
import { VectorStoreQueryMode } from "llamaindex/vector-store";
import { TestableQdrantVectorStore } from "../mocks/TestableQdrantVectorStore.js";
vi.mock("@qdrant/js-client-rest");
@@ -0,0 +1,85 @@
import { Document } from "llamaindex";
import { PGVectorStore } from "llamaindex/vector-store/PGVectorStore";
import pg from "pg";
import { registerTypes } from "pgvector/pg";
import { describe, expect, test } from "vitest";
import { VectorStoreQueryMode } from "../../src/index.js";
describe("pg - init", () => {
test("init with client", async () => {
const client = new pg.Client({
database: "llamaindex_node_test",
});
await client.connect();
await client.query("CREATE EXTENSION IF NOT EXISTS vector");
await registerTypes(client);
const vectorStore = new PGVectorStore(client);
expect(await vectorStore.client()).toBe(client);
});
test("init with pool", async () => {
const pool = new pg.Pool({
database: "llamaindex_node_test",
});
await pool.query("CREATE EXTENSION IF NOT EXISTS vector");
const client = await pool.connect();
await registerTypes(client);
const vectorStore = new PGVectorStore(client);
expect(await vectorStore.client()).toBe(client);
});
test("init without client", async () => {
const vectorStore = new PGVectorStore({
database: "llamaindex_node_test",
});
expect(await vectorStore.client()).toBeDefined();
});
});
describe("pg - save data", () => {
test("simple node", async () => {
const dimensions = 3;
const schemaName =
"llamaindex_vector_store_test_" + Math.random().toString(36).substring(7);
const nodeId = "5bb16627-f6c0-459c-bb18-71642813ef21";
const node = new Document({
text: "hello world",
id_: nodeId,
embedding: [0.1, 0.2, 0.3],
});
const vectorStore = new PGVectorStore({
database: "llamaindex_node_test",
dimensions,
schemaName,
});
await vectorStore.add([node]);
{
const result = await vectorStore.query({
mode: VectorStoreQueryMode.DEFAULT,
similarityTopK: 1,
queryEmbedding: [1, 2, 3],
});
const actualJSON = result.nodes![0]!.toJSON();
expect(actualJSON).toEqual({
...node.toJSON(),
hash: actualJSON.hash,
metadata: actualJSON.metadata,
});
expect(result.ids).toEqual([nodeId]);
expect(result.similarities).toEqual([1]);
}
await vectorStore.delete(nodeId);
{
const result = await vectorStore.query({
mode: VectorStoreQueryMode.DEFAULT,
similarityTopK: 1,
queryEmbedding: [1, 2, 3],
});
expect(result.nodes).toEqual([]);
}
});
});
+10 -20
View File
@@ -167,7 +167,7 @@ importers:
version: link:../packages/llamaindex
mongodb:
specifier: ^6.7.0
version: 6.8.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))
version: 6.8.0(@aws-sdk/credential-providers@3.637.0)
pathe:
specifier: ^1.1.2
version: 1.1.2
@@ -581,7 +581,7 @@ importers:
version: 2.0.0
mongodb:
specifier: ^6.7.0
version: 6.8.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))
version: 6.8.0(@aws-sdk/credential-providers@3.637.0)
notion-md-crawler:
specifier: ^1.0.0
version: 1.0.0(encoding@0.1.13)
@@ -594,12 +594,6 @@ importers:
pathe:
specifier: ^1.1.2
version: 1.1.2
pg:
specifier: ^8.12.0
version: 8.12.0
pgvector:
specifier: ^0.2.0
version: 0.2.0
portkey-ai:
specifier: 0.1.16
version: 0.1.16
@@ -643,6 +637,12 @@ importers:
glob:
specifier: ^11.0.0
version: 11.0.0
pg:
specifier: ^8.12.0
version: 8.12.0
pgvector:
specifier: 0.2.0
version: 0.2.0
typescript:
specifier: ^5.5.4
version: 5.5.4
@@ -17747,16 +17747,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-module-utils@2.8.2(@typescript-eslint/parser@8.3.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 8.3.0(eslint@8.57.0)(typescript@5.5.4)
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
transitivePeerDependencies:
- supports-color
eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.3.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0):
dependencies:
array-includes: 3.1.8
@@ -17767,7 +17757,7 @@ snapshots:
doctrine: 2.1.0
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.8.2(@typescript-eslint/parser@8.3.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0)
eslint-module-utils: 2.8.2(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
hasown: 2.0.2
is-core-module: 2.15.1
is-glob: 4.0.3
@@ -20495,7 +20485,7 @@ snapshots:
optionalDependencies:
'@aws-sdk/credential-providers': 3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0))
mongodb@6.8.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0))):
mongodb@6.8.0(@aws-sdk/credential-providers@3.637.0):
dependencies:
'@mongodb-js/saslprep': 1.1.7
bson: 6.8.0