Adapters
Adapters translate between native LLM SDK formats and BeliefState's universal models. All adapters include:
OpenAI
GPT-4o, GPT-4, GPT-3.5
Anthropic
Claude 3.5, Claude 3
Gemini
Gemini 2.0, 1.5
Ollama
Llama 3, Mistral, etc.
LiteLLM
100+ providers
OpenAI
pythonfrom beliefstate.adapters import OpenAIAdapter
adapter = OpenAIAdapter(
model="gpt-4o", # Chat completion model
embed_model="text-embedding-3-small", # Embedding model
timeout=30.0, # Request timeout (seconds)
)
is_healthy = await adapter.health_check()
from beliefstate.adapters.common import RetryConfig
adapter = OpenAIAdapter(
model="gpt-4o",
retry_config=RetryConfig(
max_retries=3,
initial_delay=1.0,
max_delay=30.0,
exponential_base=2.0,
jitter=True, # Prevents thundering herd
)
)
Set OPENAI_API_KEY environment variable or pass via api_key parameter.
Anthropic (Claude)
pythonfrom beliefstate.adapters import AnthropicAdapter
adapter = AnthropicAdapter(
model="claude-3-5-sonnet-latest",
timeout=30.0
)
⚠️ Note: Anthropic does not provide an embeddings API. Use the Dual-Adapter pattern with OpenAI or Ollama as the internal_adapter for embedding generation.
Google Gemini
pythonfrom beliefstate.adapters import GeminiAdapter
adapter = GeminiAdapter(
model="gemini-2.0-flash",
embed_model="text-embedding-004",
timeout=30.0
)
Set GOOGLE_API_KEY or GEMINI_API_KEY environment variable.
Ollama (Local)
pythonfrom beliefstate.adapters import OllamaAdapter
adapter = OllamaAdapter(
model="llama3.2",
embed_model="nomic-embed-text",
host="http://localhost",
port=11434
)
💡 Tip: Ollama is perfect as an internal_adapter in the Dual-Adapter pattern — completely free, fast, and runs locally.
LiteLLM (Multi-Provider)
pythonfrom beliefstate.adapters import LiteLLMAdapter
adapter = LiteLLMAdapter(
model="azure/gpt-4", # Azure OpenAI
embed_model="cohere/embed-english-v3.0" # Cohere embeddings
)
adapter = LiteLLMAdapter(model="bedrock/anthropic.claude-3-sonnet")
Dual-Adapter Architecture
Use a premium model for your application and a cheaper/local model for background tracking to optimize costs:
pythonfrom beliefstate.adapters import AnthropicAdapter, OllamaAdapter
app_adapter = AnthropicAdapter(model="claude-3-5-sonnet-latest")
bg_adapter = OllamaAdapter(model="llama3", embed_model="nomic-embed-text")
tracker = BeliefTracker(
config=config,
adapter=app_adapter, # Intercepts the Claude API payload
internal_adapter=bg_adapter # Runs extraction, embeddings, and judge
)
┌─────────────────────┐ ┌─────────────────────┐ │ App Adapter │ │ Internal Adapter │ │ (Claude 3.5 Sonnet) │ │ (Ollama / Llama3) │ │ │ │ │ │ • to_llm_call() │ │ • generate() │ │ • to_llm_response()│ ────────▶ │ • get_embeddings() │ │ (payload parsing) │ belief tasks │ • health_check() │ └─────────────────────┘ └─────────────────────┘
Payload Normalization Design
Different model providers use radically different SDK payload signatures. For example:
- OpenAI: Accesses response text via
response.choices[0].message.content. - Anthropic: Accesses response text via
response.content[0].text. - Google Gemini: Accesses response text via
response.text.
To enable universal tracking, each adapter implements the ProviderAdapter protocol to normalize inputs and outputs:
-
to_llm_call(*args, **kwargs):Intercepts raw arguments passed to the provider SDK and extracts the conversation history, converting them into a standardizedLLMCallstructure containing a unified list of message dictionaries. -
to_llm_response(raw_response):Normalizes the provider's returned response object into anLLMResponsestructure, exposing the message content, model name, and token usage metadata.
This decoupling is what enables the **Dual-Adapter** pattern: the premium adapter parses the main application LLM calls, while the internal adapter handles all background vector embeddings, fact extractions, and logical checks using completely different API calls (or a local instance like Ollama).