composio-sdk 0.3.0

Minimal Rust SDK for Composio Tool Router REST API
Documentation
# 📊 Análise: Sistema de Versionamento de Toolkits


## 🎯 Objetivo

Implementar o sistema de versionamento de toolkits do Python SDK no Rust SDK.

---

## 📋 O que o Python SDK tem (`temp/composio/core/types.py`)


### Tipos Definidos:


```python
# 1. ToolkitLatestVersion - Literal "latest"

ToolkitLatestVersion = te.Literal["latest"]

# 2. ToolkitVersion - Pode ser "latest" OU uma string de versão

ToolkitVersion = t.Union[ToolkitLatestVersion, str]

# 3. ToolkitVersions - Dicionário de versões por toolkit

ToolkitVersions = t.Dict[str, ToolkitVersion]

# 4. ToolkitVersionParam - Parâmetro flexível

ToolkitVersionParam = t.Union[ToolkitVersions, ToolkitLatestVersion, None]
```

### Onde é usado no Python:

- `composio/__init__.py` - Exporta os tipos
- `composio/types.py` - Re-exporta
- `composio/sdk.py` - Usa `ToolkitVersionParam` na config
- `composio/utils/toolkit_version.py` - Gerencia versões
- `composio/core/models/tools.py` - Controla versões de ferramentas
- `composio/core/models/triggers.py` - Controla versões de triggers

---

## ✅ O que o Rust SDK JÁ TEM


### 1. **Estrutura de Versão em ToolSchema**
**Arquivo:** `src/models/response.rs`

```rust
pub struct ToolSchema {
    pub version: String,              // ✅ Versão atual
    pub available_versions: Vec<String>, // ✅ Versões disponíveis
    pub is_deprecated: bool,          // ✅ Flag de depreciação
    // ... outros campos
}
```

### 2. **Parâmetros de Versão em ToolExecutionRequest**
**Arquivo:** `src/models/request.rs`

```rust
pub struct ToolExecutionRequest {
    pub version: Option<String>,  // ✅ Versão específica para executar
    pub dangerously_skip_version_check: Option<bool>, // ✅ Skip de validação
    // ... outros campos
}
```

### 3. **Versão em ToolkitMeta**
**Arquivo:** `src/models/response.rs`

```rust
pub struct ToolkitMeta {
    pub version: String,  // ✅ Versão do toolkit
    // ... outros campos
}
```

---

## ❌ O que FALTA Implementar


### 1. **Tipos de Versionamento Centralizados**

Não existe um módulo central para tipos de versionamento como no Python.

**Solução:** Criar `src/models/versioning.rs`

```rust
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// Versão "latest" de um toolkit
pub const TOOLKIT_LATEST_VERSION: &str = "latest";

/// Versão de um toolkit
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]

#[serde(untagged)]

pub enum ToolkitVersion {
    /// Sempre usar a versão mais recente
    Latest,
    /// Versão específica (ex: "20250906_01")
    Specific(String),
}

/// Mapa de versões por toolkit
/// Exemplo: {"github": Latest, "gmail": Specific("20250906_01")}
pub type ToolkitVersions = HashMap<String, ToolkitVersion>;

/// Parâmetro de versão para configuração
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]

#[serde(untagged)]

pub enum ToolkitVersionParam {
    /// Mapa de versões específicas por toolkit
    Versions(ToolkitVersions),
    /// Usar "latest" para todos os toolkits
    Latest,
    /// Não especificar versão (usar padrão do servidor)
    None,
}

impl Default for ToolkitVersionParam {
    fn default() -> Self {
        Self::None
    }
}

impl ToolkitVersion {
    /// Converte para string para enviar na API
    pub fn as_str(&self) -> &str {
        match self {
            Self::Latest => TOOLKIT_LATEST_VERSION,
            Self::Specific(version) => version.as_str(),
        }
    }
}
```

### 2. **Integração com SessionConfig**

**Arquivo:** `src/models/request.rs`

Adicionar campo `toolkit_versions`:

```rust
pub struct SessionConfig {
    pub user_id: String,
    pub toolkits: Option<ToolkitFilter>,
    pub auth_configs: Option<HashMap<String, String>>,
    pub connected_accounts: Option<HashMap<String, String>>,
    pub manage_connections: Option<ManageConnectionsConfig>,
    pub tools: Option<ToolsConfig>,
    pub tags: Option<TagsConfig>,
    pub workbench: Option<WorkbenchConfig>,
    
    // ❌ FALTA ADICIONAR:
    #[serde(skip_serializing_if = "Option::is_none")]
    pub toolkit_versions: Option<ToolkitVersionParam>,
}
```

### 3. **Integração com ComposioConfig**

**Arquivo:** `src/config.rs`

Adicionar campo `toolkit_versions`:

```rust
pub struct ComposioConfig {
    pub api_key: String,
    pub base_url: String,
    pub timeout: Duration,
    pub retry_policy: RetryPolicy,
    
    // ❌ FALTA ADICIONAR:
    pub toolkit_versions: Option<ToolkitVersionParam>,
}
```

### 4. **Utilitários de Gerenciamento de Versão**

Criar `src/utils/toolkit_version.rs`:

```rust
use crate::models::versioning::{ToolkitVersion, ToolkitVersionParam, ToolkitVersions};
use std::collections::HashMap;
use std::env;

/// Obtém a versão para um toolkit específico
pub fn get_toolkit_version(
    toolkit_slug: &str,
    toolkit_versions: Option<&ToolkitVersionParam>,
) -> ToolkitVersion {
    // 1. Verificar variável de ambiente específica
    if let Ok(version) = env::var(format!("COMPOSIO_TOOLKIT_VERSION_{}", toolkit_slug.to_uppercase())) {
        return ToolkitVersion::Specific(version);
    }
    
    // 2. Verificar no parâmetro fornecido
    if let Some(versions) = toolkit_versions {
        match versions {
            ToolkitVersionParam::Latest => return ToolkitVersion::Latest,
            ToolkitVersionParam::Versions(map) => {
                if let Some(version) = map.get(toolkit_slug) {
                    return version.clone();
                }
            }
            ToolkitVersionParam::None => {}
        }
    }
    
    // 3. Verificar variável de ambiente global
    if let Ok(version) = env::var("COMPOSIO_TOOLKIT_VERSION") {
        return ToolkitVersion::Specific(version);
    }
    
    // 4. Padrão: Latest
    ToolkitVersion::Latest
}

/// Mescla configurações de versão de múltiplas fontes
pub fn merge_toolkit_versions(
    default: Option<ToolkitVersionParam>,
    override_versions: Option<ToolkitVersionParam>,
) -> ToolkitVersionParam {
    match (default, override_versions) {
        (_, Some(override_val)) => override_val,
        (Some(default_val), None) => default_val,
        (None, None) => ToolkitVersionParam::None,
    }
}

/// Extrai versões de variáveis de ambiente
pub fn get_versions_from_env() -> ToolkitVersions {
    let mut versions = HashMap::new();
    
    for (key, value) in env::vars() {
        if let Some(toolkit) = key.strip_prefix("COMPOSIO_TOOLKIT_VERSION_") {
            versions.insert(
                toolkit.to_lowercase(),
                ToolkitVersion::Specific(value),
            );
        }
    }
    
    versions
}
```

### 5. **Módulo Utils**

Criar `src/utils/mod.rs`:

```rust
//! Utility functions for the Composio SDK

pub mod toolkit_version;

pub use toolkit_version::{
    get_toolkit_version,
    merge_toolkit_versions,
    get_versions_from_env,
};
```

---

## 📝 Plano de Implementação


### Fase 1: Criar Tipos Base ✅ (Pronto para implementar)

1. ✅ Criar `src/models/versioning.rs`
2. ✅ Adicionar exports em `src/models/mod.rs`
3. ✅ Adicionar exports em `src/lib.rs`

### Fase 2: Integrar com Configuração

4. ⏳ Adicionar `toolkit_versions` em `SessionConfig`
5. ⏳ Adicionar `toolkit_versions` em `ComposioConfig`
6. ⏳ Atualizar `SessionBuilder` para aceitar versões

### Fase 3: Criar Utilitários

7. ⏳ Criar `src/utils/mod.rs`
8. ⏳ Criar `src/utils/toolkit_version.rs`
9. ⏳ Adicionar testes unitários

### Fase 4: Integrar com Execução

10. ⏳ Usar versões em `execute_tool()`
11. ⏳ Usar versões em `execute_meta_tool()`
12. ⏳ Adicionar validação de versões

### Fase 5: Documentação e Testes

13. ⏳ Adicionar exemplos de uso
14. ⏳ Atualizar README
15. ⏳ Testes de integração

---

## 🎓 Explicação Didática


### Por que precisamos disso?


Imagine que você tem um aplicativo do GitHub:
- **Versão antiga (20240101_01)**: Tem 50 ferramentas
- **Versão nova (20250906_01)**: Tem 100 ferramentas
- **"latest"**: Sempre pega a mais nova

**Sem versionamento:**
- ❌ Seu código pode quebrar quando o Composio atualiza
- ❌ Você não controla qual versão usar
- ❌ Difícil reproduzir bugs

**Com versionamento:**
- ✅ Você escolhe: "Quero sempre a versão 20250906_01"
- ✅ Ou: "Quero sempre a mais nova (latest)"
- ✅ Ou: "GitHub na v1, Gmail na v2"
- ✅ Seu código fica previsível

### Como funciona?


```rust
// Exemplo 1: Usar "latest" para tudo
let config = ComposioConfig::new("api_key")
    .toolkit_versions(ToolkitVersionParam::Latest);

// Exemplo 2: Versões específicas
let mut versions = HashMap::new();
versions.insert("github".to_string(), ToolkitVersion::Specific("20250906_01".to_string()));
versions.insert("gmail".to_string(), ToolkitVersion::Latest);

let config = ComposioConfig::new("api_key")
    .toolkit_versions(ToolkitVersionParam::Versions(versions));

// Exemplo 3: Via variável de ambiente
// COMPOSIO_TOOLKIT_VERSION_GITHUB=20250906_01
// O SDK pega automaticamente!
```

---

## ✅ Checklist de Implementação


- [ ] Criar `src/models/versioning.rs`
- [ ] Atualizar `src/models/mod.rs`
- [ ] Atualizar `src/models/request.rs` (SessionConfig)
- [ ] Atualizar `src/config.rs` (ComposioConfig)
- [ ] Criar `src/utils/mod.rs`
- [ ] Criar `src/utils/toolkit_version.rs`
- [ ] Atualizar `src/lib.rs` (exports)
- [ ] Atualizar `src/session.rs` (usar versões)
- [ ] Adicionar testes unitários
- [ ] Adicionar exemplo de uso
- [ ] Atualizar documentação

---

## 🚀 Próximos Passos


1. **Revisar esta análise** - Você entendeu tudo?
2. **Implementar Fase 1** - Criar os tipos base
3. **Testar** - Garantir que compila e funciona
4. **Continuar** - Fases 2, 3, 4, 5

Quer que eu comece implementando a **Fase 1**?