Files
env-ansible/tasks/workstation/linux/software/zeroclaw.yml
T

262 lines
8.9 KiB
YAML

---
# 2026-10-05 Hyperling
# Install a local LLM for use offline.
# - https://zeroclaw.net/blog/install-zeroclaw
# - https://zeroclaw.net/blog/set-up-zeroclaw-bot-ollama-telegram
#
# Packages Details
# - https://archlinux.org/packages/extra/x86_64/zeroclaw/
# - https://archlinux.org/packages/extra/x86_64/ollama/
#
# Individual Guides
# - https://github.com/zeroclaw-labs/zeroclaw
# - https://wiki.archlinux.org/title/Ollama
#
# Model Explanations
# - https://webscraft.org/blog/ollama-na-8-gb-ram-yaki-modeli-pratsyuyut-u-2026?lang=en
#
# Models
# - https://ollama.com/search
# Currently only testing this on Arch based distros (pacman).
- name: Workstation | Linux | Software | ZeroClaw
block:
- name: Workstation | Linux | Software | ZeroClaw | Facts 01
ansible.builtin.set_fact:
zeroclaw: zeroclaw
ollama: ollama
llm_installs:
##### QWEN #####
### 3.5, the recommended latest model of QWEN.
- qwen3.5:0.8b
- qwen3.5:2b
- qwen3.5:4b
#- qwen3.5:9b
#- qwen3.5:27b
#- qwen3.5:35b
### 3.0 Coder
#- qwen3-coder:30b
### 2.5 Coder, 7b recommended for code tasks vs QWEN 3.5 4b.
- qwen2.5-coder:0.5b
- qwen2.5-coder:1.5b
- qwen2.5-coder:3b
- qwen2.5-coder:7b
#- qwen2.5-coder:14b
#- qwen2.5-coder:32b
### 2.5, does not have "thinking" as an attribute, tempting!
#- qwen2.5:0.5b
#- qwen2.5:1.5b
#- qwen2.5:3b
#- qwen2.5:7b
#- qwen2.5:14b
#- qwen2.5:32b
### Others, TBD
#- deepseek-r1:1.5b
#- deepseek-r1:7b
#- mistal:7b
#- ministral:3b
#- ministral:8b
#- mistal:7b
#- glm4-flash
llm_removals:
- qwen3:4b # QWEN3 is the most similar to Ask Brave.
zerocode: zerocode
- name: Workstation | Linux | Software | ZeroClaw | Facts 02
ansible.builtin.set_fact:
ollama_runit_dir: "{{ runit_script_dir }}/{{ ollama }}"
ollama_runit_log_dest: "{{ global_log }}/{{ ollama }}"
zeroclaw_runit_dir: "{{ runit_script_dir }}/{{ zeroclaw }}"
zeroclaw_runit_log_dest: "{{ global_log }}/{{ zeroclaw }}"
- name: Workstation | Linux | Software | ZeroClaw | Facts 03
ansible.builtin.set_fact:
ollama_runit_script: "{{ ollama_runit_dir }}/{{ runit_service_script }}"
ollama_runit_log_dir: "{{ ollama_runit_dir }}/{{ runit_log_dir }}"
ollama_runit_log_config: "{{ ollama_runit_log_dest }}/{{ global_log_config }}"
zeroclaw_runit_script: "{{ zeroclaw_runit_dir }}/{{ runit_service_script }}"
zeroclaw_runit_log_dir: "{{ zeroclaw_runit_dir }}/{{ runit_log_dir }}"
zeroclaw_runit_log_config: "{{ zeroclaw_runit_log_dest }}/{{ global_log_config }}"
- name: Workstation | Linux | Software | ZeroClaw | Facts 04
ansible.builtin.set_fact:
ollama_runit_log_script: "{{ ollama_runit_log_dir }}/{{ runit_log_script }}"
zeroclaw_runit_log_script: "{{ zeroclaw_runit_log_dir }}/{{ runit_log_script }}"
- name: Workstation | Linux | Software | ZeroClaw | Install
ansible.builtin.package:
name:
- "{{ zeroclaw }}"
- "{{ ollama }}"
- "{{ zerocode }}"
state: present
- name: Workstation | Linux | Software | ZeroClaw | runit
block:
- name: Workstation | Linux | Software | ZeroClaw | runit | ollama | Dir | Run
ansible.builtin.file:
name: "{{ ollama_runit_dir }}"
state: directory
owner: root
mode: "0755"
- name: Workstation | Linux | Software | ZeroClaw | runit | ollama | Dir | Log Run
ansible.builtin.file:
name: "{{ ollama_runit_log_dir }}"
state: directory
owner: root
mode: "0755"
- name: Workstation | Linux | Software | ZeroClaw | runit | ollama | Dir | Log Config
ansible.builtin.file:
name: "{{ ollama_runit_log_dest }}"
state: directory
owner: "{{ user }}"
mode: "0755"
- name: Workstation | Linux | Software | ZeroClaw | runit | ollama | Script | Run
ansible.builtin.copy:
content: |
#!/bin/sh -e
# Allow pulling LLMs for use with ZeroClaw.
exec 2>&1
export HOME={{ user_user.home }}
export OLLAMA_KEEP_ALIVE=0 # default 5m
export OLLAMA_REQUEST_TIMEOUT=600 # default 300
export OLLAMA_MAX_LOADED_MODELS=1 # default is 3 if using CPUs, or 3 * NumGPUs
exec chpst -u {{ user }} ollama serve
dest: "{{ ollama_runit_script }}"
mode: "0755"
- name: Workstation | Linux | Software | ZeroClaw | runit | ollama | Script | Log
ansible.builtin.copy:
content: |
#!/bin/sh -e
exec svlogd -tt {{ ollama_runit_log_dest }}
dest: "{{ ollama_runit_log_script }}"
mode: "0755"
- name: Workstation | Linux | Software | ZeroClaw | runit | ollama | Script | Log Config
ansible.builtin.copy:
content: |
s10000000 # rotate at 10 MB
n5 # keep 5 old files
dest: "{{ ollama_runit_log_config }}"
owner: "{{ user }}"
mode: "0755"
- name: Workstation | Linux | Software | ZeroClaw | runit | zeroclaw | Dir | Run
ansible.builtin.file:
name: "{{ zeroclaw_runit_dir }}"
state: directory
owner: root
mode: "0755"
- name: Workstation | Linux | Software | ZeroClaw | runit | zeroclaw | Dir | Log
ansible.builtin.file:
name: "{{ zeroclaw_runit_log_dir }}"
state: directory
owner: root
mode: "0755"
- name: Workstation | Linux | Software | ZeroClaw | runit | zeroclaw | Dir | Log Config
ansible.builtin.file:
name: "{{ zeroclaw_runit_log_dest }}"
state: directory
owner: "{{ user }}"
mode: "0755"
- name: Workstation | Linux | Software | ZeroClaw | runit | zeroclaw | Script | File
ansible.builtin.copy:
content: |
#!/bin/sh -e
# Allow using the ZeroClaw frontend.
exec 2>&1
exec chpst -u {{ user }} zeroclaw daemon
dest: "{{ zeroclaw_runit_script }}"
mode: "0755"
- name: Workstation | Linux | Software | ZeroClaw | runit | zeroclaw | Script | Log
ansible.builtin.copy:
content: |
#!/bin/sh -e
exec svlogd -tt {{ zeroclaw_runit_log_dest }}
dest: "{{ zeroclaw_runit_log_script }}"
mode: "0755"
- name: Workstation | Linux | Software | ZeroClaw | runit | zeroclaw | Script | Log Config
ansible.builtin.copy:
content: |
s1000000 # rotate at 1 MB
n5 # keep 5 old files
dest: "{{ zeroclaw_runit_log_config }}"
mode: "0755"
when: ansible_service_mgr == "runit"
- name: Workstation | Linux | Software | ZeroClaw | Enable
ansible.builtin.service:
name: "{{ item }}"
state: started
enabled: true
loop:
- "{{ ollama }}"
- "{{ zeroclaw }}"
- name: Workstation | Linux | Software | ZeroClaw | Verify
ansible.builtin.uri:
url: "{{ item }}"
status_code: 200
timeout: 5
register: health
until: health.status == 200
retries: 12
delay: 5
loop:
- http://127.0.0.1:11434/
- http://127.0.0.1:42617/health
- name: Workstation | Linux | Software | ZeroClaw | ollama | Models | Install
ansible.builtin.shell: |
set -o pipefail
item='{{ item }}'
if ollama list | grep -q $item; then
echo "OKAY" &&
return
else
ollama pull $item 1>/dev/null &&
echo "INSTALLED" &&
return
fi
echo "FAILED"
loop: "{{ llm_installs }}"
register: shell_check
changed_when: "'INSTALLED' in shell_check.stdout"
failed_when: "'FAILED' in shell_check.stdout"
become: true
become_user: "{{ user }}"
- name: Workstation | Linux | Software | ZeroClaw | ollama | Models | Remove
ansible.builtin.shell: |
set -o pipefail
item='{{ item }}'
if ollama list | grep -q $item; then
ollama rm $item &&
echo "INSTALLED" &&
return
else
echo "OKAY" &&
return
fi
echo "FAILED"
loop: "{{ llm_removals }}"
register: shell_check
changed_when: "'INSTALLED' in shell_check.stdout"
failed_when: "'FAILED' in shell_check.stdout"
become: true
become_user: "{{ user }}"
when: ansible_pkg_mgr == "pacman"