test(agent-core): add ReActAgentComponent end-to-end test with FakeEchoModel

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
everywhere.z
2026-04-19 19:56:48 +08:00
parent 17d5deefc7
commit 404f55c94e
2 changed files with 129 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
package com.yomahub.liteflow.agent.component;
import io.agentscope.core.message.ContentBlock;
import io.agentscope.core.message.Msg;
import io.agentscope.core.message.TextBlock;
import io.agentscope.core.model.ChatResponse;
import io.agentscope.core.model.GenerateOptions;
import io.agentscope.core.model.Model;
import io.agentscope.core.model.ToolSchema;
import reactor.core.publisher.Flux;
import java.util.List;
/**
* Minimal {@link Model} implementation for tests. Returns a fixed
* "[echo]" text response regardless of input.
*/
public class FakeEchoModel implements Model {
@Override
public Flux<ChatResponse> stream(List<Msg> messages, List<ToolSchema> toolSchemas, GenerateOptions options) {
ChatResponse resp = ChatResponse.builder()
.id("fake-id")
.content(List.of(TextBlock.builder().text("[echo]").build()))
.finishReason("stop")
.build();
return Flux.just(resp);
}
@Override
public String getModelName() {
return "fake-echo-model";
}
}

View File

@@ -0,0 +1,95 @@
package com.yomahub.liteflow.agent.component;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.flow.element.Node;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.property.LiteflowConfigGetter;
import com.yomahub.liteflow.property.agent.AgentConfig;
import com.yomahub.liteflow.property.agent.ShellMode;
import com.yomahub.liteflow.slot.DataBus;
import com.yomahub.liteflow.slot.Slot;
import io.agentscope.core.model.Model;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.io.TempDir;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import static org.junit.jupiter.api.Assertions.*;
class ReActAgentComponentTest {
@TempDir
Path tmp;
@BeforeEach
void init() {
AgentConfig agent = new AgentConfig();
agent.getWorkspace().setRoot(tmp.toString());
agent.getShell().setMode(ShellMode.DISABLED);
LiteflowConfig cfg = new LiteflowConfig();
cfg.setAgent(agent);
LiteflowConfigGetter.setLiteflowConfig(cfg);
DataBus.init();
}
@AfterEach
void cleanup() {
ReActAgentComponent.AgentSessionManagerHolder.resetForTesting();
LiteflowConfigGetter.clean();
}
/**
* Concrete subclass under test.
*/
static class TestAgent extends ReActAgentComponent {
@Override
protected Model buildModel(ReActAgentContext ctx) { return new FakeEchoModel(); }
@Override
protected String systemPrompt(ReActAgentContext ctx) { return "you are helpful"; }
@Override
protected String userPrompt(ReActAgentContext ctx) {
return (String) ctx.getSlot().getChainReqData(ctx.getSlot().getChainId());
}
}
/**
* End-to-end test: process() builds an agent, calls it, and writes the reply
* into the slot's response data. Also verifies that the session workspace
* directory is created.
*/
@Test
void process_creates_workspace_and_writes_response() throws Exception {
// 1. Create a slot via DataBus
int slotIndex = DataBus.offerSlotByBean(Collections.emptyList());
Slot slot = DataBus.getSlot(slotIndex);
slot.putRequestId("req-1");
String chainId = "testChain";
slot.setChainId(chainId);
slot.setChainReqData(chainId, "hello");
// 2. Wire the NodeComponent into a Node with the slot index
TestAgent agent = new TestAgent();
agent.setNodeId("testAgent");
Node node = new Node();
node.setInstance(agent);
node.setSlotIndex(slotIndex);
node.setCurrChainId(chainId);
agent.setRefNode(node);
// 3. Execute
agent.process();
// 4. Verify workspace was created
assertTrue(Files.isDirectory(tmp.resolve("req-1")),
"session workspace directory should exist under the temp root");
// 5. Verify response data
assertEquals("[echo]", slot.getResponseData(),
"response data should be the fake echo text");
// 6. Cleanup
DataBus.releaseSlot(slotIndex);
}
}