Skip to content

openai_responses should treat final function-call arguments as authoritative #1455

Description

@ayu-exorcist

What version of Kimi Code is running?

0.23.0

Which open platform/subscription were you using?

A third-party OpenAI Responses compatible provider configured through openai_responses rather than a built-in /login subscription.

Which model were you using?

krill/gpt-5.4 and krill/gpt-5.5

What platform is your computer?

Windows 10.0.19045 x64

What issue are you seeing?

Kimi Code frequently aborts tool-calling turns when using the openai_responses provider. The failure happens while the agent is writing documentation and invoking file tools such as Read, Write, and Edit.

The error is:

Error: [provider.api_error] OpenAI Responses final function-call arguments for stream index fc_xxx do not match the streamed argument deltas.

One concrete log line from the affected session:

ChatProviderError: OpenAI Responses final function-call arguments for stream index fc_07bfe1e0fc59947e016a4c68e455208191b27c4c85dfa0793f do not match the streamed argument deltas.

The same session hit this class of error repeatedly across different function-call stream indexes. This is not a one-off transient failure.

From reading the implementation, Kimi Code currently accumulates:

  • response.output_item.added.item.arguments
  • response.function_call_arguments.delta.delta

Then, when receiving either:

  • response.function_call_arguments.done.arguments
  • or response.output_item.done.item.arguments

it requires the final arguments to match the accumulated streamed deltas, or at least to start with the accumulated value. If not, it throws and aborts the turn.

This strict byte-prefix validation appears too brittle for OpenAI Responses compatible streams. In the same provider/model setup, I did not reproduce this final function-call arguments ... do not match the streamed argument deltas failure in Pi CLI Agent or OpenAI Codex.

What steps can reproduce the bug?

  1. Configure a third-party OpenAI Responses compatible provider in Kimi Code with type = "openai_responses".
  2. Select a model such as krill/gpt-5.4 or krill/gpt-5.5.
  3. Ask Kimi Code to generate a long document that requires file tool calls, especially Write / Edit with long arguments.
  4. During a streamed function call, Kimi Code aborts with:
OpenAI Responses final function-call arguments for stream index fc_xxx do not match the streamed argument deltas.

I also checked the behavior of two other agent clients:

OpenAI Codex

OpenAI Codex, the official OpenAI CLI agent, does not appear to rely on ordinary response.function_call_arguments.delta / done events to assemble the final tool-call arguments. For ordinary function calls, Codex waits for response.output_item.done.item.arguments and uses the final item arguments when executing the tool.

In effect, Codex treats the final output_item.done arguments as authoritative.

Pi CLI Agent

Pi CLI Agent updates a temporary partialJson from response.function_call_arguments.delta, but when response.function_call_arguments.done.arguments arrives, Pi replaces the accumulated value with the final arguments. Later, when response.output_item.done.item.arguments arrives, Pi again uses the final item arguments.

If the final arguments do not start with the previous streamed partial JSON, Pi does not throw; it simply avoids emitting a suffix delta and continues with the final arguments.

So both Pi and Codex avoid aborting on this mismatch class. Codex is especially relevant here because it is OpenAI's official CLI agent and already treats final Responses tool-call arguments as authoritative.

What is the expected behavior?

Kimi Code should be compatible with this Responses stream behavior and should not abort the entire turn solely because the streamed function-call argument deltas are not a byte-prefix of the final arguments.

The final arguments should be authoritative, with this priority:

response.output_item.done.item.arguments
> response.function_call_arguments.done.arguments
> accumulated response.function_call_arguments.delta

Recommended behavior:

  1. Use function_call_arguments.delta for streaming progress / temporary buffering only.
  2. When response.function_call_arguments.done.arguments is received, replace the temporary accumulated arguments with the final arguments.
  3. When response.output_item.done.item.arguments is received, use that as the highest-priority final function-call arguments.
  4. Do not throw only because the streamed deltas differ from the final arguments at the byte-prefix level.
  5. Still keep all safety checks before tool execution: JSON parsing, tool schema validation, approval flow, path safety, and command safety.
  6. If no final arguments are available, or if the final arguments cannot be parsed/validated for the selected tool, then fail before executing the tool.

This compatibility should be the default behavior for openai_responses, not an optional workaround. Since OpenAI Codex already follows a final-arguments-authoritative approach for ordinary function calls, Kimi Code should align with that behavior for better OpenAI Responses compatibility.

Additional information

It would also help if this error path logged safe diagnostics without exposing full tool arguments, for example:

  • accumulated argument length
  • final argument length
  • hash of both strings
  • whether the final value starts with the accumulated value
  • whether both values are valid JSON
  • whether the parsed JSON values are semantically equivalent
  • whether the mismatch came from function_call_arguments.done or output_item.done

That would make it much easier to distinguish provider stream issues from client parsing assumptions without leaking file contents, shell commands, or other sensitive tool arguments.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    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