Skip to content

feat: Support staged re-invocation of agents (bidirectional workflows) - #68

Draft
Aviral Dua (aviraldua93) wants to merge 2 commits into
microsoft:mainfrom
aviraldua93:feature/staged-reinvocation-65
Draft

feat: Support staged re-invocation of agents (bidirectional workflows)#68
Aviral Dua (aviraldua93) wants to merge 2 commits into
microsoft:mainfrom
aviraldua93:feature/staged-reinvocation-65

Conversation

@aviraldua93

Copy link
Copy Markdown
Contributor

Summary

Implements staged re-invocation of agents (#65) — allowing the same agent to appear at multiple stages in a workflow with different prompts, inputs, and outputs while sharing model, tools, and system prompt configuration.

Problem

In real company workflows, the same role both directs work (going down) and reviews results (coming back up). Currently this requires duplicate agent nodes with duplicated config.

Solution

A new optional stages dict on AgentDef:

`yaml
agents:

  • name: vp_engineering
    model: gpt-4.1
    system_prompt: "You are VP Engineering..."
    prompt: "Set technical direction..."
    stages:
    review:
    prompt: "Review your team's output..."
    input: [ic.output]
    routes:
    - to: ic
    when: "verdict == 'revise'"
    - to: $end
    `

Stages expand into synthetic AgentDef instances at config load time (vp:default, vp:review), so the engine requires zero changes to workflow.py and router.py.

Changes

AreaFilesDetails
Schemaschema.py, expander.py (new)StageDef model, AgentDef.stages field, expansion logic with name collision detection
Validationvalidator.pyStage-qualified input refs, for-each/parallel stages rejection
Enginecontext.pyDual-key storage (agent:stage + agent latest), stages dict for Jinja2
Teststest_expander.py, test_staged_workflow.py42 tests: schema, expansion, integration, backward compat
Examplestaged-review.yamlVP→IC→VP:review pattern
QAtake_screenshots.pyPlaywright tests: 8 screenshots, 20 assertions

Design Decisions

  1. Config-time expansion — stages become regular agents at load time, keeping the engine unchanged
  2. Colon notation (agent:stage) — avoids collision with dot-path output references
  3. Dual-key context storage{{ vp.output }} returns latest output from any stage, {{ stages.vp.review.output }} accesses specific stage
  4. Backward compatiblestages defaults to None; existing workflows unchanged

Screenshots

Completed Staged Workflow

Completed

Node Detail (vp:review)

Node Detail

In-Progress

In Progress

Dark Mode

Dark Mode

Mobile

Mobile

Test Results

  • 42 new tests passing (schema, expansion, engine integration, backward compat)
  • 719 existing tests passing (no regressions)
  • Lint clean (ruff)
  • Type check clean (ty)
  • 20 Playwright assertions passing
  • make validate-examples passes

Closes#65

Aviral Duaand others added 2 commits March 29, 2026 22:42
Implements GitHub issue microsoft#65 — allows the same agent to appear at multiple
stages in a workflow with different prompts, inputs, and outputs while
sharing model, tools, and system prompt configuration.
## Design
Agents can now declare a stages dict with named invocation points:
`yaml
agents:
- name: vp_engineering
model: gpt-4.1
prompt: 'Set technical direction...'
stages:
review:
prompt: 'Review your team''s output...'
input: [ic.output]
`
Stages are expanded into synthetic AgentDef instances at config load time
(e.g., �p_engineering:default, �p_engineering:review), so the workflow
engine sees regular agents and requires minimal changes.
## Changes
**Schema & Config** (src/conductor/config/):
- New StageDef Pydantic model with optional overrides (prompt, input,
output, routes, description)
- AgentDef.stages: dict[str, StageDef] | None field
- �xpander.py — stage expansion with name collision detection, route
rewriting, and entry point rewriting
- Validator updated for stage-qualified input refs, for-each inline
agent stages rejection, and parallel group stages rejection
**Engine** (src/conductor/engine/context.py):
- Dual-key storage: stage-qualified outputs stored under both
�gent:stage and �gent (latest) keys for backward compatibility
- _build_stages_dict() for Jinja2 access via stages.agent.stage.output
- Stages dict injected into all three context modes
**Tests** (42 new tests):
- est_expander.py — 34 tests covering StageDef schema, expansion,
edge cases, name collisions, for-each validation
- est_staged_workflow.py — 8 integration tests covering VP→IC→VP:review
execution, loop-back, backward compatibility, context storage
**Example**: �xamples/staged-review.yaml — VP→IC→VP:review pattern
Closesmicrosoft#65
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- 20 assertions: node rendering, detail panels, API state, token counts
- Screenshots: completed, in-progress, each node detail, mobile, dark mode
- Tests: stage-qualified agents visible, API returns correct events
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support staged re-invocation of agents (bidirectional workflows)

1 participant

@aviraldua93