Created: 2026-09-10 Thu 12:16
We are looking for local agents to support our development. We need to create a simple system to make sure:
AI is a crucial component of product life-cycle. I use AI only for things I can test myself and I avoid using it in a chat. AI should be integrated in project files which will serve as documentation and make the product reproducible.
Agents support with multiple tasks but can get quickly out of control. The setting we build here has the following features:
Following is a visual representation of the differences between two extremes:
v The estimate comes from the following considerations:
| conf | consistency | control | privacy | proficiency | integration | overview | versatility |
|---|---|---|---|---|---|---|---|
| vibe+public | 3.7 | 2.5 | 0.5 | 5.0 | 3.7 | 2.7 | 2.5 |
| emacs@local | 4.7 | 4.9 | 5.0 | 3.7 | 4.8 | 4.8 | 5.0 |
Single tools can improve some features but make other less effective:
Figure 1: Evaluation of local vs cloud alternatives
Contribution of single tools
| conf | consistency | control | safety | boost | integration | overview | enhancement |
|---|---|---|---|---|---|---|---|
| +gptel | 0 | -0.2 | -0.2 | 0.4 | 0.3 | 0.8 | 0.2 |
| +ellama | 0 | -0.2 | -0.2 | 0.3 | 0.2 | 0.3 | 0.3 |
| +mcp | 0 | -0.2 | -0.2 | 0.2 | 1.0 | 0 | 0.5 |
| +org | 1.0 | 0.3 | 0 | 0.4 | 0.4 | 1.0 | 0.4 |
| +repl | 1.0 | 0.3 | 0 | 0.2 | 0.7 | 0.3 | 0.6 |
| +pi-code | 0 | -0.5 | -0.4 | 0.5 | 0.2 | -0.2 | 0.3 |
Figure 2: Contribution of the single tools to the project
quadrantChart
title implementation benefits
x-axis Low help --> High assistance
y-axis Low control --> High ownership
quadrant-1 control and productivity
quadrant-2 control but useless
quadrant-3 unpredictable
quadrant-4 high costs/low ownership
current setup: [0.6, 0.7]
public models: [0.9, 0.23]
no coding agent: [0.30, 0.69]
no docker: [0.6, 0.34]
no .org file: [0.40, 0.34]
Figure 3: Quadrant representation of the project and its goals
Agents can fulfill many tasks. The work has shifted from the paradigm of executing tasks (and often not document them) to document first what you want to do and plan (or let plan) the agents to execute. The most important task is to test and quality check the results which means to own the pipeline and put enough logs and monitoring tools to allow traceability (know what agent did what).
We need an interface which is usually an IDE or a terminal to plan and orchestrate everything.
Here the choice is:
Here is a sketch of the project
---
title: implementation sketch
---
flowchart LR
KN["`
script
knowledge
agenda
links
tasks
`"]
DOC@{ shape: docs, label: "Knowledge"}
MC@{ shape: procs, label: "mcp server"}
DT@{ shape: lin-cyl, label: "storage" }
EL@{ shape: notch-pent, label: "ellama" }
GP@{ shape: notch-pent, label: "gptel" }
PI@{ img: "/home/sabeiro/lav/src/spiega/icon/dev.svg", label: "pi-coding", pos: "c", w: 60, h: 60, constraint: "off" }
%%A@{ icon: "fa:user", form: "square", label: "User Icon", pos: "t", h: 60 }
E(emacs) --> GP
E --> EL
E -- ask --> EL
EL -- connect --> OL[\ollama\]
OL -- answer --> EL
EL -- insert --> E
GP -- connects --> MC
MC -- summarize --> DOC
GP -- decide --> JT[\vllm\]
JT -- elaborate --> GP
GP -- insert --> E
E -- debug --> PI
PI -- write --> DT
PI -- edit --> E
E -- edit --> OR[org-file]
OR -- contain --> KN
Figure 4: diagram of the implementation
The documentation is generated inside this
A brief representation of the implementation plan
graph LR A[emacs] --> B[gptel] A[emacs] --> C[ellama]
Code for generating the documentation.
Here we explore different options to deploy local models, the only common denominator is docker because we want to control what those models can access and reduce context. Many services have docker options but the pre-built images are difficult to integrate in our workflow and the proposed images are heavy and hard to tune. To find a performant solution we decided to start from a “yeast” image following simple principles:
The build time takes 10min to 1h so we really need to separate the static components from the dynamic one. We want to standardize the process because unfortunately every service has its own: folder structure, endpoints, configuration files, ports, enviroment… Here I force all the different project to be reachable from the host in a similar way to avoid re-writing patches and integration tools. Additionally part of the hardware we use runs on ARM so we need to build our own images.
The “yeast” start from a ubuntu image and installs basic libraries
FROM ubuntu:latestRUN apt-get update && apt-get install -y localesRUN apt install -y curl libatomic1 python3-pip bash git#&& rm -rf /var/lib/apt/lists/*#RUN localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8ENV LANG en_US.utf8
We copy the app files into the container
COPY ./app /appRUN chmod +x /app/run.shWORKDIR /app
We need then to allow the container user to edit the files keeping the same permission as the host user to allow coding assistants to edit the files keeping the same consistency. Unfortunately this step is not easy in docker for reasons I don’t understand but I found a workaround ref1.
ARG UID=1000ARG GID=1000RUN usermod -l $USER ubuntuRUN usermod -aG ubuntu $USERRUN usermod -aG $USER $USERRUN usermod -d /home/$USER/ $USERRUN usermod -s /bin/bash $USERRUN groupadd $USER
We grant sudo and no password:
RUN passwd --delete sabeiroRUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoersRUN adduser sabeiro sudoRUN mkdir -p /home/sabeiro/ && chown -R ${UID}:${GID} /home/sabeiro/USER sabeiroRUN sudo ls
We need to add to docker-compose.yml to mount the volume as non-root
user: "${UID}:${GID}"
On top of this image we install some applications
RUN curl -fsSL https://openclaw.ai/install.sh | bash -s -- --no-prompt --no-onboardRUN curl -fsSL https://pi.dev/install.sh | bash -s -- --no-prompt --no-onboardRUN curl -fsSL https://opencode.ai/install | bash -s -- --no-prompt --no-onboardRUN curl -LsSf https://aider.chat/install.sh | bash -s --RUN curl -fsSL https://unsloth.ai/install.sh | sh
And we build the image
docker compose up --build
We then test the configuration using bash inside the container
docker compose exec -it ubuntu bash
Docker compose here starts the container built in the previous step
services:ubuntu_base:build:context: ./dockerfile: Dockerfilecontainer_name: ubuntu_basedeploy:resources:reservations:devices:- driver: nvidiacount: allcapabilities: [gpu]runtime: "nvidia"ports:- "8083:8083"restart: unless-stoppedstdin_open: truetty: trueworking_dir: /app/entrypoint: ["bash","/app/run.sh"]healthcheck:test: ["CMD", "cat", "/app/run.sh"]interval: 30stimeout: 30sretries: 3volumes:- ${HOME}/Downloads/llm_model/:${HOME}/models/- ${HOME}/lav/src/:${HOME}/lav/src/- ${HOME}/log/ubuntu/:/var/log/- ./app/:/app/- /var/run/docker.sock:/var/run/docker.socknetworks:- webserver-netnetworks:webserver-net:name: webserver_webserver-netdriver: bridgeexternal: true
Network and webserver are on a separate container
services:nginx:container_name: nginxbuild:context: nginx/restart: unless-stoppedtty: truecpus: 0.2environment:SERVICE_NAME: appSERVICE_TAGS: devvolumes:- ./nginx/conf.d:/etc/nginx/conf.d- ${HOME}/lav/siti:/var/www/html/- ${HOME}/log:/var/log/ports:- "80:80"- "443:443"networks:- webserver-net
We use GPUs in this project
deploy:resources:reservations:devices:- driver: nvidiacount: allcapabilities: [gpu]runtime: "nvidia"
We can as well limit RAM and CPU resources which we tune restarting the containers.
Volumes are managed by docker-compose, we use a standard structure:
We use a webserver-net network to connect the different containers. This network is managed from the nginx container. To let the host and the container to communicate we could use socat.
services:blender-mcp-bridge:image: alpine/socat:latestcontainer_name: blender-mcp-bridgenetwork_mode: "host"command: TCP-LISTEN:9192,fork,reuseaddr TCP:127.0.0.1:9191restart: unless-stoppedlemonade-mcp-bridge:image: alpine/socat:latestcontainer_name: lemonade-mcp-bridgenetwork_mode: "host"command: TCP-LISTEN:13306,fork,reuseaddr TCP:127.0.0.1:13305restart: unless-stopped
To allow the agents to work on the host system we need different workarounds:
All the LLM services like ollama, llama.cpp, unsloth, lmstudio… have docker versions we can use but those implementations can be barely used outside of testing since the real added value of LLM is the combination with a coding assistant. Ollama is by far the most easy to integrate tool, their APIs are included in many packages and you can integrate
This is the but we want to deploy our local agents on other devices as well. Those are the main specs.
| Component | Specification |
|---|---|
| CPU | AMD Ryzen 7 260/7 (16 cores, 32 threads) |
| GPU | NVIDIA GeForce RTX 5060 (8GB GDDR6) |
| Driver | NVIDIA 595.71.05 |
| CUDA | CUDA 13.2 |
| RAM | 30GB DDR5 |
| iGPU | AMD Radeon 780M integrated |
| Storage | 1TB SSD / NVMe |
| OS | Ubuntu 22.04 LTS |
| NPU | 16 TOPS |
| Multi-GPU | Host has additional GPUs (if any) |
We have different backends to explore:
Generally the GPU is a better option for LLM but the CPU can access 32GB of memory.
To use the nvidia graphic cards I need to install many packages
From linuxvox.
sudo apt update && sudo apt upgrade
sudo mkdir --parents --mode=0755 /etc/apt/keyrings
wget https://repo.amd.com/rocm/packages-multi-arch/gpg/rocm.gpg -O - | \
gpg --dearmor | sudo tee /etc/apt/keyrings/amdrocm.gpg > /dev/null
sudo tee /etc/apt/sources.list.d/rocm.list << EOF
deb [arch=amd64 signed-by=/etc/apt/keyrings/amdrocm.gpg] https://repo.amd.com/rocm/packages-multi-arch/ubuntu2404 stable main
EOF
sudo apt update
sudo apt install rocm
sudo usermod -a -G render,video $LOGNAME
pip install torch torchvision --extra-index-url https://download.pytorch.org/whl/rocm7.2/
Nowadays laptops have NPU (neural processing units) but it is generally difficult to use them the same way they are used in cell phones. The recommended size for LLM application is 40 tops but I should be able to use my 16 tops for light tasks like autocompletion. The idea is to use fast flow lm with this implementation Let’s try to follow this guide and the official documentation. Need to download the drivers.
Ubuntu 26 has the package lemonade: run LLMs and Whisper on the AMD XDNA 2 NPU. This solution is made up of:
sudo apt update
sudo apt install python3.12 python3.12-venv libboost-filesystem1.74.0 dkms
sudo apt update && sudo apt install linux-oem-24.04c
cd /home/sabeiro/Elŝutujo
unzip RAI_1.8_Linux_NPU_XRT.zip
sudo apt install --fix-broken -y ./xrt_202620.2.25.37_24.04-amd64-base.deb
sudo apt install --fix-broken -y ./xrt_202620.2.25.37_24.04-amd64-base-dev.deb
sudo apt install --fix-broken -y ./xrt_202620.2.25.37_24.04-amd64-npu.deb
sudo apt install --fix-broken -y ./xrt_plugin.2.25.260102.56.release_24.04-amd64-amdxdna.deb
source /opt/xilinx/xrt/setup.sh
xrt-smi examine
Need to download ryzen ai.
cd /home/sabeiro/Elŝutujo
mkdir ryzen_ai-1.8.0
cp ryzen_ai-1.8.0.tgz ryzen_ai-1.8.0
cd ryzen_ai-1.8.0
tar -xvzf ryzen_ai-1.8.0.tgz
Dependencies for docker git clone https://github.com/hpenedones/fastflowlm-docker.git cd fastflowlm-docker docker build -t fastflowlm .
sudo add-apt-repository ppa:amd-team/xrt
sudo apt update && sudo apt install libxrt-npu2
# Set memlock to unlimited (needs reboot)
echo -e "* soft memlock unlimited\n* hard memlock unlimited" | sudo tee -a /etc/security/limits.conf
sudo reboot
git clone https://github.com/hpenedones/fastflowlm-docker.git
cd fastflowlm-docker
docker build -t fastflowlm .
Between ollama, llama.cpp, unsloth, vllm the best experience was with lemonade. Lemonade has a simple UI able to manage:
Now let’s test the configuration and check what performs at best. We have tested:
curl localhost:11434/api/tags | jq | grep \"model\" | awk -F " " '{print $2}'
| qwen3.5:9b | |
| qwen2.5-coder:7b | |
| qwen2.5-coder:3b |
Figure 6: ollama results
Performances are crucial for a real added value and we need to make sure the system is well-configured. Coding agents are not effective, they keep trying until tests pass so speed is crucial.
Based on the system monitoring, here are the findings:
Temporary fix:
sudo swapoff -a
Permanent fix: Add to `/etc/rc.local` or create `/etc/systemd/system/disable-swap.service`:
[Unit]
Description=Disable Swap for LLM Workloads
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'swapoff -a'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Reduce swappiness (optional):
sudo sysctl vm.swappiness=10
# Make permanent in /etc/sysctl.conf:
vm.swappiness=10
vm.vfs_cache_pressure=50
Find and kill the port 8888 server:
pkill -f "unsloth run.*port 8888"
# or
kill $(pgrep -f "unsloth run.*--port=8888")
Your GPU has 8 GB VRAM but Qwen3.5-9B needs more than that. Here’s the optimal configuration:
For Qwen3.5-9B-GGUF:
python unsloth run \
-H 127.0.0.1 \
-p 8889 \
--model unsloth/Qwen3.5-9B-GGUF \
--context-length 32768 \
--parallel 4 \
--max-batch-size 4 \
--flash-attn on \
-c 32768 \
-ngl -1 \
--kv-unified off \
--metrics
Key optimizations:
### Step 5: Monitor and Tune
Check performance metrics:
# Watch GPU usage
watch -n 1 nvidia-smi
# Check for swap activity
watch -n 1 "free -h && swapon --show"
# Monitor Unsloth server
curl http://localhost:8889/metrics | grep -E "tokens|time|iters"
Expected improvements:
### Step 6: Alternative - Use Ollama Instead
If Unsloth continues to be slow, consider switching to Ollama which is better optimized for single-GPU laptop setups:
# Stop Unsloth
pkill -f unsloth
# Start Ollama (already configured in your system)
ollama serve
# Pull quantized model (less VRAM usage)
ollama pull qwen3.5:9b
Ollama benefits:
### Quick Performance Checklist
[ ] Swap disabled CRITICAL[ ] Redundant servers stopped[ ] `–parallel` increased to match workload[ ] Batch size tuned for throughput[ ] Flash Attention enabled ✓[ ] Context length optimized ✓### Model Recommendations for Your Hardware
| Model | VRAM Need | Recommended | Performance |
|---|---|---|---|
| Qwen3.5:9B | ~8.5GB + RAM | ✅ Current choice | Good balance |
| Qwen2.5-coder:7B | ~6GB | ✅ Better option | Faster, good for code |
| Qwen3.6:latest | >12GB | ❌ Too slow | Hardware limit |
| CodeGemma:7B | ~6GB | ✅ Fastest | Great for coding |
Best recommendation: Switch to `qwen2.5-coder:7b` or `codegemma:7b` for 30% faster performance with same quality for coding tasks.
### Emergency Commands
# Stop all Unsloth instances
pkill -f unsloth
# Check current GPU memory usage
nvidia-smi --query-gpu=index,memory.used,memory.total --format=csv
# Restart with optimized settings
~/unsloth_optimized.sh &
# Force stop if frozen
sudo fuser -k 8889/tcp
# Monitor swap (should be empty)
watch -n 1 "free -h | grep Swap"
A few tools for project management using org and agents.
A Gantt representation of the project
---
displayMode: compact
title: Ignored if specified in chart
config:
gantt:
useWidth: 800
rightPadding: 0
topAxis: true #false
numberSectionStyles: 2
---
gantt
dateFormat <YYYY-MM-DD>
title Knowledge base action plan
excludes weekends
review : vert, v1, <2026-06-22>, 1d
section local models
deploy LLMs :done, deploy, <2026-05-20>, 7d
coding agent :done, deploy, <2026-05-27>, 14d
section list & summarize
parse knowledge :done, dev, <2026-06-01>, 5d
create graphs :done, dev, <2026-06-07>, 7d
section hierarchy
hierarchy :done, distil, <2026-06-16>, 9d
visualization :crit, distil, <2026-06-20>, 4d
section video
sceencast :active, create, <2026-06-12>, 5d
animate text :active, create, <2026-06-17>, 9d
section publish
content :active, share, <2026-06-22>, 10d
publication :milestone, share, <2026-06-27>, 5d
Figure 7: Gantt representation of the project
We can as well integrate our workflow into a Kanban
---
config:
kanban:
ticketBaseUrl: 'https://mermaidchart.atlassian.net/browse/#TICKET#'
---
kanban
Todo
[compare model serve]
docs[benchmark vllm, llama.cpp and ollama]
[In progress]
id6[blog posts about the local implementation ]
id9[Ready for deploy]
id8[cloud webdav]@{ assigned: 'bot1' }
id10[Ready for test]
id4[Create parsing tests]@{ ticket: MC-2038, assigned: 'K.Sveidqvist', priority: 'High' }
id66[last item]@{ priority: 'Very Low', assigned: 'knsv' }
id11[Done]
id5[agent confs, org files]
id2[local deployment]@{ ticket: MC-2036, priority: 'Very High'}
id3[graph integration]@{ ticket: MC-2037, assigned: bot1, priority: 'High' }
Figure 8: Gantt representation of the project
We can show sankey diagrams too
---
config:
sankey:
showValues: false
---
sankey
LLM cloud,LLM local,95
cursor,pi-coding,60
cursor,aider,20
cursor,open-code,20
Figure 9: Sankey representation of the project
We can present as well a timeline regarding the development of this project
timeline
title blender twin development
2025-12-12 : nvidia jetson CV application
2026-01-12 : camera controller with pose estimate
2026-02-12 : physics optimization engine in js
2026-03-12 : moving from cloud to local LLMs
2026-04-12 : new laptop to run local + jetson
2026-05-12 : .org files and productivity workflow
2026-06-12 : knowledge graph
Figure 10: Timeline
Architectural diagram for the project:
flowchart TD
subgraph Sensors ["IoT Sensor Layer"]
A[Temperature Sensors] -->|MQTT| B[Messaging Bus]
C[Humidity Sensors] -->|MQTT| B
D[Pressure Sensors] -->|MQTT| B
end
subgraph Processing ["Processing Layer"]
B -->|Ingest| E[Data Stream Processor]
E -->|Normalize| F[Time Series DB]
E -->|Transform| G[Feature Extractor]
G -->|Analyze| H[Anomaly Detector]
end
subgraph Intelligence ["Intelligence Layer"]
H -->|Alerts| I[Predictive ML Model]
I -->|Predictions| J[Decision Engine]
F -->|Historical Data| K[Knowledge Graph]
end
subgraph Visualization ["Visualization Layer"]
J -->|Commands| L[Control Actions]
K -->|Entity Relations| M[Graph Database]
E -->|State Updates| Q[3D WebGL Viewer]
Q -->|Render| R[Blender Scene]
end
subgraph Twin ["Digital Twin Model"]
R -->|Sync| V[Physics Simulation]
V -->|Thermal Analysis| W[Heat FEM Solver]
W -->|Results| Q
end
style Sensors fill:#e1f5fe
style Processing fill:#fff3e0
style Intelligence fill:#e8f5e9
style Visualization fill:#f3e5f5
style Twin fill:#ffe0b2
linkStyle default stroke:#333,stroke-width:2px
Figure 11: result of mermaid plot
Using mainly ollama (with llama cpp took a lot of time for configuration) to serve LLMs. Ollama has a nice interface for python which basically removed all my external dependencies from langchain and llamaindex (which keeps on changing APIs and packaging and my code needs to be re-written over and over). I currently manage to run:
We tested as well other LLM serving toos: The current LLM serving tools tested
The current coding assistant is on pi-agent while opencode, aider and cursor where also tested.
The current configuration uses pi-coding and the configuration is specified in:
Emacs is omnipresent in my developments . Emacs integrates bash commands with macros and program outputs, I can connect language models with mcp servers. I currently use emacs.el as current init file and gptel_tools.el for connecting with mcp. gptel_tools_allowed commands is an additional list of bash commands which the tool allows
Features:
The most efficient way to integrate LLMs into the workflow is having a integration with all the available tools.
sequenceDiagram
emacs-->ellama: prompt
emacs-->gptel: tools
emacs-->pi_agent : instruction
pi_agent-->ollama: prompt
gptel-->mcp_server: prompt
mcp_server-->llama.cpp: instruction
gptel-->emacs: code
pi_agent-->emacs: code
Figure 12: result of mermaid plot
The most efficient way to integrate LLMs is to use and their capabilities. Org files contain many different tags which are interpreted as multiple entities.
LLMs should be able to correctly find and update those tags and automate the work of logging what the user is doing.
I currently have the following mcp servers:
The microcontollers are the eyes and ears of the LLMs. We need to extend our MCP network to access and link the different devices so we can enhance our capabilities to the physical world. Here is the list of the we use. For that we need:
Ellama is an Emacs frontend for chatting with large language models via llm-ollama. Models run locally through Ollama – no cloud API needed.
emacs.el loads the whole ellama setup lazily via ellama-load-and-call
(emacs.el lines 810-815), which adds user-emacs-directory to the load
path and pulls in ellama_setup (=~/.emacs.d/ellama_setup.el). All
providers and helpers below are defined there, not in emacs.el.
Chat providers are built with make-llm-ollama (default
http://127.0.0.1:11434). Unlike gptel, it does not route through the MCP
server (the bottino/mcp FastAPI agent), so it has no access to the MCP
tools (ollama_list_models, camera_describe_scene, etc.) or the MCP
tool-call loop.
ellama_setup.el discovers providers dynamically at startup. The
codepath used is my-unsloth-list-models — it queries Unsloth’s
{UNSLOTH_URL}/api/inference/models and requires UNSLOTH_TOKEN (sent as a
Bearer token; Unsloth rejects unauthenticated model-list requests). Set
UNSLOTH_URL (default http://127.0.0.1:8889) to point at your Unsloth
server. my-ollama-list-models (Ollama’s /api/tags via OLLAMA_URL,
default http://127.0.0.1:11434) is present but currently not used — the
refresh helper was switched to the Unsloth source.
Listed model names appear in M-x ellama-switch-provider automatically after
a 3-second idle delay at startup (or instantly via
M-x my-ellama-refresh-providers), with a qwen2.5:7b fallback provider if
discovery fails.
Note: discovery lists Unsloth model names but builds make-llm-ollama
providers — the resolved names must be reachable through your chosen backend.
Ellama starts via the global keymap defined in ellama_setup.el:
| Key | Command | Description |
|---|---|---|
C-c w |
ellama |
Start a new chat session |
C-c C-c |
ellama-chat-send-last-message |
Send last message in chat buffer |
C-c e |
Ellama keymap | a ask / b better / c chat / d define / r code-review / s summarize / t translate / w webpage |
C-c f a |
ellama-ask-about |
Ask about selected region |
C-c f c |
ellama-code-complete |
Complete code in region |
C-c f r |
ellama-code-review |
Code-review selected region |
C-c f g |
ellama-improve-grammar |
Improve grammar |
C-c f w |
ellama-improve-wording |
Improve wording |
C-c f i |
ellama-chat |
Chat |
C-c f p |
ellama-provider-select |
Pick provider |
C-c f s |
ellama-summarize |
Summarize region |
C-c f t |
ellama-translate |
Translate region |
C-x e is deliberately left unbound by ellama so it keeps its stock meaning
kmacro-end-and-call-macro (macro execute); the ellama prefix uses C-c e.
Defined in =~/.emacs.d/ellama_setup.el:
Default chat provider (ellama-provider)
qwen3.5:9bnomic-embed-textnum_ctx)
Coding provider (ellama-coding-provider)
qwen2.5-coder:7bnomic-embed-textM-x ellama-code (there is no dedicated prefix for it, but
the coding provider can also be selected with M-x ellama-switch-provider)
Summarization provider (ellama-summarization-provider)
llama3.2:latestnomic-embed-text
Translation provider (ellama-translation-provider)
qwen2.5:7bnomic-embed-text
Extraction provider (ellama-extraction-provider)
qwen2.5-coder:7b-instruct-q8_0nomic-embed-text
Naming provider (ellama-naming-provider)
qwen2.5:7bellama-generate-name-by-llm)stop non-standard param of a newlineDynamic providers for interactive switching
ellama-providers is (re)built by my-ellama-refresh-providers from the
Unsloth model list at startup (my-unsloth-list-models), falling back to a
single qwen2.5:7b provider when discovery fails. Each entry embeds
qwen2.5:7b-style make-llm-ollama settings with nomic-embed-text and
32768-token context, so newly pulled models appear automatically in
M-x ellama-switch-provider.
Switch interactively with M-x ellama-switch-provider.
Start a chat
C-c e or M-x ellama
This opens a chat buffer in full frame. Type your message, then C-c C-c
to send.
Coding assistant
M-x ellama-code or select the coding provider interactively.
Ask for code, refactoring, or debugging help. The coding provider uses
qwen2.5-coder:7b with 32K context – suitable for whole functions or
small files.
Summarize text
Select a region, then M-x ellama-summarize or M-x ellama-summarize-region.
Ellama will summarize the selected text using the summarization provider.
Translate text
M-x ellama-translate – prompts for target language, then translates the
current region or buffer.
Extract structured data
M-x ellama-extract – extracts structured information from text (e.g.
names, dates, quantities from free-form text).
Use a different model
M-x ellama-switch-provider – pick from the dynamically-discovered
providers, or any other provider you define.
Display behaviour
display-buffer-full-frame) — note that
ellama_setup.el overrides the chat/instant display action to
display-buffer-no-window at load (lines 5-6), so the interactive prompts
stay unobtrusive.ellama-context-header-line-global-mode,
ellama-session-header-line-global-mode).Requirements
ellama_setup.el — either:
UNSLOTH_URL, default
http://127.0.0.1:8889; needs UNSLOTH_TOKEN); orOLLAMA_URL, default http://127.0.0.1:11434) serving the
chat models belowollama list):
qwen3.5:9b (default chat)qwen2.5-coder:7b (coding)llama3.2:latest (summarization)qwen2.5:7b (naming, translation, fallback)qwen2.5-coder:7b-instruct-q8_0 (extraction)nomic-embed-text (embeddings)| Symptom | Likely cause | Fix |
|---|---|---|
No provider available |
Ollama not running | systemctl start ollama |
Connection refused |
Wrong host/port | Check OLLAMA_HOST env or ollama serve |
| Model not found | Model not pulled | ollama pull qwen2.5:3b |
| Model exists in Ollama but not in ellama | Need to refresh provider list | M-x my-ellama-refresh-providers or wait for idle timer |
| Slow responses | Model too large for hardware | Use qwen2.5:3b instead of 7B variants |
| Context truncated | num_ctx too small |
Increase num_ctx in provider config |
Ellama now discovers models dynamically at startup (with a 3-second idle delay so init isn’t blocked). When you pull a new model in Ollama, it appears automatically after restarting Emacs, or you can refresh on demand:
M-x my-ellama-refresh-providers
This queries Ollama’s /api/tags endpoint, filters out embedding-only
models (nomic-embed-text, all-minilm), and rebuilds the
ellama-providers alist with a make-llm-ollama entry per model.
ollama list
or from Emacs:
M-x shell-command ollama list
By default, discovery hits http://127.0.0.1:11434/api/tags. To route
through the MCP server’s nginx instead, set:
MY_OLLAMA_URL=http://bottino:11434
or in Emacs:
M-x set-variable my-ollama-url "http://bottino:11434"
M-x my-ellama-refresh-providers
ollama pull deepseek-coder:6.7b
Then in Emacs:
M-x my-ellama-refresh-providers
M-x ellama-switch-provider → select deepseek-coder:6.7b
Useful commands