courier-os
Python agent framework for OpenAI-compatible APIs, with optional local Apple Silicon inference via courier-os-binary.
Install: pip install courier-os
Import: import courier_os
Dual mode
| Mode | How | Needs binary? |
|---|---|---|
| API | Model("gpt-4o", api_key="…", base_url="…") |
No |
| Local | Model("mlx-community/…", mode="local") |
Yes (courier-os[local] / monorepo) |
Credentials resolve from args or env: COURIER_OS_API_KEY / COURIER_OS_BASE_URL, then OPENAI_API_KEY / OPENAI_BASE_URL.
from courier_os import Model, Agent, Operator, tools
@tools.tool
def get_weather(city: str) -> dict:
"""Get weather for a city."""
return {"city": city, "temp_f": 72}
# Cloud / any OpenAI-compatible endpoint
model = Model("gpt-4o", api_key="…", base_url="https://api.openai.com/v1")
# Or local MLX (requires courier-os-binary on Apple Silicon)
# model = Model("mlx-community/Qwen3.5-2B-MLX-8bit", mode="local")
# if not model.can_load:
# model = Model("gpt-4o", api_key="…", base_url="…")
agent = Agent(model, tools=[get_weather])
messages = [{"role": "user", "content": "Weather in Denver?"}]
# Agent — one model turn (you handle tool_calls if present)
resp = agent.chat(messages)
if resp.tool_calls:
messages.append({"role": "assistant", "content": resp.content, "tool_calls": resp.tool_calls})
messages.extend(agent.call_tools(resp.tool_calls))
resp = agent.chat(messages)
print(resp.content)
# Operator — auto tool loop until the model finishes
out = Operator(agent).run([{"role": "user", "content": "Weather in Denver?"}])
print(out.content)
HTTP relay
from courier_os import relay
out = relay(
model="gpt-4o",
messages=[{"role": "user", "content": "hi"}],
api_key="…",
base_url="https://api.openai.com/v1",
tools=[get_weather],
).response
Multimodal messages
OpenAI-shaped image/audio content parts work on both paths (local omni models extract media before inference):
messages = [{
"role": "user",
"content": [
{"type": "text", "text": "What is in this image?"},
{"type": "image_url", "image_url": {"url": "data:image/png;base64,…"}},
],
}]
Operator(agent).run(messages)
Local runtime
Local inference lives in the proprietary courier-os-binary package (not on public PyPI yet). In this monorepo:
cd playground && uv sync
That editable-installs courier-os → courier-os-binary.
Docs
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 courier_os-0.1.0.tar.gz.
File metadata
- Download URL: courier_os-0.1.0.tar.gz
- Upload date:
- Size: 40.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d33a378db6dfd0826426b73157a1b34e7328dfa4c16eda744797e04a908901a8
|
|
| MD5 |
894410c1a3baf908354e544671669a23
|
|
| BLAKE2b-256 |
0135fc157f23cd2f4ec51155438a1d0510e215d6a7b1e5c814994ef9b2d22d74
|
File details
Details for the file courier_os-0.1.0-py3-none-any.whl.
File metadata
- Download URL: courier_os-0.1.0-py3-none-any.whl
- Upload date:
- Size: 49.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
72c7d48092ac2e597edc2e12262c5aae4e66e57883f9e4d8aeec8c2da9f30a25
|
|
| MD5 |
6f5dec790eb69822548378799b30d87e
|
|
| BLAKE2b-256 |
c880da002396694c8db4a2f7f1b6c58f7f767a0c54f854272fefc3e342b2bf46
|