| |
| """Opal Router — the architecture-agnostic "merge" of un-mergeable models. |
| |
| Different architectures (Llama / gpt-oss / Phi / Gemma / Liquid) cannot be |
| weight-merged. So Opal combines them at the SYSTEM level: one OpenAI-compatible |
| endpoint that classifies each request and routes it to the US specialist best |
| suited to it — Llama for tool-calling, gpt-oss for hard reasoning, the Opal-8B |
| merge for code/security, Phi for general, a VLM for images. |
| |
| Zero dependencies (stdlib only). Runs locally over Ollama. No training. |
| |
| python opal_router.py # serves http://localhost:11500/v1 |
| # point any OpenAI client at it with model="opal" |
| |
| Env: OLLAMA=http://localhost:11434 PORT=11500 |
| """ |
| import json, os, re, urllib.request |
| from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer |
|
|
| ROOT = os.path.dirname(os.path.abspath(__file__)) |
| OLLAMA = os.environ.get("OLLAMA", "http://localhost:11434") |
| PORT = int(os.environ.get("PORT", "11500")) |
| ROUTES = json.load(open(os.path.join(ROOT, "configs", "routes.json")))["routes"] |
|
|
| CODE_RE = re.compile(r"```|\b(def |class |function|refactor|debug|implement|" |
| r"compile|stack ?trace|regex|SQL|python|javascript|rust|" |
| r"golang|typescript|unit test|api endpoint)\b", re.I) |
| REASON_RE = re.compile(r"\b(prove|proof|step by step|reason|derive|solve|" |
| r"why does|how many|calculate|logic|theorem|explain why|" |
| r"think through|chain of thought)\b", re.I) |
| SEC_RE = re.compile(r"\b(vulnerabilit|exploit|CVE|malware|detection|sigma rule|" |
| r"threat model|beacon|firmware|reverse engineer|yara)\b", re.I) |
|
|
|
|
| def available_models(): |
| try: |
| with urllib.request.urlopen(f"{OLLAMA}/api/tags", timeout=10) as r: |
| return {m["name"] for m in json.loads(r.read()).get("models", [])} |
| except Exception: |
| return set() |
|
|
|
|
| def classify(body): |
| """Return a capability key for this request.""" |
| if body.get("tools") or body.get("functions"): |
| return "tool" |
| msgs = body.get("messages", []) |
| |
| for m in msgs: |
| c = m.get("content") |
| if isinstance(c, list) and any( |
| isinstance(b, dict) and b.get("type") in ("image_url", "image") |
| for b in c): |
| return "vision" |
| text = " ".join(m.get("content", "") for m in msgs |
| if isinstance(m.get("content"), str))[-4000:] |
| if SEC_RE.search(text) or CODE_RE.search(text): |
| return "code" |
| if REASON_RE.search(text): |
| return "reasoning" |
| return "general" |
|
|
|
|
| def pick_model(cap, avail): |
| want = ROUTES.get(cap, ROUTES["default"]) |
| if want in avail or f"{want}:latest" in avail: |
| return want |
| return ROUTES["default"] |
|
|
|
|
| def forward(body): |
| data = json.dumps(body).encode() |
| req = urllib.request.Request(f"{OLLAMA}/v1/chat/completions", data=data, |
| headers={"Content-Type": "application/json", |
| "Authorization": "Bearer ollama"}) |
| with urllib.request.urlopen(req, timeout=900) as r: |
| return r.read() |
|
|
|
|
| class Handler(BaseHTTPRequestHandler): |
| def log_message(self, *a): |
| pass |
|
|
| def _send(self, code, payload, ctype="application/json"): |
| self.send_response(code) |
| self.send_header("Content-Type", ctype) |
| self.end_headers() |
| self.wfile.write(payload if isinstance(payload, bytes) else payload.encode()) |
|
|
| def do_GET(self): |
| if self.path.rstrip("/").endswith("/models"): |
| self._send(200, json.dumps({"object": "list", "data": [ |
| {"id": "opal", "object": "model", "owned_by": "cognis-digital"}]})) |
| else: |
| self._send(200, json.dumps({"status": "ok", "routes": ROUTES})) |
|
|
| def do_POST(self): |
| n = int(self.headers.get("Content-Length", 0)) |
| try: |
| body = json.loads(self.rfile.read(n) or b"{}") |
| except Exception: |
| return self._send(400, json.dumps({"error": "bad json"})) |
| avail = available_models() |
| cap = classify(body) |
| model = pick_model(cap, avail) |
| body["model"] = model |
| body["stream"] = False |
| print(f"[opal] route={cap:9} -> {model}", flush=True) |
| try: |
| out = forward(body) |
| except Exception as e: |
| return self._send(502, json.dumps({"error": str(e)})) |
| |
| try: |
| j = json.loads(out) |
| j.setdefault("x_opal", {})["route"] = cap |
| j["x_opal"]["model"] = model |
| out = json.dumps(j).encode() |
| except Exception: |
| pass |
| self._send(200, out) |
|
|
|
|
| if __name__ == "__main__": |
| print(f"Opal Router on :{PORT} -> Ollama {OLLAMA}") |
| print("routes:", json.dumps(ROUTES)) |
| print("available:", sorted(available_models())) |
| ThreadingHTTPServer(("0.0.0.0", PORT), Handler).serve_forever() |
|
|