> ## Documentation Index
> Fetch the complete documentation index at: https://docs.verifiedx.me/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAI Agents SDK

> Attach VerifiedX to the OpenAI Agents SDK in Python or TypeScript.

**Best for:** teams already using the OpenAI Agents SDK and wanting native protection without changing runtimes.

<Note>
  Run doctor in the repo before you wire anything:

  * TypeScript: `npx @verifiedx-core/sdk doctor`
  * Python: `verifiedx doctor`

  Protect one action free: [verifiedx.me](https://verifiedx.me/?vx_source=docs.openai-agents-sdk)

  If doctor shows a different native adapter already owns the tool loop, switch to that page before integrating.
</Note>

## Install

<CodeGroup>
  ```bash Python theme={null}
  pip install verifiedx
  ```

  ```bash TypeScript theme={null}
  npm install @verifiedx-core/sdk
  ```
</CodeGroup>

<Note>
  This page assumes your app already uses `agents` in Python or `@openai/agents` in TypeScript.
</Note>

## Net-new VerifiedX code

This is the smallest truthful integration in an existing OpenAI Agents setup.

<CodeGroup>
  ```python Python theme={null}
  from verifiedx import init_verifiedx, run_openai_agents_sync

  verifiedx = init_verifiedx()
  result = run_openai_agents_sync(agent, input, verifiedx=verifiedx)
  ```

  ```typescript TypeScript theme={null}
  import { initVerifiedX } from "@verifiedx-core/sdk";
  import { run as verifiedxRun } from "@verifiedx-core/sdk/openai-agents";

  const verifiedx = await initVerifiedX();
  const result = await verifiedxRun(agent, input, { verifiedx });
  ```
</CodeGroup>

<Note>
  That is the important part. Your existing agent, tools, instructions, handoffs, and orchestration stay the same.
</Note>

<Tip>
  Start with the wrapper-first path above. If you later want to keep calling the SDK's own runner directly, attach VerifiedX once to the agent or runner instead.
</Tip>

<Note>
  Your native tool surface is the config. VerifiedX uses your existing tool names, descriptions, schemas, approval hints, MCP servers, and built-in tool types as the source of truth for what to preflight.
</Note>

## Attach once instead of wrapping `run`

If you prefer to attach VerifiedX to the agent and keep calling the SDK runner directly, use the native attach surface.

<CodeGroup>
  ```python Python theme={null}
  from agents import Runner
  from verifiedx import attach_openai_agents_agent, init_verifiedx

  verifiedx = init_verifiedx()
  attach_openai_agents_agent(agent, verifiedx=verifiedx)

  result = Runner.run_sync(agent, input)
  ```

  ```typescript TypeScript theme={null}
  import { run as openaiRun } from "@openai/agents";
  import { initVerifiedX } from "@verifiedx-core/sdk";
  import { withVerifiedXAgent } from "@verifiedx-core/sdk/openai-agents";

  const verifiedx = await initVerifiedX();
  await withVerifiedXAgent(agent, { verifiedx });

  const result = await openaiRun(agent, input);
  ```
</CodeGroup>

## Linked runtime / runner setups

If you already manage a runner or trace installer yourself, attach VerifiedX there instead of changing the rest of your code.

<CodeGroup>
  ```python Python theme={null}
  from verifiedx import attach_openai_agents_runner, init_verifiedx

  verifiedx = init_verifiedx()
  attach_openai_agents_runner(runner, verifiedx=verifiedx)
  ```

  ```typescript TypeScript theme={null}
  import { withVerifiedXRunner } from "@verifiedx-core/sdk/openai-agents";

  await withVerifiedXRunner(runtime, {
    verifiedx,
    agent,
    input,
  });
  ```
</CodeGroup>

## Full example

<CodeGroup>
  ```python Python theme={null}
  from agents import Agent, function_tool
  from verifiedx import init_verifiedx, run_openai_agents_sync

  @function_tool
  def set_workflow_status(workflow_id: str, status: str, reason: str) -> dict:
      return {
          "ok": True,
          "workflow_id": workflow_id,
          "status": status,
          "reason": reason,
      }

  agent = Agent(
      name="WorkflowOps",
      model="gpt-5.4-mini",
      instructions="Update internal workflows safely.",
      tools=[set_workflow_status],
  )

  verifiedx = init_verifiedx()

  result = run_openai_agents_sync(
      agent,
      "Set workflow WF-1002 to awaiting_human because billing verification is missing.",
      verifiedx=verifiedx,
  )
  ```

  ```typescript TypeScript theme={null}
  import { Agent, tool } from "@openai/agents";
  import { z } from "zod";

  import { initVerifiedX } from "@verifiedx-core/sdk";
  import { run as verifiedxRun } from "@verifiedx-core/sdk/openai-agents";

  const setWorkflowStatus = tool({
    name: "set_workflow_status",
    description: "Update internal workflow status.",
    parameters: z.object({
      workflow_id: z.string(),
      status: z.string(),
      reason: z.string(),
    }),
    async execute({ workflow_id, status, reason }) {
      return {
        ok: true,
        workflow_updated: { workflow_id, status, reason },
      };
    },
  });

  const agent = new Agent({
    name: "WorkflowOps",
    model: "gpt-5.4-mini",
    instructions: "Update internal workflows safely.",
    tools: [setWorkflowStatus],
  });

  const verifiedx = await initVerifiedX();

  const result = await verifiedxRun(
    agent,
    "Set workflow WF-1002 to awaiting_human because billing verification is missing.",
    { verifiedx },
  );
  ```
</CodeGroup>

<Note>
  Do not use raw `install_runtime(...)` or `bindHarness(...)` for this path. The OpenAI Agents adapter is native to the SDK and wraps the agent or runner directly.
</Note>

## Composed systems

If this OpenAI Agents run is part of a larger multi-agent or agent+human workflow, pass upstream context into VerifiedX so the current run has better system and situational awareness before it takes a high-impact action.

This is useful when a supervisor agent, parent workflow, or human reviewer already has context that the current run should use before taking action.

VerifiedX does not require a fixed schema for this. Pass the upstream context you already have in any JSON-serializable shape.

<CodeGroup>
  ```python Python theme={null}
  upstream = {
      "source": "workflow_supervisor",
      "workflow_id": "WF-2203",
      "approval_status": "approved_with_follow_up",
      "human_review": {
          "reviewer": "ops_lead",
          "result": "approved",
      },
      "prior_agent_output": {
          "summary": "Billing verification is complete.",
      },
  }

  with verifiedx.with_upstream_context(upstream):
      result = run_openai_agents_sync(agent, input, verifiedx=verifiedx)
  ```

  ```typescript TypeScript theme={null}
  const upstream = {
    source: "workflow_supervisor",
    workflow_id: "WF-2203",
    approval_status: "approved_with_follow_up",
    human_review: {
      reviewer: "ops_lead",
      result: "approved",
    },
    prior_agent_output: {
      summary: "Billing verification is complete.",
    },
  };

  const result = await verifiedx.withUpstreamContext(upstream, async () => {
    return await verifiedxRun(agent, input, { verifiedx });
  });
  ```
</CodeGroup>

<Note>
  Upstream context is supporting workflow context from outside the current run. It is not proof that this run already executed any local action.
</Note>

## What the adapter already captures

Once attached, VerifiedX already captures and protects the native OpenAI Agents surface, including:

* Native tool-call history through tracing
* Tool execution through both `tool.execute(...)` and SDK-style `tool.invoke(...)`
* Durable memory writes inferred from tool name, schema, and description
* High-impact tools such as record mutations, system changes, and external messages
* Handoffs and delegated or subagent traces when present
* MCP server `listTools()` and `callTool(...)`
* Hosted MCP approval requests and MCP calls from response spans
* Native built-in tool types such as shell, apply-patch, computer, file search, web search, tool search, image generation, and MCP-style tools when present

<Note>
  If a trace processor cannot be installed in the current setup, VerifiedX falls back to wrapper-only mode instead of failing the integration. Wrapped tools and MCP boundaries still stay protected.
</Note>

## What to expect at runtime

Protected boundaries can return:

* `allow`
* `allow_with_warning`
* `replan_required`
* `goal_fail_terminal`

Every outcome includes a structured decision receipt.

If a tool or memory write is replanned, the side effect does not execute. The wrapped tool returns the normal VerifiedX blocked result shape, including `ok: false`, `blocked: true`, `boundary_outcome`, `safe_next_steps`, and `decision_receipt`, so the agent can keep moving toward the same goal safely or route the receipt upstream when needed.

## Production-style validation coverage

The OpenAI Agents validation paths in this repo cover real workflows including:

* Clean durable memory writes
* Clean record mutations
* Clean internal workflow updates
* Multi-step internal runs across retrieval, mutation, memory, and internal notification
* External email attempts that replan into safer internal Slack fallbacks
* Repeated adversarial external-email attempts that should not keep pushing the same unsafe action
* MCP filesystem list, read, and write flows
* Hosted MCP approval requests captured into history and boundary preflight

## Pricing note

One protected action check equals one real boundary preflight. Taint, event ingest, execution reports, and decision reads are all included at that price. The Free Sandbox includes every language, provider, framework, and adapter.

VerifiedX does not replace your orchestrator or human workflow. It returns receipts your system can keep local, route downstream, or pass upstream.

***

For the raw runtime reference, see the [Python SDK](/sdks/python) and [TypeScript SDK](/sdks/typescript). For direct OpenAI tool loops outside the Agents SDK, see the OpenAI pages.
