Skip to content

Commit c6b357c

Browse files
committed
temporal
1 parent 08868c3 commit c6b357c

File tree

3 files changed

+156
-156
lines changed

3 files changed

+156
-156
lines changed

examples/tutorials/10_async/10_temporal/000_hello_acp/tests/test_agent.py

Lines changed: 79 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,94 @@
1010
"""
1111

1212
import pytest
13+
import pytest_asyncio
1314

14-
from agentex.lib.testing import async_test_agent, assert_valid_agent_response
15+
from agentex.lib.testing import (
16+
async_test_agent,
17+
stream_agent_response,
18+
assert_valid_agent_response,
19+
assert_agent_response_contains,
20+
)
21+
from agentex.lib.testing.sessions import AsyncAgentTest
1522

1623
AGENT_NAME = "at000-hello-acp"
1724

1825

19-
@pytest.mark.asyncio
20-
async def test_agent_basic():
21-
"""Test basic agent functionality."""
22-
async with async_test_agent(agent_name=AGENT_NAME) as test:
23-
response = await test.send_event("Test message", timeout_seconds=60.0)
26+
@pytest.fixture
27+
def agent_name():
28+
"""Return the agent name for testing."""
29+
return AGENT_NAME
30+
31+
32+
@pytest_asyncio.fixture
33+
async def test_agent(agent_name: str):
34+
"""Fixture to create a test async agent."""
35+
async with async_test_agent(agent_name=agent_name) as test:
36+
yield test
37+
38+
39+
class TestNonStreamingEvents:
40+
"""Test non-streaming event sending and polling."""
41+
42+
@pytest.mark.asyncio
43+
async def test_send_event_and_poll(self, test_agent: AsyncAgentTest):
44+
"""Test sending an event and polling for the response."""
45+
# Poll for initial task creation message
46+
initial_response = await test_agent.poll_for_agent_response(timeout_seconds=15.0)
47+
assert_valid_agent_response(initial_response)
48+
assert_agent_response_contains(initial_response, "Hello! I've received your task")
49+
50+
# Send a test message and validate response
51+
response = await test_agent.send_event("Hello, this is a test message!", timeout_seconds=30.0)
52+
# Validate latest response
2453
assert_valid_agent_response(response)
54+
assert_agent_response_contains(response, "Hello! I've received your message")
55+
56+
57+
class TestStreamingEvents:
58+
"""Test streaming event sending."""
2559

60+
@pytest.mark.asyncio
61+
async def test_send_event_and_stream(self, test_agent: AsyncAgentTest):
62+
"""Test sending an event and streaming the response."""
63+
user_message = "Hello, this is a test message!"
2664

27-
@pytest.mark.asyncio
28-
async def test_agent_streaming():
29-
"""Test streaming responses."""
30-
async with async_test_agent(agent_name=AGENT_NAME) as test:
31-
events = []
32-
async for event in test.send_event_and_stream("Stream test", timeout_seconds=60.0):
33-
events.append(event)
34-
if event.get("type") == "done":
65+
# Flags to track what we've received
66+
user_echo_found = False
67+
agent_response_found = False
68+
all_events = []
69+
70+
# Stream events
71+
async for event in stream_agent_response(test_agent.client, test_agent.task_id, timeout=30.0):
72+
all_events.append(event)
73+
event_type = event.get("type")
74+
75+
if event_type == "connected":
76+
await test_agent.send_event(user_message, timeout_seconds=30.0)
77+
78+
elif event_type == "full":
79+
content = event.get("content", {})
80+
if content.get("content") is None:
81+
continue # Skip empty content
82+
83+
if content.get("type") == "text" and content.get("author") == "agent":
84+
# Check for agent response to user message
85+
if "Hello! I've received your message" in content.get("content", ""):
86+
agent_response_found = True
87+
assert user_echo_found, "User echo should be found before agent response"
88+
89+
elif content.get("type") == "text" and content.get("author") == "user":
90+
# Check for user message echo (may or may not be present)
91+
if content.get("content") == user_message:
92+
user_echo_found = True
93+
94+
# Exit early if we've found expected messages
95+
if agent_response_found and user_echo_found:
3596
break
36-
assert len(events) > 0
97+
98+
assert agent_response_found, "Did not receive agent response to user message"
99+
assert user_echo_found, "User echo message not found"
100+
assert len(all_events) > 0, "Should receive events"
37101

38102

39103
if __name__ == "__main__":

examples/tutorials/10_async/10_temporal/010_agent_chat/project/workflow.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ async def on_task_event_send(self, params: SendEventParams) -> None:
221221
"to provide accurate and well-reasoned responses."
222222
),
223223
parent_span_id=span.id if span else None,
224-
model="gpt-4o-mini",
224+
model="gpt-5-mini",
225225
model_settings=ModelSettings(
226226
# Include reasoning items in the response (IDs, summaries)
227227
# response_include=["reasoning.encrypted_content"],

examples/tutorials/10_async/10_temporal/010_agent_chat/tests/test_agent.py

Lines changed: 76 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -15,183 +15,119 @@
1515
Run: pytest tests/test_agent.py -v
1616
"""
1717

18+
import asyncio
19+
1820
import pytest
21+
import pytest_asyncio
1922

20-
from agentex.lib.testing import async_test_agent, assert_valid_agent_response
23+
from agentex.lib.testing import async_test_agent, stream_agent_response, assert_valid_agent_response
24+
from agentex.lib.testing.sessions import AsyncAgentTest
25+
from agentex.types.agent_rpc_result import StreamTaskMessageDone, StreamTaskMessageFull
2126

2227
AGENT_NAME = "at010-agent-chat"
2328

2429

25-
@pytest.mark.asyncio
26-
async def test_agent_basic():
27-
"""Test basic agent functionality."""
28-
async with async_test_agent(agent_name=AGENT_NAME) as test:
29-
response = await test.send_event("Test message", timeout_seconds=60.0)
30-
assert_valid_agent_response(response)
30+
@pytest.fixture
31+
def agent_name():
32+
"""Return the agent name for testing."""
33+
return AGENT_NAME
3134

3235

33-
@pytest.mark.asyncio
34-
async def test_agent_streaming():
35-
"""Test streaming responses."""
36-
async with async_test_agent(agent_name=AGENT_NAME) as test:
37-
events = []
38-
async for event in test.send_event_and_stream("Stream test", timeout_seconds=60.0):
39-
events.append(event)
40-
if event.get("type") == "done":
41-
break
42-
assert len(events) > 0
36+
@pytest_asyncio.fixture
37+
async def test_agent(agent_name: str):
38+
"""Fixture to create a test async agent."""
39+
async with async_test_agent(agent_name=agent_name) as test:
40+
yield test
41+
42+
class TestNonStreamingEvents:
43+
"""Test non-streaming event sending and polling with OpenAI Agents SDK."""
4344

4445
@pytest.mark.asyncio
45-
async def test_send_event_and_poll_with_calculator(self, client: AsyncAgentex, agent_id: str):
46-
"""Test sending an event that triggers calculator tool usage and polling for the response."""
47-
# Create a task for this conversation
48-
task_response = await client.agents.create_task(agent_id, params=ParamsCreateTaskRequest(name=uuid.uuid1().hex))
49-
task = task_response.result
50-
assert task is not None
46+
async def test_send_event_and_poll_simple_query(self, test_agent: AsyncAgentTest):
47+
"""Test basic agent functionality."""
48+
# Wait for state initialization
49+
await asyncio.sleep(1)
50+
51+
# Send a simple message that shouldn't require tool use
52+
response = await test_agent.send_event("Hello! Please introduce yourself briefly.", timeout_seconds=30.0)
53+
assert_valid_agent_response(response)
5154

55+
@pytest.mark.asyncio
56+
async def test_send_event_and_poll_with_calculator(self, test_agent: AsyncAgentTest):
57+
"""Test sending an event that triggers calculator tool usage and polling for the response."""
5258
# Wait for workflow to initialize
5359
await asyncio.sleep(1)
5460

5561
# Send a message that could trigger the calculator tool (though with reasoning, it may not need it)
5662
user_message = "What is 15 multiplied by 37?"
57-
has_final_agent_response = False
58-
59-
async for message in send_event_and_poll_yielding(
60-
client=client,
61-
agent_id=agent_id,
62-
task_id=task.id,
63-
user_message=user_message,
64-
timeout=60, # Longer timeout for tool use
65-
sleep_interval=1.0,
66-
):
67-
assert isinstance(message, TaskMessage)
68-
if message.content and message.content.type == "text" and message.content.author == "agent":
69-
# Check that the answer contains 555 (15 * 37)
70-
if "555" in message.content.content:
71-
has_final_agent_response = True
72-
break
73-
74-
assert has_final_agent_response, "Did not receive final agent text response with correct answer"
63+
response = await test_agent.send_event(user_message, timeout_seconds=60.0)
64+
assert_valid_agent_response(response)
65+
assert "555" in response.content, "Expected answer '555' not found in agent response"
7566

7667
@pytest.mark.asyncio
77-
async def test_multi_turn_conversation(self, client: AsyncAgentex, agent_id: str):
68+
async def test_multi_turn_conversation_with_state(self, test_agent: AsyncAgentTest):
7869
"""Test multiple turns of conversation with state preservation."""
79-
# Create a task for this conversation
80-
task_response = await client.agents.create_task(agent_id, params=ParamsCreateTaskRequest(name=uuid.uuid1().hex))
81-
task = task_response.result
82-
assert task is not None
83-
8470
# Wait for workflow to initialize
8571
await asyncio.sleep(1)
8672

87-
# First turn
88-
user_message_1 = "My favorite color is blue."
89-
async for message in send_event_and_poll_yielding(
90-
client=client,
91-
agent_id=agent_id,
92-
task_id=task.id,
93-
user_message=user_message_1,
94-
timeout=20,
95-
sleep_interval=1.0,
96-
):
97-
assert isinstance(message, TaskMessage)
98-
if (
99-
message.content
100-
and message.content.type == "text"
101-
and message.content.author == "agent"
102-
and message.content.content
103-
):
104-
break
105-
106-
# Wait a bit for state to update
107-
await asyncio.sleep(2)
108-
109-
# Second turn - reference previous context
110-
found_response = False
111-
user_message_2 = "What did I just tell you my favorite color was?"
112-
async for message in send_event_and_poll_yielding(
113-
client=client,
114-
agent_id=agent_id,
115-
task_id=task.id,
116-
user_message=user_message_2,
117-
timeout=30,
118-
sleep_interval=1.0,
119-
):
120-
if (
121-
message.content
122-
and message.content.type == "text"
123-
and message.content.author == "agent"
124-
and message.content.content
125-
):
126-
response_text = message.content.content.lower()
127-
assert "blue" in response_text, f"Expected 'blue' in response but got: {response_text}"
128-
found_response = True
129-
break
130-
131-
assert found_response, "Did not receive final agent text response with context recall"
73+
response = await test_agent.send_event("My favorite color is blue", timeout_seconds=30.0)
74+
assert_valid_agent_response(response)
75+
76+
second_response = await test_agent.send_event(
77+
"What did I just tell you my favorite color was?", timeout_seconds=30.0
78+
)
79+
assert_valid_agent_response(second_response)
80+
assert "blue" in second_response.content.lower()
13281

13382

13483
class TestStreamingEvents:
13584
"""Test streaming event sending with OpenAI Agents SDK and tool usage."""
13685

13786
@pytest.mark.asyncio
138-
async def test_send_event_and_stream_with_reasoning(self, client: AsyncAgentex, agent_id: str):
139-
"""Test streaming a simple response without tool usage."""
140-
# Create a task for this conversation
141-
task_response = await client.agents.create_task(agent_id, params=ParamsCreateTaskRequest(name=uuid.uuid1().hex))
142-
task = task_response.result
143-
assert task is not None
144-
87+
async def test_send_event_and_stream_with_reasoning(self, test_agent: AsyncAgentTest):
88+
"""Test streaming event responses."""
14589
# Wait for workflow to initialize
14690
await asyncio.sleep(1)
14791

92+
# Send message and stream response
14893
user_message = "Tell me a very short joke about programming."
14994

15095
# Check for user message and agent response
15196
user_message_found = False
15297
agent_response_found = False
15398

154-
async def stream_messages() -> None: # noqa: ANN101
155-
nonlocal user_message_found, agent_response_found
156-
async for event in stream_agent_response(
157-
client=client,
158-
task_id=task.id,
159-
timeout=60,
160-
):
161-
msg_type = event.get("type")
162-
if msg_type == "full":
163-
task_message_update = StreamTaskMessageFull.model_validate(event)
164-
if task_message_update.parent_task_message and task_message_update.parent_task_message.id:
165-
finished_message = await client.messages.retrieve(task_message_update.parent_task_message.id)
166-
if (
167-
finished_message.content
168-
and finished_message.content.type == "text"
169-
and finished_message.content.author == "user"
170-
):
171-
user_message_found = True
172-
elif (
173-
finished_message.content
174-
and finished_message.content.type == "text"
175-
and finished_message.content.author == "agent"
176-
):
177-
agent_response_found = True
178-
elif finished_message.content and finished_message.content.type == "reasoning":
179-
tool_response_found = True
180-
elif msg_type == "done":
181-
task_message_update = StreamTaskMessageDone.model_validate(event)
182-
if task_message_update.parent_task_message and task_message_update.parent_task_message.id:
183-
finished_message = await client.messages.retrieve(task_message_update.parent_task_message.id)
184-
if finished_message.content and finished_message.content.type == "reasoning":
185-
agent_response_found = True
186-
continue
187-
188-
stream_task = asyncio.create_task(stream_messages())
189-
190-
event_content = TextContentParam(type="text", author="user", content=user_message)
191-
await client.agents.send_event(agent_id=agent_id, params={"task_id": task.id, "content": event_content})
192-
193-
# Wait for streaming to complete
194-
await stream_task
99+
# Stream events
100+
async for event in stream_agent_response(test_agent.client, test_agent.task_id, timeout=60.0):
101+
event_type = event.get("type")
102+
103+
if event_type == "connected":
104+
await test_agent.send_event(user_message, timeout_seconds=30.0)
105+
106+
elif event_type == "full":
107+
print('full event', event)
108+
task_message_update = StreamTaskMessageFull.model_validate(event)
109+
if task_message_update.parent_task_message and task_message_update.parent_task_message.id:
110+
finished_message = await test_agent.client.messages.retrieve(task_message_update.parent_task_message.id)
111+
if (
112+
finished_message.content
113+
and finished_message.content.type == "text"
114+
and finished_message.content.author == "user"
115+
):
116+
user_message_found = True
117+
elif (
118+
finished_message.content
119+
and finished_message.content.type == "text"
120+
and finished_message.content.author == "agent"
121+
):
122+
agent_response_found = True
123+
elif event_type == "done":
124+
print('done event', event)
125+
task_message_update = StreamTaskMessageDone.model_validate(event)
126+
if task_message_update.parent_task_message and task_message_update.parent_task_message.id:
127+
finished_message = await test_agent.client.messages.retrieve(task_message_update.parent_task_message.id)
128+
if finished_message.content and finished_message.content.type == "text" and finished_message.content.author == "agent":
129+
agent_response_found = True
130+
continue
195131

196132
assert user_message_found, "User message not found in stream"
197133
assert agent_response_found, "Agent response not found in stream"

0 commit comments

Comments
 (0)