agent-adapter

mcp
Guvenlik Denetimi
Uyari
Health Uyari
  • License — License: Apache-2.0
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 5 GitHub stars
Code Gecti
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Gecti
  • Permissions — No dangerous permissions requested

Bu listing icin henuz AI raporu yok.

SUMMARY

A new open-source agentic framework that runs your tools anywhere, safely: one tool, 20 frameworks, any language.

README.md

Agent Adapter

The agentic framework that runs your tools anywhere, safely.

Write a tool once, as a plain Python function. Use it in any agent framework, any backend or on its own, with approvals, budgets, cost and traces built in.

Watch Agent Adapter in 29 seconds
Watch it in 29 seconds · share it

Version 1.1.0 · Python 3.11+ · Apache-2.0 · 21 frameworks and engines · Coverage gate 90%

Agent Adapter on Product Hunt

Quickstart · Why · How it works · Tour · Viewer and chat · Install · Docs · Use cases · Agent skill · Prompt for any AI

Agent Adapter is an agentic framework built around your tools: write each tool once, run it in
LangChain, CrewAI, ADK or 18 more, from any backend or language, safe, priced and traced.

It is an open-source, framework-independent Python SDK. It turns your functions into LLM
tools, checks their schemas once at startup, and runs every call through one
executor that applies approval, budgets, guards, caching and cost tracking. The core
depends only on pydantic. Every framework is an optional extra, imported lazily.

No agent framework is needed: a FastAPI service calling an LLM gets tools, approvals,
budgets, cost, cache and context compression directly. The adapter can also be your
framework: run_tool_loop with your own model is the agent loop, and Flow is the graph.

Let your AI set it up. Add the agent skill to Codex, Cursor, Copilot, Gemini CLI or 60+ more agents with
npx skills add VeloceAI/agent-adapter --skill agent-adapter -a <agent> (e.g. -a codex), or in Claude Code /plugin marketplace add VeloceAI/agent-adapter.

Quickstart

import agent_adapter as aa


@aa.tool
def add(a: int, b: int) -> int:
    """Add two numbers."""
    return a + b


print(aa.call(add, a=1, b=2))  # 3: validated and guarded by the default executor

This is examples/hello.py, which the test suite runs. @aa.tool registers the function
on the default registry; aa.call runs it through the default executor. From async code
(FastAPI, ...) use await aa.acall(add, a=1, b=2). The full walk-through is the
Quickstart.

Why Agent Adapter

Each framework has its own tool format, its own idea of approval and no shared view of cost.
Change framework, or run two, and the rules are rewritten. Agent Adapter keeps them in one place.

You need Without it With Agent Adapter
A person to approve risky actions each framework's own flag, easy to bypass a one-use approval the executor checks on every call, from any source; it survives a restart
Spending limits prices added up by hand BudgetHook per run, user or team, per day or month; every call priced in a ledger
Rules you can prove settings spread across code one policy file for access, approvals, guards and budgets; a signed, hash-chained audit log
To change framework rewrite the tools keep them: one module per framework, the same tools everywhere

How it works

Every call, from any source, goes through the same executor. Frameworks, protocols and
model APIs are thin adapters around it, so the safety rules hold everywhere.

flowchart LR
  subgraph IN["Where calls come from"]
    A["your code<br/>run · run_sync · call"]
    B["model APIs<br/>OpenAI · Gemini · Anthropic"]
    C["agent frameworks<br/>LangGraph · ADK · CrewAI · 16 more"]
    D["protocols<br/>MCP · HTTP · A2A · AG-UI"]
  end
  R[("Registry<br/>your functions<br/>as checked tools")]
  subgraph EX["Executor: one pipeline for every call"]
    direction TB
    V["validate arguments"] --> G["guards and budgets"]
    G --> P["approval<br/>one-use decision"]
    P --> K["cache"]
    K --> T["run the tool<br/>retry · timeout"]
    T --> L["ledger · events"]
  end
  O["outputs<br/>result · cost · trace<br/>run viewer · OpenTelemetry"]
  IN --> R --> EX --> O
Layer Package Does
Tools core, schema functions become ToolSpecs; schemas are checked once and rendered per provider
Execution exec, hooks, approval, cache, cost the pipeline above: validation, hooks, approval, cache, retries, ledger
Orchestration flow, exec.tool_loop portable graph flows and the built-in agent loop
Models models, embeddings, context model ports, fallbacks, usage, context compression
Edges integrations, server, handlers frameworks, MCP, HTTP, A2A, AG-UI, queues and serverless
Insight tracing, viewer, optimiser events, OpenTelemetry, the local run viewer and chat, offline tuning

A tour in code

Human approval that survives a restart

A confirm=True tool runs only after a one-use approval. Park the call in SQLite and
resume it later, in any process (examples/hello_approval.py):

@aa.tool(confirm=True)
def refund(order_id: str, amount: float) -> str:
    """Refund an order."""
    return f"refunded {amount} on {order_id}"


executor = aa.configure(approval=aa.DeferredApproval.sqlite(folder / "approvals.db"))
try:
    aa.call(refund, order_id="o-7", amount=500)
except aa.ApprovalPending as pending:
    approval_id = pending.approval_id  # store it, show it to a reviewer
# ... later, in any process that opens the same file:
result = executor.resume_sync(approval_id, True, decided_by="ana")
print(result.value)  # runs once; a second resume is refused

Budgets, limits, cost and logs

executor = aa.Executor(
    registry,
    hooks=[aa.LoggingHook(), aa.BudgetHook(0.50)],  # stop a run past $0.50
    ledger=aa.Ledger(),  # priced per call, per run
    limits=aa.RunLimits(max_calls=20),  # at most 20 tool calls a run
)

A flow: decide, fan out, join, pause

A Flow is a validated graph over one pydantic state. The local FlowRunner runs it; the
same graph compiles to LangGraph and ADK (examples/first_flow.py):

flow = (
    Flow("support", state=Ticket)
    .node("classify", classify)
    .node("policy", Call("lookup_policy", args=lambda t: {"category": t.category}, into="reply"))
    .node("escalate", escalate)
    .route(
        "classify",
        Route(
            lambda t: "policy" if t.category == "refund" else "escalate",
            targets=["policy", "escalate"],
        ),
    )
    .end("policy", "escalate")
)
result = run_sync(FlowRunner(Executor(registry)).run(flow, {"text": "I want a refund"}))
flowchart LR
  S((start)) --> classify
  classify -- "refund" --> policy["policy<br/>tool: lookup_policy"]
  classify -- "other" --> escalate
  policy --> E((end))
  escalate --> E

Map fans one node out over a list, Join merges the branches, Merge rules say how
parallel writes combine, and pause=True on a node waits for a person. See
Flows and Chat flows by example.

Your own agent loop

run_tool_loop drives any model port through tool calls until it answers. Every call goes
through the executor, so approval, cache, budgets and cost apply (examples/tool_loop.py):

model = CallableModel(my_llm, provider="host", model="router-v2")  # or OpenAIModel, ...
result = await run_tool_loop(model, registry, question, executor=executor)
print(result.finish, result.steps, result.final.text)

The same tools over MCP and HTTP

from agent_adapter.integrations.mcp import mcp_server
from agent_adapter.server import bearer_auth, create_app

server = mcp_server(registry, name="shop-tools")  # MCP, stdio or HTTP
app = create_app(registry, authenticate=bearer_auth(TOKENS))  # REST + SSE + OpenAPI, MCP at /mcp

The TypeScript client, A2A and AG-UI are in Connect anywhere.

See your runs and chat with your agent

Record runs with agent_adapter.viewer.record(executor), then open the local viewer:
a run list, a navigable flow graph, a timeline, events with filters, state and cost. Start
it with an agent and the same page becomes a chat, like a playground for any framework:

The chat page: chats on the left, a turn with tool calls in the middle, the turn's live flow graph on the right

agent-adapter ui                                         # browse recorded runs
agent-adapter ui --agent app:chat                        # chat with any agent
agent-adapter ui --model app:model --tools app:registry  # the built-in tool loop

It binds 127.0.0.1 only and opens with a private token link. Try both live, nothing to
install: the run viewer demo
(graph, replay, timeline, compare) and the chat demo.

Attach anywhere

You have Use
a script, a service, a notebook await executor.run(...); run_sync(...) from sync code (Flask, Django WSGI, Celery)
code you cannot edit registry.wrap(obj.method), unchanged
a raw model API chat_tools, function_declarations, anthropic_tools, then executor.run_call per tool call; or run_tool_loop
an agent framework one module and one extra per framework (LangGraph, ADK, LangChain, MCP, OpenAI Agents SDK, Pydantic AI, LlamaIndex, CrewAI, Agent Framework, Agno, Strands, Haystack, Claude Agent SDK, Semantic Kernel, DSPy, smolagents, AutoGen, CAMEL-AI, AG2)
another agent or a UI A2A (server and client), AG-UI (event stream)
another language MCP or HTTP, tested end to end from TypeScript, Python, C#, Go, Rust, Ruby, Java, Kotlin, Swift and PHP (clients, Connect anywhere)
a queue, a Lambda, a pipeline the backend guides

Safe by default

Rule What it means
One-use approval A confirm tool runs only after the executor's ApprovalPort approves. A decision is used once, by the call it answers: same run, call id, tool and argument digest. No port: denied. One opt-in exception: an MCP server built with client_approval=True makes the MCP client's user the approver (MCP approval)
Framework approval never counts alone A framework's own "approved" signal only adds a gate. A bridge passes approval only as a one-use token the adapter issued after its own port approved
HTTP server security model No authenticator is a startup error unless anonymous mode is chosen. Ids are scoped to the caller; only the invoker or an approver sees an approval; hooks fail closed. See the security model
Local viewer and chat 127.0.0.1 only, a private token link, Origin and CSRF checks, a strict content security policy; chat is off unless you pass an agent
Budgets and guards BudgetHook(max_usd), once_per_run, RunLimits, per-kind caps, rate limits, timeouts, retries
No secrets in logs LoggingHook redacts secret-looking keys and never logs confirm tool arguments; foreign exceptions reach the model without their text

Features

Area What you get
Tools @registry.tool, registry.wrap(); shaping (fixed=, hide=, rename=); portable-schema check; typed errors under AdapterError
Schemas OpenAI (Chat, Responses, strict), Gemini and Anthropic renderers; strict-mode null means "use the default"
Execution run, run_many, run_plan waves, parallel, as_completed; retry, timeout, hooks, run guards
Multi-agent agents as tools (agent_tool, LoopAgent) and handoffs (handoff, HandoffModel) in one run, with a depth guard
Guardrails PIIGuard (emails, phones, cards, IBANs, secrets; no model), CallableGuard, Presidio, NeMo; block, redact or approve
Policy file access, approvals, guards, budgets and limits per tool, team and environment in one YAML, TOML or JSON file; agent-adapter policy check (Policy file)
Audit log a signed, hash-chained log of approvals, guard blocks, budget stops and memory erases; agent-adapter audit verify and export to CSV (Audit log)
Flows a portable Flow (route, map, join, loop, pause, sub-flows, node cache) with a local runner; compiles to LangGraph and ADK
Approval ports (AutoApprove, CallbackApproval, DeferredApproval), stores (SQLite, Redis, SQLAlchemy, DynamoDB), batch approval, framework bridges
Cost and cache priced ledger with context windows, usage normalisers; tool-result, LLM-response and provider prefix caches
Models OpenAIModel, GeminiModel, AnthropicModel, CallableModel, FallbackModel, run_tool_loop; recipes for Bedrock, Azure OpenAI, Mistral, Groq, OpenRouter
Context compression a CompressionPolicy (trim, cut, shrink tool results, de-duplicate, rank, summarise) with your own models; compress_for keeps every framework's own message type
Cross-language MCP server and importer, HTTP tool server (ASGI and WSGI), TypeScript client, A2A, AG-UI
Observability standard logging, an event catalogue, sinks, OpenTelemetry GenAI spans (Langfuse, Phoenix, OpenLLMetry); the local run viewer and chat page
Durability crash-safe flows and tool loops (checkpoint stores, recover); Temporal or DBOS as the engine
Sandboxed code code_tool over Docker or a hosted sandbox; every run needs approval
Memory and RAG per-user memory (SQLiteMemory, Mem0, Zep, Graphiti) through memory_tools; retriever_tool with citations and host-set scope filters
Evals run_eval on any agent with graders (exact, regex, JSON schema, tools, cost, latency, LLM judge); JUnit, Markdown and JSON reports; agent-adapter eval; a pytest plugin; an Evals tab in the viewer
Evals from production and cost advisor recorded runs become eval cases (Evals from production); a cheaper model per flow node or stage that keeps the score (Cut model costs per step)
Optimiser offline Propose → Probe → Compose loop over your eval cases that writes a reviewable diff

The full list, with a guide for each feature: Features. Next: the Roadmap.

Install

Requires Python 3.11 or later.

pip install agent-adapter                 # core (pydantic only)
pip install "agent-adapter[openai]"       # + the extras you need
Extra Adds
openai, gemini, anthropic the provider SDK, for the model ports
langgraph, langchain, mcp, openai-agents, pydantic-ai, llamaindex, agent-framework, agno, haystack, claude-agent, smolagents, autogen, ag2 that framework
crewai, strands, semantic-kernel, adk, camel, dspy that framework, in its own environment (why)
a2a, ag-ui that protocol
openapi import_openapi (httpx, PyYAML)
server, server-wsgi the HTTP tool server (Starlette + uvicorn; a2wsgi)
redis, otel Redis cache and stores; OpenTelemetry sink
sqlalchemy, dynamodb database approval stores
presidio, nemo the Presidio and NeMo Guardrails guards (not in all)
mem0, zep, graphiti memory backends (not in all)
temporal, dbos flows on Temporal or DBOS (not in all)
all every extra that co-installs; not crewai, strands, semantic-kernel, adk, camel, dspy, presidio, nemo, mem0, zep, graphiti, temporal, dbos
dev, docs tests, linters, nox; the docs site

Pins per extra: Install, Support matrix.

Command line

Command Does
agent-adapter init fastapi my-service writes a starter project from a tested template (script, fastapi, flask, celery, langgraph, openai-agents, mcp-server, pydantic-ai, adk, agno, strands, crewai)
agent-adapter policy check policy.yaml --env prod checks a policy file and prints the effective rules per tool
agent-adapter audit verify .agent_adapter/audit checks the audit log's signatures and chain; audit export writes JSONL or CSV
agent-adapter migrate src/ --diff finds framework tools and prints a suggested patch to registry tools (read-only)
agent-adapter doctor checks Python, installed extras, optional backends (guards, OTel exporters), integrations and the pip index
agent-adapter ui the local run viewer; with --agent or --model, the chat page
agent-adapter eval app:agent cases.jsonl --min-score 0.9 grades an agent on eval cases; exits 1 below the score or on a regression
agent-adapter guide prints the guide for AI coding agents (AGENTS.md); --full adds every signature

Project layout

agent_adapter/   the package: one sub-package per layer (see "How it works")
examples/        runnable examples; the test suite runs them, the docs include them
docs/            the MkDocs site: get started, how-to, concepts, reference, demos
tests/           pytest suite mirroring the package, plus docs, example and JS tests
clients/         the TypeScript client for the HTTP tool server
scripts/         check.py (every gate) and the generators for docs and guides

Working on the code itself? CODEBASE.md is the map: architecture, where
everything lives, the rules, the gates and the generated files.

Documentation

The site is agent-adapter.veloceai.in; its source is
docs/ (MkDocs Material, mkdocs build --strict). Start with How-to → Attach anywhere, or
build a whole app with the golden path tutorial. Before
production, read the threat model and the
API stability policy.

Development

pip install -e ".[dev,docs,openapi]"   # openapi brings httpx, which mypy checks against
python scripts/check.py

scripts/check.py runs every gate in order and stops at the first failure: pytest with
coverage (≥ 90 %, warnings are errors), ruff check, ruff format --check, mypy --strict
and mkdocs build --strict. The nox sessions in noxfile.py run the same suite per Python
version and per integration. Releases follow docs/contributing/release.md;
changes are listed in CHANGELOG.md.

Licence

Apache License 2.0. See LICENSE and NOTICE. Copyright 2026 Veloce AI.

Yorumlar (0)

Sonuc bulunamadi