feat: refactoring

Travis Fischer 2023-05-25 20:30:36 -07:00
rodzic 8b3ebb4515
commit 9e68e1a1ee
12 zmienionych plików z 862 dodań i 345 usunięć

Wyświetl plik

@ -2,7 +2,7 @@ import dotenv from 'dotenv-safe'
import { OpenAIClient } from 'openai-fetch'
import { z } from 'zod'
import { Agentic } from './../src/llm'
import { Agentic } from '../src'
dotenv.config()
@ -11,46 +11,48 @@ async function main() {
const ai = new Agentic({ openai })
const out = await ai
.gpt4(`I need random facts about {{topic}}`)
.gpt4(`Give me random facts about {{topic}}`)
.output(z.array(z.string()))
.input(z.object({ topic: z.string() }))
.modelParams({ temperature: 0.9 })
.call({ topic: 'cats' })
console.log(out)
/*
Example output:
[
'The scientific name for the domestic cat is Felis catus.',
'Cats spend 70% of their lives sleeping.',
'A group of cats is called a clowder.',
'Cats have over 100 different vocal sounds.',
'A cats nose pad is ridged with a unique pattern, just like a human fingerprint.',
'Cats can jump up to six times their length.',
'Cats can make over 20 different sounds.',
'Cats have five toes on each front paw, but only four toes on each back paw.',
'A cats whiskers are highly sensitive and can detect changes in air currents.',
'Cats have a flexible spine and can rotate their ears 180 degrees.',
'Cats can run up to 30 miles per hour.',
'Cats are believed to be the only mammals who dont taste sweetness.',
'Cats have excellent night vision and can see at one-sixth the light level required for human vision.',
'Cats cant see directly under their nose.',
'Cats can make more than 100 different sounds.',
'A cat can travel at a top speed of approximately 31 mph (49 km) over a short distance.',
'Cats are capable of walking very precisely. When they take a step, they place their back paw almost exactly in the same place as their front paw was – this is called direct registering.',
'A cats hearing is much more sensitive than humans and dogs.',
'Cats have been domesticated for around 4,000 years.',
'Cats use their tails to maintain balance and communicate their mood.',
'A cats brain is biologically more similar to a human brain than it is to a dogs.',
'Cats conserve energy by sleeping for an average of 13 to 14 hours a day.',
'A cat has a total of 24 whiskers – 4 first-order, 8 second-order, and 12 third-order.',
'Cats can pick up on changes in the weather, which can indicate to them that a storm is coming.',
'Cats have an acute sense of hearing and can detect an ultra-sonic range of sounds up to two octaves higher than humans.',
'Cats can learn to manipulate humans with their meows.',
'Cats have 32 muscles in each ear.',
'The average lifespan of an indoor cat is 13 to 17 years.',
'Cats are one of the most popular pets in the world, and there are more than 500 million domestic cats in existence.'
]
*/
Example output:
[
'The scientific name for the domestic cat is Felis catus.',
'Cats spend 70% of their lives sleeping.',
'A group of cats is called a clowder.',
'Cats have over 100 different vocal sounds.',
'A cats nose pad is ridged with a unique pattern, just like a human fingerprint.',
'Cats can jump up to six times their length.',
'Cats can make over 20 different sounds.',
'Cats have five toes on each front paw, but only four toes on each back paw.',
'A cats whiskers are highly sensitive and can detect changes in air currents.',
'Cats have a flexible spine and can rotate their ears 180 degrees.',
'Cats can run up to 30 miles per hour.',
'Cats are believed to be the only mammals who dont taste sweetness.',
'Cats have excellent night vision and can see at one-sixth the light level required for human vision.',
'Cats cant see directly under their nose.',
'Cats can make more than 100 different sounds.',
'A cat can travel at a top speed of approximately 31 mph (49 km) over a short distance.',
'Cats are capable of walking very precisely. When they take a step, they place their back paw almost exactly in the same place as their front paw was – this is called direct registering.',
'A cats hearing is much more sensitive than humans and dogs.',
'Cats have been domesticated for around 4,000 years.',
'Cats use their tails to maintain balance and communicate their mood.',
'A cats brain is biologically more similar to a human brain than it is to a dogs.',
'Cats conserve energy by sleeping for an average of 13 to 14 hours a day.',
'A cat has a total of 24 whiskers – 4 first-order, 8 second-order, and 12 third-order.',
'Cats can pick up on changes in the weather, which can indicate to them that a storm is coming.',
'Cats have an acute sense of hearing and can detect an ultra-sonic range of sounds up to two octaves higher than humans.',
'Cats can learn to manipulate humans with their meows.',
'Cats have 32 muscles in each ear.',
'The average lifespan of an indoor cat is 13 to 17 years.',
'Cats are one of the most popular pets in the world, and there are more than 500 million domestic cats in existence.'
]
*/
}
main()

Wyświetl plik

@ -1,13 +1,18 @@
import dotenv from 'dotenv-safe'
import { OpenAIClient } from 'openai-fetch'
import { z } from 'zod'
async function main() {
const $ = {} as any
import { Agentic } from '../src'
// work with a single input or an array of inputs using p-map under the hood
dotenv.config()
async function main() {
const openai = new OpenAIClient({ apiKey: process.env.OPENAI_API_KEY! })
const $ = new Agentic({ openai })
const ex0 = await $.gpt4(`give me a single boolean value: `)
.output(z.boolean())
.retry({ attempts: 3 })
// .retry({ attempts: 3 })
.call()
// LLM
@ -17,7 +22,8 @@ async function main() {
const ex1 = await $.gpt4('give me a list of character names from star wars')
.output(z.array(z.string().nonempty()))
.stream()
// .stream()
.call()
const ex2 = await $.gpt4(`Summarize the following text: {{text}}`)
.output(z.string().nonempty())
@ -26,11 +32,11 @@ async function main() {
text: 'The quick brown fox jumps over the lazy dog.'
})
const ext22 = await $.gpt4({ temperature: 0 }).call({
messages: [
// TEST
]
})
// const ext22 = await $.gpt4({ temperature: 0 }).call({
// messages: [
// // TEST
// ]
// })
const ex3 = await $.gpt4({
temperature: 0,
@ -75,3 +81,5 @@ async function main() {
.output(z.string().nonempty())
.call()
}
main()

Wyświetl plik

@ -0,0 +1,37 @@
import dotenv from 'dotenv-safe'
import { OpenAIClient } from 'openai-fetch'
import { z } from 'zod'
import { Agentic } from '../src'
dotenv.config()
async function main() {
const openai = new OpenAIClient({ apiKey: process.env.OPENAI_API_KEY! })
const $ = new Agentic({ openai })
// const ex0 = await $.gpt4(`give me a single boolean value`)
// .output(z.boolean())
// // .retry({ attempts: 3 })
// .call()
// console.log(ex0)
// const ex1 = await $.gpt4(`give me fake data`)
// .output(z.object({ foo: z.string(), bar: z.number() }))
// // .output(z.string())
// // .retry({ attempts: 3 })
// .call()
// console.log(ex1)
const getBoolean = $.gpt4(`are you {{mood}}?`)
.input(z.object({ mood: z.string() }))
.output(z.boolean())
const results = await Promise.all([
getBoolean.call({ mood: 'happy' }),
getBoolean.call({ mood: 'sad' })
])
console.log(results)
}
main()

Wyświetl plik

@ -20,6 +20,7 @@
"pre-commit": "lint-staged",
"pretest": "run-s build",
"test": "run-p test:*",
"test:unit": "ava",
"test:prettier": "prettier '**/*.{js,jsx,ts,tsx}' --check"
},
"dependencies": {
@ -29,7 +30,6 @@
"mustache": "^4.2.0",
"openai-fetch": "^1.2.1",
"p-map": "^6.0.0",
"parse-json": "^7.0.0",
"ts-dedent": "^2.2.0",
"type-fest": "^3.10.0",
"zod": "^3.21.4",
@ -40,6 +40,7 @@
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
"@types/mustache": "^4.2.2",
"@types/node": "^20.2.0",
"ava": "^5.3.0",
"del-cli": "^5.0.0",
"husky": "^8.0.3",
"lint-staged": "^13.2.2",
@ -54,6 +55,14 @@
"prettier --write"
]
},
"ava": {
"extensions": {
"ts": "module"
},
"nodeArguments": [
"--loader=tsx"
]
},
"keywords": [
"ai",
"agent",

Wyświetl plik

@ -19,9 +19,6 @@ dependencies:
p-map:
specifier: ^6.0.0
version: 6.0.0
parse-json:
specifier: ^7.0.0
version: 7.0.0(typescript@5.0.4)
ts-dedent:
specifier: ^2.2.0
version: 2.2.0
@ -48,6 +45,9 @@ devDependencies:
'@types/node':
specifier: ^20.2.0
version: 20.2.0
ava:
specifier: ^5.3.0
version: 5.3.0
del-cli:
specifier: ^5.0.0
version: 5.0.0
@ -80,6 +80,7 @@ packages:
engines: {node: '>=6.9.0'}
dependencies:
'@babel/highlight': 7.18.6
dev: true
/@babel/generator@7.17.7:
resolution: {integrity: sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==}
@ -125,6 +126,7 @@ packages:
/@babel/helper-validator-identifier@7.19.1:
resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==}
engines: {node: '>=6.9.0'}
dev: true
/@babel/highlight@7.18.6:
resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==}
@ -133,6 +135,7 @@ packages:
'@babel/helper-validator-identifier': 7.19.1
chalk: 2.4.2
js-tokens: 4.0.0
dev: true
/@babel/parser@7.21.8:
resolution: {integrity: sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==}
@ -500,6 +503,17 @@ packages:
resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
dev: true
/acorn-walk@8.2.0:
resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
engines: {node: '>=0.4.0'}
dev: true
/acorn@8.8.2:
resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==}
engines: {node: '>=0.4.0'}
hasBin: true
dev: true
/aggregate-error@3.1.0:
resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
engines: {node: '>=8'}
@ -538,6 +552,7 @@ packages:
engines: {node: '>=4'}
dependencies:
color-convert: 1.9.3
dev: true
/ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
@ -563,6 +578,12 @@ packages:
picomatch: 2.3.1
dev: true
/argparse@1.0.10:
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
dependencies:
sprintf-js: 1.0.3
dev: true
/array-buffer-byte-length@1.0.0:
resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==}
dependencies:
@ -570,21 +591,93 @@ packages:
is-array-buffer: 3.0.2
dev: true
/array-find-index@1.0.2:
resolution: {integrity: sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==}
engines: {node: '>=0.10.0'}
dev: true
/array-union@2.1.0:
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
engines: {node: '>=8'}
dev: true
/arrgv@1.0.2:
resolution: {integrity: sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==}
engines: {node: '>=8.0.0'}
dev: true
/arrify@1.0.1:
resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==}
engines: {node: '>=0.10.0'}
dev: true
/arrify@3.0.0:
resolution: {integrity: sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==}
engines: {node: '>=12'}
dev: true
/astral-regex@2.0.0:
resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
engines: {node: '>=8'}
dev: true
/ava@5.3.0:
resolution: {integrity: sha512-QYvBdyygl1LGX13IuYsC4bkwVCzZeovMGbxYkD73i7DVJxNlWnFa06YgrBOTbjw2QvSKUl5fOJ92Kj5WK9hSeg==}
engines: {node: '>=14.19 <15 || >=16.15 <17 || >=18'}
hasBin: true
peerDependencies:
'@ava/typescript': '*'
peerDependenciesMeta:
'@ava/typescript':
optional: true
dependencies:
acorn: 8.8.2
acorn-walk: 8.2.0
ansi-styles: 6.2.1
arrgv: 1.0.2
arrify: 3.0.0
callsites: 4.0.0
cbor: 8.1.0
chalk: 5.2.0
chokidar: 3.5.3
chunkd: 2.0.1
ci-info: 3.8.0
ci-parallel-vars: 1.0.1
clean-yaml-object: 0.1.0
cli-truncate: 3.1.0
code-excerpt: 4.0.0
common-path-prefix: 3.0.0
concordance: 5.0.4
currently-unhandled: 0.4.1
debug: 4.3.4
emittery: 1.0.1
figures: 5.0.0
globby: 13.1.4
ignore-by-default: 2.1.0
indent-string: 5.0.0
is-error: 2.2.2
is-plain-object: 5.0.0
is-promise: 4.0.0
matcher: 5.0.0
mem: 9.0.2
ms: 2.1.3
p-event: 5.0.1
p-map: 5.5.0
picomatch: 2.3.1
pkg-conf: 4.0.0
plur: 5.1.0
pretty-ms: 8.0.0
resolve-cwd: 3.0.0
stack-utils: 2.0.6
strip-ansi: 7.0.1
supertap: 3.0.1
temp-dir: 3.0.0
write-file-atomic: 5.0.1
yargs: 17.7.2
transitivePeerDependencies:
- supports-color
dev: true
/available-typed-arrays@1.0.5:
resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
engines: {node: '>= 0.4'}
@ -599,6 +692,10 @@ packages:
engines: {node: '>=8'}
dev: true
/blueimp-md5@2.19.0:
resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==}
dev: true
/brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
dependencies:
@ -639,6 +736,11 @@ packages:
get-intrinsic: 1.2.1
dev: true
/callsites@4.0.0:
resolution: {integrity: sha512-y3jRROutgpKdz5vzEhWM34TidDU8vkJppF8dszITeb1PQmSqV3DTxyV8G/lyO/DNvtE1YTedehmw9MPZsCBHxQ==}
engines: {node: '>=12.20'}
dev: true
/camelcase-keys@7.0.2:
resolution: {integrity: sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==}
engines: {node: '>=12'}
@ -654,6 +756,13 @@ packages:
engines: {node: '>=10'}
dev: true
/cbor@8.1.0:
resolution: {integrity: sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==}
engines: {node: '>=12.19'}
dependencies:
nofilter: 3.1.0
dev: true
/chalk@2.4.2:
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
engines: {node: '>=4'}
@ -661,6 +770,7 @@ packages:
ansi-styles: 3.2.1
escape-string-regexp: 1.0.5
supports-color: 5.5.0
dev: true
/chalk@5.2.0:
resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==}
@ -682,6 +792,19 @@ packages:
fsevents: 2.3.2
dev: true
/chunkd@2.0.1:
resolution: {integrity: sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==}
dev: true
/ci-info@3.8.0:
resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==}
engines: {node: '>=8'}
dev: true
/ci-parallel-vars@1.0.1:
resolution: {integrity: sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==}
dev: true
/clean-stack@2.2.0:
resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
engines: {node: '>=6'}
@ -694,6 +817,11 @@ packages:
escape-string-regexp: 5.0.0
dev: true
/clean-yaml-object@0.1.0:
resolution: {integrity: sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==}
engines: {node: '>=0.10.0'}
dev: true
/cli-cursor@3.1.0:
resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
engines: {node: '>=8'}
@ -717,10 +845,27 @@ packages:
string-width: 5.1.2
dev: true
/cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
dependencies:
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi: 7.0.0
dev: true
/code-excerpt@4.0.0:
resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
convert-to-spaces: 2.0.1
dev: true
/color-convert@1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
dependencies:
color-name: 1.1.3
dev: true
/color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
@ -731,6 +876,7 @@ packages:
/color-name@1.1.3:
resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
dev: true
/color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
@ -750,10 +896,33 @@ packages:
engines: {node: '>= 6'}
dev: true
/common-path-prefix@3.0.0:
resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==}
dev: true
/concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
dev: true
/concordance@5.0.4:
resolution: {integrity: sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==}
engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'}
dependencies:
date-time: 3.1.0
esutils: 2.0.3
fast-diff: 1.3.0
js-string-escape: 1.0.1
lodash: 4.17.21
md5-hex: 3.0.1
semver: 7.5.1
well-known-symbols: 2.0.0
dev: true
/convert-to-spaces@2.0.1:
resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: true
/cross-spawn@6.0.5:
resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==}
engines: {node: '>=4.8'}
@ -774,6 +943,20 @@ packages:
which: 2.0.2
dev: true
/currently-unhandled@0.4.1:
resolution: {integrity: sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==}
engines: {node: '>=0.10.0'}
dependencies:
array-find-index: 1.0.2
dev: true
/date-time@3.1.0:
resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==}
engines: {node: '>=6'}
dependencies:
time-zone: 1.0.0
dev: true
/debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
@ -857,6 +1040,11 @@ packages:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
dev: true
/emittery@1.0.1:
resolution: {integrity: sha512-2ID6FdrMD9KDLldGesP6317G78K7km/kMcwItRtVFva7I/cSEOIaLpewaUb+YLXVwdAp3Ctfxh/V5zIl1sj7dQ==}
engines: {node: '>=14.16'}
dev: true
/emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
dev: true
@ -869,6 +1057,7 @@ packages:
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
dependencies:
is-arrayish: 0.2.1
dev: true
/es-abstract@1.21.2:
resolution: {integrity: sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==}
@ -958,15 +1147,37 @@ packages:
'@esbuild/win32-x64': 0.17.19
dev: true
/escalade@3.1.1:
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
engines: {node: '>=6'}
dev: true
/escape-string-regexp@1.0.5:
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
engines: {node: '>=0.8.0'}
dev: true
/escape-string-regexp@2.0.0:
resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
engines: {node: '>=8'}
dev: true
/escape-string-regexp@5.0.0:
resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
engines: {node: '>=12'}
dev: true
/esprima@4.0.1:
resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
engines: {node: '>=4'}
hasBin: true
dev: true
/esutils@2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
dev: true
/execa@5.1.1:
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
engines: {node: '>=10'}
@ -997,6 +1208,10 @@ packages:
strip-final-newline: 3.0.0
dev: true
/fast-diff@1.3.0:
resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
dev: true
/fast-glob@3.2.12:
resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==}
engines: {node: '>=8.6.0'}
@ -1014,6 +1229,14 @@ packages:
reusify: 1.0.4
dev: true
/figures@5.0.0:
resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==}
engines: {node: '>=14'}
dependencies:
escape-string-regexp: 5.0.0
is-unicode-supported: 1.3.0
dev: true
/fill-range@7.0.1:
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
engines: {node: '>=8'}
@ -1029,6 +1252,14 @@ packages:
path-exists: 4.0.0
dev: true
/find-up@6.3.0:
resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
locate-path: 7.2.0
path-exists: 5.0.0
dev: true
/for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
dependencies:
@ -1065,6 +1296,11 @@ packages:
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
dev: true
/get-caller-file@2.0.5:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
dev: true
/get-intrinsic@1.2.1:
resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==}
dependencies:
@ -1177,6 +1413,7 @@ packages:
/has-flag@3.0.0:
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
engines: {node: '>=4'}
dev: true
/has-property-descriptors@1.0.0:
resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==}
@ -1235,11 +1472,21 @@ packages:
hasBin: true
dev: true
/ignore-by-default@2.1.0:
resolution: {integrity: sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==}
engines: {node: '>=10 <11 || >=12 <13 || >=14'}
dev: true
/ignore@5.2.4:
resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
engines: {node: '>= 4'}
dev: true
/imurmurhash@0.1.4:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'}
dev: true
/indent-string@4.0.0:
resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
engines: {node: '>=8'}
@ -1270,6 +1517,11 @@ packages:
side-channel: 1.0.4
dev: true
/irregular-plurals@3.5.0:
resolution: {integrity: sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==}
engines: {node: '>=8'}
dev: true
/is-array-buffer@3.0.2:
resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==}
dependencies:
@ -1280,6 +1532,7 @@ packages:
/is-arrayish@0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
dev: true
/is-bigint@1.0.4:
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
@ -1320,6 +1573,10 @@ packages:
has-tostringtag: 1.0.0
dev: true
/is-error@2.2.2:
resolution: {integrity: sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==}
dev: true
/is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
@ -1374,6 +1631,15 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/is-plain-object@5.0.0:
resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
engines: {node: '>=0.10.0'}
dev: true
/is-promise@4.0.0:
resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
dev: true
/is-regex@1.1.4:
resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
engines: {node: '>= 0.4'}
@ -1423,6 +1689,11 @@ packages:
has-tostringtag: 1.0.0
dev: true
/is-unicode-supported@1.3.0:
resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==}
engines: {node: '>=12'}
dev: true
/is-weakref@1.0.2:
resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
dependencies:
@ -1442,8 +1713,22 @@ packages:
engines: {node: '>=10'}
dev: true
/js-string-escape@1.0.1:
resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==}
engines: {node: '>= 0.8'}
dev: true
/js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
dev: true
/js-yaml@3.14.1:
resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
hasBin: true
dependencies:
argparse: 1.0.10
esprima: 4.0.1
dev: true
/jsesc@2.5.2:
resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
@ -1459,11 +1744,6 @@ packages:
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
dev: true
/json-parse-even-better-errors@3.0.0:
resolution: {integrity: sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
dev: false
/jsonrepair@3.1.0:
resolution: {integrity: sha512-idqReg23J0PVRAADmZMc5xQM3xeOX5bTB6OTyMnzq33IXJXmn9iJuWIEvGmrN80rQf4d7uLTMEDwpzujNcI0Rg==}
hasBin: true
@ -1488,11 +1768,6 @@ packages:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
dev: true
/lines-and-columns@2.0.3:
resolution: {integrity: sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: false
/lint-staged@13.2.2:
resolution: {integrity: sha512-71gSwXKy649VrSU09s10uAT0rWCcY3aewhMaHyl2N84oBk4Xs9HgxvUp3AYu+bNsK4NrOYYxvSgg7FyGJ+jGcA==}
engines: {node: ^14.13.1 || >=16.0.0}
@ -1545,6 +1820,11 @@ packages:
strip-bom: 3.0.0
dev: true
/load-json-file@7.0.1:
resolution: {integrity: sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: true
/load-tsconfig@0.2.5:
resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@ -1557,6 +1837,13 @@ packages:
p-locate: 5.0.0
dev: true
/locate-path@7.2.0:
resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
p-locate: 6.0.0
dev: true
/lodash.sortby@4.7.0:
resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==}
dev: true
@ -1582,6 +1869,13 @@ packages:
yallist: 4.0.0
dev: true
/map-age-cleaner@0.1.3:
resolution: {integrity: sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==}
engines: {node: '>=6'}
dependencies:
p-defer: 1.0.0
dev: true
/map-obj@1.0.1:
resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==}
engines: {node: '>=0.10.0'}
@ -1592,6 +1886,28 @@ packages:
engines: {node: '>=8'}
dev: true
/matcher@5.0.0:
resolution: {integrity: sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
escape-string-regexp: 5.0.0
dev: true
/md5-hex@3.0.1:
resolution: {integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==}
engines: {node: '>=8'}
dependencies:
blueimp-md5: 2.19.0
dev: true
/mem@9.0.2:
resolution: {integrity: sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A==}
engines: {node: '>=12.20'}
dependencies:
map-age-cleaner: 0.1.3
mimic-fn: 4.0.0
dev: true
/memorystream@0.3.1:
resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==}
engines: {node: '>= 0.10.0'}
@ -1666,6 +1982,10 @@ packages:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
dev: true
/ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
dev: true
/mustache@4.2.0:
resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==}
hasBin: true
@ -1683,6 +2003,11 @@ packages:
resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==}
dev: true
/nofilter@3.1.0:
resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==}
engines: {node: '>=12.19'}
dev: true
/normalize-package-data@2.5.0:
resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
dependencies:
@ -1788,6 +2113,18 @@ packages:
zod: 3.21.4
dev: false
/p-defer@1.0.0:
resolution: {integrity: sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==}
engines: {node: '>=4'}
dev: true
/p-event@5.0.1:
resolution: {integrity: sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
p-timeout: 5.1.0
dev: true
/p-limit@3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
@ -1795,6 +2132,13 @@ packages:
yocto-queue: 0.1.0
dev: true
/p-limit@4.0.0:
resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
yocto-queue: 1.0.0
dev: true
/p-locate@5.0.0:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
@ -1802,6 +2146,13 @@ packages:
p-limit: 3.1.0
dev: true
/p-locate@6.0.0:
resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
p-limit: 4.0.0
dev: true
/p-map@4.0.0:
resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==}
engines: {node: '>=10'}
@ -1821,6 +2172,11 @@ packages:
engines: {node: '>=16'}
dev: false
/p-timeout@5.1.0:
resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==}
engines: {node: '>=12'}
dev: true
/parse-json@4.0.0:
resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==}
engines: {node: '>=4'}
@ -1839,24 +2195,21 @@ packages:
lines-and-columns: 1.2.4
dev: true
/parse-json@7.0.0(typescript@5.0.4):
resolution: {integrity: sha512-kP+TQYAzAiVnzOlWOe0diD6L35s9bJh0SCn95PIbZFKrOYuIRQsQkeWEYxzVDuHTt9V9YqvYCJ2Qo4z9wdfZPw==}
engines: {node: '>=16'}
dependencies:
'@babel/code-frame': 7.21.4
error-ex: 1.3.2
json-parse-even-better-errors: 3.0.0
lines-and-columns: 2.0.3
type-fest: 3.10.0(typescript@5.0.4)
transitivePeerDependencies:
- typescript
dev: false
/parse-ms@3.0.0:
resolution: {integrity: sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==}
engines: {node: '>=12'}
dev: true
/path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
dev: true
/path-exists@5.0.0:
resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: true
/path-is-absolute@1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
@ -1920,6 +2273,21 @@ packages:
engines: {node: '>= 6'}
dev: true
/pkg-conf@4.0.0:
resolution: {integrity: sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
find-up: 6.3.0
load-json-file: 7.0.1
dev: true
/plur@5.1.0:
resolution: {integrity: sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
irregular-plurals: 3.5.0
dev: true
/postcss-load-config@3.1.4:
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
engines: {node: '>= 10'}
@ -1942,6 +2310,13 @@ packages:
hasBin: true
dev: true
/pretty-ms@8.0.0:
resolution: {integrity: sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==}
engines: {node: '>=14.16'}
dependencies:
parse-ms: 3.0.0
dev: true
/punycode@2.3.0:
resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
engines: {node: '>=6'}
@ -2008,6 +2383,18 @@ packages:
functions-have-names: 1.2.3
dev: true
/require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
dev: true
/resolve-cwd@3.0.0:
resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==}
engines: {node: '>=8'}
dependencies:
resolve-from: 5.0.0
dev: true
/resolve-from@5.0.0:
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
engines: {node: '>=8'}
@ -2087,6 +2474,13 @@ packages:
lru-cache: 6.0.0
dev: true
/serialize-error@7.0.1:
resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
engines: {node: '>=10'}
dependencies:
type-fest: 0.13.1
dev: true
/shebang-command@1.2.0:
resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==}
engines: {node: '>=0.10.0'}
@ -2127,6 +2521,11 @@ packages:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
dev: true
/signal-exit@4.0.2:
resolution: {integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==}
engines: {node: '>=14'}
dev: true
/slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
@ -2209,6 +2608,17 @@ packages:
resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==}
dev: true
/sprintf-js@1.0.3:
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
dev: true
/stack-utils@2.0.6:
resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
engines: {node: '>=10'}
dependencies:
escape-string-regexp: 2.0.0
dev: true
/string-argv@0.3.2:
resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
engines: {node: '>=0.6.19'}
@ -2316,17 +2726,33 @@ packages:
ts-interface-checker: 0.1.13
dev: true
/supertap@3.0.1:
resolution: {integrity: sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
indent-string: 5.0.0
js-yaml: 3.14.1
serialize-error: 7.0.1
strip-ansi: 7.0.1
dev: true
/supports-color@5.5.0:
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
engines: {node: '>=4'}
dependencies:
has-flag: 3.0.0
dev: true
/supports-preserve-symlinks-flag@1.0.0:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
dev: true
/temp-dir@3.0.0:
resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==}
engines: {node: '>=14.16'}
dev: true
/thenify-all@1.6.0:
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
engines: {node: '>=0.8'}
@ -2344,6 +2770,11 @@ packages:
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
dev: true
/time-zone@1.0.0:
resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==}
engines: {node: '>=4'}
dev: true
/to-fast-properties@2.0.0:
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
engines: {node: '>=4'}
@ -2432,6 +2863,11 @@ packages:
fsevents: 2.3.2
dev: true
/type-fest@0.13.1:
resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
engines: {node: '>=10'}
dev: true
/type-fest@0.21.3:
resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
engines: {node: '>=10'}
@ -2484,6 +2920,11 @@ packages:
resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
dev: true
/well-known-symbols@2.0.0:
resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==}
engines: {node: '>=6'}
dev: true
/whatwg-url@7.1.0:
resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
dependencies:
@ -2551,6 +2992,19 @@ packages:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
dev: true
/write-file-atomic@5.0.1:
resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
dependencies:
imurmurhash: 0.1.4
signal-exit: 4.0.2
dev: true
/y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
dev: true
/yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
dev: true
@ -2570,11 +3024,34 @@ packages:
engines: {node: '>=10'}
dev: true
/yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
dev: true
/yargs@17.7.2:
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
engines: {node: '>=12'}
dependencies:
cliui: 8.0.1
escalade: 3.1.1
get-caller-file: 2.0.5
require-directory: 2.1.1
string-width: 4.2.3
y18n: 5.0.8
yargs-parser: 21.1.1
dev: true
/yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
dev: true
/yocto-queue@1.0.0:
resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
engines: {node: '>=12.20'}
dev: true
/zod-to-ts@1.1.4(typescript@5.0.4)(zod@3.21.4):
resolution: {integrity: sha512-jsCg+pTNxLAdJOfW4ul+SpechdGYEJPPnssSbqWdR2LSIkotT22k+UvqPb1nEHwe/YbEcbUOlZUfGM0npgR+Jg==}
peerDependencies:

67
src/agentic.ts 100644
Wyświetl plik

@ -0,0 +1,67 @@
import * as types from './types'
import { defaultOpenAIModel } from './constants'
import { OpenAIChatModelBuilder } from './openai'
export class Agentic {
_client: types.openai.OpenAIClient
_verbosity: number
_defaults: Pick<
types.BaseLLMOptions,
'provider' | 'model' | 'modelParams' | 'timeoutMs' | 'retryConfig'
>
constructor(opts: {
openai: types.openai.OpenAIClient
verbosity?: number
defaults?: Pick<
types.BaseLLMOptions,
'provider' | 'model' | 'modelParams' | 'timeoutMs' | 'retryConfig'
>
}) {
this._client = opts.openai
this._verbosity = opts.verbosity ?? 0
this._defaults = {
provider: 'openai',
model: defaultOpenAIModel,
modelParams: {},
timeoutMs: 30000,
retryConfig: {
attempts: 3,
strategy: 'heal',
...opts.defaults?.retryConfig
},
...opts.defaults
}
}
gpt4(
promptOrChatCompletionParams:
| string
| Omit<types.openai.ChatCompletionParams, 'model'>
) {
let options: Omit<types.openai.ChatCompletionParams, 'model'>
if (typeof promptOrChatCompletionParams === 'string') {
options = {
messages: [
{
role: 'user',
content: promptOrChatCompletionParams
}
]
}
} else {
options = promptOrChatCompletionParams
if (!options.messages) {
throw new Error('messages must be provided')
}
}
return new OpenAIChatModelBuilder(this._client, {
...(this._defaults as any), // TODO
model: 'gpt-4',
...options
})
}
}

1
src/constants.ts 100644
Wyświetl plik

@ -0,0 +1 @@
export const defaultOpenAIModel = 'gpt-3.5-turbo'

Wyświetl plik

@ -1,2 +1,4 @@
export * from './agentic'
export * from './llm'
export * from './openai'
export * from './tokenizer'

Wyświetl plik

@ -1,79 +1,6 @@
import { jsonrepair } from 'jsonrepair'
import Mustache from 'mustache'
import { dedent } from 'ts-dedent'
import type { SetRequired } from 'type-fest'
import { ZodRawShape, ZodTypeAny, z } from 'zod'
import { printNode, zodToTs } from 'zod-to-ts'
import * as types from './types'
import {
extractJSONArrayFromString,
extractJSONObjectFromString
} from './utils'
const defaultOpenAIModel = 'gpt-3.5-turbo'
export class Agentic {
_client: types.openai.OpenAIClient
_verbosity: number
_defaults: Pick<
types.BaseLLMOptions,
'provider' | 'model' | 'modelParams' | 'timeoutMs' | 'retryConfig'
>
constructor(opts: {
openai: types.openai.OpenAIClient
verbosity?: number
defaults?: Pick<
types.BaseLLMOptions,
'provider' | 'model' | 'modelParams' | 'timeoutMs' | 'retryConfig'
>
}) {
this._client = opts.openai
this._verbosity = opts.verbosity ?? 0
this._defaults = {
provider: 'openai',
model: defaultOpenAIModel,
modelParams: {},
timeoutMs: 30000,
retryConfig: {
attempts: 3,
strategy: 'heal',
...opts.defaults?.retryConfig
},
...opts.defaults
}
}
gpt4(
promptOrChatCompletionParams: string | types.openai.ChatCompletionParams
) {
let options: Omit<types.openai.ChatCompletionParams, 'model'>
if (typeof promptOrChatCompletionParams === 'string') {
options = {
messages: [
{
role: 'user',
content: promptOrChatCompletionParams
}
]
}
} else {
options = promptOrChatCompletionParams
if (!options.messages) {
throw new Error('messages must be provided')
}
}
return new OpenAIChatModelBuilder(this._client, {
...(this._defaults as any), // TODO
model: 'gpt-4',
...options
})
}
}
export abstract class BaseLLMCallBuilder<
TInput extends ZodRawShape | ZodTypeAny = ZodTypeAny,
@ -148,138 +75,3 @@ export abstract class ChatModelBuilder<
this._messages = options.messages
}
}
export class OpenAIChatModelBuilder<
TInput extends ZodRawShape | ZodTypeAny = ZodTypeAny,
TOutput extends ZodRawShape | ZodTypeAny = z.ZodType<string>
> extends ChatModelBuilder<
TInput,
TOutput,
SetRequired<Omit<types.openai.ChatCompletionParams, 'messages'>, 'model'>
> {
_client: types.openai.OpenAIClient
constructor(
client: types.openai.OpenAIClient,
options: types.ChatModelOptions<
TInput,
TOutput,
Omit<types.openai.ChatCompletionParams, 'messages'>
>
) {
super({
provider: 'openai',
model: defaultOpenAIModel,
...options
})
this._client = client
}
override async call(
input?: types.ParsedData<TInput>
): Promise<types.ParsedData<TOutput>> {
if (this._options.input) {
const inputSchema =
this._options.input instanceof z.ZodType
? this._options.input
: z.object(this._options.input)
// TODO: handle errors gracefully
input = inputSchema.parse(input)
}
// TODO: validate input message variables against input schema
const messages = this._messages
.map((message) => {
return {
...message,
content: message.content
? Mustache.render(dedent(message.content), input).trim()
: ''
}
})
.filter((message) => message.content)
if (this._options.output) {
const outputSchema =
this._options.output instanceof z.ZodType
? this._options.output
: z.object(this._options.output)
const { node } = zodToTs(outputSchema)
if (node.kind === 152) {
// ignore raw strings
messages.push({
role: 'system',
content: dedent`Output a string`
})
} else {
const tsTypeString = printNode(node, {
removeComments: false,
// TODO: this doesn't seem to actually work, so we're doing it manually below
omitTrailingSemicolon: true,
noEmitHelpers: true
})
.replace(/^ /gm, ' ')
.replace(/;$/gm, '')
messages.push({
role: 'system',
content: dedent`Output JSON only in the following format:
\`\`\`ts
${tsTypeString}
\`\`\``
})
}
}
// TODO: filter/compress messages based on token counts
console.log('>>>')
console.log(messages)
const completion = await this._client.createChatCompletion({
model: defaultOpenAIModel, // TODO: this shouldn't be necessary but TS is complaining
...this._options.modelParams,
messages
})
if (this._options.output) {
const outputSchema =
this._options.output instanceof z.ZodType
? this._options.output
: z.object(this._options.output)
let output: any = completion.message.content
console.log('===')
console.log(output)
console.log('<<<')
if (outputSchema instanceof z.ZodArray) {
try {
const trimmedOutput = extractJSONArrayFromString(output)
output = JSON.parse(jsonrepair(trimmedOutput ?? output))
} catch (err) {
// TODO
throw err
}
} else if (outputSchema instanceof z.ZodObject) {
try {
const trimmedOutput = extractJSONObjectFromString(output)
output = JSON.parse(jsonrepair(trimmedOutput ?? output))
} catch (err) {
// TODO
throw err
}
}
// TODO: handle errors, retry logic, and self-healing
return outputSchema.parse(output)
} else {
return completion.message.content as any
}
}
}

188
src/openai.ts 100644
Wyświetl plik

@ -0,0 +1,188 @@
import { jsonrepair } from 'jsonrepair'
import Mustache from 'mustache'
import { dedent } from 'ts-dedent'
import type { SetRequired } from 'type-fest'
import { ZodRawShape, ZodTypeAny, z } from 'zod'
import { printNode, zodToTs } from 'zod-to-ts'
import * as types from './types'
import { defaultOpenAIModel } from './constants'
import { ChatModelBuilder } from './llm'
import {
extractJSONArrayFromString,
extractJSONObjectFromString
} from './utils'
export class OpenAIChatModelBuilder<
TInput extends ZodRawShape | ZodTypeAny = ZodTypeAny,
TOutput extends ZodRawShape | ZodTypeAny = z.ZodType<string>
> extends ChatModelBuilder<
TInput,
TOutput,
SetRequired<Omit<types.openai.ChatCompletionParams, 'messages'>, 'model'>
> {
_client: types.openai.OpenAIClient
constructor(
client: types.openai.OpenAIClient,
options: types.ChatModelOptions<
TInput,
TOutput,
Omit<types.openai.ChatCompletionParams, 'messages'>
>
) {
super({
provider: 'openai',
model: defaultOpenAIModel,
...options
})
this._client = client
}
override async call(
input?: types.ParsedData<TInput>
): Promise<types.ParsedData<TOutput>> {
if (this._options.input) {
const inputSchema =
this._options.input instanceof z.ZodType
? this._options.input
: z.object(this._options.input)
// TODO: handle errors gracefully
input = inputSchema.parse(input)
}
// TODO: validate input message variables against input schema
const messages = this._messages
.map((message) => {
return {
...message,
content: message.content
? Mustache.render(dedent(message.content), input).trim()
: ''
}
})
.filter((message) => message.content)
if (this._options.examples?.length) {
// TODO: smarter example selection
for (const example of this._options.examples) {
messages.push({
role: 'system',
content: `Example input: ${example.input}\n\nExample output: ${example.output}`
})
}
}
if (this._options.output) {
const outputSchema =
this._options.output instanceof z.ZodType
? this._options.output
: z.object(this._options.output)
const { node } = zodToTs(outputSchema)
if (node.kind === 152) {
// handle raw strings differently
messages.push({
role: 'system',
content: dedent`Output a raw string only, without any additional text.`
})
} else {
const tsTypeString = printNode(node, {
removeComments: false,
// TODO: this doesn't seem to actually work, so we're doing it manually below
omitTrailingSemicolon: true,
noEmitHelpers: true
})
.replace(/^ /gm, ' ')
.replace(/;$/gm, '')
messages.push({
role: 'system',
content: dedent`Output JSON only in the following format:
\`\`\`ts
${tsTypeString}
\`\`\``
})
}
}
// TODO: filter/compress messages based on token counts
console.log('>>>')
console.log(messages)
const completion = await this._client.createChatCompletion({
model: defaultOpenAIModel, // TODO: this shouldn't be necessary but TS is complaining
...this._options.modelParams,
messages
})
if (this._options.output) {
const outputSchema =
this._options.output instanceof z.ZodType
? this._options.output
: z.object(this._options.output)
let output: any = completion.message.content
console.log('===')
console.log(output)
console.log('<<<')
if (outputSchema instanceof z.ZodArray) {
try {
const trimmedOutput = extractJSONArrayFromString(output)
output = JSON.parse(jsonrepair(trimmedOutput ?? output))
} catch (err) {
// TODO
throw err
}
} else if (outputSchema instanceof z.ZodObject) {
try {
const trimmedOutput = extractJSONObjectFromString(output)
output = JSON.parse(jsonrepair(trimmedOutput ?? output))
} catch (err) {
// TODO
throw err
}
} else if (outputSchema instanceof z.ZodBoolean) {
output = output.toLowerCase().trim()
const booleanOutputs = {
true: true,
false: false,
yes: true,
no: false,
1: true,
0: false
}
const booleanOutput = booleanOutputs[output]
if (booleanOutput !== undefined) {
output = booleanOutput
} else {
throw new Error(`invalid boolean output: ${output}`)
}
} else if (outputSchema instanceof z.ZodNumber) {
output = output.trim()
const numberOutput = outputSchema.isInt
? parseInt(output)
: parseFloat(output)
if (isNaN(numberOutput)) {
throw new Error(`invalid number output: ${output}`)
} else {
output = numberOutput
}
}
// TODO: handle errors, retry logic, and self-healing
return outputSchema.parse(output)
} else {
return completion.message.content as any
}
}
}

Wyświetl plik

@ -1,38 +0,0 @@
import dotenv from 'dotenv-safe'
import { OpenAIClient } from 'openai-fetch'
import { z } from 'zod'
import { Agentic } from './llm'
// import { LLMQuery } from '@agentic/llm-query'
dotenv.config()
async function main() {
const openai = new OpenAIClient({ apiKey: process.env.OPENAI_API_KEY! })
const $ = new Agentic({ openai })
// const ex0 = await $.gpt4(`give me a single boolean value`)
// .output(z.boolean())
// // .retry({ attempts: 3 })
// .call()
// console.log(ex0)
const ex1 = await $.gpt4(`give me fake data`)
.output(z.object({ foo: z.string(), bar: z.number() }))
// .output(z.string())
// .retry({ attempts: 3 })
.call()
console.log(ex1)
// const getBoolean = $.gpt4(`give me a single boolean value {{foo}}`)
// .input(z.object({ foo: z.string() }))
// .output(z.boolean())
// await Promise.all([
// getBoolean.call({ foo: 'foo' }),
// getBoolean.call({ foo: 'bar' })
// ])
}
main()

Wyświetl plik

@ -1,28 +0,0 @@
import { ZodRawShape, ZodType, ZodTypeAny, z } from 'zod'
import * as types from './types'
class Test<T extends ZodRawShape | ZodTypeAny = ZodTypeAny> {
_schema: T
schema<U extends ZodRawShape | ZodTypeAny>(schema: U): Test<U> {
;(this as unknown as Test<U>)._schema = schema
return this as unknown as Test<U>
}
call(value: types.ParsedData<T>): types.ParsedData<T> {
const finalSchema =
this._schema instanceof ZodType ? this._schema : z.object(this._schema)
return finalSchema.parse(value)
}
}
async function main() {
const t = new Test()
const t2 = t.schema(z.string())
const t3 = t2.call('foo')
console.log(t3)
}
main()