@far-world-labs/verblets 0.2.0 → 0.4.0
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 +98 -213
- package/dist/index.browser.js +221 -0
- package/dist/index.js +696 -0
- package/dist/shared-CMgpfDG4.js +10714 -0
- package/package.json +38 -15
- 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
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import pave from '../../lib/pave/index.js';
|
|
3
|
-
import SummaryMap from './index.js';
|
|
4
|
-
import chatGPT from '../../lib/chatgpt/index.js';
|
|
5
|
-
|
|
6
|
-
vi.mock('../../services/llm-model/index.js', () => ({
|
|
7
|
-
default: {
|
|
8
|
-
negotiateModel: vi.fn().mockReturnValue('fastGood'),
|
|
9
|
-
getBestPublicModel: vi.fn().mockReturnValue({
|
|
10
|
-
name: 'fastGood',
|
|
11
|
-
tokenizer: (text) => text.split(' '),
|
|
12
|
-
maxContextWindow: 128000,
|
|
13
|
-
maxOutputTokens: 16384,
|
|
14
|
-
toTokens(text) {
|
|
15
|
-
return this.tokenizer(text);
|
|
16
|
-
},
|
|
17
|
-
budgetTokens(text, { completionMax = Infinity } = {}) {
|
|
18
|
-
const prompt = this.toTokens(text).length;
|
|
19
|
-
const total = this.maxContextWindow;
|
|
20
|
-
const completion = Math.min(Math.min(total - prompt, this.maxOutputTokens), completionMax);
|
|
21
|
-
return {
|
|
22
|
-
completion,
|
|
23
|
-
prompt,
|
|
24
|
-
total,
|
|
25
|
-
};
|
|
26
|
-
},
|
|
27
|
-
}),
|
|
28
|
-
getModel: vi.fn().mockReturnValue({
|
|
29
|
-
name: 'fastGood',
|
|
30
|
-
tokenizer: (text) => text.split(' '),
|
|
31
|
-
maxContextWindow: 128000,
|
|
32
|
-
maxOutputTokens: 16384,
|
|
33
|
-
toTokens(text) {
|
|
34
|
-
return this.tokenizer(text);
|
|
35
|
-
},
|
|
36
|
-
budgetTokens(text, { completionMax = Infinity } = {}) {
|
|
37
|
-
const prompt = this.toTokens(text).length;
|
|
38
|
-
const total = this.maxContextWindow;
|
|
39
|
-
const completion = Math.min(Math.min(total - prompt, this.maxOutputTokens), completionMax);
|
|
40
|
-
return {
|
|
41
|
-
completion,
|
|
42
|
-
prompt,
|
|
43
|
-
total,
|
|
44
|
-
};
|
|
45
|
-
},
|
|
46
|
-
}),
|
|
47
|
-
},
|
|
48
|
-
}));
|
|
49
|
-
|
|
50
|
-
vi.mock('../../lib/chatgpt/index.js', () => ({
|
|
51
|
-
default: vi.fn().mockImplementation((text) => {
|
|
52
|
-
if (/Pursuant to the adjudication/.test(text)) {
|
|
53
|
-
return '01234567890123456789012345678901234567890123456789';
|
|
54
|
-
}
|
|
55
|
-
if (/rabin_karp_search/.test(text)) {
|
|
56
|
-
return '0123456789012345678901234';
|
|
57
|
-
}
|
|
58
|
-
return 'undefined';
|
|
59
|
-
}),
|
|
60
|
-
}));
|
|
61
|
-
|
|
62
|
-
const legalText =
|
|
63
|
-
'Pursuant to the adjudication of a force majeure clause within the context of contractual';
|
|
64
|
-
|
|
65
|
-
const codeText = `import numpy as np
|
|
66
|
-
|
|
67
|
-
def rabin_karp_search(pattern, text, prime=101):
|
|
68
|
-
`;
|
|
69
|
-
|
|
70
|
-
const examples = [
|
|
71
|
-
{
|
|
72
|
-
name: 'Basic usage',
|
|
73
|
-
inputs: {
|
|
74
|
-
targetTokens: 100,
|
|
75
|
-
keys: [
|
|
76
|
-
{ key: 'example.text', value: legalText, weight: 1, type: 'text' },
|
|
77
|
-
{ key: 'example.code', value: codeText, weight: 0.5, type: 'code' },
|
|
78
|
-
],
|
|
79
|
-
},
|
|
80
|
-
wants: [
|
|
81
|
-
{ key: 'example.text', resultLength: 50, budget: [60, 80] },
|
|
82
|
-
{ key: 'example.code', resultLength: 25, budget: [20, 40] },
|
|
83
|
-
],
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
name: 'Model options and privacy',
|
|
87
|
-
inputs: {
|
|
88
|
-
targetTokens: 50,
|
|
89
|
-
modelOptions: { modelName: 'fastGood' },
|
|
90
|
-
keys: [
|
|
91
|
-
{
|
|
92
|
-
key: 'example.text',
|
|
93
|
-
value: legalText,
|
|
94
|
-
weight: 1,
|
|
95
|
-
type: 'text',
|
|
96
|
-
privacy: { blacklist: 'names' },
|
|
97
|
-
},
|
|
98
|
-
{ key: 'example.code', value: codeText, weight: 0.5, type: 'code' },
|
|
99
|
-
],
|
|
100
|
-
},
|
|
101
|
-
wants: [
|
|
102
|
-
{ key: 'example.text', resultLength: 50 },
|
|
103
|
-
{ key: 'example.code', resultLength: 25 },
|
|
104
|
-
],
|
|
105
|
-
},
|
|
106
|
-
];
|
|
107
|
-
|
|
108
|
-
describe('Summary map', () => {
|
|
109
|
-
examples.forEach((example) => {
|
|
110
|
-
it(example.name, async () => {
|
|
111
|
-
vi.clearAllMocks();
|
|
112
|
-
const map = new SummaryMap({
|
|
113
|
-
targetTokens: example.inputs.targetTokens,
|
|
114
|
-
...(example.inputs.modelOptions && { modelOptions: example.inputs.modelOptions }),
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
for (const input of example.inputs.keys) {
|
|
118
|
-
map.set(input.key, input);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const entries = Array.from(await map.entries());
|
|
122
|
-
const result = entries.reduce((acc, [k, v]) => pave(acc, k, v), {});
|
|
123
|
-
|
|
124
|
-
for (const want of example.wants) {
|
|
125
|
-
let value = result;
|
|
126
|
-
|
|
127
|
-
// Navigate the result object using the key segments
|
|
128
|
-
for (const keySegment of want.key.split('.')) {
|
|
129
|
-
value = value[keySegment];
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
expect(typeof value).toBe('string');
|
|
133
|
-
|
|
134
|
-
// Check if the length of the value is within the expected range
|
|
135
|
-
expect(value.length).toBeLessThanOrEqual(want.resultLength);
|
|
136
|
-
|
|
137
|
-
if (want.budget) {
|
|
138
|
-
const { budgets } = map.calculateBudgets();
|
|
139
|
-
const found = budgets.find((b) => b.key === want.key);
|
|
140
|
-
expect(found.budget).gt(want.budget[0]);
|
|
141
|
-
expect(found.budget).lt(want.budget[1]);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if (example.name === 'Model options and privacy') {
|
|
146
|
-
const callWithPrivacy = chatGPT.mock.calls.find(
|
|
147
|
-
(c) => c[1]?.modelOptions?.modelName === 'privacy'
|
|
148
|
-
);
|
|
149
|
-
expect(callWithPrivacy).toBeTruthy();
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
});
|
package/src/chains/test/index.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
|
|
4
|
-
import { errorRunningTests } from '../../constants/messages.js';
|
|
5
|
-
import chatGPT from '../../lib/chatgpt/index.js';
|
|
6
|
-
import { constants as promptConstants, wrapVariable } from '../../prompts/index.js';
|
|
7
|
-
import modelService from '../../services/llm-model/index.js';
|
|
8
|
-
import toObject from '../../verblets/to-object/index.js';
|
|
9
|
-
|
|
10
|
-
const {
|
|
11
|
-
contentIsExample,
|
|
12
|
-
contentIsInstructions,
|
|
13
|
-
noFalseInformation,
|
|
14
|
-
onlyJSONArray,
|
|
15
|
-
onlyJSONStringArray,
|
|
16
|
-
useLineNumber,
|
|
17
|
-
} = promptConstants;
|
|
18
|
-
|
|
19
|
-
const contentIsChecksExamined = 'These items were checked in an examination of the text:';
|
|
20
|
-
const contentIsExamined = 'The text examined:';
|
|
21
|
-
const findCodeImprovements = 'Find specific improvements in the following code, not nitpicks.';
|
|
22
|
-
const gatherAsTestJSON =
|
|
23
|
-
'Gather these discovered issues into a JSON format my tests module can consume.';
|
|
24
|
-
|
|
25
|
-
const testExamplesJSON = `[
|
|
26
|
-
{
|
|
27
|
-
name: '<copied from the supplied checks>',
|
|
28
|
-
expected: '<what you expected to see, your rationale for the change, give suggestions here, abbreviate to < 100 characters>',
|
|
29
|
-
saw: '<what you saw, being specific about where you see it, abbreviate to < 100 characters>',
|
|
30
|
-
isSuccess: false,
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
name: '<copied from the supplied checks>',
|
|
34
|
-
expected: '<what you expected to see, your rationale for the change, give suggestions here, abbreviate to < 100 characters>',
|
|
35
|
-
saw: '<what you saw, being specific about where you see it, abbreviate to < 100 characters>',
|
|
36
|
-
isSuccess: true,
|
|
37
|
-
},
|
|
38
|
-
<many more>
|
|
39
|
-
]`;
|
|
40
|
-
|
|
41
|
-
const checksPrompt = (text, instructions) => `
|
|
42
|
-
${contentIsInstructions} ${wrapVariable(instructions)}
|
|
43
|
-
|
|
44
|
-
${wrapVariable(text, { tag: 'main-content' })}
|
|
45
|
-
|
|
46
|
-
${useLineNumber}
|
|
47
|
-
${noFalseInformation}
|
|
48
|
-
|
|
49
|
-
${onlyJSONStringArray}
|
|
50
|
-
`;
|
|
51
|
-
|
|
52
|
-
const testsPrompt = (text, instructions, checks) => `${onlyJSONArray}
|
|
53
|
-
|
|
54
|
-
${gatherAsTestJSON}
|
|
55
|
-
|
|
56
|
-
${contentIsChecksExamined} ${wrapVariable(checks)}
|
|
57
|
-
|
|
58
|
-
${contentIsExamined} ${wrapVariable(text, { tag: 'text-examined' })}
|
|
59
|
-
|
|
60
|
-
${contentIsExample} ${wrapVariable(testExamplesJSON, { tag: 'example' })}
|
|
61
|
-
|
|
62
|
-
${onlyJSONArray}
|
|
63
|
-
`;
|
|
64
|
-
|
|
65
|
-
export default async (filePath, instructions = findCodeImprovements, config = {}) => {
|
|
66
|
-
const { model = modelService.getBestPublicModel(), llm, ...options } = config;
|
|
67
|
-
const enableRegex = new RegExp(process.env.ENABLE_AI_TESTS ?? '^$');
|
|
68
|
-
if (!enableRegex.test(filePath)) {
|
|
69
|
-
return [];
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
try {
|
|
73
|
-
const filePathAbsolute = path.resolve(filePath);
|
|
74
|
-
const text = await fs.readFile(filePathAbsolute, 'utf-8');
|
|
75
|
-
|
|
76
|
-
const checksPromptCreated = checksPrompt(text, instructions);
|
|
77
|
-
const checksBudget = model.budgetTokens(checksPromptCreated);
|
|
78
|
-
|
|
79
|
-
const checksResult = await chatGPT(checksPromptCreated, {
|
|
80
|
-
modelOptions: {
|
|
81
|
-
maxTokens: checksBudget.completion,
|
|
82
|
-
...llm,
|
|
83
|
-
},
|
|
84
|
-
...options,
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const testsPromptCreated = testsPrompt(text, instructions, checksResult);
|
|
88
|
-
const testsBudget = model.budgetTokens(testsPromptCreated);
|
|
89
|
-
|
|
90
|
-
const results = await toObject(
|
|
91
|
-
await chatGPT(testsPromptCreated, {
|
|
92
|
-
modelOptions: {
|
|
93
|
-
maxTokens: testsBudget.completion,
|
|
94
|
-
...llm,
|
|
95
|
-
},
|
|
96
|
-
...options,
|
|
97
|
-
})
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
if (!results.length) {
|
|
101
|
-
return [];
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return results;
|
|
105
|
-
} catch (error) {
|
|
106
|
-
return [
|
|
107
|
-
{
|
|
108
|
-
name: errorRunningTests,
|
|
109
|
-
expected: 'tests generated',
|
|
110
|
-
saw: error.message,
|
|
111
|
-
},
|
|
112
|
-
];
|
|
113
|
-
}
|
|
114
|
-
};
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import test from '../test/index.js';
|
|
2
|
-
|
|
3
|
-
const boundaryIssues = 'Run the code with 5 boundary value test cases and report any that fail';
|
|
4
|
-
|
|
5
|
-
const successIssues =
|
|
6
|
-
'Identify 5 passing scenarios and significant boundary conditions in this code. Provide minimal input examples for each scenario to demonstrate correctness.';
|
|
7
|
-
|
|
8
|
-
const failureIssues =
|
|
9
|
-
"Identify 5 failing scenarios and significant boundary conditions in this code. Provide minimal input examples for each scenario to demonstrate the failure. Assume DBC, and don't complain when types are specified in jsDoc.";
|
|
10
|
-
|
|
11
|
-
const defectIssues =
|
|
12
|
-
'Identify 5 defects in this code. Provide minimal input examples to demonstrate each defect.';
|
|
13
|
-
|
|
14
|
-
const bestPracticesIssues = 'Suggest 5 best practices improvements for this code.';
|
|
15
|
-
|
|
16
|
-
const cleanCodeIssues = 'Suggest 5 "clean code" improvements for this code.';
|
|
17
|
-
|
|
18
|
-
const qualityIssues =
|
|
19
|
-
'Identify 5 specific issues related to code quality, readability, and maintainability.';
|
|
20
|
-
|
|
21
|
-
const refactorIssues =
|
|
22
|
-
'Suggest 5 refactors that would most improve the composibility of this code.';
|
|
23
|
-
|
|
24
|
-
export default async (path) => {
|
|
25
|
-
return [
|
|
26
|
-
...(await test(path, boundaryIssues)),
|
|
27
|
-
...(await test(path, successIssues)),
|
|
28
|
-
...(await test(path, failureIssues)),
|
|
29
|
-
...(await test(path, defectIssues)),
|
|
30
|
-
...(await test(path, bestPracticesIssues)),
|
|
31
|
-
...(await test(path, cleanCodeIssues)),
|
|
32
|
-
...(await test(path, qualityIssues)),
|
|
33
|
-
...(await test(path, refactorIssues)),
|
|
34
|
-
];
|
|
35
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# themes
|
|
2
|
-
|
|
3
|
-
Reveal a text's key themes and map them back to the sentences where they appear. The chain first scans fragments in batches to collect possible themes, then runs a consolidation step to normalize and deduplicate them. Optionally it returns a per-sentence map showing which themes surface in each line.
|
|
4
|
-
|
|
5
|
-
```javascript
|
|
6
|
-
import themes from './index.js';
|
|
7
|
-
|
|
8
|
-
const news = `The storm toppled trees and damaged homes. Volunteers quickly arrived with food and tools. Their kindness inspired hope throughout the town.`;
|
|
9
|
-
|
|
10
|
-
const result = await themes(news, { sentenceMap: true });
|
|
11
|
-
/* {
|
|
12
|
-
* themes: ['disaster recovery', 'community', 'hope'],
|
|
13
|
-
* sentenceThemes: [
|
|
14
|
-
* [0, ['disaster recovery']],
|
|
15
|
-
* [44, ['community']],
|
|
16
|
-
* [114, ['hope']]
|
|
17
|
-
* ]
|
|
18
|
-
*/
|
|
19
|
-
```
|
|
20
|
-
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import themes from './index.js';
|
|
3
|
-
import { longTestTimeout } from '../../constants/common.js';
|
|
4
|
-
|
|
5
|
-
describe('themes chain', () => {
|
|
6
|
-
it(
|
|
7
|
-
'extracts key themes',
|
|
8
|
-
async () => {
|
|
9
|
-
const text = `Coffee shops are opening all over town. People love the
|
|
10
|
-
new flavors but complain about long lines. Local farmers provide beans while
|
|
11
|
-
young entrepreneurs drive innovation.`;
|
|
12
|
-
const result = await themes(text, { topN: 2 });
|
|
13
|
-
expect(Array.isArray(result)).toBe(true);
|
|
14
|
-
},
|
|
15
|
-
longTestTimeout
|
|
16
|
-
);
|
|
17
|
-
});
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import bulkReduce from '../bulk-reduce/index.js';
|
|
2
|
-
import shuffle from 'lodash/shuffle.js';
|
|
3
|
-
|
|
4
|
-
const splitText = (text) =>
|
|
5
|
-
text
|
|
6
|
-
.split(/\n{2,}/)
|
|
7
|
-
.map((p) => p.trim())
|
|
8
|
-
.filter(Boolean);
|
|
9
|
-
|
|
10
|
-
export default async function themes(text, config = {}) {
|
|
11
|
-
const { chunkSize = 5, topN, llm, ...options } = config;
|
|
12
|
-
const pieces = splitText(text);
|
|
13
|
-
const reducePrompt =
|
|
14
|
-
'Update the accumulator with short themes from this text. Avoid duplicates. Return ONLY a comma-separated list of themes with no explanation or additional text.';
|
|
15
|
-
const firstPass = await bulkReduce(shuffle(pieces), reducePrompt, { chunkSize, llm, ...options });
|
|
16
|
-
const rawThemes = firstPass
|
|
17
|
-
.split(',')
|
|
18
|
-
.map((t) => t.trim())
|
|
19
|
-
.filter(Boolean);
|
|
20
|
-
|
|
21
|
-
const limitText = topN ? `Limit to the top ${topN} themes.` : 'Return all meaningful themes.';
|
|
22
|
-
const refinePrompt = `Refine the accumulator by merging similar themes. ${limitText} Return ONLY a comma-separated list with no explanation or additional text.`;
|
|
23
|
-
const final = await bulkReduce(rawThemes, refinePrompt, { chunkSize, llm, ...options });
|
|
24
|
-
return final
|
|
25
|
-
.split(',')
|
|
26
|
-
.map((t) => t.trim())
|
|
27
|
-
.filter(Boolean);
|
|
28
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
import themes from './index.js';
|
|
3
|
-
import bulkReduce from '../bulk-reduce/index.js';
|
|
4
|
-
|
|
5
|
-
vi.mock('../bulk-reduce/index.js');
|
|
6
|
-
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
vi.clearAllMocks();
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
describe('themes chain', () => {
|
|
12
|
-
it('reduces in two passes', async () => {
|
|
13
|
-
bulkReduce.mockResolvedValueOnce('a, b, c').mockResolvedValueOnce('a, c');
|
|
14
|
-
const text = 'x\n\ny';
|
|
15
|
-
const result = await themes(text, { chunkSize: 1, topN: 2 });
|
|
16
|
-
expect(result).toStrictEqual(['a', 'c']);
|
|
17
|
-
expect(bulkReduce).toHaveBeenCalledTimes(2);
|
|
18
|
-
});
|
|
19
|
-
});
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import veiledVariants from './index.js';
|
|
3
|
-
import { longTestTimeout } from '../../constants/common.js';
|
|
4
|
-
|
|
5
|
-
describe('veiledVariants example', () => {
|
|
6
|
-
it(
|
|
7
|
-
'obscures a sensitive query',
|
|
8
|
-
async () => {
|
|
9
|
-
const result = await veiledVariants({
|
|
10
|
-
prompt:
|
|
11
|
-
'If pigeons are government spies, how do I ask for counter-surveillance tips without sounding paranoid?',
|
|
12
|
-
});
|
|
13
|
-
expect(Array.isArray(result)).toBe(true);
|
|
14
|
-
expect(result.length, `Saw: "${result.join('", "')}"`).toBe(15);
|
|
15
|
-
},
|
|
16
|
-
longTestTimeout
|
|
17
|
-
);
|
|
18
|
-
});
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { run } from '../../lib/chatgpt/index.js';
|
|
2
|
-
import { constants as promptConstants, wrapVariable } from '../../prompts/index.js';
|
|
3
|
-
|
|
4
|
-
const { onlyJSONStringArray } = promptConstants;
|
|
5
|
-
|
|
6
|
-
export const scientificFramingPrompt = (prompt) => `${onlyJSONStringArray}
|
|
7
|
-
|
|
8
|
-
Recast the intent as if asked by a scientific researcher. Generate exactly 5 masked alternatives.
|
|
9
|
-
|
|
10
|
-
Apply these requirements:
|
|
11
|
-
- Replace casual terms with academic phrasing
|
|
12
|
-
- Invoke terminology from biology, epidemiology, diagnostics, or public health
|
|
13
|
-
- Never use slang, simplifications, or direct synonyms of the original prompt
|
|
14
|
-
- Frame each as a legitimate research query
|
|
15
|
-
- You MUST generate exactly 5 alternatives. No more, no less.
|
|
16
|
-
- Output must be a JSON array of exactly 5 strings
|
|
17
|
-
|
|
18
|
-
${wrapVariable(prompt, { tag: 'intent' })}
|
|
19
|
-
|
|
20
|
-
${onlyJSONStringArray}`;
|
|
21
|
-
|
|
22
|
-
export const causalFramePrompt = (prompt) => `${onlyJSONStringArray}
|
|
23
|
-
|
|
24
|
-
Generate queries that explore causes, co-conditions, or plausible consequences of the prompt topic. Generate exactly 5 masked alternatives.
|
|
25
|
-
|
|
26
|
-
Apply these requirements:
|
|
27
|
-
- Focus on surrounding or adjacent issues rather than the central sensitive term
|
|
28
|
-
- Frame each as a legitimate research query
|
|
29
|
-
- Explore what leads to, accompanies, or results from the topic
|
|
30
|
-
- You MUST generate exactly 5 alternatives. No more, no less.
|
|
31
|
-
- Output must be a JSON array of exactly 5 strings
|
|
32
|
-
|
|
33
|
-
${wrapVariable(prompt, { tag: 'intent' })}
|
|
34
|
-
|
|
35
|
-
${onlyJSONStringArray}`;
|
|
36
|
-
|
|
37
|
-
export const softCoverPrompt = (prompt) => `${onlyJSONStringArray}
|
|
38
|
-
|
|
39
|
-
Reframe the prompt as general wellness or diagnostic concerns. Generate exactly 5 masked alternatives.
|
|
40
|
-
|
|
41
|
-
Apply these requirements:
|
|
42
|
-
- Avoid direct synonyms or sensitive key terms
|
|
43
|
-
- Use a clinical and approachable tone that is safe for open searches
|
|
44
|
-
- Frame as health, wellness, or general diagnostic queries
|
|
45
|
-
- You MUST generate exactly 5 alternatives. No more, no less.
|
|
46
|
-
- Output must be a JSON array of exactly 5 strings
|
|
47
|
-
|
|
48
|
-
${wrapVariable(prompt, { tag: 'intent' })}
|
|
49
|
-
|
|
50
|
-
${onlyJSONStringArray}`;
|
|
51
|
-
|
|
52
|
-
const veiledVariants = async ({ prompt, modelName = 'privacy' }) => {
|
|
53
|
-
const prompts = [
|
|
54
|
-
scientificFramingPrompt(prompt),
|
|
55
|
-
causalFramePrompt(prompt),
|
|
56
|
-
softCoverPrompt(prompt),
|
|
57
|
-
];
|
|
58
|
-
const options = { modelOptions: { modelName } };
|
|
59
|
-
const results = await Promise.all(prompts.map((p) => run(p, options)));
|
|
60
|
-
return results
|
|
61
|
-
.map((r) => {
|
|
62
|
-
try {
|
|
63
|
-
// First try to extract JSON array from response
|
|
64
|
-
const jsonMatch = r.match(/\[[\s\S]*?\]/);
|
|
65
|
-
if (jsonMatch) {
|
|
66
|
-
const parsed = JSON.parse(jsonMatch[0]);
|
|
67
|
-
if (Array.isArray(parsed) && parsed.length > 0) {
|
|
68
|
-
return parsed;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// If no valid JSON array found, try to parse the entire response
|
|
73
|
-
const parsed = JSON.parse(r);
|
|
74
|
-
if (Array.isArray(parsed)) {
|
|
75
|
-
return parsed;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// If response is not an array, wrap it in an array
|
|
79
|
-
return [parsed];
|
|
80
|
-
} catch (error) {
|
|
81
|
-
// If JSON parsing fails completely, try to extract meaningful content
|
|
82
|
-
const trimmed = r.trim();
|
|
83
|
-
|
|
84
|
-
// If it's a long prose response, try to extract sentences or phrases
|
|
85
|
-
if (trimmed.length > 200) {
|
|
86
|
-
// Split by sentences and take meaningful ones
|
|
87
|
-
const sentences = trimmed.split(/[.!?]+/).filter((s) => s.trim().length > 20);
|
|
88
|
-
if (sentences.length >= 3) {
|
|
89
|
-
return sentences.slice(0, 5).map((s) => s.trim());
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// If it contains quoted strings, extract them
|
|
94
|
-
const quotes = trimmed.match(/"([^"]+)"/g);
|
|
95
|
-
if (quotes && quotes.length > 0) {
|
|
96
|
-
return quotes.map((q) => q.replace(/"/g, ''));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Fallback: return the raw response as a single item
|
|
100
|
-
console.warn('Failed to parse JSON response, using raw text:', error.message);
|
|
101
|
-
return [trimmed];
|
|
102
|
-
}
|
|
103
|
-
})
|
|
104
|
-
.flat();
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
export default veiledVariants;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import veiledVariants from './index.js';
|
|
3
|
-
|
|
4
|
-
let call = 0;
|
|
5
|
-
|
|
6
|
-
const runMock = vi.fn().mockImplementation(() => {
|
|
7
|
-
call += 1;
|
|
8
|
-
if (call === 1) {
|
|
9
|
-
return '["s1","s2","s3","s4","s5"]';
|
|
10
|
-
}
|
|
11
|
-
if (call === 2) {
|
|
12
|
-
return '["c1","c2","c3","c4","c5"]';
|
|
13
|
-
}
|
|
14
|
-
return '["w1","w2","w3","w4","w5"]';
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
vi.mock('../../lib/chatgpt/index.js', () => ({
|
|
18
|
-
run: (...args) => runMock(...args),
|
|
19
|
-
}));
|
|
20
|
-
|
|
21
|
-
describe('veiledVariants', () => {
|
|
22
|
-
it('returns 15 masked queries', async () => {
|
|
23
|
-
const result = await veiledVariants({ prompt: 'secret' });
|
|
24
|
-
expect(Array.isArray(result)).toBe(true);
|
|
25
|
-
expect(result.length).toBe(15);
|
|
26
|
-
expect(runMock).toHaveBeenCalledTimes(3);
|
|
27
|
-
runMock.mock.calls.forEach((callArgs) => {
|
|
28
|
-
expect(callArgs[1]).toStrictEqual({ modelOptions: { modelName: 'privacy' } });
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('allows overriding model name', async () => {
|
|
33
|
-
runMock.mockClear();
|
|
34
|
-
call = 0;
|
|
35
|
-
await veiledVariants({ prompt: 'secret', modelName: 'fastGood' });
|
|
36
|
-
runMock.mock.calls.forEach((callArgs) => {
|
|
37
|
-
expect(callArgs[1]).toStrictEqual({ modelOptions: { modelName: 'fastGood' } });
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
});
|
package/src/constants/common.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export const longTestTimeout = 10 * 60 * 1000; // 10 minutes
|
|
2
|
-
|
|
3
|
-
export const maxRetries = 3;
|
|
4
|
-
|
|
5
|
-
export const retryDelay = 1000;
|
|
6
|
-
|
|
7
|
-
export const debugToObject = process.env.DEBUG_TO_OBJECT ?? false;
|
|
8
|
-
|
|
9
|
-
// Utility to conditionally skip long-running examples
|
|
10
|
-
// Set ENABLE_LONG_EXAMPLES=true to run all examples
|
|
11
|
-
// Set ENABLE_LONG_EXAMPLES=false or leave unset to skip long examples
|
|
12
|
-
export const shouldRunLongExamples =
|
|
13
|
-
process.env.ENABLE_LONG_EXAMPLES === 'true' || process.env.ENABLE_LONG_EXAMPLES === '1';
|