Skip to main content

aiyoplane-openai-agents

AEAP Composition Boundary Adapter for the OpenAI Agents SDK.

A thin wrapper that attaches the AEAP Runtime Decision Point (RDP) to the OpenAI Agents SDK's function-tool invocation surface. Consequential tool executions produce independently verifiable Execution Receipts. The adapter composes with the Agents SDK's own guardrails, handoffs, and session machinery — it does not replace any of them.

pip install aiyoplane-openai-agents

What this adapter is (and is not)

It is: the shape AEAP takes when attached to an OpenAI Agents SDK function tool. The underlying authorization logic lives in aiyoplane-mcp-authz; this package distributes that logic into the Agents SDK ecosystem.

It is not: a replacement for Agents SDK guardrails. Guardrails are the SDK's own input/output filter mechanism; AEAP is a protocol-level authorization decision at the Composition Boundary. The two compose: an Agents guardrail can short-circuit on input shape; AEAP decides whether the policy-governed consequential action may execute at all.

See the AEAP specification §9 for the Composition Boundary primitive this adapter realizes.

Minimal usage

from agents import Agent, function_tool
from aiyoplane_mcp_authz import create_aiyo_mcp_authz, create_local_rdp
from aiyoplane_openai_agents import aiyo_tool, BlockedByPolicy, EscalationRequired

policy = {
    "rules": [
        {"action_type": "payment", "amount_max": 1_000, "effect": "allow"},
        {"action_type": "payment", "amount_max": 10_000, "effect": "escalate"},
        {"action_type": "payment", "effect": "block"},
    ]
}

authz = create_aiyo_mcp_authz(
    rdp=create_local_rdp(policy=policy),
    tool_config={
        "transfer_funds": {
            "aiyo_gated": True,
            "action": {"type": "payment"},
        },
    },
)

# Decorator order matters: @aiyo_tool BEFORE @function_tool.
@function_tool
@aiyo_tool(
    authz=authz,
    tool_name="transfer_funds",
    intent_builder=lambda kwargs: {
        "type": "payment",
        "amount": kwargs["amount"],
        "target": kwargs["to_account"],
    },
)
def transfer_funds(amount: int, to_account: str) -> str:
    """Transfer funds between accounts."""
    return actually_transfer(amount, to_account)

# Register with your Agent the usual way:
banker = Agent(
    name="banker",
    instructions="Help the user manage their accounts.",
    tools=[transfer_funds],
)

Decorator order — important

Apply @aiyo_tool first (closest to the function), then @function_tool:

@function_tool        # OUTER — converts the gated callable into an Agents SDK tool
@aiyo_tool(...)       # INNER — wraps the function with the AEAP gate
def my_tool(...):
    ...

This order ensures the AEAP gate runs before the Agents SDK invokes the function. Reversing the order means function_tool wraps the raw function first and the AEAP gate never fires.

Function form

If the function is defined elsewhere and you can't use decorators:

from aiyoplane_openai_agents import wrap_function_tool

def transfer_funds(amount: int, to_account: str) -> str:
    return actually_transfer(amount, to_account)

guarded = wrap_function_tool(
    transfer_funds,
    authz=authz,
    tool_name="transfer_funds",
    intent_builder=lambda kwargs: {"type": "payment", "amount": kwargs["amount"]},
)

# Pass guarded through @function_tool manually:
from agents import function_tool
agent_tool = function_tool(guarded)

Composition Boundary — what the adapter actually does

For each wrapped tool invocation:

  1. Intent construction. intent_builder(kwargs) produces an AEAP Intent payload.
  2. RDP evaluation. The Intent is passed to aiyoplane-mcp-authz's AiyoAuthz middleware.
  3. Verdict composition.
    • ALLOW → the inner function runs with the original kwargs. On attach_receipt=True, returns {"result": ..., "aeap_receipt": ...}.
    • ESCALATE → EscalationRequired is raised with an escalation_id.
    • BLOCK → BlockedByPolicy is raised; the function never executes.
  4. Fail-closed default. Any ambiguous condition — missing intent_builder, non-dict Intent, RDP unreachable, misconfigured tool_config — results in BlockedByPolicy.

Composing with Agents SDK guardrails

AEAP and Agents SDK guardrails are complementary:

from agents import Agent, function_tool, input_guardrail

@input_guardrail
async def validate_shape(ctx, agent, input_data):
    # Guardrail: cheap input-shape check (SDK-native).
    return not malformed(input_data)

@function_tool
@aiyo_tool(authz=authz, tool_name="transfer_funds", intent_builder=...)
def transfer_funds(amount: int, to_account: str) -> str:
    return actually_transfer(amount, to_account)

agent = Agent(
    name="banker",
    tools=[transfer_funds],
    input_guardrails=[validate_shape],
)

The guardrail runs on input shape; the AEAP gate runs on policy evaluation at the tool-invocation boundary. Different layers, both valuable.

Local vs. hosted RDP

from aiyoplane_mcp_authz import create_local_rdp, create_hosted_rdp

# Development:
authz = create_aiyo_mcp_authz(rdp=create_local_rdp(policy=policy), tool_config={...})

# Production:
authz = create_aiyo_mcp_authz(
    rdp=create_hosted_rdp(api_key="aiyo_live_..."),
    tool_config={...},
)

API reference

aiyo_tool(*, authz, tool_name, intent_builder, attach_receipt=False)

Decorator form. Returns a decorator that wraps a function with an AEAP gate.

wrap_function_tool(fn, *, authz, tool_name, intent_builder, attach_receipt=False)

Function form. Equivalent to applying aiyo_tool(...) as a decorator.

Exceptions

  • AiyoOpenAIAgentsError — base class
  • AdapterConfigError — adapter configuration is invalid
  • BlockedByPolicy — RDP returned BLOCK; the tool did not execute
  • EscalationRequired — RDP returned ESCALATE; the tool call is held pending resolution

License

Apache License 2.0.

OpenAI and the OpenAI Agents SDK are trademarks of OpenAI, Inc. This package is an independent AEAP Composition Boundary Adapter and is not affiliated with or endorsed by OpenAI, Inc.

Verify First. Execute Second.

Metadata

Release files for aiyoplane-openai-agents 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aiyoplane-openai-agents 1.0.0
File Size Uploaded
aiyoplane_openai_agents-1.0.0.tar.gz 13.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aiyoplane-openai-agents 1.0.0
File Interpreter ABI Platform
aiyoplane_openai_agents-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 26.1 kB

Release files / aiyoplane_openai_agents-1.0.0.tar.gz

Download URL aiyoplane_openai_agents-1.0.0.tar.gz
Size 13.3 kB
Tags Source
SHA-256 checksum
How to use checksums
378a74e804cf385abd7fae2c3df921ed03fa66b0fbf8ee12e6f07095b94ec8c8
BLAKE2b-256 checksum
How to use checksums
c61663b6348fca052f4754f6fdf484a0ed842269f02083bc58bfad3353898b5d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / aiyoplane_openai_agents-1.0.0-py3-none-any.whl

Download URL aiyoplane_openai_agents-1.0.0-py3-none-any.whl
Size 12.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c7ec39767625de43e87b3ac8ca5a271981b77ee3db139e7bac6a0df5f930b248
BLAKE2b-256 checksum
How to use checksums
639b726edffe23fbb753a2ee4bbf7f05337c0c575d83943b3dc54733c7700b5d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page