@anvia/pgvector 0.1.6 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ pnpm --filter @anvia/pgvector build
|
|
|
19
19
|
## Usage
|
|
20
20
|
|
|
21
21
|
```ts
|
|
22
|
-
import { embedDocuments } from "@anvia/core";
|
|
22
|
+
import { embedDocuments } from "@anvia/core/embeddings";
|
|
23
23
|
import { OpenAIClient } from "@anvia/openai";
|
|
24
24
|
import { PgVectorStore } from "@anvia/pgvector";
|
|
25
25
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { VectorMetadata,
|
|
1
|
+
import { VectorMetadata, EmbeddingModel, EmbeddedDocument } from '@anvia/core/embeddings';
|
|
2
|
+
import { Tool } from '@anvia/core/tool';
|
|
3
|
+
import { VectorSearchIndex, VectorSearchRequest, VectorSearchResult, VectorSearchToolOptions, VectorFilter } from '@anvia/core/vector-store';
|
|
2
4
|
|
|
3
5
|
type PgVectorDistance = "cosine" | "l2" | "innerProduct";
|
|
4
6
|
type PgVectorWhere = {
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { createHash } from "crypto";
|
|
3
3
|
import {
|
|
4
|
-
createVectorSearchTool,
|
|
5
4
|
embedText
|
|
6
|
-
} from "@anvia/core";
|
|
5
|
+
} from "@anvia/core/embeddings";
|
|
6
|
+
import {
|
|
7
|
+
createVectorSearchTool
|
|
8
|
+
} from "@anvia/core/vector-store";
|
|
7
9
|
import pgvector from "pgvector";
|
|
8
10
|
var reservedMetadataPrefix = "__anvia_";
|
|
9
11
|
var PgVectorStore = class _PgVectorStore {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport {\n createVectorSearchTool,\n type EmbeddedDocument,\n type EmbeddingModel,\n embedText,\n type Tool,\n type VectorFilter,\n type VectorMetadata,\n type VectorMetadataValue,\n type VectorSearchIndex,\n type VectorSearchRequest,\n type VectorSearchResult,\n type VectorSearchToolOptions,\n} from \"@anvia/core\";\nimport pgvector from \"pgvector\";\n\nconst reservedMetadataPrefix = \"__anvia_\";\n\nexport type PgVectorDistance = \"cosine\" | \"l2\" | \"innerProduct\";\n\nexport type PgVectorWhere = {\n sql: string;\n values: unknown[];\n};\n\ntype PgClientLike = {\n query(text: string, values?: readonly unknown[]): Promise<{ rows: Record<string, unknown>[] }>;\n};\n\nexport type PgVectorStoreConnectOptions = {\n client?: PgClientLike | undefined;\n connectionString?: string | undefined;\n tableName: string;\n vectorSize: number;\n createIfMissing?: boolean | undefined;\n distance?: PgVectorDistance | undefined;\n};\n\nexport class PgVectorStore<T, Metadata extends VectorMetadata = VectorMetadata> {\n private constructor(\n private readonly client: PgClientLike,\n private readonly tableName: string,\n private readonly distance: PgVectorDistance,\n ) {}\n\n static async connect<T, Metadata extends VectorMetadata = VectorMetadata>(\n options: PgVectorStoreConnectOptions,\n ): Promise<PgVectorStore<T, Metadata>> {\n const client = options.client ?? (await defaultPgClient(options.connectionString));\n const tableName = quoteQualifiedIdentifier(options.tableName);\n const distance = options.distance ?? \"cosine\";\n\n if (options.createIfMissing !== false) {\n await client.query(\"CREATE EXTENSION IF NOT EXISTS vector\");\n await client.query(`CREATE TABLE IF NOT EXISTS ${tableName} (\n id text PRIMARY KEY,\n document_id text NOT NULL,\n document jsonb NOT NULL,\n metadata jsonb,\n embedding vector(${options.vectorSize}) NOT NULL\n)`);\n }\n\n await validateTable(client, tableName, options.vectorSize);\n return new PgVectorStore<T, Metadata>(client, tableName, distance);\n }\n\n async upsertDocuments(documents: Array<EmbeddedDocument<T, Metadata>>): Promise<void> {\n const rows = documents.flatMap((document) => pgVectorRows(document));\n if (rows.length === 0) {\n return;\n }\n\n const values = rows.flatMap((row) => [\n row.id,\n row.documentId,\n JSON.stringify(row.document),\n row.metadata === undefined ? null : JSON.stringify(row.metadata),\n pgvector.toSql(row.embedding),\n ]);\n const placeholders = rows.map((_, index) => {\n const offset = index * 5;\n return `($${offset + 1}, $${offset + 2}, $${offset + 3}::jsonb, $${offset + 4}::jsonb, $${\n offset + 5\n }::vector)`;\n });\n\n await this.client.query(\n `INSERT INTO ${this.tableName} (id, document_id, document, metadata, embedding)\nVALUES ${placeholders.join(\", \")}\nON CONFLICT (id) DO UPDATE SET\n document_id = EXCLUDED.document_id,\n document = EXCLUDED.document,\n metadata = EXCLUDED.metadata,\n embedding = EXCLUDED.embedding`,\n values,\n );\n }\n\n index(model: EmbeddingModel): PgVectorIndex<T, Metadata> {\n return new PgVectorIndex(model, this.client, this.tableName, this.distance);\n }\n}\n\nexport class PgVectorIndex<T, Metadata extends VectorMetadata = VectorMetadata>\n implements VectorSearchIndex<T, Metadata>\n{\n constructor(\n private readonly model: EmbeddingModel,\n private readonly client: PgClientLike,\n private readonly tableName: string,\n private readonly distance: PgVectorDistance,\n ) {}\n\n async search(request: VectorSearchRequest): Promise<Array<VectorSearchResult<T, Metadata>>> {\n const queryEmbedding = await embedText(this.model, request.query);\n const operator = distanceOperator(this.distance);\n const where = filterToPgVectorWhere(request.filter, 2);\n const limitParameter = 2 + (where?.values.length ?? 0);\n const response = await this.client.query(\n `SELECT id, document_id, document, metadata, embedding ${operator} $1::vector AS distance\nFROM ${this.tableName}\n${where === undefined ? \"\" : `WHERE ${where.sql}`}\nORDER BY embedding ${operator} $1::vector\nLIMIT $${limitParameter}`,\n [\n pgvector.toSql(queryEmbedding.vector),\n ...(where?.values ?? []),\n normalizedTopK(request.topK),\n ],\n );\n\n return parseSearchRows<T, Metadata>(\n response.rows as Array<{\n id: string;\n document_id: string;\n document: unknown;\n metadata: Metadata | null;\n distance: number | string;\n }>,\n request.threshold,\n this.distance,\n );\n }\n\n async searchIds(request: VectorSearchRequest): Promise<Array<{ score: number; id: string }>> {\n return (await this.search(request)).map(({ score, id }) => ({ score, id }));\n }\n\n asTool(options: VectorSearchToolOptions): Tool<{ query: string; topK?: number }, unknown> {\n return createVectorSearchTool(this, options);\n }\n}\n\nexport function filterToPgVectorWhere(\n filter: VectorFilter | undefined,\n startIndex = 1,\n): PgVectorWhere | undefined {\n if (filter === undefined) {\n return undefined;\n }\n const state = { nextIndex: startIndex };\n const sql = buildFilterSql(filter, state);\n return { sql, values: stateValues(filter) };\n}\n\nasync function defaultPgClient(connectionString: string | undefined): Promise<PgClientLike> {\n const pg = await import(\"pg\");\n return new pg.Pool(connectionString === undefined ? {} : { connectionString }) as PgClientLike;\n}\n\nasync function validateTable(\n client: PgClientLike,\n tableName: string,\n vectorSize: number,\n): Promise<void> {\n const result = await client.query(\n `SELECT a.atttypmod AS vector_size\nFROM pg_attribute a\nWHERE a.attrelid = $1::regclass\n AND a.attname = 'embedding'\n AND NOT a.attisdropped`,\n [tableName],\n );\n const rawSize = result.rows[0]?.vector_size;\n if (rawSize === undefined) {\n throw new Error(`PgVector table ${tableName} is missing an embedding vector column`);\n }\n const actualSize = Number(rawSize);\n if (actualSize !== vectorSize) {\n throw new Error(\n `PgVector table ${tableName} has vector size ${actualSize}; expected ${vectorSize}`,\n );\n }\n}\n\nfunction distanceOperator(distance: PgVectorDistance): \"<=>\" | \"<->\" | \"<#>\" {\n switch (distance) {\n case \"cosine\":\n return \"<=>\";\n case \"l2\":\n return \"<->\";\n case \"innerProduct\":\n return \"<#>\";\n }\n}\n\nfunction scoreFromDistance(distance: number, strategy: PgVectorDistance): number {\n return strategy === \"cosine\" ? 1 - distance : -distance;\n}\n\nfunction parseSearchRows<T, Metadata extends VectorMetadata>(\n rows: Array<{\n id: string;\n document_id: string;\n document: unknown;\n metadata: Metadata | null;\n distance: number | string;\n }>,\n threshold: number | undefined,\n distanceStrategy: PgVectorDistance,\n): Array<VectorSearchResult<T, Metadata>> {\n const byId = new Map<string, VectorSearchResult<T, Metadata>>();\n\n for (const row of rows) {\n const score = scoreFromDistance(Number(row.distance), distanceStrategy);\n if (threshold !== undefined && score < threshold) {\n continue;\n }\n const result = {\n id: row.document_id,\n score,\n document: row.document as T,\n ...(row.metadata === null ? {} : { metadata: row.metadata }),\n } as VectorSearchResult<T, Metadata>;\n const current = byId.get(result.id);\n if (current === undefined || result.score > current.score) {\n byId.set(result.id, result);\n }\n }\n\n return [...byId.values()];\n}\n\nfunction pgVectorRows<T, Metadata extends VectorMetadata>(\n document: EmbeddedDocument<T, Metadata>,\n): Array<{\n id: string;\n documentId: string;\n document: T;\n metadata: Metadata | undefined;\n embedding: number[];\n}> {\n if (document.embeddings.length === 0) {\n throw new Error(`Document ${document.id} has no embeddings`);\n }\n assertNoReservedMetadata(document.metadata);\n\n return document.embeddings.map((embedding, index) => {\n const logicalId =\n document.embeddings.length === 1 ? document.id : `${document.id}#embedding:${index}`;\n return {\n id: pointId(logicalId),\n documentId: document.id,\n document: document.document,\n metadata: document.metadata,\n embedding: embedding.vector,\n };\n });\n}\n\nfunction assertNoReservedMetadata(metadata: VectorMetadata | undefined): void {\n for (const key of Object.keys(metadata ?? {})) {\n if (key.startsWith(reservedMetadataPrefix)) {\n throw new Error(`Metadata key ${key} is reserved for Anvia pgvector metadata`);\n }\n }\n}\n\nfunction pointId(id: string): string {\n const hex = createHash(\"sha256\").update(id).digest(\"hex\").slice(0, 32);\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(\n 16,\n 20,\n )}-${hex.slice(20)}`;\n}\n\nfunction quoteQualifiedIdentifier(identifier: string): string {\n const parts = identifier.split(\".\");\n if (parts.length === 0 || parts.some((part) => part.length === 0)) {\n throw new Error(`Invalid Postgres identifier: ${identifier}`);\n }\n return parts.map(quoteIdentifier).join(\".\");\n}\n\nfunction quoteIdentifier(identifier: string): string {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(identifier)) {\n throw new Error(`Invalid Postgres identifier: ${identifier}`);\n }\n return `\"${identifier.replaceAll('\"', '\"\"')}\"`;\n}\n\nfunction normalizedTopK(topK: number): number {\n return Math.max(0, Math.trunc(topK));\n}\n\nfunction buildFilterSql(filter: VectorFilter, state: { nextIndex: number }): string {\n switch (filter.type) {\n case \"eq\": {\n const keyIndex = state.nextIndex++;\n const valueIndex = state.nextIndex++;\n return `(metadata ->> $${keyIndex}) = $${valueIndex}`;\n }\n case \"gt\": {\n assertNumericFilterValue(filter.value, filter.type);\n const keyIndex = state.nextIndex++;\n const valueIndex = state.nextIndex++;\n return `(metadata ->> $${keyIndex})::numeric > $${valueIndex}`;\n }\n case \"lt\": {\n assertNumericFilterValue(filter.value, filter.type);\n const keyIndex = state.nextIndex++;\n const valueIndex = state.nextIndex++;\n return `(metadata ->> $${keyIndex})::numeric < $${valueIndex}`;\n }\n case \"and\":\n return `(${buildFilterSql(filter.filters[0], state)} AND ${buildFilterSql(\n filter.filters[1],\n state,\n )})`;\n case \"or\":\n return `(${buildFilterSql(filter.filters[0], state)} OR ${buildFilterSql(\n filter.filters[1],\n state,\n )})`;\n }\n}\n\nfunction stateValues(filter: VectorFilter): unknown[] {\n switch (filter.type) {\n case \"eq\":\n return [filter.key, serializeMetadataValue(filter.value)];\n case \"gt\":\n case \"lt\":\n assertNumericFilterValue(filter.value, filter.type);\n return [filter.key, filter.value];\n case \"and\":\n case \"or\":\n return [...stateValues(filter.filters[0]), ...stateValues(filter.filters[1])];\n }\n}\n\nfunction serializeMetadataValue(value: VectorMetadataValue): string | null {\n return value === null ? null : String(value);\n}\n\nfunction assertNumericFilterValue(value: VectorMetadataValue, operator: \"gt\" | \"lt\"): void {\n if (typeof value !== \"number\") {\n throw new Error(`PgVector ${operator} filters require numeric metadata values`);\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport {\n type EmbeddedDocument,\n type EmbeddingModel,\n embedText,\n type VectorMetadata,\n type VectorMetadataValue,\n} from \"@anvia/core/embeddings\";\nimport type { Tool } from \"@anvia/core/tool\";\nimport {\n createVectorSearchTool,\n type VectorFilter,\n type VectorSearchIndex,\n type VectorSearchRequest,\n type VectorSearchResult,\n type VectorSearchToolOptions,\n} from \"@anvia/core/vector-store\";\nimport pgvector from \"pgvector\";\n\nconst reservedMetadataPrefix = \"__anvia_\";\n\nexport type PgVectorDistance = \"cosine\" | \"l2\" | \"innerProduct\";\n\nexport type PgVectorWhere = {\n sql: string;\n values: unknown[];\n};\n\ntype PgClientLike = {\n query(text: string, values?: readonly unknown[]): Promise<{ rows: Record<string, unknown>[] }>;\n};\n\nexport type PgVectorStoreConnectOptions = {\n client?: PgClientLike | undefined;\n connectionString?: string | undefined;\n tableName: string;\n vectorSize: number;\n createIfMissing?: boolean | undefined;\n distance?: PgVectorDistance | undefined;\n};\n\nexport class PgVectorStore<T, Metadata extends VectorMetadata = VectorMetadata> {\n private constructor(\n private readonly client: PgClientLike,\n private readonly tableName: string,\n private readonly distance: PgVectorDistance,\n ) {}\n\n static async connect<T, Metadata extends VectorMetadata = VectorMetadata>(\n options: PgVectorStoreConnectOptions,\n ): Promise<PgVectorStore<T, Metadata>> {\n const client = options.client ?? (await defaultPgClient(options.connectionString));\n const tableName = quoteQualifiedIdentifier(options.tableName);\n const distance = options.distance ?? \"cosine\";\n\n if (options.createIfMissing !== false) {\n await client.query(\"CREATE EXTENSION IF NOT EXISTS vector\");\n await client.query(`CREATE TABLE IF NOT EXISTS ${tableName} (\n id text PRIMARY KEY,\n document_id text NOT NULL,\n document jsonb NOT NULL,\n metadata jsonb,\n embedding vector(${options.vectorSize}) NOT NULL\n)`);\n }\n\n await validateTable(client, tableName, options.vectorSize);\n return new PgVectorStore<T, Metadata>(client, tableName, distance);\n }\n\n async upsertDocuments(documents: Array<EmbeddedDocument<T, Metadata>>): Promise<void> {\n const rows = documents.flatMap((document) => pgVectorRows(document));\n if (rows.length === 0) {\n return;\n }\n\n const values = rows.flatMap((row) => [\n row.id,\n row.documentId,\n JSON.stringify(row.document),\n row.metadata === undefined ? null : JSON.stringify(row.metadata),\n pgvector.toSql(row.embedding),\n ]);\n const placeholders = rows.map((_, index) => {\n const offset = index * 5;\n return `($${offset + 1}, $${offset + 2}, $${offset + 3}::jsonb, $${offset + 4}::jsonb, $${\n offset + 5\n }::vector)`;\n });\n\n await this.client.query(\n `INSERT INTO ${this.tableName} (id, document_id, document, metadata, embedding)\nVALUES ${placeholders.join(\", \")}\nON CONFLICT (id) DO UPDATE SET\n document_id = EXCLUDED.document_id,\n document = EXCLUDED.document,\n metadata = EXCLUDED.metadata,\n embedding = EXCLUDED.embedding`,\n values,\n );\n }\n\n index(model: EmbeddingModel): PgVectorIndex<T, Metadata> {\n return new PgVectorIndex(model, this.client, this.tableName, this.distance);\n }\n}\n\nexport class PgVectorIndex<T, Metadata extends VectorMetadata = VectorMetadata>\n implements VectorSearchIndex<T, Metadata>\n{\n constructor(\n private readonly model: EmbeddingModel,\n private readonly client: PgClientLike,\n private readonly tableName: string,\n private readonly distance: PgVectorDistance,\n ) {}\n\n async search(request: VectorSearchRequest): Promise<Array<VectorSearchResult<T, Metadata>>> {\n const queryEmbedding = await embedText(this.model, request.query);\n const operator = distanceOperator(this.distance);\n const where = filterToPgVectorWhere(request.filter, 2);\n const limitParameter = 2 + (where?.values.length ?? 0);\n const response = await this.client.query(\n `SELECT id, document_id, document, metadata, embedding ${operator} $1::vector AS distance\nFROM ${this.tableName}\n${where === undefined ? \"\" : `WHERE ${where.sql}`}\nORDER BY embedding ${operator} $1::vector\nLIMIT $${limitParameter}`,\n [\n pgvector.toSql(queryEmbedding.vector),\n ...(where?.values ?? []),\n normalizedTopK(request.topK),\n ],\n );\n\n return parseSearchRows<T, Metadata>(\n response.rows as Array<{\n id: string;\n document_id: string;\n document: unknown;\n metadata: Metadata | null;\n distance: number | string;\n }>,\n request.threshold,\n this.distance,\n );\n }\n\n async searchIds(request: VectorSearchRequest): Promise<Array<{ score: number; id: string }>> {\n return (await this.search(request)).map(({ score, id }) => ({ score, id }));\n }\n\n asTool(options: VectorSearchToolOptions): Tool<{ query: string; topK?: number }, unknown> {\n return createVectorSearchTool(this, options);\n }\n}\n\nexport function filterToPgVectorWhere(\n filter: VectorFilter | undefined,\n startIndex = 1,\n): PgVectorWhere | undefined {\n if (filter === undefined) {\n return undefined;\n }\n const state = { nextIndex: startIndex };\n const sql = buildFilterSql(filter, state);\n return { sql, values: stateValues(filter) };\n}\n\nasync function defaultPgClient(connectionString: string | undefined): Promise<PgClientLike> {\n const pg = await import(\"pg\");\n return new pg.Pool(connectionString === undefined ? {} : { connectionString }) as PgClientLike;\n}\n\nasync function validateTable(\n client: PgClientLike,\n tableName: string,\n vectorSize: number,\n): Promise<void> {\n const result = await client.query(\n `SELECT a.atttypmod AS vector_size\nFROM pg_attribute a\nWHERE a.attrelid = $1::regclass\n AND a.attname = 'embedding'\n AND NOT a.attisdropped`,\n [tableName],\n );\n const rawSize = result.rows[0]?.vector_size;\n if (rawSize === undefined) {\n throw new Error(`PgVector table ${tableName} is missing an embedding vector column`);\n }\n const actualSize = Number(rawSize);\n if (actualSize !== vectorSize) {\n throw new Error(\n `PgVector table ${tableName} has vector size ${actualSize}; expected ${vectorSize}`,\n );\n }\n}\n\nfunction distanceOperator(distance: PgVectorDistance): \"<=>\" | \"<->\" | \"<#>\" {\n switch (distance) {\n case \"cosine\":\n return \"<=>\";\n case \"l2\":\n return \"<->\";\n case \"innerProduct\":\n return \"<#>\";\n }\n}\n\nfunction scoreFromDistance(distance: number, strategy: PgVectorDistance): number {\n return strategy === \"cosine\" ? 1 - distance : -distance;\n}\n\nfunction parseSearchRows<T, Metadata extends VectorMetadata>(\n rows: Array<{\n id: string;\n document_id: string;\n document: unknown;\n metadata: Metadata | null;\n distance: number | string;\n }>,\n threshold: number | undefined,\n distanceStrategy: PgVectorDistance,\n): Array<VectorSearchResult<T, Metadata>> {\n const byId = new Map<string, VectorSearchResult<T, Metadata>>();\n\n for (const row of rows) {\n const score = scoreFromDistance(Number(row.distance), distanceStrategy);\n if (threshold !== undefined && score < threshold) {\n continue;\n }\n const result = {\n id: row.document_id,\n score,\n document: row.document as T,\n ...(row.metadata === null ? {} : { metadata: row.metadata }),\n } as VectorSearchResult<T, Metadata>;\n const current = byId.get(result.id);\n if (current === undefined || result.score > current.score) {\n byId.set(result.id, result);\n }\n }\n\n return [...byId.values()];\n}\n\nfunction pgVectorRows<T, Metadata extends VectorMetadata>(\n document: EmbeddedDocument<T, Metadata>,\n): Array<{\n id: string;\n documentId: string;\n document: T;\n metadata: Metadata | undefined;\n embedding: number[];\n}> {\n if (document.embeddings.length === 0) {\n throw new Error(`Document ${document.id} has no embeddings`);\n }\n assertNoReservedMetadata(document.metadata);\n\n return document.embeddings.map((embedding, index) => {\n const logicalId =\n document.embeddings.length === 1 ? document.id : `${document.id}#embedding:${index}`;\n return {\n id: pointId(logicalId),\n documentId: document.id,\n document: document.document,\n metadata: document.metadata,\n embedding: embedding.vector,\n };\n });\n}\n\nfunction assertNoReservedMetadata(metadata: VectorMetadata | undefined): void {\n for (const key of Object.keys(metadata ?? {})) {\n if (key.startsWith(reservedMetadataPrefix)) {\n throw new Error(`Metadata key ${key} is reserved for Anvia pgvector metadata`);\n }\n }\n}\n\nfunction pointId(id: string): string {\n const hex = createHash(\"sha256\").update(id).digest(\"hex\").slice(0, 32);\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(\n 16,\n 20,\n )}-${hex.slice(20)}`;\n}\n\nfunction quoteQualifiedIdentifier(identifier: string): string {\n const parts = identifier.split(\".\");\n if (parts.length === 0 || parts.some((part) => part.length === 0)) {\n throw new Error(`Invalid Postgres identifier: ${identifier}`);\n }\n return parts.map(quoteIdentifier).join(\".\");\n}\n\nfunction quoteIdentifier(identifier: string): string {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(identifier)) {\n throw new Error(`Invalid Postgres identifier: ${identifier}`);\n }\n return `\"${identifier.replaceAll('\"', '\"\"')}\"`;\n}\n\nfunction normalizedTopK(topK: number): number {\n return Math.max(0, Math.trunc(topK));\n}\n\nfunction buildFilterSql(filter: VectorFilter, state: { nextIndex: number }): string {\n switch (filter.type) {\n case \"eq\": {\n const keyIndex = state.nextIndex++;\n const valueIndex = state.nextIndex++;\n return `(metadata ->> $${keyIndex}) = $${valueIndex}`;\n }\n case \"gt\": {\n assertNumericFilterValue(filter.value, filter.type);\n const keyIndex = state.nextIndex++;\n const valueIndex = state.nextIndex++;\n return `(metadata ->> $${keyIndex})::numeric > $${valueIndex}`;\n }\n case \"lt\": {\n assertNumericFilterValue(filter.value, filter.type);\n const keyIndex = state.nextIndex++;\n const valueIndex = state.nextIndex++;\n return `(metadata ->> $${keyIndex})::numeric < $${valueIndex}`;\n }\n case \"and\":\n return `(${buildFilterSql(filter.filters[0], state)} AND ${buildFilterSql(\n filter.filters[1],\n state,\n )})`;\n case \"or\":\n return `(${buildFilterSql(filter.filters[0], state)} OR ${buildFilterSql(\n filter.filters[1],\n state,\n )})`;\n }\n}\n\nfunction stateValues(filter: VectorFilter): unknown[] {\n switch (filter.type) {\n case \"eq\":\n return [filter.key, serializeMetadataValue(filter.value)];\n case \"gt\":\n case \"lt\":\n assertNumericFilterValue(filter.value, filter.type);\n return [filter.key, filter.value];\n case \"and\":\n case \"or\":\n return [...stateValues(filter.filters[0]), ...stateValues(filter.filters[1])];\n }\n}\n\nfunction serializeMetadataValue(value: VectorMetadataValue): string | null {\n return value === null ? null : String(value);\n}\n\nfunction assertNumericFilterValue(value: VectorMetadataValue, operator: \"gt\" | \"lt\"): void {\n if (typeof value !== \"number\") {\n throw new Error(`PgVector ${operator} filters require numeric metadata values`);\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anvia/pgvector",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Postgres pgvector store adapter for Anvia.",
|
|
5
5
|
"author": "anvia",
|
|
6
6
|
"maintainer": "Indra Zulfi",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"pg": "^8.21.0",
|
|
30
30
|
"pgvector": "^0.3.0",
|
|
31
|
-
"@anvia/core": "0.
|
|
31
|
+
"@anvia/core": "0.4.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/node": "^24.9.1",
|