@nhtio/adk 1.20260607.2 → 1.20260609.1
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 +230 -0
- package/batteries/embeddings/openai/adapter.cjs +1 -1
- package/batteries/embeddings/openai/adapter.mjs +1 -1
- package/batteries/embeddings/openai/exceptions.cjs +1 -1
- package/batteries/embeddings/openai/exceptions.mjs +1 -1
- package/batteries/embeddings/openai/types.d.ts +7 -0
- package/batteries/embeddings/webllm/adapter.cjs +1 -1
- package/batteries/embeddings/webllm/adapter.mjs +1 -1
- package/batteries/embeddings/webllm/exceptions.cjs +1 -1
- package/batteries/embeddings/webllm/exceptions.mjs +1 -1
- package/batteries/llm/chat_common/helpers.d.ts +165 -0
- package/batteries/llm/chat_common/types.d.ts +309 -0
- package/batteries/llm/index.d.ts +5 -0
- package/batteries/llm/ollama/adapter.cjs +736 -0
- package/batteries/llm/ollama/adapter.cjs.map +1 -0
- package/batteries/llm/ollama/adapter.d.ts +64 -0
- package/batteries/llm/ollama/adapter.mjs +734 -0
- package/batteries/llm/ollama/adapter.mjs.map +1 -0
- package/batteries/llm/ollama/exceptions.cjs +105 -0
- package/batteries/llm/ollama/exceptions.cjs.map +1 -0
- package/batteries/llm/ollama/exceptions.d.ts +112 -0
- package/batteries/llm/ollama/exceptions.mjs +96 -0
- package/batteries/llm/ollama/exceptions.mjs.map +1 -0
- package/batteries/llm/ollama/helpers.cjs +487 -0
- package/batteries/llm/ollama/helpers.cjs.map +1 -0
- package/batteries/llm/ollama/helpers.d.ts +158 -0
- package/batteries/llm/ollama/helpers.mjs +450 -0
- package/batteries/llm/ollama/helpers.mjs.map +1 -0
- package/batteries/llm/ollama/index.d.ts +29 -0
- package/batteries/llm/ollama/types.cjs +2 -0
- package/batteries/llm/ollama/types.d.ts +334 -0
- package/batteries/llm/ollama/types.mjs +0 -0
- package/batteries/llm/ollama/validation.cjs +130 -0
- package/batteries/llm/ollama/validation.cjs.map +1 -0
- package/batteries/llm/ollama/validation.d.ts +31 -0
- package/batteries/llm/ollama/validation.mjs +127 -0
- package/batteries/llm/ollama/validation.mjs.map +1 -0
- package/batteries/llm/ollama.cjs +54 -0
- package/batteries/llm/ollama.mjs +6 -0
- package/batteries/llm/openai_chat_completions/adapter.cjs +36 -19
- package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/adapter.mjs +23 -6
- package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -1
- package/batteries/llm/openai_chat_completions/exceptions.cjs +1 -1
- package/batteries/llm/openai_chat_completions/exceptions.mjs +1 -1
- package/batteries/llm/openai_chat_completions/helpers.cjs +80 -320
- package/batteries/llm/openai_chat_completions/helpers.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/helpers.d.ts +68 -144
- package/batteries/llm/openai_chat_completions/helpers.mjs +40 -280
- package/batteries/llm/openai_chat_completions/helpers.mjs.map +1 -1
- package/batteries/llm/openai_chat_completions/types.d.ts +273 -181
- 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/openai_chat_completions.cjs +29 -28
- package/batteries/llm/openai_chat_completions.mjs +2 -1
- package/batteries/llm/webllm_chat_completions/adapter.cjs +38 -19
- package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/adapter.d.ts +18 -0
- package/batteries/llm/webllm_chat_completions/adapter.mjs +25 -6
- package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/exceptions.cjs +1 -1
- package/batteries/llm/webllm_chat_completions/exceptions.mjs +1 -1
- package/batteries/llm/webllm_chat_completions/helpers.cjs +29 -28
- package/batteries/llm/webllm_chat_completions/helpers.mjs +2 -1
- package/batteries/llm/webllm_chat_completions/types.d.ts +21 -0
- package/batteries/llm/webllm_chat_completions/validation.cjs +13 -1
- package/batteries/llm/webllm_chat_completions/validation.cjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/validation.d.ts +12 -0
- package/batteries/llm/webllm_chat_completions/validation.mjs +13 -1
- package/batteries/llm/webllm_chat_completions/validation.mjs.map +1 -1
- package/batteries/llm/webllm_chat_completions.cjs +29 -28
- package/batteries/llm/webllm_chat_completions.mjs +2 -1
- package/batteries/llm.cjs +44 -28
- package/batteries/llm.mjs +9 -4
- package/batteries/storage/flydrive.cjs +1 -1
- package/batteries/storage/flydrive.mjs +1 -1
- package/batteries/storage/in_memory/index.d.ts +1 -1
- package/batteries/storage/in_memory.cjs +2 -2
- package/batteries/storage/in_memory.cjs.map +1 -1
- package/batteries/storage/in_memory.mjs +2 -2
- package/batteries/storage/in_memory.mjs.map +1 -1
- package/batteries/storage/opfs/index.d.ts +19 -0
- package/batteries/storage/opfs.cjs +1 -1
- package/batteries/storage/opfs.cjs.map +1 -1
- package/batteries/storage/opfs.mjs +1 -1
- package/batteries/storage/opfs.mjs.map +1 -1
- package/batteries/tools/_shared/index.d.ts +121 -0
- package/batteries/tools/_shared.cjs +157 -0
- package/batteries/tools/_shared.cjs.map +1 -0
- package/batteries/tools/_shared.mjs +149 -0
- package/batteries/tools/_shared.mjs.map +1 -0
- package/batteries/tools/color.cjs +3 -2
- package/batteries/tools/color.cjs.map +1 -1
- package/batteries/tools/color.mjs +3 -2
- package/batteries/tools/color.mjs.map +1 -1
- package/batteries/tools/comparison.cjs +4 -3
- package/batteries/tools/comparison.cjs.map +1 -1
- package/batteries/tools/comparison.mjs +4 -3
- package/batteries/tools/comparison.mjs.map +1 -1
- package/batteries/tools/data_structure.cjs +30 -10
- package/batteries/tools/data_structure.cjs.map +1 -1
- package/batteries/tools/data_structure.mjs +30 -10
- package/batteries/tools/data_structure.mjs.map +1 -1
- package/batteries/tools/datetime_extended.cjs +5 -10
- package/batteries/tools/datetime_extended.cjs.map +1 -1
- package/batteries/tools/datetime_extended.mjs +5 -10
- package/batteries/tools/datetime_extended.mjs.map +1 -1
- package/batteries/tools/datetime_math.cjs +2 -2
- package/batteries/tools/datetime_math.mjs +2 -2
- package/batteries/tools/encoding.cjs +13 -4
- package/batteries/tools/encoding.cjs.map +1 -1
- package/batteries/tools/encoding.mjs +13 -4
- package/batteries/tools/encoding.mjs.map +1 -1
- package/batteries/tools/formatting.cjs +4 -4
- package/batteries/tools/formatting.cjs.map +1 -1
- package/batteries/tools/formatting.mjs +4 -4
- package/batteries/tools/formatting.mjs.map +1 -1
- package/batteries/tools/geo_basics.cjs +2 -2
- package/batteries/tools/geo_basics.mjs +2 -2
- package/batteries/tools/index.d.ts +3 -0
- package/batteries/tools/math.cjs +10 -8
- package/batteries/tools/math.cjs.map +1 -1
- package/batteries/tools/math.mjs +10 -8
- 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 +9 -5
- package/batteries/tools/parsing.cjs.map +1 -1
- package/batteries/tools/parsing.mjs +9 -5
- package/batteries/tools/parsing.mjs.map +1 -1
- package/batteries/tools/retrievables.cjs +4 -4
- package/batteries/tools/retrievables.mjs +4 -4
- package/batteries/tools/scrapper/exceptions.d.ts +21 -0
- package/batteries/tools/scrapper/index.d.ts +172 -0
- package/batteries/tools/scrapper/shared.d.ts +139 -0
- package/batteries/tools/scrapper.cjs +8 -0
- package/batteries/tools/scrapper.mjs +2 -0
- package/batteries/tools/searxng/exceptions.d.ts +21 -0
- package/batteries/tools/searxng/index.d.ts +177 -0
- package/batteries/tools/searxng.cjs +6 -0
- package/batteries/tools/searxng.mjs +2 -0
- package/batteries/tools/standing_instructions.cjs +4 -4
- package/batteries/tools/standing_instructions.mjs +4 -4
- package/batteries/tools/statistics.cjs +54 -43
- package/batteries/tools/statistics.cjs.map +1 -1
- package/batteries/tools/statistics.mjs +54 -43
- package/batteries/tools/statistics.mjs.map +1 -1
- package/batteries/tools/string_processing.cjs +5 -5
- package/batteries/tools/string_processing.cjs.map +1 -1
- package/batteries/tools/string_processing.mjs +5 -5
- package/batteries/tools/string_processing.mjs.map +1 -1
- package/batteries/tools/structured_data.cjs +8 -13
- package/batteries/tools/structured_data.cjs.map +1 -1
- package/batteries/tools/structured_data.mjs +8 -13
- package/batteries/tools/structured_data.mjs.map +1 -1
- 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 +10 -8
- package/batteries/tools/unit_conversion.cjs.map +1 -1
- package/batteries/tools/unit_conversion.mjs +10 -8
- package/batteries/tools/unit_conversion.mjs.map +1 -1
- package/batteries/tools/web_retrieval/index.d.ts +186 -0
- package/batteries/tools/web_retrieval.cjs +206 -0
- package/batteries/tools/web_retrieval.cjs.map +1 -0
- package/batteries/tools/web_retrieval.mjs +201 -0
- package/batteries/tools/web_retrieval.mjs.map +1 -0
- package/batteries/tools.cjs +15 -0
- package/batteries/tools.mjs +4 -1
- package/batteries/vector/arangodb/index.d.ts +2 -0
- package/batteries/vector/arangodb.cjs +2 -1
- package/batteries/vector/arangodb.cjs.map +1 -1
- package/batteries/vector/arangodb.mjs +2 -1
- package/batteries/vector/arangodb.mjs.map +1 -1
- package/batteries/vector/builder.cjs +31 -0
- package/batteries/vector/builder.cjs.map +1 -1
- package/batteries/vector/builder.d.ts +58 -0
- package/batteries/vector/builder.mjs +31 -0
- package/batteries/vector/builder.mjs.map +1 -1
- package/batteries/vector/chroma/index.d.ts +4 -0
- package/batteries/vector/chroma.cjs +3 -0
- package/batteries/vector/chroma.cjs.map +1 -1
- package/batteries/vector/chroma.mjs +3 -0
- package/batteries/vector/chroma.mjs.map +1 -1
- package/batteries/vector/clickhouse/index.d.ts +2 -0
- package/batteries/vector/clickhouse.cjs +2 -1
- package/batteries/vector/clickhouse.cjs.map +1 -1
- package/batteries/vector/clickhouse.mjs +2 -1
- package/batteries/vector/clickhouse.mjs.map +1 -1
- package/batteries/vector/cloudflare/index.d.ts +2 -0
- package/batteries/vector/cloudflare.cjs +2 -1
- package/batteries/vector/cloudflare.cjs.map +1 -1
- package/batteries/vector/cloudflare.mjs +2 -1
- package/batteries/vector/cloudflare.mjs.map +1 -1
- package/batteries/vector/conformance/index.d.ts +22 -0
- package/batteries/vector/conformance.cjs +22 -0
- package/batteries/vector/conformance.cjs.map +1 -1
- package/batteries/vector/conformance.mjs +22 -0
- package/batteries/vector/conformance.mjs.map +1 -1
- package/batteries/vector/contract.cjs +22 -0
- package/batteries/vector/contract.cjs.map +1 -1
- package/batteries/vector/contract.d.ts +51 -0
- package/batteries/vector/contract.mjs +22 -0
- package/batteries/vector/contract.mjs.map +1 -1
- package/batteries/vector/couchbase/index.d.ts +2 -0
- package/batteries/vector/couchbase.cjs +2 -1
- package/batteries/vector/couchbase.cjs.map +1 -1
- package/batteries/vector/couchbase.mjs +2 -1
- package/batteries/vector/couchbase.mjs.map +1 -1
- package/batteries/vector/duckdb/index.d.ts +2 -0
- package/batteries/vector/duckdb.cjs +2 -1
- package/batteries/vector/duckdb.cjs.map +1 -1
- package/batteries/vector/duckdb.mjs +2 -1
- package/batteries/vector/duckdb.mjs.map +1 -1
- package/batteries/vector/elasticsearch/index.d.ts +2 -0
- package/batteries/vector/elasticsearch.cjs +2 -1
- package/batteries/vector/elasticsearch.cjs.map +1 -1
- package/batteries/vector/elasticsearch.mjs +2 -1
- package/batteries/vector/elasticsearch.mjs.map +1 -1
- package/batteries/vector/exceptions.cjs +1 -1
- package/batteries/vector/exceptions.mjs +1 -1
- package/batteries/vector/factory.cjs +6 -0
- package/batteries/vector/factory.cjs.map +1 -1
- package/batteries/vector/factory.d.ts +14 -0
- package/batteries/vector/factory.mjs +6 -0
- package/batteries/vector/factory.mjs.map +1 -1
- package/batteries/vector/filters.cjs +22 -1
- package/batteries/vector/filters.cjs.map +1 -1
- package/batteries/vector/filters.d.ts +38 -0
- package/batteries/vector/filters.mjs +22 -1
- package/batteries/vector/filters.mjs.map +1 -1
- package/batteries/vector/helpers.cjs +13 -0
- package/batteries/vector/helpers.cjs.map +1 -1
- package/batteries/vector/helpers.d.ts +14 -0
- package/batteries/vector/helpers.mjs +13 -0
- package/batteries/vector/helpers.mjs.map +1 -1
- package/batteries/vector/hnswlib/index.d.ts +2 -0
- package/batteries/vector/hnswlib.cjs +2 -1
- package/batteries/vector/hnswlib.cjs.map +1 -1
- package/batteries/vector/hnswlib.mjs +2 -1
- package/batteries/vector/hnswlib.mjs.map +1 -1
- package/batteries/vector/in_memory/index.d.ts +1 -0
- package/batteries/vector/in_memory.cjs +1 -0
- package/batteries/vector/in_memory.cjs.map +1 -1
- package/batteries/vector/in_memory.mjs +1 -0
- package/batteries/vector/in_memory.mjs.map +1 -1
- package/batteries/vector/lancedb/index.d.ts +2 -0
- package/batteries/vector/lancedb.cjs +2 -1
- package/batteries/vector/lancedb.cjs.map +1 -1
- package/batteries/vector/lancedb.mjs +2 -1
- package/batteries/vector/lancedb.mjs.map +1 -1
- package/batteries/vector/mariadb/index.d.ts +2 -0
- package/batteries/vector/mariadb.cjs +2 -1
- package/batteries/vector/mariadb.cjs.map +1 -1
- package/batteries/vector/mariadb.mjs +2 -1
- package/batteries/vector/mariadb.mjs.map +1 -1
- package/batteries/vector/meilisearch/index.d.ts +2 -0
- package/batteries/vector/meilisearch.cjs +2 -1
- package/batteries/vector/meilisearch.cjs.map +1 -1
- package/batteries/vector/meilisearch.mjs +2 -1
- package/batteries/vector/meilisearch.mjs.map +1 -1
- package/batteries/vector/migrate.cjs +18 -1
- package/batteries/vector/migrate.cjs.map +1 -1
- package/batteries/vector/migrate.d.ts +31 -0
- package/batteries/vector/migrate.mjs +18 -1
- package/batteries/vector/migrate.mjs.map +1 -1
- package/batteries/vector/milvus/index.d.ts +5 -0
- package/batteries/vector/milvus.cjs +4 -0
- package/batteries/vector/milvus.cjs.map +1 -1
- package/batteries/vector/milvus.mjs +4 -0
- package/batteries/vector/milvus.mjs.map +1 -1
- package/batteries/vector/mongodb/index.d.ts +2 -0
- package/batteries/vector/mongodb.cjs +2 -1
- package/batteries/vector/mongodb.cjs.map +1 -1
- package/batteries/vector/mongodb.mjs +2 -1
- package/batteries/vector/mongodb.mjs.map +1 -1
- package/batteries/vector/neo4j/index.d.ts +2 -0
- package/batteries/vector/neo4j.cjs +2 -1
- package/batteries/vector/neo4j.cjs.map +1 -1
- package/batteries/vector/neo4j.mjs +2 -1
- package/batteries/vector/neo4j.mjs.map +1 -1
- package/batteries/vector/opensearch/index.d.ts +2 -0
- package/batteries/vector/opensearch.cjs +2 -1
- package/batteries/vector/opensearch.cjs.map +1 -1
- package/batteries/vector/opensearch.mjs +2 -1
- package/batteries/vector/opensearch.mjs.map +1 -1
- package/batteries/vector/oracle23ai/index.d.ts +2 -0
- package/batteries/vector/oracle23ai.cjs +2 -1
- package/batteries/vector/oracle23ai.cjs.map +1 -1
- package/batteries/vector/oracle23ai.mjs +2 -1
- package/batteries/vector/oracle23ai.mjs.map +1 -1
- package/batteries/vector/orama/index.d.ts +1 -0
- package/batteries/vector/orama.cjs +1 -0
- package/batteries/vector/orama.cjs.map +1 -1
- package/batteries/vector/orama.mjs +1 -0
- package/batteries/vector/orama.mjs.map +1 -1
- package/batteries/vector/pgvector/index.d.ts +9 -2
- package/batteries/vector/pgvector.cjs +4 -0
- package/batteries/vector/pgvector.cjs.map +1 -1
- package/batteries/vector/pgvector.mjs +4 -0
- package/batteries/vector/pgvector.mjs.map +1 -1
- package/batteries/vector/pinecone/index.d.ts +5 -0
- package/batteries/vector/pinecone.cjs +3 -1
- package/batteries/vector/pinecone.cjs.map +1 -1
- package/batteries/vector/pinecone.mjs +3 -1
- package/batteries/vector/pinecone.mjs.map +1 -1
- package/batteries/vector/plan.d.ts +27 -0
- package/batteries/vector/qdrant/index.d.ts +5 -0
- package/batteries/vector/qdrant.cjs +4 -0
- package/batteries/vector/qdrant.cjs.map +1 -1
- package/batteries/vector/qdrant.mjs +4 -0
- package/batteries/vector/qdrant.mjs.map +1 -1
- package/batteries/vector/redis/index.d.ts +2 -0
- package/batteries/vector/redis.cjs +2 -1
- package/batteries/vector/redis.cjs.map +1 -1
- package/batteries/vector/redis.mjs +2 -1
- package/batteries/vector/redis.mjs.map +1 -1
- package/batteries/vector/retrievable.cjs +9 -1
- package/batteries/vector/retrievable.cjs.map +1 -1
- package/batteries/vector/retrievable.mjs +9 -1
- package/batteries/vector/retrievable.mjs.map +1 -1
- package/batteries/vector/retrievable_glue.d.ts +21 -0
- package/batteries/vector/s3vectors/index.d.ts +2 -0
- package/batteries/vector/s3vectors.cjs +2 -1
- package/batteries/vector/s3vectors.cjs.map +1 -1
- package/batteries/vector/s3vectors.mjs +2 -1
- package/batteries/vector/s3vectors.mjs.map +1 -1
- package/batteries/vector/schema.cjs +28 -0
- package/batteries/vector/schema.cjs.map +1 -1
- package/batteries/vector/schema.d.ts +39 -0
- package/batteries/vector/schema.mjs +28 -0
- package/batteries/vector/schema.mjs.map +1 -1
- package/batteries/vector/solr/index.d.ts +2 -0
- package/batteries/vector/solr.cjs +2 -1
- package/batteries/vector/solr.cjs.map +1 -1
- package/batteries/vector/solr.mjs +2 -1
- package/batteries/vector/solr.mjs.map +1 -1
- package/batteries/vector/sqlite_vec/index.d.ts +6 -3
- package/batteries/vector/sqlite_vec.cjs +2 -0
- package/batteries/vector/sqlite_vec.cjs.map +1 -1
- package/batteries/vector/sqlite_vec.mjs +2 -0
- package/batteries/vector/sqlite_vec.mjs.map +1 -1
- package/batteries/vector/surrealdb/index.d.ts +2 -0
- package/batteries/vector/surrealdb.cjs +2 -1
- package/batteries/vector/surrealdb.cjs.map +1 -1
- package/batteries/vector/surrealdb.mjs +2 -1
- package/batteries/vector/surrealdb.mjs.map +1 -1
- package/batteries/vector/types.d.ts +27 -0
- package/batteries/vector/typesense/index.d.ts +2 -0
- package/batteries/vector/typesense.cjs +2 -1
- package/batteries/vector/typesense.cjs.map +1 -1
- package/batteries/vector/typesense.mjs +2 -1
- package/batteries/vector/typesense.mjs.map +1 -1
- package/batteries/vector/validation.cjs +14 -0
- package/batteries/vector/validation.cjs.map +1 -1
- package/batteries/vector/validation.d.ts +14 -0
- package/batteries/vector/validation.mjs +14 -0
- package/batteries/vector/validation.mjs.map +1 -1
- package/batteries/vector/vector_store_constructor.cjs +1 -1
- package/batteries/vector/vector_store_constructor.cjs.map +1 -1
- package/batteries/vector/vector_store_constructor.d.ts +1 -1
- package/batteries/vector/vector_store_constructor.mjs +1 -1
- package/batteries/vector/vector_store_constructor.mjs.map +1 -1
- package/batteries/vector/vespa/index.d.ts +2 -0
- package/batteries/vector/vespa.cjs +2 -1
- package/batteries/vector/vespa.cjs.map +1 -1
- package/batteries/vector/vespa.mjs +2 -1
- package/batteries/vector/vespa.mjs.map +1 -1
- package/batteries/vector/weaviate/index.d.ts +2 -0
- package/batteries/vector/weaviate.cjs +2 -1
- package/batteries/vector/weaviate.cjs.map +1 -1
- package/batteries/vector/weaviate.mjs +2 -1
- package/batteries/vector/weaviate.mjs.map +1 -1
- package/batteries.cjs +58 -28
- package/batteries.mjs +12 -5
- package/{common-BT0nfCi9.mjs → common-DYDUi99O.mjs} +9 -9
- package/common-DYDUi99O.mjs.map +1 -0
- package/{common-Cj8TaQ9U.js → common-DZl3ADJs.js} +9 -9
- package/common-DZl3ADJs.js.map +1 -0
- package/common.cjs +7 -7
- package/common.mjs +7 -7
- package/{dispatch_runner-DPcS7Y_M.mjs → dispatch_runner--ZhdDWRZ.mjs} +27 -5
- package/{dispatch_runner-DPcS7Y_M.mjs.map → dispatch_runner--ZhdDWRZ.mjs.map} +1 -1
- package/{dispatch_runner-BHBNupqp.js → dispatch_runner-nHDKkxye.js} +27 -5
- package/{dispatch_runner-BHBNupqp.js.map → dispatch_runner-nHDKkxye.js.map} +1 -1
- package/dispatch_runner.cjs +1 -1
- package/dispatch_runner.d.ts +1 -1
- package/dispatch_runner.mjs +1 -1
- package/eslint/rules/artifact_tool_forbids_artifact_constructor.cjs +1 -0
- package/eslint/rules/artifact_tool_forbids_artifact_constructor.cjs.map +1 -1
- package/eslint/rules/artifact_tool_forbids_artifact_constructor.d.ts +1 -0
- package/eslint/rules/artifact_tool_forbids_artifact_constructor.mjs +1 -0
- package/eslint/rules/artifact_tool_forbids_artifact_constructor.mjs.map +1 -1
- package/eslint/rules/no_model_in_tool_handler.cjs +1 -0
- package/eslint/rules/no_model_in_tool_handler.cjs.map +1 -1
- package/eslint/rules/no_model_in_tool_handler.d.ts +1 -0
- package/eslint/rules/no_model_in_tool_handler.mjs +1 -0
- package/eslint/rules/no_model_in_tool_handler.mjs.map +1 -1
- package/eslint/rules/require_validator_any_required.cjs +1 -0
- package/eslint/rules/require_validator_any_required.cjs.map +1 -1
- package/eslint/rules/require_validator_any_required.d.ts +1 -0
- package/eslint/rules/require_validator_any_required.mjs +1 -0
- package/eslint/rules/require_validator_any_required.mjs.map +1 -1
- package/eslint/rules/thought_payload_requires_replay_tag.cjs +1 -0
- package/eslint/rules/thought_payload_requires_replay_tag.cjs.map +1 -1
- package/eslint/rules/thought_payload_requires_replay_tag.d.ts +1 -0
- package/eslint/rules/thought_payload_requires_replay_tag.mjs +1 -0
- package/eslint/rules/thought_payload_requires_replay_tag.mjs.map +1 -1
- package/eslint/rules/token_encoding_requires_context_window.cjs +1 -0
- package/eslint/rules/token_encoding_requires_context_window.cjs.map +1 -1
- package/eslint/rules/token_encoding_requires_context_window.d.ts +1 -0
- package/eslint/rules/token_encoding_requires_context_window.mjs +1 -0
- package/eslint/rules/token_encoding_requires_context_window.mjs.map +1 -1
- package/eslint/rules.cjs +1 -1
- package/eslint/rules.mjs +1 -1
- package/eslint.cjs +2 -2
- package/eslint.mjs +2 -2
- package/{exceptions-BeWH2FwP.mjs → exceptions-BDhN0Xzr.mjs} +3 -2
- package/exceptions-BDhN0Xzr.mjs.map +1 -0
- package/{exceptions-CitH5wZI.js → exceptions-BRXrUKiW.js} +3 -2
- package/exceptions-BRXrUKiW.js.map +1 -0
- package/exceptions.cjs +2 -2
- package/exceptions.mjs +2 -2
- package/factories.cjs +1 -1
- package/factories.mjs +1 -1
- package/forge.cjs +4 -4
- package/forge.d.ts +1 -1
- package/forge.mjs +4 -4
- package/guards.cjs +9 -9
- package/guards.mjs +9 -9
- package/helpers-DSTFxTiC.js +497 -0
- package/helpers-DSTFxTiC.js.map +1 -0
- package/helpers-xhrQbMAG.mjs +306 -0
- package/helpers-xhrQbMAG.mjs.map +1 -0
- package/index.cjs +12 -12
- package/index.mjs +12 -12
- package/lib/classes/base_exception.d.ts +1 -0
- package/lib/classes/media.d.ts +10 -0
- package/lib/classes/retrievable.d.ts +1 -1
- package/lib/classes/spooled_json_artifact.d.ts +1 -1
- package/lib/classes/spooled_markdown_artifact.d.ts +1 -0
- package/lib/classes/tokenizable.d.ts +3 -0
- package/lib/classes/tool.d.ts +8 -0
- package/lib/classes/turn_gate.d.ts +6 -0
- package/lib/dispatch_runner.d.ts +4 -32
- package/lib/helpers/bignum.cjs +82 -0
- package/lib/helpers/bignum.cjs.map +1 -0
- package/lib/helpers/bignum.d.ts +52 -0
- package/lib/helpers/bignum.mjs +74 -0
- package/lib/helpers/bignum.mjs.map +1 -0
- package/lib/turn_runner.d.ts +1 -1
- package/lib/types/dispatch_runner.d.ts +83 -0
- package/lib/utils/exceptions.d.ts +1 -1
- package/lib/utils/retry.cjs.map +1 -1
- package/lib/utils/retry.d.ts +2 -0
- package/lib/utils/retry.mjs.map +1 -1
- package/mcp/adk-docs-corpus.json +1 -1
- package/package.json +259 -204
- package/{runtime-j92CNi5z.mjs → runtime-Bz5zA8wc.mjs} +2 -2
- package/{runtime-j92CNi5z.mjs.map → runtime-Bz5zA8wc.mjs.map} +1 -1
- package/{runtime-MFFcJrRv.js → runtime-DslE1aBw.js} +2 -2
- package/{runtime-MFFcJrRv.js.map → runtime-DslE1aBw.js.map} +1 -1
- package/scrapper-BHM1mCde.mjs +432 -0
- package/scrapper-BHM1mCde.mjs.map +1 -0
- package/scrapper-BeweWurk.js +462 -0
- package/scrapper-BeweWurk.js.map +1 -0
- package/searxng-BJFulNcK.mjs +247 -0
- package/searxng-BJFulNcK.mjs.map +1 -0
- package/searxng-B_D--V5q.js +265 -0
- package/searxng-B_D--V5q.js.map +1 -0
- package/skills/adk-assembly/SKILL.md +2 -2
- package/{spooled_artifact-CHoZgWwI.mjs → spooled_artifact-7eePq7JA.mjs} +5 -5
- package/{spooled_artifact-CHoZgWwI.mjs.map → spooled_artifact-7eePq7JA.mjs.map} +1 -1
- package/{spooled_artifact-BTq6Nzfy.js → spooled_artifact-DX8LLyUX.js} +5 -5
- package/{spooled_artifact-BTq6Nzfy.js.map → spooled_artifact-DX8LLyUX.js.map} +1 -1
- package/spooled_artifact.cjs +2 -2
- package/spooled_artifact.mjs +2 -2
- package/{spooled_markdown_artifact-CALSDxIx.js → spooled_markdown_artifact-ClX72lek.js} +4 -4
- package/spooled_markdown_artifact-ClX72lek.js.map +1 -0
- package/{spooled_markdown_artifact-Ci5UL7l4.mjs → spooled_markdown_artifact-wkrBF3oX.mjs} +4 -4
- package/spooled_markdown_artifact-wkrBF3oX.mjs.map +1 -0
- package/{thought-D34QQZZ9.mjs → thought-B_vxAiKU.mjs} +5 -5
- package/{thought-D34QQZZ9.mjs.map → thought-B_vxAiKU.mjs.map} +1 -1
- package/{thought-BbwhJ1wb.js → thought-DLwpF7MI.js} +5 -5
- package/{thought-BbwhJ1wb.js.map → thought-DLwpF7MI.js.map} +1 -1
- package/{tool-CVyZkFC7.js → tool-D5WGVIcI.js} +4 -4
- package/{tool-CVyZkFC7.js.map → tool-D5WGVIcI.js.map} +1 -1
- package/{tool-CMhaDRNd.mjs → tool-wMYMVl60.mjs} +4 -4
- package/{tool-CMhaDRNd.mjs.map → tool-wMYMVl60.mjs.map} +1 -1
- package/{tool_call-CV5qVNlb.mjs → tool_call-B4-_-vjG.mjs} +5 -5
- package/tool_call-B4-_-vjG.mjs.map +1 -0
- package/{tool_call-Db68hB7y.js → tool_call-DixVlW40.js} +5 -5
- package/tool_call-DixVlW40.js.map +1 -0
- package/{tool_registry-D1pSSlsd.mjs → tool_registry-791Vrjtf.mjs} +4 -3
- package/tool_registry-791Vrjtf.mjs.map +1 -0
- package/{tool_registry-DYUYqXvo.js → tool_registry-CKJPze3j.js} +4 -3
- package/tool_registry-CKJPze3j.js.map +1 -0
- package/{turn_runner-DqWHNP80.js → turn_runner-HXImLGIn.js} +7 -7
- package/turn_runner-HXImLGIn.js.map +1 -0
- package/{turn_runner-fg1Wc3dK.mjs → turn_runner-ZyYO-Kti.mjs} +7 -7
- package/turn_runner-ZyYO-Kti.mjs.map +1 -0
- package/turn_runner.cjs +1 -1
- package/turn_runner.mjs +1 -1
- package/types.d.ts +1 -1
- package/common-BT0nfCi9.mjs.map +0 -1
- package/common-Cj8TaQ9U.js.map +0 -1
- package/exceptions-BeWH2FwP.mjs.map +0 -1
- package/exceptions-CitH5wZI.js.map +0 -1
- package/spooled_markdown_artifact-CALSDxIx.js.map +0 -1
- package/spooled_markdown_artifact-Ci5UL7l4.mjs.map +0 -1
- package/tool_call-CV5qVNlb.mjs.map +0 -1
- package/tool_call-Db68hB7y.js.map +0 -1
- package/tool_registry-D1pSSlsd.mjs.map +0 -1
- package/tool_registry-DYUYqXvo.js.map +0 -1
- package/turn_runner-DqWHNP80.js.map +0 -1
- package/turn_runner-fg1Wc3dK.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"couchbase.mjs","names":["#opts","#phys","#cluster","#cb","#bucket","#sleep","#scope","#scopeName","#coll","#dims","#metrics","#vecIndexName","#parseMeta","#project"],"sources":["../../../src/batteries/vector/couchbase/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/couchbase\n *\n * Couchbase (Enterprise) vector-store adapter. Vector search is Enterprise Edition only; the\n * Community Edition will throw \"vector typed fields not supported\". A logical collection maps to a\n * Couchbase scope.collection inside a bucket. KV operations (upsert/get/remove) use strong\n * consistency, while the scoped FTS vector index is async (settle-polled after writes).\n *\n * Scoring rule: do NOT trust FTS native scores (they vary per metric and are unbounded for\n * euclidean/l2_norm). Instead, use FTS only to retrieve the candidate id set, then KV-get each\n * candidate doc and RE-COMPUTE the similarity score from the stored vec vs query vec using\n * normalizeScore — guaranteeing the [0,1] contract regardless of backend metric quirks.\n *\n * Filter-scan, enumerate, and delete-by-filter use N1QL with RequestPlus for strong consistency.\n */\n\nimport { evaluateFilter } from '../filters'\nimport { normalizeScore } from '../helpers'\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 DistanceMetric,\n} from '../types'\n\nconst similarity = (metric: DistanceMetric): string =>\n metric === 'cosine' ? 'cosine' : metric === 'dot' ? 'dot_product' : 'l2_norm'\n\nconst cosineSim = (a: number[], b: number[]): number => {\n let dot = 0\n let normA = 0\n let normB = 0\n a.forEach((av, i) => {\n const bv = b[i]\n dot += av * bv\n normA += av * av\n normB += bv * bv\n })\n const denom = Math.sqrt(normA) * Math.sqrt(normB)\n return denom === 0 ? 0 : dot / denom\n}\n\nconst dotProd = (a: number[], b: number[]): number => {\n let s = 0\n a.forEach((av, i) => {\n s += av * b[i]\n })\n return s\n}\n\nconst euclideanDist = (a: number[], b: number[]): number => {\n let s = 0\n a.forEach((av, i) => {\n const d = av - b[i]\n s += d * d\n })\n return Math.sqrt(s)\n}\n\nconst computeScore = (vec: number[], query: number[], metric: DistanceMetric): number => {\n if (metric === 'cosine') {\n const raw = cosineSim(vec, query)\n return normalizeScore(raw, 'cosine', 'similarity')\n } else if (metric === 'dot') {\n const raw = dotProd(vec, query)\n return normalizeScore(raw, 'dot', 'similarity')\n } else if (metric === 'euclidean') {\n const raw = euclideanDist(vec, query)\n return normalizeScore(raw, 'euclidean', 'distance')\n } else {\n // Fallback\n const raw = cosineSim(vec, query)\n return normalizeScore(raw, 'cosine', 'similarity')\n }\n}\n\nconst getCB = async (): Promise<any> => {\n try {\n return await import('couchbase')\n } catch {\n throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(['couchbase'])\n }\n}\n\nexport interface CouchbaseVectorStoreOptions extends BaseVectorStoreOptions {\n connection: {\n url: string\n username: string\n password: string\n bucket: string\n scope?: string\n /**\n * When set, the physical Couchbase collection becomes `${collectionPrefix}${collection}`. The\n * logical collection the builder/base see is unchanged. Lets callers (and the test suite)\n * isolate otherwise identically-named collections — useful because the scoped FTS vector index\n * builds asynchronously, so a fresh collection per use avoids drop+rebuild-index churn.\n */\n collectionPrefix?: string\n }\n}\n\nexport class CouchbaseVectorStore extends BaseVectorStore {\n readonly capabilities: VectorStoreCapabilities = {\n transactions: false,\n namedVectors: false,\n rename: false,\n rawSql: false,\n builtInEncoding: false,\n consistency: { configurable: false, default: 'strong', modes: ['strong'] },\n }\n\n #cluster: any | null = null\n #bucket: any | null = null\n #cb: any | null = null\n #dims: Map<string, number> = new Map()\n #metrics: Map<string, DistanceMetric> = new Map()\n\n get #opts(): CouchbaseVectorStoreOptions {\n return this.options as CouchbaseVectorStoreOptions\n }\n\n #scopeName(): string {\n return this.#opts.connection.scope ?? '_default'\n }\n\n // Map a logical collection name to its physical Couchbase collection (optional prefix).\n #phys(collection: string): string {\n const prefix = this.#opts.connection.collectionPrefix\n return prefix ? `${prefix}${collection}` : collection\n }\n\n #vecIndexName(collection: string): string {\n return `${this.#phys(collection)}_vec`\n }\n\n static isAvailable(): boolean {\n return typeof process !== 'undefined'\n }\n\n isAvailable(): boolean {\n return typeof process !== 'undefined'\n }\n\n async connect(): Promise<void> {\n if (this.#cluster) return\n const couchbase = await getCB()\n this.#cb = couchbase\n const c = this.#opts.connection\n try {\n this.#cluster = await couchbase.connect(c.url, { username: c.username, password: c.password })\n this.#bucket = this.#cluster.bucket(c.bucket)\n } catch (err) {\n throw new E_VECTOR_STORE_CONNECTION_FAILED([String(err)])\n }\n }\n\n async close(): Promise<void> {\n if (this.#cluster) {\n await this.#cluster.close()\n this.#cluster = null\n this.#bucket = null\n }\n }\n\n async #sleep(ms: number): Promise<void> {\n await new Promise((r) => setTimeout(r, ms))\n }\n\n async #scope(): Promise<any> {\n if (!this.#bucket) await this.connect()\n return this.#bucket.scope(this.#scopeName())\n }\n\n async #coll(scope: any, collection: string): Promise<any> {\n return scope.collection(this.#phys(collection))\n }\n\n async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n if (!this.#bucket) await this.connect()\n const cm = this.#bucket.collections()\n const scopeName = this.#scopeName()\n this.#dims.set(spec.collection, spec.vector.dimensions)\n this.#metrics.set(spec.collection, spec.vector.metric)\n\n // Physical collection name (logical name + optional prefix); the FTS index, N1QL identifiers\n // and the collection-manager ops all key off the physical name.\n const collectionName = this.#phys(spec.collection)\n const indexName = this.#vecIndexName(spec.collection)\n\n try {\n // Create scope.collection\n try {\n await cm.createCollection({ name: collectionName, scopeName })\n } catch (err: any) {\n if (err.message && err.message.includes('CollectionExists')) {\n if (ifNotExists) {\n // Clear existing collection\n try {\n await this.#cluster.query(\n `DELETE FROM \\`${this.#opts.connection.bucket}\\`.\\`${scopeName}\\`.\\`${collectionName}\\``\n )\n } catch {\n // Ignore cleanup failures\n }\n } else {\n // Drop and recreate\n await cm.dropCollection(collectionName, scopeName)\n await cm.createCollection({ name: collectionName, scopeName })\n }\n } else {\n throw err\n }\n }\n\n // Wait for collection to be ready\n await this.#sleep(1000)\n\n // Create primary index\n try {\n await this.#cluster.query(\n `CREATE PRIMARY INDEX ON \\`${this.#opts.connection.bucket}\\`.\\`${scopeName}\\`.\\`${collectionName}\\``\n )\n } catch {\n // Ignore if already exists\n }\n\n // Create FTS vector index\n const mgr = this.#bucket.scope(scopeName).searchIndexes()\n try {\n await mgr.upsertIndex({\n name: indexName,\n sourceType: 'gocbcore',\n sourceName: this.#opts.connection.bucket,\n type: 'fulltext-index',\n planParams: { indexPartitions: 1 },\n params: {\n doc_config: {\n mode: 'scope.collection.type_field',\n type_field: 'type',\n },\n mapping: {\n default_mapping: { enabled: false },\n default_analyzer: 'standard',\n default_type: '_default',\n types: {\n [`${scopeName}.${collectionName}`]: {\n enabled: true,\n dynamic: false,\n properties: {\n vec: {\n enabled: true,\n fields: [\n {\n name: 'vec',\n type: 'vector',\n dims: spec.vector.dimensions,\n similarity: similarity(spec.vector.metric),\n index: true,\n },\n ],\n },\n },\n },\n },\n },\n },\n })\n } catch {\n // Ignore if index already exists\n }\n\n // Poll until index is queryable\n const scope = this.#bucket.scope(scopeName)\n const probe = new Array(spec.vector.dimensions).fill(0)\n probe[0] = 1\n for (let i = 0; i < 60; i++) {\n try {\n const req = this.#cb.SearchRequest.create(\n this.#cb.VectorSearch.fromVectorQuery(\n this.#cb.VectorQuery.create('vec', probe).numCandidates(10)\n )\n )\n await scope.search(indexName, req, { timeout: 10000 })\n break\n } catch {\n await this.#sleep(1000)\n }\n }\n } catch (err) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['createCollection', String(err)])\n }\n }\n\n async dropCollection(collection: string, ifExists: boolean): Promise<void> {\n if (!this.#bucket) await this.connect()\n const cm = this.#bucket.collections()\n const scopeName = this.#scopeName()\n const physical = this.#phys(collection)\n const indexName = this.#vecIndexName(collection)\n const mgr = this.#bucket.scope(scopeName).searchIndexes()\n\n try {\n // Drop FTS index\n try {\n await mgr.dropIndex(indexName)\n } catch {\n // Ignore if index doesn't exist\n }\n\n // Drop collection\n try {\n const scopes = await cm.getAllScopes()\n const scope = scopes.find((s: any) => s.name === scopeName)\n if (!scope) {\n if (ifExists) return\n throw new Error(`scope not found: ${scopeName}`)\n }\n const coll = scope.collections?.find((c: any) => c.name === physical)\n if (!coll) {\n if (ifExists) return\n throw new Error(`collection not found: ${collection}`)\n }\n } catch (err: any) {\n if (err.message && err.message.includes('not found')) {\n if (ifExists) return\n throw err\n }\n throw err\n }\n\n await cm.dropCollection(physical, scopeName)\n this.#dims.delete(collection)\n this.#metrics.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 if (!this.#bucket) await this.connect()\n const cm = this.#bucket.collections()\n const scopeName = this.#scopeName()\n try {\n const scopes = await cm.getAllScopes()\n const scope = scopes.find((s: any) => s.name === scopeName)\n if (!scope) return false\n return !!scope.collections?.find((c: any) => c.name === this.#phys(collection))\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', 'couchbase'])\n }\n\n async executeUpsert(plan: UpsertPlan): Promise<void> {\n if (plan.records.length === 0) return\n validateRecords(plan.records)\n const scope = await this.#scope()\n const coll = await this.#coll(scope, plan.collection)\n const expected = this.#opts.dimensions ?? this.#dims.get(plan.collection)\n const dims = expected ?? 0\n const indexName = this.#vecIndexName(plan.collection)\n\n try {\n const ids: string[] = []\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 await coll.upsert(r.id, {\n id: r.id,\n vec: vector,\n document: r.document ?? '',\n metadata: r.metadata ? JSON.stringify(r.metadata) : '{}',\n type: plan.collection,\n })\n ids.push(r.id)\n }\n\n // Poll until FTS index shows all ids\n const probe = new Array(dims).fill(0)\n probe[0] = 1\n const deadline = Date.now() + 10_000\n while (Date.now() < deadline) {\n let seen = new Set<string>()\n try {\n const req = this.#cb.SearchRequest.create(\n this.#cb.VectorSearch.fromVectorQuery(\n this.#cb.VectorQuery.create('vec', probe).numCandidates(100)\n )\n )\n const res: any = await scope.search(indexName, req, { timeout: 10000 })\n seen = new Set(res.rows?.map((row: any) => row.id) ?? [])\n } catch {\n // Continue polling\n }\n if (ids.every((id) => seen.has(id))) break\n await this.#sleep(300)\n }\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 scope = await this.#scope()\n const coll = await this.#coll(scope, plan.collection)\n const indexName = this.#vecIndexName(plan.collection)\n const metric: DistanceMetric =\n this.#metrics.get(plan.collection) ?? this.#opts.metric ?? 'cosine'\n const oversample = 10\n\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 try {\n const got: any = await coll.get(plan.near.id)\n queryVector = got.content?.vec\n if (!queryVector) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n } catch (err: any) {\n if (err.message && err.message.includes('DocumentNotFound')) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)])\n }\n }\n }\n\n const offset = plan.offset ?? 0\n\n try {\n if (queryVector) {\n // Similarity search: FTS for candidates, then KV-get and re-score\n const k = (plan.filter ? 1000 : (plan.topK + offset) * oversample) || 100\n const req = this.#cb.SearchRequest.create(\n this.#cb.VectorSearch.fromVectorQuery(\n this.#cb.VectorQuery.create('vec', queryVector).numCandidates(Math.max(k, 100))\n )\n )\n const res: any = await scope.search(indexName, req, { timeout: 10000 })\n const candidateIds = res.rows?.map((row: any) => row.id) ?? []\n\n // KV-get each candidate to get full doc\n const candidates: any[] = []\n for (const id of candidateIds) {\n try {\n const got: any = await coll.get(id)\n candidates.push(got.content)\n } catch {\n // Skip docs that can't be read\n }\n }\n\n // Apply filter and compute scores\n const filtered = candidates.filter((d) =>\n evaluateFilter(plan.filter ?? {}, this.#parseMeta(d.metadata))\n )\n\n // Re-compute scores and sort\n const scored = filtered.map((d) => ({\n ...d,\n score: computeScore(d.vec, queryVector, metric),\n }))\n scored.sort((a, b) => b.score - a.score)\n\n return scored\n .slice(offset, offset + plan.topK)\n .map((d: any) => this.#project(d, plan, true))\n } else {\n // Filter-scan: N1QL\n const bucket = this.#opts.connection.bucket\n const scopeName = this.#scopeName()\n const q = await this.#cluster.query(\n `SELECT d.id, d.vec, d.document, d.metadata FROM \\`${bucket}\\`.\\`${scopeName}\\`.\\`${this.#phys(plan.collection)}\\` d`,\n { scanConsistency: this.#cb.QueryScanConsistency.RequestPlus }\n )\n const docs: any[] = q.rows ?? []\n\n const filtered = docs.filter((d) =>\n evaluateFilter(plan.filter ?? {}, this.#parseMeta(d.metadata))\n )\n\n return filtered\n .slice(offset, offset + plan.topK)\n .map((d: any) => this.#project(d, plan, false))\n }\n } catch (err: any) {\n if (err?.message?.includes('Referenced id not found')) {\n throw err\n }\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(doc: any, plan: SearchPlan, hasScore: boolean): VectorMatch {\n const proj = plan.projection\n const out: VectorMatch = {}\n if (proj.id) out.id = doc.id as string\n if (proj.vector && Array.isArray(doc.vec)) out.vector = (doc.vec as number[]).map(Number)\n if (proj.document) out.document = (doc.document ?? undefined) as string | undefined\n if (proj.metadata) out.metadata = this.#parseMeta(doc.metadata)\n if (hasScore && typeof doc.score === 'number') {\n out.score = doc.score\n }\n return out\n }\n\n async executeDelete(plan: DeletePlan): Promise<void> {\n const scope = await this.#scope()\n const coll = await this.#coll(scope, plan.collection)\n const bucket = this.#opts.connection.bucket\n const scopeName = this.#scopeName()\n\n try {\n if (plan.ids && plan.ids.length > 0) {\n // Delete by ids\n for (const id of plan.ids) {\n try {\n await coll.remove(id)\n } catch {\n // Ignore DocumentNotFoundError\n }\n }\n } else if (plan.filter) {\n // Enumerate via N1QL, filter, then delete\n const q = await this.#cluster.query(\n `SELECT d.id, d.metadata FROM \\`${bucket}\\`.\\`${scopeName}\\`.\\`${this.#phys(plan.collection)}\\` d`,\n { scanConsistency: this.#cb.QueryScanConsistency.RequestPlus }\n )\n const docs: any[] = q.rows ?? []\n\n const targets = docs\n .filter((d) => evaluateFilter(plan.filter!, this.#parseMeta(d.metadata)))\n .map((d: any) => d.id as string)\n\n for (const id of targets) {\n try {\n await coll.remove(id)\n } catch {\n // Ignore DocumentNotFoundError\n }\n }\n } else {\n // Delete all\n await this.#cluster.query(\n `DELETE FROM \\`${bucket}\\`.\\`${scopeName}\\`.\\`${this.#phys(plan.collection)}\\` d`,\n { scanConsistency: this.#cb.QueryScanConsistency.RequestPlus }\n )\n }\n } catch (err) {\n throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"couchbase.mjs","names":["#opts","#phys","#cluster","#cb","#bucket","#sleep","#scope","#scopeName","#coll","#dims","#metrics","#vecIndexName","#parseMeta","#project"],"sources":["../../../src/batteries/vector/couchbase/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/couchbase\n *\n * Couchbase (Enterprise) vector-store adapter. Vector search is Enterprise Edition only; the\n * Community Edition will throw \"vector typed fields not supported\". A logical collection maps to a\n * Couchbase scope.collection inside a bucket. KV operations (upsert/get/remove) use strong\n * consistency, while the scoped FTS vector index is async (settle-polled after writes).\n *\n * Scoring rule: do NOT trust FTS native scores (they vary per metric and are unbounded for\n * euclidean/l2_norm). Instead, use FTS only to retrieve the candidate id set, then KV-get each\n * candidate doc and RE-COMPUTE the similarity score from the stored vec vs query vec using\n * normalizeScore — guaranteeing the [0,1] contract regardless of backend metric quirks.\n *\n * Filter-scan, enumerate, and delete-by-filter use N1QL with RequestPlus for strong consistency.\n */\n\nimport { evaluateFilter } from '../filters'\nimport { normalizeScore } from '../helpers'\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 DistanceMetric,\n} from '../types'\n\nconst similarity = (metric: DistanceMetric): string =>\n metric === 'cosine' ? 'cosine' : metric === 'dot' ? 'dot_product' : 'l2_norm'\n\nconst cosineSim = (a: number[], b: number[]): number => {\n let dot = 0\n let normA = 0\n let normB = 0\n a.forEach((av, i) => {\n const bv = b[i]\n dot += av * bv\n normA += av * av\n normB += bv * bv\n })\n const denom = Math.sqrt(normA) * Math.sqrt(normB)\n return denom === 0 ? 0 : dot / denom\n}\n\nconst dotProd = (a: number[], b: number[]): number => {\n let s = 0\n a.forEach((av, i) => {\n s += av * b[i]\n })\n return s\n}\n\nconst euclideanDist = (a: number[], b: number[]): number => {\n let s = 0\n a.forEach((av, i) => {\n const d = av - b[i]\n s += d * d\n })\n return Math.sqrt(s)\n}\n\nconst computeScore = (vec: number[], query: number[], metric: DistanceMetric): number => {\n if (metric === 'cosine') {\n const raw = cosineSim(vec, query)\n return normalizeScore(raw, 'cosine', 'similarity')\n } else if (metric === 'dot') {\n const raw = dotProd(vec, query)\n return normalizeScore(raw, 'dot', 'similarity')\n } else if (metric === 'euclidean') {\n const raw = euclideanDist(vec, query)\n return normalizeScore(raw, 'euclidean', 'distance')\n } else {\n // Fallback\n const raw = cosineSim(vec, query)\n return normalizeScore(raw, 'cosine', 'similarity')\n }\n}\n\nconst getCB = async (): Promise<any> => {\n try {\n return await import('couchbase')\n } catch {\n throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(['couchbase'])\n }\n}\n\nexport interface CouchbaseVectorStoreOptions extends BaseVectorStoreOptions {\n /** Connection and authentication parameters for the backend. */\n connection: {\n url: string\n username: string\n password: string\n bucket: string\n scope?: string\n /**\n * When set, the physical Couchbase collection becomes `${collectionPrefix}${collection}`. The\n * logical collection the builder/base see is unchanged. Lets callers (and the test suite)\n * isolate otherwise identically-named collections — useful because the scoped FTS vector index\n * builds asynchronously, so a fresh collection per use avoids drop+rebuild-index churn.\n */\n collectionPrefix?: string\n }\n}\n\nexport class CouchbaseVectorStore extends BaseVectorStore {\n readonly capabilities: VectorStoreCapabilities = {\n transactions: false,\n namedVectors: false,\n rename: false,\n rawSql: false,\n builtInEncoding: false,\n consistency: { configurable: false, default: 'strong', modes: ['strong'] },\n }\n\n #cluster: any | null = null\n #bucket: any | null = null\n #cb: any | null = null\n #dims: Map<string, number> = new Map()\n #metrics: Map<string, DistanceMetric> = new Map()\n\n get #opts(): CouchbaseVectorStoreOptions {\n return this.options as CouchbaseVectorStoreOptions\n }\n\n #scopeName(): string {\n return this.#opts.connection.scope ?? '_default'\n }\n\n // Map a logical collection name to its physical Couchbase collection (optional prefix).\n #phys(collection: string): string {\n const prefix = this.#opts.connection.collectionPrefix\n return prefix ? `${prefix}${collection}` : collection\n }\n\n #vecIndexName(collection: string): string {\n return `${this.#phys(collection)}_vec`\n }\n\n /** Static availability probe: whether this adapter's runtime driver can load in the current environment. */\n static isAvailable(): boolean {\n return typeof process !== 'undefined'\n }\n\n isAvailable(): boolean {\n return typeof process !== 'undefined'\n }\n\n async connect(): Promise<void> {\n if (this.#cluster) return\n const couchbase = await getCB()\n this.#cb = couchbase\n const c = this.#opts.connection\n try {\n this.#cluster = await couchbase.connect(c.url, { username: c.username, password: c.password })\n this.#bucket = this.#cluster.bucket(c.bucket)\n } catch (err) {\n throw new E_VECTOR_STORE_CONNECTION_FAILED([String(err)])\n }\n }\n\n async close(): Promise<void> {\n if (this.#cluster) {\n await this.#cluster.close()\n this.#cluster = null\n this.#bucket = null\n }\n }\n\n async #sleep(ms: number): Promise<void> {\n await new Promise((r) => setTimeout(r, ms))\n }\n\n async #scope(): Promise<any> {\n if (!this.#bucket) await this.connect()\n return this.#bucket.scope(this.#scopeName())\n }\n\n async #coll(scope: any, collection: string): Promise<any> {\n return scope.collection(this.#phys(collection))\n }\n\n async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n if (!this.#bucket) await this.connect()\n const cm = this.#bucket.collections()\n const scopeName = this.#scopeName()\n this.#dims.set(spec.collection, spec.vector.dimensions)\n this.#metrics.set(spec.collection, spec.vector.metric)\n\n // Physical collection name (logical name + optional prefix); the FTS index, N1QL identifiers\n // and the collection-manager ops all key off the physical name.\n const collectionName = this.#phys(spec.collection)\n const indexName = this.#vecIndexName(spec.collection)\n\n try {\n // Create scope.collection\n try {\n await cm.createCollection({ name: collectionName, scopeName })\n } catch (err: any) {\n if (err.message && err.message.includes('CollectionExists')) {\n if (ifNotExists) {\n // Clear existing collection\n try {\n await this.#cluster.query(\n `DELETE FROM \\`${this.#opts.connection.bucket}\\`.\\`${scopeName}\\`.\\`${collectionName}\\``\n )\n } catch {\n // Ignore cleanup failures\n }\n } else {\n // Drop and recreate\n await cm.dropCollection(collectionName, scopeName)\n await cm.createCollection({ name: collectionName, scopeName })\n }\n } else {\n throw err\n }\n }\n\n // Wait for collection to be ready\n await this.#sleep(1000)\n\n // Create primary index\n try {\n await this.#cluster.query(\n `CREATE PRIMARY INDEX ON \\`${this.#opts.connection.bucket}\\`.\\`${scopeName}\\`.\\`${collectionName}\\``\n )\n } catch {\n // Ignore if already exists\n }\n\n // Create FTS vector index\n const mgr = this.#bucket.scope(scopeName).searchIndexes()\n try {\n await mgr.upsertIndex({\n name: indexName,\n sourceType: 'gocbcore',\n sourceName: this.#opts.connection.bucket,\n type: 'fulltext-index',\n planParams: { indexPartitions: 1 },\n params: {\n doc_config: {\n mode: 'scope.collection.type_field',\n type_field: 'type',\n },\n mapping: {\n default_mapping: { enabled: false },\n default_analyzer: 'standard',\n default_type: '_default',\n types: {\n [`${scopeName}.${collectionName}`]: {\n enabled: true,\n dynamic: false,\n properties: {\n vec: {\n enabled: true,\n fields: [\n {\n name: 'vec',\n type: 'vector',\n dims: spec.vector.dimensions,\n similarity: similarity(spec.vector.metric),\n index: true,\n },\n ],\n },\n },\n },\n },\n },\n },\n })\n } catch {\n // Ignore if index already exists\n }\n\n // Poll until index is queryable\n const scope = this.#bucket.scope(scopeName)\n const probe = new Array(spec.vector.dimensions).fill(0)\n probe[0] = 1\n for (let i = 0; i < 60; i++) {\n try {\n const req = this.#cb.SearchRequest.create(\n this.#cb.VectorSearch.fromVectorQuery(\n this.#cb.VectorQuery.create('vec', probe).numCandidates(10)\n )\n )\n await scope.search(indexName, req, { timeout: 10000 })\n break\n } catch {\n await this.#sleep(1000)\n }\n }\n } catch (err) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['createCollection', String(err)])\n }\n }\n\n async dropCollection(collection: string, ifExists: boolean): Promise<void> {\n if (!this.#bucket) await this.connect()\n const cm = this.#bucket.collections()\n const scopeName = this.#scopeName()\n const physical = this.#phys(collection)\n const indexName = this.#vecIndexName(collection)\n const mgr = this.#bucket.scope(scopeName).searchIndexes()\n\n try {\n // Drop FTS index\n try {\n await mgr.dropIndex(indexName)\n } catch {\n // Ignore if index doesn't exist\n }\n\n // Drop collection\n try {\n const scopes = await cm.getAllScopes()\n const scope = scopes.find((s: any) => s.name === scopeName)\n if (!scope) {\n if (ifExists) return\n throw new Error(`scope not found: ${scopeName}`)\n }\n const coll = scope.collections?.find((c: any) => c.name === physical)\n if (!coll) {\n if (ifExists) return\n throw new Error(`collection not found: ${collection}`)\n }\n } catch (err: any) {\n if (err.message && err.message.includes('not found')) {\n if (ifExists) return\n throw err\n }\n throw err\n }\n\n await cm.dropCollection(physical, scopeName)\n this.#dims.delete(collection)\n this.#metrics.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 if (!this.#bucket) await this.connect()\n const cm = this.#bucket.collections()\n const scopeName = this.#scopeName()\n try {\n const scopes = await cm.getAllScopes()\n const scope = scopes.find((s: any) => s.name === scopeName)\n if (!scope) return false\n return !!scope.collections?.find((c: any) => c.name === this.#phys(collection))\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', 'couchbase'])\n }\n\n async executeUpsert(plan: UpsertPlan): Promise<void> {\n if (plan.records.length === 0) return\n validateRecords(plan.records)\n const scope = await this.#scope()\n const coll = await this.#coll(scope, plan.collection)\n const expected = this.#opts.dimensions ?? this.#dims.get(plan.collection)\n const dims = expected ?? 0\n const indexName = this.#vecIndexName(plan.collection)\n\n try {\n const ids: string[] = []\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 await coll.upsert(r.id, {\n id: r.id,\n vec: vector,\n document: r.document ?? '',\n metadata: r.metadata ? JSON.stringify(r.metadata) : '{}',\n type: plan.collection,\n })\n ids.push(r.id)\n }\n\n // Poll until FTS index shows all ids\n const probe = new Array(dims).fill(0)\n probe[0] = 1\n const deadline = Date.now() + 10_000\n while (Date.now() < deadline) {\n let seen = new Set<string>()\n try {\n const req = this.#cb.SearchRequest.create(\n this.#cb.VectorSearch.fromVectorQuery(\n this.#cb.VectorQuery.create('vec', probe).numCandidates(100)\n )\n )\n const res: any = await scope.search(indexName, req, { timeout: 10000 })\n seen = new Set(res.rows?.map((row: any) => row.id) ?? [])\n } catch {\n // Continue polling\n }\n if (ids.every((id) => seen.has(id))) break\n await this.#sleep(300)\n }\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 scope = await this.#scope()\n const coll = await this.#coll(scope, plan.collection)\n const indexName = this.#vecIndexName(plan.collection)\n const metric: DistanceMetric =\n this.#metrics.get(plan.collection) ?? this.#opts.metric ?? 'cosine'\n const oversample = 10\n\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 try {\n const got: any = await coll.get(plan.near.id)\n queryVector = got.content?.vec\n if (!queryVector) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n } catch (err: any) {\n if (err.message && err.message.includes('DocumentNotFound')) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)])\n }\n }\n }\n\n const offset = plan.offset ?? 0\n\n try {\n if (queryVector) {\n // Similarity search: FTS for candidates, then KV-get and re-score\n const k = (plan.filter ? 1000 : (plan.topK + offset) * oversample) || 100\n const req = this.#cb.SearchRequest.create(\n this.#cb.VectorSearch.fromVectorQuery(\n this.#cb.VectorQuery.create('vec', queryVector).numCandidates(Math.max(k, 100))\n )\n )\n const res: any = await scope.search(indexName, req, { timeout: 10000 })\n const candidateIds = res.rows?.map((row: any) => row.id) ?? []\n\n // KV-get each candidate to get full doc\n const candidates: any[] = []\n for (const id of candidateIds) {\n try {\n const got: any = await coll.get(id)\n candidates.push(got.content)\n } catch {\n // Skip docs that can't be read\n }\n }\n\n // Apply filter and compute scores\n const filtered = candidates.filter((d) =>\n evaluateFilter(plan.filter ?? {}, this.#parseMeta(d.metadata))\n )\n\n // Re-compute scores and sort\n const scored = filtered.map((d) => ({\n ...d,\n score: computeScore(d.vec, queryVector, metric),\n }))\n scored.sort((a, b) => b.score - a.score)\n\n return scored\n .slice(offset, offset + plan.topK)\n .map((d: any) => this.#project(d, plan, true))\n } else {\n // Filter-scan: N1QL\n const bucket = this.#opts.connection.bucket\n const scopeName = this.#scopeName()\n const q = await this.#cluster.query(\n `SELECT d.id, d.vec, d.document, d.metadata FROM \\`${bucket}\\`.\\`${scopeName}\\`.\\`${this.#phys(plan.collection)}\\` d`,\n { scanConsistency: this.#cb.QueryScanConsistency.RequestPlus }\n )\n const docs: any[] = q.rows ?? []\n\n const filtered = docs.filter((d) =>\n evaluateFilter(plan.filter ?? {}, this.#parseMeta(d.metadata))\n )\n\n return filtered\n .slice(offset, offset + plan.topK)\n .map((d: any) => this.#project(d, plan, false))\n }\n } catch (err: any) {\n if (err?.message?.includes('Referenced id not found')) {\n throw err\n }\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(doc: any, plan: SearchPlan, hasScore: boolean): VectorMatch {\n const proj = plan.projection\n const out: VectorMatch = {}\n if (proj.id) out.id = doc.id as string\n if (proj.vector && Array.isArray(doc.vec)) out.vector = (doc.vec as number[]).map(Number)\n if (proj.document) out.document = (doc.document ?? undefined) as string | undefined\n if (proj.metadata) out.metadata = this.#parseMeta(doc.metadata)\n if (hasScore && typeof doc.score === 'number') {\n out.score = doc.score\n }\n return out\n }\n\n async executeDelete(plan: DeletePlan): Promise<void> {\n const scope = await this.#scope()\n const coll = await this.#coll(scope, plan.collection)\n const bucket = this.#opts.connection.bucket\n const scopeName = this.#scopeName()\n\n try {\n if (plan.ids && plan.ids.length > 0) {\n // Delete by ids\n for (const id of plan.ids) {\n try {\n await coll.remove(id)\n } catch {\n // Ignore DocumentNotFoundError\n }\n }\n } else if (plan.filter) {\n // Enumerate via N1QL, filter, then delete\n const q = await this.#cluster.query(\n `SELECT d.id, d.metadata FROM \\`${bucket}\\`.\\`${scopeName}\\`.\\`${this.#phys(plan.collection)}\\` d`,\n { scanConsistency: this.#cb.QueryScanConsistency.RequestPlus }\n )\n const docs: any[] = q.rows ?? []\n\n const targets = docs\n .filter((d) => evaluateFilter(plan.filter!, this.#parseMeta(d.metadata)))\n .map((d: any) => d.id as string)\n\n for (const id of targets) {\n try {\n await coll.remove(id)\n } catch {\n // Ignore DocumentNotFoundError\n }\n }\n } else {\n // Delete all\n await this.#cluster.query(\n `DELETE FROM \\`${bucket}\\`.\\`${scopeName}\\`.\\`${this.#phys(plan.collection)}\\` d`,\n { scanConsistency: this.#cb.QueryScanConsistency.RequestPlus }\n )\n }\n } catch (err) {\n throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ import { BaseVectorStore } from "../contract";
|
|
|
12
12
|
import type { SearchPlan, UpsertPlan, DeletePlan, CollectionSpec } from "../plan";
|
|
13
13
|
import type { VectorMatch, VectorStoreCapabilities, BaseVectorStoreOptions } from "../types";
|
|
14
14
|
export interface DuckDBVectorStoreOptions extends BaseVectorStoreOptions {
|
|
15
|
+
/** Connection and authentication parameters for the backend. */
|
|
15
16
|
connection?: {
|
|
16
17
|
path?: string;
|
|
17
18
|
};
|
|
@@ -19,6 +20,7 @@ export interface DuckDBVectorStoreOptions extends BaseVectorStoreOptions {
|
|
|
19
20
|
export declare class DuckDBVectorStore extends BaseVectorStore {
|
|
20
21
|
#private;
|
|
21
22
|
readonly capabilities: VectorStoreCapabilities;
|
|
23
|
+
/** Static availability probe: whether this adapter's runtime driver can load in the current environment. */
|
|
22
24
|
static isAvailable(): boolean;
|
|
23
25
|
isAvailable(): boolean;
|
|
24
26
|
connect(): Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("../../chunk-Ble4zEEl.js");
|
|
3
|
-
const require_tool_registry = require("../../tool_registry-
|
|
3
|
+
const require_tool_registry = require("../../tool_registry-CKJPze3j.js");
|
|
4
4
|
require("../../guards.cjs");
|
|
5
5
|
const require_batteries_vector_filters = require("./filters.cjs");
|
|
6
6
|
const require_batteries_vector_helpers = require("./helpers.cjs");
|
|
@@ -48,6 +48,7 @@ var DuckDBVectorStore = class extends require_batteries_vector_contract.BaseVect
|
|
|
48
48
|
get #opts() {
|
|
49
49
|
return this.options;
|
|
50
50
|
}
|
|
51
|
+
/** Static availability probe: whether this adapter's runtime driver can load in the current environment. */
|
|
51
52
|
static isAvailable() {
|
|
52
53
|
return typeof process !== "undefined";
|
|
53
54
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"duckdb.cjs","names":["#opts","#conn","#instance","#ensure","#rows","#dims","#unwrapVector","#parseMeta","#project"],"sources":["../../../src/batteries/vector/duckdb/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/duckdb\n *\n * In-process DuckDB adapter (like sqlite_vec — no server). Uses the `vss` community\n * extension for vector distance functions over a `FLOAT[N]` column; metadata lives in a\n * `JSON` column filtered with DuckDB's `json_extract*` functions. Each collection is a\n * table; the document and id are plain columns.\n *\n * Driver: `@duckdb/node-api` (promise-based). Path defaults to `:memory:`.\n */\n\nimport { evaluateFilter } from '../filters'\nimport { normalizeScore } from '../helpers'\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 DistanceMetric,\n} from '../types'\n\nexport interface DuckDBVectorStoreOptions extends BaseVectorStoreOptions {\n connection?: { path?: string }\n}\n\nconst getDuckDB = async () => {\n try {\n const mod = await import('@duckdb/node-api')\n return mod.DuckDBInstance\n } catch {\n throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(['@duckdb/node-api'])\n }\n}\n\n// DuckDB vss distance function per metric (all return a distance — lower is closer).\nconst distanceFn = (metric: DistanceMetric): string =>\n metric === 'euclidean'\n ? 'array_distance'\n : metric === 'dot'\n ? 'array_negative_inner_product'\n : 'array_cosine_distance'\n\n// A double-quoted SQL identifier (table/column), escaping embedded quotes.\nconst ident = (name: string): string => `\"${name.replace(/\"/g, '\"\"')}\"`\n\n// A single-quoted SQL string literal, escaping embedded quotes.\nconst lit = (value: string): string => `'${value.replace(/'/g, \"''\")}'`\n\n// Render a number[] as a DuckDB FLOAT[N] array literal: [1.0, 2.0, ...]::FLOAT[N].\nconst vectorLiteral = (vector: number[]): string =>\n `[${vector.map((n) => (Number.isFinite(n) ? String(n) : '0')).join(', ')}]::FLOAT[${vector.length}]`\n\nexport class DuckDBVectorStore extends BaseVectorStore {\n readonly capabilities: VectorStoreCapabilities = {\n transactions: true,\n namedVectors: false,\n rename: true,\n rawSql: true,\n builtInEncoding: false,\n // In-process and synchronous: a write is visible on resolve. The option is a no-op.\n consistency: { configurable: false, default: 'strong', modes: ['strong'] },\n }\n\n #instance: any | null = null\n #conn: any | null = null\n #dims: Map<string, number> = new Map()\n\n get #opts(): DuckDBVectorStoreOptions {\n return this.options as DuckDBVectorStoreOptions\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.#conn) return\n const DuckDBInstance = await getDuckDB()\n const path = this.#opts.connection?.path ?? ':memory:'\n try {\n this.#instance = await DuckDBInstance.create(path)\n this.#conn = await this.#instance.connect()\n // vss provides the array_*_distance vector functions.\n await this.#conn.run('INSTALL vss;')\n await this.#conn.run('LOAD vss;')\n } catch (err) {\n throw new E_VECTOR_STORE_CONNECTION_FAILED([String(err)])\n }\n }\n\n async close(): Promise<void> {\n // @duckdb/node-api connections are GC-managed; drop references.\n this.#conn = null\n this.#instance = null\n }\n\n async #ensure(): Promise<any> {\n if (!this.#conn) await this.connect()\n return this.#conn!\n }\n\n async #rows(sql: string): Promise<any[][]> {\n const conn = await this.#ensure()\n const reader = await conn.runAndReadAll(sql)\n return reader.getRows()\n }\n\n async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n const conn = await this.#ensure()\n this.#dims.set(spec.collection, spec.vector.dimensions)\n const ine = ifNotExists ? 'IF NOT EXISTS ' : ''\n try {\n await conn.run(\n `CREATE TABLE ${ine}${ident(spec.collection)} (` +\n `id VARCHAR PRIMARY KEY, ` +\n `vec FLOAT[${spec.vector.dimensions}], ` +\n `document VARCHAR, ` +\n `metadata JSON)`\n )\n } catch (err) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['createCollection', String(err)])\n }\n }\n\n async dropCollection(collection: string, ifExists: boolean): Promise<void> {\n const conn = await this.#ensure()\n const ie = ifExists ? 'IF EXISTS ' : ''\n try {\n await conn.run(`DROP TABLE ${ie}${ident(collection)}`)\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 rows = await this.#rows(\n `SELECT 1 FROM information_schema.tables WHERE table_name = ${lit(collection)}`\n )\n return rows.length > 0\n }\n\n async renameCollection(from: string, to: string): Promise<void> {\n const conn = await this.#ensure()\n try {\n await conn.run(`ALTER TABLE ${ident(from)} RENAME TO ${ident(to)}`)\n const d = this.#dims.get(from)\n if (d !== undefined) {\n this.#dims.set(to, d)\n this.#dims.delete(from)\n }\n } catch (err) {\n throw new E_VECTOR_STORE_UNSUPPORTED_OPERATION(['renameCollection', String(err)])\n }\n }\n\n async executeUpsert(plan: UpsertPlan): Promise<void> {\n if (plan.records.length === 0) return\n validateRecords(plan.records)\n const conn = await this.#ensure()\n const expected = this.#opts.dimensions ?? this.#dims.get(plan.collection)\n try {\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 meta = r.metadata ? JSON.stringify(r.metadata) : '{}'\n const doc = r.document === undefined ? 'NULL' : lit(r.document)\n // DuckDB upsert: delete-then-insert keeps it simple and dialect-portable.\n await conn.run(`DELETE FROM ${ident(plan.collection)} WHERE id = ${lit(r.id)}`)\n await conn.run(\n `INSERT INTO ${ident(plan.collection)} (id, vec, document, metadata) VALUES (` +\n `${lit(r.id)}, ${vectorLiteral(vector)}, ${doc}, ${lit(meta)}::JSON)`\n )\n }\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 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 rows = await this.#rows(\n `SELECT vec FROM ${ident(plan.collection)} WHERE id = ${lit(plan.near.id)}`\n )\n if (rows.length === 0) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n queryVector = this.#unwrapVector(rows[0][0])\n }\n }\n\n const offset = plan.offset ?? 0\n try {\n if (queryVector) {\n // Compute distance in DuckDB (vss), then apply the neutral filter with the JS\n // reference evaluator before sorting + limiting — so similarity + filter semantics\n // exactly match every other adapter. DuckDB scans are fast at the in-process scale.\n const fn = distanceFn(metric)\n const distExpr = `${fn}(vec, ${vectorLiteral(queryVector)})`\n const rows = await this.#rows(\n `SELECT id, vec, document, metadata, ${distExpr} AS __dist FROM ${ident(plan.collection)}`\n )\n const filtered = plan.filter\n ? rows.filter((row) => evaluateFilter(plan.filter!, this.#parseMeta(row[3])))\n : rows\n filtered.sort((a, b) => Number(a[4]) - Number(b[4]))\n return filtered\n .slice(offset, offset + plan.topK)\n .map((row) => this.#project(row, plan, metric, true))\n } else {\n // Filter-scan: no similarity, just the neutral filter (JS evaluator) + limit.\n const rows = await this.#rows(\n `SELECT id, vec, document, metadata, NULL AS __dist FROM ${ident(plan.collection)}`\n )\n const filtered = plan.filter\n ? rows.filter((row) => evaluateFilter(plan.filter!, this.#parseMeta(row[3])))\n : rows\n return filtered\n .slice(offset, offset + plan.topK)\n .map((row) => this.#project(row, plan, metric, false))\n }\n } catch (err) {\n throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)])\n }\n }\n\n #unwrapVector(val: unknown): number[] {\n // DuckDB FLOAT[] comes back as { items: number[] } via node-api.\n if (val && typeof val === 'object' && Array.isArray((val as any).items)) {\n return (val as any).items as number[]\n }\n if (Array.isArray(val)) return val as number[]\n return []\n }\n\n #parseMeta(val: unknown): VectorMetadata {\n if (val === null || val === undefined) return {}\n if (typeof val === 'string') {\n try {\n return JSON.parse(val) as VectorMetadata\n } catch {\n return {}\n }\n }\n if (typeof val === 'object') return val as VectorMetadata\n return {}\n }\n\n #project(row: any[], plan: SearchPlan, metric: string, isKnn: boolean): VectorMatch {\n // Row order: id, vec, document, metadata, __dist\n const [id, vec, document, metadata, dist] = row\n const proj = plan.projection\n const out: VectorMatch = {}\n if (proj.id) out.id = id as string\n if (proj.vector) out.vector = this.#unwrapVector(vec)\n if (proj.document) out.document = (document ?? undefined) as string | undefined\n if (proj.metadata) out.metadata = this.#parseMeta(metadata)\n if (isKnn && dist !== null && dist !== undefined) {\n out.score = normalizeScore(Number(dist), metric as DistanceMetric, 'distance')\n }\n return out\n }\n\n async executeDelete(plan: DeletePlan): Promise<void> {\n const conn = await this.#ensure()\n try {\n if (plan.ids && plan.ids.length > 0) {\n const list = plan.ids.map((id) => lit(id)).join(', ')\n await conn.run(`DELETE FROM ${ident(plan.collection)} WHERE id IN (${list})`)\n } else if (plan.filter) {\n // Resolve target ids in JS via the reference evaluator, then delete by id.\n const rows = await this.#rows(`SELECT id, metadata FROM ${ident(plan.collection)}`)\n const targets = rows\n .filter((row) => evaluateFilter(plan.filter!, this.#parseMeta(row[1])))\n .map((row) => row[0] as string)\n if (targets.length > 0) {\n const list = targets.map((id) => lit(id)).join(', ')\n await conn.run(`DELETE FROM ${ident(plan.collection)} WHERE id IN (${list})`)\n }\n } else {\n await conn.run(`DELETE FROM ${ident(plan.collection)}`)\n }\n } catch (err) {\n throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"duckdb.cjs","names":["#opts","#conn","#instance","#ensure","#rows","#dims","#unwrapVector","#parseMeta","#project"],"sources":["../../../src/batteries/vector/duckdb/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/duckdb\n *\n * In-process DuckDB adapter (like sqlite_vec — no server). Uses the `vss` community\n * extension for vector distance functions over a `FLOAT[N]` column; metadata lives in a\n * `JSON` column filtered with DuckDB's `json_extract*` functions. Each collection is a\n * table; the document and id are plain columns.\n *\n * Driver: `@duckdb/node-api` (promise-based). Path defaults to `:memory:`.\n */\n\nimport { evaluateFilter } from '../filters'\nimport { normalizeScore } from '../helpers'\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 DistanceMetric,\n} from '../types'\n\nexport interface DuckDBVectorStoreOptions extends BaseVectorStoreOptions {\n /** Connection and authentication parameters for the backend. */\n connection?: { path?: string }\n}\n\nconst getDuckDB = async () => {\n try {\n const mod = await import('@duckdb/node-api')\n return mod.DuckDBInstance\n } catch {\n throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(['@duckdb/node-api'])\n }\n}\n\n// DuckDB vss distance function per metric (all return a distance — lower is closer).\nconst distanceFn = (metric: DistanceMetric): string =>\n metric === 'euclidean'\n ? 'array_distance'\n : metric === 'dot'\n ? 'array_negative_inner_product'\n : 'array_cosine_distance'\n\n// A double-quoted SQL identifier (table/column), escaping embedded quotes.\nconst ident = (name: string): string => `\"${name.replace(/\"/g, '\"\"')}\"`\n\n// A single-quoted SQL string literal, escaping embedded quotes.\nconst lit = (value: string): string => `'${value.replace(/'/g, \"''\")}'`\n\n// Render a number[] as a DuckDB FLOAT[N] array literal: [1.0, 2.0, ...]::FLOAT[N].\nconst vectorLiteral = (vector: number[]): string =>\n `[${vector.map((n) => (Number.isFinite(n) ? String(n) : '0')).join(', ')}]::FLOAT[${vector.length}]`\n\nexport class DuckDBVectorStore extends BaseVectorStore {\n readonly capabilities: VectorStoreCapabilities = {\n transactions: true,\n namedVectors: false,\n rename: true,\n rawSql: true,\n builtInEncoding: false,\n // In-process and synchronous: a write is visible on resolve. The option is a no-op.\n consistency: { configurable: false, default: 'strong', modes: ['strong'] },\n }\n\n #instance: any | null = null\n #conn: any | null = null\n #dims: Map<string, number> = new Map()\n\n get #opts(): DuckDBVectorStoreOptions {\n return this.options as DuckDBVectorStoreOptions\n }\n\n /** Static availability probe: whether this adapter's runtime driver can load in the current environment. */\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.#conn) return\n const DuckDBInstance = await getDuckDB()\n const path = this.#opts.connection?.path ?? ':memory:'\n try {\n this.#instance = await DuckDBInstance.create(path)\n this.#conn = await this.#instance.connect()\n // vss provides the array_*_distance vector functions.\n await this.#conn.run('INSTALL vss;')\n await this.#conn.run('LOAD vss;')\n } catch (err) {\n throw new E_VECTOR_STORE_CONNECTION_FAILED([String(err)])\n }\n }\n\n async close(): Promise<void> {\n // @duckdb/node-api connections are GC-managed; drop references.\n this.#conn = null\n this.#instance = null\n }\n\n async #ensure(): Promise<any> {\n if (!this.#conn) await this.connect()\n return this.#conn!\n }\n\n async #rows(sql: string): Promise<any[][]> {\n const conn = await this.#ensure()\n const reader = await conn.runAndReadAll(sql)\n return reader.getRows()\n }\n\n async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n const conn = await this.#ensure()\n this.#dims.set(spec.collection, spec.vector.dimensions)\n const ine = ifNotExists ? 'IF NOT EXISTS ' : ''\n try {\n await conn.run(\n `CREATE TABLE ${ine}${ident(spec.collection)} (` +\n `id VARCHAR PRIMARY KEY, ` +\n `vec FLOAT[${spec.vector.dimensions}], ` +\n `document VARCHAR, ` +\n `metadata JSON)`\n )\n } catch (err) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['createCollection', String(err)])\n }\n }\n\n async dropCollection(collection: string, ifExists: boolean): Promise<void> {\n const conn = await this.#ensure()\n const ie = ifExists ? 'IF EXISTS ' : ''\n try {\n await conn.run(`DROP TABLE ${ie}${ident(collection)}`)\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 rows = await this.#rows(\n `SELECT 1 FROM information_schema.tables WHERE table_name = ${lit(collection)}`\n )\n return rows.length > 0\n }\n\n async renameCollection(from: string, to: string): Promise<void> {\n const conn = await this.#ensure()\n try {\n await conn.run(`ALTER TABLE ${ident(from)} RENAME TO ${ident(to)}`)\n const d = this.#dims.get(from)\n if (d !== undefined) {\n this.#dims.set(to, d)\n this.#dims.delete(from)\n }\n } catch (err) {\n throw new E_VECTOR_STORE_UNSUPPORTED_OPERATION(['renameCollection', String(err)])\n }\n }\n\n async executeUpsert(plan: UpsertPlan): Promise<void> {\n if (plan.records.length === 0) return\n validateRecords(plan.records)\n const conn = await this.#ensure()\n const expected = this.#opts.dimensions ?? this.#dims.get(plan.collection)\n try {\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 meta = r.metadata ? JSON.stringify(r.metadata) : '{}'\n const doc = r.document === undefined ? 'NULL' : lit(r.document)\n // DuckDB upsert: delete-then-insert keeps it simple and dialect-portable.\n await conn.run(`DELETE FROM ${ident(plan.collection)} WHERE id = ${lit(r.id)}`)\n await conn.run(\n `INSERT INTO ${ident(plan.collection)} (id, vec, document, metadata) VALUES (` +\n `${lit(r.id)}, ${vectorLiteral(vector)}, ${doc}, ${lit(meta)}::JSON)`\n )\n }\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 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 rows = await this.#rows(\n `SELECT vec FROM ${ident(plan.collection)} WHERE id = ${lit(plan.near.id)}`\n )\n if (rows.length === 0) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n queryVector = this.#unwrapVector(rows[0][0])\n }\n }\n\n const offset = plan.offset ?? 0\n try {\n if (queryVector) {\n // Compute distance in DuckDB (vss), then apply the neutral filter with the JS\n // reference evaluator before sorting + limiting — so similarity + filter semantics\n // exactly match every other adapter. DuckDB scans are fast at the in-process scale.\n const fn = distanceFn(metric)\n const distExpr = `${fn}(vec, ${vectorLiteral(queryVector)})`\n const rows = await this.#rows(\n `SELECT id, vec, document, metadata, ${distExpr} AS __dist FROM ${ident(plan.collection)}`\n )\n const filtered = plan.filter\n ? rows.filter((row) => evaluateFilter(plan.filter!, this.#parseMeta(row[3])))\n : rows\n filtered.sort((a, b) => Number(a[4]) - Number(b[4]))\n return filtered\n .slice(offset, offset + plan.topK)\n .map((row) => this.#project(row, plan, metric, true))\n } else {\n // Filter-scan: no similarity, just the neutral filter (JS evaluator) + limit.\n const rows = await this.#rows(\n `SELECT id, vec, document, metadata, NULL AS __dist FROM ${ident(plan.collection)}`\n )\n const filtered = plan.filter\n ? rows.filter((row) => evaluateFilter(plan.filter!, this.#parseMeta(row[3])))\n : rows\n return filtered\n .slice(offset, offset + plan.topK)\n .map((row) => this.#project(row, plan, metric, false))\n }\n } catch (err) {\n throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)])\n }\n }\n\n #unwrapVector(val: unknown): number[] {\n // DuckDB FLOAT[] comes back as { items: number[] } via node-api.\n if (val && typeof val === 'object' && Array.isArray((val as any).items)) {\n return (val as any).items as number[]\n }\n if (Array.isArray(val)) return val as number[]\n return []\n }\n\n #parseMeta(val: unknown): VectorMetadata {\n if (val === null || val === undefined) return {}\n if (typeof val === 'string') {\n try {\n return JSON.parse(val) as VectorMetadata\n } catch {\n return {}\n }\n }\n if (typeof val === 'object') return val as VectorMetadata\n return {}\n }\n\n #project(row: any[], plan: SearchPlan, metric: string, isKnn: boolean): VectorMatch {\n // Row order: id, vec, document, metadata, __dist\n const [id, vec, document, metadata, dist] = row\n const proj = plan.projection\n const out: VectorMatch = {}\n if (proj.id) out.id = id as string\n if (proj.vector) out.vector = this.#unwrapVector(vec)\n if (proj.document) out.document = (document ?? undefined) as string | undefined\n if (proj.metadata) out.metadata = this.#parseMeta(metadata)\n if (isKnn && dist !== null && dist !== undefined) {\n out.score = normalizeScore(Number(dist), metric as DistanceMetric, 'distance')\n }\n return out\n }\n\n async executeDelete(plan: DeletePlan): Promise<void> {\n const conn = await this.#ensure()\n try {\n if (plan.ids && plan.ids.length > 0) {\n const list = plan.ids.map((id) => lit(id)).join(', ')\n await conn.run(`DELETE FROM ${ident(plan.collection)} WHERE id IN (${list})`)\n } else if (plan.filter) {\n // Resolve target ids in JS via the reference evaluator, then delete by id.\n const rows = await this.#rows(`SELECT id, metadata FROM ${ident(plan.collection)}`)\n const targets = rows\n .filter((row) => evaluateFilter(plan.filter!, this.#parseMeta(row[1])))\n .map((row) => row[0] as string)\n if (targets.length > 0) {\n const list = targets.map((id) => lit(id)).join(', ')\n await conn.run(`DELETE FROM ${ident(plan.collection)} WHERE id IN (${list})`)\n }\n } else {\n await conn.run(`DELETE FROM ${ident(plan.collection)}`)\n }\n } catch (err) {\n throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { s as isInstanceOf } from "../../tool_registry-
|
|
1
|
+
import { s as isInstanceOf } from "../../tool_registry-791Vrjtf.mjs";
|
|
2
2
|
import "../../guards.mjs";
|
|
3
3
|
import { evaluateFilter } from "./filters.mjs";
|
|
4
4
|
import { normalizeScore } from "./helpers.mjs";
|
|
@@ -46,6 +46,7 @@ var DuckDBVectorStore = class extends BaseVectorStore {
|
|
|
46
46
|
get #opts() {
|
|
47
47
|
return this.options;
|
|
48
48
|
}
|
|
49
|
+
/** Static availability probe: whether this adapter's runtime driver can load in the current environment. */
|
|
49
50
|
static isAvailable() {
|
|
50
51
|
return typeof process !== "undefined";
|
|
51
52
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"duckdb.mjs","names":["#opts","#conn","#instance","#ensure","#rows","#dims","#unwrapVector","#parseMeta","#project"],"sources":["../../../src/batteries/vector/duckdb/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/duckdb\n *\n * In-process DuckDB adapter (like sqlite_vec — no server). Uses the `vss` community\n * extension for vector distance functions over a `FLOAT[N]` column; metadata lives in a\n * `JSON` column filtered with DuckDB's `json_extract*` functions. Each collection is a\n * table; the document and id are plain columns.\n *\n * Driver: `@duckdb/node-api` (promise-based). Path defaults to `:memory:`.\n */\n\nimport { evaluateFilter } from '../filters'\nimport { normalizeScore } from '../helpers'\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 DistanceMetric,\n} from '../types'\n\nexport interface DuckDBVectorStoreOptions extends BaseVectorStoreOptions {\n connection?: { path?: string }\n}\n\nconst getDuckDB = async () => {\n try {\n const mod = await import('@duckdb/node-api')\n return mod.DuckDBInstance\n } catch {\n throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(['@duckdb/node-api'])\n }\n}\n\n// DuckDB vss distance function per metric (all return a distance — lower is closer).\nconst distanceFn = (metric: DistanceMetric): string =>\n metric === 'euclidean'\n ? 'array_distance'\n : metric === 'dot'\n ? 'array_negative_inner_product'\n : 'array_cosine_distance'\n\n// A double-quoted SQL identifier (table/column), escaping embedded quotes.\nconst ident = (name: string): string => `\"${name.replace(/\"/g, '\"\"')}\"`\n\n// A single-quoted SQL string literal, escaping embedded quotes.\nconst lit = (value: string): string => `'${value.replace(/'/g, \"''\")}'`\n\n// Render a number[] as a DuckDB FLOAT[N] array literal: [1.0, 2.0, ...]::FLOAT[N].\nconst vectorLiteral = (vector: number[]): string =>\n `[${vector.map((n) => (Number.isFinite(n) ? String(n) : '0')).join(', ')}]::FLOAT[${vector.length}]`\n\nexport class DuckDBVectorStore extends BaseVectorStore {\n readonly capabilities: VectorStoreCapabilities = {\n transactions: true,\n namedVectors: false,\n rename: true,\n rawSql: true,\n builtInEncoding: false,\n // In-process and synchronous: a write is visible on resolve. The option is a no-op.\n consistency: { configurable: false, default: 'strong', modes: ['strong'] },\n }\n\n #instance: any | null = null\n #conn: any | null = null\n #dims: Map<string, number> = new Map()\n\n get #opts(): DuckDBVectorStoreOptions {\n return this.options as DuckDBVectorStoreOptions\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.#conn) return\n const DuckDBInstance = await getDuckDB()\n const path = this.#opts.connection?.path ?? ':memory:'\n try {\n this.#instance = await DuckDBInstance.create(path)\n this.#conn = await this.#instance.connect()\n // vss provides the array_*_distance vector functions.\n await this.#conn.run('INSTALL vss;')\n await this.#conn.run('LOAD vss;')\n } catch (err) {\n throw new E_VECTOR_STORE_CONNECTION_FAILED([String(err)])\n }\n }\n\n async close(): Promise<void> {\n // @duckdb/node-api connections are GC-managed; drop references.\n this.#conn = null\n this.#instance = null\n }\n\n async #ensure(): Promise<any> {\n if (!this.#conn) await this.connect()\n return this.#conn!\n }\n\n async #rows(sql: string): Promise<any[][]> {\n const conn = await this.#ensure()\n const reader = await conn.runAndReadAll(sql)\n return reader.getRows()\n }\n\n async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n const conn = await this.#ensure()\n this.#dims.set(spec.collection, spec.vector.dimensions)\n const ine = ifNotExists ? 'IF NOT EXISTS ' : ''\n try {\n await conn.run(\n `CREATE TABLE ${ine}${ident(spec.collection)} (` +\n `id VARCHAR PRIMARY KEY, ` +\n `vec FLOAT[${spec.vector.dimensions}], ` +\n `document VARCHAR, ` +\n `metadata JSON)`\n )\n } catch (err) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['createCollection', String(err)])\n }\n }\n\n async dropCollection(collection: string, ifExists: boolean): Promise<void> {\n const conn = await this.#ensure()\n const ie = ifExists ? 'IF EXISTS ' : ''\n try {\n await conn.run(`DROP TABLE ${ie}${ident(collection)}`)\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 rows = await this.#rows(\n `SELECT 1 FROM information_schema.tables WHERE table_name = ${lit(collection)}`\n )\n return rows.length > 0\n }\n\n async renameCollection(from: string, to: string): Promise<void> {\n const conn = await this.#ensure()\n try {\n await conn.run(`ALTER TABLE ${ident(from)} RENAME TO ${ident(to)}`)\n const d = this.#dims.get(from)\n if (d !== undefined) {\n this.#dims.set(to, d)\n this.#dims.delete(from)\n }\n } catch (err) {\n throw new E_VECTOR_STORE_UNSUPPORTED_OPERATION(['renameCollection', String(err)])\n }\n }\n\n async executeUpsert(plan: UpsertPlan): Promise<void> {\n if (plan.records.length === 0) return\n validateRecords(plan.records)\n const conn = await this.#ensure()\n const expected = this.#opts.dimensions ?? this.#dims.get(plan.collection)\n try {\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 meta = r.metadata ? JSON.stringify(r.metadata) : '{}'\n const doc = r.document === undefined ? 'NULL' : lit(r.document)\n // DuckDB upsert: delete-then-insert keeps it simple and dialect-portable.\n await conn.run(`DELETE FROM ${ident(plan.collection)} WHERE id = ${lit(r.id)}`)\n await conn.run(\n `INSERT INTO ${ident(plan.collection)} (id, vec, document, metadata) VALUES (` +\n `${lit(r.id)}, ${vectorLiteral(vector)}, ${doc}, ${lit(meta)}::JSON)`\n )\n }\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 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 rows = await this.#rows(\n `SELECT vec FROM ${ident(plan.collection)} WHERE id = ${lit(plan.near.id)}`\n )\n if (rows.length === 0) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n queryVector = this.#unwrapVector(rows[0][0])\n }\n }\n\n const offset = plan.offset ?? 0\n try {\n if (queryVector) {\n // Compute distance in DuckDB (vss), then apply the neutral filter with the JS\n // reference evaluator before sorting + limiting — so similarity + filter semantics\n // exactly match every other adapter. DuckDB scans are fast at the in-process scale.\n const fn = distanceFn(metric)\n const distExpr = `${fn}(vec, ${vectorLiteral(queryVector)})`\n const rows = await this.#rows(\n `SELECT id, vec, document, metadata, ${distExpr} AS __dist FROM ${ident(plan.collection)}`\n )\n const filtered = plan.filter\n ? rows.filter((row) => evaluateFilter(plan.filter!, this.#parseMeta(row[3])))\n : rows\n filtered.sort((a, b) => Number(a[4]) - Number(b[4]))\n return filtered\n .slice(offset, offset + plan.topK)\n .map((row) => this.#project(row, plan, metric, true))\n } else {\n // Filter-scan: no similarity, just the neutral filter (JS evaluator) + limit.\n const rows = await this.#rows(\n `SELECT id, vec, document, metadata, NULL AS __dist FROM ${ident(plan.collection)}`\n )\n const filtered = plan.filter\n ? rows.filter((row) => evaluateFilter(plan.filter!, this.#parseMeta(row[3])))\n : rows\n return filtered\n .slice(offset, offset + plan.topK)\n .map((row) => this.#project(row, plan, metric, false))\n }\n } catch (err) {\n throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)])\n }\n }\n\n #unwrapVector(val: unknown): number[] {\n // DuckDB FLOAT[] comes back as { items: number[] } via node-api.\n if (val && typeof val === 'object' && Array.isArray((val as any).items)) {\n return (val as any).items as number[]\n }\n if (Array.isArray(val)) return val as number[]\n return []\n }\n\n #parseMeta(val: unknown): VectorMetadata {\n if (val === null || val === undefined) return {}\n if (typeof val === 'string') {\n try {\n return JSON.parse(val) as VectorMetadata\n } catch {\n return {}\n }\n }\n if (typeof val === 'object') return val as VectorMetadata\n return {}\n }\n\n #project(row: any[], plan: SearchPlan, metric: string, isKnn: boolean): VectorMatch {\n // Row order: id, vec, document, metadata, __dist\n const [id, vec, document, metadata, dist] = row\n const proj = plan.projection\n const out: VectorMatch = {}\n if (proj.id) out.id = id as string\n if (proj.vector) out.vector = this.#unwrapVector(vec)\n if (proj.document) out.document = (document ?? undefined) as string | undefined\n if (proj.metadata) out.metadata = this.#parseMeta(metadata)\n if (isKnn && dist !== null && dist !== undefined) {\n out.score = normalizeScore(Number(dist), metric as DistanceMetric, 'distance')\n }\n return out\n }\n\n async executeDelete(plan: DeletePlan): Promise<void> {\n const conn = await this.#ensure()\n try {\n if (plan.ids && plan.ids.length > 0) {\n const list = plan.ids.map((id) => lit(id)).join(', ')\n await conn.run(`DELETE FROM ${ident(plan.collection)} WHERE id IN (${list})`)\n } else if (plan.filter) {\n // Resolve target ids in JS via the reference evaluator, then delete by id.\n const rows = await this.#rows(`SELECT id, metadata FROM ${ident(plan.collection)}`)\n const targets = rows\n .filter((row) => evaluateFilter(plan.filter!, this.#parseMeta(row[1])))\n .map((row) => row[0] as string)\n if (targets.length > 0) {\n const list = targets.map((id) => lit(id)).join(', ')\n await conn.run(`DELETE FROM ${ident(plan.collection)} WHERE id IN (${list})`)\n }\n } else {\n await conn.run(`DELETE FROM ${ident(plan.collection)}`)\n }\n } catch (err) {\n throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"duckdb.mjs","names":["#opts","#conn","#instance","#ensure","#rows","#dims","#unwrapVector","#parseMeta","#project"],"sources":["../../../src/batteries/vector/duckdb/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/duckdb\n *\n * In-process DuckDB adapter (like sqlite_vec — no server). Uses the `vss` community\n * extension for vector distance functions over a `FLOAT[N]` column; metadata lives in a\n * `JSON` column filtered with DuckDB's `json_extract*` functions. Each collection is a\n * table; the document and id are plain columns.\n *\n * Driver: `@duckdb/node-api` (promise-based). Path defaults to `:memory:`.\n */\n\nimport { evaluateFilter } from '../filters'\nimport { normalizeScore } from '../helpers'\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 DistanceMetric,\n} from '../types'\n\nexport interface DuckDBVectorStoreOptions extends BaseVectorStoreOptions {\n /** Connection and authentication parameters for the backend. */\n connection?: { path?: string }\n}\n\nconst getDuckDB = async () => {\n try {\n const mod = await import('@duckdb/node-api')\n return mod.DuckDBInstance\n } catch {\n throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(['@duckdb/node-api'])\n }\n}\n\n// DuckDB vss distance function per metric (all return a distance — lower is closer).\nconst distanceFn = (metric: DistanceMetric): string =>\n metric === 'euclidean'\n ? 'array_distance'\n : metric === 'dot'\n ? 'array_negative_inner_product'\n : 'array_cosine_distance'\n\n// A double-quoted SQL identifier (table/column), escaping embedded quotes.\nconst ident = (name: string): string => `\"${name.replace(/\"/g, '\"\"')}\"`\n\n// A single-quoted SQL string literal, escaping embedded quotes.\nconst lit = (value: string): string => `'${value.replace(/'/g, \"''\")}'`\n\n// Render a number[] as a DuckDB FLOAT[N] array literal: [1.0, 2.0, ...]::FLOAT[N].\nconst vectorLiteral = (vector: number[]): string =>\n `[${vector.map((n) => (Number.isFinite(n) ? String(n) : '0')).join(', ')}]::FLOAT[${vector.length}]`\n\nexport class DuckDBVectorStore extends BaseVectorStore {\n readonly capabilities: VectorStoreCapabilities = {\n transactions: true,\n namedVectors: false,\n rename: true,\n rawSql: true,\n builtInEncoding: false,\n // In-process and synchronous: a write is visible on resolve. The option is a no-op.\n consistency: { configurable: false, default: 'strong', modes: ['strong'] },\n }\n\n #instance: any | null = null\n #conn: any | null = null\n #dims: Map<string, number> = new Map()\n\n get #opts(): DuckDBVectorStoreOptions {\n return this.options as DuckDBVectorStoreOptions\n }\n\n /** Static availability probe: whether this adapter's runtime driver can load in the current environment. */\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.#conn) return\n const DuckDBInstance = await getDuckDB()\n const path = this.#opts.connection?.path ?? ':memory:'\n try {\n this.#instance = await DuckDBInstance.create(path)\n this.#conn = await this.#instance.connect()\n // vss provides the array_*_distance vector functions.\n await this.#conn.run('INSTALL vss;')\n await this.#conn.run('LOAD vss;')\n } catch (err) {\n throw new E_VECTOR_STORE_CONNECTION_FAILED([String(err)])\n }\n }\n\n async close(): Promise<void> {\n // @duckdb/node-api connections are GC-managed; drop references.\n this.#conn = null\n this.#instance = null\n }\n\n async #ensure(): Promise<any> {\n if (!this.#conn) await this.connect()\n return this.#conn!\n }\n\n async #rows(sql: string): Promise<any[][]> {\n const conn = await this.#ensure()\n const reader = await conn.runAndReadAll(sql)\n return reader.getRows()\n }\n\n async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n const conn = await this.#ensure()\n this.#dims.set(spec.collection, spec.vector.dimensions)\n const ine = ifNotExists ? 'IF NOT EXISTS ' : ''\n try {\n await conn.run(\n `CREATE TABLE ${ine}${ident(spec.collection)} (` +\n `id VARCHAR PRIMARY KEY, ` +\n `vec FLOAT[${spec.vector.dimensions}], ` +\n `document VARCHAR, ` +\n `metadata JSON)`\n )\n } catch (err) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['createCollection', String(err)])\n }\n }\n\n async dropCollection(collection: string, ifExists: boolean): Promise<void> {\n const conn = await this.#ensure()\n const ie = ifExists ? 'IF EXISTS ' : ''\n try {\n await conn.run(`DROP TABLE ${ie}${ident(collection)}`)\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 rows = await this.#rows(\n `SELECT 1 FROM information_schema.tables WHERE table_name = ${lit(collection)}`\n )\n return rows.length > 0\n }\n\n async renameCollection(from: string, to: string): Promise<void> {\n const conn = await this.#ensure()\n try {\n await conn.run(`ALTER TABLE ${ident(from)} RENAME TO ${ident(to)}`)\n const d = this.#dims.get(from)\n if (d !== undefined) {\n this.#dims.set(to, d)\n this.#dims.delete(from)\n }\n } catch (err) {\n throw new E_VECTOR_STORE_UNSUPPORTED_OPERATION(['renameCollection', String(err)])\n }\n }\n\n async executeUpsert(plan: UpsertPlan): Promise<void> {\n if (plan.records.length === 0) return\n validateRecords(plan.records)\n const conn = await this.#ensure()\n const expected = this.#opts.dimensions ?? this.#dims.get(plan.collection)\n try {\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 meta = r.metadata ? JSON.stringify(r.metadata) : '{}'\n const doc = r.document === undefined ? 'NULL' : lit(r.document)\n // DuckDB upsert: delete-then-insert keeps it simple and dialect-portable.\n await conn.run(`DELETE FROM ${ident(plan.collection)} WHERE id = ${lit(r.id)}`)\n await conn.run(\n `INSERT INTO ${ident(plan.collection)} (id, vec, document, metadata) VALUES (` +\n `${lit(r.id)}, ${vectorLiteral(vector)}, ${doc}, ${lit(meta)}::JSON)`\n )\n }\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 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 rows = await this.#rows(\n `SELECT vec FROM ${ident(plan.collection)} WHERE id = ${lit(plan.near.id)}`\n )\n if (rows.length === 0) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n queryVector = this.#unwrapVector(rows[0][0])\n }\n }\n\n const offset = plan.offset ?? 0\n try {\n if (queryVector) {\n // Compute distance in DuckDB (vss), then apply the neutral filter with the JS\n // reference evaluator before sorting + limiting — so similarity + filter semantics\n // exactly match every other adapter. DuckDB scans are fast at the in-process scale.\n const fn = distanceFn(metric)\n const distExpr = `${fn}(vec, ${vectorLiteral(queryVector)})`\n const rows = await this.#rows(\n `SELECT id, vec, document, metadata, ${distExpr} AS __dist FROM ${ident(plan.collection)}`\n )\n const filtered = plan.filter\n ? rows.filter((row) => evaluateFilter(plan.filter!, this.#parseMeta(row[3])))\n : rows\n filtered.sort((a, b) => Number(a[4]) - Number(b[4]))\n return filtered\n .slice(offset, offset + plan.topK)\n .map((row) => this.#project(row, plan, metric, true))\n } else {\n // Filter-scan: no similarity, just the neutral filter (JS evaluator) + limit.\n const rows = await this.#rows(\n `SELECT id, vec, document, metadata, NULL AS __dist FROM ${ident(plan.collection)}`\n )\n const filtered = plan.filter\n ? rows.filter((row) => evaluateFilter(plan.filter!, this.#parseMeta(row[3])))\n : rows\n return filtered\n .slice(offset, offset + plan.topK)\n .map((row) => this.#project(row, plan, metric, false))\n }\n } catch (err) {\n throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)])\n }\n }\n\n #unwrapVector(val: unknown): number[] {\n // DuckDB FLOAT[] comes back as { items: number[] } via node-api.\n if (val && typeof val === 'object' && Array.isArray((val as any).items)) {\n return (val as any).items as number[]\n }\n if (Array.isArray(val)) return val as number[]\n return []\n }\n\n #parseMeta(val: unknown): VectorMetadata {\n if (val === null || val === undefined) return {}\n if (typeof val === 'string') {\n try {\n return JSON.parse(val) as VectorMetadata\n } catch {\n return {}\n }\n }\n if (typeof val === 'object') return val as VectorMetadata\n return {}\n }\n\n #project(row: any[], plan: SearchPlan, metric: string, isKnn: boolean): VectorMatch {\n // Row order: id, vec, document, metadata, __dist\n const [id, vec, document, metadata, dist] = row\n const proj = plan.projection\n const out: VectorMatch = {}\n if (proj.id) out.id = id as string\n if (proj.vector) out.vector = this.#unwrapVector(vec)\n if (proj.document) out.document = (document ?? undefined) as string | undefined\n if (proj.metadata) out.metadata = this.#parseMeta(metadata)\n if (isKnn && dist !== null && dist !== undefined) {\n out.score = normalizeScore(Number(dist), metric as DistanceMetric, 'distance')\n }\n return out\n }\n\n async executeDelete(plan: DeletePlan): Promise<void> {\n const conn = await this.#ensure()\n try {\n if (plan.ids && plan.ids.length > 0) {\n const list = plan.ids.map((id) => lit(id)).join(', ')\n await conn.run(`DELETE FROM ${ident(plan.collection)} WHERE id IN (${list})`)\n } else if (plan.filter) {\n // Resolve target ids in JS via the reference evaluator, then delete by id.\n const rows = await this.#rows(`SELECT id, metadata FROM ${ident(plan.collection)}`)\n const targets = rows\n .filter((row) => evaluateFilter(plan.filter!, this.#parseMeta(row[1])))\n .map((row) => row[0] as string)\n if (targets.length > 0) {\n const list = targets.map((id) => lit(id)).join(', ')\n await conn.run(`DELETE FROM ${ident(plan.collection)} WHERE id IN (${list})`)\n }\n } else {\n await conn.run(`DELETE FROM ${ident(plan.collection)}`)\n }\n } catch (err) {\n throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ import type { VectorFilter } from "../filters";
|
|
|
10
10
|
import type { SearchPlan, UpsertPlan, DeletePlan, CollectionSpec } from "../plan";
|
|
11
11
|
import type { VectorMatch, VectorStoreCapabilities, BaseVectorStoreOptions } from "../types";
|
|
12
12
|
export interface ElasticsearchVectorStoreOptions extends BaseVectorStoreOptions {
|
|
13
|
+
/** Connection and authentication parameters for the backend. */
|
|
13
14
|
connection?: {
|
|
14
15
|
node?: string;
|
|
15
16
|
auth?: {
|
|
@@ -29,6 +30,7 @@ export declare const translateElasticsearchFilter: (filter?: VectorFilter) => Re
|
|
|
29
30
|
export declare class ElasticsearchVectorStore extends BaseVectorStore {
|
|
30
31
|
#private;
|
|
31
32
|
readonly capabilities: VectorStoreCapabilities;
|
|
33
|
+
/** Static availability probe: whether this adapter's runtime driver can load in the current environment. */
|
|
32
34
|
static isAvailable(): boolean;
|
|
33
35
|
isAvailable(): boolean;
|
|
34
36
|
connect(): Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("../../chunk-Ble4zEEl.js");
|
|
3
|
-
const require_tool_registry = require("../../tool_registry-
|
|
3
|
+
const require_tool_registry = require("../../tool_registry-CKJPze3j.js");
|
|
4
4
|
require("../../guards.cjs");
|
|
5
5
|
const require_batteries_vector_filters = require("./filters.cjs");
|
|
6
6
|
const require_batteries_vector_helpers = require("./helpers.cjs");
|
|
@@ -88,6 +88,7 @@ var ElasticsearchVectorStore = class extends require_batteries_vector_contract.B
|
|
|
88
88
|
get #opts() {
|
|
89
89
|
return this.options;
|
|
90
90
|
}
|
|
91
|
+
/** Static availability probe: whether this adapter's runtime driver can load in the current environment. */
|
|
91
92
|
static isAvailable() {
|
|
92
93
|
return typeof process !== "undefined";
|
|
93
94
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elasticsearch.cjs","names":["#opts","#client","#ensure","#dims","#body","#project"],"sources":["../../../src/batteries/vector/elasticsearch/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/elasticsearch\n *\n * Elasticsearch 8 adapter — each collection is an index with a `dense_vector` field; KNN uses ES8's\n * top-level `knn` search clause with an optional `filter`; the neutral filter tree compiles to bool/term/range\n * over `metadata.*`. Distinct from the opensearch adapter (which speaks OpenSearch's `knn_vector`/`query.knn` dialect).\n */\n\nimport { normalizeScore } from '../helpers'\nimport { BaseVectorStore } from '../contract'\nimport { validateRecords } from '../validation'\nimport { isInstanceOf } from '@nhtio/adk/guards'\nimport { isFilterCondition, isRawFilter, isFilterGroup } from '../filters'\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 E_VECTOR_STORE_UNSUPPORTED_FILTER_OPERATOR,\n} from '../exceptions'\nimport type { VectorFilter } from '../filters'\nimport type { SearchPlan, UpsertPlan, DeletePlan, CollectionSpec } from '../plan'\nimport type {\n VectorMatch,\n VectorStoreCapabilities,\n BaseVectorStoreOptions,\n VectorMetadata,\n DistanceMetric,\n} from '../types'\n\nexport interface ElasticsearchVectorStoreOptions extends BaseVectorStoreOptions {\n connection?: {\n node?: string // default 'http://localhost:9200'\n auth?: { username: string; password: string } | { apiKey: string }\n client?: unknown // BYO @elastic/elasticsearch Client; overrides node\n }\n}\n\nconst getElasticsearchClient = async () => {\n try {\n const mod = await import('@elastic/elasticsearch')\n return mod.Client\n } catch {\n throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(['@elastic/elasticsearch'])\n }\n}\n\n// Elasticsearch similarity per metric.\nconst similarity = (metric: DistanceMetric): string =>\n metric === 'cosine' ? 'cosine' : metric === 'dot' ? 'dot_product' : 'l2_norm'\n\n/**\n * Compile the neutral filter tree to an Elasticsearch bool-query clause over `metadata.*`.\n * String values use the `.keyword` sub-field for exact match; numbers use range/term.\n */\nexport const translateElasticsearchFilter = (\n filter?: VectorFilter\n): Record<string, unknown> | undefined => {\n if (!filter) return undefined\n if (isRawFilter(filter)) {\n if (filter.$dialect === 'elasticsearch' || filter.$dialect === 'opensearch') {\n return filter.$raw as Record<string, unknown>\n }\n throw new E_VECTOR_STORE_UNSUPPORTED_FILTER_OPERATOR(['elasticsearch', String(filter.$dialect)])\n }\n if (isFilterCondition(filter)) {\n const { field, op, value } = filter\n const f = `metadata.${field}`\n const kw = `metadata.${field}.keyword`\n const term = (v: unknown) =>\n typeof v === 'number' || typeof v === 'boolean' ? { term: { [f]: v } } : { term: { [kw]: v } }\n switch (op) {\n case 'eq':\n return term(value)\n case 'ne':\n return { bool: { must_not: [term(value)] } }\n case 'gt':\n return { range: { [f]: { gt: value } } }\n case 'gte':\n return { range: { [f]: { gte: value } } }\n case 'lt':\n return { range: { [f]: { lt: value } } }\n case 'lte':\n return { range: { [f]: { lte: value } } }\n case 'in': {\n const arr = Array.isArray(value) ? value : [value]\n const allNum = arr.every((v) => typeof v === 'number' || typeof v === 'boolean')\n return { terms: { [allNum ? f : kw]: arr } }\n }\n case 'nin': {\n const arr = Array.isArray(value) ? value : [value]\n const allNum = arr.every((v) => typeof v === 'number' || typeof v === 'boolean')\n return { bool: { must_not: [{ terms: { [allNum ? f : kw]: arr } }] } }\n }\n case 'exists':\n return { exists: { field: f } }\n default:\n throw new E_VECTOR_STORE_UNSUPPORTED_FILTER_OPERATOR(['elasticsearch', op])\n }\n }\n if (isFilterGroup(filter)) {\n const { and, or, not } = filter\n if (and) {\n const must = and.map(translateElasticsearchFilter).filter(Boolean)\n return { bool: { must } }\n }\n if (or) {\n const should = or.map(translateElasticsearchFilter).filter(Boolean)\n return { bool: { should, minimum_should_match: 1 } }\n }\n if (not) {\n const inner = translateElasticsearchFilter(not)\n return inner ? { bool: { must_not: [inner] } } : undefined\n }\n }\n return undefined\n}\n\nexport class ElasticsearchVectorStore extends BaseVectorStore {\n readonly capabilities: VectorStoreCapabilities = {\n transactions: false,\n namedVectors: false,\n rename: false,\n rawSql: false,\n builtInEncoding: false,\n // Made strongly consistent by refreshing the index after every write (refresh: true /\n // explicit _refresh), so a write is visible to the next search. The option is a no-op.\n consistency: { configurable: false, default: 'strong', modes: ['strong'] },\n }\n\n #client: any | null = null\n #dims: Map<string, number> = new Map()\n\n get #opts(): ElasticsearchVectorStoreOptions {\n return this.options as ElasticsearchVectorStoreOptions\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.#client) return\n const c = this.#opts.connection || {}\n if (c.client) {\n this.#client = c.client\n return\n }\n const Client = await getElasticsearchClient()\n try {\n this.#client = new Client({ node: c.node ?? 'http://localhost:9200', auth: c.auth })\n } catch (err) {\n throw new E_VECTOR_STORE_CONNECTION_FAILED([String(err)])\n }\n }\n\n async close(): Promise<void> {\n if (\n this.#client &&\n typeof this.#client.close === 'function' &&\n !this.#opts.connection?.client\n ) {\n await this.#client.close()\n }\n this.#client = null\n }\n\n async #ensure(): Promise<any> {\n if (!this.#client) await this.connect()\n return this.#client!\n }\n\n // Unwrap the {body}/direct response shape across client versions.\n #body(res: any): any {\n return res && res.body !== undefined ? res.body : res\n }\n\n async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n const client = await this.#ensure()\n this.#dims.set(spec.collection, spec.vector.dimensions)\n if (ifNotExists && (await this.hasCollection(spec.collection))) return\n try {\n await client.indices.create({\n index: spec.collection,\n mappings: {\n properties: {\n vec: {\n type: 'dense_vector',\n dims: spec.vector.dimensions,\n index: true,\n similarity: similarity(spec.vector.metric),\n },\n document: { type: 'text' },\n metadata: { type: 'object', enabled: true },\n },\n },\n })\n } catch (err) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['createCollection', String(err)])\n }\n }\n\n async dropCollection(collection: string, ifExists: boolean): Promise<void> {\n const client = await this.#ensure()\n if (ifExists && !(await this.hasCollection(collection))) return\n try {\n await client.indices.delete({ index: collection })\n this.#dims.delete(collection)\n } catch (err) {\n const msg = String(err)\n if (ifExists && msg.includes('index_not_found')) return\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['dropCollection', msg])\n }\n }\n\n async hasCollection(collection: string): Promise<boolean> {\n const client = await this.#ensure()\n try {\n const res = await client.indices.exists({ index: collection })\n const body = this.#body(res)\n return body === true || body === 200 || res?.statusCode === 200\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', 'elasticsearch'])\n }\n\n async executeUpsert(plan: UpsertPlan): Promise<void> {\n if (plan.records.length === 0) return\n validateRecords(plan.records)\n const client = await this.#ensure()\n const expected = this.#opts.dimensions ?? this.#dims.get(plan.collection)\n try {\n const operations: any[] = []\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 operations.push({ index: { _index: plan.collection, _id: r.id } })\n operations.push({ vec: vector, document: r.document ?? '', metadata: r.metadata ?? {} })\n }\n await client.bulk({ operations, refresh: true })\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 client = await this.#ensure()\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 try {\n const res = await client.get({ index: plan.collection, id: plan.near.id })\n queryVector = this.#body(res)?._source?.vec as number[]\n } catch {\n queryVector = undefined\n }\n if (!queryVector) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n }\n }\n\n const filter = translateElasticsearchFilter(plan.filter)\n const size = plan.topK\n const from = plan.offset ?? 0\n try {\n let res: any\n if (queryVector) {\n const knn: any = {\n field: 'vec',\n query_vector: queryVector,\n k: size + from,\n num_candidates: Math.max((size + from) * 10, 100),\n }\n if (filter) knn.filter = filter\n res = await client.search({ index: plan.collection, knn, size, from, _source: true })\n } else {\n res = await client.search({\n index: plan.collection,\n size,\n from,\n query: filter ?? { match_all: {} },\n })\n }\n const hits = this.#body(res)?.hits?.hits ?? []\n return hits.map((hit: any) => this.#project(hit, plan, metric, !!queryVector))\n } catch (err) {\n throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)])\n }\n }\n\n #project(hit: any, plan: SearchPlan, metric: string, isKnn: boolean): VectorMatch {\n const proj = plan.projection\n const src = hit._source ?? {}\n const out: VectorMatch = {}\n if (proj.id) out.id = hit._id as string\n if (proj.vector && src.vec) out.vector = src.vec as number[]\n if (proj.document) out.document = src.document as string | undefined\n if (proj.metadata) out.metadata = (src.metadata ?? {}) as VectorMetadata\n if (isKnn && typeof hit._score === 'number') {\n // Elasticsearch cosine _score is already (sim+1)/2 ∈ [0,1]; normalize defensively to [0,1].\n out.score = normalizeScore(hit._score, metric as DistanceMetric, 'similarity')\n }\n return out\n }\n\n async executeDelete(plan: DeletePlan): Promise<void> {\n const client = await this.#ensure()\n try {\n if (plan.ids && plan.ids.length > 0) {\n const operations = plan.ids.map((id) => ({ delete: { _index: plan.collection, _id: id } }))\n await client.bulk({ operations, refresh: true })\n } else if (plan.filter) {\n const filter = translateElasticsearchFilter(plan.filter)\n await client.deleteByQuery({\n index: plan.collection,\n refresh: true,\n query: filter ?? { match_all: {} },\n })\n } else {\n await client.deleteByQuery({\n index: plan.collection,\n refresh: true,\n query: { match_all: {} },\n })\n }\n } catch (err) {\n throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"elasticsearch.cjs","names":["#opts","#client","#ensure","#dims","#body","#project"],"sources":["../../../src/batteries/vector/elasticsearch/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/elasticsearch\n *\n * Elasticsearch 8 adapter — each collection is an index with a `dense_vector` field; KNN uses ES8's\n * top-level `knn` search clause with an optional `filter`; the neutral filter tree compiles to bool/term/range\n * over `metadata.*`. Distinct from the opensearch adapter (which speaks OpenSearch's `knn_vector`/`query.knn` dialect).\n */\n\nimport { normalizeScore } from '../helpers'\nimport { BaseVectorStore } from '../contract'\nimport { validateRecords } from '../validation'\nimport { isInstanceOf } from '@nhtio/adk/guards'\nimport { isFilterCondition, isRawFilter, isFilterGroup } from '../filters'\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 E_VECTOR_STORE_UNSUPPORTED_FILTER_OPERATOR,\n} from '../exceptions'\nimport type { VectorFilter } from '../filters'\nimport type { SearchPlan, UpsertPlan, DeletePlan, CollectionSpec } from '../plan'\nimport type {\n VectorMatch,\n VectorStoreCapabilities,\n BaseVectorStoreOptions,\n VectorMetadata,\n DistanceMetric,\n} from '../types'\n\nexport interface ElasticsearchVectorStoreOptions extends BaseVectorStoreOptions {\n /** Connection and authentication parameters for the backend. */\n connection?: {\n node?: string // default 'http://localhost:9200'\n auth?: { username: string; password: string } | { apiKey: string }\n client?: unknown // BYO @elastic/elasticsearch Client; overrides node\n }\n}\n\nconst getElasticsearchClient = async () => {\n try {\n const mod = await import('@elastic/elasticsearch')\n return mod.Client\n } catch {\n throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(['@elastic/elasticsearch'])\n }\n}\n\n// Elasticsearch similarity per metric.\nconst similarity = (metric: DistanceMetric): string =>\n metric === 'cosine' ? 'cosine' : metric === 'dot' ? 'dot_product' : 'l2_norm'\n\n/**\n * Compile the neutral filter tree to an Elasticsearch bool-query clause over `metadata.*`.\n * String values use the `.keyword` sub-field for exact match; numbers use range/term.\n */\nexport const translateElasticsearchFilter = (\n filter?: VectorFilter\n): Record<string, unknown> | undefined => {\n if (!filter) return undefined\n if (isRawFilter(filter)) {\n if (filter.$dialect === 'elasticsearch' || filter.$dialect === 'opensearch') {\n return filter.$raw as Record<string, unknown>\n }\n throw new E_VECTOR_STORE_UNSUPPORTED_FILTER_OPERATOR(['elasticsearch', String(filter.$dialect)])\n }\n if (isFilterCondition(filter)) {\n const { field, op, value } = filter\n const f = `metadata.${field}`\n const kw = `metadata.${field}.keyword`\n const term = (v: unknown) =>\n typeof v === 'number' || typeof v === 'boolean' ? { term: { [f]: v } } : { term: { [kw]: v } }\n switch (op) {\n case 'eq':\n return term(value)\n case 'ne':\n return { bool: { must_not: [term(value)] } }\n case 'gt':\n return { range: { [f]: { gt: value } } }\n case 'gte':\n return { range: { [f]: { gte: value } } }\n case 'lt':\n return { range: { [f]: { lt: value } } }\n case 'lte':\n return { range: { [f]: { lte: value } } }\n case 'in': {\n const arr = Array.isArray(value) ? value : [value]\n const allNum = arr.every((v) => typeof v === 'number' || typeof v === 'boolean')\n return { terms: { [allNum ? f : kw]: arr } }\n }\n case 'nin': {\n const arr = Array.isArray(value) ? value : [value]\n const allNum = arr.every((v) => typeof v === 'number' || typeof v === 'boolean')\n return { bool: { must_not: [{ terms: { [allNum ? f : kw]: arr } }] } }\n }\n case 'exists':\n return { exists: { field: f } }\n default:\n throw new E_VECTOR_STORE_UNSUPPORTED_FILTER_OPERATOR(['elasticsearch', op])\n }\n }\n if (isFilterGroup(filter)) {\n const { and, or, not } = filter\n if (and) {\n const must = and.map(translateElasticsearchFilter).filter(Boolean)\n return { bool: { must } }\n }\n if (or) {\n const should = or.map(translateElasticsearchFilter).filter(Boolean)\n return { bool: { should, minimum_should_match: 1 } }\n }\n if (not) {\n const inner = translateElasticsearchFilter(not)\n return inner ? { bool: { must_not: [inner] } } : undefined\n }\n }\n return undefined\n}\n\nexport class ElasticsearchVectorStore extends BaseVectorStore {\n readonly capabilities: VectorStoreCapabilities = {\n transactions: false,\n namedVectors: false,\n rename: false,\n rawSql: false,\n builtInEncoding: false,\n // Made strongly consistent by refreshing the index after every write (refresh: true /\n // explicit _refresh), so a write is visible to the next search. The option is a no-op.\n consistency: { configurable: false, default: 'strong', modes: ['strong'] },\n }\n\n #client: any | null = null\n #dims: Map<string, number> = new Map()\n\n get #opts(): ElasticsearchVectorStoreOptions {\n return this.options as ElasticsearchVectorStoreOptions\n }\n\n /** Static availability probe: whether this adapter's runtime driver can load in the current environment. */\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.#client) return\n const c = this.#opts.connection || {}\n if (c.client) {\n this.#client = c.client\n return\n }\n const Client = await getElasticsearchClient()\n try {\n this.#client = new Client({ node: c.node ?? 'http://localhost:9200', auth: c.auth })\n } catch (err) {\n throw new E_VECTOR_STORE_CONNECTION_FAILED([String(err)])\n }\n }\n\n async close(): Promise<void> {\n if (\n this.#client &&\n typeof this.#client.close === 'function' &&\n !this.#opts.connection?.client\n ) {\n await this.#client.close()\n }\n this.#client = null\n }\n\n async #ensure(): Promise<any> {\n if (!this.#client) await this.connect()\n return this.#client!\n }\n\n // Unwrap the {body}/direct response shape across client versions.\n #body(res: any): any {\n return res && res.body !== undefined ? res.body : res\n }\n\n async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n const client = await this.#ensure()\n this.#dims.set(spec.collection, spec.vector.dimensions)\n if (ifNotExists && (await this.hasCollection(spec.collection))) return\n try {\n await client.indices.create({\n index: spec.collection,\n mappings: {\n properties: {\n vec: {\n type: 'dense_vector',\n dims: spec.vector.dimensions,\n index: true,\n similarity: similarity(spec.vector.metric),\n },\n document: { type: 'text' },\n metadata: { type: 'object', enabled: true },\n },\n },\n })\n } catch (err) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['createCollection', String(err)])\n }\n }\n\n async dropCollection(collection: string, ifExists: boolean): Promise<void> {\n const client = await this.#ensure()\n if (ifExists && !(await this.hasCollection(collection))) return\n try {\n await client.indices.delete({ index: collection })\n this.#dims.delete(collection)\n } catch (err) {\n const msg = String(err)\n if (ifExists && msg.includes('index_not_found')) return\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['dropCollection', msg])\n }\n }\n\n async hasCollection(collection: string): Promise<boolean> {\n const client = await this.#ensure()\n try {\n const res = await client.indices.exists({ index: collection })\n const body = this.#body(res)\n return body === true || body === 200 || res?.statusCode === 200\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', 'elasticsearch'])\n }\n\n async executeUpsert(plan: UpsertPlan): Promise<void> {\n if (plan.records.length === 0) return\n validateRecords(plan.records)\n const client = await this.#ensure()\n const expected = this.#opts.dimensions ?? this.#dims.get(plan.collection)\n try {\n const operations: any[] = []\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 operations.push({ index: { _index: plan.collection, _id: r.id } })\n operations.push({ vec: vector, document: r.document ?? '', metadata: r.metadata ?? {} })\n }\n await client.bulk({ operations, refresh: true })\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 client = await this.#ensure()\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 try {\n const res = await client.get({ index: plan.collection, id: plan.near.id })\n queryVector = this.#body(res)?._source?.vec as number[]\n } catch {\n queryVector = undefined\n }\n if (!queryVector) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n }\n }\n\n const filter = translateElasticsearchFilter(plan.filter)\n const size = plan.topK\n const from = plan.offset ?? 0\n try {\n let res: any\n if (queryVector) {\n const knn: any = {\n field: 'vec',\n query_vector: queryVector,\n k: size + from,\n num_candidates: Math.max((size + from) * 10, 100),\n }\n if (filter) knn.filter = filter\n res = await client.search({ index: plan.collection, knn, size, from, _source: true })\n } else {\n res = await client.search({\n index: plan.collection,\n size,\n from,\n query: filter ?? { match_all: {} },\n })\n }\n const hits = this.#body(res)?.hits?.hits ?? []\n return hits.map((hit: any) => this.#project(hit, plan, metric, !!queryVector))\n } catch (err) {\n throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)])\n }\n }\n\n #project(hit: any, plan: SearchPlan, metric: string, isKnn: boolean): VectorMatch {\n const proj = plan.projection\n const src = hit._source ?? {}\n const out: VectorMatch = {}\n if (proj.id) out.id = hit._id as string\n if (proj.vector && src.vec) out.vector = src.vec as number[]\n if (proj.document) out.document = src.document as string | undefined\n if (proj.metadata) out.metadata = (src.metadata ?? {}) as VectorMetadata\n if (isKnn && typeof hit._score === 'number') {\n // Elasticsearch cosine _score is already (sim+1)/2 ∈ [0,1]; normalize defensively to [0,1].\n out.score = normalizeScore(hit._score, metric as DistanceMetric, 'similarity')\n }\n return out\n }\n\n async executeDelete(plan: DeletePlan): Promise<void> {\n const client = await this.#ensure()\n try {\n if (plan.ids && plan.ids.length > 0) {\n const operations = plan.ids.map((id) => ({ delete: { _index: plan.collection, _id: id } }))\n await client.bulk({ operations, refresh: true })\n } else if (plan.filter) {\n const filter = translateElasticsearchFilter(plan.filter)\n await client.deleteByQuery({\n index: plan.collection,\n refresh: true,\n query: filter ?? { match_all: {} },\n })\n } else {\n await client.deleteByQuery({\n index: plan.collection,\n refresh: true,\n query: { match_all: {} },\n })\n }\n } catch (err) {\n throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { s as isInstanceOf } from "../../tool_registry-
|
|
1
|
+
import { s as isInstanceOf } from "../../tool_registry-791Vrjtf.mjs";
|
|
2
2
|
import "../../guards.mjs";
|
|
3
3
|
import { isFilterCondition, isFilterGroup, isRawFilter } from "./filters.mjs";
|
|
4
4
|
import { normalizeScore } from "./helpers.mjs";
|
|
@@ -86,6 +86,7 @@ var ElasticsearchVectorStore = class extends BaseVectorStore {
|
|
|
86
86
|
get #opts() {
|
|
87
87
|
return this.options;
|
|
88
88
|
}
|
|
89
|
+
/** Static availability probe: whether this adapter's runtime driver can load in the current environment. */
|
|
89
90
|
static isAvailable() {
|
|
90
91
|
return typeof process !== "undefined";
|
|
91
92
|
}
|