@@ -38,23 +38,29 @@ Contents:
3838
3939## Run it
4040
41+ The sample has its own uv project because the repository's root lock still
42+ pins ` openai ` 2.x for the LiteLLM samples, while ` temporalio-openai-agents `
43+ 1.1.0 needs ` openai ` 3. Run everything from this directory:
44+
4145``` bash
46+ cd arize_tracing
47+
4248# 1. Start Phoenix (UI, REST API, and OTLP collector on port 6006)
43- docker compose -f arize_tracing/ phoenix/docker-compose.yml up -d
49+ docker compose -f phoenix/docker-compose.yml up -d
4450curl -sf http://localhost:6006/healthz && echo ok
4551# ...or without Docker: uvx --from "arize-phoenix==20.16.0" phoenix serve
4652
47- # 2. Install dependencies and set environment (repo root)
48- uv sync --group arize-tracing
49- cp arize_tracing/ .env.example arize_tracing/ .env # edit the LLM settings
50- set -a; source arize_tracing/ .env; set +a
53+ # 2. Install dependencies and set environment
54+ uv sync
55+ cp .env.example .env # edit the LLM settings
56+ set -a; source .env; set +a
5157
5258# 3. Run the sample (two terminals, same environment)
53- uv run python -m arize_tracing. ticket_triage.worker
54- uv run python -m arize_tracing. ticket_triage.starter
59+ uv run python -m ticket_triage.worker
60+ uv run python -m ticket_triage.starter
5561
5662# 4. Verify the trace through the Phoenix API (uses the printed trace ID)
57- uv run python -m arize_tracing. verify_trace --trace-id < printed trace id>
63+ uv run verify_trace.py --trace-id < printed trace id>
5864```
5965
6066The starter prints a direct link to the trace in Phoenix (project
@@ -86,11 +92,9 @@ session.
8692### With the OpenAI Agents SDK
8793
8894``` bash
89- # Two worker processes (see "Known issue" below), then the starter
90- uv run python -m arize_tracing.ticket_triage_agents.worker --role workflows
91- uv run python -m arize_tracing.ticket_triage_agents.worker --role activities
92- uv run python -m arize_tracing.ticket_triage_agents.starter
93- uv run python -m arize_tracing.verify_trace --trace-id < printed trace id> --scenario agents
95+ uv run python -m ticket_triage_agents.worker
96+ uv run python -m ticket_triage_agents.starter
97+ uv run verify_trace.py --trace-id < printed trace id> --scenario agents
9498```
9599
96100Here the Agents SDK trace itself becomes the root, and the plugin's
@@ -102,40 +106,17 @@ Ticket triage agents AGENT (root; session, user, in
102106│ └─ temporal:executeWorkflow CHAIN
103107│ ├─ Agent workflow → Triage agent AGENT
104108│ │ ├─ turn CHAIN
105- │ │ │ └─ temporal:startActivity CHAIN (model call)
106- │ │ │ ├─ temporal:executeActivity → response LLM
107- │ │ │ └─ lookup_account TOOL (a Temporal activity as an agent tool)
108- │ │ │ └─ temporal:startActivity → temporal:executeActivity
109+ │ │ │ ├─ temporal:startActivity → temporal:executeActivity → response LLM (model call)
110+ │ │ │ └─ lookup_account TOOL (a Temporal activity as an agent tool)
111+ │ │ │ └─ temporal:startActivity → temporal:executeActivity
109112│ │ └─ turn → temporal:startActivity → temporal:executeActivity → response LLM
110113│ └─ Agent workflow → Reply agent AGENT
111114│ └─ turn → temporal:startActivity → temporal:executeActivity → response LLM
112115└─ temporal:updateWorkflow CHAIN
113116```
114117
115- (The tool span nests under the preceding model call's ` temporal:startActivity `
116- span rather than directly under the turn because ` temporalio-openai-agents `
117- 1.0.0 leaves that span current in the Agents SDK scope after it finishes
118- ([ temporalio/sdk-python #1855 ] ( https://github.com/temporalio/sdk-python/issues/1855 ) ,
119- fixed upstream in
120- [ temporalio/ai-integrations #26 ] ( https://github.com/temporalio/ai-integrations/pull/26 )
121- but not yet released).)
122-
123118![ Ticket triage agents trace in Phoenix] ( phoenix-ticket-triage-agents.png )
124119
125- ** Known issue.** With ` use_otel_instrumentation=True ` , ` temporalio-openai-agents `
126- 1.0.0 (like ` temporalio.contrib.openai_agents ` ) exports the
127- ` temporal:startActivity ` spans with a parent that is not in the trace when a
128- single worker process runs both the workflow and its activities, so the
129- model-call and tool subtrees appear detached from the agent turns in Arize
130- ([ temporalio/sdk-python #1852 ] ( https://github.com/temporalio/sdk-python/issues/1852 ) ).
131- The fix is merged upstream in
132- [ temporalio/ai-integrations #26 ] ( https://github.com/temporalio/ai-integrations/pull/26 )
133- but not yet in a release. ` verify_trace.py ` reports the problem as spans
134- referencing a missing parent. Running the workflow and the activities in
135- separate worker processes, as above, avoids it; ` worker.py ` without ` --role `
136- runs both in one process, so keep the split until a release with the fix is
137- out.
138-
139120## How replay, retries, and restarts show up
140121
141122Durable execution means workflow code re-executes (replays) on worker
@@ -159,37 +140,37 @@ Reproduce each case with the flags below; every run must still verify cleanly:
159140``` bash
160141# Replay stress: disable the workflow cache so EVERY workflow task replays
161142# the workflow from the start of history. The trace must be identical.
162- uv run python -m arize_tracing. ticket_triage.worker --replay-stress
163- uv run python -m arize_tracing. ticket_triage.starter
164- uv run python -m arize_tracing. verify_trace --trace-id < printed trace id>
143+ uv run python -m ticket_triage.worker --replay-stress
144+ uv run python -m ticket_triage.starter
145+ uv run verify_trace.py --trace-id < printed trace id>
165146
166147# Worker restart mid-workflow: the starter waits 20s before sending the
167148# approval. Give the triage activities a few seconds to finish, then kill the
168149# worker while the workflow durably awaits approval; start a new worker and
169150# watch the workflow (and its trace) complete cleanly.
170- uv run python -m arize_tracing. ticket_triage.starter --pause-before-approval 20
151+ uv run python -m ticket_triage.starter --pause-before-approval 20
171152# ... after ~5s, ctrl+c the worker, then start it again in another terminal
172- uv run python -m arize_tracing. verify_trace --trace-id < printed trace id>
153+ uv run verify_trace.py --trace-id < printed trace id>
173154
174155# Activity retry: classify_ticket fails on its first attempt. Arize shows two
175156# RunActivity:classify_ticket spans, the first with an error status.
176- uv run python -m arize_tracing. ticket_triage.worker --fail-first-attempt
177- uv run python -m arize_tracing. ticket_triage.starter
178- uv run python -m arize_tracing. verify_trace --trace-id < id> --expect-attempts classify_ticket=2
157+ uv run python -m ticket_triage.worker --fail-first-attempt
158+ uv run python -m ticket_triage.starter
159+ uv run verify_trace.py --trace-id < id> --expect-attempts classify_ticket=2
179160
180161# Worker crash mid-activity: classify_ticket heartbeats for 30s first. Kill
181162# the worker hard (kill -9) during that time and start a new one. The first
182163# attempt's span was never ended, so it is absent; the retry appears with
183164# attempt 2 after the heartbeat timeout.
184- uv run python -m arize_tracing. ticket_triage.worker --slow-classify 30
185- uv run python -m arize_tracing. ticket_triage.starter
186- uv run python -m arize_tracing. verify_trace --trace-id < id> --expect-attempt classify_ticket=2
165+ uv run python -m ticket_triage.worker --slow-classify 30
166+ uv run python -m ticket_triage.starter
167+ uv run verify_trace.py --trace-id < id> --expect-attempt classify_ticket=2
187168
188169# Reset: rerun a finished workflow from its first workflow task. The reset
189170# reapplies the original approval update, and the new run shares the trace as
190171# a second RunWorkflow span with its own run ID.
191172temporal workflow reset --workflow-id < workflow id> --type FirstWorkflowTask --reason demo
192- uv run python -m arize_tracing. verify_trace --workflow-id < workflow id> --expect-runs 2
173+ uv run verify_trace.py --workflow-id < workflow id> --expect-runs 2
193174```
194175
195176![ Activity retry attempts in Phoenix] ( phoenix-retry-attempts.png )
@@ -241,27 +222,25 @@ and have not been exercised against an AX space here.
241222- ` OTEL_SDK_DISABLED=true ` turns off export without code changes.
242223- Ingestion is asynchronous; ` verify_trace.py ` polls until the trace is stable.
243224- The OpenAI Agents SDK bridge (` use_otel_instrumentation=True ` ) ships in the
244- standalone ` temporalio-openai-agents ` package and is Public Preview. Run the
245- starter, the workflow worker, and the activity worker as separate processes,
246- as the sample does (see the known issue above), and see
247- ` quiet_otel_context_detach_errors() ` in ` telemetry.py ` for a log-noise issue
248- in 1.0.0 (fixed upstream in temporalio/ai-integrations #26 ).
225+ standalone ` temporalio-openai-agents ` package and is Public Preview. Use
226+ 1.1.0 or later: earlier versions mis-parent the ` temporal:startActivity `
227+ spans when one worker runs both the workflow and its activities
228+ ([ temporalio/sdk-python #1852 ] ( https://github.com/temporalio/sdk-python/issues/1852 ) ).
249229
250230## Tests
251231
252- ` tests/arize_tracing/ ` runs without Arize, Docker, or an LLM: mocked activities
232+ ` tests/ ` runs without Arize, Docker, or an LLM: mocked activities
253233(and the SDK's ` TestModel ` for the agents scenario), an in-memory span
254234exporter, a worker with the workflow cache disabled, whole-tree span
255235assertions, enrichment and retry-attempt assertions, and a ` Replayer ` pass
256236asserting that replaying the finished workflow's history emits zero new spans.
257237
258238``` bash
259- uv run --group arize-tracing pytest tests/arize_tracing -v
239+ uv run poe test # or: uv run pytest -v
240+ uv run poe test --workflow-environment time-skipping
260241```
261242
262243## Using this outside samples-python
263244
264- The sample is self-contained: copy the ` arize_tracing/ ` directory, change the
265- absolute imports (` arize_tracing.ticket_triage.activities ` →
266- ` ticket_triage.activities ` or similar), and install the dependencies listed
267- under ` arize-tracing ` in this repo's ` pyproject.toml ` .
245+ The sample is self-contained: copy this directory, keep its ` pyproject.toml `
246+ (or merge its dependencies into yours), and run the same commands.
0 commit comments