|
| 1 | +#!/usr/bin/env bash |
| 2 | +# mios-ollama -- thin wrapper around the upstream `ollama` CLI that |
| 3 | +# pins OLLAMA_HOST to the locally-running Ollama Quadlet |
| 4 | +# (usr/share/containers/systemd/ollama.container, port 11434), so |
| 5 | +# `ollama list / pull / run / rm` Just Work from any host shell -- |
| 6 | +# including Ptyxis flatpak's `flatpak-spawn --host bash` session, |
| 7 | +# the MiOS-DEV WSLg-routed terminal, or a plain TTY on a deployed |
| 8 | +# MiOS host. |
| 9 | +# |
| 10 | +# mios-ollama list installed models |
| 11 | +# mios-ollama run <model> interactive chat (upstream UX) |
| 12 | +# mios-ollama pull <model> download a model |
| 13 | +# mios-ollama rm <model> delete a model |
| 14 | +# mios-ollama serve (don't -- the Quadlet does this) |
| 15 | +# mios-ollama chat "<prompt>" one-shot prompt via OpenAI-compat |
| 16 | +# /v1/chat/completions; routes through |
| 17 | +# /usr/bin/mios with MIOS_AI_ENDPOINT |
| 18 | +# pointed at Ollama (:11434/v1) and |
| 19 | +# falls back to streaming raw curl |
| 20 | +# when the openai SDK is unavailable |
| 21 | +# |
| 22 | +# Env overrides: |
| 23 | +# OLLAMA_HOST default http://localhost:11434 |
| 24 | +# OLLAMA_API_BASE default http://localhost:11434/v1 (OpenAI-compat) |
| 25 | +# MIOS_AI_MODEL default qwen2.5-coder:7b |
| 26 | +# |
| 27 | +# Note: per Architectural Law 5, the canonical agent surface is |
| 28 | +# MIOS_AI_ENDPOINT (LocalAI on :8080). This wrapper is for operators |
| 29 | +# who want to drive Ollama directly without changing global env. |
| 30 | +set -euo pipefail |
| 31 | + |
| 32 | +OLLAMA_HOST="${OLLAMA_HOST:-http://localhost:11434}" |
| 33 | +OLLAMA_API_BASE="${OLLAMA_API_BASE:-${OLLAMA_HOST%/}/v1}" |
| 34 | +MIOS_AI_MODEL="${MIOS_AI_MODEL:-qwen2.5-coder:7b}" |
| 35 | +export OLLAMA_HOST |
| 36 | + |
| 37 | +if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then |
| 38 | + sed -n '2,28p' "$0" | sed 's/^# \?//' |
| 39 | + exit 0 |
| 40 | +fi |
| 41 | + |
| 42 | +# `mios-ollama chat "<prompt>"` routes through the canonical mios CLI |
| 43 | +# but pins MIOS_AI_ENDPOINT/KEY at Ollama. Streams + tool-calls work |
| 44 | +# the same way; the local model just happens to be served by Ollama. |
| 45 | +if [[ "${1:-}" == "chat" ]]; then |
| 46 | + shift |
| 47 | + if [[ -x /usr/bin/mios ]]; then |
| 48 | + exec env \ |
| 49 | + MIOS_AI_ENDPOINT="$OLLAMA_API_BASE" \ |
| 50 | + MIOS_AI_MODEL="$MIOS_AI_MODEL" \ |
| 51 | + MIOS_AI_KEY="${MIOS_AI_KEY:-sk-noop}" \ |
| 52 | + /usr/bin/mios "$@" |
| 53 | + fi |
| 54 | + # Fallback: openai SDK / mios CLI not available -- raw curl streaming. |
| 55 | + # Useful in minimal images that haven't pulled python3-openai yet. |
| 56 | + if [[ $# -eq 0 ]]; then echo "mios-ollama chat <prompt>" >&2; exit 2; fi |
| 57 | + body=$(jq -n \ |
| 58 | + --arg model "$MIOS_AI_MODEL" \ |
| 59 | + --arg content "$*" \ |
| 60 | + '{model:$model, stream:true, messages:[{role:"user",content:$content}]}') |
| 61 | + curl -sNH "Content-Type: application/json" -d "$body" \ |
| 62 | + "$OLLAMA_API_BASE/chat/completions" \ |
| 63 | + | sed -nE 's/^data: //p' \ |
| 64 | + | jq -j 'select(. != "[DONE]") | .choices[0].delta.content // empty' |
| 65 | + echo |
| 66 | + exit 0 |
| 67 | +fi |
| 68 | + |
| 69 | +# Anything else: delegate to the upstream `ollama` CLI verbatim. |
| 70 | +if ! command -v ollama >/dev/null 2>&1; then |
| 71 | + echo "mios-ollama: /usr/bin/ollama not found -- check 37-ollama-prep.sh ran" >&2 |
| 72 | + exit 127 |
| 73 | +fi |
| 74 | +exec /usr/bin/ollama "$@" |
0 commit comments