diff --git a/README.md b/README.md index 48f7ab0..7cc54c5 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ ProxyBat comes with specialized AI agents that can: - **Built-in Terminal** - Integrated terminal for running commands and scripts - **File System Tools** - AI agents can read, write, and analyze files in your workspace - **LLM API Server** - Built-in OpenAI-compatible API server for integrating with other tools -- **Multiple AI Providers** - Support for OpenAI, Anthropic, GitHub Copilot, and more +- **Multiple AI Providers** - Support for Kimi, GitHub Copilot, ZAI/GLM-5, Codex CLI, DeepSeek, and more - **Smart Filtering** - Filter traffic by domain, method, status code, and custom patterns - **SSL/TLS Management** - Automatic certificate generation and management @@ -158,9 +158,11 @@ ProxyBat is built with a modern tech stack: Configure your AI providers in the Settings tab: -- **OpenAI** - Add your API key -- **Anthropic** - Configure Claude API access -- **GitHub Copilot** - Use Copilot's AI capabilities +- **Kimi (Moonshot)** - `k2p5` via Anthropic-compatible coding endpoint +- **GitHub Copilot** - Claude / GPT / Gemini / Grok models routed through Copilot +- **ZAI / GLM-5** - GLM Coding Plan +- **Codex CLI** - GPT-5 / GPT-5.1 / GPT-5.2 codex variants via local Codex login +- **DeepSeek** - `deepseek-v4-flash` and `deepseek-v4-pro` (reasoning) via official DeepSeek API - **Custom Providers** - Add any OpenAI-compatible API ### Proxy Settings diff --git a/package-lock.json b/package-lock.json index c77dc59..b555901 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,16 @@ { "name": "ProxyBat", - "version": "0.1.1", + "version": "0.2.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ProxyBat", - "version": "0.1.1", + "version": "0.2.3", "license": "MIT", "dependencies": { "@ai-sdk/anthropic": "^3.0.46", + "@ai-sdk/deepseek": "^2.0.33", "@ai-sdk/openai": "^3.0.30", "@codemirror/lang-python": "^6.2.1", "@codemirror/theme-one-dark": "^6.1.3", @@ -88,6 +89,51 @@ "zod": "^3.25.76 || ^4.1.8" } }, + "node_modules/@ai-sdk/deepseek": { + "version": "2.0.33", + "resolved": "https://registry.npmjs.org/@ai-sdk/deepseek/-/deepseek-2.0.33.tgz", + "integrity": "sha512-yiy3v2hRF1MZ5TInkPBkisyPiFd+5NiXa396cdosAZaN/jYYBD24EU4rOxd37DB2ldMjimrbzgB1cQLZLqZ/AQ==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "3.0.10", + "@ai-sdk/provider-utils": "4.0.26" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/@ai-sdk/deepseek/node_modules/@ai-sdk/provider": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-3.0.10.tgz", + "integrity": "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw==", + "license": "Apache-2.0", + "dependencies": { + "json-schema": "^0.4.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ai-sdk/deepseek/node_modules/@ai-sdk/provider-utils": { + "version": "4.0.26", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-4.0.26.tgz", + "integrity": "sha512-CsKNLKsOpvPujRlIYvoz+Ybw+kGn7J4/fIZa/58+R7iWLLfwn6ifE2G6Yq8K9XvH/I/3bzaDAJ3NhRwEMsLBKQ==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "3.0.10", + "@standard-schema/spec": "^1.1.0", + "eventsource-parser": "^3.0.8" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, "node_modules/@ai-sdk/gateway": { "version": "3.0.53", "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-3.0.53.tgz", @@ -210,6 +256,7 @@ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -585,6 +632,7 @@ "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.39.15.tgz", "integrity": "sha512-aCWjgweIIXLBHh7bY6cACvXuyrZ0xGafjQ2VInjp4RM4gMfscK5uESiNdrH0pE+e1lZr2B4ONGsjchl2KsKZzg==", "license": "MIT", + "peer": true, "dependencies": { "@codemirror/state": "^6.5.0", "crelt": "^1.0.6", @@ -3487,6 +3535,7 @@ "integrity": "sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~6.21.0" } @@ -3508,6 +3557,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -3518,6 +3568,7 @@ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "devOptional": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -3694,7 +3745,8 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz", "integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/7zip-bin": { "version": "5.2.0", @@ -3808,6 +3860,7 @@ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4008,7 +4061,6 @@ "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "archiver-utils": "^2.1.0", "async": "^3.2.4", @@ -4028,7 +4080,6 @@ "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "glob": "^7.1.4", "graceful-fs": "^4.2.0", @@ -4051,7 +4102,6 @@ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -4067,8 +4117,7 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/archiver-utils/node_modules/string_decoder": { "version": "1.1.1", @@ -4076,7 +4125,6 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -4406,6 +4454,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -5087,7 +5136,6 @@ "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "buffer-crc32": "^0.2.13", "crc32-stream": "^4.0.2", @@ -5202,7 +5250,6 @@ "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "crc32": "bin/crc32.njs" }, @@ -5242,7 +5289,6 @@ "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^3.4.0" @@ -5542,6 +5588,7 @@ "integrity": "sha512-NoXo6Liy2heSklTI5OIZbCgXC1RzrDQsZkeEwXhdOro3FT1VBOvbubvscdPnjVuQ4AMwwv61oaH96AbiYg9EnQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "app-builder-lib": "25.1.8", "builder-util": "25.1.7", @@ -5693,6 +5740,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "@electron/get": "^2.0.0", "@types/node": "^20.9.0", @@ -5737,7 +5785,6 @@ "integrity": "sha512-2ntkJ+9+0GFP6nAISiMabKt6eqBB0kX1QqHNWFWAXgi0VULKGisM46luRFpIBiU3u/TDmhZMM8tzvo2Abn3ayg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "app-builder-lib": "25.1.8", "archiver": "^5.3.1", @@ -5751,7 +5798,6 @@ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -5767,7 +5813,6 @@ "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "universalify": "^2.0.0" }, @@ -5781,7 +5826,6 @@ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 10.0.0" } @@ -6179,9 +6223,9 @@ } }, "node_modules/eventsource-parser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", - "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.8.tgz", + "integrity": "sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==", "license": "MIT", "engines": { "node": ">=18.0.0" @@ -7285,8 +7329,7 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/isbinaryfile": { "version": "5.0.7", @@ -7348,6 +7391,7 @@ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, "license": "MIT", + "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -7463,7 +7507,6 @@ "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "readable-stream": "^2.0.5" }, @@ -7477,7 +7520,6 @@ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -7493,8 +7535,7 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/lazystream/node_modules/string_decoder": { "version": "1.1.1", @@ -7502,7 +7543,6 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -7561,16 +7601,14 @@ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/lodash.difference": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/lodash.escaperegexp": { "version": "4.1.2", @@ -7583,8 +7621,7 @@ "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/lodash.isequal": { "version": "4.5.0", @@ -7598,16 +7635,14 @@ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/lodash.union": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", @@ -9378,6 +9413,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -9440,6 +9476,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -9615,8 +9652,7 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/progress": { "version": "2.0.3", @@ -9733,6 +9769,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -9742,6 +9779,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -9898,7 +9936,6 @@ "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "minimatch": "^5.1.0" } @@ -9908,8 +9945,7 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/readdir-glob/node_modules/brace-expansion": { "version": "2.0.2", @@ -9917,7 +9953,6 @@ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -9928,7 +9963,6 @@ "integrity": "sha512-FjiwU9HaHW6YB3H4a1sFudnv93lvydNjz2lmyUXR6IwKhGI+bgL3SOZrBGn6kvvX2pJvhEkGSGjyTHN47O4rqA==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -10776,6 +10810,7 @@ "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -11391,6 +11426,7 @@ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -12157,7 +12193,6 @@ "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "archiver-utils": "^3.0.4", "compress-commons": "^4.1.2", @@ -12173,7 +12208,6 @@ "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "glob": "^7.2.3", "graceful-fs": "^4.2.0", @@ -12195,6 +12229,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index 83ec25d..c92b56b 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ }, "dependencies": { "@ai-sdk/anthropic": "^3.0.46", + "@ai-sdk/deepseek": "^2.0.33", "@ai-sdk/openai": "^3.0.30", "@codemirror/lang-python": "^6.2.1", "@codemirror/theme-one-dark": "^6.1.3", @@ -94,7 +95,10 @@ "target": [ { "target": "dmg", - "arch": ["x64", "arm64"] + "arch": [ + "x64", + "arm64" + ] } ], "category": "public.app-category.developer-tools", diff --git a/src/main/agent/AgentManager.ts b/src/main/agent/AgentManager.ts index e55e0c4..de1fdf3 100644 --- a/src/main/agent/AgentManager.ts +++ b/src/main/agent/AgentManager.ts @@ -1,4 +1,5 @@ import { createAnthropic } from "@ai-sdk/anthropic"; +import { createDeepSeek } from "@ai-sdk/deepseek"; import { createGitHubCopilotOpenAICompatible } from "@opeoginni/github-copilot-openai-compatible"; import { PUSH } from "@shared/ipc-contracts"; import type { ModelMessage } from "ai"; @@ -65,6 +66,13 @@ function getActiveModel(): any { return codexCli(s.activeModel || "gpt-5.2-codex", { codexPath }); } + case "deepseek": { + const deepseek = createDeepSeek({ + apiKey: s.deepseekApiKey, + }); + return deepseek(s.activeModel || "deepseek-v4-flash"); + } + default: { // Fallback: Kimi with whatever key we have const kimi = createAnthropic({ @@ -129,6 +137,13 @@ function getTitleModel(): any { return codexCli("gpt-5.2-codex", { codexPath }); } + case "deepseek": { + const deepseek = createDeepSeek({ + apiKey: s.deepseekApiKey, + }); + return deepseek("deepseek-v4-flash"); + } + default: return getActiveModel(); } diff --git a/src/main/ipc/settings.ts b/src/main/ipc/settings.ts index 9a92952..9d684e6 100644 --- a/src/main/ipc/settings.ts +++ b/src/main/ipc/settings.ts @@ -64,6 +64,8 @@ export function registerSettingsHandlers(): void { // ZAI — prefer zai-coding-plan key (has coding endpoint), fall back to zhipuai if (data['zai-coding-plan']?.key) found.zaiApiKey = data['zai-coding-plan'].key else if (data['zhipuai']?.key) found.zaiApiKey = data['zhipuai'].key + // DeepSeek + if (data['deepseek']?.key) found.deepseekApiKey = data['deepseek'].key return { found, fileFound: true } } catch (err) { diff --git a/src/main/llm-api/LlmApiServer.ts b/src/main/llm-api/LlmApiServer.ts index ff88ac1..4ffc899 100644 --- a/src/main/llm-api/LlmApiServer.ts +++ b/src/main/llm-api/LlmApiServer.ts @@ -15,6 +15,7 @@ import { createServer, IncomingMessage, ServerResponse, Server } from 'http' import { createAnthropic } from '@ai-sdk/anthropic' +import { createDeepSeek } from '@ai-sdk/deepseek' import { createGitHubCopilotOpenAICompatible } from '@opeoginni/github-copilot-openai-compatible' import { createZhipu } from 'zhipu-ai-provider' import { codexCli } from 'ai-sdk-provider-codex-cli' @@ -71,6 +72,13 @@ function getModel(modelOverride?: string): any { return codexCli(model || 'gpt-5.2-codex', { codexPath }) } + case 'deepseek': { + const deepseek = createDeepSeek({ + apiKey: s.deepseekApiKey, + }) + return deepseek(model || 'deepseek-v4-flash') + } + default: { // Fallback: Kimi const kimi = createAnthropic({ diff --git a/src/main/storage/SettingsStore.ts b/src/main/storage/SettingsStore.ts index e56564d..caf6ca3 100644 --- a/src/main/storage/SettingsStore.ts +++ b/src/main/storage/SettingsStore.ts @@ -107,6 +107,7 @@ export class SettingsStore { kimiApiKey: this.get("ai_kimi_key") ?? "", copilotApiKey: this.get("ai_copilot_key") ?? "", zaiApiKey: this.get("ai_zai_key") ?? "", + deepseekApiKey: this.get("ai_deepseek_key") ?? "", codexPath, }; } @@ -122,6 +123,8 @@ export class SettingsStore { this.set("ai_copilot_key", settings.copilotApiKey); if (settings.zaiApiKey !== undefined) this.set("ai_zai_key", settings.zaiApiKey); + if (settings.deepseekApiKey !== undefined) + this.set("ai_deepseek_key", settings.deepseekApiKey); if (settings.codexPath !== undefined) this.set("ai_codex_path", settings.codexPath); } diff --git a/src/renderer/src/pages/Settings/SettingsPage.tsx b/src/renderer/src/pages/Settings/SettingsPage.tsx index e50a41b..993a0ff 100644 --- a/src/renderer/src/pages/Settings/SettingsPage.tsx +++ b/src/renderer/src/pages/Settings/SettingsPage.tsx @@ -130,6 +130,8 @@ export function SettingsPage() { setShowCopilotKey={settings.setShowCopilotKey} showZaiKey={settings.showZaiKey} setShowZaiKey={settings.setShowZaiKey} + showDeepseekKey={settings.showDeepseekKey} + setShowDeepseekKey={settings.setShowDeepseekKey} opencodeInPath={settings.opencodeInPath} crawlLoading={settings.crawlLoading} crawlFound={settings.crawlFound} diff --git a/src/renderer/src/pages/Settings/constants.ts b/src/renderer/src/pages/Settings/constants.ts index d197791..2d09179 100644 --- a/src/renderer/src/pages/Settings/constants.ts +++ b/src/renderer/src/pages/Settings/constants.ts @@ -53,6 +53,11 @@ export const COPILOT_MODELS = [ export const ZAI_MODELS = [{ label: "glm-5 — GLM Coding Plan", value: "glm-5" }]; +export const DEEPSEEK_MODELS = [ + { label: "deepseek-v4-flash — Fast", value: "deepseek-v4-flash" }, + { label: "deepseek-v4-pro — Pro reasoning", value: "deepseek-v4-pro" }, +]; + export const CODEX_MODELS = [ { label: "gpt-5.2-codex — Latest agentic", value: "gpt-5.2-codex" }, { label: "gpt-5.2 — Latest general purpose", value: "gpt-5.2" }, @@ -74,6 +79,7 @@ export const PROVIDER_MODELS: Record = { @@ -81,4 +87,5 @@ export const PROVIDER_LABELS: Record = { copilot: "GitHub Copilot", zai: "ZAI / GLM-5", codex: "Codex CLI", + deepseek: "DeepSeek", }; diff --git a/src/renderer/src/pages/Settings/hooks/useSettings.ts b/src/renderer/src/pages/Settings/hooks/useSettings.ts index b3bf55a..76623d3 100644 --- a/src/renderer/src/pages/Settings/hooks/useSettings.ts +++ b/src/renderer/src/pages/Settings/hooks/useSettings.ts @@ -15,6 +15,7 @@ const DEFAULT_AI_SETTINGS: AiProviderSettings = { kimiApiKey: "", copilotApiKey: "", zaiApiKey: "", + deepseekApiKey: "", codexPath: "", }; @@ -52,6 +53,7 @@ export function useSettings() { const [showKimiKey, setShowKimiKey] = useState(false); const [showCopilotKey, setShowCopilotKey] = useState(false); const [showZaiKey, setShowZaiKey] = useState(false); + const [showDeepseekKey, setShowDeepseekKey] = useState(false); // Crawl from OpenCode modal const [opencodeInPath, setOpencodeInPath] = useState(false); @@ -261,7 +263,12 @@ export function useSettings() { setCrawlError(res.error); } else { const found = res.found; - if (!found.kimiApiKey && !found.copilotApiKey && !found.zaiApiKey) { + if ( + !found.kimiApiKey && + !found.copilotApiKey && + !found.zaiApiKey && + !found.deepseekApiKey + ) { setCrawlError("No known AI provider keys found in auth.json"); } else { setCrawlFound(found); @@ -269,6 +276,7 @@ export function useSettings() { if (found.kimiApiKey) selected.add("kimiApiKey"); if (found.copilotApiKey) selected.add("copilotApiKey"); if (found.zaiApiKey) selected.add("zaiApiKey"); + if (found.deepseekApiKey) selected.add("deepseekApiKey"); setCrawlSelected(selected); } } @@ -288,6 +296,8 @@ export function useSettings() { patch.copilotApiKey = crawlFound.copilotApiKey; if (crawlSelected.has("zaiApiKey") && crawlFound.zaiApiKey) patch.zaiApiKey = crawlFound.zaiApiKey; + if (crawlSelected.has("deepseekApiKey") && crawlFound.deepseekApiKey) + patch.deepseekApiKey = crawlFound.deepseekApiKey; setAiSettings((s) => ({ ...s, ...patch })); setCrawlFound(null); setCrawlSelected(new Set()); @@ -390,6 +400,7 @@ export function useSettings() { showKimiKey, showCopilotKey, showZaiKey, + showDeepseekKey, opencodeInPath, crawlLoading, crawlFound, @@ -412,6 +423,7 @@ export function useSettings() { setShowKimiKey, setShowCopilotKey, setShowZaiKey, + setShowDeepseekKey, setCrawlSelected, setCrawlFound, diff --git a/src/renderer/src/pages/Settings/tabs/AiProvidersTab.tsx b/src/renderer/src/pages/Settings/tabs/AiProvidersTab.tsx index 530e7c6..a3ef5d2 100644 --- a/src/renderer/src/pages/Settings/tabs/AiProvidersTab.tsx +++ b/src/renderer/src/pages/Settings/tabs/AiProvidersTab.tsx @@ -16,6 +16,8 @@ interface AiProvidersTabProps { setShowCopilotKey: (fn: (v: boolean) => boolean) => void; showZaiKey: boolean; setShowZaiKey: (fn: (v: boolean) => boolean) => void; + showDeepseekKey: boolean; + setShowDeepseekKey: (fn: (v: boolean) => boolean) => void; opencodeInPath: boolean; crawlLoading: boolean; crawlFound: CrawledAiKeys | null; @@ -39,6 +41,8 @@ export function AiProvidersTab({ setShowCopilotKey, showZaiKey, setShowZaiKey, + showDeepseekKey, + setShowDeepseekKey, opencodeInPath, crawlLoading, crawlFound, @@ -206,6 +210,44 @@ export function AiProvidersTab({ + {/* DeepSeek */} +
+ +
+ + setAiSettings((s) => ({ + ...s, + deepseekApiKey: e.target.value, + })) + } + className="h-8 text-xs font-mono pr-8" + placeholder="sk-…" + /> + +
+

+ Get a key at{" "} + platform.deepseek.com. Uses + OpenAI-compatible endpoint{" "} + api.deepseek.com/v1. +

+
+ {/* Codex CLI path */}
)} + {crawlFound.deepseekApiKey && ( + + )}