chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
"""
|
||||
Tool Router - Authorization Example
|
||||
|
||||
This example demonstrates how to authorize a toolkit connection
|
||||
within a Tool Router session.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from composio import Composio
|
||||
|
||||
# Initialize Composio
|
||||
# Set COMPOSIO_API_KEY environment variable or pass api_key parameter
|
||||
api_key = os.environ.get("COMPOSIO_API_KEY")
|
||||
if not api_key:
|
||||
print("Error: COMPOSIO_API_KEY environment variable not set")
|
||||
print("Please set it using: export COMPOSIO_API_KEY='your_api_key'")
|
||||
exit(1)
|
||||
|
||||
composio = Composio(api_key=api_key)
|
||||
|
||||
# Create a tool router session
|
||||
session = composio.create(
|
||||
user_id="user_123",
|
||||
toolkits=["github", "gmail"],
|
||||
)
|
||||
|
||||
print(f"Session created: {session.session_id}")
|
||||
|
||||
# Authorize a toolkit connection
|
||||
# This initiates the OAuth flow and returns a connection request
|
||||
connection_request = session.authorize("github")
|
||||
|
||||
print(f"\nConnection Request ID: {connection_request.id}")
|
||||
print(f"Status: {connection_request.status}")
|
||||
print(f"Redirect URL: {connection_request.redirect_url}")
|
||||
print("\nPlease visit the URL above to authorize the connection.")
|
||||
|
||||
# Wait for the user to complete the authorization
|
||||
# This will poll the API until the connection is active or timeout occurs
|
||||
try:
|
||||
connected_account = connection_request.wait_for_connection()
|
||||
print("\n✅ Connection successful!")
|
||||
print(f"Connected Account ID: {connected_account.id}")
|
||||
print(f"Status: {connected_account.status}")
|
||||
except Exception as e:
|
||||
print(f"\n❌ Connection failed: {e}")
|
||||
@@ -0,0 +1,33 @@
|
||||
import asyncio
|
||||
|
||||
from claude_agent_sdk import ClaudeAgentOptions, query
|
||||
from composio_claude_agent_sdk import ClaudeAgentSDKProvider
|
||||
|
||||
from composio import Composio
|
||||
|
||||
composio = Composio(provider=ClaudeAgentSDKProvider())
|
||||
session = composio.create(
|
||||
user_id="user_123",
|
||||
)
|
||||
|
||||
|
||||
async def main():
|
||||
options = ClaudeAgentOptions(
|
||||
system_prompt="You are an expert Python developer",
|
||||
permission_mode="bypassPermissions",
|
||||
mcp_servers={
|
||||
"composio": {
|
||||
"type": session.mcp.type,
|
||||
"url": session.mcp.url,
|
||||
"headers": session.mcp.headers,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
async for message in query(
|
||||
prompt="Fetch my last email and summarize it.", options=options
|
||||
):
|
||||
print(message)
|
||||
|
||||
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,32 @@
|
||||
from crewai import Agent, Crew, Task
|
||||
from crewai.mcp import MCPServerHTTP
|
||||
|
||||
from composio import Composio
|
||||
|
||||
composio = Composio()
|
||||
session = composio.create(
|
||||
user_id="user_123",
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
role="Gmail agent",
|
||||
goal="helps with gmail related queries",
|
||||
backstory="You are a helpful assistant that can use the tools provided to you.",
|
||||
mcps=[
|
||||
MCPServerHTTP(
|
||||
url=session.mcp.url,
|
||||
headers=session.mcp.headers,
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
# Define task
|
||||
task = Task(
|
||||
description=("Find the last email and summarize it."),
|
||||
expected_output="A summary of the last email including sender, subject, and key points.",
|
||||
agent=agent,
|
||||
)
|
||||
|
||||
my_crew = Crew(agents=[agent], tasks=[task])
|
||||
result = my_crew.kickoff()
|
||||
print(result)
|
||||
@@ -0,0 +1,95 @@
|
||||
"""
|
||||
Tool Router direct_tools session preset with OpenAI Agents.
|
||||
|
||||
SESSION_PRESET_DIRECT_TOOLS is a shortcut for sessions where the full allowed
|
||||
tool set is known upfront. It loads all tools allowed by the filters directly
|
||||
into session.tools() and the MCP tool list.
|
||||
|
||||
Usage:
|
||||
COMPOSIO_API_KEY=... OPENAI_API_KEY=... python examples/tool_router/direct_tools_preset.py
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from agents import Agent, Runner
|
||||
from composio_openai_agents import OpenAIAgentsProvider
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from composio import Composio, SESSION_PRESET_DIRECT_TOOLS
|
||||
|
||||
|
||||
def require_env(name: str) -> str:
|
||||
value = os.environ.get(name)
|
||||
if not value:
|
||||
raise RuntimeError(f"Set {name} before running this example.")
|
||||
return value
|
||||
|
||||
|
||||
composio = Composio(
|
||||
api_key=require_env("COMPOSIO_API_KEY"),
|
||||
base_url=os.environ.get("COMPOSIO_BASE_URL"),
|
||||
provider=OpenAIAgentsProvider(),
|
||||
)
|
||||
require_env("OPENAI_API_KEY")
|
||||
|
||||
|
||||
class UserNoteInput(BaseModel):
|
||||
username: str = Field(description="Hacker News username, for example pg")
|
||||
|
||||
|
||||
hn_research = composio.experimental.Toolkit(
|
||||
slug="HN_RESEARCH",
|
||||
name="Hacker News research",
|
||||
description="Internal research notes for Hacker News users.",
|
||||
)
|
||||
|
||||
|
||||
@hn_research.tool(
|
||||
slug="GET_USER_NOTE",
|
||||
name="Get Hacker News user note",
|
||||
description="Return an internal research note for a Hacker News username.",
|
||||
)
|
||||
def get_user_note(input: UserNoteInput, ctx):
|
||||
username = input.username.lower()
|
||||
return {
|
||||
"username": input.username,
|
||||
"note": (
|
||||
"Paul Graham; YC co-founder and essayist."
|
||||
if username == "pg"
|
||||
else f"No curated internal note for {input.username}."
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
session = composio.create(
|
||||
user_id="direct-tools-example-user",
|
||||
session_preset=SESSION_PRESET_DIRECT_TOOLS,
|
||||
toolkits=["hackernews"],
|
||||
tools={"hackernews": {"enable": ["HACKERNEWS_GET_USER"]}},
|
||||
experimental={
|
||||
"custom_toolkits": [hn_research],
|
||||
},
|
||||
)
|
||||
|
||||
tools = session.tools()
|
||||
tool_names = [tool.name for tool in tools]
|
||||
assert "HACKERNEWS_GET_USER" in tool_names
|
||||
assert "LOCAL_HN_RESEARCH_GET_USER_NOTE" in tool_names
|
||||
assert "COMPOSIO_SEARCH_TOOLS" not in tool_names
|
||||
|
||||
print("Direct tools exposed to the agent:")
|
||||
for tool in tools:
|
||||
print(f"- {tool.name}")
|
||||
|
||||
agent = Agent(
|
||||
name="Direct Tools Demo Agent",
|
||||
instructions="Use the provided tools to perform the task.",
|
||||
model=os.environ.get("OPENAI_MODEL", "gpt-5.5"),
|
||||
tools=tools,
|
||||
)
|
||||
|
||||
result = Runner.run_sync(
|
||||
agent,
|
||||
'Look up user "pg" on Hacker News and include any internal research note.',
|
||||
)
|
||||
print(result.final_output)
|
||||
@@ -0,0 +1,85 @@
|
||||
"""
|
||||
Example demonstrating the Tool Router session files API.
|
||||
|
||||
Shows how to list, upload, download, and delete files in a tool router
|
||||
session's virtual filesystem. Also demonstrates search and execute.
|
||||
|
||||
Requires COMPOSIO_API_KEY and OPENAI_API_KEY to be set.
|
||||
"""
|
||||
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
from composio import Composio
|
||||
from composio_openai import OpenAIProvider
|
||||
|
||||
|
||||
def main():
|
||||
composio = Composio(provider=OpenAIProvider())
|
||||
|
||||
# Create a session
|
||||
print("Creating tool router session...")
|
||||
session = composio.tool_router.create(user_id="demo_files_user")
|
||||
print(f" Session ID: {session.session_id}")
|
||||
|
||||
# Upload a file (from bytes)
|
||||
print("\nUploading file (bytes)...")
|
||||
remote = session.experimental.files.upload(
|
||||
b'{"hello": "world"}',
|
||||
remote_path="test_data.json",
|
||||
mimetype="application/json",
|
||||
)
|
||||
print(f" Uploaded to: {remote.mount_relative_path}")
|
||||
|
||||
# List files
|
||||
print("\nListing files...")
|
||||
result = session.experimental.files.list(path="/")
|
||||
print(f" Items: {len(result.items)}")
|
||||
for item in result.items:
|
||||
print(f" - {item.mount_relative_path} ({item.size} bytes)")
|
||||
|
||||
# Download the file
|
||||
print("\nDownloading file...")
|
||||
downloaded = session.experimental.files.download(remote.mount_relative_path)
|
||||
content = downloaded.text()
|
||||
print(f" Content: {content[:80]}...")
|
||||
|
||||
# Upload from local file
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) as f:
|
||||
f.write("Hello from local file")
|
||||
local_path = f.name
|
||||
try:
|
||||
print("\nUploading from local path...")
|
||||
remote2 = session.experimental.files.upload(local_path)
|
||||
print(f" Uploaded to: {remote2.mount_relative_path}")
|
||||
finally:
|
||||
Path(local_path).unlink(missing_ok=True)
|
||||
|
||||
# List again
|
||||
print("\nListing files (after 2nd upload)...")
|
||||
result2 = session.experimental.files.list(path="/")
|
||||
print(f" Items: {len(result2.items)}")
|
||||
for item in result2.items:
|
||||
print(f" - {item.mount_relative_path} ({item.size} bytes)")
|
||||
|
||||
# Delete
|
||||
print("\nDeleting test files...")
|
||||
session.experimental.files.delete(remote.mount_relative_path)
|
||||
session.experimental.files.delete(remote2.mount_relative_path)
|
||||
print(" Deleted.")
|
||||
|
||||
# Search for tools
|
||||
print("\nSearching for tools...")
|
||||
search_result = session.search(query="send email")
|
||||
print(f" Success: {search_result.success}, Results: {len(search_result.results)}")
|
||||
if search_result.results:
|
||||
r = search_result.results[0]
|
||||
print(
|
||||
f" First result: {r.primary_tool_slugs[:3] if r.primary_tool_slugs else []}"
|
||||
)
|
||||
|
||||
print("\nAll files API operations succeeded.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,48 @@
|
||||
import asyncio
|
||||
|
||||
from langchain.agents import create_agent
|
||||
from langchain_mcp_adapters.client import MultiServerMCPClient
|
||||
from langchain_openai.chat_models import ChatOpenAI
|
||||
|
||||
from composio import Composio
|
||||
|
||||
composio = Composio()
|
||||
session = composio.create(
|
||||
user_id="user_123",
|
||||
)
|
||||
|
||||
|
||||
async def main():
|
||||
try:
|
||||
mcp_client = MultiServerMCPClient(
|
||||
{
|
||||
"composio": {
|
||||
"transport": "streamable_http",
|
||||
"url": session.mcp.url,
|
||||
"headers": session.mcp.headers,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
tools = await mcp_client.get_tools()
|
||||
|
||||
agent = create_agent(
|
||||
tools=tools,
|
||||
model=ChatOpenAI(model="gpt-4o"),
|
||||
)
|
||||
|
||||
result = await agent.ainvoke(
|
||||
{
|
||||
"messages": [
|
||||
{"role": "user", "content": "Fetch my last email and summarize?"}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
print(result)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,33 @@
|
||||
from agents import Agent, HostedMCPTool, Runner
|
||||
|
||||
from composio import Composio
|
||||
|
||||
composio = Composio()
|
||||
session = composio.create(
|
||||
user_id="user_123",
|
||||
)
|
||||
|
||||
print(session.mcp)
|
||||
|
||||
composio_mcp = HostedMCPTool(
|
||||
tool_config={
|
||||
"type": "mcp",
|
||||
"server_label": "tool_router",
|
||||
"server_url": session.mcp.url,
|
||||
"require_approval": "never",
|
||||
"headers": session.mcp.headers,
|
||||
}
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
name="My Agent",
|
||||
instructions="You are a helpful assistant that can use the tools provided to you.",
|
||||
tools=[composio_mcp],
|
||||
)
|
||||
|
||||
result = Runner.run_sync(
|
||||
starting_agent=agent,
|
||||
input="Find my last email and summarize it.",
|
||||
)
|
||||
|
||||
print(result.final_output)
|
||||
@@ -0,0 +1,170 @@
|
||||
"""
|
||||
Tool Router preload with OpenAI Agents.
|
||||
|
||||
Shows direct tool exposure for:
|
||||
1. Composio tools via preload["tools"].
|
||||
2. SDK custom tools via preload=True on the custom tool or toolkit.
|
||||
3. A nested custom tool override with preload=False inside a preloaded toolkit.
|
||||
|
||||
Usage:
|
||||
COMPOSIO_API_KEY=... OPENAI_API_KEY=... python examples/tool_router/preload.py
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from agents import Agent, Runner
|
||||
from composio_openai_agents import OpenAIAgentsProvider
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from composio import Composio
|
||||
|
||||
|
||||
def require_env(name: str) -> str:
|
||||
value = os.environ.get(name)
|
||||
if not value:
|
||||
raise RuntimeError(f"Set {name} before running this example.")
|
||||
return value
|
||||
|
||||
|
||||
class UserLookupInput(BaseModel):
|
||||
user_id: str = Field(description="Internal user ID, for example user-1")
|
||||
|
||||
|
||||
class TeamSearchInput(BaseModel):
|
||||
team: str = Field(description="Team name to search for")
|
||||
|
||||
|
||||
class AccountInput(BaseModel):
|
||||
user_id: str = Field(description="Internal user ID")
|
||||
|
||||
|
||||
INTERNAL_USERS = {
|
||||
"user-1": {
|
||||
"id": "user-1",
|
||||
"name": "Ada Lovelace",
|
||||
"email": "ada@example.com",
|
||||
"team": "platform",
|
||||
"plan": "enterprise",
|
||||
},
|
||||
"user-2": {
|
||||
"id": "user-2",
|
||||
"name": "Grace Hopper",
|
||||
"email": "grace@example.com",
|
||||
"team": "developer-tools",
|
||||
"plan": "startup",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
composio = Composio(
|
||||
api_key=require_env("COMPOSIO_API_KEY"),
|
||||
base_url=os.environ.get("COMPOSIO_BASE_URL"),
|
||||
provider=OpenAIAgentsProvider(),
|
||||
)
|
||||
require_env("OPENAI_API_KEY")
|
||||
|
||||
|
||||
@composio.experimental.tool(
|
||||
slug="LOOKUP_INTERNAL_USER",
|
||||
name="Lookup internal user",
|
||||
description="Look up an internal demo user profile by user ID.",
|
||||
preload=True,
|
||||
)
|
||||
def lookup_internal_user(input: UserLookupInput, ctx):
|
||||
user = INTERNAL_USERS.get(input.user_id)
|
||||
if not user:
|
||||
raise ValueError(f'User "{input.user_id}" not found')
|
||||
return user
|
||||
|
||||
|
||||
@composio.experimental.tool(
|
||||
slug="SEARCH_INTERNAL_USERS",
|
||||
name="Search internal users",
|
||||
description=(
|
||||
"Search demo internal users by team. This custom tool is search-only "
|
||||
"because preload is not enabled."
|
||||
),
|
||||
)
|
||||
def search_internal_users(input: TeamSearchInput, ctx):
|
||||
return {
|
||||
"results": [
|
||||
user for user in INTERNAL_USERS.values() if user["team"] == input.team
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
internal_admin = composio.experimental.Toolkit(
|
||||
slug="INTERNAL_ADMIN",
|
||||
name="Internal admin",
|
||||
description="Demo internal administration tools.",
|
||||
preload=True,
|
||||
)
|
||||
|
||||
|
||||
@internal_admin.tool(
|
||||
slug="GET_ACCOUNT_HEALTH",
|
||||
name="Get account health",
|
||||
description="Return internal account health details for a user.",
|
||||
)
|
||||
def get_account_health(input: AccountInput, ctx):
|
||||
return {
|
||||
"user_id": input.user_id,
|
||||
"health": "green",
|
||||
"open_incidents": 0,
|
||||
"renewal_risk": "low",
|
||||
}
|
||||
|
||||
|
||||
@internal_admin.tool(
|
||||
slug="GET_ACCOUNT_AUDIT_LOG",
|
||||
name="Get account audit log",
|
||||
description=(
|
||||
"Return internal account audit events. This overrides the toolkit "
|
||||
"preload default and remains search-only."
|
||||
),
|
||||
preload=False,
|
||||
)
|
||||
def get_account_audit_log(input: AccountInput, ctx):
|
||||
return {
|
||||
"user_id": input.user_id,
|
||||
"events": ["login", "settings_viewed"],
|
||||
}
|
||||
|
||||
|
||||
session = composio.create(
|
||||
user_id="preload-example-user",
|
||||
toolkits=["hackernews"],
|
||||
tools={"hackernews": {"enable": ["HACKERNEWS_GET_USER"]}},
|
||||
preload={"tools": ["HACKERNEWS_GET_USER"]},
|
||||
manage_connections=False,
|
||||
experimental={
|
||||
"custom_tools": [lookup_internal_user, search_internal_users],
|
||||
"custom_toolkits": [internal_admin],
|
||||
},
|
||||
)
|
||||
|
||||
tools = session.tools()
|
||||
tool_names = [tool.name for tool in tools]
|
||||
assert "HACKERNEWS_GET_USER" in tool_names
|
||||
assert "LOCAL_LOOKUP_INTERNAL_USER" in tool_names
|
||||
assert "LOCAL_INTERNAL_ADMIN_GET_ACCOUNT_HEALTH" in tool_names
|
||||
assert "LOCAL_SEARCH_INTERNAL_USERS" not in tool_names
|
||||
assert "LOCAL_INTERNAL_ADMIN_GET_ACCOUNT_AUDIT_LOG" not in tool_names
|
||||
|
||||
print("Direct tools exposed to the agent:")
|
||||
for tool in tools:
|
||||
print(f"- {tool.name}")
|
||||
|
||||
agent = Agent(
|
||||
name="Preload Demo Agent",
|
||||
instructions="Use the provided tools to perform the task.",
|
||||
model=os.environ.get("OPENAI_MODEL", "gpt-5.5"),
|
||||
tools=tools,
|
||||
)
|
||||
|
||||
prompt = (
|
||||
'Look up Hacker News user "pg", then look up internal user user-1 and '
|
||||
"their account health. Summarize the useful facts."
|
||||
)
|
||||
result = Runner.run_sync(agent, prompt)
|
||||
print(result.final_output)
|
||||
@@ -0,0 +1,47 @@
|
||||
"""
|
||||
Tool Router - Session Update Example
|
||||
|
||||
Demonstrates using session.update() to modify a session's configuration
|
||||
after creation — e.g. adding toolkits, changing workbench settings, or
|
||||
updating preload config without creating a new session.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from composio import Composio
|
||||
|
||||
composio = Composio(base_url=os.environ.get("COMPOSIO_BASE_URL"))
|
||||
|
||||
# Create a session with gmail only
|
||||
session = composio.create(
|
||||
user_id="session-update-demo",
|
||||
toolkits=["gmail"],
|
||||
manage_connections=False,
|
||||
)
|
||||
|
||||
print(f"Session created: {session.session_id}")
|
||||
print(f"Preload: {session.preload}")
|
||||
|
||||
# Update: add github toolkit, enable workbench, and preload a tool
|
||||
session.update(
|
||||
toolkits={"enable": ["gmail", "github"]},
|
||||
workbench={"enable": True, "sandbox_size": "medium"},
|
||||
preload={"tools": ["GITHUB_CREATE_AN_ISSUE"]},
|
||||
)
|
||||
|
||||
print("\nAfter update:")
|
||||
print(f"Preload: {session.preload}")
|
||||
|
||||
# Update: disable workbench entirely
|
||||
session.update(
|
||||
workbench={"enable": False},
|
||||
)
|
||||
|
||||
print("\nAfter disabling workbench: done")
|
||||
|
||||
# Update: clear manage_connections by passing None
|
||||
session.update(
|
||||
manage_connections=None,
|
||||
)
|
||||
|
||||
print("\nAfter clearing manage_connections: done")
|
||||
@@ -0,0 +1,73 @@
|
||||
"""
|
||||
Tool Router - MCP (Model Context Protocol) Example with OpenAI Agents
|
||||
|
||||
This example demonstrates how to use Tool Router with MCP servers and OpenAI Agents provider.
|
||||
The MCP server provides a standardized way to access tools across different platforms,
|
||||
and OpenAI Agents provider allows you to use these tools with OpenAI's agent framework.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from agents import Agent, HostedMCPTool, Runner
|
||||
from composio_openai_agents import OpenAIAgentsProvider
|
||||
|
||||
from composio import Composio
|
||||
|
||||
|
||||
async def main():
|
||||
# Initialize Composio with OpenAI Agents provider
|
||||
# Set COMPOSIO_API_KEY environment variable or pass api_key parameter
|
||||
api_key = os.environ.get("COMPOSIO_API_KEY")
|
||||
if not api_key:
|
||||
print("Error: COMPOSIO_API_KEY environment variable not set")
|
||||
print("Please set it using: export COMPOSIO_API_KEY='your_api_key'")
|
||||
return
|
||||
|
||||
composio = Composio(api_key=api_key, provider=OpenAIAgentsProvider())
|
||||
|
||||
# Create a tool router session
|
||||
session = composio.create(
|
||||
user_id="user_123",
|
||||
toolkits=["github", "gmail"],
|
||||
)
|
||||
|
||||
mcpTool = HostedMCPTool(
|
||||
tool_config={
|
||||
"type": "mcp",
|
||||
"server_label": "tool_router",
|
||||
"server_url": session.mcp.url,
|
||||
"require_approval": "never",
|
||||
"headers": session.mcp.headers,
|
||||
}
|
||||
)
|
||||
|
||||
print(f"Session created: {session.session_id}")
|
||||
print(f"MCP Server URL: {session.mcp.url}")
|
||||
print(f"MCP Server Type: {session.mcp.type}")
|
||||
|
||||
# Create an agent with the tools from tool router
|
||||
agent = Agent(
|
||||
name="MCP Tool Router Agent",
|
||||
instructions=(
|
||||
"You are a helpful assistant that can use GitHub and Gmail tools "
|
||||
"through the MCP (Model Context Protocol) server. "
|
||||
"Help users with their GitHub and email tasks."
|
||||
),
|
||||
tools=[mcpTool],
|
||||
)
|
||||
|
||||
# Run the agent with a sample task
|
||||
print("\n--- Running Agent with Tool Router Tools ---")
|
||||
result = await Runner.run(
|
||||
starting_agent=agent,
|
||||
input=(
|
||||
"List my recent GitHub repositories and tell me about them. "
|
||||
"If successful, respond with a summary of what you found."
|
||||
),
|
||||
)
|
||||
print(f"\nAgent Result: {result.final_output}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,27 @@
|
||||
"""
|
||||
Tool Router - Toolkits Example
|
||||
|
||||
This example demonstrates how to retrieve available toolkits
|
||||
and their connection status in a Tool Router session.
|
||||
"""
|
||||
|
||||
from composio import Composio
|
||||
|
||||
composio = Composio()
|
||||
|
||||
# Create a tool router session
|
||||
# When manage_connections is enabled, tools for managing connections are included
|
||||
session = composio.create(
|
||||
user_id="pg-test-37ee710c-d5be-4775-91f2-a8e06b937d9b",
|
||||
manage_connections=True,
|
||||
)
|
||||
|
||||
print(f"Session created: {session.session_id}")
|
||||
print(f"MCP Server: {session.mcp.url}")
|
||||
|
||||
# Get available toolkits for the session
|
||||
# This returns information about all toolkits available to the user
|
||||
toolkits = session.toolkits()
|
||||
|
||||
print("\nAvailable toolkits:")
|
||||
print(toolkits)
|
||||
@@ -0,0 +1,91 @@
|
||||
"""
|
||||
Tool Router - OpenAI Agents Example
|
||||
|
||||
This example demonstrates how to use Tool Router with OpenAI Agents framework.
|
||||
OpenAI Agents provides a powerful way to build AI agents that can use tools
|
||||
and execute complex workflows.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
|
||||
from agents import Agent, Runner
|
||||
from composio_openai_agents import OpenAIAgentsProvider
|
||||
|
||||
from composio import Composio, after_execute, before_execute
|
||||
from composio.types import ToolExecuteParams, ToolExecutionResponse
|
||||
|
||||
|
||||
async def main():
|
||||
# Initialize Composio with OpenAI Agents provider
|
||||
composio = Composio(provider=OpenAIAgentsProvider())
|
||||
|
||||
# Create a tool router session for a specific user
|
||||
# This creates an isolated session with tools for the specified toolkits
|
||||
session = composio.create(
|
||||
user_id="user_123",
|
||||
toolkits=["gmail"],
|
||||
)
|
||||
|
||||
# Define logging modifiers to track tool calls
|
||||
# Pass empty lists to apply to all tools
|
||||
@before_execute(tools=[])
|
||||
def log_before_execute(
|
||||
tool: str,
|
||||
toolkit: str,
|
||||
params: ToolExecuteParams,
|
||||
) -> ToolExecuteParams:
|
||||
"""Log tool execution before it runs."""
|
||||
print(f"🔧 Executing tool: {toolkit}.{tool}")
|
||||
print(f" Arguments: {params.get('arguments', {})}")
|
||||
return params
|
||||
|
||||
@after_execute(tools=[])
|
||||
def log_after_execute(
|
||||
tool: str,
|
||||
toolkit: str,
|
||||
response: ToolExecutionResponse,
|
||||
) -> ToolExecutionResponse:
|
||||
"""Log tool execution after it completes."""
|
||||
print(f"✅ Completed tool: {toolkit}.{tool}")
|
||||
if "data" in response:
|
||||
print(f" Response data: {response['data']}")
|
||||
return response
|
||||
|
||||
# Get tools wrapped for OpenAI Agents with logging modifiers
|
||||
# These tools are ready to be used with the OpenAI Agents framework
|
||||
tools = session.tools(modifiers=[log_before_execute, log_after_execute])
|
||||
|
||||
print(f"\nAvailable tools: {len(tools)}")
|
||||
|
||||
# Create an agent with the tools from the session
|
||||
agent = Agent(
|
||||
name="Gmail Assistant",
|
||||
instructions=(
|
||||
"You are a helpful assistant that helps users manage their "
|
||||
"Gmail accounts. You can check emails, "
|
||||
"send messages, and perform various actions on the Gmail platform."
|
||||
),
|
||||
tools=tools,
|
||||
)
|
||||
|
||||
# Define the task
|
||||
task = "Fetch my last email from gmail and summarize it"
|
||||
|
||||
print(f"\nTask: {task}")
|
||||
print("\nAgent working...\n")
|
||||
|
||||
# Run the agent
|
||||
result = await Runner.run(
|
||||
starting_agent=agent,
|
||||
input=task,
|
||||
)
|
||||
|
||||
# Print the final output
|
||||
print("\n" + "=" * 50)
|
||||
print("RESULT:")
|
||||
print("=" * 50)
|
||||
print(result.final_output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user