openai-api-rs

repository·main·Indexed 19 days ago

https://github.com/dongri/openai-api-rs

An unofficial Rust client library for the OpenAI API and compatible providers like OpenRouter. Version 10.0.1 provides access to a wide range of API categories including Chat, Completions, Embeddings, Audio, Assistants, and the Realtime API. It includes specialized modules for WebSocket-based Realtime API interactions with support for ClientEvent and ServerEvent handling, as well as comprehensive types for configuring sessions, audio formats, and tool definitions.

Tokens
13.3K
Snippets
43
Records
56
Agent score
65%

What's inside openai-api-rs

  1. Configure API keys via environment variables

    main

    The library requires an API key. It is recommended to set your key as an environment variable before running your application.

    For OpenAI, use OPENAI_API_KEY. For OpenRouter, use OPENROUTER_API_KEY.

    You can also optionally set OPENAI_API_BASE to override the default OpenAI endpoint.

    $ export OPENAI_API_KEY=sk-xxxxxxx
    # or
    $ export OPENROUTER_API_KEY=sk-xxxxxxx
    
    # Optional: set custom base URL
    $ export OPENAI_API_BASE=https://api.openai.com/v1
  2. Understand Realtime API Response Statuses

    main

    The Response object includes a status field of type ResponseStatus. This indicates the current state of the response processing:

    • InProgress: The response is being generated.
    • Completed: The response was generated successfully.
    • Cancelled: The response was stopped by a cancellation event.
    • Failed: The response generation failed.
    • Incomplete: The response was cut short (e.g., due to an interruption or token limits).

    Detailed Statuses

    If the status is not Completed or InProgress, status_details (of type ResponseStatusDetail) provides more context:

    • Cancelled: Provides a CancelledReason (TurnDetected or ClientCancelled).
    • Incomplete: Provides an IncompleteReason (Interruption, MaxOutputTokens, or ContentFilter).
    • Failed: Provides a FailedError containing a code, message, and type.
  3. Understand FineTuningJobObject and FineTuningJobError

    main

    When a fine-tuning job is retrieved or listed, it returns a FineTuningJobObject. Key fields include:

    • id: The unique identifier for the job.
    • status: The current state of the job.
    • fine_tuned_model: The ID of the resulting model (available when finished).
    • error: An optional FineTuningJobError if the job failed.

    If an error occurs, FineTuningJobError provides:

    • code: A machine-readable error code.
    • message: A human-readable description of the error.
    • param: The specific parameter that caused the error (if applicable).
  4. Configure Assistant tool resources

    main

    The ToolResource struct allows you to configure specific resources for the assistant's tools. It supports:

    • code_interpreter: Can be configured with a list of file_ids via the CodeInterpreter struct.
    • file_search: Can be configured with vector_store_ids or a vector_stores object via the FileSearch struct.

    VectorStores configuration includes:

    • file_ids: A list of file IDs to include.
    • chunking_strategy: The strategy used for chunking files.
    • metadata: Custom metadata for the vector store.
    let tool_resources = ToolResource {
        file_search: Some(FileSearch {
            vector_store_ids: Some(vec!["vs_123".to_string()]),
            vector_stores: None,
        }),
        code_interpreter: None,
    };
  5. Use request transforms

    main

    The transforms field in ChatCompletionRequest accepts an optional Vec<String>. These strings represent names of transforms that can be applied to the request before it is sent to the API. This is useful for implementing features like prompt rewriting or content filtering at the client level.

    let req = ChatCompletionRequest::new("gpt-4".to_string(), vec![])
        .transforms(vec!["transform1".to_string(), "transform2".to_string()]);
  6. Configure reasoning effort and summary

    main

    For models supporting reasoning (like OpenAI's o1 series), you can control the model's internal thought process using the Reasoning struct.

    ReasoningEffort

    Controls the amount of computational effort spent on reasoning. Values (lowercase in JSON):

    • none
    • minimal
    • low
    • medium
    • high
    • xhigh

    ReasoningSummary

    Controls the verbosity of the reasoning summary. Values (lowercase in JSON):

    • auto
    • concise
    • detailed
    use crate::v1::chat_completion::{Reasoning, ReasoningEffort, ReasoningSummary};
    
    let reasoning_config = Reasoning {
        effort: Some(ReasoningEffort::Medium),
        summary: Some(ReasoningSummary::Concise),
    };
  7. Define Tools and Function Calling

    main

    You can extend the Realtime API capabilities by providing tools.

    ToolDefinition

    Use the ToolDefinition::Function variant to define a tool:

    • name: The name of the function.
    • description: A description of what the function does.
    • parameters: A serde_json::Value representing the JSON Schema for the function arguments.

    ToolChoice

    Control how the model uses tools using the ToolChoice enum:

    • Auto: The model decides whether to call a function.
    • None: The model does not call functions.
    • Required: The model must call a function.
    • Function { type: FunctionType::Function, name: String }: Forces the model to call a specific function by name.
    // Example ToolDefinition
    let tool = ToolDefinition::Function {
        name: "get_weather".to_string(),
        description: "Get the current weather".to_string(),
        parameters: serde_json::json!({
            "type": "object",
            "properties": {
                "location": { "type": "string" }
            }
        }),
    };
  8. Configure reasoning for reasoning models

    main

    For models that support reasoning, you can control the depth and style of the reasoning process using reasoning and reasoning_effort within a ChatCompletionRequest.

    • reasoning: A Reasoning struct that allows specifying both effort (e.g., ReasoningEffort::High) and summary (e.g., ReasoningSummary::Detailed).
    • reasoning_effort: A direct way to set the effort level via the ReasoningEffort enum (e.g., Low, Medium, High, Xhigh, Minimal, or None).
    let mut req = ChatCompletionRequest::new("gpt-5.1".to_string(), vec![]);
    req.reasoning_effort = Some(ReasoningEffort::Minimal);
  9. Perform a Chat Completion

    main

    To generate a chat response, create a ChatCompletionRequest with a model name and a vector of ChatCompletionMessage objects. Then, call client.chat_completion(req).await?.

    use openai_api_rs::v1::api::OpenAIClient;
    use openai_api_rs::v1::chat_completion::{self, ChatCompletionRequest};
    use openai_api_rs::v1::common::GPT4_O;
    use std::env;
    
    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
        let api_key = env::var("OPENAI_API_KEY").unwrap().to_string();
        let mut client = OpenAIClient::builder().with_api_key(api_key).build()?;
    
        let req = ChatCompletionRequest::new(
            GPT4_O.to_string(),
            vec![chat_completion::ChatCompletionMessage {
                role: chat_completion::MessageRole::user,
                content: chat_completion::Content::Text(String::from("What is bitcoin?")),
                name: None,
                tool_calls: None,
                tool_call_id: None,
            }],
        );
    
        let result = client.chat_completion(req).await?;
        println!("Content: {:?}", result.choices[0].message.content);
    
        // Accessing response headers if available
        if let Some(headers) = client.headers.as_ref() {
            for (key, value) in headers.iter() {
                println!("{}: {:?}", key, value);
            }
        }
    
        Ok()
    }
  10. Initialize an OpenRouter client

    main

    To use OpenRouter instead of OpenAI, use the builder to specify the OpenRouter endpoint via .with_endpoint("https://openrouter.ai/api/v1") along with your OpenRouter API key.

    let api_key = env::var("OPENROUTER_API_KEY").unwrap().to_string();
    let mut client = OpenAIClient::builder()
        .with_endpoint("https://openrouter.ai/api/v1")
        .with_api_key(api_key)
        .build()?;
  11. Initialize an OpenAIClient

    main

    Use the OpenAIClient::builder() to create a client instance. You must provide an API key using .with_api_key().

    let api_key = env::var("OPENAI_API_KEY").unwrap().to_string();
    let mut client = OpenAIClient::builder().with_api_key(api_key).build()?;