From 0bda3d82ba3f05b728daf40e117890f68e73adb2 Mon Sep 17 00:00:00 2001 From: Daniel Miller Date: Tue, 24 Mar 2026 11:22:24 -0400 Subject: [PATCH 1/5] Fix missing imports in sync-openai-agents template The sync-openai-agents template uses StreamTaskMessageFull and TextContent in the no-API-key error path but never imports them, causing a NameError at runtime. Also adds a missing return after the error yield. Co-Authored-By: Claude Opus 4.6 --- .../lib/cli/templates/sync-openai-agents/project/acp.py.j2 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/agentex/lib/cli/templates/sync-openai-agents/project/acp.py.j2 b/src/agentex/lib/cli/templates/sync-openai-agents/project/acp.py.j2 index 20b31caf3..1a7d5ca5d 100644 --- a/src/agentex/lib/cli/templates/sync-openai-agents/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/sync-openai-agents/project/acp.py.j2 @@ -9,8 +9,9 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce from agentex.lib.types.tracing import SGPTracingProcessorConfig from agentex.lib.utils.model_utils import BaseModel -from agentex.types.task_message_update import TaskMessageUpdate +from agentex.types.task_message_update import TaskMessageUpdate, StreamTaskMessageFull from agentex.types.task_message_content import TaskMessageContent +from agentex.types.text_content import TextContent from agentex.lib.utils.logging import make_logger from agents import Agent, Runner, RunConfig, function_tool @@ -83,6 +84,7 @@ async def handle_message_send( content="Hey, sorry I'm unable to respond to your message because you're running this example without an OpenAI API key. Please set the OPENAI_API_KEY environment variable to run this example. Do this by either by adding a .env file to the project/ directory or by setting the environment variable in your terminal.", ), ) + return user_prompt = params.content.content From b7f1c66c5b99809adb4d908bce43347a9a5aca31 Mon Sep 17 00:00:00 2001 From: Daniel Miller Date: Tue, 24 Mar 2026 11:38:06 -0400 Subject: [PATCH 2/5] Lazy-import OpenAIAgentsPlugin to fix opentelemetry.sdk import error The top-level import of OpenAIAgentsPlugin in temporal/utils.py triggers the temporalio.contrib.opentelemetry chain which requires opentelemetry-sdk. This breaks all agents (including sync ones) when opentelemetry-sdk is not installed. Moving the import to the only function that uses it (get_temporal_client) avoids this for non-Temporal agents. Co-Authored-By: Claude Opus 4.6 --- src/agentex/lib/core/clients/temporal/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/agentex/lib/core/clients/temporal/utils.py b/src/agentex/lib/core/clients/temporal/utils.py index 9be7cf5c4..991e7cd1c 100644 --- a/src/agentex/lib/core/clients/temporal/utils.py +++ b/src/agentex/lib/core/clients/temporal/utils.py @@ -6,7 +6,6 @@ from temporalio.worker import Interceptor from temporalio.runtime import Runtime, TelemetryConfig, OpenTelemetryConfig from temporalio.contrib.pydantic import pydantic_data_converter -from temporalio.contrib.openai_agents import OpenAIAgentsPlugin # class DateTimeJSONEncoder(AdvancedJSONEncoder): # def default(self, o: Any) -> Any: @@ -97,6 +96,8 @@ async def get_temporal_client(temporal_address: str, metrics_url: str | None = N validate_client_plugins(plugins) # Check if OpenAI plugin is present - it needs to configure its own data converter + # Lazy import to avoid pulling in opentelemetry.sdk for non-Temporal agents + from temporalio.contrib.openai_agents import OpenAIAgentsPlugin has_openai_plugin = any( isinstance(p, OpenAIAgentsPlugin) for p in (plugins or []) ) From edb7a9998287553c2cc990cce8cbf3a74c89a9bf Mon Sep 17 00:00:00 2001 From: Daniel Miller Date: Tue, 24 Mar 2026 11:42:59 -0400 Subject: [PATCH 3/5] Use local SDK wheel for tutorial tests when --build-cli is set The test runner was using the published SDK for pytest even when --build-cli was set, meaning source fixes weren't reflected in tests. Now uses --with to overlay the local wheel for both the agent process and the test runner. Co-Authored-By: Claude Opus 4.6 --- examples/tutorials/run_agent_test.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/examples/tutorials/run_agent_test.sh b/examples/tutorials/run_agent_test.sh index f396cfd00..804994e7f 100755 --- a/examples/tutorials/run_agent_test.sh +++ b/examples/tutorials/run_agent_test.sh @@ -270,7 +270,16 @@ run_test() { fi # Stream pytest output directly in real-time - uv run pytest tests/test_agent.py -v -s + if [ "$BUILD_CLI" = true ]; then + local wheel_file=$(ls /home/runner/work/*/*/dist/agentex_sdk-*.whl 2>/dev/null | head -n1) + if [[ -n "$wheel_file" ]]; then + uv run --with "$wheel_file" pytest tests/test_agent.py -v -s + else + uv run pytest tests/test_agent.py -v -s + fi + else + uv run pytest tests/test_agent.py -v -s + fi exit_code=$? if [ $exit_code -eq 0 ]; then From 5431cfda6e505608c01859eb79c81e054128e7c9 Mon Sep 17 00:00:00 2001 From: Daniel Miller Date: Tue, 24 Mar 2026 11:47:00 -0400 Subject: [PATCH 4/5] Revert "Use local SDK wheel for tutorial tests when --build-cli is set" This reverts commit edb7a9998287553c2cc990cce8cbf3a74c89a9bf. --- examples/tutorials/run_agent_test.sh | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/examples/tutorials/run_agent_test.sh b/examples/tutorials/run_agent_test.sh index 804994e7f..f396cfd00 100755 --- a/examples/tutorials/run_agent_test.sh +++ b/examples/tutorials/run_agent_test.sh @@ -270,16 +270,7 @@ run_test() { fi # Stream pytest output directly in real-time - if [ "$BUILD_CLI" = true ]; then - local wheel_file=$(ls /home/runner/work/*/*/dist/agentex_sdk-*.whl 2>/dev/null | head -n1) - if [[ -n "$wheel_file" ]]; then - uv run --with "$wheel_file" pytest tests/test_agent.py -v -s - else - uv run pytest tests/test_agent.py -v -s - fi - else - uv run pytest tests/test_agent.py -v -s - fi + uv run pytest tests/test_agent.py -v -s exit_code=$? if [ $exit_code -eq 0 ]; then From 50a0d786ca9db7d84bb4661fb709ea7dfbb6b4cc Mon Sep 17 00:00:00 2001 From: Daniel Miller Date: Tue, 24 Mar 2026 12:34:45 -0400 Subject: [PATCH 5/5] Add opentelemetry-sdk as a dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit temporalio 1.23.0+ internally imports opentelemetry-sdk via contrib.openai_agents → contrib.opentelemetry. Since we pin temporalio>=1.18.2,<2 and need to support newer versions for CVE fixes, opentelemetry-sdk must be an explicit dependency. Co-Authored-By: Claude Opus 4.6 --- pyproject.toml | 2 ++ uv.lock | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 17e758d54..ab746b262 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,6 +49,8 @@ dependencies = [ "claude-agent-sdk>=0.1.0", "anthropic>=0.40.0", "langgraph-checkpoint>=2.0.0", + "opentelemetry-sdk>=1.20.0", + "opentelemetry-api>=1.20.0", ] requires-python = ">= 3.12,<4" diff --git a/uv.lock b/uv.lock index 828726620..ed3d0a690 100644 --- a/uv.lock +++ b/uv.lock @@ -8,7 +8,7 @@ resolution-markers = [ [[package]] name = "agentex-sdk" -version = "0.9.3" +version = "0.9.4" source = { editable = "." } dependencies = [ { name = "aiohttp" }, @@ -32,6 +32,8 @@ dependencies = [ { name = "mcp", extra = ["cli"] }, { name = "openai" }, { name = "openai-agents" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-sdk" }, { name = "pydantic" }, { name = "pytest" }, { name = "pytest-asyncio" }, @@ -94,6 +96,8 @@ requires-dist = [ { name = "mcp", extras = ["cli"], specifier = ">=1.4.1" }, { name = "openai", specifier = ">=2.2,<3" }, { name = "openai-agents", specifier = "==0.4.2" }, + { name = "opentelemetry-api", specifier = ">=1.20.0" }, + { name = "opentelemetry-sdk", specifier = ">=1.20.0" }, { name = "pydantic", specifier = ">=2.0.0,<3" }, { name = "pytest", specifier = ">=8.4.0" }, { name = "pytest-asyncio", specifier = ">=1.0.0" }, @@ -1489,6 +1493,33 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/91/48/28ed9e55dcf2f453128df738210a980e09f4e468a456fa3c763dbc8be70a/opentelemetry_api-1.37.0-py3-none-any.whl", hash = "sha256:accf2024d3e89faec14302213bc39550ec0f4095d1cf5ca688e1bfb1c8612f47", size = 65732, upload-time = "2025-09-11T10:28:41.826Z" }, ] +[[package]] +name = "opentelemetry-sdk" +version = "1.37.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f4/62/2e0ca80d7fe94f0b193135375da92c640d15fe81f636658d2acf373086bc/opentelemetry_sdk-1.37.0.tar.gz", hash = "sha256:cc8e089c10953ded765b5ab5669b198bbe0af1b3f89f1007d19acd32dc46dda5", size = 170404, upload-time = "2025-09-11T10:29:11.779Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/62/9f4ad6a54126fb00f7ed4bb5034964c6e4f00fcd5a905e115bd22707e20d/opentelemetry_sdk-1.37.0-py3-none-any.whl", hash = "sha256:8f3c3c22063e52475c5dbced7209495c2c16723d016d39287dfc215d1771257c", size = 131941, upload-time = "2025-09-11T10:28:57.83Z" }, +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.58b0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/aa/1b/90701d91e6300d9f2fb352153fb1721ed99ed1f6ea14fa992c756016e63a/opentelemetry_semantic_conventions-0.58b0.tar.gz", hash = "sha256:6bd46f51264279c433755767bb44ad00f1c9e2367e1b42af563372c5a6fa0c25", size = 129867, upload-time = "2025-09-11T10:29:12.597Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/90/68152b7465f50285d3ce2481b3aec2f82822e3f52e5152eeeaf516bab841/opentelemetry_semantic_conventions-0.58b0-py3-none-any.whl", hash = "sha256:5564905ab1458b96684db1340232729fce3b5375a06e140e8904c78e4f815b28", size = 207954, upload-time = "2025-09-11T10:28:59.218Z" }, +] + [[package]] name = "orjson" version = "3.11.7"