chalchitra / scripts /smoke_test.py
ajit3259's picture
test: add local smoke test for the oracle against LM Studio
872a93a
Raw
History Blame Contribute Delete
2.33 kB
"""Smoke-test the oracle against whatever provider is configured (LM Studio).
Generates a couple of moody synthetic images + a fragment, runs the full
interpret() flow, and pretty-prints the result. Lets us judge prompt/model
quality before any UI exists.
Usage:
.venv/bin/python -m scripts.smoke_test [model]
e.g.
.venv/bin/python -m scripts.smoke_test google/gemma-4-12b
"""
import base64
import io
import json
import os
import sys
import time
from PIL import Image, ImageDraw
from dotenv import load_dotenv
load_dotenv()
# Allow overriding the model from the CLI for quick A/B (e4b vs 12b).
if len(sys.argv) > 1:
os.environ["CHALCHITRA_MODEL"] = sys.argv[1]
from backend import interpret # noqa: E402 (after env setup)
from backend.providers import get_provider # noqa: E402
def moody_jpeg(top, bottom, blob=None) -> str:
"""A vertical gradient with an optional soft blob — enough texture for a read."""
w, h = 640, 480
img = Image.new("RGB", (w, h))
px = img.load()
for y in range(h):
t = y / h
px_row = tuple(int(top[i] * (1 - t) + bottom[i] * t) for i in range(3))
for x in range(w):
px[x, y] = px_row
if blob:
d = ImageDraw.Draw(img, "RGBA")
d.ellipse([w * 0.5, h * 0.25, w * 0.85, h * 0.6], fill=blob)
buf = io.BytesIO()
img.save(buf, format="JPEG", quality=72)
b64 = base64.b64encode(buf.getvalue()).decode()
return f"data:image/jpeg;base64,{b64}"
def main() -> None:
p = get_provider()
print(f"provider={p.name} model={getattr(p, 'model', '?')} "
f"base_url={getattr(p, 'base_url', 'n/a')}")
images = [
moody_jpeg((20, 24, 40), (90, 70, 60), blob=(255, 200, 120, 60)), # dusk / amber window
moody_jpeg((12, 14, 18), (40, 50, 70)), # blue night
]
fragment = "rain on the window, the city out of focus"
print(f"\nfragment: {fragment!r}\nimages: {len(images)} synthetic mood frames\n")
t0 = time.time()
result = interpret(images, fragment)
dt = time.time() - t0
print(json.dumps(result, indent=2, ensure_ascii=False))
print(f"\n--- {dt:.1f}s ---")
print(f"interpretation: {len(result['interpretation'])} chars, "
f"{len(result['films'])} films")
if __name__ == "__main__":
main()