@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,51 +0,0 @@
1
- import Ajv from 'ajv';
2
- import fs from 'node:fs/promises';
3
- import { describe, expect, it } from 'vitest';
4
-
5
- import { longTestTimeout } from '../../constants/common.js';
6
- import schemaOrg from './index.js';
7
-
8
- const resultSchemaWith = (type) => async () => {
9
- return JSON.parse(
10
- await fs.readFile(`./src/json-schemas/schema-dot-org-${type.toLowerCase()}.json`)
11
- );
12
- };
13
-
14
- const examples = [
15
- {
16
- inputs: { text: 'Kyoto (location)' },
17
- want: { resultSchema: resultSchemaWith('Place') },
18
- },
19
- {
20
- inputs: { text: 'Kyoto (location)', type: 'Photograph' },
21
- want: { resultSchema: resultSchemaWith('Photograph') },
22
- },
23
- ];
24
-
25
- describe('Schema.org verblet', () => {
26
- examples.forEach((example) => {
27
- const typeDisplay = example.inputs.type ? ` - ${example.inputs.type}` : '';
28
- it(
29
- `${example.inputs.text}${typeDisplay}`,
30
- async () => {
31
- const result = await schemaOrg(example.inputs.text, example.inputs.type);
32
-
33
- if (example.want.resultSchema) {
34
- const schema = await example.want.resultSchema();
35
- const ajv = new Ajv();
36
- const validate = ajv.compile(schema);
37
-
38
- const isValid = validate(result);
39
- if (!isValid) {
40
- console.error('Validation errors:');
41
- console.error(JSON.stringify(validate.errors, null, 2));
42
- console.error('Returned result:');
43
- console.error(JSON.stringify(result, null, 2));
44
- }
45
- expect(isValid).toStrictEqual(true);
46
- }
47
- },
48
- longTestTimeout
49
- );
50
- });
51
- });
@@ -1,37 +0,0 @@
1
- import fs from 'node:fs/promises';
2
- import chatGPT from '../../lib/chatgpt/index.js';
3
- import stripResponse from '../../lib/strip-response/index.js';
4
- import { asSchemaOrgText } from '../../prompts/index.js';
5
-
6
- const getSchema = async (type) => {
7
- return JSON.parse(
8
- await fs.readFile(`./src/json-schemas/schema-dot-org-${type.toLowerCase()}.json`)
9
- );
10
- };
11
-
12
- export default async (text, type, config = {}) => {
13
- const { llm, ...options } = config;
14
- const schema = type ? await getSchema(type) : undefined;
15
-
16
- const modelOptions = schema
17
- ? {
18
- response_format: {
19
- type: 'json_schema',
20
- json_schema: {
21
- name: `schema_org_${type.toLowerCase()}`,
22
- schema,
23
- },
24
- },
25
- ...llm,
26
- }
27
- : {
28
- response_format: { type: 'json_object' },
29
- ...llm,
30
- };
31
-
32
- const response = await chatGPT(asSchemaOrgText(text, type, schema), {
33
- modelOptions,
34
- ...options,
35
- });
36
- return JSON.parse(stripResponse(response));
37
- };
@@ -1,39 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
-
3
- import schemaOrg from './index.js';
4
-
5
- vi.mock('../../lib/chatgpt/index.js', () => ({
6
- default: vi.fn().mockImplementation((text) => {
7
- if (/Kyoto \(location\)/.test(text)) {
8
- // Nothing is done with the result
9
- // so returning something complicated only introduces complexity
10
- return '{}';
11
- }
12
- return 'undefined';
13
- }),
14
- }));
15
-
16
- const examples = [
17
- {
18
- name: 'Basic usage',
19
- inputs: { text: 'Kyoto (location)' },
20
- want: { typeOfResult: 'object' },
21
- },
22
- {
23
- name: 'Basic usage',
24
- inputs: { text: 'Kyoto (location)', type: 'Photo' },
25
- want: { typeOfResult: 'object' },
26
- },
27
- ];
28
-
29
- describe('Schema.org verblet', () => {
30
- examples.forEach((example) => {
31
- it(example.name, async () => {
32
- const result = await schemaOrg(example.inputs.text);
33
-
34
- if (example.want.typeOfResult) {
35
- expect(typeof result).toStrictEqual(example.want.typeOfResult);
36
- }
37
- });
38
- });
39
- });
@@ -1,10 +0,0 @@
1
- # sentiment
2
-
3
- Determine whether a piece of text expresses a positive, negative, or neutral tone.
4
-
5
- ```javascript
6
- import sentiment from './index.js';
7
-
8
- const mood = await sentiment('I feel fantastic about the future!');
9
- // mood === 'positive'
10
- ```
@@ -1,20 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import sentiment from './index.js';
3
- import { longTestTimeout } from '../../constants/common.js';
4
-
5
- const examples = [
6
- { text: 'I love sunny days!', want: 'positive' },
7
- { text: 'This is the worst movie ever.', want: 'negative' },
8
- ];
9
-
10
- describe('sentiment', () => {
11
- examples.forEach(({ text, want }) => {
12
- it(
13
- text,
14
- async () => {
15
- expect(await sentiment(text)).toBe(want);
16
- },
17
- longTestTimeout
18
- );
19
- });
20
- });
@@ -1,9 +0,0 @@
1
- import chatGPT from '../../lib/chatgpt/index.js';
2
- import stripResponse from '../../lib/strip-response/index.js';
3
-
4
- export default async function sentiment(text, config = {}) {
5
- const { llm, ...options } = config;
6
- const prompt = `Identify the overall sentiment of the following text as "positive", "negative", or "neutral" and return only that word.\n\n${text}`;
7
- const response = await chatGPT(prompt, { modelOptions: { ...llm }, ...options });
8
- return stripResponse(response).toLowerCase();
9
- }
@@ -1,20 +0,0 @@
1
- import { describe, it, expect, vi } from 'vitest';
2
- import sentiment from './index.js';
3
-
4
- vi.mock('../../lib/chatgpt/index.js', () => ({
5
- default: vi.fn(async (prompt) => {
6
- if (/fantastic/.test(prompt)) return 'positive';
7
- if (/worst/.test(prompt)) return 'negative';
8
- return 'neutral';
9
- }),
10
- }));
11
-
12
- describe('sentiment verblt', () => {
13
- it('classifies positive text', async () => {
14
- expect(await sentiment('fantastic news')).toBe('positive');
15
- });
16
-
17
- it('classifies negative text', async () => {
18
- expect(await sentiment('worst day')).toBe('negative');
19
- });
20
- });
@@ -1,38 +0,0 @@
1
- # to-object - JSON repair and validation
2
-
3
- This module is designed to take JSON results from ChatGPT calls, which can often be imperfect or malformed, and repair them to create valid JSON. If a JSON Schema is provided, the module also validates the repaired JSON against it. This process ensures that the JSON data is both well-formed and conforms to the expected structure.
4
-
5
- ## Features
6
-
7
- - Automatic repair of malformed JSON data returned by ChatGPT.
8
- - Validation of repaired JSON data against provided JSON Schemas using the [Ajv](https://ajv.js.org/) library.
9
- - Recursive repair attempts through internal calls to ChatGPT for particularly stubborn cases.
10
- - Detailed error handling and validation messages
11
- - Custom ValidationError class for understanding where the returned JSON fails to meet the schema.
12
-
13
- ## Installation
14
-
15
- This module is part of a larger project and is not designed to be installed standalone. However, you can copy the module into your own project and install the necessary dependencies via npm or yarn:
16
-
17
- ```bash
18
- npm install ajv
19
- ```
20
-
21
- ## Usage
22
-
23
- The primary function exported by this module takes two arguments: a text string to be parsed into JSON, and an optional schema object which describes the expected format of the JSON data.
24
-
25
- Here is an example of how to use the module:
26
- ```javascript
27
- import toObject from './path/to/module';
28
-
29
- const text = '...'; // JSON string returned from a ChatGPT call
30
- const schema = { ... }; // Optional JSON Schema
31
-
32
- try {
33
- const result = await toObject(text, schema);
34
- console.error(result); // Repaired and validated JSON
35
- } catch (error) {
36
- console.error(error); // Validation message if JSON doesn't meet the schema
37
- }
38
- ```
@@ -1,29 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
-
3
- import toObject from './index.js';
4
- import chatGPT from '../../lib/chatgpt/index.js';
5
- import { longTestTimeout } from '../../constants/common.js';
6
-
7
- const examples = [
8
- {
9
- inputs: { text: 'Describe SpaceX Starship' },
10
- want: { typeOfResult: 'object' },
11
- },
12
- ];
13
-
14
- describe('To object verblet', () => {
15
- examples.forEach((example) => {
16
- it(
17
- example.inputs.text,
18
- async () => {
19
- const chatGPTResult = await chatGPT(example.inputs.text);
20
- const result = await toObject(chatGPTResult);
21
-
22
- if (example.want.typeOfResult) {
23
- expect(typeof result).toStrictEqual(example.want.typeOfResult);
24
- }
25
- },
26
- longTestTimeout
27
- );
28
- });
29
- });
@@ -1,131 +0,0 @@
1
- import Ajv from 'ajv';
2
-
3
- import { debugToObject } from '../../constants/common.js';
4
- import { retryJSONParse } from '../../constants/messages.js';
5
- import chatGPT from '../../lib/chatgpt/index.js';
6
- import stripResponse from '../../lib/strip-response/index.js';
7
- import { constants as promptConstants, wrapVariable } from '../../prompts/index.js';
8
-
9
- const { contentIsSchema, contentToJSON, onlyJSON, shapeAsJSON } = promptConstants;
10
-
11
- class ValidationError extends Error {
12
- constructor(message, details) {
13
- super(message);
14
- this.name = 'ValidationError';
15
- this.details = details;
16
- }
17
- }
18
-
19
- const buildJsonPrompt = function (text, schema, errors) {
20
- let errorsDisplay = '';
21
- if (errors?.length) {
22
- errorsDisplay = wrapVariable(JSON.stringify(errors) ?? '', {
23
- tag: 'json-schema-errors--do-not-output',
24
- });
25
- }
26
-
27
- let schemaPart = '';
28
- if (schema) {
29
- schemaPart = `${contentIsSchema} ${wrapVariable(JSON.stringify(schema), {
30
- tag: 'json-schema--do-not-output',
31
- })}`;
32
- }
33
-
34
- return `${onlyJSON} ${shapeAsJSON}
35
-
36
- ${schemaPart}
37
-
38
- ${errorsDisplay}
39
-
40
- ${contentToJSON} ${wrapVariable(stripResponse(text), { tag: 'content' })}
41
-
42
- ${onlyJSON}`;
43
- };
44
-
45
- export default async (text, schema, config = {}) => {
46
- const { llm, ...options } = config;
47
- let prompt;
48
- let result;
49
- let response = text;
50
- let errorDetails;
51
-
52
- try {
53
- result = JSON.parse(stripResponse(response));
54
- if (schema) {
55
- const ajv = new Ajv();
56
- const validate = ajv.compile(schema);
57
- const isValid = validate(result);
58
-
59
- if (!isValid) {
60
- throw new ValidationError('Ajv validation failed', validate.errors);
61
- }
62
- return result;
63
- }
64
- return result;
65
- } catch (error) {
66
- errorDetails = error.details;
67
- if (debugToObject) {
68
- console.error(`Parse JSON [error]: ${error.message} ${retryJSONParse}`);
69
- console.error('<prompt attempt=1 value="unknown" />');
70
- console.error('<response>');
71
- console.error(stripResponse(response));
72
- console.error('</response>');
73
- console.error('<error>');
74
- console.error(error);
75
- console.error('</error>');
76
- }
77
- }
78
-
79
- try {
80
- prompt = buildJsonPrompt(response, schema, errorDetails);
81
- response = await chatGPT(prompt, {
82
- modelOptions: { modelName: 'fastGood', ...llm },
83
- ...options,
84
- });
85
- result = JSON.parse(stripResponse(response));
86
-
87
- if (schema) {
88
- const ajv = new Ajv();
89
- const validate = ajv.compile(schema);
90
- const isValid = validate(result);
91
-
92
- if (!isValid) {
93
- throw new ValidationError('Ajv validation failed', validate.errors);
94
- }
95
- return result;
96
- }
97
- } catch (error) {
98
- errorDetails = error.details;
99
- if (debugToObject) {
100
- console.error(`Parse JSON [error]: ${error.message} ${retryJSONParse}`);
101
- console.error('<prompt attempt=2>');
102
- console.error(prompt);
103
- console.error('</prompt>');
104
- console.error('<response>');
105
- console.error(stripResponse(response));
106
- console.error('</response>');
107
- console.error('<error>');
108
- console.error(error);
109
- console.error('</error>');
110
- }
111
-
112
- prompt = buildJsonPrompt(response, schema, errorDetails);
113
- response = await chatGPT(prompt, {
114
- modelOptions: { modelName: 'fastGood', ...llm },
115
- ...options,
116
- });
117
- result = JSON.parse(stripResponse(response));
118
-
119
- if (debugToObject) {
120
- console.error(`Parse JSON [error]: ${error.message} ${retryJSONParse}`);
121
- console.error('<prompt attempt=3>');
122
- console.error(prompt);
123
- console.error('</prompt>');
124
- console.error('<response>');
125
- console.error(stripResponse(response));
126
- console.error('</response>');
127
- }
128
- }
129
-
130
- return result;
131
- };
@@ -1,71 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
-
3
- import toObject from './index.js';
4
-
5
- vi.mock('../../lib/chatgpt/index.js', () => ({
6
- default: vi.fn().mockImplementation((text) => {
7
- if (/test/.test(text)) {
8
- return '{}';
9
- }
10
- if (/valid-schema/.test(text)) {
11
- return '{"key": "value"}';
12
- }
13
- if (/invalid-schema/.test(text)) {
14
- return '{"key": "value", "extra": "unexpected"}';
15
- }
16
- return 'undefined';
17
- }),
18
- }));
19
-
20
- const examples = [
21
- {
22
- name: 'Basic usage',
23
- inputs: { text: 'test' },
24
- want: { typeOfResult: 'object' },
25
- },
26
- {
27
- name: 'Valid schema',
28
- inputs: {
29
- text: 'valid-schema',
30
- schema: {
31
- type: 'object',
32
- properties: { key: { type: 'string' } },
33
- required: ['key'],
34
- },
35
- },
36
- want: { typeOfResult: 'object' },
37
- },
38
- {
39
- name: 'Invalid schema',
40
- inputs: {
41
- text: 'invalid-schema',
42
- schema: {
43
- type: 'object',
44
- properties: { key: { type: 'string' } },
45
- additionalProperties: false,
46
- required: ['key'],
47
- },
48
- },
49
- wantError: true,
50
- },
51
- ];
52
-
53
- describe('To object verblet', () => {
54
- examples.forEach((example) => {
55
- it(example.name, async () => {
56
- try {
57
- const result = await toObject(example.inputs.text, example.inputs.schema);
58
-
59
- if (example.want.typeOfResult) {
60
- expect(typeof result).toStrictEqual(example.want.typeOfResult);
61
- }
62
- } catch (error) {
63
- if (example.wantError) {
64
- expect(error).toBeInstanceOf(Error);
65
- } else {
66
- throw error;
67
- }
68
- }
69
- });
70
- });
71
- });