microsoft / microsoft/agent-framework

Python: [Bug]: SequentialBuilder second agent receives assistant-ending history and some models return empty text

Open
#8,240 0 comments 0 reactions 1 assignee View on GitHub

@eavanvalkenburg is already working on this.

Since Sep 10, 2026.

orchestration python
Dominant language
Python
Stars
13.6k
Forks
2.3k
Avg merge
2d 45m
Merged PRs (30d)
358

Description

### Description

When using `SequentialBuilder` with multiple agent participants (default settings), the second (and later) participant is invoked with the prior agent's `full_conversation`.

Observed shape for a two-agent sequential run:

```text
[user, assistant(writer output)]
```

That matches the documented chaining behavior (`AgentExecutor.from_response` with default `context_mode="full"` → `prior.full_conversation`).

With at least one OpenAI-compatible chat model we tested (`qwen3.8-27b@4bit` behind a chat-completions API), a completion whose input **ends with an `assistant` message** returns essentially empty text:

- `finish_reason=stop`
- `contents` empty (or only a usage chunk)
- `usage.output_token_count` ≈ 1

So the second participant (e.g. “reviewer”) appears to “run successfully”, but produces no assistant text. Downstream AG-UI workflow streaming then has no `TEXT_MESSAGE_*` events for that turn (only an empty `AgentResponseUpdate` surfaced as a custom/`workflow_output`-style payload).

**Expected:** We are looking for guidance from maintainers on how Sequential / multi-agent conversation chaining is intended to work with providers that do not emit text when the prompt ends on `assistant`.

**Repro outline**

1. Build `SequentialBuilder(participants=[writer, reviewer]).build()` with two chat agents on the model above.
2. Run with a simple user prompt (streaming or non-streaming).
3. Writer returns normal assistant text.
4. Reviewer is called with `[user, assistant(writer)]` and returns empty assistant content.

Same empty result when calling the second agent directly:

```python
agent.run([
Message(role="user", contents=["go"]),
Message(role="assistant", contents=["W-OK"]),
], stream=True)
# → stop with empty text
```

While:

```python
agent.run([Message(role="user", contents=["go"])], stream=True)
# → normal text
```

and

```python
agent.run([
Message(role="user", contents=["go"]),
Message(role="assistant", contents=["W-OK"]),
Message(role="user", contents=["continue"]),
], stream=True)
# → normal text
```

No exception is raised; the workflow completes with `executor_completed` / `RUN_FINISHED`.

### Code Sample

```python
from agent_framework.orchestrations import SequentialBuilder

workflow = SequentialBuilder(participants=[writer, reviewer]).build()

# stream=True or stream=False both show the same empty second-agent text
async for event in workflow.run("go", stream=True):
...
# reviewer AgentResponse / AgentResponseUpdate has empty text contents
```

### Error Messages / Stack Traces

No exception. Empty model completion only.

Example observed update for the second agent:

```text
AgentResponseUpdate(contents=[], role=assistant, finish_reason=stop, ...)
# followed by a usage-only update
```

### Package Versions

agent-framework (core): 1.15.0
agent-framework-orchestrations: 1.1.1
agent-framework-ag-ui: (used when observing AG-UI TEXT_MESSAGE absence; core issue reproduces without AG-UI via `workflow.run` / `agent.run`)

### Python Version

Python 3.14

### Additional Context

- Default Sequential settings (`chain_only_agent_responses=False`). With `chain_only_agent_responses=True`, the second agent still receives an assistant-ending message list (`[assistant(writer)]`), and we observed the same empty completion pattern.
- First participant is fine; only subsequent participants that inherit assistant-ending history are affected on this model.
- Happy to provide more traces (executor_invoked payloads / raw chat-completions request bodies) if useful.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.