continuedev / continuedev/continue

Ollama provider drops `tools` after the first tool call, breaking multi-step agent loops

Open Beginner friendly
#13,254 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
36k
Forks
5.4k
PR merge metrics
No merged PRs in 30d

Description

Before submitting your bug report
Relevant environment info
- OS: Windows 11
- Continue version: 2.0.0 (VS Code extension, win32-x64)
- IDE version: 1.137.0
- Model: Qwen3.8 27B
- config:
  
    provider: ollama
    capabilities:
      - tool_use
    roles:
      - chat
      - edit
      - apply
Description

In agent mode with an Ollama model, the agent executes exactly one tool call per user
message and then stops — it narrates its next intended step as plain text but never
emits the follow-up tool call. Re-prompting produces one more tool call, then stops again.

Root cause
In the Ollama provider's chat-args builder, the tools array is only attached when the
last message is a user message:

if (options.tools?.length && ollamaMessages.at(-1)?.role === "user") {
  chatOptions.tools = options.tools.map(...);
}

During an agent loop, the turn that immediately follows a tool execution has a tool
(tool-result) message as its last message, not user. So the tool schema is omitted on
exactly the turn where the model needs to decide on the next tool call. With no tools in
the request, the model can't continue the loop and falls back to prose.

Suggested fix

extension.js (line 524024)

Drop the ollamaMessages.at(-1)?.role === "user" condition:

if (options.tools?.length) {
chatOptions.tools = options.tools.map(...);
}

To reproduce
  1. Configure any tool-capable Ollama model in agent mode.
  2. Give it a task requiring 2+ sequential tool calls (e.g. "read file A, then read file B").
  3. Observe: it calls the tool for A, receives the result, then emits text like
  4. "Let me now check B…" and stops without calling the tool for B.
Log output
Minimal reproduction against Ollama /api/chat (no Continue needed), showing that
omitting the `tools` array on the turn whose last message is a tool result stops
the model from continuing — which is exactly what Continue's Ollama provider does.

Model under test: a tool-capable Ollama model (reproduced on a Qwen3-family GGUF).
Conversation state = [user, assistant(tool_call read_file A), tool(result for A)].

--- CASE 1: request WITHOUT tools (what Continue sends after a tool result) ---
POST http://localhost:11434/api/chat
{
  "model": "<tool-capable-model>",
  "stream": false,
  "messages": [
    {"role":"user","content":"Read fileA.cs then fileB.cs to understand the structure."},
    {"role":"assistant","content":"","tool_calls":[
      {"function":{"name":"read_file","arguments":{"filepath":"fileA.cs"}}}]},
    {"role":"tool","content":"public class A { void OnBar(){} }"}
  ]
}
Response:
  message.content    = ""       (no follow-up)
  message.tool_calls = (none)   <-- loop dead: model cannot continue

--- CASE 2: identical request but WITH tools resent ---
POST http://localhost:11434/api/chat
{
  "model": "<tool-capable-model>",
  "stream": false,
  "messages": [ ...same three messages as above... ],
  "tools": [
    {"type":"function","function":{
      "name":"read_file",
      "description":"Read a file",
      "parameters":{"type":"object","required":["filepath"],
        "properties":{"filepath":{"type":"string"}}}}}
  ]
}
Response:
  message.tool_calls = [
    {"function":{"name":"read_file","arguments":{"filepath":"fileB.cs"}}}
  ]   <-- correct: proceeds to the next file

The ONLY difference between the two requests is the presence of `tools`.
In agent mode the follow-up turn's last message is role `tool`, so the provider's
guard `ollamaMessages.at(-1)?.role === "user"` is false and `tools` is dropped,
producing CASE 1. Removing that role check produces CASE 2 on every turn.

Continue 2.0.0 (VS Code, win32-x64); Ollama 0.34.0; Windows 11.

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 at extension.js around line 524024 and inspect the Ollama provider's chat-args builder, especially how it handles the final message role. Reproduce the issue with a task requiring two sequential tool calls and compare requests after the first tool result. Done means the follow-up request retains the tool schema and the agent proceeds to the second call.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.