Commit Graph
141 Commits
Author SHA1 Message Date
haylan a3437e9cc7 chore(ai): enalbeld mtp mode 2026-09-25 08:13:23 +02:00
haylan ea07daa3cc Merge pull request 'Docs cleanup: restructure, move code comments into docs, remove image generation' (#65) from docs/cleanup-and-restructure into main
Reviewed-on: #65
2026-09-24 20:01:30 +00:00
haylanandClaude Bot e27f5c03b6 docs(agents): add writing-docs guide and new-term procedure
docs/agents/writing-docs.md holds the doc/comment rules and done-check,
reached via a pointer in CLAUDE.md (AGENTS.md and QWEN.md import it).
docs/agents/domain.md gains the procedure for new or conflicting terms.

Refs #55 (agent guide #62)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:52:19 +02:00
haylanandClaude Bot 05effe5c88 chore: move code comments into docs, leave one-line pointers
Explanations from docker-compose.yml, .env.example and
scripts/update.sh now live in docs/architecture.md, gateway.md,
network-access.md and operations.md. Code keeps `# see docs/...`
pointers, one-line warnings (storage key, SSRF guard, WAL grace period,
git pull ordering) and "auto-filled — leave blank" markers.

Refs #55 (comment destination map #61)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:52:00 +02:00
haylanandClaude Bot a0e5e9704b docs: restructure around source-of-truth pages
- CONTEXT.md glossary
- README reduced to intro, quickstart and doc index
- new architecture.md, gateway.md (from proxy-key-onboarding.md),
  operations.md; network-access.md rewritten
- coding-cli-setup: stale OMNIROUTE_PORT:-4000 endpoint, terms and
  duplicated per-slot/classifier explanations fixed
- research/README.md index; proxy-request-priority.md moved there as
  superseded

Every doc names keys instead of restating values and links its source.

Refs #55 (#56, #57, #59, #60)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:51:01 +02:00
haylanandClaude Bot 072eeb78c2 fix(qdrant): bind port to loopback only
qdrant has no auth; it was reachable from the whole LAN.

Refs #55 (intent vs. source #63)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:47:16 +02:00
haylanandClaude Bot fd55ce6669 chore: remove image generation, Open WebUI, Lazytainer and neo4j
Drops the comfyui, downloader-comfyui, open-webui, lazytainer and neo4j
services with their volumes, env keys and update.sh steps, plus
scripts/switch-model.sh and the two image-generation research docs.

Refs #55 (removal inventory #58, intent vs. source #63)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:47:12 +02:00
haylanandClaude Bot 8ae32102f9 feat(open-webui): add chat+image frontend, bypass omniroute for comfyui
OmniRoute's built-in comfyui provider hardcodes a CheckpointLoaderSimple
(single-file-checkpoint) workflow with no override (confirmed by
reading open-sse/handlers/imageGeneration/providers/comfyUI.ts
upstream), so it can't drive Qwen-Image 2.1's split unet/text-encoder/
vae GGUF loader chain. Open WebUI's own ComfyUI image backend is fully
generic instead — any exported workflow_api.json with arbitrary node
IDs mapped to parameters — so it can point straight at comfyui:8188.

Chat still goes through omniroute like every other client, via a
per-workload key (OPENWEBUI_OMNIROUTE_KEY, minted by hand same as
always). Published on host port 8008 per user request.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 23:28:44 +02:00
haylanandClaude Bot d09a99accd fix(comfyui): seed custom_nodes/input/output/user dirs under --base-directory
main.py crashed on boot (FileNotFoundError on /storage/custom_nodes) -
--base-directory fully relocates custom_nodes/input/output/user/temp
under it, it doesn't create them or fall back to the image's own
ComfyUI/custom_nodes (which has ComfyUI-Manager baked in). Seed
/storage/custom_nodes from the image's copy on first boot only (skips
once populated), so Manager survives the base-directory switch and
persists across recreates.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 23:09:27 +02:00
haylanandClaude Bot 9903b66094 fix(comfyui): correct HF subfolder paths for text encoder/VAE download
abenzerps/Qwen-Image-2.1-Uncensored-GGUF keeps the diffusion GGUFs at
repo root but the companion text encoder and VAE under text_encoders/
and vae/ subfolders — confirmed via the HF API's file listing, not
present in the file list used when these URLs were first written.
404'd on first real run. Local storage paths are unaffected.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 23:04:07 +02:00
haylanandClaude Bot 78adbf4cdf fix(update.sh): remove stale downloader-fast call
That service was merged into llama-server a while back (see the
comment on llama-server-fast's old alias), but update.sh's set -euo
pipefail meant every run since has hard-exited there — silently
skipping downloader-comfyui and the final `docker compose up -d`
recreate step on every invocation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 23:02:38 +02:00
haylanandClaude Bot 69d0d76d49 fix(comfyui): add missing launch command, drop dead PUID/PGID vars
yurisasc/comfyui-rocm7.1 has no entrypoint/CMD of its own (drops into
bash) and never reads PUID/PGID/VIDEO_GID/RENDER_GID/BASE_STORAGE_PATH
- confirmed by inspecting the image directly. Without an explicit
command the container just exits 0 immediately and restart-loops
forever with zero log output, which is what was actually blocking
comfyui.home/8138, unrelated to the earlier GGUF model swap.

Add `command: python main.py --listen 0.0.0.0 --port 8188
--base-directory /storage` (the real way to point it at the storage
volume) and remove COMFYUI_PUID/COMFYUI_PGID, since nothing consumes
them.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 23:01:24 +02:00
haylanandClaude Bot 38ec636fb5 chore(scripts): mark switch-model.sh executable
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 22:43:36 +02:00
haylan db1ef90688 Merge remote-tracking branch 'origin/tool-cassefier-model' 2026-09-22 22:39:21 +02:00
haylanandClaude Bot 4e310741c7 feat(comfyui): switch to Qwen-Image 2.1 uncensored GGUF model
Replace the Comfy-Org FP8 safetensors split with abenzerps'
Qwen-Image-2.1-Uncensored-GGUF (Q4_K_M diffusion weights + int8 text
encoder + bf16 VAE). GGUF weights land in models/unet per
ComfyUI-GGUF's convention instead of models/diffusion_models.

Flagged as unconfirmed: whether yurisasc/comfyui-rocm7.1 already
bundles the ComfyUI-GGUF custom node needed for the "Unet Loader
(GGUF)" node — check on deploy and install manually if absent.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 22:38:27 +02:00
haylan a3f1099bfc docs(research): OmniRoute memory tools hijack classifier tool-call, x-omniroute-no-memory fix 2026-09-15 23:31:58 +02:00
haylan ed90256f43 docs(research): trace 48-min outage to third OmniRoute timeout and open ROCm#6630 GPU hang 2026-09-15 23:31:58 +02:00
haylan fa852c8fb4 docs(research): qwen-classifier needs no context-window match; 8B/30B won't fit VRAM 2026-09-15 23:31:58 +02:00
haylan edad6b2249 Merge branch 'research/opencode-auto-compact' 2026-09-14 07:44:32 +02:00
haylan 2250e804db Implement code changes to enhance functionality and improve performance 2026-09-11 13:15:30 +02:00
haylanandClaude Bot e31647812a fix(omniroute): raise REQUEST_TIMEOUT_MS and enable --cache-reuse to stop non-ping SSE stream aborts
STREAM_IDLE_TIMEOUT_MS was raised to 180s on 2026-09-09 to give contended
llama-server prefill room to produce a first token, but qwen-code sessions
kept hitting "Stream produced no non-ping SSE event within 95000ms" the very
next morning. Per OmniRoute's own docs, that's the wrong timer: the first
non-ping SSE event's deadline inherits REQUEST_TIMEOUT_MS (default 10 min,
computed as remaining budget after retries/cooldowns), not
STREAM_IDLE_TIMEOUT_MS (which only bounds gaps between chunks once streaming
has already started).

Two changes:
- Add REQUEST_TIMEOUT_MS=1800000 (30 min) on the omniroute service, exposed
  as OMNIROUTE_REQUEST_TIMEOUT_MS like the existing stream-idle var. Safety
  margin, not the root-cause fix.
- Add --cache-reuse 256 to llama-server: it had no KV-cache reuse configured,
  so every request reprefilled its full prompt from scratch even when most
  of a conversation's prefix was unchanged. This is the actual fix for why
  compact-prompt prefill was slow enough to hit the timeout in the first
  place.

Documents the distinction and root cause in docs/research/.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqWBahogLCkrXNfzCSvcVc
2026-09-10 10:12:02 +02:00
haylanandClaude Bot 930e407053 docs(llm): document qwen-classifier reality, add --reasoning off safety net
- docker-compose.yml: add --reasoning off to qwen-classifier per
  fast-model-choice.md's own recommendation (ggml-org/llama.cpp#20809
  safety net) — missed in the original rollout, caught while writing
  this up.
- docs/coding-cli-setup/qwen-code.md: rewritten to match what's actually
  deployed (qwen-classifier, partial GPU offload, 65536 ctx, Q4_K_XL) —
  previously described an unimplemented llama-server-fast/8192-ctx plan.
  Documents the non-interactive MCP tool allow-list gap found live-testing.
- docs/coding-cli-setup/opencode.md: fix stale 65536 example that didn't
  match its own documented LLAMA_CTX_SIZE/LLAMA_PARALLEL formula (131072).
- docs/research/fast-model-choice.md: implementation note recording where
  the actual rollout diverged from this doc's original recommendations
  (service name, quant, context size, CPU-first-then-GPU path).
- docs/research/omniroute-account-semaphore-timeout.md: new — the
  hardcoded 30s per-connection semaphore timeout found during the
  pr-agent investigation, root-caused against OmniRoute's own source,
  and the maxConcurrent:null + providerSpecificData.timeoutMs fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 19:10:32 +02:00
haylanandClaude Bot 76043e2c6f tune(llm): partial GPU offload for qwen-classifier, real headroom
Full offload (999 layers) left only ~768MB free VRAM regardless of
batch-size/flash-attn tuning — that gap tracks roughly fixed regardless
of those knobs, most likely ROCm's own per-process HIP context overhead
(same ROCm#5706 quirk already noted for two HIP contexts sharing this
card, see llama-server's GPU_MAX_HW_QUEUES comment above). Dropping to
28/36 layers on GPU (6 layers + their KV on CPU) trades a slice of
speed for real freed VRAM — still >80% of layers on GPU, nowhere near
CPU-only's unusable latency. Verifying live before locking this number in.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 18:10:39 +02:00
haylanandClaude Bot 1102273384 fix(llm): enable flash-attn on qwen-classifier, real VRAM cause found
Batch/ubatch reduction barely moved measured VRAM (~768MB free, same as
before) — wrong lever. llama-server runs with --flash-attn on; this
service didn't. Without it, the unfused attention compute buffer at
65536 ctx is far larger than flash-attn's fused workspace, which is
what the naive weights+KV estimate missed. Matches llama-server's flag.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 17:04:05 +02:00
haylanandClaude Bot ba9ace6f71 fix(llm): shrink qwen-classifier's compute buffer for real VRAM headroom
Measured live: full-offload weights+KV (~4.9GiB estimate) actually used
~5.85GiB, leaving only ~700MB free on the R9700 — too tight, real OOM
risk for either GPU process. The gap was compute-buffer/graph overhead
the naive estimate didn't account for. Drop --batch-size/--ubatch-size
well below llama-server's defaults (2048/512) to shrink it — a
single-request classifier has no batching throughput to lose.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 17:02:44 +02:00
haylanandClaude Bot 8e2650807c fix(llm): move qwen-classifier to GPU, right-size context
CPU-only was too slow in practice: real classification calls blew past
OmniRoute's 60s timeout and retry-looped (504/499). Moved to GPU.

Also traced qwen-code's actual classifier transcript cap in its source
(MAX_TRANSCRIPT_MESSAGES=40, MAX_HISTORICAL_ACTION_CHARS=4000/message) —
worst case is ~40-50K tokens, not the 131072 originally set in
settings.json (copied from the main model's entry, not a real qwen-code
requirement). Dropped ctx-size to 65536 (~1.5x margin) so Q4_K_XL
weights + q4_0/q4_0 KV fit fully on GPU (~4.9GiB) inside the ~6.1GiB
free on the R9700, instead of needing partial CPU/GPU offload.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 16:59:02 +02:00
haylanandClaude Bot 4353e5c0e8 merge: follow-up fix for qwen-classifier model file
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 16:38:11 +02:00
haylanandClaude Bot 20cc0bcc70 fix(llm): point qwen-classifier at the Q8 GGUF already on disk
The Q4_K_M-class file this originally specced didn't exist yet on
gameserver (classifier crash-looped: "No such file or directory").
A Q8_K_XL GGUF for the same model was already sitting in the models
volume from something earlier — point at that instead of downloading a
new file, and drop the KV cache quant to q4_0/q4_0 to keep total RAM
comfortable now that the weights are the larger Q8 variant.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 16:37:54 +02:00
haylan c1e30ec9bb Merge pull request 'Fix/omniroute pr agent timeout' (#54) from fix/omniroute-pr-agent-timeout into main
Reviewed-on: #54
2026-09-09 14:29:13 +00:00
haylan b3a64fe4b5 chroe(chore): added markdown for harnesses 2026-09-09 16:28:42 +02:00
haylanandClaude Bot 828bd4c046 feat(llm): dedicate a CPU-only backend for the qwen-code tool-call classifier
fastModel in ~/.qwen/settings.json (permissions.autoMode.classifier) was
aliased onto llama-server's own 27B connection, so every tool-call safety
check queued behind whatever heavy generation was already running on that
model's 2 GPU slots.

Add qwen-classifier: a separate llama.cpp instance, CPU-only, running
Qwen3-4B-Instruct-2507 (the smallest Qwen3 with native >=131072 context,
qwen-code's requirement, without lossy RoPE scaling). Structurally isolated
from llama-server's queue instead of sharing it. Sized for gameserver's
~17GiB free system RAM: q8_0/q8_0 KV at full 131072 ctx (~9.8GiB) + Q4_K_M-
class weights (~2.3GiB) fits comfortably, with better KV quality than the
q4_0 that would've been needed to fit this on the GPU's ~6GiB free VRAM.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 16:26:51 +02:00
haylan 16df051318 docs(research): add ponytail audit report highlighting over-engineering and complexity issues 2026-09-09 08:22:31 +02:00
haylan 128503b68a docs: add AGENTS.md and QWEN.md with agent instructions and project overview 2026-09-09 07:32:09 +02:00
haylan df900404c0 chore(config): fix ignored path .qwen/temp to .qwen/tmp 2026-09-08 12:46:32 +02:00
haylan f4729ba704 docs(research): evaluate Colibrì for this stack
Assess whether the Colibrì disk-streaming MoE inference engine fits the AMD ROCm single-GPU setup or fills a gap beyond the existing llama.cpp/OmniRoute/Qdrant/Neo4j/ComfyUI stack. Conclusion: worth a passing watch, not worth integrating today.
2026-09-08 12:46:16 +02:00
haylanandClaude Bot 8f3feb4881 Merge branch 'feat-rag-databases'
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-08 12:30:27 +02:00
haylanandClaude Bot 6f4e736da8 docs(coding-cli-setup): split per-CLI docs into their own files
Move docs/coding-cli-setup.md to docs/coding-cli-setup/ with one file
per CLI (claude-code, kimi-cli, opencode, qwen-code) plus a shared
index.md for the gateway intro, tool-calling risk note, and summary
table.

Also fixes the qwen-code doc: context sizes are per-slot
(LLAMA_CTX_SIZE / LLAMA_PARALLEL), not raw LLAMA_CTX_SIZE (same fix
applied to OpenCode's limit.context); documents the fastModel
classifier provider and its own context math; adds the omniroute-search
MCP server (SearXNG web search) and Auto Mode permissions tuning that
were missing from the original qwen-code section.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-08 12:30:08 +02:00
haylan 4c8a9c039e Merge pull request 'fix(update.sh): stop config sync loop from dying silently on a missing key' (#53) from feat-rag-databases into main
Reviewed-on: #53
2026-09-07 18:10:23 +00:00
haylan 2ee308c1d9 Merge branch 'main' into feat-rag-databases 2026-09-07 18:10:16 +00:00
haylanandClaude Bot 1fcf30e9a1 fix(update.sh): stop config sync loop from dying silently on a missing key
current=$(grep ...) ran before checking whether the key existed in .env
at all. Under set -euo pipefail, a key missing from .env (e.g. a new
tunable this branch just added to .env.example) made that grep exit 1,
pipefail propagated it, and set -e killed the script instantly with no
output - looked exactly like a gum hang but never reached ensure_gum.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bs8xf8Dt8X6tRBvBiLCXYc
2026-09-07 20:09:31 +02:00
haylan 31e9aab1f3 Merge pull request 'Add Qdrant/Neo4j RAG storage + update.sh gum fixes' (#52) from feat-rag-databases into main
Reviewed-on: #52
2026-09-07 18:07:48 +00:00
haylan 665c3cb630 Merge branch 'main' into feat-rag-databases 2026-09-07 18:07:42 +00:00
haylanandClaude Bot e151aa6ffe feat(update.sh): vendor gum binary for the R9700's offline install
The server has no outbound internet access, so the curl download in
ensure_gum always failed silently and fell back to plain prompts.
Vendor the x86_64 release tarball under scripts/vendor/ and check it
before attempting a download - download stays as a fallback for other
archs or a version bump without a re-vendor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bs8xf8Dt8X6tRBvBiLCXYc
2026-09-07 20:04:56 +02:00
haylanandClaude Bot feb7469f0b fix(update.sh): report why gum auto-install failed instead of failing silently
curl -fsSL | tar swallowed curl errors entirely, so a network failure
fetching gum looked identical to a successful skip - just silently
dropped into the plain-prompt fallback with no explanation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bs8xf8Dt8X6tRBvBiLCXYc
2026-09-07 20:01:20 +02:00
haylan b51f7f9ad5 Merge pull request 'feat: add qdrant and neo4j for RAG vector/graph storage' (#50) from feat-rag-databases into main
Reviewed-on: #50
2026-09-07 17:56:49 +00:00
haylan fbb949d417 Merge branch 'main' into feat-rag-databases 2026-09-07 17:56:40 +00:00
haylan 9767261a96 Merge pull request 'feat: remove llama-server-fast (Qwen3-4B classifier model)' (#51) from remove-fast-model into main
Reviewed-on: #51
2026-09-07 17:56:27 +00:00
haylan 7a654ead91 chore: ignore .qwen/temp 2026-09-07 19:54:38 +02:00
haylanandClaude Bot 2bfe6dbd29 docs: point knowledge.proxy-ai.home at Neo4j's browser
Documents the NPM route for the RAG knowledge graph alongside the
existing proxy-ai.home/search.home entries. Neo4j (not Qdrant) gets
the hostname — it's the human-facing graph browser; Qdrant's
dashboard stays on its raw port for now.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DjhxWirQepKFEQj1huXNJR
2026-09-07 19:40:51 +02:00
haylanandClaude Bot 5d6a17fd9b feat: remove llama-server-fast (Qwen3-4B classifier model)
Drops the second always-resident llama.cpp instance, its downloader,
and the omniroute depends_on entry. Also strips the now-dead
LLAMA_FAST_* block from .env.example and the stale VRAM-budget comment
in scripts/switch-model.sh that assumed this service was always up.

Note: this was qwen-code's Auto Mode Stage 1 classifier (fastModel) —
see docs/research/fast-model-choice.md and issue #44. Auto Mode will
lose that classifier until/unless it's reconfigured to route
elsewhere or fall back to prompt-only classification.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DjhxWirQepKFEQj1huXNJR
2026-09-07 19:33:50 +02:00