microsoft / microsoft/agent-framework
.NET: [Feature/RFC]: DevUI visual authoring with declarative and code round-tripping
@chetantoshniwal is already working on this.
Since Aug 3, 2026.
- Dominant language
- Python
- Stars
- 13.6k
- Forks
- 2.3k
- Avg merge
- 2d 45m
- Merged PRs (30d)
- 358
Description
Summary
Evolve DevUI developer mode from an execution/debugging surface into an opt-in local authoring environment for agents, harnesses, workflows, and subworkflows.
The proposed experience would let developers:
- Discover and open existing agents, harness configurations, workflows, and subworkflows.
- Create and edit them visually.
- Edit the corresponding declarative YAML alongside the visual representation.
- Generate deterministic, idiomatic C# and Python code, with an architecture that can add Go.
- Import supported code patterns into the visual model.
- Synchronize changes bidirectionally without overwriting custom application logic.
- Validate, preview the source diff, hot-reload, run, and debug the edited entity in the same DevUI experience.
Why revisit this now?
This follows up on #1655 and its discussion of AutoGen Studio/n8n-style authoring, code generation, and UI-to-code synchronization. That issue was closed as completed, but DevUI currently provides workflow execution and visualization rather than the full visual-authoring and round-trip experience discussed in its comments.
The repository and framework have moved significantly since that discussion:
- Agent Framework 1.0 is released with stable APIs for .NET and Python: https://devblogs.microsoft.com/agent-framework/microsoft-agent-framework-version-1-0/
- Declarative workflows are now 1.0 across both SDKs. Python's package joined the already-stable .NET package: https://devblogs.microsoft.com/agent-framework/move-agent-orchestration-workflows-out-of-code-with-agent-framework-declarative-workflows-1-0/
- The Agent Framework Harness is stable in both .NET and Python: https://devblogs.microsoft.com/agent-framework/the-microsoft-agent-framework-harness-is-now-released/
- DevUI already has a shared React frontend for .NET and Python and an existing React Flow workflow canvas.
- Microsoft Foundry already demonstrates editable visual/YAML synchronization, proving that the underlying declarative model can support this interaction: https://learn.microsoft.com/azure/foundry/agents/concepts/workflow?view=foundry#configure-additional-features
The prerequisite mentioned in #1655—stabilizing the declarative workflow design and bringing Python support alongside .NET—has therefore been met.
Related requests include #1686, #1462, and #3570.
Important scope boundary
Bidirectional synchronization should cover:
- Declarative definitions.
- Designer-managed generated code.
- A documented set of recognizable code-first patterns.
It should not promise lossless visual editing of arbitrary Turing-complete C#, Python, or Go. Dynamic or unsupported constructs should remain visible as opaque code-backed components with source navigation and explicit portability diagnostics.
That scope makes the feature deterministic and maintainable.
Proposed architecture: a common authoring model
Introduce a versioned, language-neutral Agent Framework Authoring IR as the synchronization pivot:
flowchart LR
UI["DevUI visual designer"]
IR["Versioned Agent Framework Authoring IR"]
YAML["Declarative YAML"]
CS["C# adapter (Roslyn)"]
PY["Python adapter (LibCST)"]
GO["Go adapter (go/ast + go/types)"]
Runtime["Validate, reload, run, and debug"]
UI <--> IR
YAML <--> IR
CS <--> IR
PY <--> IR
GO <--> IR
IR --> Runtime
The GUI should not directly translate between YAML, C#, Python, and Go. Each representation maps through the same normalized IR.
The IR should contain:
- Agents, models, instructions, tools, tool schemas, and resources.
- Middleware and context providers.
- Harness components such as planning, todos, memory, skills, approvals, loops, file access, and background agents.
- Workflows, typed ports, executors, edges, conditions, and subworkflows.
- Stable component IDs.
- Source locations, symbols, and ownership information.
- Portable configuration plus language-specific extension data.
- Capability, validation, and portability diagnostics.
The existing declarative YAML should remain the primary portable representation. This proposal should not introduce a competing runtime DSL.
Source ownership modes
1. Declarative-owned
YAML is authoritative. Visual edits update YAML, and YAML edits update the visual model. Code is an optional generated artifact.
2. Designer-managed code
DevUI owns clearly marked generated files. Custom tools, executors, predicates, and middleware live in separate user-owned files and are referenced by symbol/import path.
3. Imported code
DevUI analyzes recognized construction patterns and offers safe edits for the supported subset. Unsupported logic appears as an opaque code node. A developer can explicitly choose Adopt into designer to create a managed declarative definition and generated source.
This ownership model prevents generated output from overwriting application code.
Synchronization method
Maintain three semantic snapshots per entity:
- The last synchronized base IR.
- The current source-derived IR.
- The edited DevUI IR.
Synchronize through a semantic three-way merge keyed by stable component IDs:
- Parse or project the source into IR.
- Apply UI edits as JSON Patch operations against the base revision.
- Automatically merge non-overlapping changes.
- Present property-level conflicts in a merge UI.
- Generate a complete source diff for review.
- Parse, validate, compile/type-check, and format the proposed output.
- Replace files atomically only after validation succeeds.
- Update the base revision and hot-reload the entity.
Use content hashes/ETags and If-Match semantics to prevent lost updates.
Semantic configuration should remain in YAML or code. Editor-only data such as positions, colors, viewport, and collapsed subworkflows can live in a committed .maf/design/*.json sidecar keyed by the same stable IDs.
Deterministic code generation
Code generation should be deterministic and template/AST based. AI-assisted conversion can be offered as an optional migration helper, but it should not be the synchronization engine.
.NET
- Use Roslyn
MSBuildWorkspace,SemanticModel, andSyntaxEditorfor discovery, symbol resolution, diagnostics, and safe supported edits. - Use an incremental source generator or companion
dotnet toolto generate*.g.csfrom the Authoring IR/declarative files. - Generate a single explicit registration entry point and partial hooks for user implementations.
- Compile the resulting project before applying the change.
Python
- Use LibCST rather than only
ast, so formatting and comments can be preserved when supported source is edited. - Generate a managed
_maf_generated.pymodule. - Reference custom tools and predicates through qualified import paths.
- Validate with Ruff and Pyright where available.
- Treat dynamic factories, monkey-patching, and runtime-computed graphs as read-only/opaque unless adopted.
Go
- Use
go/packages,go/ast,go/types, andgo/format. - Generate
zz_generated.maf.gothroughgo generate. - Keep user implementations in normal
.gofiles and reference them by typed symbol. - Design the Authoring IR and capability protocol for Go from the start, while delivering the Go adapter after the initial .NET/Python implementation.
The Go SDK is currently in public preview in a separate repository, and DevUI/declarative workflows are not yet at parity: https://github.com/microsoft/agent-framework-go/blob/main/docs/dotnet-go-sdk-feature-comparison.md
Suggested technology stack
| Area | Technology | Why |
|---|---|---|
| Designer | Existing React, TypeScript, Vite, @xyflow/react, Zustand, Radix, Tailwind |
Reuses the frontend already shared by Python and .NET DevUI. |
| YAML/code editor | Lazy-loaded Monaco Editor | Mature code/diff editing, diagnostics, source navigation, and familiar VS Code experience. |
| Contracts | Versioned JSON Schema and OpenAPI | Language-neutral validation and schema-driven property forms. |
| Expressions | Existing Power Fx model | Avoids inventing another expression language and matches declarative workflows. |
| .NET adapter | Roslyn | Semantic understanding and syntax-preserving supported edits. |
| Python adapter | LibCST + Ruff/Pyright | Concrete-syntax preservation plus fast diagnostics. |
| Go adapter | Standard Go analysis/format packages | Idiomatic, deterministic, and toolchain-native. |
| Synchronization | Stable IDs, ETags, JSON Patch, semantic three-way merge | Prevents lost updates and avoids fragile line-based merging. |
Capability-driven UI
Each runtime/language adapter should publish capability descriptors and JSON Schemas for the node/component types it supports.
DevUI can then:
- Populate its palette dynamically.
- Generate configuration forms from schemas.
- Mark unsupported nodes for a selected target language.
- Explain why a definition is not portable.
- Avoid hard-coding every .NET, Python, and Go component in the frontend.
This is important for controlling the maintenance cost raised in #1655.
Security model
Visual authoring materially expands DevUI's trust boundary and should therefore be:
- Disabled by default and enabled explicitly, for example with
--authoringorAddDevUI(options => options.EnableAuthoring = true). - Restricted to an explicit project root with canonical path validation.
- Loopback-only by default, consistent with DevUI's current security posture.
- Diff-before-write, with no silent source modification.
- Atomic and revision checked.
- Static-analysis-first; importing a project should not execute arbitrary source merely to discover its graph.
- Secret-reference-only: environment-variable and connection names may be edited, but secret values must never be returned to the browser or written into generated files.
- Generator allowlist based: only registered component templates/adapters may emit code.
How this addresses the concerns raised in #1655
| Concern | Proposed response |
|---|---|
| A visual DSL cannot express all real-world logic | Use the existing declarative model for the portable subset and retain code references/opaque nodes as escape hatches. |
| Arbitrary UI-authored logic is risky | Generate only known typed components, require explicit diff approval, validate before writing, and keep authoring local/opt-in. |
| Keeping UI and code features synchronized is expensive | Publish versioned capability descriptors from each runtime and drive the UI from schemas. |
| Production deployments ultimately use code | Treat deterministic generated code as a first-class output with user-owned extension hooks. |
| Round-tripping arbitrary code is unreliable | Clearly scope round-tripping to declarative and designer-managed patterns; import other code as read-only or partially editable. |
Suggested delivery phases
Phase 1: Declarative workflow authoring
- Visual create/open/edit/save for .NET and Python declarative workflows.
- Live visual/YAML synchronization.
- Schema and Power Fx validation.
- Source diff, atomic save, hot reload, run, and debug.
- Layout sidecars and stable IDs.
Phase 2: Agents and harnesses
- Declarative agent editing.
- Nested visualization for tools, middleware, context providers, and stable harness components.
- Capability-driven configuration forms.
Phase 3: Managed C# and Python
- Deterministic code generation.
- Source maps and navigation.
- Supported-pattern import and adoption.
- Semantic conflict resolution.
Phase 4: Composition
- Subworkflow authoring.
- Expand/collapse and depth controls.
- Reusable templates/components.
- Cross-entity references and dependency validation.
Phase 5: Go
- DevUI discovery/hosting adapter in
agent-framework-go. - Go generator and supported-pattern importer.
- Cross-language conformance tests against the Authoring IR.
MVP acceptance criteria
- A developer can open an existing declarative workflow in DevUI, edit it visually, save it, and observe a valid YAML diff.
- Editing the YAML updates the visual model without losing stable node identity.
- The saved workflow loads and executes in both .NET and Python.
- DevUI can generate deterministic C# and Python for the supported declarative subset.
- Regenerating unchanged input produces byte-for-byte equivalent generated output after formatting.
- Custom tools and conditions remain in user-owned files and survive regeneration.
- Concurrent file/UI edits are detected and merged or shown as conflicts.
- Unsupported constructs are preserved as opaque nodes and never silently dropped.
- Secrets are neither returned to the browser nor emitted into generated source.
- The authoring capability is opt-in and restricted to an explicit local project root.
Non-goals
- A production low-code hosting platform.
- Lossless editing of arbitrary C#, Python, or Go.
- Executing arbitrary code merely to inspect a project.
- Replacing code-first Agent Framework APIs.
- Depending on an LLM for repeatable code generation or synchronization.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.