Skip to content

feat(orchestration): DAG TaskGraph + pre-execution validation - #47016

Closed
kuangmi-bit wants to merge 2 commits into
NousResearch:mainfrom
kuangmi-bit:feat/orchestration-dag-validation
Closed

feat(orchestration): DAG TaskGraph + pre-execution validation#47016
kuangmi-bit wants to merge 2 commits into
NousResearch:mainfrom
kuangmi-bit:feat/orchestration-dag-validation

Conversation

@kuangmi-bit

Copy link
Copy Markdown

Summary

Multi-agent orchestration with dependency-graph execution and structured pre-flight validation, building on @georgex8001's work in #12436.

What's Included

TaskGraph — DAG Executor (src/orchestration/task_graph.py, 280 LOC)

  • DFS cycle detection
  • Parallel wave execution via asyncio
  • Fail-fast propagation (dependent tasks → SKIPPED)

Pre-flight Validation (validate_dag())

Returns structured ValidationReport:

Check Severity Rule
Cycle detection REJECT Any cycle → reject
Orphan detection WARNING Zero in+out degree nodes
Depth limit WARNING/REJECT >4 warning, >8 reject (configurable)
Blast radius INFO BFS → risk level (routine/elevated/critical)

Supporting Modules

  • AgentCommunicationBus — in-process async pub/sub for A2A messaging
  • MultiAgentOrchestrator — coordinates via existing delegate_task
  • Reflex hints — record/load failure patterns for self-improvement
  • HonchoContext — long-term memory injection bridge

Design Decisions

  • Stdlib onlyasyncio, no new dependencies
  • All validation is pre-flight — fails BEFORE any task runs
  • Independent of transport — works with A2A, delegate_task, or direct calls

Tests

18 tests in tests/orchestration/test_task_graph.py:

  • Node-level: cycle detection, fan-out, fan-in, deep chains
  • Graph-level: multi-wave parallelism, fail-fast cascade, depth enforcement
  • Boundary: empty DAG, single node, duplicate deps, unknown nodes

Related

Co-authored-by: @georgex8001

@kuangmi-bit
kuangmi-bit requested a review from a team June 16, 2026 03:43
@alt-glitch alt-glitch added type/feature New feature or request comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint tool/delegate Subagent delegation P3 Low — cosmetic, nice to have labels Jun 16, 2026

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the DAG validation work. Current main needs substantial integration work before this can safely land.

Problems

  • src/orchestration/delegate_runner.py:51 passes toolsets to delegate_task, but current main removed that argument in ba0bc01d1; this path will raise before a child starts.
  • src/orchestration/multi_agent_orchestrator.py:29 builds TaskGraph without calling validate_dag, so the advertised depth/orphan/blast-radius pre-flight checks never gate execution.
  • Parallel waves reach asyncio.to_thread (delegate_runner.py:81), while _temporary_environ mutates process-global os.environ (delegate_runner.py:47); concurrent nodes can cross-contaminate profile_env.
  • The existing Kanban graph already rejects cycles and dependency-gates work (hermes_cli/kanban_db.py:2814-2841) and dispatches ready tasks (hermes_cli/kanban_db.py:7240-7309).

Suggested changes

  • Rework against the current delegation contract, integrate validation into the actual execution path, and avoid global environment mutation.
  • Re-scope around a concrete Kanban integration; remove unused bus/registry pieces, or wire and test them. broadcast_tool_hint also only constructs a message at agent_bus.py:53-65, as noted in the prior review.

Automated hermes-sweeper review.

raw = delegate_task(
goal=spec.goal,
context=merged_ctx or None,
toolsets=list(spec.toolsets) if spec.toolsets else None,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: current main removed the toolsets parameter from delegate_task in ba0bc01, so this call raises TypeError before any child starts. Child toolsets now inherit from the parent; rework this bridge around that contract.

env_updates = dict(spec.profile_env or {})
env_updates.update(optional_honcho_env_patch())

with _temporary_environ(env_updates):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: this mutates process-global os.environ, but parallel graph roots reach this code concurrently through asyncio.to_thread. Two nodes with different profile_env values can observe or restore each other's environment; use explicit child configuration or process isolation instead.

parent_agent: Any,
specs: Sequence[GraphTaskSpec],
) -> Mapping[str, GraphTaskRun]:
graph = TaskGraph(specs)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: this execution entry point never calls validate_dag, so depth, orphan, and blast-radius findings do not run before delegates are started. Validate here and define the reject behavior before constructing/running the graph.

Comment thread src/orchestration/agent_bus.py Outdated
break
return out

def broadcast_tool_hint(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method only builds an AgentMessage addressed to "*"; it never calls publish or enqueues messages for peers. Either implement real broadcast semantics with a delivery test or rename it to make the builder-only behavior explicit.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users labels Jul 14, 2026
@kuangmi-bit

Copy link
Copy Markdown
Author

@teknium1 thanks for the thorough analysis. The salvageability=low assessment is fair — this PR was an early prototype and main has moved significantly since.

Given the Kanban already handles cycle detection and dependency-gating, and the delegation contract has changed (toolsets removed), a full rewrite against current main is needed.

Question for you: is the DAG TaskGraph direction still interesting to the project, or should I close this and focus on more targeted contributions?

@kuangmi-bit

Copy link
Copy Markdown
Author

Closing — no maintainer response on whether the DAG/AgentContext direction is still interesting to the project. The mainframe-to-AI-agent architecture work will continue in the standalone MACS project (github.com/deeparchi-ai/macs). Happy to reopen if a maintainer signals interest.

@kuangmi-bit kuangmi-bit reopened this Jul 18, 2026
邝谧 and others added 2 commits July 19, 2026 06:24
Multi-agent orchestration with dependency-graph execution and structured
pre-flight validation.  Based on work by @georgex8001 (PR NousResearch#12436) with
additional validation layers.

TaskGraph: DAG executor with DFS cycle detection, parallel wave execution
via asyncio, fail-fast propagation (dependents -> SKIPPED).

validate_dag(): pre-execution validation returning structured
ValidationReport:
  - Cycle detection (REJECT)
  - Orphan detection (WARNING for zero in+out degree nodes)
  - Depth limit (WARNING >4, REJECT >8, configurable)
  - Blast radius BFS (risk level: routine/elevated/critical)

AgentCommunicationBus: in-process async pub/sub for A2A messaging.
MultiAgentOrchestrator: coordinates via existing delegate_task.
Reflex hints: record/load failure patterns for self-improvement.

Stdlib only — no new dependencies.  18 tests pass.

Co-authored-by: georgex8001 <georgex8001@users.noreply.github.com>
…int + doc double-validation

1. broadcast_tool_hint now actually broadcasts to all known peers
   (iterates self._queues under lock, skips sender).  Was dead code
   that constructed a message and returned it without publishing.

2. TaskGraph.__init__ now documents why _validate_specs may run twice
   (constructor guard is intentional even if caller ran validate_dag).
@kuangmi-bit
kuangmi-bit force-pushed the feat/orchestration-dag-validation branch from b95ba52 to 6a4571f Compare July 18, 2026 22:25
@kuangmi-bit

Copy link
Copy Markdown
Author

Addressed knoal's blocking review:

  1. broadcast_tool_hint now actually broadcasts to all known peers (iterates self._queues under lock, skips sender). No longer dead code — the function does what its name says.
  2. TaskGraph.init documents why _validate_specs may run twice (constructor guard is intentional even if caller ran validate_dag).

Branch rebased onto current main (zero conflicts). Ready for re-review.

@kuangmi-bit

Copy link
Copy Markdown
Author

Closing as announced on Jul 18 — this was an early prototype and main has moved significantly (overlapping direction also explored in #12436). If the DAG/AgentContext direction is still wanted, a fresh PR against current main is the cleaner path.

@kuangmi-bit kuangmi-bit closed this Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P3 Low — cosmetic, nice to have sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state tool/delegate Subagent delegation type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants