ROCm / ROCm/FastFlowLM

gpt-oss:20b never emits tool_calls even with valid OpenAI-style tools schema + tool_choice:auto

Open
#684 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
1.9k
Forks
152
Avg merge
4h 14m
Merged PRs (30d)
11

Description

Summary

gpt-oss:20b never invokes any tool via the /v1/chat/completions OpenAI-compatible endpoint, even when the request includes a well-formed tools array and tool_choice: "auto". Instead of returning a tool_calls field, it always falls back to describing the requested action in plain text (e.g. "here's how you'd do this manually"). This occurs both when calling FLM directly and when using OpenCode (an agentic coding CLI that relies on real tool calls).

Related to #677 — found while reproducing that report's methodology on gpt-oss:20b.

Environment

item value
CPU / NPU AMD Ryzen AI 9 365 w/ Radeon 880M, XDNA, 50 TOPS
OS Arch Linux
FLM v1.0.2 (flm serve)
Model gpt-oss:20b

Minimal repro

curl http://127.0.0.1:52625/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-oss:20b",
    "messages": [{"role":"user","content":"Crea un archivo llamado test.txt con el contenido hola mundo."}],
    "temperature": 1.0,
    "top_p": 1.0,
    "tool_choice": "auto",
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "write",
          "description": "Escribe contenido a un archivo en el sistema.",
          "parameters": {
            "type": "object",
            "properties": {
              "filePath": {"type": "string"},
              "content": {"type": "string"}
            },
            "required": ["filePath", "content"]
          }
        }
      }
    ]
  }'

Actual output

No tool_calls field anywhere in the response. The model's own reasoning_content indicates it never considers the tool at all:

"reasoning_content": "The user says: "Crea un archivo llamado test.txt con el contenido hola mundo." So we need to create a file named test.txt with content "hola mundo". Likely they want us to provide the code or instructions? In typical ChatGPT environment, can't actually create files. We can show how to do it in various languages or via terminal commands.

Thus answer: Provide instructions on how to create file...",
"content": "¡Claro! Aquí tienes varias formas de crear un archivo llamado `test.txt`...
```bash
echo "hola mundo" > test.txt
```..."

Expected output

A tool_calls field with the write function invoked, e.g.:

"tool_calls": [
  {
    "id": "call_...",
    "type": "function",
    "function": {
      "name": "write",
      "arguments": "{"filePath":"test.txt","content":"hola mundo"}"
    }
  }
]

Additional evidence: same model works correctly via Ollama

Running the identical class of task (multi-step file creation/editing) against gpt-oss:20b served through Ollama correctly produces write/edit tool calls and completes the task end-to-end. This suggests the issue is specific to how FLM serves or translates tool-calling for this model, rather than a limitation of gpt-oss itself.

Hypothesis

gpt-oss uses OpenAI's Harmony chat format, where tool availability is communicated through a specific channel structure (<|channel|>analysis<|message|>...<|channel|>final<|message|>...). FLM's chat template for this model may not be correctly translating the OpenAI-style tools array into the function namespace Harmony expects. As a result, the model never registers tool access and consistently defaults to reasoning as a plain chatbot.

Side note: reasoning token budget

While testing, I also noticed that reasoning and final content appear to share the same max_tokens budget, with reasoning generated first. With a low max_tokens (100), the request returned an empty content field with finish_reason: "stop" because the entire budget was consumed by reasoning_content:

{"content":""},"finish_reason":"stop"
"usage": {"completion_tokens": 100, ...}

Raising max_tokens to 500 resolved this. While this may be expected behavior given that no separate reasoning/output budget is exposed via the API, flagging it here as it could explain edge cases where responses silently fail with short max_tokens settings.

Happy to test specific builds or flags and provide full request/response logs if helpful.

Contributor guide

Open the contributing guide

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 by running the minimal curl request against the /v1/chat/completions endpoint and compare the response with the expected tool_calls structure. Trace how the tools array and tool_choice are translated for gpt-oss's Harmony chat format. Done means the request produces the write tool call, with regression coverage for this behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
ai, api, backend-api-design
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.