"""Complete native tool rounds. Python 3.8+, pip install requests."""
import argparse
import copy
import json
import os

import requests

PARAMETERS = {"type": "object", "properties": {"order_id": {"type": "string"}}, "required": ["order_id"], "additionalProperties": False}
DESCRIPTION = "Find an order's shipping information using its order_id."


def lookup_order(arguments):
    if not isinstance(arguments, dict) or set(arguments) != {"order_id"} or arguments["order_id"] != "A17":
        raise ValueError("Only the example order A17 is allowed")
    return {"order_id": "A17", "status": "shipped", "tracking": "YQ-TOOL-9241"}


def run_tools(protocol, model, key, prompt="Use lookup_order to find the tracking code for order A17. Return only its tracking code.", transport=None):
    if protocol == "gemini":
        raise ValueError("Gemini native function-result continuation is not in the current YunQi integration contract")
    history = [{"role": "user", "content": prompt}]
    used = []
    for turn in range(4):
        if protocol == "responses":
            route = "/v1/responses"
            body = {"model": model, "input": history, "max_output_tokens": 8192, "tools": [{"type": "function", "name": "lookup_order", "description": DESCRIPTION, "parameters": PARAMETERS, "strict": True}]}
            headers = {"Authorization": "Bearer " + key}
        elif protocol == "messages":
            route = "/v1/messages"
            body = {"model": model, "messages": history, "max_tokens": 8192, "tools": [{"name": "lookup_order", "description": DESCRIPTION, "input_schema": PARAMETERS}]}
            headers = {"x-api-key": key, "anthropic-version": "2023-06-01"}
        else:
            route = "/v1/chat/completions"
            body = {"model": model, "messages": history, "max_tokens": 8192, "tools": [{"type": "function", "function": {"name": "lookup_order", "description": DESCRIPTION, "parameters": PARAMETERS}}]}
            headers = {"Authorization": "Bearer " + key}
        if transport:
            data = transport(turn, route, copy.deepcopy(body))
        else:
            response = requests.post("https://www.yunqiai.chat" + route, headers=headers, json=body, allow_redirects=False, timeout=(15, 300))
            if not 200 <= response.status_code < 300:
                raise RuntimeError("HTTP " + str(response.status_code) + ": " + response.text[:4000])
            data = response.json()
        if data.get("error"):
            raise RuntimeError("Tool round API error: " + json.dumps(data["error"], ensure_ascii=False))
        if protocol == "responses":
            if data.get("status") != "completed":
                raise RuntimeError("Responses tool round did not complete")
            output = data.get("output", [])
            calls = [item for item in output if item.get("type") == "function_call"]
            history.extend(output)
            text = "".join(p.get("text", "") for item in output if item.get("type") == "message" for p in item.get("content", []) if p.get("type") == "output_text")
            for call in calls:
                if call.get("name") != "lookup_order":
                    raise ValueError("Unapproved function")
                result = lookup_order(json.loads(call["arguments"]))
                used.append(call["name"])
                history.append({"type": "function_call_output", "call_id": call["call_id"], "output": json.dumps(result)})
        elif protocol == "messages":
            if data.get("stop_reason") not in ["end_turn", "tool_use"]:
                raise RuntimeError("Messages tool round truncated or interrupted")
            blocks = data.get("content", [])
            calls = [block for block in blocks if block.get("type") == "tool_use"]
            history.append({"role": "assistant", "content": blocks})
            text = "".join(block.get("text", "") for block in blocks if block.get("type") == "text")
            results = []
            for call in calls:
                if call.get("name") != "lookup_order":
                    raise ValueError("Unapproved function")
                result = lookup_order(call["input"])
                used.append(call["name"])
                results.append({"type": "tool_result", "tool_use_id": call["id"], "content": json.dumps(result)})
            if results:
                history.append({"role": "user", "content": results})
        else:
            choices = data.get("choices", [])
            if not choices or choices[0].get("finish_reason") not in ["stop", "tool_calls"]:
                raise RuntimeError("Chat tool round did not complete")
            message = choices[0]["message"]
            calls = message.get("tool_calls") or []
            history.append(message)
            text = message.get("content") or ""
            for call in calls:
                if call.get("function", {}).get("name") != "lookup_order":
                    raise ValueError("Unapproved function")
                result = lookup_order(json.loads(call["function"]["arguments"]))
                used.append(call["function"]["name"])
                history.append({"role": "tool", "tool_call_id": call["id"], "content": json.dumps(result)})
        if not calls:
            if not used or not text.strip():
                raise RuntimeError("No complete tool-execution-and-answer round")
            return {"text": text, "tools_used": used, "turns": turn + 1}
    raise RuntimeError("Tool round limit reached")


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("protocol", choices=["responses", "messages", "chat"])
    args = parser.parse_args()
    print(json.dumps(run_tools(args.protocol, os.environ["YUNQIAI_MODEL"], os.environ["YUNQIAI_API_KEY"]), ensure_ascii=False))
