Ollama provider drops `tools` after the first tool call, breaking multi-step agent loops
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
- Domain
- ai, backend-api-design
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.
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.
- Dominant language
- TypeScript
- Stars
- 36k
- Forks
- 5.4k
- PR merge metrics
- No merged PRs in 30d
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.
More from continuedev/continue
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
continuedev/continue#13291 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
continuedev/continue#13233 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 85/100
continuedev/continue#13198 · 1 comment ·
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
continuedev/continue#13197 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
continuedev/continue#13185 · 9 comments · 3 reactions ·
All issues in continuedev/continue
Similar issues
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 91/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 95/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Automattic/studio#4908 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100