Files
esh-pfi-infrastructure/stacks/zed-fim-proxy/conf/proxy.py
T
vh a300cdcd26 feat: Zed edit-predictions keyless FIM route (Qwen2.5-Coder-1.5B / coder-fast)
Deep-research-picked Qwen2.5-Coder-1.5B (BASE, Apache-2.0, native FIM) as a
low-latency inline-completion seat:
- stacks/vllm: vllm-coder service (ana-ml2 GPU1 :8020) + granite shrunk
  (util 0.27->0.13, max-len 131072->16384, seqs 1024->256; granite phasing out)
  to free GPU1 room.
- stacks/litellm: coder-fast alias -> :8020 (mode: completion, /v1/completions).
- stacks/zed-fim-proxy (NEW): keyless /v1/completions front door on ana-docker
  :4141 for Zed (which can't send an auth header) — POST + path + model
  allowlist, injects a coder-fast-scoped virtual key -> LiteLLM :4000. Anon
  /ping liveness. Verified keyless FIM end-to-end.

Zed api_url = http://10.250.50.70:4141/v1, model coder-fast, prompt_format qwen.
Source-IP allowlist off pending the Mac's observed source IP.
2026-07-27 22:55:21 -07:00

103 lines
4.6 KiB
Python

"""zed-fim-proxy — a keyless front door for Zed's edit-prediction feature.
Zed's edit_predictions.open_ai_compatible_api provider cannot send an
Authorization header, so it needs a route where POST /v1/completions succeeds
with no key. This proxy is that route, on a separate port from LiteLLM, with
four narrow guards + an injected model-scoped key:
1. POST only, path exactly /v1/completions (GET /ping is an anonymous liveness).
2. source-IP allowlist (best-effort — set ZED_ALLOWED_IPS; empty = allow all).
NOTE: only meaningful if this process sees the real client IP — run the
container with network_mode: host (docker port-publish would NAT the source
to the bridge gateway and defeat it). Behind a site-to-site NAT it may still
see a mesh IP, not the Mac — verify against the access log at deploy.
3. request body "model" must equal ZED_ALLOWED_MODEL (default coder-fast).
4. injects Authorization: Bearer $ZED_SCOPED_KEY (a LiteLLM virtual key scoped
to that ONE model) and forwards to $ZED_UPSTREAM. The scoped key is the real
blast-radius bound: even if guards 1-3 were bypassed, the key can reach
nothing but coder-fast.
Stdlib only (no pip) — runs in a bare python:slim container.
"""
import json
import os
import sys
import urllib.error
import urllib.request
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
UPSTREAM = os.environ.get("ZED_UPSTREAM", "http://localhost:4000").rstrip("/")
SCOPED_KEY = os.environ["ZED_SCOPED_KEY"]
ALLOWED_MODEL = os.environ.get("ZED_ALLOWED_MODEL", "coder-fast")
ALLOWED_IPS = set(x.strip() for x in os.environ.get("ZED_ALLOWED_IPS", "").split(",") if x.strip())
PORT = int(os.environ.get("ZED_PORT", "4141"))
TIMEOUT = float(os.environ.get("ZED_TIMEOUT", "60"))
class Handler(BaseHTTPRequestHandler):
server_version = "zed-fim-proxy/1.0"
def _json(self, code, obj):
body = json.dumps(obj).encode()
self.send_response(code)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def do_GET(self):
if self.path.rstrip("/") == "/ping":
return self._json(200, {"service": "ok"})
return self._json(404, {"error": "not found"})
def do_POST(self):
src = self.client_address[0]
if ALLOWED_IPS and src not in ALLOWED_IPS:
return self._json(403, {"error": f"source {src} not allowed"})
# Accept both /v1/completions and /completions so the Zed api_url can be
# set to either http://host:4141/v1 or http://host:4141 (Zed appends
# /completions). /v1/chat/completions is NOT in the set → stays rejected.
if self.path.split("?")[0].rstrip("/") not in ("/v1/completions", "/completions"):
return self._json(404, {"error": "only POST /v1/completions or /completions"})
try:
length = int(self.headers.get("Content-Length", 0))
except ValueError:
return self._json(400, {"error": "bad content-length"})
raw = self.rfile.read(length)
try:
body = json.loads(raw)
except Exception:
return self._json(400, {"error": "invalid json body"})
if body.get("model") != ALLOWED_MODEL:
return self._json(403, {"error": f"model must be '{ALLOWED_MODEL}'"})
req = urllib.request.Request(
UPSTREAM + "/v1/completions",
data=raw,
method="POST",
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {SCOPED_KEY}",
},
)
try:
with urllib.request.urlopen(req, timeout=TIMEOUT) as r:
data, code, ctype = r.read(), r.status, r.headers.get("Content-Type", "application/json")
except urllib.error.HTTPError as e:
data, code, ctype = e.read(), e.code, e.headers.get("Content-Type", "application/json")
except Exception as e: # noqa: BLE001
return self._json(502, {"error": f"upstream error: {e}"})
self.send_response(code)
self.send_header("Content-Type", ctype)
self.send_header("Content-Length", str(len(data)))
self.end_headers()
self.wfile.write(data)
def log_message(self, fmt, *args):
sys.stderr.write("%s - %s\n" % (self.client_address[0], fmt % args))
if __name__ == "__main__":
print(f"zed-fim-proxy on :{PORT} -> {UPSTREAM} (model={ALLOWED_MODEL}, "
f"ip-allowlist={'set' if ALLOWED_IPS else 'OFF'})", flush=True)
ThreadingHTTPServer(("0.0.0.0", PORT), Handler).serve_forever()