A unified async client for interacting with multiple LLM providers
Project description
Unified LLM Client
A unified async client library for interacting with multiple LLM providers (OpenAI, Anthropic, and more) using a consistent API.
Features
- Unified interface for multiple LLM providers (OpenAI, Anthropic, Ollama)
- Async-first design for high-performance applications
- Tool/function calling support with a consistent interface
- Streaming support for improved user experience with long responses
- Rich error handling and logging
- Support for both OpenAI Completions and Responses APIs
- Support for local models via Ollama integration
- Type hints throughout the codebase
Installation
pip install unified-llm-client
Quick Start
import asyncio
from llm import AsyncLLMClient, ToolRegistry, llm_tool
# Define a tool function using the decorator
@llm_tool
async def get_weather(location: str, unit: str = "celsius"):
"""Get the current weather for a location."""
# Mock implementation
return f"The weather in {location} is sunny and 22 degrees {unit}"
async def main():
# Create a tool registry and register your tools
tools = ToolRegistry()
tools.register("get_weather", get_weather)
# Initialize the client with the tool registry
client = AsyncLLMClient(tool_registry=tools)
# Use the client with different models
response = await client.response(
"What's the weather like in Paris?",
model="gpt-4o-mini", # Default model is gpt-4o-mini
instructions="You are a helpful assistant that provides weather information."
)
print(response["text"])
# Use with Anthropic's Claude
claude_response = await client.response(
"What's the weather like in Tokyo?",
model="claude-3-opus-20240229",
instructions="You are a helpful assistant that provides weather information."
)
print(claude_response["text"])
# Use with Ollama (local models)
# Requires Ollama to be installed: https://ollama.com
ollama_response = await client.response(
"What's the weather like in London?",
model="llama3", # Or any model you've pulled with Ollama
instructions="You are a helpful assistant that provides weather information.",
base_url="http://localhost:11434/v1",
api_key="ollama",
use_responses_api=False
)
print(ollama_response["text"])
if __name__ == "__main__":
asyncio.run(main())
Advanced Features
Using Conversations
import asyncio
from llm import AsyncLLMClient, Message
async def main():
client = AsyncLLMClient()
# Create a conversation with multiple messages
messages = [
{"role": "system", "content": "You are a helpful coding assistant."},
{"role": "user", "content": "How do I read a file in Python?"},
{"role": "assistant", "content": "You can use the built-in `open()` function..."},
{"role": "user", "content": "Can you show me how to read a JSON file specifically?"}
]
response = await client.response(
messages,
model="gpt-4o"
)
print(response["text"])
if __name__ == "__main__":
asyncio.run(main())
Tool/Function Calling
The library supports a consistent interface for tool calling across providers:
import asyncio
import json
from llm import AsyncLLMClient, ToolRegistry, llm_tool
@llm_tool
async def search_database(query: str, limit: int = 5):
"""Search a database for information."""
# Mock implementation
results = [{"id": i, "title": f"Result {i} for {query}"} for i in range(limit)]
return results
async def main():
tools = ToolRegistry()
tools.register("search_database", search_database)
client = AsyncLLMClient(tool_registry=tools)
response = await client.response(
"Find information about machine learning frameworks",
model="gpt-4o",
instructions="You are a helpful assistant with access to a database."
)
print(response["text"])
if __name__ == "__main__":
asyncio.run(main())
Streaming Responses
The library supports streaming responses for both OpenAI and Anthropic models, which improves perceived latency and user experience for longer responses:
import asyncio
from llm import AsyncLLMClient, StreamHandler
# Define a custom handler function for the stream chunks
async def handle_chunk(chunk: str):
print(chunk, end="", flush=True)
async def main():
client = AsyncLLMClient()
# Stream a response from OpenAI
response = await client.stream(
"Explain the theory of relativity in simple terms",
model="gpt-4o",
stream_handler=handle_chunk
)
print(f"\n\nTotal tokens: {response['input_tokens']} input, {response['output_tokens']} output")
# Stream a response from Anthropic
response = await client.stream(
"Write a short story about a robot discovering emotions",
model="claude-3-5-haiku-latest",
stream_handler=handle_chunk
)
print(f"\n\nTotal tokens: {response['input_tokens']} input, {response['output_tokens']} output")
if __name__ == "__main__":
asyncio.run(main())
Streaming also works with conversation history, system instructions, and tool usage.
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Development Installation
To set up the development environment:
git clone https://github.com/skitsanos/unified-llm-client.git
cd unified-llm-client
pip install -e .
pip install -r requirements-dev.txt
Testing
Run tests with pytest:
pytest
Publishing to PyPI
See Publishing Documentation for detailed instructions on publishing releases to PyPI.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file unified_llm_client-0.1.1.tar.gz.
File metadata
- Download URL: unified_llm_client-0.1.1.tar.gz
- Upload date:
- Size: 35.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c368a3bb0b3c16a51c9c31a465a37ed0e0f480908df07e092239517ef36ddc4e
|
|
| MD5 |
a27feb072a3f42055b8cdc4dc05ce47e
|
|
| BLAKE2b-256 |
bb50e73571ebb7d5cb953c9571017949eab21cb65c6af3eb4068d4c5dd3166a5
|
File details
Details for the file unified_llm_client-0.1.1-py3-none-any.whl.
File metadata
- Download URL: unified_llm_client-0.1.1-py3-none-any.whl
- Upload date:
- Size: 28.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e0a6b69c932eab5882f6a475ccb7f34d52a85fd08eb98966f28c7b2fa744e1eb
|
|
| MD5 |
b62fd649152e71750244d8144195dfa5
|
|
| BLAKE2b-256 |
e4a5fa86c13cf7e753ccf0bcd0070fc1722f70aafe2166ab00b673952929e618
|