@far-world-labs/verblets 0.1.7 → 0.3.2

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 (306) hide show
  1. package/README.md +86 -213
  2. package/dist/index.browser.js +74 -0
  3. package/dist/index.js +548 -0
  4. package/dist/shared-C6kPWghF.js +7806 -0
  5. package/package.json +32 -8
  6. package/.cursor/launch.json +0 -30
  7. package/.cursor/settings.json +0 -20
  8. package/.github/workflows/branch-protection.yml +0 -22
  9. package/.github/workflows/ci.yml +0 -165
  10. package/.husky/pre-commit +0 -4
  11. package/.prettierrc +0 -6
  12. package/.release-it.json +0 -12
  13. package/.vitest.config.examples.js +0 -8
  14. package/.vitest.config.js +0 -8
  15. package/.vscode/launch.json +0 -31
  16. package/AGENTS.md +0 -220
  17. package/DEVELOPING.md +0 -105
  18. package/docker-compose.yml +0 -7
  19. package/eslint.config.js +0 -80
  20. package/scripts/generate-chain/index.js +0 -111
  21. package/scripts/generate-lib/index.js +0 -68
  22. package/scripts/generate-test/index.js +0 -137
  23. package/scripts/generate-verblet/README.md +0 -17
  24. package/scripts/generate-verblet/index.js +0 -110
  25. package/scripts/run.sh +0 -15
  26. package/scripts/runner/index.js +0 -56
  27. package/scripts/simple-editor/README.md +0 -34
  28. package/scripts/simple-editor/index.js +0 -79
  29. package/scripts/summarize-files/index.js +0 -70
  30. package/src/chains/README.md +0 -30
  31. package/src/chains/anonymize/README.md +0 -21
  32. package/src/chains/anonymize/index.examples.js +0 -75
  33. package/src/chains/anonymize/index.js +0 -121
  34. package/src/chains/anonymize/index.spec.js +0 -78
  35. package/src/chains/bulk-central-tendency/index.examples.js +0 -138
  36. package/src/chains/bulk-central-tendency/index.js +0 -91
  37. package/src/chains/bulk-filter/README.md +0 -21
  38. package/src/chains/bulk-filter/index.examples.js +0 -22
  39. package/src/chains/bulk-filter/index.js +0 -58
  40. package/src/chains/bulk-filter/index.spec.js +0 -38
  41. package/src/chains/bulk-find/README.md +0 -16
  42. package/src/chains/bulk-find/index.examples.js +0 -20
  43. package/src/chains/bulk-find/index.js +0 -30
  44. package/src/chains/bulk-find/index.spec.js +0 -26
  45. package/src/chains/bulk-group/README.md +0 -23
  46. package/src/chains/bulk-group/index.examples.js +0 -18
  47. package/src/chains/bulk-group/index.js +0 -34
  48. package/src/chains/bulk-group/index.spec.js +0 -41
  49. package/src/chains/bulk-map/README.md +0 -43
  50. package/src/chains/bulk-map/index.examples.js +0 -17
  51. package/src/chains/bulk-map/index.js +0 -86
  52. package/src/chains/bulk-map/index.spec.js +0 -44
  53. package/src/chains/bulk-reduce/README.md +0 -12
  54. package/src/chains/bulk-reduce/index.examples.js +0 -15
  55. package/src/chains/bulk-reduce/index.js +0 -13
  56. package/src/chains/bulk-reduce/index.spec.js +0 -25
  57. package/src/chains/bulk-score/README.md +0 -16
  58. package/src/chains/bulk-score/bulk-score-result.json +0 -18
  59. package/src/chains/bulk-score/index.examples.js +0 -22
  60. package/src/chains/bulk-score/index.js +0 -133
  61. package/src/chains/bulk-score/index.spec.js +0 -30
  62. package/src/chains/category-samples/README.md +0 -61
  63. package/src/chains/category-samples/index.examples.js +0 -103
  64. package/src/chains/category-samples/index.js +0 -134
  65. package/src/chains/collect-terms/README.md +0 -12
  66. package/src/chains/collect-terms/index.examples.js +0 -16
  67. package/src/chains/collect-terms/index.js +0 -44
  68. package/src/chains/collect-terms/index.spec.js +0 -25
  69. package/src/chains/date/README.md +0 -12
  70. package/src/chains/date/index.examples.js +0 -47
  71. package/src/chains/date/index.js +0 -74
  72. package/src/chains/date/index.spec.js +0 -62
  73. package/src/chains/disambiguate/README.md +0 -22
  74. package/src/chains/disambiguate/disambiguate-meanings-result.json +0 -16
  75. package/src/chains/disambiguate/index.examples.js +0 -18
  76. package/src/chains/disambiguate/index.js +0 -92
  77. package/src/chains/disambiguate/index.spec.js +0 -25
  78. package/src/chains/dismantle/README.md +0 -67
  79. package/src/chains/dismantle/dismantle.examples.js +0 -27
  80. package/src/chains/dismantle/index.examples.js +0 -30
  81. package/src/chains/dismantle/index.js +0 -303
  82. package/src/chains/dismantle/index.spec.js +0 -32
  83. package/src/chains/expect/README.md +0 -171
  84. package/src/chains/expect/index.examples.js +0 -146
  85. package/src/chains/expect/index.js +0 -173
  86. package/src/chains/expect/index.spec.js +0 -324
  87. package/src/chains/filter-ambiguous/README.md +0 -11
  88. package/src/chains/filter-ambiguous/index.examples.js +0 -20
  89. package/src/chains/filter-ambiguous/index.js +0 -49
  90. package/src/chains/filter-ambiguous/index.spec.js +0 -31
  91. package/src/chains/glossary/README.md +0 -19
  92. package/src/chains/glossary/index.examples.js +0 -386
  93. package/src/chains/glossary/index.js +0 -75
  94. package/src/chains/glossary/index.spec.js +0 -19
  95. package/src/chains/intersections/README.md +0 -152
  96. package/src/chains/intersections/index.examples.js +0 -279
  97. package/src/chains/intersections/index.js +0 -366
  98. package/src/chains/intersections/intersection-result.json +0 -38
  99. package/src/chains/list/index.examples.js +0 -68
  100. package/src/chains/list/index.js +0 -214
  101. package/src/chains/list/index.spec.js +0 -67
  102. package/src/chains/list/list-result.json +0 -16
  103. package/src/chains/list/schema.json +0 -24
  104. package/src/chains/llm-logger/README.md +0 -208
  105. package/src/chains/llm-logger/index.js +0 -205
  106. package/src/chains/llm-logger/index.spec.js +0 -330
  107. package/src/chains/questions/index.examples.js +0 -69
  108. package/src/chains/questions/index.js +0 -135
  109. package/src/chains/questions/index.spec.js +0 -29
  110. package/src/chains/scan-js/index.js +0 -116
  111. package/src/chains/set-interval/README.md +0 -81
  112. package/src/chains/set-interval/index.examples.js +0 -36
  113. package/src/chains/set-interval/index.js +0 -131
  114. package/src/chains/set-interval/index.spec.js +0 -70
  115. package/src/chains/socratic/README.md +0 -17
  116. package/src/chains/socratic/index.js +0 -64
  117. package/src/chains/socratic/index.spec.js +0 -24
  118. package/src/chains/sort/index.examples.js +0 -36
  119. package/src/chains/sort/index.js +0 -163
  120. package/src/chains/sort/index.spec.js +0 -112
  121. package/src/chains/sort/sort-result.json +0 -16
  122. package/src/chains/summary-map/README.md +0 -41
  123. package/src/chains/summary-map/index.examples.js +0 -64
  124. package/src/chains/summary-map/index.js +0 -226
  125. package/src/chains/summary-map/index.spec.js +0 -153
  126. package/src/chains/test/index.js +0 -114
  127. package/src/chains/test-advice/index.js +0 -35
  128. package/src/chains/themes/README.md +0 -20
  129. package/src/chains/themes/index.examples.js +0 -17
  130. package/src/chains/themes/index.js +0 -28
  131. package/src/chains/themes/index.spec.js +0 -19
  132. package/src/chains/veiled-variants/index.examples.js +0 -18
  133. package/src/chains/veiled-variants/index.js +0 -107
  134. package/src/chains/veiled-variants/index.spec.js +0 -40
  135. package/src/constants/common.js +0 -7
  136. package/src/constants/messages.js +0 -3
  137. package/src/constants/models.js +0 -183
  138. package/src/index.js +0 -193
  139. package/src/json-schemas/README.md +0 -13
  140. package/src/json-schemas/cars-test.json +0 -11
  141. package/src/json-schemas/index.js +0 -12
  142. package/src/json-schemas/intent.json +0 -38
  143. package/src/json-schemas/schema-dot-org-photograph.json +0 -133
  144. package/src/json-schemas/schema-dot-org-place.json +0 -129
  145. package/src/lib/README.md +0 -26
  146. package/src/lib/any-signal/index.js +0 -28
  147. package/src/lib/bulk-filter/README.md +0 -22
  148. package/src/lib/bulk-filter/index.examples.js +0 -27
  149. package/src/lib/bulk-filter/index.js +0 -63
  150. package/src/lib/bulk-filter/index.spec.js +0 -38
  151. package/src/lib/bulk-find/README.md +0 -18
  152. package/src/lib/bulk-find/index.examples.js +0 -19
  153. package/src/lib/bulk-find/index.js +0 -30
  154. package/src/lib/bulk-find/index.spec.js +0 -41
  155. package/src/lib/chatgpt/index.js +0 -163
  156. package/src/lib/combinations/index.js +0 -30
  157. package/src/lib/combinations/index.spec.js +0 -23
  158. package/src/lib/editor/index.js +0 -31
  159. package/src/lib/functional/index.js +0 -28
  160. package/src/lib/logger-service/index.js +0 -32
  161. package/src/lib/parse-js-parts/index.js +0 -321
  162. package/src/lib/parse-js-parts/index.spec.js +0 -156
  163. package/src/lib/parse-llm-list/README.md +0 -39
  164. package/src/lib/parse-llm-list/index.js +0 -54
  165. package/src/lib/parse-llm-list/index.spec.js +0 -59
  166. package/src/lib/path-aliases/index.js +0 -37
  167. package/src/lib/path-aliases/index.spec.js +0 -64
  168. package/src/lib/pave/index.js +0 -34
  169. package/src/lib/pave/index.spec.js +0 -76
  170. package/src/lib/prompt-cache/index.js +0 -50
  171. package/src/lib/retry/index.js +0 -66
  172. package/src/lib/retry/index.spec.js +0 -86
  173. package/src/lib/ring-buffer/README.md +0 -460
  174. package/src/lib/ring-buffer/index.js +0 -1074
  175. package/src/lib/search-best-first/city-walk.spec.js +0 -37
  176. package/src/lib/search-best-first/index.js +0 -97
  177. package/src/lib/search-best-first/index.spec.js +0 -35
  178. package/src/lib/search-js-files/code-features-property-definitions.json +0 -123
  179. package/src/lib/search-js-files/index.examples.js +0 -22
  180. package/src/lib/search-js-files/index.js +0 -155
  181. package/src/lib/search-js-files/index.spec.js +0 -34
  182. package/src/lib/search-js-files/scan-file.js +0 -242
  183. package/src/lib/shorten-text/index.js +0 -25
  184. package/src/lib/shorten-text/index.spec.js +0 -68
  185. package/src/lib/strip-numeric/index.js +0 -5
  186. package/src/lib/strip-response/index.js +0 -30
  187. package/src/lib/template-replace/index.js +0 -23
  188. package/src/lib/template-replace/index.spec.js +0 -60
  189. package/src/lib/timed-abort-controller/index.js +0 -41
  190. package/src/lib/to-bool/index.js +0 -8
  191. package/src/lib/to-date/index.js +0 -11
  192. package/src/lib/to-enum/index.js +0 -14
  193. package/src/lib/to-number/index.js +0 -12
  194. package/src/lib/to-number-with-units/index.js +0 -51
  195. package/src/lib/transcribe/index.js +0 -78
  196. package/src/prompts/README.md +0 -17
  197. package/src/prompts/as-enum.js +0 -5
  198. package/src/prompts/as-json-schema.js +0 -9
  199. package/src/prompts/as-object-with-schema.js +0 -26
  200. package/src/prompts/as-schema-org-text.js +0 -25
  201. package/src/prompts/as-schema-org-type.js +0 -1
  202. package/src/prompts/blog-post.js +0 -7
  203. package/src/prompts/code-features.js +0 -24
  204. package/src/prompts/constants.js +0 -101
  205. package/src/prompts/features-json-schema.js +0 -27
  206. package/src/prompts/generate-collection.js +0 -26
  207. package/src/prompts/generate-list.js +0 -48
  208. package/src/prompts/generate-questions.js +0 -19
  209. package/src/prompts/index.js +0 -20
  210. package/src/prompts/intent.js +0 -60
  211. package/src/prompts/output-succinct-names.js +0 -3
  212. package/src/prompts/select-from-threshold.js +0 -17
  213. package/src/prompts/sort.js +0 -31
  214. package/src/prompts/style.js +0 -38
  215. package/src/prompts/summarize.js +0 -13
  216. package/src/prompts/token-budget.js +0 -3
  217. package/src/prompts/wrap-list.js +0 -11
  218. package/src/prompts/wrap-variable.js +0 -36
  219. package/src/services/llm-model/global-overrides.spec.js +0 -432
  220. package/src/services/llm-model/index.js +0 -308
  221. package/src/services/llm-model/model.js +0 -21
  222. package/src/services/llm-model/negotiate.spec.js +0 -447
  223. package/src/services/redis/index.js +0 -147
  224. package/src/test/setup.js +0 -20
  225. package/src/verblets/README.md +0 -26
  226. package/src/verblets/auto/index.examples.js +0 -31
  227. package/src/verblets/auto/index.js +0 -28
  228. package/src/verblets/auto/index.spec.js +0 -32
  229. package/src/verblets/bool/README.md +0 -36
  230. package/src/verblets/bool/index.examples.js +0 -80
  231. package/src/verblets/bool/index.js +0 -25
  232. package/src/verblets/bool/index.schema.json +0 -14
  233. package/src/verblets/bool/index.spec.js +0 -33
  234. package/src/verblets/central-tendency/README.md +0 -166
  235. package/src/verblets/central-tendency/central-tendency-result.json +0 -24
  236. package/src/verblets/central-tendency/index.examples.js +0 -196
  237. package/src/verblets/central-tendency/index.js +0 -171
  238. package/src/verblets/central-tendency/index.spec.js +0 -148
  239. package/src/verblets/enum/index.examples.js +0 -30
  240. package/src/verblets/enum/index.js +0 -18
  241. package/src/verblets/enum/index.spec.js +0 -35
  242. package/src/verblets/expect/README.md +0 -64
  243. package/src/verblets/expect/index.examples.js +0 -109
  244. package/src/verblets/expect/index.js +0 -75
  245. package/src/verblets/expect/index.spec.js +0 -127
  246. package/src/verblets/intent/index.examples.js +0 -139
  247. package/src/verblets/intent/index.js +0 -60
  248. package/src/verblets/intent/index.spec.js +0 -31
  249. package/src/verblets/intersection/README.md +0 -16
  250. package/src/verblets/intersection/index.examples.js +0 -89
  251. package/src/verblets/intersection/index.js +0 -84
  252. package/src/verblets/intersection/index.spec.js +0 -60
  253. package/src/verblets/intersection/intersection-result.json +0 -16
  254. package/src/verblets/list-expand/README.md +0 -10
  255. package/src/verblets/list-expand/index.examples.js +0 -14
  256. package/src/verblets/list-expand/index.js +0 -104
  257. package/src/verblets/list-expand/index.spec.js +0 -18
  258. package/src/verblets/list-expand/list-expand-result.json +0 -16
  259. package/src/verblets/list-filter/README.md +0 -22
  260. package/src/verblets/list-filter/index.examples.js +0 -26
  261. package/src/verblets/list-filter/index.js +0 -18
  262. package/src/verblets/list-filter/index.spec.js +0 -19
  263. package/src/verblets/list-find/README.md +0 -11
  264. package/src/verblets/list-find/index.examples.js +0 -15
  265. package/src/verblets/list-find/index.js +0 -17
  266. package/src/verblets/list-find/index.spec.js +0 -19
  267. package/src/verblets/list-group/README.md +0 -16
  268. package/src/verblets/list-group/index.examples.js +0 -16
  269. package/src/verblets/list-group/index.js +0 -112
  270. package/src/verblets/list-group/index.spec.js +0 -35
  271. package/src/verblets/list-group/list-group-result.json +0 -16
  272. package/src/verblets/list-map/README.md +0 -11
  273. package/src/verblets/list-map/index.examples.js +0 -15
  274. package/src/verblets/list-map/index.js +0 -26
  275. package/src/verblets/list-map/index.spec.js +0 -17
  276. package/src/verblets/list-reduce/README.md +0 -10
  277. package/src/verblets/list-reduce/index.examples.js +0 -14
  278. package/src/verblets/list-reduce/index.js +0 -21
  279. package/src/verblets/list-reduce/index.spec.js +0 -27
  280. package/src/verblets/list-reduce/index.spec.jsx +0 -27
  281. package/src/verblets/name/README.md +0 -15
  282. package/src/verblets/name/index.examples.js +0 -28
  283. package/src/verblets/name/index.js +0 -19
  284. package/src/verblets/name/index.spec.js +0 -33
  285. package/src/verblets/name-similar-to/README.md +0 -26
  286. package/src/verblets/name-similar-to/index.examples.js +0 -18
  287. package/src/verblets/name-similar-to/index.js +0 -20
  288. package/src/verblets/name-similar-to/index.spec.js +0 -13
  289. package/src/verblets/number/index.examples.js +0 -199
  290. package/src/verblets/number/index.js +0 -25
  291. package/src/verblets/number/index.spec.js +0 -33
  292. package/src/verblets/number-with-units/index.examples.js +0 -38
  293. package/src/verblets/number-with-units/index.js +0 -84
  294. package/src/verblets/number-with-units/index.spec.js +0 -46
  295. package/src/verblets/number-with-units/number-with-units-result.json +0 -23
  296. package/src/verblets/schema-org/index.examples.js +0 -51
  297. package/src/verblets/schema-org/index.js +0 -37
  298. package/src/verblets/schema-org/index.spec.js +0 -39
  299. package/src/verblets/sentiment/README.md +0 -10
  300. package/src/verblets/sentiment/index.examples.js +0 -20
  301. package/src/verblets/sentiment/index.js +0 -9
  302. package/src/verblets/sentiment/index.spec.js +0 -20
  303. package/src/verblets/to-object/README.md +0 -38
  304. package/src/verblets/to-object/index.examples.js +0 -29
  305. package/src/verblets/to-object/index.js +0 -131
  306. package/src/verblets/to-object/index.spec.js +0 -71
@@ -1,129 +0,0 @@
1
- {
2
- "$schema": "http://json-schema.org/draft-07/schema#",
3
- "type": "object",
4
- "additionalProperties": false,
5
- "properties": {
6
- "@context": {
7
- "type": "string",
8
- "pattern": "^https://schema.org$"
9
- },
10
- "@type": {
11
- "type": "string",
12
- "enum": ["Place", "City"]
13
- },
14
- "name": {
15
- "type": "string"
16
- },
17
- "alternateName": {
18
- "type": "string"
19
- },
20
- "description": {
21
- "type": "string"
22
- },
23
- "population": {
24
- "type": "integer",
25
- "minimum": 0
26
- },
27
- "area": {
28
- "type": "object",
29
- "additionalProperties": false,
30
- "properties": {
31
- "@type": {
32
- "type": "string",
33
- "enum": ["QuantitativeValue"]
34
- },
35
- "value": {
36
- "type": "number",
37
- "minimum": 0
38
- },
39
- "unitCode": {
40
- "type": "string"
41
- }
42
- }
43
- },
44
- "elevation": {
45
- "type": "object",
46
- "additionalProperties": false,
47
- "properties": {
48
- "@type": {
49
- "type": "string",
50
- "enum": ["QuantitativeValue"]
51
- },
52
- "value": {
53
- "type": "number"
54
- },
55
- "unitCode": {
56
- "type": "string"
57
- }
58
- }
59
- },
60
- "address": {
61
- "type": "object",
62
- "additionalProperties": false,
63
- "properties": {
64
- "@type": {
65
- "type": "string",
66
- "enum": ["PostalAddress"]
67
- },
68
- "streetAddress": {
69
- "type": "string"
70
- },
71
- "addressLocality": {
72
- "type": "string"
73
- },
74
- "addressRegion": {
75
- "type": "string"
76
- },
77
- "postalCode": {
78
- "type": "string"
79
- },
80
- "addressCountry": {
81
- "type": "string"
82
- }
83
- }
84
- },
85
- "geo": {
86
- "type": "object",
87
- "additionalProperties": false,
88
- "properties": {
89
- "@type": {
90
- "type": "string",
91
- "enum": ["GeoCoordinates"]
92
- },
93
- "latitude": {
94
- "type": "number"
95
- },
96
- "longitude": {
97
- "type": "number"
98
- }
99
- }
100
- },
101
- "areaServed": {
102
- "oneOf": [
103
- {
104
- "type": "string"
105
- },
106
- {
107
- "type": "object",
108
- "additionalProperties": false,
109
- "properties": {
110
- "@type": {
111
- "type": "string",
112
- "enum": ["AdministrativeArea"]
113
- },
114
- "name": {
115
- "type": "string"
116
- }
117
- }
118
- }
119
- ]
120
- },
121
- "additionalType": {
122
- "type": "string"
123
- },
124
- "sameAs": {
125
- "type": "string"
126
- }
127
- },
128
- "required": ["@type", "name"]
129
- }
package/src/lib/README.md DELETED
@@ -1,26 +0,0 @@
1
- # Library Helpers
2
-
3
- The `lib` directory houses reusable utilities used by verblets and chains. Each subfolder contains a focused helper function or class.
4
-
5
- Modules include:
6
-
7
- <!-- commonly used utilities -->
8
- - [chatgpt](./chatgpt) – wrapper around OpenAI's ChatGPT API.
9
- - [prompt-cache](./prompt-cache) – cache prompts/responses locally.
10
- - [retry](./retry) – generic async retry helper.
11
- - [search-best-first](./search-best-first) – best-first tree search algorithm.
12
- - [search-js-files](./search-js-files) – locate and analyze JavaScript files.
13
- - [combinations](./combinations) – generate array combinations.
14
- - [rangeCombinations](./combinations) – combinations across multiple sizes.
15
- - [shorten-text](./shorten-text) – shorten text using an LLM.
16
- - [bulk-map](./bulk-map) – map lists in retryable batches.
17
- - [bulk-filter](./bulk-filter) – filter lists in retryable batches.
18
- - [strip-numeric](./strip-numeric) – remove non-digit characters.
19
- - [strip-response](./strip-response) – clean up model responses.
20
- - [to-bool](./to-bool) – parse text into a boolean.
21
- - [to-enum](./to-enum) – parse text into an enum value.
22
- - [to-number](./to-number) – parse text into a number.
23
- - [to-number-with-units](./to-number-with-units) – parse numbers that include units.
24
- - [transcribe](./transcribe) – microphone transcription via Whisper.
25
-
26
- These helpers are building blocks used throughout the rest of the project.
@@ -1,28 +0,0 @@
1
- /**
2
- * Creates a new AbortSignal that is triggered when any of the given signals are aborted.
3
- *
4
- * @param {AbortSignal[]} signals - An array of AbortSignal instances to listen to.
5
- * @returns {AbortSignal} - A new AbortSignal that is aborted when any of the input signals are aborted.
6
- *
7
- * @example
8
- * const abortController1 = new AbortController();
9
- * const abortController2 = new AbortController();
10
- * const combinedSignal = anySignal([abortController1.signal, abortController2.signal]);
11
- * fetch('https://example.com', { signal: combinedSignal });
12
- * abortController1.abort(); // This will abort the fetch operation
13
- */
14
- export default (signalsInitial) => {
15
- const signals = signalsInitial.filter((s) => s);
16
-
17
- const controller = new AbortController();
18
- for (const signal of signals) {
19
- if (signal.aborted) {
20
- controller.abort();
21
- break;
22
- }
23
- signal.addEventListener('abort', () => {
24
- controller.abort();
25
- });
26
- }
27
- return controller.signal;
28
- };
@@ -1,22 +0,0 @@
1
- # bulk-filter
2
-
3
- Filter long lists in batches using `listFilter`. Batches that fail can be retried.
4
-
5
- ```javascript
6
- import bulkFilter from './index.js';
7
-
8
- const reflections = [
9
- 'Losing that match taught me the value of persistence.',
10
- "I hate losing and it proves I'm worthless.",
11
- 'After failing my exam, I studied harder and passed the retake.',
12
- "No matter what I do, I'll never succeed.",
13
- ];
14
- const growth = await bulkFilter(
15
- reflections,
16
- 'keep only reflections that show personal growth or learning from mistakes'
17
- );
18
- // growth === [
19
- // 'Losing that match taught me the value of persistence.',
20
- // 'After failing my exam, I studied harder and passed the retake.',
21
- // ]
22
- ```
@@ -1,27 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import bulkFilter from './index.js';
3
- import { longTestTimeout } from '../../constants/common.js';
4
-
5
- describe('bulk-filter examples', () => {
6
- it(
7
- 'filters items in batches',
8
- async () => {
9
- const entries = [
10
- 'Losing that match taught me the value of persistence.',
11
- "I hate losing and it proves I'm worthless.",
12
- 'After failing my exam, I studied harder and passed the retake.',
13
- "No matter what I do, I'll never succeed.",
14
- ];
15
- const result = await bulkFilter(
16
- entries,
17
- 'keep only reflections that show personal growth or learning from mistakes',
18
- 2
19
- );
20
- expect(result).toStrictEqual([
21
- 'Losing that match taught me the value of persistence.',
22
- 'After failing my exam, I studied harder and passed the retake.',
23
- ]);
24
- },
25
- longTestTimeout
26
- );
27
- });
@@ -1,63 +0,0 @@
1
- import listFilter from '../../verblets/list-filter/index.js';
2
-
3
- /**
4
- * Filter a list by processing newline-delimited batches with `listFilter`.
5
- *
6
- * @param {string[]} list - array of items to evaluate
7
- * @param {string} instructions - filter instructions for `listFilter`
8
- * @param {number} [chunkSize=10] - how many items per batch
9
- * @returns {Promise<string[]>} filtered items preserving order
10
- */
11
- export default async function bulkFilter(list, instructions, chunkSize = 10) {
12
- const batches = [];
13
- for (let i = 0; i < list.length; i += chunkSize) {
14
- const batch = list.slice(i, i + chunkSize);
15
- const filtered = await listFilter(batch, instructions);
16
- batches.push(filtered);
17
- }
18
- return batches.flat();
19
- }
20
-
21
- /**
22
- * Retry filtering failed batches until `maxAttempts` is reached.
23
- *
24
- * @param {string[]} list
25
- * @param {string} instructions
26
- * @param {object} [options]
27
- * @param {number} [options.chunkSize=10]
28
- * @param {number} [options.maxAttempts=3]
29
- * @returns {Promise<string[]>}
30
- */
31
- export async function bulkFilterRetry(
32
- list,
33
- instructions,
34
- { chunkSize = 10, maxAttempts = 3 } = {}
35
- ) {
36
- const batches = [];
37
- for (let i = 0; i < list.length; i += chunkSize) {
38
- batches.push(list.slice(i, i + chunkSize));
39
- }
40
- const results = new Array(batches.length).fill(null);
41
- let pending = batches.map((_, idx) => idx);
42
-
43
- for (let attempt = 0; attempt < maxAttempts && pending.length > 0; attempt += 1) {
44
- const newPending = [];
45
- for (const idx of pending) {
46
- const batch = batches[idx];
47
- try {
48
- const filtered = await listFilter(batch, instructions);
49
- const valid = filtered.every((line) => batch.includes(line));
50
- if (valid) {
51
- results[idx] = filtered;
52
- } else {
53
- newPending.push(idx);
54
- }
55
- } catch {
56
- newPending.push(idx);
57
- }
58
- }
59
- pending = newPending;
60
- }
61
-
62
- return results.flat().filter(Boolean);
63
- }
@@ -1,38 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from 'vitest';
2
- import bulkFilter, { bulkFilterRetry } from './index.js';
3
- import listFilter from '../../verblets/list-filter/index.js';
4
-
5
- vi.mock('../../verblets/list-filter/index.js', () => ({
6
- default: vi.fn(async (items, instructions) => {
7
- if (items.includes('FAIL')) throw new Error('fail');
8
- return items.filter((l) => l.includes(instructions));
9
- }),
10
- }));
11
-
12
- beforeEach(() => {
13
- vi.clearAllMocks();
14
- });
15
-
16
- describe('bulk-filter', () => {
17
- it('filters fragments in batches', async () => {
18
- const result = await bulkFilter(['aa', 'b', 'ca', 'd'], 'a', 2);
19
- expect(result).toStrictEqual(['aa', 'ca']);
20
- expect(listFilter).toHaveBeenCalledTimes(2);
21
- });
22
-
23
- it('retries failed batches', async () => {
24
- let call = 0;
25
- listFilter.mockImplementation(async (items) => {
26
- call += 1;
27
- if (call === 1) throw new Error('fail');
28
- return items.filter((l) => l.includes('a'));
29
- });
30
-
31
- const result = await bulkFilterRetry(['aa', 'b', 'ca'], 'a', {
32
- chunkSize: 2,
33
- maxAttempts: 2,
34
- });
35
- expect(result).toStrictEqual(['aa', 'ca']);
36
- expect(listFilter).toHaveBeenCalledTimes(3);
37
- });
38
- });
@@ -1,18 +0,0 @@
1
- # bulk-find
2
-
3
- Search large lists in batches using `listFind` and return the first matching item.
4
- Failed batches can be retried with `bulkFindRetry`.
5
-
6
- ```javascript
7
- import bulkFind, { bulkFindRetry } from './index.js';
8
-
9
- const diaryEntries = [
10
- 'Hiked up the mountains today and saw breathtaking views',
11
- 'Visited the local market and tried a spicy stew',
12
- 'Spotted penguins playing on the beach this morning'
13
- ];
14
- const penguinMoment = await bulkFindRetry(diaryEntries, 'mentions penguins', {
15
- chunkSize: 2
16
- });
17
- // penguinMoment === 'Spotted penguins playing on the beach this morning'
18
- ```
@@ -1,19 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { bulkFindRetry } from './index.js';
3
- import { longTestTimeout } from '../../constants/common.js';
4
-
5
- describe('bulk-find examples', () => {
6
- it(
7
- 'finds an item across batches',
8
- async () => {
9
- const diaryEntries = [
10
- 'Hiked up the mountains today and saw breathtaking views',
11
- 'Visited the local market and tried a spicy stew',
12
- 'Spotted penguins playing on the beach this morning',
13
- ];
14
- const result = await bulkFindRetry(diaryEntries, 'mentions penguins');
15
- expect(result).toBeDefined();
16
- },
17
- longTestTimeout
18
- );
19
- });
@@ -1,30 +0,0 @@
1
- import listFind from '../../verblets/list-find/index.js';
2
-
3
- /**
4
- * Search a list in batches using `listFind`.
5
- *
6
- * @param { string[] } list - array of items to search
7
- * @param { string } instructions - criteria passed to `listFind`
8
- * @param { number } [chunkSize=10] - how many items per batch
9
- * @returns { Promise<string|undefined> } first match or undefined
10
- */
11
- export default async function bulkFind(list, instructions, chunkSize = 10) {
12
- for (let i = 0; i < list.length; i += chunkSize) {
13
- const batch = list.slice(i, i + chunkSize);
14
- try {
15
- const result = await listFind(batch, instructions);
16
- if (result) return result;
17
- } catch {
18
- // ignore and continue to next batch
19
- }
20
- }
21
- return undefined;
22
- }
23
-
24
- export async function bulkFindRetry(list, instructions, { chunkSize = 10, maxAttempts = 3 } = {}) {
25
- for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
26
- const result = await bulkFind(list, instructions, chunkSize);
27
- if (result) return result;
28
- }
29
- return undefined;
30
- }
@@ -1,41 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from 'vitest';
2
- import bulkFind, { bulkFindRetry } from './index.js';
3
- import listFind from '../../verblets/list-find/index.js';
4
-
5
- vi.mock('../../verblets/list-find/index.js', () => ({
6
- default: vi.fn(async (list, instructions) => list.find((l) => l.includes(instructions)) || ''),
7
- }));
8
-
9
- beforeEach(() => {
10
- vi.clearAllMocks();
11
- });
12
-
13
- describe('bulk-find', () => {
14
- it('returns first match across batches', async () => {
15
- const result = await bulkFind(['a', 'b', 'c', 'd'], 'c', 2);
16
- expect(result).toBe('c');
17
- expect(listFind).toHaveBeenCalledTimes(2);
18
- });
19
-
20
- it('returns undefined when not found', async () => {
21
- listFind.mockResolvedValueOnce('');
22
- listFind.mockResolvedValueOnce('');
23
- const result = await bulkFind(['a', 'b'], 'x', 1);
24
- expect(result).toBeUndefined();
25
- });
26
-
27
- it('retries until a match is found', async () => {
28
- listFind.mockResolvedValueOnce('');
29
- listFind.mockResolvedValueOnce('c');
30
- const result = await bulkFindRetry(['a', 'b', 'c'], 'c', { chunkSize: 2, maxAttempts: 2 });
31
- expect(result).toBe('c');
32
- expect(listFind).toHaveBeenCalledTimes(2);
33
- });
34
-
35
- it('returns undefined after maxAttempts', async () => {
36
- listFind.mockResolvedValue('');
37
- const result = await bulkFindRetry(['a', 'b'], 'x', { chunkSize: 1, maxAttempts: 2 });
38
- expect(result).toBeUndefined();
39
- expect(listFind).toHaveBeenCalledTimes(4);
40
- });
41
- });
@@ -1,163 +0,0 @@
1
- import fetch from 'node-fetch';
2
-
3
- import {
4
- debugPromptGlobally,
5
- debugPromptGloballyIfChanged,
6
- debugResultGlobally,
7
- debugResultGloballyIfChanged,
8
- models,
9
- } from '../../constants/models.js';
10
- import anySignal from '../any-signal/index.js';
11
- import { get as getPromptResult, set as setPromptResult } from '../prompt-cache/index.js';
12
- import TimedAbortController from '../timed-abort-controller/index.js';
13
- import modelService from '../../services/llm-model/index.js';
14
- import { getClient as getRedis } from '../../services/redis/index.js';
15
-
16
- const shapeOutputDefault = (result) => {
17
- // GPT-4
18
- if (result.choices[0].message.tool_calls?.length) {
19
- const toolCall = result.choices[0].message.tool_calls[0];
20
- return {
21
- name: toolCall.function.name,
22
- arguments: JSON.parse(toolCall.function.arguments),
23
- result: result.choices[0].message.tool_calls[0].function,
24
- };
25
- }
26
- if (result.choices[0].message) {
27
- return result.choices[0].message.content.trim();
28
- }
29
- return result.choices[0].text.trim();
30
- };
31
-
32
- const onBeforeRequestDefault = ({ debugPrompt, isCached, prompt }) => {
33
- if (debugPrompt || debugPromptGlobally || (debugPromptGloballyIfChanged && !isCached)) {
34
- console.error('+++ DEBUG PROMPT +++');
35
- console.error(prompt);
36
- console.error('+++ DEBUG PROMPT END +++');
37
- }
38
- };
39
-
40
- const onAfterRequestDefault = ({ debugResult, isCached, resultShaped }) => {
41
- if (debugResult || debugResultGlobally || (debugResultGloballyIfChanged && !isCached)) {
42
- console.error('+++ DEBUG RESULT +++');
43
- console.error(resultShaped);
44
- console.error('+++ DEBUG RESULT END +++');
45
- }
46
- };
47
-
48
- export const run = async (prompt, config = {}) => {
49
- // Handle config parameter - can be string (model name) or object (full options)
50
- let options;
51
- if (typeof config === 'string') {
52
- options = { modelOptions: { modelName: config } };
53
- } else {
54
- options = config;
55
- }
56
-
57
- const {
58
- abortSignal,
59
- debugPrompt,
60
- debugResult,
61
- forceQuery,
62
- modelOptions = {},
63
- onAfterRequest = onAfterRequestDefault,
64
- onBeforeRequest = onBeforeRequestDefault,
65
- shapeOutput = shapeOutputDefault,
66
- } = options;
67
-
68
- // Apply global overrides to model options
69
- const modelOptionsWithOverrides = modelService.applyGlobalOverrides(modelOptions);
70
-
71
- // Check if negotiation was applied via global override
72
- const negotiationFromGlobalOverride = modelService.getGlobalOverride('negotiate');
73
-
74
- const modelNameNegotiated = modelOptionsWithOverrides.negotiate
75
- ? modelService.negotiateModel(
76
- // If negotiation came from global override, don't use preferred model
77
- negotiationFromGlobalOverride ? null : modelOptionsWithOverrides.modelName,
78
- modelOptionsWithOverrides.negotiate
79
- )
80
- : modelOptionsWithOverrides.modelName;
81
-
82
- const modelFound = modelService.getModel(modelNameNegotiated);
83
-
84
- // Use model-specific API URL and key if defined, otherwise fall back to defaults
85
- const apiUrl = modelFound?.apiUrl || models.fastGood.apiUrl;
86
- const apiKey = modelFound?.apiKey || models.fastGood.apiKey;
87
-
88
- const requestConfig = modelService.getRequestConfig({
89
- prompt,
90
- ...modelOptionsWithOverrides,
91
- modelName: modelNameNegotiated,
92
- });
93
-
94
- // Check if caching is disabled via environment variable
95
- const cachingDisabled = process.env.DISABLE_CACHE === 'true';
96
-
97
- let cacheResult = null;
98
- let cache = null;
99
-
100
- if (!cachingDisabled) {
101
- cache = await getRedis();
102
- const { result } = await getPromptResult(cache, requestConfig);
103
- cacheResult = result;
104
- }
105
-
106
- onBeforeRequest({
107
- isCached: !!cacheResult,
108
- debugPrompt,
109
- prompt,
110
- requestConfig,
111
- });
112
-
113
- let result = cacheResult;
114
- if (!cacheResult || forceQuery) {
115
- // Use custom requestTimeout from modelOptions if provided, otherwise use model default
116
- const requestTimeout =
117
- modelOptionsWithOverrides.requestTimeout ||
118
- modelService.getModel(modelNameNegotiated).requestTimeout;
119
-
120
- const timeoutController = new TimedAbortController(requestTimeout);
121
-
122
- // console.log(requestConfig, `${apiUrl}${modelFound.endpoint}`)
123
-
124
- const response = await fetch(`${apiUrl}${modelFound.endpoint}`, {
125
- method: 'POST',
126
- headers: {
127
- Authorization: `Bearer ${apiKey}`,
128
- 'Content-Type': 'application/json',
129
- },
130
- body: JSON.stringify(requestConfig),
131
- signal: anySignal([abortSignal, timeoutController.signal]),
132
- });
133
-
134
- result = await response.json();
135
-
136
- if (!response.ok) {
137
- const vars = [`status: ${response?.status}`, `type: ${result?.error?.type}`].join(', ');
138
- throw new Error(`Completions request [error]: ${result?.error?.message} (${vars})`);
139
- }
140
-
141
- timeoutController.clearTimeout();
142
-
143
- // Only cache the result if caching is not disabled
144
- if (!cachingDisabled && cache) {
145
- await setPromptResult(cache, requestConfig, result);
146
- }
147
- }
148
-
149
- const resultShaped = shapeOutput(result);
150
-
151
- onAfterRequest({
152
- debugResult,
153
- isCached: !!cacheResult,
154
- prompt,
155
- requestConfig,
156
- result,
157
- resultShaped,
158
- });
159
-
160
- return resultShaped;
161
- };
162
-
163
- export default run;
@@ -1,30 +0,0 @@
1
- export default function combinations(items, size = 2) {
2
- const result = [];
3
- if (!Array.isArray(items) || size < 1) return result;
4
-
5
- const combo = [];
6
- const generate = (start) => {
7
- if (combo.length === size) {
8
- result.push([...combo]);
9
- return;
10
- }
11
- for (let i = start; i < items.length; i++) {
12
- combo.push(items[i]);
13
- generate(i + 1);
14
- combo.pop();
15
- }
16
- };
17
-
18
- generate(0);
19
- return result;
20
- }
21
-
22
- export function rangeCombinations(items, minSize = 2, maxSize = items.length) {
23
- const sets = [];
24
- if (!Array.isArray(items)) return sets;
25
- const upper = Math.min(items.length, maxSize);
26
- for (let s = minSize; s <= upper; s++) {
27
- sets.push(...combinations(items, s));
28
- }
29
- return sets;
30
- }
@@ -1,23 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import combinations, { rangeCombinations } from './index.js';
3
-
4
- describe('combinations helper', () => {
5
- it('generates pairwise combinations', () => {
6
- const result = combinations(['a', 'b', 'c'], 2);
7
- expect(result).toStrictEqual([
8
- ['a', 'b'],
9
- ['a', 'c'],
10
- ['b', 'c'],
11
- ]);
12
- });
13
-
14
- it('generates combinations of varying sizes', () => {
15
- const result = rangeCombinations(['a', 'b', 'c']);
16
- expect(result).toStrictEqual([
17
- ['a', 'b'],
18
- ['a', 'c'],
19
- ['b', 'c'],
20
- ['a', 'b', 'c'],
21
- ]);
22
- });
23
- });