from __future__ import annotations
import json
import threading
import webbrowser
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from pathlib import Path
HOST = "127.0.0.1"
PORT = 8765
SETTINGS_PATH = Path(__file__).with_name("local_settings.json")
PAGE = """
Gemma Heretic Demo Settings
Gemma Heretic Demo Settings
These defaults apply the next time the local app starts.
"""
class SettingsHandler(BaseHTTPRequestHandler):
def _send(self, status: int, content_type: str, body: bytes) -> None:
self.send_response(status)
self.send_header("Content-Type", content_type)
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def do_GET(self) -> None:
if self.path == "/":
self._send(200, "text/html; charset=utf-8", PAGE.encode())
return
if self.path == "/api/settings":
self._send(200, "application/json", SETTINGS_PATH.read_bytes())
return
self._send(404, "text/plain", b"Not found")
def do_POST(self) -> None:
if self.path != "/api/settings":
self._send(404, "text/plain", b"Not found")
return
length = int(self.headers.get("Content-Length", "0"))
try:
data = json.loads(self.rfile.read(length))
required = {
"model_id",
"system_prompt",
"thinking",
"max_new_tokens",
"temperature",
"top_p",
"top_k",
"repetition_penalty",
"max_input_tokens",
"history_messages",
}
if set(data) != required:
raise ValueError("Unexpected settings fields.")
SETTINGS_PATH.write_text(
json.dumps(data, indent=2, ensure_ascii=False) + "\n",
encoding="utf-8",
)
except (ValueError, TypeError, json.JSONDecodeError):
self._send(400, "application/json", b'{"ok":false}')
return
self._send(200, "application/json", b'{"ok":true}')
def log_message(self, format: str, *args: object) -> None:
return
if __name__ == "__main__":
server = ThreadingHTTPServer((HOST, PORT), SettingsHandler)
url = f"http://{HOST}:{PORT}"
threading.Timer(0.4, webbrowser.open, args=(url,)).start()
print(f"Settings page: {url}")
print("Press Ctrl+C to stop.")
server.serve_forever()