@nhtio/adk 1.20260604.0 → 1.20260607.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/CHANGELOG.md +261 -0
- package/adk-mcp.mjs +1 -1
- package/batteries/embeddings/openai/adapter.cjs +1 -1
- package/batteries/embeddings/openai/adapter.mjs +1 -1
- package/batteries/embeddings/webllm/adapter.cjs +1 -1
- package/batteries/embeddings/webllm/adapter.mjs +1 -1
- package/batteries/index.d.ts +1 -0
- package/batteries/llm/openai_chat_completions/adapter.cjs +6 -6
- package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/adapter.mjs +6 -6
- package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -1
- package/batteries/llm/openai_chat_completions/helpers.cjs +2 -2
- package/batteries/llm/openai_chat_completions/helpers.mjs +2 -2
- package/batteries/llm/openai_chat_completions/validation.cjs +2 -2
- package/batteries/llm/openai_chat_completions/validation.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/validation.mjs +2 -2
- package/batteries/llm/openai_chat_completions/validation.mjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/adapter.cjs +6 -6
- package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/adapter.mjs +6 -6
- package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/validation.cjs +2 -2
- package/batteries/llm/webllm_chat_completions/validation.cjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/validation.mjs +2 -2
- package/batteries/llm/webllm_chat_completions/validation.mjs.map +1 -1
- package/batteries/storage/flydrive.cjs +1 -1
- package/batteries/storage/flydrive.mjs +2 -2
- package/batteries/storage/in_memory.cjs +1 -1
- package/batteries/storage/in_memory.mjs +1 -1
- package/batteries/storage/opfs.cjs +1 -1
- package/batteries/storage/opfs.mjs +1 -1
- package/batteries/tools/color.cjs +2 -2
- package/batteries/tools/color.mjs +2 -2
- package/batteries/tools/comparison.cjs +3 -3
- package/batteries/tools/comparison.mjs +3 -3
- package/batteries/tools/data_structure.cjs +3 -3
- package/batteries/tools/data_structure.mjs +3 -3
- package/batteries/tools/datetime_extended.cjs +2 -2
- package/batteries/tools/datetime_extended.mjs +2 -2
- package/batteries/tools/datetime_math.cjs +2 -2
- package/batteries/tools/datetime_math.mjs +2 -2
- package/batteries/tools/encoding.cjs +3 -3
- package/batteries/tools/encoding.mjs +3 -3
- package/batteries/tools/formatting.cjs +3 -3
- package/batteries/tools/formatting.mjs +3 -3
- package/batteries/tools/geo_basics.cjs +2 -2
- package/batteries/tools/geo_basics.mjs +2 -2
- package/batteries/tools/math/index.d.ts +16 -5
- package/batteries/tools/math.cjs +340 -22
- package/batteries/tools/math.cjs.map +1 -1
- package/batteries/tools/math.mjs +338 -21
- package/batteries/tools/math.mjs.map +1 -1
- package/batteries/tools/memory.cjs +5 -5
- package/batteries/tools/memory.mjs +5 -5
- package/batteries/tools/parsing.cjs +4 -4
- package/batteries/tools/parsing.mjs +4 -4
- package/batteries/tools/retrievables.cjs +4 -4
- package/batteries/tools/retrievables.mjs +4 -4
- package/batteries/tools/standing_instructions.cjs +4 -4
- package/batteries/tools/standing_instructions.mjs +4 -4
- package/batteries/tools/statistics.cjs +4 -4
- package/batteries/tools/statistics.mjs +4 -4
- package/batteries/tools/string_processing.cjs +3 -3
- package/batteries/tools/string_processing.mjs +3 -3
- package/batteries/tools/structured_data.cjs +3 -3
- package/batteries/tools/structured_data.mjs +3 -3
- package/batteries/tools/text_analysis.cjs +3 -3
- package/batteries/tools/text_analysis.mjs +3 -3
- package/batteries/tools/text_comparison.cjs +2 -2
- package/batteries/tools/text_comparison.mjs +2 -2
- package/batteries/tools/time.cjs +2 -2
- package/batteries/tools/time.mjs +2 -2
- package/batteries/tools/unit_conversion.cjs +2 -2
- package/batteries/tools/unit_conversion.mjs +2 -2
- package/batteries/vector/arangodb/index.d.ts +38 -0
- package/batteries/vector/arangodb.cjs +257 -0
- package/batteries/vector/arangodb.cjs.map +1 -0
- package/batteries/vector/arangodb.mjs +255 -0
- package/batteries/vector/arangodb.mjs.map +1 -0
- package/batteries/vector/builder.cjs +297 -0
- package/batteries/vector/builder.cjs.map +1 -0
- package/batteries/vector/builder.d.ts +87 -0
- package/batteries/vector/builder.mjs +294 -0
- package/batteries/vector/builder.mjs.map +1 -0
- package/batteries/vector/chroma/index.d.ts +32 -0
- package/batteries/vector/chroma.cjs +305 -0
- package/batteries/vector/chroma.cjs.map +1 -0
- package/batteries/vector/chroma.mjs +302 -0
- package/batteries/vector/chroma.mjs.map +1 -0
- package/batteries/vector/clickhouse/index.d.ts +39 -0
- package/batteries/vector/clickhouse.cjs +246 -0
- package/batteries/vector/clickhouse.cjs.map +1 -0
- package/batteries/vector/clickhouse.mjs +244 -0
- package/batteries/vector/clickhouse.mjs.map +1 -0
- package/batteries/vector/cloudflare/index.d.ts +43 -0
- package/batteries/vector/cloudflare.cjs +397 -0
- package/batteries/vector/cloudflare.cjs.map +1 -0
- package/batteries/vector/cloudflare.mjs +395 -0
- package/batteries/vector/cloudflare.mjs.map +1 -0
- package/batteries/vector/conformance/index.d.ts +15 -0
- package/batteries/vector/conformance.cjs +209 -0
- package/batteries/vector/conformance.cjs.map +1 -0
- package/batteries/vector/conformance.mjs +205 -0
- package/batteries/vector/conformance.mjs.map +1 -0
- package/batteries/vector/contract.cjs +42 -0
- package/batteries/vector/contract.cjs.map +1 -0
- package/batteries/vector/contract.d.ts +39 -0
- package/batteries/vector/contract.mjs +40 -0
- package/batteries/vector/contract.mjs.map +1 -0
- package/batteries/vector/couchbase/index.d.ts +49 -0
- package/batteries/vector/couchbase.cjs +401 -0
- package/batteries/vector/couchbase.cjs.map +1 -0
- package/batteries/vector/couchbase.mjs +399 -0
- package/batteries/vector/couchbase.mjs.map +1 -0
- package/batteries/vector/duckdb/index.d.ts +33 -0
- package/batteries/vector/duckdb.cjs +218 -0
- package/batteries/vector/duckdb.cjs.map +1 -0
- package/batteries/vector/duckdb.mjs +216 -0
- package/batteries/vector/duckdb.mjs.map +1 -0
- package/batteries/vector/elasticsearch/index.d.ts +43 -0
- package/batteries/vector/elasticsearch.cjs +306 -0
- package/batteries/vector/elasticsearch.cjs.map +1 -0
- package/batteries/vector/elasticsearch.mjs +303 -0
- package/batteries/vector/elasticsearch.mjs.map +1 -0
- package/batteries/vector/exceptions.cjs +126 -0
- package/batteries/vector/exceptions.cjs.map +1 -0
- package/batteries/vector/exceptions.d.ts +142 -0
- package/batteries/vector/exceptions.mjs +107 -0
- package/batteries/vector/exceptions.mjs.map +1 -0
- package/batteries/vector/factory.cjs +28 -0
- package/batteries/vector/factory.cjs.map +1 -0
- package/batteries/vector/factory.d.ts +38 -0
- package/batteries/vector/factory.mjs +25 -0
- package/batteries/vector/factory.mjs.map +1 -0
- package/batteries/vector/filters.cjs +107 -0
- package/batteries/vector/filters.cjs.map +1 -0
- package/batteries/vector/filters.d.ts +34 -0
- package/batteries/vector/filters.mjs +99 -0
- package/batteries/vector/filters.mjs.map +1 -0
- package/batteries/vector/helpers.cjs +23 -0
- package/batteries/vector/helpers.cjs.map +1 -0
- package/batteries/vector/helpers.d.ts +12 -0
- package/batteries/vector/helpers.mjs +17 -0
- package/batteries/vector/helpers.mjs.map +1 -0
- package/batteries/vector/hnswlib/index.d.ts +35 -0
- package/batteries/vector/hnswlib.cjs +237 -0
- package/batteries/vector/hnswlib.cjs.map +1 -0
- package/batteries/vector/hnswlib.mjs +235 -0
- package/batteries/vector/hnswlib.mjs.map +1 -0
- package/batteries/vector/in_memory/index.d.ts +23 -0
- package/batteries/vector/in_memory.cjs +178 -0
- package/batteries/vector/in_memory.cjs.map +1 -0
- package/batteries/vector/in_memory.mjs +176 -0
- package/batteries/vector/in_memory.mjs.map +1 -0
- package/batteries/vector/index.d.ts +18 -0
- package/batteries/vector/lancedb/index.d.ts +34 -0
- package/batteries/vector/lancedb.cjs +224 -0
- package/batteries/vector/lancedb.cjs.map +1 -0
- package/batteries/vector/lancedb.mjs +222 -0
- package/batteries/vector/lancedb.mjs.map +1 -0
- package/batteries/vector/mariadb/index.d.ts +39 -0
- package/batteries/vector/mariadb.cjs +228 -0
- package/batteries/vector/mariadb.cjs.map +1 -0
- package/batteries/vector/mariadb.mjs +226 -0
- package/batteries/vector/mariadb.mjs.map +1 -0
- package/batteries/vector/meilisearch/index.d.ts +36 -0
- package/batteries/vector/meilisearch.cjs +242 -0
- package/batteries/vector/meilisearch.cjs.map +1 -0
- package/batteries/vector/meilisearch.mjs +240 -0
- package/batteries/vector/meilisearch.mjs.map +1 -0
- package/batteries/vector/migrate.cjs +54 -0
- package/batteries/vector/migrate.cjs.map +1 -0
- package/batteries/vector/migrate.d.ts +30 -0
- package/batteries/vector/migrate.mjs +52 -0
- package/batteries/vector/migrate.mjs.map +1 -0
- package/batteries/vector/milvus/index.d.ts +35 -0
- package/batteries/vector/milvus.cjs +357 -0
- package/batteries/vector/milvus.cjs.map +1 -0
- package/batteries/vector/milvus.mjs +354 -0
- package/batteries/vector/milvus.mjs.map +1 -0
- package/batteries/vector/mongodb/index.d.ts +46 -0
- package/batteries/vector/mongodb.cjs +270 -0
- package/batteries/vector/mongodb.cjs.map +1 -0
- package/batteries/vector/mongodb.mjs +268 -0
- package/batteries/vector/mongodb.mjs.map +1 -0
- package/batteries/vector/neo4j/index.d.ts +38 -0
- package/batteries/vector/neo4j.cjs +231 -0
- package/batteries/vector/neo4j.cjs.map +1 -0
- package/batteries/vector/neo4j.mjs +229 -0
- package/batteries/vector/neo4j.mjs.map +1 -0
- package/batteries/vector/opensearch/index.d.ts +46 -0
- package/batteries/vector/opensearch.cjs +316 -0
- package/batteries/vector/opensearch.cjs.map +1 -0
- package/batteries/vector/opensearch.mjs +313 -0
- package/batteries/vector/opensearch.mjs.map +1 -0
- package/batteries/vector/oracle23ai/index.d.ts +45 -0
- package/batteries/vector/oracle23ai.cjs +340 -0
- package/batteries/vector/oracle23ai.cjs.map +1 -0
- package/batteries/vector/oracle23ai.mjs +338 -0
- package/batteries/vector/oracle23ai.mjs.map +1 -0
- package/batteries/vector/orama/index.d.ts +23 -0
- package/batteries/vector/orama.cjs +272 -0
- package/batteries/vector/orama.cjs.map +1 -0
- package/batteries/vector/orama.mjs +270 -0
- package/batteries/vector/orama.mjs.map +1 -0
- package/batteries/vector/pgvector/index.d.ts +43 -0
- package/batteries/vector/pgvector.cjs +411 -0
- package/batteries/vector/pgvector.cjs.map +1 -0
- package/batteries/vector/pgvector.mjs +408 -0
- package/batteries/vector/pgvector.mjs.map +1 -0
- package/batteries/vector/pinecone/index.d.ts +38 -0
- package/batteries/vector/pinecone.cjs +415 -0
- package/batteries/vector/pinecone.cjs.map +1 -0
- package/batteries/vector/pinecone.mjs +412 -0
- package/batteries/vector/pinecone.mjs.map +1 -0
- package/batteries/vector/plan.cjs +2 -0
- package/batteries/vector/plan.d.ts +65 -0
- package/batteries/vector/plan.mjs +0 -0
- package/batteries/vector/qdrant/index.d.ts +34 -0
- package/batteries/vector/qdrant.cjs +286 -0
- package/batteries/vector/qdrant.cjs.map +1 -0
- package/batteries/vector/qdrant.mjs +284 -0
- package/batteries/vector/qdrant.mjs.map +1 -0
- package/batteries/vector/redis/index.d.ts +44 -0
- package/batteries/vector/redis.cjs +391 -0
- package/batteries/vector/redis.cjs.map +1 -0
- package/batteries/vector/redis.mjs +388 -0
- package/batteries/vector/redis.mjs.map +1 -0
- package/batteries/vector/retrievable.cjs +69 -0
- package/batteries/vector/retrievable.cjs.map +1 -0
- package/batteries/vector/retrievable.mjs +67 -0
- package/batteries/vector/retrievable.mjs.map +1 -0
- package/batteries/vector/retrievable_glue.d.ts +24 -0
- package/batteries/vector/s3vectors/index.d.ts +52 -0
- package/batteries/vector/s3vectors.cjs +438 -0
- package/batteries/vector/s3vectors.cjs.map +1 -0
- package/batteries/vector/s3vectors.mjs +436 -0
- package/batteries/vector/s3vectors.mjs.map +1 -0
- package/batteries/vector/schema.cjs +96 -0
- package/batteries/vector/schema.cjs.map +1 -0
- package/batteries/vector/schema.d.ts +40 -0
- package/batteries/vector/schema.mjs +93 -0
- package/batteries/vector/schema.mjs.map +1 -0
- package/batteries/vector/solr/index.d.ts +36 -0
- package/batteries/vector/solr.cjs +230 -0
- package/batteries/vector/solr.cjs.map +1 -0
- package/batteries/vector/solr.mjs +228 -0
- package/batteries/vector/solr.mjs.map +1 -0
- package/batteries/vector/sqlite_vec/index.d.ts +30 -0
- package/batteries/vector/sqlite_vec.cjs +318 -0
- package/batteries/vector/sqlite_vec.cjs.map +1 -0
- package/batteries/vector/sqlite_vec.mjs +316 -0
- package/batteries/vector/sqlite_vec.mjs.map +1 -0
- package/batteries/vector/surrealdb/index.d.ts +37 -0
- package/batteries/vector/surrealdb.cjs +230 -0
- package/batteries/vector/surrealdb.cjs.map +1 -0
- package/batteries/vector/surrealdb.mjs +228 -0
- package/batteries/vector/surrealdb.mjs.map +1 -0
- package/batteries/vector/types.cjs +2 -0
- package/batteries/vector/types.d.ts +100 -0
- package/batteries/vector/types.mjs +0 -0
- package/batteries/vector/typesense/index.d.ts +38 -0
- package/batteries/vector/typesense.cjs +272 -0
- package/batteries/vector/typesense.cjs.map +1 -0
- package/batteries/vector/typesense.mjs +270 -0
- package/batteries/vector/typesense.mjs.map +1 -0
- package/batteries/vector/validation.cjs +90 -0
- package/batteries/vector/validation.cjs.map +1 -0
- package/batteries/vector/validation.d.ts +18 -0
- package/batteries/vector/validation.mjs +83 -0
- package/batteries/vector/validation.mjs.map +1 -0
- package/batteries/vector/vector_store_constructor.cjs +56 -0
- package/batteries/vector/vector_store_constructor.cjs.map +1 -0
- package/batteries/vector/vector_store_constructor.d.ts +30 -0
- package/batteries/vector/vector_store_constructor.mjs +53 -0
- package/batteries/vector/vector_store_constructor.mjs.map +1 -0
- package/batteries/vector/vespa/index.d.ts +39 -0
- package/batteries/vector/vespa.cjs +423 -0
- package/batteries/vector/vespa.cjs.map +1 -0
- package/batteries/vector/vespa.mjs +421 -0
- package/batteries/vector/vespa.mjs.map +1 -0
- package/batteries/vector/weaviate/index.d.ts +57 -0
- package/batteries/vector/weaviate.cjs +325 -0
- package/batteries/vector/weaviate.cjs.map +1 -0
- package/batteries/vector/weaviate.mjs +322 -0
- package/batteries/vector/weaviate.mjs.map +1 -0
- package/batteries/vector.cjs +63 -0
- package/batteries/vector.mjs +14 -0
- package/batteries.cjs +62 -0
- package/batteries.mjs +15 -1
- package/{chunk-kRvK8_k2.mjs → chunk-Bpcn9VDT.mjs} +5 -1
- package/{common-lMrnzoyn.mjs → common-BT0nfCi9.mjs} +8 -8
- package/{common-lMrnzoyn.mjs.map → common-BT0nfCi9.mjs.map} +1 -1
- package/{common-D_e5zYsG.js → common-Cj8TaQ9U.js} +8 -8
- package/{common-D_e5zYsG.js.map → common-Cj8TaQ9U.js.map} +1 -1
- package/common.cjs +7 -7
- package/common.mjs +7 -7
- package/{dispatch_runner-CpuyATj1.js → dispatch_runner-BHBNupqp.js} +2 -2
- package/dispatch_runner-BHBNupqp.js.map +1 -0
- package/{dispatch_runner-CDF3X0nv.mjs → dispatch_runner-DPcS7Y_M.mjs} +2 -2
- package/dispatch_runner-DPcS7Y_M.mjs.map +1 -0
- package/dispatch_runner.cjs +1 -1
- package/dispatch_runner.mjs +1 -1
- package/forge.cjs +4 -4
- package/forge.mjs +4 -4
- package/guards.cjs +8 -8
- package/guards.mjs +8 -8
- package/index.cjs +12 -12
- package/index.mjs +12 -12
- package/lib/classes/tool_registry.d.ts +70 -4
- package/mcp/adk-docs-corpus.json +1 -1
- package/package.json +424 -88
- package/skills/adk-assembly/SKILL.md +2 -2
- package/{spooled_artifact-B8gIIn9h.js → spooled_artifact-BTq6Nzfy.js} +4 -4
- package/spooled_artifact-BTq6Nzfy.js.map +1 -0
- package/{spooled_artifact-CWoKUDEm.mjs → spooled_artifact-CHoZgWwI.mjs} +4 -4
- package/spooled_artifact-CHoZgWwI.mjs.map +1 -0
- package/spooled_artifact.cjs +2 -2
- package/spooled_artifact.mjs +2 -2
- package/{spooled_markdown_artifact-DQX0RCdI.js → spooled_markdown_artifact-CALSDxIx.js} +3 -3
- package/{spooled_markdown_artifact-DQX0RCdI.js.map → spooled_markdown_artifact-CALSDxIx.js.map} +1 -1
- package/{spooled_markdown_artifact-CNle4jXN.mjs → spooled_markdown_artifact-Ci5UL7l4.mjs} +3 -3
- package/{spooled_markdown_artifact-CNle4jXN.mjs.map → spooled_markdown_artifact-Ci5UL7l4.mjs.map} +1 -1
- package/src/types/evaluatex.d.ts +31 -0
- package/{thought-BD6AkkOr.js → thought-BbwhJ1wb.js} +4 -4
- package/thought-BbwhJ1wb.js.map +1 -0
- package/{thought-B_P8LiB6.mjs → thought-D34QQZZ9.mjs} +4 -4
- package/thought-D34QQZZ9.mjs.map +1 -0
- package/{tool-CRZSUcdP.mjs → tool-CMhaDRNd.mjs} +3 -3
- package/tool-CMhaDRNd.mjs.map +1 -0
- package/{tool-CX9vNHAw.js → tool-CVyZkFC7.js} +3 -3
- package/tool-CVyZkFC7.js.map +1 -0
- package/{tool_call-BUeMuCc6.mjs → tool_call-CV5qVNlb.mjs} +3 -3
- package/{tool_call-BUeMuCc6.mjs.map → tool_call-CV5qVNlb.mjs.map} +1 -1
- package/{tool_call--7ti-frB.js → tool_call-Db68hB7y.js} +3 -3
- package/{tool_call--7ti-frB.js.map → tool_call-Db68hB7y.js.map} +1 -1
- package/{tool_registry-BGHg6KTq.mjs → tool_registry-D1pSSlsd.mjs} +109 -22
- package/tool_registry-D1pSSlsd.mjs.map +1 -0
- package/{tool_registry-CtCQ4Xoz.js → tool_registry-DYUYqXvo.js} +109 -22
- package/tool_registry-DYUYqXvo.js.map +1 -0
- package/{turn_runner-BJTtAORU.js → turn_runner-DqWHNP80.js} +5 -5
- package/turn_runner-DqWHNP80.js.map +1 -0
- package/{turn_runner-C02LZHjt.mjs → turn_runner-fg1Wc3dK.mjs} +5 -5
- package/turn_runner-fg1Wc3dK.mjs.map +1 -0
- package/turn_runner.cjs +1 -1
- package/turn_runner.mjs +1 -1
- package/dispatch_runner-CDF3X0nv.mjs.map +0 -1
- package/dispatch_runner-CpuyATj1.js.map +0 -1
- package/spooled_artifact-B8gIIn9h.js.map +0 -1
- package/spooled_artifact-CWoKUDEm.mjs.map +0 -1
- package/thought-BD6AkkOr.js.map +0 -1
- package/thought-B_P8LiB6.mjs.map +0 -1
- package/tool-CRZSUcdP.mjs.map +0 -1
- package/tool-CX9vNHAw.js.map +0 -1
- package/tool_registry-BGHg6KTq.mjs.map +0 -1
- package/tool_registry-CtCQ4Xoz.js.map +0 -1
- package/turn_runner-BJTtAORU.js.map +0 -1
- package/turn_runner-C02LZHjt.mjs.map +0 -1
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { s as isInstanceOf } from "../../tool_registry-D1pSSlsd.mjs";
|
|
2
|
+
import "../../guards.mjs";
|
|
3
|
+
import { evaluateFilter } from "./filters.mjs";
|
|
4
|
+
import { E_VECTOR_STORE_COLLECTION_FAILED, E_VECTOR_STORE_CONNECTION_FAILED, E_VECTOR_STORE_DELETE_FAILED, E_VECTOR_STORE_DIMENSION_MISMATCH, E_VECTOR_STORE_DRIVER_UNAVAILABLE, E_VECTOR_STORE_SEARCH_FAILED, E_VECTOR_STORE_UNSUPPORTED_OPERATION, E_VECTOR_STORE_UPSERT_FAILED } from "./exceptions.mjs";
|
|
5
|
+
import { BaseVectorStore } from "./contract.mjs";
|
|
6
|
+
import { validateRecords } from "./validation.mjs";
|
|
7
|
+
//#region src/batteries/vector/arangodb/index.ts
|
|
8
|
+
/**
|
|
9
|
+
* @module @nhtio/adk/batteries/vector/arangodb
|
|
10
|
+
*
|
|
11
|
+
* ArangoDB adapter (experimental vector index, 3.12.4+). Each collection is an ArangoDB
|
|
12
|
+
* document collection keyed by `_key`; a `vector` index on `vec` enables KNN via
|
|
13
|
+
* `APPROX_NEAR_COSINE` / `APPROX_NEAR_L2`. Metadata is a JSON string attribute filtered with
|
|
14
|
+
* the neutral filter tree's JS reference evaluator for exact cross-adapter parity.
|
|
15
|
+
*
|
|
16
|
+
* Driver: `arangojs` (pure JS). Requires the server started with
|
|
17
|
+
* `--experimental-vector-index=true`. All values are passed as AQL bind parameters.
|
|
18
|
+
*/
|
|
19
|
+
var getArango = async () => {
|
|
20
|
+
try {
|
|
21
|
+
return await import("arangojs");
|
|
22
|
+
} catch {
|
|
23
|
+
throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(["arangojs"]);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var ArangoDBVectorStore = class extends BaseVectorStore {
|
|
27
|
+
capabilities = {
|
|
28
|
+
transactions: false,
|
|
29
|
+
namedVectors: false,
|
|
30
|
+
rename: false,
|
|
31
|
+
rawSql: false,
|
|
32
|
+
builtInEncoding: false,
|
|
33
|
+
consistency: {
|
|
34
|
+
configurable: false,
|
|
35
|
+
default: "strong",
|
|
36
|
+
modes: ["strong"]
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
#db = null;
|
|
40
|
+
#aql = null;
|
|
41
|
+
#dims = /* @__PURE__ */ new Map();
|
|
42
|
+
#indexed = /* @__PURE__ */ new Set();
|
|
43
|
+
get #opts() {
|
|
44
|
+
return this.options;
|
|
45
|
+
}
|
|
46
|
+
static isAvailable() {
|
|
47
|
+
return typeof process !== "undefined";
|
|
48
|
+
}
|
|
49
|
+
isAvailable() {
|
|
50
|
+
return typeof process !== "undefined";
|
|
51
|
+
}
|
|
52
|
+
async connect() {
|
|
53
|
+
if (this.#db) return;
|
|
54
|
+
const arango = await getArango();
|
|
55
|
+
this.#aql = arango.aql;
|
|
56
|
+
const c = this.#opts.connection;
|
|
57
|
+
const dbName = c.database ?? "vector";
|
|
58
|
+
try {
|
|
59
|
+
const auth = c.username ? {
|
|
60
|
+
username: c.username,
|
|
61
|
+
password: c.password ?? ""
|
|
62
|
+
} : void 0;
|
|
63
|
+
const sys = new arango.Database({
|
|
64
|
+
url: c.url,
|
|
65
|
+
auth
|
|
66
|
+
});
|
|
67
|
+
if (!await sys.listDatabases().then((dbs) => dbs.includes(dbName))) await sys.createDatabase(dbName);
|
|
68
|
+
this.#db = new arango.Database({
|
|
69
|
+
url: c.url,
|
|
70
|
+
databaseName: dbName,
|
|
71
|
+
auth
|
|
72
|
+
});
|
|
73
|
+
} catch (err) {
|
|
74
|
+
throw new E_VECTOR_STORE_CONNECTION_FAILED([String(err)]);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async close() {
|
|
78
|
+
this.#db = null;
|
|
79
|
+
this.#aql = null;
|
|
80
|
+
}
|
|
81
|
+
async #ensure() {
|
|
82
|
+
if (!this.#db) await this.connect();
|
|
83
|
+
return this.#db;
|
|
84
|
+
}
|
|
85
|
+
async createCollection(spec, ifNotExists) {
|
|
86
|
+
const db = await this.#ensure();
|
|
87
|
+
this.#dims.set(spec.collection, spec.vector.dimensions);
|
|
88
|
+
try {
|
|
89
|
+
const col = db.collection(spec.collection);
|
|
90
|
+
if (await col.exists() && !ifNotExists) {
|
|
91
|
+
await col.drop();
|
|
92
|
+
this.#indexed.delete(spec.collection);
|
|
93
|
+
}
|
|
94
|
+
if (!await col.exists()) {
|
|
95
|
+
await col.create();
|
|
96
|
+
this.#indexed.delete(spec.collection);
|
|
97
|
+
}
|
|
98
|
+
} catch (err) {
|
|
99
|
+
throw new E_VECTOR_STORE_COLLECTION_FAILED(["createCollection", String(err)]);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async #ensureVectorIndex(collection) {
|
|
103
|
+
if (this.#indexed.has(collection)) return;
|
|
104
|
+
const col = (await this.#ensure()).collection(collection);
|
|
105
|
+
const metric = this.#opts.metric ?? "cosine";
|
|
106
|
+
const dim = this.#dims.get(collection) ?? this.#opts.dimensions;
|
|
107
|
+
if (dim === void 0) return;
|
|
108
|
+
try {
|
|
109
|
+
await col.ensureIndex({
|
|
110
|
+
type: "vector",
|
|
111
|
+
fields: ["vec"],
|
|
112
|
+
params: {
|
|
113
|
+
metric: metric === "euclidean" ? "l2" : "cosine",
|
|
114
|
+
dimension: dim,
|
|
115
|
+
nLists: this.#opts.connection.nLists ?? 1
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
this.#indexed.add(collection);
|
|
119
|
+
} catch {}
|
|
120
|
+
}
|
|
121
|
+
async dropCollection(collection, ifExists) {
|
|
122
|
+
const db = await this.#ensure();
|
|
123
|
+
try {
|
|
124
|
+
const col = db.collection(collection);
|
|
125
|
+
if (await col.exists()) await col.drop();
|
|
126
|
+
else if (!ifExists) throw new Error("collection not found: " + collection);
|
|
127
|
+
this.#dims.delete(collection);
|
|
128
|
+
} catch (err) {
|
|
129
|
+
throw new E_VECTOR_STORE_COLLECTION_FAILED(["dropCollection", String(err)]);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async hasCollection(collection) {
|
|
133
|
+
const db = await this.#ensure();
|
|
134
|
+
try {
|
|
135
|
+
return await db.collection(collection).exists();
|
|
136
|
+
} catch {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async renameCollection(_from, _to) {
|
|
141
|
+
throw new E_VECTOR_STORE_UNSUPPORTED_OPERATION(["renameCollection", "arangodb"]);
|
|
142
|
+
}
|
|
143
|
+
async executeUpsert(plan) {
|
|
144
|
+
if (plan.records.length === 0) return;
|
|
145
|
+
validateRecords(plan.records);
|
|
146
|
+
const db = await this.#ensure();
|
|
147
|
+
const expected = this.#opts.dimensions ?? this.#dims.get(plan.collection);
|
|
148
|
+
try {
|
|
149
|
+
const col = db.collection(plan.collection);
|
|
150
|
+
for (const r of plan.records) {
|
|
151
|
+
let vector = r.vector;
|
|
152
|
+
if (!vector && r.document) {
|
|
153
|
+
const [v] = await this.encode([r.document], "document");
|
|
154
|
+
vector = v;
|
|
155
|
+
}
|
|
156
|
+
if (!vector) throw new E_VECTOR_STORE_UPSERT_FAILED(["Record missing vector and document"]);
|
|
157
|
+
if (expected !== void 0 && vector.length !== expected) throw new E_VECTOR_STORE_DIMENSION_MISMATCH([expected, vector.length]);
|
|
158
|
+
const doc = {
|
|
159
|
+
_key: r.id,
|
|
160
|
+
vec: vector,
|
|
161
|
+
document: r.document ?? "",
|
|
162
|
+
metadata: r.metadata ? JSON.stringify(r.metadata) : "{}"
|
|
163
|
+
};
|
|
164
|
+
await col.save(doc, { overwriteMode: "replace" });
|
|
165
|
+
}
|
|
166
|
+
await this.#ensureVectorIndex(plan.collection);
|
|
167
|
+
} catch (err) {
|
|
168
|
+
if (isInstanceOf(err, "E_VECTOR_STORE_DIMENSION_MISMATCH", E_VECTOR_STORE_DIMENSION_MISMATCH) || isInstanceOf(err, "E_VECTOR_STORE_UPSERT_FAILED", E_VECTOR_STORE_UPSERT_FAILED)) throw err;
|
|
169
|
+
throw new E_VECTOR_STORE_UPSERT_FAILED([String(err)]);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async executeSearch(plan) {
|
|
173
|
+
const db = await this.#ensure();
|
|
174
|
+
const aql = this.#aql;
|
|
175
|
+
const metric = this.#opts.metric ?? "cosine";
|
|
176
|
+
let queryVector;
|
|
177
|
+
if (plan.near) {
|
|
178
|
+
if ("vector" in plan.near) queryVector = plan.near.vector;
|
|
179
|
+
else if ("serverText" in plan.near) {
|
|
180
|
+
const [v] = await this.encode([plan.near.serverText], "query");
|
|
181
|
+
queryVector = v;
|
|
182
|
+
} else if ("id" in plan.near) {
|
|
183
|
+
const col = db.collection(plan.collection);
|
|
184
|
+
try {
|
|
185
|
+
queryVector = (await col.document(plan.near.id)).vec;
|
|
186
|
+
} catch {
|
|
187
|
+
throw new E_VECTOR_STORE_SEARCH_FAILED(["Referenced id not found: " + plan.near.id]);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const offset = plan.offset ?? 0;
|
|
192
|
+
try {
|
|
193
|
+
let rows;
|
|
194
|
+
if (queryVector) {
|
|
195
|
+
const useL2 = metric === "euclidean";
|
|
196
|
+
const fn = useL2 ? "L2_DISTANCE" : "COSINE_SIMILARITY";
|
|
197
|
+
const dir = useL2 ? "ASC" : "DESC";
|
|
198
|
+
const k = plan.filter ? 1e5 : plan.topK + offset;
|
|
199
|
+
const query = `FOR d IN @@col LET __score = ${fn}(d.vec, @qv) SORT __score ${dir} LIMIT @k RETURN { id: d._key, vec: d.vec, document: d.document, metadata: d.metadata, score: __score }`;
|
|
200
|
+
rows = await (await db.query(query, {
|
|
201
|
+
"@col": plan.collection,
|
|
202
|
+
"qv": queryVector,
|
|
203
|
+
k
|
|
204
|
+
})).all();
|
|
205
|
+
return (plan.filter ? rows.filter((row) => evaluateFilter(plan.filter, this.#parseMeta(row.metadata))) : rows).slice(offset, offset + plan.topK).map((row) => this.#project(row, plan, true));
|
|
206
|
+
} else {
|
|
207
|
+
rows = await (await db.query(aql`FOR d IN ${db.collection(plan.collection)} RETURN { id: d._key, vec: d.vec, document: d.document, metadata: d.metadata }`)).all();
|
|
208
|
+
return (plan.filter ? rows.filter((row) => evaluateFilter(plan.filter, this.#parseMeta(row.metadata))) : rows).slice(offset, offset + plan.topK).map((row) => this.#project(row, plan, false));
|
|
209
|
+
}
|
|
210
|
+
} catch (err) {
|
|
211
|
+
throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)]);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
#parseMeta(val) {
|
|
215
|
+
if (typeof val === "string") try {
|
|
216
|
+
return JSON.parse(val);
|
|
217
|
+
} catch {
|
|
218
|
+
return {};
|
|
219
|
+
}
|
|
220
|
+
if (val && typeof val === "object") return val;
|
|
221
|
+
return {};
|
|
222
|
+
}
|
|
223
|
+
#project(row, plan, isKnn) {
|
|
224
|
+
const proj = plan.projection;
|
|
225
|
+
const out = {};
|
|
226
|
+
if (proj.id) out.id = row.id;
|
|
227
|
+
if (proj.vector && Array.isArray(row.vec)) out.vector = row.vec.map(Number);
|
|
228
|
+
if (proj.document) out.document = row.document ?? void 0;
|
|
229
|
+
if (proj.metadata) out.metadata = this.#parseMeta(row.metadata);
|
|
230
|
+
if (isKnn && row.score !== void 0 && row.score !== null) out.score = (this.#opts.metric ?? "cosine") === "euclidean" ? 1 / (1 + Number(row.score)) : Number(row.score);
|
|
231
|
+
return out;
|
|
232
|
+
}
|
|
233
|
+
async executeDelete(plan) {
|
|
234
|
+
const db = await this.#ensure();
|
|
235
|
+
const aql = this.#aql;
|
|
236
|
+
try {
|
|
237
|
+
const col = db.collection(plan.collection);
|
|
238
|
+
if (plan.ids && plan.ids.length > 0) await col.removeAll(plan.ids).catch(async () => {
|
|
239
|
+
for (const id of plan.ids) await col.remove(id).catch(() => void 0);
|
|
240
|
+
});
|
|
241
|
+
else if (plan.filter) {
|
|
242
|
+
const targets = (await (await db.query(aql`FOR d IN ${col} RETURN { id: d._key, metadata: d.metadata }`)).all()).filter((row) => evaluateFilter(plan.filter, this.#parseMeta(row.metadata))).map((row) => row.id);
|
|
243
|
+
if (targets.length > 0) await col.removeAll(targets).catch(async () => {
|
|
244
|
+
for (const id of targets) await col.remove(id).catch(() => void 0);
|
|
245
|
+
});
|
|
246
|
+
} else await col.truncate();
|
|
247
|
+
} catch (err) {
|
|
248
|
+
throw new E_VECTOR_STORE_DELETE_FAILED([String(err)]);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
//#endregion
|
|
253
|
+
export { ArangoDBVectorStore };
|
|
254
|
+
|
|
255
|
+
//# sourceMappingURL=arangodb.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arangodb.mjs","names":["#opts","#db","#aql","#ensure","#dims","#indexed","#ensureVectorIndex","#parseMeta","#project"],"sources":["../../../src/batteries/vector/arangodb/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/arangodb\n *\n * ArangoDB adapter (experimental vector index, 3.12.4+). Each collection is an ArangoDB\n * document collection keyed by `_key`; a `vector` index on `vec` enables KNN via\n * `APPROX_NEAR_COSINE` / `APPROX_NEAR_L2`. Metadata is a JSON string attribute filtered with\n * the neutral filter tree's JS reference evaluator for exact cross-adapter parity.\n *\n * Driver: `arangojs` (pure JS). Requires the server started with\n * `--experimental-vector-index=true`. All values are passed as AQL bind parameters.\n */\n\nimport { evaluateFilter } from '../filters'\nimport { BaseVectorStore } from '../contract'\nimport { validateRecords } from '../validation'\nimport { isInstanceOf } from '@nhtio/adk/guards'\nimport {\n E_VECTOR_STORE_DRIVER_UNAVAILABLE,\n E_VECTOR_STORE_CONNECTION_FAILED,\n E_VECTOR_STORE_COLLECTION_FAILED,\n E_VECTOR_STORE_UPSERT_FAILED,\n E_VECTOR_STORE_SEARCH_FAILED,\n E_VECTOR_STORE_DELETE_FAILED,\n E_VECTOR_STORE_DIMENSION_MISMATCH,\n E_VECTOR_STORE_UNSUPPORTED_OPERATION,\n} from '../exceptions'\nimport type { SearchPlan, UpsertPlan, DeletePlan, CollectionSpec } from '../plan'\nimport type {\n VectorMatch,\n VectorStoreCapabilities,\n BaseVectorStoreOptions,\n VectorMetadata,\n} from '../types'\n\nexport interface ArangoDBVectorStoreOptions extends BaseVectorStoreOptions {\n connection: {\n url: string\n username?: string\n password?: string\n database?: string\n nLists?: number\n }\n}\n\nconst getArango = async () => {\n try {\n const mod = await import('arangojs')\n return mod\n } catch {\n throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(['arangojs'])\n }\n}\n\nexport class ArangoDBVectorStore extends BaseVectorStore {\n readonly capabilities: VectorStoreCapabilities = {\n transactions: false,\n namedVectors: false,\n rename: false,\n rawSql: false,\n builtInEncoding: false,\n // Document writes are synchronous (visible on resolve). The option is a no-op.\n consistency: { configurable: false, default: 'strong', modes: ['strong'] },\n }\n\n #db: any | null = null\n #aql: any | null = null\n #dims: Map<string, number> = new Map()\n // ArangoDB's IVF vector index can't be created on an empty collection (\"not ready\") and\n // needs nLists <= doc count. We therefore create the index lazily after the first upsert.\n #indexed: Set<string> = new Set()\n\n get #opts(): ArangoDBVectorStoreOptions {\n return this.options as ArangoDBVectorStoreOptions\n }\n\n static isAvailable(): boolean {\n return typeof process !== 'undefined'\n }\n isAvailable(): boolean {\n return typeof process !== 'undefined'\n }\n\n async connect(): Promise<void> {\n if (this.#db) return\n const arango = await getArango()\n this.#aql = arango.aql\n const c = this.#opts.connection\n const dbName = c.database ?? 'vector'\n try {\n const auth = c.username ? { username: c.username, password: c.password ?? '' } : undefined\n const sys = new arango.Database({ url: c.url, auth })\n const exists = await sys.listDatabases().then((dbs: string[]) => dbs.includes(dbName))\n if (!exists) {\n await sys.createDatabase(dbName)\n }\n this.#db = new arango.Database({ url: c.url, databaseName: dbName, auth })\n } catch (err) {\n throw new E_VECTOR_STORE_CONNECTION_FAILED([String(err)])\n }\n }\n\n async close(): Promise<void> {\n this.#db = null\n this.#aql = null\n }\n\n async #ensure(): Promise<any> {\n if (!this.#db) await this.connect()\n return this.#db!\n }\n\n async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n const db = await this.#ensure()\n this.#dims.set(spec.collection, spec.vector.dimensions)\n try {\n const col = db.collection(spec.collection)\n const exists = await col.exists()\n if (exists && !ifNotExists) {\n await col.drop()\n this.#indexed.delete(spec.collection)\n }\n if (!(await col.exists())) {\n await col.create()\n this.#indexed.delete(spec.collection)\n }\n // The vector index is created lazily on first upsert (see #ensureVectorIndex): ArangoDB\n // rejects creating it on an empty collection (\"vector index not ready\").\n } catch (err) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['createCollection', String(err)])\n }\n }\n\n // Create the IVF vector index once the collection has data (idempotent per collection).\n async #ensureVectorIndex(collection: string): Promise<void> {\n if (this.#indexed.has(collection)) return\n const db = await this.#ensure()\n const col = db.collection(collection)\n const metric = this.#opts.metric ?? 'cosine'\n const dim = this.#dims.get(collection) ?? this.#opts.dimensions\n if (dim === undefined) return\n try {\n await col.ensureIndex({\n type: 'vector',\n fields: ['vec'],\n params: {\n metric: metric === 'euclidean' ? 'l2' : 'cosine',\n dimension: dim,\n nLists: this.#opts.connection.nLists ?? 1,\n },\n })\n this.#indexed.add(collection)\n } catch {\n // If it still isn't ready (too few docs), leave it; executeSearch falls back to a\n // brute-force AQL scan so correctness holds regardless of the index.\n }\n }\n\n async dropCollection(collection: string, ifExists: boolean): Promise<void> {\n const db = await this.#ensure()\n try {\n const col = db.collection(collection)\n if (await col.exists()) {\n await col.drop()\n } else if (!ifExists) {\n throw new Error('collection not found: ' + collection)\n }\n this.#dims.delete(collection)\n } catch (err) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['dropCollection', String(err)])\n }\n }\n\n async hasCollection(collection: string): Promise<boolean> {\n const db = await this.#ensure()\n try {\n return await db.collection(collection).exists()\n } catch {\n return false\n }\n }\n\n async renameCollection(_from: string, _to: string): Promise<void> {\n throw new E_VECTOR_STORE_UNSUPPORTED_OPERATION(['renameCollection', 'arangodb'])\n }\n\n async executeUpsert(plan: UpsertPlan): Promise<void> {\n if (plan.records.length === 0) return\n validateRecords(plan.records)\n const db = await this.#ensure()\n const expected = this.#opts.dimensions ?? this.#dims.get(plan.collection)\n try {\n const col = db.collection(plan.collection)\n for (const r of plan.records) {\n let vector = r.vector\n if (!vector && r.document) {\n const [v] = await this.encode([r.document], 'document')\n vector = v\n }\n if (!vector) {\n throw new E_VECTOR_STORE_UPSERT_FAILED(['Record missing vector and document'])\n }\n if (expected !== undefined && vector.length !== expected) {\n throw new E_VECTOR_STORE_DIMENSION_MISMATCH([expected, vector.length])\n }\n const doc = {\n _key: r.id,\n vec: vector,\n document: r.document ?? '',\n metadata: r.metadata ? JSON.stringify(r.metadata) : '{}',\n }\n await col.save(doc, { overwriteMode: 'replace' })\n }\n // Now that the collection has data, ensure the IVF vector index exists.\n await this.#ensureVectorIndex(plan.collection)\n } catch (err) {\n if (\n isInstanceOf(err, 'E_VECTOR_STORE_DIMENSION_MISMATCH', E_VECTOR_STORE_DIMENSION_MISMATCH) ||\n isInstanceOf(err, 'E_VECTOR_STORE_UPSERT_FAILED', E_VECTOR_STORE_UPSERT_FAILED)\n ) {\n throw err\n }\n throw new E_VECTOR_STORE_UPSERT_FAILED([String(err)])\n }\n }\n\n async executeSearch(plan: SearchPlan): Promise<VectorMatch[]> {\n const db = await this.#ensure()\n const aql = this.#aql\n const metric = this.#opts.metric ?? 'cosine'\n let queryVector: number[] | undefined\n if (plan.near) {\n if ('vector' in plan.near) {\n queryVector = plan.near.vector\n } else if ('serverText' in plan.near) {\n const [v] = await this.encode([plan.near.serverText], 'query')\n queryVector = v\n } else if ('id' in plan.near) {\n const col = db.collection(plan.collection)\n try {\n const doc = await col.document(plan.near.id)\n queryVector = doc.vec as number[]\n } catch {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n }\n }\n\n const offset = plan.offset ?? 0\n try {\n let rows: any[]\n if (queryVector) {\n // Use the exact AQL distance functions (COSINE_SIMILARITY / L2_DISTANCE) rather than the\n // APPROX_NEAR_* index functions: they need no index, are always correct, and avoid\n // ArangoDB's IVF \"not ready\" / nLists-vs-doc-count constraints. The IVF index is still\n // created lazily on upsert for production-scale ANN; here correctness comes first.\n const useL2 = metric === 'euclidean'\n const fn = useL2 ? 'L2_DISTANCE' : 'COSINE_SIMILARITY'\n const dir = useL2 ? 'ASC' : 'DESC'\n const k = plan.filter ? 100000 : plan.topK + offset\n const query =\n `FOR d IN @@col ` +\n `LET __score = ${fn}(d.vec, @qv) ` +\n `SORT __score ${dir} LIMIT @k ` +\n `RETURN { id: d._key, vec: d.vec, document: d.document, metadata: d.metadata, score: __score }`\n const cursor = await db.query(query, {\n '@col': plan.collection,\n 'qv': queryVector,\n k,\n })\n rows = await cursor.all()\n const filtered = plan.filter\n ? rows.filter((row) => evaluateFilter(plan.filter!, this.#parseMeta(row.metadata)))\n : rows\n return filtered\n .slice(offset, offset + plan.topK)\n .map((row) => this.#project(row, plan, true))\n } else {\n const cursor = await db.query(\n aql`FOR d IN ${db.collection(plan.collection)} RETURN { id: d._key, vec: d.vec, document: d.document, metadata: d.metadata }`\n )\n rows = await cursor.all()\n const filtered = plan.filter\n ? rows.filter((row) => evaluateFilter(plan.filter!, this.#parseMeta(row.metadata)))\n : rows\n return filtered\n .slice(offset, offset + plan.topK)\n .map((row) => this.#project(row, plan, false))\n }\n } catch (err) {\n throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)])\n }\n }\n\n #parseMeta(val: unknown): VectorMetadata {\n if (typeof val === 'string') {\n try {\n return JSON.parse(val) as VectorMetadata\n } catch {\n return {}\n }\n }\n if (val && typeof val === 'object') return val as VectorMetadata\n return {}\n }\n\n #project(row: any, plan: SearchPlan, isKnn: boolean): VectorMatch {\n const proj = plan.projection\n const out: VectorMatch = {}\n if (proj.id) out.id = row.id as string\n if (proj.vector && Array.isArray(row.vec)) out.vector = (row.vec as number[]).map(Number)\n if (proj.document) out.document = (row.document ?? undefined) as string | undefined\n if (proj.metadata) out.metadata = this.#parseMeta(row.metadata)\n if (isKnn && row.score !== undefined && row.score !== null) {\n // APPROX_NEAR_COSINE returns cosine similarity in [0,1]; L2 returns a distance.\n const m = this.#opts.metric ?? 'cosine'\n out.score = m === 'euclidean' ? 1 / (1 + Number(row.score)) : Number(row.score)\n }\n return out\n }\n\n async executeDelete(plan: DeletePlan): Promise<void> {\n const db = await this.#ensure()\n const aql = this.#aql\n try {\n const col = db.collection(plan.collection)\n if (plan.ids && plan.ids.length > 0) {\n await col.removeAll(plan.ids).catch(async () => {\n for (const id of plan.ids!) await col.remove(id).catch(() => undefined)\n })\n } else if (plan.filter) {\n const cursor = await db.query(\n aql`FOR d IN ${col} RETURN { id: d._key, metadata: d.metadata }`\n )\n const rows = await cursor.all()\n const targets = rows\n .filter((row: any) => evaluateFilter(plan.filter!, this.#parseMeta(row.metadata)))\n .map((row: any) => row.id as string)\n if (targets.length > 0) {\n await col.removeAll(targets).catch(async () => {\n for (const id of targets) await col.remove(id).catch(() => undefined)\n })\n }\n } else {\n await col.truncate()\n }\n } catch (err) {\n throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../../chunk-Ble4zEEl.js");
|
|
3
|
+
const require_batteries_vector_filters = require("./filters.cjs");
|
|
4
|
+
const require_batteries_vector_exceptions = require("./exceptions.cjs");
|
|
5
|
+
//#region src/batteries/vector/builder.ts
|
|
6
|
+
/**
|
|
7
|
+
* Knex-style chainable query builder for the vector storage battery.
|
|
8
|
+
*
|
|
9
|
+
* @module @nhtio/adk/batteries/vector/builder
|
|
10
|
+
*/
|
|
11
|
+
var OP_ALIASES = {
|
|
12
|
+
"=": "eq",
|
|
13
|
+
"==": "eq",
|
|
14
|
+
"===": "eq",
|
|
15
|
+
"!=": "ne",
|
|
16
|
+
"<>": "ne",
|
|
17
|
+
"!==": "ne",
|
|
18
|
+
">": "gt",
|
|
19
|
+
">=": "gte",
|
|
20
|
+
"<": "lt",
|
|
21
|
+
"<=": "lte",
|
|
22
|
+
"eq": "eq",
|
|
23
|
+
"ne": "ne",
|
|
24
|
+
"gt": "gt",
|
|
25
|
+
"gte": "gte",
|
|
26
|
+
"lt": "lt",
|
|
27
|
+
"lte": "lte",
|
|
28
|
+
"in": "in",
|
|
29
|
+
"nin": "nin",
|
|
30
|
+
"exists": "exists",
|
|
31
|
+
"contains": "contains"
|
|
32
|
+
};
|
|
33
|
+
var normalizeOp = (op) => {
|
|
34
|
+
const norm = OP_ALIASES[op];
|
|
35
|
+
if (!norm) throw new require_batteries_vector_exceptions.E_VECTOR_STORE_UNSUPPORTED_FILTER_OPERATOR(["builder", op]);
|
|
36
|
+
return norm;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* The where-clause surface of the query builder, factored out so a grouping callback can be handed
|
|
40
|
+
* a builder that only exposes filter methods (not `near*`/`select`/`limit` or the terminals).
|
|
41
|
+
*
|
|
42
|
+
* Chained `.where()` ANDs; the first `.orWhere()` snapshots the accumulated AND-list into the first
|
|
43
|
+
* branch of an OR (knex semantics). Any of the where-methods also accepts a {@link FilterCallback}
|
|
44
|
+
* to open a nested group, letting AND and OR mix to any depth.
|
|
45
|
+
*/
|
|
46
|
+
var FilterBuilder = class FilterBuilder {
|
|
47
|
+
andConditions = [];
|
|
48
|
+
orBranches = [];
|
|
49
|
+
/** Build a nested group by running `cb` against a fresh {@link FilterBuilder}. */
|
|
50
|
+
runGroup(cb) {
|
|
51
|
+
const fb = new FilterBuilder();
|
|
52
|
+
cb(fb);
|
|
53
|
+
return fb.buildFilter();
|
|
54
|
+
}
|
|
55
|
+
where(a, b, c) {
|
|
56
|
+
if (typeof a === "function") {
|
|
57
|
+
const group = this.runGroup(a);
|
|
58
|
+
if (group !== void 0) this.andConditions.push(group);
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
if (typeof a === "object" && !Array.isArray(a)) {
|
|
62
|
+
for (const key of Object.keys(a)) this.andConditions.push({
|
|
63
|
+
field: key,
|
|
64
|
+
op: "eq",
|
|
65
|
+
value: a[key]
|
|
66
|
+
});
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
const field = a;
|
|
70
|
+
const value = b !== void 0 ? c !== void 0 ? c : b : b;
|
|
71
|
+
const op = c !== void 0 ? normalizeOp(b) : "eq";
|
|
72
|
+
this.andConditions.push({
|
|
73
|
+
field,
|
|
74
|
+
op,
|
|
75
|
+
value
|
|
76
|
+
});
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
andWhere(a, b, c) {
|
|
80
|
+
return this.where(a, b, c);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Open a new OR branch holding a single filter. The accumulated AND-list is contributed as the
|
|
84
|
+
* first OR-group by {@link buildFilter}, so each branch carries only its own condition(s) — that
|
|
85
|
+
* is what makes `where(A).where(B).orWhere(C)` resolve to `(A AND B) OR C`.
|
|
86
|
+
*/
|
|
87
|
+
#pushOrBranch(filter) {
|
|
88
|
+
this.orBranches.push([filter]);
|
|
89
|
+
}
|
|
90
|
+
orWhere(field, b, c) {
|
|
91
|
+
if (typeof field === "function") {
|
|
92
|
+
const group = this.runGroup(field);
|
|
93
|
+
if (group !== void 0) this.#pushOrBranch(group);
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
const value = c !== void 0 ? c : b;
|
|
97
|
+
const op = c !== void 0 ? normalizeOp(b) : "eq";
|
|
98
|
+
this.#pushOrBranch({
|
|
99
|
+
field,
|
|
100
|
+
op,
|
|
101
|
+
value
|
|
102
|
+
});
|
|
103
|
+
return this;
|
|
104
|
+
}
|
|
105
|
+
whereNot(field, value) {
|
|
106
|
+
if (typeof field === "function") {
|
|
107
|
+
const group = this.runGroup(field);
|
|
108
|
+
if (group !== void 0) this.andConditions.push({ not: group });
|
|
109
|
+
return this;
|
|
110
|
+
}
|
|
111
|
+
return this.where(field, "ne", value);
|
|
112
|
+
}
|
|
113
|
+
orWhereNot(field, value) {
|
|
114
|
+
if (typeof field === "function") {
|
|
115
|
+
const group = this.runGroup(field);
|
|
116
|
+
if (group !== void 0) this.#pushOrBranch({ not: group });
|
|
117
|
+
return this;
|
|
118
|
+
}
|
|
119
|
+
return this.orWhere(field, "ne", value);
|
|
120
|
+
}
|
|
121
|
+
whereIn(field, values) {
|
|
122
|
+
return this.where(field, "in", values);
|
|
123
|
+
}
|
|
124
|
+
whereNotIn(field, values) {
|
|
125
|
+
return this.where(field, "nin", values);
|
|
126
|
+
}
|
|
127
|
+
whereNull(field) {
|
|
128
|
+
return this.where(field, "exists", false);
|
|
129
|
+
}
|
|
130
|
+
whereExists(field) {
|
|
131
|
+
return this.where(field, "exists", true);
|
|
132
|
+
}
|
|
133
|
+
whereRaw(sqlOrObj, bindings) {
|
|
134
|
+
if (typeof sqlOrObj === "object") this.andConditions.push({
|
|
135
|
+
$dialect: sqlOrObj.$dialect,
|
|
136
|
+
$raw: sqlOrObj.$raw,
|
|
137
|
+
$bindings: sqlOrObj.$bindings ?? []
|
|
138
|
+
});
|
|
139
|
+
else this.andConditions.push({
|
|
140
|
+
$dialect: "sql",
|
|
141
|
+
$raw: sqlOrObj,
|
|
142
|
+
$bindings: bindings ?? []
|
|
143
|
+
});
|
|
144
|
+
return this;
|
|
145
|
+
}
|
|
146
|
+
buildFilter() {
|
|
147
|
+
if (this.andConditions.length === 0 && this.orBranches.length === 0) return;
|
|
148
|
+
if (this.orBranches.length > 0) {
|
|
149
|
+
const orGroups = [];
|
|
150
|
+
if (this.andConditions.length > 0) orGroups.push(this.andConditions);
|
|
151
|
+
for (const branch of this.orBranches) if (branch.length > 0) orGroups.push(branch);
|
|
152
|
+
if (orGroups.length === 1) return { and: orGroups[0] };
|
|
153
|
+
return { or: orGroups.map((conds) => ({ and: conds })) };
|
|
154
|
+
}
|
|
155
|
+
return { and: this.andConditions };
|
|
156
|
+
}
|
|
157
|
+
extractIdsFromFilter() {
|
|
158
|
+
const ids = [];
|
|
159
|
+
const only = this.andConditions.length === 1 ? this.andConditions[0] : void 0;
|
|
160
|
+
if (only && require_batteries_vector_filters.isFilterCondition(only) && only.field === "id" && only.op === "in" && Array.isArray(only.value)) ids.push(...only.value);
|
|
161
|
+
return ids;
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
var VectorQueryBuilder = class extends FilterBuilder {
|
|
165
|
+
#sink;
|
|
166
|
+
#collection;
|
|
167
|
+
#near;
|
|
168
|
+
#projection = {
|
|
169
|
+
id: false,
|
|
170
|
+
vector: false,
|
|
171
|
+
document: false,
|
|
172
|
+
metadata: false
|
|
173
|
+
};
|
|
174
|
+
#topK;
|
|
175
|
+
#offset = 0;
|
|
176
|
+
#selectCalled = false;
|
|
177
|
+
#consistency;
|
|
178
|
+
constructor(sink, collection, defaultTopK) {
|
|
179
|
+
super();
|
|
180
|
+
this.#sink = sink;
|
|
181
|
+
this.#collection = collection;
|
|
182
|
+
this.#topK = defaultTopK;
|
|
183
|
+
}
|
|
184
|
+
nearVector(vector) {
|
|
185
|
+
if (this.#near !== void 0) throw new require_batteries_vector_exceptions.E_VECTOR_STORE_QUERY_CONFLICT(["a near* clause was already set"]);
|
|
186
|
+
this.#near = { vector };
|
|
187
|
+
return this;
|
|
188
|
+
}
|
|
189
|
+
nearText(text) {
|
|
190
|
+
if (this.#near !== void 0) throw new require_batteries_vector_exceptions.E_VECTOR_STORE_QUERY_CONFLICT(["a near* clause was already set"]);
|
|
191
|
+
this.#near = { serverText: text };
|
|
192
|
+
return this;
|
|
193
|
+
}
|
|
194
|
+
nearId(id) {
|
|
195
|
+
if (this.#near !== void 0) throw new require_batteries_vector_exceptions.E_VECTOR_STORE_QUERY_CONFLICT(["a near* clause was already set"]);
|
|
196
|
+
this.#near = { id };
|
|
197
|
+
return this;
|
|
198
|
+
}
|
|
199
|
+
select(...args) {
|
|
200
|
+
this.#selectCalled = true;
|
|
201
|
+
for (const arg of args) if (typeof arg === "string") {
|
|
202
|
+
if (arg === "*") this.#projection = {
|
|
203
|
+
id: true,
|
|
204
|
+
vector: {},
|
|
205
|
+
document: {},
|
|
206
|
+
metadata: {}
|
|
207
|
+
};
|
|
208
|
+
else if (arg === "id") this.#projection.id = true;
|
|
209
|
+
else if (arg === "vector") this.#projection.vector = {};
|
|
210
|
+
else if (arg === "document") this.#projection.document = {};
|
|
211
|
+
else if (arg === "metadata") this.#projection.metadata = {};
|
|
212
|
+
} else if (Array.isArray(arg)) {
|
|
213
|
+
const [field, config] = arg;
|
|
214
|
+
if (field === "vector") this.#projection.vector = config;
|
|
215
|
+
else if (field === "document") this.#projection.document = config;
|
|
216
|
+
else if (field === "metadata") this.#projection.metadata = config;
|
|
217
|
+
else if (field === "id") this.#projection.id = true;
|
|
218
|
+
} else if (typeof arg === "object") {
|
|
219
|
+
for (const key of Object.keys(arg)) if (key === "vector") this.#projection.vector = arg[key];
|
|
220
|
+
else if (key === "document") this.#projection.document = arg[key];
|
|
221
|
+
else if (key === "metadata") this.#projection.metadata = arg[key];
|
|
222
|
+
else if (key === "id") this.#projection.id = true;
|
|
223
|
+
}
|
|
224
|
+
return this;
|
|
225
|
+
}
|
|
226
|
+
limit(n) {
|
|
227
|
+
this.#topK = n;
|
|
228
|
+
return this;
|
|
229
|
+
}
|
|
230
|
+
offset(n) {
|
|
231
|
+
this.#offset = n;
|
|
232
|
+
return this;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Per-operation read-after-write override for the terminal `.upsert()` / `.delete()`.
|
|
236
|
+
* Universal across adapters: strongly-consistent backends ignore it (no-op), so a chain
|
|
237
|
+
* written for an eventually-consistent backend keeps working verbatim when the adapter is
|
|
238
|
+
* swapped. Precedence: this > the store's `consistency` option > the adapter's declared
|
|
239
|
+
* `capabilities.consistency.default`. See {@link VectorConsistency}.
|
|
240
|
+
*/
|
|
241
|
+
consistency(mode) {
|
|
242
|
+
this.#consistency = mode;
|
|
243
|
+
return this;
|
|
244
|
+
}
|
|
245
|
+
then(onfulfilled, onrejected) {
|
|
246
|
+
return this.#run().then(onfulfilled, onrejected);
|
|
247
|
+
}
|
|
248
|
+
async #run() {
|
|
249
|
+
if (!this.#selectCalled) throw new require_batteries_vector_exceptions.E_VECTOR_STORE_PROJECTION_REQUIRED();
|
|
250
|
+
const filter = this.buildFilter();
|
|
251
|
+
const plan = {
|
|
252
|
+
collection: this.#collection,
|
|
253
|
+
near: this.#near,
|
|
254
|
+
filter,
|
|
255
|
+
topK: this.#topK,
|
|
256
|
+
offset: this.#offset,
|
|
257
|
+
projection: this.#projection
|
|
258
|
+
};
|
|
259
|
+
this.#validateRawFilters(plan.filter);
|
|
260
|
+
return await this.#sink.executeSearch(plan);
|
|
261
|
+
}
|
|
262
|
+
async upsert(records) {
|
|
263
|
+
const plan = {
|
|
264
|
+
collection: this.#collection,
|
|
265
|
+
records,
|
|
266
|
+
consistency: this.#consistency
|
|
267
|
+
};
|
|
268
|
+
await this.#sink.executeUpsert(plan);
|
|
269
|
+
}
|
|
270
|
+
async delete() {
|
|
271
|
+
const ids = this.extractIdsFromFilter();
|
|
272
|
+
const filter = this.buildFilter();
|
|
273
|
+
const plan = {
|
|
274
|
+
collection: this.#collection,
|
|
275
|
+
ids: ids.length > 0 ? ids : void 0,
|
|
276
|
+
filter: filter && Object.keys(filter).length > 0 ? filter : void 0,
|
|
277
|
+
consistency: this.#consistency
|
|
278
|
+
};
|
|
279
|
+
await this.#sink.executeDelete(plan);
|
|
280
|
+
}
|
|
281
|
+
#validateRawFilters(filter) {
|
|
282
|
+
if (!filter) return;
|
|
283
|
+
if (require_batteries_vector_filters.isRawFilter(filter)) {
|
|
284
|
+
const placeholders = (filter.$raw.match(/\?/g) || []).length;
|
|
285
|
+
if (placeholders !== filter.$bindings?.length) throw new require_batteries_vector_exceptions.E_VECTOR_STORE_RAW_BINDING_MISMATCH([placeholders, filter.$bindings?.length ?? 0]);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if ("and" in filter && filter.and) for (const f of filter.and) this.#validateRawFilters(f);
|
|
289
|
+
if ("or" in filter && filter.or) for (const f of filter.or) this.#validateRawFilters(f);
|
|
290
|
+
if ("not" in filter && filter.not) this.#validateRawFilters(filter.not);
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
//#endregion
|
|
294
|
+
exports.FilterBuilder = FilterBuilder;
|
|
295
|
+
exports.VectorQueryBuilder = VectorQueryBuilder;
|
|
296
|
+
|
|
297
|
+
//# sourceMappingURL=builder.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.cjs","names":["#pushOrBranch","#sink","#collection","#topK","#near","#selectCalled","#projection","#offset","#consistency","#run","#validateRawFilters"],"sources":["../../../src/batteries/vector/builder.ts"],"sourcesContent":["/**\n * Knex-style chainable query builder for the vector storage battery.\n *\n * @module @nhtio/adk/batteries/vector/builder\n */\n\nimport { isRawFilter, isFilterCondition } from './filters'\nimport {\n E_VECTOR_STORE_QUERY_CONFLICT,\n E_VECTOR_STORE_PROJECTION_REQUIRED,\n E_VECTOR_STORE_RAW_BINDING_MISMATCH,\n E_VECTOR_STORE_UNSUPPORTED_FILTER_OPERATOR,\n} from './exceptions'\nimport type { VectorRecord, VectorMatch, VectorConsistency } from './types'\nimport type { SearchPlan, UpsertPlan, DeletePlan, Projection } from './plan'\nimport type { VectorFilter, FilterCondition, FilterOperator } from './filters'\n\nconst OP_ALIASES: Record<string, FilterOperator> = {\n '=': 'eq',\n '==': 'eq',\n '===': 'eq',\n '!=': 'ne',\n '<>': 'ne',\n '!==': 'ne',\n '>': 'gt',\n '>=': 'gte',\n '<': 'lt',\n '<=': 'lte',\n 'eq': 'eq',\n 'ne': 'ne',\n 'gt': 'gt',\n 'gte': 'gte',\n 'lt': 'lt',\n 'lte': 'lte',\n 'in': 'in',\n 'nin': 'nin',\n 'exists': 'exists',\n 'contains': 'contains',\n}\nconst normalizeOp = (op: string): FilterOperator => {\n const norm = OP_ALIASES[op]\n if (!norm) throw new E_VECTOR_STORE_UNSUPPORTED_FILTER_OPERATOR(['builder', op])\n return norm\n}\n\nexport interface PlanSink {\n executeSearch(plan: SearchPlan): Promise<VectorMatch[]>\n executeUpsert(plan: UpsertPlan): Promise<void>\n executeDelete(plan: DeletePlan): Promise<void>\n}\n\nexport type SelectArg =\n | string\n | [string, Record<string, unknown>]\n | Record<string, Record<string, unknown> | true>\n\n/**\n * A callback that receives a fresh filter-only builder, used to express a parenthesized group of\n * conditions — `A AND (B OR C)`, `NOT (…)`, and arbitrary nesting. The callback mutates the builder\n * in place (knex-style); its accumulated conditions become a single nested `VectorFilter`.\n *\n * @see {@link FilterBuilder.where}\n */\nexport type FilterCallback = (qb: FilterBuilder) => void\n\n/**\n * The where-clause surface of the query builder, factored out so a grouping callback can be handed\n * a builder that only exposes filter methods (not `near*`/`select`/`limit` or the terminals).\n *\n * Chained `.where()` ANDs; the first `.orWhere()` snapshots the accumulated AND-list into the first\n * branch of an OR (knex semantics). Any of the where-methods also accepts a {@link FilterCallback}\n * to open a nested group, letting AND and OR mix to any depth.\n */\nclass FilterBuilder {\n protected andConditions: VectorFilter[] = []\n protected orBranches: VectorFilter[][] = []\n\n /** Build a nested group by running `cb` against a fresh {@link FilterBuilder}. */\n protected runGroup(cb: FilterCallback): VectorFilter | undefined {\n const fb = new FilterBuilder()\n cb(fb)\n return fb.buildFilter()\n }\n\n where(cb: FilterCallback): this\n where(a: string, b?: unknown, c?: unknown): this\n where(obj: Record<string, unknown>): this\n where(a: string | Record<string, unknown> | FilterCallback, b?: unknown, c?: unknown): this {\n if (typeof a === 'function') {\n const group = this.runGroup(a)\n if (group !== undefined) {\n this.andConditions.push(group)\n }\n return this\n }\n if (typeof a === 'object' && !Array.isArray(a)) {\n for (const key of Object.keys(a)) {\n this.andConditions.push({\n field: key,\n op: 'eq',\n value: a[key] as FilterCondition['value'],\n })\n }\n return this\n }\n const field = a as string\n const value = b !== undefined ? (c !== undefined ? c : b) : b\n const op = c !== undefined ? normalizeOp(b as string) : 'eq'\n this.andConditions.push({ field, op, value: value as FilterCondition['value'] })\n return this\n }\n\n andWhere(cb: FilterCallback): this\n andWhere(a: string, b?: unknown, c?: unknown): this\n andWhere(obj: Record<string, unknown>): this\n andWhere(a: string | Record<string, unknown> | FilterCallback, b?: unknown, c?: unknown): this {\n return this.where(a as any, b, c)\n }\n\n /**\n * Open a new OR branch holding a single filter. The accumulated AND-list is contributed as the\n * first OR-group by {@link buildFilter}, so each branch carries only its own condition(s) — that\n * is what makes `where(A).where(B).orWhere(C)` resolve to `(A AND B) OR C`.\n */\n #pushOrBranch(filter: VectorFilter): void {\n this.orBranches.push([filter])\n }\n\n orWhere(cb: FilterCallback): this\n orWhere(field: string, value: unknown): this\n orWhere(field: string, op: FilterOperator, value: unknown): this\n orWhere(field: string | FilterCallback, b?: unknown, c?: unknown): this {\n if (typeof field === 'function') {\n const group = this.runGroup(field)\n if (group !== undefined) {\n this.#pushOrBranch(group)\n }\n return this\n }\n const value = c !== undefined ? c : b\n const op = c !== undefined ? normalizeOp(b as string) : 'eq'\n this.#pushOrBranch({ field, op, value: value as FilterCondition['value'] })\n return this\n }\n\n whereNot(cb: FilterCallback): this\n whereNot(field: string, value: unknown): this\n whereNot(field: string | FilterCallback, value?: unknown): this {\n if (typeof field === 'function') {\n const group = this.runGroup(field)\n if (group !== undefined) {\n this.andConditions.push({ not: group })\n }\n return this\n }\n return this.where(field, 'ne', value as FilterCondition['value'])\n }\n\n orWhereNot(cb: FilterCallback): this\n orWhereNot(field: string, value: unknown): this\n orWhereNot(field: string | FilterCallback, value?: unknown): this {\n if (typeof field === 'function') {\n const group = this.runGroup(field)\n if (group !== undefined) {\n this.#pushOrBranch({ not: group })\n }\n return this\n }\n return this.orWhere(field, 'ne', value)\n }\n\n whereIn(field: string, values: unknown[]): this {\n return this.where(field, 'in', values as FilterCondition['value'])\n }\n\n whereNotIn(field: string, values: unknown[]): this {\n return this.where(field, 'nin', values as FilterCondition['value'])\n }\n\n whereNull(field: string): this {\n return this.where(field, 'exists', false as FilterCondition['value'])\n }\n\n whereExists(field: string): this {\n return this.where(field, 'exists', true as FilterCondition['value'])\n }\n\n whereRaw(sql: string, bindings?: unknown[]): this\n whereRaw(rawObj: { $dialect: string; $raw: unknown; $bindings?: unknown[] }): this\n whereRaw(\n sqlOrObj: string | { $dialect: string; $raw: unknown; $bindings?: unknown[] },\n bindings?: unknown[]\n ): this {\n if (typeof sqlOrObj === 'object') {\n this.andConditions.push({\n $dialect: sqlOrObj.$dialect,\n $raw: sqlOrObj.$raw,\n $bindings: sqlOrObj.$bindings ?? [],\n })\n } else {\n this.andConditions.push({ $dialect: 'sql', $raw: sqlOrObj, $bindings: bindings ?? [] })\n }\n return this\n }\n\n protected buildFilter(): VectorFilter | undefined {\n if (this.andConditions.length === 0 && this.orBranches.length === 0) {\n return undefined\n }\n\n if (this.orBranches.length > 0) {\n const orGroups: VectorFilter[][] = []\n if (this.andConditions.length > 0) {\n orGroups.push(this.andConditions)\n }\n for (const branch of this.orBranches) {\n if (branch.length > 0) {\n orGroups.push(branch)\n }\n }\n if (orGroups.length === 1) {\n return { and: orGroups[0] }\n }\n return { or: orGroups.map((conds) => ({ and: conds })) }\n }\n\n return { and: this.andConditions }\n }\n\n protected extractIdsFromFilter(): string[] {\n const ids: string[] = []\n const only = this.andConditions.length === 1 ? this.andConditions[0] : undefined\n if (\n only &&\n isFilterCondition(only) &&\n only.field === 'id' &&\n only.op === 'in' &&\n Array.isArray(only.value)\n ) {\n ids.push(...(only.value as string[]))\n }\n return ids\n }\n}\n\nclass VectorQueryBuilder extends FilterBuilder implements PromiseLike<VectorMatch[]> {\n #sink: PlanSink\n #collection: string\n #near: { vector: number[] } | { serverText: string } | { id: string } | undefined\n #projection: Projection = { id: false, vector: false, document: false, metadata: false }\n #topK: number\n #offset: number = 0\n #selectCalled: boolean = false\n #consistency: VectorConsistency | undefined\n\n constructor(sink: PlanSink, collection: string, defaultTopK: number) {\n super()\n this.#sink = sink\n this.#collection = collection\n this.#topK = defaultTopK\n }\n\n nearVector(vector: number[]): this {\n if (this.#near !== undefined) {\n throw new E_VECTOR_STORE_QUERY_CONFLICT(['a near* clause was already set'])\n }\n this.#near = { vector }\n return this\n }\n\n nearText(text: string): this {\n if (this.#near !== undefined) {\n throw new E_VECTOR_STORE_QUERY_CONFLICT(['a near* clause was already set'])\n }\n this.#near = { serverText: text }\n return this\n }\n\n nearId(id: string): this {\n if (this.#near !== undefined) {\n throw new E_VECTOR_STORE_QUERY_CONFLICT(['a near* clause was already set'])\n }\n this.#near = { id }\n return this\n }\n\n select(...args: SelectArg[]): this {\n this.#selectCalled = true\n for (const arg of args) {\n if (typeof arg === 'string') {\n if (arg === '*') {\n this.#projection = { id: true, vector: {}, document: {}, metadata: {} }\n } else {\n if (arg === 'id') {\n this.#projection.id = true\n } else if (arg === 'vector') {\n this.#projection.vector = {}\n } else if (arg === 'document') {\n this.#projection.document = {}\n } else if (arg === 'metadata') {\n this.#projection.metadata = {}\n }\n }\n } else if (Array.isArray(arg)) {\n const [field, config] = arg\n if (field === 'vector') {\n this.#projection.vector = config as { name?: string }\n } else if (field === 'document') {\n this.#projection.document = config as { field?: string }\n } else if (field === 'metadata') {\n this.#projection.metadata = config as { fields?: string[] }\n } else if (field === 'id') {\n this.#projection.id = true\n }\n } else if (typeof arg === 'object') {\n for (const key of Object.keys(arg)) {\n if (key === 'vector') {\n this.#projection.vector = arg[key] as { name?: string }\n } else if (key === 'document') {\n this.#projection.document = arg[key] as { field?: string }\n } else if (key === 'metadata') {\n this.#projection.metadata = arg[key] as { fields?: string[] }\n } else if (key === 'id') {\n this.#projection.id = true\n }\n }\n }\n }\n return this\n }\n\n limit(n: number): this {\n this.#topK = n\n return this\n }\n\n offset(n: number): this {\n this.#offset = n\n return this\n }\n\n /**\n * Per-operation read-after-write override for the terminal `.upsert()` / `.delete()`.\n * Universal across adapters: strongly-consistent backends ignore it (no-op), so a chain\n * written for an eventually-consistent backend keeps working verbatim when the adapter is\n * swapped. Precedence: this > the store's `consistency` option > the adapter's declared\n * `capabilities.consistency.default`. See {@link VectorConsistency}.\n */\n consistency(mode: VectorConsistency): this {\n this.#consistency = mode\n return this\n }\n\n then<TR1 = VectorMatch[], TR2 = never>(\n onfulfilled?: ((value: VectorMatch[]) => TR1 | PromiseLike<TR1>) | null,\n onrejected?: ((reason: unknown) => TR2 | PromiseLike<TR2>) | null\n ): PromiseLike<TR1 | TR2> {\n return this.#run().then(onfulfilled as any, onrejected as any)\n }\n\n async #run(): Promise<VectorMatch[]> {\n if (!this.#selectCalled) {\n throw new E_VECTOR_STORE_PROJECTION_REQUIRED()\n }\n\n const filter = this.buildFilter()\n\n const plan: SearchPlan = {\n collection: this.#collection,\n near: this.#near,\n filter,\n topK: this.#topK,\n offset: this.#offset,\n projection: this.#projection,\n }\n\n this.#validateRawFilters(plan.filter)\n\n return await this.#sink.executeSearch(plan)\n }\n\n async upsert(records: VectorRecord[]): Promise<void> {\n const plan: UpsertPlan = {\n collection: this.#collection,\n records,\n consistency: this.#consistency,\n }\n await this.#sink.executeUpsert(plan)\n }\n\n async delete(): Promise<void> {\n const ids = this.extractIdsFromFilter()\n const filter = this.buildFilter()\n\n const plan: DeletePlan = {\n collection: this.#collection,\n ids: ids.length > 0 ? ids : undefined,\n filter: filter && Object.keys(filter).length > 0 ? filter : undefined,\n consistency: this.#consistency,\n }\n\n await this.#sink.executeDelete(plan)\n }\n\n #validateRawFilters(filter: VectorFilter | undefined): void {\n if (!filter) {\n return\n }\n\n if (isRawFilter(filter)) {\n const raw = filter.$raw as string\n const placeholders = (raw.match(/\\?/g) || []).length\n if (placeholders !== filter.$bindings?.length) {\n throw new E_VECTOR_STORE_RAW_BINDING_MISMATCH([placeholders, filter.$bindings?.length ?? 0])\n }\n return\n }\n\n if ('and' in filter && filter.and) {\n for (const f of filter.and) {\n this.#validateRawFilters(f)\n }\n }\n\n if ('or' in filter && filter.or) {\n for (const f of filter.or) {\n this.#validateRawFilters(f)\n }\n }\n\n if ('not' in filter && filter.not) {\n this.#validateRawFilters(filter.not)\n }\n }\n}\n\nexport { VectorQueryBuilder, FilterBuilder }\n"],"mappings":"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"}
|