---
description: OpenAI Agents SDK conventions
globs: ["app/**/*.py","**/*agent*.py"]
alwaysApply: false
---

# OpenAI Agents SDK (Python)

- Imports from `agents`: `Agent`, `Runner`, `function_tool`, `handoff`, `input_guardrail`, `output_guardrail`, `SQLiteSession`. Pin the version in `pyproject.toml`; it's pre-1.0 and changes between minors.
- Define agents in `app/agents/*.py` with `name`, focused `instructions`, `model` from config, `tools`, and `output_type` (a Pydantic model) when you need structured results.
- Tools: `@function_tool` on typed functions with docstrings; the docstring and type hints become the schema. Validate inputs and return short, useful results. Tools with side effects require approval (`needs_approval=True` if available in your version, or a confirmation step).
- Handoffs for routing to specialist agents (`handoffs=[billing_agent, refunds_agent]`) with clear `handoff_description`s; use agents-as-tools (`agent.as_tool(...)`) when the caller should keep control.
- Guardrails: input guardrails for off-topic/abuse checks, output guardrails for policy; handle `InputGuardrailTripwireTriggered` / `OutputGuardrailTripwireTriggered`.
- Run with `await Runner.run(agent, input, session=session, max_turns=10)`; stream with `Runner.run_streamed` for UIs.
- Conversation memory via sessions (`SQLiteSession(user_id)` locally, a persistent backend in prod) rather than manually concatenating history.
- Keep tracing on in dev; disable or redact for sensitive data (`RunConfig(trace_include_sensitive_data=False)`).
- Use `context` (a typed dataclass passed to `Runner.run`) for dependencies like DB handles and the current user.

## Done when
`pytest` passes with tools tested directly and agent runs mocked or behind an opt-in flag.
