Harness.for_<framework>() factory wires the framework’s natural turn boundary to on_turn_end and preserves its session resolution (session identity comes from the PandaProbe SDK’s session context, so harness evaluations and SDK traces line up automatically).
| Factory | Framework | Turn detector | Extra |
|---|---|---|---|
Harness.for_langgraph() | LangGraph | LangChain callback: root on_chain_end (via harness.adapter.make_callback()) | [langgraph] |
Harness.for_langchain() | LangChain | Same root-chain-end callback | [langchain] |
Harness.for_deepagents() | DeepAgents | Same root-chain-end callback | [deepagents] |
Harness.for_crewai() | CrewAI | Patches Crew.kickoff (auto-instrument()) | [crewai] |
Harness.for_claude_agent_sdk() | Claude Agent SDK | Patches ClaudeSDKClient.receive_response — one stream = one turn | [claude-agent-sdk] |
Harness.for_openai_agents() | OpenAI Agents SDK | TracingProcessor — fires on trace end; one Runner.run = one turn | [openai-agents] |
- pip
- uv
session_id= (a fixed session for single-conversation processes), config=, cli=, and replay= for closed-loop validation.
LangGraph (LangChain & DeepAgents work the same way)
CrewAI
Claude Agent SDK
OpenAI Agents SDK
Rebuilding the preamble per turn
Frameworks that rebuild the system prompt each turn get the live banner and freshly-retrieved rules for free. For frameworks that fix the prompt at construction time, either rebuild the agent per conversation, or rely on the standing protocol (the agent checks its mailbox every turn regardless) — the notices are in the workspace either way. Runnable end-to-end sketches for every framework live in the repository’sexamples/ directory.
