refactor(ai): update AI provider configuration and replace OpenAI references with new AI model setup

This commit is contained in:
cfngc4594 2026-04-28 17:58:50 +08:00
parent a0920a0099
commit 03fa169a81
14 changed files with 61 additions and 92 deletions

View File

@ -19,9 +19,10 @@ AUTH_GITHUB_SECRET="your_github_client_secret"
# The base URL for authentication callbacks, typically the root URL of your application # The base URL for authentication callbacks, typically the root URL of your application
AUTH_URL="http://localhost:3000" AUTH_URL="http://localhost:3000"
# OpenAI API key and base URL for AI services # AI provider configuration
OPENAI_API_KEY="your_openai_api_key" AI_API_KEY="your_ai_api_key"
OPENAI_BASE_URL="your_openai_base_url_if_custom" AI_BASE_URL="your_ai_base_url_if_custom"
AI_MODEL="your_ai_model_id"
# Docker Remote Access Configuration # Docker Remote Access Configuration
DOCKER_HOST_MODE="remote_or_blank" DOCKER_HOST_MODE="remote_or_blank"

View File

@ -123,11 +123,12 @@ bun install
AUTH_URL="http://localhost:3000" # Replace with your production URL if deployed AUTH_URL="http://localhost:3000" # Replace with your production URL if deployed
``` ```
- **OpenAI API Configuration** (Optional): - **AI Provider Configuration**:
If you use OpenAI-based features, provide your API key and custom endpoint (if applicable): If you use AI features, provide your API key, model, and custom endpoint:
```sh ```sh
OPENAI_API_KEY="your_openai_api_key" # Required for AI features AI_API_KEY="your_ai_api_key" # Required for AI features
OPENAI_BASE_URL="your_openai_base_url_if_custom" # Optional, for self-hosted proxies AI_BASE_URL="your_ai_base_url_if_custom" # Required, for OpenAI-compatible endpoints
AI_MODEL="your_ai_model_id" # Required
``` ```
- **Docker Remote Access Configuration** (Optional): - **Docker Remote Access Configuration** (Optional):

View File

@ -4,8 +4,7 @@
"": { "": {
"name": "monaco-editor-lsp-next", "name": "monaco-editor-lsp-next",
"dependencies": { "dependencies": {
"@ai-sdk/deepseek": "^0.2.14", "@ai-sdk/openai-compatible": "0.2.14",
"@ai-sdk/openai": "^1.3.0",
"@ai-sdk/react": "^1.2.0", "@ai-sdk/react": "^1.2.0",
"@auth/prisma-adapter": "^2.8.0", "@auth/prisma-adapter": "^2.8.0",
"@fontsource/fira-code": "^5.1.1", "@fontsource/fira-code": "^5.1.1",
@ -111,11 +110,7 @@
}, },
}, },
"packages": { "packages": {
"@ai-sdk/deepseek": ["@ai-sdk/deepseek@0.2.14", "https://registry.npmmirror.com/@ai-sdk/deepseek/-/deepseek-0.2.14.tgz", { "dependencies": { "@ai-sdk/openai-compatible": "0.2.14", "@ai-sdk/provider": "1.1.3", "@ai-sdk/provider-utils": "2.2.8" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-TISD1FzBWuQkHEHoVustoJILV33ZNgfYxeTkq1xU2vHEZuWTGZV7/IlXixyFsfqDCdVgrbLeIABk5FuCw7niLg=="], "@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@0.2.14", "", { "dependencies": { "@ai-sdk/provider": "1.1.3", "@ai-sdk/provider-utils": "2.2.8" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-icjObfMCHKSIbywijaoLdZ1nSnuRnWgMEMLgwoxPJgxsUHMx0aVORnsLUid4SPtdhHI3X2masrt6iaEQLvOSFw=="],
"@ai-sdk/openai": ["@ai-sdk/openai@1.3.22", "https://registry.npmmirror.com/@ai-sdk/openai/-/openai-1.3.22.tgz", { "dependencies": { "@ai-sdk/provider": "1.1.3", "@ai-sdk/provider-utils": "2.2.8" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-QwA+2EkG0QyjVR+7h6FE7iOu2ivNqAVMm9UJZkVxxTk5OIq5fFJDTEI/zICEMuHImTTXR2JjsL6EirJ28Jc4cw=="],
"@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@0.2.14", "https://registry.npmmirror.com/@ai-sdk/openai-compatible/-/openai-compatible-0.2.14.tgz", { "dependencies": { "@ai-sdk/provider": "1.1.3", "@ai-sdk/provider-utils": "2.2.8" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-icjObfMCHKSIbywijaoLdZ1nSnuRnWgMEMLgwoxPJgxsUHMx0aVORnsLUid4SPtdhHI3X2masrt6iaEQLvOSFw=="],
"@ai-sdk/provider": ["@ai-sdk/provider@1.1.3", "https://registry.npmmirror.com/@ai-sdk/provider/-/provider-1.1.3.tgz", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg=="], "@ai-sdk/provider": ["@ai-sdk/provider@1.1.3", "https://registry.npmmirror.com/@ai-sdk/provider/-/provider-1.1.3.tgz", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg=="],
@ -1973,28 +1968,6 @@
"@radix-ui/react-alert-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.2", "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-1.2.2.tgz", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-y7TBO4xN4Y94FvcWIOIh18fM4R1A8S4q1jhoz4PNzOoHsFcN8pogcFmZrTYAm4F9VRUrWP/Mw7xSKybIeRI+CQ=="], "@radix-ui/react-alert-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.2", "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-1.2.2.tgz", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-y7TBO4xN4Y94FvcWIOIh18fM4R1A8S4q1jhoz4PNzOoHsFcN8pogcFmZrTYAm4F9VRUrWP/Mw7xSKybIeRI+CQ=="],
"@radix-ui/react-avatar/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
"@radix-ui/react-collapsible/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
"@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.2", "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-1.2.2.tgz", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-y7TBO4xN4Y94FvcWIOIh18fM4R1A8S4q1jhoz4PNzOoHsFcN8pogcFmZrTYAm4F9VRUrWP/Mw7xSKybIeRI+CQ=="],
"@radix-ui/react-dialog/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
"@radix-ui/react-dismissable-layer/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
"@radix-ui/react-dropdown-menu/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
"@radix-ui/react-focus-scope/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
"@radix-ui/react-menu/@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw=="],
"@radix-ui/react-menu/@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.7", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ=="],
"@radix-ui/react-menu/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
"@radix-ui/react-menu/@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.10", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q=="],
"@radix-ui/react-popover/@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.9", "https://registry.npmmirror.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.9.tgz", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.2", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-way197PiTvNp+WBP7svMJasHl+vibhWGQDb6Mgf5mhEWJkgb85z7Lfl9TUdkqpWsf8GRNmoopx9ZxCyDzmgRMQ=="], "@radix-ui/react-popover/@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.9", "https://registry.npmmirror.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.9.tgz", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.2", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-way197PiTvNp+WBP7svMJasHl+vibhWGQDb6Mgf5mhEWJkgb85z7Lfl9TUdkqpWsf8GRNmoopx9ZxCyDzmgRMQ=="],
"@radix-ui/react-popover/@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.6", "https://registry.npmmirror.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.6.tgz", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.2", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-r9zpYNUQY+2jWHWZGyddQLL9YHkM/XvSFHVcWs7bdVuxMAnCwTAuy6Pf47Z4nw7dYcUou1vg/VgjjrrH03VeBw=="], "@radix-ui/react-popover/@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.6", "https://registry.npmmirror.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.6.tgz", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.2", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-r9zpYNUQY+2jWHWZGyddQLL9YHkM/XvSFHVcWs7bdVuxMAnCwTAuy6Pf47Z4nw7dYcUou1vg/VgjjrrH03VeBw=="],
@ -2003,10 +1976,6 @@
"@radix-ui/react-popover/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.2", "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-1.2.2.tgz", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-y7TBO4xN4Y94FvcWIOIh18fM4R1A8S4q1jhoz4PNzOoHsFcN8pogcFmZrTYAm4F9VRUrWP/Mw7xSKybIeRI+CQ=="], "@radix-ui/react-popover/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.2", "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-1.2.2.tgz", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-y7TBO4xN4Y94FvcWIOIh18fM4R1A8S4q1jhoz4PNzOoHsFcN8pogcFmZrTYAm4F9VRUrWP/Mw7xSKybIeRI+CQ=="],
"@radix-ui/react-portal/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
"@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.2", "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-1.2.2.tgz", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-y7TBO4xN4Y94FvcWIOIh18fM4R1A8S4q1jhoz4PNzOoHsFcN8pogcFmZrTYAm4F9VRUrWP/Mw7xSKybIeRI+CQ=="],
"@radix-ui/react-select/@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.9", "https://registry.npmmirror.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.9.tgz", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.2", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-way197PiTvNp+WBP7svMJasHl+vibhWGQDb6Mgf5mhEWJkgb85z7Lfl9TUdkqpWsf8GRNmoopx9ZxCyDzmgRMQ=="], "@radix-ui/react-select/@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.9", "https://registry.npmmirror.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.9.tgz", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.2", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-way197PiTvNp+WBP7svMJasHl+vibhWGQDb6Mgf5mhEWJkgb85z7Lfl9TUdkqpWsf8GRNmoopx9ZxCyDzmgRMQ=="],
"@radix-ui/react-select/@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.6", "https://registry.npmmirror.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.6.tgz", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.2", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-r9zpYNUQY+2jWHWZGyddQLL9YHkM/XvSFHVcWs7bdVuxMAnCwTAuy6Pf47Z4nw7dYcUou1vg/VgjjrrH03VeBw=="], "@radix-ui/react-select/@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.6", "https://registry.npmmirror.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.6.tgz", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.2", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-r9zpYNUQY+2jWHWZGyddQLL9YHkM/XvSFHVcWs7bdVuxMAnCwTAuy6Pf47Z4nw7dYcUou1vg/VgjjrrH03VeBw=="],
@ -2015,14 +1984,6 @@
"@radix-ui/react-select/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.2", "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-1.2.2.tgz", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-y7TBO4xN4Y94FvcWIOIh18fM4R1A8S4q1jhoz4PNzOoHsFcN8pogcFmZrTYAm4F9VRUrWP/Mw7xSKybIeRI+CQ=="], "@radix-ui/react-select/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.2", "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-1.2.2.tgz", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-y7TBO4xN4Y94FvcWIOIh18fM4R1A8S4q1jhoz4PNzOoHsFcN8pogcFmZrTYAm4F9VRUrWP/Mw7xSKybIeRI+CQ=="],
"@radix-ui/react-separator/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
"@radix-ui/react-tooltip/@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.7", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ=="],
"@radix-ui/react-tooltip/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
"@radix-ui/react-tooltip/@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.3", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug=="],
"@types/ssh2/@types/node": ["@types/node@18.19.100", "https://registry.npmmirror.com/@types/node/-/node-18.19.100.tgz", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-ojmMP8SZBKprc3qGrGk8Ujpo80AXkrP7G2tOT4VWr5jlr5DHjsJF+emXJz+Wm0glmy4Js62oKMdZZ6B9Y+tEcA=="], "@types/ssh2/@types/node": ["@types/node@18.19.100", "https://registry.npmmirror.com/@types/node/-/node-18.19.100.tgz", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-ojmMP8SZBKprc3qGrGk8Ujpo80AXkrP7G2tOT4VWr5jlr5DHjsJF+emXJz+Wm0glmy4Js62oKMdZZ6B9Y+tEcA=="],
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
@ -2097,10 +2058,6 @@
"@radix-ui/react-alert-dialog/@radix-ui/react-dialog/@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.8", "https://registry.npmmirror.com/@radix-ui/react-portal/-/react-portal-1.1.8.tgz", { "dependencies": { "@radix-ui/react-primitive": "2.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-hQsTUIn7p7fxCPvao/q6wpbxmCwgLrlz+nOrJgC+RwfZqWY/WN+UMqkXzrtKbPrF82P43eCTl3ekeKuyAQbFeg=="], "@radix-ui/react-alert-dialog/@radix-ui/react-dialog/@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.8", "https://registry.npmmirror.com/@radix-ui/react-portal/-/react-portal-1.1.8.tgz", { "dependencies": { "@radix-ui/react-primitive": "2.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-hQsTUIn7p7fxCPvao/q6wpbxmCwgLrlz+nOrJgC+RwfZqWY/WN+UMqkXzrtKbPrF82P43eCTl3ekeKuyAQbFeg=="],
"@radix-ui/react-menu/@radix-ui/react-popper/@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="],
"@radix-ui/react-tooltip/@radix-ui/react-popper/@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="],
"@types/ssh2/@types/node/undici-types": ["undici-types@5.26.5", "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], "@types/ssh2/@types/node/undici-types": ["undici-types@5.26.5", "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],

View File

@ -37,8 +37,9 @@ services:
- AUTH_GITHUB_ID=${AUTH_GITHUB_ID} - AUTH_GITHUB_ID=${AUTH_GITHUB_ID}
- AUTH_GITHUB_SECRET=${AUTH_GITHUB_SECRET} - AUTH_GITHUB_SECRET=${AUTH_GITHUB_SECRET}
- AUTH_URL=${AUTH_URL} - AUTH_URL=${AUTH_URL}
- OPENAI_API_KEY=${OPENAI_API_KEY} - AI_API_KEY=${AI_API_KEY}
- OPENAI_BASE_URL=${OPENAI_BASE_URL} # Optional - AI_BASE_URL=${AI_BASE_URL}
- AI_MODEL=${AI_MODEL}
# Remote Docker configuration (activate only for remote Docker): # Remote Docker configuration (activate only for remote Docker):
# - DOCKER_HOST_MODE=${DOCKER_HOST_MODE} # Options: "remote" or leave empty for local # - DOCKER_HOST_MODE=${DOCKER_HOST_MODE} # Options: "remote" or leave empty for local
# - DOCKER_REMOTE_PROTOCOL=${DOCKER_REMOTE_PROTOCOL} # Example: "https" or "http" or "ssh" # - DOCKER_REMOTE_PROTOCOL=${DOCKER_REMOTE_PROTOCOL} # Example: "https" or "http" or "ssh"

View File

@ -40,8 +40,9 @@ services:
- AUTH_GITHUB_ID=${AUTH_GITHUB_ID} - AUTH_GITHUB_ID=${AUTH_GITHUB_ID}
- AUTH_GITHUB_SECRET=${AUTH_GITHUB_SECRET} - AUTH_GITHUB_SECRET=${AUTH_GITHUB_SECRET}
- AUTH_URL=${AUTH_URL} - AUTH_URL=${AUTH_URL}
- OPENAI_API_KEY=${OPENAI_API_KEY} - AI_API_KEY=${AI_API_KEY}
- OPENAI_BASE_URL=${OPENAI_BASE_URL} # Optional - AI_BASE_URL=${AI_BASE_URL}
- AI_MODEL=${AI_MODEL}
# Remote Docker configuration (activate only for remote Docker): # Remote Docker configuration (activate only for remote Docker):
# - DOCKER_HOST_MODE=${DOCKER_HOST_MODE} # Options: "remote" or leave empty for local # - DOCKER_HOST_MODE=${DOCKER_HOST_MODE} # Options: "remote" or leave empty for local
# - DOCKER_REMOTE_PROTOCOL=${DOCKER_REMOTE_PROTOCOL} # Example: "https" or "http" or "ssh" # - DOCKER_REMOTE_PROTOCOL=${DOCKER_REMOTE_PROTOCOL} # Example: "https" or "http" or "ssh"

View File

@ -40,9 +40,9 @@ services:
- AUTH_GITHUB_ID=${AUTH_GITHUB_ID} - AUTH_GITHUB_ID=${AUTH_GITHUB_ID}
- AUTH_GITHUB_SECRET=${AUTH_GITHUB_SECRET} - AUTH_GITHUB_SECRET=${AUTH_GITHUB_SECRET}
- AUTH_URL=${AUTH_URL} - AUTH_URL=${AUTH_URL}
- OPENAI_API_KEY=${OPENAI_API_KEY} - AI_API_KEY=${AI_API_KEY}
- OPENAI_BASE_URL=${OPENAI_BASE_URL} # Optional - AI_BASE_URL=${AI_BASE_URL}
- DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY} - AI_MODEL=${AI_MODEL}
# Remote Docker configuration (activate only for remote Docker): # Remote Docker configuration (activate only for remote Docker):
# - DOCKER_HOST_MODE=${DOCKER_HOST_MODE} # Options: "remote" or leave empty for local # - DOCKER_HOST_MODE=${DOCKER_HOST_MODE} # Options: "remote" or leave empty for local
# - DOCKER_REMOTE_PROTOCOL=${DOCKER_REMOTE_PROTOCOL} # Example: "https" or "http" or "ssh" # - DOCKER_REMOTE_PROTOCOL=${DOCKER_REMOTE_PROTOCOL} # Example: "https" or "http" or "ssh"

View File

@ -37,8 +37,9 @@ services:
- AUTH_GITHUB_ID=${AUTH_GITHUB_ID} - AUTH_GITHUB_ID=${AUTH_GITHUB_ID}
- AUTH_GITHUB_SECRET=${AUTH_GITHUB_SECRET} - AUTH_GITHUB_SECRET=${AUTH_GITHUB_SECRET}
- AUTH_URL=${AUTH_URL} - AUTH_URL=${AUTH_URL}
- OPENAI_API_KEY=${OPENAI_API_KEY} - AI_API_KEY=${AI_API_KEY}
- OPENAI_BASE_URL=${OPENAI_BASE_URL} # Optional - AI_BASE_URL=${AI_BASE_URL}
- AI_MODEL=${AI_MODEL}
# Remote Docker configuration (activate only for remote Docker): # Remote Docker configuration (activate only for remote Docker):
# - DOCKER_HOST_MODE=${DOCKER_HOST_MODE} # Options: "remote" or leave empty for local # - DOCKER_HOST_MODE=${DOCKER_HOST_MODE} # Options: "remote" or leave empty for local
# - DOCKER_REMOTE_PROTOCOL=${DOCKER_REMOTE_PROTOCOL} # Example: "https" or "http" or "ssh" # - DOCKER_REMOTE_PROTOCOL=${DOCKER_REMOTE_PROTOCOL} # Example: "https" or "http" or "ssh"

View File

@ -13,8 +13,7 @@
"seed": "tsx prisma/seed.ts" "seed": "tsx prisma/seed.ts"
}, },
"dependencies": { "dependencies": {
"@ai-sdk/deepseek": "^0.2.14", "@ai-sdk/openai-compatible": "0.2.14",
"@ai-sdk/openai": "^1.3.0",
"@ai-sdk/react": "^1.2.0", "@ai-sdk/react": "^1.2.0",
"@auth/prisma-adapter": "^2.8.0", "@auth/prisma-adapter": "^2.8.0",
"@fontsource/fira-code": "^5.1.1", "@fontsource/fira-code": "^5.1.1",

View File

@ -6,7 +6,7 @@ import {
OptimizeCodeOutputSchema, OptimizeCodeOutputSchema,
} from "@/types/ai-improve"; } from "@/types/ai-improve";
import prisma from "@/lib/prisma"; import prisma from "@/lib/prisma";
import { deepseek } from "@/lib/ai"; import { model } from "@/lib/ai";
import { CoreMessage, generateText } from "ai"; import { CoreMessage, generateText } from "ai";
/** /**
@ -17,8 +17,6 @@ import { CoreMessage, generateText } from "ai";
export const optimizeCode = async ( export const optimizeCode = async (
input: OptimizeCodeInput input: OptimizeCodeInput
): Promise<OptimizeCodeOutput> => { ): Promise<OptimizeCodeOutput> => {
const model = deepseek("deepseek-chat");
// 获取题目详情如果提供了problemId // 获取题目详情如果提供了problemId
let problemDetails = ""; let problemDetails = "";
let templateDetails = ""; let templateDetails = "";
@ -134,7 +132,7 @@ Format:
`; `;
console.log("Prompt:", prompt); console.log("Prompt:", prompt);
// 发送请求给OpenAI // 发送请求给 AI provider
const messages: CoreMessage[] = [{ role: "user", content: prompt }]; const messages: CoreMessage[] = [{ role: "user", content: prompt }];
let text; let text;
try { try {
@ -144,8 +142,8 @@ Format:
}); });
text = response.text; text = response.text;
} catch (error) { } catch (error) {
console.error("Error generating text with OpenAI:", error); console.error("Error generating text with AI provider:", error);
throw new Error("Failed to generate response from OpenAI"); throw new Error("Failed to generate response from AI provider");
} }
// 解析LLM响应 // 解析LLM响应

View File

@ -6,7 +6,7 @@ import {
AITestCaseOutputSchema, AITestCaseOutputSchema,
} from "@/types/ai-testcase"; } from "@/types/ai-testcase";
import { deepseek } from "@/lib/ai"; import { model } from "@/lib/ai";
import { CoreMessage, generateText } from "ai"; import { CoreMessage, generateText } from "ai";
import prisma from "@/lib/prisma"; import prisma from "@/lib/prisma";
@ -18,8 +18,6 @@ import prisma from "@/lib/prisma";
export const generateAITestcase = async ( export const generateAITestcase = async (
input: AITestCaseInput input: AITestCaseInput
): Promise<AITestCaseOutput> => { ): Promise<AITestCaseOutput> => {
const model = deepseek("deepseek-chat");
let problemDetails = ""; let problemDetails = "";
if (input.problemId) { if (input.problemId) {
@ -119,7 +117,7 @@ Respond **ONLY** with this JSON structure.
`; `;
// 发送请求给OpenAI // 发送请求给 AI provider
const messages: CoreMessage[] = [{ role: "user", content: prompt }]; const messages: CoreMessage[] = [{ role: "user", content: prompt }];
let text; let text;
try { try {
@ -129,8 +127,8 @@ Respond **ONLY** with this JSON structure.
}); });
text = response.text; text = response.text;
} catch (error) { } catch (error) {
console.error("Error generating text with OpenAI:", error); console.error("Error generating text with AI provider:", error);
throw new Error("Failed to generate response from OpenAI"); throw new Error("Failed to generate response from AI provider");
} }
// 解析LLM响应 // 解析LLM响应

View File

@ -3,7 +3,7 @@ import "server-only";
import { z } from "zod"; import { z } from "zod";
import prisma from "@/lib/prisma"; import prisma from "@/lib/prisma";
import { generateText, tool } from "ai"; import { generateText, tool } from "ai";
import { deepseek } from "@ai-sdk/deepseek"; import { model } from "@/lib/ai";
import { Complexity } from "@/types/complexity"; import { Complexity } from "@/types/complexity";
interface analyzeCodeProps { interface analyzeCodeProps {
@ -30,7 +30,7 @@ export const analyzeCode = async ({
}); });
await generateText({ await generateText({
model: deepseek("deepseek-chat"), model,
system: `You are an AI assistant that rigorously analyzes code for time and space complexity, and assesses overall code quality. system: `You are an AI assistant that rigorously analyzes code for time and space complexity, and assesses overall code quality.
**Time/Space Complexity MUST be one of these values:** **Time/Space Complexity MUST be one of these values:**

View File

@ -6,7 +6,7 @@ import {
Complexity, Complexity,
} from "@/types/complexity"; } from "@/types/complexity";
import prisma from "@/lib/prisma"; import prisma from "@/lib/prisma";
import { openai } from "@/lib/ai"; import { model } from "@/lib/ai";
import { auth } from "@/lib/auth"; import { auth } from "@/lib/auth";
import { CoreMessage, generateText } from "ai"; import { CoreMessage, generateText } from "ai";
import { CodeAnalysis } from "@/generated/client"; import { CodeAnalysis } from "@/generated/client";
@ -14,8 +14,6 @@ import { CodeAnalysis } from "@/generated/client";
export const analyzeComplexity = async ( export const analyzeComplexity = async (
content: string content: string
): Promise<AnalyzeComplexityResponse> => { ): Promise<AnalyzeComplexityResponse> => {
const model = openai("gpt-4o-mini");
const prompt = ` const prompt = `
Analyze the time and space complexity of the following programming code snippet. Analyze the time and space complexity of the following programming code snippet.
Determine the Big O notation from this list: ${Complexity.options.join(", ")}. Determine the Big O notation from this list: ${Complexity.options.join(", ")}.
@ -89,8 +87,6 @@ export const getAnalysis = async (
}; };
export const optimizeCode = async (content: string): Promise<string> => { export const optimizeCode = async (content: string): Promise<string> => {
const model = openai("gpt-4o-mini");
const prompt = ` const prompt = `
Optimize the following code snippet for better performance, readability, and maintainability. Optimize the following code snippet for better performance, readability, and maintainability.
Provide ONLY the improved code without any explanations, comments, or additional text. Provide ONLY the improved code without any explanations, comments, or additional text.

View File

@ -1,5 +1,5 @@
import { streamText } from "ai"; import { streamText } from "ai";
import { deepseek } from "@/lib/ai"; import { model } from "@/lib/ai";
// Allow streaming responses up to 30 seconds // Allow streaming responses up to 30 seconds
export const maxDuration = 30; export const maxDuration = 30;
@ -20,7 +20,7 @@ For the best response, please take your time to carefully consider my questions,
** Reply in the user's language ! **`; ** Reply in the user's language ! **`;
const result = streamText({ const result = streamText({
model: deepseek("deepseek-chat"), model,
system: system, system: system,
messages: messages, messages: messages,
}); });

View File

@ -1,13 +1,29 @@
import "server-only"; import "server-only";
import { createOpenAI } from "@ai-sdk/openai"; import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import { createDeepSeek } from "@ai-sdk/deepseek";
export const deepseek = createDeepSeek({ const getRequiredEnv = (
apiKey: process.env.DEEPSEEK_API_KEY ?? "", name: "AI_API_KEY" | "AI_BASE_URL" | "AI_MODEL",
): string => {
const value = process.env[name];
if (!value) {
throw new Error(`Missing required environment variable: ${name}`);
}
return value;
};
const apiKey = getRequiredEnv("AI_API_KEY");
const baseURL = getRequiredEnv("AI_BASE_URL");
export const modelId = getRequiredEnv("AI_MODEL");
export const aiProvider = createOpenAICompatible({
name: "ai",
apiKey,
baseURL,
}); });
export const openai = createOpenAI({ export const model = aiProvider(modelId);
apiKey: process.env.OPENAI_API_KEY,
baseURL: process.env.OPENAI_BASE_URL,
});