Compare commits

...

3 Commits

Author SHA1 Message Date
dzq b9d7f495ad feat(llm-chat): 实现流式API响应和打字机效果
添加流式API调用功能,替换原有的模拟响应。实现以下功能:
1. 使用SSE连接处理AI响应
2. 添加打字机效果逐字显示AI回复
3. 增加错误处理和连接管理
4. 移除未使用的Vant组件声明
2025-12-19 18:02:31 +08:00
dzq 935c662203 feat(agent): 添加流式对话API实现
实现基于SSE的流式对话接口,支持消息发送和回调处理
添加@microsoft/fetch-event-source依赖
2025-12-19 17:19:11 +08:00
dzq e60dac31fd refactor: 移除vite-plugin-vue-devtools及相关依赖
- 从package.json和pnpm-lock.yaml中移除vite-plugin-vue-devtools
- 更新README文档,移除相关插件说明
- 清理构建配置文件中相关插件代码
- 调整聊天输入组件按钮样式
- 移除示例聊天数据
2025-12-19 17:03:54 +08:00
9 changed files with 226 additions and 404 deletions

View File

@ -90,7 +90,6 @@ An mobile web apps template based on the Vue 3 ecosystem.
- [vite-plugin-vconsole](https://github.com/vadxq/vite-plugin-vconsole) - A lightweight, extendable front-end developer tool for mobile web page - [vite-plugin-vconsole](https://github.com/vadxq/vite-plugin-vconsole) - A lightweight, extendable front-end developer tool for mobile web page
- [vite-plugin-mock-dev-server](https://github.com/pengzhanbo/vite-plugin-mock-dev-server) - Vite Plugin for API mock dev server - [vite-plugin-mock-dev-server](https://github.com/pengzhanbo/vite-plugin-mock-dev-server) - Vite Plugin for API mock dev server
- [postcss-mobile-forever](https://github.com/wswmsword/postcss-mobile-forever) - To adapt different displays by one mobile viewport - [postcss-mobile-forever](https://github.com/wswmsword/postcss-mobile-forever) - To adapt different displays by one mobile viewport
- [vite-plugin-vue-devtools](https://github.com/vuejs/devtools-next) - Designed to enhance the Vue developer experience
- [vueuse](https://github.com/antfu/vueuse) - collection of useful composition APIs - [vueuse](https://github.com/antfu/vueuse) - collection of useful composition APIs
- [@unhead/vue v2](https://github.com/unjs/unhead) - manipulate document head reactively - [@unhead/vue v2](https://github.com/unjs/unhead) - manipulate document head reactively
- [vite-plugin-pwa](https://github.com/antfu/vite-plugin-pwa) - PWA - [vite-plugin-pwa](https://github.com/antfu/vite-plugin-pwa) - PWA

View File

@ -90,7 +90,6 @@ An mobile web apps template based on the Vue 3 ecosystem.
- [vite-plugin-vconsole](https://github.com/vadxq/vite-plugin-vconsole) - vConsole 的 vite 插件 - [vite-plugin-vconsole](https://github.com/vadxq/vite-plugin-vconsole) - vConsole 的 vite 插件
- [vite-plugin-mock-dev-server](https://github.com/pengzhanbo/vite-plugin-mock-dev-server) - vite mock 开发服务mock-dev-server插件 - [vite-plugin-mock-dev-server](https://github.com/pengzhanbo/vite-plugin-mock-dev-server) - vite mock 开发服务mock-dev-server插件
- [postcss-mobile-forever](https://github.com/wswmsword/postcss-mobile-forever) - 一款 PostCSS 插件,将固定尺寸的移动端视图转为具有最大宽度的可伸缩的移动端视图 - [postcss-mobile-forever](https://github.com/wswmsword/postcss-mobile-forever) - 一款 PostCSS 插件,将固定尺寸的移动端视图转为具有最大宽度的可伸缩的移动端视图
- [vite-plugin-vue-devtools](https://github.com/vuejs/devtools-next) - 旨在增强Vue开发者体验的Vite插件
- [vueuse](https://github.com/antfu/vueuse) - 实用的 Composition API 工具合集 - [vueuse](https://github.com/antfu/vueuse) - 实用的 Composition API 工具合集
- [@unhead/vue v2](https://github.com/unjs/unhead) - 响应式地操作文档头信息 - [@unhead/vue v2](https://github.com/unjs/unhead) - 响应式地操作文档头信息
- [vite-plugin-pwa](https://github.com/antfu/vite-plugin-pwa) - PWA - [vite-plugin-pwa](https://github.com/antfu/vite-plugin-pwa) - PWA

View File

@ -13,7 +13,6 @@ import VueRouter from 'unplugin-vue-router/vite'
import { mockDevServerPlugin } from 'vite-plugin-mock-dev-server' import { mockDevServerPlugin } from 'vite-plugin-mock-dev-server'
import { VitePWA } from 'vite-plugin-pwa' import { VitePWA } from 'vite-plugin-pwa'
import Sitemap from 'vite-plugin-sitemap' import Sitemap from 'vite-plugin-sitemap'
import VueDevTools from 'vite-plugin-vue-devtools'
import { loadEnv } from 'vite' import { loadEnv } from 'vite'
import { createViteVConsole } from './vconsole' import { createViteVConsole } from './vconsole'
@ -80,9 +79,6 @@ export function createVitePlugins(mode: string) {
// https://github.com/vadxq/vite-plugin-vconsole // https://github.com/vadxq/vite-plugin-vconsole
createViteVConsole(mode), createViteVConsole(mode),
// https://github.com/vuejs/devtools-next
VueDevTools(),
// https://github.com/antfu/vite-plugin-pwa // https://github.com/antfu/vite-plugin-pwa
VitePWA({ VitePWA({
registerType: 'autoUpdate', registerType: 'autoUpdate',

View File

@ -20,6 +20,7 @@
"prepare": "" "prepare": ""
}, },
"dependencies": { "dependencies": {
"@microsoft/fetch-event-source": "^2.0.1",
"@unhead/vue": "2.0.19", "@unhead/vue": "2.0.19",
"@vant/touch-emulator": "^1.4.0", "@vant/touch-emulator": "^1.4.0",
"@vant/use": "^1.6.0", "@vant/use": "^1.6.0",
@ -69,7 +70,6 @@
"vite-plugin-pwa": "^1.2.0", "vite-plugin-pwa": "^1.2.0",
"vite-plugin-sitemap": "^0.8.2", "vite-plugin-sitemap": "^0.8.2",
"vite-plugin-vconsole": "^2.1.1", "vite-plugin-vconsole": "^2.1.1",
"vite-plugin-vue-devtools": "^8.0.5",
"vue-tsc": "^3.1.8" "vue-tsc": "^3.1.8"
}, },
"pnpm": { "pnpm": {

View File

@ -11,6 +11,9 @@ importers:
.: .:
dependencies: dependencies:
'@microsoft/fetch-event-source':
specifier: ^2.0.1
version: 2.0.1
'@unhead/vue': '@unhead/vue':
specifier: 2.0.19 specifier: 2.0.19
version: 2.0.19(vue@3.5.25(typescript@5.9.3)) version: 2.0.19(vue@3.5.25(typescript@5.9.3))
@ -153,9 +156,6 @@ importers:
vite-plugin-vconsole: vite-plugin-vconsole:
specifier: ^2.1.1 specifier: ^2.1.1
version: 2.1.1 version: 2.1.1
vite-plugin-vue-devtools:
specifier: ^8.0.5
version: 8.0.5(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))
vue-tsc: vue-tsc:
specifier: ^3.1.8 specifier: ^3.1.8
version: 3.1.8(typescript@5.9.3) version: 3.1.8(typescript@5.9.3)
@ -369,24 +369,12 @@ packages:
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0 '@babel/core': ^7.0.0
'@babel/plugin-proposal-decorators@7.28.0':
resolution: {integrity: sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2':
resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0-0 '@babel/core': ^7.0.0-0
'@babel/plugin-syntax-decorators@7.27.1':
resolution: {integrity: sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-syntax-import-assertions@7.27.1': '@babel/plugin-syntax-import-assertions@7.27.1':
resolution: {integrity: sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==} resolution: {integrity: sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -399,23 +387,6 @@ packages:
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0-0 '@babel/core': ^7.0.0-0
'@babel/plugin-syntax-import-meta@7.10.4':
resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-syntax-jsx@7.27.1':
resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-syntax-typescript@7.27.1':
resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-syntax-unicode-sets-regex@7.18.6': '@babel/plugin-syntax-unicode-sets-regex@7.18.6':
resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -704,12 +675,6 @@ packages:
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0-0 '@babel/core': ^7.0.0-0
'@babel/plugin-transform-typescript@7.28.5':
resolution: {integrity: sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-transform-unicode-escapes@7.27.1': '@babel/plugin-transform-unicode-escapes@7.27.1':
resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==} resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -1055,6 +1020,9 @@ packages:
'@jridgewell/trace-mapping@0.3.31': '@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
'@microsoft/fetch-event-source@2.0.1':
resolution: {integrity: sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==}
'@noble/hashes@1.8.0': '@noble/hashes@1.8.0':
resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==}
engines: {node: ^14.21.3 || >=16} engines: {node: ^14.21.3 || >=16}
@ -1520,22 +1488,6 @@ packages:
vue: vue:
optional: true optional: true
'@vue/babel-helper-vue-transform-on@1.5.0':
resolution: {integrity: sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==}
'@vue/babel-plugin-jsx@1.5.0':
resolution: {integrity: sha512-mneBhw1oOqCd2247O0Yw/mRwC9jIGACAJUlawkmMBiNmL4dGA2eMzuNZVNqOUfYTa6vqmND4CtOPzmEEEqLKFw==}
peerDependencies:
'@babel/core': ^7.0.0-0
peerDependenciesMeta:
'@babel/core':
optional: true
'@vue/babel-plugin-resolve-type@1.5.0':
resolution: {integrity: sha512-Wm/60o+53JwJODm4Knz47dxJnLDJ9FnKnGZJbUUf8nQRAtt6P+undLUAVU3Ha33LxOJe6IPoifRQ6F/0RrU31w==}
peerDependencies:
'@babel/core': ^7.0.0-0
'@vue/compiler-core@3.5.25': '@vue/compiler-core@3.5.25':
resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==} resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==}
@ -1554,23 +1506,12 @@ packages:
'@vue/devtools-api@7.7.9': '@vue/devtools-api@7.7.9':
resolution: {integrity: sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==} resolution: {integrity: sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==}
'@vue/devtools-core@8.0.5':
resolution: {integrity: sha512-dpCw8nl0GDBuiL9SaY0mtDxoGIEmU38w+TQiYEPOLhW03VDC0lfNMYXS/qhl4I0YlysGp04NLY4UNn6xgD0VIQ==}
peerDependencies:
vue: ^3.0.0
'@vue/devtools-kit@7.7.9': '@vue/devtools-kit@7.7.9':
resolution: {integrity: sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==} resolution: {integrity: sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==}
'@vue/devtools-kit@8.0.5':
resolution: {integrity: sha512-q2VV6x1U3KJMTQPUlRMyWEKVbcHuxhqJdSr6Jtjz5uAThAIrfJ6WVZdGZm5cuO63ZnSUz0RCsVwiUUb0mDV0Yg==}
'@vue/devtools-shared@7.7.9': '@vue/devtools-shared@7.7.9':
resolution: {integrity: sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==} resolution: {integrity: sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==}
'@vue/devtools-shared@8.0.5':
resolution: {integrity: sha512-bRLn6/spxpmgLk+iwOrR29KrYnJjG9DGpHGkDFG82UM21ZpJ39ztUT9OXX3g+usW7/b2z+h46I9ZiYyB07XMXg==}
'@vue/language-core@3.1.8': '@vue/language-core@3.1.8':
resolution: {integrity: sha512-PfwAW7BLopqaJbneChNL6cUOTL3GL+0l8paYP5shhgY5toBNidWnMXWM+qDwL7MC9+zDtzCF2enT8r6VPu64iw==} resolution: {integrity: sha512-PfwAW7BLopqaJbneChNL6cUOTL3GL+0l8paYP5shhgY5toBNidWnMXWM+qDwL7MC9+zDtzCF2enT8r6VPu64iw==}
peerDependencies: peerDependencies:
@ -1775,10 +1716,6 @@ packages:
engines: {node: '>=18'} engines: {node: '>=18'}
hasBin: true hasBin: true
bundle-name@4.1.0:
resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==}
engines: {node: '>=18'}
bytes@3.1.2: bytes@3.1.2:
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
@ -1984,22 +1921,10 @@ packages:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
default-browser-id@5.0.1:
resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==}
engines: {node: '>=18'}
default-browser@5.4.0:
resolution: {integrity: sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==}
engines: {node: '>=18'}
define-data-property@1.1.4: define-data-property@1.1.4:
resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
define-lazy-prop@3.0.0:
resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==}
engines: {node: '>=12'}
define-properties@1.2.1: define-properties@1.2.1:
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -2077,9 +2002,6 @@ packages:
resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
hasBin: true hasBin: true
error-stack-parser-es@1.0.5:
resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==}
es-abstract@1.24.0: es-abstract@1.24.0:
resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -2668,11 +2590,6 @@ packages:
resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
is-docker@3.0.0:
resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
hasBin: true
is-extglob@2.1.1: is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -2693,11 +2610,6 @@ packages:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
is-inside-container@1.0.0:
resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
engines: {node: '>=14.16'}
hasBin: true
is-map@2.0.3: is-map@2.0.3:
resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -2772,10 +2684,6 @@ packages:
resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==} resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==}
engines: {node: '>=18'} engines: {node: '>=18'}
is-wsl@3.1.0:
resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==}
engines: {node: '>=16'}
isarray@2.0.5: isarray@2.0.5:
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
@ -2855,9 +2763,6 @@ packages:
keyv@4.5.4: keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
kolorist@1.8.0:
resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
less@4.4.2: less@4.4.2:
resolution: {integrity: sha512-j1n1IuTX1VQjIy3tT7cyGbX7nvQOsFLoIqobZv4ttI5axP923gA44zUj6miiA6R5Aoms4sEGVIIcucXUbRI14g==} resolution: {integrity: sha512-j1n1IuTX1VQjIy3tT7cyGbX7nvQOsFLoIqobZv4ttI5axP923gA44zUj6miiA6R5Aoms4sEGVIIcucXUbRI14g==}
engines: {node: '>=14'} engines: {node: '>=14'}
@ -3140,11 +3045,6 @@ packages:
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true hasBin: true
nanoid@5.1.6:
resolution: {integrity: sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==}
engines: {node: ^18 || >=20}
hasBin: true
natural-compare@1.4.0: natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
@ -3214,10 +3114,6 @@ packages:
resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
open@10.2.0:
resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==}
engines: {node: '>=18'}
optionator@0.9.4: optionator@0.9.4:
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
@ -3505,10 +3401,6 @@ packages:
engines: {node: '>=18.0.0', npm: '>=8.0.0'} engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true hasBin: true
run-applescript@7.1.0:
resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==}
engines: {node: '>=18'}
safe-array-concat@1.1.3: safe-array-concat@1.1.3:
resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==}
engines: {node: '>=0.4'} engines: {node: '>=0.4'}
@ -3968,26 +3860,6 @@ packages:
vconsole@3.15.1: vconsole@3.15.1:
resolution: {integrity: sha512-KH8XLdrq9T5YHJO/ixrjivHfmF2PC2CdVoK6RWZB4yftMykYIaXY1mxZYAic70vADM54kpMQF+dYmvl5NRNy1g==} resolution: {integrity: sha512-KH8XLdrq9T5YHJO/ixrjivHfmF2PC2CdVoK6RWZB4yftMykYIaXY1mxZYAic70vADM54kpMQF+dYmvl5NRNy1g==}
vite-dev-rpc@1.1.0:
resolution: {integrity: sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==}
peerDependencies:
vite: ^7.2.7
vite-hot-client@2.1.0:
resolution: {integrity: sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==}
peerDependencies:
vite: ^7.2.7
vite-plugin-inspect@11.3.3:
resolution: {integrity: sha512-u2eV5La99oHoYPHE6UvbwgEqKKOQGz86wMg40CCosP6q8BkB6e5xPneZfYagK4ojPJSj5anHCrnvC20DpwVdRA==}
engines: {node: '>=14'}
peerDependencies:
'@nuxt/kit': '*'
vite: ^7.2.7
peerDependenciesMeta:
'@nuxt/kit':
optional: true
vite-plugin-mock-dev-server@2.0.6: vite-plugin-mock-dev-server@2.0.6:
resolution: {integrity: sha512-n0pBPSy4L5RU3BnXaul5b0NsEF4YI555vbzOHtyQ/EhBzRSHYXmey504w0hRJ/8yRMiHO0eUXKIH7aA/3TUbxA==} resolution: {integrity: sha512-n0pBPSy4L5RU3BnXaul5b0NsEF4YI555vbzOHtyQ/EhBzRSHYXmey504w0hRJ/8yRMiHO0eUXKIH7aA/3TUbxA==}
engines: {node: ^18 || ^20 || >=22} engines: {node: ^18 || ^20 || >=22}
@ -4019,17 +3891,6 @@ packages:
vite-plugin-vconsole@2.1.1: vite-plugin-vconsole@2.1.1:
resolution: {integrity: sha512-369FlBnQhzR5pF2+nsmbMeF5qNO6MzUIk3l+DHa8In15cscyk4eXT5pWfExoSLn41dgeI1FPP+kgAKViePYPdQ==} resolution: {integrity: sha512-369FlBnQhzR5pF2+nsmbMeF5qNO6MzUIk3l+DHa8In15cscyk4eXT5pWfExoSLn41dgeI1FPP+kgAKViePYPdQ==}
vite-plugin-vue-devtools@8.0.5:
resolution: {integrity: sha512-p619BlKFOqQXJ6uDWS1vUPQzuJOD6xJTfftj57JXBGoBD/yeQCowR7pnWcr/FEX4/HVkFbreI6w2uuGBmQOh6A==}
engines: {node: '>=v14.21.3'}
peerDependencies:
vite: ^7.2.7
vite-plugin-vue-inspector@5.3.2:
resolution: {integrity: sha512-YvEKooQcSiBTAs0DoYLfefNja9bLgkFM7NI2b07bE2SruuvX0MEa9cMaxjKVMkeCp5Nz9FRIdcN1rOdFVBeL6Q==}
peerDependencies:
vite: ^7.2.7
vite@7.2.7: vite@7.2.7:
resolution: {integrity: sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==} resolution: {integrity: sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
@ -4203,10 +4064,6 @@ packages:
utf-8-validate: utf-8-validate:
optional: true optional: true
wsl-utils@0.1.0:
resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==}
engines: {node: '>=18'}
xml-name-validator@4.0.0: xml-name-validator@4.0.0:
resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -4493,24 +4350,10 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@babel/plugin-proposal-decorators@7.28.0(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5)
'@babel/helper-plugin-utils': 7.27.1
'@babel/plugin-syntax-decorators': 7.27.1(@babel/core@7.28.5)
transitivePeerDependencies:
- supports-color
'@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5)': '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5)':
dependencies: dependencies:
'@babel/core': 7.28.5 '@babel/core': 7.28.5
'@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
'@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.5)': '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.5)':
dependencies: dependencies:
'@babel/core': 7.28.5 '@babel/core': 7.28.5
@ -4521,21 +4364,6 @@ snapshots:
'@babel/core': 7.28.5 '@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1 '@babel/helper-plugin-utils': 7.27.1
'@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
'@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
'@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
'@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.5)': '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.5)':
dependencies: dependencies:
'@babel/core': 7.28.5 '@babel/core': 7.28.5
@ -4852,17 +4680,6 @@ snapshots:
'@babel/core': 7.28.5 '@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1 '@babel/helper-plugin-utils': 7.27.1
'@babel/plugin-transform-typescript@7.28.5(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-annotate-as-pure': 7.27.3
'@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5)
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-skip-transparent-expression-wrappers': 7.27.1
'@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5)
transitivePeerDependencies:
- supports-color
'@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.5)': '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.5)':
dependencies: dependencies:
'@babel/core': 7.28.5 '@babel/core': 7.28.5
@ -5242,6 +5059,8 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2 '@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/sourcemap-codec': 1.5.5
'@microsoft/fetch-event-source@2.0.1': {}
'@noble/hashes@1.8.0': {} '@noble/hashes@1.8.0': {}
'@paralleldrive/cuid2@2.3.1': '@paralleldrive/cuid2@2.3.1':
@ -5761,35 +5580,6 @@ snapshots:
optionalDependencies: optionalDependencies:
vue: 3.5.25(typescript@5.9.3) vue: 3.5.25(typescript@5.9.3)
'@vue/babel-helper-vue-transform-on@1.5.0': {}
'@vue/babel-plugin-jsx@1.5.0(@babel/core@7.28.5)':
dependencies:
'@babel/helper-module-imports': 7.27.1
'@babel/helper-plugin-utils': 7.27.1
'@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5)
'@babel/template': 7.27.2
'@babel/traverse': 7.28.5
'@babel/types': 7.28.5
'@vue/babel-helper-vue-transform-on': 1.5.0
'@vue/babel-plugin-resolve-type': 1.5.0(@babel/core@7.28.5)
'@vue/shared': 3.5.25
optionalDependencies:
'@babel/core': 7.28.5
transitivePeerDependencies:
- supports-color
'@vue/babel-plugin-resolve-type@1.5.0(@babel/core@7.28.5)':
dependencies:
'@babel/code-frame': 7.27.1
'@babel/core': 7.28.5
'@babel/helper-module-imports': 7.27.1
'@babel/helper-plugin-utils': 7.27.1
'@babel/parser': 7.28.5
'@vue/compiler-sfc': 3.5.25
transitivePeerDependencies:
- supports-color
'@vue/compiler-core@3.5.25': '@vue/compiler-core@3.5.25':
dependencies: dependencies:
'@babel/parser': 7.28.5 '@babel/parser': 7.28.5
@ -5826,18 +5616,6 @@ snapshots:
dependencies: dependencies:
'@vue/devtools-kit': 7.7.9 '@vue/devtools-kit': 7.7.9
'@vue/devtools-core@8.0.5(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))':
dependencies:
'@vue/devtools-kit': 8.0.5
'@vue/devtools-shared': 8.0.5
mitt: 3.0.1
nanoid: 5.1.6
pathe: 2.0.3
vite-hot-client: 2.1.0(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2))
vue: 3.5.25(typescript@5.9.3)
transitivePeerDependencies:
- vite
'@vue/devtools-kit@7.7.9': '@vue/devtools-kit@7.7.9':
dependencies: dependencies:
'@vue/devtools-shared': 7.7.9 '@vue/devtools-shared': 7.7.9
@ -5848,24 +5626,10 @@ snapshots:
speakingurl: 14.0.1 speakingurl: 14.0.1
superjson: 2.2.6 superjson: 2.2.6
'@vue/devtools-kit@8.0.5':
dependencies:
'@vue/devtools-shared': 8.0.5
birpc: 2.9.0
hookable: 5.5.3
mitt: 3.0.1
perfect-debounce: 2.0.0
speakingurl: 14.0.1
superjson: 2.2.6
'@vue/devtools-shared@7.7.9': '@vue/devtools-shared@7.7.9':
dependencies: dependencies:
rfdc: 1.4.1 rfdc: 1.4.1
'@vue/devtools-shared@8.0.5':
dependencies:
rfdc: 1.4.1
'@vue/language-core@3.1.8(typescript@5.9.3)': '@vue/language-core@3.1.8(typescript@5.9.3)':
dependencies: dependencies:
'@volar/language-core': 2.4.26 '@volar/language-core': 2.4.26
@ -6099,10 +5863,6 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- magicast - magicast
bundle-name@4.1.0:
dependencies:
run-applescript: 7.1.0
bytes@3.1.2: {} bytes@3.1.2: {}
c12@3.3.2: c12@3.3.2:
@ -6304,21 +6064,12 @@ snapshots:
deepmerge@4.3.1: {} deepmerge@4.3.1: {}
default-browser-id@5.0.1: {}
default-browser@5.4.0:
dependencies:
bundle-name: 4.1.0
default-browser-id: 5.0.1
define-data-property@1.1.4: define-data-property@1.1.4:
dependencies: dependencies:
es-define-property: 1.0.1 es-define-property: 1.0.1
es-errors: 1.3.0 es-errors: 1.3.0
gopd: 1.2.0 gopd: 1.2.0
define-lazy-prop@3.0.0: {}
define-properties@1.2.1: define-properties@1.2.1:
dependencies: dependencies:
define-data-property: 1.1.4 define-data-property: 1.1.4
@ -6385,8 +6136,6 @@ snapshots:
prr: 1.0.1 prr: 1.0.1
optional: true optional: true
error-stack-parser-es@1.0.5: {}
es-abstract@1.24.0: es-abstract@1.24.0:
dependencies: dependencies:
array-buffer-byte-length: 1.0.2 array-buffer-byte-length: 1.0.2
@ -7120,8 +6869,6 @@ snapshots:
call-bound: 1.0.4 call-bound: 1.0.4
has-tostringtag: 1.0.2 has-tostringtag: 1.0.2
is-docker@3.0.0: {}
is-extglob@2.1.1: {} is-extglob@2.1.1: {}
is-finalizationregistry@1.1.1: is-finalizationregistry@1.1.1:
@ -7144,10 +6891,6 @@ snapshots:
dependencies: dependencies:
is-extglob: 2.1.1 is-extglob: 2.1.1
is-inside-container@1.0.0:
dependencies:
is-docker: 3.0.0
is-map@2.0.3: {} is-map@2.0.3: {}
is-module@1.0.0: {} is-module@1.0.0: {}
@ -7210,10 +6953,6 @@ snapshots:
is-what@5.5.0: {} is-what@5.5.0: {}
is-wsl@3.1.0:
dependencies:
is-inside-container: 1.0.0
isarray@2.0.5: {} isarray@2.0.5: {}
isexe@2.0.0: {} isexe@2.0.0: {}
@ -7275,8 +7014,6 @@ snapshots:
dependencies: dependencies:
json-buffer: 3.0.1 json-buffer: 3.0.1
kolorist@1.8.0: {}
less@4.4.2: less@4.4.2:
dependencies: dependencies:
copy-anything: 2.0.6 copy-anything: 2.0.6
@ -7749,8 +7486,6 @@ snapshots:
nanoid@3.3.11: {} nanoid@3.3.11: {}
nanoid@5.1.6: {}
natural-compare@1.4.0: {} natural-compare@1.4.0: {}
natural-orderby@5.0.0: {} natural-orderby@5.0.0: {}
@ -7816,13 +7551,6 @@ snapshots:
dependencies: dependencies:
mimic-function: 5.0.1 mimic-function: 5.0.1
open@10.2.0:
dependencies:
default-browser: 5.4.0
define-lazy-prop: 3.0.0
is-inside-container: 1.0.0
wsl-utils: 0.1.0
optionator@0.9.4: optionator@0.9.4:
dependencies: dependencies:
deep-is: 0.1.4 deep-is: 0.1.4
@ -8101,8 +7829,6 @@ snapshots:
'@rollup/rollup-win32-x64-msvc': 4.53.3 '@rollup/rollup-win32-x64-msvc': 4.53.3
fsevents: 2.3.3 fsevents: 2.3.3
run-applescript@7.1.0: {}
safe-array-concat@1.1.3: safe-array-concat@1.1.3:
dependencies: dependencies:
call-bind: 1.0.8 call-bind: 1.0.8
@ -8656,31 +8382,6 @@ snapshots:
core-js: 3.47.0 core-js: 3.47.0
mutation-observer: 1.0.3 mutation-observer: 1.0.3
vite-dev-rpc@1.1.0(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2)):
dependencies:
birpc: 2.9.0
vite: 7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2)
vite-hot-client: 2.1.0(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2))
vite-hot-client@2.1.0(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2)):
dependencies:
vite: 7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2)
vite-plugin-inspect@11.3.3(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2)):
dependencies:
ansis: 4.2.0
debug: 4.4.3
error-stack-parser-es: 1.0.5
ohash: 2.0.11
open: 10.2.0
perfect-debounce: 2.0.0
sirv: 3.0.2
unplugin-utils: 0.3.1
vite: 7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2)
vite-dev-rpc: 1.1.0(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2))
transitivePeerDependencies:
- supports-color
vite-plugin-mock-dev-server@2.0.6(esbuild@0.25.12)(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2)): vite-plugin-mock-dev-server@2.0.6(esbuild@0.25.12)(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2)):
dependencies: dependencies:
'@pengzhanbo/utils': 2.1.2 '@pengzhanbo/utils': 2.1.2
@ -8722,35 +8423,6 @@ snapshots:
vite-plugin-vconsole@2.1.1: {} vite-plugin-vconsole@2.1.1: {}
vite-plugin-vue-devtools@8.0.5(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)):
dependencies:
'@vue/devtools-core': 8.0.5(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))
'@vue/devtools-kit': 8.0.5
'@vue/devtools-shared': 8.0.5
sirv: 3.0.2
vite: 7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2)
vite-plugin-inspect: 11.3.3(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2))
vite-plugin-vue-inspector: 5.3.2(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2))
transitivePeerDependencies:
- '@nuxt/kit'
- supports-color
- vue
vite-plugin-vue-inspector@5.3.2(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2)):
dependencies:
'@babel/core': 7.28.5
'@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.5)
'@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.5)
'@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.5)
'@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.28.5)
'@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.28.5)
'@vue/compiler-dom': 3.5.25
kolorist: 1.8.0
magic-string: 0.30.21
vite: 7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2)
transitivePeerDependencies:
- supports-color
vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2): vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.1)(yaml@2.8.2):
dependencies: dependencies:
esbuild: 0.25.12 esbuild: 0.25.12
@ -8984,10 +8656,6 @@ snapshots:
ws@8.18.3: {} ws@8.18.3: {}
wsl-utils@0.1.0:
dependencies:
is-wsl: 3.1.0
xml-name-validator@4.0.0: {} xml-name-validator@4.0.0: {}
yallist@3.1.1: {} yallist@3.1.1: {}

98
src/api/agent/index.ts Normal file
View File

@ -0,0 +1,98 @@
const AGENT_BASE_URL = '';
import { fetchEventSource } from '@microsoft/fetch-event-source';
export const baseInfoApi = () => {
return fetch(`${AGENT_BASE_URL}`, {
method: 'GET',
});
}
/**
* JSON {"text":"我来"}
* @param message
* @param callbacks
* @param options abort signal
* @example
* // 使用示例:
* streamApi('你好', {
* onopen(response) {
* console.log('连接已建立', response);
* },
* onmessage(data) {
* // data 是服务器发送的原始字符串,如 '{"text":"我来"}'
* console.log('收到消息:', data);
* },
* onclose() {
* console.log('连接已关闭');
* },
* onerror(error) {
* console.error('连接错误:', error);
* }
* }, { signal: abortController.signal });
*/
export const streamApi = (
message: string,
callbacks: {
onopen?: (response: Response) => void;
onmessage?: (data: string) => void;
onclose?: () => void;
onerror?: (error: Error) => void;
},
options?: { signal?: AbortSignal }
) => {
// 启动 fetchEventSource
fetchEventSource(`${AGENT_BASE_URL}/stream`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ message }),
signal: options?.signal,
async onopen(response) {
// 检查响应是否正常
if (response.ok && response.headers.get('content-type')?.includes('text/event-stream')) {
// 连接成功,调用 onopen 回调
callbacks.onopen?.(response);
} else {
// 如果响应不正常,抛出错误
throw new Error(`SSE 连接失败: ${response.status} ${response.statusText}`);
}
},
onmessage(msg) {
// 处理服务器发送的消息
// msg.data 应该是 JSON 字符串,如 {"text":"..."}
try {
const data = msg.data;
console.log('Received message:', data);
if (data && data !== '[DONE]') {
callbacks.onmessage?.(data);
}
} catch (error) {
console.warn('处理 SSE 消息时出错:', error);
}
},
onclose() {
// 连接关闭
console.log('SSE 连接已关闭');
callbacks.onclose?.();
},
onerror(err) {
// 发生错误
console.error('SSE 连接错误:', err);
callbacks.onerror?.(err instanceof Error ? err : new Error(String(err)));
// 重新抛出错误以停止重试
throw err;
},
}).catch(error => {
// 捕获 fetchEventSource 的 Promise 拒绝
if (error.name !== 'AbortError') {
console.error('fetchEventSource 错误:', error);
callbacks.onerror?.(error instanceof Error ? error : new Error(String(error)));
} else {
// AbortError 是正常的取消操作,不需要调用 onerror
console.log('请求已被取消');
}
});
}

View File

@ -52,15 +52,12 @@ defineExpose({
<van-button <van-button
type="primary" type="primary"
round
:disabled="!props.modelValue.trim() || disabled" :disabled="!props.modelValue.trim() || disabled"
:loading="loading" :loading="loading"
class="flex-shrink-0" class="flex-shrink-0"
@click="handleSend" @click="handleSend"
icon="upgrade"
> >
<template #icon>
<van-icon name="send" />
</template>
</van-button> </van-button>
</div> </div>
</template> </template>

View File

@ -1,38 +1,22 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ChatMessage } from '@/types/chat' import type { ChatMessage } from '@/types/chat'
import { useScroll } from '@vueuse/core' import { useScroll } from '@vueuse/core'
import { isDark, toggleDark } from '@/composables/dark' import { streamApi } from '@/api/agent'
// Sample chat data for demonstration // Sample chat data for demonstration
const messages = ref<ChatMessage[]>([ const messages = ref<ChatMessage[]>([
{
id: 1,
content: 'Hello! I\'m your AI assistant. How can I help you today?',
sender: 'ai',
timestamp: new Date('2025-12-17T10:00:00'),
status: 'sent',
},
{
id: 2,
content: 'Can you explain how to use Vue 3 with TypeScript?',
sender: 'user',
timestamp: new Date('2025-12-17T10:01:00'),
status: 'sent',
},
{
id: 3,
content: 'Vue 3 with TypeScript provides excellent type safety and developer experience. You can use the Composition API with typed refs and reactive objects.',
sender: 'ai',
timestamp: new Date('2025-12-17T10:02:00'),
status: 'sent',
},
]) ])
const inputText = ref('') const inputText = ref('')
const isLoading = ref(false) const isLoading = ref(false)
const messagesContainer = ref<HTMLElement>() const messagesContainer = ref<HTMLElement>()
//
const currentAiMessage = ref<ChatMessage | null>(null)
const isStreaming = ref(false)
const streamController = ref<AbortController | null>(null)
const { arrivedState } = useScroll(messagesContainer, { const { arrivedState } = useScroll(messagesContainer, {
offset: { bottom: 100 }, offset: { bottom: 100 },
}) })
@ -50,7 +34,7 @@ function handleSend(text: string) {
if (!text.trim()) if (!text.trim())
return return
// Add user message //
const userMessage: ChatMessage = { const userMessage: ChatMessage = {
id: Date.now(), id: Date.now(),
content: text, content: text,
@ -60,24 +44,121 @@ function handleSend(text: string) {
} }
messages.value.push(userMessage) messages.value.push(userMessage)
// Clear input // AI
inputText.value = ''
// Simulate AI response after delay
isLoading.value = true
setTimeout(() => {
userMessage.status = 'sent'
const aiMessage: ChatMessage = { const aiMessage: ChatMessage = {
id: Date.now() + 1, id: Date.now() + 1,
content: `I received your message: "${text}". This is a simulated response.`, content: '',
sender: 'ai', sender: 'ai',
timestamp: new Date(), timestamp: new Date(),
status: 'sent', status: 'sending',
} }
messages.value.push(aiMessage) messages.value.push(aiMessage)
currentAiMessage.value = aiMessage
//
inputText.value = ''
//
isLoading.value = true
isStreaming.value = true
// AbortController
const controller = new AbortController()
streamController.value = controller
// API
streamApi(
text,
{
onopen(response) {
console.log('SSE 连接已建立:', response)
},
onmessage(data) {
try {
const parsed = JSON.parse(data) as { text: string }
if (parsed.text) {
//
typewriterEffect(parsed.text)
}
} catch (error) {
console.error('解析 SSE 数据失败:', error)
}
},
onclose() {
console.log('SSE 连接已关闭')
completeMessage()
},
onerror(error) {
console.error('SSE 连接错误:', error)
handleStreamError(error)
}
},
{ signal: controller.signal }
)
}
//
function typewriterEffect(text: string) {
if (!currentAiMessage.value)
return
const duration = 100 //
const fullText = currentAiMessage.value.content + text
function updateChar(index: number) {
if (!currentAiMessage.value)
return
if (index < fullText.length) {
currentAiMessage.value.content = fullText.slice(0, index + 1)
// Vue
const messageIndex = messages.value.findIndex(m => m.id === currentAiMessage.value?.id)
if (messageIndex !== -1) {
messages.value[messageIndex] = { ...currentAiMessage.value }
}
setTimeout(() => updateChar(index + 1), duration)
}
}
updateChar(currentAiMessage.value.content.length)
}
//
function completeMessage() {
if (currentAiMessage.value) {
currentAiMessage.value.status = 'sent'
const messageIndex = messages.value.findIndex(m => m.id === currentAiMessage.value?.id)
if (messageIndex !== -1) {
messages.value[messageIndex] = { ...currentAiMessage.value }
}
}
cleanupStream()
}
//
function handleStreamError(error: Error) {
if (currentAiMessage.value) {
currentAiMessage.value.status = 'error'
currentAiMessage.value.content += ' (连接错误)'
const messageIndex = messages.value.findIndex(m => m.id === currentAiMessage.value?.id)
if (messageIndex !== -1) {
messages.value[messageIndex] = { ...currentAiMessage.value }
}
}
// vant Toast
console.error('AI 响应错误:', error)
cleanupStream()
}
//
function cleanupStream() {
isLoading.value = false isLoading.value = false
}, 1000) isStreaming.value = false
streamController.value = null
currentAiMessage.value = null
} }
function handleKeydown(e: KeyboardEvent) { function handleKeydown(e: KeyboardEvent) {
@ -88,25 +169,11 @@ function handleKeydown(e: KeyboardEvent) {
<template> <template>
<div class="bg-gray-50 flex flex-col h-screen dark:bg-gray-950"> <div class="bg-gray-50 flex flex-col h-screen dark:bg-gray-950">
<!-- Header -->
<van-nav-bar
title="AI Chat"
placeholder safe-area-inset-top fixed
>
<template #right>
<van-icon
:name="isDark ? 'sun-o' : 'moon-o'"
class="text-lg"
@click="toggleDark()"
/>
</template>
</van-nav-bar>
<!-- Messages container --> <!-- Messages container -->
<van-list <van-list
ref="messagesContainer" ref="messagesContainer"
class="p-4 pb-24 pt-16 flex-1" class="p-4 pb-24 flex-1"
:finished="true" :finished="true"
:loading="false" :loading="false"
finished-text="" finished-text=""

View File

@ -30,8 +30,6 @@ declare module 'vue' {
VanImage: typeof import('vant/es')['Image'] VanImage: typeof import('vant/es')['Image']
VanList: typeof import('vant/es')['List'] VanList: typeof import('vant/es')['List']
VanNavBar: typeof import('vant/es')['NavBar'] VanNavBar: typeof import('vant/es')['NavBar']
VanPicker: typeof import('vant/es')['Picker']
VanPopup: typeof import('vant/es')['Popup']
VanSpace: typeof import('vant/es')['Space'] VanSpace: typeof import('vant/es')['Space']
VanStepper: typeof import('vant/es')['Stepper'] VanStepper: typeof import('vant/es')['Stepper']
VanSwitch: typeof import('vant/es')['Switch'] VanSwitch: typeof import('vant/es')['Switch']