Skip to content

Commit 97079d8

Browse files
declan-scaleclaude
andcommitted
fix(codex): poll for response in async live tests; collab_tool_call errors
- The async-base and temporal live tests used the sync send_message pattern, which returns an empty result for async (event-driven) agents (assert 0 >= 1). Rewrite to create_task + send_event + poll task messages, matching how these agents actually handle events (on_task_event_send / RECEIVE_EVENT signal). - _tool_output_for: route collab_tool_call through the same error/result handling as mcp_tool_call so a failed collab call is reported with is_error=True instead of a generic success dump [greptile]. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent c60a0d2 commit 97079d8

3 files changed

Lines changed: 73 additions & 17 deletions

File tree

examples/tutorials/10_async/00_base/harness_codex/tests/test_agent.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,19 +145,44 @@ def client(self):
145145

146146
return Agentex(base_url=AGENTEX_API_BASE_URL)
147147

148-
def test_send_simple_message(self, client):
148+
@pytest.fixture
149+
def agent_id(self, client):
150+
for agent in client.agents.list():
151+
if agent.name == AGENT_NAME:
152+
return agent.id
153+
raise ValueError(f"Agent {AGENT_NAME!r} not found.")
154+
155+
def test_send_simple_message(self, client, agent_id: str):
156+
"""Async agents process events out of band, so create a task, send an
157+
event, and poll the task's messages for the agent's response."""
158+
import time
159+
import uuid
160+
149161
from agentex.types import TextContentParam
150-
from agentex.types.agent_rpc_params import ParamsSendMessageRequest
162+
from agentex.types.agent_rpc_params import ParamsSendEventRequest, ParamsCreateTaskRequest
163+
164+
task = client.agents.create_task(agent_id, params=ParamsCreateTaskRequest(name=uuid.uuid1().hex)).result
165+
assert task is not None
151166

152-
response = client.agents.send_message(
153-
agent_name=AGENT_NAME,
154-
params=ParamsSendMessageRequest(
167+
client.agents.send_event(
168+
agent_id=agent_id,
169+
params=ParamsSendEventRequest(
170+
task_id=task.id,
155171
content=TextContentParam(
156172
author="user",
157173
content="What is 3+3? Reply with just the number.",
158174
type="text",
159-
)
175+
),
160176
),
161177
)
162-
assert response.result is not None
163-
assert len(response.result) >= 1
178+
179+
deadline = time.monotonic() + 60
180+
while time.monotonic() < deadline:
181+
msgs = client.messages.list(task_id=task.id)
182+
agent_msgs = [m for m in msgs if getattr(m.content, "author", None) == "agent"]
183+
if agent_msgs:
184+
assert len(agent_msgs) >= 1
185+
return
186+
time.sleep(2)
187+
188+
raise AssertionError("No agent response received within 60 s")

examples/tutorials/10_async/10_temporal/harness_codex/tests/test_agent.py

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -199,19 +199,47 @@ def client(self):
199199

200200
return Agentex(base_url=AGENTEX_API_BASE_URL)
201201

202-
def test_send_simple_message(self, client):
202+
@pytest.fixture
203+
def agent_id(self, client):
204+
for agent in client.agents.list():
205+
if agent.name == AGENT_NAME:
206+
return agent.id
207+
raise ValueError(f"Agent {AGENT_NAME!r} not found.")
208+
209+
def test_send_simple_message(self, client, agent_id: str):
210+
"""Temporal agents process events out of band, so create a task, send an
211+
event, and poll the task's messages for the agent's response."""
212+
import time
213+
import uuid
214+
203215
from agentex.types import TextContentParam
204-
from agentex.types.agent_rpc_params import ParamsSendMessageRequest
216+
from agentex.types.agent_rpc_params import ParamsSendEventRequest, ParamsCreateTaskRequest
205217

206-
response = client.agents.send_message(
207-
agent_name=AGENT_NAME,
208-
params=ParamsSendMessageRequest(
218+
task = client.agents.create_task(agent_id, params=ParamsCreateTaskRequest(name=uuid.uuid1().hex)).result
219+
assert task is not None
220+
221+
client.agents.send_event(
222+
agent_id=agent_id,
223+
params=ParamsSendEventRequest(
224+
task_id=task.id,
209225
content=TextContentParam(
210226
author="user",
211227
content="What is 5+5? Reply with just the number.",
212228
type="text",
213-
)
229+
),
214230
),
215231
)
216-
assert response.result is not None
217-
assert len(response.result) >= 1
232+
233+
deadline = time.monotonic() + 90
234+
while time.monotonic() < deadline:
235+
msgs = client.messages.list(task_id=task.id)
236+
agent_msgs = [m for m in msgs if getattr(m.content, "author", None) == "agent"]
237+
response_msgs = [
238+
m for m in agent_msgs if "Task initialized" not in str(getattr(m.content, "content", ""))
239+
]
240+
if response_msgs:
241+
assert len(response_msgs) >= 1
242+
return
243+
time.sleep(3)
244+
245+
raise AssertionError("No agent response received within 90 s")

src/agentex/lib/adk/_modules/_codex_sync.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,10 @@ def _tool_output_for(item_type: str, payload: dict[str, Any]) -> tuple[str, bool
156156
exit_code = payload.get("exit_code")
157157
is_error = exit_code is not None and exit_code != 0
158158
return _truncate(out), is_error
159-
if item_type == "mcp_tool_call":
159+
if item_type in ("mcp_tool_call", "collab_tool_call"):
160+
# collab_tool_call mirrors mcp_tool_call's error/result convention
161+
# (see _tool_args_for); without this branch a failed collab call would
162+
# fall through to the generic path and be reported as a success.
160163
err = payload.get("error")
161164
if err:
162165
msg = err.get("message", "") if isinstance(err, dict) else str(err)

0 commit comments

Comments
 (0)