@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.
- package/README.md +86 -213
- package/dist/index.browser.js +74 -0
- package/dist/index.js +548 -0
- package/dist/shared-C6kPWghF.js +7806 -0
- package/package.json +32 -8
- package/.cursor/launch.json +0 -30
- package/.cursor/settings.json +0 -20
- package/.github/workflows/branch-protection.yml +0 -22
- package/.github/workflows/ci.yml +0 -165
- package/.husky/pre-commit +0 -4
- package/.prettierrc +0 -6
- package/.release-it.json +0 -12
- package/.vitest.config.examples.js +0 -8
- package/.vitest.config.js +0 -8
- package/.vscode/launch.json +0 -31
- package/AGENTS.md +0 -220
- package/DEVELOPING.md +0 -105
- package/docker-compose.yml +0 -7
- package/eslint.config.js +0 -80
- package/scripts/generate-chain/index.js +0 -111
- package/scripts/generate-lib/index.js +0 -68
- package/scripts/generate-test/index.js +0 -137
- package/scripts/generate-verblet/README.md +0 -17
- package/scripts/generate-verblet/index.js +0 -110
- package/scripts/run.sh +0 -15
- package/scripts/runner/index.js +0 -56
- package/scripts/simple-editor/README.md +0 -34
- package/scripts/simple-editor/index.js +0 -79
- package/scripts/summarize-files/index.js +0 -70
- package/src/chains/README.md +0 -30
- package/src/chains/anonymize/README.md +0 -21
- package/src/chains/anonymize/index.examples.js +0 -75
- package/src/chains/anonymize/index.js +0 -121
- package/src/chains/anonymize/index.spec.js +0 -78
- package/src/chains/bulk-central-tendency/index.examples.js +0 -138
- package/src/chains/bulk-central-tendency/index.js +0 -91
- package/src/chains/bulk-filter/README.md +0 -21
- package/src/chains/bulk-filter/index.examples.js +0 -22
- package/src/chains/bulk-filter/index.js +0 -58
- package/src/chains/bulk-filter/index.spec.js +0 -38
- package/src/chains/bulk-find/README.md +0 -16
- package/src/chains/bulk-find/index.examples.js +0 -20
- package/src/chains/bulk-find/index.js +0 -30
- package/src/chains/bulk-find/index.spec.js +0 -26
- package/src/chains/bulk-group/README.md +0 -23
- package/src/chains/bulk-group/index.examples.js +0 -18
- package/src/chains/bulk-group/index.js +0 -34
- package/src/chains/bulk-group/index.spec.js +0 -41
- package/src/chains/bulk-map/README.md +0 -43
- package/src/chains/bulk-map/index.examples.js +0 -17
- package/src/chains/bulk-map/index.js +0 -86
- package/src/chains/bulk-map/index.spec.js +0 -44
- package/src/chains/bulk-reduce/README.md +0 -12
- package/src/chains/bulk-reduce/index.examples.js +0 -15
- package/src/chains/bulk-reduce/index.js +0 -13
- package/src/chains/bulk-reduce/index.spec.js +0 -25
- package/src/chains/bulk-score/README.md +0 -16
- package/src/chains/bulk-score/bulk-score-result.json +0 -18
- package/src/chains/bulk-score/index.examples.js +0 -22
- package/src/chains/bulk-score/index.js +0 -133
- package/src/chains/bulk-score/index.spec.js +0 -30
- package/src/chains/category-samples/README.md +0 -61
- package/src/chains/category-samples/index.examples.js +0 -103
- package/src/chains/category-samples/index.js +0 -134
- package/src/chains/collect-terms/README.md +0 -12
- package/src/chains/collect-terms/index.examples.js +0 -16
- package/src/chains/collect-terms/index.js +0 -44
- package/src/chains/collect-terms/index.spec.js +0 -25
- package/src/chains/date/README.md +0 -12
- package/src/chains/date/index.examples.js +0 -47
- package/src/chains/date/index.js +0 -74
- package/src/chains/date/index.spec.js +0 -62
- package/src/chains/disambiguate/README.md +0 -22
- package/src/chains/disambiguate/disambiguate-meanings-result.json +0 -16
- package/src/chains/disambiguate/index.examples.js +0 -18
- package/src/chains/disambiguate/index.js +0 -92
- package/src/chains/disambiguate/index.spec.js +0 -25
- package/src/chains/dismantle/README.md +0 -67
- package/src/chains/dismantle/dismantle.examples.js +0 -27
- package/src/chains/dismantle/index.examples.js +0 -30
- package/src/chains/dismantle/index.js +0 -303
- package/src/chains/dismantle/index.spec.js +0 -32
- package/src/chains/expect/README.md +0 -171
- package/src/chains/expect/index.examples.js +0 -146
- package/src/chains/expect/index.js +0 -173
- package/src/chains/expect/index.spec.js +0 -324
- package/src/chains/filter-ambiguous/README.md +0 -11
- package/src/chains/filter-ambiguous/index.examples.js +0 -20
- package/src/chains/filter-ambiguous/index.js +0 -49
- package/src/chains/filter-ambiguous/index.spec.js +0 -31
- package/src/chains/glossary/README.md +0 -19
- package/src/chains/glossary/index.examples.js +0 -386
- package/src/chains/glossary/index.js +0 -75
- package/src/chains/glossary/index.spec.js +0 -19
- package/src/chains/intersections/README.md +0 -152
- package/src/chains/intersections/index.examples.js +0 -279
- package/src/chains/intersections/index.js +0 -366
- package/src/chains/intersections/intersection-result.json +0 -38
- package/src/chains/list/index.examples.js +0 -68
- package/src/chains/list/index.js +0 -214
- package/src/chains/list/index.spec.js +0 -67
- package/src/chains/list/list-result.json +0 -16
- package/src/chains/list/schema.json +0 -24
- package/src/chains/llm-logger/README.md +0 -208
- package/src/chains/llm-logger/index.js +0 -205
- package/src/chains/llm-logger/index.spec.js +0 -330
- package/src/chains/questions/index.examples.js +0 -69
- package/src/chains/questions/index.js +0 -135
- package/src/chains/questions/index.spec.js +0 -29
- package/src/chains/scan-js/index.js +0 -116
- package/src/chains/set-interval/README.md +0 -81
- package/src/chains/set-interval/index.examples.js +0 -36
- package/src/chains/set-interval/index.js +0 -131
- package/src/chains/set-interval/index.spec.js +0 -70
- package/src/chains/socratic/README.md +0 -17
- package/src/chains/socratic/index.js +0 -64
- package/src/chains/socratic/index.spec.js +0 -24
- package/src/chains/sort/index.examples.js +0 -36
- package/src/chains/sort/index.js +0 -163
- package/src/chains/sort/index.spec.js +0 -112
- package/src/chains/sort/sort-result.json +0 -16
- package/src/chains/summary-map/README.md +0 -41
- package/src/chains/summary-map/index.examples.js +0 -64
- package/src/chains/summary-map/index.js +0 -226
- package/src/chains/summary-map/index.spec.js +0 -153
- package/src/chains/test/index.js +0 -114
- package/src/chains/test-advice/index.js +0 -35
- package/src/chains/themes/README.md +0 -20
- package/src/chains/themes/index.examples.js +0 -17
- package/src/chains/themes/index.js +0 -28
- package/src/chains/themes/index.spec.js +0 -19
- package/src/chains/veiled-variants/index.examples.js +0 -18
- package/src/chains/veiled-variants/index.js +0 -107
- package/src/chains/veiled-variants/index.spec.js +0 -40
- package/src/constants/common.js +0 -7
- package/src/constants/messages.js +0 -3
- package/src/constants/models.js +0 -183
- package/src/index.js +0 -193
- package/src/json-schemas/README.md +0 -13
- package/src/json-schemas/cars-test.json +0 -11
- package/src/json-schemas/index.js +0 -12
- package/src/json-schemas/intent.json +0 -38
- package/src/json-schemas/schema-dot-org-photograph.json +0 -133
- package/src/json-schemas/schema-dot-org-place.json +0 -129
- package/src/lib/README.md +0 -26
- package/src/lib/any-signal/index.js +0 -28
- package/src/lib/bulk-filter/README.md +0 -22
- package/src/lib/bulk-filter/index.examples.js +0 -27
- package/src/lib/bulk-filter/index.js +0 -63
- package/src/lib/bulk-filter/index.spec.js +0 -38
- package/src/lib/bulk-find/README.md +0 -18
- package/src/lib/bulk-find/index.examples.js +0 -19
- package/src/lib/bulk-find/index.js +0 -30
- package/src/lib/bulk-find/index.spec.js +0 -41
- package/src/lib/chatgpt/index.js +0 -163
- package/src/lib/combinations/index.js +0 -30
- package/src/lib/combinations/index.spec.js +0 -23
- package/src/lib/editor/index.js +0 -31
- package/src/lib/functional/index.js +0 -28
- package/src/lib/logger-service/index.js +0 -32
- package/src/lib/parse-js-parts/index.js +0 -321
- package/src/lib/parse-js-parts/index.spec.js +0 -156
- package/src/lib/parse-llm-list/README.md +0 -39
- package/src/lib/parse-llm-list/index.js +0 -54
- package/src/lib/parse-llm-list/index.spec.js +0 -59
- package/src/lib/path-aliases/index.js +0 -37
- package/src/lib/path-aliases/index.spec.js +0 -64
- package/src/lib/pave/index.js +0 -34
- package/src/lib/pave/index.spec.js +0 -76
- package/src/lib/prompt-cache/index.js +0 -50
- package/src/lib/retry/index.js +0 -66
- package/src/lib/retry/index.spec.js +0 -86
- package/src/lib/ring-buffer/README.md +0 -460
- package/src/lib/ring-buffer/index.js +0 -1074
- package/src/lib/search-best-first/city-walk.spec.js +0 -37
- package/src/lib/search-best-first/index.js +0 -97
- package/src/lib/search-best-first/index.spec.js +0 -35
- package/src/lib/search-js-files/code-features-property-definitions.json +0 -123
- package/src/lib/search-js-files/index.examples.js +0 -22
- package/src/lib/search-js-files/index.js +0 -155
- package/src/lib/search-js-files/index.spec.js +0 -34
- package/src/lib/search-js-files/scan-file.js +0 -242
- package/src/lib/shorten-text/index.js +0 -25
- package/src/lib/shorten-text/index.spec.js +0 -68
- package/src/lib/strip-numeric/index.js +0 -5
- package/src/lib/strip-response/index.js +0 -30
- package/src/lib/template-replace/index.js +0 -23
- package/src/lib/template-replace/index.spec.js +0 -60
- package/src/lib/timed-abort-controller/index.js +0 -41
- package/src/lib/to-bool/index.js +0 -8
- package/src/lib/to-date/index.js +0 -11
- package/src/lib/to-enum/index.js +0 -14
- package/src/lib/to-number/index.js +0 -12
- package/src/lib/to-number-with-units/index.js +0 -51
- package/src/lib/transcribe/index.js +0 -78
- package/src/prompts/README.md +0 -17
- package/src/prompts/as-enum.js +0 -5
- package/src/prompts/as-json-schema.js +0 -9
- package/src/prompts/as-object-with-schema.js +0 -26
- package/src/prompts/as-schema-org-text.js +0 -25
- package/src/prompts/as-schema-org-type.js +0 -1
- package/src/prompts/blog-post.js +0 -7
- package/src/prompts/code-features.js +0 -24
- package/src/prompts/constants.js +0 -101
- package/src/prompts/features-json-schema.js +0 -27
- package/src/prompts/generate-collection.js +0 -26
- package/src/prompts/generate-list.js +0 -48
- package/src/prompts/generate-questions.js +0 -19
- package/src/prompts/index.js +0 -20
- package/src/prompts/intent.js +0 -60
- package/src/prompts/output-succinct-names.js +0 -3
- package/src/prompts/select-from-threshold.js +0 -17
- package/src/prompts/sort.js +0 -31
- package/src/prompts/style.js +0 -38
- package/src/prompts/summarize.js +0 -13
- package/src/prompts/token-budget.js +0 -3
- package/src/prompts/wrap-list.js +0 -11
- package/src/prompts/wrap-variable.js +0 -36
- package/src/services/llm-model/global-overrides.spec.js +0 -432
- package/src/services/llm-model/index.js +0 -308
- package/src/services/llm-model/model.js +0 -21
- package/src/services/llm-model/negotiate.spec.js +0 -447
- package/src/services/redis/index.js +0 -147
- package/src/test/setup.js +0 -20
- package/src/verblets/README.md +0 -26
- package/src/verblets/auto/index.examples.js +0 -31
- package/src/verblets/auto/index.js +0 -28
- package/src/verblets/auto/index.spec.js +0 -32
- package/src/verblets/bool/README.md +0 -36
- package/src/verblets/bool/index.examples.js +0 -80
- package/src/verblets/bool/index.js +0 -25
- package/src/verblets/bool/index.schema.json +0 -14
- package/src/verblets/bool/index.spec.js +0 -33
- package/src/verblets/central-tendency/README.md +0 -166
- package/src/verblets/central-tendency/central-tendency-result.json +0 -24
- package/src/verblets/central-tendency/index.examples.js +0 -196
- package/src/verblets/central-tendency/index.js +0 -171
- package/src/verblets/central-tendency/index.spec.js +0 -148
- package/src/verblets/enum/index.examples.js +0 -30
- package/src/verblets/enum/index.js +0 -18
- package/src/verblets/enum/index.spec.js +0 -35
- package/src/verblets/expect/README.md +0 -64
- package/src/verblets/expect/index.examples.js +0 -109
- package/src/verblets/expect/index.js +0 -75
- package/src/verblets/expect/index.spec.js +0 -127
- package/src/verblets/intent/index.examples.js +0 -139
- package/src/verblets/intent/index.js +0 -60
- package/src/verblets/intent/index.spec.js +0 -31
- package/src/verblets/intersection/README.md +0 -16
- package/src/verblets/intersection/index.examples.js +0 -89
- package/src/verblets/intersection/index.js +0 -84
- package/src/verblets/intersection/index.spec.js +0 -60
- package/src/verblets/intersection/intersection-result.json +0 -16
- package/src/verblets/list-expand/README.md +0 -10
- package/src/verblets/list-expand/index.examples.js +0 -14
- package/src/verblets/list-expand/index.js +0 -104
- package/src/verblets/list-expand/index.spec.js +0 -18
- package/src/verblets/list-expand/list-expand-result.json +0 -16
- package/src/verblets/list-filter/README.md +0 -22
- package/src/verblets/list-filter/index.examples.js +0 -26
- package/src/verblets/list-filter/index.js +0 -18
- package/src/verblets/list-filter/index.spec.js +0 -19
- package/src/verblets/list-find/README.md +0 -11
- package/src/verblets/list-find/index.examples.js +0 -15
- package/src/verblets/list-find/index.js +0 -17
- package/src/verblets/list-find/index.spec.js +0 -19
- package/src/verblets/list-group/README.md +0 -16
- package/src/verblets/list-group/index.examples.js +0 -16
- package/src/verblets/list-group/index.js +0 -112
- package/src/verblets/list-group/index.spec.js +0 -35
- package/src/verblets/list-group/list-group-result.json +0 -16
- package/src/verblets/list-map/README.md +0 -11
- package/src/verblets/list-map/index.examples.js +0 -15
- package/src/verblets/list-map/index.js +0 -26
- package/src/verblets/list-map/index.spec.js +0 -17
- package/src/verblets/list-reduce/README.md +0 -10
- package/src/verblets/list-reduce/index.examples.js +0 -14
- package/src/verblets/list-reduce/index.js +0 -21
- package/src/verblets/list-reduce/index.spec.js +0 -27
- package/src/verblets/list-reduce/index.spec.jsx +0 -27
- package/src/verblets/name/README.md +0 -15
- package/src/verblets/name/index.examples.js +0 -28
- package/src/verblets/name/index.js +0 -19
- package/src/verblets/name/index.spec.js +0 -33
- package/src/verblets/name-similar-to/README.md +0 -26
- package/src/verblets/name-similar-to/index.examples.js +0 -18
- package/src/verblets/name-similar-to/index.js +0 -20
- package/src/verblets/name-similar-to/index.spec.js +0 -13
- package/src/verblets/number/index.examples.js +0 -199
- package/src/verblets/number/index.js +0 -25
- package/src/verblets/number/index.spec.js +0 -33
- package/src/verblets/number-with-units/index.examples.js +0 -38
- package/src/verblets/number-with-units/index.js +0 -84
- package/src/verblets/number-with-units/index.spec.js +0 -46
- package/src/verblets/number-with-units/number-with-units-result.json +0 -23
- package/src/verblets/schema-org/index.examples.js +0 -51
- package/src/verblets/schema-org/index.js +0 -37
- package/src/verblets/schema-org/index.spec.js +0 -39
- package/src/verblets/sentiment/README.md +0 -10
- package/src/verblets/sentiment/index.examples.js +0 -20
- package/src/verblets/sentiment/index.js +0 -9
- package/src/verblets/sentiment/index.spec.js +0 -20
- package/src/verblets/to-object/README.md +0 -38
- package/src/verblets/to-object/index.examples.js +0 -29
- package/src/verblets/to-object/index.js +0 -131
- 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
|
-
});
|