# Provider System - Guia Visual
## π¬ Fluxo Completo: Do Composio ao Framework
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. COMPOSIO CORE - Formato Universal β
β β
β Tool { β
β slug: "GITHUB_CREATE_ISSUE" β
β description: "Create a GitHub issue" β
β input_parameters: { β
β type: "object", β
β properties: { β
β owner: {type: "string"}, β
β repo: {type: "string"}, β
β title: {type: "string"} β
β } β
β } β
β } β
ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββ
β
β provider.wrap_tool(tool)
β
ββββββββββββββββββββ΄βββββββββββββββββββ
β β
βΌ βΌ
βββββββββββββββββββββββββ ββββββββββββββββββββββββββ
β 2A. OPENAI FORMAT β β 2B. ANTHROPIC FORMAT β
β β β β
β ChatCompletionTool { β β Tool { β
β type: "function", β β name: "GITHUB_...", β
β function: { β β description: "...", β
β name: "GITHUB_...",β β input_schema: { β
β description: "...",β β type: "object", β
β parameters: {...} β β properties: {...} β
β } β β } β
β } β β } β
βββββββββββββββββββββββββ ββββββββββββββββββββββββββ
```
---
## π Ciclo de Vida: NonAgentic vs Agentic
### NonAgentic (Controle Manual)
```
βββββββββββββββ
β 1. Developerβ
β Calls SDK β
ββββββββ¬βββββββ
β
β composio.tools.get(user_id, toolkits=["github"])
β
βΌ
ββββββββββββββββββββ
β 2. Provider β
β Converts Tools β
ββββββββ¬ββββββββββββ
β
β Returns: [ChatCompletionToolParam, ...]
β
βΌ
ββββββββββββββββββββ
β 3. Developer β
β Passes to LLM β
ββββββββ¬ββββββββββββ
β
β openai.chat.completions.create(tools=tools)
β
βΌ
ββββββββββββββββββββ
β 4. LLM β
β Returns β
β Tool Calls β
ββββββββ¬ββββββββββββ
β
β response.choices[0].message.tool_calls
β
βΌ
ββββββββββββββββββββ
β 5. Developer β
β MANUALLY β
β Executes Tools β
ββββββββ¬ββββββββββββ
β
β for tool_call in tool_calls:
β composio.tools.execute(...)
β
βΌ
ββββββββββββββββββββ
β 6. Composio β
β Executes & β
β Returns Result β
ββββββββ¬ββββββββββββ
β
β {data: {...}, error: null, successful: true}
β
βΌ
ββββββββββββββββββββ
β 7. Developer β
β Sends Results β
β Back to LLM β
ββββββββββββββββββββ
```
### Agentic (AutomΓ‘tico)
```
βββββββββββββββ
β 1. Developerβ
β Calls SDK β
ββββββββ¬βββββββ
β
β composio.tools.get(user_id, toolkits=["github"])
β
βΌ
ββββββββββββββββββββ
β 2. Provider β
β Converts Tools β
β + Injects β
β Execute Fn β
ββββββββ¬ββββββββββββ
β
β Returns: [FunctionTool(on_invoke=execute_fn), ...]
β
βΌ
ββββββββββββββββββββ
β 3. Developer β
β Passes to β
β Agent β
ββββββββ¬ββββββββββββ
β
β agent = Agent(tools=tools)
β agent.run("Create issue")
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. Framework Loop (AUTOMATIC) β
β β
β βββββββββββββββββββββββββββββββββββββββ β
β β a. Call LLM β β
β ββββββββββββββ¬βββββββββββββββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββ β
β β b. Detect Tool Calls β β
β ββββββββββββββ¬βββββββββββββββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββ β
β β c. AUTOMATICALLY Execute β β
β β (calls on_invoke_tool) β β
β ββββββββββββββ¬βββββββββββββββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββ β
β β d. Send Results Back to LLM β β
β ββββββββββββββ¬βββββββββββββββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββ β
β β e. Repeat Until Task Complete β β
β βββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
β Final result
β
βΌ
ββββββββββββββββββββ
β 5. Developer β
β Gets Final β
β Result β
ββββββββββββββββββββ
```
---
## π Exemplo PrΓ‘tico: Mesma Tarefa, Diferentes Providers
### Tarefa: "Create a GitHub issue titled 'Bug fix'"
#### OpenAI Provider (NonAgentic)
```python
# Setup
composio = Composio(provider=OpenAIProvider())
tools = composio.tools.get(user_id="user_123", toolkits=["github"])
# Step 1: Call LLM
response = openai.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Create issue 'Bug fix'"}],
tools=tools # β [ChatCompletionToolParam, ...]
)
# Step 2: Extract tool calls
tool_call = response.choices[0].message.tool_calls[0]
# {
# id: "call_123",
# function: {
# name: "GITHUB_CREATE_ISSUE",
# arguments: '{"owner":"composio","repo":"composio","title":"Bug fix"}'
# }
# }
# Step 3: Execute manually
result = composio.tools.execute(
slug=tool_call.function.name,
arguments=json.loads(tool_call.function.arguments),
user_id="user_123"
)
# Step 4: Send back to LLM
final_response = openai.chat.completions.create(
model="gpt-4",
messages=[
{"role": "user", "content": "Create issue 'Bug fix'"},
response.choices[0].message,
{"role": "tool", "tool_call_id": tool_call.id, "content": json.dumps(result)}
]
)
```
#### OpenAI Agents Provider (Agentic)
```python
# Setup
composio = Composio(provider=OpenAIAgentsProvider())
tools = composio.tools.get(user_id="user_123", toolkits=["github"])
# One call - framework handles everything!
agent = Agent(model="gpt-4", tools=tools)
result = agent.run("Create issue 'Bug fix'")
# β Framework automatically:
# 1. Calls LLM
# 2. Detects tool call
# 3. Executes GITHUB_CREATE_ISSUE (via on_invoke_tool)
# 4. Sends result back to LLM
# 5. Returns final response
```
---
## π Anatomia de um Provider
### Estrutura Completa
```python
class MyCustomProvider(NonAgenticProvider[MyTool, List[MyTool]], name="my_provider"):
"""
Custom provider for MyFramework
"""
# 1. REQUIRED: Convert single tool
def wrap_tool(self, tool: Tool) -> MyTool:
return MyTool(
name=tool.slug,
description=tool.description,
schema=tool.input_parameters
)
# 2. REQUIRED: Convert multiple tools
def wrap_tools(self, tools: Sequence[Tool]) -> List[MyTool]:
return [self.wrap_tool(tool) for tool in tools]
# 3. OPTIONAL: Helper methods
def handle_tool_calls(self, response: MyResponse) -> List[ToolExecutionResponse]:
"""Extract and execute tool calls from framework response"""
results = []
for call in response.tool_calls:
result = self.execute_tool( # β Injected by SDK
slug=call.name,
arguments=call.arguments,
user_id=self.user_id
)
results.append(result)
return results
# 4. OPTIONAL: Framework-specific optimizations
def optimize_schema(self, schema: dict) -> dict:
"""Optimize schema for framework requirements"""
# Remove unsupported fields
# Add framework-specific fields
return optimized_schema
```
---
## π Matriz de Compatibilidade
| OpenAI Chat | NonAgentic | β | `handle_tool_calls` | β
Stable |
| OpenAI Responses | NonAgentic | β | `handle_tool_calls` | β
Stable |
| OpenAI Agents | Agentic | β
| - | β
Stable |
| Anthropic | NonAgentic | β | `handle_tool_calls` | β
Stable |
| Google Gemini | NonAgentic | β | `handle_tool_calls` | β
Stable |
| LangChain | Agentic | β
| - | β
Stable |
| CrewAI | Agentic | β
| - | β
Stable |
| AutoGen | Agentic | β
| - | β
Stable |
| LlamaIndex | Agentic | β
| - | β
Stable |
---
## π― DecisΓ£o: Qual Provider Usar?
```
βββββββββββββββββββββββββββββββββββββββββββ
β VocΓͺ quer controlar o loop de execuΓ§Γ£o?β
ββββββββββββββ¬βββββββββββββββββββββββββββββ
β
ββββββββ΄βββββββ
β β
SIM NΓO
β β
βΌ βΌ
βββββββββββββββ ββββββββββββββββ
β NonAgentic β β Agentic β
β β β β
β - OpenAI β β - OpenAI β
β Chat β β Agents β
β - Anthropic β β - LangChain β
β - Gemini β β - CrewAI β
β β β - AutoGen β
β β β β
β VocΓͺ: β β Framework: β
β β’ Chama LLM β β β’ Chama LLM β
β β’ Executa β β β’ Executa β
β β’ Controla β β β’ Controla β
βββββββββββββββ ββββββββββββββββ
```
---
## π‘ Dicas de ImplementaΓ§Γ£o
### 1. ComeΓ§ar Simples
```rust
// ImplementaΓ§Γ£o mΓnima
pub trait Provider {
type Tool;
type ToolCollection;
fn wrap_tool(&self, tool: &ToolSchema) -> Self::Tool;
fn wrap_tools(&self, tools: Vec<ToolSchema>) -> Self::ToolCollection;
}
```
### 2. Adicionar Helpers Gradualmente
```rust
// Adicionar mΓ©todos opcionais conforme necessΓ‘rio
pub trait ProviderHelpers: Provider {
fn handle_tool_calls(&self, response: Response) -> Vec<ToolExecutionResponse> {
// Default implementation
vec![]
}
}
```
### 3. Usar Associated Types
```rust
// Melhor que generics para este caso
pub trait Provider {
type Tool: Serialize; // β Associated type
type ToolCollection: IntoIterator<Item = Self::Tool>;
// MΓ©todos usam Self::Tool automaticamente
fn wrap_tool(&self, tool: &ToolSchema) -> Self::Tool;
}
```
---
## π PrΓ³ximos Passos
1. **Implementar trait base** em Rust
2. **Criar OpenAIProvider** como referΓͺncia
3. **Testar com cliente genΓ©rico**
4. **Adicionar mais providers** conforme demanda
5. **Documentar padrΓ΅es** para contribuidores
O Provider System Γ© a fundaΓ§Γ£o para um SDK verdadeiramente universal! π