hf2q 0.1.10

Pure Rust CLI for converting HuggingFace models to hardware-optimized formats and serving them over an OpenAI-compatible API on Apple Silicon
# Getting started: hf2q + OpenCode + local web research

This guide takes a fresh Mac from nothing to a working local coding agent:
hf2q serving a verified Qwen3.8-27B model, OpenCode connected to it, Agentic
Kit installed, and a local search/fetch research stack the agent can use.

You need an Apple Silicon Mac, about 20 GiB of free disk space, Node.js,
`jq`, and `curl`. Google Chrome is required later for the research stack's
browser fallback. The flow was validated on an Apple M5 Max with 128 GiB
unified memory; that names the validation host, not a minimum.

## 1. Install hf2q

```bash
curl -fsSL https://hf2q.us/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
hf2q setup
hf2q doctor
```

`hf2q setup` asks five questions and writes `~/.hf2q/config.toml`; every
answer can be changed later by rerunning it:

- **Quantization** — keep the default `q4_k_m`.
- **Optimize for long agent and tool-use prompts** — answer `Y` for agentic
  coding; it selects the batched scheduler and persists the qualified
  agentic serving profile (repetition penalty and bounded thinking budgets)
  into the configuration, so `hf2q serve` inherits it with no environment
  variables to set.
- **Maximum simultaneous active requests**`4` is a good agentic-coding
  value on a 128 GiB host; `1` is the safe default elsewhere.
- **LAN access**`N` keeps the server on loopback.
- **Port** — keep the default `8081`.

Non-interactive shells can run `hf2q setup --accept-defaults` instead.
`hf2q doctor` confirms the installation is healthy before you download 17 GiB.

## 2. Download the verified model

The model repository also hosts GGUFs built for a different engine; those do
not run on hf2q. Use only the two hf2q-named files from this pinned,
checksummed artifact commit:

```bash
MODEL_DIR="$HOME/.local/share/hf2q/models/qwen3.8"
HF_REV="40d771ee15d826017f297261f5bedcf2c32cf4c2"
HF_BASE="https://huggingface.co/jenerallee78/Qwen3.8-27B-Abliterated-SFT/resolve/$HF_REV/gguf"
mkdir -p "$MODEL_DIR"

for FILE in \
  qwen38-abliterated-sft-hf2q-q4_k_m.gguf \
  qwen38-abliterated-sft-hf2q-q4_k_m-mmproj.gguf \
  hf2q-q4_k_m-SHA256SUMS.txt
do
  curl -fL -C - -o "$MODEL_DIR/$FILE" "$HF_BASE/$FILE"
done

(
  cd "$MODEL_DIR"
  shasum -a 256 -c hf2q-q4_k_m-SHA256SUMS.txt
)
```

Both lines must print `OK`. The download resumes if interrupted; if a hash
fails, delete that one file and rerun the block. The text GGUF embeds the
projector's digest, so hf2q also rejects a mixed or damaged pair at load.

## 3. Serve the model (terminal 1)

```bash
hf2q serve \
  --model "$HOME/.local/share/hf2q/models/qwen3.8/qwen38-abliterated-sft-hf2q-q4_k_m.gguf" \
  --mmproj "$HOME/.local/share/hf2q/models/qwen3.8/qwen38-abliterated-sft-hf2q-q4_k_m-mmproj.gguf"
```

That is the whole command. Host, port, scheduler, and slot count come from
your `hf2q setup` answers; `--mmproj` adds vision. The server runs in the
foreground — leave this terminal open and stop it later with Ctrl-C.

Wait until the log reports the model loaded and listening before continuing.

## 4. Chat with the model (terminal 2)

```bash
hf2q chat
```

Chat discovers the running server on this machine and connects. Ask it
something real — a good answer here is the proof that serving works.
`/status` shows the endpoint and token statistics; `/quit` exits.

## 5. Prove vision with one request

Still in terminal 2:

```bash
RED_PNG="iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAAlC+aJAAABEElEQVR4Ae3AA6AkWZbG8f937o3IzKdyS2Oubdu2bdu2bdu2bWmMnpZKr54yMyLu+Xa3anqmhztr1a8+5ZZb+F+M4H83gv/dCP53I/jfjeB/N4L/3Qj+dyP4343gfzeC/90I/ncj+N+N4H83gv/dCP53I/jfjeB/N4L/3Qj+dyP4343gfzeC/90I/ncj+N+N4H83gv/dCP53I/jfjeB/N4L/3Qj+dyP4343gfzeC/90I/ncj+N+N4H83gv/dCP53I/jfjeB/N4L/3Qj+dyP4343gfzeC/90I/ncj+N+N4H83gv/dCP534x8BmV0Bmx29tGQAAAAASUVORK5CYII="
MODEL_ID="$(curl -fsS http://127.0.0.1:8081/v1/models |
  jq -er '.data | map(select(.loaded == true)) | .[0].id')"
jq -n --arg model "$MODEL_ID" --arg image "data:image/png;base64,$RED_PNG" '{
  model: $model,
  messages: [{role: "user", content: [
    {type: "text", text: "What is the dominant color? One word."},
    {type: "image_url", image_url: {url: $image}}
  ]}],
  temperature: 0, max_tokens: 16, stream: false, hf2q_enable_thinking: false
}' | curl -fsS http://127.0.0.1:8081/v1/chat/completions \
  -H 'Content-Type: application/json' -d @- |
  jq -er '.choices[0].message.content' | grep -i red
```

It must print an answer containing `red`. If it does, text, streaming, and
vision are all proven. Do not continue until both this and the previous
section pass; otherwise read the server output in terminal 1 and fix that
first — a retrying client hides the original error.

## 6. Install OpenCode

```bash
npm install -g opencode-ai
```

## 7. Point OpenCode at hf2q

This merge adds the local hf2q provider and selects its model.
It preserves every existing agent, tool, permission, plugin, instruction,
and MCP setting:

```bash
CONFIG="$HOME/.config/opencode/opencode.json"
MODEL_ID="$(curl -fsS http://127.0.0.1:8081/v1/models |
  jq -er '.data | map(select(.loaded == true)) | .[0].id')"
mkdir -p "$(dirname "$CONFIG")"
[ -f "$CONFIG" ] || printf '{}\n' > "$CONFIG"
cp "$CONFIG" "$CONFIG.$(date +%Y%m%d%H%M%S).bak"

jq --arg model_id "$MODEL_ID" '
  .provider = (.provider // {})
  | .provider.hf2q = ((.provider.hf2q // {}) + {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Local hf2q",
      "options": {"baseURL": "http://127.0.0.1:8081/v1", "apiKey": "local"},
      "models": {
        ($model_id): {
          "name": "Qwen3.8 27B Abliterated SFT via hf2q",
          "tool_call": true,
          "attachment": true,
          "modalities": {"input": ["text", "image"], "output": ["text"]},
          "reasoning": true,
          "interleaved": "reasoning_content",
          "temperature": true,
          "cost": {"input": 0, "output": 0},
          "limit": {"context": 262144, "output": 8192}
        }
      }
    })
  | .model = ("hf2q/" + $model_id)
' "$CONFIG" > "$CONFIG.tmp" && mv "$CONFIG.tmp" "$CONFIG"
```

Try it: `opencode --model "hf2q/$MODEL_ID"`, then ask the agent to list the
current directory. The transcript must show a real Bash tool call and its
result — a prose claim that tools exist is not proof.

## 8. Install Agentic Kit

Run this from the Git repository where you want Agentic Kit's project files.
Project setup may replace existing agent configuration, so commit or back up
first.

```bash
npm install -g @pacphi/agentic-kit@next
ak setup
ak setup --opencode
ak sync
ak status
```

The first `ak setup` performs machine and project setup. The second wires the
OpenCode host integration, and `ak sync` upgrades, heals, and verifies the
whole kit. `ak status` should report the memory backend, MCP integrations,
and OpenCode convergence as healthy.

## 9. Install the local research stack

This gives the agent `web_search`, `web_fetch`, `web_crawl`, and `web_extract`
(plus capitalized aliases) backed by local SearXNG and fetch services. Both
services bind to `127.0.0.1` only, restart automatically at login, and need
no API keys. Google Chrome is required for the JavaScript and anti-bot fetch
fallbacks:

```bash
if [ ! -d '/Applications/Google Chrome.app' ]; then
  brew install --cask google-chrome
fi

curl -fsSL \
  https://raw.githubusercontent.com/robertelee78/hf2q/main/scripts/install_opencode_web_stack.sh \
  | bash
```

If `brew` is missing, install Chrome from <https://www.google.com/chrome/>
first. The installer pins every dependency, backs up changed files, and
verifies the services live before exiting — a successful run is the
installation proof. Restart OpenCode once afterward so it loads the plugin.

## 10. Use the full stack

```bash
opencode
```

Ask it to research something current, for example a library released this
month. The transcript must contain a real `web_search` tool call with fetched
page content, and ordinary Bash/file tools must work in the same session.
That transcript is the end-to-end acceptance proof.

To stop the model server, press Ctrl-C in terminal 1. To manage the research
services, rerun the installer with `--status`, `--disable`, `--enable`, or
`--uninstall` (removal moves everything into a timestamped Trash folder; the
model, hf2q, OpenCode, and Agentic Kit are untouched).

## Troubleshooting

- **Server fails to start or generate** — read the output in terminal 1, then
  repeat sections 4 and 5.
- **Port 8081 already in use** — something else is listening; inspect with
  `lsof -nP -iTCP:8081 -sTCP:LISTEN`, or rerun `hf2q setup` and pick another
  port (use the same port in section 7's `baseURL`).
- **Projector binding failed** — re-download both hf2q-named files from the
  pinned commit in section 2; do not substitute other GGUFs from that repo.
- **OpenCode has no tools** — run `opencode debug config` and remove any
  agent-level `permission: "deny"` or `tools: {"*": false}` left by other
  configuration; this guide writes neither.
- **Agentic Kit unhealthy** — run `ak sync`, then `ak status`.
- **Research tools missing** — restart OpenCode, then rerun the installer
  with `--status` to see which check fails.