@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
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import intersection from './index.js';
|
|
3
|
-
|
|
4
|
-
vi.mock('../../lib/chatgpt/index.js', () => ({
|
|
5
|
-
default: vi.fn(async (prompt) => {
|
|
6
|
-
console.log('Mock received prompt:', prompt);
|
|
7
|
-
// Look for quoted items in the prompt
|
|
8
|
-
const match = prompt.match(/"([^"]+)"/);
|
|
9
|
-
if (match) {
|
|
10
|
-
const itemsLine = match[1];
|
|
11
|
-
const items = itemsLine.split(' | ');
|
|
12
|
-
const commonalities = items.map((item) => `common: ${item}`);
|
|
13
|
-
// Add combinations
|
|
14
|
-
for (let i = 0; i < items.length; i++) {
|
|
15
|
-
for (let j = i + 1; j < items.length; j++) {
|
|
16
|
-
commonalities.push(`common: ${items[i]} | ${items[j]}`);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
// Add all items combination
|
|
20
|
-
if (items.length > 2) {
|
|
21
|
-
commonalities.push(`common: ${items.join(' | ')}`);
|
|
22
|
-
}
|
|
23
|
-
console.log('Mock returning:', JSON.stringify(commonalities));
|
|
24
|
-
return JSON.stringify(commonalities);
|
|
25
|
-
}
|
|
26
|
-
console.log('Mock: no match found, returning empty array');
|
|
27
|
-
return JSON.stringify([]);
|
|
28
|
-
}),
|
|
29
|
-
}));
|
|
30
|
-
|
|
31
|
-
describe('intersection verblet', () => {
|
|
32
|
-
it('describes commonalities between sets', async () => {
|
|
33
|
-
const result = await intersection(['a', 'b', 'c']);
|
|
34
|
-
expect(result).toStrictEqual([
|
|
35
|
-
'common: a',
|
|
36
|
-
'common: b',
|
|
37
|
-
'common: c',
|
|
38
|
-
'common: a | b',
|
|
39
|
-
'common: a | c',
|
|
40
|
-
'common: b | c',
|
|
41
|
-
'common: a | b | c',
|
|
42
|
-
]);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('includes custom instructions in the prompt', async () => {
|
|
46
|
-
const chatGPT = (await import('../../lib/chatgpt/index.js')).default;
|
|
47
|
-
await intersection(['x', 'y', 'z'], { instructions: 'focus on features' });
|
|
48
|
-
expect(chatGPT).toHaveBeenCalledWith(
|
|
49
|
-
expect.stringContaining('focus on features'),
|
|
50
|
-
expect.any(Object)
|
|
51
|
-
);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('returns empty array when model returns empty response', async () => {
|
|
55
|
-
const chatGPT = (await import('../../lib/chatgpt/index.js')).default;
|
|
56
|
-
chatGPT.mockResolvedValueOnce('[]');
|
|
57
|
-
const result = await intersection(['x', 'y']);
|
|
58
|
-
expect(result).toStrictEqual([]);
|
|
59
|
-
});
|
|
60
|
-
});
|
|
@@ -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 common features, instances, or relational links shared by all items",
|
|
8
|
-
"items": {
|
|
9
|
-
"type": "string",
|
|
10
|
-
"description": "A common feature, instance, or relational link"
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
"required": ["items"],
|
|
15
|
-
"additionalProperties": false
|
|
16
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# list-expand
|
|
2
|
-
|
|
3
|
-
Generate additional items that fit naturally with the given list. The function sends the provided items to ChatGPT and requests more entries of the same kind, returning the expanded list.
|
|
4
|
-
|
|
5
|
-
```javascript
|
|
6
|
-
import listExpand from './index.js';
|
|
7
|
-
|
|
8
|
-
await listExpand(['red', 'green'], 5);
|
|
9
|
-
// => ['red', 'green', 'blue', 'yellow', 'purple']
|
|
10
|
-
```
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import listExpand from './index.js';
|
|
3
|
-
import { longTestTimeout } from '../../constants/common.js';
|
|
4
|
-
|
|
5
|
-
describe('list-expand examples', () => {
|
|
6
|
-
it(
|
|
7
|
-
'expands a short list of fruits',
|
|
8
|
-
async () => {
|
|
9
|
-
const result = await listExpand(['apple', 'banana'], 5);
|
|
10
|
-
expect(result.length).toBeGreaterThanOrEqual(5);
|
|
11
|
-
},
|
|
12
|
-
longTestTimeout
|
|
13
|
-
);
|
|
14
|
-
});
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import chatGPT from '../../lib/chatgpt/index.js';
|
|
5
|
-
import wrapVariable from '../../prompts/wrap-variable.js';
|
|
6
|
-
|
|
7
|
-
// Get the directory of this module
|
|
8
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
-
const __dirname = path.dirname(__filename);
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Load the JSON schema for list expand results
|
|
13
|
-
* @returns {Promise<Object>} JSON schema for validation
|
|
14
|
-
*/
|
|
15
|
-
async function getListExpandSchema() {
|
|
16
|
-
const schemaPath = path.join(__dirname, 'list-expand-result.json');
|
|
17
|
-
return JSON.parse(await fs.readFile(schemaPath, 'utf8'));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Create model options for structured outputs
|
|
22
|
-
* @param {string|Object} llm - LLM model name or configuration object
|
|
23
|
-
* @returns {Promise<Object>} Model options for chatGPT
|
|
24
|
-
*/
|
|
25
|
-
async function createModelOptions(llm = 'fastGoodCheap') {
|
|
26
|
-
const schema = await getListExpandSchema();
|
|
27
|
-
|
|
28
|
-
const responseFormat = {
|
|
29
|
-
type: 'json_schema',
|
|
30
|
-
json_schema: {
|
|
31
|
-
name: 'list_expand_result',
|
|
32
|
-
schema,
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
if (typeof llm === 'string') {
|
|
37
|
-
return {
|
|
38
|
-
modelName: llm,
|
|
39
|
-
response_format: responseFormat,
|
|
40
|
-
};
|
|
41
|
-
} else {
|
|
42
|
-
return {
|
|
43
|
-
...llm,
|
|
44
|
-
response_format: responseFormat,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// TODO: This could potentially be refactored to use the list chain (../../chains/list/index.js)
|
|
50
|
-
// for better consistency, but would require adapting the list chain to support this simpler
|
|
51
|
-
// expansion use case without changing the current behavior and test expectations.
|
|
52
|
-
|
|
53
|
-
const buildPrompt = function (list, count) {
|
|
54
|
-
const listBlock = wrapVariable(list.join('\n'), { tag: 'list' });
|
|
55
|
-
return (
|
|
56
|
-
`Expand <list> with new items that belong to the same category and ` +
|
|
57
|
-
`match the style of the existing entries. Avoid duplicates or extraneous ` +
|
|
58
|
-
`text. Continue adding entries until there are at least ${count} in total. ` +
|
|
59
|
-
`Return a JSON object with an "items" array containing all the expanded items.\n\n${listBlock}`
|
|
60
|
-
);
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Expand a list with new items that belong to the same category and match the style.
|
|
65
|
-
* This is a simplified interface to the list chain for expansion use cases.
|
|
66
|
-
*
|
|
67
|
-
* @param {string[]} existingList - The list to expand
|
|
68
|
-
* @param {number} targetCount - Target total count (default: double the input)
|
|
69
|
-
* @param {Object} config - Configuration options including llm settings
|
|
70
|
-
* @returns {Promise<string[]>} Expanded list
|
|
71
|
-
*/
|
|
72
|
-
export default async function listExpand(list, count = list.length * 2, config = {}) {
|
|
73
|
-
const { llm, ...options } = config;
|
|
74
|
-
const modelOptions = await createModelOptions(llm);
|
|
75
|
-
const output = await chatGPT(buildPrompt(list, count), { modelOptions, ...options });
|
|
76
|
-
|
|
77
|
-
// With structured outputs, response should already be parsed and validated
|
|
78
|
-
let parsed;
|
|
79
|
-
if (typeof output === 'string') {
|
|
80
|
-
try {
|
|
81
|
-
parsed = JSON.parse(output);
|
|
82
|
-
} catch {
|
|
83
|
-
// Handle non-JSON responses (e.g., from mocks or fallback cases)
|
|
84
|
-
// Split by newlines and filter out empty lines
|
|
85
|
-
const lines = output
|
|
86
|
-
.split('\n')
|
|
87
|
-
.map((line) => line.trim())
|
|
88
|
-
.filter((line) => line.length > 0);
|
|
89
|
-
parsed = { items: lines };
|
|
90
|
-
}
|
|
91
|
-
} else {
|
|
92
|
-
parsed = output;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Extract items from the object structure
|
|
96
|
-
const items = parsed?.items || parsed;
|
|
97
|
-
|
|
98
|
-
if (!Array.isArray(items)) {
|
|
99
|
-
console.warn('Expected items array, got:', typeof items);
|
|
100
|
-
return [];
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return items;
|
|
104
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import listExpand from './index.js';
|
|
3
|
-
|
|
4
|
-
vi.mock('../../lib/chatgpt/index.js', () => ({
|
|
5
|
-
default: vi.fn(async (prompt) => {
|
|
6
|
-
const match = prompt.match(/<list>\n([\s\S]*?)\n<\/list>/);
|
|
7
|
-
const lines = match ? match[1].split('\n') : [];
|
|
8
|
-
const extras = lines.map((l) => `${l}-extra`);
|
|
9
|
-
return [...lines, ...extras].join('\n');
|
|
10
|
-
}),
|
|
11
|
-
}));
|
|
12
|
-
|
|
13
|
-
describe('list-expand verblet', () => {
|
|
14
|
-
it('expands items to at least the requested count', async () => {
|
|
15
|
-
const result = await listExpand(['alpha', 'beta'], 4);
|
|
16
|
-
expect(result).toStrictEqual(['alpha', 'beta', 'alpha-extra', 'beta-extra']);
|
|
17
|
-
});
|
|
18
|
-
});
|
|
@@ -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 expanded list items",
|
|
8
|
-
"items": {
|
|
9
|
-
"type": "string",
|
|
10
|
-
"description": "A list item that belongs to the same category and matches the style"
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
"required": ["items"],
|
|
15
|
-
"additionalProperties": false
|
|
16
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# list-filter
|
|
2
|
-
|
|
3
|
-
Filter a list with a single ChatGPT call using custom instructions.
|
|
4
|
-
|
|
5
|
-
```javascript
|
|
6
|
-
import listFilter from './index.js';
|
|
7
|
-
|
|
8
|
-
const reflections = [
|
|
9
|
-
'Losing that match taught me the value of persistence.',
|
|
10
|
-
"I hate losing and it proves I'm worthless.",
|
|
11
|
-
'After failing my exam, I studied harder and passed the retake.',
|
|
12
|
-
"No matter what I do, I'll never succeed.",
|
|
13
|
-
];
|
|
14
|
-
const growth = await listFilter(
|
|
15
|
-
reflections,
|
|
16
|
-
'keep only reflections that show personal growth or learning from mistakes'
|
|
17
|
-
);
|
|
18
|
-
// => [
|
|
19
|
-
// 'Losing that match taught me the value of persistence.',
|
|
20
|
-
// 'After failing my exam, I studied harder and passed the retake.',
|
|
21
|
-
// ]
|
|
22
|
-
```
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import listFilter from './index.js';
|
|
3
|
-
import { longTestTimeout } from '../../constants/common.js';
|
|
4
|
-
|
|
5
|
-
describe('list-filter examples', () => {
|
|
6
|
-
it(
|
|
7
|
-
'filters items with custom instructions',
|
|
8
|
-
async () => {
|
|
9
|
-
const entries = [
|
|
10
|
-
'Losing that match taught me the value of persistence.',
|
|
11
|
-
"I hate losing and it proves I'm worthless.",
|
|
12
|
-
'After failing my exam, I studied harder and passed the retake.',
|
|
13
|
-
"No matter what I do, I'll never succeed.",
|
|
14
|
-
];
|
|
15
|
-
const result = await listFilter(
|
|
16
|
-
entries,
|
|
17
|
-
'keep only reflections that show personal growth or learning from mistakes'
|
|
18
|
-
);
|
|
19
|
-
expect(result).toStrictEqual([
|
|
20
|
-
'Losing that match taught me the value of persistence.',
|
|
21
|
-
'After failing my exam, I studied harder and passed the retake.',
|
|
22
|
-
]);
|
|
23
|
-
},
|
|
24
|
-
longTestTimeout
|
|
25
|
-
);
|
|
26
|
-
});
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import chatGPT from '../../lib/chatgpt/index.js';
|
|
2
|
-
import wrapVariable from '../../prompts/wrap-variable.js';
|
|
3
|
-
|
|
4
|
-
function buildPrompt(list, instructions) {
|
|
5
|
-
const instructionsBlock = wrapVariable(instructions, { tag: 'instructions' });
|
|
6
|
-
const listBlock = wrapVariable(list.join('\n'), { tag: 'list' });
|
|
7
|
-
return `From the <list>, select only the items that satisfy the <instructions>. Return one item per line without numbering. If none match, return an empty string.\n\n${instructionsBlock}\n${listBlock}`;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export default async function listFilter(list, instructions, config = {}) {
|
|
11
|
-
const { llm, ...options } = config;
|
|
12
|
-
const output = await chatGPT(buildPrompt(list, instructions), {
|
|
13
|
-
modelOptions: { ...llm },
|
|
14
|
-
...options,
|
|
15
|
-
});
|
|
16
|
-
const trimmed = output.trim();
|
|
17
|
-
return trimmed ? trimmed.split('\n') : [];
|
|
18
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import listFilter from './index.js';
|
|
3
|
-
|
|
4
|
-
vi.mock('../../lib/chatgpt/index.js', () => ({
|
|
5
|
-
default: vi.fn(async (prompt) => {
|
|
6
|
-
const listMatch = prompt.match(/<list>\n([\s\S]*?)\n<\/list>/);
|
|
7
|
-
const lines = listMatch ? listMatch[1].split('\n') : [];
|
|
8
|
-
const instMatch = prompt.match(/"([^"]+)"/);
|
|
9
|
-
const letter = instMatch ? instMatch[1] : '';
|
|
10
|
-
return lines.filter((l) => l.includes(letter)).join('\n');
|
|
11
|
-
}),
|
|
12
|
-
}));
|
|
13
|
-
|
|
14
|
-
describe('list-filter verblet', () => {
|
|
15
|
-
it('filters items using instructions', async () => {
|
|
16
|
-
const result = await listFilter(['alpha', 'beta', 'gamma'], 'm');
|
|
17
|
-
expect(result).toStrictEqual(['gamma']);
|
|
18
|
-
});
|
|
19
|
-
});
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# list-find
|
|
2
|
-
|
|
3
|
-
Find the single best match in a list using natural language instructions.
|
|
4
|
-
|
|
5
|
-
```javascript
|
|
6
|
-
import listFind from './index.js';
|
|
7
|
-
|
|
8
|
-
const snacks = ['apple pie', 'fruit roll-up', 'carrot sticks'];
|
|
9
|
-
await listFind(snacks, 'which snack feels most nostalgic for kids of the 90s?');
|
|
10
|
-
// => 'fruit roll-up'
|
|
11
|
-
```
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import listFind from './index.js';
|
|
3
|
-
import { longTestTimeout } from '../../constants/common.js';
|
|
4
|
-
|
|
5
|
-
describe('list-find examples', () => {
|
|
6
|
-
it(
|
|
7
|
-
'finds the item that best fits the instructions',
|
|
8
|
-
async () => {
|
|
9
|
-
const books = ['space adventure', 'medieval romance', 'futuristic mystery'];
|
|
10
|
-
const result = await listFind(books, 'which book sounds most futuristic?');
|
|
11
|
-
expect(result).toBeDefined();
|
|
12
|
-
},
|
|
13
|
-
longTestTimeout
|
|
14
|
-
);
|
|
15
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import chatGPT from '../../lib/chatgpt/index.js';
|
|
2
|
-
import wrapVariable from '../../prompts/wrap-variable.js';
|
|
3
|
-
|
|
4
|
-
const buildPrompt = (list, instructions) => {
|
|
5
|
-
const instructionsBlock = wrapVariable(instructions, { tag: 'instructions' });
|
|
6
|
-
const listBlock = wrapVariable(list.join('\n'), { tag: 'list' });
|
|
7
|
-
return `From the <list>, select the single item that best satisfies the <instructions>. If none apply, return an empty string.\n\n${instructionsBlock}\n${listBlock}`;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export default async function listFind(list, instructions, config = {}) {
|
|
11
|
-
const { llm, ...options } = config;
|
|
12
|
-
const output = await chatGPT(buildPrompt(list, instructions), {
|
|
13
|
-
modelOptions: { ...llm },
|
|
14
|
-
...options,
|
|
15
|
-
});
|
|
16
|
-
return output.trim();
|
|
17
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import listFind from './index.js';
|
|
3
|
-
|
|
4
|
-
vi.mock('../../lib/chatgpt/index.js', () => ({
|
|
5
|
-
default: vi.fn(async (prompt) => {
|
|
6
|
-
const listMatch = prompt.match(/<list>\n([\s\S]*?)\n<\/list>/);
|
|
7
|
-
const lines = listMatch ? listMatch[1].split('\n') : [];
|
|
8
|
-
const parts = prompt.split('"');
|
|
9
|
-
const letter = [...parts].reverse().find((p) => /^[a-z]+$/i.test(p.trim())) || '';
|
|
10
|
-
return lines.find((l) => l.includes(letter)) || '';
|
|
11
|
-
}),
|
|
12
|
-
}));
|
|
13
|
-
|
|
14
|
-
describe('list-find verblet', () => {
|
|
15
|
-
it('finds item using instructions', async () => {
|
|
16
|
-
const result = await listFind(['alpha', 'beta', 'gamma'], 'find "b"');
|
|
17
|
-
expect(result).toBe('beta');
|
|
18
|
-
});
|
|
19
|
-
});
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# list-group
|
|
2
|
-
|
|
3
|
-
Group a list into stable groups using custom instructions. Optionally
|
|
4
|
-
provide a list of categories to maintain consistency across runs.
|
|
5
|
-
|
|
6
|
-
```javascript
|
|
7
|
-
import listGroup from './index.js';
|
|
8
|
-
|
|
9
|
-
const categories = ['fruit', 'vegetable'];
|
|
10
|
-
await listGroup(
|
|
11
|
-
['apple', 'banana', 'carrot'],
|
|
12
|
-
'Classify each item',
|
|
13
|
-
categories
|
|
14
|
-
);
|
|
15
|
-
// => { fruit: ['apple', 'banana'], vegetable: ['carrot'] }
|
|
16
|
-
```
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import listGroup from './index.js';
|
|
3
|
-
import { longTestTimeout } from '../../constants/common.js';
|
|
4
|
-
|
|
5
|
-
describe('list-group examples', () => {
|
|
6
|
-
it(
|
|
7
|
-
'groups a list into categories',
|
|
8
|
-
async () => {
|
|
9
|
-
const items = ['apple', 'beer', 'orange', 'wine', 'banana'];
|
|
10
|
-
const result = await listGroup(items, 'Group as drinks or food', ['drink', 'food']);
|
|
11
|
-
expect(typeof result).toBe('object');
|
|
12
|
-
expect(Object.keys(result).length).toBeGreaterThan(0);
|
|
13
|
-
},
|
|
14
|
-
longTestTimeout
|
|
15
|
-
);
|
|
16
|
-
});
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import chatGPT from '../../lib/chatgpt/index.js';
|
|
5
|
-
import wrapVariable from '../../prompts/wrap-variable.js';
|
|
6
|
-
|
|
7
|
-
// Get the directory of this module
|
|
8
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
-
const __dirname = path.dirname(__filename);
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Load the JSON schema for list group results
|
|
13
|
-
* @returns {Promise<Object>} JSON schema for validation
|
|
14
|
-
*/
|
|
15
|
-
async function getListGroupSchema() {
|
|
16
|
-
const schemaPath = path.join(__dirname, 'list-group-result.json');
|
|
17
|
-
return JSON.parse(await fs.readFile(schemaPath, 'utf8'));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Create model options for structured outputs
|
|
22
|
-
* @param {string|Object} llm - LLM model name or configuration object
|
|
23
|
-
* @returns {Promise<Object>} Model options for chatGPT
|
|
24
|
-
*/
|
|
25
|
-
async function createModelOptions(llm = 'fastGoodCheap') {
|
|
26
|
-
const schema = await getListGroupSchema();
|
|
27
|
-
|
|
28
|
-
const responseFormat = {
|
|
29
|
-
type: 'json_schema',
|
|
30
|
-
json_schema: {
|
|
31
|
-
name: 'list_group_result',
|
|
32
|
-
schema,
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
if (typeof llm === 'string') {
|
|
37
|
-
return {
|
|
38
|
-
modelName: llm,
|
|
39
|
-
response_format: responseFormat,
|
|
40
|
-
};
|
|
41
|
-
} else {
|
|
42
|
-
return {
|
|
43
|
-
...llm,
|
|
44
|
-
response_format: responseFormat,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const buildPrompt = (list, instructions, categories) => {
|
|
50
|
-
const instructionsBlock = wrapVariable(instructions, { tag: 'instructions' });
|
|
51
|
-
const listBlock = wrapVariable(list.join('\n'), { tag: 'list' });
|
|
52
|
-
const categoryBlock =
|
|
53
|
-
categories && categories.length
|
|
54
|
-
? `${wrapVariable(categories.join('\n'), { tag: 'categories' })}\n`
|
|
55
|
-
: '';
|
|
56
|
-
const categoryText = categories && categories.length ? 'one of the <categories>' : 'a group';
|
|
57
|
-
|
|
58
|
-
return `Assign each line in <list> to ${categoryText} according to <instructions>.
|
|
59
|
-
|
|
60
|
-
Return a JSON object with a "labels" array containing exactly ${list.length} group names, one for each item in the same order as the input list.
|
|
61
|
-
|
|
62
|
-
${instructionsBlock}
|
|
63
|
-
${categoryBlock}${listBlock}
|
|
64
|
-
|
|
65
|
-
Output format: {"labels": [array with exactly ${list.length} group names]}`;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export default async function listGroup(list, instructions, categories, config = {}) {
|
|
69
|
-
const { llm, ...options } = config;
|
|
70
|
-
const modelOptions = await createModelOptions(llm);
|
|
71
|
-
const output = await chatGPT(buildPrompt(list, instructions, categories), {
|
|
72
|
-
modelOptions,
|
|
73
|
-
...options,
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
// With structured outputs, response should already be parsed and validated
|
|
77
|
-
let parsed;
|
|
78
|
-
if (typeof output === 'string') {
|
|
79
|
-
try {
|
|
80
|
-
parsed = JSON.parse(output);
|
|
81
|
-
} catch {
|
|
82
|
-
// Handle non-JSON responses (e.g., from mocks or fallback cases)
|
|
83
|
-
// Split by newlines and filter out empty lines
|
|
84
|
-
const lines = output
|
|
85
|
-
.split('\n')
|
|
86
|
-
.map((line) => line.trim())
|
|
87
|
-
.filter((line) => line.length > 0);
|
|
88
|
-
parsed = { labels: lines };
|
|
89
|
-
}
|
|
90
|
-
} else {
|
|
91
|
-
parsed = output;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Extract labels from the object structure
|
|
95
|
-
const labels = parsed?.labels || parsed;
|
|
96
|
-
|
|
97
|
-
if (!Array.isArray(labels) || labels.length !== list.length) {
|
|
98
|
-
console.warn(`Expected ${list.length} labels, got ${labels?.length || 0}`);
|
|
99
|
-
// Fallback to default labels if parsing fails
|
|
100
|
-
return { other: [...list] };
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Group items by their labels
|
|
104
|
-
const result = {};
|
|
105
|
-
labels.forEach((label, idx) => {
|
|
106
|
-
const key = String(label).trim() || 'other';
|
|
107
|
-
if (!result[key]) result[key] = [];
|
|
108
|
-
result[key].push(list[idx]);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
return result;
|
|
112
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import listGroup from './index.js';
|
|
2
|
-
import { vi, describe, it, expect } from 'vitest';
|
|
3
|
-
|
|
4
|
-
vi.mock('../../lib/chatgpt/index.js', () => ({
|
|
5
|
-
default: vi.fn(() => 'odd\neven\nodd'),
|
|
6
|
-
}));
|
|
7
|
-
|
|
8
|
-
const examples = [
|
|
9
|
-
{
|
|
10
|
-
inputs: {
|
|
11
|
-
list: ['a', 'bb', 'ccc'],
|
|
12
|
-
instructions: 'odd or even length',
|
|
13
|
-
categories: ['odd', 'even'],
|
|
14
|
-
},
|
|
15
|
-
want: { result: { odd: ['a', 'ccc'], even: ['bb'] } },
|
|
16
|
-
},
|
|
17
|
-
];
|
|
18
|
-
|
|
19
|
-
describe('list-group verblet', () => {
|
|
20
|
-
it('groups items using instructions', async () => {
|
|
21
|
-
const result = await listGroup(['a', 'bb', 'ccc'], 'odd or even length', ['odd', 'even']);
|
|
22
|
-
expect(result).toStrictEqual({ odd: ['a', 'ccc'], even: ['bb'] });
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
examples.forEach((example) => {
|
|
26
|
-
it(example.inputs.instructions, async () => {
|
|
27
|
-
const result = await listGroup(
|
|
28
|
-
example.inputs.list,
|
|
29
|
-
example.inputs.instructions,
|
|
30
|
-
example.inputs.categories
|
|
31
|
-
);
|
|
32
|
-
expect(result).toStrictEqual(example.want.result);
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
});
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"type": "object",
|
|
4
|
-
"properties": {
|
|
5
|
-
"labels": {
|
|
6
|
-
"type": "array",
|
|
7
|
-
"description": "Array of group labels corresponding to input items in the same order",
|
|
8
|
-
"items": {
|
|
9
|
-
"type": "string",
|
|
10
|
-
"description": "Group label for the corresponding item"
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
"required": ["labels"],
|
|
15
|
-
"additionalProperties": false
|
|
16
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# list-map
|
|
2
|
-
|
|
3
|
-
Transform a list with a single ChatGPT call by providing mapping instructions.
|
|
4
|
-
The function hides the boilerplate prompting so you only supply the instructions.
|
|
5
|
-
|
|
6
|
-
```javascript
|
|
7
|
-
import { listMap } from '../../index.js';
|
|
8
|
-
|
|
9
|
-
await listMap(['Budget smartphone', 'Luxury watch'], 'Write a short playful tagline');
|
|
10
|
-
// => ['Affordable tech for everyone', 'Elegance that tells time']
|
|
11
|
-
```
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import listMap from './index.js';
|
|
3
|
-
import { longTestTimeout } from '../../constants/common.js';
|
|
4
|
-
|
|
5
|
-
describe('list-map examples', () => {
|
|
6
|
-
it(
|
|
7
|
-
'maps creative slogans',
|
|
8
|
-
async () => {
|
|
9
|
-
const items = ['smart toaster', 'robot vacuum'];
|
|
10
|
-
const result = await listMap(items, 'Give a playful marketing slogan');
|
|
11
|
-
expect(result.length).toBe(2);
|
|
12
|
-
},
|
|
13
|
-
longTestTimeout
|
|
14
|
-
);
|
|
15
|
-
});
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import chatGPT from '../../lib/chatgpt/index.js';
|
|
2
|
-
import wrapVariable from '../../prompts/wrap-variable.js';
|
|
3
|
-
|
|
4
|
-
const buildPrompt = function (list, instructions) {
|
|
5
|
-
const instructionsBlock = wrapVariable(instructions, { tag: 'instructions' });
|
|
6
|
-
const listBlock = wrapVariable(list.join('\n'), { tag: 'list' });
|
|
7
|
-
return `For each line in <list>, apply the <instructions> to transform it.\nReturn the same number of lines without numbering.\n\n${instructionsBlock}\n${listBlock}`;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export default async function listMap(list, instructions, config = {}) {
|
|
11
|
-
const { llm, ...options } = config;
|
|
12
|
-
const output = await chatGPT(buildPrompt(list, instructions), {
|
|
13
|
-
modelOptions: { ...llm },
|
|
14
|
-
...options,
|
|
15
|
-
});
|
|
16
|
-
const lines = output
|
|
17
|
-
.split('\n')
|
|
18
|
-
.map((line) => line.trim())
|
|
19
|
-
.filter((line) => line.length > 0);
|
|
20
|
-
if (lines.length !== list.length) {
|
|
21
|
-
throw new Error(
|
|
22
|
-
`Batch output line count mismatch (expected ${list.length}, got ${lines.length})`
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
return lines;
|
|
26
|
-
}
|