@nhtio/adk 1.20260607.2 → 1.20260609.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 (501) hide show
  1. package/CHANGELOG.md +185 -0
  2. package/batteries/embeddings/openai/adapter.cjs +1 -1
  3. package/batteries/embeddings/openai/adapter.mjs +1 -1
  4. package/batteries/embeddings/openai/exceptions.cjs +1 -1
  5. package/batteries/embeddings/openai/exceptions.mjs +1 -1
  6. package/batteries/embeddings/openai/types.d.ts +7 -0
  7. package/batteries/embeddings/webllm/adapter.cjs +1 -1
  8. package/batteries/embeddings/webllm/adapter.mjs +1 -1
  9. package/batteries/embeddings/webllm/exceptions.cjs +1 -1
  10. package/batteries/embeddings/webllm/exceptions.mjs +1 -1
  11. package/batteries/llm/chat_common/helpers.d.ts +165 -0
  12. package/batteries/llm/chat_common/types.d.ts +309 -0
  13. package/batteries/llm/index.d.ts +5 -0
  14. package/batteries/llm/ollama/adapter.cjs +736 -0
  15. package/batteries/llm/ollama/adapter.cjs.map +1 -0
  16. package/batteries/llm/ollama/adapter.d.ts +64 -0
  17. package/batteries/llm/ollama/adapter.mjs +734 -0
  18. package/batteries/llm/ollama/adapter.mjs.map +1 -0
  19. package/batteries/llm/ollama/exceptions.cjs +105 -0
  20. package/batteries/llm/ollama/exceptions.cjs.map +1 -0
  21. package/batteries/llm/ollama/exceptions.d.ts +112 -0
  22. package/batteries/llm/ollama/exceptions.mjs +96 -0
  23. package/batteries/llm/ollama/exceptions.mjs.map +1 -0
  24. package/batteries/llm/ollama/helpers.cjs +487 -0
  25. package/batteries/llm/ollama/helpers.cjs.map +1 -0
  26. package/batteries/llm/ollama/helpers.d.ts +158 -0
  27. package/batteries/llm/ollama/helpers.mjs +450 -0
  28. package/batteries/llm/ollama/helpers.mjs.map +1 -0
  29. package/batteries/llm/ollama/index.d.ts +29 -0
  30. package/batteries/llm/ollama/types.cjs +2 -0
  31. package/batteries/llm/ollama/types.d.ts +334 -0
  32. package/batteries/llm/ollama/types.mjs +0 -0
  33. package/batteries/llm/ollama/validation.cjs +130 -0
  34. package/batteries/llm/ollama/validation.cjs.map +1 -0
  35. package/batteries/llm/ollama/validation.d.ts +31 -0
  36. package/batteries/llm/ollama/validation.mjs +127 -0
  37. package/batteries/llm/ollama/validation.mjs.map +1 -0
  38. package/batteries/llm/ollama.cjs +54 -0
  39. package/batteries/llm/ollama.mjs +6 -0
  40. package/batteries/llm/openai_chat_completions/adapter.cjs +36 -19
  41. package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -1
  42. package/batteries/llm/openai_chat_completions/adapter.mjs +23 -6
  43. package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -1
  44. package/batteries/llm/openai_chat_completions/exceptions.cjs +1 -1
  45. package/batteries/llm/openai_chat_completions/exceptions.mjs +1 -1
  46. package/batteries/llm/openai_chat_completions/helpers.cjs +80 -320
  47. package/batteries/llm/openai_chat_completions/helpers.cjs.map +1 -1
  48. package/batteries/llm/openai_chat_completions/helpers.d.ts +68 -144
  49. package/batteries/llm/openai_chat_completions/helpers.mjs +40 -280
  50. package/batteries/llm/openai_chat_completions/helpers.mjs.map +1 -1
  51. package/batteries/llm/openai_chat_completions/types.d.ts +273 -181
  52. package/batteries/llm/openai_chat_completions/validation.cjs +2 -2
  53. package/batteries/llm/openai_chat_completions/validation.cjs.map +1 -1
  54. package/batteries/llm/openai_chat_completions/validation.mjs +2 -2
  55. package/batteries/llm/openai_chat_completions/validation.mjs.map +1 -1
  56. package/batteries/llm/openai_chat_completions.cjs +29 -28
  57. package/batteries/llm/openai_chat_completions.mjs +2 -1
  58. package/batteries/llm/webllm_chat_completions/adapter.cjs +38 -19
  59. package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -1
  60. package/batteries/llm/webllm_chat_completions/adapter.d.ts +18 -0
  61. package/batteries/llm/webllm_chat_completions/adapter.mjs +25 -6
  62. package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -1
  63. package/batteries/llm/webllm_chat_completions/exceptions.cjs +1 -1
  64. package/batteries/llm/webllm_chat_completions/exceptions.mjs +1 -1
  65. package/batteries/llm/webllm_chat_completions/helpers.cjs +29 -28
  66. package/batteries/llm/webllm_chat_completions/helpers.mjs +2 -1
  67. package/batteries/llm/webllm_chat_completions/types.d.ts +21 -0
  68. package/batteries/llm/webllm_chat_completions/validation.cjs +13 -1
  69. package/batteries/llm/webllm_chat_completions/validation.cjs.map +1 -1
  70. package/batteries/llm/webllm_chat_completions/validation.d.ts +12 -0
  71. package/batteries/llm/webllm_chat_completions/validation.mjs +13 -1
  72. package/batteries/llm/webllm_chat_completions/validation.mjs.map +1 -1
  73. package/batteries/llm/webllm_chat_completions.cjs +29 -28
  74. package/batteries/llm/webllm_chat_completions.mjs +2 -1
  75. package/batteries/llm.cjs +44 -28
  76. package/batteries/llm.mjs +9 -4
  77. package/batteries/storage/flydrive.cjs +1 -1
  78. package/batteries/storage/flydrive.mjs +1 -1
  79. package/batteries/storage/in_memory/index.d.ts +1 -1
  80. package/batteries/storage/in_memory.cjs +2 -2
  81. package/batteries/storage/in_memory.cjs.map +1 -1
  82. package/batteries/storage/in_memory.mjs +2 -2
  83. package/batteries/storage/in_memory.mjs.map +1 -1
  84. package/batteries/storage/opfs/index.d.ts +19 -0
  85. package/batteries/storage/opfs.cjs +1 -1
  86. package/batteries/storage/opfs.cjs.map +1 -1
  87. package/batteries/storage/opfs.mjs +1 -1
  88. package/batteries/storage/opfs.mjs.map +1 -1
  89. package/batteries/tools/color.cjs +3 -2
  90. package/batteries/tools/color.cjs.map +1 -1
  91. package/batteries/tools/color.mjs +3 -2
  92. package/batteries/tools/color.mjs.map +1 -1
  93. package/batteries/tools/comparison.cjs +4 -3
  94. package/batteries/tools/comparison.cjs.map +1 -1
  95. package/batteries/tools/comparison.mjs +4 -3
  96. package/batteries/tools/comparison.mjs.map +1 -1
  97. package/batteries/tools/data_structure.cjs +30 -10
  98. package/batteries/tools/data_structure.cjs.map +1 -1
  99. package/batteries/tools/data_structure.mjs +30 -10
  100. package/batteries/tools/data_structure.mjs.map +1 -1
  101. package/batteries/tools/datetime_extended.cjs +5 -10
  102. package/batteries/tools/datetime_extended.cjs.map +1 -1
  103. package/batteries/tools/datetime_extended.mjs +5 -10
  104. package/batteries/tools/datetime_extended.mjs.map +1 -1
  105. package/batteries/tools/datetime_math.cjs +2 -2
  106. package/batteries/tools/datetime_math.mjs +2 -2
  107. package/batteries/tools/encoding.cjs +13 -4
  108. package/batteries/tools/encoding.cjs.map +1 -1
  109. package/batteries/tools/encoding.mjs +13 -4
  110. package/batteries/tools/encoding.mjs.map +1 -1
  111. package/batteries/tools/formatting.cjs +4 -4
  112. package/batteries/tools/formatting.cjs.map +1 -1
  113. package/batteries/tools/formatting.mjs +4 -4
  114. package/batteries/tools/formatting.mjs.map +1 -1
  115. package/batteries/tools/geo_basics.cjs +2 -2
  116. package/batteries/tools/geo_basics.mjs +2 -2
  117. package/batteries/tools/index.d.ts +1 -0
  118. package/batteries/tools/math.cjs +10 -8
  119. package/batteries/tools/math.cjs.map +1 -1
  120. package/batteries/tools/math.mjs +10 -8
  121. package/batteries/tools/math.mjs.map +1 -1
  122. package/batteries/tools/memory.cjs +5 -5
  123. package/batteries/tools/memory.mjs +5 -5
  124. package/batteries/tools/parsing.cjs +9 -5
  125. package/batteries/tools/parsing.cjs.map +1 -1
  126. package/batteries/tools/parsing.mjs +9 -5
  127. package/batteries/tools/parsing.mjs.map +1 -1
  128. package/batteries/tools/retrievables.cjs +4 -4
  129. package/batteries/tools/retrievables.mjs +4 -4
  130. package/batteries/tools/searxng/exceptions.d.ts +21 -0
  131. package/batteries/tools/searxng/index.d.ts +150 -0
  132. package/batteries/tools/searxng.cjs +5 -0
  133. package/batteries/tools/searxng.mjs +2 -0
  134. package/batteries/tools/standing_instructions.cjs +4 -4
  135. package/batteries/tools/standing_instructions.mjs +4 -4
  136. package/batteries/tools/statistics.cjs +54 -43
  137. package/batteries/tools/statistics.cjs.map +1 -1
  138. package/batteries/tools/statistics.mjs +54 -43
  139. package/batteries/tools/statistics.mjs.map +1 -1
  140. package/batteries/tools/string_processing.cjs +5 -5
  141. package/batteries/tools/string_processing.cjs.map +1 -1
  142. package/batteries/tools/string_processing.mjs +5 -5
  143. package/batteries/tools/string_processing.mjs.map +1 -1
  144. package/batteries/tools/structured_data.cjs +8 -13
  145. package/batteries/tools/structured_data.cjs.map +1 -1
  146. package/batteries/tools/structured_data.mjs +8 -13
  147. package/batteries/tools/structured_data.mjs.map +1 -1
  148. package/batteries/tools/text_analysis.cjs +3 -3
  149. package/batteries/tools/text_analysis.mjs +3 -3
  150. package/batteries/tools/text_comparison.cjs +2 -2
  151. package/batteries/tools/text_comparison.mjs +2 -2
  152. package/batteries/tools/time.cjs +2 -2
  153. package/batteries/tools/time.mjs +2 -2
  154. package/batteries/tools/unit_conversion.cjs +10 -8
  155. package/batteries/tools/unit_conversion.cjs.map +1 -1
  156. package/batteries/tools/unit_conversion.mjs +10 -8
  157. package/batteries/tools/unit_conversion.mjs.map +1 -1
  158. package/batteries/tools.cjs +3 -0
  159. package/batteries/tools.mjs +2 -1
  160. package/batteries/vector/arangodb/index.d.ts +2 -0
  161. package/batteries/vector/arangodb.cjs +2 -1
  162. package/batteries/vector/arangodb.cjs.map +1 -1
  163. package/batteries/vector/arangodb.mjs +2 -1
  164. package/batteries/vector/arangodb.mjs.map +1 -1
  165. package/batteries/vector/builder.cjs +31 -0
  166. package/batteries/vector/builder.cjs.map +1 -1
  167. package/batteries/vector/builder.d.ts +58 -0
  168. package/batteries/vector/builder.mjs +31 -0
  169. package/batteries/vector/builder.mjs.map +1 -1
  170. package/batteries/vector/chroma/index.d.ts +4 -0
  171. package/batteries/vector/chroma.cjs +3 -0
  172. package/batteries/vector/chroma.cjs.map +1 -1
  173. package/batteries/vector/chroma.mjs +3 -0
  174. package/batteries/vector/chroma.mjs.map +1 -1
  175. package/batteries/vector/clickhouse/index.d.ts +2 -0
  176. package/batteries/vector/clickhouse.cjs +2 -1
  177. package/batteries/vector/clickhouse.cjs.map +1 -1
  178. package/batteries/vector/clickhouse.mjs +2 -1
  179. package/batteries/vector/clickhouse.mjs.map +1 -1
  180. package/batteries/vector/cloudflare/index.d.ts +2 -0
  181. package/batteries/vector/cloudflare.cjs +2 -1
  182. package/batteries/vector/cloudflare.cjs.map +1 -1
  183. package/batteries/vector/cloudflare.mjs +2 -1
  184. package/batteries/vector/cloudflare.mjs.map +1 -1
  185. package/batteries/vector/conformance/index.d.ts +22 -0
  186. package/batteries/vector/conformance.cjs +22 -0
  187. package/batteries/vector/conformance.cjs.map +1 -1
  188. package/batteries/vector/conformance.mjs +22 -0
  189. package/batteries/vector/conformance.mjs.map +1 -1
  190. package/batteries/vector/contract.cjs +22 -0
  191. package/batteries/vector/contract.cjs.map +1 -1
  192. package/batteries/vector/contract.d.ts +51 -0
  193. package/batteries/vector/contract.mjs +22 -0
  194. package/batteries/vector/contract.mjs.map +1 -1
  195. package/batteries/vector/couchbase/index.d.ts +2 -0
  196. package/batteries/vector/couchbase.cjs +2 -1
  197. package/batteries/vector/couchbase.cjs.map +1 -1
  198. package/batteries/vector/couchbase.mjs +2 -1
  199. package/batteries/vector/couchbase.mjs.map +1 -1
  200. package/batteries/vector/duckdb/index.d.ts +2 -0
  201. package/batteries/vector/duckdb.cjs +2 -1
  202. package/batteries/vector/duckdb.cjs.map +1 -1
  203. package/batteries/vector/duckdb.mjs +2 -1
  204. package/batteries/vector/duckdb.mjs.map +1 -1
  205. package/batteries/vector/elasticsearch/index.d.ts +2 -0
  206. package/batteries/vector/elasticsearch.cjs +2 -1
  207. package/batteries/vector/elasticsearch.cjs.map +1 -1
  208. package/batteries/vector/elasticsearch.mjs +2 -1
  209. package/batteries/vector/elasticsearch.mjs.map +1 -1
  210. package/batteries/vector/exceptions.cjs +1 -1
  211. package/batteries/vector/exceptions.mjs +1 -1
  212. package/batteries/vector/factory.cjs +6 -0
  213. package/batteries/vector/factory.cjs.map +1 -1
  214. package/batteries/vector/factory.d.ts +14 -0
  215. package/batteries/vector/factory.mjs +6 -0
  216. package/batteries/vector/factory.mjs.map +1 -1
  217. package/batteries/vector/filters.cjs +22 -1
  218. package/batteries/vector/filters.cjs.map +1 -1
  219. package/batteries/vector/filters.d.ts +38 -0
  220. package/batteries/vector/filters.mjs +22 -1
  221. package/batteries/vector/filters.mjs.map +1 -1
  222. package/batteries/vector/helpers.cjs +13 -0
  223. package/batteries/vector/helpers.cjs.map +1 -1
  224. package/batteries/vector/helpers.d.ts +14 -0
  225. package/batteries/vector/helpers.mjs +13 -0
  226. package/batteries/vector/helpers.mjs.map +1 -1
  227. package/batteries/vector/hnswlib/index.d.ts +2 -0
  228. package/batteries/vector/hnswlib.cjs +2 -1
  229. package/batteries/vector/hnswlib.cjs.map +1 -1
  230. package/batteries/vector/hnswlib.mjs +2 -1
  231. package/batteries/vector/hnswlib.mjs.map +1 -1
  232. package/batteries/vector/in_memory/index.d.ts +1 -0
  233. package/batteries/vector/in_memory.cjs +1 -0
  234. package/batteries/vector/in_memory.cjs.map +1 -1
  235. package/batteries/vector/in_memory.mjs +1 -0
  236. package/batteries/vector/in_memory.mjs.map +1 -1
  237. package/batteries/vector/lancedb/index.d.ts +2 -0
  238. package/batteries/vector/lancedb.cjs +2 -1
  239. package/batteries/vector/lancedb.cjs.map +1 -1
  240. package/batteries/vector/lancedb.mjs +2 -1
  241. package/batteries/vector/lancedb.mjs.map +1 -1
  242. package/batteries/vector/mariadb/index.d.ts +2 -0
  243. package/batteries/vector/mariadb.cjs +2 -1
  244. package/batteries/vector/mariadb.cjs.map +1 -1
  245. package/batteries/vector/mariadb.mjs +2 -1
  246. package/batteries/vector/mariadb.mjs.map +1 -1
  247. package/batteries/vector/meilisearch/index.d.ts +2 -0
  248. package/batteries/vector/meilisearch.cjs +2 -1
  249. package/batteries/vector/meilisearch.cjs.map +1 -1
  250. package/batteries/vector/meilisearch.mjs +2 -1
  251. package/batteries/vector/meilisearch.mjs.map +1 -1
  252. package/batteries/vector/migrate.cjs +18 -1
  253. package/batteries/vector/migrate.cjs.map +1 -1
  254. package/batteries/vector/migrate.d.ts +31 -0
  255. package/batteries/vector/migrate.mjs +18 -1
  256. package/batteries/vector/migrate.mjs.map +1 -1
  257. package/batteries/vector/milvus/index.d.ts +5 -0
  258. package/batteries/vector/milvus.cjs +4 -0
  259. package/batteries/vector/milvus.cjs.map +1 -1
  260. package/batteries/vector/milvus.mjs +4 -0
  261. package/batteries/vector/milvus.mjs.map +1 -1
  262. package/batteries/vector/mongodb/index.d.ts +2 -0
  263. package/batteries/vector/mongodb.cjs +2 -1
  264. package/batteries/vector/mongodb.cjs.map +1 -1
  265. package/batteries/vector/mongodb.mjs +2 -1
  266. package/batteries/vector/mongodb.mjs.map +1 -1
  267. package/batteries/vector/neo4j/index.d.ts +2 -0
  268. package/batteries/vector/neo4j.cjs +2 -1
  269. package/batteries/vector/neo4j.cjs.map +1 -1
  270. package/batteries/vector/neo4j.mjs +2 -1
  271. package/batteries/vector/neo4j.mjs.map +1 -1
  272. package/batteries/vector/opensearch/index.d.ts +2 -0
  273. package/batteries/vector/opensearch.cjs +2 -1
  274. package/batteries/vector/opensearch.cjs.map +1 -1
  275. package/batteries/vector/opensearch.mjs +2 -1
  276. package/batteries/vector/opensearch.mjs.map +1 -1
  277. package/batteries/vector/oracle23ai/index.d.ts +2 -0
  278. package/batteries/vector/oracle23ai.cjs +2 -1
  279. package/batteries/vector/oracle23ai.cjs.map +1 -1
  280. package/batteries/vector/oracle23ai.mjs +2 -1
  281. package/batteries/vector/oracle23ai.mjs.map +1 -1
  282. package/batteries/vector/orama/index.d.ts +1 -0
  283. package/batteries/vector/orama.cjs +1 -0
  284. package/batteries/vector/orama.cjs.map +1 -1
  285. package/batteries/vector/orama.mjs +1 -0
  286. package/batteries/vector/orama.mjs.map +1 -1
  287. package/batteries/vector/pgvector/index.d.ts +9 -2
  288. package/batteries/vector/pgvector.cjs +4 -0
  289. package/batteries/vector/pgvector.cjs.map +1 -1
  290. package/batteries/vector/pgvector.mjs +4 -0
  291. package/batteries/vector/pgvector.mjs.map +1 -1
  292. package/batteries/vector/pinecone/index.d.ts +5 -0
  293. package/batteries/vector/pinecone.cjs +3 -1
  294. package/batteries/vector/pinecone.cjs.map +1 -1
  295. package/batteries/vector/pinecone.mjs +3 -1
  296. package/batteries/vector/pinecone.mjs.map +1 -1
  297. package/batteries/vector/plan.d.ts +27 -0
  298. package/batteries/vector/qdrant/index.d.ts +5 -0
  299. package/batteries/vector/qdrant.cjs +4 -0
  300. package/batteries/vector/qdrant.cjs.map +1 -1
  301. package/batteries/vector/qdrant.mjs +4 -0
  302. package/batteries/vector/qdrant.mjs.map +1 -1
  303. package/batteries/vector/redis/index.d.ts +2 -0
  304. package/batteries/vector/redis.cjs +2 -1
  305. package/batteries/vector/redis.cjs.map +1 -1
  306. package/batteries/vector/redis.mjs +2 -1
  307. package/batteries/vector/redis.mjs.map +1 -1
  308. package/batteries/vector/retrievable.cjs +9 -1
  309. package/batteries/vector/retrievable.cjs.map +1 -1
  310. package/batteries/vector/retrievable.mjs +9 -1
  311. package/batteries/vector/retrievable.mjs.map +1 -1
  312. package/batteries/vector/retrievable_glue.d.ts +21 -0
  313. package/batteries/vector/s3vectors/index.d.ts +2 -0
  314. package/batteries/vector/s3vectors.cjs +2 -1
  315. package/batteries/vector/s3vectors.cjs.map +1 -1
  316. package/batteries/vector/s3vectors.mjs +2 -1
  317. package/batteries/vector/s3vectors.mjs.map +1 -1
  318. package/batteries/vector/schema.cjs +28 -0
  319. package/batteries/vector/schema.cjs.map +1 -1
  320. package/batteries/vector/schema.d.ts +39 -0
  321. package/batteries/vector/schema.mjs +28 -0
  322. package/batteries/vector/schema.mjs.map +1 -1
  323. package/batteries/vector/solr/index.d.ts +2 -0
  324. package/batteries/vector/solr.cjs +2 -1
  325. package/batteries/vector/solr.cjs.map +1 -1
  326. package/batteries/vector/solr.mjs +2 -1
  327. package/batteries/vector/solr.mjs.map +1 -1
  328. package/batteries/vector/sqlite_vec/index.d.ts +6 -3
  329. package/batteries/vector/sqlite_vec.cjs +2 -0
  330. package/batteries/vector/sqlite_vec.cjs.map +1 -1
  331. package/batteries/vector/sqlite_vec.mjs +2 -0
  332. package/batteries/vector/sqlite_vec.mjs.map +1 -1
  333. package/batteries/vector/surrealdb/index.d.ts +2 -0
  334. package/batteries/vector/surrealdb.cjs +2 -1
  335. package/batteries/vector/surrealdb.cjs.map +1 -1
  336. package/batteries/vector/surrealdb.mjs +2 -1
  337. package/batteries/vector/surrealdb.mjs.map +1 -1
  338. package/batteries/vector/types.d.ts +27 -0
  339. package/batteries/vector/typesense/index.d.ts +2 -0
  340. package/batteries/vector/typesense.cjs +2 -1
  341. package/batteries/vector/typesense.cjs.map +1 -1
  342. package/batteries/vector/typesense.mjs +2 -1
  343. package/batteries/vector/typesense.mjs.map +1 -1
  344. package/batteries/vector/validation.cjs +14 -0
  345. package/batteries/vector/validation.cjs.map +1 -1
  346. package/batteries/vector/validation.d.ts +14 -0
  347. package/batteries/vector/validation.mjs +14 -0
  348. package/batteries/vector/validation.mjs.map +1 -1
  349. package/batteries/vector/vector_store_constructor.cjs +1 -1
  350. package/batteries/vector/vector_store_constructor.cjs.map +1 -1
  351. package/batteries/vector/vector_store_constructor.d.ts +1 -1
  352. package/batteries/vector/vector_store_constructor.mjs +1 -1
  353. package/batteries/vector/vector_store_constructor.mjs.map +1 -1
  354. package/batteries/vector/vespa/index.d.ts +2 -0
  355. package/batteries/vector/vespa.cjs +2 -1
  356. package/batteries/vector/vespa.cjs.map +1 -1
  357. package/batteries/vector/vespa.mjs +2 -1
  358. package/batteries/vector/vespa.mjs.map +1 -1
  359. package/batteries/vector/weaviate/index.d.ts +2 -0
  360. package/batteries/vector/weaviate.cjs +2 -1
  361. package/batteries/vector/weaviate.cjs.map +1 -1
  362. package/batteries/vector/weaviate.mjs +2 -1
  363. package/batteries/vector/weaviate.mjs.map +1 -1
  364. package/batteries.cjs +46 -28
  365. package/batteries.mjs +10 -5
  366. package/{common-BT0nfCi9.mjs → common-DYDUi99O.mjs} +9 -9
  367. package/common-DYDUi99O.mjs.map +1 -0
  368. package/{common-Cj8TaQ9U.js → common-DZl3ADJs.js} +9 -9
  369. package/common-DZl3ADJs.js.map +1 -0
  370. package/common.cjs +7 -7
  371. package/common.d.ts +1 -1
  372. package/common.mjs +7 -7
  373. package/{dispatch_runner-DPcS7Y_M.mjs → dispatch_runner--ZhdDWRZ.mjs} +27 -5
  374. package/{dispatch_runner-DPcS7Y_M.mjs.map → dispatch_runner--ZhdDWRZ.mjs.map} +1 -1
  375. package/{dispatch_runner-BHBNupqp.js → dispatch_runner-nHDKkxye.js} +27 -5
  376. package/{dispatch_runner-BHBNupqp.js.map → dispatch_runner-nHDKkxye.js.map} +1 -1
  377. package/dispatch_runner.cjs +1 -1
  378. package/dispatch_runner.d.ts +1 -1
  379. package/dispatch_runner.mjs +1 -1
  380. package/eslint/rules/artifact_tool_forbids_artifact_constructor.cjs +1 -0
  381. package/eslint/rules/artifact_tool_forbids_artifact_constructor.cjs.map +1 -1
  382. package/eslint/rules/artifact_tool_forbids_artifact_constructor.d.ts +1 -0
  383. package/eslint/rules/artifact_tool_forbids_artifact_constructor.mjs +1 -0
  384. package/eslint/rules/artifact_tool_forbids_artifact_constructor.mjs.map +1 -1
  385. package/eslint/rules/no_model_in_tool_handler.cjs +1 -0
  386. package/eslint/rules/no_model_in_tool_handler.cjs.map +1 -1
  387. package/eslint/rules/no_model_in_tool_handler.d.ts +1 -0
  388. package/eslint/rules/no_model_in_tool_handler.mjs +1 -0
  389. package/eslint/rules/no_model_in_tool_handler.mjs.map +1 -1
  390. package/eslint/rules/require_validator_any_required.cjs +1 -0
  391. package/eslint/rules/require_validator_any_required.cjs.map +1 -1
  392. package/eslint/rules/require_validator_any_required.d.ts +1 -0
  393. package/eslint/rules/require_validator_any_required.mjs +1 -0
  394. package/eslint/rules/require_validator_any_required.mjs.map +1 -1
  395. package/eslint/rules/thought_payload_requires_replay_tag.cjs +1 -0
  396. package/eslint/rules/thought_payload_requires_replay_tag.cjs.map +1 -1
  397. package/eslint/rules/thought_payload_requires_replay_tag.d.ts +1 -0
  398. package/eslint/rules/thought_payload_requires_replay_tag.mjs +1 -0
  399. package/eslint/rules/thought_payload_requires_replay_tag.mjs.map +1 -1
  400. package/eslint/rules/token_encoding_requires_context_window.cjs +1 -0
  401. package/eslint/rules/token_encoding_requires_context_window.cjs.map +1 -1
  402. package/eslint/rules/token_encoding_requires_context_window.d.ts +1 -0
  403. package/eslint/rules/token_encoding_requires_context_window.mjs +1 -0
  404. package/eslint/rules/token_encoding_requires_context_window.mjs.map +1 -1
  405. package/eslint.cjs +1 -1
  406. package/eslint.mjs +1 -1
  407. package/{exceptions-BeWH2FwP.mjs → exceptions-BDhN0Xzr.mjs} +3 -2
  408. package/exceptions-BDhN0Xzr.mjs.map +1 -0
  409. package/{exceptions-CitH5wZI.js → exceptions-BRXrUKiW.js} +3 -2
  410. package/exceptions-BRXrUKiW.js.map +1 -0
  411. package/exceptions.cjs +2 -2
  412. package/exceptions.mjs +2 -2
  413. package/factories.cjs +1 -1
  414. package/factories.mjs +1 -1
  415. package/forge.cjs +4 -4
  416. package/forge.d.ts +1 -1
  417. package/forge.mjs +4 -4
  418. package/guards.cjs +9 -9
  419. package/guards.mjs +9 -9
  420. package/helpers-DSTFxTiC.js +497 -0
  421. package/helpers-DSTFxTiC.js.map +1 -0
  422. package/helpers-xhrQbMAG.mjs +306 -0
  423. package/helpers-xhrQbMAG.mjs.map +1 -0
  424. package/index.cjs +13 -13
  425. package/index.mjs +13 -13
  426. package/lib/classes/base_exception.d.ts +1 -0
  427. package/lib/classes/media.d.ts +10 -0
  428. package/lib/classes/retrievable.d.ts +1 -1
  429. package/lib/classes/spooled_json_artifact.d.ts +1 -1
  430. package/lib/classes/spooled_markdown_artifact.d.ts +1 -0
  431. package/lib/classes/tokenizable.d.ts +3 -0
  432. package/lib/classes/tool.d.ts +8 -0
  433. package/lib/classes/turn_gate.d.ts +6 -0
  434. package/lib/dispatch_runner.d.ts +4 -32
  435. package/lib/helpers/bignum.cjs +82 -0
  436. package/lib/helpers/bignum.cjs.map +1 -0
  437. package/lib/helpers/bignum.d.ts +52 -0
  438. package/lib/helpers/bignum.mjs +74 -0
  439. package/lib/helpers/bignum.mjs.map +1 -0
  440. package/lib/turn_runner.d.ts +1 -1
  441. package/lib/types/dispatch_runner.d.ts +83 -0
  442. package/lib/utils/exceptions.d.ts +1 -1
  443. package/lib/utils/retry.cjs.map +1 -1
  444. package/lib/utils/retry.d.ts +2 -0
  445. package/lib/utils/retry.mjs.map +1 -1
  446. package/mcp/adk-docs-corpus.json +1 -1
  447. package/package.json +264 -224
  448. package/{runtime-j92CNi5z.mjs → runtime-Bz5zA8wc.mjs} +2 -2
  449. package/{runtime-j92CNi5z.mjs.map → runtime-Bz5zA8wc.mjs.map} +1 -1
  450. package/{runtime-MFFcJrRv.js → runtime-DslE1aBw.js} +2 -2
  451. package/{runtime-MFFcJrRv.js.map → runtime-DslE1aBw.js.map} +1 -1
  452. package/searxng-Bkrwhwhw.js +269 -0
  453. package/searxng-Bkrwhwhw.js.map +1 -0
  454. package/searxng-CyA-nEu5.mjs +257 -0
  455. package/searxng-CyA-nEu5.mjs.map +1 -0
  456. package/skills/adk-assembly/SKILL.md +2 -2
  457. package/{spooled_artifact-CHoZgWwI.mjs → spooled_artifact-7eePq7JA.mjs} +5 -5
  458. package/{spooled_artifact-CHoZgWwI.mjs.map → spooled_artifact-7eePq7JA.mjs.map} +1 -1
  459. package/{spooled_artifact-BTq6Nzfy.js → spooled_artifact-DX8LLyUX.js} +5 -5
  460. package/{spooled_artifact-BTq6Nzfy.js.map → spooled_artifact-DX8LLyUX.js.map} +1 -1
  461. package/spooled_artifact.cjs +2 -2
  462. package/spooled_artifact.mjs +2 -2
  463. package/{spooled_markdown_artifact-CALSDxIx.js → spooled_markdown_artifact-ClX72lek.js} +4 -4
  464. package/spooled_markdown_artifact-ClX72lek.js.map +1 -0
  465. package/{spooled_markdown_artifact-Ci5UL7l4.mjs → spooled_markdown_artifact-wkrBF3oX.mjs} +4 -4
  466. package/spooled_markdown_artifact-wkrBF3oX.mjs.map +1 -0
  467. package/{thought-D34QQZZ9.mjs → thought-B_vxAiKU.mjs} +5 -5
  468. package/{thought-D34QQZZ9.mjs.map → thought-B_vxAiKU.mjs.map} +1 -1
  469. package/{thought-BbwhJ1wb.js → thought-DLwpF7MI.js} +5 -5
  470. package/{thought-BbwhJ1wb.js.map → thought-DLwpF7MI.js.map} +1 -1
  471. package/{tool-CVyZkFC7.js → tool-D5WGVIcI.js} +4 -4
  472. package/{tool-CVyZkFC7.js.map → tool-D5WGVIcI.js.map} +1 -1
  473. package/{tool-CMhaDRNd.mjs → tool-wMYMVl60.mjs} +4 -4
  474. package/{tool-CMhaDRNd.mjs.map → tool-wMYMVl60.mjs.map} +1 -1
  475. package/{tool_call-CV5qVNlb.mjs → tool_call-B4-_-vjG.mjs} +5 -5
  476. package/tool_call-B4-_-vjG.mjs.map +1 -0
  477. package/{tool_call-Db68hB7y.js → tool_call-DixVlW40.js} +5 -5
  478. package/tool_call-DixVlW40.js.map +1 -0
  479. package/{tool_registry-D1pSSlsd.mjs → tool_registry-791Vrjtf.mjs} +4 -3
  480. package/tool_registry-791Vrjtf.mjs.map +1 -0
  481. package/{tool_registry-DYUYqXvo.js → tool_registry-CKJPze3j.js} +4 -3
  482. package/tool_registry-CKJPze3j.js.map +1 -0
  483. package/{turn_runner-DqWHNP80.js → turn_runner-HXImLGIn.js} +7 -7
  484. package/turn_runner-HXImLGIn.js.map +1 -0
  485. package/{turn_runner-fg1Wc3dK.mjs → turn_runner-ZyYO-Kti.mjs} +7 -7
  486. package/turn_runner-ZyYO-Kti.mjs.map +1 -0
  487. package/turn_runner.cjs +1 -1
  488. package/turn_runner.mjs +1 -1
  489. package/types.d.ts +1 -1
  490. package/common-BT0nfCi9.mjs.map +0 -1
  491. package/common-Cj8TaQ9U.js.map +0 -1
  492. package/exceptions-BeWH2FwP.mjs.map +0 -1
  493. package/exceptions-CitH5wZI.js.map +0 -1
  494. package/spooled_markdown_artifact-CALSDxIx.js.map +0 -1
  495. package/spooled_markdown_artifact-Ci5UL7l4.mjs.map +0 -1
  496. package/tool_call-CV5qVNlb.mjs.map +0 -1
  497. package/tool_call-Db68hB7y.js.map +0 -1
  498. package/tool_registry-D1pSSlsd.mjs.map +0 -1
  499. package/tool_registry-DYUYqXvo.js.map +0 -1
  500. package/turn_runner-DqWHNP80.js.map +0 -1
  501. package/turn_runner-fg1Wc3dK.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"cloudflare.cjs","names":["#opts","#baseUrl","#authHeaders","#req","#base","#headers","#settle","#index","#dims","#metrics","#projectMeta","#project"],"sources":["../../../src/batteries/vector/cloudflare/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/cloudflare\n *\n * Managed Cloudflare Vectorize V2 vector-store adapter over REST (pure fetch, no driver).\n * A logical collection maps to a Vectorize **index**. Supported dimensions: 32–1536.\n *\n * Upserter: POST /{name}/upsert via `multipart/form-data` with field name `vectors`\n * (content-type `application/x-ndjson`). Each line: `{\"id\":\"..\",\"values\":[..],\"metadata\":{..}}`.\n * Query/get/delete use JSON bodies. Eventual consistency is handled by settle-polling.\n *\n * Native filtering: Vectorize requires pre-created metadata indexes and lacks `$and`/`$or`.\n * For guaranteed cross-adapter parity, **over-fetch + JS evaluateFilter** (topK cap 100).\n *\n * Scores: returned as-is from Vectorize, then re-computed locally (cosineSim/dotProd/euclideanDist)\n * to guarantee the [0,1] contract.\n *\n * Document: stored under the reserved metadata key `__document`; extracted on read.\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_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\n// Cloudflare Vectorize V2 REST endpoint base\nconst BASE_URL = 'https://api.cloudflare.com/client/v4/accounts'\n\n// Over-fetch constant for JS filtering (Vectorize native filtering needs metadata indexes + lacks\n// $and/$or). Cloudflare caps topK at 50 when returnValues=true or returnMetadata=all (which we\n// need to recompute scores + filter locally), so 50 is the ceiling.\nconst OVERFETCH = 50\n\nconst mapMetricToCF = (metric: DistanceMetric): string => {\n if (metric === 'cosine') return 'cosine'\n if (metric === 'euclidean') return 'euclidean'\n if (metric === 'dot') return 'dot-product'\n throw new E_VECTOR_STORE_COLLECTION_FAILED([\n 'createCollection',\n `Metric \"${metric}\" is not supported by Cloudflare Vectorize; use \"cosine\", \"euclidean\", or \"dot\"`,\n ])\n}\n\n// Score computation helpers (copied from couchbase/index.ts)\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\nexport interface CloudflareVectorizeVectorStoreOptions extends BaseVectorStoreOptions {\n connection: {\n accountId: string\n apiKey: string\n indexNamePrefix?: string\n }\n}\n\nexport class CloudflareVectorizeVectorStore 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 #baseUrl: string | null = null\n #authHeaders: Record<string, string> | null = null\n #dims: Map<string, number> = new Map()\n #metrics: Map<string, DistanceMetric> = new Map()\n\n get #opts(): CloudflareVectorizeVectorStoreOptions {\n return this.options as CloudflareVectorizeVectorStoreOptions\n }\n\n static isAvailable(): boolean {\n return typeof process !== 'undefined' && typeof fetch !== 'undefined'\n }\n\n isAvailable(): boolean {\n return typeof process !== 'undefined' && typeof fetch !== 'undefined'\n }\n\n #base(): string {\n if (!this.#baseUrl) {\n this.#baseUrl = `${BASE_URL}/${this.#opts.connection.accountId}/vectorize/v2/indexes`\n }\n return this.#baseUrl\n }\n\n #headers(): Record<string, string> {\n if (!this.#authHeaders) {\n this.#authHeaders = { Authorization: `Bearer ${this.#opts.connection.apiKey}` }\n }\n return this.#authHeaders\n }\n\n // Map a logical collection name to its physical Vectorize index name (with optional prefix).\n #index(collection: string): string {\n const prefix = this.#opts.connection.indexNamePrefix ?? ''\n return `${prefix}${collection}`\n }\n\n async #req<T = any>(\n method: string,\n path: string,\n { json, form }: { json?: any; form?: FormData } = {}\n ): Promise<T> {\n const url = this.#base() + path\n const headers: Record<string, string> = { ...this.#headers() }\n let body: BodyInit | undefined\n if (form) {\n body = form\n } else if (json !== undefined) {\n body = JSON.stringify(json)\n headers['Content-Type'] = 'application/json'\n }\n const res = await fetch(url, { method, headers, body })\n const payload: any = await res.json().catch(() => ({}))\n if (!res.ok || !payload.success) {\n const msg = payload.errors?.[0]?.message || payload.messages?.[0] || `HTTP ${res.status}`\n throw new Error(msg)\n }\n return payload.result\n }\n\n // Settle-poll after writes/deletes against the QUERY index (the surface reads go through).\n //\n // Vectorize is aggressively eventually-consistent: a fresh index takes ~20s before its first\n // write is queryable, and the query index FLAPS — a just-written id can appear then vanish (or a\n // just-deleted id reappear) across consecutive polls for several seconds. A single converged poll\n // is therefore not enough. We require STABILITY: `STABLE` consecutive polls that all satisfy the\n // present/absent condition before returning, so the subsequent read-after-write is reliable.\n async #settle(\n collection: string,\n opts: { present?: string[]; absent?: string[] }\n ): Promise<void> {\n const present = opts.present ?? []\n const absent = opts.absent ?? []\n if (present.length === 0 && absent.length === 0) return\n\n const physicalIndex = this.#index(collection)\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const STABLE = 3 // consecutive satisfying polls required to declare settled\n const deadline = Date.now() + 60_000\n let streak = 0\n while (Date.now() < deadline) {\n let ok = true\n try {\n const res = await this.#req<{ matches: any[] }>('POST', `/${physicalIndex}/query`, {\n json: { vector: probeVec, topK: 50, returnValues: false, returnMetadata: 'none' },\n })\n const seen = new Set((res.matches ?? []).map((m: any) => m.id))\n if (present.length > 0 && !present.every((id) => seen.has(id))) ok = false\n if (absent.length > 0 && !absent.every((id) => !seen.has(id))) ok = false\n } catch {\n ok = false\n }\n streak = ok ? streak + 1 : 0\n if (streak >= STABLE) return\n await new Promise((r) => setTimeout(r, 500))\n }\n }\n\n async connect(): Promise<void> {\n // HTTP is stateless; the base URL + auth headers are built lazily and cached on first use.\n }\n\n async close(): Promise<void> {\n this.#baseUrl = null\n this.#authHeaders = null\n }\n\n async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n const collection = spec.collection\n const physicalIndex = this.#index(collection)\n const dims = spec.vector.dimensions\n const metric = spec.vector.metric\n\n // Validate dimensions (32–1536)\n if (dims < 32 || dims > 1536) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED([\n 'createCollection',\n `Dimensions must be 32–1536; got ${dims}`,\n ])\n }\n\n this.#dims.set(collection, dims)\n this.#metrics.set(collection, metric)\n\n if (ifNotExists) {\n if (await this.hasCollection(collection)) return\n }\n\n try {\n await this.connect()\n const body: any = {\n name: physicalIndex,\n config: {\n dimensions: dims,\n metric: mapMetricToCF(metric),\n },\n }\n await this.#req('POST', '', { json: body })\n } catch (err: any) {\n const msg = String(err)\n if (ifNotExists && msg.toLowerCase().includes('already exists')) {\n return\n }\n // If NOT ifNotExists and exists, best-effort clear (Vectorize has no bulk-clear;\n // per-test isolation uses prefix so fresh index is effectively empty).\n if (!ifNotExists && msg.toLowerCase().includes('already exists')) {\n try {\n await this.dropCollection(collection, true)\n await this.createCollection(spec, false)\n return\n } catch {\n // Fall through to rethrow original\n }\n }\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['createCollection', msg])\n }\n }\n\n async dropCollection(collection: string, ifExists: boolean): Promise<void> {\n const physicalIndex = this.#index(collection)\n\n if (ifExists) {\n if (!(await this.hasCollection(collection))) return\n } else if (!(await this.hasCollection(collection))) {\n return\n }\n\n try {\n await this.connect()\n await this.#req('DELETE', `/${physicalIndex}`)\n // Clear local state\n this.#dims.delete(collection)\n this.#metrics.delete(collection)\n } catch (err: any) {\n const msg = String(err)\n if (ifExists && (msg.includes('not found') || msg.includes('404'))) {\n return\n }\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['dropCollection', msg])\n }\n }\n\n async hasCollection(collection: string): Promise<boolean> {\n await this.connect()\n const physicalIndex = this.#index(collection)\n try {\n const res: any = await this.#req('GET', `/${physicalIndex}`)\n return !!res\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', 'cloudflare'])\n }\n\n async executeUpsert(plan: UpsertPlan): Promise<void> {\n if (plan.records.length === 0) return\n validateRecords(plan.records)\n\n const collection = plan.collection\n const physicalIndex = this.#index(collection)\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions\n\n try {\n await this.connect()\n\n const ndjsonLines: 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 (dims !== undefined && vector.length !== dims) {\n throw new E_VECTOR_STORE_DIMENSION_MISMATCH([dims, vector.length])\n }\n const meta: any = { ...(r.metadata ?? {}) }\n if (r.document) meta.__document = r.document\n ndjsonLines.push(JSON.stringify({ id: r.id, values: vector, metadata: meta }))\n }\n\n const ndjson = ndjsonLines.join('\\n')\n\n // Build FormData for multipart upload\n const fd = new FormData()\n fd.append('vectors', new Blob([ndjson], { type: 'application/x-ndjson' }), 'vectors.ndjson')\n\n await this.#req('POST', `/${physicalIndex}/upsert`, { form: fd })\n\n // Settle until all ids are visible\n await this.#settle(collection, { present: plan.records.map((r) => r.id) })\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 await this.connect()\n const collection = plan.collection\n const physicalIndex = this.#index(collection)\n const metric = this.#metrics.get(collection) ?? this.#opts.metric ?? 'cosine'\n const offset = plan.offset ?? 0\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\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 res: any = await this.#req('POST', `/${physicalIndex}/get_by_ids`, {\n json: { ids: [plan.near.id] },\n })\n const match = Array.isArray(res) ? res[0] : res?.result?.[0]\n if (!match || !match.values) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n queryVector = match.values\n } catch (err: any) {\n const msg = String(err)\n if (msg.includes('not found') || msg.includes('404')) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n throw new E_VECTOR_STORE_SEARCH_FAILED([msg])\n }\n }\n }\n\n if (queryVector) {\n // Similarity search: query with over-fetch, JS-filter, recompute scores\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: queryVector,\n topK: OVERFETCH,\n filter: undefined, // no native filter for parity\n returnValues: true,\n returnMetadata: 'all',\n },\n })\n let rawMatches = res.matches ?? []\n\n // Filter by JS-evaluateFilter\n if (plan.filter) {\n rawMatches = rawMatches.filter((m: any) => {\n const meta = this.#projectMeta(m.metadata)\n return evaluateFilter(plan.filter!, meta)\n })\n }\n\n // Slice offset+topK\n rawMatches = rawMatches.slice(offset, offset + plan.topK)\n\n // Re-compute scores and project\n const out: VectorMatch[] = []\n for (const m of rawMatches) {\n const projected = this.#project(m, plan, undefined, metric, queryVector)\n if (projected) out.push(projected)\n }\n return out\n } else {\n // Filter-scan: query with arbitrary probe vector, over-fetch, JS-filter\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: probeVec,\n topK: OVERFETCH,\n filter: undefined,\n returnValues: false,\n returnMetadata: 'all',\n },\n })\n let rawMatches = res.matches ?? []\n\n // JS-filter\n if (plan.filter) {\n rawMatches = rawMatches.filter((m: any) => {\n const meta = this.#projectMeta(m.metadata)\n return evaluateFilter(plan.filter!, meta)\n })\n }\n\n // Slice\n rawMatches = rawMatches.slice(offset, offset + plan.topK)\n\n // Project without score\n const out: VectorMatch[] = []\n for (const m of rawMatches) {\n const projected = this.#project(m, plan, undefined, metric, undefined)\n if (projected) out.push(projected)\n }\n return out\n }\n }\n\n #projectMeta(metadata: any): VectorMetadata {\n if (!metadata || typeof metadata !== 'object') return {}\n const out: VectorMetadata = {}\n for (const key in metadata) {\n if (key !== '__document') out[key] = metadata[key]\n }\n return out\n }\n\n #project(\n match: any,\n plan: SearchPlan,\n score: number | undefined,\n metric: DistanceMetric,\n queryVector: number[] | undefined\n ): VectorMatch | null {\n const proj = plan.projection\n const out: VectorMatch = {}\n\n if (proj.id) out.id = match.id\n\n if (proj.document) {\n const meta = match.metadata ?? {}\n if (typeof meta.__document === 'string') {\n out.document = meta.__document\n }\n }\n\n if (proj.metadata) {\n out.metadata = this.#projectMeta(match.metadata)\n }\n\n if (proj.vector) {\n out.vector = match.values\n }\n\n if (typeof score === 'number') {\n out.score = score\n } else if (queryVector && match.values) {\n // Recompute score for the [0,1] contract\n out.score = computeScore(match.values, queryVector, metric)\n }\n\n // If nothing was projected, return null to filter out\n if (Object.keys(out).length === 0) return null\n return out\n }\n\n async executeDelete(plan: DeletePlan): Promise<void> {\n const collection = plan.collection\n const physicalIndex = this.#index(collection)\n\n try {\n await this.connect()\n\n if (plan.ids && plan.ids.length > 0) {\n await this.#req('POST', `/${physicalIndex}/delete_by_ids`, {\n json: { ids: plan.ids },\n })\n await this.#settle(collection, { absent: plan.ids })\n } else if (plan.filter) {\n // Enumerate all, JS-filter, delete matched\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: probeVec,\n topK: OVERFETCH,\n returnValues: true,\n returnMetadata: 'all',\n },\n })\n const targets: string[] = []\n for (const m of res.matches ?? []) {\n const meta = this.#projectMeta(m.metadata)\n if (evaluateFilter(plan.filter!, meta)) {\n targets.push(m.id)\n }\n }\n\n if (targets.length > 0) {\n await this.#req('POST', `/${physicalIndex}/delete_by_ids`, {\n json: { ids: targets },\n })\n await this.#settle(collection, { absent: targets })\n }\n } else {\n // Delete all: enumerate all ids then delete\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: probeVec,\n topK: OVERFETCH,\n returnValues: true,\n returnMetadata: 'all',\n },\n })\n\n const allIds = (res.matches ?? []).map((m: any) => m.id)\n if (allIds.length > 0) {\n await this.#req('POST', `/${physicalIndex}/delete_by_ids`, {\n json: { ids: allIds },\n })\n await this.#settle(collection, { absent: allIds })\n }\n }\n } catch (err: any) {\n throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cloudflare.cjs","names":["#opts","#baseUrl","#authHeaders","#req","#base","#headers","#settle","#index","#dims","#metrics","#projectMeta","#project"],"sources":["../../../src/batteries/vector/cloudflare/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/cloudflare\n *\n * Managed Cloudflare Vectorize V2 vector-store adapter over REST (pure fetch, no driver).\n * A logical collection maps to a Vectorize **index**. Supported dimensions: 32–1536.\n *\n * Upserter: POST /{name}/upsert via `multipart/form-data` with field name `vectors`\n * (content-type `application/x-ndjson`). Each line: `{\"id\":\"..\",\"values\":[..],\"metadata\":{..}}`.\n * Query/get/delete use JSON bodies. Eventual consistency is handled by settle-polling.\n *\n * Native filtering: Vectorize requires pre-created metadata indexes and lacks `$and`/`$or`.\n * For guaranteed cross-adapter parity, **over-fetch + JS evaluateFilter** (topK cap 100).\n *\n * Scores: returned as-is from Vectorize, then re-computed locally (cosineSim/dotProd/euclideanDist)\n * to guarantee the [0,1] contract.\n *\n * Document: stored under the reserved metadata key `__document`; extracted on read.\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_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\n// Cloudflare Vectorize V2 REST endpoint base\nconst BASE_URL = 'https://api.cloudflare.com/client/v4/accounts'\n\n// Over-fetch constant for JS filtering (Vectorize native filtering needs metadata indexes + lacks\n// $and/$or). Cloudflare caps topK at 50 when returnValues=true or returnMetadata=all (which we\n// need to recompute scores + filter locally), so 50 is the ceiling.\nconst OVERFETCH = 50\n\nconst mapMetricToCF = (metric: DistanceMetric): string => {\n if (metric === 'cosine') return 'cosine'\n if (metric === 'euclidean') return 'euclidean'\n if (metric === 'dot') return 'dot-product'\n throw new E_VECTOR_STORE_COLLECTION_FAILED([\n 'createCollection',\n `Metric \"${metric}\" is not supported by Cloudflare Vectorize; use \"cosine\", \"euclidean\", or \"dot\"`,\n ])\n}\n\n// Score computation helpers (copied from couchbase/index.ts)\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\nexport interface CloudflareVectorizeVectorStoreOptions extends BaseVectorStoreOptions {\n /** Connection and authentication parameters for the backend. */\n connection: {\n accountId: string\n apiKey: string\n indexNamePrefix?: string\n }\n}\n\nexport class CloudflareVectorizeVectorStore 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 #baseUrl: string | null = null\n #authHeaders: Record<string, string> | null = null\n #dims: Map<string, number> = new Map()\n #metrics: Map<string, DistanceMetric> = new Map()\n\n get #opts(): CloudflareVectorizeVectorStoreOptions {\n return this.options as CloudflareVectorizeVectorStoreOptions\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' && typeof fetch !== 'undefined'\n }\n\n isAvailable(): boolean {\n return typeof process !== 'undefined' && typeof fetch !== 'undefined'\n }\n\n #base(): string {\n if (!this.#baseUrl) {\n this.#baseUrl = `${BASE_URL}/${this.#opts.connection.accountId}/vectorize/v2/indexes`\n }\n return this.#baseUrl\n }\n\n #headers(): Record<string, string> {\n if (!this.#authHeaders) {\n this.#authHeaders = { Authorization: `Bearer ${this.#opts.connection.apiKey}` }\n }\n return this.#authHeaders\n }\n\n // Map a logical collection name to its physical Vectorize index name (with optional prefix).\n #index(collection: string): string {\n const prefix = this.#opts.connection.indexNamePrefix ?? ''\n return `${prefix}${collection}`\n }\n\n async #req<T = any>(\n method: string,\n path: string,\n { json, form }: { json?: any; form?: FormData } = {}\n ): Promise<T> {\n const url = this.#base() + path\n const headers: Record<string, string> = { ...this.#headers() }\n let body: BodyInit | undefined\n if (form) {\n body = form\n } else if (json !== undefined) {\n body = JSON.stringify(json)\n headers['Content-Type'] = 'application/json'\n }\n const res = await fetch(url, { method, headers, body })\n const payload: any = await res.json().catch(() => ({}))\n if (!res.ok || !payload.success) {\n const msg = payload.errors?.[0]?.message || payload.messages?.[0] || `HTTP ${res.status}`\n throw new Error(msg)\n }\n return payload.result\n }\n\n // Settle-poll after writes/deletes against the QUERY index (the surface reads go through).\n //\n // Vectorize is aggressively eventually-consistent: a fresh index takes ~20s before its first\n // write is queryable, and the query index FLAPS — a just-written id can appear then vanish (or a\n // just-deleted id reappear) across consecutive polls for several seconds. A single converged poll\n // is therefore not enough. We require STABILITY: `STABLE` consecutive polls that all satisfy the\n // present/absent condition before returning, so the subsequent read-after-write is reliable.\n async #settle(\n collection: string,\n opts: { present?: string[]; absent?: string[] }\n ): Promise<void> {\n const present = opts.present ?? []\n const absent = opts.absent ?? []\n if (present.length === 0 && absent.length === 0) return\n\n const physicalIndex = this.#index(collection)\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const STABLE = 3 // consecutive satisfying polls required to declare settled\n const deadline = Date.now() + 60_000\n let streak = 0\n while (Date.now() < deadline) {\n let ok = true\n try {\n const res = await this.#req<{ matches: any[] }>('POST', `/${physicalIndex}/query`, {\n json: { vector: probeVec, topK: 50, returnValues: false, returnMetadata: 'none' },\n })\n const seen = new Set((res.matches ?? []).map((m: any) => m.id))\n if (present.length > 0 && !present.every((id) => seen.has(id))) ok = false\n if (absent.length > 0 && !absent.every((id) => !seen.has(id))) ok = false\n } catch {\n ok = false\n }\n streak = ok ? streak + 1 : 0\n if (streak >= STABLE) return\n await new Promise((r) => setTimeout(r, 500))\n }\n }\n\n async connect(): Promise<void> {\n // HTTP is stateless; the base URL + auth headers are built lazily and cached on first use.\n }\n\n async close(): Promise<void> {\n this.#baseUrl = null\n this.#authHeaders = null\n }\n\n async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n const collection = spec.collection\n const physicalIndex = this.#index(collection)\n const dims = spec.vector.dimensions\n const metric = spec.vector.metric\n\n // Validate dimensions (32–1536)\n if (dims < 32 || dims > 1536) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED([\n 'createCollection',\n `Dimensions must be 32–1536; got ${dims}`,\n ])\n }\n\n this.#dims.set(collection, dims)\n this.#metrics.set(collection, metric)\n\n if (ifNotExists) {\n if (await this.hasCollection(collection)) return\n }\n\n try {\n await this.connect()\n const body: any = {\n name: physicalIndex,\n config: {\n dimensions: dims,\n metric: mapMetricToCF(metric),\n },\n }\n await this.#req('POST', '', { json: body })\n } catch (err: any) {\n const msg = String(err)\n if (ifNotExists && msg.toLowerCase().includes('already exists')) {\n return\n }\n // If NOT ifNotExists and exists, best-effort clear (Vectorize has no bulk-clear;\n // per-test isolation uses prefix so fresh index is effectively empty).\n if (!ifNotExists && msg.toLowerCase().includes('already exists')) {\n try {\n await this.dropCollection(collection, true)\n await this.createCollection(spec, false)\n return\n } catch {\n // Fall through to rethrow original\n }\n }\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['createCollection', msg])\n }\n }\n\n async dropCollection(collection: string, ifExists: boolean): Promise<void> {\n const physicalIndex = this.#index(collection)\n\n if (ifExists) {\n if (!(await this.hasCollection(collection))) return\n } else if (!(await this.hasCollection(collection))) {\n return\n }\n\n try {\n await this.connect()\n await this.#req('DELETE', `/${physicalIndex}`)\n // Clear local state\n this.#dims.delete(collection)\n this.#metrics.delete(collection)\n } catch (err: any) {\n const msg = String(err)\n if (ifExists && (msg.includes('not found') || msg.includes('404'))) {\n return\n }\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['dropCollection', msg])\n }\n }\n\n async hasCollection(collection: string): Promise<boolean> {\n await this.connect()\n const physicalIndex = this.#index(collection)\n try {\n const res: any = await this.#req('GET', `/${physicalIndex}`)\n return !!res\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', 'cloudflare'])\n }\n\n async executeUpsert(plan: UpsertPlan): Promise<void> {\n if (plan.records.length === 0) return\n validateRecords(plan.records)\n\n const collection = plan.collection\n const physicalIndex = this.#index(collection)\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions\n\n try {\n await this.connect()\n\n const ndjsonLines: 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 (dims !== undefined && vector.length !== dims) {\n throw new E_VECTOR_STORE_DIMENSION_MISMATCH([dims, vector.length])\n }\n const meta: any = { ...(r.metadata ?? {}) }\n if (r.document) meta.__document = r.document\n ndjsonLines.push(JSON.stringify({ id: r.id, values: vector, metadata: meta }))\n }\n\n const ndjson = ndjsonLines.join('\\n')\n\n // Build FormData for multipart upload\n const fd = new FormData()\n fd.append('vectors', new Blob([ndjson], { type: 'application/x-ndjson' }), 'vectors.ndjson')\n\n await this.#req('POST', `/${physicalIndex}/upsert`, { form: fd })\n\n // Settle until all ids are visible\n await this.#settle(collection, { present: plan.records.map((r) => r.id) })\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 await this.connect()\n const collection = plan.collection\n const physicalIndex = this.#index(collection)\n const metric = this.#metrics.get(collection) ?? this.#opts.metric ?? 'cosine'\n const offset = plan.offset ?? 0\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\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 res: any = await this.#req('POST', `/${physicalIndex}/get_by_ids`, {\n json: { ids: [plan.near.id] },\n })\n const match = Array.isArray(res) ? res[0] : res?.result?.[0]\n if (!match || !match.values) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n queryVector = match.values\n } catch (err: any) {\n const msg = String(err)\n if (msg.includes('not found') || msg.includes('404')) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n throw new E_VECTOR_STORE_SEARCH_FAILED([msg])\n }\n }\n }\n\n if (queryVector) {\n // Similarity search: query with over-fetch, JS-filter, recompute scores\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: queryVector,\n topK: OVERFETCH,\n filter: undefined, // no native filter for parity\n returnValues: true,\n returnMetadata: 'all',\n },\n })\n let rawMatches = res.matches ?? []\n\n // Filter by JS-evaluateFilter\n if (plan.filter) {\n rawMatches = rawMatches.filter((m: any) => {\n const meta = this.#projectMeta(m.metadata)\n return evaluateFilter(plan.filter!, meta)\n })\n }\n\n // Slice offset+topK\n rawMatches = rawMatches.slice(offset, offset + plan.topK)\n\n // Re-compute scores and project\n const out: VectorMatch[] = []\n for (const m of rawMatches) {\n const projected = this.#project(m, plan, undefined, metric, queryVector)\n if (projected) out.push(projected)\n }\n return out\n } else {\n // Filter-scan: query with arbitrary probe vector, over-fetch, JS-filter\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: probeVec,\n topK: OVERFETCH,\n filter: undefined,\n returnValues: false,\n returnMetadata: 'all',\n },\n })\n let rawMatches = res.matches ?? []\n\n // JS-filter\n if (plan.filter) {\n rawMatches = rawMatches.filter((m: any) => {\n const meta = this.#projectMeta(m.metadata)\n return evaluateFilter(plan.filter!, meta)\n })\n }\n\n // Slice\n rawMatches = rawMatches.slice(offset, offset + plan.topK)\n\n // Project without score\n const out: VectorMatch[] = []\n for (const m of rawMatches) {\n const projected = this.#project(m, plan, undefined, metric, undefined)\n if (projected) out.push(projected)\n }\n return out\n }\n }\n\n #projectMeta(metadata: any): VectorMetadata {\n if (!metadata || typeof metadata !== 'object') return {}\n const out: VectorMetadata = {}\n for (const key in metadata) {\n if (key !== '__document') out[key] = metadata[key]\n }\n return out\n }\n\n #project(\n match: any,\n plan: SearchPlan,\n score: number | undefined,\n metric: DistanceMetric,\n queryVector: number[] | undefined\n ): VectorMatch | null {\n const proj = plan.projection\n const out: VectorMatch = {}\n\n if (proj.id) out.id = match.id\n\n if (proj.document) {\n const meta = match.metadata ?? {}\n if (typeof meta.__document === 'string') {\n out.document = meta.__document\n }\n }\n\n if (proj.metadata) {\n out.metadata = this.#projectMeta(match.metadata)\n }\n\n if (proj.vector) {\n out.vector = match.values\n }\n\n if (typeof score === 'number') {\n out.score = score\n } else if (queryVector && match.values) {\n // Recompute score for the [0,1] contract\n out.score = computeScore(match.values, queryVector, metric)\n }\n\n // If nothing was projected, return null to filter out\n if (Object.keys(out).length === 0) return null\n return out\n }\n\n async executeDelete(plan: DeletePlan): Promise<void> {\n const collection = plan.collection\n const physicalIndex = this.#index(collection)\n\n try {\n await this.connect()\n\n if (plan.ids && plan.ids.length > 0) {\n await this.#req('POST', `/${physicalIndex}/delete_by_ids`, {\n json: { ids: plan.ids },\n })\n await this.#settle(collection, { absent: plan.ids })\n } else if (plan.filter) {\n // Enumerate all, JS-filter, delete matched\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: probeVec,\n topK: OVERFETCH,\n returnValues: true,\n returnMetadata: 'all',\n },\n })\n const targets: string[] = []\n for (const m of res.matches ?? []) {\n const meta = this.#projectMeta(m.metadata)\n if (evaluateFilter(plan.filter!, meta)) {\n targets.push(m.id)\n }\n }\n\n if (targets.length > 0) {\n await this.#req('POST', `/${physicalIndex}/delete_by_ids`, {\n json: { ids: targets },\n })\n await this.#settle(collection, { absent: targets })\n }\n } else {\n // Delete all: enumerate all ids then delete\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: probeVec,\n topK: OVERFETCH,\n returnValues: true,\n returnMetadata: 'all',\n },\n })\n\n const allIds = (res.matches ?? []).map((m: any) => m.id)\n if (allIds.length > 0) {\n await this.#req('POST', `/${physicalIndex}/delete_by_ids`, {\n json: { ids: allIds },\n })\n await this.#settle(collection, { absent: allIds })\n }\n }\n } catch (err: any) {\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-D1pSSlsd.mjs";
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";
@@ -86,6 +86,7 @@ var CloudflareVectorizeVectorStore = 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" && typeof fetch !== "undefined";
91
92
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cloudflare.mjs","names":["#opts","#baseUrl","#authHeaders","#req","#base","#headers","#settle","#index","#dims","#metrics","#projectMeta","#project"],"sources":["../../../src/batteries/vector/cloudflare/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/cloudflare\n *\n * Managed Cloudflare Vectorize V2 vector-store adapter over REST (pure fetch, no driver).\n * A logical collection maps to a Vectorize **index**. Supported dimensions: 32–1536.\n *\n * Upserter: POST /{name}/upsert via `multipart/form-data` with field name `vectors`\n * (content-type `application/x-ndjson`). Each line: `{\"id\":\"..\",\"values\":[..],\"metadata\":{..}}`.\n * Query/get/delete use JSON bodies. Eventual consistency is handled by settle-polling.\n *\n * Native filtering: Vectorize requires pre-created metadata indexes and lacks `$and`/`$or`.\n * For guaranteed cross-adapter parity, **over-fetch + JS evaluateFilter** (topK cap 100).\n *\n * Scores: returned as-is from Vectorize, then re-computed locally (cosineSim/dotProd/euclideanDist)\n * to guarantee the [0,1] contract.\n *\n * Document: stored under the reserved metadata key `__document`; extracted on read.\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_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\n// Cloudflare Vectorize V2 REST endpoint base\nconst BASE_URL = 'https://api.cloudflare.com/client/v4/accounts'\n\n// Over-fetch constant for JS filtering (Vectorize native filtering needs metadata indexes + lacks\n// $and/$or). Cloudflare caps topK at 50 when returnValues=true or returnMetadata=all (which we\n// need to recompute scores + filter locally), so 50 is the ceiling.\nconst OVERFETCH = 50\n\nconst mapMetricToCF = (metric: DistanceMetric): string => {\n if (metric === 'cosine') return 'cosine'\n if (metric === 'euclidean') return 'euclidean'\n if (metric === 'dot') return 'dot-product'\n throw new E_VECTOR_STORE_COLLECTION_FAILED([\n 'createCollection',\n `Metric \"${metric}\" is not supported by Cloudflare Vectorize; use \"cosine\", \"euclidean\", or \"dot\"`,\n ])\n}\n\n// Score computation helpers (copied from couchbase/index.ts)\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\nexport interface CloudflareVectorizeVectorStoreOptions extends BaseVectorStoreOptions {\n connection: {\n accountId: string\n apiKey: string\n indexNamePrefix?: string\n }\n}\n\nexport class CloudflareVectorizeVectorStore 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 #baseUrl: string | null = null\n #authHeaders: Record<string, string> | null = null\n #dims: Map<string, number> = new Map()\n #metrics: Map<string, DistanceMetric> = new Map()\n\n get #opts(): CloudflareVectorizeVectorStoreOptions {\n return this.options as CloudflareVectorizeVectorStoreOptions\n }\n\n static isAvailable(): boolean {\n return typeof process !== 'undefined' && typeof fetch !== 'undefined'\n }\n\n isAvailable(): boolean {\n return typeof process !== 'undefined' && typeof fetch !== 'undefined'\n }\n\n #base(): string {\n if (!this.#baseUrl) {\n this.#baseUrl = `${BASE_URL}/${this.#opts.connection.accountId}/vectorize/v2/indexes`\n }\n return this.#baseUrl\n }\n\n #headers(): Record<string, string> {\n if (!this.#authHeaders) {\n this.#authHeaders = { Authorization: `Bearer ${this.#opts.connection.apiKey}` }\n }\n return this.#authHeaders\n }\n\n // Map a logical collection name to its physical Vectorize index name (with optional prefix).\n #index(collection: string): string {\n const prefix = this.#opts.connection.indexNamePrefix ?? ''\n return `${prefix}${collection}`\n }\n\n async #req<T = any>(\n method: string,\n path: string,\n { json, form }: { json?: any; form?: FormData } = {}\n ): Promise<T> {\n const url = this.#base() + path\n const headers: Record<string, string> = { ...this.#headers() }\n let body: BodyInit | undefined\n if (form) {\n body = form\n } else if (json !== undefined) {\n body = JSON.stringify(json)\n headers['Content-Type'] = 'application/json'\n }\n const res = await fetch(url, { method, headers, body })\n const payload: any = await res.json().catch(() => ({}))\n if (!res.ok || !payload.success) {\n const msg = payload.errors?.[0]?.message || payload.messages?.[0] || `HTTP ${res.status}`\n throw new Error(msg)\n }\n return payload.result\n }\n\n // Settle-poll after writes/deletes against the QUERY index (the surface reads go through).\n //\n // Vectorize is aggressively eventually-consistent: a fresh index takes ~20s before its first\n // write is queryable, and the query index FLAPS — a just-written id can appear then vanish (or a\n // just-deleted id reappear) across consecutive polls for several seconds. A single converged poll\n // is therefore not enough. We require STABILITY: `STABLE` consecutive polls that all satisfy the\n // present/absent condition before returning, so the subsequent read-after-write is reliable.\n async #settle(\n collection: string,\n opts: { present?: string[]; absent?: string[] }\n ): Promise<void> {\n const present = opts.present ?? []\n const absent = opts.absent ?? []\n if (present.length === 0 && absent.length === 0) return\n\n const physicalIndex = this.#index(collection)\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const STABLE = 3 // consecutive satisfying polls required to declare settled\n const deadline = Date.now() + 60_000\n let streak = 0\n while (Date.now() < deadline) {\n let ok = true\n try {\n const res = await this.#req<{ matches: any[] }>('POST', `/${physicalIndex}/query`, {\n json: { vector: probeVec, topK: 50, returnValues: false, returnMetadata: 'none' },\n })\n const seen = new Set((res.matches ?? []).map((m: any) => m.id))\n if (present.length > 0 && !present.every((id) => seen.has(id))) ok = false\n if (absent.length > 0 && !absent.every((id) => !seen.has(id))) ok = false\n } catch {\n ok = false\n }\n streak = ok ? streak + 1 : 0\n if (streak >= STABLE) return\n await new Promise((r) => setTimeout(r, 500))\n }\n }\n\n async connect(): Promise<void> {\n // HTTP is stateless; the base URL + auth headers are built lazily and cached on first use.\n }\n\n async close(): Promise<void> {\n this.#baseUrl = null\n this.#authHeaders = null\n }\n\n async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n const collection = spec.collection\n const physicalIndex = this.#index(collection)\n const dims = spec.vector.dimensions\n const metric = spec.vector.metric\n\n // Validate dimensions (32–1536)\n if (dims < 32 || dims > 1536) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED([\n 'createCollection',\n `Dimensions must be 32–1536; got ${dims}`,\n ])\n }\n\n this.#dims.set(collection, dims)\n this.#metrics.set(collection, metric)\n\n if (ifNotExists) {\n if (await this.hasCollection(collection)) return\n }\n\n try {\n await this.connect()\n const body: any = {\n name: physicalIndex,\n config: {\n dimensions: dims,\n metric: mapMetricToCF(metric),\n },\n }\n await this.#req('POST', '', { json: body })\n } catch (err: any) {\n const msg = String(err)\n if (ifNotExists && msg.toLowerCase().includes('already exists')) {\n return\n }\n // If NOT ifNotExists and exists, best-effort clear (Vectorize has no bulk-clear;\n // per-test isolation uses prefix so fresh index is effectively empty).\n if (!ifNotExists && msg.toLowerCase().includes('already exists')) {\n try {\n await this.dropCollection(collection, true)\n await this.createCollection(spec, false)\n return\n } catch {\n // Fall through to rethrow original\n }\n }\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['createCollection', msg])\n }\n }\n\n async dropCollection(collection: string, ifExists: boolean): Promise<void> {\n const physicalIndex = this.#index(collection)\n\n if (ifExists) {\n if (!(await this.hasCollection(collection))) return\n } else if (!(await this.hasCollection(collection))) {\n return\n }\n\n try {\n await this.connect()\n await this.#req('DELETE', `/${physicalIndex}`)\n // Clear local state\n this.#dims.delete(collection)\n this.#metrics.delete(collection)\n } catch (err: any) {\n const msg = String(err)\n if (ifExists && (msg.includes('not found') || msg.includes('404'))) {\n return\n }\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['dropCollection', msg])\n }\n }\n\n async hasCollection(collection: string): Promise<boolean> {\n await this.connect()\n const physicalIndex = this.#index(collection)\n try {\n const res: any = await this.#req('GET', `/${physicalIndex}`)\n return !!res\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', 'cloudflare'])\n }\n\n async executeUpsert(plan: UpsertPlan): Promise<void> {\n if (plan.records.length === 0) return\n validateRecords(plan.records)\n\n const collection = plan.collection\n const physicalIndex = this.#index(collection)\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions\n\n try {\n await this.connect()\n\n const ndjsonLines: 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 (dims !== undefined && vector.length !== dims) {\n throw new E_VECTOR_STORE_DIMENSION_MISMATCH([dims, vector.length])\n }\n const meta: any = { ...(r.metadata ?? {}) }\n if (r.document) meta.__document = r.document\n ndjsonLines.push(JSON.stringify({ id: r.id, values: vector, metadata: meta }))\n }\n\n const ndjson = ndjsonLines.join('\\n')\n\n // Build FormData for multipart upload\n const fd = new FormData()\n fd.append('vectors', new Blob([ndjson], { type: 'application/x-ndjson' }), 'vectors.ndjson')\n\n await this.#req('POST', `/${physicalIndex}/upsert`, { form: fd })\n\n // Settle until all ids are visible\n await this.#settle(collection, { present: plan.records.map((r) => r.id) })\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 await this.connect()\n const collection = plan.collection\n const physicalIndex = this.#index(collection)\n const metric = this.#metrics.get(collection) ?? this.#opts.metric ?? 'cosine'\n const offset = plan.offset ?? 0\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\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 res: any = await this.#req('POST', `/${physicalIndex}/get_by_ids`, {\n json: { ids: [plan.near.id] },\n })\n const match = Array.isArray(res) ? res[0] : res?.result?.[0]\n if (!match || !match.values) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n queryVector = match.values\n } catch (err: any) {\n const msg = String(err)\n if (msg.includes('not found') || msg.includes('404')) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n throw new E_VECTOR_STORE_SEARCH_FAILED([msg])\n }\n }\n }\n\n if (queryVector) {\n // Similarity search: query with over-fetch, JS-filter, recompute scores\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: queryVector,\n topK: OVERFETCH,\n filter: undefined, // no native filter for parity\n returnValues: true,\n returnMetadata: 'all',\n },\n })\n let rawMatches = res.matches ?? []\n\n // Filter by JS-evaluateFilter\n if (plan.filter) {\n rawMatches = rawMatches.filter((m: any) => {\n const meta = this.#projectMeta(m.metadata)\n return evaluateFilter(plan.filter!, meta)\n })\n }\n\n // Slice offset+topK\n rawMatches = rawMatches.slice(offset, offset + plan.topK)\n\n // Re-compute scores and project\n const out: VectorMatch[] = []\n for (const m of rawMatches) {\n const projected = this.#project(m, plan, undefined, metric, queryVector)\n if (projected) out.push(projected)\n }\n return out\n } else {\n // Filter-scan: query with arbitrary probe vector, over-fetch, JS-filter\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: probeVec,\n topK: OVERFETCH,\n filter: undefined,\n returnValues: false,\n returnMetadata: 'all',\n },\n })\n let rawMatches = res.matches ?? []\n\n // JS-filter\n if (plan.filter) {\n rawMatches = rawMatches.filter((m: any) => {\n const meta = this.#projectMeta(m.metadata)\n return evaluateFilter(plan.filter!, meta)\n })\n }\n\n // Slice\n rawMatches = rawMatches.slice(offset, offset + plan.topK)\n\n // Project without score\n const out: VectorMatch[] = []\n for (const m of rawMatches) {\n const projected = this.#project(m, plan, undefined, metric, undefined)\n if (projected) out.push(projected)\n }\n return out\n }\n }\n\n #projectMeta(metadata: any): VectorMetadata {\n if (!metadata || typeof metadata !== 'object') return {}\n const out: VectorMetadata = {}\n for (const key in metadata) {\n if (key !== '__document') out[key] = metadata[key]\n }\n return out\n }\n\n #project(\n match: any,\n plan: SearchPlan,\n score: number | undefined,\n metric: DistanceMetric,\n queryVector: number[] | undefined\n ): VectorMatch | null {\n const proj = plan.projection\n const out: VectorMatch = {}\n\n if (proj.id) out.id = match.id\n\n if (proj.document) {\n const meta = match.metadata ?? {}\n if (typeof meta.__document === 'string') {\n out.document = meta.__document\n }\n }\n\n if (proj.metadata) {\n out.metadata = this.#projectMeta(match.metadata)\n }\n\n if (proj.vector) {\n out.vector = match.values\n }\n\n if (typeof score === 'number') {\n out.score = score\n } else if (queryVector && match.values) {\n // Recompute score for the [0,1] contract\n out.score = computeScore(match.values, queryVector, metric)\n }\n\n // If nothing was projected, return null to filter out\n if (Object.keys(out).length === 0) return null\n return out\n }\n\n async executeDelete(plan: DeletePlan): Promise<void> {\n const collection = plan.collection\n const physicalIndex = this.#index(collection)\n\n try {\n await this.connect()\n\n if (plan.ids && plan.ids.length > 0) {\n await this.#req('POST', `/${physicalIndex}/delete_by_ids`, {\n json: { ids: plan.ids },\n })\n await this.#settle(collection, { absent: plan.ids })\n } else if (plan.filter) {\n // Enumerate all, JS-filter, delete matched\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: probeVec,\n topK: OVERFETCH,\n returnValues: true,\n returnMetadata: 'all',\n },\n })\n const targets: string[] = []\n for (const m of res.matches ?? []) {\n const meta = this.#projectMeta(m.metadata)\n if (evaluateFilter(plan.filter!, meta)) {\n targets.push(m.id)\n }\n }\n\n if (targets.length > 0) {\n await this.#req('POST', `/${physicalIndex}/delete_by_ids`, {\n json: { ids: targets },\n })\n await this.#settle(collection, { absent: targets })\n }\n } else {\n // Delete all: enumerate all ids then delete\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: probeVec,\n topK: OVERFETCH,\n returnValues: true,\n returnMetadata: 'all',\n },\n })\n\n const allIds = (res.matches ?? []).map((m: any) => m.id)\n if (allIds.length > 0) {\n await this.#req('POST', `/${physicalIndex}/delete_by_ids`, {\n json: { ids: allIds },\n })\n await this.#settle(collection, { absent: allIds })\n }\n }\n } catch (err: any) {\n throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cloudflare.mjs","names":["#opts","#baseUrl","#authHeaders","#req","#base","#headers","#settle","#index","#dims","#metrics","#projectMeta","#project"],"sources":["../../../src/batteries/vector/cloudflare/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/cloudflare\n *\n * Managed Cloudflare Vectorize V2 vector-store adapter over REST (pure fetch, no driver).\n * A logical collection maps to a Vectorize **index**. Supported dimensions: 32–1536.\n *\n * Upserter: POST /{name}/upsert via `multipart/form-data` with field name `vectors`\n * (content-type `application/x-ndjson`). Each line: `{\"id\":\"..\",\"values\":[..],\"metadata\":{..}}`.\n * Query/get/delete use JSON bodies. Eventual consistency is handled by settle-polling.\n *\n * Native filtering: Vectorize requires pre-created metadata indexes and lacks `$and`/`$or`.\n * For guaranteed cross-adapter parity, **over-fetch + JS evaluateFilter** (topK cap 100).\n *\n * Scores: returned as-is from Vectorize, then re-computed locally (cosineSim/dotProd/euclideanDist)\n * to guarantee the [0,1] contract.\n *\n * Document: stored under the reserved metadata key `__document`; extracted on read.\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_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\n// Cloudflare Vectorize V2 REST endpoint base\nconst BASE_URL = 'https://api.cloudflare.com/client/v4/accounts'\n\n// Over-fetch constant for JS filtering (Vectorize native filtering needs metadata indexes + lacks\n// $and/$or). Cloudflare caps topK at 50 when returnValues=true or returnMetadata=all (which we\n// need to recompute scores + filter locally), so 50 is the ceiling.\nconst OVERFETCH = 50\n\nconst mapMetricToCF = (metric: DistanceMetric): string => {\n if (metric === 'cosine') return 'cosine'\n if (metric === 'euclidean') return 'euclidean'\n if (metric === 'dot') return 'dot-product'\n throw new E_VECTOR_STORE_COLLECTION_FAILED([\n 'createCollection',\n `Metric \"${metric}\" is not supported by Cloudflare Vectorize; use \"cosine\", \"euclidean\", or \"dot\"`,\n ])\n}\n\n// Score computation helpers (copied from couchbase/index.ts)\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\nexport interface CloudflareVectorizeVectorStoreOptions extends BaseVectorStoreOptions {\n /** Connection and authentication parameters for the backend. */\n connection: {\n accountId: string\n apiKey: string\n indexNamePrefix?: string\n }\n}\n\nexport class CloudflareVectorizeVectorStore 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 #baseUrl: string | null = null\n #authHeaders: Record<string, string> | null = null\n #dims: Map<string, number> = new Map()\n #metrics: Map<string, DistanceMetric> = new Map()\n\n get #opts(): CloudflareVectorizeVectorStoreOptions {\n return this.options as CloudflareVectorizeVectorStoreOptions\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' && typeof fetch !== 'undefined'\n }\n\n isAvailable(): boolean {\n return typeof process !== 'undefined' && typeof fetch !== 'undefined'\n }\n\n #base(): string {\n if (!this.#baseUrl) {\n this.#baseUrl = `${BASE_URL}/${this.#opts.connection.accountId}/vectorize/v2/indexes`\n }\n return this.#baseUrl\n }\n\n #headers(): Record<string, string> {\n if (!this.#authHeaders) {\n this.#authHeaders = { Authorization: `Bearer ${this.#opts.connection.apiKey}` }\n }\n return this.#authHeaders\n }\n\n // Map a logical collection name to its physical Vectorize index name (with optional prefix).\n #index(collection: string): string {\n const prefix = this.#opts.connection.indexNamePrefix ?? ''\n return `${prefix}${collection}`\n }\n\n async #req<T = any>(\n method: string,\n path: string,\n { json, form }: { json?: any; form?: FormData } = {}\n ): Promise<T> {\n const url = this.#base() + path\n const headers: Record<string, string> = { ...this.#headers() }\n let body: BodyInit | undefined\n if (form) {\n body = form\n } else if (json !== undefined) {\n body = JSON.stringify(json)\n headers['Content-Type'] = 'application/json'\n }\n const res = await fetch(url, { method, headers, body })\n const payload: any = await res.json().catch(() => ({}))\n if (!res.ok || !payload.success) {\n const msg = payload.errors?.[0]?.message || payload.messages?.[0] || `HTTP ${res.status}`\n throw new Error(msg)\n }\n return payload.result\n }\n\n // Settle-poll after writes/deletes against the QUERY index (the surface reads go through).\n //\n // Vectorize is aggressively eventually-consistent: a fresh index takes ~20s before its first\n // write is queryable, and the query index FLAPS — a just-written id can appear then vanish (or a\n // just-deleted id reappear) across consecutive polls for several seconds. A single converged poll\n // is therefore not enough. We require STABILITY: `STABLE` consecutive polls that all satisfy the\n // present/absent condition before returning, so the subsequent read-after-write is reliable.\n async #settle(\n collection: string,\n opts: { present?: string[]; absent?: string[] }\n ): Promise<void> {\n const present = opts.present ?? []\n const absent = opts.absent ?? []\n if (present.length === 0 && absent.length === 0) return\n\n const physicalIndex = this.#index(collection)\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const STABLE = 3 // consecutive satisfying polls required to declare settled\n const deadline = Date.now() + 60_000\n let streak = 0\n while (Date.now() < deadline) {\n let ok = true\n try {\n const res = await this.#req<{ matches: any[] }>('POST', `/${physicalIndex}/query`, {\n json: { vector: probeVec, topK: 50, returnValues: false, returnMetadata: 'none' },\n })\n const seen = new Set((res.matches ?? []).map((m: any) => m.id))\n if (present.length > 0 && !present.every((id) => seen.has(id))) ok = false\n if (absent.length > 0 && !absent.every((id) => !seen.has(id))) ok = false\n } catch {\n ok = false\n }\n streak = ok ? streak + 1 : 0\n if (streak >= STABLE) return\n await new Promise((r) => setTimeout(r, 500))\n }\n }\n\n async connect(): Promise<void> {\n // HTTP is stateless; the base URL + auth headers are built lazily and cached on first use.\n }\n\n async close(): Promise<void> {\n this.#baseUrl = null\n this.#authHeaders = null\n }\n\n async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n const collection = spec.collection\n const physicalIndex = this.#index(collection)\n const dims = spec.vector.dimensions\n const metric = spec.vector.metric\n\n // Validate dimensions (32–1536)\n if (dims < 32 || dims > 1536) {\n throw new E_VECTOR_STORE_COLLECTION_FAILED([\n 'createCollection',\n `Dimensions must be 32–1536; got ${dims}`,\n ])\n }\n\n this.#dims.set(collection, dims)\n this.#metrics.set(collection, metric)\n\n if (ifNotExists) {\n if (await this.hasCollection(collection)) return\n }\n\n try {\n await this.connect()\n const body: any = {\n name: physicalIndex,\n config: {\n dimensions: dims,\n metric: mapMetricToCF(metric),\n },\n }\n await this.#req('POST', '', { json: body })\n } catch (err: any) {\n const msg = String(err)\n if (ifNotExists && msg.toLowerCase().includes('already exists')) {\n return\n }\n // If NOT ifNotExists and exists, best-effort clear (Vectorize has no bulk-clear;\n // per-test isolation uses prefix so fresh index is effectively empty).\n if (!ifNotExists && msg.toLowerCase().includes('already exists')) {\n try {\n await this.dropCollection(collection, true)\n await this.createCollection(spec, false)\n return\n } catch {\n // Fall through to rethrow original\n }\n }\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['createCollection', msg])\n }\n }\n\n async dropCollection(collection: string, ifExists: boolean): Promise<void> {\n const physicalIndex = this.#index(collection)\n\n if (ifExists) {\n if (!(await this.hasCollection(collection))) return\n } else if (!(await this.hasCollection(collection))) {\n return\n }\n\n try {\n await this.connect()\n await this.#req('DELETE', `/${physicalIndex}`)\n // Clear local state\n this.#dims.delete(collection)\n this.#metrics.delete(collection)\n } catch (err: any) {\n const msg = String(err)\n if (ifExists && (msg.includes('not found') || msg.includes('404'))) {\n return\n }\n throw new E_VECTOR_STORE_COLLECTION_FAILED(['dropCollection', msg])\n }\n }\n\n async hasCollection(collection: string): Promise<boolean> {\n await this.connect()\n const physicalIndex = this.#index(collection)\n try {\n const res: any = await this.#req('GET', `/${physicalIndex}`)\n return !!res\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', 'cloudflare'])\n }\n\n async executeUpsert(plan: UpsertPlan): Promise<void> {\n if (plan.records.length === 0) return\n validateRecords(plan.records)\n\n const collection = plan.collection\n const physicalIndex = this.#index(collection)\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions\n\n try {\n await this.connect()\n\n const ndjsonLines: 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 (dims !== undefined && vector.length !== dims) {\n throw new E_VECTOR_STORE_DIMENSION_MISMATCH([dims, vector.length])\n }\n const meta: any = { ...(r.metadata ?? {}) }\n if (r.document) meta.__document = r.document\n ndjsonLines.push(JSON.stringify({ id: r.id, values: vector, metadata: meta }))\n }\n\n const ndjson = ndjsonLines.join('\\n')\n\n // Build FormData for multipart upload\n const fd = new FormData()\n fd.append('vectors', new Blob([ndjson], { type: 'application/x-ndjson' }), 'vectors.ndjson')\n\n await this.#req('POST', `/${physicalIndex}/upsert`, { form: fd })\n\n // Settle until all ids are visible\n await this.#settle(collection, { present: plan.records.map((r) => r.id) })\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 await this.connect()\n const collection = plan.collection\n const physicalIndex = this.#index(collection)\n const metric = this.#metrics.get(collection) ?? this.#opts.metric ?? 'cosine'\n const offset = plan.offset ?? 0\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\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 res: any = await this.#req('POST', `/${physicalIndex}/get_by_ids`, {\n json: { ids: [plan.near.id] },\n })\n const match = Array.isArray(res) ? res[0] : res?.result?.[0]\n if (!match || !match.values) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n queryVector = match.values\n } catch (err: any) {\n const msg = String(err)\n if (msg.includes('not found') || msg.includes('404')) {\n throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n }\n throw new E_VECTOR_STORE_SEARCH_FAILED([msg])\n }\n }\n }\n\n if (queryVector) {\n // Similarity search: query with over-fetch, JS-filter, recompute scores\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: queryVector,\n topK: OVERFETCH,\n filter: undefined, // no native filter for parity\n returnValues: true,\n returnMetadata: 'all',\n },\n })\n let rawMatches = res.matches ?? []\n\n // Filter by JS-evaluateFilter\n if (plan.filter) {\n rawMatches = rawMatches.filter((m: any) => {\n const meta = this.#projectMeta(m.metadata)\n return evaluateFilter(plan.filter!, meta)\n })\n }\n\n // Slice offset+topK\n rawMatches = rawMatches.slice(offset, offset + plan.topK)\n\n // Re-compute scores and project\n const out: VectorMatch[] = []\n for (const m of rawMatches) {\n const projected = this.#project(m, plan, undefined, metric, queryVector)\n if (projected) out.push(projected)\n }\n return out\n } else {\n // Filter-scan: query with arbitrary probe vector, over-fetch, JS-filter\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: probeVec,\n topK: OVERFETCH,\n filter: undefined,\n returnValues: false,\n returnMetadata: 'all',\n },\n })\n let rawMatches = res.matches ?? []\n\n // JS-filter\n if (plan.filter) {\n rawMatches = rawMatches.filter((m: any) => {\n const meta = this.#projectMeta(m.metadata)\n return evaluateFilter(plan.filter!, meta)\n })\n }\n\n // Slice\n rawMatches = rawMatches.slice(offset, offset + plan.topK)\n\n // Project without score\n const out: VectorMatch[] = []\n for (const m of rawMatches) {\n const projected = this.#project(m, plan, undefined, metric, undefined)\n if (projected) out.push(projected)\n }\n return out\n }\n }\n\n #projectMeta(metadata: any): VectorMetadata {\n if (!metadata || typeof metadata !== 'object') return {}\n const out: VectorMetadata = {}\n for (const key in metadata) {\n if (key !== '__document') out[key] = metadata[key]\n }\n return out\n }\n\n #project(\n match: any,\n plan: SearchPlan,\n score: number | undefined,\n metric: DistanceMetric,\n queryVector: number[] | undefined\n ): VectorMatch | null {\n const proj = plan.projection\n const out: VectorMatch = {}\n\n if (proj.id) out.id = match.id\n\n if (proj.document) {\n const meta = match.metadata ?? {}\n if (typeof meta.__document === 'string') {\n out.document = meta.__document\n }\n }\n\n if (proj.metadata) {\n out.metadata = this.#projectMeta(match.metadata)\n }\n\n if (proj.vector) {\n out.vector = match.values\n }\n\n if (typeof score === 'number') {\n out.score = score\n } else if (queryVector && match.values) {\n // Recompute score for the [0,1] contract\n out.score = computeScore(match.values, queryVector, metric)\n }\n\n // If nothing was projected, return null to filter out\n if (Object.keys(out).length === 0) return null\n return out\n }\n\n async executeDelete(plan: DeletePlan): Promise<void> {\n const collection = plan.collection\n const physicalIndex = this.#index(collection)\n\n try {\n await this.connect()\n\n if (plan.ids && plan.ids.length > 0) {\n await this.#req('POST', `/${physicalIndex}/delete_by_ids`, {\n json: { ids: plan.ids },\n })\n await this.#settle(collection, { absent: plan.ids })\n } else if (plan.filter) {\n // Enumerate all, JS-filter, delete matched\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: probeVec,\n topK: OVERFETCH,\n returnValues: true,\n returnMetadata: 'all',\n },\n })\n const targets: string[] = []\n for (const m of res.matches ?? []) {\n const meta = this.#projectMeta(m.metadata)\n if (evaluateFilter(plan.filter!, meta)) {\n targets.push(m.id)\n }\n }\n\n if (targets.length > 0) {\n await this.#req('POST', `/${physicalIndex}/delete_by_ids`, {\n json: { ids: targets },\n })\n await this.#settle(collection, { absent: targets })\n }\n } else {\n // Delete all: enumerate all ids then delete\n const dims = this.#dims.get(collection) ?? this.#opts.dimensions ?? 32\n const probeVec = new Array(dims).fill(0)\n probeVec[0] = 1\n\n const res: any = await this.#req('POST', `/${physicalIndex}/query`, {\n json: {\n vector: probeVec,\n topK: OVERFETCH,\n returnValues: true,\n returnMetadata: 'all',\n },\n })\n\n const allIds = (res.matches ?? []).map((m: any) => m.id)\n if (allIds.length > 0) {\n await this.#req('POST', `/${physicalIndex}/delete_by_ids`, {\n json: { ids: allIds },\n })\n await this.#settle(collection, { absent: allIds })\n }\n }\n } catch (err: any) {\n throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n }\n }\n}\n"],"mappings":"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"}
@@ -7,8 +7,30 @@
7
7
  * @module @nhtio/adk/batteries/vector/conformance
8
8
  */
9
9
  import type { CallableVectorStore } from "../contract";
10
+ /** A deterministic stub encoder producing a 3-dim vector from simple text features. */
10
11
  export declare const stubEncoder: (texts: string[], _kind: "query" | "document") => Promise<number[][]>;
12
+ /**
13
+ * A dimension-padding encoder factory: wraps {@link stubEncoder} and zero-extends to `dim`. Used by
14
+ * backends that enforce a minimum dimension (e.g. Cloudflare Vectorize requires 32–1536).
15
+ */
11
16
  export declare const paddedStubEncoder: (dim: number) => (texts: string[], kind: "query" | "document") => Promise<number[][]>;
17
+ /**
18
+ * Drive a vector-store adapter through the shared contract suite.
19
+ *
20
+ * @remarks
21
+ * `makeStore` must return an already-connected store whose `'docs'` collection is created at the
22
+ * matching dimension; it is re-invoked per test so retries are self-contained. `dim` defaults to 3
23
+ * — pass a larger value for backends with a dimension floor (the harness pads every test vector to
24
+ * `dim`). `opts.retry` / `opts.timeout` are forwarded to every `it()` (defaults: retry 0, 5s) and
25
+ * exist for aggressively eventually-consistent managed backends whose read-after-write can flap for
26
+ * seconds — a retried attempt re-runs `makeStore()` against an index that has had more time to
27
+ * settle, without weakening any assertion.
28
+ *
29
+ * @param label - Human-readable label for the suite (the adapter name).
30
+ * @param makeStore - Factory returning a fresh, connected store with the `'docs'` collection.
31
+ * @param dim - Vector dimensionality the harness pads to (default 3).
32
+ * @param opts - Per-`it` retry/timeout overrides.
33
+ */
12
34
  export declare const runVectorStoreConformance: (label: string, makeStore: () => Promise<CallableVectorStore>, dim?: number, opts?: {
13
35
  retry?: number;
14
36
  timeout?: number;
@@ -10,11 +10,16 @@ let vitest = require("vitest");
10
10
  *
11
11
  * @module @nhtio/adk/batteries/vector/conformance
12
12
  */
13
+ /** A deterministic stub encoder producing a 3-dim vector from simple text features. */
13
14
  var stubEncoder = async (texts, _kind) => texts.map((tx) => [
14
15
  tx.length,
15
16
  tx.includes("cat") ? 1 : 0,
16
17
  tx.includes("dog") ? 1 : 0
17
18
  ]);
19
+ /**
20
+ * A dimension-padding encoder factory: wraps {@link stubEncoder} and zero-extends to `dim`. Used by
21
+ * backends that enforce a minimum dimension (e.g. Cloudflare Vectorize requires 32–1536).
22
+ */
18
23
  var paddedStubEncoder = (dim) => async (texts, kind) => {
19
24
  return (await stubEncoder(texts, kind)).map((v) => padVector(v, dim));
20
25
  };
@@ -23,6 +28,23 @@ var padVector = (v, dim) => {
23
28
  if (v.length > dim) return v.slice(0, dim);
24
29
  return [...v, ...new Array(dim - v.length).fill(0)];
25
30
  };
31
+ /**
32
+ * Drive a vector-store adapter through the shared contract suite.
33
+ *
34
+ * @remarks
35
+ * `makeStore` must return an already-connected store whose `'docs'` collection is created at the
36
+ * matching dimension; it is re-invoked per test so retries are self-contained. `dim` defaults to 3
37
+ * — pass a larger value for backends with a dimension floor (the harness pads every test vector to
38
+ * `dim`). `opts.retry` / `opts.timeout` are forwarded to every `it()` (defaults: retry 0, 5s) and
39
+ * exist for aggressively eventually-consistent managed backends whose read-after-write can flap for
40
+ * seconds — a retried attempt re-runs `makeStore()` against an index that has had more time to
41
+ * settle, without weakening any assertion.
42
+ *
43
+ * @param label - Human-readable label for the suite (the adapter name).
44
+ * @param makeStore - Factory returning a fresh, connected store with the `'docs'` collection.
45
+ * @param dim - Vector dimensionality the harness pads to (default 3).
46
+ * @param opts - Per-`it` retry/timeout overrides.
47
+ */
26
48
  var runVectorStoreConformance = (label, makeStore, dim = 3, opts = {}) => {
27
49
  const p = (v) => padVector(v, dim);
28
50
  const io = {
@@ -1 +1 @@
1
- {"version":3,"file":"conformance.cjs","names":[],"sources":["../../../src/batteries/vector/conformance/index.ts"],"sourcesContent":["/**\n * Shared conformance suite for vector-store adapters. Drive any adapter through\n * {@link runVectorStoreConformance} to verify it honours the same contract all shipped adapters do.\n * Public, deep-import-only (`@nhtio/adk/batteries/vector/conformance`) — it imports `vitest`, an\n * optional peer you install to run the suite; it is never pulled in by the battery barrel.\n *\n * @module @nhtio/adk/batteries/vector/conformance\n */\n\nimport { describe, expect, it } from 'vitest'\nimport type { CallableVectorStore } from '../contract'\n\n// A deterministic stub encoder: 3-dim vector from text features.\nexport const stubEncoder = async (\n texts: string[],\n _kind: 'query' | 'document'\n): Promise<number[][]> =>\n texts.map((tx) => [tx.length, tx.includes('cat') ? 1 : 0, tx.includes('dog') ? 1 : 0])\n\n// A dimension-padding encoder factory: wraps the 3-feature stub and zero-extends to `dim`.\n// Used by backends that enforce a minimum dimension (e.g. Cloudflare Vectorize requires 32–1536).\nexport const paddedStubEncoder =\n (dim: number) =>\n async (texts: string[], kind: 'query' | 'document'): Promise<number[][]> => {\n const base = await stubEncoder(texts, kind)\n return base.map((v) => padVector(v, dim))\n }\n\n// Zero-extend (or truncate) a vector to exactly `dim` entries. dim===3 (the default) returns the\n// vector unchanged, so existing callers are byte-for-byte identical.\nconst padVector = (v: number[], dim: number): number[] => {\n if (v.length === dim) return v\n if (v.length > dim) return v.slice(0, dim)\n return [...v, ...new Array(dim - v.length).fill(0)]\n}\n\n// makeStore: () => Promise<CallableVectorStore> | CallableVectorStore (already connected +\n// collection 'docs' created with the matching dimension). `dim` defaults to 3 — pass a larger\n// value for backends with a dimension floor (the harness pads every test vector to `dim`, and the\n// store's collection must be created at the same `dim`).\n//\n// `opts.retry` / `opts.timeout` are forwarded to every `it()`. Both default to vitest's defaults\n// (retry 0), so existing callers are unchanged. They exist for aggressively eventually-consistent\n// managed backends (e.g. Cloudflare Vectorize) whose read-after-write can flap for seconds: a\n// retried attempt re-runs `makeStore()` (re-clearing state) against an index that's had more time\n// to settle, turning transient-consistency flake into deterministic green without weakening any\n// assertion. Each `it` re-derives its store via makeStore, so retries are self-contained.\nexport const runVectorStoreConformance = (\n label: string,\n makeStore: () => Promise<CallableVectorStore>,\n dim = 3,\n opts: { retry?: number; timeout?: number } = {}\n): void => {\n const p = (v: number[]): number[] => padVector(v, dim)\n const io = { retry: opts.retry ?? 0, timeout: opts.timeout ?? 5000 }\n describe('conformance: ' + label, () => {\n it('upserts vectors and searches by nearVector with [0,1] score', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([\n { id: '1', vector: p([3, 1, 0]), metadata: { kind: 'animal' } },\n { id: '2', vector: p([3, 0, 1]), metadata: { kind: 'animal' } },\n ])\n const res = await vs('docs')\n .nearVector(p([3, 1, 0]))\n .select('id', 'score')\n .limit(2)\n expect(res.length).toBe(2)\n expect(res[0].id).toBeDefined()\n expect(typeof res[0].score).toBe('number')\n expect(res[0].score! >= 0 && res[0].score! <= 1).toBe(true)\n })\n it('encodes text on upsert+nearText when an encoder is configured', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([{ id: 'c', document: 'cat', metadata: {} }])\n const res = await vs('docs').nearText('cat').select('id').limit(1)\n expect(res.length).toBe(1)\n expect(res[0].id).toBe('c')\n })\n it('requires .select() on reads', io, async () => {\n const vs = await makeStore()\n await expect(\n (async () => {\n await vs('docs').nearVector(p([1, 1, 1]))\n })()\n ).rejects.toThrow()\n })\n it('filter-scan (no near) returns rows without score', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([{ id: '1', vector: p([1, 0, 0]), metadata: { kind: 'x' } }])\n const res = await vs('docs').where('kind', 'x').select('id', 'metadata').limit(10)\n expect(res.length).toBe(1)\n expect(res[0].score).toBeUndefined()\n })\n it('nested filter A AND (B OR C) selects the right subset', io, async () => {\n const vs = await makeStore()\n // Every record carries all three fields so the test probes nested AND/OR routing, not\n // backend-specific missing-field semantics (e.g. Chroma's $or excludes records missing a\n // referenced key, where the JS evaluator treats that clause as merely false).\n await vs('docs').upsert([\n { id: 'a', vector: p([1, 0, 0]), metadata: { kind: 'doc', year: 2024, pinned: false } }, // kept (year arm)\n { id: 'b', vector: p([0, 1, 0]), metadata: { kind: 'doc', year: 2010, pinned: false } }, // dropped (neither arm)\n { id: 'c', vector: p([0, 0, 1]), metadata: { kind: 'doc', year: 2010, pinned: true } }, // kept (pinned arm)\n { id: 'd', vector: p([1, 1, 0]), metadata: { kind: 'other', year: 2024, pinned: true } }, // dropped (kind mismatch)\n ])\n // kind = 'doc' AND (year >= 2024 OR pinned = true)\n const res = await vs('docs')\n .where('kind', 'doc')\n .andWhere((qb) => qb.where('year', '>=', 2024).orWhere('pinned', true))\n .select('id')\n .limit(10)\n expect(res.map((r) => r.id).sort()).toEqual(['a', 'c'])\n })\n it('projection: vector excluded unless selected', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([{ id: '1', vector: p([1, 0, 0]) }])\n const noVec = await vs('docs')\n .nearVector(p([1, 0, 0]))\n .select('id')\n .limit(1)\n expect(noVec[0].vector).toBeUndefined()\n const withVec = await vs('docs')\n .nearVector(p([1, 0, 0]))\n .select('id', 'vector')\n .limit(1)\n expect(Array.isArray(withVec[0].vector)).toBe(true)\n })\n it('deletes by id', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([\n { id: '1', vector: p([1, 0, 0]) },\n { id: '2', vector: p([0, 1, 0]) },\n ])\n await vs('docs').whereIn('id', ['1']).delete()\n const all = await vs('docs').select('id').limit(10)\n expect(all.length).toBe(1)\n })\n it('throws transaction-unsupported when capabilities.transactions is false', io, async () => {\n const vs = await makeStore()\n if (!vs.capabilities.transactions) {\n await expect(vs.transaction(async () => {})).rejects.toThrow()\n }\n })\n })\n}\n"],"mappings":";;;;;;;;;;;;AAaA,IAAa,cAAc,OACzB,OACA,UAEA,MAAM,KAAK,OAAO;CAAC,GAAG;CAAQ,GAAG,SAAS,KAAK,IAAI,IAAI;CAAG,GAAG,SAAS,KAAK,IAAI,IAAI;AAAC,CAAC;AAIvF,IAAa,qBACV,QACD,OAAO,OAAiB,SAAoD;CAE1E,QAAO,MADY,YAAY,OAAO,IAAI,GAC9B,KAAK,MAAM,UAAU,GAAG,GAAG,CAAC;AAC1C;AAIF,IAAM,aAAa,GAAa,QAA0B;CACxD,IAAI,EAAE,WAAW,KAAK,OAAO;CAC7B,IAAI,EAAE,SAAS,KAAK,OAAO,EAAE,MAAM,GAAG,GAAG;CACzC,OAAO,CAAC,GAAG,GAAG,GAAG,IAAI,MAAM,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AACpD;AAaA,IAAa,6BACX,OACA,WACA,MAAM,GACN,OAA6C,CAAC,MACrC;CACT,MAAM,KAAK,MAA0B,UAAU,GAAG,GAAG;CACrD,MAAM,KAAK;EAAE,OAAO,KAAK,SAAS;EAAG,SAAS,KAAK,WAAW;CAAK;CACnE,CAAA,GAAA,OAAA,UAAS,kBAAkB,aAAa;EACtC,CAAA,GAAA,OAAA,IAAG,+DAA+D,IAAI,YAAY;GAChF,MAAM,KAAK,MAAM,UAAU;GAC3B,MAAM,GAAG,MAAM,EAAE,OAAO,CACtB;IAAE,IAAI;IAAK,QAAQ,EAAE;KAAC;KAAG;KAAG;IAAC,CAAC;IAAG,UAAU,EAAE,MAAM,SAAS;GAAE,GAC9D;IAAE,IAAI;IAAK,QAAQ,EAAE;KAAC;KAAG;KAAG;IAAC,CAAC;IAAG,UAAU,EAAE,MAAM,SAAS;GAAE,CAChE,CAAC;GACD,MAAM,MAAM,MAAM,GAAG,MAAM,EACxB,WAAW,EAAE;IAAC;IAAG;IAAG;GAAC,CAAC,CAAC,EACvB,OAAO,MAAM,OAAO,EACpB,MAAM,CAAC;GACV,CAAA,GAAA,OAAA,QAAO,IAAI,MAAM,EAAE,KAAK,CAAC;GACzB,CAAA,GAAA,OAAA,QAAO,IAAI,GAAG,EAAE,EAAE,YAAY;GAC9B,CAAA,GAAA,OAAA,QAAO,OAAO,IAAI,GAAG,KAAK,EAAE,KAAK,QAAQ;GACzC,CAAA,GAAA,OAAA,QAAO,IAAI,GAAG,SAAU,KAAK,IAAI,GAAG,SAAU,CAAC,EAAE,KAAK,IAAI;EAC5D,CAAC;EACD,CAAA,GAAA,OAAA,IAAG,iEAAiE,IAAI,YAAY;GAClF,MAAM,KAAK,MAAM,UAAU;GAC3B,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC;IAAE,IAAI;IAAK,UAAU;IAAO,UAAU,CAAC;GAAE,CAAC,CAAC;GACpE,MAAM,MAAM,MAAM,GAAG,MAAM,EAAE,SAAS,KAAK,EAAE,OAAO,IAAI,EAAE,MAAM,CAAC;GACjE,CAAA,GAAA,OAAA,QAAO,IAAI,MAAM,EAAE,KAAK,CAAC;GACzB,CAAA,GAAA,OAAA,QAAO,IAAI,GAAG,EAAE,EAAE,KAAK,GAAG;EAC5B,CAAC;EACD,CAAA,GAAA,OAAA,IAAG,+BAA+B,IAAI,YAAY;GAChD,MAAM,KAAK,MAAM,UAAU;GAC3B,OAAA,GAAA,OAAA,SACG,YAAY;IACX,MAAM,GAAG,MAAM,EAAE,WAAW,EAAE;KAAC;KAAG;KAAG;IAAC,CAAC,CAAC;GAC1C,GAAG,CACL,EAAE,QAAQ,QAAQ;EACpB,CAAC;EACD,CAAA,GAAA,OAAA,IAAG,oDAAoD,IAAI,YAAY;GACrE,MAAM,KAAK,MAAM,UAAU;GAC3B,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC;IAAE,IAAI;IAAK,QAAQ,EAAE;KAAC;KAAG;KAAG;IAAC,CAAC;IAAG,UAAU,EAAE,MAAM,IAAI;GAAE,CAAC,CAAC;GACpF,MAAM,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,QAAQ,GAAG,EAAE,OAAO,MAAM,UAAU,EAAE,MAAM,EAAE;GACjF,CAAA,GAAA,OAAA,QAAO,IAAI,MAAM,EAAE,KAAK,CAAC;GACzB,CAAA,GAAA,OAAA,QAAO,IAAI,GAAG,KAAK,EAAE,cAAc;EACrC,CAAC;EACD,CAAA,GAAA,OAAA,IAAG,yDAAyD,IAAI,YAAY;GAC1E,MAAM,KAAK,MAAM,UAAU;GAI3B,MAAM,GAAG,MAAM,EAAE,OAAO;IACtB;KAAE,IAAI;KAAK,QAAQ,EAAE;MAAC;MAAG;MAAG;KAAC,CAAC;KAAG,UAAU;MAAE,MAAM;MAAO,MAAM;MAAM,QAAQ;KAAM;IAAE;IACtF;KAAE,IAAI;KAAK,QAAQ,EAAE;MAAC;MAAG;MAAG;KAAC,CAAC;KAAG,UAAU;MAAE,MAAM;MAAO,MAAM;MAAM,QAAQ;KAAM;IAAE;IACtF;KAAE,IAAI;KAAK,QAAQ,EAAE;MAAC;MAAG;MAAG;KAAC,CAAC;KAAG,UAAU;MAAE,MAAM;MAAO,MAAM;MAAM,QAAQ;KAAK;IAAE;IACrF;KAAE,IAAI;KAAK,QAAQ,EAAE;MAAC;MAAG;MAAG;KAAC,CAAC;KAAG,UAAU;MAAE,MAAM;MAAS,MAAM;MAAM,QAAQ;KAAK;IAAE;GACzF,CAAC;GAOD,CAAA,GAAA,OAAA,SAAO,MALW,GAAG,MAAM,EACxB,MAAM,QAAQ,KAAK,EACnB,UAAU,OAAO,GAAG,MAAM,QAAQ,MAAM,IAAI,EAAE,QAAQ,UAAU,IAAI,CAAC,EACrE,OAAO,IAAI,EACX,MAAM,EAAE,GACA,KAAK,MAAM,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,CAAC;EACxD,CAAC;EACD,CAAA,GAAA,OAAA,IAAG,+CAA+C,IAAI,YAAY;GAChE,MAAM,KAAK,MAAM,UAAU;GAC3B,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC;IAAE,IAAI;IAAK,QAAQ,EAAE;KAAC;KAAG;KAAG;IAAC,CAAC;GAAE,CAAC,CAAC;GAK3D,CAAA,GAAA,OAAA,SAAO,MAJa,GAAG,MAAM,EAC1B,WAAW,EAAE;IAAC;IAAG;IAAG;GAAC,CAAC,CAAC,EACvB,OAAO,IAAI,EACX,MAAM,CAAC,GACG,GAAG,MAAM,EAAE,cAAc;GACtC,MAAM,UAAU,MAAM,GAAG,MAAM,EAC5B,WAAW,EAAE;IAAC;IAAG;IAAG;GAAC,CAAC,CAAC,EACvB,OAAO,MAAM,QAAQ,EACrB,MAAM,CAAC;GACV,CAAA,GAAA,OAAA,QAAO,MAAM,QAAQ,QAAQ,GAAG,MAAM,CAAC,EAAE,KAAK,IAAI;EACpD,CAAC;EACD,CAAA,GAAA,OAAA,IAAG,iBAAiB,IAAI,YAAY;GAClC,MAAM,KAAK,MAAM,UAAU;GAC3B,MAAM,GAAG,MAAM,EAAE,OAAO,CACtB;IAAE,IAAI;IAAK,QAAQ,EAAE;KAAC;KAAG;KAAG;IAAC,CAAC;GAAE,GAChC;IAAE,IAAI;IAAK,QAAQ,EAAE;KAAC;KAAG;KAAG;IAAC,CAAC;GAAE,CAClC,CAAC;GACD,MAAM,GAAG,MAAM,EAAE,QAAQ,MAAM,CAAC,GAAG,CAAC,EAAE,OAAO;GAE7C,CAAA,GAAA,OAAA,SAAO,MADW,GAAG,MAAM,EAAE,OAAO,IAAI,EAAE,MAAM,EAAE,GACvC,MAAM,EAAE,KAAK,CAAC;EAC3B,CAAC;EACD,CAAA,GAAA,OAAA,IAAG,0EAA0E,IAAI,YAAY;GAC3F,MAAM,KAAK,MAAM,UAAU;GAC3B,IAAI,CAAC,GAAG,aAAa,cACnB,OAAA,GAAA,OAAA,QAAa,GAAG,YAAY,YAAY,CAAC,CAAC,CAAC,EAAE,QAAQ,QAAQ;EAEjE,CAAC;CACH,CAAC;AACH"}
1
+ {"version":3,"file":"conformance.cjs","names":[],"sources":["../../../src/batteries/vector/conformance/index.ts"],"sourcesContent":["/**\n * Shared conformance suite for vector-store adapters. Drive any adapter through\n * {@link runVectorStoreConformance} to verify it honours the same contract all shipped adapters do.\n * Public, deep-import-only (`@nhtio/adk/batteries/vector/conformance`) — it imports `vitest`, an\n * optional peer you install to run the suite; it is never pulled in by the battery barrel.\n *\n * @module @nhtio/adk/batteries/vector/conformance\n */\n\nimport { describe, expect, it } from 'vitest'\nimport type { CallableVectorStore } from '../contract'\n\n/** A deterministic stub encoder producing a 3-dim vector from simple text features. */\nexport const stubEncoder = async (\n texts: string[],\n _kind: 'query' | 'document'\n): Promise<number[][]> =>\n texts.map((tx) => [tx.length, tx.includes('cat') ? 1 : 0, tx.includes('dog') ? 1 : 0])\n\n/**\n * A dimension-padding encoder factory: wraps {@link stubEncoder} and zero-extends to `dim`. Used by\n * backends that enforce a minimum dimension (e.g. Cloudflare Vectorize requires 32–1536).\n */\nexport const paddedStubEncoder =\n (dim: number) =>\n async (texts: string[], kind: 'query' | 'document'): Promise<number[][]> => {\n const base = await stubEncoder(texts, kind)\n return base.map((v) => padVector(v, dim))\n }\n\n// Zero-extend (or truncate) a vector to exactly `dim` entries. dim===3 (the default) returns the\n// vector unchanged, so existing callers are byte-for-byte identical.\nconst padVector = (v: number[], dim: number): number[] => {\n if (v.length === dim) return v\n if (v.length > dim) return v.slice(0, dim)\n return [...v, ...new Array(dim - v.length).fill(0)]\n}\n\n/**\n * Drive a vector-store adapter through the shared contract suite.\n *\n * @remarks\n * `makeStore` must return an already-connected store whose `'docs'` collection is created at the\n * matching dimension; it is re-invoked per test so retries are self-contained. `dim` defaults to 3\n * — pass a larger value for backends with a dimension floor (the harness pads every test vector to\n * `dim`). `opts.retry` / `opts.timeout` are forwarded to every `it()` (defaults: retry 0, 5s) and\n * exist for aggressively eventually-consistent managed backends whose read-after-write can flap for\n * seconds — a retried attempt re-runs `makeStore()` against an index that has had more time to\n * settle, without weakening any assertion.\n *\n * @param label - Human-readable label for the suite (the adapter name).\n * @param makeStore - Factory returning a fresh, connected store with the `'docs'` collection.\n * @param dim - Vector dimensionality the harness pads to (default 3).\n * @param opts - Per-`it` retry/timeout overrides.\n */\nexport const runVectorStoreConformance = (\n label: string,\n makeStore: () => Promise<CallableVectorStore>,\n dim = 3,\n opts: { retry?: number; timeout?: number } = {}\n): void => {\n const p = (v: number[]): number[] => padVector(v, dim)\n const io = { retry: opts.retry ?? 0, timeout: opts.timeout ?? 5000 }\n describe('conformance: ' + label, () => {\n it('upserts vectors and searches by nearVector with [0,1] score', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([\n { id: '1', vector: p([3, 1, 0]), metadata: { kind: 'animal' } },\n { id: '2', vector: p([3, 0, 1]), metadata: { kind: 'animal' } },\n ])\n const res = await vs('docs')\n .nearVector(p([3, 1, 0]))\n .select('id', 'score')\n .limit(2)\n expect(res.length).toBe(2)\n expect(res[0].id).toBeDefined()\n expect(typeof res[0].score).toBe('number')\n expect(res[0].score! >= 0 && res[0].score! <= 1).toBe(true)\n })\n it('encodes text on upsert+nearText when an encoder is configured', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([{ id: 'c', document: 'cat', metadata: {} }])\n const res = await vs('docs').nearText('cat').select('id').limit(1)\n expect(res.length).toBe(1)\n expect(res[0].id).toBe('c')\n })\n it('requires .select() on reads', io, async () => {\n const vs = await makeStore()\n await expect(\n (async () => {\n await vs('docs').nearVector(p([1, 1, 1]))\n })()\n ).rejects.toThrow()\n })\n it('filter-scan (no near) returns rows without score', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([{ id: '1', vector: p([1, 0, 0]), metadata: { kind: 'x' } }])\n const res = await vs('docs').where('kind', 'x').select('id', 'metadata').limit(10)\n expect(res.length).toBe(1)\n expect(res[0].score).toBeUndefined()\n })\n it('nested filter A AND (B OR C) selects the right subset', io, async () => {\n const vs = await makeStore()\n // Every record carries all three fields so the test probes nested AND/OR routing, not\n // backend-specific missing-field semantics (e.g. Chroma's $or excludes records missing a\n // referenced key, where the JS evaluator treats that clause as merely false).\n await vs('docs').upsert([\n { id: 'a', vector: p([1, 0, 0]), metadata: { kind: 'doc', year: 2024, pinned: false } }, // kept (year arm)\n { id: 'b', vector: p([0, 1, 0]), metadata: { kind: 'doc', year: 2010, pinned: false } }, // dropped (neither arm)\n { id: 'c', vector: p([0, 0, 1]), metadata: { kind: 'doc', year: 2010, pinned: true } }, // kept (pinned arm)\n { id: 'd', vector: p([1, 1, 0]), metadata: { kind: 'other', year: 2024, pinned: true } }, // dropped (kind mismatch)\n ])\n // kind = 'doc' AND (year >= 2024 OR pinned = true)\n const res = await vs('docs')\n .where('kind', 'doc')\n .andWhere((qb) => qb.where('year', '>=', 2024).orWhere('pinned', true))\n .select('id')\n .limit(10)\n expect(res.map((r) => r.id).sort()).toEqual(['a', 'c'])\n })\n it('projection: vector excluded unless selected', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([{ id: '1', vector: p([1, 0, 0]) }])\n const noVec = await vs('docs')\n .nearVector(p([1, 0, 0]))\n .select('id')\n .limit(1)\n expect(noVec[0].vector).toBeUndefined()\n const withVec = await vs('docs')\n .nearVector(p([1, 0, 0]))\n .select('id', 'vector')\n .limit(1)\n expect(Array.isArray(withVec[0].vector)).toBe(true)\n })\n it('deletes by id', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([\n { id: '1', vector: p([1, 0, 0]) },\n { id: '2', vector: p([0, 1, 0]) },\n ])\n await vs('docs').whereIn('id', ['1']).delete()\n const all = await vs('docs').select('id').limit(10)\n expect(all.length).toBe(1)\n })\n it('throws transaction-unsupported when capabilities.transactions is false', io, async () => {\n const vs = await makeStore()\n if (!vs.capabilities.transactions) {\n await expect(vs.transaction(async () => {})).rejects.toThrow()\n }\n })\n })\n}\n"],"mappings":"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"}
@@ -8,11 +8,16 @@ import { describe, expect, it } from "vitest";
8
8
  *
9
9
  * @module @nhtio/adk/batteries/vector/conformance
10
10
  */
11
+ /** A deterministic stub encoder producing a 3-dim vector from simple text features. */
11
12
  var stubEncoder = async (texts, _kind) => texts.map((tx) => [
12
13
  tx.length,
13
14
  tx.includes("cat") ? 1 : 0,
14
15
  tx.includes("dog") ? 1 : 0
15
16
  ]);
17
+ /**
18
+ * A dimension-padding encoder factory: wraps {@link stubEncoder} and zero-extends to `dim`. Used by
19
+ * backends that enforce a minimum dimension (e.g. Cloudflare Vectorize requires 32–1536).
20
+ */
16
21
  var paddedStubEncoder = (dim) => async (texts, kind) => {
17
22
  return (await stubEncoder(texts, kind)).map((v) => padVector(v, dim));
18
23
  };
@@ -21,6 +26,23 @@ var padVector = (v, dim) => {
21
26
  if (v.length > dim) return v.slice(0, dim);
22
27
  return [...v, ...new Array(dim - v.length).fill(0)];
23
28
  };
29
+ /**
30
+ * Drive a vector-store adapter through the shared contract suite.
31
+ *
32
+ * @remarks
33
+ * `makeStore` must return an already-connected store whose `'docs'` collection is created at the
34
+ * matching dimension; it is re-invoked per test so retries are self-contained. `dim` defaults to 3
35
+ * — pass a larger value for backends with a dimension floor (the harness pads every test vector to
36
+ * `dim`). `opts.retry` / `opts.timeout` are forwarded to every `it()` (defaults: retry 0, 5s) and
37
+ * exist for aggressively eventually-consistent managed backends whose read-after-write can flap for
38
+ * seconds — a retried attempt re-runs `makeStore()` against an index that has had more time to
39
+ * settle, without weakening any assertion.
40
+ *
41
+ * @param label - Human-readable label for the suite (the adapter name).
42
+ * @param makeStore - Factory returning a fresh, connected store with the `'docs'` collection.
43
+ * @param dim - Vector dimensionality the harness pads to (default 3).
44
+ * @param opts - Per-`it` retry/timeout overrides.
45
+ */
24
46
  var runVectorStoreConformance = (label, makeStore, dim = 3, opts = {}) => {
25
47
  const p = (v) => padVector(v, dim);
26
48
  const io = {
@@ -1 +1 @@
1
- {"version":3,"file":"conformance.mjs","names":[],"sources":["../../../src/batteries/vector/conformance/index.ts"],"sourcesContent":["/**\n * Shared conformance suite for vector-store adapters. Drive any adapter through\n * {@link runVectorStoreConformance} to verify it honours the same contract all shipped adapters do.\n * Public, deep-import-only (`@nhtio/adk/batteries/vector/conformance`) — it imports `vitest`, an\n * optional peer you install to run the suite; it is never pulled in by the battery barrel.\n *\n * @module @nhtio/adk/batteries/vector/conformance\n */\n\nimport { describe, expect, it } from 'vitest'\nimport type { CallableVectorStore } from '../contract'\n\n// A deterministic stub encoder: 3-dim vector from text features.\nexport const stubEncoder = async (\n texts: string[],\n _kind: 'query' | 'document'\n): Promise<number[][]> =>\n texts.map((tx) => [tx.length, tx.includes('cat') ? 1 : 0, tx.includes('dog') ? 1 : 0])\n\n// A dimension-padding encoder factory: wraps the 3-feature stub and zero-extends to `dim`.\n// Used by backends that enforce a minimum dimension (e.g. Cloudflare Vectorize requires 32–1536).\nexport const paddedStubEncoder =\n (dim: number) =>\n async (texts: string[], kind: 'query' | 'document'): Promise<number[][]> => {\n const base = await stubEncoder(texts, kind)\n return base.map((v) => padVector(v, dim))\n }\n\n// Zero-extend (or truncate) a vector to exactly `dim` entries. dim===3 (the default) returns the\n// vector unchanged, so existing callers are byte-for-byte identical.\nconst padVector = (v: number[], dim: number): number[] => {\n if (v.length === dim) return v\n if (v.length > dim) return v.slice(0, dim)\n return [...v, ...new Array(dim - v.length).fill(0)]\n}\n\n// makeStore: () => Promise<CallableVectorStore> | CallableVectorStore (already connected +\n// collection 'docs' created with the matching dimension). `dim` defaults to 3 — pass a larger\n// value for backends with a dimension floor (the harness pads every test vector to `dim`, and the\n// store's collection must be created at the same `dim`).\n//\n// `opts.retry` / `opts.timeout` are forwarded to every `it()`. Both default to vitest's defaults\n// (retry 0), so existing callers are unchanged. They exist for aggressively eventually-consistent\n// managed backends (e.g. Cloudflare Vectorize) whose read-after-write can flap for seconds: a\n// retried attempt re-runs `makeStore()` (re-clearing state) against an index that's had more time\n// to settle, turning transient-consistency flake into deterministic green without weakening any\n// assertion. Each `it` re-derives its store via makeStore, so retries are self-contained.\nexport const runVectorStoreConformance = (\n label: string,\n makeStore: () => Promise<CallableVectorStore>,\n dim = 3,\n opts: { retry?: number; timeout?: number } = {}\n): void => {\n const p = (v: number[]): number[] => padVector(v, dim)\n const io = { retry: opts.retry ?? 0, timeout: opts.timeout ?? 5000 }\n describe('conformance: ' + label, () => {\n it('upserts vectors and searches by nearVector with [0,1] score', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([\n { id: '1', vector: p([3, 1, 0]), metadata: { kind: 'animal' } },\n { id: '2', vector: p([3, 0, 1]), metadata: { kind: 'animal' } },\n ])\n const res = await vs('docs')\n .nearVector(p([3, 1, 0]))\n .select('id', 'score')\n .limit(2)\n expect(res.length).toBe(2)\n expect(res[0].id).toBeDefined()\n expect(typeof res[0].score).toBe('number')\n expect(res[0].score! >= 0 && res[0].score! <= 1).toBe(true)\n })\n it('encodes text on upsert+nearText when an encoder is configured', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([{ id: 'c', document: 'cat', metadata: {} }])\n const res = await vs('docs').nearText('cat').select('id').limit(1)\n expect(res.length).toBe(1)\n expect(res[0].id).toBe('c')\n })\n it('requires .select() on reads', io, async () => {\n const vs = await makeStore()\n await expect(\n (async () => {\n await vs('docs').nearVector(p([1, 1, 1]))\n })()\n ).rejects.toThrow()\n })\n it('filter-scan (no near) returns rows without score', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([{ id: '1', vector: p([1, 0, 0]), metadata: { kind: 'x' } }])\n const res = await vs('docs').where('kind', 'x').select('id', 'metadata').limit(10)\n expect(res.length).toBe(1)\n expect(res[0].score).toBeUndefined()\n })\n it('nested filter A AND (B OR C) selects the right subset', io, async () => {\n const vs = await makeStore()\n // Every record carries all three fields so the test probes nested AND/OR routing, not\n // backend-specific missing-field semantics (e.g. Chroma's $or excludes records missing a\n // referenced key, where the JS evaluator treats that clause as merely false).\n await vs('docs').upsert([\n { id: 'a', vector: p([1, 0, 0]), metadata: { kind: 'doc', year: 2024, pinned: false } }, // kept (year arm)\n { id: 'b', vector: p([0, 1, 0]), metadata: { kind: 'doc', year: 2010, pinned: false } }, // dropped (neither arm)\n { id: 'c', vector: p([0, 0, 1]), metadata: { kind: 'doc', year: 2010, pinned: true } }, // kept (pinned arm)\n { id: 'd', vector: p([1, 1, 0]), metadata: { kind: 'other', year: 2024, pinned: true } }, // dropped (kind mismatch)\n ])\n // kind = 'doc' AND (year >= 2024 OR pinned = true)\n const res = await vs('docs')\n .where('kind', 'doc')\n .andWhere((qb) => qb.where('year', '>=', 2024).orWhere('pinned', true))\n .select('id')\n .limit(10)\n expect(res.map((r) => r.id).sort()).toEqual(['a', 'c'])\n })\n it('projection: vector excluded unless selected', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([{ id: '1', vector: p([1, 0, 0]) }])\n const noVec = await vs('docs')\n .nearVector(p([1, 0, 0]))\n .select('id')\n .limit(1)\n expect(noVec[0].vector).toBeUndefined()\n const withVec = await vs('docs')\n .nearVector(p([1, 0, 0]))\n .select('id', 'vector')\n .limit(1)\n expect(Array.isArray(withVec[0].vector)).toBe(true)\n })\n it('deletes by id', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([\n { id: '1', vector: p([1, 0, 0]) },\n { id: '2', vector: p([0, 1, 0]) },\n ])\n await vs('docs').whereIn('id', ['1']).delete()\n const all = await vs('docs').select('id').limit(10)\n expect(all.length).toBe(1)\n })\n it('throws transaction-unsupported when capabilities.transactions is false', io, async () => {\n const vs = await makeStore()\n if (!vs.capabilities.transactions) {\n await expect(vs.transaction(async () => {})).rejects.toThrow()\n }\n })\n })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"conformance.mjs","names":[],"sources":["../../../src/batteries/vector/conformance/index.ts"],"sourcesContent":["/**\n * Shared conformance suite for vector-store adapters. Drive any adapter through\n * {@link runVectorStoreConformance} to verify it honours the same contract all shipped adapters do.\n * Public, deep-import-only (`@nhtio/adk/batteries/vector/conformance`) — it imports `vitest`, an\n * optional peer you install to run the suite; it is never pulled in by the battery barrel.\n *\n * @module @nhtio/adk/batteries/vector/conformance\n */\n\nimport { describe, expect, it } from 'vitest'\nimport type { CallableVectorStore } from '../contract'\n\n/** A deterministic stub encoder producing a 3-dim vector from simple text features. */\nexport const stubEncoder = async (\n texts: string[],\n _kind: 'query' | 'document'\n): Promise<number[][]> =>\n texts.map((tx) => [tx.length, tx.includes('cat') ? 1 : 0, tx.includes('dog') ? 1 : 0])\n\n/**\n * A dimension-padding encoder factory: wraps {@link stubEncoder} and zero-extends to `dim`. Used by\n * backends that enforce a minimum dimension (e.g. Cloudflare Vectorize requires 32–1536).\n */\nexport const paddedStubEncoder =\n (dim: number) =>\n async (texts: string[], kind: 'query' | 'document'): Promise<number[][]> => {\n const base = await stubEncoder(texts, kind)\n return base.map((v) => padVector(v, dim))\n }\n\n// Zero-extend (or truncate) a vector to exactly `dim` entries. dim===3 (the default) returns the\n// vector unchanged, so existing callers are byte-for-byte identical.\nconst padVector = (v: number[], dim: number): number[] => {\n if (v.length === dim) return v\n if (v.length > dim) return v.slice(0, dim)\n return [...v, ...new Array(dim - v.length).fill(0)]\n}\n\n/**\n * Drive a vector-store adapter through the shared contract suite.\n *\n * @remarks\n * `makeStore` must return an already-connected store whose `'docs'` collection is created at the\n * matching dimension; it is re-invoked per test so retries are self-contained. `dim` defaults to 3\n * — pass a larger value for backends with a dimension floor (the harness pads every test vector to\n * `dim`). `opts.retry` / `opts.timeout` are forwarded to every `it()` (defaults: retry 0, 5s) and\n * exist for aggressively eventually-consistent managed backends whose read-after-write can flap for\n * seconds — a retried attempt re-runs `makeStore()` against an index that has had more time to\n * settle, without weakening any assertion.\n *\n * @param label - Human-readable label for the suite (the adapter name).\n * @param makeStore - Factory returning a fresh, connected store with the `'docs'` collection.\n * @param dim - Vector dimensionality the harness pads to (default 3).\n * @param opts - Per-`it` retry/timeout overrides.\n */\nexport const runVectorStoreConformance = (\n label: string,\n makeStore: () => Promise<CallableVectorStore>,\n dim = 3,\n opts: { retry?: number; timeout?: number } = {}\n): void => {\n const p = (v: number[]): number[] => padVector(v, dim)\n const io = { retry: opts.retry ?? 0, timeout: opts.timeout ?? 5000 }\n describe('conformance: ' + label, () => {\n it('upserts vectors and searches by nearVector with [0,1] score', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([\n { id: '1', vector: p([3, 1, 0]), metadata: { kind: 'animal' } },\n { id: '2', vector: p([3, 0, 1]), metadata: { kind: 'animal' } },\n ])\n const res = await vs('docs')\n .nearVector(p([3, 1, 0]))\n .select('id', 'score')\n .limit(2)\n expect(res.length).toBe(2)\n expect(res[0].id).toBeDefined()\n expect(typeof res[0].score).toBe('number')\n expect(res[0].score! >= 0 && res[0].score! <= 1).toBe(true)\n })\n it('encodes text on upsert+nearText when an encoder is configured', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([{ id: 'c', document: 'cat', metadata: {} }])\n const res = await vs('docs').nearText('cat').select('id').limit(1)\n expect(res.length).toBe(1)\n expect(res[0].id).toBe('c')\n })\n it('requires .select() on reads', io, async () => {\n const vs = await makeStore()\n await expect(\n (async () => {\n await vs('docs').nearVector(p([1, 1, 1]))\n })()\n ).rejects.toThrow()\n })\n it('filter-scan (no near) returns rows without score', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([{ id: '1', vector: p([1, 0, 0]), metadata: { kind: 'x' } }])\n const res = await vs('docs').where('kind', 'x').select('id', 'metadata').limit(10)\n expect(res.length).toBe(1)\n expect(res[0].score).toBeUndefined()\n })\n it('nested filter A AND (B OR C) selects the right subset', io, async () => {\n const vs = await makeStore()\n // Every record carries all three fields so the test probes nested AND/OR routing, not\n // backend-specific missing-field semantics (e.g. Chroma's $or excludes records missing a\n // referenced key, where the JS evaluator treats that clause as merely false).\n await vs('docs').upsert([\n { id: 'a', vector: p([1, 0, 0]), metadata: { kind: 'doc', year: 2024, pinned: false } }, // kept (year arm)\n { id: 'b', vector: p([0, 1, 0]), metadata: { kind: 'doc', year: 2010, pinned: false } }, // dropped (neither arm)\n { id: 'c', vector: p([0, 0, 1]), metadata: { kind: 'doc', year: 2010, pinned: true } }, // kept (pinned arm)\n { id: 'd', vector: p([1, 1, 0]), metadata: { kind: 'other', year: 2024, pinned: true } }, // dropped (kind mismatch)\n ])\n // kind = 'doc' AND (year >= 2024 OR pinned = true)\n const res = await vs('docs')\n .where('kind', 'doc')\n .andWhere((qb) => qb.where('year', '>=', 2024).orWhere('pinned', true))\n .select('id')\n .limit(10)\n expect(res.map((r) => r.id).sort()).toEqual(['a', 'c'])\n })\n it('projection: vector excluded unless selected', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([{ id: '1', vector: p([1, 0, 0]) }])\n const noVec = await vs('docs')\n .nearVector(p([1, 0, 0]))\n .select('id')\n .limit(1)\n expect(noVec[0].vector).toBeUndefined()\n const withVec = await vs('docs')\n .nearVector(p([1, 0, 0]))\n .select('id', 'vector')\n .limit(1)\n expect(Array.isArray(withVec[0].vector)).toBe(true)\n })\n it('deletes by id', io, async () => {\n const vs = await makeStore()\n await vs('docs').upsert([\n { id: '1', vector: p([1, 0, 0]) },\n { id: '2', vector: p([0, 1, 0]) },\n ])\n await vs('docs').whereIn('id', ['1']).delete()\n const all = await vs('docs').select('id').limit(10)\n expect(all.length).toBe(1)\n })\n it('throws transaction-unsupported when capabilities.transactions is false', io, async () => {\n const vs = await makeStore()\n if (!vs.capabilities.transactions) {\n await expect(vs.transaction(async () => {})).rejects.toThrow()\n }\n })\n })\n}\n"],"mappings":"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"}
@@ -7,25 +7,47 @@ const require_batteries_vector_schema = require("./schema.cjs");
7
7
  /**
8
8
  * @module @nhtio/adk/batteries/vector/contract
9
9
  */
10
+ /**
11
+ * Abstract base shared by every bundled vector adapter. It implements the cross-cutting surface
12
+ * (`query`/`schema`/`transaction`/`asCallable`/`encode`) on top of the small set of backend-specific
13
+ * abstract methods each adapter fills in (`connect`, `executeSearch`, `createCollection`, …). Concrete
14
+ * adapters inherit the doc comments below unless they override them.
15
+ */
10
16
  var BaseVectorStore = class {
17
+ /** Construction options (connection details and the optional encoder), held for later use. */
11
18
  options;
12
19
  constructor(options) {
13
20
  this.options = options;
14
21
  }
22
+ /**
23
+ * Encode text to vectors via the configured encoder. Throws {@link E_VECTOR_STORE_ENCODER_REQUIRED}
24
+ * when the backend has no built-in encoding and no encoder was supplied.
25
+ */
15
26
  async encode(texts, kind) {
16
27
  if (this.capabilities.builtInEncoding) throw new require_batteries_vector_exceptions.E_VECTOR_STORE_ENCODER_REQUIRED(["contract"]);
17
28
  if (!this.options.encoder) throw new require_batteries_vector_exceptions.E_VECTOR_STORE_ENCODER_REQUIRED([this.constructor.name]);
18
29
  return this.options.encoder(texts, kind);
19
30
  }
31
+ /**
32
+ * Run `fn` inside a backend transaction. The base implementation rejects with
33
+ * {@link E_VECTOR_STORE_TRANSACTIONS_UNSUPPORTED}; adapters whose backend supports transactions
34
+ * override this.
35
+ */
20
36
  async transaction(_fn) {
21
37
  throw new require_batteries_vector_exceptions.E_VECTOR_STORE_TRANSACTIONS_UNSUPPORTED([this.constructor.name]);
22
38
  }
39
+ /** Schema builder bound to this store, for creating/dropping/migrating collections. */
23
40
  get schema() {
24
41
  return new require_batteries_vector_schema.VectorSchemaBuilder(this);
25
42
  }
43
+ /** Open a {@link VectorQueryBuilder} scoped to `collection` (default top-K of 10). */
26
44
  query(collection) {
27
45
  return new require_batteries_vector_builder.VectorQueryBuilder(this, collection, 10);
28
46
  }
47
+ /**
48
+ * Wrap this store in a callable proxy so `store('collection')` is shorthand for
49
+ * `store.query('collection')`, while all other methods/properties pass through unchanged.
50
+ */
29
51
  asCallable() {
30
52
  const self = this;
31
53
  const fn = ((collection) => self.query(collection));