Observed since 20 Oct, 21:59 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Framework-neutral portability layer for AI agents, tools, and model providers.
A compatibility and portability layer for AI agents, tools, and model providers.
AgentFrameRelay lets you define agents and tools once and run them across different AI runtimes through a common interface.
Instead of rewriting the same agent/tool logic for every framework, AgentFrameRelay provides a framework-neutral layer based on:
AgentSpecToolSpecModelSpecThe goal is not to replace LangChain, CrewAI, OpenAI Agents, Google ADK, MCP, or LiteLLM.
The goal is to make it easier to move between them, compare them, and avoid unnecessary framework lock-in.
AI agent frameworks are evolving quickly, but application code can become tightly coupled to whichever runtime was chosen first.
For example, the same business tool may need different wrappers for:
AgentFrameRelay separates the portable definition from the runtime implementation.
AgentFrameRelay
│
┌─────────────┼─────────────┐
│ │ │
▼ ▼ ▼
PORTABILITY RELIABILITY EVALUATION
│ │ │
AgentSpec Validation Benchmarks
ToolSpec Errors Metrics
ModelSpec Async Comparison
│ Execution
└─────────────┬─────────────┘
│
Runtime Adapter
│
┌────────┬───────┼────────┬──────────┐
▼ ▼ ▼ ▼ ▼
LangChain CrewAI MCP Google-ADK OpenAI Agents
AgentFrameRelay is currently focused on Phase 1: Core Portability and the foundation of Phase 2: Reliable Tool Execution.
AgentSpecToolSpecModelSpecAgent.run() interfaceAgentResultThe current foundation includes:
invoke()ainvoke()Retry policies, lifecycle hooks, timeouts, middleware, authorization, and tracing are planned reliability features. They should not be considered part of the current public API unless explicitly implemented in the installed version.
Install the core package:
pip install agentframerelay
Install the integrations you need using optional dependencies:
pip install "agentframerelay[langchain]"
pip install "agentframerelay[crewai]"
pip install "agentframerelay[openai]"
pip install "agentframerelay[litellm]"
pip install "agentframerelay[google-adk]"
pip install "agentframerelay[mcp]"
For development:
pip install "agentframerelay[dev]"
from agentframerelay import tool
@tool
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
The tool contains its own:
You can execute it directly:
result = add.invoke(10, 20)
print(result)
Tool inputs are validated before execution.
from agentframerelay import tool
@tool
def divide(a: float, b: float) -> float:
"""Divide a by b."""
return a / b
Invalid inputs are normalized into AgentFrameRelay tool errors instead of exposing framework-specific validation behavior.
The goal is to keep tool execution consistent regardless of the runtime using the tool.
Async tools are supported directly.
from agentframerelay import tool
@tool
async def fetch_data(url: str) -> str:
"""Fetch data from a URL."""
...
Use:
result = await fetch_data.ainvoke("https://example.com")
The synchronous invoke() path also handles async tools safely when it is running outside an existing event loop.
AgentFrameRelay exposes framework-neutral tool errors.
from agentframerelay.errors import (
AgentFrameRelayError,
ToolError,
ToolInputError,
ToolExecutionError,
AsyncToolError,
)
This means application code can handle failures without depending directly on the exception types of a specific agent framework.
from agentframerelay import Agent
agent = Agent(
name="math-agent",
runtime=RUNTIME,
model={
"provider": MODEL_PROVIDER,
"model": MODEL_NAME,
"api_key": MODEL_API_KEY,
},
instructions="""
You are a helpful mathematical assistant.""",
tools=[
add,
multiply,
],
)
Run it through the common API:
result = agent.run("What is 10 + 20?")
print(result.output)
The same high-level API can be used with supported runtime adapters.
AgentFrameRelay currently provides adapters for:
| Runtime | Adapter |
|---|---|
| Mock | mock |
| LangChain | langchain |
| CrewAI | crewai |
| OpenAI Agents | openai |
| Google ADK | google_adk |
| LiteLLM | litellm |
| MCP | mcp |
Example:
agent = Agent(
name="research-agent",
runtime="langchain",
model={
"provider": MODEL_PROVIDER,
"model": MODEL_NAME,
"api_key": MODEL_API_KEY,
},
instructions="Research the topic and summarize the findings.",
tools=[my_tool],
)
Changing the runtime does not require changing the portable tool definition.
A runtime and a model provider are different concepts.
The runtime tells AgentFrameRelay which agent runtime to use.
The model tells AgentFrameRelay which model provider and model to use.
Use the model configuration in this form:
Agent(
name="math-agent",
runtime=RUNTIME,
model={
"provider": MODEL_PROVIDER,
"model": MODEL_NAME,
"api_key": MODEL_API_KEY,
},
instructions="You are a helpful mathematical assistant.",
tools=[add, multiply],
)
For example:
RUNTIME = "langchain"
MODEL_PROVIDER = "openai"
MODEL_NAME = "gpt-4o-mini"
MODEL_API_KEY = None
Or:
RUNTIME = "crewai"
MODEL_PROVIDER = "groq"
MODEL_NAME = "llama-3.3-70b-versatile"
MODEL_API_KEY = None
The portable representation is backed by ModelSpec:
from agentframerelay import ModelSpec
model = ModelSpec(
provider=MODEL_PROVIDER,
model=MODEL_NAME,
api_key=MODEL_API_KEY,
parameters={},
)
Provider-specific model parameters can be supplied through parameters.
ModelSpec(
provider="openai",
model="gpt-4o-mini",
api_key=None,
parameters={
"temperature": 0.2,
},
)
AgentFrameRelay intentionally supports two ideas:
Use the AgentFrameRelay abstractions when portability matters.
agent.run(...)
tool.invoke(...)
When you need a framework-specific feature, access the native runtime object:
native_agent = agent.native()
This is an important design principle:
Portable when you want portability. Native when you need native features.
AgentFrameRelay should not prevent developers from using capabilities that are unique to a particular runtime.
A single relay tool can be converted for supported runtimes.
Conceptually:
@tool
def search(query: str) -> str:
"""Search for information."""
...
The same tool can be adapted to different ecosystems:
search.to_langchain()
search.to_crewai()
search.to_openai()
search.to_google_adk()
search.to_mcp()
search.to_litellm()
This keeps the canonical tool implementation in one place while allowing runtime-specific integrations.
Different agent runtimes provide different features.
AgentFrameRelay exposes capability information:
agent.capabilities()
A runtime can advertise capabilities such as:
{
"streaming": True,
"memory": True,
"human_in_loop": False,
"durable_execution": False,
"multi_agent": True,
}
This prevents AgentFrameRelay from pretending that every runtime supports exactly the same functionality.
Applications can inspect capabilities before relying on runtime-specific behavior.
The architecture is intentionally layered.
Application
│
▼
AgentFrameRelay
│
├── AgentSpec
├── ToolSpec
├── ModelSpec
├── Tool execution
├── Validation
├── Errors
└── Capabilities
│
▼
Runtime Adapter
│
├── LangChain
├── CrewAI
├── OpenAI Agents
├── Google ADK
├── LiteLLM
└── MCP
The portable layer should contain the application's stable intent.
The adapter should contain runtime-specific implementation details.
The core package should not require every supported framework.
Optional integrations are installed separately.
The portable tool should own its:
Adapters should translate that definition rather than duplicate business logic.
LangChain, CrewAI, OpenAI Agents, Google ADK, MCP, and other runtimes have different execution models.
AgentFrameRelay exposes capabilities rather than pretending those differences do not exist.
Portability should never mean giving up access to native framework functionality.
Use:
agent.native()
when the native runtime is required.
Installing the core package should not require installing every supported AI framework.
Runtime-specific dependencies should remain optional.
Status: Foundation implemented
Status: Foundation implemented
invoke()ainvoke()Planned additions:
Planned:
A major goal of AgentFrameRelay is to make agents comparable across runtimes.
The same agent specification could eventually be evaluated using:
Example:
AgentSpec
│
┌─────────┼─────────┐
▼ ▼ ▼
LangChain CrewAI ADK
│ │ │
▼ ▼ ▼
Evaluate Evaluate Evaluate
│ │ │
└─────────┼─────────┘
▼
Comparison
Eventually, AgentFrameRelay can become a practical benchmark layer for agent runtimes.
For the same workload:
AgentSpec
│
├── Runtime A → quality / latency / cost / reliability
├── Runtime B → quality / latency / cost / reliability
└── Runtime C → quality / latency / cost / reliability
This can help answer:
Which runtime performs best for this workload?
rather than assuming one framework is always best.
Planned:
Longer term:
agentframerelay/
├── src/
│ └── agentframerelay/
│ ├── agent.py
│ ├── errors.py
│ ├── runtime.py
│ ├── specs.py
│ ├── tool.py
│ └── adapters/
│ ├── crewai.py
│ ├── google_adk.py
│ ├── langgraph.py
│ ├── litellm.py
│ ├── mcp.py
│ ├── mock.py
│ └── openai_agents.py
│
├── tests/
├── examples/
├── docs/
├── pyproject.toml
└── README.md
Clone the repository and install development dependencies:
pip install -e ".[dev]"
Run tests:
pytest
Compile-check the source:
python -m compileall -q src tests
Linting can be run with:
ruff check .
Framework-specific integration tests require the corresponding optional dependencies.
AgentFrameRelay does not aim to make every framework identical.
Instead:
Common semantics
+
Runtime-specific capabilities
+
Native escape hatch
=
Practical portability
The abstraction should be strong enough to make common operations portable, while remaining honest about the differences between runtimes.
AI frameworks will continue to change.
A useful portability layer should allow an application to keep its core agent and tool definitions stable while runtimes evolve underneath them.
The long-term vision for AgentFrameRelay is therefore:
Define once. Run across runtimes. Measure the differences. Choose deliberately.
AgentFrameRelay aims to become a compatibility, reliability, and evaluation layer for the rapidly evolving AI agent ecosystem.
MIT License.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.2 | 6 Sept 2026 | 15 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 21:59 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:1745b6986aad9f274dd9af05988fdc5c5ba9bb6e4810b83eaf981a1da0b4d8c1