Skip to content

Commit 229b0c6

Browse files
updated tests
1 parent 5db7569 commit 229b0c6

File tree

23 files changed

+618
-3249
lines changed

23 files changed

+618
-3249
lines changed
Lines changed: 41 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,129 +1,64 @@
11
"""
2-
Sample tests for AgentEx ACP agent.
2+
Tests for s000-hello-acp (sync agent)
33
4-
This test suite demonstrates how to test the main AgentEx API functions:
4+
This test suite demonstrates testing a sync agent using the AgentEx testing framework.
5+
6+
Test coverage:
57
- Non-streaming message sending
68
- Streaming message sending
7-
- Task creation via RPC
89
9-
To run these tests:
10-
1. Make sure the agent is running (via docker-compose or `agentex agents run`)
11-
2. Set the AGENTEX_API_BASE_URL environment variable if not using default
12-
3. Run: pytest test_agent.py -v
10+
Prerequisites:
11+
- AgentEx services running (make dev)
12+
- Agent running: agentex agents run --manifest manifest.yaml
1313
14-
Configuration:
15-
- AGENTEX_API_BASE_URL: Base URL for the AgentEx server (default: http://localhost:5003)
16-
- AGENT_NAME: Name of the agent to test (default: hello-acp)
14+
Run tests:
15+
pytest tests/test_agent.py -v
1716
"""
1817

19-
import os
18+
from agentex.lib.testing import (
19+
test_sync_agent,
20+
collect_streaming_deltas,
21+
assert_valid_agent_response,
22+
)
2023

21-
import pytest
24+
AGENT_NAME = "s000-hello-acp"
2225

23-
from agentex import Agentex
24-
from agentex.types import TextDelta, TextContent, TextContentParam
25-
from agentex.types.agent_rpc_params import ParamsSendMessageRequest
26-
from agentex.types.task_message_update import StreamTaskMessageFull, StreamTaskMessageDelta
2726

28-
# Configuration from environment variables
29-
AGENTEX_API_BASE_URL = os.environ.get("AGENTEX_API_BASE_URL", "http://localhost:5003")
30-
AGENT_NAME = os.environ.get("AGENT_NAME", "s000-hello-acp")
27+
def test_send_simple_message():
28+
"""Test sending a simple message and receiving a response."""
29+
with test_sync_agent(agent_name=AGENT_NAME) as test:
30+
message_content = "Hello, Agent! How are you?"
31+
response = test.send_message(message_content)
3132

33+
# Validate response
34+
assert_valid_agent_response(response)
3235

33-
@pytest.fixture
34-
def client():
35-
"""Create an AgentEx client instance for testing."""
36-
client = Agentex(base_url=AGENTEX_API_BASE_URL)
37-
yield client
38-
# Clean up: close the client connection
39-
client.close()
36+
# Check expected response format
37+
expected = f"Hello! I've received your message. Here's a generic response, but in future tutorials we'll see how you can get me to intelligently respond to your message. This is what I heard you say: {message_content}"
38+
assert response.content == expected, f"Expected: {expected}\nGot: {response.content}"
4039

4140

42-
@pytest.fixture
43-
def agent_name():
44-
"""Return the agent name for testing."""
45-
return AGENT_NAME
41+
def test_stream_simple_message():
42+
"""Test streaming a simple message and aggregating deltas."""
43+
with test_sync_agent(agent_name=AGENT_NAME) as test:
44+
message_content = "Hello, Agent! Can you stream your response?"
4645

46+
# Get streaming response
47+
response_gen = test.send_message_streaming(message_content)
4748

48-
class TestNonStreamingMessages:
49-
"""Test non-streaming message sending."""
49+
# Collect streaming deltas
50+
aggregated_content, chunks = collect_streaming_deltas(response_gen)
5051

51-
def test_send_simple_message(self, client: Agentex, agent_name: str):
52-
"""Test sending a simple message and receiving a response."""
52+
# Validate we got content
53+
assert len(chunks) > 0, "Should receive at least one chunk"
54+
assert len(aggregated_content) > 0, "Should receive content"
5355

54-
message_content = "Hello, Agent! How are you?"
55-
response = client.agents.send_message(
56-
agent_name=agent_name,
57-
params=ParamsSendMessageRequest(
58-
content=TextContentParam(
59-
author="user",
60-
content=message_content,
61-
type="text",
62-
)
63-
),
64-
)
65-
result = response.result
66-
assert result is not None
67-
assert len(result) == 1
68-
message = result[0]
69-
assert isinstance(message.content, TextContent)
70-
assert (
71-
message.content.content
72-
== f"Hello! I've received your message. Here's a generic response, but in future tutorials we'll see how you can get me to intelligently respond to your message. This is what I heard you say: {message_content}"
73-
)
74-
75-
76-
class TestStreamingMessages:
77-
"""Test streaming message sending."""
78-
79-
def test_stream_simple_message(self, client: Agentex, agent_name: str):
80-
"""Test streaming a simple message and aggregating deltas."""
81-
82-
message_content = "Hello, Agent! Can you stream your response?"
83-
aggregated_content = ""
84-
full_content = ""
85-
received_chunks = False
86-
87-
for chunk in client.agents.send_message_stream(
88-
agent_name=agent_name,
89-
params=ParamsSendMessageRequest(
90-
content=TextContentParam(
91-
author="user",
92-
content=message_content,
93-
type="text",
94-
)
95-
),
96-
):
97-
received_chunks = True
98-
task_message_update = chunk.result
99-
# Collect text deltas as they arrive or check full messages
100-
if isinstance(task_message_update, StreamTaskMessageDelta) and task_message_update.delta is not None:
101-
delta = task_message_update.delta
102-
if isinstance(delta, TextDelta) and delta.text_delta is not None:
103-
aggregated_content += delta.text_delta
104-
105-
elif isinstance(task_message_update, StreamTaskMessageFull):
106-
content = task_message_update.content
107-
if isinstance(content, TextContent):
108-
full_content = content.content
109-
110-
if not full_content and not aggregated_content:
111-
raise AssertionError("No content was received in the streaming response.")
112-
if not received_chunks:
113-
raise AssertionError("No streaming chunks were received, when at least 1 was expected.")
114-
115-
if full_content:
116-
assert (
117-
full_content
118-
== f"Hello! I've received your message. Here's a generic response, but in future tutorials we'll see how you can get me to intelligently respond to your message. This is what I heard you say: {message_content}"
119-
)
120-
121-
if aggregated_content:
122-
assert (
123-
aggregated_content
124-
== f"Hello! I've received your message. Here's a generic response, but in future tutorials we'll see how you can get me to intelligently respond to your message. This is what I heard you say: {message_content}"
125-
)
56+
# Check expected response format
57+
expected = f"Hello! I've received your message. Here's a generic response, but in future tutorials we'll see how you can get me to intelligently respond to your message. This is what I heard you say: {message_content}"
58+
assert aggregated_content == expected, f"Expected: {expected}\nGot: {aggregated_content}"
12659

12760

12861
if __name__ == "__main__":
62+
import pytest
63+
12964
pytest.main([__file__, "-v"])
Lines changed: 54 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,83 @@
11
"""
2-
Sample tests for AgentEx ACP agent.
2+
Tests for s010-multiturn (sync agent)
33
4-
This test suite demonstrates how to test the main AgentEx API functions:
5-
- Non-streaming message sending
6-
- Streaming message sending
7-
- Task creation via RPC
4+
This test suite demonstrates testing a multi-turn sync agent using the AgentEx testing framework.
85
9-
To run these tests:
10-
1. Make sure the agent is running (via docker-compose or `agentex agents run`)
11-
2. Set the AGENTEX_API_BASE_URL environment variable if not using default
12-
3. Run: pytest test_agent.py -v
6+
Test coverage:
7+
- Multi-turn non-streaming conversation
8+
- Multi-turn streaming conversation
9+
- State management across turns
1310
14-
Configuration:
15-
- AGENTEX_API_BASE_URL: Base URL for the AgentEx server (default: http://localhost:5003)
16-
- AGENT_NAME: Name of the agent to test (default: s010-multiturn)
17-
"""
18-
19-
import os
20-
21-
import pytest
22-
from test_utils.sync import validate_text_in_string, collect_streaming_response
23-
24-
from agentex import Agentex
25-
from agentex.types import TextContent, TextContentParam
26-
from agentex.types.agent_rpc_params import ParamsCreateTaskRequest, ParamsSendMessageRequest
27-
from agentex.lib.sdk.fastacp.base.base_acp_server import uuid
28-
29-
# Configuration from environment variables
30-
AGENTEX_API_BASE_URL = os.environ.get("AGENTEX_API_BASE_URL", "http://localhost:5003")
31-
AGENT_NAME = os.environ.get("AGENT_NAME", "s010-multiturn")
11+
Prerequisites:
12+
- AgentEx services running (make dev)
13+
- Agent running: agentex agents run --manifest manifest.yaml
3214
15+
Run tests:
16+
pytest tests/test_agent.py -v
17+
"""
3318

34-
@pytest.fixture
35-
def client():
36-
"""Create an AgentEx client instance for testing."""
37-
return Agentex(base_url=AGENTEX_API_BASE_URL)
38-
19+
from agentex.lib.testing import (
20+
test_sync_agent,
21+
collect_streaming_deltas,
22+
assert_valid_agent_response,
23+
assert_agent_response_contains,
24+
)
3925

40-
@pytest.fixture
41-
def agent_name():
42-
"""Return the agent name for testing."""
43-
return AGENT_NAME
26+
AGENT_NAME = "s010-multiturn"
4427

4528

46-
@pytest.fixture
47-
def agent_id(client, agent_name):
48-
"""Retrieve the agent ID based on the agent name."""
49-
agents = client.agents.list()
50-
for agent in agents:
51-
if agent.name == agent_name:
52-
return agent.id
53-
raise ValueError(f"Agent with name {agent_name} not found.")
29+
def test_multiturn_conversation():
30+
"""Test multi-turn conversation with non-streaming messages."""
31+
with test_sync_agent(agent_name=AGENT_NAME) as test:
32+
messages = [
33+
"Hello, can you tell me a little bit about tennis? I want to you make sure you use the word 'tennis' in each response.",
34+
"Pick one of the things you just mentioned, and dive deeper into it.",
35+
"Can you now output a summary of this conversation",
36+
]
5437

38+
for msg in messages:
39+
response = test.send_message(msg)
5540

56-
class TestNonStreamingMessages:
57-
"""Test non-streaming message sending."""
41+
# Validate response
42+
assert_valid_agent_response(response)
5843

59-
def test_send_message(self, client: Agentex, agent_name: str, agent_id: str):
60-
task_response = client.agents.create_task(agent_id, params=ParamsCreateTaskRequest(name=uuid.uuid1().hex))
61-
task = task_response.result
44+
# Validate "tennis" appears in response (per agent's behavior)
45+
assert_agent_response_contains(response, "tennis")
6246

63-
assert task is not None
47+
# Verify conversation history
48+
history = test.get_conversation_history()
49+
assert len(history) >= 6, f"Expected >= 6 messages (3 user + 3 agent), got {len(history)}"
6450

65-
messages = [
66-
"Hello, can you tell me a litle bit about tennis? I want to you make sure you use the word 'tennis' in each response.",
67-
"Pick one of the things you just mentioned, and dive deeper into it.",
68-
"Can you now output a summary of this conversation",
69-
]
7051

71-
for i, msg in enumerate(messages):
72-
response = client.agents.send_message(
73-
agent_name=agent_name,
74-
params=ParamsSendMessageRequest(
75-
content=TextContentParam(
76-
author="user",
77-
content=msg,
78-
type="text",
79-
),
80-
task_id=task.id,
81-
),
82-
)
83-
assert response is not None and response.result is not None
84-
result = response.result
85-
86-
for message in result:
87-
content = message.content
88-
assert content is not None
89-
assert isinstance(content, TextContent) and isinstance(content.content, str)
90-
validate_text_in_string("tennis", content.content)
91-
92-
states = client.states.list(agent_id=agent_id, task_id=task.id)
93-
assert len(states) == 1
94-
95-
state = states[0]
96-
assert state.state is not None
97-
assert state.state.get("system_prompt", None) == "You are a helpful assistant that can answer questions."
98-
99-
message_history = client.messages.list(
100-
task_id=task.id,
101-
)
102-
assert len(message_history) == (i + 1) * 2 # user + agent messages
103-
104-
105-
class TestStreamingMessages:
106-
"""Test streaming message sending."""
107-
108-
def test_stream_message(self, client: Agentex, agent_name: str, agent_id: str):
109-
"""Test streaming messages in a multi-turn conversation."""
110-
111-
# create a task for this specific conversation
112-
task_response = client.agents.create_task(agent_id, params=ParamsCreateTaskRequest(name=uuid.uuid1().hex))
113-
task = task_response.result
114-
115-
assert task is not None
52+
def test_multiturn_streaming():
53+
"""Test multi-turn conversation with streaming messages."""
54+
with test_sync_agent(agent_name=AGENT_NAME) as test:
11655
messages = [
11756
"Hello, can you tell me a little bit about tennis? I want you to make sure you use the word 'tennis' in each response.",
11857
"Pick one of the things you just mentioned, and dive deeper into it.",
11958
"Can you now output a summary of this conversation",
12059
]
12160

122-
for i, msg in enumerate(messages):
123-
stream = client.agents.send_message_stream(
124-
agent_name=agent_name,
125-
params=ParamsSendMessageRequest(
126-
content=TextContentParam(
127-
author="user",
128-
content=msg,
129-
type="text",
130-
),
131-
task_id=task.id,
132-
),
133-
)
61+
for msg in messages:
62+
# Get streaming response
63+
response_gen = test.send_message_streaming(msg)
13464

135-
# Collect the streaming response
136-
aggregated_content, chunks = collect_streaming_response(stream)
65+
# Collect streaming deltas
66+
aggregated_content, chunks = collect_streaming_deltas(response_gen)
13767

138-
assert len(chunks) == 1
139-
# Get the actual content (prefer full_content if available, otherwise use aggregated)
68+
# Validate we got content
69+
assert len(chunks) > 0, "Should receive chunks"
70+
assert len(aggregated_content) > 0, "Should receive content"
14071

141-
# Validate that "tennis" appears in the response because that is what our model does
142-
validate_text_in_string("tennis", aggregated_content)
72+
# Validate "tennis" appears in response
73+
assert "tennis" in aggregated_content.lower(), f"Expected 'tennis' in: {aggregated_content[:100]}"
14374

144-
states = client.states.list(task_id=task.id)
145-
assert len(states) == 1
146-
147-
message_history = client.messages.list(
148-
task_id=task.id,
149-
)
150-
assert len(message_history) == (i + 1) * 2 # user + agent messages
75+
# Verify conversation history
76+
history = test.get_conversation_history()
77+
assert len(history) >= 6, f"Expected >= 6 messages, got {len(history)}"
15178

15279

15380
if __name__ == "__main__":
81+
import pytest
82+
15483
pytest.main([__file__, "-v"])

0 commit comments

Comments
 (0)