Phase 0.5: Re-add ADMIN_KEY, /admin/keys endpoints, dual-key logging #1

Open
mumuni-bot wants to merge 3 commits from SyslogSolution/syslog-harness:main into main
19 changed files with 7893 additions and 251 deletions
Showing only changes of commit 937ba2c1ce - Show all commits
+13 -53
View File
@@ -1,4 +1,4 @@
version: "3.8" version: '3.8'
services: services:
redis: redis:
@@ -16,37 +16,18 @@ services:
timeout: 3s timeout: 3s
retries: 5 retries: 5
postgres:
image: postgres:16-alpine
container_name: harness-postgres
restart: unless-stopped
ports:
- "127.0.0.1:5432:5432"
environment:
- POSTGRES_DB=litellm
- POSTGRES_USER=litellm
- POSTGRES_PASSWORD=d9fc143e3dc1a7a8e672c359fea95c5e
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U litellm"]
interval: 5s
timeout: 3s
retries: 5
router: router:
build: ./router build: ./router
container_name: harness-router container_name: harness-router
restart: unless-stopped restart: unless-stopped
ports: network_mode: host
- "127.0.0.1:9000:9000"
environment: environment:
- REDIS_URL=redis://redis:6379 - REDIS_URL=redis://127.0.0.1:6379
- GPU_MOE_URL=http://192.168.68.15:8080/v1 - GPU_MOE_URL=http://192.168.68.15:8080/v1
- GPU_DENSE_URL=http://192.168.68.8:8080/v1 - GPU_DENSE_URL=http://192.168.68.8:8080/v1
- GPU_LIGHT_URL=http://192.168.68.110:8080/v1 - GPU_LIGHT_URL=http://192.168.68.110:8080/v1
- API_KEYS={"sk-syslog-local-master-key":{"tier":"enterprise","agent":"admin","deprecated":true},"sk-9e65b69a67-e54af421c1b09fb8bd4f75dacb38cb64":{"tier":"enterprise","agent":"admin"},"sk-syslog-abiba":{"tier":"enterprise","agent":"Abiba","deprecated":true},"sk-856ffb0bbb-e5aaf78b10054eca608f8fbcbd73a889":{"tier":"enterprise","agent":"Abiba"},"sk-syslog-mumuni":{"tier":"enterprise","agent":"Mumuni","deprecated":true},"sk-b57e6e042e-47573660114f3138c852c47f62da807e":{"tier":"enterprise","agent":"Mumuni"},"sk-syslog-tanko":{"tier":"enterprise","agent":"Tanko","deprecated":true},"sk-620a05e95a-e93d875476b650a4d1137249ead8eaa7":{"tier":"enterprise","agent":"Tanko"},"sk-syslog-koby":{"tier":"enterprise","agent":"Koby","deprecated":true},"sk-eb3e6fc1c0-de1bf2edf35a53cb3749a2400483fdee":{"tier":"enterprise","agent":"Koby"},"sk-syslog-kagenz0":{"tier":"enterprise","agent":"Kagenz0","deprecated":true},"sk-12b66b3392-b548aed9138aeb6f698e8e521650ed9b":{"tier":"enterprise","agent":"Kagenz0"},"sk-syslog-koonimo":{"tier":"enterprise","agent":"Koonimo","deprecated":true},"sk-680d06686c-00ee8bf9dc3c93b276af122d49a14dfe":{"tier":"enterprise","agent":"Koonimo"},"sk-starter-abc123":{"tier":"starter","agent":"test-starter","deprecated":true},"sk-55da55907a-1bd7ff344e26feda50e9ac2219697860":{"tier":"starter","agent":"test-starter"},"sk-professional-xyz789":{"tier":"professional","agent":"test-pro","deprecated":true},"sk-b5159863e6-8df3ae52fb958cfe76cc2888c8c8e676":{"tier":"professional","agent":"test-pro"}} - API_KEYS={"sk-sys...-key":{"tier":"enterprise","agent":"admin","deprecated":true},"sk-9e6...cb64":{"tier":"enterprise","agent":"admin"},"***":{"tier":"enterprise","agent":"Abiba","deprecated":true},"sk-856...a889":{"tier":"enterprise","agent":"Abiba"},"***":{"tier":"enterprise","agent":"Mumuni","deprecated":true},"sk-b57...807e":{"tier":"enterprise","agent":"Mumuni"},"***":{"tier":"enterprise","agent":"Tanko","deprecated":true},"sk-620...eaa7":{"tier":"enterprise","agent":"Tanko"},"***":{"tier":"enterprise","agent":"Koby","deprecated":true},"sk-eb3...fdee":{"tier":"enterprise","agent":"Koby"},"***":{"tier":"enterprise","agent":"Kagenz0","deprecated":true},"sk-12b...ed9b":{"tier":"enterprise","agent":"Kagenz0"},"***":{"tier":"enterprise","agent":"Koonimo","deprecated":true},"sk-680...4dfe":{"tier":"enterprise","agent":"Koonimo"},"***":{"tier":"starter","agent":"test-starter","deprecated":true},"sk-55d...7860":{"tier":"starter","agent":"test-starter"},"sk-pro...z789":{"tier":"professional","agent":"test-pro","deprecated":true},"sk-b51...e676":{"tier":"professional","agent":"test-pro"}}
- ADMIN_KEY=sk-admin-ee09fffd04978b61a1569ac670c68814 - ADMIN_KEY=sk-adm...8814
healthcheck: healthcheck:
test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:9000/health')"] test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:9000/health')"]
interval: 30s interval: 30s
@@ -57,47 +38,24 @@ services:
condition: service_healthy condition: service_healthy
litellm: litellm:
image: docker.litellm.ai/berriai/litellm:1.90.0-rc.1 image: ghcr.io/berriai/litellm:main-stable
command: ["--config", "/app/config.yaml", "--port", "4000"] command: ["--config", "/app/config.yaml", "--port", "4000"]
container_name: harness-litellm container_name: harness-litellm
restart: unless-stopped restart: unless-stopped
ports: ports:
- "4001:4000" - "127.0.0.1:8081:4000"
volumes: volumes:
- ./litellm_config.yaml:/app/config.yaml - ./litellm_config.yaml:/app/config.yaml
- /opt/combined-ca-bundle.pem:/etc/ssl/certs/ca-certificates.crt:ro
environment: environment:
- LITELLM_MASTER_KEY=sk-litellm-7f96080dd99b15c36bd4b333b58a6796 - LITELLM_MASTER_KEY=sk-sys...-key
- ROUTER_API_KEY=sk-9e65b69a67-e54af421c1b09fb8bd4f75dacb38cb64
- DATABASE_URL=postgresql://litellm:d9fc143e3dc1a7a8e672c359fea95c5e@postgres:5432/litellm
- STORE_MODEL_IN_DB=True
- LITELLM_UI_USERNAME=admin
- LITELLM_UI_PASSWORD=syslog-admin-2026
- UI_USERNAME=admin
- UI_PASSWORD=syslog-admin-2026
- OPENAI_API_KEY=not-used
- PROXY_BASE_URL=https://litellm.sysloggh.net
- DOCS_URL=/docs
- ANTHROPIC_API_KEY=not-used
- GENERIC_CLIENT_ID=FHd7bs9dP5gHad2Ki23iUL5kQvFa0GRaj3nlLnNU
- GENERIC_CLIENT_SECRET=aDkXQx82duqpxc98xxqp0quzzUf1mawsnOTqj7sx1acaS7rWSt02N5ksBCi92n8ZilRavigoYME6fLakP20Ixc9H2pxnSZFiOqQLb7BPi8UtsvfxmzXklD0HJIdbKFxe
- GENERIC_AUTHORIZATION_ENDPOINT=https://auth.sysloggh.net/application/o/authorize/
- GENERIC_TOKEN_ENDPOINT=http://harness-nginx/application/o/token/
- GENERIC_USERINFO_ENDPOINT=http://harness-nginx/application/o/userinfo/
- GENERIC_SCOPE=openid email profile
- GENERIC_ROLE_MAPPINGS_DEFAULT_ROLE=proxy_admin
- SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
extra_hosts: extra_hosts:
- "host.docker.internal:host-gateway" - "host.docker.internal:host-gateway"
- "auth.sysloggh.net:192.168.68.11"
healthcheck: healthcheck:
test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:4000/health/liveliness')"] test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:4000/health/liveliness')"]
interval: 15s interval: 15s
timeout: 5s timeout: 5s
retries: 3 retries: 3
depends_on: depends_on:
postgres:
condition: service_healthy
redis: redis:
condition: service_healthy condition: service_healthy
@@ -111,7 +69,7 @@ services:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./dashboard:/opt/inference-harness/dashboard:ro - ./dashboard:/opt/inference-harness/dashboard:ro
extra_hosts: extra_hosts:
- "auth.sysloggh.net:192.168.68.11" - "host.docker.internal:host-gateway"
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://127.0.0.1/health"] test: ["CMD", "curl", "-f", "http://127.0.0.1/health"]
interval: 30s interval: 30s
@@ -128,7 +86,7 @@ services:
ports: ports:
- "127.0.0.1:3000:3000" - "127.0.0.1:3000:3000"
environment: environment:
- REDIS_URL=redis://redis:6379 - REDIS_URL=redis://127.0.0.1:6379
- GPU_SIDECARS=192.168.68.15:8090,192.168.68.8:8090,192.168.68.110:8090 - GPU_SIDECARS=192.168.68.15:8090,192.168.68.8:8090,192.168.68.110:8090
healthcheck: healthcheck:
test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:3000/health')"] test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:3000/health')"]
@@ -140,4 +98,6 @@ services:
volumes: volumes:
redis-data: redis-data:
pgdata:
# LiteLLM command override to load config
# (appended to fix config loading issue)
+280
View File
@@ -0,0 +1,280 @@
{
"communities": {
"0": [
"router_route_v2",
"router_route_v2_route",
"router_route_v3",
"router_route_v3_moe_spillover",
"router_route_v3_rationale_81",
"router_route_v3_route",
"router_router_available_models",
"router_router_estimate_tokens",
"router_router_is_gpu_busy",
"router_router_moe_spillover",
"router_router_rationale_180",
"router_router_rationale_216",
"router_router_rationale_239",
"router_router_rationale_386",
"router_router_route",
"router_router_select_best_gpu"
],
"1": [
"dashboard_dashboard",
"dashboard_dashboard_api_performance",
"dashboard_dashboard_api_scatter",
"dashboard_dashboard_api_state",
"dashboard_dashboard_api_stream",
"dashboard_dashboard_api_timeseries",
"dashboard_dashboard_broadcast_loop",
"dashboard_dashboard_dashboard",
"dashboard_dashboard_fetch_state",
"dashboard_dashboard_health",
"dashboard_dashboard_rationale_1"
],
"2": [
"queue_service_queue_service",
"queue_service_queue_service_check_gpu_health",
"queue_service_queue_service_enqueue",
"queue_service_queue_service_get_queue_depth",
"queue_service_queue_service_get_redis",
"queue_service_queue_service_health",
"queue_service_queue_service_rationale_100",
"queue_service_queue_service_rationale_62",
"queue_service_queue_service_rationale_68",
"queue_service_queue_service_status"
],
"3": [
"router_router_admin_auth",
"router_router_admin_deprecation_summary",
"router_router_admin_generate_key",
"router_router_admin_keys",
"router_router_admin_revoke_key",
"router_router_rationale_895",
"router_router_rationale_905",
"router_router_rationale_928",
"router_router_rationale_950",
"router_router_rationale_978"
],
"4": [
"router_router",
"router_router_bcast",
"router_router_get_metrics",
"router_router_metrics",
"router_router_metrics_circuit_breaker",
"router_router_metrics_timeseries",
"router_router_models",
"router_router_rationale_811",
"router_router_stream"
],
"5": [
"router_router_get_redis",
"router_router_gpu_decr",
"router_router_gpu_incr",
"router_router_half_open_probe",
"router_router_is_circuit_tripped",
"router_router_performance",
"router_router_rationale_282",
"router_router_rationale_297",
"router_router_rationale_619"
],
"6": [
"router_router_check_gpu_health",
"router_router_gpu_active_count",
"router_router_gpu_health_score",
"router_router_health",
"router_router_metrics_gpu_health",
"router_router_rationale_141",
"router_router_rationale_225",
"router_router_rationale_828"
],
"7": [
"router_router_chat",
"router_router_check_rate_limit",
"router_router_clean_response",
"router_router_clean_unicode",
"router_router_rationale_184",
"router_router_rationale_72",
"router_router_store_perf_record"
],
"8": [
"maintenance",
"maintenance_sh__entry"
],
"9": [
"router_router_counter_audit_loop",
"router_router_rationale_116"
],
"10": [
"router_router_metrics_latency",
"router_router_rationale_859"
],
"11": [
"router_router_rationale_288",
"router_router_trip_circuit"
],
"12": [
"router_router_rationale_736",
"router_router_scatter"
],
"13": [
"router_http_patch"
]
},
"cohesion": {
"0": 0.20833333333333334,
"1": 0.21818181818181817,
"2": 0.3111111111111111,
"3": 0.2,
"4": 0.2777777777777778,
"5": 0.2222222222222222,
"6": 0.35714285714285715,
"7": 0.3333333333333333,
"8": 1.0,
"9": 1.0,
"10": 1.0,
"11": 1.0,
"12": 1.0,
"13": 1.0
},
"gods": [
{
"id": "router_router_chat",
"label": "chat()",
"degree": 12
},
{
"id": "router_router_get_redis",
"label": "get_redis()",
"degree": 11
},
{
"id": "router_router_gpu_active_count",
"label": "gpu_active_count()",
"degree": 9
},
{
"id": "router_router_is_gpu_busy",
"label": "is_gpu_busy()",
"degree": 9
},
{
"id": "router_router_select_best_gpu",
"label": "select_best_gpu()",
"degree": 8
},
{
"id": "router_router_route",
"label": "route()",
"degree": 8
},
{
"id": "router_route_v3_route",
"label": "route()",
"degree": 6
},
{
"id": "router_router_check_gpu_health",
"label": "check_gpu_health()",
"degree": 6
},
{
"id": "router_router_available_models",
"label": "available_models()",
"degree": 6
},
{
"id": "router_router_estimate_tokens",
"label": "estimate_tokens()",
"degree": 6
}
],
"surprises": [
{
"source": "route()",
"target": "available_models()",
"source_files": [
"router/route_v2.py",
"router/router.py"
],
"confidence": "INFERRED",
"relation": "calls",
"why": "inferred connection - not explicitly stated in source"
},
{
"source": "route()",
"target": "estimate_tokens()",
"source_files": [
"router/route_v2.py",
"router/router.py"
],
"confidence": "INFERRED",
"relation": "calls",
"why": "inferred connection - not explicitly stated in source"
},
{
"source": "route()",
"target": "is_gpu_busy()",
"source_files": [
"router/route_v2.py",
"router/router.py"
],
"confidence": "INFERRED",
"relation": "calls",
"why": "inferred connection - not explicitly stated in source"
},
{
"source": "route()",
"target": "select_best_gpu()",
"source_files": [
"router/route_v2.py",
"router/router.py"
],
"confidence": "INFERRED",
"relation": "calls",
"why": "inferred connection - not explicitly stated in source"
},
{
"source": "route()",
"target": "available_models()",
"source_files": [
"router/route_v3.py",
"router/router.py"
],
"confidence": "INFERRED",
"relation": "calls",
"why": "inferred connection - not explicitly stated in source"
}
],
"questions": [
{
"type": "bridge_node",
"question": "Why does `is_gpu_busy()` connect `Community 0` to `Community 4`, `Community 6`?",
"why": "High betweenness centrality (0.061) - this node is a cross-community bridge."
},
{
"type": "bridge_node",
"question": "Why does `select_best_gpu()` connect `Community 0` to `Community 4`, `Community 6`?",
"why": "High betweenness centrality (0.031) - this node is a cross-community bridge."
},
{
"type": "bridge_node",
"question": "Why does `estimate_tokens()` connect `Community 0` to `Community 4`, `Community 7`?",
"why": "High betweenness centrality (0.030) - this node is a cross-community bridge."
},
{
"type": "verify_inferred",
"question": "Are the 3 inferred relationships involving `is_gpu_busy()` (e.g. with `route()` and `moe_spillover()`) actually correct?",
"why": "`is_gpu_busy()` has 3 INFERRED edges - model-reasoned connections that need verification."
},
{
"type": "verify_inferred",
"question": "Are the 3 inferred relationships involving `select_best_gpu()` (e.g. with `route()` and `route()`) actually correct?",
"why": "`select_best_gpu()` has 3 INFERRED edges - model-reasoned connections that need verification."
},
{
"type": "isolated_nodes",
"question": "What connects `SyslogAI Harness Dashboard \u2014 Modern Design.`, `maintenance.sh script`, `Nginx upstream health probe. Returns 200 if service is alive.` to the rest of the system?",
"why": "28 weakly-connected nodes found - possible documentation gaps or missing edges."
}
]
}
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
{"files": {"code": ["/root/syslog-harness-repo/dashboard/dashboard.py", "/root/syslog-harness-repo/maintenance.sh", "/root/syslog-harness-repo/phase0-dual-keys.json", "/root/syslog-harness-repo/queue-service/queue-service.py", "/root/syslog-harness-repo/router/http_patch.py", "/root/syslog-harness-repo/router/route_v2.py", "/root/syslog-harness-repo/router/route_v3.py", "/root/syslog-harness-repo/router/router.py"], "document": ["/root/syslog-harness-repo/LITELLM-MIGRATION-PLAN.md", "/root/syslog-harness-repo/MIGRATION_PLAN.md", "/root/syslog-harness-repo/README.md", "/root/syslog-harness-repo/dashboard/dashboard.html", "/root/syslog-harness-repo/dashboard/harness.html", "/root/syslog-harness-repo/dashboard/requirements.txt", "/root/syslog-harness-repo/docker-compose.yml", "/root/syslog-harness-repo/litellm_config.yaml", "/root/syslog-harness-repo/router/requirements.txt", "/root/syslog-harness-repo/ssl/README.md"], "paper": [], "image": [], "video": []}, "total_files": 18, "total_words": 14667, "needs_graph": false, "warning": "Corpus is ~14,667 words - fits in a single context window. You may not need a graph.", "skipped_sensitive": ["/root/syslog-harness-repo/.env.example"], "unclassified": ["/root/syslog-harness-repo/.gitignore", "/root/syslog-harness-repo/Dockerfile.dashboard", "/root/syslog-harness-repo/Dockerfile.queue", "/root/syslog-harness-repo/backups/20260602_103344/dashboard.py.bak", "/root/syslog-harness-repo/backups/20260602_103344/router.py.bak", "/root/syslog-harness-repo/backups/20260602_103344/ts_patch.py.bak", "/root/syslog-harness-repo/dashboard/Dockerfile", "/root/syslog-harness-repo/docker-compose.yml.bak", "/root/syslog-harness-repo/gpu-router-docker.conf", "/root/syslog-harness-repo/gpu-router.conf", "/root/syslog-harness-repo/nginx/nginx.conf", "/root/syslog-harness-repo/nginx/nginx.conf.bak", "/root/syslog-harness-repo/router/Dockerfile", "/root/syslog-harness-repo/router/router.py.bak.20260518074236"], "graphifyignore_patterns": 3, "scan_root": "/root/syslog-harness-repo"}
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
{"nodes": [], "edges": [], "hyperedges": [], "input_tokens": 0, "output_tokens": 0}
+106
View File
@@ -0,0 +1,106 @@
# Graph Report - . (2026-07-08)
## Corpus Check
- Corpus is ~14,667 words - fits in a single context window. You may not need a graph.
## Summary
- 91 nodes · 151 edges · 14 communities (9 shown, 5 thin omitted)
- Extraction: 93% EXTRACTED · 7% INFERRED · 0% AMBIGUOUS · INFERRED: 10 edges (avg confidence: 0.77)
- Token cost: 0 input · 0 output
## Community Hubs (Navigation)
- Community 0
- Community 1
- Community 2
- Community 3
- Community 4
- Community 5
- Community 6
- Community 7
- Community 8
- Community 9
- Community 10
- Community 11
- Community 12
## God Nodes (most connected - your core abstractions)
1. `chat()` - 12 edges
2. `get_redis()` - 11 edges
3. `gpu_active_count()` - 9 edges
4. `is_gpu_busy()` - 9 edges
5. `select_best_gpu()` - 8 edges
6. `route()` - 8 edges
7. `route()` - 6 edges
8. `check_gpu_health()` - 6 edges
9. `available_models()` - 6 edges
10. `estimate_tokens()` - 6 edges
## Surprising Connections (you probably didn't know these)
- `route()` --calls--> `available_models()` [INFERRED]
router/route_v2.py → router/router.py
- `route()` --calls--> `estimate_tokens()` [INFERRED]
router/route_v2.py → router/router.py
- `route()` --calls--> `is_gpu_busy()` [INFERRED]
router/route_v2.py → router/router.py
- `route()` --calls--> `select_best_gpu()` [INFERRED]
router/route_v2.py → router/router.py
- `route()` --calls--> `available_models()` [INFERRED]
router/route_v3.py → router/router.py
## Import Cycles
- None detected.
## Communities (14 total, 5 thin omitted)
### Community 0 - "Community 0"
Cohesion: 0.21
Nodes (14): route(), moe_spillover(), Spill 40% of MoE-first traffic to Dense to prevent Strix Halo overheating. O, route(), available_models(), estimate_tokens(), is_gpu_busy(), moe_spillover() (+6 more)
### Community 1 - "Community 1"
Cohesion: 0.22
Nodes (4): api_state(), broadcast_loop(), fetch_state(), SyslogAI Harness Dashboard — Modern Design.
### Community 2 - "Community 2"
Cohesion: 0.31
Nodes (9): check_gpu_health(), enqueue(), get_queue_depth(), get_redis(), health(), GET queue depth + circuit breaker state + GPU health., Nginx upstream health probe. Returns 200 if service is alive., Fallback endpoint — Nginx calls this when all GPU upstreams are down. (+1 more)
### Community 3 - "Community 3"
Cohesion: 0.20
Nodes (10): _admin_auth(), admin_deprecation_summary(), admin_generate_key(), admin_keys(), admin_revoke_key(), Require admin key for management endpoints., List all API keys (masked) with agent, tier, and deprecation status., Summary of deprecated key usage (from Redis logs, if available). (+2 more)
### Community 4 - "Community 4"
Cohesion: 0.28
Nodes (5): bcast(), get_metrics(), metrics(), metrics_circuit_breaker(), Expose circuit breaker status per model. Phase 1.
### Community 5 - "Community 5"
Cohesion: 0.22
Nodes (9): get_redis(), gpu_decr(), gpu_incr(), half_open_probe(), is_circuit_tripped(), performance(), Check if a GPU host is currently blacklisted., Check if a GPU host can be un-blacklisted. (+1 more)
### Community 6 - "Community 6"
Cohesion: 0.36
Nodes (8): check_gpu_health(), gpu_active_count(), gpu_health_score(), health(), metrics_gpu_health(), Get number of in-flight requests for a GPU., Score a GPU based on VRAM, temperature, and load. Lower = better., Live GPU health scores + circuit breaker + KPIs.
### Community 7 - "Community 7"
Cohesion: 0.33
Nodes (7): chat(), check_rate_limit(), clean_response(), clean_unicode(), Store detailed performance record in Redis for analytics., Token bucket rate limiter using Redis. Returns (allowed, retry_after_or_remainin, store_perf_record()
## Knowledge Gaps
- **1 isolated node(s):** `maintenance.sh script`
These have ≤1 connection - possible missing edges or undocumented components.
- **5 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
## Suggested Questions
_Questions this graph is uniquely positioned to answer:_
- **Why does `is_gpu_busy()` connect `Community 0` to `Community 4`, `Community 6`?**
_High betweenness centrality (0.061) - this node is a cross-community bridge._
- **Why does `select_best_gpu()` connect `Community 0` to `Community 4`, `Community 6`?**
_High betweenness centrality (0.031) - this node is a cross-community bridge._
- **Why does `estimate_tokens()` connect `Community 0` to `Community 4`, `Community 7`?**
_High betweenness centrality (0.030) - this node is a cross-community bridge._
- **Are the 3 inferred relationships involving `is_gpu_busy()` (e.g. with `route()` and `moe_spillover()`) actually correct?**
_`is_gpu_busy()` has 3 INFERRED edges - model-reasoned connections that need verification._
- **Are the 3 inferred relationships involving `select_best_gpu()` (e.g. with `route()` and `route()`) actually correct?**
_`select_best_gpu()` has 3 INFERRED edges - model-reasoned connections that need verification._
- **What connects `SyslogAI Harness Dashboard — Modern Design.`, `maintenance.sh script`, `Nginx upstream health probe. Returns 200 if service is alive.` to the rest of the system?**
_28 weakly-connected nodes found - possible documentation gaps or missing edges._
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "root_syslog_harness_repo_router_http_patch_py", "label": "http_patch.py", "file_type": "code", "source_file": "router/http_patch.py", "source_location": "L1"}], "edges": [{"source": "root_syslog_harness_repo_router_http_patch_py", "target": "re", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "router/http_patch.py", "source_location": "L2", "weight": 1.0}], "raw_calls": []}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "root_syslog_harness_repo_maintenance_sh", "label": "maintenance.sh", "file_type": "code", "source_file": "maintenance.sh", "source_location": "L1", "metadata": {"language": "bash", "kind": "file"}}, {"id": "root_syslog_harness_repo_maintenance_sh__entry", "label": "maintenance.sh script", "file_type": "code", "source_file": "maintenance.sh", "source_location": "L1", "metadata": {"language": "bash", "kind": "bash_entrypoint"}}], "edges": [{"source": "root_syslog_harness_repo_maintenance_sh", "target": "root_syslog_harness_repo_maintenance_sh__entry", "relation": "contains", "confidence": "EXTRACTED", "source_file": "maintenance.sh", "source_location": "L1", "weight": 1.0}]}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
{"/root/syslog-harness-repo/LITELLM-MIGRATION-PLAN.md":{"size":31561,"mtime_ns":1781468608211508160,"word_count":3762},"/root/syslog-harness-repo/MIGRATION_PLAN.md":{"size":1966,"mtime_ns":1781121183850310435,"word_count":303},"/root/syslog-harness-repo/README.md":{"size":2447,"mtime_ns":1781121183850310435,"word_count":377},"/root/syslog-harness-repo/dashboard/dashboard.html":{"size":8331,"mtime_ns":1781316813360201927,"word_count":415},"/root/syslog-harness-repo/dashboard/dashboard.py":{"size":29010,"mtime_ns":1781121183851178603,"word_count":1615,"hash":"654e97aa6df1872b0717f32f676c067d15b9795a0dc04a86936730a7e133c214"},"/root/syslog-harness-repo/dashboard/harness.html":{"size":23388,"mtime_ns":1781316813362649901,"word_count":1869},"/root/syslog-harness-repo/dashboard/requirements.txt":{"size":30,"mtime_ns":1781121183851178603,"word_count":2},"/root/syslog-harness-repo/docker-compose.yml":{"size":3900,"mtime_ns":1782224658037786319,"word_count":200},"/root/syslog-harness-repo/litellm_config.yaml":{"size":618,"mtime_ns":1781121183851178603,"word_count":39},"/root/syslog-harness-repo/maintenance.sh":{"size":1302,"mtime_ns":1781121183851178603,"word_count":192,"hash":"801feb2c0b7f4052cb2c4ef933d295d3494c8791766687b891c04cc7b5495d09"},"/root/syslog-harness-repo/phase0-dual-keys.json":{"size":1628,"mtime_ns":1781121183851610673,"word_count":110,"hash":"0f115313f2c86df2f57e48bdf180b768d6452d0337bae4e3c3d2b52b9f5267a7"},"/root/syslog-harness-repo/queue-service/queue-service.py":{"size":3284,"mtime_ns":1781121183851610673,"word_count":325,"hash":"c9a9d2e5c9f1fb7d35a73f91c83a047ce92dc2d09c9ddab8fc2d6e82d92a093d"},"/root/syslog-harness-repo/router/http_patch.py":{"size":3562,"mtime_ns":1781121183851788825,"word_count":290,"hash":"53edfda5145db02bc35b9e9d8e06e5c731ce50c3a50cec3db65b3b886bed95a6"},"/root/syslog-harness-repo/router/requirements.txt":{"size":43,"mtime_ns":1781121183851788825,"word_count":3},"/root/syslog-harness-repo/router/route_v2.py":{"size":3954,"mtime_ns":1781121183851788825,"word_count":435,"hash":"e96ac2ae879e0a876d4190daff4cc566d13798b97c4820f3efa47e06627bbbcb"},"/root/syslog-harness-repo/router/route_v3.py":{"size":4703,"mtime_ns":1781121183851788825,"word_count":504,"hash":"30b202626b1f50da90b78272001e253cc7086b0bdc52e46553414c5313e3fb4e"},"/root/syslog-harness-repo/router/router.py":{"size":44307,"mtime_ns":1781316813360201927,"word_count":4198,"hash":"9c6817ae09f6bb5b2862f0282cacab7d4ce5da051e4ddc95e2e4099c7bf09716"},"/root/syslog-harness-repo/ssl/README.md":{"size":204,"mtime_ns":1781121183851788825,"word_count":28}}
File diff suppressed because it is too large Load Diff
+18 -86
View File
@@ -1,89 +1,21 @@
general_settings:
master_key: os.environ/LITELLM_MASTER_KEY
store_model_in_db: true
guardrails:
- guardrail_name: input-moderation
litellm_params:
guardrail: openai_moderation
mode: pre_call
- guardrail_name: output-moderation
litellm_params:
guardrail: openai_moderation
mode: post_call
- guardrail_name: harmful-content-filter
litellm_params:
categories:
- action: BLOCK
category: harmful_self_harm
enabled: true
severity_threshold: medium
- action: BLOCK
category: harmful_violence
enabled: true
severity_threshold: medium
- action: BLOCK
category: harmful_illegal_weapons
enabled: true
severity_threshold: medium
guardrail: litellm_content_filter
mode: pre_call
litellm_settings:
failure_callback:
- prometheus
model_cost:
gemma-4-12b:
input_cost_per_token: 0.0
output_cost_per_token: 0.0
qwen3.6-27B-code:
input_cost_per_token: 0.0
output_cost_per_token: 0.0
qwen3.6-35B-A3B:
input_cost_per_token: 0.0
output_cost_per_token: 0.0
syslog-auto:
input_cost_per_token: 0.0
output_cost_per_token: 0.0
num_retries: 0
request_timeout: 600
set_verbose: true
sso_callback: /sso/callback
model_list: model_list:
- litellm_params: - model_name: qwen3.6-35B-A3B
api_base: http://router:9000/v1 litellm_params:
api_key: os.environ/ROUTER_API_KEY
model: openai/syslog-auto
rpm: 600
model_name: syslog-auto
- litellm_params:
api_base: http://router:9000/v1
api_key: os.environ/ROUTER_API_KEY
model: openai/qwen3.6-35B-A3B model: openai/qwen3.6-35B-A3B
model_name: qwen3.6-35B-A3B api_base: http://192.168.68.15:8080/v1
- litellm_params: api_key: not-needed
api_base: http://router:9000/v1 - model_name: gpu-dense
api_key: os.environ/ROUTER_API_KEY litellm_params:
model: openai/qwen3.6-27B-code model: openai/qwen3.6-27B-code-text
model_name: qwen3.6-27B-code api_base: http://192.168.68.8:8080/v1
- litellm_params: api_key: not-needed
api_base: http://router:9000/v1 - model_name: gpu-light
api_key: os.environ/ROUTER_API_KEY litellm_params:
model: openai/gemma-4-12b model: openai/gemma-4-12b
model_name: gemma-4-12b api_base: http://192.168.68.110:8080/v1
router_settings: api_key: not-needed
allowed_fails: 100 general_settings:
enable_loadbalancing_on_proxy: false master_key: sk-syslog-local-master-key
fallbacks: litellm_settings:
- syslog-auto: drop_params: true
- qwen3.6-35B-A3B request_timeout: 120
- qwen3.6-27B-code
- gemma-4-12b
- qwen3.6-35B-A3B:
- qwen3.6-27B-code
- gemma-4-12b
- qwen3.6-27B-code:
- qwen3.6-35B-A3B
- gemma-4-12b
- gemma-4-12b:
- qwen3.6-27B-code
- qwen3.6-35B-A3B
routing_strategy: usage-based-routing
+25
View File
@@ -0,0 +1,25 @@
model_list:
- model_name: qwen3.6-35B-A3B
litellm_params:
model: openai/qwen3.6-35B-A3B
api_base: http://192.168.68.15:8080/v1
api_key: "not-needed"
- model_name: qwen3.6-27B-code
litellm_params:
model: openai/qwen3.6-27B-code-text
api_base: http://192.168.68.8:8080/v1
api_key: "not-needed"
- model_name: gemma-4-12b
litellm_params:
model: openai/gemma-4-12b
api_base: http://192.168.68.110:8080/v1
api_key: "not-needed"
general_settings:
master_key: sk-syslog-local-master-key
litellm_settings:
drop_params: true
request_timeout: 120
+56 -112
View File
@@ -1,51 +1,39 @@
events { worker_processes auto;
worker_connections 1024; error_log /var/log/nginx/error.log warn;
} pid /var/run/nginx.pid;
events { worker_connections 1024; }
http { http {
include /etc/nginx/mime.types; include /etc/nginx/mime.types;
default_type application/octet-stream; default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" rt=$request_time';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log;
sendfile on; sendfile on;
keepalive_timeout 65; keepalive_timeout 65;
# Docker DNS resolver — forces request-time resolution for variable-based proxy_pass. upstream router_api { server host.docker.internal:9000; }
# Without this, nginx resolves upstream hostnames at config load time, upstream dashboard_ui { server dashboard:3000; }
# which fails when Docker DNS (127.0.0.11) isn't ready yet on container start. upstream litellm_backend { server litellm:4000; }
resolver 127.0.0.11 valid=30s;
# Dynamic upstream resolution via nginx variables.
# Using $var in proxy_pass forces request-time resolution through the resolver.
# Without this, 'host not found in upstream' crashes nginx when Docker DNS is slow.
map $host $router_api_url {
default http://harness-router:9000;
}
map $host $dashboard_ui_url {
default http://harness-dashboard:3000;
}
map $host $litellm_backend_url {
default http://harness-litellm:4000;
}
# ════════════════════════════════════════════════════════════════
# Server :80 — harness entrypoint
# dashboard (/), router API (/v1/, /admin/, /stream, /api/, /metrics),
# router fallback, health
# ════════════════════════════════════════════════════════════════
server { server {
listen 80; listen 80;
# Authentik OIDC subrequest # Security headers
location /authentik/auth { add_header X-Content-Type-Options nosniff always;
internal; add_header X-Frame-Options SAMEORIGIN always;
proxy_pass https://auth.sysloggh.net/outpost.goauthentik.io/auth/nginx; add_header X-XSS-Protection "1; mode=block" always;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 2-Layer: /v1/ → router (existing keys work unchanged) # Disable buffering for SSE streams
proxy_buffering off;
# API through router
location /v1/ { location /v1/ {
proxy_pass $router_api_url; proxy_pass http://router_api;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
@@ -53,122 +41,78 @@ http {
proxy_connect_timeout 10s; proxy_connect_timeout 10s;
proxy_read_timeout 600s; proxy_read_timeout 600s;
proxy_buffering off; proxy_buffering off;
error_page 502 503 = @router_fallback;
}
location @router_fallback {
proxy_pass $router_api_url;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Authorization $http_authorization;
proxy_read_timeout 600s;
} }
location /admin/ { location /admin/ {
proxy_pass $router_api_url; proxy_pass http://router_api;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Authorization $http_authorization; proxy_set_header Authorization $http_authorization;
proxy_read_timeout 600s;
} }
# SSE streaming endpoint
location /stream { location /stream {
proxy_pass $router_api_url/stream; proxy_pass http://router_api;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header Connection "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off; proxy_buffering off;
chunked_transfer_encoding off;
} }
# Dashboard API proxy for SSE
location /api/ { location /api/ {
proxy_pass $router_api_url/; proxy_pass http://dashboard_ui;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Host $host; proxy_set_header Host $host;
}
location /dashboard/ {
proxy_pass $dashboard_ui_url/;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
# LiteLLM redirect target /litellm (no trailing slash) -> add slash back
location = /litellm {
return 301 /litellm/;
}
# LiteLLM static assets (Next.js chunks, CSS, fonts)
location /litellm-asset-prefix/ {
proxy_pass $litellm_backend_url;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_connect_timeout 10s;
proxy_read_timeout 60s;
}
# LiteLLM admin UI and API proxy — strip /litellm prefix so /litellm/ui/ → /ui/
location /litellm/ {
rewrite ^/litellm(/.*)$ $1 break;
proxy_pass $litellm_backend_url;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off; proxy_buffering off;
} }
# Auth proxy to Authentik — accepts HTTP from LiteLLM, proxies HTTPS to .11 with SSL verify off # LiteLLM debug
location /application/o/ { location /litellm/ {
proxy_pass https://192.168.68.11; rewrite ^/litellm/(.*) /$1 break;
proxy_ssl_verify off; proxy_pass http://litellm_backend;
proxy_set_header Host auth.sysloggh.net; proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host;
proxy_connect_timeout 10s; proxy_set_header Authorization $http_authorization;
proxy_read_timeout 30s;
} }
# All other requests → 404 # Professional Dashboard (Phase 1-3) - Static HTML served via Nginx
location /dashboard/ {
alias /opt/inference-harness/dashboard/;
index dashboard.html;
add_header Cache-Control "public, max-age=3600";
add_header X-Content-Type-Options nosniff;
}
# Legacy Dashboard (root) - Proxy to Flask app
location / { location / {
return 404; proxy_pass http://dashboard_ui;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_buffering off;
} }
# Performance analytics
location /metrics/ { location /metrics/ {
proxy_pass $router_api_url/metrics/; proxy_pass http://router_api;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Host $host; proxy_set_header Host $host;
} }
# Circuit Breaker metrics (Phase 1)
location /metrics/circuit-breaker { location /metrics/circuit-breaker {
proxy_pass $router_api_url/metrics/circuit-breaker; proxy_pass http://router_api/metrics/circuit-breaker;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
location /router/ {
proxy_pass $router_api_url/;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
location /health/unified {
proxy_pass $router_api_url/health/unified;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Host $host; proxy_set_header Host $host;
} }
location /health { location /health {
proxy_pass $router_api_url/health; proxy_pass http://router_api/health;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
} }
} }
} }