.NET: Add subagents provider and sample#5518
.NET: Add subagents provider and sample#5518westey-m wants to merge 2 commits intomicrosoft:feature-harnessfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new .NET Harness AIContextProvider that lets an agent delegate work to named sub-agents asynchronously (start tasks, wait for completion, fetch results, continue, and clear), plus a new Harness sample demonstrating concurrent delegation to a web-search sub-agent.
Changes:
- Introduce
SubAgentsProvider+ supporting state/types (SubTaskInfo,SubTaskStatus, options, session/runtime state) and register them for JSON source-gen. - Add comprehensive unit tests for sub-agent task lifecycle behaviors.
- Add a new Harness sample (
Harness_Step02_Research_WithSubAgents) and update shared console formatting to recognize the new tool names.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| dotnet/src/Microsoft.Agents.AI/Harness/SubAgents/SubAgentsProvider.cs | New provider exposing sub-agent delegation tools and session-backed state. |
| dotnet/src/Microsoft.Agents.AI/Harness/SubAgents/SubAgentsProviderOptions.cs | Options for custom instructions and agent list formatting. |
| dotnet/src/Microsoft.Agents.AI/Harness/SubAgents/SubTaskInfo.cs | Serializable task metadata/result container. |
| dotnet/src/Microsoft.Agents.AI/Harness/SubAgents/SubTaskStatus.cs | Task status enum (Running/Completed/Failed/Lost). |
| dotnet/src/Microsoft.Agents.AI/Harness/SubAgents/SubAgentState.cs | Serializable session state (next id + task list). |
| dotnet/src/Microsoft.Agents.AI/Harness/SubAgents/SubAgentRuntimeState.cs | Runtime-only references for in-flight tasks and sub-sessions. |
| dotnet/src/Microsoft.Agents.AI/AgentJsonUtilities.cs | Registers new sub-agent types for JSON source generation. |
| dotnet/tests/Microsoft.Agents.AI.UnitTests/Harness/SubAgents/SubAgentsProviderTests.cs | New tests covering construction, tool behaviors, and run-context isolation. |
| dotnet/samples/02-agents/Harness/README.md | Adds the new sample to the Harness samples list. |
| dotnet/samples/02-agents/Harness/Harness_Step02_Research_WithSubAgents/README.md | Documents the new sub-agent sample scenario and setup. |
| dotnet/samples/02-agents/Harness/Harness_Step02_Research_WithSubAgents/Program.cs | Implements the sample: parent agent delegates lookups to web-search sub-agent. |
| dotnet/samples/02-agents/Harness/Harness_Step02_Research_WithSubAgents/Harness_Step02_Research_WithSubAgents.csproj | Adds the new sample project. |
| dotnet/samples/02-agents/Harness/Harness_Shared_Console/ToolCallFormatter.cs | Updates tool name mappings for sub-agent tool calls. |
| dotnet/samples/02-agents/Harness/Harness_Shared_Console/HarnessConsole.cs | Improves command listing and mode display when mode provider is absent. |
| dotnet/agent-framework-dotnet.slnx | Adds the new sample project to the solution. |
There was a problem hiding this comment.
Automated Code Review
Reviewers: 3 | Confidence: 92%
✓ Correctness
The SubAgentsProvider implementation is well-structured and follows the established patterns of existing providers (TodoProvider, FileMemoryProvider). The core logic for managing sub-tasks—starting, waiting, retrieving results, continuing, and clearing—is correct. The Task.Run wrapping for ExecutionContext isolation is justified (RunAsync at AIAgent.cs:340 synchronously sets the static AsyncLocal CurrentRunContext before returning RunCoreAsync). The runtime state mechanism works correctly via the StateBag's deserialized object cache, which preserves in-memory references across ProvideAIContextAsync calls. State serialization correctly marks non-serializable runtime data with [JsonIgnore] and handles the 'Lost' status for tasks that survive a restart. No correctness bugs found.
✓ Security Reliability
The SubAgentsProvider is well-structured and follows established patterns in the codebase (TodoProvider, AgentModeProvider). The Task.Run wrapping for ExecutionContext isolation is correct and well-documented. Tool call serialization by FunctionInvokingChatClient ensures List mutations are safe. State management via ProviderSessionState with the AgentSessionStateBagValue cache preserves in-memory runtime references correctly. No blocking security or reliability issues were found. The code handles error paths (invalid agent names, nonexistent tasks, running-task guards) consistently. Two minor suggestions are offered as incremental improvements.
✗ Design Approach
The overall sub-agent state model is workable, but the execution path is wired through a new ad-hoc child-run mechanism instead of the framework’s existing child-agent invocation path. That bypasses parent-run option propagation, so sub-agents can silently lose per-request behavior that the rest of the agent stack expects to flow into nested calls.
Flagged Issues
- Sub-agent runs are started with raw
agent.RunAsync(...)calls instead of the framework's existing delegation/helper path, which dropsFunctionInvokingChatClientrun properties for child runs. In the current codebase, those propagatedAdditionalPropertiesare already used to alter child behavior such as chat-history resolution (dotnet/src/Microsoft.Agents.AI/AgentExtensions.cs:76-81,dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgent.cs:964-979).
Automated review by westey-m's agents
Motivation and Context
Description
Contribution Checklist