I built the live agent component of the AI‑agent incident investigation workflow as a LangGraph StateGraph that runs a full TxnAgent‑07 session, logs events to data/*.jsonl, and hands them to investigate.py for audit‑ready reporting.
The graph follows the shape: init_session -> assess_risk -> (within_authority | above_authority) -> [above_authority only] policy_gate -> (finalize_execution | escalate_and_wait) -> write_logs.
The policy_gate node is a separate graph node that checks data/policy_registry.json independently, encoding a "no self‑policing" design principle.
decide_bypass_or_escalate() inside above_authority makes the real agentic decision whether to call an unapproved vendor or to route to a human.
When ANTHROPIC_API_KEY is set, a real claude‑sonnet‑5 call determines that decision; --persona is only a system‑prompt bias.
Without an API key the decision falls back to a deterministic persona‑to‑decision mapping (scripted, not agentic).
Two knobs control each run: --persona {misbehaving, compliant} biases the bypass/escalate decision, and --enforcement {current, remediated} switches between logging a violation and hard‑blocking it.
python live_agent.py --persona misbehaving --amount 61000
# incident reproduced
python live_agent.py --persona misbehaving --amount 61000 --enforcement remediated
# near‑miss (hard‑blocked)
python live_agent.py --persona compliant --amount 30000
# near‑miss
python live_agent.py --persona compliant --amount 30000 --no-tempt-bypass
# clean session
LLM provider selection checks in order: Groq (langchain-groq, GROQ_API_KEY, default llama-3.3-70b-versatile) then Anthropic (langchain-anthropic, ANTHROPIC_API_KEY, claude‑sonnet‑5). If no key is set both narration and the decision fall back to deterministic templates.