Commit Graph
109 Commits
Author SHA1 Message Date
Abiba d901235c03 docs: LiteLLM migration plan — two-layer architecture with model identity gap analysis
Architecture review identifying metric accuracy issue where router silently
reroutes explicit model requests. Proposes Option A: strict passthrough for
explicit models with LiteLLM-native fallback chains. Keeps syslog-auto for
content-based routing. Awaiting Mumuni and Kagenz0 review.
2026-06-14 00:40:07 +00:00
jerome 4c7ac3350d fix(dashboard): latest visual fixes (navbar, layout, status labels) 2026-06-12 22:13:33 -04:00
Abiba 316f2f5f45 fix(router): handle None temp_c/vram_pct in gpu_health_score
AMD sidecar returns null for temp_c/power_w fields.
gpu_health_score now uses  fallback for all numeric fields.
check_gpu_health also defaults temp_c and gpu_util_pct to 0.

Fixes 500 error on /metrics/gpu-health
2026-06-12 18:11:23 +00:00
Abiba 574076119c merge: accept our deployed Phase 1-3 + dashboard as authoritative
Mumuni pushed parallel Phase 1-2 commits to syslog/main. Our branch
has the deployed-and-verified versions with gpu-health endpoint and
dashboard v2. Using ours strategy to accept our working tree.
2026-06-12 17:58:22 +00:00
Abiba ad9881f141 feat(dashboard): live GPU health scoring + real KPIs
- Added /metrics/gpu-health endpoint with live health scores (VRAM 40%, temp 30%, load 30%)
- Added /metrics/latency endpoint for dashboard KPIs
- Added GPU_LABELS for human-readable model names
- Dashboard v2: rewired to real data endpoints
  - KPI cards: GPUs online, circuit trips, avg latency, req/min, active requests
  - Health scores from actual gpu_health_score() function
  - Rolling 60-sample history chart (real data, no simulation)
  - Status: green/yellow/red based on tripped circuits
  - No CDN dependency (pure CSS)
  - Auto-refresh every 15s
- nginx: /dashboard/ serves static files with cache headers
- docker-compose: dashboard volume mount

Co-authored-by: Abiba <abiba@sysloggh.com>
2026-06-12 17:57:46 +00:00
jerome 3625fdc860 feat(harness): sync production-ready fixes (context, circuit-breaker, ports) 2026-06-12 13:10:38 -04:00
Abiba a860a8fd0f feat(router): Phase 3 - Dynamic GPU Weighting via Health Scoring 2026-06-11 01:06:13 +00:00
Abiba fabbe340d6 feat(router): Phase 2 - Atomic session token tracking via Redis Lua script 2026-06-11 00:57:29 +00:00
Abiba 2e24ee5598 feat(router): Phase 1 - Circuit Breaker + /metrics/circuit-breaker endpoint 2026-06-11 00:47:15 +00:00
Abiba 19f7d90cc1 feat(nginx): Phase 1 - add /metrics/circuit-breaker proxy route 2026-06-11 00:39:21 +00:00
Abiba b79af634d7 feat(router): Phase 1 - Actual Circuit Breaker for GPU hosts
- Added is_circuit_tripped(), trip_circuit(), half_open_probe() functions
- Filters out models with tripped circuits in route() function
- Trips circuit on 502/504 errors and timeouts in chat() function
- Prevents hung GPU cascades (Node #480 scenario)

Approved by Abiba via relay #635

Signed-off-by: Mumuni <mumuni@sysloggh.com>
2026-06-11 00:29:53 +00:00
jerome a992d4b88f feat(nginx): Phase 1 - Add /metrics/circuit-breaker proxy route
- Added Nginx location block for circuit breaker metrics endpoint
- Enables visibility into which GPUs degrade most often

Signed-off-by: Mumuni <mumuni@sysloggh.com>
2026-06-10 19:27:50 -04:00
jerome c3dfe62cec feat(router): Phase 1 - Circuit Breaker for GPU hosts
- Added is_circuit_tripped(), trip_circuit(), half_open_probe() functions
- Filters out models with tripped circuits in route() function
- Trips circuit on 502/504 errors in chat() function
- Added /metrics/circuit-breaker endpoint for visibility (Abba suggestion)
- Prevents hung GPU cascades (Node #480 scenario)

Signed-off-by: Mumuni <mumuni@sysloggh.com>
2026-06-10 19:16:28 -04:00
Abiba f1d095e411 Phase 0.5 deployed: admin endpoints + nginx /admin/ routing + ADMIN_KEY 2026-06-08 11:31:07 +00:00
jerome ae3f581e3e Phase 0.5: Re-add ADMIN_KEY, /admin/keys endpoints, dual-key logging to current HEAD
Restores the Phase 0 security features that were lost during the merge of
SyslogSolution/syslog-harness into abiba-bot/inference-harness (commit 815ed799).

Changes:
- Added ADMIN_KEY env var + _admin_auth() for endpoint protection
- Added GET /admin/keys — list all keys with deprecation status
- Added GET /admin/keys/deprecation-summary — deprecated key usage from Redis
- Added POST /admin/keys/generate — generate new keys (memory-only)
- Added POST /admin/keys/revoke — revoke deprecated keys (memory-only)
- Added dual-key deprecated key logging to chat() endpoint
- Preserves: Redis lazy reconnect, MoE spillover, 5-tier routing, vision guard
2026-06-08 05:18:20 -04:00
Abiba c7b22f4d09 Fix counter_audit_loop: use get_redis() instead of stale r/rd refs 2026-06-07 23:33:43 +00:00
Abiba 815ed7991f Merge SyslogSolution/syslog-harness: accept current state (Phase 0 + Redis lazy reconnect + dashboard fix) 2026-06-07 23:14:28 +00:00
Abiba 633afc5e29 Router: lazy Redis reconnect (survives Redis restarts/reboots) 2026-06-07 23:01:20 +00:00
Abiba 85608d7c60 Dashboard + LiteLLM config updates from maintenance 2026-06-07 22:49:50 +00:00
Abiba 24f0928ea1 Phase 0: model migration (qwen3.5-9b-vlm → gemma-4-12b), context alignment (all 262K), routing tiers + MoE spillover, fix dashboard window=1h parsing 2026-06-07 22:49:46 +00:00
Abiba Bot 867a6189df Dashboard: fix undefined labels for retired models + safe fallback helpers
- Added qwen3.5-9b-vlm to MODELS array as (retired) with gray color
- Added modelLabel() / modelColor() safe lookup helpers
- Replaced all raw mlab[] and mcol[] lookups with safe fallbacks
- Unknown model IDs now show raw ID instead of 'undefined'
- Prevents stale Redis perf data from breaking renderPerf/renderScatter
2026-06-06 01:46:53 +00:00
Abiba Bot 39cf297a8f Phase 0: Dual-key router — no hardcoded keys, gemma sync, 262K context fix
- Removed all hardcoded API_KEYS from source (env var now REQUIRED)
- Added dual-key transition support (old keys deprecated, logged)
- Model sync: qwen3.5-9b-vlm → gemma-4-12b everywhere
- Dense context: 131K → 262K (all 3 models at 262K)
- Added /admin/keys endpoints for key lifecycle management
- Added ADMIN_KEY env var for admin auth
- Dashboard already synced to gemma-4-12b labels

Deployment: set API_KEYS from phase0-dual-keys.json in docker-compose
Transition: 7 days dual-key, then POST /admin/keys/revoke
2026-06-06 00:51:29 +00:00
Abiba Bot 1e24bc3b9b docs: update model table with context windows, capabilities, GPU labels 2026-06-05 23:49:03 +00:00
Abiba Bot e6a6c30211 router: v3 — 5-tier routing with vision guard, MoE spillover, code hint
GUARD: multimodal -> VLM only
TIER 1 Tiny: VLM->Dense->MoE
TIER 2 Light: VLM->Dense->MoE
TIER 3 Medium: MoE<->Dense (40% spill)->VLM
TIER 4 Heavy: Dense->MoE->VLM (quality first)
TIER 5 Default: MoE<->Dense (40% spill)->VLM
HINTS: speed->VLM, quality->MoE, code->Dense

+ moe_spillover(): 60/40 MoE/Dense load distribution
2026-06-05 23:48:45 +00:00
Abiba Bot c0be4c1699 router: reference - new 5-tier routing with vision guard (deployed CT116)
Vision guard: multimodal -> VLM only
TIER 1 Tiny: VLM->Dense->MoE
TIER 2 Light: Dense->VLM->MoE
TIER 3 Medium: MoE->Dense->VLM
TIER 4 Heavy: MoE->Dense->VLM
TIER 5 Default: MoE->Dense->VLM
Hints: speed->VLM, quality->MoE, code->Dense
2026-06-05 23:32:27 +00:00
Abiba Bot 424d943b12 router: fix Dense context window 98K→262K (matches actual n_ctx) 2026-06-05 23:15:18 +00:00
Abiba Bot b6abd84062 dashboard: rename VLM GPU label 'New Backend' → 'RTX 5070' for consistency 2026-06-05 21:53:07 +00:00
Abiba Bot dace488f93 VLM migration: qwen3.5-9b-vlm → gemma-4-12b across entire harness
- router/router.py: model ID, context window (131K→262K), VRAM comment
- litellm_config.yaml: model name updated
- gpu-router.conf, gpu-router-docker.conf: pool names, comments
- dashboard/dashboard.py: MODELS array refactor for single-point config
- README.md: architecture diagram, model table
2026-06-05 21:37:18 +00:00
Abiba Bot 370f5546dd dashboard: migrate VLM model qwen3.5-9b-vlm → gemma-4-12b (new backend 192.168.68.110:8080/v1) 2026-06-05 21:26:51 +00:00
AbibaandAbiba via Kwame 0cb4597b0e security: move API keys to env var, strip from source code fallback
- Added API_KEYS env var to router service in docker-compose.yml
- Replaced hardcoded agent keys in router.py fallback with dev-only placeholder
- Production now loads keys from environment, not source code
- Resolves the final remaining item from CT116 security deep-dive

Co-authored-by: Abiba via Kwame
2026-06-03 12:40:04 +00:00
Abiba 9a633583ab fix: Security hardening from CT116 deep-dive review
- API keys moved from hardcoded dict to env var (API_KEYS JSON) with fallback
- Rate limiting added: token bucket per API key (Redis-backed), 429 responses with Retry-After
- Rate limit tiers: enterprise 120/min, professional 60/min, starter 20/min
- X-RateLimit-* headers on all responses
- Dashboard polling reduced from 3s to 5s backend, 10s JS fallback
- SSE detection disables redundant polling when stream is connected
- Deleted ts_patch.py (dead one-shot migration, already applied)
- Added ssl/README.md documenting upstream SSL termination

Ref: Relay #444 (Mumuni CT116 harness deep-dive)
Reviewed-by: Abiba <abiba@sysloggh.com>
2026-06-02 10:37:10 +00:00
Abiba 060a47fce9 revert: MoE back to 2 slots (cross-agent spread now prevents hotspot)
Cross-agent GPU awareness ensures Tanko+Mumuni never
simultaneously hit MoE. Second agent always overflows
to Dense/VLM. MoE can safely use its extra VRAM with
2 slots since distinct agents never pile on.
2026-05-30 13:15:19 +00:00
Abiba 34fb7516e1 fix: cross-agent GPU spreading prevents hotspot hammering
OLD: checked only if CURRENT agent was on a GPU
  Tanko→MoE, Mumuni also→MoE (didnt see Tanko)

NEW: checks if ANY agent is on a GPU (cross-agent awareness)
  Pass 1: prefer GPUs with 0 agents
  Pass 2: prefer GPU this agent is not already on
  Pass 3: any non-busy GPU

Prevents Tanko+Mumuni piling onto same GPU simultaneously
even when both slots are free. Combined with MoE=1 slot,
guarantees overflow goes to idle Dense.
2026-05-30 12:55:29 +00:00
Abiba acbcb20837 fix: MoE concurrency 2→1 (95C thermal emergency)
MoE at 95C with p50=13s latency — thermal throttling causing
death spiral. Both slots stuck processing for 113s p95.
Dense idle at 38C with 2 free slots. Reducing MoE to 1 slot
forces heavy overflow to Dense, giving MoE thermal headroom.

Heavy tier: MoE → Dense → VLM still valid — first heavy goes
to MoE, second overflows to Dense.
2026-05-30 12:52:23 +00:00
Abiba a3bca93d9b fix: buffer SSE chunks for large streaming responses
Mumuni 23K-token responses split the final SSE timings chunk
across HTTP frames. The old per-chunk check missed timings when
split. Now accumulates lines in a buffer before parsing.

Also fixed: store_perf_record accidentally dropped in prior edit.
2026-05-29 09:45:41 +00:00
Abiba d53685d874 feat: agent-aware GPU load balancing
select_best_gpu() now spreads different agents across GPUs:
- If agent already has a request on a GPU, prefer other GPUs first
- Tracked via Redis agent_gpu:{agent}:{model} with 120s TTL
- Same agent can still use multiple slots on same GPU if needed
- Falls back to normal priority when only one option available

Prevents Tanko+Mumuni from piling onto MoE simultaneously
while Dense sits idle. Each agent naturally spreads across
available GPUs.
2026-05-28 21:45:23 +00:00
Abiba 54a4f26db7 fix: Default tier back to Dense-first (MoE overheating at 91°C)
Heavy tier keeps MoE primary (workhorse for >25K tok).
Default tier routes Dense → VLM → MoE to prevent MoE overload.
MoE had 5 timeouts in 15 min when Default pushed overflow to it.
2026-05-28 21:40:18 +00:00
Abiba fb1d51b93b restructure: routing prioritized by reasoning requirements
Tier 1 (Lightweight): VLM → Dense → MoE     ≤500 tok, 1 turn
Tier 2 (Simple):      VLM → Dense → MoE     ≤15K tok, ≤12 turns (was 10K/10)
Tier 3 (Medium):      Dense → VLM → MoE     ≤25K tok
Tier 4 (Heavy):       MoE → Dense → VLM     >25K tok (MoE PRIMARY workhorse)
Tier 5 (Default):     MoE → Dense → VLM     MoE primary fallback

Target: MoE ~50% (heavy primary), VLM ~25% (raised simple + fallback),
        Dense ~25% (medium primary + heavy fallback)

Removed turn limit from Medium tier — Simple tier handles conversational
requests up to 12 turns now.
2026-05-27 07:22:30 +00:00
Abiba 9a0d69ce8d feat: Dense 128K context + 2 slots, VLM second in Heavy tier
- Dense GPU_CONTEXT: 192K→128K (131072) to free VRAM
- Dense max_concurrent: 1→2 (VRAM now sufficient)
- Heavy tier: Dense → VLM → MoE (VLM handles 262K context)
- Total slots: 6 (2 Dense + 2 MoE + 2 VLM)

Distribution target: Dense 50%, VLM 30%, MoE 20%

NOTE: Requires llama.cpp restart on 192.168.68.8 with --ctx-size 131072
2026-05-27 07:15:58 +00:00
Abiba 621a897bec tune: raise Tier 2 threshold 4K→10K tok, 6→10 turns for VLM
More conversations now route to VLM as primary. 9B VLM has 262K
context window and 88 tok/s average — well suited for moderate
conversations. Dense absorbs overflow and heavy reasoning.
2026-05-27 00:29:25 +00:00
Abiba 93d0d3cc4b revert: MoE concurrency back to 2 (Dense-first routing handles thermal) 2026-05-27 00:04:42 +00:00
Abiba c4ea5e3a98 fix: flip Tier 4 (Heavy) to Dense-first for thermal safety
Dense → MoE → VLM instead of MoE → Dense → VLM.
Combined with MoE at 1 concurrent slot, Dense absorbs all
primary traffic. MoE only activates when Dense saturated.
Prevents Strix Halo from hitting 94C thermal limit.
2026-05-27 00:01:33 +00:00
Abiba ebe8f9ced4 fix: reduce MoE concurrency 2→1 to prevent thermal timeout (94°C)
Strix Halo running qwen3.6-35B-A3B was hitting 94°C with 2 concurrent
slots, causing 300s request timeouts. Mumuni + Koby accumulated 15
timeouts in the last hour. Reduced to 1 slot for thermal headroom.

Medium and Default tiers already route VLM before MoE as fallback,
minimizing overflow traffic to the hot GPU.
2026-05-26 23:47:08 +00:00
Abiba b3db0841ef feat: redesigned routing tiers for even GPU distribution + speed priority
OLD: Dense was last choice in every tier, got 4% of auto-routed traffic
NEW: 5-tier routing with speed-first prioritization

Tier 1 (Lightweight): VLM → Dense → MoE    (≤500 tok, ≤100 words)
Tier 2 (Simple):      VLM → Dense → MoE    (≤4000 tok, ≤6 turns)
Tier 3 (Medium):      DENSE → MoE → VLM    (≤25000 tok, ≤15 turns)
Tier 4 (Heavy):       MoE → Dense → VLM    (>25000 tok or >15 turns)
Tier 5 (Default):     DENSE → MoE → VLM    (balanced fallback)

Also: quality hint now routes to MoE (better reasoning)
Bugfix: Tier 1 now checks token count to prevent giant single-word
inputs from being routed as lightweight
2026-05-26 22:00:20 +00:00
Abiba 80362fa528 fix: default performance window to 24h so all models appear immediately 2026-05-26 12:37:52 +00:00
Abiba 7ef9e58f61 fix: restore /api/performance route in dashboard (was overwritten to /api/timeseries) 2026-05-26 12:31:53 +00:00
Abiba f47c3f3304 feat: latency vs prompt size scatter plot on dashboard
Router: new /metrics/scatter endpoint returns individual data points
(prompt_tokens, inference_ms, model, agent, reason, stream)
for scatter visualization.

Dashboard: new panel showing latency vs prompt size by model.
- Log-scale X axis (prompt tokens) with model color coding
- Dropdown to filter by individual model or view all
- Hover tooltips with details per point
- Auto-refresh every 30s

Enables direct observation of context-length vs latency
relationship — validates routing tier decisions.
2026-05-26 12:18:31 +00:00
Abiba cfb05fa501 feat: capture streaming token counts from SSE final chunk
Router now buffers streaming response chunks to extract timings
(prompt_n, predicted_n, predicted_per_second) from the final
SSE data frame before yielding to the client. Streaming requests
get real throughput data instead of 0 tok/s.

Uses llama.cpp timings field in the last content chunk:
- completion_tokens = predicted_n
- tokens_per_sec = predicted_per_second
- inference_ms = predicted_ms (generation only)

Client sees identical stream, no perceptible delay.
2026-05-25 19:58:51 +00:00
Abiba b2ec4b0572 fix: throughput panel handles streaming-only models gracefully
- Dashboard: when a model has zero non-streaming records, shows
  "streaming only" instead of misleading 0 tok/s
- Dashboard: minimum bar width enforced (6% avg, 4% p50) so
  low-tps models are always visible
- Router: removed inflated streaming tps estimate (prompt tokens
  skewed results for long conversations)

Fixes Dense model appearing to "register nothing" when Mumuni
sends mostly streaming requests.
2026-05-25 19:45:21 +00:00
Abiba 8c5c922a4e fix: handle single data point in performance percentiles 2026-05-25 17:00:40 +00:00