"""Live integration test for the pi agent wrapper (SPEC §16 DoD).

Gated behind ``ATTRACTOR_LIVE_LLM=1`` so CI (and any contributor
without provider credentials configured for pi) skips it cleanly. Per
SPEC §16, this is the one mandatory live test for the agent module —
proof the wrapper drives a real ``pi --mode rpc`` session and the
model can call ``report_outcome``.

Pick the provider/model with ``ATTRACTOR_LIVE_MODEL`` (default
``anthropic/claude-haiku-4-5``). pi resolves the credential itself
(env var or ``~/.pi/agent/auth.json``), so authenticate pi first:

    pi --provider anthropic   # or `pi` then `/login`

Invoke it manually with::

    ATTRACTOR_LIVE_LLM=1 uv run pytest tests/test_agent/test_live.py -v

Cost target: a single small-model call, ``max_turns=4``, extremely
short prompt. Expect <$0.01 per run.
"""

from __future__ import annotations

import os
import shutil
from pathlib import Path

import pytest

from attractor.agent import AgentConfig, OutcomeStatus, run_agent_node

LIVE_ENV_VAR = "ATTRACTOR_LIVE_LLM"
MODEL_ENV_VAR = "ATTRACTOR_LIVE_MODEL"
DEFAULT_MODEL = "anthropic/claude-haiku-4-5"


# [int->REQ-AGENT-TOOLS-V01]
# [int->REQ-AGENT-SESSION-API]
# [int->REQ-LLM-AUTH-ENV]
@pytest.mark.asyncio
async def test_report_outcome_reaches_outcome(tmp_path: Path) -> None:
    """Real pi round-trip: model invokes report_outcome("SUCCESS", "done")."""
    if os.environ.get(LIVE_ENV_VAR) != "1":
        pytest.skip(
            f"Set {LIVE_ENV_VAR}=1 (and authenticate pi) to run the live "
            "pi agent test."
        )
    if shutil.which("pi") is None:
        pytest.skip("pi binary not on PATH; cannot run live test.")

    config = AgentConfig(
        model=os.environ.get(MODEL_ENV_VAR, DEFAULT_MODEL),
        workflow_goal="Smoke test the wrapper.",
        node_prompt=(
            "Reply with the word 'ok' and then call the `report_outcome` "
            "tool with outcome='SUCCESS' and reason='done'. Do nothing else."
        ),
        cwd=tmp_path,
        max_turns=4,
        timeout_seconds=120.0,
    )

    outcome = await run_agent_node(config)

    assert outcome.status == OutcomeStatus.SUCCESS, (
        f"expected success path (b) via report_outcome, got: {outcome}"
    )
    assert outcome.captured_output == "done", (
        f"captured_output should be the report_outcome reason, "
        f"got: {outcome.captured_output!r}"
    )
    assert outcome.usage_input_tokens > 0, "expected pi to report usage"
    assert outcome.usage_output_tokens > 0, "expected pi to report usage"
