microsoft / microsoft/agent-framework
.NET: [Feature]: Make `Workflow.Edges`, `EdgeData.Connection` and `FanOutEdgeData` public
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 13.6k
- Forks
- 2.3k
- Avg merge
- 2d 45m
- Merged PRs (30d)
- 358
Description
`Workflow` exposes executors and a serializable projection of the graph's *shape*, but the **routing behaviour** (edge conditions and fan-out assigners) is unreachable outside the assembly. Anything that wants to run, analyze or visualize a workflow (alternative execution hosts, diagram tools, static validators) has to live in this repo or be granted `InternalsVisibleTo`.
## API change proposal
Three declarations, plus the overrides they force:
```csharp
// Workflow.cs:26
internal Dictionary> Edges { get; init; } = [];
// -> public IReadOnlyDictionary> Edges { get; internal init; }
// EdgeData.cs:15 (EdgeData is already public)
internal abstract EdgeConnection Connection { get; }
// -> public abstract EdgeConnection Connection { get; }
// FanOutEdgeData.cs:14 (SourceId / SinkIds / EdgeAssigner are already public)
internal sealed class FanOutEdgeData : EdgeData
// -> public sealed class FanOutEdgeData : EdgeData
// DirectEdgeData.cs:39, FanInEdgeData.cs:31, FanOutEdgeData.cs:41
// required by the EdgeData.Connection change: an override can't reduce accessibility (else CS0507)
internal override EdgeConnection Connection { get; }
// -> public override EdgeConnection Connection { get; }
```
**Not a breaking change.** All four are `internal` -> `public` widening, so nothing public becomes less accessible and no existing consumer breaks. The new public abstract `EdgeData.Connection` can't break external subclasses either, since `EdgeData`'s only constructor is internal. There are no `PublicAPI.*.txt` baselines to update.
`Edges` is the only one that touches existing code, and only code that can already see it. `IReadOnlyDictionary` isn't covariant in `TValue` (its `TryGetValue` takes an `out TValue`), so this isn't a plain re-type. `WorkflowBuilder` projects once where it builds the workflow,
```csharp
Edges = this._edges.ToDictionary(
keySelector: kvp => kvp.Key,
elementSelector: kvp => (IReadOnlyCollection)kvp.Value),
```
and `InProcessRunnerContext` changes one `out HashSet?` to `out IReadOnlyCollection?`. Every other reader binds unchanged, since they only enumerate, index or count. We never mutate these, so a read-only view is all a consumer needs.
**No new construction surface.** Every `EdgeData` subclass constructor, and `EdgeData`'s own, is already `internal`, so nobody outside can derive from it or construct an edge. `WorkflowBuilder` stays the only way to build a graph.
## Why `ReflectEdges()` isn't enough
`DirectEdgeInfo`/`FanOutEdgeInfo` expose `bool HasCondition`/`HasAssigner`, not the delegates, and `EdgeInfo.IsMatch(Edge)` is internal, so results can't be correlated back to edges. Hanging `Func<>` on `EdgeInfo` would conflate serializable checkpoint metadata with live behaviour. A conditions-only accessor keyed by `(SourceId, SinkId)` is lossy: `WorkflowBuilder.cs:378` only guards duplicates when `condition is null`, so two conditional edges between the same pair are legal today and would collapse.
Separately, `FanOutEdgeData` being internal while the identically shaped `DirectEdgeData` is public means direct edges are inspectable today and fan-out edges are not.
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.
Research direction
Start with Workflow.cs, EdgeData.cs, FanOutEdgeData.cs, DirectEdgeData.cs, and FanInEdgeData.cs, then inspect the related projections in WorkflowBuilder.cs and InProcessRunnerContext. Verify the public accessibility changes, the read-only Edges projection, and the required override updates by building and running the existing .NET test suite.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend-api-design
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100