Skip to content
AgentEnsemble AgentEnsemble
Get Started

Network Testing

AgentEnsemble provides test doubles for NetworkTask and NetworkTool so you can test ensembles in isolation without real WebSocket connections.

Stubs return a canned response on every invocation. Use them when you need predictable behavior from a remote capability:

// Stub a task
StubNetworkTask mealStub = NetworkTask.stub("kitchen", "prepare-meal",
"Meal prepared: wagyu steak, medium-rare. Estimated 25 minutes.");
// Stub a tool
StubNetworkTool inventoryStub = NetworkTool.stub("kitchen", "check-inventory",
"3 portions available");
// Use in an ensemble
Ensemble roomService = Ensemble.builder()
.chatLanguageModel(model)
.task(Task.builder()
.description("Handle room service request")
.tools(mealStub, inventoryStub)
.build())
.build();
EnsembleOutput result = roomService.run();

Recordings capture every request for later assertion. Use them to verify what your ensemble sends to remote capabilities:

RecordingNetworkTask recorder = NetworkTask.recording("kitchen", "prepare-meal");
Ensemble roomService = Ensemble.builder()
.chatLanguageModel(model)
.task(Task.builder()
.description("Handle room service request")
.tools(recorder)
.build())
.build();
roomService.run();
// Assert what was sent
assertThat(recorder.callCount()).isEqualTo(1);
assertThat(recorder.lastRequest()).contains("wagyu");
assertThat(recorder.requests()).hasSize(1);

By default, recordings return "recorded". You can provide a custom response:

RecordingNetworkTask recorder = NetworkTask.recording("kitchen", "prepare-meal",
"Meal prepared in 25 minutes");

Both stubs and recordings use the same name() format as real network tools: "ensemble.capability" (e.g., "kitchen.prepare-meal").

All test doubles are thread-safe. RecordingNetworkTask and RecordingNetworkTool use CopyOnWriteArrayList internally, so concurrent calls from parallel tool execution are safely recorded.

MethodDescription
execute(input)Returns the canned response as ToolResult.success()
name()Returns "ensemble.task" format
ensembleName()The configured ensemble name
taskName() / toolName()The configured task/tool name
cannedResponse() / cannedResult()The configured canned response

RecordingNetworkTask / RecordingNetworkTool

Section titled “RecordingNetworkTask / RecordingNetworkTool”
MethodDescription
execute(input)Records the input and returns the default response
callCount()Number of times invoked
lastRequest()Most recent input (throws if none)
requests()Immutable list of all inputs
name()Returns "ensemble.task" format