microsoft / microsoft/amplifier

provider-openai: recovered incomplete streaming response can leave unpaired function_call items, permanently breaking the session

Open
#353 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
3.1k
Forks
261
Avg merge
3h 28m
Merged PRs (30d)
13

Description

Summary

provider-openai has a recovery path that salvages non-completed streaming responses:

[PROVIDER] OpenAI recovered a non-completed streaming response (status=incomplete...): returning the partial response instead of failing.

(The warning references amplifier-support#339; that repo is not publicly resolvable, so this issue is filed here.)

When the salvaged partial response contains a function_call item, the salvage can leave that call unpaired (no function_call_output) in persisted conversation history. Because the Responses API requires every function_call item in replayed input to have a matching function_call_output, every subsequent request in the session fails — the session is permanently wedged and no retry can ever succeed.

Observed behavior

  • Model: gpt-5.6-sol, with enable_response_chaining: auto.

  • A chained continuation response (llm:response event with continuation_count: 1, output_tokens: 2050, cost_usd: null, 2026-08-01) ended non-completed and was salvaged by the recovery path.

  • The salvaged partial contained:

    1. A function call with truncated/empty arguments {}, which failed tool schema validation ("Command is required").
    2. A function_call item (call_NpD59KEhgybRvh2IyJ4AEWKF) that never received a function_call_output.
  • Every subsequent request in that session failed with:

    InvalidRequestError: "No tool output found for function call call_NpD59KEhgybRvh2IyJ4AEWKF"

    14 occurrences in the session log, including retries 7 hours later. Because the dangling function_call is persisted in history, retries can never succeed.

Note: the caps were NOT the cause

The request budget was max_output_tokens=128000 with a 900k context, and the turn was at ~110k input / 2k output. So the non-completed status was likely content_filter or a stream drop — but the warning text only guesses "max_output_tokens".

Proposed fix

When salvaging a non-completed response (especially mid-continuation):

  1. Drop function_call items whose arguments are truncated/unparseable.
  2. Guarantee pairing: every retained function_call must get an output — synthesize an error function_call_output (e.g. "call truncated by provider") for any salvaged call that tooling didn't execute.
  3. Log incomplete_details.reason explicitly in the salvage warning instead of guessing at the cause.

Affected code

amplifier-module-provider-openai — the streaming recovery/salvage path and response chaining.

Contributor guide

No contributing guide indexed for this repository

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.

Research direction

Start in the amplifier-module-provider-openai streaming recovery/salvage path and its response-chaining handling for non-completed responses. Trace how salvaged function_call items enter persisted conversation history and how incomplete_details is currently reported. Done means truncated calls are handled safely, retained calls are paired, and the recovery warning records the provider's explicit reason.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.