Skip to content

Commit 8f62814

Browse files
committed
fixes
1 parent 82ed9c8 commit 8f62814

File tree

3 files changed

+124
-89
lines changed

3 files changed

+124
-89
lines changed

examples/tutorials/10_async/00_base/010_multiturn/tests/test_agent.py

Lines changed: 63 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,43 @@
1616
"""
1717

1818
import asyncio
19-
2019
import pytest
20+
import pytest_asyncio
21+
22+
from agentex.lib.testing.sessions import AsyncAgentTest
23+
from agentex.lib.testing import stream_agent_response
2124

22-
from agentex import AsyncAgentex
2325
from agentex.lib.testing import (
2426
async_test_agent,
2527
assert_valid_agent_response,
28+
assert_agent_response_contains,
2629
)
2730

2831
AGENT_NAME = "ab010-multiturn"
2932

33+
@pytest.fixture
34+
def agent_name():
35+
"""Return the agent name for testing."""
36+
return AGENT_NAME
3037

31-
@pytest.mark.asyncio
32-
async def test_multiturn_with_state_management():
33-
"""Test multi-turn conversation with state management validation."""
34-
# Need client access to check state
35-
client = AsyncAgentex(api_key="test", base_url="http://localhost:5003")
3638

37-
# Get agent ID
38-
agents = await client.agents.list()
39-
agent = next((a for a in agents if a.name == AGENT_NAME), None)
40-
assert agent is not None, f"Agent {AGENT_NAME} not found"
39+
@pytest_asyncio.fixture
40+
async def test_agent(agent_name: str):
41+
"""Fixture to create a test async agent."""
42+
async with async_test_agent(agent_name=agent_name) as test:
43+
yield test
4144

42-
async with async_test_agent(agent_name=AGENT_NAME) as test:
43-
# Wait for state initialization
44-
await asyncio.sleep(1)
4545

46-
# Check initial state
47-
states = await client.states.list(agent_id=agent.id, task_id=test.task_id)
48-
assert len(states) == 1
46+
class TestNonStreamingEvents:
47+
"""Test non-streaming event sending and polling."""
4948

49+
@pytest.mark.asyncio
50+
async def test_send_event_and_poll(self, test_agent: AsyncAgentTest):
51+
"""Test sending an event and polling for the response."""
52+
await asyncio.sleep(1) # Wait for state initialization
53+
states = await test_agent.client.states.list(agent_id=test_agent.agent.id, task_id=test_agent.task_id)
54+
assert len(states) == 1
55+
# Check initial state
5056
state = states[0].state
5157
assert state is not None
5258
messages = state.get("messages", [])
@@ -57,41 +63,33 @@ async def test_multiturn_with_state_management():
5763
"content": "You are a helpful assistant that can answer questions.",
5864
}
5965

60-
# Send first message
6166
user_message = "Hello! Here is my test message"
62-
response = await test.send_event(user_message, timeout_seconds=30.0)
67+
response = await test_agent.send_event(user_message, timeout_seconds=30.0)
6368
assert_valid_agent_response(response)
6469

65-
# Wait for state update (agent may or may not update state with messages)
70+
# Wait for state update
6671
await asyncio.sleep(2)
6772

6873
# Check if state was updated (optional - depends on agent implementation)
69-
states = await client.states.list(agent_id=agent.id, task_id=test.task_id)
70-
if len(states) > 0:
71-
state = states[0].state
72-
messages = state.get("messages", [])
73-
assert isinstance(messages, list)
74-
# Note: State updates depend on agent implementation
75-
print(f"State has {len(messages)} messages")
76-
77-
78-
@pytest.mark.asyncio
79-
async def test_streaming_events():
80-
"""Test streaming events from async agent."""
81-
# Need client access to check state
82-
client = AsyncAgentex(api_key="test", base_url="http://localhost:5003")
83-
84-
# Get agent ID
85-
agents = await client.agents.list()
86-
agent = next((a for a in agents if a.name == AGENT_NAME), None)
87-
assert agent is not None, f"Agent {AGENT_NAME} not found"
88-
89-
async with async_test_agent(agent_name=AGENT_NAME) as test:
74+
states = await test_agent.client.states.list(agent_id=test_agent.agent.id, task_id=test_agent.task_id)
75+
assert len(states) == 1
76+
state = states[0].state
77+
messages = state.get("messages", [])
78+
assert isinstance(messages, list)
79+
assert len(messages) == 3
80+
81+
82+
class TestStreamingEvents:
83+
"""Test streaming event sending."""
84+
85+
@pytest.mark.asyncio
86+
async def test_streaming_events(self, test_agent: AsyncAgentTest):
87+
"""Test streaming events from async agent."""
9088
# Wait for state initialization
9189
await asyncio.sleep(1)
9290

9391
# Check initial state
94-
states = await client.states.list(agent_id=agent.id, task_id=test.task_id)
92+
states = await test_agent.client.states.list(agent_id=test_agent.agent.id, task_id=test_agent.task_id)
9593
assert len(states) == 1
9694

9795
state = states[0].state
@@ -108,28 +106,47 @@ async def test_streaming_events():
108106
user_message = "Hello! Stream this response"
109107

110108
events_received = []
109+
user_echo_found = False
111110
agent_response_found = False
112111

113112
# Stream events
114-
async for event in test.send_event_and_stream(user_message, timeout_seconds=30.0):
113+
async for event in stream_agent_response(test_agent.client, test_agent.task_id, timeout=30.0):
115114
events_received.append(event)
116115
event_type = event.get("type")
117116

118-
if event_type == "done":
117+
if event_type == 'connected':
118+
await test_agent.send_event(user_message, timeout_seconds=30.0)
119+
120+
elif event_type == "done":
119121
break
122+
120123
elif event_type == "full":
121124
content = event.get("content", {})
122-
if content.get("author") == "agent":
125+
if content.get("content") is None:
126+
continue # Skip empty content
127+
128+
if content.get("type") == "text" and content.get("author") == "agent":
129+
# Check for agent response to user message
123130
agent_response_found = True
131+
assert user_echo_found, "User echo should be found before agent response"
132+
133+
elif content.get("type") == "text" and content.get("author") == "user":
134+
# Check for user message echo
135+
if content.get("content") == user_message:
136+
user_echo_found = True
137+
138+
if agent_response_found and user_echo_found:
139+
break
124140

125141
# Validate we received events
126142
assert len(events_received) > 0, "Should receive streaming events"
127143
assert agent_response_found, "Should receive agent response event"
144+
assert user_echo_found, "Should receive user message event"
128145

129146
# Verify state has been updated
130147
await asyncio.sleep(1) # Wait for state update
131148

132-
states = await client.states.list(agent_id=agent.id, task_id=test.task_id)
149+
states = await test_agent.client.states.list(agent_id=test_agent.agent.id, task_id=test_agent.task_id)
133150
assert len(states) == 1
134151
state = states[0].state
135152
messages = state.get("messages", [])

examples/tutorials/10_async/00_base/020_streaming/tests/test_agent.py

Lines changed: 61 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,43 @@
1212
Run: pytest tests/test_agent.py -v
1313
"""
1414
import asyncio
15-
1615
import pytest
16+
import pytest_asyncio
17+
18+
from agentex.lib.testing.sessions import AsyncAgentTest
19+
from agentex.lib.testing import stream_agent_response
1720

18-
from agentex import AsyncAgentex
1921
from agentex.lib.testing import (
20-
assert_valid_agent_response,
2122
async_test_agent,
23+
assert_valid_agent_response,
24+
assert_agent_response_contains,
2225
)
2326

2427
AGENT_NAME = "ab020-streaming"
2528

29+
@pytest.fixture
30+
def agent_name():
31+
"""Return the agent name for testing."""
32+
return AGENT_NAME
2633

27-
@pytest.mark.asyncio
28-
async def test_send_event_and_poll():
29-
"""Test sending events and polling for responses."""
30-
# Need client access to check state
31-
client = AsyncAgentex(api_key="test", base_url="http://localhost:5003")
3234

33-
# Get agent ID
34-
agents = await client.agents.list()
35-
agent = next((a for a in agents if a.name == AGENT_NAME), None)
36-
assert agent is not None, f"Agent {AGENT_NAME} not found"
35+
@pytest_asyncio.fixture
36+
async def test_agent(agent_name: str):
37+
"""Fixture to create a test async agent."""
38+
async with async_test_agent(agent_name=agent_name) as test:
39+
yield test
3740

38-
async with async_test_agent(agent_name=AGENT_NAME) as test:
39-
# Wait for state initialization
40-
await asyncio.sleep(1)
4141

42-
# Check initial state
43-
states = await client.states.list(agent_id=agent.id, task_id=test.task_id)
44-
assert len(states) == 1
42+
class TestNonStreamingEvents:
43+
"""Test non-streaming event sending and polling."""
4544

45+
@pytest.mark.asyncio
46+
async def test_send_event_and_poll(self, test_agent: AsyncAgentTest):
47+
"""Test sending an event and polling for the response."""
48+
await asyncio.sleep(1) # Wait for state initialization
49+
states = await test_agent.client.states.list(agent_id=test_agent.agent.id, task_id=test_agent.task_id)
50+
assert len(states) == 1
51+
# Check initial state
4652
state = states[0].state
4753
assert state is not None
4854
messages = state.get("messages", [])
@@ -53,39 +59,33 @@ async def test_send_event_and_poll():
5359
"content": "You are a helpful assistant that can answer questions.",
5460
}
5561

56-
# Send first message
5762
user_message = "Hello! Here is my test message"
58-
response = await test.send_event(user_message, timeout_seconds=30.0)
63+
response = await test_agent.send_event(user_message, timeout_seconds=30.0)
5964
assert_valid_agent_response(response)
6065

61-
# Wait for state update (agent may or may not update state with messages)
66+
# Wait for state update
6267
await asyncio.sleep(2)
6368

64-
# Check if state was updated
65-
states = await client.states.list(agent_id=agent.id, task_id=test.task_id)
69+
# Check if state was updated (optional - depends on agent implementation)
70+
states = await test_agent.client.states.list(agent_id=test_agent.agent.id, task_id=test_agent.task_id)
71+
assert len(states) == 1
6672
state = states[0].state
6773
messages = state.get("messages", [])
6874
assert isinstance(messages, list)
69-
assert len(messages) == 3
70-
75+
assert len(messages) == 3
7176

72-
@pytest.mark.asyncio
73-
async def test_streaming_events():
74-
"""Test streaming event responses."""
75-
# Need client access to check state
76-
client = AsyncAgentex(api_key="test", base_url="http://localhost:5003")
7777

78-
# Get agent ID
79-
agents = await client.agents.list()
80-
agent = next((a for a in agents if a.name == AGENT_NAME), None)
81-
assert agent is not None, f"Agent {AGENT_NAME} not found"
78+
class TestStreamingEvents:
79+
"""Test streaming event sending."""
8280

83-
async with async_test_agent(agent_name=AGENT_NAME) as test:
81+
@pytest.mark.asyncio
82+
async def test_streaming_events(self, test_agent: AsyncAgentTest):
83+
"""Test streaming events from async agent."""
8484
# Wait for state initialization
8585
await asyncio.sleep(1)
8686

8787
# Check initial state
88-
states = await client.states.list(agent_id=agent.id, task_id=test.task_id)
88+
states = await test_agent.client.states.list(agent_id=test_agent.agent.id, task_id=test_agent.task_id)
8989
assert len(states) == 1
9090

9191
state = states[0].state
@@ -102,32 +102,52 @@ async def test_streaming_events():
102102
user_message = "Hello! Stream this response"
103103

104104
events_received = []
105+
user_echo_found = False
105106
agent_response_found = False
106107
delta_messages_found = False
107108

108109
# Stream events
109-
async for event in test.send_event_and_stream(user_message, timeout_seconds=30.0):
110+
async for event in stream_agent_response(test_agent.client, test_agent.task_id, timeout=30.0):
110111
events_received.append(event)
111112
event_type = event.get("type")
112113

113-
if event_type == "done":
114+
if event_type == 'connected':
115+
await test_agent.send_event(user_message, timeout_seconds=30.0)
116+
117+
elif event_type == "done":
114118
break
119+
115120
elif event_type == "full":
116121
content = event.get("content", {})
117-
if content.get("author") == "agent":
122+
if content.get("content") is None:
123+
continue # Skip empty content
124+
125+
if content.get("type") == "text" and content.get("author") == "agent":
126+
# Check for agent response to user message
118127
agent_response_found = True
128+
assert user_echo_found, "User echo should be found before agent response"
129+
130+
elif content.get("type") == "text" and content.get("author") == "user":
131+
# Check for user message echo
132+
if content.get("content") == user_message:
133+
user_echo_found = True
134+
119135
elif event_type == "delta":
120136
delta_messages_found = True
121137

138+
if agent_response_found and user_echo_found:
139+
break
140+
122141
# Validate we received events
123142
assert len(events_received) > 0, "Should receive streaming events"
124143
assert agent_response_found, "Should receive agent response event"
125-
assert delta_messages_found, "Should receive delta agent message events"
144+
assert user_echo_found, "Should receive user message event"
145+
assert delta_messages_found, "Should receive delta streaming events"
126146

127147
# Verify state has been updated
128148
await asyncio.sleep(1) # Wait for state update
129149

130-
states = await client.states.list(agent_id=agent.id, task_id=test.task_id)
150+
states = await test_agent.client.states.list(agent_id=test_agent.agent.id, task_id=test_agent.task_id)
131151
assert len(states) == 1
132152
state = states[0].state
133153
messages = state.get("messages", [])

src/agentex/lib/testing/poller.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,13 @@ async def poll_for_response(
6363
self,
6464
timeout_seconds: float,
6565
expected_author: MessageAuthor,
66-
match_content: str | None = None,
6766
) -> TextContent:
6867
"""
6968
Poll for new agent response with exponential backoff.
7069
7170
Args:
7271
timeout_seconds: Maximum time to wait for response
7372
expected_author: Expected message author (e.g., MessageAuthor("agent"))
74-
match_content: Optional content substring to match in response
7573
7674
Returns:
7775
New agent response as TextContent

0 commit comments

Comments
 (0)