Skip to content

Add Ollama provider support for local model inference#9386

Open
simpletoolsindia wants to merge 2 commits intowarpdotdev:masterfrom
simpletoolsindia:feature/ollama-provider
Open

Add Ollama provider support for local model inference#9386
simpletoolsindia wants to merge 2 commits intowarpdotdev:masterfrom
simpletoolsindia:feature/ollama-provider

Conversation

@simpletoolsindia
Copy link
Copy Markdown

Summary

  • Add Ollama variant to LLMProvider enum
  • Add ollama_url field to ApiKeys for BYOK (Bring Your Own Key) configuration
  • Create ollama_client module with chat and streaming support
  • Add reqwest dependency for HTTP client

Motivation

This enables Warp to use locally-hosted Ollama models, providing:

  • Offline AI features
  • User control over their own models
  • Privacy-preserving local inference

Technical Details

Ollama provides a REST API at localhost:11434 that supports both streaming and non-streaming chat completions.

API Endpoints Used

  • GET /api/tags - List available models
  • POST /api/chat - Chat completions (with streaming support)

Test Plan

  • cargo check -p ai passes
  • cargo test -p ai -- ollama passes
  • Manual testing with Ollama server running

TODO

  • Add Ollama icon to the icon system
  • Add UI for configuring Ollama URL in settings
  • Wire up actual model selection for agent mode

🤖 Generated with Claude Code

This adds client-side support for using Ollama as a local LLM provider,
enabling offline AI features and giving users control over their models.

Changes:
- Add Ollama variant to LLMProvider enum
- Add ollama_url field to ApiKeys for BYOK configuration
- Create ollama_client module with chat and streaming support
- Add reqwest dependency for HTTP client

Ollama provides a simple REST API at localhost:11434 that supports
both streaming and non-streaming chat completions.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented Apr 29, 2026

Thank you for your pull request and welcome to our community. We could not parse the GitHub identity of the following contributors: Sridhar Karuppusamy.
This is most likely caused by a git client misconfiguration; please make sure to:

  1. check if your git client is configured with an email to sign commits git config --list | grep email
  2. If not, set it up using git config --global user.email email@example.com
  3. Make sure that the git commit email is configured in your GitHub account settings, see https://github.com/settings/emails

@oz-for-oss
Copy link
Copy Markdown

oz-for-oss Bot commented Apr 29, 2026

@simpletoolsindia

I'm starting a first review of this pull request.

You can view the conversation on Warp.

I requested changes on this pull request and posted feedback.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This PR adds an Ollama provider enum variant, persists an Ollama URL with BYOK settings, and introduces a new Ollama HTTP client.

Concerns

  • The changes currently appear to break compilation in multiple places: the generated multi-agent API settings type is initialized with a new field that this PR does not add to the generated dependency, and the new Ollama client uses anyhow::Context in functions returning OllamaResult.
  • The streaming response handling does not correctly deserialize Ollama's boolean done field and treats arbitrary byte chunks as complete newline-delimited JSON records, so streaming would fail or drop/corrupt chunks.
  • Security pass: sending a user-configured local Ollama URL through remote request settings would leak local endpoint configuration and would not provide local inference semantics; Ollama calls should remain client-side unless a dedicated trusted routing design exists.

Verdict

Found: 2 critical, 2 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Comment thread crates/ai/src/api_keys.rs Outdated
openai,
google,
open_router,
ollama_url,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [CRITICAL] This initializes the generated warp_multi_agent_api::request::settings::ApiKeys with ollama_url, but this PR does not update that generated type, so cargo check -p ai will fail; additionally, local Ollama URLs should not be sent through remote request settings.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Removed ollama_url from api_keys_for_request() since local Ollama endpoints should never be sent through remote request settings.

Comment thread crates/ai/src/ollama_client.rs Outdated
.get(format!("{}/api/tags", self.base_url))
.send()
.await
.context("Failed to send request to Ollama")?;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [CRITICAL] context(...) converts the error into anyhow::Error, but this function returns OllamaResult, so ? cannot convert it to OllamaError; map the reqwest::Error directly instead, including the same pattern below.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Removed and changed to use directly which properly converts to via the trait.

Comment thread crates/ai/src/ollama_client.rs Outdated

/// A streaming chunk from Ollama's chat API.
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "done")]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] Ollama sends done as a boolean, but an internally tagged enum expects the tag to match a variant identifier, so serde_json::from_str will reject \"done\": false; use an untagged enum or a struct with done: bool.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Changed StreamChunk to use a helper struct that deserializes done as a boolean field and then converts to the appropriate enum variant.

)));
}

let stream = response.bytes_stream().map(|chunk_result| {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] bytes_stream() chunks are not NDJSON record boundaries, so this drops additional lines, misparses split JSON objects, and emits fake empty chunks; buffer until newline boundaries and yield each parsed record.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Rewrote the streaming parser to buffer characters and only parse complete lines delimited by newlines, ensuring proper NDJSON parsing.

- Remove ollama_url from api_keys_for_request() since local endpoints
  should not be sent through remote request settings
- Fix StreamChunk to use untagged deserialization with a helper struct
  since Ollama sends done as a boolean, not a variant tag
- Fix error handling in list_models and chat to map reqwest errors
  directly instead of using anyhow::Context
- Fix chat_streaming to properly buffer by newline boundaries
  instead of using bytes_stream() which splits chunks incorrectly

Co-Authored-By: Claude <noreply@anthropic.com>
@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented Apr 29, 2026

Thank you for your pull request and welcome to our community. We could not parse the GitHub identity of the following contributors: Sridhar Karuppusamy.
This is most likely caused by a git client misconfiguration; please make sure to:

  1. check if your git client is configured with an email to sign commits git config --list | grep email
  2. If not, set it up using git config --global user.email email@example.com
  3. Make sure that the git commit email is configured in your GitHub account settings, see https://github.com/settings/emails

@oz-for-oss
Copy link
Copy Markdown

oz-for-oss Bot commented Apr 29, 2026

@simpletoolsindia

I'm checking this implementation PR for association with a likely matching ready issue.

Powered by Oz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant