@far-world-labs/verblets 0.1.1 → 0.1.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/.cursor/launch.json +30 -0
- package/.cursor/settings.json +20 -0
- package/.github/workflows/branch-protection.yml +22 -0
- package/.github/workflows/ci.yml +117 -0
- package/.prettierrc +6 -0
- package/.release-it.json +4 -1
- package/.vscode/launch.json +31 -0
- package/AGENTS.md +220 -0
- package/DEVELOPING.md +105 -0
- package/README.md +671 -0
- package/eslint.config.js +80 -0
- package/package.json +28 -16
- package/scripts/generate-test/index.js +29 -3
- package/scripts/runner/index.js +26 -0
- package/scripts/simple-editor/index.js +29 -18
- package/scripts/summarize-files/index.js +28 -4
- package/src/chains/README.md +30 -0
- package/src/chains/anonymize/README.md +21 -0
- package/src/chains/anonymize/index.examples.js +75 -0
- package/src/chains/anonymize/index.js +121 -0
- package/src/chains/anonymize/index.spec.js +78 -0
- package/src/chains/bulk-central-tendency/index.examples.js +138 -0
- package/src/chains/bulk-central-tendency/index.js +91 -0
- package/src/chains/bulk-filter/README.md +21 -0
- package/src/chains/bulk-filter/index.examples.js +22 -0
- package/src/chains/bulk-filter/index.js +58 -0
- package/src/chains/bulk-filter/index.spec.js +38 -0
- package/src/chains/bulk-find/README.md +16 -0
- package/src/chains/bulk-find/index.examples.js +20 -0
- package/src/chains/bulk-find/index.js +30 -0
- package/src/chains/bulk-find/index.spec.js +26 -0
- package/src/chains/bulk-group/README.md +23 -0
- package/src/chains/bulk-group/index.examples.js +18 -0
- package/src/chains/bulk-group/index.js +34 -0
- package/src/chains/bulk-group/index.spec.js +41 -0
- package/src/chains/bulk-map/README.md +43 -0
- package/src/chains/bulk-map/index.examples.js +17 -0
- package/src/chains/bulk-map/index.js +86 -0
- package/src/chains/bulk-map/index.spec.js +44 -0
- package/src/chains/bulk-reduce/README.md +12 -0
- package/src/chains/bulk-reduce/index.examples.js +15 -0
- package/src/chains/bulk-reduce/index.js +13 -0
- package/src/chains/bulk-reduce/index.spec.js +25 -0
- package/src/chains/bulk-score/README.md +16 -0
- package/src/chains/bulk-score/bulk-score-result.json +18 -0
- package/src/chains/bulk-score/index.examples.js +22 -0
- package/src/chains/bulk-score/index.js +133 -0
- package/src/chains/bulk-score/index.spec.js +30 -0
- package/src/chains/category-samples/README.md +61 -0
- package/src/chains/category-samples/index.examples.js +103 -0
- package/src/chains/category-samples/index.js +134 -0
- package/src/chains/collect-terms/README.md +12 -0
- package/src/chains/collect-terms/index.examples.js +16 -0
- package/src/chains/collect-terms/index.js +44 -0
- package/src/chains/collect-terms/index.spec.js +25 -0
- package/src/chains/date/README.md +12 -0
- package/src/chains/date/index.examples.js +47 -0
- package/src/chains/date/index.js +74 -0
- package/src/chains/date/index.spec.js +62 -0
- package/src/chains/disambiguate/README.md +22 -0
- package/src/chains/disambiguate/disambiguate-meanings-result.json +16 -0
- package/src/chains/disambiguate/index.examples.js +18 -0
- package/src/chains/disambiguate/index.js +92 -0
- package/src/chains/disambiguate/index.spec.js +25 -0
- package/src/chains/dismantle/README.md +67 -0
- package/src/chains/dismantle/dismantle.examples.js +27 -0
- package/src/chains/dismantle/index.js +6 -17
- package/src/chains/dismantle/index.spec.js +1 -2
- package/src/chains/expect/README.md +171 -0
- package/src/chains/expect/index.examples.js +146 -0
- package/src/chains/expect/index.js +173 -0
- package/src/chains/expect/index.spec.js +324 -0
- package/src/chains/filter-ambiguous/README.md +11 -0
- package/src/chains/filter-ambiguous/index.examples.js +20 -0
- package/src/chains/filter-ambiguous/index.js +49 -0
- package/src/chains/filter-ambiguous/index.spec.js +31 -0
- package/src/chains/glossary/README.md +19 -0
- package/src/chains/glossary/index.examples.js +386 -0
- package/src/chains/glossary/index.js +75 -0
- package/src/chains/glossary/index.spec.js +19 -0
- package/src/chains/intersections/README.md +152 -0
- package/src/chains/intersections/index.examples.js +279 -0
- package/src/chains/intersections/index.js +366 -0
- package/src/chains/intersections/intersection-result.json +38 -0
- package/src/chains/list/index.examples.js +12 -16
- package/src/chains/list/index.js +106 -53
- package/src/chains/list/index.spec.js +3 -9
- package/src/chains/list/list-result.json +16 -0
- package/src/chains/llm-logger/README.md +208 -0
- package/src/chains/llm-logger/index.js +205 -0
- package/src/chains/llm-logger/index.spec.js +330 -0
- package/src/chains/questions/index.examples.js +2 -1
- package/src/chains/questions/index.js +14 -15
- package/src/chains/scan-js/index.js +6 -9
- package/src/chains/set-interval/README.md +81 -0
- package/src/chains/set-interval/index.examples.js +36 -0
- package/src/chains/set-interval/index.js +131 -0
- package/src/chains/set-interval/index.spec.js +70 -0
- package/src/chains/socratic/README.md +17 -0
- package/src/chains/socratic/index.js +64 -0
- package/src/chains/socratic/index.spec.js +24 -0
- package/src/chains/sort/index.examples.js +3 -7
- package/src/chains/sort/index.js +65 -15
- package/src/chains/sort/index.spec.js +5 -8
- package/src/chains/sort/sort-result.json +16 -0
- package/src/chains/summary-map/README.md +9 -1
- package/src/chains/summary-map/index.examples.js +9 -2
- package/src/chains/summary-map/index.js +43 -25
- package/src/chains/summary-map/index.spec.js +78 -3
- package/src/chains/test/index.js +9 -13
- package/src/chains/test-advice/index.js +4 -5
- package/src/chains/themes/README.md +20 -0
- package/src/chains/themes/index.examples.js +17 -0
- package/src/chains/themes/index.js +28 -0
- package/src/chains/themes/index.spec.js +19 -0
- package/src/chains/veiled-variants/index.examples.js +18 -0
- package/src/chains/veiled-variants/index.js +107 -0
- package/src/chains/veiled-variants/index.spec.js +40 -0
- package/src/constants/common.js +0 -2
- package/src/constants/models.js +172 -0
- package/src/index.js +178 -18
- package/src/json-schemas/README.md +13 -0
- package/src/json-schemas/index.js +8 -14
- package/src/json-schemas/schema-dot-org-photograph.json +11 -5
- package/src/json-schemas/schema-dot-org-place.json +78 -5
- package/src/lib/README.md +26 -0
- package/src/lib/bulk-filter/README.md +22 -0
- package/src/lib/bulk-filter/index.examples.js +27 -0
- package/src/lib/bulk-filter/index.js +63 -0
- package/src/lib/bulk-filter/index.spec.js +38 -0
- package/src/lib/bulk-find/README.md +18 -0
- package/src/lib/bulk-find/index.examples.js +19 -0
- package/src/lib/bulk-find/index.js +30 -0
- package/src/lib/bulk-find/index.spec.js +41 -0
- package/src/lib/chatgpt/index.js +63 -43
- package/src/lib/combinations/index.js +30 -0
- package/src/lib/combinations/index.spec.js +23 -0
- package/src/lib/functional/index.js +28 -0
- package/src/lib/logger-service/index.js +32 -0
- package/src/lib/parse-js-parts/index.js +9 -21
- package/src/lib/parse-llm-list/README.md +39 -0
- package/src/lib/parse-llm-list/index.js +54 -0
- package/src/lib/parse-llm-list/index.spec.js +59 -0
- package/src/lib/path-aliases/index.js +1 -3
- package/src/lib/path-aliases/index.spec.js +2 -8
- package/src/lib/pave/index.js +4 -4
- package/src/lib/pave/index.spec.js +6 -3
- package/src/lib/prompt-cache/index.js +14 -10
- package/src/lib/retry/index.js +11 -8
- package/src/lib/ring-buffer/README.md +460 -0
- package/src/lib/ring-buffer/index.js +1074 -0
- package/src/lib/search-best-first/city-walk.spec.js +37 -0
- package/src/lib/search-best-first/index.js +42 -11
- package/src/lib/search-best-first/index.spec.js +35 -0
- package/src/lib/search-js-files/index.js +21 -41
- package/src/lib/search-js-files/scan-file.js +10 -21
- package/src/lib/shorten-text/index.js +2 -7
- package/src/lib/shorten-text/index.spec.js +3 -3
- package/src/lib/strip-response/index.js +2 -7
- package/src/lib/template-replace/index.js +23 -0
- package/src/lib/template-replace/index.spec.js +60 -0
- package/src/lib/to-date/index.js +11 -0
- package/src/lib/to-number/index.js +1 -1
- package/src/lib/transcribe/index.js +4 -4
- package/src/prompts/README.md +3 -1
- package/src/prompts/as-object-with-schema.js +3 -8
- package/src/prompts/as-schema-org-text.js +10 -2
- package/src/prompts/code-features.js +1 -5
- package/src/prompts/constants.js +27 -27
- package/src/prompts/generate-collection.js +1 -1
- package/src/prompts/intent.js +11 -16
- package/src/prompts/select-from-threshold.js +1 -2
- package/src/prompts/sort.js +4 -8
- package/src/prompts/style.js +4 -7
- package/src/prompts/wrap-list.js +1 -4
- package/src/services/llm-model/global-overrides.spec.js +432 -0
- package/src/services/llm-model/index.js +234 -40
- package/src/services/llm-model/model.js +2 -2
- package/src/services/llm-model/negotiate.spec.js +447 -0
- package/src/services/redis/index.js +70 -7
- package/src/test/setup.js +20 -0
- package/src/verblets/README.md +26 -0
- package/src/verblets/auto/index.examples.js +12 -9
- package/src/verblets/auto/index.js +10 -10
- package/src/verblets/auto/index.spec.js +4 -6
- package/src/verblets/bool/README.md +36 -0
- package/src/verblets/bool/index.examples.js +53 -1
- package/src/verblets/bool/index.js +6 -9
- package/src/verblets/bool/index.spec.js +1 -3
- package/src/verblets/central-tendency/README.md +166 -0
- package/src/verblets/central-tendency/central-tendency-result.json +24 -0
- package/src/verblets/central-tendency/index.examples.js +196 -0
- package/src/verblets/central-tendency/index.js +171 -0
- package/src/verblets/central-tendency/index.spec.js +148 -0
- package/src/verblets/enum/index.examples.js +1 -4
- package/src/verblets/enum/index.js +7 -4
- package/src/verblets/expect/README.md +64 -0
- package/src/verblets/expect/index.examples.js +109 -0
- package/src/verblets/expect/index.js +75 -0
- package/src/verblets/expect/index.spec.js +127 -0
- package/src/verblets/intent/index.examples.js +84 -1
- package/src/verblets/intent/index.js +56 -68
- package/src/verblets/intersection/README.md +16 -0
- package/src/verblets/intersection/index.examples.js +89 -0
- package/src/verblets/intersection/index.js +84 -0
- package/src/verblets/intersection/index.spec.js +60 -0
- package/src/verblets/intersection/intersection-result.json +16 -0
- package/src/verblets/list-expand/README.md +10 -0
- package/src/verblets/list-expand/index.examples.js +14 -0
- package/src/verblets/list-expand/index.js +104 -0
- package/src/verblets/list-expand/index.spec.js +18 -0
- package/src/verblets/list-expand/list-expand-result.json +16 -0
- package/src/verblets/list-filter/README.md +22 -0
- package/src/verblets/list-filter/index.examples.js +26 -0
- package/src/verblets/list-filter/index.js +18 -0
- package/src/verblets/list-filter/index.spec.js +19 -0
- package/src/verblets/list-find/README.md +11 -0
- package/src/verblets/list-find/index.examples.js +15 -0
- package/src/verblets/list-find/index.js +17 -0
- package/src/verblets/list-find/index.spec.js +19 -0
- package/src/verblets/list-group/README.md +16 -0
- package/src/verblets/list-group/index.examples.js +16 -0
- package/src/verblets/list-group/index.js +112 -0
- package/src/verblets/list-group/index.spec.js +35 -0
- package/src/verblets/list-group/list-group-result.json +16 -0
- package/src/verblets/list-map/README.md +11 -0
- package/src/verblets/list-map/index.examples.js +15 -0
- package/src/verblets/list-map/index.js +26 -0
- package/src/verblets/list-map/index.spec.js +17 -0
- package/src/verblets/list-reduce/README.md +10 -0
- package/src/verblets/list-reduce/index.examples.js +14 -0
- package/src/verblets/list-reduce/index.js +21 -0
- package/src/verblets/list-reduce/index.spec.js +27 -0
- package/src/verblets/list-reduce/index.spec.jsx +27 -0
- package/src/verblets/name/README.md +15 -0
- package/src/verblets/name/index.examples.js +28 -0
- package/src/verblets/name/index.js +19 -0
- package/src/verblets/name/index.spec.js +33 -0
- package/src/verblets/name-similar-to/README.md +26 -0
- package/src/verblets/name-similar-to/index.examples.js +18 -0
- package/src/verblets/name-similar-to/index.js +20 -0
- package/src/verblets/name-similar-to/index.spec.js +13 -0
- package/src/verblets/number/index.examples.js +173 -7
- package/src/verblets/number/index.js +5 -2
- package/src/verblets/number/index.spec.js +1 -3
- package/src/verblets/number-with-units/index.examples.js +5 -1
- package/src/verblets/number-with-units/index.js +74 -9
- package/src/verblets/number-with-units/number-with-units-result.json +23 -0
- package/src/verblets/schema-org/index.examples.js +2 -7
- package/src/verblets/schema-org/index.js +32 -3
- package/src/verblets/sentiment/README.md +10 -0
- package/src/verblets/sentiment/index.examples.js +20 -0
- package/src/verblets/sentiment/index.js +9 -0
- package/src/verblets/sentiment/index.spec.js +20 -0
- package/src/verblets/to-object/index.js +10 -15
- package/src/verblets/to-object/index.spec.js +1 -4
- package/.eslintrc.json +0 -42
- package/docs/README.md +0 -41
- package/docs/babel.config.js +0 -3
- package/docs/blog/2019-05-28-first-blog-post.md +0 -12
- package/docs/blog/2019-05-29-long-blog-post.md +0 -44
- package/docs/blog/2021-08-01-mdx-blog-post.mdx +0 -20
- package/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg +0 -0
- package/docs/blog/2021-08-26-welcome/index.md +0 -25
- package/docs/blog/authors.yml +0 -17
- package/docs/docs/api/bool.md +0 -74
- package/docs/docs/api/search.md +0 -51
- package/docs/docs/intro.md +0 -47
- package/docs/docs/tutorial-basics/_category_.json +0 -8
- package/docs/docs/tutorial-basics/congratulations.md +0 -23
- package/docs/docs/tutorial-basics/create-a-blog-post.md +0 -34
- package/docs/docs/tutorial-basics/create-a-document.md +0 -57
- package/docs/docs/tutorial-basics/create-a-page.md +0 -43
- package/docs/docs/tutorial-basics/deploy-your-site.md +0 -31
- package/docs/docs/tutorial-basics/markdown-features.mdx +0 -152
- package/docs/docs/tutorial-extras/_category_.json +0 -7
- package/docs/docs/tutorial-extras/img/docsVersionDropdown.png +0 -0
- package/docs/docs/tutorial-extras/img/localeDropdown.png +0 -0
- package/docs/docs/tutorial-extras/manage-docs-versions.md +0 -55
- package/docs/docs/tutorial-extras/translate-your-site.md +0 -88
- package/docs/docusaurus.config.js +0 -120
- package/docs/package.json +0 -44
- package/docs/sidebars.js +0 -31
- package/docs/src/components/HomepageFeatures/index.js +0 -61
- package/docs/src/components/HomepageFeatures/styles.module.css +0 -11
- package/docs/src/css/custom.css +0 -30
- package/docs/src/pages/index.js +0 -43
- package/docs/src/pages/index.module.css +0 -23
- package/docs/src/pages/markdown-page.md +0 -7
- package/docs/static/.nojekyll +0 -0
- package/docs/static/img/docusaurus-social-card.jpg +0 -0
- package/docs/static/img/docusaurus.png +0 -0
- package/docs/static/img/favicon.ico +0 -0
- package/docs/static/img/logo.svg +0 -1
- package/docs/static/img/undraw_docusaurus_mountain.svg +0 -171
- package/docs/static/img/undraw_docusaurus_react.svg +0 -170
- package/docs/static/img/undraw_docusaurus_tree.svg +0 -40
- package/src/constants/openai.js +0 -65
- /package/{.vite.config.examples.js → .vitest.config.examples.js} +0 -0
- /package/{.vite.config.js → .vitest.config.js} +0 -0
package/eslint.config.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@far-world-labs/verblets",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "OpenAI Client",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -15,56 +15,68 @@
|
|
|
15
15
|
"--": "npm run script -- generate-verblet foo",
|
|
16
16
|
"script": "./scripts/run.sh",
|
|
17
17
|
"test": "vitest",
|
|
18
|
-
"examples": "EXAMPLES=true vitest --config .
|
|
18
|
+
"examples:warn": "source .env && LLM_EXPECT_MODE=info EXAMPLES=true vitest --config .vitest.config.examples.js",
|
|
19
|
+
"examples": "source .env && LLM_EXPECT_MODE=error EXAMPLES=true vitest --config .vitest.config.examples.js",
|
|
19
20
|
"lint": "eslint 'src/**/*.{js,jsx}'",
|
|
20
21
|
"lint:fix": "eslint 'src/**/*.{js,jsx}' --fix",
|
|
22
|
+
"check:deps": "npx npm-deprecated-check current",
|
|
21
23
|
"husky:install": "husky install",
|
|
22
24
|
"husky:uninstall": "husky uninstall",
|
|
23
|
-
"prepare": "npx husky install"
|
|
25
|
+
"prepare": "npx husky install",
|
|
26
|
+
"version:patch": "npm version patch",
|
|
27
|
+
"version:minor": "npm version minor",
|
|
28
|
+
"version:major": "npm version major"
|
|
24
29
|
},
|
|
25
30
|
"config": {
|
|
26
31
|
"gen-script": "./scripts/run.sh gen-$1"
|
|
27
32
|
},
|
|
28
33
|
"author": "Far World Labs",
|
|
29
34
|
"license": "All Rights Reserved",
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
30
38
|
"dependencies": {
|
|
31
39
|
"acorn": "^8.8.2",
|
|
32
40
|
"acorn-walk": "^8.2.0",
|
|
33
41
|
"ajv": "^8.12.0",
|
|
34
42
|
"chai": "^4.3.7",
|
|
35
43
|
"change-case": "^4.1.2",
|
|
44
|
+
"commander": "^11.0.0",
|
|
45
|
+
"compromise": "^14.14.4",
|
|
36
46
|
"dependency-tree": "^10.0.1",
|
|
37
47
|
"dotenv": "^16.0.3",
|
|
38
48
|
"gpt-tokenizer": "^2.1.2",
|
|
39
49
|
"gpt4-tokenizer": "^1.3.0",
|
|
50
|
+
"lodash": "^4.17.21",
|
|
40
51
|
"mocha": "^10.2.0",
|
|
41
52
|
"node-fetch": "^3.3.0",
|
|
42
|
-
"
|
|
53
|
+
"node-record-lpcm16": "^1.0.1",
|
|
43
54
|
"ramda": "^0.29.0",
|
|
44
55
|
"redis": "^4.6.5",
|
|
45
56
|
"uuid": "^9.0.0",
|
|
46
|
-
"vitest": "^
|
|
57
|
+
"vitest": "^3.1.3",
|
|
58
|
+
"whisper-node": "^1.1.1",
|
|
47
59
|
"yargs": "^17.7.1"
|
|
48
60
|
},
|
|
49
61
|
"devDependencies": {
|
|
62
|
+
"@eslint/js": "^9.28.0",
|
|
63
|
+
"@stylistic/eslint-plugin": "^4.4.0",
|
|
50
64
|
"@types/node": "^18.16.3",
|
|
51
|
-
"
|
|
52
|
-
"eslint
|
|
65
|
+
"@vitest/ui": "^3.1.3",
|
|
66
|
+
"eslint": "^9.28.0",
|
|
53
67
|
"eslint-config-prettier": "^8.8.0",
|
|
54
|
-
"eslint-plugin-import": "^2.
|
|
55
|
-
"eslint-plugin-jest": "^
|
|
56
|
-
"eslint-plugin-jsx-a11y": "^6.7.1",
|
|
68
|
+
"eslint-plugin-import": "^2.31.0",
|
|
69
|
+
"eslint-plugin-jest": "^28.12.0",
|
|
57
70
|
"eslint-plugin-prettier": "^4.2.1",
|
|
58
|
-
"eslint-plugin-
|
|
59
|
-
"eslint-plugin-
|
|
71
|
+
"eslint-plugin-unicorn": "^59.0.1",
|
|
72
|
+
"eslint-plugin-vitest": "^0.5.4",
|
|
60
73
|
"husky": "^8.0.3",
|
|
61
74
|
"install-peerdeps": "^3.0.3",
|
|
62
75
|
"lint-staged": "^13.2.2",
|
|
63
|
-
"
|
|
64
|
-
"npm-check": "^
|
|
76
|
+
"nodemon": "^3.1.10",
|
|
77
|
+
"npm-deprecated-check": "^1.5.0",
|
|
65
78
|
"prettier": "^2.8.8",
|
|
66
|
-
"release-it": "^
|
|
67
|
-
"whisper-node": "^1.1.1",
|
|
79
|
+
"release-it": "^19.0.3",
|
|
68
80
|
"why-is-node-running": "^2.2.2"
|
|
69
81
|
},
|
|
70
82
|
"lint-staged": {
|
|
@@ -8,9 +8,35 @@ chatGPT,
|
|
|
8
8
|
getRedis,
|
|
9
9
|
SummaryMap
|
|
10
10
|
} from '../../src/index.js';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
+
}
|
|
14
40
|
|
|
15
41
|
if (!modulePath) {
|
|
16
42
|
console.error('Please specify a module to test.');
|
package/scripts/runner/index.js
CHANGED
|
@@ -5,6 +5,32 @@ import chatGPT, {
|
|
|
5
5
|
retry as run,
|
|
6
6
|
schemas,
|
|
7
7
|
} from '../../src/index.js';
|
|
8
|
+
import modelService from '../../src/services/llm-model/index.js';
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
|
|
11
|
+
const program = new Command();
|
|
12
|
+
program
|
|
13
|
+
.option('-p, --privacy', 'Use privacy model if configured')
|
|
14
|
+
.option('-m, --model <modelName>', 'Specify model name to use');
|
|
15
|
+
|
|
16
|
+
program.parse(process.argv);
|
|
17
|
+
|
|
18
|
+
const options = program.opts();
|
|
19
|
+
|
|
20
|
+
if (options.privacy) {
|
|
21
|
+
try {
|
|
22
|
+
modelService.setGlobalOverride('modelName', 'privacy');
|
|
23
|
+
} catch (err) {
|
|
24
|
+
console.error(`Privacy model error: ${err.message}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (options.model) {
|
|
28
|
+
try {
|
|
29
|
+
modelService.setGlobalOverride('modelName', options.model);
|
|
30
|
+
} catch (err) {
|
|
31
|
+
console.error(`Model override error: ${err.message}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
8
34
|
|
|
9
35
|
await run(async () => {
|
|
10
36
|
const results = await chatGPT('make a list of nintendo games with a schema that includes a title, year, and maybe a couple others of your choice', {
|
|
@@ -1,25 +1,36 @@
|
|
|
1
1
|
import dotenv from 'dotenv/config';
|
|
2
|
-
import
|
|
3
|
-
import { hideBin } from 'yargs/helpers';
|
|
2
|
+
import { Command } from 'commander';
|
|
4
3
|
|
|
5
4
|
import chatGPT, { getRedis, auto, bool } from '../../src/index.js';
|
|
5
|
+
import modelService from '../../src/services/llm-model/index.js';
|
|
6
6
|
import edit from '../../src/lib/editor/index.js';
|
|
7
7
|
import Transcriber from '../../src/lib/transcribe/index.js';
|
|
8
8
|
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
9
|
+
const program = new Command();
|
|
10
|
+
program
|
|
11
|
+
.option('-t, --transcribe', 'Enable audio transcription')
|
|
12
|
+
.option('--no-use-intent', 'Disable intent parsing')
|
|
13
|
+
.option('-p, --privacy', 'Use privacy model if configured')
|
|
14
|
+
.option('-m, --model <modelName>', 'Specify model name to use');
|
|
15
|
+
|
|
16
|
+
program.parse(process.argv);
|
|
17
|
+
|
|
18
|
+
const argv = program.opts();
|
|
19
|
+
|
|
20
|
+
if (argv.privacy) {
|
|
21
|
+
try {
|
|
22
|
+
modelService.setGlobalOverride('modelName', 'privacy');
|
|
23
|
+
} catch (err) {
|
|
24
|
+
console.error(`Privacy model error: ${err.message}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (argv.model) {
|
|
28
|
+
try {
|
|
29
|
+
modelService.setGlobalOverride('modelName', argv.model);
|
|
30
|
+
} catch (err) {
|
|
31
|
+
console.error(`Model override error: ${err.message}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
23
34
|
|
|
24
35
|
const operations = [
|
|
25
36
|
{
|
|
@@ -32,7 +43,7 @@ const operations = [
|
|
|
32
43
|
|
|
33
44
|
|
|
34
45
|
let userInput;
|
|
35
|
-
const useTranscribe =
|
|
46
|
+
const useTranscribe = !!argv.transcribe;
|
|
36
47
|
if (useTranscribe) {
|
|
37
48
|
const transcriber = new Transcriber("stopword"); // Replace "stopword" with the word you want to trigger the stop
|
|
38
49
|
userInput = await transcriber.startRecording()
|
|
@@ -40,7 +51,7 @@ if (useTranscribe) {
|
|
|
40
51
|
userInput = await edit();
|
|
41
52
|
}
|
|
42
53
|
|
|
43
|
-
const useIntent =
|
|
54
|
+
const useIntent = argv.useIntent !== false;
|
|
44
55
|
|
|
45
56
|
const commandType = useIntent ? 'Tool selection' : 'Direct ChatGPT';
|
|
46
57
|
console.error(`Command: ${commandType}`);
|
|
@@ -1,12 +1,36 @@
|
|
|
1
1
|
import glob from 'glob';
|
|
2
2
|
import { readFile } from 'fs/promises';
|
|
3
3
|
import SummaryMap from '../../src/chains/summary-map/index.js';
|
|
4
|
+
import modelService from '../../src/services/llm-model/index.js';
|
|
5
|
+
import { Command } from 'commander';
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
const program = new Command();
|
|
8
|
+
program
|
|
9
|
+
.argument('[globPattern]', 'Glob pattern to summarize', './src/**/*.js')
|
|
10
|
+
.argument('[targetTokens]', 'Target token count', '4097')
|
|
11
|
+
.option('-p, --privacy', 'Use privacy model if configured')
|
|
12
|
+
.option('-m, --model <modelName>', 'Specify model name to use');
|
|
7
13
|
|
|
8
|
-
|
|
9
|
-
|
|
14
|
+
program.parse(process.argv);
|
|
15
|
+
|
|
16
|
+
const options = program.opts();
|
|
17
|
+
const [globPattern, targetTokensInput] = program.args;
|
|
18
|
+
const targetTokens = Number(targetTokensInput);
|
|
19
|
+
|
|
20
|
+
if (options.privacy) {
|
|
21
|
+
try {
|
|
22
|
+
modelService.setGlobalOverride('modelName', 'privacy');
|
|
23
|
+
} catch (err) {
|
|
24
|
+
console.error(`Privacy model error: ${err.message}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (options.model) {
|
|
28
|
+
try {
|
|
29
|
+
modelService.setGlobalOverride('modelName', options.model);
|
|
30
|
+
} catch (err) {
|
|
31
|
+
console.error(`Model override error: ${err.message}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
10
34
|
|
|
11
35
|
// Initialize the SummaryMap with the target tokens
|
|
12
36
|
const map = new SummaryMap({
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Chains
|
|
2
|
+
|
|
3
|
+
Chains orchestrate multiple verblets or helper functions to perform more complex tasks. Each subdirectory exposes a specific workflow that can be imported as a single function.
|
|
4
|
+
|
|
5
|
+
Available chains:
|
|
6
|
+
|
|
7
|
+
- [anonymize](./anonymize)
|
|
8
|
+
- [bulk-map](./bulk-map)
|
|
9
|
+
- [bulk-reduce](./bulk-reduce)
|
|
10
|
+
- [bulk-filter](./bulk-filter)
|
|
11
|
+
- [bulk-group](./bulk-group)
|
|
12
|
+
- [dismantle](./dismantle)
|
|
13
|
+
- [disambiguate](./disambiguate)
|
|
14
|
+
- [intersections](./intersections)
|
|
15
|
+
- [list](./list)
|
|
16
|
+
- [questions](./questions)
|
|
17
|
+
- [socratic](./socratic)
|
|
18
|
+
- [glossary](./glossary)
|
|
19
|
+
- [scan-js](./scan-js)
|
|
20
|
+
- [sort](./sort)
|
|
21
|
+
- [summary-map](./summary-map)
|
|
22
|
+
- [themes](./themes)
|
|
23
|
+
- [set-interval](./set-interval)
|
|
24
|
+
- [test](./test)
|
|
25
|
+
- [test-advice](./test-advice)
|
|
26
|
+
- [veiled-variants](./veiled-variants)
|
|
27
|
+
- [collect-terms](./collect-terms) - gather complex vocabulary
|
|
28
|
+
|
|
29
|
+
Chains are free to use any utilities from [`../lib`](../lib/README.md) and often rely on one or more verblets from [`../verblets`](../verblets/README.md).
|
|
30
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# anonymize
|
|
2
|
+
|
|
3
|
+
Remove personal style, references, and formatting from text to conceal the original author. The chain runs through your configured LLM models, so it works with fully private or self‑hosted LLMs.
|
|
4
|
+
|
|
5
|
+
Supported methods: `STRICT`, `BALANCED`, and `LIGHT` to control how aggressively style is removed.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
```javascript
|
|
9
|
+
import anonymize, { anonymizeMethod } from './index.js';
|
|
10
|
+
|
|
11
|
+
const message = `As a software lead in Chicago, I've found our new UI framework helps junior devs ramp up fast.`;
|
|
12
|
+
|
|
13
|
+
const { text } = await anonymize({
|
|
14
|
+
text: message,
|
|
15
|
+
method: anonymizeMethod.STRICT,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
console.log(text);
|
|
19
|
+
// => "The new UI framework shortens the learning curve for new developers."
|
|
20
|
+
```
|
|
21
|
+
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { describe, it } from 'vitest';
|
|
2
|
+
import { expect } from 'chai';
|
|
3
|
+
import { anonymize, anonymizeMethod } from './index.js';
|
|
4
|
+
|
|
5
|
+
const sampleText = `As a seasoned engineer from Silicon Valley, I've found that React's
|
|
6
|
+
component lifecycle is like a well-oiled machine - understanding the mounting
|
|
7
|
+
phase is crucial, especially with those pesky useEffect hooks. Trust me, after
|
|
8
|
+
10 years of experience, proper cleanup is key to avoiding memory leaks!`;
|
|
9
|
+
|
|
10
|
+
describe('anonymize examples', () => {
|
|
11
|
+
it.only('should anonymize text using strict method', { timeout: 60_000 }, async () => {
|
|
12
|
+
const input = {
|
|
13
|
+
text: sampleText,
|
|
14
|
+
method: anonymizeMethod.STRICT,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const result = await anonymize(input);
|
|
18
|
+
|
|
19
|
+
expect(result).to.have.property('text');
|
|
20
|
+
expect(result).to.have.property('stages');
|
|
21
|
+
expect(result.stages).to.have.property('distinctiveContentRemoved');
|
|
22
|
+
expect(result.stages).to.have.property('structureNormalized');
|
|
23
|
+
expect(result.stages).to.have.property('patternsSuppressed');
|
|
24
|
+
|
|
25
|
+
// Verify anonymization removed personal markers
|
|
26
|
+
expect(result.text).to.not.include('Silicon Valley');
|
|
27
|
+
expect(result.text).to.not.include('10 years of experience');
|
|
28
|
+
expect(result.text).to.not.include('Trust me');
|
|
29
|
+
|
|
30
|
+
// Verify metaphors and idioms are removed
|
|
31
|
+
expect(result.text).to.not.include('well-oiled machine');
|
|
32
|
+
expect(result.text).to.not.include('pesky');
|
|
33
|
+
|
|
34
|
+
// Verify the text has been transformed
|
|
35
|
+
expect(result.text).to.not.equal(sampleText);
|
|
36
|
+
expect(result.text.length).to.be.lessThan(sampleText.length);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should preserve more content with balanced method', { timeout: 60_000 }, async () => {
|
|
40
|
+
const input = {
|
|
41
|
+
text: sampleText,
|
|
42
|
+
method: anonymizeMethod.BALANCED,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const result = await anonymize(input);
|
|
46
|
+
|
|
47
|
+
// Verify some personal markers are still removed
|
|
48
|
+
expect(result.text).to.not.include('Silicon Valley');
|
|
49
|
+
expect(result.text).to.not.include('Trust me');
|
|
50
|
+
|
|
51
|
+
// But technical content is more preserved
|
|
52
|
+
expect(result.text.length).to.be.greaterThan(
|
|
53
|
+
(await anonymize({ text: sampleText, method: anonymizeMethod.STRICT })).text.length
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should minimally transform text with light method', { timeout: 60_000 }, async () => {
|
|
58
|
+
const input = {
|
|
59
|
+
text: sampleText,
|
|
60
|
+
method: anonymizeMethod.LIGHT,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const result = await anonymize(input);
|
|
64
|
+
|
|
65
|
+
// Verify minimal transformation
|
|
66
|
+
expect(result.text.length).to.be.greaterThan(
|
|
67
|
+
(await anonymize({ text: sampleText, method: anonymizeMethod.BALANCED })).text.length
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// Only the most obvious personal markers should be removed
|
|
71
|
+
expect(result.text).to.not.include('Trust me');
|
|
72
|
+
|
|
73
|
+
expect(result.text).to.not.include("I've found");
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { run } from '../../lib/chatgpt/index.js';
|
|
2
|
+
|
|
3
|
+
export const anonymizeMethod = {
|
|
4
|
+
STRICT: 'strict',
|
|
5
|
+
BALANCED: 'balanced',
|
|
6
|
+
LIGHT: 'light',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const METHODS = Object.values(anonymizeMethod);
|
|
10
|
+
|
|
11
|
+
const validateInput = (input) => {
|
|
12
|
+
if (!input || typeof input !== 'object') {
|
|
13
|
+
throw new Error('Input must be an object');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const { text, method, context } = input;
|
|
17
|
+
|
|
18
|
+
if (!text || typeof text !== 'string') {
|
|
19
|
+
throw new Error('Input must include a text string');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!method || !METHODS.includes(method)) {
|
|
23
|
+
throw new Error(`Method must be one of: ${METHODS.join(', ')}`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (context !== undefined && typeof context !== 'string') {
|
|
27
|
+
throw new Error('Context must be a string if provided');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return { text, method, context };
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const stage1Prompt = (text, context) => `
|
|
34
|
+
Remove Distinctive Content and Markers
|
|
35
|
+
- Identify and replace every distinctive or uncommon word, phrase, or sentence structure with the most widely used, nondescript alternative.
|
|
36
|
+
- Remove all idioms, metaphors, analogies, cultural references, personal perspectives, and subjective tones.
|
|
37
|
+
- Eliminate any explicit or implicit references to the author's identity, background, education, expertise, region, or intent.
|
|
38
|
+
|
|
39
|
+
${context ? `Context: ${context}\n` : ''}
|
|
40
|
+
Text to process:
|
|
41
|
+
${text}
|
|
42
|
+
|
|
43
|
+
Return ONLY the processed text, with no explanations or additional content.`;
|
|
44
|
+
|
|
45
|
+
const stage2Prompt = (text, context) => `
|
|
46
|
+
Normalize Structure, Formatting, and Tone
|
|
47
|
+
- Restructure sentences and paragraphs to strictly follow standard, average patterns in length, order, and construction. Avoid any distinctive rhythm, complexity, or flow.
|
|
48
|
+
- Uniformly normalize punctuation, formatting, and paragraphing; avoid any variation or emphasis that could signal style.
|
|
49
|
+
- Strip out all emotional, evaluative, or expressive language, enforcing a neutral, impersonal, and objective tone.
|
|
50
|
+
|
|
51
|
+
${context ? `Context: ${context}\n` : ''}
|
|
52
|
+
Text to process:
|
|
53
|
+
${text}
|
|
54
|
+
|
|
55
|
+
Return ONLY the normalized text, with no explanations or additional content.`;
|
|
56
|
+
|
|
57
|
+
const stage3Prompt = (text, context) => `
|
|
58
|
+
Stage 3: Suppress Latent Stylistic Patterns
|
|
59
|
+
- Review for and suppress any recurring linguistic patterns, syntactic habits, or structural quirks—even if they appear common.
|
|
60
|
+
- For all possible ways to phrase content, always select the plainest, most generic, and least distinctive form.
|
|
61
|
+
- Ensure the final text reads as if generated by an automated system, with no evidence of personality, emotion, region, or any unique authorial traits.
|
|
62
|
+
|
|
63
|
+
${context ? `Context: ${context}\n` : ''}
|
|
64
|
+
Text to process:
|
|
65
|
+
${text}
|
|
66
|
+
|
|
67
|
+
Return ONLY the final anonymized text, with no explanations or additional content.`;
|
|
68
|
+
|
|
69
|
+
const anonymize = async (input, config = {}) => {
|
|
70
|
+
const { text, method, context } = validateInput(input);
|
|
71
|
+
const { llm, ...options } = config;
|
|
72
|
+
|
|
73
|
+
// Stage 1: Remove distinctive content
|
|
74
|
+
const stage1Result = await run(stage1Prompt(text, method, context), {
|
|
75
|
+
modelOptions: { modelName: 'privacy', ...llm },
|
|
76
|
+
...options,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
if (method === anonymizeMethod.LIGHT) {
|
|
80
|
+
return {
|
|
81
|
+
text: stage1Result,
|
|
82
|
+
stages: {
|
|
83
|
+
distinctiveContentRemoved: stage1Result,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Stage 2: Normalize structure and tone
|
|
89
|
+
const stage2Result = await run(stage2Prompt(stage1Result, method), {
|
|
90
|
+
modelOptions: { modelName: 'privacy', ...llm },
|
|
91
|
+
...options,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (method === anonymizeMethod.BALANCED) {
|
|
95
|
+
return {
|
|
96
|
+
text: stage2Result,
|
|
97
|
+
stages: {
|
|
98
|
+
distinctiveContentRemoved: stage1Result,
|
|
99
|
+
structureNormalized: stage2Result,
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Stage 3: Suppress stylistic patterns
|
|
105
|
+
const stage3Result = await run(stage3Prompt(stage2Result, method), {
|
|
106
|
+
modelOptions: { modelName: 'privacy', ...llm },
|
|
107
|
+
...options,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
text: stage3Result,
|
|
112
|
+
stages: {
|
|
113
|
+
distinctiveContentRemoved: stage1Result,
|
|
114
|
+
structureNormalized: stage2Result,
|
|
115
|
+
patternsSuppressed: stage3Result,
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export { anonymize };
|
|
121
|
+
export default anonymize;
|