continuedev / continuedev/continue
Ollama provider drops `tools` after the first tool call, breaking multi-step agent loops
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
- I've tried finding an answer on the Continue docs site
- I'm not able to find an open issue that reports the same bug
- I've seen the troubleshooting guide on the Continue Docs
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
- Configure any tool-capable Ollama model in agent mode.
- Give it a task requiring 2+ sequential tool calls (e.g. "read file A, then read file B").
- Observe: it calls the tool for A, receives the result, then emits text like
- "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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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