Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

agnosmodel2 - Universal GenAI Provider Abstraction

Python 3.11+ License: PolyForm NC

⚠️ Alpha Release - This is the debut release of agnosmodel2. While functional, the API may change in future versions.

Universal Generative AI Provider Interface - Switch between any GenAI provider (OpenAI, Anthropic, local models) without changing your code. Define providers once, switch seamlessly at runtime.

Part of the Agnosweaver™ project suite.

🔥 Why agnosmodel2?

Tired of AI vendor lock-in? Frustrated with rewriting code every time you want to try a different model? agnosmodel2 solves this by providing a unified interface across all GenAI providers.

# Define once, switch anytime
manager = GenManager()
manager.add_provider('gpt', 'openai', {'model': 'gpt-4', 'api_key': '...'})
manager.add_provider('claude', 'anthropic', {'model': 'claude-3', 'api_key': '...'})

response = manager.generate("Hello world")  # Uses current provider
manager.switch_provider('claude')
response = manager.generate("Hello world")  # Now uses Claude - same code!

✨ Features

  • 🔄 Provider Agnostic: Switch between OpenAI, Anthropic, local models, or any GenAI provider
  • 📊 Datatype Agnostic: Handle JSON, XML, binary, protobuf, or any data format seamlessly
  • 🏗️ Extensible Architecture: Bring-your-own provider implementations
  • ⚡ Sync & Async: Full support for both synchronous and asynchronous operations
  • 🌊 Streaming Support: Real-time streaming responses when supported by providers
  • 📦 Minimal Core: Lightweight interface without bloat
  • 🎯 Standardized Responses: Consistent response format across all providers
  • 🔌 Plugin System: Registry-based provider discovery and registration

📦 Installation

# PyPI
pip install agnosmodel2

# GitHub
pip install git+https://github.com/agnosweaver/agnosmodel2.git

Requirements: Python 3.11 or higher

🚀 Quick Start

1. Basic Setup

from agnosmodel2 import GenManager, ProviderRegistry, BaseGenProvider

# Create manager
manager = GenManager()

2. Implement a Provider

Since agnosmodel2 provides the core interface, you need to implement providers for your specific needs:

class OpenAIProvider(BaseGenProvider):
    def generate(self, prompt: str, **kwargs):
        # Your OpenAI implementation
        response = self.call_openai_api(prompt)
        return GenResponse(
            content=response.text,
            provider=self.name,
            model=self.model,
            timestamp=datetime.now().isoformat(),
            content_type="text/plain"
        )
    
    async def agenerate(self, prompt: str, **kwargs):
        # Your async OpenAI implementation
        pass
    
    def validate(self):
        return 'api_key' in self.config

# Register your provider
ProviderRegistry.register('openai', OpenAIProvider)

3. Use It!

# Add providers
manager.add_provider('gpt4', 'openai', {
    'model': 'gpt-4',
    'api_key': 'your-key'
})

manager.add_provider('claude', 'anthropic', {
    'model': 'claude-3-sonnet',
    'api_key': 'your-key'
})

# Generate responses
response = manager.generate("Explain quantum computing")
print(f"Response from {response.provider}: {response.content}")

# Switch providers seamlessly
manager.switch_provider('claude')
response = manager.generate("Explain quantum computing")  # Same call, different provider!

🎯 Common Use Cases

Model A/B Testing

# Test different models with the same prompt
results = {}
for provider in ['gpt4', 'claude', 'local-llama']:
    manager.switch_provider(provider)
    response = manager.generate("Write a haiku about AI")
    results[provider] = response.content

Fallback Strategy

def generate_with_fallback(prompt):
    providers = ['premium-model', 'standard-model', 'local-backup']
    
    for provider in providers:
        try:
            manager.switch_provider(provider)
            return manager.generate(prompt)
        except Exception as e:
            print(f"{provider} failed: {e}")
            continue
    
    raise Exception("All providers failed")

Cost Optimization

# Route simple queries to cheaper models
def smart_generate(prompt):
    if len(prompt) < 100:
        manager.switch_provider('gpt-3.5')
    else:
        manager.switch_provider('gpt-4')
    
    return manager.generate(prompt)

Streaming Responses

# Stream from any provider that supports it
for chunk in manager.generate_stream("Tell me a long story"):
    print(chunk.content, end='', flush=True)
    if chunk.is_final:
        break

Multi-Modal Generation

# Stream from any provider that supports it
for chunk in manager.generate_stream("Tell me a long story"):
    print(chunk.content, end='', flush=True)
    if chunk.is_final:
        break

# Handle different data types seamlessly
audio_response = manager.generate("Say hello", output_type="audio")
video_response = manager.generate("Create a short clip", output_type="video")

# Content can be any type: str, bytes, custom objects
if isinstance(audio_response.content, bytes):
    with open("output.wav", "wb") as f:
        f.write(audio_response.content)

📚 API Reference

Core Classes

GenManager

Main interface for managing and switching between providers.

Methods:

  • add_provider(name, provider_type, config) - Add a new provider
  • switch_provider(name) - Switch to a different provider
  • generate(prompt, **kwargs) - Generate content synchronously
  • agenerate(prompt, **kwargs) - Generate content asynchronously
  • generate_stream(prompt, **kwargs) - Stream content synchronously
  • agenerate_stream(prompt, **kwargs) - Stream content asynchronously

BaseGenProvider

Abstract base class for all providers.

Must Implement:

  • generate(prompt, **kwargs) - Sync generation
  • agenerate(prompt, **kwargs) - Async generation
  • validate() - Configuration validation

Optional Override:

  • generate_stream(prompt, **kwargs) - Sync streaming
  • agenerate_stream(prompt, **kwargs) - Async streaming

ProviderRegistry

Registry for provider discovery and instantiation.

Methods:

  • register(provider_type, provider_class) - Register a provider class
  • create(provider_type, name, config) - Create provider instance
  • list_types() - List registered provider types

Data Structures

GenResponse

@dataclass
class GenResponse:
    content: Union[str, bytes, Any]
    provider: str
    model: str
    timestamp: str
    content_type: Optional[str] = None
    metadata: Optional[Dict[str, Any]] = None

GenStreamChunk

@dataclass
class GenStreamChunk:
    content: Union[str, bytes, Any]
    provider: str
    model: str
    timestamp: str
    content_type: Optional[str] = None
    metadata: Optional[Dict[str, Any]] = None
    is_final: bool = False

🏗️ Architecture

agnosmodel2 follows a clean, extensible architecture:

┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   GenManager    │────│ ProviderRegistry │────│ BaseGenProvider │
│   (Router)      │    │   (Discovery)    │    │ (Implementation)│
└─────────────────┘    └──────────────────┘    └─────────────────┘
         │                       │                      │
         │              ┌────────┴────────┐             │
         │              │                 │             │
         ▼              ▼                 ▼             ▼
┌─────────────────┐ ┌──────────┐ ┌──────────────┐ ┌──────────────┐
│  Your App Code  │ │ OpenAI   │ │  Anthropic   │ │ Local Model  │
│                 │ │ Provider │ │   Provider   │ │   Provider   │
└─────────────────┘ └──────────┘ └──────────────┘ └──────────────┘

Key Principles:

  • Separation of Concerns: Core routing logic separate from provider implementations
  • Plugin Architecture: Providers register themselves via the registry
  • Consistent Interface: All providers expose the same methods
  • Transport Agnostic: Supports HTTP, gRPC, local calls, anything

⚡ Advanced Features

Custom Transport Layer

class HTTPTransport(BaseModelTransport):
    def send(self, request_data, **kwargs):
        # Custom HTTP implementation
        pass

class gRPCTransport(BaseModelTransport):
    def send(self, request_data, **kwargs):
        # Custom gRPC implementation
        pass

Response Parsing

class JSONResponseParser(BaseResponseParser):
    def parse_response(self, raw_response):
        return json.loads(raw_response)['content']
    
    def get_content_type(self, raw_response):
        return "application/json"

🤝 Contributing

Coming Soon: A dedicated repository for community contributions and ideas is being set up. Stay tuned!

For now, if you have suggestions or find issues, please reach out via email.

📄 License

Licensed under the PolyForm Noncommercial License 1.0.0.

⚠️ Important: This license prohibits commercial use. If you need to use agnosmodel2 in a commercial project, please contact agnosweaver@gmail.com for a commercial license.

📞 Contact


Built for developers who hate being boxed in.

Pick, switch, and combine GenAI providers freely.

Metadata

Release files for agnosmodel2 0.0.1a0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agnosmodel2 0.0.1a0
File Size Uploaded Provenance
agnosmodel2-0.0.1a0.tar.gz 17.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for agnosmodel2 0.0.1a0
File Interpreter ABI Platform
agnosmodel2-0.0.1a0-py3-none-any.whl Python 3 none any Details

Total release size: 33.8 kB

Release files / agnosmodel2-0.0.1a0.tar.gz

Download URL agnosmodel2-0.0.1a0.tar.gz
Size 17.7 kB
Tags Source
SHA-256 checksum
How to use checksums
1bb9fc29cb961e0a127274f89c41deb645025e05b7ae46491376a534020b5086
BLAKE2b-256 checksum
How to use checksums
b1d25bd30dd106775806069d3b0f301e96fd5d21c3f66abce1305dfda5e27207
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.10

Release files / agnosmodel2-0.0.1a0-py3-none-any.whl

Download URL agnosmodel2-0.0.1a0-py3-none-any.whl
Size 16.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
76fcfd3903f53e45f6ba0f96eb9398da247758e3e8436d11b42e12270c1472f4
BLAKE2b-256 checksum
How to use checksums
6f895b7f74e1c441c66e55b224ad0ebec52a7f5cd18b08c8a6d55dbff7e71ca7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.10

Security for agnosmodel2 0.0.1a0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page