DrekAI OpenAI Wrapper
A modern, async-first Python wrapper for OpenAI-compatible LLM APIs with built-in tool/function calling support.
Works with OpenAI, Gemini (via proxy), and any OpenAI-compatible endpoint.
✨ Features
- Async-native – built on
httpx/openaiasync client - Tool use – define Python functions as AI-callable tools with automatic sandbox parameter injection
- Streaming – stream responses token-by-token with a simple callback
- Sandboxed parameters – keep secrets invisible to the LLM while still passing them to tools
- Multi-turn chats – conversation history management
- Image support – send local files, URLs, or base64 images inline
- Thinking / reasoning – support for extended-thinking models with effort control
- Gemini compatibility – automatic tool-call shimming for Gemini models behind OpenAI proxies
📦 Installation
pip install drekai
Or install from source:
git clone https://github.com/drek124/drekai.git
cd drekai
pip install .
🚀 Quick Start
import asyncio
from drekai import Model, Chatbot
# 1. Define a model endpoint
model = Model("gpt-4o", "https://api.openai.com/v1", api_key="sk-...")
# 2. Create a chatbot
bot = Chatbot(
name="Helper",
system_prompt="You are a helpful assistant.",
parent_model=model,
temperature=0.7,
)
async def main():
# One-shot generation
response = await bot.generate_text("Hello!")
print(response.choices[0].message.content)
# Multi-turn chat
chat = bot.start_chat()
r1 = await chat.generate_reply("What's the weather in Tokyo?")
print(r1.choices[0].message.content)
r2 = await chat.generate_reply("And in London?") # Context retained
print(r2.choices[0].message.content)
asyncio.run(main())
🛠️ Tool Use
from drekai import Model, Chatbot
from drekai.tools import Tool
model = Model("gpt-4o", "https://api.openai.com/v1", api_key="sk-...")
bot = Chatbot("Assistant", "You are a helpful assistant.", model)
async def get_weather(city: str):
"""Get the current weather for a city."""
# In a real app, call a weather API here
return f"The weather in {city} is sunny, 25°C."
tools = [
Tool(
name="fetch_weather", # Overwrite function name if needed
callback=get_weather,
)
]
async def main():
chat = bot.start_chat()
response = await chat.generate_reply(
"What's the weather in Paris?",
tools=tools,
)
print(response.choices[0].message.content)
asyncio.run(main())
Sandboxed Parameters
Keep secrets like user IDs invisible to the LLM:
async def get_friends(user, limit: int = 50) -> str:
"""Fetch the user's friends list."""
return str(user.get_friends(limit=limit))
tools = [
Tool(
callback=get_friends, # All info about the function name, description & parameters will be taken from the callback.
sandbox_params=["user"], # hidden from the LLM
)
]
await chat.generate_reply(
"Who are my friends?",
tools=tools,
sandbox_params={"user": current_user}, # injected at call time
)
🖼️ Images
from drekai.messaging import Image
# Local file
await chat.generate_reply(
"Describe this image.",
items=[Image("/path/to/photo.jpg")],
)
# URL
await chat.generate_reply(
"Describe this image.",
items=[Image("https://example.com/photo.jpg")],
)
# Base64
await chat.generate_reply(
"Describe this image.",
items=[Image(base64_data, b64=True)],
)
📖 API Reference
Model(model_id, base_url, *, api_key)
Root model representing an API endpoint.
Chatbot(name, system_prompt, parent_model, *, api_key, temperature, thinking, reasoning_effort)
A named chatbot built on a model.
Chat
Created via chatbot.start_chat(). Manages conversation history.
| Method | Description |
|---|---|
generate_reply(...) |
Generate the next response |
add_message_to_context(content, role) |
Manually add a message |
clear() |
Reset history (keeps system prompt) |
delete_first_message(role) |
Remove first message with given role |
stop_live_generation() |
Stop an active stream mid-generation |
ChatSettings(max_tokens, show_tool_error_type)
Per-chat configuration.
Tool(name, params, callback, sandbox_params)
An AI-callable function.
MessageItem / Image
Chat message attachments.
🧪 Development
# Clone and install in editable mode with dev deps
git clone https://github.com/drek124/drekai.git
cd drekai
pip install -e ".[dev]"
# Lint
ruff check drekai/
# Type check
mypy drekai/
# Test
pytest
📄 License
MIT License. See LICENSE for details.
Release files for drekai 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| drekai-1.1.0.tar.gz | 9.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| drekai-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.5 kB
Release files / drekai-1.1.0.tar.gz
| Download URL | drekai-1.1.0.tar.gz |
|---|---|
| Size | 9.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b18ca45e85f0f50364ea0e7c6b8a72c926ffde9e6a2f28e677ca52d4ee25bfdb
|
|
BLAKE2b-256 checksum How to use checksums |
00b58d2961671ac43d851f8257e8ec9fe792137de7ab7b87576e10c9e72195d8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Release files / drekai-1.1.0-py3-none-any.whl
| Download URL | drekai-1.1.0-py3-none-any.whl |
|---|---|
| Size | 12.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1bd8498dc06256d71323a1b1270e4c6c8216fe23866e9cd36c1b2fe6cebd8b2c
|
|
BLAKE2b-256 checksum How to use checksums |
7b9629c768d525c0ec91c97eed7dbf961e9d10cb1a219e8b6a8ae2d8f7662483
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|