1 unstable release
Uses new Rust 2024
| 0.1.0 | Aug 21, 2025 |
|---|
#1431 in Asynchronous
110KB
2.5K
SLoC
OpenAI Agents (Rust)
Harmony-aligned, OpenAI-compatible agent orchestration in Rust — no mocks, no automatic fallbacks.
This crate provides a library and CLI to build agents that call OpenAI-compatible models (cloud or OSS) with robust tool orchestration, optional realtime/voice support, and an environment-first configuration model. It aims for practical parity with the Python SDK while staying idiomatic in Rust.
Highlights
- No mocks or hidden fallbacks: strict, explicit errors; no auto-retries or provider defaults.
- OpenAI-compatible models: Chat Completions, Harmony-style Responses, LiteLLM pass-through.
- Tools: OpenAI tool schema and legacy function_call supported; configurable tool-choice.
- Realtime/Voice: SSE-based realtime module and STT/TTS clients (OpenAI-compatible endpoints).
- Extensible: dynamic plugin system and a simple tool registry.
Quickstart
- Create a .env with your model server details (base_url is required):
# Local OSS (e.g., vLLM / OpenAI-compatible)
OPENAI_BASE_URL=http://localhost:8000/v1
OPENAI_MODEL=openai/gpt-oss-120b
# Optional if your server requires auth
# OPENAI_API_KEY=sk-...
# Logging
RUST_LOG=info
- Build and test:
cargo test -q
- Run the CLI (starts the MCP server and a default agent):
cargo run
By default, the MCP server binds to http://127.0.0.1:8080 and the runtime registers:
- EchoAgent (simple example that calls your configured model)
- A configured agent using the experimental realtime model
Configuration
The config loader supports both file-based and environment-based configuration.
- File: set
OPENAI_AGENTS_CONFIG(default:./config.yaml). The loader also reads variables with prefixOPENAI_AGENTS__to override file keys. - Environment: common provider-style variables are respected globally:
OPENAI_BASE_URL(required)OPENAI_MODEL(required)OPENAI_API_KEY(optional)RUST_LOG(optional)
Schema (src/config/schema.rs):
api_key: String(optional)model: String(required)base_url: String(required)log_level: Stringplugins_path: PathBuf(defaults to~/.config/openai_agents/plugins)max_concurrent_requests: Option<usize>
Important policy: base_url is required and there are no provider defaults baked into the loader. If a value is missing, it stays empty and you’ll see a clear error where used.
Env override notes
- File-based overrides:
OPENAI_AGENTS__BASE_URL,OPENAI_AGENTS__MODEL, etc. map onto file keys when using a config file. - Global overrides:
OPENAI_BASE_URL,OPENAI_MODEL,OPENAI_API_KEY,RUST_LOGalways overlay the active config at runtime.
Model backends
- OpenAI Chat Completions (
/chat/completions):src/model/openai_chat.rs- Tool schema: supports
tool_callsand legacyfunction_call. - Tool-choice: auto/none and object forms; optional env overrides (see below).
- Tool schema: supports
- Harmony-style OSS Responses (
/responses):src/model/gpt_oss_responses.rs - LiteLLM pass-through:
src/model/litellm.rs(for aggregating providers behind a single base_url)
Common env toggles for OpenAI-compatible servers (especially vLLM):
VLLM_MIN_PAYLOAD(bool): minimal payload (model+messages only).VLLM_FORCE_FUNCTIONS(bool): send legacyfunctions/function_callinstead oftools.VLLM_DISABLE_PARALLEL_TOOL_CALLS(bool): don’t sendparallel_tool_calls: true.VLLM_TOOL_CHOICE(string): one ofauto,none,object:auto,object:none.VLLM_DISABLE_TOOLS_IN_LLM(bool): don’t pass tool specs to the LLM from the runner.VLLM_DEBUG_PAYLOAD(bool): pretty-print request JSON at debug level.
Tools and the runner
The Runner orchestrates tool execution and model turns.
- Behavior modes:
RunLlmAgain,StopOnFirstTool,StopAtTools([..]), or a custom decider. - Messages: constructed with optional system instructions and user input; tool outputs are appended as proper
toolmessages withtool_call_idwhen available. - Error policy: strict — unknown or disabled tool requests return explicit errors; no implicit retries.
Tools live under src/tools/ with a simple Tool trait and a registry for discovery. Tools can optionally expose an OpenAI tool spec so the model can call them via tool_calls.
Realtime and voice
- Realtime:
src/model/openai_realtime.rsandsrc/realtime.rsprovide building blocks for SSE streaming flows. - Voice:
src/voice/includes STT (audio/transcriptions) and TTS (audio/speech) clients, with a pipeline for simple voice interactions.
Plugins
Plugins are dynamically loadable and initialized at runtime:
- Loader/registry in
src/plugin/loader.rsandsrc/plugin/mod.rs. - Default search path is
~/.config/openai_agents/plugins(configurable viaplugins_path).
Parity with openai-agents-python
What’s implemented:
- Model coverage: OpenAI Chat Completions, Harmony-aligned OSS Responses, LiteLLM pass-through.
- Tool orchestration:
tool_callsand legacyfunction_call; optional tool-choice; parallel tool-calls control. - Sessions/memory scaffolding and tracing hooks; explicit errors instead of silent fallbacks.
- Realtime SSE client and voice pipeline (STT/TTS) counterparts.
Partial/roadmap:
- Agent-as-tool helper ( ergonomic wrapper ).
- Guardrails and handoffs deeper integration in the runner.
- Rich tracing exporters and span coverage.
- Hosted tool adapters and more bundled tools.
No mocks or fallbacks — by design
- The env loader doesn’t invent values and does not inject provider defaults.
- Model calls don’t auto-retry or downgrade; errors are explicit and surfaced early.
- Comments and docs avoid "fallback" semantics; behaviors are intentional and visible.
Development
Build, test, and run locally:
cargo test -q
cargo run
Optional config file example (config.yaml):
base_url: "http://localhost:8000/v1"
model: "openai/gpt-oss-120b"
log_level: "info"
plugins_path: "~/.config/openai_agents/plugins"
You can override any file keys with OPENAI_AGENTS__<KEY> (double underscore maps to nested keys) or use the global provider-style variables documented above.
Repository layout (selected)
src/
lib.rs # crate exports
main.rs # CLI: loads config, starts MCP server, runs agents
agent/ # Agent traits, runtime, runner
model/ # Models: OpenAI Chat, OSS Responses, LiteLLM, Realtime
tools/ # Tool trait + registry + function tools
plugin/ # Plugin loader/registry
config/ # Config schema + loader (env-first)
realtime/, voice/ # Streaming + STT/TTS
License
MIT — see LICENSE for details. Contributions welcome.
See also: CONTRIBUTING.md, SECURITY.md, and CHANGELOG.md.
Dependencies
~18–34MB
~494K SLoC