Skip to content

Commit 6c45e1f

Browse files
committed
Temporal fix
1 parent b236a47 commit 6c45e1f

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

docs/durable_execution/temporal.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ As workflows and activities run in separate processes, any values passed between
172172

173173
To account for these limitations, tool functions and the [event stream handler](#streaming) running inside activities receive a limited version of the agent's [`RunContext`][pydantic_ai.tools.RunContext], and it's your responsibility to make sure that the [dependencies](../dependencies.md) object provided to [`TemporalAgent.run()`][pydantic_ai.durable_exec.temporal.TemporalAgent.run] can be serialized using Pydantic.
174174

175-
Specifically, only the `deps`, `retries`, `tool_call_id`, `tool_name`, `tool_call_approved`, `retry`, `max_retries`, `run_step` and `partial_output` fields are available by default, and trying to access `model`, `usage`, `prompt`, `messages`, or `tracer` will raise an error.
175+
Specifically, only the `deps`, `run_id`, `retries`, `tool_call_id`, `tool_name`, `tool_call_approved`, `retry`, `max_retries`, `run_step` and `partial_output` fields are available by default, and trying to access `model`, `usage`, `prompt`, `messages`, or `tracer` will raise an error.
176176
If you need one or more of these attributes to be available inside activities, you can create a [`TemporalRunContext`][pydantic_ai.durable_exec.temporal.TemporalRunContext] subclass with custom `serialize_run_context` and `deserialize_run_context` class methods and pass it to [`TemporalAgent`][pydantic_ai.durable_exec.temporal.TemporalAgent] as `run_context_type`.
177177

178178
### Streaming

pydantic_ai_slim/pydantic_ai/durable_exec/temporal/_run_context.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
class TemporalRunContext(RunContext[AgentDepsT]):
1515
"""The [`RunContext`][pydantic_ai.tools.RunContext] subclass to use to serialize and deserialize the run context for use inside a Temporal activity.
1616
17-
By default, only the `deps`, `retries`, `tool_call_id`, `tool_name`, `tool_call_approved`, `retry`, `max_retries`, `run_step` and `partial_output` attributes will be available.
17+
By default, only the `deps`, `run_id`, `retries`, `tool_call_id`, `tool_name`, `tool_call_approved`, `retry`, `max_retries`, `run_step` and `partial_output` attributes will be available.
1818
To make another attribute available, create a `TemporalRunContext` subclass with a custom `serialize_run_context` class method that returns a dictionary that includes the attribute and pass it to [`TemporalAgent`][pydantic_ai.durable_exec.temporal.TemporalAgent].
1919
"""
2020

@@ -42,6 +42,7 @@ def __getattribute__(self, name: str) -> Any:
4242
def serialize_run_context(cls, ctx: RunContext[Any]) -> dict[str, Any]:
4343
"""Serialize the run context to a `dict[str, Any]`."""
4444
return {
45+
'run_id': ctx.run_id,
4546
'retries': ctx.retries,
4647
'tool_call_id': ctx.tool_call_id,
4748
'tool_name': ctx.tool_name,

tests/test_temporal.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
PartStartEvent,
3232
RetryPromptPart,
3333
RunContext,
34+
RunUsage,
3435
TextPart,
3536
TextPartDelta,
3637
ToolCallPart,
@@ -44,6 +45,7 @@
4445
from pydantic_ai.exceptions import ApprovalRequired, CallDeferred, ModelRetry, UserError
4546
from pydantic_ai.models import Model, cached_async_http_client
4647
from pydantic_ai.models.function import AgentInfo, FunctionModel
48+
from pydantic_ai.models.test import TestModel
4749
from pydantic_ai.run import AgentRunResult
4850
from pydantic_ai.tools import DeferredToolRequests, DeferredToolResults, ToolDefinition
4951
from pydantic_ai.usage import RequestUsage
@@ -63,6 +65,7 @@
6365
from pydantic_ai.durable_exec.temporal._function_toolset import TemporalFunctionToolset
6466
from pydantic_ai.durable_exec.temporal._mcp_server import TemporalMCPServer
6567
from pydantic_ai.durable_exec.temporal._model import TemporalModel
68+
from pydantic_ai.durable_exec.temporal._run_context import TemporalRunContext
6669
except ImportError: # pragma: lax no cover
6770
pytest.skip('temporal not installed', allow_module_level=True)
6871

@@ -2162,3 +2165,18 @@ async def test_web_search_agent_run_in_workflow(allow_model_requests: None, clie
21622165
assert output == snapshot(
21632166
'Severe floods and landslides across Veracruz, Hidalgo, and Puebla have cut off hundreds of communities and left dozens dead and many missing, prompting a major federal emergency response. ([apnews.com](https://apnews.com/article/5d036e18057361281e984b44402d3b1b?utm_source=openai))'
21642167
)
2168+
2169+
2170+
def test_temporal_run_context_preserves_run_id():
2171+
ctx = RunContext(
2172+
deps=None,
2173+
model=TestModel(),
2174+
usage=RunUsage(),
2175+
run_id='run-123',
2176+
)
2177+
2178+
serialized = TemporalRunContext.serialize_run_context(ctx)
2179+
assert serialized['run_id'] == 'run-123'
2180+
2181+
reconstructed = TemporalRunContext.deserialize_run_context(serialized, deps=None)
2182+
assert reconstructed.run_id == 'run-123'

0 commit comments

Comments
 (0)