✨ feat(agent): 新增实体搜索工具及API接口
新增实体搜索功能,支持按名称模糊查询店铺、柜机、商品等实体。 主要变更: - 新增 searchEntityTool 工具,支持 shop/cabinet/goods 三种实体类型查询 - 新增 agent API 模块,统一管理实体搜索和详情查询接口 - 重构 cabinetTool 使用新的 cabinetDetail API - 增强 shopTool,新增 shopDetail 查询类型 - 添加 axios 调试日志便于问题排查 - 新增 Agent API 接口文档 Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
parent
1334ad6baa
commit
e158ae34ef
|
|
@ -5,6 +5,7 @@ import {
|
||||||
shopTool,
|
shopTool,
|
||||||
dynamicInfoTool,
|
dynamicInfoTool,
|
||||||
codeExecutorTool,
|
codeExecutorTool,
|
||||||
|
searchEntityTool,
|
||||||
} from "../tools";
|
} from "../tools";
|
||||||
import { createDeepSeek } from '@ai-sdk/deepseek';
|
import { createDeepSeek } from '@ai-sdk/deepseek';
|
||||||
import { createOpenAI } from '@ai-sdk/openai';
|
import { createOpenAI } from '@ai-sdk/openai';
|
||||||
|
|
@ -47,10 +48,15 @@ export const multiFunctionAgent = new Agent({
|
||||||
你是一个具有内存功能的多功能助手,具备以下能力:
|
你是一个具有内存功能的多功能助手,具备以下能力:
|
||||||
|
|
||||||
1. **商品查询**:使用商品工具查询商品信息,支持分页查询商品列表或根据商品ID获取单个商品详情。
|
1. **商品查询**:使用商品工具查询商品信息,支持分页查询商品列表或根据商品ID获取单个商品详情。
|
||||||
2. **柜机查询**:使用柜机工具查询智能柜信息,支持查询柜机详情。
|
2. **柜机查询**:使用柜机工具根据柜机ID查询智能柜详细信息。
|
||||||
3. **门店查询**:使用门店工具查询门店相关信息,支持查询门店列表、模式列表。
|
3. **门店查询**:使用门店工具查询门店相关信息,支持查询门店列表、模式列表以及根据门店ID获取门店详细信息(含下属柜机列表)。
|
||||||
4. **借还动态查询**:使用借还动态工具查询商品借还记录,支持按商品ID、格口ID、状态、动态类型筛选,可查询借出和归还记录。
|
4. **借还动态查询**:使用借还动态工具查询商品借还记录,支持按商品ID、格口ID、状态、动态类型筛选,可查询借出和归还记录。
|
||||||
5. **代码执行**:使用代码执行工具运行 JavaScript 代码(同步执行)。对大段信息或数据进行处理时请不要直接输出,而应通过代码执行工具进行处理。
|
5. **实体搜索**:使用实体搜索工具根据名称模糊查询店铺、柜机、商品等实体。
|
||||||
|
- 输入参数:
|
||||||
|
- name: 实体名称关键词
|
||||||
|
- entityType: 实体类型(shop=店铺/门店,cabinet=智能柜,goods=商品)
|
||||||
|
- 返回匹配的实体ID和名称列表
|
||||||
|
6. **代码执行**:使用代码执行工具运行 JavaScript 代码(同步执行)。对大段信息或数据进行处理时请不要直接输出,而应通过代码执行工具进行处理。
|
||||||
- 输入参数:
|
- 输入参数:
|
||||||
- code: 要执行的 JavaScript 代码(必须以 return 语句返回结果)
|
- code: 要执行的 JavaScript 代码(必须以 return 语句返回结果)
|
||||||
- context: 可选,上下文数据对象
|
- context: 可选,上下文数据对象
|
||||||
|
|
@ -89,5 +95,6 @@ export const multiFunctionAgent = new Agent({
|
||||||
shopTool,
|
shopTool,
|
||||||
dynamicInfoTool,
|
dynamicInfoTool,
|
||||||
codeExecutorTool,
|
codeExecutorTool,
|
||||||
|
searchEntityTool,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
import { request } from "../axios"
|
||||||
|
import { ResponseData } from "../type"
|
||||||
|
|
||||||
|
export interface IdNameDTO {
|
||||||
|
/** 实体ID */
|
||||||
|
id: number
|
||||||
|
/** 实体名称 */
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CellDTO {
|
||||||
|
/** 单元格ID */
|
||||||
|
id: number
|
||||||
|
/** 单元格编号 */
|
||||||
|
cellNo: string
|
||||||
|
/** 单元格名称 */
|
||||||
|
cellName: string
|
||||||
|
/** 单元格状态 */
|
||||||
|
status: number
|
||||||
|
/** 商品ID */
|
||||||
|
goodsId: number
|
||||||
|
/** 商品名称 */
|
||||||
|
goodsName: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CabinetDetailDTO {
|
||||||
|
/** 柜机ID */
|
||||||
|
id: number
|
||||||
|
/** 柜机编号 */
|
||||||
|
cabinetNo: string
|
||||||
|
/** 柜机名称 */
|
||||||
|
cabinetName: string
|
||||||
|
/** 所属店铺ID */
|
||||||
|
shopId: number
|
||||||
|
/** 所属店铺名称 */
|
||||||
|
shopName: string
|
||||||
|
/** 柜机状态 */
|
||||||
|
status: number
|
||||||
|
/** 单元格列表 */
|
||||||
|
cells: CellDTO[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CabinetSimpleDTO {
|
||||||
|
/** 柜机ID */
|
||||||
|
id: number
|
||||||
|
/** 柜机编号 */
|
||||||
|
cabinetNo: string
|
||||||
|
/** 柜机名称 */
|
||||||
|
cabinetName: string
|
||||||
|
/** 柜机状态 */
|
||||||
|
status: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShopDetailDTO {
|
||||||
|
/** 店铺ID */
|
||||||
|
id: number
|
||||||
|
/** 店铺名称 */
|
||||||
|
shopName: string
|
||||||
|
/** 店铺编码 */
|
||||||
|
shopCode: string
|
||||||
|
/** 联系人姓名 */
|
||||||
|
contactName: string
|
||||||
|
/** 联系电话 */
|
||||||
|
contactPhone: string
|
||||||
|
/** 店铺地址 */
|
||||||
|
address: string
|
||||||
|
/** 店铺状态 */
|
||||||
|
status: number
|
||||||
|
/** 柜机列表 */
|
||||||
|
cabinets: CabinetSimpleDTO[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type EntityType = "shop" | "cabinet" | "goods"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据名称模糊查询实体列表
|
||||||
|
* 支持查询店铺(shop)、柜机(cabinet)、商品(goods)三种类型的实体
|
||||||
|
* @param name 名称关键词,支持模糊匹配
|
||||||
|
* @param entityType 实体类型,可选值:shop、cabinet、goods
|
||||||
|
* @returns Promise<ResponseData<IdNameDTO[]>>
|
||||||
|
*/
|
||||||
|
export function searchEntity(name: string, entityType: EntityType) {
|
||||||
|
return request<ResponseData<IdNameDTO[]>>({
|
||||||
|
url: "agent/searchEntity",
|
||||||
|
method: "get",
|
||||||
|
params: { name, entityType }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据柜体ID获取智能柜详细信息
|
||||||
|
* 包括柜体信息、单元格信息和商品信息
|
||||||
|
* @param cabinetId 柜体ID
|
||||||
|
* @returns Promise<ResponseData<CabinetDetailDTO>>
|
||||||
|
*/
|
||||||
|
export function cabinetDetail(cabinetId: number) {
|
||||||
|
return request<ResponseData<CabinetDetailDTO>>({
|
||||||
|
url: "agent/cabinetDetail",
|
||||||
|
method: "get",
|
||||||
|
params: { cabinetId }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据店铺ID获取店铺详细信息
|
||||||
|
* 包含下属柜机列表(不包含格口信息)
|
||||||
|
* @param shopId 店铺ID
|
||||||
|
* @returns Promise<ResponseData<ShopDetailDTO>>
|
||||||
|
*/
|
||||||
|
export function shopDetail(shopId: number) {
|
||||||
|
return request<ResponseData<ShopDetailDTO>>({
|
||||||
|
url: "agent/shopDetail",
|
||||||
|
method: "get",
|
||||||
|
params: { shopId }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -11,7 +11,14 @@ function createInstance() {
|
||||||
// 请求拦截器
|
// 请求拦截器
|
||||||
instance.interceptors.request.use(
|
instance.interceptors.request.use(
|
||||||
// 发送之前
|
// 发送之前
|
||||||
config => config,
|
config => {
|
||||||
|
console.log('Request URL:', config.url)
|
||||||
|
console.log('Request Method:', config.method)
|
||||||
|
console.log('Request Headers:', config.headers)
|
||||||
|
console.log('Request Params:', config.params)
|
||||||
|
console.log('Request Data:', config.data)
|
||||||
|
return config
|
||||||
|
},
|
||||||
// 发送失败
|
// 发送失败
|
||||||
error => Promise.reject(error)
|
error => Promise.reject(error)
|
||||||
)
|
)
|
||||||
|
|
@ -32,6 +39,9 @@ function createInstance() {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case 0:
|
case 0:
|
||||||
// 本系统采用 code === 0 来表示没有业务错误
|
// 本系统采用 code === 0 来表示没有业务错误
|
||||||
|
console.log('Response URL:', response.config.url)
|
||||||
|
console.log('Response Status:', response.status)
|
||||||
|
console.log('Response Data:', apiData)
|
||||||
return apiData
|
return apiData
|
||||||
default:
|
default:
|
||||||
// 不是正确的 code
|
// 不是正确的 code
|
||||||
|
|
@ -78,6 +88,11 @@ function createInstance() {
|
||||||
error.message = "HTTP 版本不受支持"
|
error.message = "HTTP 版本不受支持"
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
console.error('Request Error URL:', error.config?.url)
|
||||||
|
console.error('Request Error Method:', error.config?.method)
|
||||||
|
console.error('Request Error Status:', status)
|
||||||
|
console.error('Request Error Message:', error.message)
|
||||||
|
console.error('Request Error Response Data:', error.response?.data)
|
||||||
return Promise.reject(error)
|
return Promise.reject(error)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,260 @@
|
||||||
|
# Agent Controller 接口文档
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
AgentController 提供实体搜索及详情查询功能,支持店铺、柜机、商品三种类型实体的模糊搜索,以及柜机和店铺的详细信息获取。
|
||||||
|
|
||||||
|
**基础路径**: `/api/agent`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 接口列表
|
||||||
|
|
||||||
|
### 1. 根据名称模糊查询实体列表
|
||||||
|
|
||||||
|
根据名称关键词模糊查询店铺、柜机或商品实体。
|
||||||
|
|
||||||
|
**请求地址**: `GET /api/agent/searchEntity`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 必填 | 说明 |
|
||||||
|
|--------|------|------|------|
|
||||||
|
| name | String | 是 | 名称关键词,支持模糊匹配 |
|
||||||
|
| entityType | String | 是 | 实体类型,可选值:shop(店铺)、cabinet(柜机)、goods(商品) |
|
||||||
|
|
||||||
|
**请求示例**:
|
||||||
|
```
|
||||||
|
GET /api/agent/searchEntity?name=测试&entityType=shop
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应参数**:
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| code | Integer | 状态码,200表示成功 |
|
||||||
|
| msg | String | 返回消息 |
|
||||||
|
| data | List\<IdNameDTO\> | 实体列表 |
|
||||||
|
|
||||||
|
**IdNameDTO 结构**:
|
||||||
|
|
||||||
|
| 字段名 | 类型 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| id | Long | 实体ID |
|
||||||
|
| name | String | 实体名称 |
|
||||||
|
|
||||||
|
**成功响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "测试店铺A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"name": "测试店铺B"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**错误响应**:
|
||||||
|
- 当 name 为空时,返回空列表 `data: null`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. 根据柜体ID获取智能柜详细信息
|
||||||
|
|
||||||
|
根据柜体ID获取智能柜的详细信息,包括柜体信息、单元格信息和商品信息。
|
||||||
|
|
||||||
|
**请求地址**: `GET /api/agent/cabinetDetail`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 必填 | 说明 |
|
||||||
|
|--------|------|------|------|
|
||||||
|
| cabinetId | Long | 是 | 柜体ID |
|
||||||
|
|
||||||
|
**请求示例**:
|
||||||
|
```
|
||||||
|
GET /api/agent/cabinetDetail?cabinetId=1
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应参数**:
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| code | Integer | 状态码,200表示成功 |
|
||||||
|
| msg | String | 返回消息 |
|
||||||
|
| data | CabinetDetailDTO | 柜机详情对象 |
|
||||||
|
|
||||||
|
**CabinetDetailDTO 结构**:
|
||||||
|
|
||||||
|
| 字段名 | 类型 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| id | Long | 柜机ID |
|
||||||
|
| cabinetNo | String | 柜机编号 |
|
||||||
|
| cabinetName | String | 柜机名称 |
|
||||||
|
| shopId | Long | 所属店铺ID |
|
||||||
|
| shopName | String | 所属店铺名称 |
|
||||||
|
| status | Integer | 柜机状态 |
|
||||||
|
| cells | List\<CellDTO\> | 单元格列表 |
|
||||||
|
| ... | - | 其他扩展字段 |
|
||||||
|
|
||||||
|
**CellDTO 结构**:
|
||||||
|
|
||||||
|
| 字段名 | 类型 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| id | Long | 单元格ID |
|
||||||
|
| cellNo | String | 单元格编号 |
|
||||||
|
| cellName | String | 单元格名称 |
|
||||||
|
| status | Integer | 单元格状态 |
|
||||||
|
| goodsId | Long | 商品ID |
|
||||||
|
| goodsName | String | 商品名称 |
|
||||||
|
| ... | - | 其他扩展字段 |
|
||||||
|
|
||||||
|
**成功响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": {
|
||||||
|
"id": 1,
|
||||||
|
"cabinetNo": "CAB001",
|
||||||
|
"cabinetName": "一号智能柜",
|
||||||
|
"shopId": 1,
|
||||||
|
"shopName": "测试店铺",
|
||||||
|
"status": 1,
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"cellNo": "C001",
|
||||||
|
"cellName": "1号格口",
|
||||||
|
"status": 0,
|
||||||
|
"goodsId": 100,
|
||||||
|
"goodsName": "商品A"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**错误响应**:
|
||||||
|
- 当 cabinetId 为空时,返回失败状态
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. 根据店铺ID获取店铺详细信息
|
||||||
|
|
||||||
|
根据店铺ID获取店铺详细信息,包含下属柜机列表(不包含格口信息)。
|
||||||
|
|
||||||
|
**请求地址**: `GET /api/agent/shopDetail`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 必填 | 说明 |
|
||||||
|
|--------|------|------|------|
|
||||||
|
| shopId | Long | 是 | 店铺ID |
|
||||||
|
|
||||||
|
**请求示例**:
|
||||||
|
```
|
||||||
|
GET /api/agent/shopDetail?shopId=1
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应参数**:
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| code | Integer | 状态码,200表示成功 |
|
||||||
|
| msg | String | 返回消息 |
|
||||||
|
| data | ShopDetailDTO | 店铺详情对象 |
|
||||||
|
|
||||||
|
**ShopDetailDTO 结构**:
|
||||||
|
|
||||||
|
| 字段名 | 类型 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| id | Long | 店铺ID |
|
||||||
|
| shopName | String | 店铺名称 |
|
||||||
|
| shopCode | String | 店铺编码 |
|
||||||
|
| contactName | String | 联系人姓名 |
|
||||||
|
| contactPhone | String | 联系电话 |
|
||||||
|
| address | String | 店铺地址 |
|
||||||
|
| status | Integer | 店铺状态 |
|
||||||
|
| cabinets | List\<CabinetSimpleDTO\> | 柜机列表 |
|
||||||
|
| ... | - | 其他扩展字段 |
|
||||||
|
|
||||||
|
**CabinetSimpleDTO 结构**:
|
||||||
|
|
||||||
|
| 字段名 | 类型 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| id | Long | 柜机ID |
|
||||||
|
| cabinetNo | String | 柜机编号 |
|
||||||
|
| cabinetName | String | 柜机名称 |
|
||||||
|
| status | Integer | 柜机状态 |
|
||||||
|
| ... | - | 其他扩展字段 |
|
||||||
|
|
||||||
|
**成功响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": {
|
||||||
|
"id": 1,
|
||||||
|
"shopName": "测试店铺",
|
||||||
|
"shopCode": "SHOP001",
|
||||||
|
"contactName": "张三",
|
||||||
|
"contactPhone": "13800138000",
|
||||||
|
"address": "北京市朝阳区xxx",
|
||||||
|
"status": 1,
|
||||||
|
"cabinets": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"cabinetNo": "CAB001",
|
||||||
|
"cabinetName": "一号智能柜",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"cabinetNo": "CAB002",
|
||||||
|
"cabinetName": "二号智能柜",
|
||||||
|
"status": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**错误响应**:
|
||||||
|
- 当 shopId 为空时,返回失败状态
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 状态码说明
|
||||||
|
|
||||||
|
| 状态码 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| 200 | 操作成功 |
|
||||||
|
| 500 | 服务器内部错误 |
|
||||||
|
| 其他 | 具体业务错误信息 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 实体类型说明
|
||||||
|
|
||||||
|
| entityType | 说明 | 关联服务 |
|
||||||
|
|------------|------|----------|
|
||||||
|
| shop | 店铺实体 | ShopApplicationService |
|
||||||
|
| cabinet | 柜机实体 | SmartCabinetApplicationService |
|
||||||
|
| goods | 商品实体 | GoodsApplicationService |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. 所有接口均支持跨域访问(`@CrossOrigin` 配置)
|
||||||
|
2. searchEntity 接口在 name 为空时返回 null 而非空列表
|
||||||
|
3. cabinetDetail 接口返回完整的柜机及格口信息,数据量可能较大
|
||||||
|
4. shopDetail 接口仅返回柜机基本信息,不包含格口详情
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
import { createTool } from "@mastra/core/tools";
|
import { createTool } from "@mastra/core/tools";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { getCabinetDetailApi } from "../api/cabinet";
|
import { cabinetDetail } from "../api/agent/agent";
|
||||||
|
|
||||||
export const cabinetTool = createTool({
|
export const cabinetTool = createTool({
|
||||||
id: "cabinet",
|
id: "cabinet",
|
||||||
description: "查询智能柜详情",
|
description: "根据柜机ID查询智能柜详细信息",
|
||||||
|
|
||||||
inputSchema: z.object({
|
inputSchema: z.object({
|
||||||
shopId: z.number().describe("门店ID"),
|
cabinetId: z.number().describe("柜机ID"),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
outputSchema: z.object({
|
outputSchema: z.object({
|
||||||
|
|
@ -18,16 +18,16 @@ export const cabinetTool = createTool({
|
||||||
|
|
||||||
execute: async ({ context }) => {
|
execute: async ({ context }) => {
|
||||||
try {
|
try {
|
||||||
const { shopId } = context;
|
const { cabinetId } = context;
|
||||||
|
|
||||||
if (!shopId) {
|
if (!cabinetId) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: "shopId参数为必填",
|
message: "cabinetId参数为必填",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await getCabinetDetailApi(shopId);
|
const response = await cabinetDetail(cabinetId);
|
||||||
return {
|
return {
|
||||||
success: response.code === 0,
|
success: response.code === 0,
|
||||||
message: response.msg || "查询成功",
|
message: response.msg || "查询成功",
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,4 @@ export { cabinetTool } from "./cabinet-tool";
|
||||||
export { shopTool } from "./shop-tool";
|
export { shopTool } from "./shop-tool";
|
||||||
export { dynamicInfoTool } from "./dynamic-info-tool";
|
export { dynamicInfoTool } from "./dynamic-info-tool";
|
||||||
export { codeExecutorTool } from "./code-executor-tool";
|
export { codeExecutorTool } from "./code-executor-tool";
|
||||||
|
export { searchEntityTool } from "./search-entity-tool";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { createTool } from "@mastra/core/tools";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { searchEntity } from "../api/agent/agent";
|
||||||
|
|
||||||
|
export const searchEntityTool = createTool({
|
||||||
|
id: "searchEntity",
|
||||||
|
description: `根据名称关键词模糊查询实体列表,支持查询三种类型的实体:
|
||||||
|
- shop(店铺):查询门店/店铺信息
|
||||||
|
- cabinet(柜机):查询智能柜信息
|
||||||
|
- goods(商品):查询商品信息
|
||||||
|
|
||||||
|
使用场景:
|
||||||
|
- 用户想找某个名称相关的店铺、柜机或商品
|
||||||
|
- 需要从多个实体类型中搜索特定名称的实体
|
||||||
|
- 返回匹配实体的ID和名称列表
|
||||||
|
|
||||||
|
注意事项:
|
||||||
|
- entityType 必须在 ['shop', 'cabinet', 'goods'] 中选择
|
||||||
|
- name 为空时返回空列表
|
||||||
|
- 返回结果按创建时间倒序排列`,
|
||||||
|
|
||||||
|
inputSchema: z.object({
|
||||||
|
name: z.string().min(1).describe("实体名称关键词,支持模糊匹配"),
|
||||||
|
entityType: z.enum(["shop", "cabinet", "goods"]).describe(
|
||||||
|
"实体类型:'shop'=店铺/门店,'cabinet'=智能柜,'goods'=商品"
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
|
||||||
|
outputSchema: z.object({
|
||||||
|
success: z.boolean(),
|
||||||
|
message: z.string(),
|
||||||
|
data: z.array(z.object({
|
||||||
|
shopId: z.number().optional(),
|
||||||
|
cabinetId: z.number().optional(),
|
||||||
|
goodsId: z.number().optional(),
|
||||||
|
name: z.string(),
|
||||||
|
})).optional(),
|
||||||
|
}),
|
||||||
|
|
||||||
|
execute: async ({ context }) => {
|
||||||
|
try {
|
||||||
|
const { name, entityType } = context;
|
||||||
|
|
||||||
|
const response = await searchEntity(name, entityType);
|
||||||
|
|
||||||
|
const data = (response.data || []).map(item => {
|
||||||
|
switch (entityType) {
|
||||||
|
case 'shop':
|
||||||
|
return { shopId: item.id, name: item.name };
|
||||||
|
case 'cabinet':
|
||||||
|
return { cabinetId: item.id, name: item.name };
|
||||||
|
case 'goods':
|
||||||
|
return { goodsId: item.id, name: item.name };
|
||||||
|
default:
|
||||||
|
return { name: item.name };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: response.code === 200,
|
||||||
|
message: response.msg || "查询成功",
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
} catch (error: any) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: `查询失败: ${error.message || "未知错误"}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -5,19 +5,21 @@ import {
|
||||||
getModeListApi,
|
getModeListApi,
|
||||||
GetShopListParams
|
GetShopListParams
|
||||||
} from "../api/shop";
|
} from "../api/shop";
|
||||||
|
import { shopDetail } from "../api/agent/agent";
|
||||||
|
|
||||||
export const shopTool = createTool({
|
export const shopTool = createTool({
|
||||||
id: "shop",
|
id: "shop",
|
||||||
description: "查询门店相关信息,支持查询门店列表、模式列表",
|
description: "查询门店相关信息,支持查询门店列表、模式列表、门店详情",
|
||||||
|
|
||||||
inputSchema: z.object({
|
inputSchema: z.object({
|
||||||
queryType: z.enum(["shopList", "modeList"]).describe(
|
queryType: z.enum(["shopList", "modeList", "shopDetail"]).describe(
|
||||||
"查询类型:'shopList'表示获取门店列表,'modeList'表示获取模式列表"
|
"查询类型:'shopList'表示获取门店列表,'modeList'表示获取模式列表,'shopDetail'表示获取门店详情"
|
||||||
),
|
),
|
||||||
corpid: z.string().optional().describe("企业微信ID(查询门店列表时必填)"),
|
corpid: z.string().optional().describe("企业微信ID(查询门店列表时必填)"),
|
||||||
mode: z.number().optional().describe("需要排除的运行模式(查询门店列表时可选,该参数表示不查询该运行模式的门店,默认值为-1)"),
|
mode: z.number().optional().describe("需要排除的运行模式(查询门店列表时可选,该参数表示不查询该运行模式的门店,默认值为-1)"),
|
||||||
eqMode: z.number().optional().describe("运行模式(查询门店列表时可选)"),
|
eqMode: z.number().optional().describe("运行模式(查询门店列表时可选)"),
|
||||||
modeList: z.string().optional().describe("模式列表字符串(查询门店列表时可选)"),
|
modeList: z.string().optional().describe("模式列表字符串(查询门店列表时可选)"),
|
||||||
|
shopId: z.number().optional().describe("门店ID(查询门店详情时必填)"),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
outputSchema: z.object({
|
outputSchema: z.object({
|
||||||
|
|
@ -28,7 +30,7 @@ export const shopTool = createTool({
|
||||||
|
|
||||||
execute: async ({ context }) => {
|
execute: async ({ context }) => {
|
||||||
try {
|
try {
|
||||||
const { queryType, corpid, mode, eqMode, modeList } = context;
|
const { queryType, corpid, mode, eqMode, modeList, shopId } = context;
|
||||||
|
|
||||||
if (queryType === "shopList") {
|
if (queryType === "shopList") {
|
||||||
if (!corpid) {
|
if (!corpid) {
|
||||||
|
|
@ -56,6 +58,19 @@ export const shopTool = createTool({
|
||||||
message: response.msg || "查询成功",
|
message: response.msg || "查询成功",
|
||||||
data: response.data,
|
data: response.data,
|
||||||
};
|
};
|
||||||
|
} else if (queryType === "shopDetail") {
|
||||||
|
if (!shopId) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "查询门店详情时,shopId参数为必填",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const response = await shopDetail(shopId);
|
||||||
|
return {
|
||||||
|
success: response.code === 0,
|
||||||
|
message: response.msg || "查询成功",
|
||||||
|
data: response.data,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue