Prepare OpenAI Agents package cutover - #23
Conversation
Migrated-From: temporalio/sdk-python@a43349a
A failed operation evicted the pooled connection by closing it outright, which unwound the owning task's `async with backend` while concurrent operations were still using the same connection. Since `CancelledError` is a `BaseException`, activity cancellation and worker shutdown hit this path too, so cancelling one MCP activity aborted every other in-flight activity sharing the connection. The failing operation also never released its slot. Failures now retire the record: it is dropped from the cache so no later operation reuses it, and the last operation to release it closes it. Also drop a dead uniqueness check in `_MCPActivities` (`set()` over a dict compares key counts, so it never fired) and correct the deprecation directives to 1.32, the unreleased version. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Migrated-From: temporalio/sdk-python@4fb9cc8
`temporalio.contrib.mcp` is an implementation detail shared by the contrib integrations, not a public API, but it was advertised as one: the CHANGELOG called it stable, `workflow.py`/`MCPClient` were the only non-underscore names in an otherwise private package, and pydoctor rendered the package into the published docs. Rename to `_workflow._MCPClient`, mark the package PRIVATE for pydoctor, and describe the release in terms of the OpenAI Agents surface users actually call. `meta` was threaded through all seven operations, but only `call_tool` has a caller that supplies it (the OpenAI Agents base `MCPServer` resolves it per tool call). The other six accepted it and dropped it on the floor, so a caller passing metadata would silently get none. Drop the parameter there; `_CallToolRequest` now owns the field. Replace the `-k 'legacy_mcp_apis_are_deprecated or mcp_server'` CI selection with `@pytest.mark.mcp_v1`. Substring matching silently under-selects on a rename while still passing, and `mcp_server` also matches `mcp_servers` and any future `test_hosted_mcp_server_*`. The marker selects the same 13 tests today and stays correct as tests are renamed or added. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Migrated-From: temporalio/sdk-python@8b74c9e
An idle-eviction task armed before an operation acquired a pooled record could close the connection while that operation was still in flight: once a peer failure unmapped the record, `_unmap` skipped the idle check and reported the record closable. Apply the idle check regardless of whether the record is still mapped. Restore the legacy `inspect.signature` handling for MCP server factories, now shared by both backends. A factory declaring a positional parameter receives the `factory_argument` (`None` when a workflow supplied none), and a parameterless factory is called bare. Signatures that could satisfy neither form raise when the plugin is built, and passing a `factory_argument` to a parameterless factory raises a non-retryable error instead of a bare `TypeError` that retries forever. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Migrated-From: temporalio/sdk-python@0168e19
Migrated-From: temporalio/sdk-python@51d4aff
Fix the proto Docker build, which pinned googleapis-common-protos into the dev group while the conflicting requirement now lives in dev-common, leaving the following uv sync unsatisfiable. Bound the MCP pool close during worker shutdown. The run context swallows the shutdown cancellation, so an MCP server that never finishes closing its transport would hang the worker with no cancellation left to break out with. Stop treating activity cancellation as a transport failure in the connection pool. The MCP client cancels the in-flight request on the wire, so the shared connection stays healthy and should not be retired out from under every other workflow using it. Reject a callable tool_filter on a worker-side MCPServer. It needs the run context and agent, which exist only in the workflow, so the Agents SDK raises for it and the list-tools Activity would retry forever. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Migrated-From: temporalio/sdk-python@7100059
…cb4e8e (history preserved; git-filter-repo 2.47.0)
# Conflicts: # AGENTS.md
…andbox, use the public MCP client import exclude-newer = "2 weeks" limits candidates to distributions uploaded before the cutoff, so a freshly published temporalio-mcp would have no eligible release for two weeks and uv lock would keep failing after the release; exempt it like temporalio. MCPPlugin passes mcp_types through the sandbox and the adapter imports it directly, so OpenAIAgentsPlugin does the same. TemporalMCPClient is a public export of temporalio.contrib.mcp; import it from there instead of the private module.
…mported-files rule The adapter was developed in sdk-python PR #1793, closed unmerged on 2026-09-03, and migrated here with Migrated-From trailers. Its commits touch ten imported files and can never arrive from sdk-python main, so AGENTS.md, CONTRIBUTING.md, scripts/migrate/README.md and IMPORTS.md now say so, and future re-syncs merge on top of them. The cooldown docs cover the second exclude-newer-package exemption.
…ents-mcp-v2 # Conflicts: # CONTRIBUTING.md # python/mcp/README.md # python/mcp/plugin.toml # python/mcp/src/temporalio/contrib/mcp/_activities.py # python/mcp/src/temporalio/contrib/mcp/_backend.py # python/mcp/src/temporalio/contrib/mcp/_client.py # python/mcp/src/temporalio/contrib/mcp/_pool.py # python/mcp/src/temporalio/contrib/mcp/_workflow.py # python/mcp/tests/test_activities.py # python/mcp/tests/test_pool.py # python/mcp/tests/test_workflow.py # python/mcp/uv.lock # python/openai_agents/pyproject.toml
…ents-mcp-v2 # Conflicts: # python/openai_agents/pyproject.toml # scripts/ci/check_conventions.py
…' into cutover/python-openai-agents
…-agents # Conflicts: # AGENTS.md # CONTRIBUTING.md # python/openai_agents/README.md # python/openai_agents/plugin.toml # python/openai_agents/pyproject.toml # python/openai_agents/src/temporalio/openai_agents/_mcp_backend.py # python/openai_agents/src/temporalio/openai_agents/_openai_runner.py # python/openai_agents/src/temporalio/openai_agents/_temporal_mcp_server.py # python/openai_agents/src/temporalio/openai_agents/_temporal_openai_agents.py # python/openai_agents/src/temporalio/openai_agents/workflow.py # python/openai_agents/tests/test_mcp_v2.py # scripts/migrate/README.md
DABH
left a comment
There was a problem hiding this comment.
Ultrareview verdict: requesting changes because this head is not merge/release-ready in the coordinated state declared by #24. The namespace move itself is mechanically sound: public exports are preserved, existing history replay passes, artifact ownership is clean, and the full local suite is green.
Blocking coordination finding:
- #24's release plan says to publish
temporalio-mcp0.2 first and then update this branch. This head still pins both runtime/dev use totemporalio-mcp>=0.1.0,<0.2, importstemporalio.contrib.mcpin production code, documents/assertstemporalio.contrib.mcp.*Activity types, and locks 0.1.0. Its own PR description instead says to publish this PR first. Thus the two release plans contradict each other, and current CI validates only the legacy combination. After #24's compatibility decision is resolved and 0.2 is published, rebase this branch; update both constraints, imports, README, tests, and lockfile; then rerun the OpenAI suite against 0.2. The branches currently conflict inAGENTS.md, rootREADME.md,check_conventions.py, and its tests; preserve #24's stricter rule that release-ready plugins usetemporalio.<name>rather than this branch's permanent either-root allowlist. Update this PR's release-order text as well.
Additional release concerns are inline: the public Documentation metadata currently leads to instructions for the SDK-bundled package, and the temporalio>=1.33 coexistence claim needs to acknowledge split-path installs. I also noted a concrete stale migration command.
One further compatibility cleanup is advisable before making this an independently released GA package: it imports TemporalIdGenerator and ReplaySafeTracerProvider through private temporalio.contrib.opentelemetry._* modules while declaring compatibility with every Temporal 1.x release. ReplaySafeTracerProvider already has a public export; the ID-generator dependency can use a local protocol or should be publicly exported by the SDK. These private imports were safe when both components shipped together, but become an unversioned cross-package contract after this cutover.
Validation completed locally: make sync with locked Temporal 1.33.0, make lint, make test (229 passed, 2 skipped), make build, wheel/sdist ownership and metadata checks, tooling tests (93 passed), repository conventions, existing replay fixtures, and a wheel-file audit confirming no SDK overlap. GitHub CI is green. There are no substantive prior review comments; Copilot only reported quota exhaustion.
Summary
ai-integrationsauthoritative by removing the SDK upstream metadatatemporalio.contrib.openai_agentstotemporalio.openai_agentstemporalio>=1.33.0, avoiding all file overlap with the SDK-bundled integrationRelease order
temporalio-openai-agents1.0.0 through the normal release workflow.openai-agentsextra depends ontemporalio-openai-agents>=1.0.0, and its oldtemporalio.contrib.openai_agentspublic imports forward to the new package.temporalio1.34.0.Because the standalone package now installs under
temporalio.openai_agents, it can safely coexist with Temporal 1.33, whose bundled implementation remains undertemporalio.contrib.openai_agents. This removes the circular release dependency without publishing a broken package or bypassing either release workflow.User migration
New code should install the standalone package and use the new canonical import:
After Temporal 1.34.0, existing users of
temporalio[openai-agents]can upgrade normally: the extra will install the standalone distribution, and SDK compatibility modules will preserve the old publictemporalio.contrib.openai_agentsimports. Users may migrate imports totemporalio.openai_agentsindependently.Documentation and downstream repository migrations remain deferred.
Validation
make sync && make format && make lint && make test && make build