composio-sdk 0.3.0

Minimal Rust SDK for Composio Tool Router REST API
Documentation
# Telemetry Implementation


## Overview


This document describes the implementation of the telemetry module in the Composio Rust SDK, which is a translation of the Python SDK's `_telemetry.py` module.

## Architecture


### Python vs Rust Implementation


| Feature | Python Implementation | Rust Implementation |
|---------|----------------------|---------------------|
| Threading | `threading.Thread` with daemon mode | `tokio::spawn` with async task |
| Queue | `queue.Queue` | `tokio::sync::mpsc::unbounded_channel` |
| HTTP Client | `httpx` | `reqwest` |
| Global State | Module-level variables with `atexit` | `OnceLock` with `Arc<Mutex<>>` |
| Cleanup | `atexit.register` with timeout | Automatic via channel drop |
| Error Handling | Silent `try/except` | Silent `Result` handling |

## Key Components


### Data Structures


1. **ErrorData**: Error information (name, code, error_id, message, stack)
2. **SourceData**: Source/host information (host, service, language, version, platform, environment)
3. **Metadata**: Runtime metadata (project_id, provider)
4. **TelemetryData**: Complete telemetry payload
5. **EventType**: Enum for "metric" or "error" events
6. **Event**: Tuple of (EventType, TelemetryData)

### Enumerations


- **ServiceType**: sdk, apollo, hermes, thermos
- **LanguageType**: python, typescript, go, rust
- **EnvironmentType**: development, production, ci, staging, test

### Core Functions


1. **setup()**: Initializes the telemetry system with background task
2. **push_event()**: Non-blocking function to queue events
3. **create_event()**: Helper to create properly typed events
4. **push_to_server()**: Internal async function to send events to API

## Usage Examples


### Simple Metric Event


```rust
use composio_sdk::models::telemetry::{push_event, create_event, TelemetryData};

let event = create_event(
    "metric",
    TelemetryData {
        function_name: "execute_tool".to_string(),
        duration_ms: Some(150.5),
        ..Default::default()
    }
);
push_event(event);
```

### Error Event


```rust
use composio_sdk::models::telemetry::{push_event, create_event, TelemetryData, ErrorData};

let event = create_event(
    "error",
    TelemetryData {
        function_name: "execute_tool".to_string(),
        error: Some(ErrorData {
            name: "ToolExecutionError".to_string(),
            message: Some("Connection timeout".to_string()),
            ..Default::default()
        }),
        ..Default::default()
    }
);
push_event(event);
```

### Complete Event with All Fields


```rust
use composio_sdk::models::telemetry::*;
use std::collections::HashMap;

let mut props = HashMap::new();
props.insert("toolkit".to_string(), serde_json::Value::String("github".to_string()));

let event = create_event(
    "metric",
    TelemetryData {
        function_name: "execute_tool".to_string(),
        duration_ms: Some(350.8),
        props: Some(props),
        source: Some(SourceData {
            service: Some(ServiceType::Sdk),
            language: Some(LanguageType::Rust),
            version: Some(env!("CARGO_PKG_VERSION").to_string()),
            ..Default::default()
        }),
        metadata: Some(Metadata {
            project_id: Some("proj_123".to_string()),
            provider: Some("openai".to_string()),
        }),
        ..Default::default()
    }
);
push_event(event);
```

## API Endpoints


- **Metrics**: `https://telemetry.composio.dev/v1/metrics/invocations`
- **Errors**: `https://telemetry.composio.dev/v1/errors`

## Design Decisions


### 1. Async Runtime


The Rust implementation uses Tokio's async runtime instead of Python's threading model. This provides:
- Better performance with non-blocking I/O
- Native integration with the rest of the SDK (which uses async/await)
- Automatic cleanup when the channel is dropped

### 2. Channel-based Communication


Instead of Python's `queue.Queue`, we use `tokio::sync::mpsc::unbounded_channel`:
- Non-blocking sends
- Automatic backpressure handling
- Clean shutdown semantics

### 3. Global State Management


Using `OnceLock` with `Arc<Mutex<>>` provides:
- Thread-safe lazy initialization
- Safe concurrent access
- No need for explicit cleanup registration

### 4. Error Handling


Following the Python implementation, all telemetry errors are silently ignored:
- Network failures don't affect application
- Timeout errors are swallowed
- Only logged in debug mode (with `local-debug` feature)

### 5. Serialization


Using `serde` with `#[serde(skip_serializing_if = "Option::is_none")]`:
- Clean JSON output (no null fields)
- Matches Python's TypedDict behavior
- Proper camelCase/snake_case conversion

## Testing


The module includes unit tests for:
- Event creation (metric and error types)
- Non-panicking behavior
- Proper event type mapping

Run tests with:
```bash
cargo test telemetry
```

## Example Program


A complete example is available at `examples/telemetry_usage.rs`:

```bash
cargo run --example telemetry_usage
```

This demonstrates:
- Simple metric events
- Events with source information
- Events with metadata
- Error events
- Complete events with all fields

## Integration Points


The telemetry module can be integrated into the SDK at key points:

1. **Session Creation**: Track session initialization
2. **Tool Execution**: Measure execution time and success/failure
3. **API Calls**: Monitor API latency and errors
4. **Authentication**: Track auth flows and failures
5. **Meta Tools**: Monitor meta tool usage patterns

## Future Enhancements


Potential improvements:
1. Batching multiple events before sending
2. Configurable flush intervals
3. Local caching for offline scenarios
4. Sampling for high-volume scenarios
5. Custom telemetry backends

## Differences from Python Implementation


### Removed Features

- `atexit` registration (handled automatically by channel drop)
- Explicit thread join with timeout (handled by Tokio runtime)
- Queue size checking before shutdown (unbounded channel)

### Added Features

- Async/await support
- Better type safety with enums
- Compile-time guarantees
- Integration with Tokio ecosystem

## Performance Characteristics


- **Memory**: Minimal overhead (~1KB per event in queue)
- **CPU**: Negligible (async I/O, no blocking)
- **Network**: 2-second timeout per request
- **Latency**: Non-blocking push (< 1μs)

## Compatibility


The Rust implementation maintains API compatibility with the Python version:
- Same endpoint URLs
- Same JSON payload structure
- Same field names (with camelCase conversion)
- Same event types

This ensures telemetry data from both SDKs can be processed by the same backend.