feat: 标准化 Agent AG-UI 与审批运行时
- 新增 AG-UI 事件投影与协议编码模块 - 支持 Turn 级审批作用域和受信任动态审批策略
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
package com.easyagents.agui;
|
||||
|
||||
import com.easyagents.agent.runtime.event.AgentRuntimeEvent;
|
||||
import com.easyagents.agent.runtime.event.AgentRuntimeEventType;
|
||||
import io.agentscope.core.agui.event.AguiEvent;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* {@link AguiRuntimeEventProjector} 的协议顺序与终态测试。
|
||||
*/
|
||||
public class AguiRuntimeEventProjectorTest {
|
||||
|
||||
/**
|
||||
* 验证文本、推理、工具和成功终态按 AG-UI 顺序投影。
|
||||
*/
|
||||
@Test
|
||||
public void shouldProjectSuccessfulRunInProtocolOrder() {
|
||||
AguiRuntimeEventProjector projector = new AguiRuntimeEventProjector("thread-1", "run-1");
|
||||
List<Object> events = new ArrayList<>();
|
||||
|
||||
events.addAll(projector.project(event(AgentRuntimeEventType.STARTED, null, null, Map.of())));
|
||||
events.addAll(projector.project(event(
|
||||
AgentRuntimeEventType.REASONING_STARTED, "reasoning-1", null, Map.of())));
|
||||
events.addAll(projector.project(event(
|
||||
AgentRuntimeEventType.REASONING_DELTA, "reasoning-1", null, Map.of("reasoning", "分析"))));
|
||||
events.addAll(projector.project(event(
|
||||
AgentRuntimeEventType.REASONING_COMPLETED, "reasoning-1", null, Map.of())));
|
||||
events.addAll(projector.project(event(
|
||||
AgentRuntimeEventType.MESSAGE_DELTA, "message-1", null, Map.of("text", "你好"))));
|
||||
events.addAll(projector.project(event(
|
||||
AgentRuntimeEventType.TOOL_CALL, null, "tool-1",
|
||||
Map.of("toolName", "search", "input", Map.of("q", "AG-UI")))));
|
||||
events.addAll(projector.project(event(
|
||||
AgentRuntimeEventType.TOOL_RESULT, null, "tool-1", Map.of("text", "done"))));
|
||||
events.addAll(projector.project(event(AgentRuntimeEventType.COMPLETED, null, null, Map.of())));
|
||||
|
||||
Assert.assertEquals(List.of(
|
||||
"RunStarted",
|
||||
"ReasoningMessageStart",
|
||||
"ReasoningMessageContent",
|
||||
"ReasoningMessageEnd",
|
||||
"TextMessageStart",
|
||||
"TextMessageContent",
|
||||
"ToolCallStart",
|
||||
"ToolCallArgs",
|
||||
"ToolCallEnd",
|
||||
"ToolCallResult",
|
||||
"TextMessageEnd",
|
||||
"RunFinished"), events.stream().map(value -> value.getClass().getSimpleName()).toList());
|
||||
Assert.assertEquals(
|
||||
"reasoning", ((AguiEvent.ReasoningMessageStart) events.get(1)).role());
|
||||
Assert.assertTrue(projector.isTerminated());
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证失败终态不会追加成功事件,终态后的迟到事件会被丢弃。
|
||||
*/
|
||||
@Test
|
||||
public void shouldEmitSingleErrorTerminalAndIgnoreLateEvents() {
|
||||
AguiRuntimeEventProjector projector = new AguiRuntimeEventProjector("thread-1", "run-1");
|
||||
|
||||
List<Object> failed = projector.project(event(
|
||||
AgentRuntimeEventType.FAILED, null, null, Map.of("message", "boom")));
|
||||
List<Object> late = projector.project(event(AgentRuntimeEventType.COMPLETED, null, null, Map.of()));
|
||||
|
||||
Assert.assertEquals(2, failed.size());
|
||||
Assert.assertTrue(failed.get(0) instanceof AguiEvent.RunStarted);
|
||||
Assert.assertEquals(
|
||||
new AguiExtendedEvent.RunError("thread-1", "run-1", "boom", "AGENT_RUNTIME_FAILED"),
|
||||
failed.get(1));
|
||||
Assert.assertTrue(late.isEmpty());
|
||||
}
|
||||
|
||||
private static AgentRuntimeEvent event(
|
||||
AgentRuntimeEventType type,
|
||||
String messageId,
|
||||
String toolCallId,
|
||||
Map<String, Object> payload) {
|
||||
AgentRuntimeEvent event = AgentRuntimeEvent.of(type);
|
||||
event.setMessageId(messageId);
|
||||
event.setToolCallId(toolCallId);
|
||||
event.setPayload(payload);
|
||||
return event;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user