Add flyte.is_control_plane_available() and Run.first_failure() for agent edit-and-relaunch loops - #1522
Merged
Merged
Conversation
…ted forking) Three additions that make the "agent task edits a workflow, reloads it, and forks the failed run" pattern native, instead of relying on SDK internals: - flyte.refresh_code_bundle_cache(): forget in-process memoized code bundles so the next run/deploy/serve (or fork) re-bundles the working tree as it is on disk now. Also make skip_cache=True (what disable_run_cache threads through) bypass the in-process memo, not just the persistent SQLite cache. build_code_bundle*.cache_clear() is preserved for existing callers. - flyte.control_plane_available(): True when the process can submit work to a control plane. Inside a task it is decided by the orchestration mode (remote/hybrid vs local) rather than isinstance checks on the internal controller; outside a task, by whether a client is configured. - Run.first_failure() + ActionDetails.error_message: the observation half of a repair loop - which step of a run failed, and why - preferring the failed sub-action over the root action whose error just repeats it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NwQixBcyR5va6BC75jaQx3
cosmicBboy
marked this pull request as ready for review
September 2, 2026 16:55
Main removed the alru_cache on build_code_bundle entirely (rebuild after source changes), which solves the stale-bundle problem at the root. Drop this branch's refresh_code_bundle_cache() and skip_cache memo-bypass — they managed a cache that no longer exists. control_plane_available() and Run.first_failure() / ActionDetails.error_message remain. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NwQixBcyR5va6BC75jaQx3
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NwQixBcyR5va6BC75jaQx3
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NwQixBcyR5va6BC75jaQx3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The agent-mediated forking example (unionai/unionai-examples#308) — an agent task that launches a workflow, observes the failure, patches the workflow's source on disk, reloads it, and
fork()s the failed run with the fixed code — had to reach into SDK internals:isinstance(get_controller(), RemoteController)to decide whether launching/forking real runs is possible, or whether to fall back to running the workflow inline.Action.listall(...FAILED...)iteration to find which step failed and its error message.flyte._code_bundle.bundle.build_code_bundle.cache_clear()to make the next fork ship the edited working tree — no longer needed: fix(code-bundle): rebuild after source changes #1508 removed the code-bundle memoization entirely, so every launch re-bundles from disk. This PR originally shipped aflyte.refresh_code_bundle_cache()for that; it was dropped when merging main, since the cache it managed no longer exists.What
flyte.is_control_plane_available()— True when the process can submit work to a control plane (launch real runs whose actions can be awaited and replayed/forked). Inside a task, the orchestration mode decides (remote/hybrid→ True,local→ False, even when a client is configured —flyte run --localconfigures one too); outside a task, a configured client decides. This replaces the isinstance-on-internal-controller probe with theTaskContext.modethe runtime already maintains.Run.first_failure()andActionDetails.error_message— the observation half of a repair loop: which step of a run failed, and why.first_failure()returns theActionDetailsof the first failed action in creation order, preferring a failed sub-action over the failed root (whose error usually just repeats the sub-action's);error_messageis the failed action's message or"".With these, the example's loop reduces to:
Testing
is_control_plane_available()across uninitialized/client/local/remote/hybrid contexts;Run.first_failure()sub-action preference, root fallback, and no-failure;error_message.code_bundle,remote,deploy, andcli/test_run.pysuites pass (the only failures are pre-existing onmain: the twoloaded_modulesdiscovery tests).ruff,mypy, andtyclean via pre-commit hooks.🤖 Generated with Claude Code
https://claude.ai/code/session_01NwQixBcyR5va6BC75jaQx3