OpenBMB / OpenBMB/PilotDeck

bug(model): OpenAI-compatible streaming fails after tool calls when assistant content is omitted

Open Beginner friendly
#263 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
4k
Forks
453
Avg merge
12h 30m
Merged PRs (30d)
46

Description

Problem

OpenAI-compatible streaming requests can fail on the second turn after a tool call when the historical assistant tool-call message omits content.

Observed provider error:

{"error":{"message":"Instructions are required","type":"invalid_request_error"}}

The error is misleading: the request does include a system message/instructions. The failure is triggered by the serialized assistant tool-call history shape.

Reproduction shape

A multi-turn streaming request after one tool call can contain a historical assistant message like this:

{
  "role": "assistant",
  "tool_calls": [
    {
      "id": "call_test_1",
      "type": "function",
      "function": {
        "name": "noop",
        "arguments": "{}"
      }
    }
  ]
}

When sent to an OpenAI-compatible provider in stream: true mode, this can fail with HTTP 400 and Instructions are required.

Adding an explicit empty content field fixes the same request:

{
  "role": "assistant",
  "content": "",
  "tool_calls": [
    {
      "id": "call_test_1",
      "type": "function",
      "function": {
        "name": "noop",
        "arguments": "{}"
      }
    }
  ]
}

Local verification

With the same OpenAI-compatible provider and request body:

  • stream: true + assistant tool_calls + content: ""200 OK
  • stream: true + assistant tool_calls without content400 Instructions are required

Non-streaming mode may be more permissive, which makes this easy to miss if only non-streaming compatibility is tested.

Root cause

src/model/providers/openai/request.ts serializes assistant messages that only contain tool calls without setting content.

Current behavior is effectively:

content: normalContent.length > 0
  ? toOpenAIContent(normalContent)
  : (message.role === "assistant" && thinkingBlocks.length > 0 ? "" : undefined),

So assistant messages with assistantToolCalls.length > 0 and no normal text content get content: undefined.

Expected behavior

For OpenAI-compatible request serialization, assistant messages with tool_calls should include explicit empty string content:

"content": ""

This is more compatible across OpenAI-compatible providers and avoids streaming failures after tool calls.

Suggested fix

Set content: "" for assistant messages when either thinking blocks or tool calls are present but normal content is empty, for example:

content: normalContent.length > 0
  ? toOpenAIContent(normalContent)
  : (message.role === "assistant" && (thinkingBlocks.length > 0 || assistantToolCalls.length > 0) ? "" : undefined),

Impact

This affects any agent flow that performs a tool call and then continues with a streaming OpenAI-compatible provider. In Always-On discovery, the run failed immediately after a simple glob tool call because the follow-up streaming request hit this provider validation error.

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 src/model/providers/openai/request.ts and inspect how assistant messages with tool calls are serialized when normal content is empty. Reproduce the streaming request shape described in the issue, then verify that assistant tool-call messages include explicit empty content and that the follow-up request succeeds with the OpenAI-compatible provider.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.