Metadata-Version: 2.4
Name: agent-gantry
Version: 0.9.0
Summary: Universal Tool Orchestration Platform - Intelligent, secure tool orchestration for LLM-based agent systems
Project-URL: Homepage, https://github.com/CodeHalwell/Agent-Gantry
Project-URL: Repository, https://github.com/CodeHalwell/Agent-Gantry
Author: Agent-Gantry Contributors
License-Expression: MIT
License-File: LICENSE
Keywords: agents,llm,mcp,orchestration,semantic-routing,tools
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: <3.14,>=3.10
Requires-Dist: jsonschema>=4.18.0
Requires-Dist: numpy>=1.24.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pyyaml>=6.0.0
Provides-Extra: a2a
Requires-Dist: fastapi>=0.104.0; extra == 'a2a'
Requires-Dist: httpx>=0.24.0; extra == 'a2a'
Requires-Dist: uvicorn>=0.24.0; extra == 'a2a'
Provides-Extra: agent-frameworks
Requires-Dist: agent-framework<2.0.0,>=1.5.0; extra == 'agent-frameworks'
Requires-Dist: autogen-agentchat>=0.7.5; extra == 'agent-frameworks'
Requires-Dist: autogen-ext[openai]>=0.7.5; extra == 'agent-frameworks'
Requires-Dist: crewai>=1.6.1; extra == 'agent-frameworks'
Requires-Dist: google-adk>=1.14.1; extra == 'agent-frameworks'
Requires-Dist: langchain-openai>=1.2.2; extra == 'agent-frameworks'
Requires-Dist: langchain>=1.3.4; extra == 'agent-frameworks'
Requires-Dist: langgraph>=1.2.4; extra == 'agent-frameworks'
Requires-Dist: llama-index-core>=0.14.22; extra == 'agent-frameworks'
Requires-Dist: llama-index-llms-openai>=0.7.7; extra == 'agent-frameworks'
Requires-Dist: semantic-kernel>=1.36.0; extra == 'agent-frameworks'
Provides-Extra: all
Requires-Dist: agent-framework<2.0.0,>=1.5.0; extra == 'all'
Requires-Dist: anthropic>=0.107.1; extra == 'all'
Requires-Dist: asyncpg>=0.29.0; extra == 'all'
Requires-Dist: autogen-agentchat>=0.7.5; extra == 'all'
Requires-Dist: autogen-ext[openai]>=0.7.5; extra == 'all'
Requires-Dist: beautifulsoup4>=4.12.0; extra == 'all'
Requires-Dist: chromadb>=0.4.0; extra == 'all'
Requires-Dist: cohere>=7.0.3; extra == 'all'
Requires-Dist: crewai>=1.6.1; extra == 'all'
Requires-Dist: cryptography>=41.0.0; extra == 'all'
Requires-Dist: einops>=0.8.1; extra == 'all'
Requires-Dist: fastapi>=0.104.0; extra == 'all'
Requires-Dist: google-adk>=1.14.1; extra == 'all'
Requires-Dist: google-cloud-aiplatform>=1.70.0; extra == 'all'
Requires-Dist: google-genai>=1.75.0; extra == 'all'
Requires-Dist: groq>=1.4.0; extra == 'all'
Requires-Dist: httpx>=0.24.0; extra == 'all'
Requires-Dist: huggingface-hub[hf-xet]>=0.36.0; extra == 'all'
Requires-Dist: lancedb>=0.4.0; extra == 'all'
Requires-Dist: langchain-openai>=1.2.2; extra == 'all'
Requires-Dist: langchain>=1.3.4; extra == 'all'
Requires-Dist: langgraph>=1.2.4; extra == 'all'
Requires-Dist: llama-index-core>=0.14.22; extra == 'all'
Requires-Dist: llama-index-llms-openai>=0.7.7; extra == 'all'
Requires-Dist: matplotlib>=3.7.0; extra == 'all'
Requires-Dist: mcp>=1.27.2; extra == 'all'
Requires-Dist: numpy>=1.24.0; extra == 'all'
Requires-Dist: openai>=2.41.0; extra == 'all'
Requires-Dist: pandas>=2.0.0; extra == 'all'
Requires-Dist: pillow>=10.0.0; extra == 'all'
Requires-Dist: pint>=0.24.4; extra == 'all'
Requires-Dist: psutil>=5.9.0; extra == 'all'
Requires-Dist: pubchempy>=1.0.5; extra == 'all'
Requires-Dist: pyarrow>=14.0.1; extra == 'all'
Requires-Dist: pypdf>=3.0.0; extra == 'all'
Requires-Dist: pytest-asyncio<1.0.0,>=0.21.0; extra == 'all'
Requires-Dist: pytest-cov>=4.0.0; extra == 'all'
Requires-Dist: pytest>=7.0.0; extra == 'all'
Requires-Dist: python-barcode>=0.15.0; extra == 'all'
Requires-Dist: python-docx>=1.0.0; extra == 'all'
Requires-Dist: python-dotenv>=1.0.0; extra == 'all'
Requires-Dist: python-dotenv>=1.1.1; extra == 'all'
Requires-Dist: pytz>=2023.3; extra == 'all'
Requires-Dist: qdrant-client>=1.7.0; extra == 'all'
Requires-Dist: qrcode>=7.4.0; extra == 'all'
Requires-Dist: rdkit>=2025.9.3; extra == 'all'
Requires-Dist: requests>=2.31.0; extra == 'all'
Requires-Dist: ruff>=0.1.0; extra == 'all'
Requires-Dist: scikit-learn>=1.3.0; extra == 'all'
Requires-Dist: semantic-kernel>=1.36.0; extra == 'all'
Requires-Dist: sentence-transformers>=2.2.0; extra == 'all'
Requires-Dist: sympy>=1.14.0; extra == 'all'
Requires-Dist: textblob>=0.18.0; extra == 'all'
Requires-Dist: uvicorn>=0.24.0; extra == 'all'
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.107.1; extra == 'anthropic'
Provides-Extra: chroma
Requires-Dist: chromadb>=0.4.0; extra == 'chroma'
Provides-Extra: cohere
Requires-Dist: cohere>=7.0.3; extra == 'cohere'
Provides-Extra: dev
Requires-Dist: pytest-asyncio<1.0.0,>=0.21.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: python-dotenv>=1.0.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Provides-Extra: embeddings
Requires-Dist: numpy>=1.24.0; extra == 'embeddings'
Requires-Dist: sentence-transformers>=2.2.0; extra == 'embeddings'
Provides-Extra: example-tools
Requires-Dist: beautifulsoup4>=4.12.0; extra == 'example-tools'
Requires-Dist: cryptography>=41.0.0; extra == 'example-tools'
Requires-Dist: einops>=0.8.1; extra == 'example-tools'
Requires-Dist: huggingface-hub[hf-xet]>=0.36.0; extra == 'example-tools'
Requires-Dist: matplotlib>=3.7.0; extra == 'example-tools'
Requires-Dist: pandas>=2.0.0; extra == 'example-tools'
Requires-Dist: pillow>=10.0.0; extra == 'example-tools'
Requires-Dist: pint>=0.24.4; extra == 'example-tools'
Requires-Dist: psutil>=5.9.0; extra == 'example-tools'
Requires-Dist: pubchempy>=1.0.5; extra == 'example-tools'
Requires-Dist: pypdf>=3.0.0; extra == 'example-tools'
Requires-Dist: python-barcode>=0.15.0; extra == 'example-tools'
Requires-Dist: python-docx>=1.0.0; extra == 'example-tools'
Requires-Dist: python-dotenv>=1.1.1; extra == 'example-tools'
Requires-Dist: pytz>=2023.3; extra == 'example-tools'
Requires-Dist: qrcode>=7.4.0; extra == 'example-tools'
Requires-Dist: rdkit>=2025.9.3; extra == 'example-tools'
Requires-Dist: requests>=2.31.0; extra == 'example-tools'
Requires-Dist: scikit-learn>=1.3.0; extra == 'example-tools'
Requires-Dist: sympy>=1.14.0; extra == 'example-tools'
Requires-Dist: textblob>=0.18.0; extra == 'example-tools'
Provides-Extra: google-genai
Requires-Dist: google-genai>=1.75.0; extra == 'google-genai'
Provides-Extra: google-vertexai
Requires-Dist: google-cloud-aiplatform>=1.70.0; extra == 'google-vertexai'
Provides-Extra: groq
Requires-Dist: groq>=1.4.0; extra == 'groq'
Provides-Extra: lancedb
Requires-Dist: lancedb>=0.4.0; extra == 'lancedb'
Requires-Dist: pyarrow>=14.0.1; extra == 'lancedb'
Provides-Extra: llm-providers
Requires-Dist: anthropic>=0.107.1; extra == 'llm-providers'
Requires-Dist: google-cloud-aiplatform>=1.70.0; extra == 'llm-providers'
Requires-Dist: google-genai>=1.75.0; extra == 'llm-providers'
Requires-Dist: groq>=1.4.0; extra == 'llm-providers'
Requires-Dist: openai>=2.41.0; extra == 'llm-providers'
Provides-Extra: mcp
Requires-Dist: mcp>=1.27.2; extra == 'mcp'
Provides-Extra: mistral
Requires-Dist: openai>=2.41.0; extra == 'mistral'
Provides-Extra: nomic
Requires-Dist: einops>=0.8.1; extra == 'nomic'
Requires-Dist: numpy>=1.24.0; extra == 'nomic'
Requires-Dist: sentence-transformers>=2.2.0; extra == 'nomic'
Provides-Extra: openai
Requires-Dist: openai>=2.41.0; extra == 'openai'
Provides-Extra: pgvector
Requires-Dist: asyncpg>=0.29.0; extra == 'pgvector'
Provides-Extra: qdrant
Requires-Dist: qdrant-client>=1.7.0; extra == 'qdrant'
Provides-Extra: vector-stores
Requires-Dist: asyncpg>=0.29.0; extra == 'vector-stores'
Requires-Dist: chromadb>=0.4.0; extra == 'vector-stores'
Requires-Dist: qdrant-client>=1.7.0; extra == 'vector-stores'
Description-Content-Type: text/markdown

# Agent-Gantry

**Universal Tool Orchestration Platform for LLM-Based Agent Systems**

*Context is precious. Execution is sacred. Trust is earned.*

Agent-Gantry is a Python **0.8.0** library for building agents that can discover, select, and execute the right tools without flooding every prompt with every schema your organization owns. It combines semantic retrieval, provider schema conversion, secure execution, framework bridges, MCP/A2A interoperability, persistence adapters, and observability into one tool orchestration layer.

## Documentation

The project documentation is now an **Astro + React + TypeScript** site with an implementation journey, interactive tool lifecycle walkthrough, integration matrix, and production operations guidance.

```bash
npm install
npm run dev      # local docs server
npm run build    # type-check and static build
npm run preview  # verify the generated site styling
```

Start with the rich docs in [`src/pages/index.astro`](src/pages/index.astro). The published site lives at [codehalwell.github.io/Agent-Gantry](https://codehalwell.github.io/Agent-Gantry).

## Install

```bash
uv add agent-gantry
# or
pip install agent-gantry
```

Useful extras:

```bash
uv add "agent-gantry[openai]"
uv add "agent-gantry[anthropic]"
uv add "agent-gantry[google-genai]"
uv add "agent-gantry[lancedb,nomic]"
uv add "agent-gantry[mcp,a2a]"
uv add "agent-gantry[agent-frameworks]"
uv add "agent-gantry[all]"
```

## Quick start

```python
from openai import AsyncOpenAI
from agent_gantry import AgentGantry, set_default_gantry, with_semantic_tools

client = AsyncOpenAI()
gantry = AgentGantry()
set_default_gantry(gantry)

@gantry.register(tags=["weather"])
def get_weather(city: str) -> str:
    """Get the current weather for a city."""
    return f"The weather in {city} is 72°F and sunny."

@with_semantic_tools(limit=3, dialect="openai")
async def ask_llm(prompt: str, *, tools=None):
    return await client.chat.completions.create(
        model="gpt-5.5",
        messages=[{"role": "user", "content": prompt}],
        tools=tools,
    )

await ask_llm("What's the weather in San Francisco?")
```

Agent-Gantry automatically fingerprints registered tools, syncs definitions to the configured vector store, retrieves semantically relevant tools, and converts schemas to the requested provider dialect.

## Core capabilities

- **Semantic tool routing:** reduce prompt context by retrieving top-k relevant tools instead of injecting every tool.
- **Register once, run anywhere:** emit schemas for OpenAI-compatible APIs, Anthropic, Gemini, framework adapters, MCP, and A2A paths.
- **Secure execution:** run tools through policies, capabilities, timeouts, retries, rate limits, circuit breakers, callbacks, and telemetry.
- **Persistence and retrieval:** use in-memory defaults, LanceDB, Qdrant, Chroma, pgvector, OpenAI/Nomic/sentence-transformers embeddings, and rerankers.
- **Framework coverage:** Microsoft Agent Framework plus LangChain, LangGraph, LlamaIndex, CrewAI, AutoGen, Semantic Kernel, Google ADK, Pydantic AI, OpenAI Agents SDK, Smolagents, Haystack, and Agno.
- **Bundled Claude Skill:** install with `agent-gantry install-skill --claude` or target a project-local skills directory.

## Manual retrieval and execution

```python
from agent_gantry import AgentGantry
from agent_gantry.schema.execution import ToolCall

gantry = AgentGantry()

@gantry.register(tags=["finance"])
def calculate_tax(amount: float) -> float:
    """Calculate US sales tax for an amount."""
    return amount * 0.08

tools = await gantry.retrieve_tools("What is the tax on $100?", limit=5)
result = await gantry.execute(ToolCall(
    tool_name="calculate_tax",
    arguments={"amount": 100.0},
))
```

## Development

```bash
uv sync --all-extras
uv run pytest
npm install
npm run build
```

## License

MIT
