truffler 0.1.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 (214) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +18 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +425 -0
  5. data/bench/cassettes/004cad52c71fc8d847bf388eb9c2c288e1169b65ec4a28ce040cb7fea7c55f04.json +1 -0
  6. data/bench/cassettes/0547d3d23c3fbaae86772ffa0e4e96475aa152a2556b8fa4bc7568effcb81a28.json +1 -0
  7. data/bench/cassettes/07aa23d166ab3500178e3f3c0838183051b093507bef88e1e2d29efdf5759ee6.json +1 -0
  8. data/bench/cassettes/0858c5006c0bfac3e970ddaff3c139f6c110dbe3d8539fd95263706c637cdc8e.json +1 -0
  9. data/bench/cassettes/0c0eb7c27d76bd0b9263690a63cd92d6b68c305826318555fd5b084a09970b78.json +1 -0
  10. data/bench/cassettes/0fada0c0a103882e2895f7f455d73d2cbe2b4a81bf743bb19b2b4f6e0130126b.json +1 -0
  11. data/bench/cassettes/1117d79ac7c43b21beaf75e510461f91cd4ecc3cdbbe461f1794644af4aaf8f3.json +1 -0
  12. data/bench/cassettes/11b7444a074cca4d0ef1535db0cf0edefe4c34eac4be3c593c9c2f33d3b038b8.json +1 -0
  13. data/bench/cassettes/11d00371d1b993675be00463159164536f1f8ed90a48652b0935eb9c36f8b684.json +1 -0
  14. data/bench/cassettes/1456ebe12616ce961d68a14eada62778a7271ebd3d1b4cb6eefd6857651c7afc.json +1 -0
  15. data/bench/cassettes/14c3693f64b0e9ea7e470277fccae6ab501d404185eec5bb9074ef4b75c572c0.json +1 -0
  16. data/bench/cassettes/14fe9f6d8055d41f5d970dc32ab640c213ea8782d365c82d32b9884ba4f28c67.json +1 -0
  17. data/bench/cassettes/1a1d8557e4698426c2467aa573a240357715d3d9e3fa77bf066672a8b6bf9a86.json +1 -0
  18. data/bench/cassettes/1b5a8aaaf98305560588246cd51f53c6c185a951f8018c26bf588954d9de1cea.json +1 -0
  19. data/bench/cassettes/1fe596be747e33e9c7e4d7c50de32613957ac66bee43679b4bed96c551b1fd0a.json +1 -0
  20. data/bench/cassettes/21ebce6db6d39b1747dccf25bd3ceb298e1285425190b4d78830c395a7ad786a.json +1 -0
  21. data/bench/cassettes/23066253621e9cb00fd93cbe95ef1124ff0715585fcb6325b3abbd0802b2c303.json +1 -0
  22. data/bench/cassettes/2f6576325dfab696cec8d8b35fa89c29960bee15d10dab31c91cef507f4842be.json +1 -0
  23. data/bench/cassettes/33ec27d22c0f63dbbe93008f50af07fa8667a5c806a9fbfc7897683915412b40.json +1 -0
  24. data/bench/cassettes/351f745b0c47e0cf3272b0fea7fc4941b6aa733f013c55a9a19707b542543200.json +1 -0
  25. data/bench/cassettes/37d974fdc0c1876413111c244d363c8d2306e3229fec668c158b5c924ffdb983.json +1 -0
  26. data/bench/cassettes/39524467463dd612cbf03e314b9cfd8cbe1c5f06969da2289359cf7cf83de5da.json +1 -0
  27. data/bench/cassettes/3f2c758c111ab7f1163ba579f2329718afe15620507d356d3ebe2a053df237ea.json +1 -0
  28. data/bench/cassettes/44bbc3a3f0ceb0edb443b080b939af80dd145795505bd13cac113a35365d0f04.json +1 -0
  29. data/bench/cassettes/45bf701a13c348acb45a3b3a56990570e3caf797c3daee5d1358a477593ce587.json +1 -0
  30. data/bench/cassettes/4676a0f2df29493fdfa0b7cd75c097e647373862d88373dc0e1fa9fca26707c2.json +1 -0
  31. data/bench/cassettes/49708a50e3c78f45beed2f1b8d8d5375b99ea4ab3497fed7650e6ece4ec81ba8.json +1 -0
  32. data/bench/cassettes/54ea30ecca8fa49f607d5c8265296eb16edb48d0620a7399c6480d4cb0f43ae1.json +1 -0
  33. data/bench/cassettes/550e73a8291f53d0f2b008f166560eff4d10cc7c09a927d3c4f70544f2578300.json +1 -0
  34. data/bench/cassettes/570039823d5af1b6c1d4bcbe14f9802d40e851f8e4946278a46884c76c0ceee1.json +1 -0
  35. data/bench/cassettes/5ae9dce82fa7b9084b592f657a24acfd5852c4fcb091a6a8e22f2cbbf947bcdd.json +1 -0
  36. data/bench/cassettes/5c40794d3bf6e229c6ffd26922388776121f971ef27279e02a35ce004e0794dd.json +1 -0
  37. data/bench/cassettes/62f2e71a2d9cfdc18fdd6600f5a1450519b25a75c2f799b7695258627250497d.json +1 -0
  38. data/bench/cassettes/642becd7ad9cd4cc2ac6d389ef8ff14fd9fe125beca834afee625ea2c31476be.json +1 -0
  39. data/bench/cassettes/656cc1158890e928c129d9cd54c1e08af1b6a2c0f6f94bacf395b13a198dc81f.json +1 -0
  40. data/bench/cassettes/67b30efd5681046fb5f2252d73f9aedf603be1b7c7895e4e71c6cfb88238309e.json +1 -0
  41. data/bench/cassettes/691958dd39537d72c4b0ab4ba69fea3c51b8e06a49a772f3ffd5bb5747dfe99d.json +1 -0
  42. data/bench/cassettes/6931e51f0455b5e3260165aa22a445d3a4f782ae5233a961384149cfbb045fe0.json +1 -0
  43. data/bench/cassettes/6b79cf1a80fc9edd09bb4606613ff2de2ab2bc61487983dffac1174025270997.json +1 -0
  44. data/bench/cassettes/6d683884d5d039db072ac18c9420bdcc989838f08a71096076cccc2edcd48234.json +1 -0
  45. data/bench/cassettes/6df49dc7eae4104adf1b020fd846d893da3e49f4f13a4c6fd1f87a78c410ba31.json +1 -0
  46. data/bench/cassettes/75cc5d99bbc1d48ace6095d41daae1e2e2c829291f01d40f0ce40d6eea52c0bf.json +1 -0
  47. data/bench/cassettes/771a86cbb6c025101384a50d01a4745683e1c2b17bbfff73e40e475dbf016efb.json +1 -0
  48. data/bench/cassettes/7a2a93c357473f4a289a6ec250e3bfe6f51152a0c448e5420ffebee7872f9d11.json +1 -0
  49. data/bench/cassettes/7a4774a02c3eebe24d4fbd443ea90661711fe5cb8248bce7a2dedfedf6ddbc03.json +1 -0
  50. data/bench/cassettes/7c1fa04f8eb43251ca3f6652977b698e4e6ba5e120da8301b4dbce79ef01ccb9.json +1 -0
  51. data/bench/cassettes/7c4dea48c2bc2c413da81307ce3cbb2749b20e16e4d831fca5861decf11ec55b.json +1 -0
  52. data/bench/cassettes/7dd499da389eaeeb59eba533695c20fd1a43e25f89f21e3456b826f9953b2010.json +1 -0
  53. data/bench/cassettes/80438d0bbfe106baa236eef358e46260693e6491f67e7a9f8ea1076c6fbfd449.json +1 -0
  54. data/bench/cassettes/80db562534181514f243ac74d7ddaec1fafc28b2b72ae35482cfc2de8f2d9e61.json +1 -0
  55. data/bench/cassettes/825a51543665a468a55c823788c68eb5785c90be8131988f72bf98f4f0294177.json +1 -0
  56. data/bench/cassettes/83d8276c227b73e542bd70c023d9a8ffa1c2cf4dd78e71d61457f097bc743d19.json +1 -0
  57. data/bench/cassettes/891405ffd7727b6d4c4186e2c60a08aa8b62c7b711bd1558c8033fcf8e4178a4.json +1 -0
  58. data/bench/cassettes/89fabff05dc4c0abdf630781a324b7802cbc0dc8bd09b20ce59643465a2aeaec.json +1 -0
  59. data/bench/cassettes/8cbceece3ca6136b6c6bb71c9bf28f409a5fa070596ebfc0f3187aba287bf6d3.json +1 -0
  60. data/bench/cassettes/8d56da27350d9dea20468eae30fa51cbbb10637c06d977b3e1a00734966be46f.json +1 -0
  61. data/bench/cassettes/8fb43b452b5e15248f34bf48e41cfc227129cfe349fe4b3fc4ab7133d66914bc.json +1 -0
  62. data/bench/cassettes/92e5426bd0c1f31d7acca92f77d7f2586e74054467729f0be28d139f515354d5.json +1 -0
  63. data/bench/cassettes/938be225155e1952b817652778b7cab377017fc4a219628ae89ad01a9c1151bc.json +1 -0
  64. data/bench/cassettes/9519ad701b28e7b2c5f1e1cad5df1ec3e5254c8cec969b9bee1361af8803d39d.json +1 -0
  65. data/bench/cassettes/9536e8ed68330eda400d765c3ca16a4dd3bfe0d026b569599a33e7e4951f4860.json +1 -0
  66. data/bench/cassettes/99c6e5aefd97722f4028bacc11d299eb9036805cd5cf7bf75f879ebe3f27c00a.json +1 -0
  67. data/bench/cassettes/9cdfd2f3ef8dc4cde917a9d196e3137159067c10ec8d2132f32da034865f9959.json +1 -0
  68. data/bench/cassettes/a1e3030984d4e1982fb5a2b2068664187358c88c6b71f768841d3e78406e9535.json +1 -0
  69. data/bench/cassettes/a2140f51b8fa25da73efd387a41f9eb84ffbc1f1ab47dec0c3b37b249ff373a0.json +1 -0
  70. data/bench/cassettes/a36d248ce5c26fd66430b780c8ecdd176f29830ac4edb2bf0b2e07cb93ffb865.json +1 -0
  71. data/bench/cassettes/a64329816ca1e537e90b89862a86be119e1e6236c6f3cf0141a96505b0734364.json +1 -0
  72. data/bench/cassettes/aba24c67dcaefa51c204a529b5ea3fe01333181a608a8ab8899568c731677e7d.json +1 -0
  73. data/bench/cassettes/aed233524926f2b4ff8c2ec21224bd284595c91eb57e0fb6981cdc8ac7e7d8d3.json +1 -0
  74. data/bench/cassettes/b00e9da6403e48aa1f4f9346419f88b2a336e1a2ac4a28515d84b2337eb777b2.json +1 -0
  75. data/bench/cassettes/b02f4c76c073882ff0fd12fddc28e4db52d9e6486a130194bf1057c7693de831.json +1 -0
  76. data/bench/cassettes/b6a9cb89ae4afd08a6919eaf7f609790c895d4cf22d47dad6c3b287b9278be87.json +1 -0
  77. data/bench/cassettes/b71b982225eab48d02c81913877571dfa53717c0983d1d72cbe3787242dda055.json +1 -0
  78. data/bench/cassettes/bda5e115b566e7f955aa45222859fe4f725949d5f91e3d794821701491448510.json +1 -0
  79. data/bench/cassettes/c0ac703268faf8d49dbc1ad0e877693a9f52181ae6070de844fcd4218d33d5e4.json +1 -0
  80. data/bench/cassettes/c0b57bcbb4004edd44c2d8c7e1f8cfc3567d954a3d5b21b2cda7257e3bc07437.json +1 -0
  81. data/bench/cassettes/d1ade9adde20981211c470a77b4d560264cae290941e692be6876a79227e3d18.json +1 -0
  82. data/bench/cassettes/d28de3038544a5bf9c8425b6976e360fae71c5ca96409784ad6642703701986a.json +1 -0
  83. data/bench/cassettes/d6418acb9f7f58ffdf3049481cbd17cfb3f0581064e157c9c58c19a3fc26b4d4.json +1 -0
  84. data/bench/cassettes/d71e8cf7c2be4b6e4089eb40c5a108c0c45fc58398af5138f905129f640afbb8.json +1 -0
  85. data/bench/cassettes/d9672c45b5358b92f7740abfb20b287235cf949990c88558f41d3a9c00eb6d3b.json +1 -0
  86. data/bench/cassettes/da0c9ce695111f6acf3cfb58dc0494f79230739d1773377db420bf438fd2e244.json +1 -0
  87. data/bench/cassettes/db57e3a15971cd2832313172c0d7df6e6a48b13a276ba9877eeb7d39389d74d3.json +1 -0
  88. data/bench/cassettes/db9c8c4d0a8d855a2578572afe5edc5eebb39c0fd5f04489614ea2557ec4f0cd.json +1 -0
  89. data/bench/cassettes/e2c396b0475a07a615dde9208b088e9e479720c1ec5889ade07fbfd0d28fb517.json +1 -0
  90. data/bench/cassettes/e3006ccc97646f43f4ea23694665526e47982fa1ea413359b9669071f6cb990d.json +1 -0
  91. data/bench/cassettes/e623737636e797d22f80d128cbff46101837044e159f41fa62a8d3d0cc6bb996.json +1 -0
  92. data/bench/cassettes/ea0cefaaac1a62e8eac962391df025a3b14c3a3d5b69fe57d60b65811010908c.json +1 -0
  93. data/bench/cassettes/ee3e06456cf4201ab46f579dd53bdea4071ce43bfe02e9b870bcb4b9c1c680b4.json +1 -0
  94. data/bench/cassettes/f26e675da9088f08cb76dd6b3fd89230b84fd1b9be3767c36857217bda2da15b.json +1 -0
  95. data/bench/cassettes/f396f34b2356d42af385eac9f5760e97e553a584c3f93da7bd618ad311e04d93.json +1 -0
  96. data/bench/cassettes/fce02c5c04cb8c27e868f6c54cfcbbbf69bde2f7f612d50ff8fb6d0aec9df3e3.json +1 -0
  97. data/bench/cassettes/ffc09a04b083822c1597dd96bb27ee4cde365bc8346175ebf6e378ab2ab1b598.json +1 -0
  98. data/bench/cassettes/manifest.json +1 -0
  99. data/bench/fixtures/gold.jsonl +27 -0
  100. data/bench/fixtures/injection.jsonl +6 -0
  101. data/bench/fixtures/records.jsonl +90 -0
  102. data/bench/params.yml +30 -0
  103. data/lib/generators/truffler/install/install_generator.rb +51 -0
  104. data/lib/generators/truffler/install/templates/channel.rb.tt +17 -0
  105. data/lib/generators/truffler/install/templates/initializer.rb.tt +23 -0
  106. data/lib/generators/truffler/install/templates/migration.rb.tt +109 -0
  107. data/lib/tasks/truffler/bench.rake +30 -0
  108. data/lib/tasks/truffler/suggestions.rake +8 -0
  109. data/lib/tasks/truffler.rake +26 -0
  110. data/lib/truffler/answers.rb +66 -0
  111. data/lib/truffler/benchmark/adapters.rb +80 -0
  112. data/lib/truffler/benchmark/database.rb +31 -0
  113. data/lib/truffler/benchmark/dataset.rb +65 -0
  114. data/lib/truffler/benchmark/email.rb +50 -0
  115. data/lib/truffler/benchmark/generator.rb +188 -0
  116. data/lib/truffler/benchmark/metrics.rb +62 -0
  117. data/lib/truffler/benchmark/params.rb +91 -0
  118. data/lib/truffler/benchmark/runner.rb +370 -0
  119. data/lib/truffler/benchmark/synthetic_jev.rb +85 -0
  120. data/lib/truffler/benchmark.rb +29 -0
  121. data/lib/truffler/broadcaster.rb +46 -0
  122. data/lib/truffler/budget.rb +118 -0
  123. data/lib/truffler/canonical.rb +27 -0
  124. data/lib/truffler/clients/base.rb +49 -0
  125. data/lib/truffler/clients/callable.rb +26 -0
  126. data/lib/truffler/clients/cassette.rb +44 -0
  127. data/lib/truffler/clients/fake.rb +85 -0
  128. data/lib/truffler/clients/ruby_llm_typesafe.rb +32 -0
  129. data/lib/truffler/configuration.rb +89 -0
  130. data/lib/truffler/definition.rb +176 -0
  131. data/lib/truffler/embeddings/backfill.rb +48 -0
  132. data/lib/truffler/embeddings/column_store.rb +65 -0
  133. data/lib/truffler/embeddings/embedder.rb +53 -0
  134. data/lib/truffler/embeddings/fake_embedder.rb +45 -0
  135. data/lib/truffler/embeddings/label_vector.rb +81 -0
  136. data/lib/truffler/embeddings/neighbor_store.rb +66 -0
  137. data/lib/truffler/embeddings/ruby_llm_embedder.rb +25 -0
  138. data/lib/truffler/embeddings/ruby_store.rb +12 -0
  139. data/lib/truffler/embeddings/vector_store.rb +84 -0
  140. data/lib/truffler/embeddings.rb +30 -0
  141. data/lib/truffler/errors.rb +40 -0
  142. data/lib/truffler/instrumentation.rb +17 -0
  143. data/lib/truffler/jobs/backfill_job.rb +45 -0
  144. data/lib/truffler/jobs/embed_job.rb +33 -0
  145. data/lib/truffler/jobs/encode_query_job.rb +17 -0
  146. data/lib/truffler/jobs/expire_lenses_job.rb +15 -0
  147. data/lib/truffler/jobs/label_flush_job.rb +39 -0
  148. data/lib/truffler/jobs/lens_backfill_job.rb +33 -0
  149. data/lib/truffler/jobs/provider_search_job.rb +18 -0
  150. data/lib/truffler/jobs/prune_query_misses_job.rb +15 -0
  151. data/lib/truffler/jobs/rerank_chunk_job.rb +14 -0
  152. data/lib/truffler/jobs/resume_job.rb +61 -0
  153. data/lib/truffler/jobs/smart_search_job.rb +14 -0
  154. data/lib/truffler/label_definition.rb +153 -0
  155. data/lib/truffler/labeling/backfill.rb +189 -0
  156. data/lib/truffler/labeling/labeler.rb +161 -0
  157. data/lib/truffler/labeling/queue.rb +125 -0
  158. data/lib/truffler/labeling/request_builder.rb +87 -0
  159. data/lib/truffler/labeling/supplied.rb +70 -0
  160. data/lib/truffler/lenses/activator.rb +51 -0
  161. data/lib/truffler/lenses/backfill.rb +112 -0
  162. data/lib/truffler/lenses/draft.rb +16 -0
  163. data/lib/truffler/lenses/drafter.rb +147 -0
  164. data/lib/truffler/lenses/fake_generator.rb +58 -0
  165. data/lib/truffler/lenses/lens.rb +161 -0
  166. data/lib/truffler/lenses/lens_label.rb +51 -0
  167. data/lib/truffler/lenses/policy.rb +46 -0
  168. data/lib/truffler/lenses/previewer.rb +217 -0
  169. data/lib/truffler/lenses/proposer.rb +53 -0
  170. data/lib/truffler/lenses/ruby_llm_generator.rb +42 -0
  171. data/lib/truffler/lenses/scope.rb +35 -0
  172. data/lib/truffler/lenses/sealed_description.rb +29 -0
  173. data/lib/truffler/lenses/settings.rb +45 -0
  174. data/lib/truffler/lenses/validation.rb +69 -0
  175. data/lib/truffler/lenses/version.rb +34 -0
  176. data/lib/truffler/lenses.rb +138 -0
  177. data/lib/truffler/misses/clusterer.rb +69 -0
  178. data/lib/truffler/misses/recorder.rb +29 -0
  179. data/lib/truffler/misses/suggestions.rb +49 -0
  180. data/lib/truffler/misses.rb +83 -0
  181. data/lib/truffler/model.rb +111 -0
  182. data/lib/truffler/providers/backup.rb +58 -0
  183. data/lib/truffler/providers/runner.rb +67 -0
  184. data/lib/truffler/providers.rb +57 -0
  185. data/lib/truffler/query_encoding/cache.rb +71 -0
  186. data/lib/truffler/query_encoding/encoder.rb +183 -0
  187. data/lib/truffler/query_encoding/prefetch.rb +34 -0
  188. data/lib/truffler/query_encoding.rb +12 -0
  189. data/lib/truffler/questions.rb +78 -0
  190. data/lib/truffler/railtie.rb +11 -0
  191. data/lib/truffler/records/embedding.rb +39 -0
  192. data/lib/truffler/records/label.rb +11 -0
  193. data/lib/truffler/records/query_miss.rb +20 -0
  194. data/lib/truffler/records/record_state.rb +30 -0
  195. data/lib/truffler/redaction.rb +24 -0
  196. data/lib/truffler/registry.rb +16 -0
  197. data/lib/truffler/search/encoding.rb +84 -0
  198. data/lib/truffler/search/encoding_cache.rb +68 -0
  199. data/lib/truffler/search/keystroke.rb +149 -0
  200. data/lib/truffler/search/query.rb +67 -0
  201. data/lib/truffler/search/result.rb +100 -0
  202. data/lib/truffler/search/sql.rb +197 -0
  203. data/lib/truffler/smart_search/dispatcher.rb +88 -0
  204. data/lib/truffler/smart_search/reranker.rb +105 -0
  205. data/lib/truffler/smart_search/run.rb +306 -0
  206. data/lib/truffler/smart_search/starter.rb +73 -0
  207. data/lib/truffler/smart_search/store.rb +89 -0
  208. data/lib/truffler/smart_search.rb +43 -0
  209. data/lib/truffler/tokens.rb +12 -0
  210. data/lib/truffler/usage.rb +7 -0
  211. data/lib/truffler/version.rb +3 -0
  212. data/lib/truffler/vocabulary.rb +48 -0
  213. data/lib/truffler.rb +41 -0
  214. metadata +336 -0
@@ -0,0 +1,43 @@
1
+ module Truffler
2
+ # Smart search on explicit action (KTD11-KTD13, R22-R24, R26, R27). The
3
+ # host starts a run; `SmartSearchJob` checks the rerank budget, waits for
4
+ # an in-flight query encoding up to the deadline, re-applies its filters to
5
+ # the candidate snapshot, and fans out one `RerankChunkJob` per chunk. Each
6
+ # chunk's scores append to the Strong, Possible, and Unlikely buckets in
7
+ # arrival order and a data-free ping tells the host to reload.
8
+ module SmartSearch
9
+ BUCKETS = %i[strong possible unlikely].freeze
10
+ COLLAPSED_BY_DEFAULT = %i[unlikely].freeze
11
+ SMART = "smart".freeze
12
+ PROVIDER = "provider".freeze
13
+
14
+ module_function
15
+
16
+ # Starts a run and returns it, already `reserved?`. See `Starter`.
17
+ def start(model, query, **options)
18
+ Starter.new(model, query, **options).call
19
+ end
20
+
21
+ # The run for `run_id`, or an expired run once the cache let it go or
22
+ # when it belongs to another searcher or tenant.
23
+ def find(run_id, user:, tenant:, store: Store.new)
24
+ Run.find(run_id, user: user, tenant: tenant, store: store)
25
+ end
26
+
27
+ # Cancels the current run for (model, tenant, user, surface), as when the
28
+ # searcher edits the query or accepts or removes a chip (R24).
29
+ def cancel(model, tenant:, user:, surface: nil, store: Store.new)
30
+ run_id = store.current_run_id(model.polymorphic_name, tenant&.to_s, Search::Keystroke.user_key(user), surface&.to_s)
31
+ run = run_id && Run.load(run_id, store: store)
32
+ run&.cancel!
33
+ run
34
+ end
35
+
36
+ def bucket_for(score, thresholds: Truffler.config.smart_thresholds)
37
+ if score >= thresholds.fetch(:strong) then :strong
38
+ elsif score >= thresholds.fetch(:possible) then :possible
39
+ else :unlikely
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,12 @@
1
+ module Truffler
2
+ module Tokens
3
+ CHARS_PER_TOKEN = 3
4
+
5
+ module_function
6
+
7
+ def estimate(value)
8
+ text = value.is_a?(String) ? value : JSON.generate(value)
9
+ (text.length / CHARS_PER_TOKEN.to_f).ceil
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ module Truffler
2
+ Usage = Data.define(:input_tokens, :estimated) do
3
+ def cost
4
+ Truffler.config.cost_for(input_tokens)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module Truffler
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,48 @@
1
+ module Truffler
2
+ # A label's fingerprint is the SHA-256 of its canonical question plus the
3
+ # pinned Jev model; a host-supplied label's is its supplied fingerprint
4
+ # (type, options, version), which no Jev model change touches. The
5
+ # vocabulary version digests every fingerprint. A stored label is stale
6
+ # when its fingerprint differs from the current one.
7
+ #
8
+ # A scope's vocabulary also holds its active lens labels (KTD21), so a lens
9
+ # changes the version only where it applies. user_key is the searcher key
10
+ # keystroke search hands the encoding hook; all_users: true is the labeling
11
+ # scope, which includes every user's personal lenses in the tenant.
12
+ class Vocabulary
13
+ attr_reader :definition, :model
14
+
15
+ def initialize(definition, model: Truffler.config.model)
16
+ @definition = definition
17
+ @model = model
18
+ end
19
+
20
+ # {key => LabelDefinition or Lenses::LensLabel}: the declared labels,
21
+ # then the lens labels keyed "lens:<id>:<label>".
22
+ def labels_for(tenant_key: nil, user_key: nil, all_users: false)
23
+ lenses = Lenses.labels(definition.model, tenant_key: tenant_key, user_key: user_key, all_users: all_users)
24
+ lenses.empty? ? definition.labels : definition.labels.merge(lenses)
25
+ end
26
+
27
+ def fingerprint(label_key, tenant_key: nil)
28
+ fingerprint_of(definition.label(label_key), tenant_key)
29
+ end
30
+
31
+ def fingerprints(tenant_key: nil, user_key: nil, all_users: false)
32
+ labels_for(tenant_key: tenant_key, user_key: user_key, all_users: all_users)
33
+ .transform_values { |label| fingerprint_of(label, tenant_key) }
34
+ end
35
+
36
+ def version(tenant_key: nil, user_key: nil, all_users: false)
37
+ Canonical.digest(fingerprints(tenant_key: tenant_key, user_key: user_key, all_users: all_users))
38
+ end
39
+
40
+ private
41
+
42
+ def fingerprint_of(label, tenant_key)
43
+ return label.supplied_fingerprint(tenant_key) if label.supplied?
44
+
45
+ Canonical.digest(question: label.question(tenant_key), model: model)
46
+ end
47
+ end
48
+ end
data/lib/truffler.rb ADDED
@@ -0,0 +1,41 @@
1
+ require "active_support"
2
+ require "active_support/core_ext"
3
+ require "active_record"
4
+ require "active_job"
5
+ require "zeitwerk"
6
+
7
+ require_relative "truffler/version"
8
+ require_relative "truffler/errors"
9
+
10
+ loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
11
+ loader.inflector.inflect("ruby_llm_typesafe" => "RubyLLMTypeSafe")
12
+ loader.ignore("#{__dir__}/generators", "#{__dir__}/tasks")
13
+ loader.ignore("#{__dir__}/truffler/errors.rb", "#{__dir__}/truffler/railtie.rb")
14
+ loader.do_not_eager_load("#{__dir__}/truffler/clients/ruby_llm_typesafe.rb")
15
+ loader.inflector.inflect("ruby_llm_embedder" => "RubyLLMEmbedder")
16
+ loader.do_not_eager_load("#{__dir__}/truffler/embeddings/ruby_llm_embedder.rb")
17
+ loader.inflector.inflect("ruby_llm_generator" => "RubyLLMGenerator")
18
+ loader.do_not_eager_load("#{__dir__}/truffler/lenses/ruby_llm_generator.rb")
19
+ loader.setup
20
+
21
+ module Truffler
22
+ class << self
23
+ def config
24
+ @config ||= Configuration.new
25
+ end
26
+
27
+ def configure
28
+ yield config
29
+ end
30
+
31
+ def reset_config!
32
+ @config = Configuration.new
33
+ end
34
+
35
+ def registry
36
+ @registry ||= Registry.new
37
+ end
38
+ end
39
+ end
40
+
41
+ require_relative "truffler/railtie" if defined?(Rails::Railtie)
metadata ADDED
@@ -0,0 +1,336 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: truffler
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Kieran Klaassen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-09-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activejob
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '7.2'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '9'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '7.2'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '9'
33
+ - !ruby/object:Gem::Dependency
34
+ name: activerecord
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '7.2'
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '9'
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '7.2'
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '9'
53
+ - !ruby/object:Gem::Dependency
54
+ name: activesupport
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '7.2'
60
+ - - "<"
61
+ - !ruby/object:Gem::Version
62
+ version: '9'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '7.2'
70
+ - - "<"
71
+ - !ruby/object:Gem::Version
72
+ version: '9'
73
+ - !ruby/object:Gem::Dependency
74
+ name: zeitwerk
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '2.6'
80
+ type: :runtime
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - "~>"
85
+ - !ruby/object:Gem::Version
86
+ version: '2.6'
87
+ description: Labels records with TypeSafe Jev when they are saved, stores the answers
88
+ as numbers your database filters and sorts, turns queries into label filters and
89
+ boosts, and streams a Jev rerank on explicit action.
90
+ email:
91
+ - kieranklaassen@gmail.com
92
+ executables: []
93
+ extensions: []
94
+ extra_rdoc_files: []
95
+ files:
96
+ - CHANGELOG.md
97
+ - LICENSE.txt
98
+ - README.md
99
+ - bench/cassettes/004cad52c71fc8d847bf388eb9c2c288e1169b65ec4a28ce040cb7fea7c55f04.json
100
+ - bench/cassettes/0547d3d23c3fbaae86772ffa0e4e96475aa152a2556b8fa4bc7568effcb81a28.json
101
+ - bench/cassettes/07aa23d166ab3500178e3f3c0838183051b093507bef88e1e2d29efdf5759ee6.json
102
+ - bench/cassettes/0858c5006c0bfac3e970ddaff3c139f6c110dbe3d8539fd95263706c637cdc8e.json
103
+ - bench/cassettes/0c0eb7c27d76bd0b9263690a63cd92d6b68c305826318555fd5b084a09970b78.json
104
+ - bench/cassettes/0fada0c0a103882e2895f7f455d73d2cbe2b4a81bf743bb19b2b4f6e0130126b.json
105
+ - bench/cassettes/1117d79ac7c43b21beaf75e510461f91cd4ecc3cdbbe461f1794644af4aaf8f3.json
106
+ - bench/cassettes/11b7444a074cca4d0ef1535db0cf0edefe4c34eac4be3c593c9c2f33d3b038b8.json
107
+ - bench/cassettes/11d00371d1b993675be00463159164536f1f8ed90a48652b0935eb9c36f8b684.json
108
+ - bench/cassettes/1456ebe12616ce961d68a14eada62778a7271ebd3d1b4cb6eefd6857651c7afc.json
109
+ - bench/cassettes/14c3693f64b0e9ea7e470277fccae6ab501d404185eec5bb9074ef4b75c572c0.json
110
+ - bench/cassettes/14fe9f6d8055d41f5d970dc32ab640c213ea8782d365c82d32b9884ba4f28c67.json
111
+ - bench/cassettes/1a1d8557e4698426c2467aa573a240357715d3d9e3fa77bf066672a8b6bf9a86.json
112
+ - bench/cassettes/1b5a8aaaf98305560588246cd51f53c6c185a951f8018c26bf588954d9de1cea.json
113
+ - bench/cassettes/1fe596be747e33e9c7e4d7c50de32613957ac66bee43679b4bed96c551b1fd0a.json
114
+ - bench/cassettes/21ebce6db6d39b1747dccf25bd3ceb298e1285425190b4d78830c395a7ad786a.json
115
+ - bench/cassettes/23066253621e9cb00fd93cbe95ef1124ff0715585fcb6325b3abbd0802b2c303.json
116
+ - bench/cassettes/2f6576325dfab696cec8d8b35fa89c29960bee15d10dab31c91cef507f4842be.json
117
+ - bench/cassettes/33ec27d22c0f63dbbe93008f50af07fa8667a5c806a9fbfc7897683915412b40.json
118
+ - bench/cassettes/351f745b0c47e0cf3272b0fea7fc4941b6aa733f013c55a9a19707b542543200.json
119
+ - bench/cassettes/37d974fdc0c1876413111c244d363c8d2306e3229fec668c158b5c924ffdb983.json
120
+ - bench/cassettes/39524467463dd612cbf03e314b9cfd8cbe1c5f06969da2289359cf7cf83de5da.json
121
+ - bench/cassettes/3f2c758c111ab7f1163ba579f2329718afe15620507d356d3ebe2a053df237ea.json
122
+ - bench/cassettes/44bbc3a3f0ceb0edb443b080b939af80dd145795505bd13cac113a35365d0f04.json
123
+ - bench/cassettes/45bf701a13c348acb45a3b3a56990570e3caf797c3daee5d1358a477593ce587.json
124
+ - bench/cassettes/4676a0f2df29493fdfa0b7cd75c097e647373862d88373dc0e1fa9fca26707c2.json
125
+ - bench/cassettes/49708a50e3c78f45beed2f1b8d8d5375b99ea4ab3497fed7650e6ece4ec81ba8.json
126
+ - bench/cassettes/54ea30ecca8fa49f607d5c8265296eb16edb48d0620a7399c6480d4cb0f43ae1.json
127
+ - bench/cassettes/550e73a8291f53d0f2b008f166560eff4d10cc7c09a927d3c4f70544f2578300.json
128
+ - bench/cassettes/570039823d5af1b6c1d4bcbe14f9802d40e851f8e4946278a46884c76c0ceee1.json
129
+ - bench/cassettes/5ae9dce82fa7b9084b592f657a24acfd5852c4fcb091a6a8e22f2cbbf947bcdd.json
130
+ - bench/cassettes/5c40794d3bf6e229c6ffd26922388776121f971ef27279e02a35ce004e0794dd.json
131
+ - bench/cassettes/62f2e71a2d9cfdc18fdd6600f5a1450519b25a75c2f799b7695258627250497d.json
132
+ - bench/cassettes/642becd7ad9cd4cc2ac6d389ef8ff14fd9fe125beca834afee625ea2c31476be.json
133
+ - bench/cassettes/656cc1158890e928c129d9cd54c1e08af1b6a2c0f6f94bacf395b13a198dc81f.json
134
+ - bench/cassettes/67b30efd5681046fb5f2252d73f9aedf603be1b7c7895e4e71c6cfb88238309e.json
135
+ - bench/cassettes/691958dd39537d72c4b0ab4ba69fea3c51b8e06a49a772f3ffd5bb5747dfe99d.json
136
+ - bench/cassettes/6931e51f0455b5e3260165aa22a445d3a4f782ae5233a961384149cfbb045fe0.json
137
+ - bench/cassettes/6b79cf1a80fc9edd09bb4606613ff2de2ab2bc61487983dffac1174025270997.json
138
+ - bench/cassettes/6d683884d5d039db072ac18c9420bdcc989838f08a71096076cccc2edcd48234.json
139
+ - bench/cassettes/6df49dc7eae4104adf1b020fd846d893da3e49f4f13a4c6fd1f87a78c410ba31.json
140
+ - bench/cassettes/75cc5d99bbc1d48ace6095d41daae1e2e2c829291f01d40f0ce40d6eea52c0bf.json
141
+ - bench/cassettes/771a86cbb6c025101384a50d01a4745683e1c2b17bbfff73e40e475dbf016efb.json
142
+ - bench/cassettes/7a2a93c357473f4a289a6ec250e3bfe6f51152a0c448e5420ffebee7872f9d11.json
143
+ - bench/cassettes/7a4774a02c3eebe24d4fbd443ea90661711fe5cb8248bce7a2dedfedf6ddbc03.json
144
+ - bench/cassettes/7c1fa04f8eb43251ca3f6652977b698e4e6ba5e120da8301b4dbce79ef01ccb9.json
145
+ - bench/cassettes/7c4dea48c2bc2c413da81307ce3cbb2749b20e16e4d831fca5861decf11ec55b.json
146
+ - bench/cassettes/7dd499da389eaeeb59eba533695c20fd1a43e25f89f21e3456b826f9953b2010.json
147
+ - bench/cassettes/80438d0bbfe106baa236eef358e46260693e6491f67e7a9f8ea1076c6fbfd449.json
148
+ - bench/cassettes/80db562534181514f243ac74d7ddaec1fafc28b2b72ae35482cfc2de8f2d9e61.json
149
+ - bench/cassettes/825a51543665a468a55c823788c68eb5785c90be8131988f72bf98f4f0294177.json
150
+ - bench/cassettes/83d8276c227b73e542bd70c023d9a8ffa1c2cf4dd78e71d61457f097bc743d19.json
151
+ - bench/cassettes/891405ffd7727b6d4c4186e2c60a08aa8b62c7b711bd1558c8033fcf8e4178a4.json
152
+ - bench/cassettes/89fabff05dc4c0abdf630781a324b7802cbc0dc8bd09b20ce59643465a2aeaec.json
153
+ - bench/cassettes/8cbceece3ca6136b6c6bb71c9bf28f409a5fa070596ebfc0f3187aba287bf6d3.json
154
+ - bench/cassettes/8d56da27350d9dea20468eae30fa51cbbb10637c06d977b3e1a00734966be46f.json
155
+ - bench/cassettes/8fb43b452b5e15248f34bf48e41cfc227129cfe349fe4b3fc4ab7133d66914bc.json
156
+ - bench/cassettes/92e5426bd0c1f31d7acca92f77d7f2586e74054467729f0be28d139f515354d5.json
157
+ - bench/cassettes/938be225155e1952b817652778b7cab377017fc4a219628ae89ad01a9c1151bc.json
158
+ - bench/cassettes/9519ad701b28e7b2c5f1e1cad5df1ec3e5254c8cec969b9bee1361af8803d39d.json
159
+ - bench/cassettes/9536e8ed68330eda400d765c3ca16a4dd3bfe0d026b569599a33e7e4951f4860.json
160
+ - bench/cassettes/99c6e5aefd97722f4028bacc11d299eb9036805cd5cf7bf75f879ebe3f27c00a.json
161
+ - bench/cassettes/9cdfd2f3ef8dc4cde917a9d196e3137159067c10ec8d2132f32da034865f9959.json
162
+ - bench/cassettes/a1e3030984d4e1982fb5a2b2068664187358c88c6b71f768841d3e78406e9535.json
163
+ - bench/cassettes/a2140f51b8fa25da73efd387a41f9eb84ffbc1f1ab47dec0c3b37b249ff373a0.json
164
+ - bench/cassettes/a36d248ce5c26fd66430b780c8ecdd176f29830ac4edb2bf0b2e07cb93ffb865.json
165
+ - bench/cassettes/a64329816ca1e537e90b89862a86be119e1e6236c6f3cf0141a96505b0734364.json
166
+ - bench/cassettes/aba24c67dcaefa51c204a529b5ea3fe01333181a608a8ab8899568c731677e7d.json
167
+ - bench/cassettes/aed233524926f2b4ff8c2ec21224bd284595c91eb57e0fb6981cdc8ac7e7d8d3.json
168
+ - bench/cassettes/b00e9da6403e48aa1f4f9346419f88b2a336e1a2ac4a28515d84b2337eb777b2.json
169
+ - bench/cassettes/b02f4c76c073882ff0fd12fddc28e4db52d9e6486a130194bf1057c7693de831.json
170
+ - bench/cassettes/b6a9cb89ae4afd08a6919eaf7f609790c895d4cf22d47dad6c3b287b9278be87.json
171
+ - bench/cassettes/b71b982225eab48d02c81913877571dfa53717c0983d1d72cbe3787242dda055.json
172
+ - bench/cassettes/bda5e115b566e7f955aa45222859fe4f725949d5f91e3d794821701491448510.json
173
+ - bench/cassettes/c0ac703268faf8d49dbc1ad0e877693a9f52181ae6070de844fcd4218d33d5e4.json
174
+ - bench/cassettes/c0b57bcbb4004edd44c2d8c7e1f8cfc3567d954a3d5b21b2cda7257e3bc07437.json
175
+ - bench/cassettes/d1ade9adde20981211c470a77b4d560264cae290941e692be6876a79227e3d18.json
176
+ - bench/cassettes/d28de3038544a5bf9c8425b6976e360fae71c5ca96409784ad6642703701986a.json
177
+ - bench/cassettes/d6418acb9f7f58ffdf3049481cbd17cfb3f0581064e157c9c58c19a3fc26b4d4.json
178
+ - bench/cassettes/d71e8cf7c2be4b6e4089eb40c5a108c0c45fc58398af5138f905129f640afbb8.json
179
+ - bench/cassettes/d9672c45b5358b92f7740abfb20b287235cf949990c88558f41d3a9c00eb6d3b.json
180
+ - bench/cassettes/da0c9ce695111f6acf3cfb58dc0494f79230739d1773377db420bf438fd2e244.json
181
+ - bench/cassettes/db57e3a15971cd2832313172c0d7df6e6a48b13a276ba9877eeb7d39389d74d3.json
182
+ - bench/cassettes/db9c8c4d0a8d855a2578572afe5edc5eebb39c0fd5f04489614ea2557ec4f0cd.json
183
+ - bench/cassettes/e2c396b0475a07a615dde9208b088e9e479720c1ec5889ade07fbfd0d28fb517.json
184
+ - bench/cassettes/e3006ccc97646f43f4ea23694665526e47982fa1ea413359b9669071f6cb990d.json
185
+ - bench/cassettes/e623737636e797d22f80d128cbff46101837044e159f41fa62a8d3d0cc6bb996.json
186
+ - bench/cassettes/ea0cefaaac1a62e8eac962391df025a3b14c3a3d5b69fe57d60b65811010908c.json
187
+ - bench/cassettes/ee3e06456cf4201ab46f579dd53bdea4071ce43bfe02e9b870bcb4b9c1c680b4.json
188
+ - bench/cassettes/f26e675da9088f08cb76dd6b3fd89230b84fd1b9be3767c36857217bda2da15b.json
189
+ - bench/cassettes/f396f34b2356d42af385eac9f5760e97e553a584c3f93da7bd618ad311e04d93.json
190
+ - bench/cassettes/fce02c5c04cb8c27e868f6c54cfcbbbf69bde2f7f612d50ff8fb6d0aec9df3e3.json
191
+ - bench/cassettes/ffc09a04b083822c1597dd96bb27ee4cde365bc8346175ebf6e378ab2ab1b598.json
192
+ - bench/cassettes/manifest.json
193
+ - bench/fixtures/gold.jsonl
194
+ - bench/fixtures/injection.jsonl
195
+ - bench/fixtures/records.jsonl
196
+ - bench/params.yml
197
+ - lib/generators/truffler/install/install_generator.rb
198
+ - lib/generators/truffler/install/templates/channel.rb.tt
199
+ - lib/generators/truffler/install/templates/initializer.rb.tt
200
+ - lib/generators/truffler/install/templates/migration.rb.tt
201
+ - lib/tasks/truffler.rake
202
+ - lib/tasks/truffler/bench.rake
203
+ - lib/tasks/truffler/suggestions.rake
204
+ - lib/truffler.rb
205
+ - lib/truffler/answers.rb
206
+ - lib/truffler/benchmark.rb
207
+ - lib/truffler/benchmark/adapters.rb
208
+ - lib/truffler/benchmark/database.rb
209
+ - lib/truffler/benchmark/dataset.rb
210
+ - lib/truffler/benchmark/email.rb
211
+ - lib/truffler/benchmark/generator.rb
212
+ - lib/truffler/benchmark/metrics.rb
213
+ - lib/truffler/benchmark/params.rb
214
+ - lib/truffler/benchmark/runner.rb
215
+ - lib/truffler/benchmark/synthetic_jev.rb
216
+ - lib/truffler/broadcaster.rb
217
+ - lib/truffler/budget.rb
218
+ - lib/truffler/canonical.rb
219
+ - lib/truffler/clients/base.rb
220
+ - lib/truffler/clients/callable.rb
221
+ - lib/truffler/clients/cassette.rb
222
+ - lib/truffler/clients/fake.rb
223
+ - lib/truffler/clients/ruby_llm_typesafe.rb
224
+ - lib/truffler/configuration.rb
225
+ - lib/truffler/definition.rb
226
+ - lib/truffler/embeddings.rb
227
+ - lib/truffler/embeddings/backfill.rb
228
+ - lib/truffler/embeddings/column_store.rb
229
+ - lib/truffler/embeddings/embedder.rb
230
+ - lib/truffler/embeddings/fake_embedder.rb
231
+ - lib/truffler/embeddings/label_vector.rb
232
+ - lib/truffler/embeddings/neighbor_store.rb
233
+ - lib/truffler/embeddings/ruby_llm_embedder.rb
234
+ - lib/truffler/embeddings/ruby_store.rb
235
+ - lib/truffler/embeddings/vector_store.rb
236
+ - lib/truffler/errors.rb
237
+ - lib/truffler/instrumentation.rb
238
+ - lib/truffler/jobs/backfill_job.rb
239
+ - lib/truffler/jobs/embed_job.rb
240
+ - lib/truffler/jobs/encode_query_job.rb
241
+ - lib/truffler/jobs/expire_lenses_job.rb
242
+ - lib/truffler/jobs/label_flush_job.rb
243
+ - lib/truffler/jobs/lens_backfill_job.rb
244
+ - lib/truffler/jobs/provider_search_job.rb
245
+ - lib/truffler/jobs/prune_query_misses_job.rb
246
+ - lib/truffler/jobs/rerank_chunk_job.rb
247
+ - lib/truffler/jobs/resume_job.rb
248
+ - lib/truffler/jobs/smart_search_job.rb
249
+ - lib/truffler/label_definition.rb
250
+ - lib/truffler/labeling/backfill.rb
251
+ - lib/truffler/labeling/labeler.rb
252
+ - lib/truffler/labeling/queue.rb
253
+ - lib/truffler/labeling/request_builder.rb
254
+ - lib/truffler/labeling/supplied.rb
255
+ - lib/truffler/lenses.rb
256
+ - lib/truffler/lenses/activator.rb
257
+ - lib/truffler/lenses/backfill.rb
258
+ - lib/truffler/lenses/draft.rb
259
+ - lib/truffler/lenses/drafter.rb
260
+ - lib/truffler/lenses/fake_generator.rb
261
+ - lib/truffler/lenses/lens.rb
262
+ - lib/truffler/lenses/lens_label.rb
263
+ - lib/truffler/lenses/policy.rb
264
+ - lib/truffler/lenses/previewer.rb
265
+ - lib/truffler/lenses/proposer.rb
266
+ - lib/truffler/lenses/ruby_llm_generator.rb
267
+ - lib/truffler/lenses/scope.rb
268
+ - lib/truffler/lenses/sealed_description.rb
269
+ - lib/truffler/lenses/settings.rb
270
+ - lib/truffler/lenses/validation.rb
271
+ - lib/truffler/lenses/version.rb
272
+ - lib/truffler/misses.rb
273
+ - lib/truffler/misses/clusterer.rb
274
+ - lib/truffler/misses/recorder.rb
275
+ - lib/truffler/misses/suggestions.rb
276
+ - lib/truffler/model.rb
277
+ - lib/truffler/providers.rb
278
+ - lib/truffler/providers/backup.rb
279
+ - lib/truffler/providers/runner.rb
280
+ - lib/truffler/query_encoding.rb
281
+ - lib/truffler/query_encoding/cache.rb
282
+ - lib/truffler/query_encoding/encoder.rb
283
+ - lib/truffler/query_encoding/prefetch.rb
284
+ - lib/truffler/questions.rb
285
+ - lib/truffler/railtie.rb
286
+ - lib/truffler/records/embedding.rb
287
+ - lib/truffler/records/label.rb
288
+ - lib/truffler/records/query_miss.rb
289
+ - lib/truffler/records/record_state.rb
290
+ - lib/truffler/redaction.rb
291
+ - lib/truffler/registry.rb
292
+ - lib/truffler/search/encoding.rb
293
+ - lib/truffler/search/encoding_cache.rb
294
+ - lib/truffler/search/keystroke.rb
295
+ - lib/truffler/search/query.rb
296
+ - lib/truffler/search/result.rb
297
+ - lib/truffler/search/sql.rb
298
+ - lib/truffler/smart_search.rb
299
+ - lib/truffler/smart_search/dispatcher.rb
300
+ - lib/truffler/smart_search/reranker.rb
301
+ - lib/truffler/smart_search/run.rb
302
+ - lib/truffler/smart_search/starter.rb
303
+ - lib/truffler/smart_search/store.rb
304
+ - lib/truffler/tokens.rb
305
+ - lib/truffler/usage.rb
306
+ - lib/truffler/version.rb
307
+ - lib/truffler/vocabulary.rb
308
+ homepage: https://github.com/kieranklaassen/truffler
309
+ licenses:
310
+ - MIT
311
+ metadata:
312
+ homepage_uri: https://github.com/kieranklaassen/truffler
313
+ source_code_uri: https://github.com/kieranklaassen/truffler
314
+ changelog_uri: https://github.com/kieranklaassen/truffler/blob/main/CHANGELOG.md
315
+ rubygems_mfa_required: 'true'
316
+ post_install_message:
317
+ rdoc_options: []
318
+ require_paths:
319
+ - lib
320
+ required_ruby_version: !ruby/object:Gem::Requirement
321
+ requirements:
322
+ - - ">="
323
+ - !ruby/object:Gem::Version
324
+ version: '3.2'
325
+ required_rubygems_version: !ruby/object:Gem::Requirement
326
+ requirements:
327
+ - - ">="
328
+ - !ruby/object:Gem::Version
329
+ version: '0'
330
+ requirements: []
331
+ rubygems_version: 3.4.20
332
+ signing_key:
333
+ specification_version: 4
334
+ summary: 'Intent search for Rails: Jev labels, query understanding, and reranking
335
+ over your own database'
336
+ test_files: []