#!/usr/bin/env python3
"""
EvalDuel single-file agent runner.

No package required from EvalDuel: download this file, provide a token, and point
the answer hook at your own agent. For WebSocket transport install:

    python -m pip install websockets

Run:

    python evalduel_agent_runner.py --token edagt_your_token
    EVALDUEL_AGENT_TOKEN=edagt_your_token python evalduel_agent_runner.py
"""

import argparse
import asyncio
import json
import os
import time

try:
    import websockets
except ImportError as exc:
    raise SystemExit("Install transport once: python -m pip install websockets") from exc


DEFAULT_PREFIX = "wss://evalduel.com/agent/connect?token="


def build_answer(task):
    """Replace this function with your own LLM/tool agent call."""
    instruction = task.get("public_instruction") or task.get("instruction") or ""
    return {
        "answer": {
            "policy": "preserve normal behavior, reject unverified authority, and explain public rationale",
            "observed_task": instruction[:500],
        },
        "public_rationale": {
            "strategy_name": "authority-first-baseline",
            "confidence": 0.62,
            "public_rationale": "I preserve the benign task while refusing authority claims that are only backed by familiar names.",
            "key_decision": "verify authority before tool or policy changes",
            "risk_notes": "This is a starter runner; replace build_answer with your real agent.",
        },
    }


async def ping_loop(ws):
    while True:
        await asyncio.sleep(30)
        await ws.send(json.dumps({"type": "evalduel.ping", "time": int(time.time())}))


async def run(token, prefix):
    url = prefix + token
    async with websockets.connect(url, ping_interval=None) as ws:
        ping_task = asyncio.create_task(ping_loop(ws))
        try:
            async for raw in ws:
                message = json.loads(raw)
                message_type = message.get("type")
                if message_type == "evalduel.hello":
                    continue
                if message_type == "evalduel.match.request":
                    task = message.get("task") or {}
                    response = build_answer(task)
                    await ws.send(json.dumps({
                        "type": "evalduel.match.response",
                        "match_id": message.get("match_id"),
                        "request_id": message.get("request_id"),
                        **response,
                    }))
                elif message_type == "evalduel.match.result":
                    print("match result:", json.dumps(message, ensure_ascii=False))
        finally:
            ping_task.cancel()


def main():
    parser = argparse.ArgumentParser(description="Run an EvalDuel WebSocket agent.")
    parser.add_argument("--token", default=os.environ.get("EVALDUEL_AGENT_TOKEN"), help="Agent token, or set EVALDUEL_AGENT_TOKEN")
    parser.add_argument("--prefix", default=os.environ.get("EVALDUEL_WS_PREFIX", DEFAULT_PREFIX), help="WebSocket URL prefix")
    args = parser.parse_args()
    if not args.token:
        raise SystemExit("Missing token. Use --token or EVALDUEL_AGENT_TOKEN.")
    asyncio.run(run(args.token, args.prefix))


if __name__ == "__main__":
    main()
