@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/DEVELOPING.md
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
# Developing Verblets
|
|
2
|
-
|
|
3
|
-
This document explains the development workflow and testing strategy for the Verblets library.
|
|
4
|
-
|
|
5
|
-
## Testing Strategy
|
|
6
|
-
|
|
7
|
-
The Verblets library uses a dual testing approach with two types of test files:
|
|
8
|
-
|
|
9
|
-
### 1. Spec Files (`*.spec.js`)
|
|
10
|
-
- **Purpose**: Deterministic unit tests with mocked LLM responses
|
|
11
|
-
- **Reliability**: Should always pass consistently
|
|
12
|
-
- **LLM Usage**: Uses mocked responses, no actual API calls
|
|
13
|
-
- **Caching**: Uses in-memory `NullRedisClient` or local mocking (no Redis required)
|
|
14
|
-
- **Speed**: Fast execution
|
|
15
|
-
- **Use Case**: CI/CD, development validation, regression testing
|
|
16
|
-
|
|
17
|
-
### 2. Example Files (`*.examples.js`)
|
|
18
|
-
- **Purpose**: Non-deterministic integration tests with real LLM calls
|
|
19
|
-
- **Reliability**: May fail due to LLM response variability
|
|
20
|
-
- **LLM Usage**: Makes actual API calls to language models
|
|
21
|
-
- **Caching**: Uses Redis for response caching (when available)
|
|
22
|
-
- **Speed**: Slower due to network calls (mitigated by caching)
|
|
23
|
-
- **Use Case**: Manual testing, demonstrating real-world usage, validating LLM integration
|
|
24
|
-
|
|
25
|
-
## Environment Configuration
|
|
26
|
-
|
|
27
|
-
### Spec Tests
|
|
28
|
-
```bash
|
|
29
|
-
npm test # Runs spec tests with mocked responses
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Example Tests
|
|
33
|
-
```bash
|
|
34
|
-
npm run examples # Runs example tests with real LLM calls
|
|
35
|
-
EXAMPLES=true npm run examples # Automatically set, enables Redis caching
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### Caching Control
|
|
39
|
-
```bash
|
|
40
|
-
# Disable caching for all LLM calls (forces fresh API calls)
|
|
41
|
-
DISABLE_CACHE=true npm run examples
|
|
42
|
-
|
|
43
|
-
# Enable caching (default behavior when Redis is available)
|
|
44
|
-
npm run examples
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Caching System
|
|
48
|
-
|
|
49
|
-
### Redis Caching for Examples
|
|
50
|
-
- Example tests use Redis to cache LLM responses based on prompt content
|
|
51
|
-
- Cached responses reduce API costs and improve test speed
|
|
52
|
-
- Falls back to in-memory caching if Redis is unavailable
|
|
53
|
-
|
|
54
|
-
### Cache Behavior
|
|
55
|
-
- **Cache Hit**: Returns cached response instantly
|
|
56
|
-
- **Cache Miss**: Makes LLM API call and caches the response
|
|
57
|
-
- **TTL**: Cached responses expire after 365 days (configurable via `CHATGPT_CACHE_TTL`)
|
|
58
|
-
- **Fallback**: Gracefully handles Redis connection failures
|
|
59
|
-
|
|
60
|
-
## Development Workflow
|
|
61
|
-
|
|
62
|
-
### Adding New Verblets or Chains
|
|
63
|
-
|
|
64
|
-
When creating a new verblet or chain, you should add both types of tests:
|
|
65
|
-
|
|
66
|
-
#### 1. Create Spec File (`index.spec.js`)
|
|
67
|
-
```javascript
|
|
68
|
-
import { describe, expect, it } from 'vitest';
|
|
69
|
-
import myVerblet from './index.js';
|
|
70
|
-
|
|
71
|
-
const examples = [
|
|
72
|
-
{
|
|
73
|
-
inputs: { text: 'test input' },
|
|
74
|
-
want: { result: 'expected output' },
|
|
75
|
-
},
|
|
76
|
-
];
|
|
77
|
-
|
|
78
|
-
describe('My Verblet', () => {
|
|
79
|
-
examples.forEach((example) => {
|
|
80
|
-
it(example.inputs.text, async () => {
|
|
81
|
-
const result = await myVerblet(example.inputs.text);
|
|
82
|
-
expect(result).toStrictEqual(example.want.result);
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
#### 2. Create Example File (`index.examples.js`)
|
|
89
|
-
```javascript
|
|
90
|
-
import { describe, expect, it } from 'vitest';
|
|
91
|
-
import myVerblet from './index.js';
|
|
92
|
-
import { longTestTimeout } from '../../constants/common.js';
|
|
93
|
-
|
|
94
|
-
describe('My Verblet Examples', () => {
|
|
95
|
-
it(
|
|
96
|
-
'processes real input',
|
|
97
|
-
async () => {
|
|
98
|
-
const result = await myVerblet('What is the capital of France?');
|
|
99
|
-
expect(typeof result).toBe('string');
|
|
100
|
-
expect(result.length).toBeGreaterThan(0);
|
|
101
|
-
},
|
|
102
|
-
longTestTimeout
|
|
103
|
-
);
|
|
104
|
-
});
|
|
105
|
-
```
|
package/docker-compose.yml
DELETED
package/eslint.config.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import js from '@eslint/js';
|
|
2
|
-
import prettierConfig from 'eslint-config-prettier';
|
|
3
|
-
import prettierPlugin from 'eslint-plugin-prettier';
|
|
4
|
-
|
|
5
|
-
export default [
|
|
6
|
-
js.configs.recommended,
|
|
7
|
-
{
|
|
8
|
-
files: ['src/**/*.js'],
|
|
9
|
-
languageOptions: {
|
|
10
|
-
ecmaVersion: 2022,
|
|
11
|
-
sourceType: 'module',
|
|
12
|
-
globals: {
|
|
13
|
-
console: 'readonly',
|
|
14
|
-
process: 'readonly',
|
|
15
|
-
Buffer: 'readonly',
|
|
16
|
-
__dirname: 'readonly',
|
|
17
|
-
__filename: 'readonly',
|
|
18
|
-
URL: 'readonly',
|
|
19
|
-
AbortController: 'readonly',
|
|
20
|
-
fetch: 'readonly',
|
|
21
|
-
setTimeout: 'readonly',
|
|
22
|
-
clearTimeout: 'readonly',
|
|
23
|
-
setInterval: 'readonly',
|
|
24
|
-
clearInterval: 'readonly',
|
|
25
|
-
// Vitest
|
|
26
|
-
beforeEach: 'readonly',
|
|
27
|
-
afterEach: 'readonly',
|
|
28
|
-
describe: 'readonly',
|
|
29
|
-
it: 'readonly',
|
|
30
|
-
expect: 'readonly',
|
|
31
|
-
vi: 'readonly',
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
linterOptions: {
|
|
35
|
-
reportUnusedDisableDirectives: false,
|
|
36
|
-
},
|
|
37
|
-
plugins: {
|
|
38
|
-
prettier: prettierPlugin,
|
|
39
|
-
},
|
|
40
|
-
rules: {
|
|
41
|
-
'prettier/prettier': 'error',
|
|
42
|
-
|
|
43
|
-
// TODO: Remove console statements and replace with proper logging
|
|
44
|
-
'no-console': 'off',
|
|
45
|
-
|
|
46
|
-
// TODO: Refactor await-in-loop patterns to use Promise.all()
|
|
47
|
-
'no-await-in-loop': 'off',
|
|
48
|
-
|
|
49
|
-
// Customize recommended rules
|
|
50
|
-
'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
|
51
|
-
|
|
52
|
-
// Additional quality rules not in recommended
|
|
53
|
-
'require-await': 'error',
|
|
54
|
-
'prefer-arrow-callback': 'error',
|
|
55
|
-
'prefer-template': 'error',
|
|
56
|
-
'object-shorthand': 'error',
|
|
57
|
-
'array-callback-return': 'error',
|
|
58
|
-
|
|
59
|
-
// Syntax restrictions
|
|
60
|
-
'no-restricted-syntax': [
|
|
61
|
-
'error',
|
|
62
|
-
{
|
|
63
|
-
selector: 'ForInStatement',
|
|
64
|
-
message: 'Use Object.{keys,values,entries} instead of for..in',
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
selector: 'WithStatement',
|
|
68
|
-
message: '`with` is not allowed',
|
|
69
|
-
},
|
|
70
|
-
],
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
files: ['**/*.spec.js', '**/*.test.js'],
|
|
75
|
-
rules: {
|
|
76
|
-
'require-await': 'off', // Test functions often don't need await
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
prettierConfig,
|
|
80
|
-
];
|
package/scripts/clear-redis.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { getClient as getRedis } from '../src/services/redis/index.js';
|
|
4
|
-
|
|
5
|
-
async function clearRedisKeys() {
|
|
6
|
-
let redis = null;
|
|
7
|
-
|
|
8
|
-
try {
|
|
9
|
-
console.log('🔄 Connecting to Redis...');
|
|
10
|
-
redis = await getRedis();
|
|
11
|
-
|
|
12
|
-
// Check if this is the NullRedisClient (in-memory fallback)
|
|
13
|
-
if (redis.store !== undefined) {
|
|
14
|
-
// This is the in-memory client
|
|
15
|
-
const keyCount = Object.keys(redis.store).length;
|
|
16
|
-
if (keyCount === 0) {
|
|
17
|
-
console.log('✅ In-memory cache is already empty - no keys to clear');
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
console.log(`🗑️ Found ${keyCount} keys in in-memory cache to clear`);
|
|
22
|
-
redis.store = {};
|
|
23
|
-
console.log(`✅ Successfully cleared ${keyCount} in-memory cache keys`);
|
|
24
|
-
console.log('🧹 In-memory cache has been cleared - tests can now run with fresh responses');
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// This is the SafeRedisClient wrapper - access underlying Redis client
|
|
29
|
-
const underlyingClient = redis.redisClient;
|
|
30
|
-
if (!underlyingClient) {
|
|
31
|
-
console.log('⚠️ No underlying Redis client found - using fallback method');
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Get count of keys before clearing
|
|
36
|
-
const keys = await underlyingClient.keys('*');
|
|
37
|
-
const keyCount = keys.length;
|
|
38
|
-
|
|
39
|
-
if (keyCount === 0) {
|
|
40
|
-
console.log('✅ Redis is already empty - no keys to clear');
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
console.log(`🗑️ Found ${keyCount} keys to clear`);
|
|
45
|
-
|
|
46
|
-
// Use FLUSHDB to clear all keys in the current database
|
|
47
|
-
// This is more efficient and reliable than deleting individual keys
|
|
48
|
-
await underlyingClient.flushDb();
|
|
49
|
-
|
|
50
|
-
console.log(`✅ Successfully cleared all ${keyCount} Redis keys`);
|
|
51
|
-
console.log('🧹 Redis cache has been cleared - tests can now run with fresh responses');
|
|
52
|
-
|
|
53
|
-
} catch (error) {
|
|
54
|
-
if (error.message.includes('ECONNREFUSED') || error.message.includes('connection')) {
|
|
55
|
-
console.log('⚠️ Redis is not running or not accessible - nothing to clear');
|
|
56
|
-
console.log(' This is normal if you\'re using the in-memory cache fallback');
|
|
57
|
-
} else {
|
|
58
|
-
console.error('❌ Error clearing Redis keys:', error.message);
|
|
59
|
-
process.exit(1);
|
|
60
|
-
}
|
|
61
|
-
} finally {
|
|
62
|
-
if (redis && typeof redis.disconnect === 'function') {
|
|
63
|
-
try {
|
|
64
|
-
await redis.disconnect();
|
|
65
|
-
console.log('🔌 Disconnected from Redis');
|
|
66
|
-
} catch (disconnectError) {
|
|
67
|
-
// Ignore disconnect errors
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Run the script
|
|
74
|
-
clearRedisKeys();
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import {
|
|
4
|
-
camelCase,
|
|
5
|
-
paramCase,
|
|
6
|
-
sentenceCase,
|
|
7
|
-
} from 'change-case';
|
|
8
|
-
|
|
9
|
-
const chainName = process.argv[2];
|
|
10
|
-
|
|
11
|
-
if (!chainName) {
|
|
12
|
-
console.error('Please specify a chain name.');
|
|
13
|
-
process.exit(1);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const chainDir = `./src/chains/${paramCase(chainName)}`;
|
|
17
|
-
const indexFile = `${chainDir}/index.js`;
|
|
18
|
-
const testFile = `${chainDir}/index.spec.js`;
|
|
19
|
-
const exampleFile = `${chainDir}/index.examples.js`;
|
|
20
|
-
|
|
21
|
-
const createFileIfNotExists = (filePath, fileContent, fileType) => {
|
|
22
|
-
if (!fs.existsSync(filePath)) {
|
|
23
|
-
fs.writeFileSync(filePath, fileContent);
|
|
24
|
-
console.error(`Created new ${fileType} file: ${filePath}`);
|
|
25
|
-
} else {
|
|
26
|
-
console.error(`Creating ${fileType} file [skipped]: '${filePath}' exists`);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Check if the chain directory already exists
|
|
31
|
-
if (!fs.existsSync(chainDir)) {
|
|
32
|
-
// Create the chain directory
|
|
33
|
-
fs.mkdirSync(chainDir, { recursive: true });
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const indexContent = `
|
|
37
|
-
export default async (text) => {
|
|
38
|
-
// TODO: Implement ${paramCase(chainName)} chain
|
|
39
|
-
};
|
|
40
|
-
`;
|
|
41
|
-
createFileIfNotExists(indexFile, indexContent, 'module file');
|
|
42
|
-
|
|
43
|
-
const testContent = `import { describe, expect, it, vi } from 'vitest';
|
|
44
|
-
|
|
45
|
-
import ${camelCase(chainName)} from './index.js';
|
|
46
|
-
|
|
47
|
-
vi.mock('../../lib/chatgpt/index.js', () => ({
|
|
48
|
-
default: vi.fn().mockImplementation((text) => {
|
|
49
|
-
if (/prompt text to match/.test(text)) {
|
|
50
|
-
return 'True';
|
|
51
|
-
} else {
|
|
52
|
-
return 'undefined';
|
|
53
|
-
}
|
|
54
|
-
}),
|
|
55
|
-
}));
|
|
56
|
-
|
|
57
|
-
const examples = [
|
|
58
|
-
{
|
|
59
|
-
name: 'Basic usage',
|
|
60
|
-
inputs: { text: 'test' },
|
|
61
|
-
want: { result: true }
|
|
62
|
-
}
|
|
63
|
-
];
|
|
64
|
-
|
|
65
|
-
describe('${sentenceCase(chainName)} chain', () => {
|
|
66
|
-
examples.forEach((example) => {
|
|
67
|
-
it(example.name, async () => {
|
|
68
|
-
const result = await ${camelCase(chainName)}(example.inputs.text);
|
|
69
|
-
|
|
70
|
-
if (example.want.typeOfResult) {
|
|
71
|
-
expect(typeof result)
|
|
72
|
-
.toStrictEqual(example.want.typeOfResult);
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
`;
|
|
78
|
-
createFileIfNotExists(testFile, testContent, 'test');
|
|
79
|
-
|
|
80
|
-
const exampleContent = `import { describe, expect, it, vi } from 'vitest';
|
|
81
|
-
|
|
82
|
-
import ${camelCase(chainName)} from './index.js';
|
|
83
|
-
|
|
84
|
-
const examples = [
|
|
85
|
-
{
|
|
86
|
-
inputs: { text: 'test' },
|
|
87
|
-
want: { result: true }
|
|
88
|
-
}
|
|
89
|
-
];
|
|
90
|
-
|
|
91
|
-
describe('${sentenceCase(chainName)} chain', () => {
|
|
92
|
-
examples.forEach((example) => {
|
|
93
|
-
it(example.inputs.text, async () => {
|
|
94
|
-
const result = await ${camelCase(chainName)}(example.inputs.text)
|
|
95
|
-
|
|
96
|
-
if (example.want.typeOfResult) {
|
|
97
|
-
expect(typeof result)
|
|
98
|
-
.toStrictEqual(example.want.typeOfResult);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (example.want.result) {
|
|
102
|
-
expect(result)
|
|
103
|
-
.toStrictEqual(example.want.result);
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
`;
|
|
109
|
-
createFileIfNotExists(exampleFile, exampleContent, 'example');
|
|
110
|
-
|
|
111
|
-
console.error(`Created new chain: ${chainName}`);
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import {
|
|
3
|
-
camelCase,
|
|
4
|
-
paramCase,
|
|
5
|
-
sentenceCase,
|
|
6
|
-
} from 'change-case';
|
|
7
|
-
|
|
8
|
-
const libName = process.argv[2];
|
|
9
|
-
|
|
10
|
-
if (!libName) {
|
|
11
|
-
console.error('Please specify a library name.');
|
|
12
|
-
process.exit(1);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const libDir = `./src/lib/${paramCase(libName)}`;
|
|
16
|
-
const indexFile = `${libDir}/index.js`;
|
|
17
|
-
const testFile = `${libDir}/index.spec.js`;
|
|
18
|
-
|
|
19
|
-
const createFileIfNotExists = (filePath, fileContent, fileType) => {
|
|
20
|
-
if (!fs.existsSync(filePath)) {
|
|
21
|
-
fs.writeFileSync(filePath, fileContent);
|
|
22
|
-
console.error(`Created new ${fileType} file: ${filePath}`);
|
|
23
|
-
} else {
|
|
24
|
-
console.error(`Creating ${fileType} file [skipped]: '${filePath}' exists`);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Check if the lib directory already exists
|
|
29
|
-
if (!fs.existsSync(libDir)) {
|
|
30
|
-
// Create the lib directory
|
|
31
|
-
fs.mkdirSync(libDir, { recursive: true });
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const indexContent = `
|
|
35
|
-
export default async (text) => {
|
|
36
|
-
// TODO: Implement ${paramCase(libName)} lib
|
|
37
|
-
};
|
|
38
|
-
`;
|
|
39
|
-
createFileIfNotExists(indexFile, indexContent, 'module file');
|
|
40
|
-
|
|
41
|
-
const testContent = `import { describe, expect, it, vi } from 'vitest';
|
|
42
|
-
|
|
43
|
-
import ${camelCase(libName)} from './index.js';
|
|
44
|
-
|
|
45
|
-
const examples = [
|
|
46
|
-
{
|
|
47
|
-
name: 'Basic usage',
|
|
48
|
-
inputs: { text: 'test' },
|
|
49
|
-
want: { result: true }
|
|
50
|
-
}
|
|
51
|
-
];
|
|
52
|
-
|
|
53
|
-
describe('${sentenceCase(libName)} lib', () => {
|
|
54
|
-
examples.forEach((example) => {
|
|
55
|
-
it(example.name, async () => {
|
|
56
|
-
const result = await ${camelCase(libName)}(example.inputs.text);
|
|
57
|
-
|
|
58
|
-
if (example.want.typeOfResult) {
|
|
59
|
-
expect(typeof result)
|
|
60
|
-
.toStrictEqual(example.want.typeOfResult);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
`;
|
|
66
|
-
createFileIfNotExists(testFile, testContent, 'test');
|
|
67
|
-
|
|
68
|
-
console.error(`Created new lib: ${libName}`);
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
|
|
4
|
-
import parseJSParts from '../../src/lib/parse-js-parts/index.js';
|
|
5
|
-
import
|
|
6
|
-
chatGPT,
|
|
7
|
-
{
|
|
8
|
-
getRedis,
|
|
9
|
-
SummaryMap
|
|
10
|
-
} from '../../src/index.js';
|
|
11
|
-
import modelService from '../../src/services/llm-model/index.js';
|
|
12
|
-
import { Command } from 'commander';
|
|
13
|
-
|
|
14
|
-
const program = new Command();
|
|
15
|
-
program
|
|
16
|
-
.argument('<modulePath>', 'Module to test')
|
|
17
|
-
.argument('[functionName]', 'Specific function to test')
|
|
18
|
-
.option('-p, --privacy', 'Use privacy model if configured')
|
|
19
|
-
.option('-m, --model <modelName>', 'Specify model name to use');
|
|
20
|
-
|
|
21
|
-
program.parse(process.argv);
|
|
22
|
-
|
|
23
|
-
const options = program.opts();
|
|
24
|
-
const [modulePath, functionName] = program.args;
|
|
25
|
-
|
|
26
|
-
if (options.privacy) {
|
|
27
|
-
try {
|
|
28
|
-
modelService.setGlobalOverride('modelName', 'privacy');
|
|
29
|
-
} catch (err) {
|
|
30
|
-
console.error(`Privacy model error: ${err.message}`);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
if (options.model) {
|
|
34
|
-
try {
|
|
35
|
-
modelService.setGlobalOverride('modelName', options.model);
|
|
36
|
-
} catch (err) {
|
|
37
|
-
console.error(`Model override error: ${err.message}`);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (!modulePath) {
|
|
42
|
-
console.error('Please specify a module to test.');
|
|
43
|
-
process.exit(1);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
try {
|
|
47
|
-
await fs.stat(modulePath);
|
|
48
|
-
} catch (err) {
|
|
49
|
-
console.error(`Module not found at: ${modulePath}`);
|
|
50
|
-
process.exit(1);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const moduleDir = path.dirname(modulePath);
|
|
54
|
-
const moduleName = path.basename(moduleDir);
|
|
55
|
-
const testFile = path.join(moduleDir, `${moduleName}.spec.js`);
|
|
56
|
-
|
|
57
|
-
const examplePath1 = './src/lib/parse-js-parts/parse-js-parts.spec.js';
|
|
58
|
-
|
|
59
|
-
try {
|
|
60
|
-
await fs.stat(examplePath1);
|
|
61
|
-
} catch (error) {
|
|
62
|
-
console.error(`Generate test [error]: ${error.message}`);
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const generatePrompt = ({ moduleFile, modulePath, examples=[] }) => {
|
|
67
|
-
const examplesJoined = examples.map((example) => `<example>${example}</example>`).join('\n');
|
|
68
|
-
|
|
69
|
-
let prompt = `Generate a test file for module shown below.
|
|
70
|
-
|
|
71
|
-
Examples to inform the results:
|
|
72
|
-
${examplesJoined}
|
|
73
|
-
|
|
74
|
-
<module-to-test>${moduleFile}</module-to-test>`;
|
|
75
|
-
|
|
76
|
-
return prompt;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async function generateTestFile(modulePath) {
|
|
80
|
-
const moduleFile = await fs.readFile(modulePath, 'utf-8');
|
|
81
|
-
|
|
82
|
-
const example1 = (await fs.readFile(examplePath1, 'utf-8'));
|
|
83
|
-
// const example2 = await fs.readFile(examplePath2, 'utf-8');
|
|
84
|
-
|
|
85
|
-
const fixes = [];
|
|
86
|
-
if (functionName) {
|
|
87
|
-
fixes.push('For the function "${functionName}", keep as much of the code as you can.');
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
let functionNameDisplay = '';
|
|
91
|
-
if (functionName) {
|
|
92
|
-
functionNameDisplay = `, only for "${functionName}"`
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
let moduleFileSliced = moduleFile;
|
|
96
|
-
if (functionName) {
|
|
97
|
-
const results = parseJSParts(modulePath, moduleFile);
|
|
98
|
-
|
|
99
|
-
const funcs = Object.keys(results.functionsMap);
|
|
100
|
-
const funcFound = funcs.find(f => (new RegExp(`${functionName}$`)).test(f));
|
|
101
|
-
const funcDefFound = results.functionsMap?.[funcFound];
|
|
102
|
-
if (funcDefFound) {
|
|
103
|
-
moduleFileSliced = moduleFile.slice(funcDefFound.start, funcDefFound.end);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const argsMap = new SummaryMap({ promptText: generatePrompt.toString() });
|
|
108
|
-
|
|
109
|
-
argsMap.set('functionName', { value: functionName });
|
|
110
|
-
argsMap.set('modulePath', { value: modulePath });
|
|
111
|
-
argsMap.set('moduleFile', {
|
|
112
|
-
value: moduleFileSliced,
|
|
113
|
-
weight: 1,
|
|
114
|
-
type: 'code',
|
|
115
|
-
fixes,
|
|
116
|
-
})
|
|
117
|
-
argsMap.set('examples.0', {
|
|
118
|
-
value: example1,
|
|
119
|
-
weight: 1,
|
|
120
|
-
type: 'code',
|
|
121
|
-
fixes: ['Keep at least one of the example definitions in the example array'],
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
const prompt = await generatePrompt(await argsMap.pavedSummaryResult());
|
|
125
|
-
|
|
126
|
-
console.error(prompt)
|
|
127
|
-
|
|
128
|
-
const response = await chatGPT(prompt);
|
|
129
|
-
|
|
130
|
-
// use standard shell IO to apply the generated code
|
|
131
|
-
console.error(response);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Example usage:
|
|
135
|
-
await generateTestFile(modulePath);
|
|
136
|
-
|
|
137
|
-
await (await getRedis()).disconnect();
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# Verblet Generator
|
|
2
|
-
|
|
3
|
-
This is a Node script that generates a new "verblet" module and test file in a specific directory structure.
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
|
|
7
|
-
To use this script, run the following command:
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
npm run script -- generate-verblet [verblet-name]
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
Replace `[verblet-name]` with the name of your new verblet. The script will create a new directory called `./src/verblets/[verblet-name]` and generate an `index.js` file and a test file inside that directory.
|
|
14
|
-
|
|
15
|
-
The generated `index.js` file exports a single default async function that you can implement to define the behavior of the verblet.
|
|
16
|
-
|
|
17
|
-
The generated test file is located at `./src/verblets/[verblet-name]/[verblet-name].spec.js`. It contains a sample test that you can modify to test your verblet implementation.
|