Metadata-Version: 2.4
Name: uutel
Version: 1.0.5
Summary: Universal AI Provider for LiteLLM - extends LiteLLM with Claude Code, Gemini CLI, Google Cloud Code, and OpenAI Codex providers for unified LLM inferencing
Project-URL: Homepage, https://github.com/twardoch/uutel
Project-URL: Documentation, https://github.com/twardoch/uutel#readme
Project-URL: Repository, https://github.com/twardoch/uutel
Project-URL: Source, https://github.com/twardoch/uutel
Project-URL: Bug Tracker, https://github.com/twardoch/uutel/issues
Project-URL: Issues, https://github.com/twardoch/uutel/issues
Project-URL: Changelog, https://github.com/twardoch/uutel/blob/main/CHANGELOG.md
Project-URL: Development Guide, https://github.com/twardoch/uutel/blob/main/DEVELOPMENT.md
Project-URL: Contributing, https://github.com/twardoch/uutel/blob/main/CONTRIBUTING.md
Author-email: Adam Twardoch <adam+github@twardoch.com>
Maintainer-email: Adam Twardoch <adam+github@twardoch.com>
License: MIT
License-File: LICENSE
Keywords: ai,anthropic,api,artificial-intelligence,chat,chatgpt,claude,cloud-code,codex,completion,conversational-ai,function-calling,gemini,google,gpt,litellm,llm,machine-learning,mcp,nlp,oauth,openai,providers,sdk,streaming,tool-calling,universal,vertex-ai
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Environment :: Web Environment
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Communications :: Chat
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing :: Linguistic
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: aiohttp>=3.9.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: litellm>=1.74.0
Requires-Dist: loguru>=0.7.2
Requires-Dist: pydantic-settings>=2.4.0
Requires-Dist: pydantic>=2.8.0
Provides-Extra: all
Requires-Dist: browser-cookie3>=0.19.1; extra == 'all'
Requires-Dist: click>=8.1.0; extra == 'all'
Requires-Dist: google-api-python-client>=2.130.0; extra == 'all'
Requires-Dist: google-auth-oauthlib>=1.2.0; extra == 'all'
Requires-Dist: google-auth>=2.29.0; extra == 'all'
Requires-Dist: google-cloud-aiplatform>=1.55.0; extra == 'all'
Requires-Dist: google-cloud-core>=2.4.1; extra == 'all'
Requires-Dist: google-cloud-resource-manager>=1.12.3; extra == 'all'
Requires-Dist: keyring>=24.3.1; extra == 'all'
Requires-Dist: mkdocs-gen-files>=0.5.0; extra == 'all'
Requires-Dist: mkdocs-material>=9.5.0; extra == 'all'
Requires-Dist: mkdocs>=1.6.0; extra == 'all'
Requires-Dist: mkdocstrings[python]>=0.25.0; extra == 'all'
Requires-Dist: openai>=1.35.0; extra == 'all'
Requires-Dist: requests>=2.31.0; extra == 'all'
Requires-Dist: rich>=13.7.0; extra == 'all'
Requires-Dist: selenium>=4.18.0; extra == 'all'
Requires-Dist: tiktoken>=0.7.0; extra == 'all'
Requires-Dist: typer>=0.12.0; extra == 'all'
Provides-Extra: auth
Requires-Dist: browser-cookie3>=0.19.1; extra == 'auth'
Requires-Dist: google-auth-oauthlib>=1.2.0; extra == 'auth'
Requires-Dist: google-auth>=2.29.0; extra == 'auth'
Requires-Dist: google-cloud-core>=2.4.1; extra == 'auth'
Requires-Dist: keyring>=24.3.1; extra == 'auth'
Provides-Extra: claude-code
Requires-Dist: browser-cookie3>=0.19.1; extra == 'claude-code'
Requires-Dist: requests>=2.31.0; extra == 'claude-code'
Requires-Dist: selenium>=4.18.0; extra == 'claude-code'
Provides-Extra: cli
Requires-Dist: click>=8.1.0; extra == 'cli'
Requires-Dist: rich>=13.7.0; extra == 'cli'
Requires-Dist: typer>=0.12.0; extra == 'cli'
Provides-Extra: cloud-code
Requires-Dist: google-api-python-client>=2.130.0; extra == 'cloud-code'
Requires-Dist: google-auth>=2.29.0; extra == 'cloud-code'
Requires-Dist: google-cloud-core>=2.4.1; extra == 'cloud-code'
Requires-Dist: google-cloud-resource-manager>=1.12.3; extra == 'cloud-code'
Provides-Extra: codex
Requires-Dist: keyring>=24.3.1; extra == 'codex'
Requires-Dist: openai>=1.35.0; extra == 'codex'
Requires-Dist: tiktoken>=0.7.0; extra == 'codex'
Provides-Extra: dev
Requires-Dist: bandit[toml]>=1.7.5; extra == 'dev'
Requires-Dist: mypy>=1.10.0; extra == 'dev'
Requires-Dist: pre-commit>=3.7.0; extra == 'dev'
Requires-Dist: ruff>=0.5.0; extra == 'dev'
Requires-Dist: safety>=3.2.0; extra == 'dev'
Requires-Dist: uv>=0.2.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-gen-files>=0.5.0; extra == 'docs'
Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
Requires-Dist: mkdocs>=1.6.0; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.25.0; extra == 'docs'
Provides-Extra: full
Requires-Dist: bandit[toml]>=1.7.5; extra == 'full'
Requires-Dist: browser-cookie3>=0.19.1; extra == 'full'
Requires-Dist: click>=8.1.0; extra == 'full'
Requires-Dist: coverage[toml]>=7.5.0; extra == 'full'
Requires-Dist: google-api-python-client>=2.130.0; extra == 'full'
Requires-Dist: google-auth-oauthlib>=1.2.0; extra == 'full'
Requires-Dist: google-auth>=2.29.0; extra == 'full'
Requires-Dist: google-cloud-aiplatform>=1.55.0; extra == 'full'
Requires-Dist: google-cloud-core>=2.4.1; extra == 'full'
Requires-Dist: google-cloud-resource-manager>=1.12.3; extra == 'full'
Requires-Dist: httpx[socks]>=0.27.0; extra == 'full'
Requires-Dist: keyring>=24.3.1; extra == 'full'
Requires-Dist: line-profiler>=4.1.0; extra == 'full'
Requires-Dist: memory-profiler>=0.61.0; extra == 'full'
Requires-Dist: mkdocs-gen-files>=0.5.0; extra == 'full'
Requires-Dist: mkdocs-material>=9.5.0; extra == 'full'
Requires-Dist: mkdocs>=1.6.0; extra == 'full'
Requires-Dist: mkdocstrings[python]>=0.25.0; extra == 'full'
Requires-Dist: mypy>=1.10.0; extra == 'full'
Requires-Dist: openai>=1.35.0; extra == 'full'
Requires-Dist: pre-commit>=3.7.0; extra == 'full'
Requires-Dist: psutil>=5.9.0; extra == 'full'
Requires-Dist: py-spy>=0.3.0; extra == 'full'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'full'
Requires-Dist: pytest-cov>=5.0.0; extra == 'full'
Requires-Dist: pytest-mock>=3.14.0; extra == 'full'
Requires-Dist: pytest-xdist>=3.6.0; extra == 'full'
Requires-Dist: pytest>=8.2.0; extra == 'full'
Requires-Dist: requests>=2.31.0; extra == 'full'
Requires-Dist: rich>=13.7.0; extra == 'full'
Requires-Dist: ruff>=0.5.0; extra == 'full'
Requires-Dist: safety>=3.2.0; extra == 'full'
Requires-Dist: selenium>=4.18.0; extra == 'full'
Requires-Dist: tiktoken>=0.7.0; extra == 'full'
Requires-Dist: typer>=0.12.0; extra == 'full'
Requires-Dist: uv>=0.2.0; extra == 'full'
Provides-Extra: gemini-cli
Requires-Dist: google-api-python-client>=2.130.0; extra == 'gemini-cli'
Requires-Dist: google-auth-oauthlib>=1.2.0; extra == 'gemini-cli'
Requires-Dist: google-auth>=2.29.0; extra == 'gemini-cli'
Requires-Dist: google-cloud-aiplatform>=1.55.0; extra == 'gemini-cli'
Provides-Extra: profile
Requires-Dist: line-profiler>=4.1.0; extra == 'profile'
Requires-Dist: memory-profiler>=0.61.0; extra == 'profile'
Requires-Dist: py-spy>=0.3.0; extra == 'profile'
Provides-Extra: providers
Requires-Dist: browser-cookie3>=0.19.1; extra == 'providers'
Requires-Dist: google-api-python-client>=2.130.0; extra == 'providers'
Requires-Dist: google-auth-oauthlib>=1.2.0; extra == 'providers'
Requires-Dist: google-auth>=2.29.0; extra == 'providers'
Requires-Dist: google-cloud-aiplatform>=1.55.0; extra == 'providers'
Requires-Dist: google-cloud-core>=2.4.1; extra == 'providers'
Requires-Dist: google-cloud-resource-manager>=1.12.3; extra == 'providers'
Requires-Dist: keyring>=24.3.1; extra == 'providers'
Requires-Dist: openai>=1.35.0; extra == 'providers'
Requires-Dist: requests>=2.31.0; extra == 'providers'
Requires-Dist: selenium>=4.18.0; extra == 'providers'
Requires-Dist: tiktoken>=0.7.0; extra == 'providers'
Provides-Extra: test
Requires-Dist: coverage[toml]>=7.5.0; extra == 'test'
Requires-Dist: httpx[socks]>=0.27.0; extra == 'test'
Requires-Dist: psutil>=5.9.0; extra == 'test'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'test'
Requires-Dist: pytest-cov>=5.0.0; extra == 'test'
Requires-Dist: pytest-mock>=3.14.0; extra == 'test'
Requires-Dist: pytest-xdist>=3.6.0; extra == 'test'
Requires-Dist: pytest>=8.2.0; extra == 'test'
Description-Content-Type: text/markdown

# UUTEL: Universal AI Provider for LiteLLM

[![CI](https://github.com/twardoch/uutel/actions/workflows/ci.yml/badge.svg)](https://github.com/twardoch/uutel/actions/workflows/ci.yml)
[![Coverage](https://codecov.io/gh/twardoch/uutel/branch/main/graph/badge.svg)](https://codecov.io/gh/twardoch/uutel)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

**UUTEL** is a comprehensive Python package that provides a robust foundation for extending LiteLLM's provider ecosystem. It implements the **Universal Unit (UU)** pattern and provides core infrastructure for custom AI providers including Claude Code, Gemini CLI, Google Cloud Code, and OpenAI Codex.

## Current Status: Foundation Complete ✅

UUTEL currently provides a **production-ready foundation** with comprehensive tooling and infrastructure. The core framework is complete and ready for provider implementations.

### What's Built and Working

- **🏗️ Core Infrastructure**: Complete `BaseUU` class extending LiteLLM's `CustomLLM`
- **🔐 Authentication Framework**: Flexible `BaseAuth` system with secure credential handling
- **🛠️ Tool Calling**: 5 OpenAI-compatible utilities for function calling workflows
- **📡 Streaming Support**: Async/sync streaming with chunk processing and error handling
- **🚨 Exception Handling**: 7 specialized exception types with provider context
- **🧪 Testing Infrastructure**: 71 tests with 84% coverage, comprehensive fixtures
- **⚙️ CI/CD Pipeline**: Multi-platform testing, code quality, security scanning
- **📚 Examples**: Working demonstrations of all capabilities
- **🔧 Developer Experience**: Modern tooling with ruff, mypy, pre-commit ready

### Planned Providers (Phase 2)

The foundation supports these upcoming provider implementations:

- **ClaudeCodeUU**: OAuth-based Claude Code provider with MCP tool integration
- **GeminiCLIUU**: Multi-auth Gemini CLI provider (API keys, Vertex AI, OAuth)
- **CloudCodeUU**: Google Cloud Code provider with service account authentication
- **CodexUU**: OpenAI Codex provider with ChatGPT backend integration

## Key Features

- **🔗 LiteLLM Compatibility**: Full adherence to LiteLLM's provider interface patterns
- **🌐 Unified API**: Consistent OpenAI-compatible interface across all providers
- **🔐 Authentication Management**: Secure handling of OAuth, API keys, and service accounts
- **📡 Streaming Support**: Real-time response streaming with comprehensive error handling
- **🛠️ Tool Calling**: Complete OpenAI-compatible function calling implementation
- **🚨 Error Handling**: Robust error mapping, fallback mechanisms, and detailed context
- **🧪 Test Coverage**: 84% coverage with comprehensive test suite
- **⚙️ Production Ready**: CI/CD pipeline, security scanning, quality checks

## Installation

```bash
pip install uutel

# With all optional dependencies
pip install uutel[all]

# Development installation
pip install -e .[dev]
```

## Quick Start

### Using Core Infrastructure

```python
from uutel import BaseUU, BaseAuth, validate_tool_schema, create_tool_call_response

# Example of extending BaseUU for your own provider
class MyProviderUU(BaseUU):
    def __init__(self):
        super().__init__()
        self.provider_name = "my-provider"
        self.supported_models = ["my-model-1.0"]

    def completion(self, model, messages, **kwargs):
        # Your provider implementation
        return {"choices": [{"message": {"role": "assistant", "content": "Hello!"}}]}

# Use authentication framework
auth = BaseAuth()
# Implement your authentication logic

# Use tool calling utilities
tool = {
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Get weather information",
        "parameters": {"type": "object", "properties": {"location": {"type": "string"}}}
    }
}

is_valid = validate_tool_schema(tool)  # True
response = create_tool_call_response("call_123", "get_weather", {"temp": "22°C"})
```

### Tool Calling Capabilities

```python
from uutel import (
    validate_tool_schema,
    transform_openai_tools_to_provider,
    create_tool_call_response,
    extract_tool_calls_from_response
)

# Validate OpenAI tool schemas
tool = {"type": "function", "function": {"name": "calc", "description": "Calculate"}}
is_valid = validate_tool_schema(tool)

# Transform tools between formats
provider_tools = transform_openai_tools_to_provider([tool], "my-provider")

# Create tool responses
response = create_tool_call_response(
    tool_call_id="call_123",
    function_name="calculate",
    function_result={"result": 42}
)

# Extract tool calls from provider responses
tool_calls = extract_tool_calls_from_response(provider_response)
```

### Streaming Support

```python
from uutel import BaseUU
import asyncio

class StreamingProvider(BaseUU):
    def simulate_streaming(self, text):
        """Example streaming implementation"""
        for word in text.split():
            yield {"choices": [{"delta": {"content": f"{word} "}}]}
        yield {"choices": [{"delta": {}, "finish_reason": "stop"}]}

# Use streaming (see examples/streaming_example.py for full demo)
provider = StreamingProvider()
for chunk in provider.simulate_streaming("Hello world"):
    content = chunk["choices"][0]["delta"].get("content", "")
    if content:
        print(content, end="")
```

### Authentication Framework

```python
from uutel import BaseAuth, AuthResult
from datetime import datetime

class MyAuth(BaseAuth):
    def authenticate(self, **kwargs):
        # Implement your authentication logic
        return AuthResult(
            success=True,
            token="your-token",
            expires_at=datetime.now(),
            error=None
        )

    def get_headers(self):
        return {"Authorization": f"Bearer {self.get_token()}"}

# Use in your provider
auth = MyAuth()
headers = auth.get_headers()
```

## Package Structure

```
uutel/
├── __init__.py                 # Main exports and provider registration
├── core/
│   ├── base.py                 # BaseUU class and common interfaces
│   ├── auth.py                 # Common authentication utilities
│   ├── exceptions.py           # Custom exception classes
│   └── utils.py                # Common utilities and helpers
├── providers/
│   ├── claude_code/           # Claude Code provider implementation
│   ├── gemini_cli/            # Gemini CLI provider implementation
│   ├── cloud_code/            # Google Cloud Code provider implementation
│   └── codex/                 # OpenAI Codex provider implementation
├── tests/                     # Comprehensive test suite
└── examples/                  # Usage examples and demos
```

## Examples

UUTEL includes comprehensive examples demonstrating all capabilities:

### Basic Usage Example
```bash
python examples/basic_usage.py
```
Demonstrates core infrastructure, authentication framework, error handling, and utilities.

### Tool Calling Example
```bash
python examples/tool_calling_example.py
```
Complete demonstration of OpenAI-compatible tool calling with validation, transformation, and workflow simulation.

### Streaming Example
```bash
python examples/streaming_example.py
```
Async/sync streaming responses with chunk processing, error handling, and concurrent request management.

## Development

This project uses modern Python tooling for an excellent developer experience:

### Development Tools
- **[Hatch](https://hatch.pypa.io/)**: Project management and virtual environments
- **[Ruff](https://github.com/astral-sh/ruff)**: Fast linting and formatting
- **[MyPy](https://mypy.readthedocs.io/)**: Static type checking
- **[Pytest](https://pytest.org/)**: Testing framework with 71 tests
- **[GitHub Actions](https://github.com/features/actions)**: CI/CD pipeline

### Quick Setup

```bash
# Clone repository
git clone https://github.com/twardoch/uutel.git
cd uutel

# Install UV (recommended)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install dependencies
uv sync --all-extras

# Run tests
uv run pytest

# Run all quality checks
uv run ruff check src/uutel tests
uv run ruff format src/uutel tests
uv run mypy src/uutel
```

### Using Hatch (Alternative)

```bash
# Install hatch
pip install hatch

# Create and activate development environment
hatch shell

# Run tests (RECOMMENDED for all async tests)
hatch run test

# Run tests with coverage
hatch run test-cov

# Note: Always use 'hatch run test' instead of 'hatch test'
# to ensure proper async plugin loading

# Run linting and formatting
hatch run lint
hatch run format

# Type checking
hatch run typecheck
```

### Using Make (Convenience)

```bash
# Install development dependencies
make install-dev

# Run all checks
make check

# Run tests
make test

# Clean build artifacts
make clean
```

## Architecture & Design

### Universal Unit (UU) Pattern

UUTEL implements a consistent **Universal Unit** pattern where all provider classes follow the `{ProviderName}UU` naming convention:

```python
# Base class
class BaseUU(CustomLLM):  # Extends LiteLLM's CustomLLM
    def __init__(self):
        self.provider_name: str = "base"
        self.supported_models: list[str] = []

# Provider implementations (future)
class ClaudeCodeUU(BaseUU): ...
class GeminiCLIUU(BaseUU): ...
class CloudCodeUU(BaseUU): ...
class CodexUU(BaseUU): ...
```

### Core Components

1. **`BaseUU`**: LiteLLM-compatible provider base class
2. **`BaseAuth`**: Flexible authentication framework
3. **Exception Framework**: 7 specialized exception types
4. **Tool Calling**: 5 OpenAI-compatible utilities
5. **Streaming Support**: Async/sync response handling
6. **Utilities**: HTTP clients, validation, transformation

### Quality Assurance

- **84% Test Coverage**: 71 comprehensive tests
- **CI/CD Pipeline**: Multi-platform testing (Ubuntu, macOS, Windows)
- **Code Quality**: Ruff formatting, MyPy type checking
- **Security Scanning**: Bandit and Safety integration
- **Documentation**: Examples, architecture docs, API reference

## Roadmap

### Phase 2: Provider Implementations (Upcoming)
- **ClaudeCodeUU**: OAuth authentication, MCP tool integration
- **GeminiCLIUU**: Multi-auth support (API key, Vertex AI, OAuth)
- **CloudCodeUU**: Google Cloud service account authentication
- **CodexUU**: ChatGPT backend integration with session management

### Phase 3: LiteLLM Integration
- Provider registration with LiteLLM
- Model name mapping (`uutel/provider/model`)
- Configuration management and validation
- Production deployment support

### Phase 4: Advanced Features
- Response caching and performance optimization
- Monitoring and observability tools
- Community plugin system
- Enterprise features and team management

## Contributing

We welcome contributions! The project is designed with simplicity and extensibility in mind.

### Getting Started
1. Fork the repository
2. Set up development environment: `uv sync --all-extras`
3. Run tests: `uv run pytest`
4. Make your changes
5. Ensure tests pass and code quality checks pass
6. Submit a pull request

### Development Guidelines
- Follow the **UU naming pattern** (`{ProviderName}UU`)
- Write tests first (TDD approach)
- Maintain 80%+ test coverage
- Use modern Python features (3.10+ type hints)
- Keep functions under 20 lines, files under 200 lines
- Document with clear docstrings

### Current Focus
The project is currently accepting contributions for:
- Provider implementations (Phase 2)
- Documentation improvements
- Example applications
- Performance optimizations
- Bug fixes and quality improvements

## Support

- **Documentation**: [GitHub Wiki](https://github.com/twardoch/uutel/wiki) (coming soon)
- **Issues**: [GitHub Issues](https://github.com/twardoch/uutel/issues)
- **Discussions**: [GitHub Discussions](https://github.com/twardoch/uutel/discussions)

## License

MIT License - see [LICENSE](LICENSE) file for details.

---

**UUTEL** provides the universal foundation for AI provider integration. Built with modern Python practices, comprehensive testing, and extensibility in mind.
