Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
import modelengine.fel.tool.info.entity.ReturnPropertyEntity;
import modelengine.fel.tool.info.entity.SchemaEntity;
import modelengine.fitframework.annotation.Property;
import modelengine.fitframework.annotation.util.PropertyHelper;
import modelengine.fitframework.util.StringUtils;

import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.method.ParameterDescription;

import static modelengine.fitframework.inspection.Validation.notNull;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
Expand Down Expand Up @@ -79,7 +80,9 @@ private static Map<String, Object> getStringObjectMap(ReturnPropertyEntity retur
if (returnPropertyEntity.getConvertor() != null) {
returnProperty.put("convertor", returnPropertyEntity.getConvertor());
}
returnProperty.put("examples", returnPropertyEntity.getExamples());
if (returnPropertyEntity.getExamples() != null) {
returnProperty.put("examples", returnPropertyEntity.getExamples());
}
return returnProperty;
}

Expand Down Expand Up @@ -113,8 +116,14 @@ private static PropertyEntity parseProperty(ParameterDescription parameterDescri
Property property = paramAnnotation.load();
entity.setDescription(property.description());
entity.setNeed(property.required());
entity.setDefaultValue(property.defaultValue());
entity.setExamples(Collections.singletonList(property.example()));
String defaultValue = property.defaultValue();
if (defaultValue != null && PropertyHelper.isCustomValue(defaultValue)) {
entity.setDefaultValue(defaultValue);
}
String example = property.example();
if (StringUtils.isNotEmpty(example)) {
entity.setExamples(Collections.singletonList(example));
}
}
return entity;
}
Expand All @@ -127,7 +136,10 @@ private static ReturnPropertyEntity parseReturnProperty(MethodDescription method
Property property = returnAnnotation.load();
returnPropertyEntity.setName(property.name());
returnPropertyEntity.setDescription(property.description());
returnPropertyEntity.setExamples(Collections.singletonList(property.example()));
String example = property.example();
if (StringUtils.isNotEmpty(example)) {
returnPropertyEntity.setExamples(Collections.singletonList(example));
}
}
notNull(methodDescription.getReturnType(), "The return type cannot be null.");
JsonNode jsonNode = JacksonTypeParser.getParameterSchema(methodDescription.getReturnType());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ public interface Rain {
*/
@ToolMethod(name = "rain_today", description = "该方法获取今天的下雨信息")
@Genericable("genericable_weather_rain_today")
String today(@Property(description = "查询地点", required = true, example = "Hangzhou") String location,
@Property(description = "查询日期", required = true) Date date,
String today(@Property(description = "查询地点", required = true, defaultValue = "Shanghai", example = "Hangzhou")
String location, @Property(description = "查询日期", required = true) Date date,
@Property(description = "下雨的经纬度") RainPosition rainPosition,
@Property(description = "其他信息") Object info);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,12 @@
"name" : "location",
"type" : "string",
"examples" : [ "Hangzhou" ],
"default" : ""
"default" : "Shanghai"
},
"date" : {
"description" : "查询日期",
"name" : "date",
"type" : "string",
"examples" : [ "" ],
"default" : ""
"type" : "string"
},
"rainPosition" : {
"description" : "下雨的经纬度",
Expand All @@ -38,17 +36,13 @@
"type" : "string"
}
},
"examples" : [ "" ],
"required" : [ "latitude", "longitude" ],
"default" : ""
"required" : [ "latitude", "longitude" ]
},
"info" : {
"description" : "其他信息",
"name" : "info",
"type" : "object",
"properties" : { },
"examples" : [ "" ],
"default" : ""
"properties" : { }
}
},
"required" : [ "location", "date" ]
Expand Down Expand Up @@ -136,8 +130,7 @@
"name" : "",
"description" : "获取今日下雨信息的结果",
"type" : "string",
"convertor" : "",
"examples" : [ "" ]
"convertor" : ""
}
},
"runnables" : {
Expand Down Expand Up @@ -174,8 +167,7 @@
"name" : "",
"description" : "获取明日下雨信息的结果",
"type" : "string",
"convertor" : "",
"examples" : [ "" ]
"convertor" : ""
}
},
"runnables" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import modelengine.fel.tool.annotation.Group;
import modelengine.fel.tool.annotation.ToolMethod;
import modelengine.fitframework.annotation.Property;
import modelengine.fitframework.annotation.util.PropertyHelper;
import modelengine.fitframework.json.schema.JsonSchemaManager;
import modelengine.fitframework.util.MapBuilder;
import modelengine.fitframework.util.StringUtils;
Expand Down Expand Up @@ -67,7 +68,10 @@ public Object parameterDefaultValue(String name) {
// TODO 需要考虑注解值的类型匹配与基础类型的默认值问题
Property annotation = parameter.getDeclaredAnnotation(Property.class);
if (annotation != null) {
return annotation.defaultValue();
String defaultValue = annotation.defaultValue();
if (defaultValue != null && PropertyHelper.isCustomValue(defaultValue)) {
return defaultValue;
}
}
return null;
}).orElse(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,20 +185,42 @@ void shouldReturnParameterIndex() {
assertThat(actual).isEqualTo(0);
}

@Test
@DisplayName("当参数名称不存在时,返回 -1 序号")
void shouldReturnParameterIndexNegativeWhenNameNotExists() {
int actual = this.toolMetadata.parameterIndex("NotExists");
assertThat(actual).isEqualTo(-1);
}

@Test
@DisplayName("返回正确的必须参数名字列表")
void shouldReturnRequired() {
Set<String> parameterNames = this.toolMetadata.requiredParameters();
assertThat(parameterNames).containsExactly("P1");
}

@Test
@DisplayName("当参数为基础类型时,必须参数应包含该参数")
void shouldReturnRequiredWhenPrimitiveParam() throws NoSuchMethodException {
Method primitiveMethod = PrimitiveInterface.class.getDeclaredMethod("primitiveMethod", int.class);
Tool.Metadata primitiveMetadata = Tool.Metadata.fromMethod(primitiveMethod);
Set<String> required = primitiveMetadata.requiredParameters();
assertThat(required).containsExactly("i");
}

@Test
@DisplayName("返回正确的返回值类型")
void shouldReturnReturnType() {
Map<String, Object> type = this.toolMetadata.returnType();
assertThat(type).isEqualTo(JsonSchemaManager.create().createSchema(String.class).toJsonObject());
}

@Test
@DisplayName("返回转换器字符串为空")
void shouldReturnEmptyReturnConverter() {
assertThat(this.toolMetadata.returnConverter()).isEqualTo("");
}

@Test
@DisplayName("返回正确的格式规范描述")
void shouldReturnSchema() {
Expand All @@ -217,6 +239,23 @@ void shouldReturnDefaultValueNull() {
assertThat(definitionGroupName).isNotNull();
}

@Test
@DisplayName("参数默认值非自定义占位时应为 null")
void shouldReturnNullParameterDefaultValueWhenNotCustom() {
Object defaultValue = this.toolMetadata.parameterDefaultValue("P1");
assertThat(defaultValue).isEqualTo("default_value");
}

@Test
@DisplayName("返回方法、名称、分组与描述信息正确")
void shouldReturnMethodAndDefinitions() {
assertThat(this.toolMetadata.getMethod()).isPresent();
assertThat(this.toolMetadata.getMethod().orElse(null)).isEqualTo(this.testMethod);
assertThat(this.toolMetadata.definitionName()).isEqualTo("test_tool_def_name");
assertThat(this.toolMetadata.definitionGroupName()).isEqualTo("test_def_group_name");
assertThat(this.toolMetadata.description()).isEqualTo("测试方法的描述信息");
}

@Group(name = "test_def_group_name")
interface TestInterface {
/**
Expand All @@ -229,4 +268,10 @@ interface TestInterface {
@Genericable(id = "t1", description = "desc")
String testMethod(@Property(name = "P1", required = true, defaultValue = "default_value") String p1);
}

@Group(name = "primitive_group")
interface PrimitiveInterface {
@ToolMethod(name = "primitive_tool", description = "primitive")
int primitiveMethod(@Property(name = "i") int i);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
public @interface Property {
/**
* 表示未设置默认值的标记常量。
*/
String UNSET_DEFAULT_VALUE = "$$Fit$UnsetDefaultValue$$";

/**
* 获取参数的名字。
*
Expand All @@ -50,7 +55,7 @@
*
* @return 表示参数的默认值的 {@link String}。
*/
String defaultValue() default StringUtils.EMPTY;
String defaultValue() default UNSET_DEFAULT_VALUE;

/**
* 获取参数的样例值。
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
* This file is a part of the ModelEngine Project.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

package modelengine.fitframework.annotation.util;

import modelengine.fitframework.annotation.Property;

/**
* 为 Property 注解提供工具类。
*
* @author 杭潇
* @since 2025-10-29
*/
public final class PropertyHelper {
/**
* 隐藏默认构造方法,避免工具类被实例化。
*/
private PropertyHelper() {}

/**
* 判断给定的默认值是否为设置状态。
*
* @param defaultValue 要检查的默认值。
* @return 如果自定义参数值则返回 {@code true},否则返回 {@code false}。
*/
public static boolean isCustomValue(String defaultValue) {
return !Property.UNSET_DEFAULT_VALUE.equals(defaultValue);
}
}