Skip to content

[Bug]: openai-completions: Kimi/SGLang streamed tool-call arguments can arrive in a shape that breaks tool dispatch #69672

@varoudis

Description

@varoudis

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

When using a self-hosted Kimi model behind an OpenAI-compatible SGLang endpoint with OpenClaw’s openai-completions transport, tool-call conversations can break because streamed tool-call arguments are not always reconstructed into usable tool args before dispatch.

In my setup, this surfaced as tools being invoked with empty or malformed arguments, which then broke the turn.

Steps to reproduce

Minimal backend reproduction

This curl request produces the streaming shape I observed from Kimi/SGLang:

curl -N -sS http://YOUR_SGLANG_HOST:30000/v1/chat/completions
-H 'Authorization: Bearer YOUR_API_KEY'
-H 'Content-Type: application/json'
-d '{
"model": "mymodel",
"messages": [
{
"role": "system",
"content": "You are a test harness. Return exactly one tool call to read with JSON args only. Do not answer in natural language."
},
{
"role": "user",
"content": "Call the read tool exactly once with path /tmp/hello.txt"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "read",
"description": "Read a file",
"parameters": {
"type": "object",
"properties": {
"path": { "type": "string" }
},
"required": ["path"],
"additionalProperties": false
}
}
}
],
"tool_choice": {
"type": "function",
"function": { "name": "read" }
},
"temperature": 0,
"stream": true
}'

Expected behavior

OpenClaw should robustly reconstruct streamed tool-call arguments for OpenAI-compatible backends before dispatching tools, including cases where:

tool arguments arrive in multiple deltas
the first delta contains empty arguments
tool ids use nonstandard but valid strings like functions.read:0
reasoning deltas and tool deltas are interleaved

Actual behavior

OpenClaw sometimes dispatches the tool call with incomplete arguments, leading to errors such as:

read tool called without path

OpenClaw version

all for the last month at least

Operating system

MacOS

Install method

No response

Model

kimi 2.5 and 2.6

Provider / routing chain

sglang:latest (and :dev)

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Impact and severity

No response

Additional information

In failing runs, OpenClaw logs showed errors like:

[agent/embedded] read tool called without path: toolCallId=call_... argsType=object

That indicates the tool call reached the tool layer as an object, but without the required path field.

The conversation would then derail because the model believed it had called the tool correctly, but OpenClaw dispatched an empty or unusable argument object.

What I found

Direct API testing against the backend showed that Kimi/SGLang streams tool calls in an OpenAI-like format, but with some notable differences:

  • streamed reasoning arrives as reasoning_content
  • tool call ids look like functions.read:0
  • tool arguments are streamed in fragments across multiple chunks
  • the first tool-call delta may contain an empty arguments string, with later chunks appending the JSON pieces

Example streaming pattern from the backend:

{
  "delta": {
    "tool_calls": [
      {
        "id": "functions.read:0",
        "index": 0,
        "type": "function",
        "function": {
          "name": "read",
          "arguments": ""
        }
      }
    ]
  }
}

followed by deltas like:

{"arguments":"{\"path\": \"/"}
{"arguments":"tmp"}
{"arguments":"/hello"}
{"arguments":".txt\"}"}

This is close to OpenAI-compatible behavior, but OpenClaw appears to have trouble in some real runs reconstructing these streamed arguments reliably before tool dispatch.

Why I think this is an OpenClaw bug

There is already code in OpenClaw that attempts to repair malformed streamed tool-call arguments, but in my investigation that repair path was gated in a way that did not apply to my openai-completions self-hosted Kimi route.

So the failure is not necessarily that the backend is fully invalid. It looks like OpenClaw has an existing compatibility path for this class of problem, but it is not consistently active for self-hosted OpenAI-compatible Kimi/SGLang configurations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingregressionBehavior that previously worked and now fails

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions