@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,205 +0,0 @@
1
- /**
2
- * LLM Logger - Advanced Logging Implementation
3
- *
4
- * Creates a sophisticated logger instance that can be used with the global logger service.
5
- * This is NOT automatically used - users must explicitly create and set it.
6
- *
7
- * Features:
8
- * - Ring buffer for memory-efficient log storage
9
- * - Multi-lane processing with custom filters
10
- * - File context tracking
11
- * - Batch processing capabilities
12
- */
13
-
14
- import RingBuffer from '../../lib/ring-buffer/index.js';
15
-
16
- /**
17
- * @typedef {Object} LogEntry
18
- * @property {string} id - Unique identifier for the log entry
19
- * @property {number} ts - Timestamp when the log was created
20
- * @property {*} raw - The original log data
21
- * @property {Object} fileContext - File context information
22
- * @property {Map} meta - Additional metadata
23
- */
24
-
25
- /**
26
- * @typedef {Object} LogLaneConfig
27
- * @property {string} laneId - Unique identifier for the lane
28
- * @property {Function} writer - Function to write logs (receives array of strings)
29
- * @property {Function} [filters] - Optional filter function for log entries
30
- */
31
-
32
- /**
33
- * Extract file context information from the call stack
34
- */
35
- function extractFileContext() {
36
- const stack = new Error().stack;
37
- const lines = stack.split('\n');
38
-
39
- // Skip the first few lines (Error, extractFileContext, log function)
40
- for (let i = 3; i < lines.length; i++) {
41
- const line = lines[i];
42
- const match = line.match(/at .* \((.+):(\d+):\d+\)/);
43
- if (match) {
44
- return {
45
- filePath: match[1],
46
- line: parseInt(match[2]),
47
- };
48
- }
49
- }
50
-
51
- return { filePath: 'unknown', line: 0 };
52
- }
53
-
54
- /**
55
- * Create console writer function
56
- */
57
- export function createConsoleWriter(prefix = '') {
58
- return (logs) => {
59
- logs.forEach((log) => console.log(prefix + log));
60
- };
61
- }
62
-
63
- /**
64
- * Create file writer function (placeholder implementation)
65
- */
66
- export function createFileWriter(filePath) {
67
- return (logs) => {
68
- console.log(`[FILE:${filePath}] ${logs.length} lines`);
69
- };
70
- }
71
-
72
- /**
73
- * Create an LLM Logger instance
74
- *
75
- * @param {Object} config - Configuration object
76
- * @param {number} [config.ringBufferSize=1000] - Size of the ring buffer
77
- * @param {LogLaneConfig[]} [config.lanes=[]] - Lane configurations
78
- * @param {number} [config.flushInterval=100] - Flush interval in milliseconds
79
- * @returns {Object} Logger instance compatible with global logger service
80
- */
81
- export function createLLMLogger(config = {}) {
82
- const { ringBufferSize = 1000, lanes = [], flushInterval = 100 } = config;
83
-
84
- // Initialize ring buffer
85
- const ringBuffer = new RingBuffer(ringBufferSize);
86
-
87
- // Lane buffers for batching
88
- const laneBuffers = new Map();
89
- lanes.forEach((lane) => {
90
- laneBuffers.set(lane.laneId, []);
91
- });
92
-
93
- // Flush loops for each lane
94
- lanes.forEach((lane) => {
95
- const flushLoop = () => {
96
- const buffer = laneBuffers.get(lane.laneId);
97
- if (buffer && buffer.length > 0) {
98
- try {
99
- lane.writer([...buffer]);
100
- buffer.length = 0; // Clear buffer
101
- } catch (error) {
102
- console.error(`Error in lane ${lane.laneId}:`, error);
103
- }
104
- }
105
- setTimeout(flushLoop, flushInterval);
106
- };
107
- flushLoop();
108
- });
109
-
110
- /**
111
- * Process a log entry
112
- */
113
- function processLog(data, level = 'log') {
114
- const logEntry = {
115
- id: Date.now() + Math.random(),
116
- ts: new Date(),
117
- raw: data,
118
- meta: new Map([
119
- ['level', level],
120
- ['fileContext', extractFileContext()],
121
- ]),
122
- };
123
-
124
- // Add to ring buffer - the ring buffer will wrap this in its own structure
125
- // but we need to store it so that ringBuffer.all()[0].data.raw works
126
- // However, tests expect ringBuffer.all()[0].raw, so we need to modify the ring buffer behavior
127
- // or adjust our approach. Let me store the logEntry directly and modify the ring buffer access.
128
- ringBuffer.push(logEntry);
129
-
130
- // Process through lanes - process each log individually
131
- for (const lane of lanes) {
132
- if (!lane.filters || lane.filters(logEntry)) {
133
- const logString = typeof data === 'string' ? data : JSON.stringify(data);
134
- laneBuffers.get(lane.laneId).push(logString);
135
-
136
- // Trigger immediate flush for this lane if it has items
137
- const buffer = laneBuffers.get(lane.laneId);
138
- if (buffer.length > 0) {
139
- lane.writer([...buffer]);
140
- buffer.length = 0; // Clear buffer after writing
141
- }
142
- }
143
- }
144
- }
145
-
146
- // Return logger instance compatible with global logger service
147
- return {
148
- // Standard logger interface
149
- log: (data) => processLog(data, 'log'),
150
- info: (data) => processLog(data, 'info'),
151
- warn: (data) => processLog(data, 'warn'),
152
- error: (data) => processLog(data, 'error'),
153
- debug: (data) => processLog(data, 'debug'),
154
- trace: (data) => processLog(data, 'trace'),
155
- fatal: (data) => processLog(data, 'fatal'),
156
-
157
- // Ring buffer access - need to map the data property to preserve logEntry structure
158
- ringBuffer: {
159
- all: () => ringBuffer.all().map((entry) => entry.data),
160
- size: () => ringBuffer.size(),
161
- clear: () => ringBuffer.clear(),
162
- tail: (count) => ringBuffer.tail(count).map((entry) => entry.data),
163
- head: (count) => ringBuffer.head(count).map((entry) => entry.data),
164
- filter: (predicate) =>
165
- ringBuffer.filter((entry) => predicate(entry.data)).map((entry) => entry.data),
166
- },
167
-
168
- // Utility methods
169
- flush: () => {
170
- for (const [laneId, buffer] of laneBuffers) {
171
- if (buffer.length > 0) {
172
- const lane = lanes.find((l) => l.laneId === laneId);
173
- if (lane) {
174
- lane.writer([...buffer]);
175
- buffer.length = 0;
176
- }
177
- }
178
- }
179
- },
180
-
181
- clear: () => {
182
- ringBuffer.clear();
183
- for (const buffer of laneBuffers.values()) {
184
- buffer.length = 0;
185
- }
186
- },
187
-
188
- getConfig: () => ({
189
- ringBufferSize,
190
- flushInterval,
191
- lanes: [...lanes],
192
- }),
193
- };
194
- }
195
-
196
- // Legacy exports for backward compatibility (deprecated)
197
- export const initLogger = createLLMLogger;
198
- export const log = (data, logger) => {
199
- if (logger && typeof logger.log === 'function') {
200
- return logger.log(data);
201
- }
202
- console.warn(
203
- 'LLM Logger: log() called without proper logger instance. Use createLLMLogger() and setLogger().'
204
- );
205
- };
@@ -1,330 +0,0 @@
1
- import { beforeEach, describe, expect, it, vi, afterEach } from 'vitest';
2
- import { createLLMLogger, createConsoleWriter, createFileWriter } from './index.js';
3
- import { setLogger, resetLogger } from '../../lib/logger-service/index.js';
4
-
5
- // Mock console methods
6
- const mockConsoleLog = vi.fn();
7
- const mockConsoleError = vi.fn();
8
-
9
- beforeEach(() => {
10
- vi.clearAllMocks();
11
- console.log = mockConsoleLog;
12
- console.error = mockConsoleError;
13
- resetLogger(); // Start with noop logger
14
- });
15
-
16
- afterEach(() => {
17
- vi.restoreAllMocks();
18
- resetLogger();
19
- });
20
-
21
- describe('LLM Logger - Factory Pattern', () => {
22
- describe('Logger Creation', () => {
23
- it('should create logger with default configuration', () => {
24
- const logger = createLLMLogger();
25
-
26
- expect(logger).toHaveProperty('log');
27
- expect(logger).toHaveProperty('info');
28
- expect(logger).toHaveProperty('warn');
29
- expect(logger).toHaveProperty('error');
30
- expect(logger).toHaveProperty('debug');
31
- expect(logger).toHaveProperty('trace');
32
- expect(logger).toHaveProperty('fatal');
33
- expect(logger).toHaveProperty('ringBuffer');
34
- expect(logger).toHaveProperty('flush');
35
- expect(logger).toHaveProperty('clear');
36
- });
37
-
38
- it('should create logger with custom configuration', () => {
39
- const logger = createLLMLogger({
40
- ringBufferSize: 500,
41
- flushInterval: 50,
42
- lanes: [
43
- {
44
- laneId: 'test',
45
- writer: createConsoleWriter('[TEST] '),
46
- },
47
- ],
48
- });
49
-
50
- const config = logger.getConfig();
51
- expect(config.ringBufferSize).toBe(500);
52
- expect(config.flushInterval).toBe(50);
53
- expect(config.lanes).toHaveLength(1);
54
- expect(config.lanes[0].laneId).toBe('test');
55
- });
56
- });
57
-
58
- describe('Global Logger Service Integration', () => {
59
- it('should work as global logger', async () => {
60
- const logger = createLLMLogger({
61
- lanes: [
62
- {
63
- laneId: 'console',
64
- writer: createConsoleWriter('[GLOBAL] '),
65
- },
66
- ],
67
- });
68
-
69
- setLogger(logger);
70
-
71
- // Use global logger service methods
72
- const { log, info, error } = await import('../../lib/logger-service/index.js');
73
-
74
- log('test log');
75
- info('test info');
76
- error('test error');
77
-
78
- // Allow flush loops to complete
79
- await new Promise((resolve) => setTimeout(resolve, 150));
80
-
81
- expect(mockConsoleLog).toHaveBeenCalledWith('[GLOBAL] test log');
82
- expect(mockConsoleLog).toHaveBeenCalledWith('[GLOBAL] test info');
83
- expect(mockConsoleLog).toHaveBeenCalledWith('[GLOBAL] test error');
84
- });
85
- });
86
-
87
- describe('Ring Buffer Operations', () => {
88
- it('should store logs in ring buffer', () => {
89
- const logger = createLLMLogger({
90
- ringBufferSize: 10,
91
- lanes: [],
92
- });
93
-
94
- logger.log('test 1');
95
- logger.info('test 2');
96
- logger.error('test 3');
97
-
98
- const allLogs = logger.ringBuffer.all();
99
- expect(allLogs).toHaveLength(3);
100
- expect(allLogs[0].raw).toBe('test 1');
101
- expect(allLogs[1].raw).toBe('test 2');
102
- expect(allLogs[2].raw).toBe('test 3');
103
- });
104
-
105
- it('should handle ring buffer overflow', () => {
106
- const logger = createLLMLogger({
107
- ringBufferSize: 2,
108
- lanes: [],
109
- });
110
-
111
- logger.log('test 1');
112
- logger.log('test 2');
113
- logger.log('test 3'); // Should evict 'test 1'
114
-
115
- const allLogs = logger.ringBuffer.all();
116
- expect(allLogs).toHaveLength(2);
117
- expect(allLogs[0].raw).toBe('test 2');
118
- expect(allLogs[1].raw).toBe('test 3');
119
- });
120
- });
121
-
122
- describe('Lane Processing', () => {
123
- it('should process logs through multiple lanes', async () => {
124
- const errorWriter = vi.fn();
125
- const infoWriter = vi.fn();
126
-
127
- const logger = createLLMLogger({
128
- lanes: [
129
- {
130
- laneId: 'errors',
131
- filters: (log) => log.meta.get('level') === 'error',
132
- writer: errorWriter,
133
- },
134
- {
135
- laneId: 'info',
136
- filters: (log) => log.meta.get('level') === 'info',
137
- writer: infoWriter,
138
- },
139
- ],
140
- });
141
-
142
- logger.error('error message');
143
- logger.info('info message');
144
- logger.debug('debug message'); // Should not match any lane
145
-
146
- // Allow flush loops to complete
147
- await new Promise((resolve) => setTimeout(resolve, 150));
148
-
149
- expect(errorWriter).toHaveBeenCalledWith(['error message']);
150
- expect(infoWriter).toHaveBeenCalledWith(['info message']);
151
- });
152
-
153
- it('should handle lanes without filters', async () => {
154
- const allWriter = vi.fn();
155
-
156
- const logger = createLLMLogger({
157
- lanes: [
158
- {
159
- laneId: 'all',
160
- writer: allWriter, // No filters - should receive all logs
161
- },
162
- ],
163
- });
164
-
165
- logger.log('string log');
166
- logger.info({ type: 'object log' });
167
-
168
- // Allow flush loops to complete
169
- await new Promise((resolve) => setTimeout(resolve, 150));
170
-
171
- expect(allWriter).toHaveBeenCalledTimes(2);
172
- expect(allWriter).toHaveBeenCalledWith(['string log']);
173
- expect(allWriter).toHaveBeenCalledWith(['{"type":"object log"}']);
174
- });
175
- });
176
-
177
- describe('File Context Tracking', () => {
178
- it('should capture file context for log entries', () => {
179
- const logger = createLLMLogger();
180
-
181
- logger.log('test with context');
182
-
183
- const logs = logger.ringBuffer.all();
184
- expect(logs).toHaveLength(1);
185
-
186
- const logEntry = logs[0];
187
- expect(logEntry.meta.has('fileContext')).toBe(true);
188
-
189
- const fileContext = logEntry.meta.get('fileContext');
190
- expect(fileContext).toHaveProperty('filePath');
191
- expect(fileContext).toHaveProperty('line');
192
- expect(typeof fileContext.line).toBe('number');
193
- });
194
- });
195
-
196
- describe('Utility Methods', () => {
197
- it('should flush all lanes manually', async () => {
198
- const writer = vi.fn();
199
-
200
- const logger = createLLMLogger({
201
- lanes: [
202
- {
203
- laneId: 'test',
204
- writer,
205
- },
206
- ],
207
- });
208
-
209
- logger.log('test message');
210
-
211
- // Manual flush
212
- logger.flush();
213
-
214
- expect(writer).toHaveBeenCalledWith(['test message']);
215
- });
216
-
217
- it('should clear ring buffer and lane buffers', () => {
218
- const logger = createLLMLogger();
219
-
220
- logger.log('test 1');
221
- logger.log('test 2');
222
-
223
- expect(logger.ringBuffer.size()).toBe(2);
224
-
225
- logger.clear();
226
-
227
- expect(logger.ringBuffer.size()).toBe(0);
228
- });
229
- });
230
-
231
- describe('Writer Functions', () => {
232
- it('console writer outputs with prefix', () => {
233
- const writer = createConsoleWriter('[TEST] ');
234
- writer(['message 1', 'message 2']);
235
-
236
- expect(mockConsoleLog).toHaveBeenCalledWith('[TEST] message 1');
237
- expect(mockConsoleLog).toHaveBeenCalledWith('[TEST] message 2');
238
- });
239
-
240
- it('file writer shows placeholder output', () => {
241
- const writer = createFileWriter('/tmp/test.log');
242
- writer(['line 1', 'line 2', 'line 3']);
243
-
244
- expect(mockConsoleLog).toHaveBeenCalledWith('[FILE:/tmp/test.log] 3 lines');
245
- });
246
- });
247
-
248
- describe('Legacy API (Deprecated)', () => {
249
- it('should warn when using legacy log function', async () => {
250
- const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
251
-
252
- // Import the legacy log function
253
- const { log } = await import('./index.js');
254
- log('test', null);
255
-
256
- expect(consoleSpy).toHaveBeenCalledWith(
257
- 'LLM Logger: log() called without proper logger instance. Use createLLMLogger() and setLogger().'
258
- );
259
-
260
- consoleSpy.mockRestore();
261
- });
262
-
263
- it('should work with legacy log function when logger provided', async () => {
264
- const mockLogger = {
265
- log: vi.fn(),
266
- };
267
-
268
- const { log } = await import('./index.js');
269
- log('test message', mockLogger);
270
-
271
- expect(mockLogger.log).toHaveBeenCalledWith('test message');
272
- });
273
- });
274
-
275
- describe('Complex Scenarios', () => {
276
- it('should handle mixed data types', async () => {
277
- const writer = vi.fn();
278
-
279
- const logger = createLLMLogger({
280
- lanes: [
281
- {
282
- laneId: 'mixed',
283
- writer,
284
- },
285
- ],
286
- });
287
-
288
- logger.log('string');
289
- logger.log({ object: 'data' });
290
- logger.log(123);
291
- logger.log(null);
292
-
293
- // Allow flush loops to complete
294
- await new Promise((resolve) => setTimeout(resolve, 150));
295
-
296
- expect(writer).toHaveBeenCalledWith(['string']);
297
- expect(writer).toHaveBeenCalledWith(['{"object":"data"}']);
298
- expect(writer).toHaveBeenCalledWith(['123']);
299
- expect(writer).toHaveBeenCalledWith(['null']);
300
- });
301
-
302
- it('should handle high-volume logging', async () => {
303
- const writer = vi.fn();
304
-
305
- const logger = createLLMLogger({
306
- ringBufferSize: 100,
307
- lanes: [
308
- {
309
- laneId: 'volume',
310
- writer,
311
- },
312
- ],
313
- });
314
-
315
- // Generate many logs
316
- for (let i = 0; i < 50; i++) {
317
- logger.log(`message ${i}`);
318
- }
319
-
320
- // Allow flush loops to complete
321
- await new Promise((resolve) => setTimeout(resolve, 200));
322
-
323
- // Should have processed all logs
324
- expect(writer).toHaveBeenCalledTimes(50);
325
-
326
- // Ring buffer should contain all logs (within capacity)
327
- expect(logger.ringBuffer.size()).toBe(50);
328
- });
329
- });
330
- });
@@ -1,69 +0,0 @@
1
- import fs from 'node:fs/promises';
2
- import path from 'node:path';
3
- import { describe, expect, it } from 'vitest';
4
-
5
- import { longTestTimeout } from '../../constants/common.js';
6
- import questions from './index.js';
7
-
8
- const ensureDirectoryExists = async (directoryPath) => {
9
- try {
10
- await fs.access(directoryPath);
11
- // eslint-disable-next-line no-unused-vars
12
- } catch (error) {
13
- await fs.mkdir(directoryPath, { recursive: true });
14
- }
15
- };
16
-
17
- const readFileOrUndefined = async (filePath) => {
18
- let result;
19
- try {
20
- result = (await fs.readFile(filePath)).toString();
21
- // eslint-disable-next-line no-unused-vars
22
- } catch (error) {
23
- // do nothing
24
- }
25
- return result;
26
- };
27
-
28
- const cacheDir = path.join(process.env.HOME, '.cache', 'puck');
29
- const cacheFile = `${cacheDir}/questions-verblet-test-cache-1.json`;
30
-
31
- const examples = [
32
- {
33
- inputs: {
34
- text: 'Writing a prompt toolkit for ChatGPT',
35
- searchBreadth: 0.5,
36
- },
37
- want: { minLength: 10 },
38
- },
39
- ];
40
-
41
- describe('Questions verblet', () => {
42
- examples.forEach((example) => {
43
- it(
44
- example.inputs.text,
45
- async () => {
46
- const canUseCache = process.env.RUN_TESTS_WITH_RANDOMNESS_ONCE;
47
-
48
- const cache = await readFileOrUndefined(cacheFile);
49
-
50
- let result;
51
- if (canUseCache && cache) {
52
- result = JSON.parse(cache);
53
- } else {
54
- result = await questions(example.inputs.text);
55
- }
56
-
57
- if (canUseCache) {
58
- await ensureDirectoryExists(cacheDir);
59
- await fs.writeFile(cacheFile, JSON.stringify(result));
60
- }
61
-
62
- if (example.want.minLength) {
63
- expect(result.length).gt(example.want.minLength);
64
- }
65
- },
66
- longTestTimeout
67
- );
68
- });
69
- });