-
Notifications
You must be signed in to change notification settings - Fork 4
Feature: multi-executor task routing — dispatch tasks to different agent runtimes #9
Description
The Problem
The wg daemon currently has one dispatch path: spawn a Claude CLI process for each ready task. This works well for code-writing agents, but falls short when workgraph is used as a general task orchestration system with multiple executor types:
-
Different agent runtimes — A project might have specialized agents (research agents, deployment agents, communication agents) that run as HTTP services, not as Claude CLI processes. Tasks intended for these agents sit unexecuted because the daemon only knows how to spawn Claude.
-
Scheduled execution — Some tasks should fire at specific times (e.g., "run this analysis at 9am daily", "deploy staging at 2pm"). There's no way to express "dispatch at time X" on a task.
-
Worktree isolation — Git worktrees create separate
.workgraph/directories. The daemon in the main repo has no visibility into worktree workgraphs. Tasks in worktrees require manually starting a separate daemon per worktree. -
External orchestrators — Tools like n8n, Temporal, or custom supervisors may want to claim and execute wg tasks. They need a way to indicate how tasks should be dispatched.
Proposed: Executor Field on Tasks
Add a first-class executor field to the task schema:
# Dispatch via default (Claude CLI)
wg add "Fix auth bug"
# Dispatch to an HTTP endpoint
wg add "Research competitor landscape" --executor http://localhost:3530/api/task
# Dispatch to a named executor profile
wg add "Deploy to staging" --executor deploy-agent
# Hold until scheduled time, then dispatch
wg add "Generate weekly report" --executor scheduled --schedule "09:00"Executor Profiles in Config
# .workgraph/config.toml
[executors.deploy-agent]
type = "http"
endpoint = "http://localhost:3531/api/task"
method = "POST"
[executors.scheduled]
type = "schedule"
# Dispatches via default executor when schedule triggers
[executors.default]
type = "claude" # current behaviorDaemon Changes
The coordinator's dispatch logic currently does:
- Find ready task
- Spawn Claude CLI
With multi-executor:
- Find ready task
- Read task's
executorfield (default: "default") - Resolve executor profile from config
- Dispatch via the profile's type:
claude: current behavior (spawn CLI)http: POST task payload to endpoint, register agentschedule: check if schedule time has arrived, dispatch if soexternal: mark task as "claimed-externally", wait for completion callback
Completion Callbacks
External executors need a way to report task completion:
# External agent calls when done:
wg done <task-id> --agent <agent-id> --artifacts '{"result": "..."}'
# Or via webhook:
POST /api/task/<task-id>/completeThe daemon already handles wg done — it just needs to accept it from agents it didn't spawn itself.
Use Cases
Multi-agent systems
A project with specialized agents (scheduler agent, research agent, code agent, ops agent) can route tasks to the right agent automatically. Each agent gets only the tasks it's equipped to handle.
Scheduled operations
DevOps tasks, report generation, periodic audits — all expressible as wg tasks that fire on schedule.
Hybrid orchestration
Some tasks dispatched by wg daemon, others by external tools (n8n workflows, custom supervisors). The graph is the single source of truth for what needs doing; multiple executors collaborate on getting it done.
Cross-worktree dispatch
A supervisor that scans all worktrees can dispatch tasks from any of them, routing to the appropriate executor. Worktrees no longer need independent daemons.
What We're Doing Today (Workaround)
We're building a routing layer in our supervisor that reads wg task tags (agent:samantha, schedule:14:00) and dispatches to different HTTP endpoints. It works but it's fragile — we're parsing tags by convention, claiming tasks to prevent double-dispatch, and managing the lifecycle outside of wg. A first-class executor field would make this robust and available to all wg users.