From 4eb9ab97dc6092063aa8973d06447c7bd2dc6361 Mon Sep 17 00:00:00 2001 From: Michael Xu Date: Wed, 9 Sep 2026 16:05:54 -0500 Subject: [PATCH 1/2] fix(templates): register the local Agentex tracing processor so the developer UI traces tab shows spans Every framework template registered only SGPTracingProcessorConfig, which disables itself when SGP_API_KEY or SGP_ACCOUNT_ID is empty. Nothing else creates a tracing processor, so spans derived by the unified harness were never written to the backend /spans API and a scaffolded agent always showed "No spans found for this task" in the developer UI, contradicting the README ("open the traces tab"). Register AgentexTracingProcessorConfig() ahead of the SGP block in all 16 framework templates (sync/default/temporal x openai-agents, pydantic-ai, langgraph, claude-code, codex, plus the local-sandbox variant), fix a sync-langgraph comment that claimed to register the Agentex processor, and add a parametrized test asserting every framework template registers it. Verified on a scaffolded sync Claude Code agent and a Temporal Claude Code agent against a local backend: with the registration, message/turn spans appear via POST /spans; without it, none do. Claude-Session: https://claude.ai/code/session_01HCVKnA7LeJZ44nxZz1uzF3 --- .../default-claude-code/project/acp.py.j2 | 5 ++++- .../templates/default-codex/project/acp.py.j2 | 5 ++++- .../default-langgraph/project/acp.py.j2 | 5 ++++- .../default-openai-agents/project/acp.py.j2 | 5 ++++- .../default-pydantic-ai/project/acp.py.j2 | 5 ++++- .../sync-claude-code/project/acp.py.j2 | 5 ++++- .../templates/sync-codex/project/acp.py.j2 | 5 ++++- .../sync-langgraph/project/acp.py.j2 | 7 +++++-- .../project/acp.py.j2 | 5 ++++- .../sync-openai-agents/project/acp.py.j2 | 5 ++++- .../sync-pydantic-ai/project/acp.py.j2 | 5 ++++- .../project/workflow.py.j2 | 5 ++++- .../temporal-codex/project/workflow.py.j2 | 5 ++++- .../temporal-langgraph/project/workflow.py.j2 | 5 ++++- .../project/workflow.py.j2 | 5 ++++- .../project/workflow.py.j2 | 5 ++++- tests/lib/cli/test_init_templates.py | 20 +++++++++++++++++++ 17 files changed, 85 insertions(+), 17 deletions(-) diff --git a/src/agentex/lib/cli/templates/default-claude-code/project/acp.py.j2 b/src/agentex/lib/cli/templates/default-claude-code/project/acp.py.j2 index 42512c601..d662c9e21 100644 --- a/src/agentex/lib/cli/templates/default-claude-code/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/default-claude-code/project/acp.py.j2 @@ -25,7 +25,7 @@ from agentex.lib.adk import ClaudeCodeTurn from agentex.lib.types.acp import SendEventParams, CancelTaskParams, CreateTaskParams from agentex.lib.core.harness import UnifiedEmitter from agentex.lib.types.fastacp import AsyncACPConfig -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from agentex.lib.utils.logging import make_logger from agentex.types.text_content import TextContent from agentex.lib.sdk.fastacp.fastacp import FastACP @@ -33,6 +33,9 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce logger = make_logger(__name__) +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + add_tracing_processor_config( SGPTracingProcessorConfig( sgp_api_key=os.environ.get("SGP_API_KEY", ""), diff --git a/src/agentex/lib/cli/templates/default-codex/project/acp.py.j2 b/src/agentex/lib/cli/templates/default-codex/project/acp.py.j2 index f676ef137..55616b85b 100644 --- a/src/agentex/lib/cli/templates/default-codex/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/default-codex/project/acp.py.j2 @@ -35,7 +35,7 @@ from agentex.lib.types.acp import SendEventParams, CancelTaskParams, CreateTaskP from agentex.types.text_content import TextContent from agentex.lib.core.harness import UnifiedEmitter from agentex.lib.types.fastacp import AsyncACPConfig -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from agentex.lib.utils.logging import make_logger from agentex.lib.utils.model_utils import BaseModel from agentex.lib.sdk.fastacp.fastacp import FastACP @@ -43,6 +43,9 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce logger = make_logger(__name__) +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + add_tracing_processor_config( SGPTracingProcessorConfig( sgp_api_key=os.environ.get("SGP_API_KEY", ""), diff --git a/src/agentex/lib/cli/templates/default-langgraph/project/acp.py.j2 b/src/agentex/lib/cli/templates/default-langgraph/project/acp.py.j2 index da5d37905..0254deec8 100644 --- a/src/agentex/lib/cli/templates/default-langgraph/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/default-langgraph/project/acp.py.j2 @@ -20,7 +20,7 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce from agentex.lib.sdk.fastacp.fastacp import FastACP from agentex.protocol.acp import SendEventParams, CancelTaskParams, CreateTaskParams from agentex.lib.types.fastacp import AsyncACPConfig -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from agentex.lib.utils.logging import make_logger from agentex.types.text_content import TextContent from agentex.lib.adk import LangGraphTurn @@ -29,6 +29,9 @@ from project.graph import create_graph logger = make_logger(__name__) +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + add_tracing_processor_config( SGPTracingProcessorConfig( sgp_api_key=os.environ.get("SGP_API_KEY", ""), diff --git a/src/agentex/lib/cli/templates/default-openai-agents/project/acp.py.j2 b/src/agentex/lib/cli/templates/default-openai-agents/project/acp.py.j2 index 66ee31243..1548ca816 100644 --- a/src/agentex/lib/cli/templates/default-openai-agents/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/default-openai-agents/project/acp.py.j2 @@ -25,7 +25,7 @@ from agents import Agent, Runner, function_tool, set_tracing_disabled from agentex.lib import adk from agentex.lib.types.acp import SendEventParams, CancelTaskParams, CreateTaskParams from agentex.lib.types.fastacp import AsyncACPConfig -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from agentex.lib.utils.logging import make_logger from agentex.types.text_content import TextContent from agentex.lib.utils.model_utils import BaseModel @@ -48,6 +48,9 @@ if _litellm_key and not os.environ.get("OPENAI_API_KEY"): _sgp_api_key = os.environ.get("SGP_API_KEY", "") _sgp_account_id = os.environ.get("SGP_ACCOUNT_ID", "") +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + if _sgp_api_key and _sgp_account_id: add_tracing_processor_config( SGPTracingProcessorConfig( diff --git a/src/agentex/lib/cli/templates/default-pydantic-ai/project/acp.py.j2 b/src/agentex/lib/cli/templates/default-pydantic-ai/project/acp.py.j2 index 245f9ec38..c42b4fda3 100644 --- a/src/agentex/lib/cli/templates/default-pydantic-ai/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/default-pydantic-ai/project/acp.py.j2 @@ -27,7 +27,7 @@ import agentex.lib.adk as adk from agentex.protocol.acp import SendEventParams, CancelTaskParams, CreateTaskParams from agentex.lib.core.harness import UnifiedEmitter from agentex.lib.types.fastacp import AsyncACPConfig -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from agentex.lib.utils.logging import make_logger from agentex.types.text_content import TextContent from agentex.lib.utils.model_utils import BaseModel @@ -42,6 +42,9 @@ logger = make_logger(__name__) # so they show up in the per-task spans dropdown out of the box. SGP_API_KEY = os.environ.get("SGP_API_KEY", "") SGP_ACCOUNT_ID = os.environ.get("SGP_ACCOUNT_ID", "") +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + if SGP_API_KEY and SGP_ACCOUNT_ID: add_tracing_processor_config( SGPTracingProcessorConfig( diff --git a/src/agentex/lib/cli/templates/sync-claude-code/project/acp.py.j2 b/src/agentex/lib/cli/templates/sync-claude-code/project/acp.py.j2 index 33a89a51e..020fd95aa 100644 --- a/src/agentex/lib/cli/templates/sync-claude-code/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/sync-claude-code/project/acp.py.j2 @@ -25,7 +25,7 @@ import agentex.lib.adk as adk from agentex.lib.adk import ClaudeCodeTurn from agentex.lib.types.acp import SendMessageParams from agentex.lib.core.harness import UnifiedEmitter -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from agentex.lib.utils.logging import make_logger from agentex.types.text_content import TextContent from agentex.lib.sdk.fastacp.fastacp import FastACP @@ -35,6 +35,9 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce logger = make_logger(__name__) +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + add_tracing_processor_config( SGPTracingProcessorConfig( sgp_api_key=os.environ.get("SGP_API_KEY", ""), diff --git a/src/agentex/lib/cli/templates/sync-codex/project/acp.py.j2 b/src/agentex/lib/cli/templates/sync-codex/project/acp.py.j2 index 0bc5d66a7..5ae59a37b 100644 --- a/src/agentex/lib/cli/templates/sync-codex/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/sync-codex/project/acp.py.j2 @@ -34,7 +34,7 @@ import agentex.lib.adk as adk from agentex.lib.adk import CodexTurn from agentex.lib.types.acp import SendMessageParams from agentex.lib.core.harness import UnifiedEmitter -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from agentex.lib.utils.logging import make_logger from agentex.types.text_content import TextContent from agentex.lib.sdk.fastacp.fastacp import FastACP @@ -44,6 +44,9 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce logger = make_logger(__name__) +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + add_tracing_processor_config( SGPTracingProcessorConfig( sgp_api_key=os.environ.get("SGP_API_KEY", ""), diff --git a/src/agentex/lib/cli/templates/sync-langgraph/project/acp.py.j2 b/src/agentex/lib/cli/templates/sync-langgraph/project/acp.py.j2 index 32d261093..3e2d98102 100644 --- a/src/agentex/lib/cli/templates/sync-langgraph/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/sync-langgraph/project/acp.py.j2 @@ -12,7 +12,7 @@ from agentex.lib.core.harness import UnifiedEmitter from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_processor_config from agentex.lib.sdk.fastacp.fastacp import FastACP from agentex.protocol.acp import SendMessageParams -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from agentex.lib.utils.logging import make_logger from agentex.types.text_content import TextContent from agentex.lib.adk import LangGraphTurn @@ -33,7 +33,10 @@ from project.graph import create_graph logger = make_logger(__name__) -# Register the Agentex tracing processor so spans are shipped to the backend +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + +# Register the Scale GenAI Platform (SGP) tracing processor add_tracing_processor_config( SGPTracingProcessorConfig( sgp_api_key=os.environ.get("SGP_API_KEY", ""), diff --git a/src/agentex/lib/cli/templates/sync-openai-agents-local-sandbox/project/acp.py.j2 b/src/agentex/lib/cli/templates/sync-openai-agents-local-sandbox/project/acp.py.j2 index 14af98351..63538a06d 100644 --- a/src/agentex/lib/cli/templates/sync-openai-agents-local-sandbox/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/sync-openai-agents-local-sandbox/project/acp.py.j2 @@ -21,7 +21,7 @@ load_dotenv() from agentex.lib import adk from project.agent import run_agent from agentex.protocol.acp import SendMessageParams -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from agentex.lib.utils.logging import make_logger from agentex.types.text_content import TextContent from agentex.lib.sdk.fastacp.fastacp import FastACP @@ -42,6 +42,9 @@ SGP_API_KEY = os.environ.get("SGP_API_KEY", "") SGP_ACCOUNT_ID = os.environ.get("SGP_ACCOUNT_ID", "") SGP_CLIENT_BASE_URL = os.environ.get("SGP_CLIENT_BASE_URL", "") +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + if SGP_API_KEY and SGP_ACCOUNT_ID: add_tracing_processor_config( SGPTracingProcessorConfig( 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 41029f2ce..08945a142 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 @@ -6,7 +6,7 @@ from agentex.lib.adk.providers._modules.sync_provider import SyncStreamingProvid from agentex.lib.sdk.fastacp.fastacp import FastACP from agentex.protocol.acp import SendMessageParams from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_processor_config -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from agentex.lib.utils.model_utils import BaseModel from agentex.types.task_message_update import TaskMessageUpdate, StreamTaskMessageFull @@ -32,6 +32,9 @@ SGP_API_KEY = os.environ.get("SGP_API_KEY", "") SGP_ACCOUNT_ID = os.environ.get("SGP_ACCOUNT_ID", "") SGP_CLIENT_BASE_URL = os.environ.get("SGP_CLIENT_BASE_URL", "") +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + if SGP_API_KEY and SGP_ACCOUNT_ID: add_tracing_processor_config( SGPTracingProcessorConfig( diff --git a/src/agentex/lib/cli/templates/sync-pydantic-ai/project/acp.py.j2 b/src/agentex/lib/cli/templates/sync-pydantic-ai/project/acp.py.j2 index 1a3c6f0a9..7a66e0e1c 100644 --- a/src/agentex/lib/cli/templates/sync-pydantic-ai/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/sync-pydantic-ai/project/acp.py.j2 @@ -20,7 +20,7 @@ from project.agent import MODEL_NAME, create_agent import agentex.lib.adk as adk from agentex.protocol.acp import SendMessageParams from agentex.lib.core.harness import UnifiedEmitter -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from agentex.lib.utils.logging import make_logger from agentex.types.text_content import TextContent from agentex.lib.sdk.fastacp.fastacp import FastACP @@ -36,6 +36,9 @@ logger = make_logger(__name__) # processor that's lazy-initialised on first span. SGP_API_KEY = os.environ.get("SGP_API_KEY", "") SGP_ACCOUNT_ID = os.environ.get("SGP_ACCOUNT_ID", "") +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + if SGP_API_KEY and SGP_ACCOUNT_ID: add_tracing_processor_config( SGPTracingProcessorConfig( diff --git a/src/agentex/lib/cli/templates/temporal-claude-code/project/workflow.py.j2 b/src/agentex/lib/cli/templates/temporal-claude-code/project/workflow.py.j2 index 8191ad80f..d1fde0362 100644 --- a/src/agentex/lib/cli/templates/temporal-claude-code/project/workflow.py.j2 +++ b/src/agentex/lib/cli/templates/temporal-claude-code/project/workflow.py.j2 @@ -26,7 +26,7 @@ from temporalio import workflow from agentex.lib import adk from agentex.lib.types.acp import SendEventParams, CreateTaskParams -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from agentex.lib.utils.logging import make_logger from agentex.types.text_content import TextContent from agentex.lib.environment_variables import EnvironmentVariables @@ -37,6 +37,9 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce with workflow.unsafe.imports_passed_through(): from project.activities import RunClaudeCodeTurnParams, run_claude_code_turn +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + add_tracing_processor_config( SGPTracingProcessorConfig( sgp_api_key=os.environ.get("SGP_API_KEY", ""), diff --git a/src/agentex/lib/cli/templates/temporal-codex/project/workflow.py.j2 b/src/agentex/lib/cli/templates/temporal-codex/project/workflow.py.j2 index 1004ebfb8..68fc3f36a 100644 --- a/src/agentex/lib/cli/templates/temporal-codex/project/workflow.py.j2 +++ b/src/agentex/lib/cli/templates/temporal-codex/project/workflow.py.j2 @@ -28,7 +28,7 @@ from temporalio import workflow from agentex.lib import adk from agentex.lib.types.acp import SendEventParams, CreateTaskParams -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from agentex.lib.utils.logging import make_logger from agentex.types.text_content import TextContent from agentex.lib.environment_variables import EnvironmentVariables @@ -39,6 +39,9 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce with workflow.unsafe.imports_passed_through(): from project.activities import RunCodexTurnParams, run_codex_turn +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + add_tracing_processor_config( SGPTracingProcessorConfig( sgp_api_key=os.environ.get("SGP_API_KEY", ""), diff --git a/src/agentex/lib/cli/templates/temporal-langgraph/project/workflow.py.j2 b/src/agentex/lib/cli/templates/temporal-langgraph/project/workflow.py.j2 index 14bafabc1..f8467eb98 100644 --- a/src/agentex/lib/cli/templates/temporal-langgraph/project/workflow.py.j2 +++ b/src/agentex/lib/cli/templates/temporal-langgraph/project/workflow.py.j2 @@ -36,7 +36,7 @@ from agentex.lib import adk from project.graph import GRAPH_NAME, build_graph from agentex.lib.adk import emit_langgraph_messages from agentex.protocol.acp import SendEventParams, CreateTaskParams -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from agentex.lib.utils.logging import make_logger from agentex.types.text_content import TextContent from agentex.lib.environment_variables import EnvironmentVariables @@ -48,6 +48,9 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce # the default processor that is lazy-initialised on first span). SGP_API_KEY = os.environ.get("SGP_API_KEY", "") SGP_ACCOUNT_ID = os.environ.get("SGP_ACCOUNT_ID", "") +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + if SGP_API_KEY and SGP_ACCOUNT_ID: add_tracing_processor_config( SGPTracingProcessorConfig( diff --git a/src/agentex/lib/cli/templates/temporal-openai-agents/project/workflow.py.j2 b/src/agentex/lib/cli/templates/temporal-openai-agents/project/workflow.py.j2 index af8b7a299..62fd99f70 100644 --- a/src/agentex/lib/cli/templates/temporal-openai-agents/project/workflow.py.j2 +++ b/src/agentex/lib/cli/templates/temporal-openai-agents/project/workflow.py.j2 @@ -25,7 +25,7 @@ from project.activities import get_weather from agentex.lib.core.tracing.tracing_processor_manager import ( add_tracing_processor_config, ) -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from datetime import timedelta @@ -39,6 +39,9 @@ if environment_variables.AGENT_NAME is None: logger = make_logger(__name__) +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + # Setup tracing for SGP (Scale GenAI Platform) # This enables visibility into your agent's execution in the SGP dashboard add_tracing_processor_config( diff --git a/src/agentex/lib/cli/templates/temporal-pydantic-ai/project/workflow.py.j2 b/src/agentex/lib/cli/templates/temporal-pydantic-ai/project/workflow.py.j2 index 6dcca3002..2e500b603 100644 --- a/src/agentex/lib/cli/templates/temporal-pydantic-ai/project/workflow.py.j2 +++ b/src/agentex/lib/cli/templates/temporal-pydantic-ai/project/workflow.py.j2 @@ -24,7 +24,7 @@ from project.agent import TaskDeps, temporal_agent from agentex.lib import adk from agentex.protocol.acp import SendEventParams, CreateTaskParams -from agentex.lib.types.tracing import SGPTracingProcessorConfig +from agentex.lib.types.tracing import SGPTracingProcessorConfig, AgentexTracingProcessorConfig from agentex.lib.utils.logging import make_logger from agentex.types.text_content import TextContent from agentex.lib.environment_variables import EnvironmentVariables @@ -39,6 +39,9 @@ if TYPE_CHECKING: # via the default Agentex processor that's lazy-initialised on first span. SGP_API_KEY = os.environ.get("SGP_API_KEY", "") SGP_ACCOUNT_ID = os.environ.get("SGP_ACCOUNT_ID", "") +# Local Agentex backend: spans appear in the developer UI's traces tab. +add_tracing_processor_config(AgentexTracingProcessorConfig()) + if SGP_API_KEY and SGP_ACCOUNT_ID: add_tracing_processor_config( SGPTracingProcessorConfig( diff --git a/tests/lib/cli/test_init_templates.py b/tests/lib/cli/test_init_templates.py index ec809cbbf..f0ecbe2cb 100644 --- a/tests/lib/cli/test_init_templates.py +++ b/tests/lib/cli/test_init_templates.py @@ -137,3 +137,23 @@ def test_requirements_include_langgraph_plugin_and_temporal(self, tmp_path: Path requirements = (project_dir / "requirements.txt").read_text() assert "temporalio[langgraph]>=1.27.0" in requirements assert "langchain-openai" in requirements + + +_FRAMEWORK_TEMPLATES = [t for t in TemplateType if t not in (TemplateType.DEFAULT, TemplateType.SYNC, TemplateType.TEMPORAL)] + + +@pytest.mark.parametrize("template_type", _FRAMEWORK_TEMPLATES) +def test_framework_templates_register_local_tracing_processor(tmp_path: Path, template_type: TemplateType): + """Every framework template registers the Agentex tracing processor. + + Without it, spans derived by the unified harness only go to the (optional) + SGP processor, and the developer UI's traces tab stays empty for a locally + scaffolded agent. + """ + project_dir = _render_project(tmp_path, template_type) + entrypoints = [p for p in project_dir.rglob("*.py") if p.name in ("acp.py", "workflow.py")] + assert entrypoints, f"{template_type.value} has no acp.py/workflow.py" + joined = "\n".join(p.read_text() for p in entrypoints) + assert "add_tracing_processor_config(AgentexTracingProcessorConfig())" in joined, ( + f"{template_type.value} does not register AgentexTracingProcessorConfig" + ) From 8a049a71ee7ed54994f0ac91f666ecf9cdd70c33 Mon Sep 17 00:00:00 2001 From: Michael Xu Date: Thu, 10 Sep 2026 12:20:06 -0500 Subject: [PATCH 2/2] fix(templates): skip the local tracing processor when the backend is disabled The runtime treats an explicitly empty AGENTEX_BASE_URL as "no backend" and skips agent registration; registering the Agentex tracing processor unconditionally would then make every span export fail. Guard the registration on the same condition in all 16 framework templates. Claude-Session: https://claude.ai/code/session_01HCVKnA7LeJZ44nxZz1uzF3 --- .../cli/templates/default-claude-code/project/acp.py.j2 | 7 +++++-- .../lib/cli/templates/default-codex/project/acp.py.j2 | 7 +++++-- .../lib/cli/templates/default-langgraph/project/acp.py.j2 | 7 +++++-- .../cli/templates/default-openai-agents/project/acp.py.j2 | 7 +++++-- .../cli/templates/default-pydantic-ai/project/acp.py.j2 | 7 +++++-- .../lib/cli/templates/sync-claude-code/project/acp.py.j2 | 7 +++++-- src/agentex/lib/cli/templates/sync-codex/project/acp.py.j2 | 7 +++++-- .../lib/cli/templates/sync-langgraph/project/acp.py.j2 | 7 +++++-- .../sync-openai-agents-local-sandbox/project/acp.py.j2 | 7 +++++-- .../lib/cli/templates/sync-openai-agents/project/acp.py.j2 | 7 +++++-- .../lib/cli/templates/sync-pydantic-ai/project/acp.py.j2 | 7 +++++-- .../templates/temporal-claude-code/project/workflow.py.j2 | 7 +++++-- .../cli/templates/temporal-codex/project/workflow.py.j2 | 7 +++++-- .../templates/temporal-langgraph/project/workflow.py.j2 | 7 +++++-- .../temporal-openai-agents/project/workflow.py.j2 | 7 +++++-- .../templates/temporal-pydantic-ai/project/workflow.py.j2 | 7 +++++-- 16 files changed, 80 insertions(+), 32 deletions(-) diff --git a/src/agentex/lib/cli/templates/default-claude-code/project/acp.py.j2 b/src/agentex/lib/cli/templates/default-claude-code/project/acp.py.j2 index d662c9e21..391a6f5cb 100644 --- a/src/agentex/lib/cli/templates/default-claude-code/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/default-claude-code/project/acp.py.j2 @@ -33,8 +33,11 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce logger = make_logger(__name__) -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) add_tracing_processor_config( SGPTracingProcessorConfig( diff --git a/src/agentex/lib/cli/templates/default-codex/project/acp.py.j2 b/src/agentex/lib/cli/templates/default-codex/project/acp.py.j2 index 55616b85b..c53a1e367 100644 --- a/src/agentex/lib/cli/templates/default-codex/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/default-codex/project/acp.py.j2 @@ -43,8 +43,11 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce logger = make_logger(__name__) -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) add_tracing_processor_config( SGPTracingProcessorConfig( diff --git a/src/agentex/lib/cli/templates/default-langgraph/project/acp.py.j2 b/src/agentex/lib/cli/templates/default-langgraph/project/acp.py.j2 index 0254deec8..5bc72f881 100644 --- a/src/agentex/lib/cli/templates/default-langgraph/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/default-langgraph/project/acp.py.j2 @@ -29,8 +29,11 @@ from project.graph import create_graph logger = make_logger(__name__) -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) add_tracing_processor_config( SGPTracingProcessorConfig( diff --git a/src/agentex/lib/cli/templates/default-openai-agents/project/acp.py.j2 b/src/agentex/lib/cli/templates/default-openai-agents/project/acp.py.j2 index 1548ca816..cee6d5087 100644 --- a/src/agentex/lib/cli/templates/default-openai-agents/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/default-openai-agents/project/acp.py.j2 @@ -48,8 +48,11 @@ if _litellm_key and not os.environ.get("OPENAI_API_KEY"): _sgp_api_key = os.environ.get("SGP_API_KEY", "") _sgp_account_id = os.environ.get("SGP_ACCOUNT_ID", "") -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) if _sgp_api_key and _sgp_account_id: add_tracing_processor_config( diff --git a/src/agentex/lib/cli/templates/default-pydantic-ai/project/acp.py.j2 b/src/agentex/lib/cli/templates/default-pydantic-ai/project/acp.py.j2 index c42b4fda3..9bc5e3e84 100644 --- a/src/agentex/lib/cli/templates/default-pydantic-ai/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/default-pydantic-ai/project/acp.py.j2 @@ -42,8 +42,11 @@ logger = make_logger(__name__) # so they show up in the per-task spans dropdown out of the box. SGP_API_KEY = os.environ.get("SGP_API_KEY", "") SGP_ACCOUNT_ID = os.environ.get("SGP_ACCOUNT_ID", "") -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) if SGP_API_KEY and SGP_ACCOUNT_ID: add_tracing_processor_config( diff --git a/src/agentex/lib/cli/templates/sync-claude-code/project/acp.py.j2 b/src/agentex/lib/cli/templates/sync-claude-code/project/acp.py.j2 index 020fd95aa..b48371736 100644 --- a/src/agentex/lib/cli/templates/sync-claude-code/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/sync-claude-code/project/acp.py.j2 @@ -35,8 +35,11 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce logger = make_logger(__name__) -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) add_tracing_processor_config( SGPTracingProcessorConfig( diff --git a/src/agentex/lib/cli/templates/sync-codex/project/acp.py.j2 b/src/agentex/lib/cli/templates/sync-codex/project/acp.py.j2 index 5ae59a37b..b0469943b 100644 --- a/src/agentex/lib/cli/templates/sync-codex/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/sync-codex/project/acp.py.j2 @@ -44,8 +44,11 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce logger = make_logger(__name__) -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) add_tracing_processor_config( SGPTracingProcessorConfig( diff --git a/src/agentex/lib/cli/templates/sync-langgraph/project/acp.py.j2 b/src/agentex/lib/cli/templates/sync-langgraph/project/acp.py.j2 index 3e2d98102..f327b2f1f 100644 --- a/src/agentex/lib/cli/templates/sync-langgraph/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/sync-langgraph/project/acp.py.j2 @@ -33,8 +33,11 @@ from project.graph import create_graph logger = make_logger(__name__) -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) # Register the Scale GenAI Platform (SGP) tracing processor add_tracing_processor_config( diff --git a/src/agentex/lib/cli/templates/sync-openai-agents-local-sandbox/project/acp.py.j2 b/src/agentex/lib/cli/templates/sync-openai-agents-local-sandbox/project/acp.py.j2 index 63538a06d..6cb578204 100644 --- a/src/agentex/lib/cli/templates/sync-openai-agents-local-sandbox/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/sync-openai-agents-local-sandbox/project/acp.py.j2 @@ -42,8 +42,11 @@ SGP_API_KEY = os.environ.get("SGP_API_KEY", "") SGP_ACCOUNT_ID = os.environ.get("SGP_ACCOUNT_ID", "") SGP_CLIENT_BASE_URL = os.environ.get("SGP_CLIENT_BASE_URL", "") -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) if SGP_API_KEY and SGP_ACCOUNT_ID: add_tracing_processor_config( 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 08945a142..28e450450 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 @@ -32,8 +32,11 @@ SGP_API_KEY = os.environ.get("SGP_API_KEY", "") SGP_ACCOUNT_ID = os.environ.get("SGP_ACCOUNT_ID", "") SGP_CLIENT_BASE_URL = os.environ.get("SGP_CLIENT_BASE_URL", "") -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) if SGP_API_KEY and SGP_ACCOUNT_ID: add_tracing_processor_config( diff --git a/src/agentex/lib/cli/templates/sync-pydantic-ai/project/acp.py.j2 b/src/agentex/lib/cli/templates/sync-pydantic-ai/project/acp.py.j2 index 7a66e0e1c..995f68248 100644 --- a/src/agentex/lib/cli/templates/sync-pydantic-ai/project/acp.py.j2 +++ b/src/agentex/lib/cli/templates/sync-pydantic-ai/project/acp.py.j2 @@ -36,8 +36,11 @@ logger = make_logger(__name__) # processor that's lazy-initialised on first span. SGP_API_KEY = os.environ.get("SGP_API_KEY", "") SGP_ACCOUNT_ID = os.environ.get("SGP_ACCOUNT_ID", "") -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) if SGP_API_KEY and SGP_ACCOUNT_ID: add_tracing_processor_config( diff --git a/src/agentex/lib/cli/templates/temporal-claude-code/project/workflow.py.j2 b/src/agentex/lib/cli/templates/temporal-claude-code/project/workflow.py.j2 index d1fde0362..69fd24d7f 100644 --- a/src/agentex/lib/cli/templates/temporal-claude-code/project/workflow.py.j2 +++ b/src/agentex/lib/cli/templates/temporal-claude-code/project/workflow.py.j2 @@ -37,8 +37,11 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce with workflow.unsafe.imports_passed_through(): from project.activities import RunClaudeCodeTurnParams, run_claude_code_turn -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) add_tracing_processor_config( SGPTracingProcessorConfig( diff --git a/src/agentex/lib/cli/templates/temporal-codex/project/workflow.py.j2 b/src/agentex/lib/cli/templates/temporal-codex/project/workflow.py.j2 index 68fc3f36a..9f19bbfa3 100644 --- a/src/agentex/lib/cli/templates/temporal-codex/project/workflow.py.j2 +++ b/src/agentex/lib/cli/templates/temporal-codex/project/workflow.py.j2 @@ -39,8 +39,11 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce with workflow.unsafe.imports_passed_through(): from project.activities import RunCodexTurnParams, run_codex_turn -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) add_tracing_processor_config( SGPTracingProcessorConfig( diff --git a/src/agentex/lib/cli/templates/temporal-langgraph/project/workflow.py.j2 b/src/agentex/lib/cli/templates/temporal-langgraph/project/workflow.py.j2 index f8467eb98..ab734e9a4 100644 --- a/src/agentex/lib/cli/templates/temporal-langgraph/project/workflow.py.j2 +++ b/src/agentex/lib/cli/templates/temporal-langgraph/project/workflow.py.j2 @@ -48,8 +48,11 @@ from agentex.lib.core.tracing.tracing_processor_manager import add_tracing_proce # the default processor that is lazy-initialised on first span). SGP_API_KEY = os.environ.get("SGP_API_KEY", "") SGP_ACCOUNT_ID = os.environ.get("SGP_ACCOUNT_ID", "") -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) if SGP_API_KEY and SGP_ACCOUNT_ID: add_tracing_processor_config( diff --git a/src/agentex/lib/cli/templates/temporal-openai-agents/project/workflow.py.j2 b/src/agentex/lib/cli/templates/temporal-openai-agents/project/workflow.py.j2 index 62fd99f70..833aab650 100644 --- a/src/agentex/lib/cli/templates/temporal-openai-agents/project/workflow.py.j2 +++ b/src/agentex/lib/cli/templates/temporal-openai-agents/project/workflow.py.j2 @@ -39,8 +39,11 @@ if environment_variables.AGENT_NAME is None: logger = make_logger(__name__) -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) # Setup tracing for SGP (Scale GenAI Platform) # This enables visibility into your agent's execution in the SGP dashboard diff --git a/src/agentex/lib/cli/templates/temporal-pydantic-ai/project/workflow.py.j2 b/src/agentex/lib/cli/templates/temporal-pydantic-ai/project/workflow.py.j2 index 2e500b603..b7f37c43f 100644 --- a/src/agentex/lib/cli/templates/temporal-pydantic-ai/project/workflow.py.j2 +++ b/src/agentex/lib/cli/templates/temporal-pydantic-ai/project/workflow.py.j2 @@ -39,8 +39,11 @@ if TYPE_CHECKING: # via the default Agentex processor that's lazy-initialised on first span. SGP_API_KEY = os.environ.get("SGP_API_KEY", "") SGP_ACCOUNT_ID = os.environ.get("SGP_ACCOUNT_ID", "") -# Local Agentex backend: spans appear in the developer UI's traces tab. -add_tracing_processor_config(AgentexTracingProcessorConfig()) +# Local Agentex backend: spans appear in the developer UI's traces tab. Skipped +# when AGENTEX_BASE_URL is explicitly empty (the runtime then treats the backend +# as disabled and skips agent registration too). +if os.environ.get("AGENTEX_BASE_URL", "http://localhost:5003"): + add_tracing_processor_config(AgentexTracingProcessorConfig()) if SGP_API_KEY and SGP_ACCOUNT_ID: add_tracing_processor_config(