845 lines
23 KiB
Markdown
845 lines
23 KiB
Markdown
# Tool Router
|
|
|
|
The Tool Router provides a powerful way to create isolated MCP (Model Context Protocol) sessions for users with scoped access to toolkits and tools. It enables dynamic configuration of which tools are available within a session and manages authentication for multiple toolkits.
|
|
|
|
## Overview
|
|
|
|
Tool Router allows you to:
|
|
|
|
- Create isolated sessions with specific toolkit configurations
|
|
- Manage authentication flows for users across multiple toolkits
|
|
- Access tools via an MCP-compatible server URL
|
|
- Query toolkit connection states
|
|
- Integrate with multiple AI frameworks (OpenAI, Anthropic, LangChain, LlamaIndex, CrewAI)
|
|
|
|
> **Note:** When using MCP clients to connect to Tool Router, you don't need to pass a provider to the Composio constructor. A provider is only required when using `session.tools()` to get framework-specific tool objects.
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
pip install composio
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
### Using MCP (Recommended)
|
|
|
|
When using Tool Router with MCP clients, you don't need to pass a provider:
|
|
|
|
```python
|
|
from composio import Composio
|
|
|
|
composio = Composio()
|
|
|
|
# Create a session for a user with access to Gmail tools
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail']
|
|
)
|
|
|
|
# Use the MCP URL with any MCP-compatible client
|
|
print(session.mcp.url)
|
|
```
|
|
|
|
### Using Framework-Specific Tools
|
|
|
|
If you want to use `session.tools()` to get tools formatted for a specific AI framework, pass the appropriate provider:
|
|
|
|
```python
|
|
from composio import Composio
|
|
from composio_openai import OpenAIProvider
|
|
|
|
composio = Composio(provider=OpenAIProvider())
|
|
|
|
# Create a session for a user with access to Gmail tools
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail']
|
|
)
|
|
|
|
# Get the tools formatted for OpenAI
|
|
tools = session.tools()
|
|
```
|
|
|
|
## Creating Sessions
|
|
|
|
### Basic Session Creation
|
|
|
|
Use `composio.tool_router.create()` to create a new Tool Router session:
|
|
|
|
```python
|
|
from composio import Composio
|
|
|
|
composio = Composio()
|
|
|
|
# Create a session with Gmail access
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail']
|
|
)
|
|
|
|
print(f"Session ID: {session.session_id}")
|
|
print(f"MCP URL: {session.mcp.url}")
|
|
```
|
|
|
|
### Using an Existing Session
|
|
|
|
If you have an existing session ID, you can retrieve it using `composio.tool_router.use()`:
|
|
|
|
```python
|
|
session = composio.tool_router.use('existing_session_id')
|
|
|
|
# Access session properties
|
|
print(session.session_id)
|
|
print(session.mcp.url)
|
|
```
|
|
|
|
## Configuration Options
|
|
|
|
The session creation accepts the following configuration options:
|
|
|
|
### `toolkits`
|
|
|
|
Specify which toolkits to enable or disable in the session.
|
|
|
|
```python
|
|
# Simple list of toolkit slugs to enable
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail', 'slack', 'github']
|
|
)
|
|
|
|
# Explicit enabled configuration
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits={'enable': ['gmail', 'slack']}
|
|
)
|
|
|
|
# Disable specific toolkits (enable all others)
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits={'disable': ['calendar']}
|
|
)
|
|
```
|
|
|
|
### `tools`
|
|
|
|
Fine-grained control over which tools are available within toolkits. This is a dictionary where keys are toolkit slugs and values specify tool configuration for that toolkit.
|
|
|
|
```python
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail', 'github', 'slack'],
|
|
tools={
|
|
# List shorthand - enables only these tools
|
|
'gmail': ['GMAIL_FETCH_EMAILS', 'GMAIL_SEND_EMAIL'],
|
|
|
|
# Explicit enable configuration
|
|
'github': {'enable': ['GITHUB_CREATE_ISSUE', 'GITHUB_LIST_ISSUES']},
|
|
|
|
# Explicit disable configuration
|
|
'slack': {'disable': ['SLACK_DELETE_MESSAGE']},
|
|
|
|
# Filter by MCP tags (readOnlyHint, destructiveHint, idempotentHint, openWorldHint)
|
|
'linear': {'tags': ['readOnlyHint', 'idempotentHint']}
|
|
}
|
|
)
|
|
```
|
|
|
|
### `tags`
|
|
|
|
Global MCP tags to filter tools by across all toolkits. Only tools matching these tags will be available. Toolkit-level tags (specified in `tools`) override this global setting.
|
|
|
|
```python
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail', 'github', 'slack'],
|
|
tags=['readOnlyHint', 'idempotentHint'] # Only show read-only and idempotent tools
|
|
)
|
|
```
|
|
|
|
Available tag values:
|
|
- `'readOnlyHint'`: Tools that only read data
|
|
- `'destructiveHint'`: Tools that modify or delete data
|
|
- `'idempotentHint'`: Tools that can be safely retried
|
|
- `'openWorldHint'`: Tools that operate in an open world context
|
|
|
|
### `auth_configs`
|
|
|
|
Map toolkits to specific authentication configurations:
|
|
|
|
```python
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail', 'github'],
|
|
auth_configs={
|
|
'gmail': 'ac_gmail_work',
|
|
'github': 'ac_github_personal'
|
|
}
|
|
)
|
|
```
|
|
|
|
### `connected_accounts`
|
|
|
|
Map toolkits to specific connected account IDs:
|
|
|
|
```python
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail'],
|
|
connected_accounts={
|
|
'gmail': 'ca_abc123'
|
|
}
|
|
)
|
|
```
|
|
|
|
### `manage_connections`
|
|
|
|
Control how connections are managed within the session:
|
|
|
|
```python
|
|
# Boolean: enable/disable automatic connection management
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail'],
|
|
manage_connections=True # default
|
|
)
|
|
|
|
# Dict: fine-grained control
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail'],
|
|
manage_connections={
|
|
'enable': True, # Whether to use tools to manage connections
|
|
'callback_url': 'https://your-app.com/auth/callback', # Optional OAuth callback URL
|
|
'wait_for_connections': True # NEW in v0.10.5: Wait for connections to complete
|
|
}
|
|
)
|
|
```
|
|
|
|
#### Wait for Connections
|
|
|
|
The `wait_for_connections` property (new in v0.10.5) allows the tool router session to wait for users to complete authentication before proceeding to the next step. When set to `True`, the session will block execution until all required connections are established.
|
|
|
|
```python
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail', 'slack'],
|
|
manage_connections={
|
|
'enable': True,
|
|
'callback_url': 'https://your-app.com/auth/callback',
|
|
'wait_for_connections': True # Session waits for connections to complete
|
|
}
|
|
)
|
|
```
|
|
|
|
### `workbench`
|
|
|
|
Configure workbench behavior:
|
|
|
|
```python
|
|
# Disable workbench entirely — no code execution tools in the session
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail'],
|
|
workbench={
|
|
'enable': False
|
|
}
|
|
)
|
|
|
|
# Fine-tune workbench settings
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail'],
|
|
workbench={
|
|
'enable': True, # default
|
|
'enable_proxy_execution': False, # Whether to allow proxy execute calls in workbench
|
|
'auto_offload_threshold': 300 # Character threshold for auto-offloading large responses to the workbench
|
|
}
|
|
)
|
|
```
|
|
|
|
| Field | Type | Default | Description |
|
|
|-------|------|---------|-------------|
|
|
| `enable` | `bool` | `True` | Enables/disables the workbench entirely. When `False`, `COMPOSIO_REMOTE_WORKBENCH` and `COMPOSIO_REMOTE_BASH_TOOL` are excluded from the session. |
|
|
| `enable_proxy_execution` | `bool` | `True` | Controls proxy API execution in the workbench. |
|
|
| `auto_offload_threshold` | `int` | auto | Character threshold for auto-offloading large responses to the workbench. |
|
|
|
|
## Session Properties and Methods
|
|
|
|
A Tool Router session provides the following properties and methods:
|
|
|
|
### `session_id`
|
|
|
|
The unique identifier for this session.
|
|
|
|
```python
|
|
print(session.session_id)
|
|
```
|
|
|
|
### `mcp`
|
|
|
|
The MCP server configuration for this session, including authentication headers.
|
|
|
|
```python
|
|
print(session.mcp.url) # The URL to connect to
|
|
print(session.mcp.type) # ToolRouterMCPServerType.HTTP or ToolRouterMCPServerType.SSE
|
|
print(session.mcp.headers) # Authentication headers (includes x-api-key)
|
|
```
|
|
|
|
### `tools(modifiers=None)`
|
|
|
|
Retrieve the tools available in the session, formatted for your AI framework.
|
|
|
|
```python
|
|
# Basic usage
|
|
tools = session.tools()
|
|
|
|
# With session-specific modifiers (new in v0.10.5)
|
|
from composio.core.models import before_execute_meta, after_execute_meta
|
|
|
|
@before_execute_meta
|
|
def before_modifier(tool, toolkit, session_id, params):
|
|
print(f"[Session: {session_id}] Executing {tool} from {toolkit}")
|
|
# Add custom logging, validation, or parameter transformation
|
|
return params
|
|
|
|
@after_execute_meta
|
|
def after_modifier(tool, toolkit, session_id, response):
|
|
print(f"[Session: {session_id}] Completed {tool}")
|
|
# Transform results, add telemetry, or handle errors
|
|
return response
|
|
|
|
tools = session.tools(modifiers=[before_modifier, after_modifier])
|
|
```
|
|
|
|
#### Session-Specific Modifiers
|
|
|
|
Tool Router sessions now support enhanced modifiers (introduced in v0.10.5) that include session context:
|
|
|
|
- **`@before_execute_meta`**: Modify parameters before execution, with access to session ID
|
|
- **`@after_execute_meta`**: Transform results after execution, with access to session ID
|
|
- **`@modify_schema_meta`**: Customize tool schemas before they're sent to the AI model
|
|
|
|
These modifiers provide better context for session-based tool execution, allowing you to track which session is executing which tools.
|
|
|
|
### Meta Tools
|
|
|
|
Tool Router provides meta tools for managing connections and session state. You can access these directly using the `get_raw_tool_router_meta_tools` method (introduced in v0.10.5):
|
|
|
|
```python
|
|
from composio import Composio
|
|
from composio.core.models import modify_schema_meta
|
|
|
|
composio = Composio()
|
|
|
|
# Define schema modifier
|
|
@modify_schema_meta
|
|
def schema_modifier(tool, toolkit, schema):
|
|
# Customize meta tool schemas
|
|
print(f"Modifying schema for {tool}")
|
|
return schema
|
|
|
|
# Get raw meta tools for a session
|
|
meta_tools = composio.tools.get_raw_tool_router_meta_tools(
|
|
session_id='session_123',
|
|
modifiers=[schema_modifier]
|
|
)
|
|
|
|
print(f"Available meta tools: {[t.name for t in meta_tools]}")
|
|
```
|
|
|
|
Meta tools allow you to:
|
|
- Authorize new toolkit connections within a session
|
|
- Query toolkit connection states
|
|
- Manage session configuration
|
|
|
|
This method is useful when you need direct access to the underlying meta tools without creating a full session object.
|
|
|
|
### `authorize(toolkit, *, callback_url=None)`
|
|
|
|
Initiate an authorization flow for a toolkit.
|
|
|
|
```python
|
|
# Start authorization for Gmail
|
|
connection_request = session.authorize('gmail')
|
|
|
|
print(connection_request.redirect_url) # URL to redirect user for auth
|
|
|
|
# Wait for the user to complete authorization
|
|
connected_account = connection_request.wait_for_connection()
|
|
print(f"Connected: {connected_account}")
|
|
|
|
# With custom callback URL
|
|
connection_request = session.authorize(
|
|
'gmail',
|
|
callback_url='https://your-app.com/auth/callback'
|
|
)
|
|
```
|
|
|
|
### `toolkits(...)`
|
|
|
|
Query the connection state of toolkits in the session.
|
|
|
|
```python
|
|
# Get all toolkits
|
|
result = session.toolkits()
|
|
|
|
for toolkit in result.items:
|
|
print(f"{toolkit.name} ({toolkit.slug})")
|
|
if toolkit.connection:
|
|
print(f" Connected: {toolkit.connection.is_active}")
|
|
if toolkit.connection.connected_account:
|
|
print(f" Account ID: {toolkit.connection.connected_account.id}")
|
|
print(f" Status: {toolkit.connection.connected_account.status}")
|
|
|
|
# With pagination
|
|
result = session.toolkits(limit=10, next_cursor='cursor_abc')
|
|
|
|
# Filter by specific toolkits
|
|
result = session.toolkits(toolkits=['gmail', 'slack'])
|
|
|
|
# Filter by connection status
|
|
connected_toolkits = session.toolkits(is_connected=True)
|
|
disconnected_toolkits = session.toolkits(is_connected=False)
|
|
|
|
# Combine all options
|
|
result = session.toolkits(
|
|
toolkits=['gmail', 'github'],
|
|
limit=5,
|
|
is_connected=True
|
|
)
|
|
```
|
|
|
|
## Framework Integrations
|
|
|
|
### OpenAI
|
|
|
|
```python
|
|
from openai import OpenAI
|
|
from composio import Composio
|
|
from composio_openai import OpenAIProvider
|
|
|
|
composio = Composio(provider=OpenAIProvider())
|
|
client = OpenAI()
|
|
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail']
|
|
)
|
|
|
|
tools = session.tools()
|
|
|
|
response = client.chat.completions.create(
|
|
model="gpt-4",
|
|
messages=[{"role": "user", "content": "Find my last email from gmail"}],
|
|
tools=tools,
|
|
)
|
|
|
|
print(response.choices[0].message)
|
|
```
|
|
|
|
### Anthropic
|
|
|
|
```python
|
|
from anthropic import Anthropic
|
|
from composio import Composio
|
|
from composio_anthropic import AnthropicProvider
|
|
|
|
composio = Composio(provider=AnthropicProvider())
|
|
client = Anthropic()
|
|
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail']
|
|
)
|
|
|
|
tools = session.tools()
|
|
|
|
response = client.messages.create(
|
|
model="claude-3-opus-20240229",
|
|
max_tokens=1024,
|
|
messages=[{"role": "user", "content": "Find my last email from gmail"}],
|
|
tools=tools,
|
|
)
|
|
|
|
print(response.content)
|
|
```
|
|
|
|
### LangChain
|
|
|
|
```python
|
|
from langchain_openai import ChatOpenAI
|
|
from langchain.agents import create_tool_calling_agent, AgentExecutor
|
|
from langchain_core.prompts import ChatPromptTemplate
|
|
from composio import Composio
|
|
from composio_langchain import LangChainProvider
|
|
|
|
composio = Composio(provider=LangChainProvider())
|
|
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail']
|
|
)
|
|
|
|
tools = session.tools()
|
|
llm = ChatOpenAI(model="gpt-4")
|
|
|
|
prompt = ChatPromptTemplate.from_messages([
|
|
("system", "You are a helpful assistant."),
|
|
("human", "{input}"),
|
|
("placeholder", "{agent_scratchpad}"),
|
|
])
|
|
|
|
agent = create_tool_calling_agent(llm, tools, prompt)
|
|
agent_executor = AgentExecutor(agent=agent, tools=tools)
|
|
|
|
result = agent_executor.invoke({"input": "Find my last email from gmail"})
|
|
print(result)
|
|
```
|
|
|
|
### Using MCP URL Directly
|
|
|
|
You can also use the MCP URL directly with any MCP-compatible client:
|
|
|
|
```python
|
|
from composio import Composio
|
|
|
|
composio = Composio()
|
|
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail'],
|
|
manage_connections=True
|
|
)
|
|
|
|
# Use with any MCP client
|
|
mcp_url = session.mcp.url
|
|
mcp_headers = session.mcp.headers # Pre-configured authentication headers
|
|
print(f"MCP URL: {mcp_url}")
|
|
print(f"MCP Type: {session.mcp.type}") # 'http' or 'sse'
|
|
print(f"MCP Headers: {mcp_headers}") # {'x-api-key': 'your-api-key'}
|
|
```
|
|
|
|
## Authorization Flow
|
|
|
|
When a user needs to connect a toolkit, use the `authorize()` method:
|
|
|
|
```python
|
|
from composio import Composio
|
|
|
|
composio = Composio()
|
|
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail']
|
|
)
|
|
|
|
# Initiate authorization for Gmail
|
|
connection_request = session.authorize('gmail')
|
|
|
|
# Log the redirect URL for the user
|
|
print(f"Redirect URL: {connection_request.redirect_url}")
|
|
|
|
# Wait for the user to complete the authorization (with timeout)
|
|
connected_account = connection_request.wait_for_connection(timeout=300)
|
|
print(f"Connected Account: {connected_account}")
|
|
```
|
|
|
|
You can also provide a custom callback URL:
|
|
|
|
```python
|
|
connection_request = session.authorize(
|
|
'gmail',
|
|
callback_url='https://your-app.com/auth/callback'
|
|
)
|
|
```
|
|
|
|
## Querying Toolkit States
|
|
|
|
Use the `toolkits()` method to check connection states:
|
|
|
|
```python
|
|
from composio import Composio
|
|
|
|
composio = Composio()
|
|
|
|
session = composio.tool_router.create(user_id='user_123')
|
|
|
|
# Get all toolkits
|
|
result = session.toolkits()
|
|
|
|
for toolkit in result.items:
|
|
status = "Connected" if toolkit.connection and toolkit.connection.is_active else "Not connected"
|
|
print(f"{toolkit.name}: {status}")
|
|
|
|
# Get only connected toolkits
|
|
connected = session.toolkits(is_connected=True)
|
|
print(f"You have {len(connected.items)} connected toolkits")
|
|
|
|
# Get only disconnected toolkits (need authorization)
|
|
disconnected = session.toolkits(is_connected=False)
|
|
for toolkit in disconnected.items:
|
|
print(f"Please connect: {toolkit.name}")
|
|
|
|
# Pagination example
|
|
result = session.toolkits(limit=10)
|
|
all_toolkits = list(result.items)
|
|
while result.next_cursor:
|
|
result = session.toolkits(limit=10, next_cursor=result.next_cursor)
|
|
all_toolkits.extend(result.items)
|
|
```
|
|
|
|
The response structure:
|
|
|
|
```python
|
|
{
|
|
'items': [
|
|
{
|
|
'slug': 'gmail',
|
|
'name': 'Gmail',
|
|
'logo': 'https://...',
|
|
'is_no_auth': False,
|
|
'connection': {
|
|
'is_active': True,
|
|
'auth_config': {
|
|
'id': 'ac_xxx',
|
|
'mode': 'OAUTH2',
|
|
'is_composio_managed': True
|
|
},
|
|
'connected_account': {
|
|
'id': 'ca_xxx',
|
|
'status': 'ACTIVE'
|
|
}
|
|
}
|
|
}
|
|
],
|
|
'next_cursor': 'cursor_abc',
|
|
'total_pages': 1
|
|
}
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **User Isolation**: Create separate sessions per user to ensure proper isolation of connections and tools.
|
|
|
|
2. **Toolkit Selection**: Only enable toolkits that are necessary for the use case to maintain security and reduce complexity.
|
|
|
|
3. **Connection Management**: Use `manage_connections=True` (default) for interactive applications where users can be prompted to connect accounts.
|
|
|
|
4. **Tag Filtering**: Use global `tags` to restrict tools to safe operations (e.g., `['readOnlyHint']`) or toolkit-specific tags in the `tools` configuration for fine-grained control.
|
|
|
|
5. **Session Reuse**: Store and reuse `session_id` to maintain user sessions across requests.
|
|
|
|
```python
|
|
import redis
|
|
|
|
# Store session ID after creation
|
|
session = composio.tool_router.create(user_id='user_123', toolkits=['gmail'])
|
|
redis_client.set(f"session:user_123", session.session_id)
|
|
|
|
# Retrieve existing session
|
|
session_id = redis_client.get(f"session:user_123")
|
|
if session_id:
|
|
session = composio.tool_router.use(session_id)
|
|
```
|
|
|
|
## Type Reference
|
|
|
|
### ToolRouterSession
|
|
|
|
```python
|
|
@dataclass
|
|
class ToolRouterSession:
|
|
session_id: str
|
|
mcp: ToolRouterMCPServerConfig
|
|
tools: Callable[[Optional[Modifiers]], Any]
|
|
authorize: Callable[..., ConnectionRequest]
|
|
toolkits: Callable[..., ToolkitConnectionsDetails]
|
|
```
|
|
|
|
### ToolRouterMCPServerConfig
|
|
|
|
```python
|
|
class ToolRouterMCPServerType(str, Enum):
|
|
HTTP = "http"
|
|
SSE = "sse"
|
|
|
|
@dataclass
|
|
class ToolRouterMCPServerConfig:
|
|
type: ToolRouterMCPServerType
|
|
url: str
|
|
headers: Optional[Dict[str, Optional[str]]] = None # Authentication headers (includes x-api-key)
|
|
```
|
|
|
|
### ToolkitConnectionState
|
|
|
|
```python
|
|
@dataclass
|
|
class ToolkitConnectionState:
|
|
slug: str
|
|
name: str
|
|
is_no_auth: bool
|
|
connection: Optional[ToolkitConnection] = None
|
|
logo: Optional[str] = None
|
|
|
|
@dataclass
|
|
class ToolkitConnection:
|
|
is_active: bool
|
|
auth_config: Optional[ToolkitConnectionAuthConfig] = None
|
|
connected_account: Optional[ToolkitConnectedAccount] = None
|
|
|
|
@dataclass
|
|
class ToolkitConnectionAuthConfig:
|
|
id: str
|
|
mode: str
|
|
is_composio_managed: bool
|
|
|
|
@dataclass
|
|
class ToolkitConnectedAccount:
|
|
id: str
|
|
status: str
|
|
```
|
|
|
|
### ToolkitConnectionsDetails
|
|
|
|
```python
|
|
@dataclass
|
|
class ToolkitConnectionsDetails:
|
|
items: List[ToolkitConnectionState]
|
|
total_pages: int
|
|
next_cursor: Optional[str] = None
|
|
```
|
|
|
|
### Configuration Types
|
|
|
|
```python
|
|
from typing import List, Dict, Union, Literal
|
|
from typing_extensions import TypedDict
|
|
|
|
# Toolkits configuration
|
|
ToolRouterToolkitsEnableConfig = TypedDict('ToolRouterToolkitsEnableConfig', {
|
|
'enable': List[str]
|
|
})
|
|
|
|
ToolRouterToolkitsDisableConfig = TypedDict('ToolRouterToolkitsDisableConfig', {
|
|
'disable': List[str]
|
|
})
|
|
|
|
toolkits: Union[
|
|
List[str], # ['gmail', 'slack']
|
|
ToolRouterToolkitsEnableConfig, # {'enable': ['gmail', 'slack']}
|
|
ToolRouterToolkitsDisableConfig # {'disable': ['calendar']}
|
|
]
|
|
|
|
# Tools configuration
|
|
ToolRouterToolsEnableConfig = TypedDict('ToolRouterToolsEnableConfig', {
|
|
'enable': List[str]
|
|
})
|
|
|
|
ToolRouterToolsDisableConfig = TypedDict('ToolRouterToolsDisableConfig', {
|
|
'disable': List[str]
|
|
})
|
|
|
|
ToolRouterToolsTagsConfig = TypedDict('ToolRouterToolsTagsConfig', {
|
|
'tags': List[Literal['readOnlyHint', 'destructiveHint', 'idempotentHint', 'openWorldHint']]
|
|
})
|
|
|
|
ToolRouterToolsConfig = Union[
|
|
List[str], # ['GMAIL_SEND_EMAIL', 'GMAIL_FETCH_EMAILS']
|
|
ToolRouterToolsEnableConfig, # {'enable': ['GMAIL_SEND_EMAIL']}
|
|
ToolRouterToolsDisableConfig, # {'disable': ['GMAIL_DELETE_EMAIL']}
|
|
ToolRouterToolsTagsConfig # {'tags': ['readOnlyHint']}
|
|
]
|
|
|
|
tools: Dict[str, ToolRouterToolsConfig] # Key is toolkit slug, value is ToolRouterToolsConfig
|
|
|
|
# Tags configuration (global)
|
|
tags: List[Literal['readOnlyHint', 'destructiveHint', 'idempotentHint', 'openWorldHint']]
|
|
|
|
# Manage connections configuration
|
|
ToolRouterManageConnectionsConfig = TypedDict('ToolRouterManageConnectionsConfig', {
|
|
'enable': bool,
|
|
'callback_url': str, # Optional
|
|
'wait_for_connections': bool # NEW in v0.10.5: Wait for connections to complete
|
|
})
|
|
|
|
manage_connections: Union[
|
|
bool,
|
|
ToolRouterManageConnectionsConfig # {'enable': True, 'callback_url': 'https://...', 'wait_for_connections': True}
|
|
]
|
|
|
|
# Workbench configuration
|
|
ToolRouterWorkbenchConfig = TypedDict('ToolRouterWorkbenchConfig', {
|
|
'enable': bool, # Enable/disable workbench entirely (default: True)
|
|
'enable_proxy_execution': bool, # Whether to allow proxy execute calls
|
|
'auto_offload_threshold': int # Character threshold for auto-offloading execution to workbench
|
|
})
|
|
|
|
workbench: ToolRouterWorkbenchConfig
|
|
```
|
|
|
|
## What's New in v0.10.5
|
|
|
|
### 1. Wait for Connections
|
|
|
|
The new `wait_for_connections` property allows sessions to wait for users to complete authentication before proceeding:
|
|
|
|
```python
|
|
session = composio.tool_router.create(
|
|
user_id='user_123',
|
|
toolkits=['gmail', 'slack'],
|
|
manage_connections={
|
|
'enable': True,
|
|
'callback_url': 'https://your-app.com/callback',
|
|
'wait_for_connections': True # NEW
|
|
}
|
|
)
|
|
```
|
|
|
|
### 2. Enhanced Session Modifiers
|
|
|
|
Session-specific modifiers now include session context, making it easier to track and manage tool execution:
|
|
|
|
```python
|
|
from composio.core.models import before_execute_meta, after_execute_meta
|
|
|
|
@before_execute_meta
|
|
def before_modifier(tool, toolkit, session_id, params):
|
|
print(f"[{session_id}] Executing {tool}")
|
|
return params
|
|
|
|
@after_execute_meta
|
|
def after_modifier(tool, toolkit, session_id, response):
|
|
print(f"[{session_id}] Completed {tool}")
|
|
return response
|
|
|
|
tools = session.tools(modifiers=[before_modifier, after_modifier])
|
|
```
|
|
|
|
### 3. Direct Meta Tools Access
|
|
|
|
New method to fetch meta tools directly from a session:
|
|
|
|
```python
|
|
from composio.core.models import modify_schema_meta
|
|
|
|
@modify_schema_meta
|
|
def schema_modifier(tool, toolkit, schema):
|
|
return schema
|
|
|
|
meta_tools = composio.tools.get_raw_tool_router_meta_tools(
|
|
session_id='session_123',
|
|
modifiers=[schema_modifier]
|
|
)
|
|
```
|
|
|
|
### 4. Performance Improvements
|
|
|
|
- Optimized tool fetching with fewer API calls
|
|
- Improved session API architecture for better reliability
|
|
- Simplified internal tool execution paths
|
|
|
|
All changes in v0.10.5 are fully backward compatible with existing code.
|
|
|