@nhtio/adk 1.20260604.0 → 1.20260607.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. package/CHANGELOG.md +261 -0
  2. package/adk-mcp.mjs +1 -1
  3. package/batteries/embeddings/openai/adapter.cjs +1 -1
  4. package/batteries/embeddings/openai/adapter.mjs +1 -1
  5. package/batteries/embeddings/webllm/adapter.cjs +1 -1
  6. package/batteries/embeddings/webllm/adapter.mjs +1 -1
  7. package/batteries/index.d.ts +1 -0
  8. package/batteries/llm/openai_chat_completions/adapter.cjs +6 -6
  9. package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -1
  10. package/batteries/llm/openai_chat_completions/adapter.mjs +6 -6
  11. package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -1
  12. package/batteries/llm/openai_chat_completions/helpers.cjs +2 -2
  13. package/batteries/llm/openai_chat_completions/helpers.mjs +2 -2
  14. package/batteries/llm/openai_chat_completions/validation.cjs +2 -2
  15. package/batteries/llm/openai_chat_completions/validation.cjs.map +1 -1
  16. package/batteries/llm/openai_chat_completions/validation.mjs +2 -2
  17. package/batteries/llm/openai_chat_completions/validation.mjs.map +1 -1
  18. package/batteries/llm/webllm_chat_completions/adapter.cjs +6 -6
  19. package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -1
  20. package/batteries/llm/webllm_chat_completions/adapter.mjs +6 -6
  21. package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -1
  22. package/batteries/llm/webllm_chat_completions/validation.cjs +2 -2
  23. package/batteries/llm/webllm_chat_completions/validation.cjs.map +1 -1
  24. package/batteries/llm/webllm_chat_completions/validation.mjs +2 -2
  25. package/batteries/llm/webllm_chat_completions/validation.mjs.map +1 -1
  26. package/batteries/storage/flydrive.cjs +1 -1
  27. package/batteries/storage/flydrive.mjs +2 -2
  28. package/batteries/storage/in_memory.cjs +1 -1
  29. package/batteries/storage/in_memory.mjs +1 -1
  30. package/batteries/storage/opfs.cjs +1 -1
  31. package/batteries/storage/opfs.mjs +1 -1
  32. package/batteries/tools/color.cjs +2 -2
  33. package/batteries/tools/color.mjs +2 -2
  34. package/batteries/tools/comparison.cjs +3 -3
  35. package/batteries/tools/comparison.mjs +3 -3
  36. package/batteries/tools/data_structure.cjs +3 -3
  37. package/batteries/tools/data_structure.mjs +3 -3
  38. package/batteries/tools/datetime_extended.cjs +2 -2
  39. package/batteries/tools/datetime_extended.mjs +2 -2
  40. package/batteries/tools/datetime_math.cjs +2 -2
  41. package/batteries/tools/datetime_math.mjs +2 -2
  42. package/batteries/tools/encoding.cjs +3 -3
  43. package/batteries/tools/encoding.mjs +3 -3
  44. package/batteries/tools/formatting.cjs +3 -3
  45. package/batteries/tools/formatting.mjs +3 -3
  46. package/batteries/tools/geo_basics.cjs +2 -2
  47. package/batteries/tools/geo_basics.mjs +2 -2
  48. package/batteries/tools/math/index.d.ts +16 -5
  49. package/batteries/tools/math.cjs +340 -22
  50. package/batteries/tools/math.cjs.map +1 -1
  51. package/batteries/tools/math.mjs +338 -21
  52. package/batteries/tools/math.mjs.map +1 -1
  53. package/batteries/tools/memory.cjs +5 -5
  54. package/batteries/tools/memory.mjs +5 -5
  55. package/batteries/tools/parsing.cjs +4 -4
  56. package/batteries/tools/parsing.mjs +4 -4
  57. package/batteries/tools/retrievables.cjs +4 -4
  58. package/batteries/tools/retrievables.mjs +4 -4
  59. package/batteries/tools/standing_instructions.cjs +4 -4
  60. package/batteries/tools/standing_instructions.mjs +4 -4
  61. package/batteries/tools/statistics.cjs +4 -4
  62. package/batteries/tools/statistics.mjs +4 -4
  63. package/batteries/tools/string_processing.cjs +3 -3
  64. package/batteries/tools/string_processing.mjs +3 -3
  65. package/batteries/tools/structured_data.cjs +3 -3
  66. package/batteries/tools/structured_data.mjs +3 -3
  67. package/batteries/tools/text_analysis.cjs +3 -3
  68. package/batteries/tools/text_analysis.mjs +3 -3
  69. package/batteries/tools/text_comparison.cjs +2 -2
  70. package/batteries/tools/text_comparison.mjs +2 -2
  71. package/batteries/tools/time.cjs +2 -2
  72. package/batteries/tools/time.mjs +2 -2
  73. package/batteries/tools/unit_conversion.cjs +2 -2
  74. package/batteries/tools/unit_conversion.mjs +2 -2
  75. package/batteries/vector/arangodb/index.d.ts +38 -0
  76. package/batteries/vector/arangodb.cjs +257 -0
  77. package/batteries/vector/arangodb.cjs.map +1 -0
  78. package/batteries/vector/arangodb.mjs +255 -0
  79. package/batteries/vector/arangodb.mjs.map +1 -0
  80. package/batteries/vector/builder.cjs +297 -0
  81. package/batteries/vector/builder.cjs.map +1 -0
  82. package/batteries/vector/builder.d.ts +87 -0
  83. package/batteries/vector/builder.mjs +294 -0
  84. package/batteries/vector/builder.mjs.map +1 -0
  85. package/batteries/vector/chroma/index.d.ts +32 -0
  86. package/batteries/vector/chroma.cjs +305 -0
  87. package/batteries/vector/chroma.cjs.map +1 -0
  88. package/batteries/vector/chroma.mjs +302 -0
  89. package/batteries/vector/chroma.mjs.map +1 -0
  90. package/batteries/vector/clickhouse/index.d.ts +39 -0
  91. package/batteries/vector/clickhouse.cjs +246 -0
  92. package/batteries/vector/clickhouse.cjs.map +1 -0
  93. package/batteries/vector/clickhouse.mjs +244 -0
  94. package/batteries/vector/clickhouse.mjs.map +1 -0
  95. package/batteries/vector/cloudflare/index.d.ts +43 -0
  96. package/batteries/vector/cloudflare.cjs +397 -0
  97. package/batteries/vector/cloudflare.cjs.map +1 -0
  98. package/batteries/vector/cloudflare.mjs +395 -0
  99. package/batteries/vector/cloudflare.mjs.map +1 -0
  100. package/batteries/vector/conformance/index.d.ts +15 -0
  101. package/batteries/vector/conformance.cjs +209 -0
  102. package/batteries/vector/conformance.cjs.map +1 -0
  103. package/batteries/vector/conformance.mjs +205 -0
  104. package/batteries/vector/conformance.mjs.map +1 -0
  105. package/batteries/vector/contract.cjs +42 -0
  106. package/batteries/vector/contract.cjs.map +1 -0
  107. package/batteries/vector/contract.d.ts +39 -0
  108. package/batteries/vector/contract.mjs +40 -0
  109. package/batteries/vector/contract.mjs.map +1 -0
  110. package/batteries/vector/couchbase/index.d.ts +49 -0
  111. package/batteries/vector/couchbase.cjs +401 -0
  112. package/batteries/vector/couchbase.cjs.map +1 -0
  113. package/batteries/vector/couchbase.mjs +399 -0
  114. package/batteries/vector/couchbase.mjs.map +1 -0
  115. package/batteries/vector/duckdb/index.d.ts +33 -0
  116. package/batteries/vector/duckdb.cjs +218 -0
  117. package/batteries/vector/duckdb.cjs.map +1 -0
  118. package/batteries/vector/duckdb.mjs +216 -0
  119. package/batteries/vector/duckdb.mjs.map +1 -0
  120. package/batteries/vector/elasticsearch/index.d.ts +43 -0
  121. package/batteries/vector/elasticsearch.cjs +306 -0
  122. package/batteries/vector/elasticsearch.cjs.map +1 -0
  123. package/batteries/vector/elasticsearch.mjs +303 -0
  124. package/batteries/vector/elasticsearch.mjs.map +1 -0
  125. package/batteries/vector/exceptions.cjs +126 -0
  126. package/batteries/vector/exceptions.cjs.map +1 -0
  127. package/batteries/vector/exceptions.d.ts +142 -0
  128. package/batteries/vector/exceptions.mjs +107 -0
  129. package/batteries/vector/exceptions.mjs.map +1 -0
  130. package/batteries/vector/factory.cjs +28 -0
  131. package/batteries/vector/factory.cjs.map +1 -0
  132. package/batteries/vector/factory.d.ts +38 -0
  133. package/batteries/vector/factory.mjs +25 -0
  134. package/batteries/vector/factory.mjs.map +1 -0
  135. package/batteries/vector/filters.cjs +107 -0
  136. package/batteries/vector/filters.cjs.map +1 -0
  137. package/batteries/vector/filters.d.ts +34 -0
  138. package/batteries/vector/filters.mjs +99 -0
  139. package/batteries/vector/filters.mjs.map +1 -0
  140. package/batteries/vector/helpers.cjs +23 -0
  141. package/batteries/vector/helpers.cjs.map +1 -0
  142. package/batteries/vector/helpers.d.ts +12 -0
  143. package/batteries/vector/helpers.mjs +17 -0
  144. package/batteries/vector/helpers.mjs.map +1 -0
  145. package/batteries/vector/hnswlib/index.d.ts +35 -0
  146. package/batteries/vector/hnswlib.cjs +237 -0
  147. package/batteries/vector/hnswlib.cjs.map +1 -0
  148. package/batteries/vector/hnswlib.mjs +235 -0
  149. package/batteries/vector/hnswlib.mjs.map +1 -0
  150. package/batteries/vector/in_memory/index.d.ts +23 -0
  151. package/batteries/vector/in_memory.cjs +178 -0
  152. package/batteries/vector/in_memory.cjs.map +1 -0
  153. package/batteries/vector/in_memory.mjs +176 -0
  154. package/batteries/vector/in_memory.mjs.map +1 -0
  155. package/batteries/vector/index.d.ts +18 -0
  156. package/batteries/vector/lancedb/index.d.ts +34 -0
  157. package/batteries/vector/lancedb.cjs +224 -0
  158. package/batteries/vector/lancedb.cjs.map +1 -0
  159. package/batteries/vector/lancedb.mjs +222 -0
  160. package/batteries/vector/lancedb.mjs.map +1 -0
  161. package/batteries/vector/mariadb/index.d.ts +39 -0
  162. package/batteries/vector/mariadb.cjs +228 -0
  163. package/batteries/vector/mariadb.cjs.map +1 -0
  164. package/batteries/vector/mariadb.mjs +226 -0
  165. package/batteries/vector/mariadb.mjs.map +1 -0
  166. package/batteries/vector/meilisearch/index.d.ts +36 -0
  167. package/batteries/vector/meilisearch.cjs +242 -0
  168. package/batteries/vector/meilisearch.cjs.map +1 -0
  169. package/batteries/vector/meilisearch.mjs +240 -0
  170. package/batteries/vector/meilisearch.mjs.map +1 -0
  171. package/batteries/vector/migrate.cjs +54 -0
  172. package/batteries/vector/migrate.cjs.map +1 -0
  173. package/batteries/vector/migrate.d.ts +30 -0
  174. package/batteries/vector/migrate.mjs +52 -0
  175. package/batteries/vector/migrate.mjs.map +1 -0
  176. package/batteries/vector/milvus/index.d.ts +35 -0
  177. package/batteries/vector/milvus.cjs +357 -0
  178. package/batteries/vector/milvus.cjs.map +1 -0
  179. package/batteries/vector/milvus.mjs +354 -0
  180. package/batteries/vector/milvus.mjs.map +1 -0
  181. package/batteries/vector/mongodb/index.d.ts +46 -0
  182. package/batteries/vector/mongodb.cjs +270 -0
  183. package/batteries/vector/mongodb.cjs.map +1 -0
  184. package/batteries/vector/mongodb.mjs +268 -0
  185. package/batteries/vector/mongodb.mjs.map +1 -0
  186. package/batteries/vector/neo4j/index.d.ts +38 -0
  187. package/batteries/vector/neo4j.cjs +231 -0
  188. package/batteries/vector/neo4j.cjs.map +1 -0
  189. package/batteries/vector/neo4j.mjs +229 -0
  190. package/batteries/vector/neo4j.mjs.map +1 -0
  191. package/batteries/vector/opensearch/index.d.ts +46 -0
  192. package/batteries/vector/opensearch.cjs +316 -0
  193. package/batteries/vector/opensearch.cjs.map +1 -0
  194. package/batteries/vector/opensearch.mjs +313 -0
  195. package/batteries/vector/opensearch.mjs.map +1 -0
  196. package/batteries/vector/oracle23ai/index.d.ts +45 -0
  197. package/batteries/vector/oracle23ai.cjs +340 -0
  198. package/batteries/vector/oracle23ai.cjs.map +1 -0
  199. package/batteries/vector/oracle23ai.mjs +338 -0
  200. package/batteries/vector/oracle23ai.mjs.map +1 -0
  201. package/batteries/vector/orama/index.d.ts +23 -0
  202. package/batteries/vector/orama.cjs +272 -0
  203. package/batteries/vector/orama.cjs.map +1 -0
  204. package/batteries/vector/orama.mjs +270 -0
  205. package/batteries/vector/orama.mjs.map +1 -0
  206. package/batteries/vector/pgvector/index.d.ts +43 -0
  207. package/batteries/vector/pgvector.cjs +411 -0
  208. package/batteries/vector/pgvector.cjs.map +1 -0
  209. package/batteries/vector/pgvector.mjs +408 -0
  210. package/batteries/vector/pgvector.mjs.map +1 -0
  211. package/batteries/vector/pinecone/index.d.ts +38 -0
  212. package/batteries/vector/pinecone.cjs +415 -0
  213. package/batteries/vector/pinecone.cjs.map +1 -0
  214. package/batteries/vector/pinecone.mjs +412 -0
  215. package/batteries/vector/pinecone.mjs.map +1 -0
  216. package/batteries/vector/plan.cjs +2 -0
  217. package/batteries/vector/plan.d.ts +65 -0
  218. package/batteries/vector/plan.mjs +0 -0
  219. package/batteries/vector/qdrant/index.d.ts +34 -0
  220. package/batteries/vector/qdrant.cjs +286 -0
  221. package/batteries/vector/qdrant.cjs.map +1 -0
  222. package/batteries/vector/qdrant.mjs +284 -0
  223. package/batteries/vector/qdrant.mjs.map +1 -0
  224. package/batteries/vector/redis/index.d.ts +44 -0
  225. package/batteries/vector/redis.cjs +391 -0
  226. package/batteries/vector/redis.cjs.map +1 -0
  227. package/batteries/vector/redis.mjs +388 -0
  228. package/batteries/vector/redis.mjs.map +1 -0
  229. package/batteries/vector/retrievable.cjs +69 -0
  230. package/batteries/vector/retrievable.cjs.map +1 -0
  231. package/batteries/vector/retrievable.mjs +67 -0
  232. package/batteries/vector/retrievable.mjs.map +1 -0
  233. package/batteries/vector/retrievable_glue.d.ts +24 -0
  234. package/batteries/vector/s3vectors/index.d.ts +52 -0
  235. package/batteries/vector/s3vectors.cjs +438 -0
  236. package/batteries/vector/s3vectors.cjs.map +1 -0
  237. package/batteries/vector/s3vectors.mjs +436 -0
  238. package/batteries/vector/s3vectors.mjs.map +1 -0
  239. package/batteries/vector/schema.cjs +96 -0
  240. package/batteries/vector/schema.cjs.map +1 -0
  241. package/batteries/vector/schema.d.ts +40 -0
  242. package/batteries/vector/schema.mjs +93 -0
  243. package/batteries/vector/schema.mjs.map +1 -0
  244. package/batteries/vector/solr/index.d.ts +36 -0
  245. package/batteries/vector/solr.cjs +230 -0
  246. package/batteries/vector/solr.cjs.map +1 -0
  247. package/batteries/vector/solr.mjs +228 -0
  248. package/batteries/vector/solr.mjs.map +1 -0
  249. package/batteries/vector/sqlite_vec/index.d.ts +30 -0
  250. package/batteries/vector/sqlite_vec.cjs +318 -0
  251. package/batteries/vector/sqlite_vec.cjs.map +1 -0
  252. package/batteries/vector/sqlite_vec.mjs +316 -0
  253. package/batteries/vector/sqlite_vec.mjs.map +1 -0
  254. package/batteries/vector/surrealdb/index.d.ts +37 -0
  255. package/batteries/vector/surrealdb.cjs +230 -0
  256. package/batteries/vector/surrealdb.cjs.map +1 -0
  257. package/batteries/vector/surrealdb.mjs +228 -0
  258. package/batteries/vector/surrealdb.mjs.map +1 -0
  259. package/batteries/vector/types.cjs +2 -0
  260. package/batteries/vector/types.d.ts +100 -0
  261. package/batteries/vector/types.mjs +0 -0
  262. package/batteries/vector/typesense/index.d.ts +38 -0
  263. package/batteries/vector/typesense.cjs +272 -0
  264. package/batteries/vector/typesense.cjs.map +1 -0
  265. package/batteries/vector/typesense.mjs +270 -0
  266. package/batteries/vector/typesense.mjs.map +1 -0
  267. package/batteries/vector/validation.cjs +90 -0
  268. package/batteries/vector/validation.cjs.map +1 -0
  269. package/batteries/vector/validation.d.ts +18 -0
  270. package/batteries/vector/validation.mjs +83 -0
  271. package/batteries/vector/validation.mjs.map +1 -0
  272. package/batteries/vector/vector_store_constructor.cjs +56 -0
  273. package/batteries/vector/vector_store_constructor.cjs.map +1 -0
  274. package/batteries/vector/vector_store_constructor.d.ts +30 -0
  275. package/batteries/vector/vector_store_constructor.mjs +53 -0
  276. package/batteries/vector/vector_store_constructor.mjs.map +1 -0
  277. package/batteries/vector/vespa/index.d.ts +39 -0
  278. package/batteries/vector/vespa.cjs +423 -0
  279. package/batteries/vector/vespa.cjs.map +1 -0
  280. package/batteries/vector/vespa.mjs +421 -0
  281. package/batteries/vector/vespa.mjs.map +1 -0
  282. package/batteries/vector/weaviate/index.d.ts +57 -0
  283. package/batteries/vector/weaviate.cjs +325 -0
  284. package/batteries/vector/weaviate.cjs.map +1 -0
  285. package/batteries/vector/weaviate.mjs +322 -0
  286. package/batteries/vector/weaviate.mjs.map +1 -0
  287. package/batteries/vector.cjs +63 -0
  288. package/batteries/vector.mjs +14 -0
  289. package/batteries.cjs +62 -0
  290. package/batteries.mjs +15 -1
  291. package/{chunk-kRvK8_k2.mjs → chunk-Bpcn9VDT.mjs} +5 -1
  292. package/{common-lMrnzoyn.mjs → common-BT0nfCi9.mjs} +8 -8
  293. package/{common-lMrnzoyn.mjs.map → common-BT0nfCi9.mjs.map} +1 -1
  294. package/{common-D_e5zYsG.js → common-Cj8TaQ9U.js} +8 -8
  295. package/{common-D_e5zYsG.js.map → common-Cj8TaQ9U.js.map} +1 -1
  296. package/common.cjs +7 -7
  297. package/common.mjs +7 -7
  298. package/{dispatch_runner-CpuyATj1.js → dispatch_runner-BHBNupqp.js} +2 -2
  299. package/dispatch_runner-BHBNupqp.js.map +1 -0
  300. package/{dispatch_runner-CDF3X0nv.mjs → dispatch_runner-DPcS7Y_M.mjs} +2 -2
  301. package/dispatch_runner-DPcS7Y_M.mjs.map +1 -0
  302. package/dispatch_runner.cjs +1 -1
  303. package/dispatch_runner.mjs +1 -1
  304. package/forge.cjs +4 -4
  305. package/forge.mjs +4 -4
  306. package/guards.cjs +8 -8
  307. package/guards.mjs +8 -8
  308. package/index.cjs +12 -12
  309. package/index.mjs +12 -12
  310. package/lib/classes/tool_registry.d.ts +70 -4
  311. package/mcp/adk-docs-corpus.json +1 -1
  312. package/package.json +424 -88
  313. package/skills/adk-assembly/SKILL.md +2 -2
  314. package/{spooled_artifact-B8gIIn9h.js → spooled_artifact-BTq6Nzfy.js} +4 -4
  315. package/spooled_artifact-BTq6Nzfy.js.map +1 -0
  316. package/{spooled_artifact-CWoKUDEm.mjs → spooled_artifact-CHoZgWwI.mjs} +4 -4
  317. package/spooled_artifact-CHoZgWwI.mjs.map +1 -0
  318. package/spooled_artifact.cjs +2 -2
  319. package/spooled_artifact.mjs +2 -2
  320. package/{spooled_markdown_artifact-DQX0RCdI.js → spooled_markdown_artifact-CALSDxIx.js} +3 -3
  321. package/{spooled_markdown_artifact-DQX0RCdI.js.map → spooled_markdown_artifact-CALSDxIx.js.map} +1 -1
  322. package/{spooled_markdown_artifact-CNle4jXN.mjs → spooled_markdown_artifact-Ci5UL7l4.mjs} +3 -3
  323. package/{spooled_markdown_artifact-CNle4jXN.mjs.map → spooled_markdown_artifact-Ci5UL7l4.mjs.map} +1 -1
  324. package/src/types/evaluatex.d.ts +31 -0
  325. package/{thought-BD6AkkOr.js → thought-BbwhJ1wb.js} +4 -4
  326. package/thought-BbwhJ1wb.js.map +1 -0
  327. package/{thought-B_P8LiB6.mjs → thought-D34QQZZ9.mjs} +4 -4
  328. package/thought-D34QQZZ9.mjs.map +1 -0
  329. package/{tool-CRZSUcdP.mjs → tool-CMhaDRNd.mjs} +3 -3
  330. package/tool-CMhaDRNd.mjs.map +1 -0
  331. package/{tool-CX9vNHAw.js → tool-CVyZkFC7.js} +3 -3
  332. package/tool-CVyZkFC7.js.map +1 -0
  333. package/{tool_call-BUeMuCc6.mjs → tool_call-CV5qVNlb.mjs} +3 -3
  334. package/{tool_call-BUeMuCc6.mjs.map → tool_call-CV5qVNlb.mjs.map} +1 -1
  335. package/{tool_call--7ti-frB.js → tool_call-Db68hB7y.js} +3 -3
  336. package/{tool_call--7ti-frB.js.map → tool_call-Db68hB7y.js.map} +1 -1
  337. package/{tool_registry-BGHg6KTq.mjs → tool_registry-D1pSSlsd.mjs} +109 -22
  338. package/tool_registry-D1pSSlsd.mjs.map +1 -0
  339. package/{tool_registry-CtCQ4Xoz.js → tool_registry-DYUYqXvo.js} +109 -22
  340. package/tool_registry-DYUYqXvo.js.map +1 -0
  341. package/{turn_runner-BJTtAORU.js → turn_runner-DqWHNP80.js} +5 -5
  342. package/turn_runner-DqWHNP80.js.map +1 -0
  343. package/{turn_runner-C02LZHjt.mjs → turn_runner-fg1Wc3dK.mjs} +5 -5
  344. package/turn_runner-fg1Wc3dK.mjs.map +1 -0
  345. package/turn_runner.cjs +1 -1
  346. package/turn_runner.mjs +1 -1
  347. package/dispatch_runner-CDF3X0nv.mjs.map +0 -1
  348. package/dispatch_runner-CpuyATj1.js.map +0 -1
  349. package/spooled_artifact-B8gIIn9h.js.map +0 -1
  350. package/spooled_artifact-CWoKUDEm.mjs.map +0 -1
  351. package/thought-BD6AkkOr.js.map +0 -1
  352. package/thought-B_P8LiB6.mjs.map +0 -1
  353. package/tool-CRZSUcdP.mjs.map +0 -1
  354. package/tool-CX9vNHAw.js.map +0 -1
  355. package/tool_registry-BGHg6KTq.mjs.map +0 -1
  356. package/tool_registry-CtCQ4Xoz.js.map +0 -1
  357. package/turn_runner-BJTtAORU.js.map +0 -1
  358. package/turn_runner-C02LZHjt.mjs.map +0 -1
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @module @nhtio/adk/batteries/vector/neo4j
3
+ *
4
+ * Neo4j adapter (native vector index, 5.13+). Each collection is a node label; records are
5
+ * nodes with `id`/`vec`/`document`/`metadata` properties and a `VECTOR INDEX` on `vec`. KNN
6
+ * uses `db.index.vector.queryNodes(index, k, vector)` (score is the similarity, already [0,1]
7
+ * for cosine). Metadata is a JSON string property filtered with the neutral filter tree's JS
8
+ * reference evaluator for exact cross-adapter parity.
9
+ *
10
+ * Driver: `neo4j-driver` (pure JS). Labels/index names can't be Cypher-parameterized, so they
11
+ * are derived from the (sanitized) collection name; all values are parameterized.
12
+ */
13
+ import { BaseVectorStore } from "../contract";
14
+ import type { SearchPlan, UpsertPlan, DeletePlan, CollectionSpec } from "../plan";
15
+ import type { VectorMatch, VectorStoreCapabilities, BaseVectorStoreOptions } from "../types";
16
+ export interface Neo4jVectorStoreOptions extends BaseVectorStoreOptions {
17
+ connection: {
18
+ url: string;
19
+ username?: string;
20
+ password?: string;
21
+ database?: string;
22
+ };
23
+ }
24
+ export declare class Neo4jVectorStore extends BaseVectorStore {
25
+ #private;
26
+ readonly capabilities: VectorStoreCapabilities;
27
+ static isAvailable(): boolean;
28
+ isAvailable(): boolean;
29
+ connect(): Promise<void>;
30
+ close(): Promise<void>;
31
+ createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void>;
32
+ dropCollection(collection: string, _ifExists: boolean): Promise<void>;
33
+ hasCollection(collection: string): Promise<boolean>;
34
+ renameCollection(_from: string, _to: string): Promise<void>;
35
+ executeUpsert(plan: UpsertPlan): Promise<void>;
36
+ executeSearch(plan: SearchPlan): Promise<VectorMatch[]>;
37
+ executeDelete(plan: DeletePlan): Promise<void>;
38
+ }
@@ -0,0 +1,231 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ require("../../chunk-Ble4zEEl.js");
3
+ const require_tool_registry = require("../../tool_registry-DYUYqXvo.js");
4
+ require("../../guards.cjs");
5
+ const require_batteries_vector_filters = require("./filters.cjs");
6
+ const require_batteries_vector_exceptions = require("./exceptions.cjs");
7
+ const require_batteries_vector_contract = require("./contract.cjs");
8
+ const require_batteries_vector_validation = require("./validation.cjs");
9
+ //#region src/batteries/vector/neo4j/index.ts
10
+ /**
11
+ * @module @nhtio/adk/batteries/vector/neo4j
12
+ *
13
+ * Neo4j adapter (native vector index, 5.13+). Each collection is a node label; records are
14
+ * nodes with `id`/`vec`/`document`/`metadata` properties and a `VECTOR INDEX` on `vec`. KNN
15
+ * uses `db.index.vector.queryNodes(index, k, vector)` (score is the similarity, already [0,1]
16
+ * for cosine). Metadata is a JSON string property filtered with the neutral filter tree's JS
17
+ * reference evaluator for exact cross-adapter parity.
18
+ *
19
+ * Driver: `neo4j-driver` (pure JS). Labels/index names can't be Cypher-parameterized, so they
20
+ * are derived from the (sanitized) collection name; all values are parameterized.
21
+ */
22
+ var getNeo4j = async () => {
23
+ try {
24
+ const mod = await import("neo4j-driver");
25
+ return mod.default ?? mod;
26
+ } catch {
27
+ throw new require_batteries_vector_exceptions.E_VECTOR_STORE_DRIVER_UNAVAILABLE(["neo4j-driver"]);
28
+ }
29
+ };
30
+ var sanitize = (name) => name.replace(/[^A-Za-z0-9_]/g, "_");
31
+ var labelFor = (collection) => "Vec_" + sanitize(collection);
32
+ var indexFor = (collection) => "vecidx_" + sanitize(collection);
33
+ var similarityFn = (metric) => metric === "euclidean" ? "euclidean" : "cosine";
34
+ var Neo4jVectorStore = class extends require_batteries_vector_contract.BaseVectorStore {
35
+ capabilities = {
36
+ transactions: false,
37
+ namedVectors: false,
38
+ rename: false,
39
+ rawSql: false,
40
+ builtInEncoding: false,
41
+ consistency: {
42
+ configurable: false,
43
+ default: "strong",
44
+ modes: ["strong"]
45
+ }
46
+ };
47
+ #driver = null;
48
+ #neo4j = null;
49
+ #dims = /* @__PURE__ */ new Map();
50
+ get #opts() {
51
+ return this.options;
52
+ }
53
+ static isAvailable() {
54
+ return typeof process !== "undefined";
55
+ }
56
+ isAvailable() {
57
+ return typeof process !== "undefined";
58
+ }
59
+ async connect() {
60
+ if (this.#driver) return;
61
+ const neo4j = await getNeo4j();
62
+ this.#neo4j = neo4j;
63
+ const c = this.#opts.connection;
64
+ try {
65
+ this.#driver = neo4j.driver(c.url, c.username ? neo4j.auth.basic(c.username, c.password ?? "") : void 0);
66
+ } catch (err) {
67
+ throw new require_batteries_vector_exceptions.E_VECTOR_STORE_CONNECTION_FAILED([String(err)]);
68
+ }
69
+ }
70
+ async close() {
71
+ if (this.#driver) {
72
+ await this.#driver.close();
73
+ this.#driver = null;
74
+ }
75
+ }
76
+ async #run(cypher, params) {
77
+ if (!this.#driver) await this.connect();
78
+ const db = this.#opts.connection.database;
79
+ const session = this.#driver.session(db ? { database: db } : void 0);
80
+ try {
81
+ return (await session.run(cypher, params)).records;
82
+ } finally {
83
+ await session.close();
84
+ }
85
+ }
86
+ async createCollection(spec, ifNotExists) {
87
+ this.#dims.set(spec.collection, spec.vector.dimensions);
88
+ const label = labelFor(spec.collection);
89
+ const index = indexFor(spec.collection);
90
+ try {
91
+ if (!ifNotExists) await this.#run(`DROP INDEX ${index} IF EXISTS`);
92
+ await this.#run(`CREATE VECTOR INDEX ${index} IF NOT EXISTS FOR (n:${label}) ON (n.vec) OPTIONS {indexConfig: {\`vector.dimensions\`: $dim, \`vector.similarity_function\`: $sim}}`, {
93
+ dim: this.#neo4j.int(spec.vector.dimensions),
94
+ sim: similarityFn(spec.vector.metric)
95
+ });
96
+ await this.#run(`CALL db.awaitIndex($index, $timeout)`, {
97
+ index,
98
+ timeout: this.#neo4j.int(30)
99
+ }).catch(() => void 0);
100
+ } catch (err) {
101
+ throw new require_batteries_vector_exceptions.E_VECTOR_STORE_COLLECTION_FAILED(["createCollection", String(err)]);
102
+ }
103
+ }
104
+ async dropCollection(collection, _ifExists) {
105
+ const label = labelFor(collection);
106
+ const index = indexFor(collection);
107
+ try {
108
+ await this.#run(`DROP INDEX ${index} IF EXISTS`);
109
+ await this.#run(`MATCH (n:${label}) DETACH DELETE n`);
110
+ this.#dims.delete(collection);
111
+ } catch (err) {
112
+ throw new require_batteries_vector_exceptions.E_VECTOR_STORE_COLLECTION_FAILED(["dropCollection", String(err)]);
113
+ }
114
+ }
115
+ async hasCollection(collection) {
116
+ const index = indexFor(collection);
117
+ try {
118
+ return (await this.#run(`SHOW INDEXES YIELD name WHERE name = $index RETURN name`, { index })).length > 0;
119
+ } catch {
120
+ return false;
121
+ }
122
+ }
123
+ async renameCollection(_from, _to) {
124
+ throw new require_batteries_vector_exceptions.E_VECTOR_STORE_UNSUPPORTED_OPERATION(["renameCollection", "neo4j"]);
125
+ }
126
+ async executeUpsert(plan) {
127
+ if (plan.records.length === 0) return;
128
+ require_batteries_vector_validation.validateRecords(plan.records);
129
+ const label = labelFor(plan.collection);
130
+ const expected = this.#opts.dimensions ?? this.#dims.get(plan.collection);
131
+ try {
132
+ for (const r of plan.records) {
133
+ let vector = r.vector;
134
+ if (!vector && r.document) {
135
+ const [v] = await this.encode([r.document], "document");
136
+ vector = v;
137
+ }
138
+ if (!vector) throw new require_batteries_vector_exceptions.E_VECTOR_STORE_UPSERT_FAILED(["Record missing vector and document"]);
139
+ if (expected !== void 0 && vector.length !== expected) throw new require_batteries_vector_exceptions.E_VECTOR_STORE_DIMENSION_MISMATCH([expected, vector.length]);
140
+ await this.#run(`MERGE (n:${label} {id: $id}) SET n.vec = $vec, n.document = $document, n.metadata = $metadata`, {
141
+ id: r.id,
142
+ vec: vector,
143
+ document: r.document ?? "",
144
+ metadata: r.metadata ? JSON.stringify(r.metadata) : "{}"
145
+ });
146
+ }
147
+ } catch (err) {
148
+ if (require_tool_registry.isInstanceOf(err, "E_VECTOR_STORE_DIMENSION_MISMATCH", require_batteries_vector_exceptions.E_VECTOR_STORE_DIMENSION_MISMATCH) || require_tool_registry.isInstanceOf(err, "E_VECTOR_STORE_UPSERT_FAILED", require_batteries_vector_exceptions.E_VECTOR_STORE_UPSERT_FAILED)) throw err;
149
+ throw new require_batteries_vector_exceptions.E_VECTOR_STORE_UPSERT_FAILED([String(err)]);
150
+ }
151
+ }
152
+ async executeSearch(plan) {
153
+ const label = labelFor(plan.collection);
154
+ const index = indexFor(plan.collection);
155
+ let queryVector;
156
+ if (plan.near) {
157
+ if ("vector" in plan.near) queryVector = plan.near.vector;
158
+ else if ("serverText" in plan.near) {
159
+ const [v] = await this.encode([plan.near.serverText], "query");
160
+ queryVector = v;
161
+ } else if ("id" in plan.near) {
162
+ const recs = await this.#run(`MATCH (n:${label} {id: $id}) RETURN n.vec AS vec`, { id: plan.near.id });
163
+ if (recs.length === 0) throw new require_batteries_vector_exceptions.E_VECTOR_STORE_SEARCH_FAILED(["Referenced id not found: " + plan.near.id]);
164
+ queryVector = recs[0].get("vec");
165
+ }
166
+ }
167
+ const offset = plan.offset ?? 0;
168
+ try {
169
+ if (queryVector) {
170
+ const k = plan.filter ? 1e3 : plan.topK + offset;
171
+ const mapped = (await this.#run("CALL db.index.vector.queryNodes($index, $k, $qv) YIELD node, score RETURN node.id AS id, node.vec AS vec, node.document AS document, node.metadata AS metadata, score ORDER BY score DESC", {
172
+ index,
173
+ k: this.#neo4j.int(k),
174
+ qv: queryVector
175
+ })).map((rec) => ({ row: {
176
+ id: rec.get("id"),
177
+ vec: rec.get("vec"),
178
+ document: rec.get("document"),
179
+ metadata: rec.get("metadata"),
180
+ score: rec.get("score")
181
+ } }));
182
+ return (plan.filter ? mapped.filter((m) => require_batteries_vector_filters.evaluateFilter(plan.filter, this.#parseMeta(m.row.metadata))) : mapped).slice(offset, offset + plan.topK).map((m) => this.#project(m.row, plan, true));
183
+ } else {
184
+ const rows = (await this.#run(`MATCH (n:${label}) RETURN n.id AS id, n.vec AS vec, n.document AS document, n.metadata AS metadata`)).map((rec) => ({
185
+ id: rec.get("id"),
186
+ vec: rec.get("vec"),
187
+ document: rec.get("document"),
188
+ metadata: rec.get("metadata")
189
+ }));
190
+ return (plan.filter ? rows.filter((row) => require_batteries_vector_filters.evaluateFilter(plan.filter, this.#parseMeta(row.metadata))) : rows).slice(offset, offset + plan.topK).map((row) => this.#project(row, plan, false));
191
+ }
192
+ } catch (err) {
193
+ throw new require_batteries_vector_exceptions.E_VECTOR_STORE_SEARCH_FAILED([String(err)]);
194
+ }
195
+ }
196
+ #parseMeta(val) {
197
+ if (typeof val === "string") try {
198
+ return JSON.parse(val);
199
+ } catch {
200
+ return {};
201
+ }
202
+ if (val && typeof val === "object") return val;
203
+ return {};
204
+ }
205
+ #project(row, plan, isKnn) {
206
+ const proj = plan.projection;
207
+ const out = {};
208
+ if (proj.id) out.id = row.id;
209
+ if (proj.vector && Array.isArray(row.vec)) out.vector = row.vec.map(Number);
210
+ if (proj.document) out.document = row.document ?? void 0;
211
+ if (proj.metadata) out.metadata = this.#parseMeta(row.metadata);
212
+ if (isKnn && row.score !== void 0 && row.score !== null) out.score = Number(row.score);
213
+ return out;
214
+ }
215
+ async executeDelete(plan) {
216
+ const label = labelFor(plan.collection);
217
+ try {
218
+ if (plan.ids && plan.ids.length > 0) await this.#run(`MATCH (n:${label}) WHERE n.id IN $ids DETACH DELETE n`, { ids: plan.ids });
219
+ else if (plan.filter) {
220
+ const targets = (await this.#run(`MATCH (n:${label}) RETURN n.id AS id, n.metadata AS metadata`)).filter((rec) => require_batteries_vector_filters.evaluateFilter(plan.filter, this.#parseMeta(rec.get("metadata")))).map((rec) => rec.get("id"));
221
+ if (targets.length > 0) await this.#run(`MATCH (n:${label}) WHERE n.id IN $ids DETACH DELETE n`, { ids: targets });
222
+ } else await this.#run(`MATCH (n:${label}) DETACH DELETE n`);
223
+ } catch (err) {
224
+ throw new require_batteries_vector_exceptions.E_VECTOR_STORE_DELETE_FAILED([String(err)]);
225
+ }
226
+ }
227
+ };
228
+ //#endregion
229
+ exports.Neo4jVectorStore = Neo4jVectorStore;
230
+
231
+ //# sourceMappingURL=neo4j.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"neo4j.cjs","names":["#opts","#driver","#neo4j","#run","#dims","#parseMeta","#project"],"sources":["../../../src/batteries/vector/neo4j/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/neo4j\n *\n * Neo4j adapter (native vector index, 5.13+). Each collection is a node label; records are\n * nodes with `id`/`vec`/`document`/`metadata` properties and a `VECTOR INDEX` on `vec`. KNN\n * uses `db.index.vector.queryNodes(index, k, vector)` (score is the similarity, already [0,1]\n * for cosine). Metadata is a JSON string property filtered with the neutral filter tree's JS\n * reference evaluator for exact cross-adapter parity.\n *\n * Driver: `neo4j-driver` (pure JS). Labels/index names can't be Cypher-parameterized, so they\n * are derived from the (sanitized) collection name; all values are parameterized.\n */\n\nimport { evaluateFilter } from '../filters'\nimport { BaseVectorStore } from '../contract'\nimport { validateRecords } from '../validation'\nimport { isInstanceOf } from '@nhtio/adk/guards'\nimport {\n E_VECTOR_STORE_DRIVER_UNAVAILABLE,\n E_VECTOR_STORE_CONNECTION_FAILED,\n E_VECTOR_STORE_COLLECTION_FAILED,\n E_VECTOR_STORE_UPSERT_FAILED,\n E_VECTOR_STORE_SEARCH_FAILED,\n E_VECTOR_STORE_DELETE_FAILED,\n E_VECTOR_STORE_DIMENSION_MISMATCH,\n E_VECTOR_STORE_UNSUPPORTED_OPERATION,\n} from '../exceptions'\nimport type { SearchPlan, UpsertPlan, DeletePlan, CollectionSpec } from '../plan'\nimport type {\n VectorMatch,\n VectorStoreCapabilities,\n BaseVectorStoreOptions,\n VectorMetadata,\n DistanceMetric,\n} from '../types'\n\nexport interface Neo4jVectorStoreOptions extends BaseVectorStoreOptions {\n connection: { url: string; username?: string; password?: string; database?: string }\n}\n\nconst getNeo4j = async () => {\n try {\n const mod = await import('neo4j-driver')\n return (mod as any).default ?? mod\n } catch {\n throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(['neo4j-driver'])\n }\n}\n\n// A Cypher-safe label/index token derived from the collection (labels can't be parameterized).\nconst sanitize = (name: string): string => name.replace(/[^A-Za-z0-9_]/g, '_')\nconst labelFor = (collection: string): string => 'Vec_' + sanitize(collection)\nconst indexFor = (collection: string): string => 'vecidx_' + sanitize(collection)\n\nconst similarityFn = (metric: DistanceMetric): string =>\n metric === 'euclidean' ? 'euclidean' : 'cosine'\n\nexport class Neo4jVectorStore extends BaseVectorStore {\n readonly capabilities: VectorStoreCapabilities = {\n transactions: false,\n namedVectors: false,\n rename: false,\n rawSql: false,\n builtInEncoding: false,\n // Writes commit synchronously over Bolt and the index awaits; visible on resolve. No-op option.\n consistency: { configurable: false, default: 'strong', modes: ['strong'] },\n }\n\n #driver: any | null = null\n #neo4j: any | null = null\n #dims: Map<string, number> = new Map()\n\n get #opts(): Neo4jVectorStoreOptions {\n return this.options as Neo4jVectorStoreOptions\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.#driver) return\n const neo4j = await getNeo4j()\n this.#neo4j = neo4j\n const c = this.#opts.connection\n try {\n this.#driver = neo4j.driver(\n c.url,\n c.username ? neo4j.auth.basic(c.username, c.password ?? '') : undefined\n )\n } catch (err) {\n throw new E_VECTOR_STORE_CONNECTION_FAILED([String(err)])\n }\n }\n\n async close(): Promise<void> {\n if (this.#driver) {\n await this.#driver.close()\n this.#driver = null\n }\n }\n\n async #run(cypher: string, params?: Record<string, unknown>): Promise<any[]> {\n if (!this.#driver) await this.connect()\n const db = this.#opts.connection.database\n const session = this.#driver.session(db ? { database: db } : undefined)\n try {\n const res = await session.run(cypher, params)\n return res.records\n } finally {\n await session.close()\n }\n }\n\n async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n this.#dims.set(spec.collection, spec.vector.dimensions)\n const label = labelFor(spec.collection)\n const index = indexFor(spec.collection)\n try {\n if (!ifNotExists) {\n await this.#run(`DROP INDEX ${index} IF EXISTS`)\n }\n await this.#run(\n `CREATE VECTOR INDEX ${index} IF NOT EXISTS FOR (n:${label}) ON (n.vec) ` +\n `OPTIONS {indexConfig: {\\`vector.dimensions\\`: $dim, \\`vector.similarity_function\\`: $sim}}`,\n { dim: this.#neo4j.int(spec.vector.dimensions), sim: similarityFn(spec.vector.metric) }\n )\n await this.#run(`CALL db.awaitIndex($index, $timeout)`, {\n index,\n timeout: this.#neo4j.int(30),\n }).catch(() => undefined)\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 label = labelFor(collection)\n const index = indexFor(collection)\n try {\n await this.#run(`DROP INDEX ${index} IF EXISTS`)\n await this.#run(`MATCH (n:${label}) DETACH DELETE n`)\n this.#dims.delete(collection)\n } catch (err) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['dropCollection', String(err)])\n }\n }\n\n async hasCollection(collection: string): Promise<boolean> {\n const index = indexFor(collection)\n try {\n const recs = await this.#run(`SHOW INDEXES YIELD name WHERE name = $index RETURN name`, {\n index,\n })\n return recs.length > 0\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', 'neo4j'])\n }\n\n async executeUpsert(plan: UpsertPlan): Promise<void> {\n if (plan.records.length === 0) return\n validateRecords(plan.records)\n const label = labelFor(plan.collection)\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 await this.#run(\n `MERGE (n:${label} {id: $id}) ` +\n `SET n.vec = $vec, n.document = $document, n.metadata = $metadata`,\n {\n id: r.id,\n vec: vector,\n document: r.document ?? '',\n metadata: r.metadata ? JSON.stringify(r.metadata) : '{}',\n }\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 label = labelFor(plan.collection)\n const index = indexFor(plan.collection)\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 recs = await this.#run(`MATCH (n:${label} {id: $id}) RETURN n.vec AS vec`, {\n id: plan.near.id,\n })\n if (recs.length === 0) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n queryVector = recs[0].get('vec') as number[]\n }\n }\n\n const offset = plan.offset ?? 0\n try {\n if (queryVector) {\n // Over-fetch when filtering so the JS post-filter still yields topK.\n const k = plan.filter ? 1000 : plan.topK + offset\n const recs = await this.#run(\n `CALL db.index.vector.queryNodes($index, $k, $qv) YIELD node, score ` +\n `RETURN node.id AS id, node.vec AS vec, node.document AS document, ` +\n `node.metadata AS metadata, score ORDER BY score DESC`,\n { index, k: this.#neo4j.int(k), qv: queryVector }\n )\n const mapped = recs.map((rec: any) => ({\n row: {\n id: rec.get('id'),\n vec: rec.get('vec'),\n document: rec.get('document'),\n metadata: rec.get('metadata'),\n score: rec.get('score'),\n },\n }))\n const filtered = plan.filter\n ? mapped.filter((m: any) => evaluateFilter(plan.filter!, this.#parseMeta(m.row.metadata)))\n : mapped\n return filtered\n .slice(offset, offset + plan.topK)\n .map((m: any) => this.#project(m.row, plan, true))\n } else {\n const recs = await this.#run(\n `MATCH (n:${label}) RETURN n.id AS id, n.vec AS vec, n.document AS document, n.metadata AS metadata`\n )\n const rows = recs.map((rec: any) => ({\n id: rec.get('id'),\n vec: rec.get('vec'),\n document: rec.get('document'),\n metadata: rec.get('metadata'),\n }))\n const filtered = plan.filter\n ? rows.filter((row: any) => evaluateFilter(plan.filter!, this.#parseMeta(row.metadata)))\n : rows\n return filtered\n .slice(offset, offset + plan.topK)\n .map((row: any) => this.#project(row, plan, false))\n }\n } catch (err) {\n throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)])\n }\n }\n\n #parseMeta(val: unknown): VectorMetadata {\n if (typeof val === 'string') {\n try {\n return JSON.parse(val) as VectorMetadata\n } catch {\n return {}\n }\n }\n if (val && typeof val === 'object') return val as VectorMetadata\n return {}\n }\n\n #project(row: any, plan: SearchPlan, isKnn: boolean): VectorMatch {\n const proj = plan.projection\n const out: VectorMatch = {}\n if (proj.id) out.id = row.id as string\n if (proj.vector && Array.isArray(row.vec)) out.vector = (row.vec as number[]).map(Number)\n if (proj.document) out.document = (row.document ?? undefined) as string | undefined\n if (proj.metadata) out.metadata = this.#parseMeta(row.metadata)\n if (isKnn && row.score !== undefined && row.score !== null) {\n // Neo4j cosine similarity score is already in [0,1], higher = closer.\n out.score = Number(row.score)\n }\n return out\n }\n\n async executeDelete(plan: DeletePlan): Promise<void> {\n const label = labelFor(plan.collection)\n try {\n if (plan.ids && plan.ids.length > 0) {\n await this.#run(`MATCH (n:${label}) WHERE n.id IN $ids DETACH DELETE n`, { ids: plan.ids })\n } else if (plan.filter) {\n const recs = await this.#run(`MATCH (n:${label}) RETURN n.id AS id, n.metadata AS metadata`)\n const targets = recs\n .filter((rec: any) => evaluateFilter(plan.filter!, this.#parseMeta(rec.get('metadata'))))\n .map((rec: any) => rec.get('id') as string)\n if (targets.length > 0) {\n await this.#run(`MATCH (n:${label}) WHERE n.id IN $ids DETACH DELETE n`, { ids: targets })\n }\n } else {\n await this.#run(`MATCH (n:${label}) DETACH DELETE n`)\n }\n } catch (err) {\n throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n }\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,229 @@
1
+ import { s as isInstanceOf } from "../../tool_registry-D1pSSlsd.mjs";
2
+ import "../../guards.mjs";
3
+ import { evaluateFilter } from "./filters.mjs";
4
+ import { E_VECTOR_STORE_COLLECTION_FAILED, E_VECTOR_STORE_CONNECTION_FAILED, E_VECTOR_STORE_DELETE_FAILED, E_VECTOR_STORE_DIMENSION_MISMATCH, E_VECTOR_STORE_DRIVER_UNAVAILABLE, E_VECTOR_STORE_SEARCH_FAILED, E_VECTOR_STORE_UNSUPPORTED_OPERATION, E_VECTOR_STORE_UPSERT_FAILED } from "./exceptions.mjs";
5
+ import { BaseVectorStore } from "./contract.mjs";
6
+ import { validateRecords } from "./validation.mjs";
7
+ //#region src/batteries/vector/neo4j/index.ts
8
+ /**
9
+ * @module @nhtio/adk/batteries/vector/neo4j
10
+ *
11
+ * Neo4j adapter (native vector index, 5.13+). Each collection is a node label; records are
12
+ * nodes with `id`/`vec`/`document`/`metadata` properties and a `VECTOR INDEX` on `vec`. KNN
13
+ * uses `db.index.vector.queryNodes(index, k, vector)` (score is the similarity, already [0,1]
14
+ * for cosine). Metadata is a JSON string property filtered with the neutral filter tree's JS
15
+ * reference evaluator for exact cross-adapter parity.
16
+ *
17
+ * Driver: `neo4j-driver` (pure JS). Labels/index names can't be Cypher-parameterized, so they
18
+ * are derived from the (sanitized) collection name; all values are parameterized.
19
+ */
20
+ var getNeo4j = async () => {
21
+ try {
22
+ const mod = await import("neo4j-driver");
23
+ return mod.default ?? mod;
24
+ } catch {
25
+ throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(["neo4j-driver"]);
26
+ }
27
+ };
28
+ var sanitize = (name) => name.replace(/[^A-Za-z0-9_]/g, "_");
29
+ var labelFor = (collection) => "Vec_" + sanitize(collection);
30
+ var indexFor = (collection) => "vecidx_" + sanitize(collection);
31
+ var similarityFn = (metric) => metric === "euclidean" ? "euclidean" : "cosine";
32
+ var Neo4jVectorStore = class extends BaseVectorStore {
33
+ capabilities = {
34
+ transactions: false,
35
+ namedVectors: false,
36
+ rename: false,
37
+ rawSql: false,
38
+ builtInEncoding: false,
39
+ consistency: {
40
+ configurable: false,
41
+ default: "strong",
42
+ modes: ["strong"]
43
+ }
44
+ };
45
+ #driver = null;
46
+ #neo4j = null;
47
+ #dims = /* @__PURE__ */ new Map();
48
+ get #opts() {
49
+ return this.options;
50
+ }
51
+ static isAvailable() {
52
+ return typeof process !== "undefined";
53
+ }
54
+ isAvailable() {
55
+ return typeof process !== "undefined";
56
+ }
57
+ async connect() {
58
+ if (this.#driver) return;
59
+ const neo4j = await getNeo4j();
60
+ this.#neo4j = neo4j;
61
+ const c = this.#opts.connection;
62
+ try {
63
+ this.#driver = neo4j.driver(c.url, c.username ? neo4j.auth.basic(c.username, c.password ?? "") : void 0);
64
+ } catch (err) {
65
+ throw new E_VECTOR_STORE_CONNECTION_FAILED([String(err)]);
66
+ }
67
+ }
68
+ async close() {
69
+ if (this.#driver) {
70
+ await this.#driver.close();
71
+ this.#driver = null;
72
+ }
73
+ }
74
+ async #run(cypher, params) {
75
+ if (!this.#driver) await this.connect();
76
+ const db = this.#opts.connection.database;
77
+ const session = this.#driver.session(db ? { database: db } : void 0);
78
+ try {
79
+ return (await session.run(cypher, params)).records;
80
+ } finally {
81
+ await session.close();
82
+ }
83
+ }
84
+ async createCollection(spec, ifNotExists) {
85
+ this.#dims.set(spec.collection, spec.vector.dimensions);
86
+ const label = labelFor(spec.collection);
87
+ const index = indexFor(spec.collection);
88
+ try {
89
+ if (!ifNotExists) await this.#run(`DROP INDEX ${index} IF EXISTS`);
90
+ await this.#run(`CREATE VECTOR INDEX ${index} IF NOT EXISTS FOR (n:${label}) ON (n.vec) OPTIONS {indexConfig: {\`vector.dimensions\`: $dim, \`vector.similarity_function\`: $sim}}`, {
91
+ dim: this.#neo4j.int(spec.vector.dimensions),
92
+ sim: similarityFn(spec.vector.metric)
93
+ });
94
+ await this.#run(`CALL db.awaitIndex($index, $timeout)`, {
95
+ index,
96
+ timeout: this.#neo4j.int(30)
97
+ }).catch(() => void 0);
98
+ } catch (err) {
99
+ throw new E_VECTOR_STORE_COLLECTION_FAILED(["createCollection", String(err)]);
100
+ }
101
+ }
102
+ async dropCollection(collection, _ifExists) {
103
+ const label = labelFor(collection);
104
+ const index = indexFor(collection);
105
+ try {
106
+ await this.#run(`DROP INDEX ${index} IF EXISTS`);
107
+ await this.#run(`MATCH (n:${label}) DETACH DELETE n`);
108
+ this.#dims.delete(collection);
109
+ } catch (err) {
110
+ throw new E_VECTOR_STORE_COLLECTION_FAILED(["dropCollection", String(err)]);
111
+ }
112
+ }
113
+ async hasCollection(collection) {
114
+ const index = indexFor(collection);
115
+ try {
116
+ return (await this.#run(`SHOW INDEXES YIELD name WHERE name = $index RETURN name`, { index })).length > 0;
117
+ } catch {
118
+ return false;
119
+ }
120
+ }
121
+ async renameCollection(_from, _to) {
122
+ throw new E_VECTOR_STORE_UNSUPPORTED_OPERATION(["renameCollection", "neo4j"]);
123
+ }
124
+ async executeUpsert(plan) {
125
+ if (plan.records.length === 0) return;
126
+ validateRecords(plan.records);
127
+ const label = labelFor(plan.collection);
128
+ const expected = this.#opts.dimensions ?? this.#dims.get(plan.collection);
129
+ try {
130
+ for (const r of plan.records) {
131
+ let vector = r.vector;
132
+ if (!vector && r.document) {
133
+ const [v] = await this.encode([r.document], "document");
134
+ vector = v;
135
+ }
136
+ if (!vector) throw new E_VECTOR_STORE_UPSERT_FAILED(["Record missing vector and document"]);
137
+ if (expected !== void 0 && vector.length !== expected) throw new E_VECTOR_STORE_DIMENSION_MISMATCH([expected, vector.length]);
138
+ await this.#run(`MERGE (n:${label} {id: $id}) SET n.vec = $vec, n.document = $document, n.metadata = $metadata`, {
139
+ id: r.id,
140
+ vec: vector,
141
+ document: r.document ?? "",
142
+ metadata: r.metadata ? JSON.stringify(r.metadata) : "{}"
143
+ });
144
+ }
145
+ } catch (err) {
146
+ if (isInstanceOf(err, "E_VECTOR_STORE_DIMENSION_MISMATCH", E_VECTOR_STORE_DIMENSION_MISMATCH) || isInstanceOf(err, "E_VECTOR_STORE_UPSERT_FAILED", E_VECTOR_STORE_UPSERT_FAILED)) throw err;
147
+ throw new E_VECTOR_STORE_UPSERT_FAILED([String(err)]);
148
+ }
149
+ }
150
+ async executeSearch(plan) {
151
+ const label = labelFor(plan.collection);
152
+ const index = indexFor(plan.collection);
153
+ let queryVector;
154
+ if (plan.near) {
155
+ if ("vector" in plan.near) queryVector = plan.near.vector;
156
+ else if ("serverText" in plan.near) {
157
+ const [v] = await this.encode([plan.near.serverText], "query");
158
+ queryVector = v;
159
+ } else if ("id" in plan.near) {
160
+ const recs = await this.#run(`MATCH (n:${label} {id: $id}) RETURN n.vec AS vec`, { id: plan.near.id });
161
+ if (recs.length === 0) throw new E_VECTOR_STORE_SEARCH_FAILED(["Referenced id not found: " + plan.near.id]);
162
+ queryVector = recs[0].get("vec");
163
+ }
164
+ }
165
+ const offset = plan.offset ?? 0;
166
+ try {
167
+ if (queryVector) {
168
+ const k = plan.filter ? 1e3 : plan.topK + offset;
169
+ const mapped = (await this.#run("CALL db.index.vector.queryNodes($index, $k, $qv) YIELD node, score RETURN node.id AS id, node.vec AS vec, node.document AS document, node.metadata AS metadata, score ORDER BY score DESC", {
170
+ index,
171
+ k: this.#neo4j.int(k),
172
+ qv: queryVector
173
+ })).map((rec) => ({ row: {
174
+ id: rec.get("id"),
175
+ vec: rec.get("vec"),
176
+ document: rec.get("document"),
177
+ metadata: rec.get("metadata"),
178
+ score: rec.get("score")
179
+ } }));
180
+ return (plan.filter ? mapped.filter((m) => evaluateFilter(plan.filter, this.#parseMeta(m.row.metadata))) : mapped).slice(offset, offset + plan.topK).map((m) => this.#project(m.row, plan, true));
181
+ } else {
182
+ const rows = (await this.#run(`MATCH (n:${label}) RETURN n.id AS id, n.vec AS vec, n.document AS document, n.metadata AS metadata`)).map((rec) => ({
183
+ id: rec.get("id"),
184
+ vec: rec.get("vec"),
185
+ document: rec.get("document"),
186
+ metadata: rec.get("metadata")
187
+ }));
188
+ return (plan.filter ? rows.filter((row) => evaluateFilter(plan.filter, this.#parseMeta(row.metadata))) : rows).slice(offset, offset + plan.topK).map((row) => this.#project(row, plan, false));
189
+ }
190
+ } catch (err) {
191
+ throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)]);
192
+ }
193
+ }
194
+ #parseMeta(val) {
195
+ if (typeof val === "string") try {
196
+ return JSON.parse(val);
197
+ } catch {
198
+ return {};
199
+ }
200
+ if (val && typeof val === "object") return val;
201
+ return {};
202
+ }
203
+ #project(row, plan, isKnn) {
204
+ const proj = plan.projection;
205
+ const out = {};
206
+ if (proj.id) out.id = row.id;
207
+ if (proj.vector && Array.isArray(row.vec)) out.vector = row.vec.map(Number);
208
+ if (proj.document) out.document = row.document ?? void 0;
209
+ if (proj.metadata) out.metadata = this.#parseMeta(row.metadata);
210
+ if (isKnn && row.score !== void 0 && row.score !== null) out.score = Number(row.score);
211
+ return out;
212
+ }
213
+ async executeDelete(plan) {
214
+ const label = labelFor(plan.collection);
215
+ try {
216
+ if (plan.ids && plan.ids.length > 0) await this.#run(`MATCH (n:${label}) WHERE n.id IN $ids DETACH DELETE n`, { ids: plan.ids });
217
+ else if (plan.filter) {
218
+ const targets = (await this.#run(`MATCH (n:${label}) RETURN n.id AS id, n.metadata AS metadata`)).filter((rec) => evaluateFilter(plan.filter, this.#parseMeta(rec.get("metadata")))).map((rec) => rec.get("id"));
219
+ if (targets.length > 0) await this.#run(`MATCH (n:${label}) WHERE n.id IN $ids DETACH DELETE n`, { ids: targets });
220
+ } else await this.#run(`MATCH (n:${label}) DETACH DELETE n`);
221
+ } catch (err) {
222
+ throw new E_VECTOR_STORE_DELETE_FAILED([String(err)]);
223
+ }
224
+ }
225
+ };
226
+ //#endregion
227
+ export { Neo4jVectorStore };
228
+
229
+ //# sourceMappingURL=neo4j.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"neo4j.mjs","names":["#opts","#driver","#neo4j","#run","#dims","#parseMeta","#project"],"sources":["../../../src/batteries/vector/neo4j/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/neo4j\n *\n * Neo4j adapter (native vector index, 5.13+). Each collection is a node label; records are\n * nodes with `id`/`vec`/`document`/`metadata` properties and a `VECTOR INDEX` on `vec`. KNN\n * uses `db.index.vector.queryNodes(index, k, vector)` (score is the similarity, already [0,1]\n * for cosine). Metadata is a JSON string property filtered with the neutral filter tree's JS\n * reference evaluator for exact cross-adapter parity.\n *\n * Driver: `neo4j-driver` (pure JS). Labels/index names can't be Cypher-parameterized, so they\n * are derived from the (sanitized) collection name; all values are parameterized.\n */\n\nimport { evaluateFilter } from '../filters'\nimport { BaseVectorStore } from '../contract'\nimport { validateRecords } from '../validation'\nimport { isInstanceOf } from '@nhtio/adk/guards'\nimport {\n E_VECTOR_STORE_DRIVER_UNAVAILABLE,\n E_VECTOR_STORE_CONNECTION_FAILED,\n E_VECTOR_STORE_COLLECTION_FAILED,\n E_VECTOR_STORE_UPSERT_FAILED,\n E_VECTOR_STORE_SEARCH_FAILED,\n E_VECTOR_STORE_DELETE_FAILED,\n E_VECTOR_STORE_DIMENSION_MISMATCH,\n E_VECTOR_STORE_UNSUPPORTED_OPERATION,\n} from '../exceptions'\nimport type { SearchPlan, UpsertPlan, DeletePlan, CollectionSpec } from '../plan'\nimport type {\n VectorMatch,\n VectorStoreCapabilities,\n BaseVectorStoreOptions,\n VectorMetadata,\n DistanceMetric,\n} from '../types'\n\nexport interface Neo4jVectorStoreOptions extends BaseVectorStoreOptions {\n connection: { url: string; username?: string; password?: string; database?: string }\n}\n\nconst getNeo4j = async () => {\n try {\n const mod = await import('neo4j-driver')\n return (mod as any).default ?? mod\n } catch {\n throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(['neo4j-driver'])\n }\n}\n\n// A Cypher-safe label/index token derived from the collection (labels can't be parameterized).\nconst sanitize = (name: string): string => name.replace(/[^A-Za-z0-9_]/g, '_')\nconst labelFor = (collection: string): string => 'Vec_' + sanitize(collection)\nconst indexFor = (collection: string): string => 'vecidx_' + sanitize(collection)\n\nconst similarityFn = (metric: DistanceMetric): string =>\n metric === 'euclidean' ? 'euclidean' : 'cosine'\n\nexport class Neo4jVectorStore extends BaseVectorStore {\n readonly capabilities: VectorStoreCapabilities = {\n transactions: false,\n namedVectors: false,\n rename: false,\n rawSql: false,\n builtInEncoding: false,\n // Writes commit synchronously over Bolt and the index awaits; visible on resolve. No-op option.\n consistency: { configurable: false, default: 'strong', modes: ['strong'] },\n }\n\n #driver: any | null = null\n #neo4j: any | null = null\n #dims: Map<string, number> = new Map()\n\n get #opts(): Neo4jVectorStoreOptions {\n return this.options as Neo4jVectorStoreOptions\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.#driver) return\n const neo4j = await getNeo4j()\n this.#neo4j = neo4j\n const c = this.#opts.connection\n try {\n this.#driver = neo4j.driver(\n c.url,\n c.username ? neo4j.auth.basic(c.username, c.password ?? '') : undefined\n )\n } catch (err) {\n throw new E_VECTOR_STORE_CONNECTION_FAILED([String(err)])\n }\n }\n\n async close(): Promise<void> {\n if (this.#driver) {\n await this.#driver.close()\n this.#driver = null\n }\n }\n\n async #run(cypher: string, params?: Record<string, unknown>): Promise<any[]> {\n if (!this.#driver) await this.connect()\n const db = this.#opts.connection.database\n const session = this.#driver.session(db ? { database: db } : undefined)\n try {\n const res = await session.run(cypher, params)\n return res.records\n } finally {\n await session.close()\n }\n }\n\n async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n this.#dims.set(spec.collection, spec.vector.dimensions)\n const label = labelFor(spec.collection)\n const index = indexFor(spec.collection)\n try {\n if (!ifNotExists) {\n await this.#run(`DROP INDEX ${index} IF EXISTS`)\n }\n await this.#run(\n `CREATE VECTOR INDEX ${index} IF NOT EXISTS FOR (n:${label}) ON (n.vec) ` +\n `OPTIONS {indexConfig: {\\`vector.dimensions\\`: $dim, \\`vector.similarity_function\\`: $sim}}`,\n { dim: this.#neo4j.int(spec.vector.dimensions), sim: similarityFn(spec.vector.metric) }\n )\n await this.#run(`CALL db.awaitIndex($index, $timeout)`, {\n index,\n timeout: this.#neo4j.int(30),\n }).catch(() => undefined)\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 label = labelFor(collection)\n const index = indexFor(collection)\n try {\n await this.#run(`DROP INDEX ${index} IF EXISTS`)\n await this.#run(`MATCH (n:${label}) DETACH DELETE n`)\n this.#dims.delete(collection)\n } catch (err) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['dropCollection', String(err)])\n }\n }\n\n async hasCollection(collection: string): Promise<boolean> {\n const index = indexFor(collection)\n try {\n const recs = await this.#run(`SHOW INDEXES YIELD name WHERE name = $index RETURN name`, {\n index,\n })\n return recs.length > 0\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', 'neo4j'])\n }\n\n async executeUpsert(plan: UpsertPlan): Promise<void> {\n if (plan.records.length === 0) return\n validateRecords(plan.records)\n const label = labelFor(plan.collection)\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 await this.#run(\n `MERGE (n:${label} {id: $id}) ` +\n `SET n.vec = $vec, n.document = $document, n.metadata = $metadata`,\n {\n id: r.id,\n vec: vector,\n document: r.document ?? '',\n metadata: r.metadata ? JSON.stringify(r.metadata) : '{}',\n }\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 label = labelFor(plan.collection)\n const index = indexFor(plan.collection)\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 recs = await this.#run(`MATCH (n:${label} {id: $id}) RETURN n.vec AS vec`, {\n id: plan.near.id,\n })\n if (recs.length === 0) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n queryVector = recs[0].get('vec') as number[]\n }\n }\n\n const offset = plan.offset ?? 0\n try {\n if (queryVector) {\n // Over-fetch when filtering so the JS post-filter still yields topK.\n const k = plan.filter ? 1000 : plan.topK + offset\n const recs = await this.#run(\n `CALL db.index.vector.queryNodes($index, $k, $qv) YIELD node, score ` +\n `RETURN node.id AS id, node.vec AS vec, node.document AS document, ` +\n `node.metadata AS metadata, score ORDER BY score DESC`,\n { index, k: this.#neo4j.int(k), qv: queryVector }\n )\n const mapped = recs.map((rec: any) => ({\n row: {\n id: rec.get('id'),\n vec: rec.get('vec'),\n document: rec.get('document'),\n metadata: rec.get('metadata'),\n score: rec.get('score'),\n },\n }))\n const filtered = plan.filter\n ? mapped.filter((m: any) => evaluateFilter(plan.filter!, this.#parseMeta(m.row.metadata)))\n : mapped\n return filtered\n .slice(offset, offset + plan.topK)\n .map((m: any) => this.#project(m.row, plan, true))\n } else {\n const recs = await this.#run(\n `MATCH (n:${label}) RETURN n.id AS id, n.vec AS vec, n.document AS document, n.metadata AS metadata`\n )\n const rows = recs.map((rec: any) => ({\n id: rec.get('id'),\n vec: rec.get('vec'),\n document: rec.get('document'),\n metadata: rec.get('metadata'),\n }))\n const filtered = plan.filter\n ? rows.filter((row: any) => evaluateFilter(plan.filter!, this.#parseMeta(row.metadata)))\n : rows\n return filtered\n .slice(offset, offset + plan.topK)\n .map((row: any) => this.#project(row, plan, false))\n }\n } catch (err) {\n throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)])\n }\n }\n\n #parseMeta(val: unknown): VectorMetadata {\n if (typeof val === 'string') {\n try {\n return JSON.parse(val) as VectorMetadata\n } catch {\n return {}\n }\n }\n if (val && typeof val === 'object') return val as VectorMetadata\n return {}\n }\n\n #project(row: any, plan: SearchPlan, isKnn: boolean): VectorMatch {\n const proj = plan.projection\n const out: VectorMatch = {}\n if (proj.id) out.id = row.id as string\n if (proj.vector && Array.isArray(row.vec)) out.vector = (row.vec as number[]).map(Number)\n if (proj.document) out.document = (row.document ?? undefined) as string | undefined\n if (proj.metadata) out.metadata = this.#parseMeta(row.metadata)\n if (isKnn && row.score !== undefined && row.score !== null) {\n // Neo4j cosine similarity score is already in [0,1], higher = closer.\n out.score = Number(row.score)\n }\n return out\n }\n\n async executeDelete(plan: DeletePlan): Promise<void> {\n const label = labelFor(plan.collection)\n try {\n if (plan.ids && plan.ids.length > 0) {\n await this.#run(`MATCH (n:${label}) WHERE n.id IN $ids DETACH DELETE n`, { ids: plan.ids })\n } else if (plan.filter) {\n const recs = await this.#run(`MATCH (n:${label}) RETURN n.id AS id, n.metadata AS metadata`)\n const targets = recs\n .filter((rec: any) => evaluateFilter(plan.filter!, this.#parseMeta(rec.get('metadata'))))\n .map((rec: any) => rec.get('id') as string)\n if (targets.length > 0) {\n await this.#run(`MATCH (n:${label}) WHERE n.id IN $ids DETACH DELETE n`, { ids: targets })\n }\n } else {\n await this.#run(`MATCH (n:${label}) DETACH DELETE n`)\n }\n } catch (err) {\n throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n }\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @module @nhtio/adk/batteries/vector/opensearch
3
+ *
4
+ * One adapter for the Elasticsearch / OpenSearch family — they share the same kNN `_search`
5
+ * data model. Each collection is an index with a `knn_vector` field; KNN search uses the
6
+ * native `knn` query, and the neutral filter tree compiles to a bool-query `filter` over
7
+ * `metadata.*` keyword/numeric sub-fields. The document and id live in `_source`.
8
+ *
9
+ * Driver: `@opensearch-project/opensearch` by default. To target Elasticsearch instead,
10
+ * pass a compatible client instance via `options.connection.client` (the `@elastic/elasticsearch`
11
+ * Client has the same `.indices`/`.index`/`.search`/`.deleteByQuery` surface used here).
12
+ */
13
+ import { BaseVectorStore } from "../contract";
14
+ import type { VectorFilter } from "../filters";
15
+ import type { SearchPlan, UpsertPlan, DeletePlan, CollectionSpec } from "../plan";
16
+ import type { VectorMatch, VectorStoreCapabilities, BaseVectorStoreOptions } from "../types";
17
+ export interface OpenSearchVectorStoreOptions extends BaseVectorStoreOptions {
18
+ connection?: {
19
+ node?: string;
20
+ auth?: {
21
+ username: string;
22
+ password: string;
23
+ };
24
+ client?: unknown;
25
+ };
26
+ }
27
+ /**
28
+ * Compile the neutral filter tree to an OpenSearch bool-query clause over `metadata.*`.
29
+ * String values use the `.keyword` sub-field for exact match; numbers use range/term.
30
+ */
31
+ export declare const translateOpenSearchFilter: (filter?: VectorFilter) => Record<string, unknown> | undefined;
32
+ export declare class OpenSearchVectorStore extends BaseVectorStore {
33
+ #private;
34
+ readonly capabilities: VectorStoreCapabilities;
35
+ static isAvailable(): boolean;
36
+ isAvailable(): boolean;
37
+ connect(): Promise<void>;
38
+ close(): Promise<void>;
39
+ createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void>;
40
+ dropCollection(collection: string, ifExists: boolean): Promise<void>;
41
+ hasCollection(collection: string): Promise<boolean>;
42
+ renameCollection(_from: string, _to: string): Promise<void>;
43
+ executeUpsert(plan: UpsertPlan): Promise<void>;
44
+ executeSearch(plan: SearchPlan): Promise<VectorMatch[]>;
45
+ executeDelete(plan: DeletePlan): Promise<void>;
46
+ }