#!/usr/bin/env python3 """Smoke test: a few direct (non-batch) calls per tier to validate schemas and measure token usage. Usage: WP20_ENV_FILE=/path/to/.env .venv/bin/python scripts/03_smoke_test.py [n_listings] [n_images] """ import json import sys from pathlib import Path import pandas as pd sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from src.extraction import client as C # noqa: E402 from src.extraction.textprep import build_text # noqa: E402 from src.feature_schema.schema import IMAGE_SCHEMA, TEXT_SCHEMA # noqa: E402 ROOT = Path(__file__).resolve().parents[1] n_l = int(sys.argv[1]) if len(sys.argv) > 1 else 2 n_i = int(sys.argv[2]) if len(sys.argv) > 2 else 3 smp = pd.read_parquet(ROOT / "data" / "processed" / "sample.parquet").head(n_l) usage = [] for r in smp.itertuples(): print(f"\n=== {r.uid} | {r.source} | {r.roll_municipalite} | built {r.roll_year_built} | {r.roll_floor_area_m2} m² | ${r.price:,.0f}") for tier in ["haiku", "sonnet"]: for i, url in enumerate(list(r.image_urls_used)[:n_i]): out = C.direct(C.image_request(tier, url, IMAGE_SCHEMA), tag="smoke") if out["ok"]: d = out["data"] print(f" [{tier}] img{i} {d['scene']:24s} q{d['photo_quality']} ext{d['exterior_condition']} int{d['interior_condition']} " f"kit={d['kitchen_grade']} clad={d['cladding']} conf={d['confidence']:.2f} | {d['evidence'][:70]} | tok {out['usage']}") usage.append({"tier": tier, "kind": "image", **out["usage"]}) else: print(f" [{tier}] img{i} FAILED {out.get('error')} {out.get('stop_reason')}") text, stats = build_text(r._asdict()) for tier in ["haiku", "sonnet"]: out = C.direct(C.text_request(tier, text, TEXT_SCHEMA), tag="smoke") if out["ok"]: d = out["data"] print(f" [{tier}] TEXT clad={d['cladding']} roof={d['roof_covering']} kit={d['kitchen_grade']} cond={d['condition_claim']} " f"reno={d['renovation_claim']} yb={d['year_built_claim']} area={d['living_area_claim_sqft']} price_leak={d['price_or_assessment_mentioned']} | tok {out['usage']} | mask {stats}") usage.append({"tier": tier, "kind": "text", **out["usage"]}) else: print(f" [{tier}] TEXT FAILED {out.get('error')}") u = pd.DataFrame(usage) print("\nmean tokens per call:\n", u.groupby(["tier", "kind"])[["input_tokens", "output_tokens"]].mean().round(0))