diff --git a/CLAUDE.md b/CLAUDE.md index 08cd507..e1089a4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -57,6 +57,7 @@ pnpm generate # 运行生成脚本 - `calculatorTool`: 基本算术运算 - `filelistTool`: 目录文件列表 - `jokeTool`: 随机笑话生成 +- `goodsTool`: 商品信息查询(支持分页查询列表和单个商品详情) ### 配置系统 - **环境变量**: `.env` 文件存储 API 密钥和配置 diff --git a/package.json b/package.json index c877941..580b812 100644 --- a/package.json +++ b/package.json @@ -2,14 +2,16 @@ "name": "myagent", "version": "1.0.0", "main": "index.js", - "type": "module", + "type": "commonjs", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "mastra dev", "build": "mastra build", + "build:vite": "vite build", "generate": "pnpx tsx ./src/scripts/index.ts", "server:dev": "cross-env NODE_ENV=development tsx watch src/server/index.ts", - "server:start": "cross-env NODE_ENV=production node .mastra/output/server/index.js" + "server:vite:dev": "vite", + "server:vite:start": "node dist/index.cjs" }, "keywords": [], "author": "", @@ -19,21 +21,29 @@ "@ai-sdk/deepseek": "^1.0.31", "@ai-sdk/openai": "^2.0.80", "@mastra/core": "^0.24.8", + "axios": "^1.13.2", "cors": "^2.8.5", "express": "^5.1.0", "helmet": "^8.1.0", + "lodash-es": "^4.17.21", "mastra": "^0.18.8", "morgan": "^1.10.0", "zod": "^4.1.13" }, "devDependencies": { - "@types/node": "^25.0.0", - "@types/express": "^5.0.0", "@types/cors": "^2.8.17", - "@types/morgan": "^1.9.9", + "@types/express": "^5.0.0", "@types/helmet": "^4.0.0", + "@types/lodash-es": "^4.17.12", + "@types/morgan": "^1.9.9", + "@types/node": "^25.0.0", + "@vitejs/plugin-react": "^5.1.2", + "@vitejs/plugin-vue": "^6.0.2", "cross-env": "^7.0.3", "tsx": "^4.19.3", - "typescript": "^5.9.3" + "typescript": "^5.9.3", + "vite": "^7.2.7", + "vite-plugin-node": "^7.0.0", + "vite-plugin-svelte": "^3.0.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cca572a..6a8746c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: '@mastra/core': specifier: ^0.24.8 version: 0.24.8(openapi-types@12.1.3)(react@19.2.1)(zod@4.1.13) + axios: + specifier: ^1.13.2 + version: 1.13.2 cors: specifier: ^2.8.5 version: 2.8.5 @@ -26,6 +29,9 @@ importers: helmet: specifier: ^8.1.0 version: 8.1.0 + lodash-es: + specifier: ^4.17.21 + version: 4.17.21 mastra: specifier: ^0.18.8 version: 0.18.8(@mastra/core@0.24.8(openapi-types@12.1.3)(react@19.2.1)(zod@4.1.13))(@opentelemetry/api@1.9.0)(typescript@5.9.3)(zod@4.1.13) @@ -45,12 +51,21 @@ importers: '@types/helmet': specifier: ^4.0.0 version: 4.0.0 + '@types/lodash-es': + specifier: ^4.17.12 + version: 4.17.12 '@types/morgan': specifier: ^1.9.9 version: 1.9.10 '@types/node': specifier: ^25.0.0 version: 25.0.0 + '@vitejs/plugin-react': + specifier: ^5.1.2 + version: 5.1.2(vite@7.2.7(@types/node@25.0.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitejs/plugin-vue': + specifier: ^6.0.2 + version: 6.0.2(vite@7.2.7(@types/node@25.0.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -60,6 +75,15 @@ importers: typescript: specifier: ^5.9.3 version: 5.9.3 + vite: + specifier: ^7.2.7 + version: 7.2.7(@types/node@25.0.0)(tsx@4.21.0)(yaml@2.8.2) + vite-plugin-node: + specifier: ^7.0.0 + version: 7.0.0(vite@7.2.7(@types/node@25.0.0)(tsx@4.21.0)(yaml@2.8.2)) + vite-plugin-svelte: + specifier: ^3.0.1 + version: 3.0.1(rollup@4.50.2)(svelte@3.59.2)(vite@7.2.7(@types/node@25.0.0)(tsx@4.21.0)(yaml@2.8.2)) packages: @@ -284,6 +308,18 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@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'} @@ -1249,6 +1285,12 @@ packages: '@protobufjs/utf8@1.1.0': resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + '@rolldown/pluginutils@1.0.0-beta.50': + resolution: {integrity: sha512-5e76wQiQVeL1ICOZVUg4LSOVYg9jyhGCin+icYozhsUzM+fHE7kddi1bdiE0jwVqTfkjba3jUFbEkoC9WkdvyA==} + + '@rolldown/pluginutils@1.0.0-beta.53': + resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} + '@rollup/plugin-alias@5.1.1': resolution: {integrity: sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==} engines: {node: '>=14.0.0'} @@ -1303,6 +1345,10 @@ packages: rollup: optional: true + '@rollup/pluginutils@4.2.1': + resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} + engines: {node: '>= 8.0.0'} + '@rollup/pluginutils@5.3.0': resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} engines: {node: '>=14.0.0'} @@ -1449,6 +1495,18 @@ packages: '@types/aws-lambda@8.10.152': resolution: {integrity: sha512-soT/c2gYBnT5ygwiHPmd9a1bftj462NWVk2tKCc1PYHSIacB2UwbTS2zYG4jzag1mRDuzg/OjtxQjQ2NKRB6Rw==} + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/body-parser@1.19.6': resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} @@ -1489,6 +1547,12 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.21': + resolution: {integrity: sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==} + '@types/memcached@2.2.10': resolution: {integrity: sha512-AM9smvZN55Gzs2wRrqeMHVP7KE8KWgCJO/XL5yCly2xF6EKa4YlbpK+cLSAH4NG/Ah64HrlegmGqW8kYws7Vxg==} @@ -1541,6 +1605,48 @@ packages: resolution: {integrity: sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw==} engines: {node: '>= 20'} + '@vitejs/plugin-react@5.1.2': + resolution: {integrity: sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + + '@vitejs/plugin-vue@6.0.2': + resolution: {integrity: sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vue: ^3.2.25 + + '@vue/compiler-core@3.5.25': + resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==} + + '@vue/compiler-dom@3.5.25': + resolution: {integrity: sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==} + + '@vue/compiler-sfc@3.5.25': + resolution: {integrity: sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==} + + '@vue/compiler-ssr@3.5.25': + resolution: {integrity: sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==} + + '@vue/reactivity@3.5.25': + resolution: {integrity: sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==} + + '@vue/runtime-core@3.5.25': + resolution: {integrity: sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==} + + '@vue/runtime-dom@3.5.25': + resolution: {integrity: sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==} + + '@vue/server-renderer@3.5.25': + resolution: {integrity: sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==} + peerDependencies: + vue: 3.5.25 + + '@vue/shared@3.5.25': + resolution: {integrity: sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==} + '@webcontainer/env@1.1.1': resolution: {integrity: sha512-6aN99yL695Hi9SuIk1oC88l9o0gmxL1nGWWQ/kNy81HigJ0FoaoTXpytCj6ItzgyCEwA9kF1wixsTuv5cjsgng==} @@ -1659,6 +1765,10 @@ packages: caniuse-lite@1.0.30001760: resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==} + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + chalk@5.6.2: resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} @@ -1740,12 +1850,19 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + date-fns@3.6.0: resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} dateformat@4.6.3: resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + debounce@2.2.0: + resolution: {integrity: sha512-Xks6RUDLZFdz8LIdR6q0MTH44k7FikOmnh5xkSjMig6ch45afc8sjTjRQf3P6ax8dMgcQrYO/AR2RGWURrruqw==} + engines: {node: '>=18'} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -1854,6 +1971,10 @@ packages: end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -1894,6 +2015,9 @@ packages: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} + estree-walker@0.6.1: + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -2054,6 +2178,10 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + has-symbols@1.1.0: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} @@ -2283,6 +2411,9 @@ packages: resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} engines: {node: '>=14'} + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} @@ -2524,6 +2655,10 @@ packages: pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} @@ -2599,6 +2734,10 @@ packages: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + react@19.2.1: resolution: {integrity: sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw==} engines: {node: '>=0.10.0'} @@ -2615,6 +2754,9 @@ packages: resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==} engines: {node: '>=8.6.0'} + require-relative@0.8.7: + resolution: {integrity: sha512-AKGr4qvHiryxRb19m3PsLRGuKVAbJLUD7E6eOaHkfKhwc+vSgVOCY5xNvm9EkolBKTOf0GrQAZKLimOCz81Khg==} + resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} @@ -2648,6 +2790,15 @@ packages: peerDependencies: rollup: ^4.0.0 + rollup-plugin-svelte@6.1.1: + resolution: {integrity: sha512-ijnm0pH1ScrY4uxwaNXBpNVejVzpL2769hIEbAlnqNUWZrffLspu5/k9/l/Wsj3NrEHLQ6wCKGagVJonyfN7ow==} + peerDependencies: + rollup: '>=1.19.2' + svelte: '*' + + rollup-pluginutils@2.8.2: + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + rollup@4.50.2: resolution: {integrity: sha512-BgLRGy7tNS9H66aIMASq1qSYbAAJV6Z6WR4QYTvj5FgF15rZ/ympT1uixHXwzbZUBDbkvqUI1KR0fH1FhMaQ9w==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -2756,6 +2907,14 @@ packages: sonic-boom@4.2.0: resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} @@ -2784,10 +2943,23 @@ packages: resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} engines: {node: '>=14.16'} + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + svelte-hmr@0.11.6: + resolution: {integrity: sha512-XUYcp7W26q/fF8tABZfCYGklwL4TDH48gc1KOjuBQNlTiMW63l/+rRqmfVOE/qKG5vns0J2NPo3zFjdahkwoHA==} + peerDependencies: + svelte: '>=3.19.0' + + svelte@3.59.2: + resolution: {integrity: sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA==} + engines: {node: '>= 8'} + swr@2.3.7: resolution: {integrity: sha512-ZEquQ82QvalqTxhBVv/DlAg2mbmUjF4UgpPg9wwk4ufb9rQnZXh1iKyyKBqV6bQGu1Ie7L1QwSYO07qFIa1p+g==} peerDependencies: @@ -2890,6 +3062,70 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + vite-plugin-node@7.0.0: + resolution: {integrity: sha512-FZqTHvCXUu+U8i6qMtlZCrEvlelUioEf6J4S77XHpZk73frveqKVot60W0hpbffv5OMECXYwP/LAiTGAOLN4/g==} + peerDependencies: + '@swc/core': ^1.7.26 + vite: ^7.0.0 + peerDependenciesMeta: + '@swc/core': + optional: true + + vite-plugin-svelte@3.0.1: + resolution: {integrity: sha512-R4XFM4pmeJ9GwKs5mcDDDQs1e6xvCrBumGLnApPdYarS6+kfDqeC0U1WOLp6LLUx1sUdv7poywnr9eNKenQfkg==} + deprecated: use @sveltejs/vite-plugin-svelte for vite2.0+ support + peerDependencies: + svelte: ^3.0.0 + vite: '>=0.20.8 <2.0.0' + + vite@7.2.7: + resolution: {integrity: sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vue@3.5.25: + resolution: {integrity: sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -3240,6 +3476,16 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@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 @@ -4385,6 +4631,10 @@ snapshots: '@protobufjs/utf8@1.1.0': {} + '@rolldown/pluginutils@1.0.0-beta.50': {} + + '@rolldown/pluginutils@1.0.0-beta.53': {} + '@rollup/plugin-alias@5.1.1(rollup@4.50.2)': optionalDependencies: rollup: 4.50.2 @@ -4428,6 +4678,11 @@ snapshots: optionalDependencies: rollup: 4.50.2 + '@rollup/pluginutils@4.2.1': + dependencies: + estree-walker: 2.0.2 + picomatch: 2.3.1 + '@rollup/pluginutils@5.3.0(rollup@4.50.2)': dependencies: '@types/estree': 1.0.8 @@ -4516,6 +4771,27 @@ snapshots: '@types/aws-lambda@8.10.152': {} + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.28.5 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.28.5 + '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 @@ -4572,6 +4848,12 @@ snapshots: '@types/json-schema@7.0.15': {} + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.21 + + '@types/lodash@4.17.21': {} + '@types/memcached@2.2.10': dependencies: '@types/node': 25.0.0 @@ -4636,6 +4918,78 @@ snapshots: '@vercel/oidc@3.0.5': {} + '@vitejs/plugin-react@5.1.2(vite@7.2.7(@types/node@25.0.0)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) + '@rolldown/pluginutils': 1.0.0-beta.53 + '@types/babel__core': 7.20.5 + react-refresh: 0.18.0 + vite: 7.2.7(@types/node@25.0.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-vue@6.0.2(vite@7.2.7(@types/node@25.0.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))': + dependencies: + '@rolldown/pluginutils': 1.0.0-beta.50 + vite: 7.2.7(@types/node@25.0.0)(tsx@4.21.0)(yaml@2.8.2) + vue: 3.5.25(typescript@5.9.3) + + '@vue/compiler-core@3.5.25': + dependencies: + '@babel/parser': 7.28.5 + '@vue/shared': 3.5.25 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.25': + dependencies: + '@vue/compiler-core': 3.5.25 + '@vue/shared': 3.5.25 + + '@vue/compiler-sfc@3.5.25': + dependencies: + '@babel/parser': 7.28.5 + '@vue/compiler-core': 3.5.25 + '@vue/compiler-dom': 3.5.25 + '@vue/compiler-ssr': 3.5.25 + '@vue/shared': 3.5.25 + estree-walker: 2.0.2 + magic-string: 0.30.21 + postcss: 8.5.6 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.25': + dependencies: + '@vue/compiler-dom': 3.5.25 + '@vue/shared': 3.5.25 + + '@vue/reactivity@3.5.25': + dependencies: + '@vue/shared': 3.5.25 + + '@vue/runtime-core@3.5.25': + dependencies: + '@vue/reactivity': 3.5.25 + '@vue/shared': 3.5.25 + + '@vue/runtime-dom@3.5.25': + dependencies: + '@vue/reactivity': 3.5.25 + '@vue/runtime-core': 3.5.25 + '@vue/shared': 3.5.25 + csstype: 3.2.3 + + '@vue/server-renderer@3.5.25(vue@3.5.25(typescript@5.9.3))': + dependencies: + '@vue/compiler-ssr': 3.5.25 + '@vue/shared': 3.5.25 + vue: 3.5.25(typescript@5.9.3) + + '@vue/shared@3.5.25': {} + '@webcontainer/env@1.1.1': {} accepts@1.3.8: @@ -4773,6 +5127,11 @@ snapshots: caniuse-lite@1.0.30001760: {} + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + chalk@5.6.2: {} cjs-module-lexer@1.4.3: {} @@ -4836,10 +5195,14 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + csstype@3.2.3: {} + date-fns@3.6.0: {} dateformat@4.6.3: {} + debounce@2.2.0: {} + debug@2.6.9: dependencies: ms: 2.0.0 @@ -4905,6 +5268,8 @@ snapshots: dependencies: once: 1.4.0 + entities@4.5.0: {} + es-define-property@1.0.1: {} es-errors@1.3.0: {} @@ -4986,6 +5351,8 @@ snapshots: escape-string-regexp@5.0.0: {} + estree-walker@0.6.1: {} + estree-walker@2.0.2: {} etag@1.8.1: {} @@ -5229,6 +5596,8 @@ snapshots: graceful-fs@4.2.11: {} + has-flag@4.0.0: {} + has-symbols@1.1.0: {} has-tostringtag@1.0.2: @@ -5398,6 +5767,8 @@ snapshots: pkg-types: 2.3.0 quansync: 0.2.11 + lodash-es@4.17.21: {} + lodash.camelcase@4.3.0: {} long@5.3.2: {} @@ -5648,6 +6019,12 @@ snapshots: exsolve: 1.0.8 pathe: 2.0.3 + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + postgres-array@2.0.0: {} postgres-bytea@1.0.0: {} @@ -5727,6 +6104,8 @@ snapshots: iconv-lite: 0.7.0 unpipe: 1.0.0 + react-refresh@0.18.0: {} + react@19.2.1: {} real-require@0.2.0: {} @@ -5741,6 +6120,8 @@ snapshots: transitivePeerDependencies: - supports-color + require-relative@0.8.7: {} + resolve-from@5.0.0: {} resolve-pkg-maps@1.0.0: {} @@ -5770,6 +6151,18 @@ snapshots: dependencies: rollup: 4.50.2 + rollup-plugin-svelte@6.1.1(rollup@4.50.2)(svelte@3.59.2): + dependencies: + require-relative: 0.8.7 + rollup: 4.50.2 + rollup-pluginutils: 2.8.2 + sourcemap-codec: 1.4.8 + svelte: 3.59.2 + + rollup-pluginutils@2.8.2: + dependencies: + estree-walker: 0.6.1 + rollup@4.50.2: dependencies: '@types/estree': 1.0.8 @@ -5947,6 +6340,10 @@ snapshots: dependencies: atomic-sleep: 1.0.0 + source-map-js@1.2.1: {} + + sourcemap-codec@1.4.8: {} + split2@4.2.0: {} statuses@2.0.1: {} @@ -5967,8 +6364,18 @@ snapshots: strip-json-comments@5.0.3: {} + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + supports-preserve-symlinks-flag@1.0.0: {} + svelte-hmr@0.11.6(svelte@3.59.2): + dependencies: + svelte: 3.59.2 + + svelte@3.59.2: {} + swr@2.3.7(react@19.2.1): dependencies: dequal: 2.0.3 @@ -6058,6 +6465,49 @@ snapshots: vary@1.1.2: {} + vite-plugin-node@7.0.0(vite@7.2.7(@types/node@25.0.0)(tsx@4.21.0)(yaml@2.8.2)): + dependencies: + '@rollup/pluginutils': 4.2.1 + chalk: 4.1.2 + debounce: 2.2.0 + debug: 4.4.3 + vite: 7.2.7(@types/node@25.0.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - supports-color + + vite-plugin-svelte@3.0.1(rollup@4.50.2)(svelte@3.59.2)(vite@7.2.7(@types/node@25.0.0)(tsx@4.21.0)(yaml@2.8.2)): + dependencies: + rollup-plugin-svelte: 6.1.1(rollup@4.50.2)(svelte@3.59.2) + svelte: 3.59.2 + svelte-hmr: 0.11.6(svelte@3.59.2) + vite: 7.2.7(@types/node@25.0.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - rollup + + vite@7.2.7(@types/node@25.0.0)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.50.2 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 25.0.0 + fsevents: 2.3.3 + tsx: 4.21.0 + yaml: 2.8.2 + + vue@3.5.25(typescript@5.9.3): + dependencies: + '@vue/compiler-dom': 3.5.25 + '@vue/compiler-sfc': 3.5.25 + '@vue/runtime-dom': 3.5.25 + '@vue/server-renderer': 3.5.25(vue@3.5.25(typescript@5.9.3)) + '@vue/shared': 3.5.25 + optionalDependencies: + typescript: 5.9.3 + webidl-conversions@3.0.1: {} whatwg-url@5.0.0: diff --git a/src/mastra/agents/multi-function-agent.ts b/src/mastra/agents/multi-function-agent.ts index 4abdbbb..0caff46 100644 --- a/src/mastra/agents/multi-function-agent.ts +++ b/src/mastra/agents/multi-function-agent.ts @@ -5,6 +5,7 @@ import { calculatorTool, filelistTool, jokeTool, + goodsTool, } from "../tools"; import { createDeepSeek } from '@ai-sdk/deepseek'; @@ -24,6 +25,7 @@ export const multiFunctionAgent = new Agent({ 3. **计算器**:执行基本算术运算(加、减、乘、除)。 4. **文件列表**:列出目录中的文件(默认当前目录)。 5. **笑话**:讲随机笑话调节气氛。 +6. **商品查询**:使用商品工具查询商品信息,支持分页查询商品列表或根据商品ID获取单个商品详情。 请始终礼貌、乐于助人。如果用户询问超出你能力范围的事情,请礼貌解释你能做什么。 @@ -38,5 +40,6 @@ export const multiFunctionAgent = new Agent({ calculatorTool, filelistTool, jokeTool, + goodsTool, }, }); \ No newline at end of file diff --git a/src/mastra/api/axios.ts b/src/mastra/api/axios.ts new file mode 100644 index 0000000..3f6ffd4 --- /dev/null +++ b/src/mastra/api/axios.ts @@ -0,0 +1,117 @@ +import type { AxiosInstance, AxiosRequestConfig } from "axios" +import axios from "axios" +import { get, merge } from "lodash-es" + +const BASE_URL = 'http://wxshop.ab98.cn/shop-api/api' + +/** 创建请求实例 */ +function createInstance() { + // 创建一个 axios 实例命名为 instance + const instance = axios.create() + // 请求拦截器 + instance.interceptors.request.use( + // 发送之前 + config => config, + // 发送失败 + error => Promise.reject(error) + ) + // 响应拦截器(可根据具体业务作出相应的调整) + instance.interceptors.response.use( + (response) => { + // apiData 是 api 返回的数据 + const apiData = response.data + // 二进制数据则直接返回 + const responseType = response.request?.responseType + if (responseType === "blob" || responseType === "arraybuffer") return apiData + // 这个 code 是和后端约定的业务 code + const code = apiData.code + // 如果没有 code, 代表这不是项目后端开发的 api + if (code === undefined) { + return Promise.reject(new Error("非本系统的接口")) + } + switch (code) { + case 0: + // 本系统采用 code === 0 来表示没有业务错误 + return apiData + default: + // 不是正确的 code + return Promise.reject(new Error(apiData.msg || apiData.message || "Error")) + } + }, + (error) => { + // status 是 HTTP 状态码 + const status = get(error, "response.status") + const message = get(error, "response.data.message") + switch (status) { + case 400: + error.message = "请求错误" + break + case 401: + // 登录过期 + error.message = message || "登录过期" + break + case 403: + error.message = message || "拒绝访问" + break + case 404: + error.message = "请求地址出错" + break + case 408: + error.message = "请求超时" + break + case 500: + error.message = "服务器内部错误" + break + case 501: + error.message = "服务未实现" + break + case 502: + error.message = "网关错误" + break + case 503: + error.message = "服务不可用" + break + case 504: + error.message = "网关超时" + break + case 505: + error.message = "HTTP 版本不受支持" + break + } + return Promise.reject(error) + } + ) + return instance +} + +/** 创建请求方法 */ +function createRequest(instance: AxiosInstance) { + return (config: AxiosRequestConfig): Promise => { + // 默认配置 + const defaultConfig: AxiosRequestConfig = { + // 接口地址 + baseURL: BASE_URL, + // 请求头 + headers: { + // 携带 Token + // "Authorization": token ? `Bearer ${token}` : undefined, + "Content-Type": "application/json" + }, + // 请求体 + data: {}, + // 请求超时 + timeout: 10000, + // 跨域请求时是否携带 Cookies + withCredentials: false + } + // 将默认配置 defaultConfig 和传入的自定义配置 config 进行合并成为 mergeConfig + const mergeConfig = merge(defaultConfig, config) + return instance(mergeConfig) + } +} + +/** 用于请求的实例 */ +const instance = createInstance() + +/** 用于请求的方法 */ +export const request = createRequest(instance) diff --git a/src/mastra/api/manage/goods.ts b/src/mastra/api/manage/goods.ts new file mode 100644 index 0000000..f96e8b9 --- /dev/null +++ b/src/mastra/api/manage/goods.ts @@ -0,0 +1,71 @@ +import { request } from "../axios" +import { PageDTO, ResponseData, BasePageQuery } from "../type" + +export interface ShopGoodsDTO { + goodsId?: number // 商品唯一ID + goodsName?: string // 商品名称 + categoryId?: number // 分类ID + externalGoodsId?: number // 外部归属类型的商品ID + corpid?: string // 企业微信id + categoryName?: string // 分类名称 + belongType?: number // 归属类型(0-借还柜 1-固资通) + price?: number // 销售价格 + stock?: number // 库存数量 + status?: number // 商品状态(1上架 2下架) + autoApproval?: number // 免审批(0否 1是) + coverImg?: string // 封面图URL + creatorId?: number // 创建者ID + creatorName?: string // 创建者名称 + createTime?: string // 创建时间 + remark?: string // 备注 + cabinetName?: string // 柜机名称 + cellNo?: number // 格口号 + cellNoStr?: string // 格口号(字符串格式) + totalStock?: number // 已分配库存 + shopNameStr?: string // 地址名称 + usageInstruction?: string // 商品使用说明 + monthlyPurchaseLimit?: number // 每人每月限购数量 + goodsDetail?: string // 商品详情(支持2000汉字+10个图片链接) +} + +export interface SearchShopGoodsQuery extends BasePageQuery { + goodsName?: string // 商品名称(模糊查询) + categoryId?: number // 商品分类ID + externalGoodsId?: number // 外部归属类型的商品ID + corpid?: string // 企业微信id + status?: number // 商品状态(1上架 2下架) + autoApproval?: number // 免审批(0否 1是) + minPrice?: number // 最低价格 + maxPrice?: number // 最高价格 + belongType?: number // 归属类型(0-借还柜 1-固资通) + beginTime?: string // 开始时间(格式:yyyy-MM-dd) + endTime?: string // 结束时间(格式:yyyy-MM-dd) +} + +/** + * 获取商品列表 + * 分页查询商品列表,支持多条件筛选和排序 + * @param query 查询参数(包含分页、筛选条件等) + * @returns Promise>> + */ +export function getGoodsList(query: SearchShopGoodsQuery) { + return request>>({ + url: "manage/goods/list", + method: "get", + params: query + }) +} + +/** + * 获取单个商品信息 + * 根据商品ID获取商品的详细信息 + * @param goodsId 商品ID(查询参数) + * @returns Promise> + */ +export function getGoodsInfo(goodsId: number) { + return request>({ + url: "manage/goods/getGoodsInfo", + method: "get", + params: { goodsId } + }) +} \ No newline at end of file diff --git a/src/mastra/api/type.ts b/src/mastra/api/type.ts new file mode 100644 index 0000000..cde7738 --- /dev/null +++ b/src/mastra/api/type.ts @@ -0,0 +1,24 @@ + +export type ResponseData = { + code: number; + msg: string; + data: T; +}; + +export type PageDTO = { + total: number; + rows: Array; +}; + +export interface BasePageQuery extends BaseQuery { + pageNum?: number; + pageSize?: number; +} + +export interface BaseQuery { + beginTime?: string; + endTime?: string; + orderColumn?: string; + orderDirection?: string; + timeRangeColumn?: string; +} \ No newline at end of file diff --git a/src/mastra/index.ts b/src/mastra/index.ts index 0905883..3d2ae42 100644 --- a/src/mastra/index.ts +++ b/src/mastra/index.ts @@ -3,4 +3,7 @@ import { multiFunctionAgent } from "./agents"; export const mastra = new Mastra({ agents: { multiFunctionAgent }, + bundler: { + externals: ["supports-color"], + }, }); \ No newline at end of file diff --git a/src/mastra/tools/goods-tool.ts b/src/mastra/tools/goods-tool.ts new file mode 100644 index 0000000..b16f9db --- /dev/null +++ b/src/mastra/tools/goods-tool.ts @@ -0,0 +1,107 @@ +import { createTool } from "@mastra/core/tools"; +import { z } from "zod"; +import { getGoodsList, getGoodsInfo, ShopGoodsDTO, SearchShopGoodsQuery } from "../api/manage/goods"; + +export const goodsTool = createTool({ + id: "goods", + description: "查询商品信息,支持分页查询商品列表或根据商品ID获取单个商品详情", + + inputSchema: z.object({ + queryType: z.enum(["list", "single"]).describe("查询类型:'list'表示分页查询商品列表,'single'表示根据商品ID查询单个商品"), + goodsId: z.number().optional().describe("商品ID(当queryType为'single'时必填)"), + goodsName: z.string().optional().describe("商品名称(模糊查询)"), + categoryId: z.number().optional().describe("商品分类ID"), + status: z.number().optional().describe("商品状态(1上架 2下架)"), + autoApproval: z.number().optional().describe("免审批(0否 1是)"), + minPrice: z.number().optional().describe("最低价格"), + maxPrice: z.number().optional().describe("最高价格"), + belongType: z.number().optional().describe("归属类型(0-借还柜 1-固资通)"), + beginTime: z.string().optional().describe("开始时间(格式:yyyy-MM-dd)"), + endTime: z.string().optional().describe("结束时间(格式:yyyy-MM-dd)"), + pageNum: z.number().optional().describe("页码,默认1"), + pageSize: z.number().optional().describe("每页大小,默认10"), + orderColumn: z.string().optional().describe("排序字段"), + orderDirection: z.string().optional().describe("排序方向(asc或desc)"), + }), + + outputSchema: z.object({ + success: z.boolean(), + message: z.string(), + data: z.any().optional(), + total: z.number().optional(), + pageNum: z.number().optional(), + pageSize: z.number().optional(), + }), + + execute: async ({ context }) => { + try { + const { + queryType, + goodsId, + goodsName, + categoryId, + status, + autoApproval, + minPrice, + maxPrice, + belongType, + beginTime, + endTime, + pageNum = 1, + pageSize = 10, + orderColumn, + orderDirection, + } = context; + + if (queryType === "single") { + if (!goodsId) { + return { + success: false, + message: "查询单个商品时,goodsId参数为必填", + }; + } + + const response = await getGoodsInfo(goodsId); + + return { + success: response.code === 0, + message: response.msg || "查询成功", + data: response.data, + }; + } else { + // 列表查询 + const query: SearchShopGoodsQuery = { + goodsName, + categoryId, + status, + autoApproval, + minPrice, + maxPrice, + belongType, + beginTime, + endTime, + pageNum, + pageSize, + orderColumn, + orderDirection, + }; + + const response = await getGoodsList(query); + + return { + success: response.code === 0, + message: response.msg || "查询成功", + data: response.data?.rows || [], + total: response.data?.total || 0, + pageNum, + pageSize, + }; + } + } catch (error: any) { + return { + success: false, + message: `查询失败: ${error.message || "未知错误"}`, + }; + } + }, +}); \ No newline at end of file diff --git a/src/mastra/tools/index.ts b/src/mastra/tools/index.ts index 7204660..6168897 100644 --- a/src/mastra/tools/index.ts +++ b/src/mastra/tools/index.ts @@ -2,4 +2,5 @@ export { weatherTool } from "./weather-tool"; export { timeTool } from "./time-tool"; export { calculatorTool } from "./calculator-tool"; export { filelistTool } from "./filelist-tool"; -export { jokeTool } from "./joke-tool"; \ No newline at end of file +export { jokeTool } from "./joke-tool"; +export { goodsTool } from "./goods-tool"; \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..f295a40 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,79 @@ +import { defineConfig } from 'vite'; +import { VitePluginNode } from 'vite-plugin-node'; + +export default defineConfig({ + root: '.', // 设置根目录 + server: { + port: 3000, + }, + build: { + outDir: 'dist', + rollupOptions: { + input: 'src/server/index.ts', + output: { + // 入口文件命名 + entryFileNames: '[name].js', + // chunk 文件命名 + chunkFileNames: 'chunks/[name]-[hash].js', + // 资源文件命名 + assetFileNames: 'assets/[name]-[hash].[ext]', + // 手动分块策略 + manualChunks(id) { + // 将 node_modules 中的依赖打包到单独的 chunk + if (id.includes('node_modules')) { + // 获取包名 + const match = id.match(/node_modules\/(@[^\/]+\/[^\/]+|[^\/]+)/); + if (match) { + const packageName = match[1]; + // 排除外部依赖(已经在 external 中配置的) + const externalPackages = [ + 'express', + 'cors', + 'helmet', + 'morgan', + '@mastra/core', + 'axios', + 'lodash-es', + 'zod', + '@ai-sdk/deepseek', + '@ai-sdk/openai', + 'mastra' + ]; + if (!externalPackages.some(pkg => packageName.startsWith(pkg))) { + return `vendor-${packageName.replace('@', '').replace('/', '-')}`; + } + } + // 其他 node_modules 依赖打包到 vendor 中 + return 'vendor'; + } + // 业务代码根据目录结构分块 + if (id.includes('src/mastra/')) { + return 'mastra'; + } + if (id.includes('src/server/')) { + return 'server'; + } + } + }, + // 排除外部依赖,让 Node 运行时加载 + external: [ + 'express', + 'cors', + 'helmet', + 'morgan', + '@mastra/core', + 'axios', + 'lodash-es', + 'zod', + '@ai-sdk/deepseek', + '@ai-sdk/openai', + 'mastra' + ] + }, + }, + plugins: VitePluginNode({ + adapter: 'express', + appPath: './src/server/index.ts', + exportName: 'default', + }), +});