Skip to content

OpenAI Agents Integration Sketch

OpenAI's Agents SDK supports guardrails and human review around agent execution. The important Planisphere attachment point is before a tool or external action mutates the world.

Reference: https://openai.github.io/openai-agents-python/guardrails/

Pattern

  1. The agent decides it wants to call a tool or perform a sensitive action.
  2. Your app builds a Planisphere proposed_action.
  3. Planisphere returns allow, needs_review, or block.
  4. The tool executes only on allow.
  5. needs_review pauses and routes to the configured reviewer.
  6. The evidence packet records what happened.

Minimal HTTP Call

The checked copyable helper is in docs/examples/python/planisphere_gate.py. Until a packaged SDK exists, use it as the common gate around side-effecting tools.

from planisphere_gate import PlanisphereClient, PlanisphereNeedsReview, route_for_review


client = PlanisphereClient(
    base_url="https://api.planisphere.ooo",
    api_key="<tenant-api-key>",
)


def before_tool_execution(action: str, context: dict) -> dict:
    try:
        return client.require_allow(
            surface="openai-agents",
            source_key=context["source_key"],
            proposed_action=action,
            law_context=context["law_context"],
            redacted_text=context.get("redacted_text"),
        )
    except PlanisphereNeedsReview as review:
        return route_for_review(review.decision)


decision = before_tool_execution(
    "File an AI-drafted motion with unverified citations.",
    {
        "source_key": "matter-safe:motion-draft-123",
        "law_context": {
            "matter_band": "litigation",
            "tool_id": "openai-agent",
            "doctrine_anchor": "fre-707",
            "jurisdiction": "federal",
        },
        "redacted_text": "AI-drafted filing contains citations requiring review.",
    },
)

if decision.get("decision") == "allow":
    print("execute tool")
elif decision.get("status") == "paused":
    print(decision["next_step"])
else:
    raise RuntimeError(decision["next_step"])