Skip to content

Add Magentic agent-workflow builder (implements #564)#565

Draft
PratikDhanave wants to merge 1 commit into
microsoft:mainfrom
PratikDhanave:feat-magentic-workflow-builder
Draft

Add Magentic agent-workflow builder (implements #564)#565
PratikDhanave wants to merge 1 commit into
microsoft:mainfrom
PratikDhanave:feat-magentic-workflow-builder

Conversation

@PratikDhanave

Copy link
Copy Markdown
Contributor

Implements the Magentic builder proposed in #564 — the last unimplemented agent-workflow builder per docs/dotnet-go-sdk-feature-comparison.md ("Handoff and Magentic builders are not yet implemented"). Handoff is #545; this is its sibling.

Filed as a draft to anchor the design discussion in #564 — the four design questions there (orchestrator handle, ledger-prompt customization, stall/reset semantics, scope) are still open, and I would rather converge on the API with you before polishing. The core orchestration is implemented and tested.

API (matches the existing New…WorkflowBuilder conventions)

wf, err := agentworkflow.NewMagenticWorkflowBuilder(researcher, coder, reviewer).
    WithManager(orchestrator).            // orchestrator agent — required
    WithMaximumRoundCount(30).            // total participant-turn cap (default 30)
    WithMaximumStallCount(3).             // no-progress rounds before re-planning (default 3)
    WithMaximumResetCount(2).             // re-plans before giving up (default 2)
    WithName("magentic").
    WithOutputFrom(reviewer).
    Build()

How it works

It is a thin wrapper over NewGroupChatWorkflowBuilder. A magenticManager supplies GroupChatManager.SelectNextAgent and ShouldTerminate:

  • Task ledger — built once on the first round: the orchestrator produces the known facts and a plan.
  • Progress ledger — each round the orchestrator returns JSON {is_request_satisfied, is_progress_being_made, is_in_loop, next_speaker, instruction}, which decides routing and termination.
  • Stall / reset — a no-progress or looping round counts against the stall budget; exceeding it re-plans (rebuilds the task ledger) and spends a reset; exhausting the reset budget stops the run.
  • Checkpointing — the ledger/counters persist as prefixed manager state via OnCheckpoint/OnCheckpointRestored, matching the round-robin manager.
  • Graceful degradation — unparseable orchestrator output is treated as a no-progress round (so the stall machinery recovers) and an unknown next_speaker ends the run rather than routing to a non-participant.

Scope / open question (ties to #564 Q1/Q3)

This PR implements orchestrator-driven selection + termination + re-planning, which is the reviewable core. Per-turn instruction injection to the selected speaker is intentionally deferred: the group-chat host broadcasts only to non-speakers, so cleanly handing the orchestrator’s instruction to the chosen agent needs either a small host hook or a manager-supplied preamble — a design choice I’d like your steer on (#564). The instruction field is already parsed and part of the ledger.

Tests

magentic_test.go (white-box, matching the package convention) covers: builder validation (missing manager, no agents), routing to the selected speaker then terminating on is_request_satisfied, stall→re-plan→reset-budget termination (bounded, not round-capped), unknown-speaker graceful termination, and progress-ledger JSON parsing (plain, fenced-with-prose, and non-JSON). Full package green; gofumpt/vet clean.

NewMagenticWorkflowBuilder(agents...) builds a manager-orchestrated
multi-agent workflow. A dedicated orchestrator agent (WithManager)
maintains a task ledger and, each round, evaluates a JSON progress ledger
to decide whether the request is satisfied, whether progress has stalled,
and which participant speaks next. It re-plans on stalls (WithMaximumStallCount)
and stops after exhausting its reset budget (WithMaximumResetCount) or the
round cap (WithMaximumRoundCount).

Reuses the group-chat host and GroupChatManager machinery: the orchestrator
drives SelectNextAgent and ShouldTerminate, with the ledger checkpoint-
persisted as manager state. Unparseable orchestrator output and unknown
next-speaker names degrade gracefully rather than failing the run.
Sign up for free to 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.

1 participant