Skip to content

About

AEAP Composition Boundary Adapter for the OpenAI Agents SDK (Python). Thin wrapper that attaches the AEAP Runtime Decision Point to agent tool invocations. Published as aiyoplane-openai-agents on PyPI.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

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.

Links

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.

About

AEAP Composition Boundary Adapter for the OpenAI Agents SDK (Python). Thin wrapper that attaches the AEAP Runtime Decision Point to agent tool invocations. Published as aiyoplane-openai-agents on PyPI.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages