extract-sdk-python.sh rewrites a fresh clone of temporalio/sdk-python so that its main
contains only one plugin's files, already at their paths in this repository, with every commit's
author, date and message intact. The result is merged into this repository with an
unrelated-histories merge commit. git log --follow, git blame and git shortlog then work on
the imported files exactly as they did upstream.
Imported history means commits reachable from the upstream repository's default branch. Never use
this procedure, the history-import label or IMPORTS.md for work that exists only on an unmerged
or closed upstream PR, feature branch or fork; port that work as ordinary local commits instead.
git checkout -b import/python-openai-agents main
PLUGIN=openai_agents scripts/migrate/extract-sdk-python.sh # prints SRC_SHA, WORK and the merge commands
git remote add sdk-python-filtered "$WORK/src"
git fetch --no-tags sdk-python-filtered main
git merge --allow-unrelated-histories --no-ff -m "Import temporalio.contrib.openai_agents from temporalio/sdk-python@<SRC_SHA> (history preserved; git-filter-repo 2.47.0)" sdk-python-filtered/main
git remote remove sdk-python-filteredThen add the files the import does not bring, as separate commits on top of the merge (never amend the merge and never edit an imported file in the same PR):
python3 scripts/new_python_plugin.py openai_agents --existing --maturity generally-available \
--upstream temporalio/sdk-python:temporalio/contrib/openai_agents \
--description "Temporal integration for the OpenAI Agents SDK"Record the import in IMPORTS.md, open a PR labelled history-import, and merge it with
"Create a merge commit". Squash or rebase merging destroys the imported history.
- Clones with
--no-tags --single-branchso no upstream release tags are imported. - Runs
git-filter-repopinned to 2.47.0 (uvx), with:- four
--pathfilters covering every location the plugin's files ever had upstream (temporalio/contrib/openai_agents/,tests/contrib/openai_agents/,tests/contrib/test_openai.py,tests/contrib/research_agents/); --path-renamerules intopython/openai_agents/...; the package README is renamed to the plugin root before the directory rename, and all filters precede all renames because filter-repo evaluates later filters against already-renamed paths;--replace-messagerewriting#123totemporalio/sdk-python#123so issue and PR links keep pointing at the SDK repository;--preserve-commit-hashesso SHAs mentioned in messages keep referring to sdk-python;--prune-empty alwaysso upstream's originally-empty commits (the 2022 "Initial commit", a dependabot bump) do not survive as unrelated root commits;- a commit callback appending
Migrated-From: temporalio/sdk-python@<original sha>as a trailer, placed contiguously with existing trailers such asCo-authored-by:; --force, needed only because the optionalSRC_REFpin fails filter-repo's fresh-clone check; the clone is a throwaway directory.
- four
Use this procedure only while the plugin's plugin.toml names sdk-python as its upstream.
Removing that field makes this repository the source of truth; do not re-sync the plugin after
that point. While the field is present, pick up upstream changes as follows:
- Run the script unchanged, fetch, and
git merge sdk-python-filtered/mainon a new branch. Only commits newer than the previous import arrive because the rewrite is byte-identical. - Resolve conflicts only where adaptation commits or documented local-only divergences touched
imported files. For the
openai_agentsMCP v2 adapter files listed in AGENTS.md, "Transition rules", preserve both the new upstream changes and the local adapter. - Diff the vendored test scaffolding against upstream and port relevant changes by hand:
tests/conftest.py,tests/__init__.py,tests/helpers/__init__.py,tests/helpers/nexus.py. - If upstream added provider-network tests, add deterministic local coverage without credentials.
- Append a row to
IMPORTS.md; open ahistory-importPR; merge with a merge commit.
The rewrite stays byte-identical only if none of these change: the --path/--path-rename
arguments, replace-message.txt, the commit callback, --prune-empty/--preserve-commit-hashes,
the pinned git-filter-repo version, and upstream default-branch history itself. SRC_REF must be
both reachable from the upstream default branch and a descendant of the previous import. Stop if
either condition is false; a PR or feature-branch ref is not a history-import input and its changes
must be ported as ordinary local commits. If a rewrite rule changes or upstream rewrites its default
branch, the plugin needs a one-time full re-import PR (delete python/<plugin>, import again,
re-apply adaptation and documented local-only commits) and a note in IMPORTS.md.
Find every historical path first:
cd /path/to/sdk-python
git log --all --diff-filter=R --name-status --format='--%h %ad' -- temporalio/contrib/<name> tests/contrib/<name>
git log --all --name-only --format= -- temporalio/contrib/<name> tests/contrib/<name> | sort -u
git log --all --oneline --follow -- temporalio/contrib/<name>/__init__.pyAdd a case entry to extract-sdk-python.sh with every path found (filters first, renames
second, README rename before directory rename). Missing a historical path cannot be fixed later
without rewriting every imported SHA.
Five initial imports are pinned to sdk-python main at
6adc0d84290a79952dee3ef02c36f6ed9334874a. Google ADK is pinned to
d61b3f3ad3dcfd9187fa6012b5d77de2d5b4cb9f, the parent of #1854. That merged PR
requires the named workflow.new_random(name) API, absent from the latest published SDK
(1.34.0); port that fix after an SDK release contains it. Both SHAs are reachable from
upstream main. The history-import merges preserve source and plugin-specific tests
unchanged. A separate local cutover commit moves all six to temporalio.<folder_name>,
including temporalio.google_adk and temporalio.strands_agents, updates imports and
examples, and flattens the test trees. This API cutover was explicitly requested with
the initial import. Active upstream metadata is removed because this repository now
owns the code. Path archaeology found no earlier locations outside their current package and test
trees. Expected filtered history counts are:
| Folder | Upstream module | Commits | Identities |
|---|---|---|---|
| deepagents | deepagents | 6 | 4 |
| google_adk | google_adk_agents | 22 | 11 |
| google_genai | google_genai | 8 | 4 |
| langgraph | langgraph | 7 | 2 |
| langsmith | langsmith | 12 | 5 |
| strands_agents | strands | 6 | 2 |
The initial live GitHub audit inspected all 64 open issues and the changed files of all 16 open
PRs. None then touched these plugin source or test trees. The related open PRs
sdk-python#1805,
sdk-python#1811, and
sdk-python#1891 concern SDK-owned Workflow
Streams or OpenTelemetry and are not imported. Closed DeepAgents alternatives #1902 and #1904
are unmerged; the merged fix #1901 is included instead. Recent merged plugin fixes, including
#1865, #1873, #1887, #1899 and #1908, are reachable from the pinned SHAs. #1854 is merged
on main but deferred for the SDK compatibility reason above.
Each plugin has its own canonical provenance support and local server fixtures. Shared upstream
helpers are copied only where used: new_worker for Google GenAI and LangSmith, Nexus/trace
helpers for LangSmith, and the span formatter and provider-reset fixtures for Google ADK.
DeepAgents sets the low history-count threshold required by its server-suggested continue-as-new
test. Its README tests point at the standalone distribution README. Provider tests use
local models, mock transports or in-process MCP servers. Final releases are enabled
after the API cutover; the committed development version remains 0.0.0.
Google GenAI and Strands README links resolve SDK-owned dependencies to the pinned SDK tree. The conventions check validates the README actually published.
The shared make targets use the committed lockfile for regular checks and re-lock to
the newest allowed dependencies on nightly runs. Lint and tests use uv run --locked
to preserve the selected versions. Dependency floors are LangGraph 1.2.0
(the imported adapter uses Runtime.execution_info), Google ADK OpenTelemetry
1.40.0 (its MCP semantic-convention imports), and pytest-asyncio 0.21.2
(the compatible pytest 9 fixture implementation). Google ADK test setup preloads OpenAI
types before workflow tasks to avoid cold-import deadlock detection on Python 3.10.
At the final audit, 63 issues and 16 PRs were open. A new draft,
sdk-python#1923, removes the bundled
implementations and forwards to the planned final APIs. It depends on publishing these
packages after cutover and is not an import input. The newer SDK main commit
3f29fd7935f9a03fbe86f24624dfe6458872098e does not change the five plugins pinned to
6adc0d84290a79952dee3ef02c36f6ed9334874a.