Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions llamanager/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 marccvictoria

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
93 changes: 93 additions & 0 deletions llamanager/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Llamanager

> **A Noctalia v5 plugin for managing local Ollama models, Modelfiles, and runtime state.**

Llamanager provides a graphical frontend for [Ollama](https://ollama.com/) inside Noctalia. It wraps the Ollama CLI and HTTP API into a single panel, and allows model management, runtime inspection, model downloads, Modelfile editing, and launcher integration without requiring direct terminal interaction.

## Demo

![Launcher](assets/launcher.gif)
![Panel](assets/panel.gif)

## Plugin

| Field | Value |
| --------------- | ---------------------------------------------------------------------------------------- |
| ID | `marccvictoria/llamanager` |
| Entries | bar widget: `widget`; service: `registry`; launcher_provider: `launcher`; panel: `panel` |
| Launcher Prefix | `/ll` |

## Usage

Before using Llamanager, complete the following setup steps:

1. Install Ollama and ensure it is available on your `PATH`. See [Requirements](#requirements).
2. Open the plugin settings and configure:
- the Modelfile directory
- the preferred AI model used by the launcher
3. Add the Llamanager widget to your Noctalia bar.

## Requirements

- **Noctalia v5**
- `ollama` available on your `PATH`: required for model management, downloads, launching models, and Modelfile operations.

Verify the installation:

```bash
ollama --version
```

## Settings

| Setting | Type | Description |
| ---------------- | -------- | ------------------------------------- |
| `modelfile_path` | `folder` | Directory containing user Modelfiles. |
| `launcher` | `string` | Model used by the launcher. |

## Implementation

### Panel

`panel.luau` renders whichever view is currently active. User interactions dispatch commands through `llamanager.nextCommand`; the service performs the requested operation, updates state, and the panel re-renders.

`registry.luau` is the headless service responsible for interacting with Ollama. Filesystem operation, CLI invocation, and HTTP request originates here. It discovers installed models through `ollama list`, queries runtime information from the Ollama HTTP API, manages Modelfiles on disk, downloads models through `/api/pull`, and executes `ollama create` and `ollama rm` when building or deleting models.

**Model List**. The list displays every model currently installed in Ollama. To launch a model, select it from the model selector and click the launch button. This executes `ollama run <model>` and opens an interactive session in a new terminal window.

**Model Downloader**. Downloads models directly through Ollama's HTTP API. Downloads execute using the streaming `/api/pull` endpoint and automatically refresh the model library after completion.

**Modelfile Editor**. Modelfiles are ordinary text files stored inside the configured Modelfile directory, with the suffix `.modelfile`.

- **Load into Ollama**. Builds the modelfile into an ollama model by executing ollama create.
- **Delete model/modelfile**. Deleting a modelfile also deletes the model in ollama using `ollama rm`. In case the modelfile has not been loaded yet to ollama, it will only delete the modelfile. When deleting a model, it is recommended to include their tag, e.g. `qwen3:latest`.
- **Create Modelfile**. Creating a Modelfile requires the Name field to be populated. This only creates the Modelfile on the directory and does not register it with Ollama. To make the model available in Ollama, use _Load into Ollama_ after creating or editing the Modelfile.
- **Edit Modelfile**. Editing a Modelfile also requires the Name field to be populated. Saving changes only updates the Modelfile on the directory; it does not update the existing Ollama model. After modifying the Modelfile, use _Load into Ollama_ to rebuild and apply the changes.

**Runtime Dashboard**

Queries `http://localhost:11434/api/ps` and displays:

- Running models
- Parameter size
- Quantization level
- Context length
- Expiration time
- Ollama version
- API connectivity

### Launcher

The launcher entry `llamanger.luau` is independent from the panel. Queries submitted through `/ll` execute the configured model directly with `ollama run`.

The launcher provides quick model execution through `/ll <question> //`. Append `//` to send, the model response can be seen through notification and can be copied in your clipboard by pressing Enter key.

## IPC

```
noctalia msg panel-toggle marccvictoria/llamanager:panel
```

## License

[MIT](LICENSE)
Binary file added llamanager/assets/launcher.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added llamanager/assets/panel.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
79 changes: 79 additions & 0 deletions llamanager/llamanager.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
function onQuery(text)
if text == "" then
launcher.setResults(text, {
{
id = "hint",
title = "Ask Ollama anything",
subtitle = "Finish with // to send",
glyph = "brain",
}
})
return
end

if not text:match("%s//%s*$") then
launcher.setResults(text, {
{
id = "waiting",
title = text,
subtitle = "Append // to send",
glyph = "keyboard",
}
})
return
end

local prompt = text:gsub("%s//%s*$", "")

launcher.setResults(text, {
{
id = "loading",
title = "Thinking...",
subtitle = prompt,
glyph = "loader",
}
})

local request = {
url = "http://localhost:11434/api/generate",
method = "POST",
headers = {
"Content-Type: application/json",
},
body = noctalia.json.encode({
model = noctalia.getConfig("launcher"),
prompt = prompt,
stream = false,
think = false,
}),
}

noctalia.http(request, function(response)
if not (response.ok and response.status == 200) then
launcher.setResults(text, {
{
id = "error",
title = "Ollama request failed",
subtitle = response.body or ("HTTP " .. tostring(response.status)),
glyph = "alert-circle",
}
})
return
end

local data = noctalia.json.decode(response.body)
noctalia.notify("LLamanager", data.response)
launcher.setResults(text, {
{
id = data.response,
title = data.response,
subtitle = "Press Enter to copy",
glyph = "brain",
}
})
end)
end

function onActivate(id)
noctalia.copyToClipboard(id, "text/plain")
end
Loading