update
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| node_modules | ||||
| .env | ||||
|  | ||||
| !.env*.example | ||||
							
								
								
									
										22
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| { | ||||
|   "name": "test-router-ai", | ||||
|   "version": "0.0.1", | ||||
|   "description": "", | ||||
|   "main": "index.js", | ||||
|   "scripts": { | ||||
|     "test": "echo \"Error: no test specified\" && exit 1" | ||||
|   }, | ||||
|   "keywords": [], | ||||
|   "author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)", | ||||
|   "license": "MIT", | ||||
|   "packageManager": "pnpm@10.14.0", | ||||
|   "type": "module", | ||||
|   "dependencies": { | ||||
|     "@kevisual/ai": "^0.0.9", | ||||
|     "@kevisual/router": "^0.0.30", | ||||
|     "@kevisual/use-config": "^1.0.19" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@types/node": "^24.9.1" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										249
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,249 @@ | ||||
| lockfileVersion: '9.0' | ||||
|  | ||||
| settings: | ||||
|   autoInstallPeers: true | ||||
|   excludeLinksFromLockfile: false | ||||
|  | ||||
| importers: | ||||
|  | ||||
|   .: | ||||
|     dependencies: | ||||
|       '@kevisual/ai': | ||||
|         specifier: ^0.0.9 | ||||
|         version: 0.0.9 | ||||
|       '@kevisual/router': | ||||
|         specifier: ^0.0.30 | ||||
|         version: 0.0.30 | ||||
|       '@kevisual/use-config': | ||||
|         specifier: ^1.0.19 | ||||
|         version: 1.0.19(dotenv@16.6.1) | ||||
|     devDependencies: | ||||
|       '@types/node': | ||||
|         specifier: ^24.9.1 | ||||
|         version: 24.9.1 | ||||
|  | ||||
| packages: | ||||
|  | ||||
|   '@kevisual/ai@0.0.9': | ||||
|     resolution: {integrity: sha512-pBe6pjN3pm3zF1CmxR4uQnhxLteGuCiT3JaKOd3pasB5OfEYFJ6qu6RfE+4upnyKiEtAAlYwXMMNR+8S3Jzf5g==} | ||||
|  | ||||
|   '@kevisual/load@0.0.6': | ||||
|     resolution: {integrity: sha512-+3YTFehRcZ1haGel5DKYMUwmi5i6f2psyaPZlfkKU/cOXgkpwoG9/BEqPCnPjicKqqnksEpixVRkyHJ+5bjLVA==} | ||||
|  | ||||
|   '@kevisual/logger@0.0.4': | ||||
|     resolution: {integrity: sha512-+fpr92eokSxoGOW1SIRl/27lPuO+zyY+feR5o2Q4YCNlAdt2x64NwC/w8r/3NEC5QenLgd4K0azyKTI2mHbARw==} | ||||
|  | ||||
|   '@kevisual/router@0.0.30': | ||||
|     resolution: {integrity: sha512-/mBo7aZFWjT4QfHkI5HPXfdgSwZzt3mAVei7dcNSBTPe9KQSoYKZ8BTq9VTUj3XE0sI6o1bZjlLYvinpVnZilw==} | ||||
|  | ||||
|   '@kevisual/use-config@1.0.19': | ||||
|     resolution: {integrity: sha512-Q1IH4eMqUe5w6Bq8etoqOSls9FPIy0xwwD3wHf26EsQLZadhccI9qkDuFzP/rFWDa57mwFPEfwbGE5UlqWOCkw==} | ||||
|     peerDependencies: | ||||
|       dotenv: ^16.4.7 | ||||
|  | ||||
|   '@types/node@24.9.1': | ||||
|     resolution: {integrity: sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==} | ||||
|  | ||||
|   debug@4.4.3: | ||||
|     resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} | ||||
|     engines: {node: '>=6.0'} | ||||
|     peerDependencies: | ||||
|       supports-color: '*' | ||||
|     peerDependenciesMeta: | ||||
|       supports-color: | ||||
|         optional: true | ||||
|  | ||||
|   depd@2.0.0: | ||||
|     resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} | ||||
|     engines: {node: '>= 0.8'} | ||||
|  | ||||
|   dotenv@16.6.1: | ||||
|     resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} | ||||
|     engines: {node: '>=12'} | ||||
|  | ||||
|   ee-first@1.1.1: | ||||
|     resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} | ||||
|  | ||||
|   encodeurl@2.0.0: | ||||
|     resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} | ||||
|     engines: {node: '>= 0.8'} | ||||
|  | ||||
|   escape-html@1.0.3: | ||||
|     resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} | ||||
|  | ||||
|   etag@1.8.1: | ||||
|     resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} | ||||
|     engines: {node: '>= 0.6'} | ||||
|  | ||||
|   eventemitter3@5.0.1: | ||||
|     resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} | ||||
|  | ||||
|   fresh@2.0.0: | ||||
|     resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} | ||||
|     engines: {node: '>= 0.8'} | ||||
|  | ||||
|   http-errors@2.0.0: | ||||
|     resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} | ||||
|     engines: {node: '>= 0.8'} | ||||
|  | ||||
|   inherits@2.0.4: | ||||
|     resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} | ||||
|  | ||||
|   mime-db@1.54.0: | ||||
|     resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} | ||||
|     engines: {node: '>= 0.6'} | ||||
|  | ||||
|   mime-types@3.0.1: | ||||
|     resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} | ||||
|     engines: {node: '>= 0.6'} | ||||
|  | ||||
|   ms@2.1.3: | ||||
|     resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} | ||||
|  | ||||
|   node-forge@1.3.1: | ||||
|     resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} | ||||
|     engines: {node: '>= 6.13.0'} | ||||
|  | ||||
|   on-finished@2.4.1: | ||||
|     resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} | ||||
|     engines: {node: '>= 0.8'} | ||||
|  | ||||
|   path-to-regexp@8.3.0: | ||||
|     resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} | ||||
|  | ||||
|   range-parser@1.2.1: | ||||
|     resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} | ||||
|     engines: {node: '>= 0.6'} | ||||
|  | ||||
|   selfsigned@3.0.1: | ||||
|     resolution: {integrity: sha512-6U6w6kSLrM9Zxo0D7mC7QdGS6ZZytMWBnj/vhF9p+dAHx6CwGezuRcO4VclTbrrI7mg7SD6zNiqXUuBHOVopNQ==} | ||||
|     engines: {node: '>=10'} | ||||
|  | ||||
|   send@1.2.0: | ||||
|     resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} | ||||
|     engines: {node: '>= 18'} | ||||
|  | ||||
|   setprototypeof@1.2.0: | ||||
|     resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} | ||||
|  | ||||
|   statuses@2.0.1: | ||||
|     resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} | ||||
|     engines: {node: '>= 0.8'} | ||||
|  | ||||
|   statuses@2.0.2: | ||||
|     resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} | ||||
|     engines: {node: '>= 0.8'} | ||||
|  | ||||
|   toidentifier@1.0.1: | ||||
|     resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} | ||||
|     engines: {node: '>=0.6'} | ||||
|  | ||||
|   undici-types@7.16.0: | ||||
|     resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} | ||||
|  | ||||
| snapshots: | ||||
|  | ||||
|   '@kevisual/ai@0.0.9': | ||||
|     dependencies: | ||||
|       '@kevisual/logger': 0.0.4 | ||||
|  | ||||
|   '@kevisual/load@0.0.6': | ||||
|     dependencies: | ||||
|       eventemitter3: 5.0.1 | ||||
|  | ||||
|   '@kevisual/logger@0.0.4': {} | ||||
|  | ||||
|   '@kevisual/router@0.0.30': | ||||
|     dependencies: | ||||
|       path-to-regexp: 8.3.0 | ||||
|       selfsigned: 3.0.1 | ||||
|       send: 1.2.0 | ||||
|     transitivePeerDependencies: | ||||
|       - supports-color | ||||
|  | ||||
|   '@kevisual/use-config@1.0.19(dotenv@16.6.1)': | ||||
|     dependencies: | ||||
|       '@kevisual/load': 0.0.6 | ||||
|       dotenv: 16.6.1 | ||||
|  | ||||
|   '@types/node@24.9.1': | ||||
|     dependencies: | ||||
|       undici-types: 7.16.0 | ||||
|  | ||||
|   debug@4.4.3: | ||||
|     dependencies: | ||||
|       ms: 2.1.3 | ||||
|  | ||||
|   depd@2.0.0: {} | ||||
|  | ||||
|   dotenv@16.6.1: {} | ||||
|  | ||||
|   ee-first@1.1.1: {} | ||||
|  | ||||
|   encodeurl@2.0.0: {} | ||||
|  | ||||
|   escape-html@1.0.3: {} | ||||
|  | ||||
|   etag@1.8.1: {} | ||||
|  | ||||
|   eventemitter3@5.0.1: {} | ||||
|  | ||||
|   fresh@2.0.0: {} | ||||
|  | ||||
|   http-errors@2.0.0: | ||||
|     dependencies: | ||||
|       depd: 2.0.0 | ||||
|       inherits: 2.0.4 | ||||
|       setprototypeof: 1.2.0 | ||||
|       statuses: 2.0.1 | ||||
|       toidentifier: 1.0.1 | ||||
|  | ||||
|   inherits@2.0.4: {} | ||||
|  | ||||
|   mime-db@1.54.0: {} | ||||
|  | ||||
|   mime-types@3.0.1: | ||||
|     dependencies: | ||||
|       mime-db: 1.54.0 | ||||
|  | ||||
|   ms@2.1.3: {} | ||||
|  | ||||
|   node-forge@1.3.1: {} | ||||
|  | ||||
|   on-finished@2.4.1: | ||||
|     dependencies: | ||||
|       ee-first: 1.1.1 | ||||
|  | ||||
|   path-to-regexp@8.3.0: {} | ||||
|  | ||||
|   range-parser@1.2.1: {} | ||||
|  | ||||
|   selfsigned@3.0.1: | ||||
|     dependencies: | ||||
|       node-forge: 1.3.1 | ||||
|  | ||||
|   send@1.2.0: | ||||
|     dependencies: | ||||
|       debug: 4.4.3 | ||||
|       encodeurl: 2.0.0 | ||||
|       escape-html: 1.0.3 | ||||
|       etag: 1.8.1 | ||||
|       fresh: 2.0.0 | ||||
|       http-errors: 2.0.0 | ||||
|       mime-types: 3.0.1 | ||||
|       ms: 2.1.3 | ||||
|       on-finished: 2.4.1 | ||||
|       range-parser: 1.2.1 | ||||
|       statuses: 2.0.2 | ||||
|     transitivePeerDependencies: | ||||
|       - supports-color | ||||
|  | ||||
|   setprototypeof@1.2.0: {} | ||||
|  | ||||
|   statuses@2.0.1: {} | ||||
|  | ||||
|   statuses@2.0.2: {} | ||||
|  | ||||
|   toidentifier@1.0.1: {} | ||||
|  | ||||
|   undici-types@7.16.0: {} | ||||
							
								
								
									
										3
									
								
								src/config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/config.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| import { useConfig } from '@kevisual/use-config' | ||||
|  | ||||
| export const config = useConfig(); | ||||
							
								
								
									
										69
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| import { BailianProvider } from '@kevisual/ai' | ||||
| import { config } from './config.ts'; | ||||
| import { App } from '@kevisual/router' | ||||
| import util from 'node:util'; | ||||
| const ai = new BailianProvider({ | ||||
|   apiKey: config.BAILIAN_API_KEY || '', | ||||
|   model: 'qwen-turbo-latest', | ||||
|   baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1' | ||||
| }) | ||||
|  | ||||
| // ai.getUsageInfo().then(console.log).catch(console.error); | ||||
|  | ||||
| const app = new App() | ||||
|  | ||||
| app.route({ | ||||
|   path: 'weather', | ||||
|   description: '获取天气的工具。 参数 city: 城市名称, 如果不传则获取当前定位城市的天气' | ||||
| }).define(async (ctx) => { | ||||
|   ctx.body = 'Hello World' | ||||
| }).addTo(app); | ||||
|  | ||||
| app.route({ | ||||
|   path: 'address', | ||||
|   description: '获取当前我的城市地址的工具' | ||||
| }).define(async (ctx) => { | ||||
|   ctx.body = 'Hello World Address' | ||||
| }).addTo(app); | ||||
|  | ||||
| app.route({ | ||||
|   path: 'news', | ||||
|   description: '获取新闻的工具' | ||||
| }).define(async (ctx) => { | ||||
|   ctx.body = 'Hello World News' | ||||
| }).addTo(app); | ||||
|  | ||||
|  | ||||
| const routes = app.router.getList() | ||||
| console.log('Routes:', routes); | ||||
|  | ||||
| const callPrompts = `你是一个拥有以下工具的助手:\n\n${routes.map(r => `工具名称: ${r.path}\n描述: ${r.description}\n`).join('\n')}\n\n当用户询问时,如果拥有工具,请返回 JSON 数据,数据的值的内容是 path description。如果有参数,在 payload 当中。其中如果需要调用多个工具,请将它们放在一个数组中。` | ||||
| const res = await ai.chat([ | ||||
|   { | ||||
|     role: 'system', | ||||
|     content: callPrompts | ||||
|   }, | ||||
|   { | ||||
|     role: 'user', | ||||
|     content: `我想要获取天气` | ||||
|   }, | ||||
|   // { role: 'assistant', content: '请告诉我您想查询哪个城市的天气?' }, | ||||
|   // { | ||||
|   //   role: 'user', | ||||
|   //   content: `北京` | ||||
|   // } | ||||
| ], | ||||
| ) | ||||
| console.log('AI Response:', res); | ||||
| const content = res.choices[0].message?.content || '' | ||||
|  | ||||
| console.log(util.inspect(res, { depth: null })) | ||||
|  | ||||
| // const json = JSON.parse(content) | ||||
| // console.log('Parsed JSON:', json); | ||||
|  | ||||
| // const callApp = await app.call({ | ||||
| //   path: json.path, | ||||
| // }) | ||||
|  | ||||
| // console.log('Call App Response:', callApp.body); | ||||
		Reference in New Issue
	
	Block a user