From fb13029efe16d3b5fa45ae7fe77fb927b8ea3ca5 Mon Sep 17 00:00:00 2001 From: nicholascole Date: Mon, 3 Aug 2026 16:18:39 -0700 Subject: [PATCH 1/6] Remove Agent E2E --- .../workflows/release-agent-e2e-bundle.yml | 73 ------------------- 1 file changed, 73 deletions(-) delete mode 100644 .github/workflows/release-agent-e2e-bundle.yml diff --git a/.github/workflows/release-agent-e2e-bundle.yml b/.github/workflows/release-agent-e2e-bundle.yml deleted file mode 100644 index 6d044af4..00000000 --- a/.github/workflows/release-agent-e2e-bundle.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: Release Agent E2E Bundle - -# Packages the agent e2e suite (e2e/) into a version-stamped, self-contained -# tarball and attaches it to the GitHub release, so downstream repos (e.g. -# orkes-io/orkes-conductor) can pin the e2e suite to the exact python-sdk -# release they run against. The bundle resolves conductor-python[agents] at -# the same version from PyPI. -# -# Runs on the same release event as release.yml (PyPI publish). Packaging is -# purely static (no install), so it does not race the PyPI publish — the -# bundle just references the package version. -# -# Mirrors conductor-oss/java-sdk and conductor-oss/javascript-sdk. Note: -# python-sdk release tags carry no `v` prefix (e.g. 2.0.0-rc2), and pip's -# PEP 440 normalization makes ==2.0.0-rc2 resolve the PyPI artifact 2.0.0rc2. - -on: - release: - types: [published] - workflow_dispatch: - inputs: - tag: - description: "Release tag to package for and attach to (e.g. 2.0.0-rc2) — must already exist" - required: true - type: string - -permissions: - contents: write - -jobs: - package-e2e-bundle: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Determine version - id: version - run: | - if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then - TAG="${{ inputs.tag }}" - else - TAG="${{ github.event.release.tag_name }}" - fi - VERSION="${TAG#v}" - echo "tag=${TAG}" >> "$GITHUB_OUTPUT" - echo "version=${VERSION}" >> "$GITHUB_OUTPUT" - echo "Packaging agent e2e bundle for tag ${TAG} (version ${VERSION})" - - - name: Package bundle - run: | - ./scripts/package-e2e-bundle.sh --version "${{ steps.version.outputs.version }}" - - - name: Validate bundle - run: | - ./scripts/test-package-e2e-bundle.sh - - - name: Generate SHA256 checksums - working-directory: scripts/e2e-bundle-dist - run: | - for f in *.tar.gz; do - sha256sum "$f" | awk '{print $1}' > "${f}.sha256" - echo " $(cat "${f}.sha256") ${f}" - done - - - name: Upload bundle to GitHub release - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release upload "${{ steps.version.outputs.tag }}" \ - scripts/e2e-bundle-dist/*.tar.gz \ - scripts/e2e-bundle-dist/*.sha256 \ - --repo "${{ github.repository }}" \ - --clobber From c5270bd5fe388c9f4e77ff2589c196b2ce02f651 Mon Sep 17 00:00:00 2001 From: nicholascole Date: Mon, 3 Aug 2026 16:39:16 -0700 Subject: [PATCH 2/6] Fix test --- tests/unit/ai/test_worker_entries.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tests/unit/ai/test_worker_entries.py b/tests/unit/ai/test_worker_entries.py index de5f0a36..45124043 100644 --- a/tests/unit/ai/test_worker_entries.py +++ b/tests/unit/ai/test_worker_entries.py @@ -161,13 +161,11 @@ def test_cross_process_spawn_roundtrip_with_hop(self): assert p.exitcode == 0 -# ── Deep-extract (real openai-agents @function_tool → FunctionTool) ──────── +# ── FunctionTool resolution (real openai-agents @function_tool) ──────────── class TestFunctionRefDeepExtract: - """openai-agents' real ``@function_tool`` → ``FunctionTool`` with no - ``.func``/``.coroutine``/``__wrapped__``; original fn only reachable via - nested attrs + closure.""" + """OpenAI Agents SDK 0.19+ exposes FunctionTool functions via wrappers.""" def test_sync_function_tool_deep_extract(self): pytest.importorskip("agents") @@ -176,7 +174,7 @@ def test_sync_function_tool_deep_extract(self): raw = _find_embedded_function(oa.oa_get_weather) assert raw is not None ref = FunctionRef.of(raw) - assert ref == FunctionRef(oa.__name__, "oa_get_weather", 0, "", deep_extract=True) + assert ref == FunctionRef(oa.__name__, "oa_get_weather", unwrap_depth=1) assert ref.resolve() is raw def test_async_function_tool_deep_extract(self): @@ -186,8 +184,8 @@ def test_async_function_tool_deep_extract(self): raw = _find_embedded_function(oa.oa_get_weather_async) assert raw is not None ref = FunctionRef.of(raw) - assert ref.deep_extract is True - assert ref.attr_hop == "" + assert ref.unwrap_depth == 1 + assert ref.deep_extract is False assert ref.resolve() is raw def test_ref_pickles(self): From a5cf4d9ae49e8fd3418719c73d63addedb88b5c2 Mon Sep 17 00:00:00 2001 From: nicholascole Date: Mon, 3 Aug 2026 17:10:40 -0700 Subject: [PATCH 3/6] Fix stateful swarm E2E worker domain --- e2e/test_suite14_stateful_domain.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/e2e/test_suite14_stateful_domain.py b/e2e/test_suite14_stateful_domain.py index 76e1aad3..9cbc8225 100644 --- a/e2e/test_suite14_stateful_domain.py +++ b/e2e/test_suite14_stateful_domain.py @@ -313,6 +313,7 @@ def test_stateful_swarm_handoff_completes(self, fresh_runtime, model): agent_a = Agent( name="swarm_agent_a", model=model, + stateful=True, max_turns=3, instructions=( "You are agent A. Call swarm_tool with task='from_a'. " @@ -323,6 +324,7 @@ def test_stateful_swarm_handoff_completes(self, fresh_runtime, model): agent_b = Agent( name="swarm_agent_b", model=model, + stateful=True, max_turns=3, instructions=( "You are agent B. Call swarm_tool with task='from_b'. " From 9bca4e0481cccf4de890324c76c3a48339694bbf Mon Sep 17 00:00:00 2001 From: nicholascole Date: Mon, 3 Aug 2026 17:25:36 -0700 Subject: [PATCH 4/6] Fix stateful swarm E2E tool domain --- e2e/test_suite14_stateful_domain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/test_suite14_stateful_domain.py b/e2e/test_suite14_stateful_domain.py index 9cbc8225..a5979b2c 100644 --- a/e2e/test_suite14_stateful_domain.py +++ b/e2e/test_suite14_stateful_domain.py @@ -90,7 +90,7 @@ def marker_tool_b(input_text: str) -> str: return "MARKER_B_DONE" -@tool +@tool(stateful=True) def swarm_tool(task: str) -> str: """Perform a task and return a marker.""" return f"SWARM_RESULT:{task}" From 9acb96ff6f4fed34f32914c7e5c484e689283ca5 Mon Sep 17 00:00:00 2001 From: nicholascole Date: Mon, 3 Aug 2026 17:37:53 -0700 Subject: [PATCH 5/6] Remove obsolete swarm handoff assertion --- e2e/test_suite14_stateful_domain.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/e2e/test_suite14_stateful_domain.py b/e2e/test_suite14_stateful_domain.py index a5979b2c..0afabf6d 100644 --- a/e2e/test_suite14_stateful_domain.py +++ b/e2e/test_suite14_stateful_domain.py @@ -356,21 +356,8 @@ def test_stateful_swarm_handoff_completes(self, fresh_runtime, model): ttd = _get_task_to_domain(result.execution_id) assert ttd, f"taskToDomain empty. {diag}" - # Verify handoff-related tasks executed all_tasks = _get_all_tasks(result.execution_id) - # handoff_check should exist and be COMPLETED - handoff_tasks = _find_tasks_by_type(all_tasks, "handoff_check") - assert handoff_tasks, ( - f"No handoff_check task found. " - f"Task names: {[t.get('taskDefName') for t in all_tasks]}" - ) - completed_handoffs = [t for t in handoff_tasks if t["status"] == "COMPLETED"] - assert completed_handoffs, ( - f"No COMPLETED handoff_check. Statuses: " - f"{[(t['status'], t.get('pollCount')) for t in handoff_tasks]}" - ) - # termination should exist and be COMPLETED term_tasks = _find_tasks_by_type(all_tasks, "termination") if term_tasks: From 262d4fef0c375e2c65ea1b0e66deceb29c813234 Mon Sep 17 00:00:00 2001 From: nicholascole Date: Mon, 3 Aug 2026 17:40:11 -0700 Subject: [PATCH 6/6] Trigger CI --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9869f550..cb20402f 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ The Python SDK for [Conductor](https://www.conductor-oss.org/) lets you build durable Conductor agents, workflows, and workers. Conductor coordinates retries, state, and observability while your Python code runs wherever you deploy it. + **Get involved:** [⭐ Conductor OSS](https://github.com/conductor-oss/conductor) · [Choose a Conductor OSS contribution](https://github.com/conductor-oss/conductor/contribute) · [Contribution guide](https://github.com/conductor-oss/conductor/blob/main/CONTRIBUTING.md) **Using an AI coding agent?** Load [Conductor Skills](https://github.com/conductor-oss/conductor-skills) so it can create, run, and operate Conductor workflows and Conductor agents: