Skip to content

Latest commit

 

History

43 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ollie.nvim

Ollie.nvim is an open-source, AI self-host backend Neovim plugin that integrates large language models into the editor through a modular routing and provider system.

It supports both local inference engines and remote APIs, enabling privacy-first and extensible AI workflows.

The architecture separates UI, request handling, and model providers, allowing developers to extend or replace backend engines without modifying core logic.

Media

Features

  • Structured handlers — Discrete commands for explanation, debugging, fixing, and many more coming soon. Each handler owns its context and prompt logic independently.
  • Streaming responses — Streaming incremental responses. No waiting for full completions.
  • Async job architecture — All I/O runs off the main thread via Neovim's vim.loop / vim.jobstart. The editor never blocks.
  • Buffer context management — Smart context assembly from the active buffer, visual selection, LSP diagnostics, and file metadata.
  • Health system — Built-in :checkhealth ollie covering hardware capability, internet reachability, model availability, and Ollama process status.
  • Security layer — Permission model, policy enforcement, and trust management for sensitive operations.
  • Selector abstraction — Picker-agnostic model and provider selection. Works with telescope.nvim, fzf-lua, vim.ui.select, or custom frontends.
  • Multi-provider support — You can add providers such as Anthropic (Claude API), OpenAI (Cloud API), Google (Cloud), Ollama (local inference). Switch providers per task. For building multi-provider support, check #Providers on doucmentation.md

Sending the query

Dashboard


Personal Assistant Architecture

┌─────────────────────────────────────────────┐
│                 UI Layer                    │                       
├─────────────────────────────────────────────┤
│              Command Layer                  │
├─────────────────────────────────────────────┤
│              Handler Layer                  │ 
├─────────────────────────────────────────────┤
|               Core router                   |
├─────────────────────────────────────────────┤
│             Provider Layer                  │
├─────────────────────────────────────────────┤
|              Stream Engine                  |
├─────────────────────────────────────────────┤
│              Core System                    |
│  ┌──────────────────┬──┬──────────────────┐ │
│  │ Context Manager  |  │ Session Manager  │ │
│  │ - buffer context |  │  - chat history  │ │
│  │ - selection      |  │  - persistence   │ │ 
│  └──────────────────┴──┴──────────────────┘ │
├─────────────────────────────────────────────┤
│               Async Job Layer               │
└─────────────────────────────────────────────┘

Default model is avexcoder_3b:latest from ollama alias. It is designed around a clean separation of concerns: providers handle model communication, security, permissions, handlers define task semantics, and the UI layer stays thin and replaceable. The goal is a plugin you can trust, extend, and run entirely on low-end till high-end devices. Its router dispatches requests asynchronously across providers and experimental hardware-aware routing — so you run the best model your environment can actually support.

NOTE: Run pkill ollama after exiting neovim.


ollie.nvim
├── providers/        # API clients for each LLM backend (cloud, local)
├── handler/          # Task logic: explain, and fix
├── core/             # Execution backend
├── parser/           # Response formatter
├── ui/               # Panel and floating window rendering
├── system/           # Boundaries and hardware-layer health verification
├── commands/         # User-facing command definitions

Design principles:

  • Providers are stateless adapters. They translate requests to API shapes and return a stream or a string. They know nothing about Neovim buffers.
  • Handlers are stateless functions. They assemble context, call a provider via the router, and write output. They know nothing about which provider is active.
  • The router is the only component that knows both sides. Swapping a provider never touches handler code.
  • The UI layer is purely presentational. It receives text and renders it. No business logic lives there.
  • The health system is a first-class citizen, not an afterthought. If something is misconfigured, :checkhealth should tell you exactly what and why.

Installation

Requirements:

  1. Neovim >= 0.10
  2. curl (for HTTP providers)

lazy.nvim

return {
  "avexcz/ollie.nvim",
  dependencies = {
    "nvim-lua/plenary.nvim",
    -- optional, for selector layer
    "nvim-telescope/telescope.nvim",
  },
  opts = {},
}

packer.nvim

return {
  "avexcz/ollie.nvim",
  requires = { "nvim-lua/plenary.nvim" },
  config = function()
    require("ollie").setup({})
  end
}

Configuration in Lazy.nvim

  return {
    "avexcz/ollie.nvim",
    lazy = false,
    event = "VimEnter",
    dependencies = { "nvim-lua/plenary.nvim" },
    config = function()
      require("ollie").setup({
        default_provider = "ollama",
        default_model = "qwen2.5-coder:1.5b",
        streaming = true,
      })
    end



  }

Model Setup

Requirements:

  1. Ollama installed
  2. Terminal

Ollie works with any Ollama-compatible model. If you don't have any model installed. Here is the setup.

Lightweight Option (Recommended for Most Users)

Install Qwen 2.5 Coder 1.5B or 0.5b:

ollama pull qwen2.5-coder:1.5b

After installation, make sure Ollama is running:

ollama serve

You can verify that the model is available:

ollama list

Then configure Ollie in your init.lua:

require("ollie").setup({
    default_provider = "ollama",
    default_model = "qwen2.5-coder:1.5b",
    streaming = true,
})

Using custom model alias

If you prefer to use custom model instead, for better coding performance. Make sure models are installed on your local machine. For example, here are practical steps to be done.

Install any model:

ollama pull qwen2.5-coder:3b

Create the Ollie model:

git clone https://github.com/avexcz/ollie.nvim
cd ollie.nvim/Modelfile

ollama create avexcoder_3b -f usernamecoder_3b

or simpler:

touch Modelfile

Configure your modelfile:

FROM qwen2.5-coder:3b

PARAMETER temperature 1
PARAMETER num_ctx 8192

SYSTEM """
You are Ollie, an AI coding assistant for Neovim.

<your idea here>

"""

Verify the installation and custom modelfile:

ollama list

You should see usernamecoder_3b:latest.

Then ollie configuration setup would be:

require("ollie").setup({

    default_provider = "ollama",
    default_model = "usernamecoder_3b", -- changeable
    streaming = true,
})

Or test/temporary run:

:OllieModel avexcoder_3b:latest

For more info check:


vim commands

Command Description
Ollie Open the dashboard
:OllieChat Open the chat interface with the active provider and model
:OllieChatContext Send the whole buffer and open the chat interface with the active provider and model
:OllieFix Diagnose and apply a fix for the current error via selection
OllieExplain Discuss the matter and provide details based on user query via selection
:OllieModel Switch the active model via selector
:OllieProvider Switch the active provider via selector
:OllieSessions Browse and resume previous sessions
OllieSessionDelete Delete single conversation history
OllieSessionClear Clear entire conversation history
:OllieHealth Validate providers, credentials, hardware health, recommanded model and dependencies

If struggling with long commands, try setting up keymaps.

local input = require("ollie.ui.behaviour.input")
local selection = require("ollie.content.selection")
local ollie_fix = require("ollie.handler.fix.init")
local ollie_explain = require("ollie.handler.explain.init")

keymap.set("v", "<leader>o", "<cmd>Ollie<cr>",                { desc = "Ollie"}) -- dashboard
keymap.set("v", "<leader>oc", "<cmd>OllieChat<cr>",           { desc = "Ollie"}) -- Chat
keymap.set("v", "<leader>O", "<cmd>OllieChatContext<cr>",     { desc = "Ollie"}) -- Chat with full context
keymap.set("x", "<leader>of", function()                                         -- OllieFix
  local selected, span = selection.get_selected_code()

     input.ask({ preview = selected }, function(query)
        ollie_fix.run_fix(query, selected, span, {})
    end)
end, { desc = "Ollie" })

keymap.set("v", "<leader>oe", function()                                         -- OllieExplain
  local selected, span = selection.get_selected_code()

    input.ask({ preview = selected }, function(query)
        ollie_explain.run_explain(query, selected, span, {})
    end)
end, { desc = "Ollie" })



Contributing

Contributions are welcome. Before opening a PR, please read the following.


Project conventions:

  • Lua files follow the existing module structure. New functionality belongs in an appropriate layer — provider logic in providers/, user-facing operations in handler/, rendering in ui/.
  • No business logic in the UI layer. No Neovim API calls in providers.
  • All async operations use vim.loop or vim.system. No blocking I/O on the main thread.
  • New providers must implement the provider interface defined in providers/init.lua.
  • New handlers must be reachable via the router and must not hardcode a provider.


For contributing, please see Contribution for contributing guidance.


Guidance

See documentation for more info.
See configuration for configuration.
See List of commands for understanding how to use commands.

Built for Neovim. Runs anywhere, is a Lua runtime and an HTTP connection (or local model), that can reach.

About

Neovim AI assistant powered by local Ollama models with privacy-first design.

Topics

Resources

Contributing

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages