Mimir: introduce AI companion plugin - #164
Conversation
Mimir is an AI companion for Noctalia — an LLM-powered chat interface with model selection, conversation history, and a bar widget. - Service-based architecture: service (brain) handles HTTP API calls, panel (chat) renders the UI, widget (status) shows bar indicator - OpenAI-compatible chat completions with dynamic model discovery - Floating side panel (center_right) with message history and simple markdown rendering (code blocks) - Model selection dropdown populated from API /models endpoint - Bar widget with brain icon to toggle chat panel - i18n via translations/en.json - Auto-detection of OpenCode Go API key from auth.json - Full-height floating panel layout matching oficial notes plugin .gitignore: add editor files, OS junk, auth secrets, compiled binary
…E with plans - plugin.toml: author leo -> Alexander, widget panel-toggle id -> alexander/mimir - widget.luau: togglePanel id -> alexander/mimir:chat - panel.luau: remove scrollBottom/dynamic key (unstable), remove setUpdateInterval - README.md: add future plans (commands, file search, etc.) - thumbnail.webp: removed (replaced by mimir-thumbnail.webp)
When api_key is empty, loadApiKey unconditionally reads the OpenCode Go credential from ~/.local/share/opencode/auth.json. A user who selects another OpenAI-compatible provider and leaves api_key empty can disclose their OpenCode Go credential to that provider. Auto-detection must be restricted to the matching OpenCode origin, or stored credentials must never be reused across configured origins.
Chat requests are rejected whenever no API key or auto-detected OpenCode credential exists. This contradicts the documented support for unauthenticated local servers at mimir/README.md:22 and mimir/README.md:87, including Ollama. Users without an OpenCode credential cannot use the advertised local, no-key configuration. Allow requests without Authorization when api_key is empty.
The catalog description says the plugin helps with terminal commands and file operations, but the current implementation only provides LLM chat. mimir/README.md:122 explicitly lists command execution, file search, and editing as future work. The manifest therefore advertises capabilities the submitted plugin does not provide. Update the description to describe the current chat functionality.
The input watcher records the current user message at mimir/service.luau:111 before calling think. think then copies that Every chat request sends the newest user prompt twice, which can alter responses and consume extra tokens. Append the message only once.
max_history is declared and documented, but service.luau never reads the setting or trims M.conversation. Long sessions therefore grow the transmitted context without bound, and changing the setting has no effect. Apply the configured limit before building and publishing conversation history. |
|
Isnt it better to connect it to hermes instead of openai? |
tryed to do something like that with open code but I couldn't any way , I finshed makeing the tool call system anyway |
|
second , I want it capable but simple hermes take 40k to 90K token just to call tools |
|
I updated version to 0.3.0 add tool calling now it can search files and run terminal commands |
|
@Ahmed5Emad Would it be possible to keep each PR specifically to one plugin instead of two? You've also added the game-launcher changes in this PR. |
fixed sorry |
The prior credential-origin finding is not fully resolved. Auto-detection now trusts any configured endpoint containing the substring "opencode" at mimir/service.luau:37, then sends the detected OpenCode Go credential to that endpoint at mimir/service.luau:131. An unrelated or attacker-controlled host whose URL contains "opencode" still receives the credential. Parse the endpoint and require the exact trusted OpenCode scheme, host, and port before reading the auth file.
The command blocklist checks only the first whitespace-delimited token, while noctalia.runAsync executes the complete string through /bin/sh -c, as confirmed at ../noctalia-shell/src/scripting/luau_host.cpp:1866. Simple destructive commands such as rm are not in the default list, and blocked commands can be bypassed using shell composition, an absolute executable path, env, sh -c, or another interpreter. In allow mode, mimir/service.luau:240 executes these model-supplied commands without confirmation. A compromised or incorrect API response can therefore delete files, read credentials, or upload data despite the documented blocklist. Raw shell commands should remain subject to per-command approval, or be replaced with narrowly scoped, structured, allowlisted operations. The current token blocklist is not a security
The README says commands can be edited before approval, but the approval UI renders each command as a label and only exposes Approve or Deny. mimir/panel.luau:279 sends only a boolean, and mimir/service.luau:314 executes the original model-provided command. Either implement the documented editable command field and pass the edited value to the service, or remove the editing claims from mimir/README.md:24, mimir/README.md:46, and mimir/README.md:69.
The documented copy button does not copy message content to the clipboard. It toggles a focused multiline input containing the message at mimir/panel.luau:191, leaving the user to copy it manually. Implement clipboard copying or describe this as exposing selectable text rather than copy-to-clipboard functionality. |
|
for number 3 sorry , I removed this and forgot to edit it (will be fixed) |
|
that should be working , add much more restricted defaults , anyway sorry for security issues , usually I use plugins for myself so I don't usually check for security 😅😅 |
Plugin
alexander/mimirWhat it does
AI companion for Noctalia — LLM-powered chat in a side panel. Type questions, get answers with basic markdown rendering (code blocks in shaded boxes). Switch models on the fly, auto-discovers models from the API.
Future
Designed for future tool-use (terminal commands, file search, code editing).
External dependencies
None. Communicates with any OpenAI-compatible HTTP API. Default endpoint is OpenCode Go (
opencode.ai/zen/go/v1). API key is user-configured in settings or auto-detected from~/.local/share/opencode/auth.json.Testing
Clicked the brain bar widget — opens/closes the panel.
Typed messages, received streaming-style replies.
Refreshed model list, switched between models.
Cleared conversation history.
Toggled panel via IPC:
noctalia msg panel-toggle alexander/mimir:chatTested with both OpenCode Go API and empty endpoint (graceful error).
Tested on Niri
Tested on Hyprland
Tested on Sway
Noctalia version tested against: 5.0.0 beta 6
Plugin API level: 16
note: tested only with opencode go api , sorry don't have 5 AI supscriptions
Screenshots / Videos
Checklist
mimir) matchesidafter/(alexander/mimir).plugin.toml,README.md,thumbnail.webp, andtranslations/en.json.README.mdfollows the README template, documents every entry id and dependency, and includes the exact IPC command.thumbnail.webpwith the thumbnail generator.0.1.0follows semver;plugin_apiis16.catalog.toml.Code review attestation
POST /chat/completions,GET /models) and filesystem read (auth.json) is accounted for.