@far-world-labs/verblets 0.2.0 → 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 -11
- 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 -12
- 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/clear-redis.js +0 -74
- 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/conversation/README.md +0 -26
- package/src/chains/conversation/index.examples.js +0 -398
- package/src/chains/conversation/index.js +0 -126
- package/src/chains/conversation/index.spec.js +0 -148
- package/src/chains/conversation/turn-policies.js +0 -93
- package/src/chains/conversation/turn-policies.md +0 -123
- package/src/chains/conversation/turn-policies.spec.js +0 -135
- 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 -207
- 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 -166
- package/src/chains/intersections/index.examples.js +0 -280
- package/src/chains/intersections/index.js +0 -218
- 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 -366
- package/src/chains/llm-logger/index.js +0 -591
- package/src/chains/llm-logger/index.spec.js +0 -391
- package/src/chains/llm-logger/schema.json +0 -105
- 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 -64
- package/src/chains/set-interval/index.js +0 -152
- 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 -13
- package/src/constants/messages.js +0 -3
- package/src/constants/models.js +0 -184
- package/src/index.js +0 -203
- 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/assert/README.md +0 -84
- package/src/lib/assert/index.js +0 -50
- 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 -82
- package/src/lib/ring-buffer/index.js +0 -235
- package/src/lib/ring-buffer/index.spec.js +0 -388
- 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/conversation-turn/README.md +0 -33
- package/src/verblets/conversation-turn/index.examples.js +0 -218
- package/src/verblets/conversation-turn/index.js +0 -68
- package/src/verblets/conversation-turn/index.spec.js +0 -77
- package/src/verblets/conversation-turn-multi/README.md +0 -31
- package/src/verblets/conversation-turn-multi/index.examples.js +0 -160
- package/src/verblets/conversation-turn-multi/index.js +0 -104
- package/src/verblets/conversation-turn-multi/index.spec.js +0 -63
- 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 -125
- 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/people-list/README.md +0 -28
- package/src/verblets/people-list/index.examples.js +0 -184
- package/src/verblets/people-list/index.js +0 -44
- package/src/verblets/people-list/index.spec.js +0 -49
- 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
package/src/chains/list/index.js
DELETED
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import { operationTimeoutMultiplier } from '../../constants/models.js';
|
|
5
|
-
import chatGPT from '../../lib/chatgpt/index.js';
|
|
6
|
-
import {
|
|
7
|
-
asObjectWithSchema as asObjectWithSchemaPrompt,
|
|
8
|
-
generateList as generateListPrompt,
|
|
9
|
-
constants as promptConstants,
|
|
10
|
-
} from '../../prompts/index.js';
|
|
11
|
-
import modelService from '../../services/llm-model/index.js';
|
|
12
|
-
|
|
13
|
-
const { onlyJSON, contentIsTransformationSource, onlyJSONArray } = promptConstants;
|
|
14
|
-
|
|
15
|
-
// Get the directory of this module
|
|
16
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
-
const __dirname = path.dirname(__filename);
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Load the JSON schema for list results
|
|
21
|
-
* @returns {Promise<Object>} JSON schema for validation
|
|
22
|
-
*/
|
|
23
|
-
async function getListSchema() {
|
|
24
|
-
const schemaPath = path.join(__dirname, 'list-result.json');
|
|
25
|
-
return JSON.parse(await fs.readFile(schemaPath, 'utf8'));
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Create model options for structured outputs
|
|
30
|
-
* @param {string|Object} llm - LLM model name or configuration object
|
|
31
|
-
* @returns {Promise<Object>} Model options for chatGPT
|
|
32
|
-
*/
|
|
33
|
-
async function createModelOptions(llm = 'fastGoodCheap') {
|
|
34
|
-
const schema = await getListSchema();
|
|
35
|
-
|
|
36
|
-
const responseFormat = {
|
|
37
|
-
type: 'json_schema',
|
|
38
|
-
json_schema: {
|
|
39
|
-
name: 'list_result',
|
|
40
|
-
schema,
|
|
41
|
-
},
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
if (typeof llm === 'string') {
|
|
45
|
-
return {
|
|
46
|
-
modelName: llm,
|
|
47
|
-
response_format: responseFormat,
|
|
48
|
-
};
|
|
49
|
-
} else {
|
|
50
|
-
return {
|
|
51
|
-
...llm,
|
|
52
|
-
response_format: responseFormat,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const outputTransformPrompt = (result, schema) => {
|
|
58
|
-
return `${contentIsTransformationSource} ${result}
|
|
59
|
-
|
|
60
|
-
${asObjectWithSchemaPrompt(schema)}
|
|
61
|
-
|
|
62
|
-
${onlyJSON}`;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const shouldSkipDefault = ({ result, resultsAll } = {}) => {
|
|
66
|
-
return resultsAll.includes(result);
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const shouldStopDefault = ({ queryCount, startTime } = {}) => {
|
|
70
|
-
return (
|
|
71
|
-
queryCount > 5 ||
|
|
72
|
-
new Date() - startTime >
|
|
73
|
-
operationTimeoutMultiplier * modelService.getBestPublicModel().requestTimeout
|
|
74
|
-
);
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export const generateList = async function* generateListGenerator(text, options = {}) {
|
|
78
|
-
const resultsAll = [];
|
|
79
|
-
const resultsAllMap = {};
|
|
80
|
-
let isDone = false;
|
|
81
|
-
const {
|
|
82
|
-
shouldSkip = shouldSkipDefault,
|
|
83
|
-
shouldStop = shouldStopDefault,
|
|
84
|
-
model = 'fastGoodCheap',
|
|
85
|
-
// eslint-disable-next-line no-unused-vars
|
|
86
|
-
_schema,
|
|
87
|
-
...passThroughOptions
|
|
88
|
-
} = options;
|
|
89
|
-
|
|
90
|
-
const startTime = new Date();
|
|
91
|
-
let queryCount = 0;
|
|
92
|
-
|
|
93
|
-
while (!isDone) {
|
|
94
|
-
const listPrompt = generateListPrompt(text, {
|
|
95
|
-
...options,
|
|
96
|
-
existing: resultsAll,
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
let resultsNew = [];
|
|
100
|
-
try {
|
|
101
|
-
const modelOptions = await createModelOptions(model);
|
|
102
|
-
// eslint-disable-next-line no-await-in-loop
|
|
103
|
-
const results = await chatGPT(listPrompt, {
|
|
104
|
-
modelOptions,
|
|
105
|
-
...passThroughOptions,
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// With structured outputs, response should already be parsed and validated
|
|
109
|
-
const parsed = typeof results === 'string' ? JSON.parse(results) : results;
|
|
110
|
-
// Extract items from the object structure
|
|
111
|
-
const resultArray = parsed?.items || parsed;
|
|
112
|
-
resultsNew = Array.isArray(resultArray) ? resultArray.filter(Boolean) : [];
|
|
113
|
-
} catch (error) {
|
|
114
|
-
if (/The operation was aborted/.test(error.message)) {
|
|
115
|
-
// eslint-disable-next-line no-console
|
|
116
|
-
console.error('Generate list [error]: Aborted');
|
|
117
|
-
resultsNew = []; // continue
|
|
118
|
-
} else {
|
|
119
|
-
// eslint-disable-next-line no-console
|
|
120
|
-
console.error(
|
|
121
|
-
`Generate list [error]: ${error.message}`,
|
|
122
|
-
listPrompt.slice(0, 100).replace('\n', '\\n')
|
|
123
|
-
);
|
|
124
|
-
isDone = true;
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const resultsNewUnique = resultsNew.filter((item) => !(item in resultsAllMap));
|
|
130
|
-
|
|
131
|
-
queryCount += 1;
|
|
132
|
-
|
|
133
|
-
for (const result of resultsNewUnique) {
|
|
134
|
-
const perResultControlFactors = {
|
|
135
|
-
result,
|
|
136
|
-
resultsAll,
|
|
137
|
-
resultsNew,
|
|
138
|
-
queryCount,
|
|
139
|
-
startTime,
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
// eslint-disable-next-line no-await-in-loop
|
|
143
|
-
if (await shouldStop(perResultControlFactors)) {
|
|
144
|
-
isDone = true;
|
|
145
|
-
break;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// eslint-disable-next-line no-await-in-loop
|
|
149
|
-
if (!(await shouldSkip(perResultControlFactors))) {
|
|
150
|
-
resultsAllMap[result] = true;
|
|
151
|
-
resultsAll.push(result);
|
|
152
|
-
|
|
153
|
-
// debug helper:
|
|
154
|
-
// console.error(R.sort((a, b) => a.localeCompare(b), resultsAll));
|
|
155
|
-
|
|
156
|
-
yield result;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const perQueryControlFactors = {
|
|
161
|
-
result: undefined,
|
|
162
|
-
resultsAll: [],
|
|
163
|
-
resultsNew: [],
|
|
164
|
-
queryCount,
|
|
165
|
-
startTime,
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
// eslint-disable-next-line no-await-in-loop
|
|
169
|
-
if (await shouldStop(perQueryControlFactors)) {
|
|
170
|
-
isDone = true;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
export default async function list(prompt, config = {}) {
|
|
176
|
-
const { llm, schema, ...options } = config;
|
|
177
|
-
const fullPrompt = `${prompt}\n\n${onlyJSONArray}`;
|
|
178
|
-
|
|
179
|
-
const modelOptions = await createModelOptions(llm);
|
|
180
|
-
const response = await chatGPT(fullPrompt, {
|
|
181
|
-
modelOptions,
|
|
182
|
-
...options,
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
// With structured outputs, response should already be parsed and validated
|
|
186
|
-
const result = typeof response === 'string' ? JSON.parse(response) : response;
|
|
187
|
-
// Extract items from the object structure
|
|
188
|
-
const resultArray = result?.items || result;
|
|
189
|
-
const items = Array.isArray(resultArray) ? resultArray : [];
|
|
190
|
-
|
|
191
|
-
// If schema is provided, transform each item to match the schema
|
|
192
|
-
if (schema && items.length > 0) {
|
|
193
|
-
const transformedItems = [];
|
|
194
|
-
for (const item of items) {
|
|
195
|
-
const transformPrompt = outputTransformPrompt(item, schema);
|
|
196
|
-
const transformResponse = await chatGPT(transformPrompt, {
|
|
197
|
-
modelOptions: {
|
|
198
|
-
...llm,
|
|
199
|
-
},
|
|
200
|
-
...options,
|
|
201
|
-
});
|
|
202
|
-
try {
|
|
203
|
-
const transformedItem = JSON.parse(transformResponse);
|
|
204
|
-
transformedItems.push(transformedItem);
|
|
205
|
-
} catch {
|
|
206
|
-
// If transformation fails, keep the original item
|
|
207
|
-
transformedItems.push(item);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return transformedItems;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
return items;
|
|
214
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
import { dirname, join } from 'path';
|
|
5
|
-
|
|
6
|
-
import toObject from '../../verblets/to-object/index.js';
|
|
7
|
-
import list from './index.js';
|
|
8
|
-
|
|
9
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
-
const __dirname = dirname(__filename);
|
|
11
|
-
|
|
12
|
-
const loadSchema = async () => {
|
|
13
|
-
const file = (await fs.readFile(join(__dirname, '../../json-schemas/cars-test.json'))).toString();
|
|
14
|
-
|
|
15
|
-
return toObject(file);
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
vi.mock('../../lib/chatgpt/index.js', () => ({
|
|
19
|
-
default: vi.fn().mockImplementation((text) => {
|
|
20
|
-
if (/Transform/.test(text) && /Model Y/.test(text)) {
|
|
21
|
-
return '{"make":"Tesla", "model": "Model Y"}';
|
|
22
|
-
}
|
|
23
|
-
if (/EV cars/.test(text)) {
|
|
24
|
-
return '["Tesla Model Y"]';
|
|
25
|
-
}
|
|
26
|
-
return 'undefined';
|
|
27
|
-
}),
|
|
28
|
-
}));
|
|
29
|
-
|
|
30
|
-
const examples = [
|
|
31
|
-
{
|
|
32
|
-
name: 'Basic usage',
|
|
33
|
-
inputs: { description: '2021 EV cars' },
|
|
34
|
-
want: { listContains: /Model Y/ },
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
name: 'Basic usage with schema',
|
|
38
|
-
inputs: {
|
|
39
|
-
description: '2021 EV cars',
|
|
40
|
-
schema: loadSchema,
|
|
41
|
-
},
|
|
42
|
-
want: { listModelContains: /Model Y/ },
|
|
43
|
-
},
|
|
44
|
-
];
|
|
45
|
-
|
|
46
|
-
describe('List verblet', () => {
|
|
47
|
-
examples.forEach((example) => {
|
|
48
|
-
it(example.name, async () => {
|
|
49
|
-
let schema;
|
|
50
|
-
if (example.inputs.schema) {
|
|
51
|
-
schema = await example.inputs.schema();
|
|
52
|
-
}
|
|
53
|
-
const result = await list(example.inputs.description, {
|
|
54
|
-
shouldStop: ({ queryCount }) => queryCount > 1,
|
|
55
|
-
schema,
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
if (example.want.listContains) {
|
|
59
|
-
expect(result.some((item) => example.want.listContains.test(item))).equals(true);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (example.want.listModelContains) {
|
|
63
|
-
expect(result.some((item) => example.want.listModelContains.test(item.model))).equals(true);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
});
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"type": "object",
|
|
4
|
-
"properties": {
|
|
5
|
-
"items": {
|
|
6
|
-
"type": "array",
|
|
7
|
-
"description": "Array of generated list items",
|
|
8
|
-
"items": {
|
|
9
|
-
"type": "string",
|
|
10
|
-
"description": "A generated list item"
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
"required": ["items"],
|
|
15
|
-
"additionalProperties": false
|
|
16
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "list",
|
|
3
|
-
"description": "Generate a list based on the input text, optionally specifying a JSON schema for the subsequent output to conform to",
|
|
4
|
-
"parameters": {
|
|
5
|
-
"type": "object",
|
|
6
|
-
"properties": {
|
|
7
|
-
"name": {
|
|
8
|
-
"type": "string",
|
|
9
|
-
"description": "Name or description of the list to be generated"
|
|
10
|
-
},
|
|
11
|
-
"options": {
|
|
12
|
-
"type": "object",
|
|
13
|
-
"description": "Options for list generation and transformation",
|
|
14
|
-
"properties": {
|
|
15
|
-
"jsonSchema": {
|
|
16
|
-
"type": "object",
|
|
17
|
-
"description": "The JSONSchema used for transforming list results"
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
"required": []
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,366 +0,0 @@
|
|
|
1
|
-
# Enhanced LLM Logger
|
|
2
|
-
|
|
3
|
-
Advanced logging system with non-destructive parallel processing, designed for AI/LLM applications that need to enhance logs without modifying original data.
|
|
4
|
-
|
|
5
|
-
## 🚀 Key Features
|
|
6
|
-
|
|
7
|
-
### Core Innovations
|
|
8
|
-
- **Fully Parallel Processing**: No coordination overhead - processors run independently
|
|
9
|
-
- **Non-Destructive Enhancement**: Original logs remain unchanged, enhancements stored as attachments
|
|
10
|
-
- **NDJSON Bulk Processing**: Efficient batch processing for LLM interaction
|
|
11
|
-
- **Smart Filtering**: AI metadata controls output without affecting stored data
|
|
12
|
-
- **Ordered Adjustments**: Processor order determines adjustment priority
|
|
13
|
-
|
|
14
|
-
### Architecture
|
|
15
|
-
- **Ring Buffer**: High-performance circular buffer for log storage
|
|
16
|
-
- **Parallel Processors**: Independent processors with individual read offsets
|
|
17
|
-
- **Attachment System**: JSON-path syntax for non-destructive data enhancement
|
|
18
|
-
- **Lane System**: Multiple output channels with independent filtering
|
|
19
|
-
- **AI Metadata**: Separate metadata layer for AI-specific flags
|
|
20
|
-
|
|
21
|
-
## 📋 Quick Start
|
|
22
|
-
|
|
23
|
-
```javascript
|
|
24
|
-
import { createLLMLogger, createConsoleWriter } from './index.js';
|
|
25
|
-
|
|
26
|
-
// Create logger with processors
|
|
27
|
-
const logger = createLLMLogger({
|
|
28
|
-
ringBufferSize: 1000,
|
|
29
|
-
processors: [
|
|
30
|
-
{
|
|
31
|
-
processorId: 'sentiment-analyzer',
|
|
32
|
-
description: 'Analyzes log sentiment',
|
|
33
|
-
batchSize: 10,
|
|
34
|
-
async process(ndjsonInput) {
|
|
35
|
-
// Process NDJSON batch and return bulk adjustments
|
|
36
|
-
const logs = parseNDJSON(ndjsonInput);
|
|
37
|
-
return logs.map(log => ({
|
|
38
|
-
logId: log.id,
|
|
39
|
-
adjustments: {
|
|
40
|
-
'analysis.sentiment': analyzeSentiment(log.data),
|
|
41
|
-
'analysis.confidence': 0.95
|
|
42
|
-
},
|
|
43
|
-
aiMeta: {
|
|
44
|
-
skip: shouldSkip(log),
|
|
45
|
-
confidence: 0.95
|
|
46
|
-
}
|
|
47
|
-
}));
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
],
|
|
51
|
-
lanes: [
|
|
52
|
-
{
|
|
53
|
-
laneId: 'console',
|
|
54
|
-
writer: createConsoleWriter('[LOG] '),
|
|
55
|
-
filters: (log) => log.meta.get('level') !== 'debug'
|
|
56
|
-
}
|
|
57
|
-
]
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
// Use the logger
|
|
61
|
-
logger.info('User logged in');
|
|
62
|
-
logger.error('Database error');
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
## 🔧 API Reference
|
|
66
|
-
|
|
67
|
-
### Logger Creation
|
|
68
|
-
|
|
69
|
-
```javascript
|
|
70
|
-
createLLMLogger(config)
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
**Config Options:**
|
|
74
|
-
- `ringBufferSize` (number): Ring buffer capacity (default: 5000)
|
|
75
|
-
- `processors` (LogProcessor[]): Array of log processors
|
|
76
|
-
- `lanes` (LogLaneConfig[]): Output lane configurations
|
|
77
|
-
- `flushInterval` (number): Flush interval in ms (default: 1000)
|
|
78
|
-
- `immediateFlush` (boolean): Immediate vs batched flushing (default: false)
|
|
79
|
-
|
|
80
|
-
### Log Processors
|
|
81
|
-
|
|
82
|
-
```javascript
|
|
83
|
-
{
|
|
84
|
-
processorId: 'unique-id',
|
|
85
|
-
description: 'Human readable description',
|
|
86
|
-
batchSize: 10,
|
|
87
|
-
async process(ndjsonInput) {
|
|
88
|
-
// Return array of BulkAdjustment objects
|
|
89
|
-
return [{
|
|
90
|
-
logId: 'log-id',
|
|
91
|
-
adjustments: {
|
|
92
|
-
'path.to.field': 'value'
|
|
93
|
-
},
|
|
94
|
-
aiMeta: {
|
|
95
|
-
skip: false,
|
|
96
|
-
confidence: 0.95
|
|
97
|
-
}
|
|
98
|
-
}];
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### Lane Configuration
|
|
104
|
-
|
|
105
|
-
```javascript
|
|
106
|
-
{
|
|
107
|
-
laneId: 'unique-lane-id',
|
|
108
|
-
writer: (logs) => { /* write logs array */ },
|
|
109
|
-
filters: (log) => { /* return boolean */ }
|
|
110
|
-
}
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### Logger Methods
|
|
114
|
-
|
|
115
|
-
#### Standard Logging
|
|
116
|
-
```javascript
|
|
117
|
-
logger.log(data)
|
|
118
|
-
logger.info(data)
|
|
119
|
-
logger.warn(data)
|
|
120
|
-
logger.error(data)
|
|
121
|
-
logger.debug(data)
|
|
122
|
-
logger.trace(data)
|
|
123
|
-
logger.fatal(data)
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
#### Enhancement API
|
|
127
|
-
```javascript
|
|
128
|
-
// Attach data to specific log
|
|
129
|
-
logger.attachToLog(logId, 'path.to.field', value)
|
|
130
|
-
|
|
131
|
-
// Get attachment data
|
|
132
|
-
logger.getLogAttachment(logId, 'path.to.field')
|
|
133
|
-
|
|
134
|
-
// Mark log as skippable
|
|
135
|
-
logger.markLogSkippable(logId, true)
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
#### Ring Buffer Access
|
|
139
|
-
```javascript
|
|
140
|
-
logger.ringBuffer.all() // Get all logs
|
|
141
|
-
logger.ringBuffer.tail(n) // Get last n logs
|
|
142
|
-
logger.ringBuffer.head(n) // Get first n logs
|
|
143
|
-
logger.ringBuffer.filter(fn) // Filter logs
|
|
144
|
-
logger.ringBuffer.clear() // Clear buffer
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
#### Utility Methods
|
|
148
|
-
```javascript
|
|
149
|
-
logger.flush() // Force flush all lanes
|
|
150
|
-
logger.clear() // Clear all data
|
|
151
|
-
logger.getStats() // Get processing statistics
|
|
152
|
-
logger.getProcessorOffsets() // Get processor progress
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
## 🔄 Processing Flow
|
|
156
|
-
|
|
157
|
-
1. **Log Entry**: Log data enters the system
|
|
158
|
-
2. **Ring Buffer**: Stored in circular buffer with metadata
|
|
159
|
-
3. **Parallel Processing**: Multiple processors work independently
|
|
160
|
-
4. **NDJSON Conversion**: Logs converted to NDJSON for LLM processing
|
|
161
|
-
5. **Bulk Adjustments**: Processors return structured adjustments
|
|
162
|
-
6. **Attachment Application**: Adjustments applied as attachments
|
|
163
|
-
7. **Lane Filtering**: Logs filtered through output lanes
|
|
164
|
-
8. **AI Metadata Filtering**: Skip flags respected during output
|
|
165
|
-
9. **Writer Output**: Final logs sent to configured writers
|
|
166
|
-
|
|
167
|
-
## 📊 Data Structures
|
|
168
|
-
|
|
169
|
-
### LogEntry
|
|
170
|
-
```javascript
|
|
171
|
-
{
|
|
172
|
-
id: 'unique-id',
|
|
173
|
-
ts: Date,
|
|
174
|
-
raw: 'original-data',
|
|
175
|
-
meta: Map,
|
|
176
|
-
attachments: {}, // Non-destructive enhancements
|
|
177
|
-
aiMeta: {} // AI-specific metadata (not output)
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### BulkAdjustment
|
|
182
|
-
```javascript
|
|
183
|
-
{
|
|
184
|
-
logId: 'target-log-id',
|
|
185
|
-
adjustments: {
|
|
186
|
-
'path.to.field': 'value',
|
|
187
|
-
'nested.object': { key: 'value' }
|
|
188
|
-
},
|
|
189
|
-
aiMeta: {
|
|
190
|
-
skip: false,
|
|
191
|
-
confidence: 0.95,
|
|
192
|
-
// ... other AI metadata
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
### NDJSON Format
|
|
198
|
-
```
|
|
199
|
-
{"id":"log-1","ts":"2024-01-01T00:00:00Z","level":"info","data":"message","attachments":{}}
|
|
200
|
-
{"id":"log-2","ts":"2024-01-01T00:00:01Z","level":"error","data":"error","attachments":{}}
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
## 🎯 Use Cases
|
|
204
|
-
|
|
205
|
-
### AI Log Analysis
|
|
206
|
-
```javascript
|
|
207
|
-
const aiProcessor = {
|
|
208
|
-
processorId: 'ai-analyzer',
|
|
209
|
-
description: 'AI-powered log analysis',
|
|
210
|
-
batchSize: 20,
|
|
211
|
-
async process(ndjsonInput) {
|
|
212
|
-
const analysis = await callLLM(ndjsonInput);
|
|
213
|
-
return analysis.map(item => ({
|
|
214
|
-
logId: item.logId,
|
|
215
|
-
adjustments: {
|
|
216
|
-
'ai.category': item.category,
|
|
217
|
-
'ai.severity': item.severity,
|
|
218
|
-
'ai.suggestions': item.suggestions
|
|
219
|
-
},
|
|
220
|
-
aiMeta: {
|
|
221
|
-
skip: item.severity === 'low',
|
|
222
|
-
confidence: item.confidence
|
|
223
|
-
}
|
|
224
|
-
}));
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
### Multi-Stage Processing
|
|
230
|
-
```javascript
|
|
231
|
-
const processors = [
|
|
232
|
-
sentimentProcessor, // Order 0: First to process
|
|
233
|
-
categoryProcessor, // Order 1: Sees sentiment results
|
|
234
|
-
priorityProcessor // Order 2: Sees all previous results
|
|
235
|
-
];
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### Conditional Output
|
|
239
|
-
```javascript
|
|
240
|
-
const lanes = [
|
|
241
|
-
{
|
|
242
|
-
laneId: 'all-logs',
|
|
243
|
-
writer: fileWriter('all.log'),
|
|
244
|
-
filters: () => true
|
|
245
|
-
},
|
|
246
|
-
{
|
|
247
|
-
laneId: 'errors-only',
|
|
248
|
-
writer: alertWriter,
|
|
249
|
-
filters: (log) => log.meta.get('level') === 'error'
|
|
250
|
-
},
|
|
251
|
-
{
|
|
252
|
-
laneId: 'high-confidence',
|
|
253
|
-
writer: analyticsWriter,
|
|
254
|
-
filters: (log) => log.attachments?.ai?.confidence > 0.8
|
|
255
|
-
}
|
|
256
|
-
];
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
## 🔍 Monitoring & Debugging
|
|
260
|
-
|
|
261
|
-
### Statistics
|
|
262
|
-
```javascript
|
|
263
|
-
const stats = logger.getStats();
|
|
264
|
-
console.log('Ring buffer usage:', stats.writeIndex, '/', stats.maxSize);
|
|
265
|
-
console.log('Processors:', stats.processors);
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
### Processor Progress
|
|
269
|
-
```javascript
|
|
270
|
-
const offsets = logger.getProcessorOffsets();
|
|
271
|
-
for (const [processorId, offset] of offsets) {
|
|
272
|
-
console.log(`${processorId}: processed up to offset ${offset}`);
|
|
273
|
-
}
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
### Log Inspection
|
|
277
|
-
```javascript
|
|
278
|
-
const recentLogs = logger.ringBuffer.tail(10);
|
|
279
|
-
recentLogs.forEach(log => {
|
|
280
|
-
console.log('Original:', log.raw);
|
|
281
|
-
console.log('Enhanced:', log.attachments);
|
|
282
|
-
console.log('AI Meta:', log.aiMeta);
|
|
283
|
-
});
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
## ⚡ Performance Characteristics
|
|
287
|
-
|
|
288
|
-
- **Parallel Processing**: No blocking between processors
|
|
289
|
-
- **Ring Buffer**: O(1) write operations
|
|
290
|
-
- **Batch Processing**: Configurable batch sizes for efficiency
|
|
291
|
-
- **Memory Bounded**: Fixed memory usage via ring buffer
|
|
292
|
-
- **Non-Blocking**: Async processing doesn't block logging
|
|
293
|
-
|
|
294
|
-
## 🔧 Configuration Examples
|
|
295
|
-
|
|
296
|
-
### High-Throughput Setup
|
|
297
|
-
```javascript
|
|
298
|
-
const logger = createLLMLogger({
|
|
299
|
-
ringBufferSize: 10000,
|
|
300
|
-
flushInterval: 100,
|
|
301
|
-
processors: processors.map(p => ({
|
|
302
|
-
...p,
|
|
303
|
-
batchSize: 50
|
|
304
|
-
}))
|
|
305
|
-
});
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
### Real-Time Setup
|
|
309
|
-
```javascript
|
|
310
|
-
const logger = createLLMLogger({
|
|
311
|
-
immediateFlush: true,
|
|
312
|
-
processors: processors.map(p => ({
|
|
313
|
-
...p,
|
|
314
|
-
batchSize: 1
|
|
315
|
-
}))
|
|
316
|
-
});
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
### Development Setup
|
|
320
|
-
```javascript
|
|
321
|
-
const logger = createLLMLogger({
|
|
322
|
-
ringBufferSize: 100,
|
|
323
|
-
immediateFlush: true,
|
|
324
|
-
lanes: [{
|
|
325
|
-
laneId: 'console',
|
|
326
|
-
writer: createConsoleWriter('[DEV] ')
|
|
327
|
-
}]
|
|
328
|
-
});
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
## 🚨 Error Handling
|
|
332
|
-
|
|
333
|
-
Processors handle errors gracefully:
|
|
334
|
-
- Failed processors retry after delay
|
|
335
|
-
- Other processors continue unaffected
|
|
336
|
-
- Original logs always preserved
|
|
337
|
-
- Error logs available in statistics
|
|
338
|
-
|
|
339
|
-
## 📈 Migration Guide
|
|
340
|
-
|
|
341
|
-
### From Basic Logger
|
|
342
|
-
```javascript
|
|
343
|
-
// Before
|
|
344
|
-
const logger = createBasicLogger();
|
|
345
|
-
logger.info('message');
|
|
346
|
-
|
|
347
|
-
// After
|
|
348
|
-
const logger = createLLMLogger({
|
|
349
|
-
lanes: [{ laneId: 'console', writer: createConsoleWriter() }]
|
|
350
|
-
});
|
|
351
|
-
logger.info('message');
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
### Adding Processors
|
|
355
|
-
```javascript
|
|
356
|
-
// Add processors incrementally
|
|
357
|
-
const logger = createLLMLogger({
|
|
358
|
-
// ... existing config
|
|
359
|
-
processors: [
|
|
360
|
-
...existingProcessors,
|
|
361
|
-
newProcessor
|
|
362
|
-
]
|
|
363
|
-
});
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
This enhanced logger provides a powerful foundation for AI-driven log processing while maintaining compatibility with existing logging patterns.
|