fix(memory): preserve session search agent id

This commit is contained in:
matevip 2026-08-13 03:51:42 -04:00
parent 06105faa4d
commit cabff7e498
2 changed files with 51 additions and 3 deletions

View File

@ -38,7 +38,7 @@ public class SessionSearchTool {
注意只会搜索已完成的会话不会返回当前正在运行中的其他会话内容
""")
public String session_search(
@ToolParam(description = "当前 Agent 的 ID") Long agentId,
@ToolParam(description = "当前 Agent 的 ID。必须作为字符串传入,避免大整数精度丢失") String agentId,
@ToolParam(description = "搜索模式recent 或 search") String mode,
@ToolParam(description = "搜索关键词mode=search 时必填)", required = false) String query,
@ToolParam(description = "返回结果数量上限,默认 10", required = false) Integer limit,
@ -64,13 +64,14 @@ public class SessionSearchTool {
int effectiveLimit = limit != null && limit > 0 ? limit : 10;
try {
Long parsedAgentId = parseAgentId(agentId);
if ("recent".equalsIgnoreCase(mode.trim())) {
return handleRecent(agentId, currentConversationId, effectiveLimit);
return handleRecent(parsedAgentId, currentConversationId, effectiveLimit);
} else if ("search".equalsIgnoreCase(mode.trim())) {
if (query == null || query.isBlank()) {
return error("mode=search 时 query 不能为空");
}
return handleSearch(agentId, currentConversationId, query, effectiveLimit);
return handleSearch(parsedAgentId, currentConversationId, query, effectiveLimit);
} else {
return error("无效的 mode: " + mode + ",请使用 recent 或 search");
}
@ -117,4 +118,16 @@ public class SessionSearchTool {
result.set("message", message);
return JSONUtil.toJsonPrettyStr(result);
}
private Long parseAgentId(String agentId) {
String trimmed = agentId != null ? agentId.trim() : "";
if (trimmed.isEmpty()) {
throw new IllegalArgumentException("agentId 不能为空");
}
try {
return Long.parseLong(trimmed);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("agentId 必须是数字字符串");
}
}
}

View File

@ -0,0 +1,35 @@
package vip.mate.memory.search;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.ai.support.ToolCallbacks;
import org.springframework.ai.tool.ToolCallback;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
class SessionSearchToolIdSchemaTest {
private static final ObjectMapper MAPPER = new ObjectMapper();
@Test
@DisplayName("session_search publishes agentId as a string parameter so LLM tool calls preserve precision")
void sessionSearchAgentIdSchemaIsString() throws Exception {
SessionSearchTool tool = new SessionSearchTool(mock(SessionSearchService.class));
String schema = callback(tool, "session_search").getToolDefinition().inputSchema();
JsonNode root = MAPPER.readTree(schema);
assertThat(root.at("/properties/agentId/type").asText()).isEqualTo("string");
}
private static ToolCallback callback(Object tool, String name) {
for (ToolCallback callback : ToolCallbacks.from(tool)) {
if (name.equals(callback.getToolDefinition().name())) {
return callback;
}
}
throw new AssertionError("Missing tool callback: " + name);
}
}