mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 03:13:41 +08:00
fix: preserve agent id precision in memory tools
This commit is contained in:
parent
4d9e7b024f
commit
b8a8aac7f9
@ -111,7 +111,7 @@ public class StructuredMemoryTool {
|
||||
readOwner(toolContext));
|
||||
|
||||
JSONObject result = new JSONObject();
|
||||
result.set("agentId", agentId);
|
||||
result.set("agentId", String.valueOf(agentId));
|
||||
result.set("count", results.size());
|
||||
result.set("entries", results);
|
||||
return JSONUtil.toJsonPrettyStr(result);
|
||||
|
||||
@ -87,7 +87,7 @@ public class WorkspaceMemoryTool {
|
||||
}
|
||||
|
||||
JSONObject result = new JSONObject();
|
||||
result.set("agentId", agentId);
|
||||
result.set("agentId", String.valueOf(agentId));
|
||||
result.set("count", files.size());
|
||||
result.set("files", items);
|
||||
return JSONUtil.toJsonPrettyStr(result);
|
||||
@ -118,7 +118,7 @@ public class WorkspaceMemoryTool {
|
||||
memoryRecallTracker.trackActiveRetrieval(agentId, filename, content);
|
||||
|
||||
JSONObject result = new JSONObject();
|
||||
result.set("agentId", agentId);
|
||||
result.set("agentId", String.valueOf(agentId));
|
||||
result.set("filename", file.getFilename());
|
||||
result.set("enabled", Boolean.TRUE.equals(file.getEnabled()));
|
||||
result.set("fileSize", file.getFileSize());
|
||||
@ -154,7 +154,7 @@ public class WorkspaceMemoryTool {
|
||||
WorkspaceFileEntity saved = workspaceFileService.saveVisibleFile(agentId, filename, content != null ? content : "", ownerKey);
|
||||
|
||||
JSONObject result = new JSONObject();
|
||||
result.set("agentId", agentId);
|
||||
result.set("agentId", String.valueOf(agentId));
|
||||
result.set("filename", saved.getFilename());
|
||||
result.set("created", before == null);
|
||||
result.set("overwritten", before != null);
|
||||
@ -222,7 +222,7 @@ public class WorkspaceMemoryTool {
|
||||
WorkspaceFileEntity saved = workspaceFileService.saveVisibleFile(agentId, filename, updated, ownerKey);
|
||||
|
||||
JSONObject result = new JSONObject();
|
||||
result.set("agentId", agentId);
|
||||
result.set("agentId", String.valueOf(agentId));
|
||||
result.set("filename", filename);
|
||||
result.set("replacements", replacements);
|
||||
result.set("replaceAll", replaceAllFlag);
|
||||
@ -296,7 +296,7 @@ public class WorkspaceMemoryTool {
|
||||
hitsJson.add(h);
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
result.set("agentId", agentId);
|
||||
result.set("agentId", String.valueOf(agentId));
|
||||
result.set("query", trimmed);
|
||||
result.set("scope", scope == null || scope.isBlank() ? "all" : scope);
|
||||
result.set("totalHits", hits.size());
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
package vip.mate.memory.tool;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import vip.mate.memory.MemoryProperties;
|
||||
import vip.mate.memory.identity.MemoryOwnerResolver;
|
||||
import vip.mate.memory.service.StructuredMemoryService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class StructuredMemoryToolIdSerializationTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("recall_structured returns agentId as a JSON string to preserve snowflake precision")
|
||||
void recallStructuredSerializesAgentIdAsString() {
|
||||
StructuredMemoryService service = mock(StructuredMemoryService.class);
|
||||
when(service.recall(anyLong(), nullable(String.class), nullable(String.class), anyString()))
|
||||
.thenReturn(List.of());
|
||||
StructuredMemoryTool tool = new StructuredMemoryTool(
|
||||
service,
|
||||
new MemoryOwnerResolver(),
|
||||
new MemoryProperties());
|
||||
|
||||
String json = tool.recall_structured(2079862124134313986L, "reference", "meeting", null);
|
||||
|
||||
assertThat(json).contains("\"agentId\": \"2079862124134313986\"");
|
||||
assertThat(json).doesNotContain("\"agentId\": 2079862124134313986");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package vip.mate.tool.builtin;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import vip.mate.memory.MemoryProperties;
|
||||
import vip.mate.memory.identity.MemoryOwnerResolver;
|
||||
import vip.mate.memory.service.MemoryRecallTracker;
|
||||
import vip.mate.workspace.document.WorkspaceFileService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class WorkspaceMemoryToolIdSerializationTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("search_workspace_memory returns agentId as a JSON string to preserve snowflake precision")
|
||||
void searchWorkspaceMemorySerializesAgentIdAsString() {
|
||||
WorkspaceFileService files = mock(WorkspaceFileService.class);
|
||||
when(files.searchSnippets(anyLong(), anyString(), anySet(), anyInt(), anyString()))
|
||||
.thenReturn(List.of());
|
||||
WorkspaceMemoryTool tool = new WorkspaceMemoryTool(
|
||||
files,
|
||||
mock(MemoryRecallTracker.class),
|
||||
new MemoryOwnerResolver(),
|
||||
new MemoryProperties());
|
||||
|
||||
String json = tool.search_workspace_memory(2079862124134313986L, "meeting", "all", 10, null);
|
||||
|
||||
assertThat(json).contains("\"agentId\": \"2079862124134313986\"");
|
||||
assertThat(json).doesNotContain("\"agentId\": 2079862124134313986");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { buildChatStreamRequestBody } from '../useChat'
|
||||
|
||||
describe('buildChatStreamRequestBody', () => {
|
||||
it('serializes agentId as a string before JSON.stringify touches the request body', () => {
|
||||
const body = buildChatStreamRequestBody('', {
|
||||
conversationId: 'wecom:2079870010935783426:DeBaDe',
|
||||
agentId: '2079862124134313986',
|
||||
contentParts: [],
|
||||
})
|
||||
|
||||
expect(body.agentId).toBe('2079862124134313986')
|
||||
expect(JSON.stringify(body)).toContain('"agentId":"2079862124134313986"')
|
||||
})
|
||||
})
|
||||
@ -193,6 +193,26 @@ export interface SendMessageOptions {
|
||||
regenerate?: boolean
|
||||
}
|
||||
|
||||
export function buildChatStreamRequestBody(content: string, options: SendMessageOptions): Record<string, any> {
|
||||
const body: Record<string, any> = {
|
||||
agentId: String(options.agentId),
|
||||
message: content,
|
||||
conversationId: options.conversationId,
|
||||
contentParts: options.contentParts || [],
|
||||
}
|
||||
if (options.thinkingLevel) {
|
||||
body.thinkingLevel = options.thinkingLevel
|
||||
}
|
||||
if (options.modelProvider && options.modelName) {
|
||||
body.modelProvider = options.modelProvider
|
||||
body.modelName = options.modelName
|
||||
}
|
||||
if (options.regenerate) {
|
||||
body.regenerate = true
|
||||
}
|
||||
return body
|
||||
}
|
||||
|
||||
export function useChat(options: UseChatOptions): UseChatReturn {
|
||||
const { baseUrl, token, onStreamEnd } = options
|
||||
const thinkingLevelRef = options.thinkingLevel
|
||||
@ -2027,24 +2047,7 @@ export function useChat(options: UseChatOptions): UseChatReturn {
|
||||
currentAssistantId.value = assistantMessage.id as string
|
||||
|
||||
// contentParts already includes file entries from buildOutgoingParts — do not re-merge attachments
|
||||
const body: Record<string, any> = {
|
||||
agentId,
|
||||
message: content,
|
||||
conversationId,
|
||||
contentParts,
|
||||
}
|
||||
if (options.thinkingLevel) {
|
||||
body.thinkingLevel = options.thinkingLevel
|
||||
}
|
||||
// Per-conversation model: the backend pins it onto the conversation row
|
||||
// so switching the model here never leaks into other conversations.
|
||||
if (options.modelProvider && options.modelName) {
|
||||
body.modelProvider = options.modelProvider
|
||||
body.modelName = options.modelName
|
||||
}
|
||||
if (options.regenerate) {
|
||||
body.regenerate = true
|
||||
}
|
||||
const body = buildChatStreamRequestBody(content, { ...options, contentParts })
|
||||
await stream.connect(body)
|
||||
} catch (e) {
|
||||
error.value = e instanceof Error ? e : new Error(String(e))
|
||||
@ -2071,7 +2074,7 @@ export function useChat(options: UseChatOptions): UseChatReturn {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
message: content,
|
||||
agentId,
|
||||
agentId: String(agentId),
|
||||
contentParts: options.contentParts || [],
|
||||
}),
|
||||
})
|
||||
|
||||
Loading…
Reference in New Issue
Block a user