task_runner
Task runner package — one-task lifecycle state machine, dispatch, and I/O protocols.
Re-exports all public names so that from agentrelay.task_runner import X
continues to work.
Subpackages
core: Protocols, state machine, dispatch, I/O boundary composition. implementations: Concrete protocol implementations.
StepDispatch
dataclass
Bases: Generic[T]
Per-step dispatch table for one lifecycle step.
Selects the right protocol implementation based on the task's
:class:~agentrelay.task.AgentFramework and
:class:~agentrelay.environments.AgentEnvironment type. Each entry
maps a (framework, env_type) key to a factory callable that
receives the :class:TaskRuntime and returns a protocol implementation.
The default fallback handles steps that don't vary by
framework/environment.
Callable — use as self._preparer(runtime) directly via
:meth:__call__.
Dispatch resolution order
- Exact match in
entriesfor(framework, type(environment)) defaultfallbackKeyErrorif neither matches
Extension guide
To add support for a new AgentFramework or AgentEnvironment,
add an entry to the entries dict for each step that has a
distinct implementation for that combo. Steps that don't vary
(e.g. preparer, merger) can continue using default.
Attributes:
| Name | Type | Description |
|---|---|---|
entries |
dict[DispatchKey, Callable[[TaskRuntime], T]]
|
Mapping of |
default |
Callable[[TaskRuntime], T] | None
|
Fallback factory used when no exact key match exists. |
Source code in src/agentrelay/task_runner/core/dispatch.py
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | |
__call__(runtime)
Resolve and return the protocol implementation for this runtime.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime
|
TaskRuntime
|
Task runtime used to extract the dispatch key from
|
required |
Returns:
| Type | Description |
|---|---|
T
|
The resolved protocol implementation instance. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If no entry matches and no default is provided. |
Source code in src/agentrelay/task_runner/core/dispatch.py
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | |
TaskCompletionChecker
Bases: Protocol
Wait for a terminal task completion signal.
Source code in src/agentrelay/task_runner/core/io.py
92 93 94 95 96 97 98 99 100 101 102 103 104 105 | |
wait_for_completion(runtime)
async
Wait for terminal task signal from the execution boundary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime
|
TaskRuntime
|
Runtime envelope being observed. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
TaskCompletionSignal |
TaskCompletionSignal
|
Terminal signal payload with outcome data. |
Source code in src/agentrelay/task_runner/core/io.py
96 97 98 99 100 101 102 103 104 105 | |
TaskCompletionSignal
dataclass
Signal payload returned by the completion checker.
Attributes:
| Name | Type | Description |
|---|---|---|
outcome |
Literal['done', 'failed']
|
Terminal completion signal from external execution.
|
pr_url |
Optional[str]
|
Pull request URL for a |
error |
Optional[str]
|
Failure detail for a |
concerns |
tuple[str, ...]
|
Semantic concerns captured during execution. |
Source code in src/agentrelay/task_runner/core/io.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | |
TaskKickoff
Bases: Protocol
Send kickoff instructions to a launched agent.
Source code in src/agentrelay/task_runner/core/io.py
78 79 80 81 82 83 84 85 86 87 88 89 | |
kickoff(runtime, agent)
Send kickoff instructions to the launched task agent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime
|
TaskRuntime
|
Runtime envelope for the task being kicked off. |
required |
agent
|
Agent
|
Live agent handle to send instructions to. |
required |
Source code in src/agentrelay/task_runner/core/io.py
82 83 84 85 86 87 88 89 | |
TaskLauncher
Bases: Protocol
Launch and return the primary agent for a task.
Source code in src/agentrelay/task_runner/core/io.py
62 63 64 65 66 67 68 69 70 71 72 73 74 75 | |
launch(runtime)
Launch and return the primary agent for this task runtime.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime
|
TaskRuntime
|
Runtime envelope to launch against. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Agent |
Agent
|
Live agent handle bound to this task. |
Source code in src/agentrelay/task_runner/core/io.py
66 67 68 69 70 71 72 73 74 75 | |
TaskMerger
Bases: Protocol
Merge the completed task PR into the integration target.
Source code in src/agentrelay/task_runner/core/io.py
108 109 110 111 112 113 114 115 116 117 118 119 | |
merge_pr(runtime, pr_url)
Merge the completed task PR.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime
|
TaskRuntime
|
Runtime envelope being merged. |
required |
pr_url
|
str
|
Pull request URL to merge. |
required |
Source code in src/agentrelay/task_runner/core/io.py
112 113 114 115 116 117 118 119 | |
TaskPreparer
Bases: Protocol
Prepare runtime execution prerequisites before agent launch.
Source code in src/agentrelay/task_runner/core/io.py
49 50 51 52 53 54 55 56 57 58 59 | |
prepare(runtime)
Prepare runtime execution prerequisites.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime
|
TaskRuntime
|
Runtime envelope to prepare (e.g. branch, signal files). |
required |
Source code in src/agentrelay/task_runner/core/io.py
53 54 55 56 57 58 59 | |
TaskTeardown
Bases: Protocol
Release runtime resources after terminal completion.
Source code in src/agentrelay/task_runner/core/io.py
122 123 124 125 126 127 128 129 130 131 132 | |
teardown(runtime)
Release runtime resources after terminal completion.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime
|
TaskRuntime
|
Runtime envelope whose resources should be cleaned up. |
required |
Source code in src/agentrelay/task_runner/core/io.py
126 127 128 129 130 131 132 | |
StandardTaskRunner
dataclass
Standard task lifecycle: prepare → launch → kickoff → wait → merge → teardown.
Uses :class:StepDispatch tables for per-step implementation selection
based on the task's AgentFramework and AgentEnvironment.
Step sensitivity reference:
+-----------------------+----------------+----------------------+ | Step | Varies by env? | Varies by framework? | +=======================+================+======================+ | preparer | No | No | +-----------------------+----------------+----------------------+ | launcher | Yes | Yes | +-----------------------+----------------+----------------------+ | kickoff | Yes | Yes | +-----------------------+----------------+----------------------+ | completion_checker | Maybe | No | +-----------------------+----------------+----------------------+ | merger | No | No | +-----------------------+----------------+----------------------+ | teardown | Partially | No | +-----------------------+----------------+----------------------+
Extension guide — adding a new framework or environment:
Add entries to the StepDispatch tables for steps that have distinct
implementations. Steps that don't vary can keep using default.
Extension guide — different lifecycle (e.g., adding a review step):
Create a new class satisfying the :class:TaskRunner protocol. It can
reuse StepDispatch tables and per-step protocol implementations.
Attributes:
| Name | Type | Description |
|---|---|---|
_preparer |
StepDispatch[TaskPreparer]
|
Dispatch table for :class: |
_launcher |
StepDispatch[TaskLauncher]
|
Dispatch table for :class: |
_kickoff |
StepDispatch[TaskKickoff]
|
Dispatch table for :class: |
_completion_checker |
StepDispatch[TaskCompletionChecker]
|
Dispatch table for :class: |
_merger |
StepDispatch[TaskMerger]
|
Dispatch table for :class: |
_teardown |
StepDispatch[TaskTeardown]
|
Dispatch table for :class: |
Source code in src/agentrelay/task_runner/core/runner.py
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | |
run(runtime, *, teardown_mode=TearDownMode.ALWAYS)
async
Execute one task lifecycle run and return a result snapshot.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime
|
TaskRuntime
|
Mutable task runtime to execute. Must enter in |
required |
teardown_mode
|
TearDownMode
|
Resource teardown policy after run completion. |
ALWAYS
|
Returns:
| Name | Type | Description |
|---|---|---|
TaskRunResult |
TaskRunResult
|
Convenience snapshot of terminal runtime fields. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/agentrelay/task_runner/core/runner.py
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | |
TaskRunner
Bases: Protocol
Protocol for the task runner boundary used by Orchestrator.
Different lifecycle variants (standard, reviewing, dry-run) are different classes satisfying this protocol. The orchestrator does not know or care about internal step structure.
Source code in src/agentrelay/task_runner/core/runner.py
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | |
run(runtime, *, teardown_mode=TearDownMode.ALWAYS)
async
Execute one task attempt and return terminal task fields.
Source code in src/agentrelay/task_runner/core/runner.py
117 118 119 120 121 122 123 124 | |
TaskRunResult
dataclass
Convenience return value mirroring terminal fields on :class:TaskRuntime.
TaskRuntime remains the single source of truth; this result is a snapshot
for ergonomic call-site consumption.
Attributes:
| Name | Type | Description |
|---|---|---|
task_id |
str
|
Task identifier. |
status |
TaskStatus
|
Terminal task status after |
pr_url |
Optional[str]
|
Task PR URL, if one was recorded. |
error |
Optional[str]
|
Task failure message, if one was recorded. |
failure_class |
Optional[IntegrationFailureClass]
|
Integration error classification for I/O boundary
failures. |
Source code in src/agentrelay/task_runner/core/runner.py
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | |
from_runtime(runtime, failure_class=None)
classmethod
Build a result snapshot from the current runtime state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime
|
TaskRuntime
|
Runtime envelope to snapshot. |
required |
failure_class
|
Optional[IntegrationFailureClass]
|
Optional integration error classification. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
TaskRunResult |
TaskRunResult
|
Snapshot of task ID, status, PR URL, and error. |
Source code in src/agentrelay/task_runner/core/runner.py
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | |
TearDownMode
Bases: str, Enum
Policy controlling whether runtime resources are torn down after run.
Attributes:
| Name | Type | Description |
|---|---|---|
ALWAYS |
Always call teardown at end of run. |
|
NEVER |
Never call teardown. |
|
ON_SUCCESS |
Call teardown only when task reaches |
Source code in src/agentrelay/task_runner/core/runner.py
48 49 50 51 52 53 54 55 56 57 58 59 | |
GhTaskMerger
dataclass
Merge a task PR via GitHub CLI and update the local integration branch.
After merging, fetches the updated integration branch and writes a
.merged signal file to the task's signal directory.
Reads integration_branch from runtime.state (set by the
orchestrator before dispatch).
Source code in src/agentrelay/task_runner/implementations/task_merger.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | |
merge_pr(runtime, pr_url)
Merge the completed task PR.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime
|
TaskRuntime
|
Runtime envelope being merged. |
required |
pr_url
|
str
|
Pull request URL to merge. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/agentrelay/task_runner/implementations/task_merger.py
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | |
SignalCompletionChecker
dataclass
Poll signal files and parse the result into a completion signal.
Watches the task's signal directory for .done or .failed files,
then parses the signal file content and any concerns.log entries
into a :class:TaskCompletionSignal.
Source code in src/agentrelay/task_runner/implementations/task_completion_checker.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | |
wait_for_completion(runtime)
async
Wait for terminal task signal from the execution boundary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime
|
TaskRuntime
|
Runtime envelope being observed. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
TaskCompletionSignal |
TaskCompletionSignal
|
Terminal signal payload with outcome data. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/agentrelay/task_runner/implementations/task_completion_checker.py
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | |
TmuxTaskKickoff
dataclass
Send kickoff instructions to a launched agent.
Delegates to :meth:Agent.send_kickoff with the path to the
instructions.md file in the task's signal directory.
Source code in src/agentrelay/task_runner/implementations/task_kickoff.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | |
kickoff(runtime, agent)
Send kickoff instructions to the launched task agent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime
|
TaskRuntime
|
Runtime envelope for the task being kicked off. |
required |
agent
|
Agent
|
Live agent handle to send instructions to. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/agentrelay/task_runner/implementations/task_kickoff.py
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | |
TmuxTaskLauncher
dataclass
Launch a Claude Code agent in a tmux pane.
Delegates to :meth:TmuxAgent.from_config to create a tmux window,
launch the Claude Code process, and return a live agent handle.
Source code in src/agentrelay/task_runner/implementations/task_launcher.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | |
launch(runtime)
Launch and return the primary agent for this task runtime.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime
|
TaskRuntime
|
Runtime envelope to launch against. Must have
|
required |
Returns:
| Name | Type | Description |
|---|---|---|
Agent |
Agent
|
Live agent handle bound to this task. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/agentrelay/task_runner/implementations/task_launcher.py
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | |
WorktreeTaskPreparer
dataclass
Create a task branch in a shared workstream worktree and write protocol files.
Creates a task-specific branch off the integration branch, checks it out
in the workstream worktree, writes manifest.json, policies.json,
and instructions.md into the signal directory, and updates the runtime
state with computed paths.
The worktree itself is owned by the workstream preparer — this class only creates and checks out branches within it.
Source code in src/agentrelay/task_runner/implementations/task_preparer.py
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | |
prepare(runtime)
Prepare runtime execution prerequisites.
Creates a task branch in the workstream worktree, checks it out, and writes protocol files to the signal directory.
Reads integration_branch and workstream_worktree_path from
runtime.state (set by the orchestrator before dispatch).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime
|
TaskRuntime
|
Runtime envelope to prepare (e.g. branch, signal files). |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/agentrelay/task_runner/implementations/task_preparer.py
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | |
WorktreeTaskTeardown
dataclass
Delegate agent-address cleanup and delete the task branch.
Performs best-effort cleanup: delegates log capture and environment teardown to the agent address, then deletes the task branch. The workstream worktree is owned by the workstream teardown handler and is not touched here. Errors during teardown are caught and not propagated.
Source code in src/agentrelay/task_runner/implementations/task_teardown.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | |
teardown(runtime)
Release runtime resources after terminal completion.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime
|
TaskRuntime
|
Runtime envelope whose resources should be cleaned up. |
required |
Source code in src/agentrelay/task_runner/implementations/task_teardown.py
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | |