"""01_from_scratch.py, the SAME agent, hand-rolled (no framework).

The agent: one tool, multiply(a, b), asked "What is 23 times 17?".
This is the baseline. Every framework file in this folder builds THIS agent a different way, read this first so you can see what the frameworks are doing for you (and what they hide).

A "tool-using agent" is just this loop:
    ask the model -> if it wants a tool, run the tool, give back the result -> repeat -> final answer.
That loop is the whole idea (M9). Frameworks = ergonomics on top of it.

Run (venv active, key in .env):
    python 01_from_scratch.py
"""

import os
from dotenv import load_dotenv
import anthropic

load_dotenv()
MODEL = "claude-opus-4-8"
TASK = "What is 23 times 17? Use the multiply tool."

TOOLS = [{
    "name": "multiply",
    "description": "Multiply two integers and return the product.",
    "input_schema": {
        "type": "object",
        "properties": {"a": {"type": "integer"}, "b": {"type": "integer"}},
        "required": ["a", "b"],
    },
}]


def multiply(a, b):
    return a * b


def run(task=TASK, client=None):
    """Hand-rolled ReAct tool loop. Returns the model's final text answer."""
    client = client or anthropic.Anthropic()
    messages = [{"role": "user", "content": task}]
    while True:
        resp = client.messages.create(model=MODEL, max_tokens=1024, tools=TOOLS, messages=messages)
        messages.append({"role": "assistant", "content": resp.content})

        if resp.stop_reason == "tool_use":
            results = []
            for block in resp.content:                      # run every tool the model asked for
                if getattr(block, "type", None) == "tool_use":
                    out = multiply(**block.input)            # <- we execute the tool ourselves
                    results.append({"type": "tool_result", "tool_use_id": block.id,
                                    "content": str(out)})
            messages.append({"role": "user", "content": results})
            continue                                         # loop back with the tool results

        return "".join(b.text for b in resp.content if getattr(b, "type", None) == "text")


if __name__ == "__main__":
    print(run())
