huangzhichao 1 місяць тому
батько
коміт
29457c5f50

+ 4 - 0
package.json

@@ -20,9 +20,13 @@
     "test:e2e": "jest --config ./test/jest-e2e.json"
   },
   "dependencies": {
+    "@nestjs/axios": "^4.0.0",
     "@nestjs/common": "^10.0.0",
     "@nestjs/core": "^10.0.0",
     "@nestjs/platform-express": "^10.0.0",
+    "axios": "^1.8.4",
+    "class-transformer": "^0.5.1",
+    "class-validator": "^0.14.1",
     "reflect-metadata": "^0.2.0",
     "rxjs": "^7.8.1",
     "tencentcloud-sdk-nodejs": "^4.1.2"

+ 100 - 15
pnpm-lock.yaml

@@ -8,15 +8,27 @@ importers:
 
   .:
     dependencies:
+      '@nestjs/axios':
+        specifier: ^4.0.0
+        version: 4.0.0(@nestjs/common@10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.8.4)(rxjs@7.8.2)
       '@nestjs/common':
         specifier: ^10.0.0
-        version: 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2)
+        version: 10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)
       '@nestjs/core':
         specifier: ^10.0.0
-        version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.2)
+        version: 10.4.15(@nestjs/common@10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.2)
       '@nestjs/platform-express':
         specifier: ^10.0.0
-        version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.15)
+        version: 10.4.15(@nestjs/common@10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.15)
+      axios:
+        specifier: ^1.8.4
+        version: 1.8.4
+      class-transformer:
+        specifier: ^0.5.1
+        version: 0.5.1
+      class-validator:
+        specifier: ^0.14.1
+        version: 0.14.1
       reflect-metadata:
         specifier: ^0.2.0
         version: 0.2.2
@@ -35,7 +47,7 @@ importers:
         version: 10.2.3(chokidar@3.6.0)(typescript@5.8.2)
       '@nestjs/testing':
         specifier: ^10.0.0
-        version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.15))
+        version: 10.4.15(@nestjs/common@10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.15)(@nestjs/platform-express@10.4.15)
       '@types/express':
         specifier: ^4.17.17
         version: 4.17.21
@@ -434,6 +446,13 @@ packages:
     resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==}
     engines: {node: '>=8'}
 
+  '@nestjs/axios@4.0.0':
+    resolution: {integrity: sha512-1cB+Jyltu/uUPNQrpUimRHEQHrnQrpLzVj6dU3dgn6iDDDdahr10TgHFGTmw5VuJ9GzKZsCLDL78VSwJAs/9JQ==}
+    peerDependencies:
+      '@nestjs/common': ^10.0.0 || ^11.0.0
+      axios: ^1.3.1
+      rxjs: ^7.0.0
+
   '@nestjs/cli@10.4.9':
     resolution: {integrity: sha512-s8qYd97bggqeK7Op3iD49X2MpFtW4LVNLAwXFkfbRxKME6IYT7X0muNTJ2+QfI8hpbNx9isWkrLWIp+g5FOhiA==}
     engines: {node: '>= 16.14'}
@@ -643,6 +662,9 @@ packages:
   '@types/supertest@6.0.2':
     resolution: {integrity: sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==}
 
+  '@types/validator@13.15.0':
+    resolution: {integrity: sha512-nh7nrWhLr6CBq9ldtw0wx+z9wKnnv/uTVLA9g/3/TcOYxbpOSZE+MhKPmWqU+K0NvThjhv12uD8MuqijB0WzEA==}
+
   '@types/yargs-parser@21.0.3':
     resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==}
 
@@ -905,6 +927,9 @@ packages:
     resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
     engines: {node: '>= 0.4'}
 
+  axios@1.8.4:
+    resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==}
+
   babel-jest@29.7.0:
     resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==}
     engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -1043,6 +1068,12 @@ packages:
   cjs-module-lexer@1.4.3:
     resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==}
 
+  class-transformer@0.5.1:
+    resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==}
+
+  class-validator@0.14.1:
+    resolution: {integrity: sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==}
+
   cli-cursor@3.1.0:
     resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
     engines: {node: '>=8'}
@@ -1557,6 +1588,15 @@ packages:
   flatted@3.3.3:
     resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
 
+  follow-redirects@1.15.9:
+    resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
+    engines: {node: '>=4.0'}
+    peerDependencies:
+      debug: '*'
+    peerDependenciesMeta:
+      debug:
+        optional: true
+
   for-each@0.3.5:
     resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
     engines: {node: '>= 0.4'}
@@ -2158,6 +2198,9 @@ packages:
     resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
     engines: {node: '>= 0.8.0'}
 
+  libphonenumber-js@1.12.6:
+    resolution: {integrity: sha512-PJiS4ETaUfCOFLpmtKzAbqZQjCCKVu2OhTV4SVNNE7c2nu/dACvtCqj4L0i/KWNnIgRv7yrILvBj5Lonv5Ncxw==}
+
   lines-and-columns@1.2.4:
     resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
 
@@ -2514,6 +2557,9 @@ packages:
     resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
     engines: {node: '>= 0.10'}
 
+  proxy-from-env@1.1.0:
+    resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+
   punycode@2.3.1:
     resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
     engines: {node: '>=6'}
@@ -3069,6 +3115,10 @@ packages:
     resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==}
     engines: {node: '>=10.12.0'}
 
+  validator@13.15.0:
+    resolution: {integrity: sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA==}
+    engines: {node: '>= 0.10'}
+
   vary@1.1.2:
     resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
     engines: {node: '>= 0.8'}
@@ -3660,6 +3710,12 @@ snapshots:
 
   '@lukeed/csprng@1.1.0': {}
 
+  '@nestjs/axios@4.0.0(@nestjs/common@10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.8.4)(rxjs@7.8.2)':
+    dependencies:
+      '@nestjs/common': 10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)
+      axios: 1.8.4
+      rxjs: 7.8.2
+
   '@nestjs/cli@10.4.9':
     dependencies:
       '@angular-devkit/core': 17.3.11(chokidar@3.6.0)
@@ -3686,17 +3742,20 @@ snapshots:
       - uglify-js
       - webpack-cli
 
-  '@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2)':
+  '@nestjs/common@10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)':
     dependencies:
       iterare: 1.2.1
       reflect-metadata: 0.2.2
       rxjs: 7.8.2
       tslib: 2.8.1
       uid: 2.0.2
+    optionalDependencies:
+      class-transformer: 0.5.1
+      class-validator: 0.14.1
 
-  '@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.2)':
+  '@nestjs/core@10.4.15(@nestjs/common@10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.2)':
     dependencies:
-      '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2)
+      '@nestjs/common': 10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)
       '@nuxtjs/opencollective': 0.3.2
       fast-safe-stringify: 2.1.1
       iterare: 1.2.1
@@ -3706,14 +3765,14 @@ snapshots:
       tslib: 2.8.1
       uid: 2.0.2
     optionalDependencies:
-      '@nestjs/platform-express': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.15)
+      '@nestjs/platform-express': 10.4.15(@nestjs/common@10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.15)
     transitivePeerDependencies:
       - encoding
 
-  '@nestjs/platform-express@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.15)':
+  '@nestjs/platform-express@10.4.15(@nestjs/common@10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.15)':
     dependencies:
-      '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2)
-      '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.2)
+      '@nestjs/common': 10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)
+      '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.2)
       body-parser: 1.20.3
       cors: 2.8.5
       express: 4.21.2
@@ -3744,13 +3803,13 @@ snapshots:
     transitivePeerDependencies:
       - chokidar
 
-  '@nestjs/testing@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.15))':
+  '@nestjs/testing@10.4.15(@nestjs/common@10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.15)(@nestjs/platform-express@10.4.15)':
     dependencies:
-      '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2)
-      '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.2)
+      '@nestjs/common': 10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)
+      '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.2)
       tslib: 2.8.1
     optionalDependencies:
-      '@nestjs/platform-express': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.15)
+      '@nestjs/platform-express': 10.4.15(@nestjs/common@10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.15)
 
   '@nodelib/fs.scandir@2.1.5':
     dependencies:
@@ -3919,6 +3978,8 @@ snapshots:
       '@types/methods': 1.1.4
       '@types/superagent': 8.1.9
 
+  '@types/validator@13.15.0': {}
+
   '@types/yargs-parser@21.0.3': {}
 
   '@types/yargs@17.0.33':
@@ -4251,6 +4312,14 @@ snapshots:
     dependencies:
       possible-typed-array-names: 1.1.0
 
+  axios@1.8.4:
+    dependencies:
+      follow-redirects: 1.15.9
+      form-data: 4.0.2
+      proxy-from-env: 1.1.0
+    transitivePeerDependencies:
+      - debug
+
   babel-jest@29.7.0(@babel/core@7.26.10):
     dependencies:
       '@babel/core': 7.26.10
@@ -4432,6 +4501,14 @@ snapshots:
 
   cjs-module-lexer@1.4.3: {}
 
+  class-transformer@0.5.1: {}
+
+  class-validator@0.14.1:
+    dependencies:
+      '@types/validator': 13.15.0
+      libphonenumber-js: 1.12.6
+      validator: 13.15.0
+
   cli-cursor@3.1.0:
     dependencies:
       restore-cursor: 3.1.0
@@ -5041,6 +5118,8 @@ snapshots:
 
   flatted@3.3.3: {}
 
+  follow-redirects@1.15.9: {}
+
   for-each@0.3.5:
     dependencies:
       is-callable: 1.2.7
@@ -5876,6 +5955,8 @@ snapshots:
       prelude-ls: 1.2.1
       type-check: 0.4.0
 
+  libphonenumber-js@1.12.6: {}
+
   lines-and-columns@1.2.4: {}
 
   loader-runner@4.3.0: {}
@@ -6190,6 +6271,8 @@ snapshots:
       forwarded: 0.2.0
       ipaddr.js: 1.9.1
 
+  proxy-from-env@1.1.0: {}
+
   punycode@2.3.1: {}
 
   pure-rand@6.1.0: {}
@@ -6804,6 +6887,8 @@ snapshots:
       '@types/istanbul-lib-coverage': 2.0.6
       convert-source-map: 2.0.0
 
+  validator@13.15.0: {}
+
   vary@1.1.2: {}
 
   walker@1.0.8:

+ 2 - 1
src/app.module.ts

@@ -1,9 +1,10 @@
 import { Module } from '@nestjs/common'
 
+import { AgentServerModule } from '@/module/agent-server/agent-server.module'
 import { SqlAgentModule } from '@/module/sql-agent/sql-agent.module'
 import { TencentCloudModule } from '@/module/tencent-cloud/tencent-cloud.module'
 
 @Module({
-  imports: [SqlAgentModule, TencentCloudModule]
+  imports: [SqlAgentModule, TencentCloudModule, AgentServerModule]
 })
 export class AppModule {}

+ 11 - 0
src/main.ts

@@ -1,3 +1,4 @@
+import { ValidationPipe } from '@nestjs/common'
 import { NestFactory } from '@nestjs/core'
 
 import { AppModule } from './app.module'
@@ -8,6 +9,16 @@ async function bootstrap() {
     origin: '*'
   })
   app.setGlobalPrefix('webserver')
+  app.useGlobalPipes(
+    new ValidationPipe({
+      whitelist: true, // 过滤掉请求参数中未定义的属性
+      transform: true, // 将请求参数转换为指定的类型
+      // forbidNonWhitelisted: true, // 如果请求参数中存在未定义的属性,则抛出异常
+      transformOptions: {
+        enableImplicitConversion: true // 启用隐式转换
+      }
+    })
+  )
   await app.listen(3000, '0.0.0.0')
 }
 bootstrap()

+ 136 - 0
src/module/agent-server/agent-server.controller.ts

@@ -0,0 +1,136 @@
+import {
+  Controller,
+  Get,
+  Header,
+  HttpCode,
+  Query,
+  Post,
+  Body
+} from '@nestjs/common'
+
+import { AgentServerService } from './agent-server.service'
+import {
+  GetStaffProfileDto,
+  ListUsersDto,
+  GetDialogueHistoryDto,
+  RunPromptDto
+} from './dto'
+
+interface ApiResponse<T> {
+  code: number
+  msg: string
+  data: T | null
+}
+
+@Controller('agentServer')
+export class AgentServerController {
+  constructor(private readonly agentServerService: AgentServerService) {}
+
+  private handleResponse<T>(response: {
+    data: T
+    code: number
+    msg: string
+  }): ApiResponse<T> {
+    if (response.code === 200) {
+      return {
+        code: 0,
+        msg: '请求成功',
+        data: response.data
+      }
+    }
+    return {
+      code: 1,
+      msg: response.msg,
+      data: null
+    }
+  }
+
+  // 获取所有员工列表
+  @Get('listStaffs')
+  @Header('Access-Control-Allow-Origin', '*')
+  @HttpCode(200)
+  async listStaffs() {
+    const response = await this.agentServerService.listStaffs()
+    return this.handleResponse(response)
+  }
+
+  // 获取员工详情
+  @Get('getStaffProfile')
+  @Header('Access-Control-Allow-Origin', '*')
+  @HttpCode(200)
+  async getStaffProfile(@Query() getStaffProfileDto: GetStaffProfileDto) {
+    const response = await this.agentServerService.getStaffProfile(
+      getStaffProfileDto.staff_id
+    )
+    return this.handleResponse(response)
+  }
+
+  // 获取用户详情
+  @Get('getUserProfile')
+  @Header('Access-Control-Allow-Origin', '*')
+  @HttpCode(200)
+  async getUserProfile(@Query() listUsersDto: ListUsersDto) {
+    const response = await this.agentServerService.getUserProfile(
+      listUsersDto.user_union_id
+    )
+    return this.handleResponse(response)
+  }
+
+  // 获取所有用户列表(根据用户名和用户union_id)
+  @Get('listUsers')
+  @Header('Access-Control-Allow-Origin', '*')
+  @HttpCode(200)
+  async listUsers(@Query() listUsersDto: ListUsersDto) {
+    const response = await this.agentServerService.listUsers(
+      listUsersDto.user_name,
+      listUsersDto.user_union_id
+    )
+    return this.handleResponse(response)
+  }
+
+  @Get('getDialogueHistory')
+  @Header('Access-Control-Allow-Origin', '*')
+  @HttpCode(200)
+  async getDialogueHistory(
+    @Query() getDialogueHistoryDto: GetDialogueHistoryDto
+  ) {
+    const response = await this.agentServerService.getDialogueHistory(
+      getDialogueHistoryDto.staff_id,
+      getDialogueHistoryDto.user_id,
+      getDialogueHistoryDto.recent_minutes
+    )
+    return this.handleResponse(response)
+  }
+
+  @Get('listModels')
+  @Header('Access-Control-Allow-Origin', '*')
+  @HttpCode(200)
+  async listModels() {
+    const response = await this.agentServerService.listModels()
+    return this.handleResponse(response)
+  }
+
+  @Get('listScenes')
+  @Header('Access-Control-Allow-Origin', '*')
+  @HttpCode(200)
+  async listScenes() {
+    const response = await this.agentServerService.listScenes()
+    return this.handleResponse(response)
+  }
+
+  @Get('getBasePrompt')
+  @Header('Access-Control-Allow-Origin', '*')
+  @HttpCode(200)
+  async getBasePrompt() {
+    const response = await this.agentServerService.getBasePrompt()
+    return this.handleResponse(response)
+  }
+
+  @Post('runPrompt')
+  @Header('Access-Control-Allow-Origin', '*')
+  @HttpCode(200)
+  async runPrompt(@Body() runPromptDto: RunPromptDto) {
+    const response = await this.agentServerService.runPrompt(runPromptDto)
+    return this.handleResponse(response)
+  }
+}

+ 17 - 0
src/module/agent-server/agent-server.module.ts

@@ -0,0 +1,17 @@
+import { HttpModule } from '@nestjs/axios'
+import { Module } from '@nestjs/common'
+
+import { AgentServerController } from './agent-server.controller'
+import { AgentServerService } from './agent-server.service'
+
+@Module({
+  imports: [
+    HttpModule.register({
+      timeout: 1000,
+      maxRedirects: 3
+    })
+  ],
+  controllers: [AgentServerController],
+  providers: [AgentServerService]
+})
+export class AgentServerModule {}

+ 71 - 0
src/module/agent-server/agent-server.service.ts

@@ -0,0 +1,71 @@
+import { HttpService } from '@nestjs/axios'
+import { Injectable } from '@nestjs/common'
+import { lastValueFrom } from 'rxjs'
+
+import { RunPromptDto } from './dto'
+
+@Injectable()
+export class AgentServerService {
+  private readonly baseUrl = 'http://192.168.206.189:8083/api'
+
+  constructor(private readonly httpService: HttpService) {}
+
+  private async makeRequest<T>(
+    endpoint: string,
+    params?: Record<string, any>
+  ): Promise<AgentServerResponseType<T>> {
+    const url = `${this.baseUrl}/${endpoint}`
+    const responseObservable = await this.httpService.get<
+      AgentServerResponseType<T>
+    >(url, { params })
+    const { data } = await lastValueFrom(responseObservable)
+    return data
+  }
+
+  async listStaffs() {
+    return this.makeRequest<StaffsType>('listStaffs')
+  }
+
+  async getStaffProfile(staff_id: string) {
+    return this.makeRequest<StaffProfile>('getStaffProfile', { staff_id })
+  }
+
+  async getUserProfile(user_id: string) {
+    return this.makeRequest<UserProfile>('getUserProfile', { user_id })
+  }
+
+  async listUsers(user_name: string, user_union_id: string) {
+    return this.makeRequest<UserProfile>('listUsers', {
+      user_name,
+      user_union_id
+    })
+  }
+
+  async getDialogueHistory(
+    staff_id: string,
+    user_id: string,
+    recent_minutes: string
+  ) {
+    return this.makeRequest<DialogueHistory>('getDialogueHistory', {
+      staff_id,
+      user_id,
+      recent_minutes
+    })
+  }
+
+  async listModels() {
+    return this.makeRequest<Model>('listModels')
+  }
+
+  async listScenes() {
+    return this.makeRequest<Scene>('listScenes')
+  }
+
+  async getBasePrompt() {
+    return this.makeRequest<BasePrompt>('getBasePrompt')
+  }
+
+  async runPrompt(runPromptDto: RunPromptDto) {
+    return this.makeRequest<RunPromptDto>('runPrompt', runPromptDto)
+  }
+}

+ 59 - 0
src/module/agent-server/dto/index.ts

@@ -0,0 +1,59 @@
+import { IsString, IsNotEmpty, ValidateIf } from 'class-validator'
+
+export class GetStaffProfileDto {
+  @IsString()
+  @IsNotEmpty({ message: 'staff_id不能为空' })
+  staff_id: string
+}
+
+export class ListUsersDto {
+  @ValidateIf((o) => !o.user_union_id)
+  @IsString()
+  user_name: string
+
+  @ValidateIf((o) => !o.user_name)
+  @IsString()
+  user_union_id: string
+}
+
+export class GetDialogueHistoryDto {
+  @IsString()
+  @IsNotEmpty({ message: 'staff_id不能为空' })
+  staff_id: string
+
+  @IsString()
+  @IsNotEmpty({ message: 'user_id不能为空' })
+  user_id: string
+
+  recent_minutes: string
+}
+
+export class RunPromptDto {
+  @IsString()
+  @IsNotEmpty({ message: 'scene不能为空' })
+  scene: string
+
+  @IsString()
+  @IsNotEmpty({ message: 'prompt不能为空' })
+  prompt: string
+
+  @IsString()
+  @IsNotEmpty({ message: 'staff_profile不能为空' })
+  staff_profile: string
+
+  @IsString()
+  @IsNotEmpty({ message: 'user_profile不能为空' })
+  user_profile: string
+
+  @IsString()
+  @IsNotEmpty({ message: 'dialogue_history不能为空' })
+  dialogue_history: string
+
+  @IsString()
+  @IsNotEmpty({ message: 'model_name不能为空' })
+  model_name: string
+
+  @IsString()
+  @IsNotEmpty({ message: 'current_timestamp不能为空' })
+  current_timestamp: string
+}

+ 44 - 0
src/module/agent-server/type.d.ts

@@ -0,0 +1,44 @@
+type AgentServerResponseType<T> = {
+  code: number
+  msg: string
+  data: T
+}
+
+type StaffsType = {
+  agent_name: string
+  name: string
+  third_party_user_id: string
+  wxid: string
+}
+
+type StaffProfile = {
+  staff_id: string
+  name: string
+}
+
+type UserProfile = {
+  user_id: string
+  name: string
+}
+
+type DialogueHistory = {
+  role: string
+  timestamp: number
+  content: string
+}
+
+type Model = {
+  model_id: string
+  model_name: string
+  display_name: string
+}
+
+type Scene = {
+  scene: string
+  display_name: string
+}
+
+type BasePrompt = {
+  model_name: string
+  content: string
+}