Framework for creating dynamic AI agents with access to broad range of capabilities.
Project description
AdeptAI
Create evolving AI agents that can choose what capabilities they need to complete a task, dynamically updating their instructions, context data and tools.
Use MCP servers as capabilities with flexible customization of which tools and resources to include. All the complexity of MCP session lifecycle management, communication, tool calling, resource retrieval and server notification handling is taken care of automatically.
Overview
The two basic concepts involved are:
- Capability - A collection of associated tools and context data, along with instructions and examples for how to use them. Look here to learn about the different types.
- AgentBuilder - Translates a role and set of capabilities into an aggregated dynamically evolving system prompt and set of tools that can be used to define an AI agent's behaviour.
An agent can be configured with many capabilities to handle a broad range of tasks, without getting overwhelmed by context and tool choice since it can enable only the capabilities it needs to get its job done.
Integrates with your favourite agent framework, or greatly simplifies the process of building powerful AI agents directly with a model provider's SDK or API.
Installation
For basic installation:
pip install adept-ai
Can also specify the following optional dependencies depending on which framework you are using: [langchain, openai, pydantic_ai, composio]
Example
Here's an example AgentBuilder configuration with a combination of inbuilt, MCP-based and Composio capabilities:
import os
from adept_ai import AgentBuilder
from adept_ai.capabilities FileSystemCapability, StdioMCPCapability, ComposioActionsCapability
ROLE = "You are a helpful assistant with access to a range of capabilities that you should use to complete the user's request."
agent_builder = AgentBuilder(
role=ROLE,
capabilities=[
FileSystemCapability(),
# Register here to get API key: https://developer.accuweather.com/
StdioMCPCapability(
name="AccuWeather",
description="Get weather data from AccuWeather, a weather forecasting and weather information service.",
command="npx",
args=["-y", "@timlukahorstmann/mcp-weather"],
env={"ACCUWEATHER_API_KEY": os.getenv("ACCUWEATHER_API_KEY", "")},
instructions=["Use a sessionId of '123' when calling tools that require one."]
),
# Check here for setup instructions: https://github.com/GongRzhe/Gmail-MCP-Server
StdioMCPCapability(
name="Gmail",
description="Access my Gmail account to read and send emails.",
command="npx",
args=["@gongrzhe/server-gmail-autoauth-mcp"],
tools=["search_emails", "read_email", "send_email", "delete_email", "batch_delete_emails"],
instructions=[
"Use `older_than:` or `newer_than:` instead of `after:` and `before:` for relative time queries"],
),
ComposioActionsCapability(
name="WebSearch",
description="Search the web for information about a topic.",
actions=["COMPOSIO_SEARCH_SEARCH"],
),
],
)
# Provides an `enable_capabilities()` tool along with tools belonging to all enabled capabilities
tools = await agent_builder.get_tools()
# Generates dynamic system prompt that includes instructions and usage examples of each enabled capability
system_prompt = await agent_builder.get_system_prompt()
This can be easily used to make a simple agent that when provided a prompt like:
Check my calendar for upcoming events for the next 2 days, check the weather forceast in London at the time of each event, and write a HTML file with a formatted table listing the events with weather information for each
Would produce the following output (with logging enabled):
> Running tool: 'enable_capabilities' with args: {'capabilities': ['GoogleCalendar', 'AccuWeather', 'Filesystem']}
> Starting MCP server: GoogleCalendar
> Starting MCP server: AccuWeather
> Running tool: 'GoogleCalendar-list_events' with args: {'timeMin': '2025-06-06T00:00:00Z', 'timeMax': '2025-06-08T00:00:00Z'}
> Running tool: 'AccuWeather-weather-get_hourly' with args: {'location': 'London, GB', 'units': 'metric'}
> Running tool: 'Filesystem-create_file' with args: {'path': 'calendar_weather_report.html', 'content': '<!DOCTYPE html>\n<html lang="en">...</html>'}
> Stopping MCP server: AccuWeather
> Stopping MCP server: GoogleCalendar
I have created an HTML file named calendar_weather_report.html that contains a formatted table listing your upcoming events for the next two days, along with the weather forecast in London for each event. You can open this file to view the details.
Features
- Fully typed and async
- Customizable system prompt template
- Helpful utilities for compatibility with LangGraph & PydanticAI frameworks and OpenAI SDK
- Auto-create tools from existing sync or async functions/methods
- Built-in Filesystem
Capabilities
Capabilities are configurable and stateful objects which provide a set of tools along with associated context data, instructions and usage examples.
Built-in Capabilities
Choose from a collection of powerful built-in capabilities:
FileSystemCapability- Allows reading & writing files, with dynamically updating directory tree context data- More TBA
Function-Based Capabilities
Use the included FunctionToolsCapability to conveniently create a capability with tools automatically generated from a set of provided functions.
Custom Capabilities
Subclass Capability to create your own infinitely customisable capabilities to suit your needs, with greater flexibility than FunctionToolsCapability such as being configurable and having state.
MCP Capabilities
- Supports both STDIO (
StdioMCPCapability) and HTTP (HTTPMCPCapability) MCP servers - Choose which tools and resources to provide to the agent
- Add description, instructions and usage examples to help agent use MCP tools reliably
- Supports multiple concurrent MCP servers with advanced MCP session lifecycle management including on-demand initialisation only when they are enabled.
- Handle server sampling requests (so MCP server can make request to LLM/agent)
- Automatic caching of tool and resource lists, with handling of server notifications to reset caches (not even officially supported by the MCP SDK yet)
- Create custom subclasses to customize the behaviour of MCP tools / resources and how they are presented to the agent
MCP capabilities can be used in isolation a powerful MCP clients:
async with StdioMCPCapability(...) as mcp_client:
tools = mcp_client.get_tools()
first_tool = tools[0]
result = await first_tool.call(arg1="foo", arg2="bar")
resources = await mcp_client.list_all_resources()
for resource in resources:
resource_content = await mcp_client.read_resource(resource.uri)
print(resource_content)
Composio Actions Capability
The ComposioActionsCapability allows simple integration with a broad range of external services, by providing a set of Composio actions as tools.
The capability description can be generated based on apps or actions if not specified.
Example:
ComposioToolsCapability(
name="WebSearch",
description="Search the web for information about a topic.",
actions=["COMPOSIO_SEARCH_SEARCH"],
)
ComposioToolsCapability(name="GoogleSheets", apps=["GOOGLESHEETS"])
Usage Examples
Using with OpenAI SDK
Includes an OpenAITools helper class to translate tools to OpenAI SDK format and handle tool execution.
from openai import AsyncOpenAI
from openai.types.responses import EasyInputMessageParam
from adept_ai.compat.openai import OpenAITools
from examples.agent_builder import get_agent_builder
async def run_openai(prompt: str, model_name: str, api_key: str):
client = AsyncOpenAI(api_key=api_key)
async with get_agent_builder() as agent_builder:
message_history = [EasyInputMessageParam(role="user", content=prompt)]
# Agent tool calling loop
while True:
# Retrieve tools within loop so they can be dynamically updated
tools = await agent_builder.get_tools()
openai_tools = OpenAITools(tools)
system_prompt = await agent_builder.get_system_prompt()
response = await client.responses.create(
model=model_name,
input=[EasyInputMessageParam(role="system", content=system_prompt)] + message_history,
tools=openai_tools.get_responses_tools(),
)
for output in response.output:
if output.type == "function_call":
# Call the tool
result = await openai_tools.handle_function_call_output(output)
# Add the tool response to the message history
message_history.append(output)
message_history.append(result)
else:
print(f"AI Agent: {response.output_text}")
break
Using with LangChain/LangGraph
The prebuilt create_react_agent() does not support dynamic updating of tools within a run, so interrupt_after is used as a workaround to achieve this.
It would be possible to create a custom graph-based agent that supports this more natively.
from langchain_core.messages import HumanMessage, ToolMessage
from langgraph.prebuilt import create_react_agent
from adept_ai.compat.langchain import tool_to_langchain_tool
from examples.agent_builder import get_agent_builder
from examples.langchain.models import get_model_from_name_and_api_key
async def run_langchain(prompt: str, model_name: str, api_key: str):
model = get_model_from_name_and_api_key(model_name=model_name, api_key=api_key)
async with get_agent_builder() as builder:
messages = [HumanMessage(content=prompt)]
while True:
agent = create_react_agent(
model,
tools=[tool_to_langchain_tool(tool) for tool in await builder.get_tools()],
prompt=await builder.get_system_prompt(),
# Interrupt after tool calls to dynamically rebuild agent with new tools and system prompt
interrupt_after=["tools"],
)
response = await agent.ainvoke({"messages": messages})
if isinstance(response["messages"][-1], ToolMessage):
messages = response["messages"]
# Continue agent tool calling loop with refreshed system prompt and tools
continue
else:
message = response["messages"][-1].content
print(f"AI Agent: {message}")
break
Using with PydanticAI
The get_pydantic_ai_tools() helper function uses PydanticAI's dynamic function tools feature,
however requires all tool definitions to be built up-front, meaning MCP servers & sessions for all MCP capabilities will need to be initialised even if they are not enabled.
A custom wrapper is also added to the tools which causes the system prompt to be dynamically updated within an agent run.
from pydantic_ai import Agent
from adept_ai.compat.pydantic_ai import get_pydantic_ai_tools
from examples.agent_builder import get_agent_builder
from examples.pydantic_ai.models import build_model_from_name_and_api_key
async def run_pydantic_ai(prompt: str, model_name: str | None, api_key: str | None = None):
# Build the model from name and API key
model = build_model_from_name_and_api_key(model_name, api_key)
async with get_agent_builder() as builder:
agent = Agent(model=model, tools=await get_pydantic_ai_tools(builder), instrument=True)
# Configure the dynamic system prompt
agent.instructions(builder.get_system_prompt)
response = await agent.run(prompt)
print(f"AI Agent: {response.output}")
Advanced
Customise MCP Capabilities
You can create custom StdioMCPCapability or HttpMCPCapability subclasses for a specific MCP server to do things like:
- Customize the behaviour of specific tools, by defining a tool that wraps one or more MCP server tools with arbitrary logic
- Create a hybrid capability which has a mix of MCP and non-MCP tools (and resources)
Future Work
General
- More logging / observability
MCP Capability
- Subscribe to resources for automatic dynamic updates and smart caching
- Dynamic / Templated resources
- MCP prompts
- Tool to allow agent to read resources
License
MIT License
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file adept_ai-0.2.2.tar.gz.
File metadata
- Download URL: adept_ai-0.2.2.tar.gz
- Upload date:
- Size: 34.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d22fe0fc752f414bb8b60a14e924954d48b8bf0bcbd6e0028ee0f0e46a76eb22
|
|
| MD5 |
784acb70709f58955ed3a668a4e37bcf
|
|
| BLAKE2b-256 |
fc40994afe795e85eacae394be91fe87d1ecaaf9755d0bb6c1e7f5f77ac6f845
|
File details
Details for the file adept_ai-0.2.2-py3-none-any.whl.
File metadata
- Download URL: adept_ai-0.2.2-py3-none-any.whl
- Upload date:
- Size: 38.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6a0095d75e080ffe11de3e6b55cccaa62625d5d41b34e2d5714796cf0b6807e6
|
|
| MD5 |
39128ec8f159958edd040aab4876b7fe
|
|
| BLAKE2b-256 |
1dfeb54d94848572c3e62bc279b8af10b7f67976cc6cb911dc7b16461f2ec378
|