microsoft / microsoft/agent-framework

Python: Support agent-to-agent communication across WorkflowExecutor boundaries

Open
#7,715 0 comments 0 reactions 1 assignee Claimed by @TaoChenOSU View on GitHub
python
Dominant language
Python
Stars
13.6k
Forks
2.3k
Avg merge
2d 45m
Merged PRs (30d)
358

Description

### Description

MAF supports agent-to-agent communication when agents are composed directly, but the same communication pattern is not supported when the downstream agent is inside a nested workflow wrapped by `WorkflowExecutor`.

The generic composition looks like this:

```text
AgentExecutor
-> AgentExecutorResponse
-> WorkflowExecutor(nested_workflow)
-> downstream agent(s)
```

The upstream `AgentExecutor` emits `AgentExecutorResponse`. However, `WorkflowExecutor` exposes only the nested workflow's declared start input types. A nested workflow that accepts `str`, `Message`, `list[str | Message]`, or `AgentExecutorRequest` therefore rejects `AgentExecutorResponse`, resulting in `TypeCompatibilityError` during graph validation.

This creates an inconsistency in composition behavior:

- Direct agent-to-agent composition supports `AgentExecutorResponse` handoff and conversation chaining.
- Agent-to-nested-workflow composition does not support the same handoff, even when the nested workflow ultimately contains agents and expects conversational input.
- `WorkflowExecutor` is required when the nested workflow's state must be captured and restored in the parent checkpoint.
- Using `nested_workflow.as_agent()` provides the message conversion, but moves execution behind `WorkflowAgent` and does not embed the nested workflow's internal state in the parent checkpoint.

In our scenario, using `WorkflowExecutor` is not optional: the parent workflow must maintain the nested workflow checkpoint state so the complete parent and subworkflow execution can be resumed from the parent's checkpoint. Replacing the nested workflow with `as_agent()` avoids the type mismatch but does not satisfy this checkpointing requirement.

Users must currently write custom glue code to unwrap `AgentExecutorResponse` before passing it to `WorkflowExecutor`, which makes a common agent composition pattern unnecessarily difficult and prevents the parent-owned checkpointing model from being used without custom code.

### Proposed capability

Add an explicit, built-in agent-response input mode or adapter for `WorkflowExecutor`, for example:

```python
WorkflowExecutor(
nested_workflow,
id="nested_workflow",
input_mode="agent_response",
)
```

The behavior should define whether the nested workflow receives `AgentExecutorResponse.agent_response.messages` or the full conversation, and should continue to capture and restore the nested workflow state as part of the parent checkpoint.

An alternative API could expose a standard framework adapter that unwraps `AgentExecutorResponse` to `list[Message]` while remaining checkpoint-aware.

### Expected outcome

Agents should be able to communicate through nested workflow boundaries using the same explicit handoff semantics as direct agent-to-agent composition, without custom adapter code, while preserving a single parent checkpoint containing the complete parent and nested workflow state.

### Additional context

This is an API/composition gap rather than an unexpected type-validation failure: the current contracts are internally consistent, but agent-to-agent composition is not consistently available across hierarchical workflow boundaries. `allow_direct_output` and `propagate_request` do not address the input type conversion.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.