Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

OpenAILanguageModel replays tool-call arguments as GeneratedContent's Codable form, not JSON

Open Beginner friendly
#324 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@gtokman is already working on this.

Since Oct 13, 2026.

  • #325 by @gtokman — open

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
82/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
swift
Domain
api

Research direction

The bug is in the .toolCalls case of the transcript conversion in Sources/AnyLanguageModel/Models/OpenAILanguageModel.swift, where JSONEncoder().encode(call.arguments) writes GeneratedContent's Codable form. Check the .responses variant, which reads the same message, and compare with OpenResponsesLanguageModel, which uses call.arguments.jsonString. Done when the replayed tool_calls arguments are plain JSON like {"query":...} in the second request's messages.

Written by the indexing model from the issue text.

Description

Summary

OpenAILanguageModel replays earlier tool calls with their arguments encoded by GeneratedContent's Codable conformance instead of as plain JSON. On the next turn the model sees arguments like:

{"kind":{"type":"structure","properties":{"query":{"kind":{"type":"string","value":"Apple stock 2026"}}},"orderedKeys":["query"]}}

instead of {"query":"Apple stock 2026"}. Models then copy that shape in their own new tool calls, the arguments don't match the tool's schema, and decoding them throws LanguageModelSession.ToolCallError, which ends the response.

Where

Sources/AnyLanguageModel/Models/OpenAILanguageModel.swift, in the .toolCalls case of the transcript conversion (line 1369 at 0.16.0, line 1374 on main / 1.0.0):

if let data = try? JSONEncoder().encode(call.arguments),
    let jsonString = String(data: data, encoding: .utf8)

GeneratedContent.encode(to:) writes id and kind, so this isn't the arguments' JSON. The .responses variant converts from the same message, so it's affected too. OpenResponsesLanguageModel already does it correctly with call.arguments.jsonString.

Suggested fix

let argumentsJSON = call.arguments.jsonString

Reproduce

  1. LanguageModelSession with OpenAILanguageModel (Chat Completions) and any tool.
  2. Ask something that makes the model call the tool, then ask a follow-up in the same session.
  3. Inspect the second request's messages: the assistant tool_calls[].function.arguments hold the {"kind":…} encoding.

Impact we measured

Benchmarking 4 models over 11 multi-turn conversations through the Vercel AI Gateway (Chat Completions): Gemini 4 Argon and Claude Haiku 5.5 each produced follow-up tool calls in the {"kind":…} shape (decoded as empty arguments, or failing to decode), which ended the reply. Claude Sonnet 5.5 happened to ignore it.

Seen on 0.16.0; the line is unchanged on main (1.0.0).

Dominant language
Swift
Stars
948
Forks
99
Avg merge
18h 38m
Merged PRs (30d)
56

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

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.

More from huggingface/AnyLanguageModel

All issues in huggingface/AnyLanguageModel

Similar issues

More Swift issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.