You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Address PR review comments and refine chatbot architecture
- Simplify basic/worker.py to use asyncio.run(main()) pattern
- Basic activity now returns str instead of Response (drops pydantic dep)
- Remove pydantic_data_converter from basic worker/starter
- Replace chatbot signal+poll with update handler (message_from_user)
- Wrap update handler body in @Traceable for input/output capture
- Inline RetryPolicy in chatbot workflow (no separate RETRY constant)
- Add comment about alternative traceable() function-call style
- Make PROJECT_NAME a shared constant in starters, pass to client-side
@Traceable so traces go to the right LangSmith project
- Update READMEs with correct trace hierarchies based on real output
- Fix wrap_openai span name (ChatOpenAI, not openai.responses.create)
- Simplify tests (mocks match new str return type, use execute_update)
- Remove poll_last_response helper
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Only `@traceable` and `wrap_openai` spans appear. The client-side `@traceable` is the root, and all workflow/activity traces nest under it via context propagation:
21
+
Only `@traceable` and `wrap_openai` spans appear. The client-side `@traceable` is the root, and workflow/activity traces nest under it via context propagation.
22
22
23
23
```
24
24
Basic LLM Request (@traceable, client-side)
25
25
└── Ask: What is Temporal? (@traceable, workflow)
26
26
└── Call OpenAI (@traceable, activity)
27
-
└── openai.responses.create (automatic via wrap_openai)
uv run --group langsmith-tracing python -m langsmith_tracing.basic.starter --add-temporal-runs
37
37
```
38
38
39
-
Temporal operation spans are added. `StartWorkflow` and `RunWorkflow`are siblings under the client root; `StartActivity` and `RunActivity`are siblings under the workflow:
39
+
Temporal operation spans are added. `StartWorkflow`/`RunWorkflow`and `StartActivity`/`RunActivity`appear as sibling pairs:
A long-running conversational workflow with tool calls, signals, and queries. Demonstrates how LangSmith traces an agentic loop where the model calls tools across multiple turns.
3
+
A long-running conversational workflow with tool callsand update handlers. Demonstrates how LangSmith traces an agentic loop where the model calls tools across multiple turns.
4
4
5
5
See the [parent README](../README.md) for prerequisites.
6
6
@@ -25,58 +25,57 @@ The model has two tools, both implemented as `@traceable` methods on the workflo
25
25
-**`save_note(name, content)`** — Stores a note in the workflow's in-memory dict. The note is durable because workflow state survives crashes and restarts via Temporal's event history.
26
26
-**`read_note(name)`** — Reads a note from the workflow's in-memory dict.
27
27
28
+
## Architecture
29
+
30
+
The main `@workflow.run` method runs a loop that processes user messages (calls `_query_openai`, which handles the tool-call loop). The `message_from_user` update handler coordinates: it hands the message to the main loop via a shared `_pending_message` field, then waits for the response.
31
+
32
+
This means:
33
+
- Activity calls and the tool loop happen inside the main workflow run
34
+
- The update handler's trace just shows the input/output of the coordination step
35
+
28
36
## Trace Structure
29
37
30
38
### `add_temporal_runs=False` (default)
31
39
32
-
Only `@traceable` and `wrap_openai` spans appear. The client-side `@traceable` wraps `start_workflow`, so the workflow's traces nest under it via context propagation. Signals and queries produce no traces in this mode.
40
+
Only `@traceable` and `wrap_openai` spans appear. The client-side `@traceable` wraps `start_workflow` and each `execute_update`, so both workflow and update traces nest under it via context propagation.
├── Session Apr 17 10:30 (@traceable, workflow main loop)
45
+
│ ├── Request: hello (@traceable, per-message in main loop)
46
+
│ │ └── Call OpenAI (@traceable, activity)
47
+
│ │ └── ChatOpenAI (automatic via wrap_openai)
48
+
│ └── Request: save that as note 15 (@traceable, per-message in main loop)
49
+
│ ├── Call OpenAI → function_call: save_note
50
+
│ ├── Save Note (@traceable, workflow method)
51
+
│ └── Call OpenAI → text response
52
+
├── Update: hello (@traceable, update handler)
53
+
└── Update: save that as note 15 (@traceable, update handler)
55
54
```
56
55
57
56
### `add_temporal_runs=True`
58
57
59
-
With `--add-temporal-runs`, Temporal operation spans are added. `StartWorkflow` and `RunWorkflow`are siblings under the client root (context propagated via headers at `start_workflow` time). Signals and queries each get their own trace.
58
+
With `--add-temporal-runs`, Temporal operation spans are added. `StartWorkflow`/`RunWorkflow`and `StartActivity`/`RunActivity` appear as sibling pairs.
│ └── Update: save that as note 15 (@traceable, update handler)
81
78
└── ...
82
79
```
80
+
81
+
Note that the `Request:` chain (with activity calls) lives under `RunWorkflow` (the main loop), while the `Update:` span lives under `HandleUpdate` (the update handler). They're connected by the shared workflow state but appear as separate subtrees.
0 commit comments