diff --git a/extensions/void/package-lock.json b/extensions/void/package-lock.json index cb1b8f87..f2b84f0f 100644 --- a/extensions/void/package-lock.json +++ b/extensions/void/package-lock.json @@ -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", diff --git a/extensions/void/package.json b/extensions/void/package.json index ebccfe72..f0223115 100644 --- a/extensions/void/package.json +++ b/extensions/void/package.json @@ -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" } } diff --git a/extensions/void/src/common/sendLLMMessage.ts b/extensions/void/src/common/sendLLMMessage.ts index ca3c34bd..f68db66d 100644 --- a/extensions/void/src/common/sendLLMMessage.ts +++ b/extensions/void/src/common/sendLLMMessage.ts @@ -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!`) + } +}