feat: ai sdk

This commit is contained in:
Jelf 2024-09-20 22:18:41 +08:00
parent 343d89304e
commit 6d5f885306
3 changed files with 575 additions and 166 deletions

View file

@ -8,7 +8,12 @@
"name": "void",
"version": "0.0.1",
"dependencies": {
"@ai-sdk/anthropic": "^0.0.50",
"@ai-sdk/azure": "^0.0.39",
"@ai-sdk/openai": "^0.0.60",
"@anthropic-ai/sdk": "^0.27.1",
"ai": "^3.3.43",
"ollama-ai-provider": "^0.15.0",
"openai": "^4.57.0"
},
"devDependencies": {
@ -46,6 +51,239 @@
"vscode": "^1.89.0"
}
},
"node_modules/@ai-sdk/anthropic": {
"version": "0.0.50",
"resolved": "https://registry.npmmirror.com/@ai-sdk/anthropic/-/anthropic-0.0.50.tgz",
"integrity": "sha512-++mqmFcUoQgjoCchAU6eVG3QfKdwkeJVNdMZ+jUiNdawn8diA6BlARlu7xFT4F7W3bcStfYv4hK1jwRyzAQtCg==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider": "0.0.23",
"@ai-sdk/provider-utils": "1.0.19"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"zod": "^3.0.0"
}
},
"node_modules/@ai-sdk/azure": {
"version": "0.0.39",
"resolved": "https://registry.npmmirror.com/@ai-sdk/azure/-/azure-0.0.39.tgz",
"integrity": "sha512-P6CdIwLfkvkhf2hHkbnhqLOkVMQLu7XlksJ2YvzS4yx2Iwl8fsKLVnaCWMX9SBlYfamT/oea+rpyF60JhkdMZg==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/openai": "0.0.61",
"@ai-sdk/provider": "0.0.23",
"@ai-sdk/provider-utils": "1.0.19"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"zod": "^3.0.0"
}
},
"node_modules/@ai-sdk/azure/node_modules/@ai-sdk/openai": {
"version": "0.0.61",
"resolved": "https://registry.npmmirror.com/@ai-sdk/openai/-/openai-0.0.61.tgz",
"integrity": "sha512-yIJ70xU9sbDjVAaNoq+W+0jnAgIUsx4e9VTnoNPXNTIQRpgpLvQ7iG8GYNgujO4oX4sLiHsWpOEMzrSwD0mNmw==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider": "0.0.23",
"@ai-sdk/provider-utils": "1.0.19"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"zod": "^3.0.0"
}
},
"node_modules/@ai-sdk/openai": {
"version": "0.0.60",
"resolved": "https://registry.npmmirror.com/@ai-sdk/openai/-/openai-0.0.60.tgz",
"integrity": "sha512-NEdDdv3o76jT6UeWHxP6I/lMYcjFQhQGQi/U2gVqW1PEU4Pjaud7tAVSy27IPbiRakg6GOzWrltI2JhZgAI1wg==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider": "0.0.23",
"@ai-sdk/provider-utils": "1.0.19"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"zod": "^3.0.0"
}
},
"node_modules/@ai-sdk/provider": {
"version": "0.0.23",
"resolved": "https://registry.npmmirror.com/@ai-sdk/provider/-/provider-0.0.23.tgz",
"integrity": "sha512-oAc49O5+xypVrKM7EUU5P/Y4DUL4JZUWVxhejoAVOTOl3WZUEWsMbP3QZR+TrimQIsS0WR/n9UuF6U0jPdp0tQ==",
"license": "Apache-2.0",
"dependencies": {
"json-schema": "0.4.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@ai-sdk/provider-utils": {
"version": "1.0.19",
"resolved": "https://registry.npmmirror.com/@ai-sdk/provider-utils/-/provider-utils-1.0.19.tgz",
"integrity": "sha512-p02Fq5Mnc8T6nwRBN1Iaou8YXvN1sDS6hbmJaD5UaRbXjizbh+8rpFS/o7jqAHTwf3uHCDitP3pnODyHdc/CDQ==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider": "0.0.23",
"eventsource-parser": "1.1.2",
"nanoid": "3.3.6",
"secure-json-parse": "2.7.0"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"zod": "^3.0.0"
},
"peerDependenciesMeta": {
"zod": {
"optional": true
}
}
},
"node_modules/@ai-sdk/provider-utils/node_modules/nanoid": {
"version": "3.3.6",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/@ai-sdk/react": {
"version": "0.0.59",
"resolved": "https://registry.npmmirror.com/@ai-sdk/react/-/react-0.0.59.tgz",
"integrity": "sha512-1WbgO3J2/OoheMuNMxy5itJ3NVqOpqpAQxFNp7AoXgnDv4wDF4kTif61rTlKh7dCPvBHj2HXLmob+TrVFaWhYw==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider-utils": "1.0.19",
"@ai-sdk/ui-utils": "0.0.44",
"swr": "2.2.5"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"react": "^18 || ^19",
"zod": "^3.0.0"
},
"peerDependenciesMeta": {
"react": {
"optional": true
},
"zod": {
"optional": true
}
}
},
"node_modules/@ai-sdk/solid": {
"version": "0.0.47",
"resolved": "https://registry.npmmirror.com/@ai-sdk/solid/-/solid-0.0.47.tgz",
"integrity": "sha512-lVMxIxtuNqoo/TObSFGflEP2dUeJv7bfPQbS4jHTZGBNlyhgBRY2Xc19yNjA3QKRfvQNDVoQusqxn+18MiHJJQ==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider-utils": "1.0.19",
"@ai-sdk/ui-utils": "0.0.44"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"solid-js": "^1.7.7"
},
"peerDependenciesMeta": {
"solid-js": {
"optional": true
}
}
},
"node_modules/@ai-sdk/svelte": {
"version": "0.0.49",
"resolved": "https://registry.npmmirror.com/@ai-sdk/svelte/-/svelte-0.0.49.tgz",
"integrity": "sha512-gV0MhaWxkatjf7uJrCAHO3bWrihokNUwGhuMCgyG+y53lwJKAYhR0zCoDRM2HnTJ89fdnx/PVe3R9fOWEVY5qA==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider-utils": "1.0.19",
"@ai-sdk/ui-utils": "0.0.44",
"sswr": "2.1.0"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"svelte": "^3.0.0 || ^4.0.0"
},
"peerDependenciesMeta": {
"svelte": {
"optional": true
}
}
},
"node_modules/@ai-sdk/ui-utils": {
"version": "0.0.44",
"resolved": "https://registry.npmmirror.com/@ai-sdk/ui-utils/-/ui-utils-0.0.44.tgz",
"integrity": "sha512-0qiyun/n5zqJzQs/WfQT86dZE5DiDhSHJc7b7ZGLYvNMztHkRQmak2zUCZP4IyGVZEicyEPQK6NEEpBgkmd3Dg==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider": "0.0.23",
"@ai-sdk/provider-utils": "1.0.19",
"json-schema": "0.4.0",
"secure-json-parse": "2.7.0",
"zod-to-json-schema": "3.23.2"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"zod": "^3.0.0"
},
"peerDependenciesMeta": {
"zod": {
"optional": true
}
}
},
"node_modules/@ai-sdk/vue": {
"version": "0.0.50",
"resolved": "https://registry.npmmirror.com/@ai-sdk/vue/-/vue-0.0.50.tgz",
"integrity": "sha512-eIWfxqpKwRdL3rxJMg1HDJcjfugFJGg4P934Tl69S7UCot2/U4BPZoESVJQFroS1elbKHaMRgv0ZJt1ddWQPjQ==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider-utils": "1.0.19",
"@ai-sdk/ui-utils": "0.0.44",
"swrv": "1.0.4"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"vue": "^3.3.4"
},
"peerDependenciesMeta": {
"vue": {
"optional": true
}
}
},
"node_modules/@alloc/quick-lru": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
@ -533,6 +771,15 @@
"node": ">= 8"
}
},
"node_modules/@opentelemetry/api": {
"version": "1.9.0",
"resolved": "https://registry.npmmirror.com/@opentelemetry/api/-/api-1.9.0.tgz",
"integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
"license": "Apache-2.0",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@ -564,6 +811,12 @@
"integrity": "sha512-qVqLpd49rmJA2nZzLVsmfS/aiiBpfVE95dHhPVwG0NmSBAt+riPxnj53wq2oBq5m4Q2RF1IWFEUpnZTgrQZfEQ==",
"dev": true
},
"node_modules/@types/diff-match-patch": {
"version": "1.0.36",
"resolved": "https://registry.npmmirror.com/@types/diff-match-patch/-/diff-match-patch-1.0.36.tgz",
"integrity": "sha512-xFdR6tkm0MWvBfO8xXCSsinYxHcqkQUlcHeSpMC2ukzOb6lwQAfDmW+Qt0AvlGd8HpsS28qKsB+oPeJn9I39jg==",
"license": "MIT"
},
"node_modules/@types/estree": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
@ -1000,6 +1253,73 @@
"node": ">= 8.0.0"
}
},
"node_modules/ai": {
"version": "3.3.43",
"resolved": "https://registry.npmmirror.com/ai/-/ai-3.3.43.tgz",
"integrity": "sha512-B4susrnVOapUVRYWuzNp3ChFZ7lBB3w9VFofIDiwrAoOkrljImkZgE2cUdIvWzwj/v3DiBtfPsPbOv+S2YRkCQ==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider": "0.0.23",
"@ai-sdk/provider-utils": "1.0.19",
"@ai-sdk/react": "0.0.59",
"@ai-sdk/solid": "0.0.47",
"@ai-sdk/svelte": "0.0.49",
"@ai-sdk/ui-utils": "0.0.44",
"@ai-sdk/vue": "0.0.50",
"@opentelemetry/api": "1.9.0",
"eventsource-parser": "1.1.2",
"json-schema": "0.4.0",
"jsondiffpatch": "0.6.0",
"nanoid": "3.3.6",
"secure-json-parse": "2.7.0",
"zod-to-json-schema": "3.23.2"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"openai": "^4.42.0",
"react": "^18 || ^19",
"sswr": "^2.1.0",
"svelte": "^3.0.0 || ^4.0.0",
"zod": "^3.0.0"
},
"peerDependenciesMeta": {
"openai": {
"optional": true
},
"react": {
"optional": true
},
"sswr": {
"optional": true
},
"svelte": {
"optional": true
},
"zod": {
"optional": true
}
}
},
"node_modules/ai/node_modules/nanoid": {
"version": "3.3.6",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@ -1670,6 +1990,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/client-only": {
"version": "0.0.1",
"resolved": "https://registry.npmmirror.com/client-only/-/client-only-0.0.1.tgz",
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
"license": "MIT"
},
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@ -1997,6 +2323,12 @@
"node": ">=0.3.1"
}
},
"node_modules/diff-match-patch": {
"version": "1.0.5",
"resolved": "https://registry.npmmirror.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
"integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==",
"license": "Apache-2.0"
},
"node_modules/diff-sequences": {
"version": "29.6.3",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
@ -2578,6 +2910,15 @@
"node": ">=6"
}
},
"node_modules/eventsource-parser": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/eventsource-parser/-/eventsource-parser-1.1.2.tgz",
"integrity": "sha512-v0eOBUbiaFojBu2s2NPBfYUoRR9GjcDNvCXVaqEf5vVfpIAh9f8RCo4vXTP8c63QRKCFwoLpMpTdPwwhEKVgzA==",
"license": "MIT",
"engines": {
"node": ">=14.18"
}
},
"node_modules/expect": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz",
@ -3957,6 +4298,12 @@
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
"dev": true
},
"node_modules/json-schema": {
"version": "0.4.0",
"resolved": "https://registry.npmmirror.com/json-schema/-/json-schema-0.4.0.tgz",
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
"license": "(AFL-2.1 OR BSD-3-Clause)"
},
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@ -3969,6 +4316,35 @@
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true
},
"node_modules/jsondiffpatch": {
"version": "0.6.0",
"resolved": "https://registry.npmmirror.com/jsondiffpatch/-/jsondiffpatch-0.6.0.tgz",
"integrity": "sha512-3QItJOXp2AP1uv7waBkao5nCvhEv+QmJAd38Ybq7wNI74Q+BBmnLn4EDKz6yI9xGAIQoUF87qHt+kc1IVxB4zQ==",
"license": "MIT",
"dependencies": {
"@types/diff-match-patch": "^1.0.36",
"chalk": "^5.3.0",
"diff-match-patch": "^1.0.5"
},
"bin": {
"jsondiffpatch": "bin/jsondiffpatch.js"
},
"engines": {
"node": "^18.0.0 || >=20.0.0"
}
},
"node_modules/jsondiffpatch/node_modules/chalk": {
"version": "5.3.0",
"resolved": "https://registry.npmmirror.com/chalk/-/chalk-5.3.0.tgz",
"integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
"license": "MIT",
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/jsx-ast-utils": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
@ -5193,6 +5569,69 @@
"whatwg-fetch": "^3.6.20"
}
},
"node_modules/ollama-ai-provider": {
"version": "0.15.0",
"resolved": "https://registry.npmmirror.com/ollama-ai-provider/-/ollama-ai-provider-0.15.0.tgz",
"integrity": "sha512-pBRv2PjOPFdjB2fxOcu4dV3oT6NUxUI+V3c0Cu3r8Dwv6WmhHkRGLMscyRMU4Q2YVAtbghrvkfBGQmaqpMh/KQ==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider": "0.0.23",
"@ai-sdk/provider-utils": "1.0.18",
"partial-json": "0.1.7"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"zod": "^3.0.0"
},
"peerDependenciesMeta": {
"zod": {
"optional": true
}
}
},
"node_modules/ollama-ai-provider/node_modules/@ai-sdk/provider-utils": {
"version": "1.0.18",
"resolved": "https://registry.npmmirror.com/@ai-sdk/provider-utils/-/provider-utils-1.0.18.tgz",
"integrity": "sha512-9u/XE/dB1gsIGcxiC5JfGOLzUz+EKRXt66T8KYWwDg4x8d02P+fI/EPOgkf+T4oLBrcQgvs4GPXPKoXGPJxBbg==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider": "0.0.23",
"eventsource-parser": "1.1.2",
"nanoid": "3.3.6",
"secure-json-parse": "2.7.0"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"zod": "^3.0.0"
},
"peerDependenciesMeta": {
"zod": {
"optional": true
}
}
},
"node_modules/ollama-ai-provider/node_modules/nanoid": {
"version": "3.3.6",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@ -5465,6 +5904,12 @@
"integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
"dev": true
},
"node_modules/partial-json": {
"version": "0.1.7",
"resolved": "https://registry.npmmirror.com/partial-json/-/partial-json-0.1.7.tgz",
"integrity": "sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==",
"license": "MIT"
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@ -6248,6 +6693,12 @@
"loose-envify": "^1.1.0"
}
},
"node_modules/secure-json-parse": {
"version": "2.7.0",
"resolved": "https://registry.npmmirror.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz",
"integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==",
"license": "BSD-3-Clause"
},
"node_modules/semver": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
@ -6386,6 +6837,18 @@
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/sswr": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/sswr/-/sswr-2.1.0.tgz",
"integrity": "sha512-Cqc355SYlTAaUt8iDPaC/4DPPXK925PePLMxyBKuWd5kKc5mwsG3nT9+Mq2tyguL5s7b4Jg+IRMpTRsNTAfpSQ==",
"license": "MIT",
"dependencies": {
"swrev": "^4.0.0"
},
"peerDependencies": {
"svelte": "^4.0.0 || ^5.0.0-next.0"
}
},
"node_modules/stack-utils": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
@ -6687,6 +7150,34 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/swr": {
"version": "2.2.5",
"resolved": "https://registry.npmmirror.com/swr/-/swr-2.2.5.tgz",
"integrity": "sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==",
"license": "MIT",
"dependencies": {
"client-only": "^0.0.1",
"use-sync-external-store": "^1.2.0"
},
"peerDependencies": {
"react": "^16.11.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/swrev": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/swrev/-/swrev-4.0.0.tgz",
"integrity": "sha512-LqVcOHSB4cPGgitD1riJ1Hh4vdmITOp+BkmfmXRh4hSF/t7EnS4iD+SOTmq7w5pPm/SiPeto4ADbKS6dHUDWFA==",
"license": "MIT"
},
"node_modules/swrv": {
"version": "1.0.4",
"resolved": "https://registry.npmmirror.com/swrv/-/swrv-1.0.4.tgz",
"integrity": "sha512-zjEkcP8Ywmj+xOJW3lIT65ciY/4AL4e/Or7Gj0MzU3zBJNMdJiT8geVZhINavnlHRMMCcJLHhraLTAiDOTmQ9g==",
"license": "Apache-2.0",
"peerDependencies": {
"vue": ">=3.2.26 < 4"
}
},
"node_modules/tailwindcss": {
"version": "3.4.12",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.12.tgz",
@ -7180,6 +7671,15 @@
"punycode": "^2.1.0"
}
},
"node_modules/use-sync-external-store": {
"version": "1.2.2",
"resolved": "https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz",
"integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==",
"license": "MIT",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@ -7575,6 +8075,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/zod-to-json-schema": {
"version": "3.23.2",
"resolved": "https://registry.npmmirror.com/zod-to-json-schema/-/zod-to-json-schema-3.23.2.tgz",
"integrity": "sha512-uSt90Gzc/tUfyNqxnjlfBs8W6WSGpNBv0rVsNxP/BVSMHMKGdthPYff4xtCHYloJGM0CFxFsb3NbC0eqPhfImw==",
"license": "ISC",
"peerDependencies": {
"zod": "^3.23.3"
}
},
"node_modules/zwitch": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",

View file

@ -137,7 +137,12 @@
"typescript-eslint": "^8.3.0"
},
"dependencies": {
"@ai-sdk/anthropic": "^0.0.50",
"@ai-sdk/azure": "^0.0.39",
"@ai-sdk/openai": "^0.0.60",
"@anthropic-ai/sdk": "^0.27.1",
"ai": "^3.3.43",
"ollama-ai-provider": "^0.15.0",
"openai": "^4.57.0"
}
}

View file

@ -1,15 +1,27 @@
import Anthropic from '@anthropic-ai/sdk';
import OpenAI from 'openai';
// import ollama from 'ollama'
import { streamText } from 'ai'
import { createOpenAI, OpenAIProviderSettings } from '@ai-sdk/openai';
import { anthropic, AnthropicProviderSettings } from '@ai-sdk/anthropic';
import { AzureOpenAIProviderSettings, createAzure } from '@ai-sdk/azure';
import { createOllama, OllamaProviderSettings } from 'ollama-ai-provider';
export type ApiConfig = {
anthropic: {
apikey: string,
apikey: string,
/** @default 'claude-3-5-sonnet-20240620' */
model?: string,
setting: AnthropicProviderSettings
},
openai: {
apikey: string
},
apikey: string
/** @default 'gpt-4o' */
model?: string,
setting: OpenAIProviderSettings
},
azure: {
apiKey: string,
deploymentId: string,
setting: AzureOpenAIProviderSettings
},
greptile: {
apikey: string,
githubPAT: string,
@ -19,14 +31,14 @@ export type ApiConfig = {
branch: string // e.g. 'main'
}
},
ollama: {
// TODO
ollama: {
/** @default 'llama3.1' */
model: string
setting: OllamaProviderSettings
},
whichApi: string
}
type OnText = (newText: string, fullText: string) => void
export type LLMMessage = {
@ -54,95 +66,6 @@ type SendLLMMessageFnTypeExternal = (params: {
abort: () => void
}
// Claude
const sendClaudeMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFinalMessage, apiConfig }) => {
const anthropic = new Anthropic({ apiKey: apiConfig.anthropic.apikey, dangerouslyAllowBrowser: true }); // defaults to process.env["ANTHROPIC_API_KEY"]
const stream = anthropic.messages.stream({
model: "claude-3-5-sonnet-20240620",
max_tokens: 1024,
messages: messages,
});
let did_abort = false
// when receive text
stream.on('text', (newText, fullText) => {
if (did_abort) return
onText(newText, fullText)
})
// when we get the final message on this stream (or when error/fail)
stream.on('finalMessage', (claude_response) => {
if (did_abort) return
// stringify the response's content
let content = claude_response.content.map(c => { if (c.type === 'text') { return c.text } }).join('\n');
onFinalMessage(content)
})
// if abort is called, onFinalMessage is NOT called, and no later onTexts are called either
const abort = () => {
// stream.abort() // this doesnt appear to do anything, but it should try to stop claude from generating anymore
did_abort = true
}
return { abort }
};
// OpenAI
const sendOpenAIMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFinalMessage, apiConfig }) => {
let did_abort = false
let fullText = ''
// if abort is called, onFinalMessage is NOT called, and no later onTexts are called either
let abort: () => void = () => { did_abort = true }
const openai = new OpenAI({ apiKey: apiConfig.openai.apikey, dangerouslyAllowBrowser: true });
openai.chat.completions.create({
model: 'gpt-4o-2024-08-06',
messages: messages,
stream: true,
})
.then(async response => {
abort = () => {
// response.controller.abort() // this isn't needed now, to keep consistency with claude will leave it commented
did_abort = true;
}
// when receive text
try {
for await (const chunk of response) {
if (did_abort) return;
const newText = chunk.choices[0]?.delta?.content || '';
fullText += newText;
onText(newText, fullText);
}
onFinalMessage(fullText);
}
// when error/fail
catch (error) {
console.error('Error in OpenAI stream:', error);
onFinalMessage(fullText);
}
// when we get the final message on this stream
onFinalMessage(fullText)
})
return { abort };
};
// Greptile
// https://docs.greptile.com/api-reference/query
// https://docs.greptile.com/quickstart#sample-response-streamed
@ -207,79 +130,51 @@ const sendGreptileMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFin
.catch(e => {
console.error('Error in Greptile stream:', e);
onFinalMessage(fullText);
});
return { abort }
}
export const sendLLMMessage: SendLLMMessageFnTypeExternal = ({ messages, onText, onFinalMessage, apiConfig }) => {
if (!apiConfig) return { abort: () => { } }
if (!apiConfig) return { abort: () => { } }
const whichApi = apiConfig.whichApi
// TODO: create an @ai-sdk provider for greptile
if (whichApi === 'greptile')
return sendGreptileMsg({ messages, onText, onFinalMessage, apiConfig })
const whichApi = apiConfig.whichApi
if (whichApi === 'anthropic') {
return sendClaudeMsg({ messages, onText, onFinalMessage, apiConfig })
}
else if (whichApi === 'openai') {
return sendOpenAIMsg({ messages, onText, onFinalMessage, apiConfig })
}
else if (whichApi === 'greptile') {
return sendGreptileMsg({ messages, onText, onFinalMessage, apiConfig })
}
else if (whichApi === 'ollama') {
return sendClaudeMsg({ messages, onText, onFinalMessage, apiConfig }) // TODO
}
else {
console.error(`Error: whichApi was ${whichApi}, which is not recognized!`)
return sendClaudeMsg({ messages, onText, onFinalMessage, apiConfig }) // TODO
}
const model = getAiModel(apiConfig.whichApi, apiConfig)
const abortController = new AbortController()
const abortSignal = abortController.signal
streamText({
model,
messages,
abortSignal,
}).then(async (result) => {
let fullText = ''
for await (const textPart of result.textStream) {
fullText += textPart
onText(textPart, fullText)
}
onFinalMessage(fullText)
})
return { abort: abortController.abort }
}
// Ollama
// const sendOllamaMsg: sendMsgFnType = ({ messages, onText, onFinalMessage }) => {
// let did_abort = false
// let fullText = ''
// // if abort is called, onFinalMessage is NOT called, and no later onTexts are called either
// let abort: () => void = () => {
// did_abort = true
// }
// ollama.chat({ model: 'llama3.1', messages: messages, stream: true })
// .then(async response => {
// abort = () => {
// // response.abort() // this isn't needed now, to keep consistency with claude will leave it commented for now
// did_abort = true;
// }
// // when receive text
// try {
// for await (const part of response) {
// if (did_abort) return
// let newText = part.message.content
// fullText += newText
// onText(newText, fullText)
// }
// }
// // when error/fail
// catch (e) {
// onFinalMessage(fullText)
// return
// }
// // when we get the final message on this stream
// onFinalMessage(fullText)
// })
// return { abort };
// };
export const getAiModel = (provider: string, apiConfig?: ApiConfig | null) => {
switch (provider) {
case 'openai': return createOpenAI({
apiKey: apiConfig?.openai.apikey,
})(apiConfig?.openai.model || 'gpt-4o')
case 'anthropic': return anthropic(apiConfig?.anthropic.model || 'claude-3-5-sonnet-20240620')
case 'ollama': return createOllama(apiConfig?.ollama.setting)(apiConfig?.ollama.model || 'llama3.1')
case 'azure': {
if (!apiConfig?.azure.deploymentId) {
throw new Error(`Error: azure deploymentId is not defined`)
}
return createAzure(apiConfig?.azure.setting)(apiConfig?.azure.deploymentId)
}
default:
throw new Error(`Error: provider was ${provider}, which is not recognized!`)
}
}