feat: add some orhter provider
This commit is contained in:
16
package.json
16
package.json
@@ -6,7 +6,6 @@
|
||||
"basename": "/root/ai-center-services",
|
||||
"app": {
|
||||
"entry": "dist/app.mjs",
|
||||
"key": "ai-center-services",
|
||||
"type": "system-app"
|
||||
},
|
||||
"files": [
|
||||
@@ -28,7 +27,7 @@
|
||||
],
|
||||
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
|
||||
"license": "MIT",
|
||||
"packageManager": "pnpm@10.23.0",
|
||||
"packageManager": "pnpm@10.24.0",
|
||||
"type": "module",
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
@@ -58,14 +57,14 @@
|
||||
"@kevisual/mark": "0.0.7",
|
||||
"@kevisual/router": "0.0.33",
|
||||
"@kevisual/types": "^0.0.10",
|
||||
"@kevisual/use-config": "^1.0.19",
|
||||
"@kevisual/use-config": "^1.0.21",
|
||||
"@types/bun": "^1.3.3",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/formidable": "^3.4.6",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^24.10.1",
|
||||
"@vitejs/plugin-basic-ssl": "^2.1.0",
|
||||
"cookie": "^1.0.2",
|
||||
"cookie": "^1.1.1",
|
||||
"cross-env": "^10.1.0",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.19",
|
||||
@@ -75,17 +74,18 @@
|
||||
"json5": "^2.2.3",
|
||||
"lodash-es": "^4.17.21",
|
||||
"openai": "6.9.1",
|
||||
"pm2": "^6.0.13",
|
||||
"pm2": "^6.0.14",
|
||||
"rimraf": "^6.1.2",
|
||||
"rollup": "^4.53.3",
|
||||
"rollup-plugin-dts": "^6.2.3",
|
||||
"rollup-plugin-dts": "^6.3.0",
|
||||
"sequelize": "^6.37.7",
|
||||
"tape": "^5.9.0",
|
||||
"tiktoken": "^1.0.22",
|
||||
"typescript": "^5.9.3",
|
||||
"vite": "^7.2.4"
|
||||
"vite": "^7.2.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@kevisual/logger": "^0.0.4"
|
||||
"@kevisual/logger": "^0.0.4",
|
||||
"@kevisual/permission": "^0.0.3"
|
||||
}
|
||||
}
|
||||
107
pnpm-lock.yaml
generated
107
pnpm-lock.yaml
generated
@@ -11,6 +11,9 @@ importers:
|
||||
'@kevisual/logger':
|
||||
specifier: ^0.0.4
|
||||
version: 0.0.4
|
||||
'@kevisual/permission':
|
||||
specifier: ^0.0.3
|
||||
version: 0.0.3
|
||||
devDependencies:
|
||||
'@kevisual/code-center-module':
|
||||
specifier: 0.0.24
|
||||
@@ -25,8 +28,8 @@ importers:
|
||||
specifier: ^0.0.10
|
||||
version: 0.0.10
|
||||
'@kevisual/use-config':
|
||||
specifier: ^1.0.19
|
||||
version: 1.0.19(dotenv@17.2.3)
|
||||
specifier: ^1.0.21
|
||||
version: 1.0.21(dotenv@17.2.3)
|
||||
'@types/bun':
|
||||
specifier: ^1.3.3
|
||||
version: 1.3.3
|
||||
@@ -44,10 +47,10 @@ importers:
|
||||
version: 24.10.1
|
||||
'@vitejs/plugin-basic-ssl':
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0(vite@7.2.4(@types/node@24.10.1))
|
||||
version: 2.1.0(vite@7.2.6(@types/node@24.10.1))
|
||||
cookie:
|
||||
specifier: ^1.0.2
|
||||
version: 1.0.2
|
||||
specifier: ^1.1.1
|
||||
version: 1.1.1
|
||||
cross-env:
|
||||
specifier: ^10.1.0
|
||||
version: 10.1.0
|
||||
@@ -76,8 +79,8 @@ importers:
|
||||
specifier: 6.9.1
|
||||
version: 6.9.1(ws@8.18.3)(zod@3.25.76)
|
||||
pm2:
|
||||
specifier: ^6.0.13
|
||||
version: 6.0.13
|
||||
specifier: ^6.0.14
|
||||
version: 6.0.14
|
||||
rimraf:
|
||||
specifier: ^6.1.2
|
||||
version: 6.1.2
|
||||
@@ -85,8 +88,8 @@ importers:
|
||||
specifier: ^4.53.3
|
||||
version: 4.53.3
|
||||
rollup-plugin-dts:
|
||||
specifier: ^6.2.3
|
||||
version: 6.2.3(rollup@4.53.3)(typescript@5.9.3)
|
||||
specifier: ^6.3.0
|
||||
version: 6.3.0(rollup@4.53.3)(typescript@5.9.3)
|
||||
sequelize:
|
||||
specifier: ^6.37.7
|
||||
version: 6.37.7(pg@8.16.3)
|
||||
@@ -100,8 +103,8 @@ importers:
|
||||
specifier: ^5.9.3
|
||||
version: 5.9.3
|
||||
vite:
|
||||
specifier: ^7.2.4
|
||||
version: 7.2.4(@types/node@24.10.1)
|
||||
specifier: ^7.2.6
|
||||
version: 7.2.6(@types/node@24.10.1)
|
||||
|
||||
packages:
|
||||
|
||||
@@ -290,6 +293,9 @@ packages:
|
||||
'@jridgewell/sourcemap-codec@1.5.4':
|
||||
resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.5':
|
||||
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
|
||||
|
||||
'@kevisual/auth@1.0.5':
|
||||
resolution: {integrity: sha512-GwsLj7unKXi7lmMiIIgdig4LwwLiDJnOy15HHZR5gMbyK6s5/uJiMY5RXPB2+onGzTNDqFo/hXjsD2wkerHPVg==}
|
||||
|
||||
@@ -305,6 +311,9 @@ packages:
|
||||
'@kevisual/mark@0.0.7':
|
||||
resolution: {integrity: sha512-PiEEy4yvWEpixw76PzgrIWeNelzm+FrhtzFmqJU92o5GkgawaFwighcvIxqcVZRKeEFF4uvlTjFrGeQvXw6F4A==}
|
||||
|
||||
'@kevisual/permission@0.0.3':
|
||||
resolution: {integrity: sha512-8JsA/5O5Ax/z+M+MYpFYdlioHE6jNmWMuFSokBWYs9CCAHNiSKMR01YLkoVDoPvncfH/Y8F5K/IEXRCbptuMNA==}
|
||||
|
||||
'@kevisual/rollup-tools@0.0.1':
|
||||
resolution: {integrity: sha512-TdCN+IU0fyHudiiqYvobXQ8r5MltfM/cKmSS59iopyL8YYwXwcipOS4S24NWA79g7uwJfSUNk5lg3yVhom79fQ==}
|
||||
hasBin: true
|
||||
@@ -321,10 +330,10 @@ packages:
|
||||
'@kevisual/types@0.0.10':
|
||||
resolution: {integrity: sha512-Q73uzzjk9UidumnmCvOpgzqDDvQxsblz22bIFuoiioUFJWwaparx8bpd8ArRyFojicYL1YJoFDzDZ9j9NN8grA==}
|
||||
|
||||
'@kevisual/use-config@1.0.19':
|
||||
resolution: {integrity: sha512-Q1IH4eMqUe5w6Bq8etoqOSls9FPIy0xwwD3wHf26EsQLZadhccI9qkDuFzP/rFWDa57mwFPEfwbGE5UlqWOCkw==}
|
||||
'@kevisual/use-config@1.0.21':
|
||||
resolution: {integrity: sha512-czgy4+tBDBJI6QTnKh2PCwswET6ZpZ4ZqBE/SPkkOivEtlrcPzLs5elwMLZ3goD1XMD4VB3yjumb5WuW/8H8MA==}
|
||||
peerDependencies:
|
||||
dotenv: ^16.4.7
|
||||
dotenv: ^17
|
||||
|
||||
'@ljharb/resumer@0.1.3':
|
||||
resolution: {integrity: sha512-d+tsDgfkj9X5QTriqM4lKesCkMMJC3IrbPKHvayP00ELx2axdXvDfWkqjxrLXIzGcQzmj7VAUT1wopqARTvafw==}
|
||||
@@ -473,67 +482,56 @@ packages:
|
||||
resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.53.3':
|
||||
resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.53.3':
|
||||
resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.53.3':
|
||||
resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.53.3':
|
||||
resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.53.3':
|
||||
resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.53.3':
|
||||
resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.53.3':
|
||||
resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.53.3':
|
||||
resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.53.3':
|
||||
resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.53.3':
|
||||
resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-openharmony-arm64@4.53.3':
|
||||
resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==}
|
||||
@@ -799,8 +797,8 @@ packages:
|
||||
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
cookie@1.0.2:
|
||||
resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
|
||||
cookie@1.1.1:
|
||||
resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
cors@2.8.5:
|
||||
@@ -1410,8 +1408,8 @@ packages:
|
||||
js-tokens@4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
|
||||
js-yaml@4.1.0:
|
||||
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
|
||||
js-yaml@4.1.1:
|
||||
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
|
||||
hasBin: true
|
||||
|
||||
jsbn@1.1.0:
|
||||
@@ -1458,6 +1456,9 @@ packages:
|
||||
magic-string@0.30.17:
|
||||
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
|
||||
|
||||
magic-string@0.30.21:
|
||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||
|
||||
math-intrinsics@1.1.0:
|
||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -1716,8 +1717,8 @@ packages:
|
||||
pm2-sysmonit@1.2.8:
|
||||
resolution: {integrity: sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA==}
|
||||
|
||||
pm2@6.0.13:
|
||||
resolution: {integrity: sha512-1hS/adMgKoDpX4S1ichJW8SiGpex+oBSZK31dP1FSYOOGtaeuemXzhXPOCefmddgIY4K6v7uu+7xNPnmEnK3ag==}
|
||||
pm2@6.0.14:
|
||||
resolution: {integrity: sha512-wX1FiFkzuT2H/UUEA8QNXDAA9MMHDsK/3UHj6Dkd5U7kxyigKDA5gyDw78ycTQZAuGCLWyUX5FiXEuVQWafukA==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
hasBin: true
|
||||
|
||||
@@ -1818,8 +1819,8 @@ packages:
|
||||
resolution: {integrity: sha512-wI8D5dvYovRMx/YYKtUNt3Yxaw4ORC9xo6Gt9t22kveWz1enG9QrhVlagzwrxSC455xD1dHMKhIJkbsQ7d48BA==}
|
||||
engines: {node: '>=8.3'}
|
||||
|
||||
rollup-plugin-dts@6.2.3:
|
||||
resolution: {integrity: sha512-UgnEsfciXSPpASuOelix7m4DrmyQgiaWBnvI0TM4GxuDh5FkqW8E5hu57bCxXB90VvR1WNfLV80yEDN18UogSA==}
|
||||
rollup-plugin-dts@6.3.0:
|
||||
resolution: {integrity: sha512-d0UrqxYd8KyZ6i3M2Nx7WOMy708qsV/7fTHMHxCMCBOAe3V/U7OMPu5GkX8hC+cmkHhzGnfeYongl1IgiooddA==}
|
||||
engines: {node: '>=16'}
|
||||
peerDependencies:
|
||||
rollup: ^3.29.4 || ^4
|
||||
@@ -2174,8 +2175,8 @@ packages:
|
||||
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
vite@7.2.4:
|
||||
resolution: {integrity: sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==}
|
||||
vite@7.2.6:
|
||||
resolution: {integrity: sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@@ -2410,13 +2411,15 @@ snapshots:
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.4': {}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.5': {}
|
||||
|
||||
'@kevisual/auth@1.0.5': {}
|
||||
|
||||
'@kevisual/code-center-module@0.0.24(dotenv@17.2.3)':
|
||||
dependencies:
|
||||
'@kevisual/auth': 1.0.5
|
||||
'@kevisual/router': 0.0.23
|
||||
'@kevisual/use-config': 1.0.19(dotenv@17.2.3)
|
||||
'@kevisual/use-config': 1.0.21(dotenv@17.2.3)
|
||||
ioredis: 5.8.2
|
||||
nanoid: 5.1.5
|
||||
pg: 8.16.3
|
||||
@@ -2449,8 +2452,8 @@ snapshots:
|
||||
'@kevisual/auth': 1.0.5
|
||||
'@kevisual/rollup-tools': 0.0.1(esbuild@0.25.8)
|
||||
'@kevisual/router': 0.0.7
|
||||
'@kevisual/use-config': 1.0.19(dotenv@17.2.3)
|
||||
cookie: 1.0.2
|
||||
'@kevisual/use-config': 1.0.21(dotenv@17.2.3)
|
||||
cookie: 1.1.1
|
||||
nanoid: 5.1.5
|
||||
pg: 8.16.3
|
||||
sequelize: 6.37.7(pg@8.16.3)
|
||||
@@ -2470,6 +2473,8 @@ snapshots:
|
||||
- tedious
|
||||
- utf-8-validate
|
||||
|
||||
'@kevisual/permission@0.0.3': {}
|
||||
|
||||
'@kevisual/rollup-tools@0.0.1(esbuild@0.25.8)':
|
||||
dependencies:
|
||||
'@rollup/plugin-alias': 5.1.1(rollup@4.53.3)
|
||||
@@ -2484,7 +2489,7 @@ snapshots:
|
||||
glob: 11.0.3
|
||||
rollup: 4.53.3
|
||||
rollup-plugin-copy: 3.5.0
|
||||
rollup-plugin-dts: 6.2.3(rollup@4.53.3)(typescript@5.9.3)
|
||||
rollup-plugin-dts: 6.3.0(rollup@4.53.3)(typescript@5.9.3)
|
||||
rollup-plugin-esbuild: 6.2.1(esbuild@0.25.8)(rollup@4.53.3)
|
||||
rollup-plugin-inject: 3.0.2
|
||||
tslib: 2.8.1
|
||||
@@ -2520,7 +2525,7 @@ snapshots:
|
||||
|
||||
'@kevisual/types@0.0.10': {}
|
||||
|
||||
'@kevisual/use-config@1.0.19(dotenv@17.2.3)':
|
||||
'@kevisual/use-config@1.0.21(dotenv@17.2.3)':
|
||||
dependencies:
|
||||
'@kevisual/load': 0.0.6
|
||||
dotenv: 17.2.3
|
||||
@@ -2787,9 +2792,9 @@ snapshots:
|
||||
|
||||
'@types/validator@13.15.2': {}
|
||||
|
||||
'@vitejs/plugin-basic-ssl@2.1.0(vite@7.2.4(@types/node@24.10.1))':
|
||||
'@vitejs/plugin-basic-ssl@2.1.0(vite@7.2.6(@types/node@24.10.1))':
|
||||
dependencies:
|
||||
vite: 7.2.4(@types/node@24.10.1)
|
||||
vite: 7.2.6(@types/node@24.10.1)
|
||||
|
||||
accepts@1.3.8:
|
||||
dependencies:
|
||||
@@ -2955,7 +2960,7 @@ snapshots:
|
||||
|
||||
cookie@0.7.2: {}
|
||||
|
||||
cookie@1.0.2: {}
|
||||
cookie@1.1.1: {}
|
||||
|
||||
cors@2.8.5:
|
||||
dependencies:
|
||||
@@ -3681,7 +3686,7 @@ snapshots:
|
||||
js-tokens@4.0.0:
|
||||
optional: true
|
||||
|
||||
js-yaml@4.1.0:
|
||||
js-yaml@4.1.1:
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
|
||||
@@ -3720,6 +3725,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.4
|
||||
|
||||
magic-string@0.30.21:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
math-intrinsics@1.1.0: {}
|
||||
|
||||
merge2@1.4.1: {}
|
||||
@@ -3966,7 +3975,7 @@ snapshots:
|
||||
- supports-color
|
||||
optional: true
|
||||
|
||||
pm2@6.0.13:
|
||||
pm2@6.0.14:
|
||||
dependencies:
|
||||
'@pm2/agent': 2.1.1
|
||||
'@pm2/blessed': 0.1.81
|
||||
@@ -3984,7 +3993,7 @@ snapshots:
|
||||
enquirer: 2.3.6
|
||||
eventemitter2: 5.0.1
|
||||
fclone: 1.0.11
|
||||
js-yaml: 4.1.0
|
||||
js-yaml: 4.1.1
|
||||
mkdirp: 1.0.4
|
||||
needle: 2.4.0
|
||||
pidusage: 3.0.2
|
||||
@@ -4118,9 +4127,9 @@ snapshots:
|
||||
globby: 10.0.1
|
||||
is-plain-object: 3.0.1
|
||||
|
||||
rollup-plugin-dts@6.2.3(rollup@4.53.3)(typescript@5.9.3):
|
||||
rollup-plugin-dts@6.3.0(rollup@4.53.3)(typescript@5.9.3):
|
||||
dependencies:
|
||||
magic-string: 0.30.17
|
||||
magic-string: 0.30.21
|
||||
rollup: 4.53.3
|
||||
typescript: 5.9.3
|
||||
optionalDependencies:
|
||||
@@ -4563,7 +4572,7 @@ snapshots:
|
||||
|
||||
vary@1.1.2: {}
|
||||
|
||||
vite@7.2.4(@types/node@24.10.1):
|
||||
vite@7.2.6(@types/node@24.10.1):
|
||||
dependencies:
|
||||
esbuild: 0.25.8
|
||||
fdir: 6.5.0(picomatch@4.0.3)
|
||||
|
||||
10
src/provider/chat-adapter/kimi.ts
Normal file
10
src/provider/chat-adapter/kimi.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { BaseChat, BaseChatOptions } from '../core/chat.ts';
|
||||
|
||||
export type KimiOptions = Partial<BaseChatOptions>;
|
||||
export class Kimi extends BaseChat {
|
||||
static BASE_URL = 'https://api.moonshot.cn/v1/';
|
||||
constructor(options: KimiOptions) {
|
||||
const baseURL = options.baseURL || Kimi.BASE_URL;
|
||||
super({ ...(options as BaseChatOptions), baseURL: baseURL });
|
||||
}
|
||||
}
|
||||
10
src/provider/chat-adapter/zhipu.ts
Normal file
10
src/provider/chat-adapter/zhipu.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { BaseChat, BaseChatOptions } from '../core/chat.ts';
|
||||
|
||||
export type ZhipuOptions = Partial<BaseChatOptions>;
|
||||
export class Zhipu extends BaseChat {
|
||||
static BASE_URL = 'https://open.bigmodel.cn/api/paas/v4/';
|
||||
constructor(options: ZhipuOptions) {
|
||||
const baseURL = options.baseURL || Zhipu.BASE_URL;
|
||||
super({ ...(options as BaseChatOptions), baseURL: baseURL });
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ import { Volces } from './chat-adapter/volces.ts';
|
||||
import { DeepSeek } from './chat-adapter/deepseek.ts';
|
||||
import { ModelScope } from './chat-adapter/model-scope.ts';
|
||||
import { BailianChat } from './chat-adapter/dashscope.ts';
|
||||
import { Zhipu } from './chat-adapter/zhipu.ts';
|
||||
import { Kimi } from './chat-adapter/kimi.ts';
|
||||
|
||||
import { ChatMessage } from './core/type.ts';
|
||||
|
||||
@@ -18,6 +20,8 @@ export const VolcesProvider = Volces;
|
||||
export const DeepSeekProvider = DeepSeek;
|
||||
export const ModelScopeProvider = ModelScope;
|
||||
export const BailianProvider = BailianChat;
|
||||
export const ZhipuProvider = Zhipu;
|
||||
export const KimiProvider = Kimi;
|
||||
|
||||
export const ChatProviderMap = {
|
||||
Ollama: OllamaProvider,
|
||||
@@ -28,6 +32,8 @@ export const ChatProviderMap = {
|
||||
ModelScope: ModelScopeProvider,
|
||||
BaseChat: BaseChat,
|
||||
Bailian: BailianProvider,
|
||||
Zhipu: ZhipuProvider,
|
||||
Kimi: KimiProvider,
|
||||
};
|
||||
|
||||
type ProviderManagerConfig = {
|
||||
|
||||
@@ -9,6 +9,7 @@ import type {
|
||||
EmbeddingMessage,
|
||||
EmbeddingMessageComplete,
|
||||
} from './type.ts';
|
||||
import { AIUtils } from './utils/index.ts';
|
||||
|
||||
export type BaseChatOptions<T = Record<string, any>> = {
|
||||
/**
|
||||
@@ -32,14 +33,7 @@ export type BaseChatOptions<T = Record<string, any>> = {
|
||||
*/
|
||||
stream?: boolean;
|
||||
} & T;
|
||||
export const getIsBrowser = () => {
|
||||
try {
|
||||
// 检查是否存在window对象
|
||||
return typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
export class BaseChat implements BaseChatInterface, BaseChatUsageInterface {
|
||||
/**
|
||||
* 默认baseURL
|
||||
@@ -53,32 +47,16 @@ export class BaseChat implements BaseChatInterface, BaseChatUsageInterface {
|
||||
* 默认apiKey
|
||||
*/
|
||||
apiKey: string;
|
||||
/**
|
||||
* 是否在浏览器中使用
|
||||
*/
|
||||
isBrowser: boolean;
|
||||
/**
|
||||
* openai实例
|
||||
*/
|
||||
openai: OpenAI;
|
||||
|
||||
prompt_tokens: number;
|
||||
total_tokens: number;
|
||||
completion_tokens: number;
|
||||
responseText: string;
|
||||
|
||||
utils: AIUtils;
|
||||
constructor(options: BaseChatOptions) {
|
||||
this.baseURL = options.baseURL;
|
||||
this.model = options.model;
|
||||
this.apiKey = options.apiKey;
|
||||
// @ts-ignore
|
||||
const DEFAULT_IS_BROWSER = getIsBrowser();
|
||||
this.isBrowser = options.isBrowser ?? DEFAULT_IS_BROWSER;
|
||||
// this.openai = new OpenAI({
|
||||
// apiKey: this.apiKey,
|
||||
// baseURL: this.baseURL,
|
||||
// dangerouslyAllowBrowser: options?.dangerouslyAllowBrowser ?? this.isBrowser,
|
||||
// });
|
||||
this.utils = new AIUtils();
|
||||
}
|
||||
post(url = '', opts: { headers?: Record<string, string>, data?: any } = {}) {
|
||||
let _url = url.startsWith('http') ? url : this.baseURL + url;
|
||||
|
||||
192
src/provider/core/utils/index.ts
Normal file
192
src/provider/core/utils/index.ts
Normal file
@@ -0,0 +1,192 @@
|
||||
export class AIUtils {
|
||||
/**
|
||||
* 从 Markdown 代码块中提取 JSON
|
||||
* @param str 包含 JSON 的字符串
|
||||
* @returns 解析后的对象或 null
|
||||
*/
|
||||
extractJsonFromMarkdown(str: string): any | null {
|
||||
// Try to extract JSON from ```json ... ```
|
||||
const jsonRegex = /```json\s*([\s\S]*?)\s*```/;
|
||||
const match = str.match(jsonRegex);
|
||||
let jsonStr = match && match[1] ? match[1] : str;
|
||||
|
||||
try {
|
||||
return JSON.parse(jsonStr);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 Markdown 代码块中提取代码
|
||||
* @param str Markdown 字符串
|
||||
* @param language 语言类型,不指定则返回所有代码块
|
||||
* @returns 提取的代码字符串或数组
|
||||
*/
|
||||
extractCodeFromMarkdown(str: string, language?: string): string | string[] | null {
|
||||
if (language) {
|
||||
const regex = new RegExp(`\`\`\`${language}\\s*([\\s\\S]*?)\\s*\`\`\``, 'g');
|
||||
const matches = str.match(regex);
|
||||
if (!matches) return null;
|
||||
return matches.map(m => m.replace(new RegExp(`\`\`\`${language}\\s*|\\s*\`\`\``, 'g'), '').trim());
|
||||
}
|
||||
|
||||
const regex = /```[\w]*\s*([\s\S]*?)\s*```/g;
|
||||
const matches = [...str.matchAll(regex)];
|
||||
if (matches.length === 0) return null;
|
||||
return matches.map(m => m[1].trim());
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理 AI 响应中的多余空白和格式
|
||||
* @param str 原始字符串
|
||||
* @returns 清理后的字符串
|
||||
*/
|
||||
cleanResponse(str: string): string {
|
||||
return str
|
||||
.trim()
|
||||
.replace(/\n{3,}/g, '\n\n') // 多个换行符替换为两个
|
||||
.replace(/[ \t]+$/gm, ''); // 删除行尾空格
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 AI 响应中提取标签
|
||||
* @param str 响应字符串
|
||||
* @returns 标签数组
|
||||
*/
|
||||
extractTags(str: string): string[] {
|
||||
const tagPatterns = [
|
||||
/#(\w+)/g, // #tag 格式
|
||||
/\[(\w+)\]/g, // [tag] 格式
|
||||
/tags?:\s*\[([^\]]+)\]/gi, // tags: [...] 格式
|
||||
];
|
||||
|
||||
const tags = new Set<string>();
|
||||
|
||||
for (const pattern of tagPatterns) {
|
||||
const matches = str.matchAll(pattern);
|
||||
for (const match of matches) {
|
||||
if (match[1]) {
|
||||
const extracted = match[1].split(/[,;]/).map(t => t.trim()).filter(Boolean);
|
||||
extracted.forEach(tag => tags.add(tag));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Array.from(tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文本中提取 URL
|
||||
* @param str 文本字符串
|
||||
* @returns URL 数组
|
||||
*/
|
||||
extractUrls(str: string): string[] {
|
||||
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
||||
const matches = str.match(urlRegex);
|
||||
return matches || [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 分割长文本为指定 token 数量的块
|
||||
* @param text 原始文本
|
||||
* @param maxTokens 每块最大 token 数(粗略估算:1 token ≈ 4 字符)
|
||||
* @returns 文本块数组
|
||||
*/
|
||||
chunkText(text: string, maxTokens: number = 1000): string[] {
|
||||
const chunkSize = maxTokens * 4; // 粗略估算
|
||||
const chunks: string[] = [];
|
||||
|
||||
// 按段落分割
|
||||
const paragraphs = text.split(/\n\n+/);
|
||||
let currentChunk = '';
|
||||
|
||||
for (const paragraph of paragraphs) {
|
||||
if ((currentChunk + paragraph).length > chunkSize && currentChunk) {
|
||||
chunks.push(currentChunk.trim());
|
||||
currentChunk = paragraph;
|
||||
} else {
|
||||
currentChunk += (currentChunk ? '\n\n' : '') + paragraph;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentChunk) {
|
||||
chunks.push(currentChunk.trim());
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除 AI 响应中的思考过程(thinking 标签)
|
||||
* @param str 响应字符串
|
||||
* @returns 清理后的字符串
|
||||
*/
|
||||
removeThinkingTags(str: string): string {
|
||||
return str
|
||||
.replace(/<thinking>[\s\S]*?<\/thinking>/gi, '')
|
||||
.replace(/\[thinking\][\s\S]*?\[\/thinking\]/gi, '')
|
||||
.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转义特殊字符用于 AI 提示词
|
||||
* @param str 原始字符串
|
||||
* @returns 转义后的字符串
|
||||
*/
|
||||
escapeForPrompt(str: string): string {
|
||||
return str
|
||||
.replace(/\\/g, '\\\\')
|
||||
.replace(/`/g, '\\`')
|
||||
.replace(/\$/g, '\\$');
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计文本的大致 token 数量
|
||||
* @param text 文本
|
||||
* @returns 估算的 token 数量
|
||||
*/
|
||||
estimateTokens(text: string): number {
|
||||
// 简单估算:中文约 1.5 字符/token,英文约 4 字符/token
|
||||
const chineseChars = (text.match(/[\u4e00-\u9fa5]/g) || []).length;
|
||||
const otherChars = text.length - chineseChars;
|
||||
return Math.ceil(chineseChars / 1.5 + otherChars / 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从响应中提取结构化数据(key: value 格式)
|
||||
* @param str 响应字符串
|
||||
* @returns 键值对对象
|
||||
*/
|
||||
extractKeyValuePairs(str: string): Record<string, string> {
|
||||
const result: Record<string, string> = {};
|
||||
const lines = str.split('\n');
|
||||
|
||||
for (const line of lines) {
|
||||
const match = line.match(/^([^::]+)[::]\s*(.+)$/);
|
||||
if (match) {
|
||||
const key = match[1].trim();
|
||||
const value = match[2].trim();
|
||||
result[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证 AI 响应是否完整(检查截断)
|
||||
* @param str 响应字符串
|
||||
* @returns 是否完整
|
||||
*/
|
||||
isResponseComplete(str: string): boolean {
|
||||
const incompleteSigns = [
|
||||
/```[\w]*\s*[\s\S]*?(?<!```)$/, // 未闭合的代码块
|
||||
/\{[\s\S]*(?<!\})$/, // 未闭合的 JSON
|
||||
/\[[\s\S]*(?<!\])$/, // 未闭合的数组
|
||||
/\.{3,}$/, // 结尾省略号
|
||||
];
|
||||
|
||||
return !incompleteSigns.some(pattern => pattern.test(str.trim()));
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
import { numTokensFromString } from './token.ts';
|
||||
|
||||
// 常量定义
|
||||
const CHUNK_SIZE = 512; // 每个chunk的最大token数
|
||||
const MAGIC_SEPARATOR = '🦛';
|
||||
const DELIMITER = [',', '.', '!', '?', '\n', ',', '。', '!', '?'];
|
||||
const PARAGRAPH_DELIMITER = '\n\n';
|
||||
|
||||
export interface Chunk {
|
||||
chunkId: number;
|
||||
text: string;
|
||||
tokens: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保每个chunk的大小不超过最大token数
|
||||
* @param chunk 输入的文本块
|
||||
* @returns 分割后的文本块及其token数的数组
|
||||
*/
|
||||
function ensureChunkSize(chunk: string): Array<[string, number]> {
|
||||
const tokens = numTokensFromString(chunk);
|
||||
if (tokens <= CHUNK_SIZE) {
|
||||
return [[chunk, tokens]];
|
||||
}
|
||||
|
||||
// 在分隔符后添加魔法分隔符
|
||||
let processedChunk = chunk;
|
||||
for (const delimiter of DELIMITER) {
|
||||
// 转义特殊字符
|
||||
const escapedDelimiter = delimiter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
processedChunk = processedChunk.replace(new RegExp(escapedDelimiter, 'g'), delimiter + MAGIC_SEPARATOR);
|
||||
}
|
||||
|
||||
const chunks: Array<[string, number]> = [];
|
||||
let tail = '';
|
||||
|
||||
// 按CHUNK_SIZE分割文本
|
||||
for (let i = 0; i < processedChunk.length; i += CHUNK_SIZE) {
|
||||
const sentences = (processedChunk.slice(i, i + CHUNK_SIZE) + ' ').split(MAGIC_SEPARATOR);
|
||||
const currentChunk = tail + sentences.slice(0, -1).join('');
|
||||
if (currentChunk.trim()) {
|
||||
const tokenCount = numTokensFromString(currentChunk);
|
||||
chunks.push([currentChunk, tokenCount]);
|
||||
}
|
||||
tail = sentences[sentences.length - 1].trim();
|
||||
}
|
||||
|
||||
// 处理最后剩余的tail
|
||||
if (tail) {
|
||||
const tokenCount = numTokensFromString(tail);
|
||||
chunks.push([tail, tokenCount]);
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将文本分割成chunks
|
||||
* @param text 输入文本
|
||||
* @returns 分割后的chunks数组
|
||||
*/
|
||||
export async function getChunks(text: string): Promise<Chunk[]> {
|
||||
// 按段落分割文本
|
||||
const paragraphs = text
|
||||
.split(PARAGRAPH_DELIMITER)
|
||||
.map((p) => p.trim())
|
||||
.filter((p) => p);
|
||||
|
||||
const chunks: Chunk[] = [];
|
||||
let currentIndex = 0;
|
||||
|
||||
// 处理每个段落
|
||||
for (const paragraph of paragraphs) {
|
||||
const splittedParagraph = ensureChunkSize(paragraph);
|
||||
for (const [text, tokens] of splittedParagraph) {
|
||||
chunks.push({
|
||||
chunkId: currentIndex,
|
||||
text,
|
||||
tokens,
|
||||
});
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
Reference in New Issue
Block a user