"""Three paid requests only with --live; otherwise local self-tests.
Save beside checkpoint_demo.py. Set OFOX_API_KEY; run in a new empty directory.
This small demonstration is read-only, not a production transaction runner.
"""
import json, os, pathlib, sys, urllib.request, urllib.error
import checkpoint_demo as demo

def run():
    if sys.argv[1:] != ["--live"]:
        demo.self_test()
        print("No API calls. Use --live explicitly to run three paid requests.")
        return
    key = os.environ["OFOX_API_KEY"]
    out = pathlib.Path("handoff-run")
    out.mkdir(exist_ok=False)  # Prevent automatic replay of an existing run.
    count = 0
    def call(name, body):
        nonlocal count
        raw = json.dumps(body, ensure_ascii=True).encode()
        if count >= 3 or len(raw) > 6000 or body["max_tokens"] > 4096:
            raise ValueError("Demo request bound exceeded")
        count += 1
        (out / (name + "-request.json")).write_bytes(raw)
        request = urllib.request.Request(
            "https://api.ofox.ai/anthropic/v1/messages", data=raw,
            headers={"x-api-key": key, "anthropic-version": "2023-06-01",
                     "content-type": "application/json"}, method="POST")
        try:
            with urllib.request.urlopen(request, timeout=180) as response:
                data = response.read()
        except urllib.error.HTTPError as error:
            (out / (name + "-error.json")).write_bytes(error.read())
            raise SystemExit("HTTP error; inspect saved response. No retry performed.")
        except (OSError, TimeoutError):
            (out / (name + "-uncertain.txt")).write_text("No complete response; billing may have occurred. No retry performed.")
            raise
        (out / (name + "-response.json")).write_bytes(data)
        result = json.loads(data)
        if "error" in result:
            raise ValueError("Error response; inspect saved file")
        return result

    tools = [{"name": "read_stock", "description": "Read all rows of the synthetic stock fixture; read only, no orders.",
              "input_schema": {"type": "object", "properties": {}, "additionalProperties": False}}]
    messages = [{"role": "user", "content": "Use read_stock to inspect all synthetic stock rows, then report shortage=max(target-available,0) for every SKU. Do not place orders. You must obtain the tool data before answering."}]
    body = {"model": "anthropic/claude-fable-5.2", "max_tokens": 4096,
            "output_config": {"effort": "low"},
            "system": "Read-only inventory analyst. Use verified tool data and keep all SKU IDs. Never place orders.",
            "tools": tools, "tool_choice": {"type": "auto"}, "messages": messages}
    first = call("01-fable-tool", body)
    calls = [b for b in first.get("content", []) if b.get("type") == "tool_use"]
    if first.get("stop_reason") != "tool_use" or len(calls) != 1:
        raise ValueError("Expected exactly one completed tool call; do not assume a lookup occurred")
    tool = calls[0]
    if tool.get("name") != "read_stock" or tool.get("input") != {} or not tool.get("id"):
        raise ValueError("Unexpected tool or arguments")
    messages.append({"role": "assistant", "content": first["content"]})
    messages.append({"role": "user", "content": [{"type": "tool_result", "tool_use_id": tool["id"], "content": json.dumps(demo.ROWS)}]})
    cp = demo.checkpoint(demo.ROWS)
    demo.verify_checkpoint(cp, demo.ROWS)
    (out / "checkpoint.json").write_text(json.dumps(cp, indent=2))
    continued = call("02-fable-continuation", body)
    if continued.get("stop_reason") != "end_turn":
        raise ValueError("Fable continuation incomplete; inspect saved response")
    received = call("03-opus-handoff", {
        "model": "anthropic/claude-opus-5.5", "max_tokens": 4096,
        "output_config": {"effort": "low"},
        "messages": [{"role": "user", "content": demo.handoff(cp)}]})
    if received.get("stop_reason") != "end_turn":
        raise ValueError("Receiving model did not complete")
    text = "\n".join(b["text"] for b in received.get("content", []) if b.get("type") == "text")
    result = json.loads(text)
    verdict = demo.validate(result, demo.ROWS)
    (out / "result.json").write_text(json.dumps(result, indent=2))
    (out / "verdict.json").write_text(json.dumps(verdict, indent=2))
    print(json.dumps(verdict))

if __name__ == "__main__":
    run()
