Rust CLI client for the OpenAI Responses API. It sends user messages to a configurable model (e.g. gpt-4o-mini) and prints the assistant’s reply. The design is trait-based so you can plug in other providers later.
- OpenAI Responses API — Uses the
/v1/responsesendpoint (request/response types match the API). - Trait-based design —
AIProviderinsrc/helpers/traits.rsdefinesnewandgpt_chat;OpenAIClientimplements it so you can swap or add providers. - Configurable — API key, model, and request timeout via
OpenAIConfig. - Interactive loop — Prompts for messages until you type exit (e.g.
exit,quit,q, or leave the line empty). - Error handling — Parses API error payloads and surfaces status and message; HTTP and timeout errors are propagated.
- Rust (e.g. via
rustup) - An OpenAI API key
-
Clone and build
cd gpt-client cargo build --release -
Configure the API key
Create a
.envin the project root (do not commit it):OPENAI_API_KEY=sk-your-key-here
The app loads this via
dotenvyand expectsOPENAI_API_KEYto be set.
gpt-client/
├── Cargo.toml
├── README.md
├── .env # Your API key (gitignored)
└── src/
├── main.rs # Binary: config, loop, prompt, gpt_chat calls
├── mod.rs
└── helpers/
├── mod.rs
└── traits.rs # Message, GptRequest, OpenAIConfig, AIProvider
src/main.rs— BuildsOpenAIConfig, constructsOpenAIClientviaAIProvider::new, then runs an interactive loop: prompt →client.gpt_chat(messages)→ print reply. Contains the API response types (ChatResponse,OutputItem,ContentItem) and error parsing (ApiErrorResponse,ApiError).src/helpers/traits.rs— Shared types and the provider trait:Message(role, content),GptRequest(model, input messages),OpenAIConfig(api_key, default_model, timeout), andAIProviderwithnewandasync fn gpt_chat.
- Config —
OpenAIConfigholdsapi_key,default_model(e.g.gpt-4o-mini), andtimeout(e.g. 10 seconds). - Client —
OpenAIClientimplementsAIProvider: innewit builds areqwest::Clientwith aBearerauth header and the given timeout;gpt_chatsends a JSON body{ model, input: messages }tohttps://api.openai.com/v1/responses. - Request — Each turn is a single user message:
Vec<Message>with oneMessage { role: "user", content }. - Response — The code parses the Responses API JSON:
output[0].content[0].text, and returns that string. On HTTP errors it parses the API error body and returns a descriptive error.
Run the binary (after cargo build or cargo run):
cargo run --releaseYou’ll see:
Enter your message: <your prompt>
Type a message and press Enter; the model’s reply is printed. The loop continues until you:
- Enter an empty line, or
- Type one of:
exit,quit,q,bye,goodbye,end,stop,terminate
Configured in code where the client is created (e.g. in main.rs):
| Field | Example | Description |
|---|---|---|
api_key |
from OPENAI_API_KEY |
OpenAI API key |
default_model |
gpt-4o-mini |
Model used for gpt_chat |
timeout |
Duration::from_secs(10) |
HTTP request timeout |
Change default_model or timeout there to adjust behavior.
- reqwest — HTTP client (with
jsonfeature). - tokio — Async runtime (
#[tokio::main], asyncgpt_chat). - serde / serde_json — Serialize request body, deserialize response and error payloads.
- async-trait — Async method in
AIProvider(gpt_chat). - dotenvy — Load
.envandOPENAI_API_KEY.
- Keep your API key in
.envand ensure.envis in.gitignore(it is). Never commit keys. - If a key was ever committed, revoke it in the OpenAI API keys dashboard and create a new one.
See the repository or add a LICENSE file as needed.