Skip to content

Commit 30a1697

Browse files
authored
Merge branch 'main' into fix-str-enum-decoding
2 parents 8cb5412 + 970509c commit 30a1697

131 files changed

Lines changed: 3230 additions & 20583 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/CODEOWNERS‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,12 @@
1515
/temporalio/contrib/google_genai/ @temporalio/ai-sdk @temporalio/sdk
1616
/temporalio/contrib/langgraph/ @temporalio/ai-sdk @temporalio/sdk
1717
/temporalio/contrib/langsmith/ @temporalio/ai-sdk @temporalio/sdk
18-
/temporalio/contrib/openai_agents/ @temporalio/ai-sdk @temporalio/sdk
1918
/temporalio/contrib/strands/ @temporalio/ai-sdk @temporalio/sdk
2019
/temporalio/contrib/workflow_streams/ @temporalio/ai-sdk @temporalio/sdk
2120
/tests/contrib/deepagents/ @temporalio/ai-sdk @temporalio/sdk
2221
/tests/contrib/google_adk_agents/ @temporalio/ai-sdk @temporalio/sdk
2322
/tests/contrib/google_genai/ @temporalio/ai-sdk @temporalio/sdk
2423
/tests/contrib/langgraph/ @temporalio/ai-sdk @temporalio/sdk
2524
/tests/contrib/langsmith/ @temporalio/ai-sdk @temporalio/sdk
26-
/tests/contrib/openai_agents/ @temporalio/ai-sdk @temporalio/sdk
2725
/tests/contrib/strands/ @temporalio/ai-sdk @temporalio/sdk
2826
/tests/contrib/workflow_streams/ @temporalio/ai-sdk @temporalio/sdk

‎.github/workflows/ci.yml‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ jobs:
2626
- os: ubuntu-latest
2727
python: "3.14"
2828
docsTarget: true
29-
openaiTestTarget: true
3029
clippyLinter: true
3130
- python: "3.10"
3231
pytestExtraArgs: '--reruns 3 --only-rerun "RuntimeError: Failed validating workflow"'
@@ -68,11 +67,6 @@ jobs:
6867
- if: ${{ !endsWith(matrix.os, '-arm') }}
6968
run: poe test ${{matrix.pytestExtraArgs}} -s --workflow-environment time-skipping --junit-xml=junit-xml/${{ matrix.python }}--${{ matrix.os }}--time-skipping.xml
7069
timeout-minutes: 10
71-
- if: ${{ matrix.openaiTestTarget && (github.event.pull_request.head.repo.full_name == '' || github.event.pull_request.head.repo.full_name == 'temporalio/sdk-python') }}
72-
run: poe test tests/contrib/openai_agents/test_openai.py ${{matrix.pytestExtraArgs}} -s --junit-xml=junit-xml/${{ matrix.python }}--${{ matrix.os }}--openai.xml
73-
timeout-minutes: 10
74-
env:
75-
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
7670
- name: "Upload junit-xml artifacts"
7771
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
7872
if: always()

‎CHANGELOG.md‎

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,53 @@ to include examples, links to docs, or any other relevant information.
2020

2121
### Added
2222

23+
### Changed
24+
25+
- Payload converters exposed by data converters and workflow/activity accessors
26+
retain transfer type conversion, so direct use behaves consistently with SDK
27+
serialization.
28+
29+
### Deprecated
30+
31+
### :boom: Breaking Changes
32+
33+
- The OpenAI Agents integration has moved to the independently versioned
34+
[`temporalio-openai-agents`](https://pypi.org/project/temporalio-openai-agents/)
35+
package. The existing `temporalio[openai-agents]` extra now installs that
36+
package, and the old public `temporalio.contrib.openai_agents` imports
37+
remain available at runtime and retain their static type information.
38+
New code should depend on `temporalio-openai-agents` directly and import
39+
`temporalio.openai_agents`.
40+
- **Experimental**: Nexus Workflow Updates now require `wait_for_stage` to be explicitly set to `ACCEPTED`.
41+
42+
### Fixed
43+
44+
- `contrib.google_adk_agents`: agents with an `output_schema` no longer fail every workflow task
45+
when calling the model. The schema type is now sent to the model activity as its JSON schema.
46+
Custom Pydantic schema generation is preserved.
47+
Integer-valued output enums are normalized to strings to match Google GenAI.
48+
49+
- `temporalio.contrib.strands` activity and MCP tools now give the model the
50+
Activity's failure message and expose its exception to after-tool hooks.
51+
52+
- Encoding a datetime search attribute without a timezone now raises
53+
`ValueError("Timezone must be present on all search attribute dates")` on
54+
the typed path, matching the deprecated untyped encoder, instead of sending
55+
a naive ISO string that the server rejects with `BadSearchAttributes`.
56+
57+
- `temporalio.contrib.opentelemetry`: `TracingInterceptor` and `OpenTelemetryInterceptor` no longer
58+
log `Failed to detach context` when a context is torn down on a different thread while
59+
OpenTelemetry's threading instrumentation (enabled by strands, among others) is active; a
60+
context is now detached exactly when its token is still valid in the current
61+
`contextvars.Context`, which it stays when a workflow resumes on another pool thread.
62+
### Security
63+
64+
## [1.34.0] - 2026-09-30
65+
66+
### Added
67+
68+
- Added `WorkflowAlreadyStartedError.first_run_id` for the first execution run
69+
ID when provided by the server.
2370
- **Experimental**: `temporalio.contrib.google_adk_agents` now supports ADK v2
2471
graph workflows, dynamic `@node` workflows, and durable HITL.
2572
- **Experimental**: Experimental support for _Event Groups_. **Event Groups** is a new form of
@@ -44,8 +91,6 @@ to include examples, links to docs, or any other relevant information.
4491
deepagents 0.7 requires `langsmith>=0.10.9`, the `langsmith` extra now allows
4592
`langsmith<0.13` (was `<0.9`).
4693

47-
### Deprecated
48-
4994
### :boom: Breaking Changes
5095

5196
- The `google-adk` extra now requires `google-adk>=2.8.0,<3`, up from `>=2.2.0`.
@@ -56,6 +101,11 @@ to include examples, links to docs, or any other relevant information.
56101

57102
### Fixed
58103

104+
- `temporalio.contrib.deepagents` now preserves model binding options such as
105+
`response_format` and `tool_choice` when tools are also bound.
106+
- Workflow handles returned when a start attaches to a running workflow now use
107+
the server-provided first execution run ID with Temporal Server 1.32.0 or
108+
later.
59109
- Restore `frozenset` values when decoding JSON payloads with a `frozenset` type hint,
60110
including nested frozen sets.
61111
- Decode enums that mix in `str` or `int` (for example `class Color(str, Enum)`) to the enum
@@ -85,8 +135,6 @@ to include examples, links to docs, or any other relevant information.
85135
workflow and activity user metadata are serialized with theirs. This covers the static summary
86136
sent when starting an operation, and the summary and details read back from a description.
87137

88-
### Security
89-
90138
## [1.33.0] - 2026-09-14
91139

92140
### Added

‎README.md‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
[![PyPI](https://img.shields.io/pypi/v/temporalio.svg?style=for-the-badge)](https://pypi.org/project/temporalio)
55
[![MIT](https://img.shields.io/pypi/l/temporalio.svg?style=for-the-badge)](LICENSE)
66

7-
**📣 News: Integration between OpenAI Agents SDK and Temporal is now in public preview. [Learn more](temporalio/contrib/openai_agents/README.md).**
8-
97
[Temporal](https://temporal.io/) is a distributed, scalable, durable, and highly available orchestration engine used to
108
execute asynchronous, long-running business logic in a scalable and resilient way.
119

‎pyproject.toml‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "temporalio"
3-
version = "1.33.0"
3+
version = "1.34.0"
44
description = "Temporal.io Python SDK"
55
authors = [{ name = "Temporal Technologies Inc", email = "sdk@temporal.io" }]
66
requires-python = ">=3.10"
@@ -28,7 +28,7 @@ classifiers = [
2828
grpc = ["grpcio>=1.48.2,<2"]
2929
opentelemetry = ["opentelemetry-api>=1.26,<2", "opentelemetry-sdk>=1.26,<2"]
3030
pydantic = ["pydantic>=2.0.0,<3"]
31-
openai-agents = ["openai-agents>=0.19.2,<0.20", "mcp>=1.9.4, <2"]
31+
openai-agents = ["temporalio-openai-agents>=1.0.0"]
3232
google-adk = ["google-adk>=2.8.0,<3", "mcp>=1.24,<2"]
3333
langgraph = ["langgraph>=1.1.0"]
3434
langsmith = ["langsmith>=0.7.34,<0.13"]
@@ -83,12 +83,10 @@ dev = [
8383
"toml>=0.10.2,<0.11",
8484
"twine>=4.0.1,<5",
8585
"maturin>=1.8.2",
86-
"openinference-instrumentation-openai-agents>=0.1.0",
86+
"temporalio-openai-agents>=1.0.0",
8787
"pytest-cov>=6.1.1",
8888
"httpx>=0.28.1",
8989
"pytest-pretty>=1.3.0",
90-
"openai-agents>=0.19.2,<0.20; python_version >= '3.14'",
91-
"openai-agents[litellm]>=0.19.2,<0.20; python_version < '3.14'",
9290
"litellm>=1.83.0",
9391
"openinference-instrumentation-google-adk>=0.1.11",
9492
"googleapis-common-protos>=1.75.0,<2",

‎temporalio/__init__.py‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@
88
:py:mod:`worker` to run workflows and activities.
99
"""
1010

11+
from pkgutil import extend_path as _extend_path
12+
1113
from .service import __version__ as __sdk_version
1214

15+
# After Python finds this ``temporalio`` package, it does not keep searching for
16+
# other ``temporalio`` directories, such as one containing the separately
17+
# installed ``temporalio-openai-agents`` package. Explicitly extend the search
18+
# path so they can be found. Every package that provides ``temporalio/__init__.py``
19+
# must do this: https://docs.python.org/3.14/library/pkgutil.html#pkgutil.extend_path
20+
__path__ = _extend_path(__path__, __name__)
21+
1322
__version__ = __sdk_version

‎temporalio/activity.py‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,13 @@ def payload_converter(self) -> temporalio.converter.PayloadConverter:
241241
self.payload_converter_class_or_instance,
242242
temporalio.converter.PayloadConverter,
243243
):
244-
self._payload_converter = self.payload_converter_class_or_instance
244+
self._payload_converter = _TemporalTransferTypePayloadConverter.wrap(
245+
self.payload_converter_class_or_instance
246+
)
245247
else:
246-
self._payload_converter = self.payload_converter_class_or_instance()
248+
self._payload_converter = _TemporalTransferTypePayloadConverter.wrap(
249+
self.payload_converter_class_or_instance()
250+
)
247251
return self._payload_converter
248252

249253
@property
@@ -458,9 +462,7 @@ def payload_converter() -> temporalio.converter.PayloadConverter:
458462
The returned converter has :py:class:`temporalio.converter.ActivitySerializationContext` set.
459463
This is often used for dynamic activities to convert payloads.
460464
"""
461-
return _TemporalTransferTypePayloadConverter.unwrap(
462-
_Context.current().payload_converter
463-
)
465+
return _Context.current().payload_converter
464466

465467

466468
def metric_meter() -> temporalio.common.MetricMeter:

‎temporalio/api/callback/v1/message_pb2.py‎

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎temporalio/api/callback/v1/message_pb2.pyi‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class CallbackInfo(google.protobuf.message.Message):
3434
LAST_ATTEMPT_FAILURE_FIELD_NUMBER: builtins.int
3535
NEXT_ATTEMPT_SCHEDULE_TIME_FIELD_NUMBER: builtins.int
3636
BLOCKED_REASON_FIELD_NUMBER: builtins.int
37+
REQUEST_ID_FIELD_NUMBER: builtins.int
3738
@property
3839
def callback(self) -> temporalio.api.common.v1.message_pb2.Callback:
3940
"""Information on how this callback should be invoked (e.g. its URL and type)."""
@@ -57,6 +58,10 @@ class CallbackInfo(google.protobuf.message.Message):
5758
"""The time when the next attempt is scheduled."""
5859
blocked_reason: builtins.str
5960
"""If the state is BLOCKED, blocked reason provides additional information."""
61+
request_id: builtins.str
62+
"""Server-generated request ID used as an idempotency token when invoking callbacks.
63+
It has no relation to caller-side request_id sent in operations like StartNexusOperationExecutionRequest.
64+
"""
6065
def __init__(
6166
self,
6267
*,
@@ -71,6 +76,7 @@ class CallbackInfo(google.protobuf.message.Message):
7176
next_attempt_schedule_time: google.protobuf.timestamp_pb2.Timestamp
7277
| None = ...,
7378
blocked_reason: builtins.str = ...,
79+
request_id: builtins.str = ...,
7480
) -> None: ...
7581
def HasField(
7682
self,
@@ -104,6 +110,8 @@ class CallbackInfo(google.protobuf.message.Message):
104110
b"next_attempt_schedule_time",
105111
"registration_time",
106112
b"registration_time",
113+
"request_id",
114+
b"request_id",
107115
"state",
108116
b"state",
109117
],

0 commit comments

Comments
 (0)