【功能新增】AI:新增 function call 示例,完成所有模型的测试 = = 累
This commit is contained in:
@@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum;
|
||||
import cn.iocoder.yudao.framework.ai.core.util.AiUtils;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessagePageReqVO;
|
||||
@@ -238,7 +239,8 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
|
||||
// 2. 构建 ChatOptions 对象
|
||||
AiPlatformEnum platform = AiPlatformEnum.validatePlatform(model.getPlatform());
|
||||
ChatOptions chatOptions = AiUtils.buildChatOptions(platform, model.getModel(),
|
||||
conversation.getTemperature(), conversation.getMaxTokens());
|
||||
conversation.getTemperature(), conversation.getMaxTokens(),
|
||||
SetUtils.asSet("directory_list", "weather_query"));
|
||||
return new Prompt(chatMessages, chatOptions);
|
||||
}
|
||||
|
||||
|
@@ -1,95 +0,0 @@
|
||||
package cn.iocoder.yudao.module.ai.service.tool;
|
||||
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.ai.tool.annotation.Tool;
|
||||
import org.springframework.ai.tool.annotation.ToolParam;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_PATTERN;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
/**
|
||||
* 目录内容列表工具:列出指定目录的内容
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
public class ListDirTool {
|
||||
|
||||
/**
|
||||
* 列出指定目录的内容
|
||||
*
|
||||
* @param relativePath 要列出内容的目录路径,相对于工作区根目录
|
||||
* @return 目录内容列表
|
||||
*/
|
||||
@Tool(name = "listDir", description = "列出指定目录的内容")
|
||||
public Response listDir(@ToolParam(description = "要列出内容的目录路径,相对于工作区根目录") String relativePath) {
|
||||
// 校验目录存在
|
||||
String path = StrUtil.blankToDefault(relativePath, ".");
|
||||
Path dirPath = Paths.get(path);
|
||||
if (!FileUtil.exist(dirPath.toString()) || !FileUtil.isDirectory(dirPath.toString())) {
|
||||
return new Response(Collections.emptyList());
|
||||
}
|
||||
// 列出目录内容
|
||||
File[] files = dirPath.toFile().listFiles();
|
||||
if (ArrayUtil.isEmpty(files)) {
|
||||
return new Response(Collections.emptyList());
|
||||
}
|
||||
return new Response(convertList(Arrays.asList(files), file -> new Response.File()
|
||||
.setDirectory(file.isDirectory()).setName(file.getName())
|
||||
.setSize(file.isFile() ? FileUtil.readableFileSize(file.length()) : null)
|
||||
.setLastModified(
|
||||
LocalDateTimeUtil.format(LocalDateTimeUtil.of(file.lastModified()), NORM_DATETIME_PATTERN))));
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class Response {
|
||||
|
||||
/**
|
||||
* 目录内容列表
|
||||
*/
|
||||
private List<File> files;
|
||||
|
||||
@Data
|
||||
public static class File {
|
||||
|
||||
/**
|
||||
* 是否为目录
|
||||
*/
|
||||
private Boolean directory;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 大小,仅对文件有效
|
||||
*/
|
||||
private String size;
|
||||
|
||||
/**
|
||||
* 最后修改时间
|
||||
*/
|
||||
private String lastModified;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -1,10 +1,11 @@
|
||||
package cn.iocoder.yudao.module.ai.service.tool;
|
||||
package cn.iocoder.yudao.module.ai.service.tool.function;
|
||||
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonClassDescription;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
@@ -12,8 +13,6 @@ import lombok.NoArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -23,21 +22,22 @@ import static cn.hutool.core.date.DatePattern.NORM_DATETIME_PATTERN;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
/**
|
||||
* 目录内容列表工具:列出指定目录的内容
|
||||
* 工具:列出指定目录的文件列表
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component("listDir")
|
||||
public class ListDirToolB implements Function<ListDirToolB.Request, ListDirToolB.Response> {
|
||||
@Component("directory_list")
|
||||
public class DirectoryListToolFunction implements Function<DirectoryListToolFunction.Request, DirectoryListToolFunction.Response> {
|
||||
|
||||
@Data
|
||||
@JsonClassDescription("列出指定目录的内容")
|
||||
@JsonClassDescription("列出指定目录的文件列表")
|
||||
public static class Request {
|
||||
|
||||
/**
|
||||
* 要列出内容的目录路径
|
||||
* 目录路径
|
||||
*/
|
||||
@JsonPropertyDescription("要列出内容的目录路径,例如说:/Users/yunai")
|
||||
@JsonProperty(required = true, value = "path")
|
||||
@JsonPropertyDescription("目录路径,例如说:/Users/yunai")
|
||||
private String path;
|
||||
|
||||
}
|
||||
@@ -48,7 +48,7 @@ public class ListDirToolB implements Function<ListDirToolB.Request, ListDirToolB
|
||||
public static class Response {
|
||||
|
||||
/**
|
||||
* 目录内容列表
|
||||
* 文件列表
|
||||
*/
|
||||
private List<File> files;
|
||||
|
||||
@@ -82,13 +82,12 @@ public class ListDirToolB implements Function<ListDirToolB.Request, ListDirToolB
|
||||
@Override
|
||||
public Response apply(Request request) {
|
||||
// 校验目录存在
|
||||
String path = StrUtil.blankToDefault(request.getPath(), ".");
|
||||
Path dirPath = Paths.get(path);
|
||||
if (!FileUtil.exist(dirPath.toString()) || !FileUtil.isDirectory(dirPath.toString())) {
|
||||
String path = StrUtil.blankToDefault(request.getPath(), "/");
|
||||
if (!FileUtil.exist(path) || !FileUtil.isDirectory(path)) {
|
||||
return new Response(Collections.emptyList());
|
||||
}
|
||||
// 列出目录内容
|
||||
File[] files = dirPath.toFile().listFiles();
|
||||
// 列出目录
|
||||
File[] files = FileUtil.ls(path);
|
||||
if (ArrayUtil.isEmpty(files)) {
|
||||
return new Response(Collections.emptyList());
|
||||
}
|
@@ -0,0 +1,118 @@
|
||||
package cn.iocoder.yudao.module.ai.service.tool.function;
|
||||
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonClassDescription;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_PATTERN;
|
||||
|
||||
/**
|
||||
* 工具:查询指定城市的天气信息
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component("weather_query")
|
||||
public class WeatherQueryToolFunction
|
||||
implements Function<WeatherQueryToolFunction.Request, WeatherQueryToolFunction.Response> {
|
||||
|
||||
private static final String[] WEATHER_CONDITIONS = { "晴朗", "多云", "阴天", "小雨", "大雨", "雷雨", "小雪", "大雪" };
|
||||
|
||||
@Data
|
||||
@JsonClassDescription("查询指定城市的天气信息")
|
||||
public static class Request {
|
||||
|
||||
/**
|
||||
* 城市名称
|
||||
*/
|
||||
@JsonProperty(required = true, value = "city")
|
||||
@JsonPropertyDescription("城市名称,例如:北京、上海、广州")
|
||||
private String city;
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class Response {
|
||||
|
||||
/**
|
||||
* 城市名称
|
||||
*/
|
||||
private String city;
|
||||
|
||||
/**
|
||||
* 天气信息
|
||||
*/
|
||||
private WeatherInfo weatherInfo;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class WeatherInfo {
|
||||
|
||||
/**
|
||||
* 温度(摄氏度)
|
||||
*/
|
||||
private Integer temperature;
|
||||
|
||||
/**
|
||||
* 天气状况
|
||||
*/
|
||||
private String condition;
|
||||
|
||||
/**
|
||||
* 湿度百分比
|
||||
*/
|
||||
private Integer humidity;
|
||||
|
||||
/**
|
||||
* 风速(km/h)
|
||||
*/
|
||||
private Integer windSpeed;
|
||||
|
||||
/**
|
||||
* 查询时间
|
||||
*/
|
||||
private String queryTime;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response apply(Request request) {
|
||||
// 检查城市名称是否为空
|
||||
if (StrUtil.isBlank(request.getCity())) {
|
||||
return new Response("未知城市", null);
|
||||
}
|
||||
|
||||
// 获取天气数据
|
||||
String city = request.getCity();
|
||||
Response.WeatherInfo weatherInfo = generateMockWeatherInfo();
|
||||
return new Response(city, weatherInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成模拟的天气数据
|
||||
* 在实际应用中,应替换为真实 API 调用
|
||||
*/
|
||||
private Response.WeatherInfo generateMockWeatherInfo() {
|
||||
int temperature = RandomUtil.randomInt(-5, 30);
|
||||
int humidity = RandomUtil.randomInt(1, 100);
|
||||
int windSpeed = RandomUtil.randomInt(1, 30);
|
||||
String condition = RandomUtil.randomEle(WEATHER_CONDITIONS);
|
||||
return new Response.WeatherInfo(temperature, condition, humidity, windSpeed,
|
||||
LocalDateTimeUtil.format(LocalDateTime.now(), NORM_DATETIME_PATTERN));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1 @@
|
||||
package cn.iocoder.yudao.module.ai.service.tool;
|
Reference in New Issue
Block a user