### Python Integration Example for Roy Server Source: https://github.com/masci/roy/blob/main/_autodocs/README.md Demonstrates starting a Roy server with specific configurations and making basic requests using Python's requests library. ```python import requests import subprocess import time # Start Roy server server_process = subprocess.Popen([ "roy", "--port", "8000", "--response-length", "200:500", "--error-code", "500", "--error-rate", "5", "--rpm", "100", "--tpm", "50000" ]) try: time.sleep(1) # Wait for server startup # Test normal request response = requests.post( "http://localhost:8000/v1/chat/completions", json={"messages": [{"role": "user", "content": "Hello"}]} ) assert response.status_code == 200 assert "usage" in response.json() # Test rate limiting # ... make 101 requests within 1 minute, expect 429 # Test error simulation # ... make multiple requests, some should return 500 finally: server_process.terminate() ``` -------------------------------- ### Start Roy with Default Configuration Source: https://github.com/masci/roy/blob/main/_autodocs/configuration.md Starts the Roy server using all default configuration settings. ```sh roy ``` -------------------------------- ### Comprehensive Configuration Example Source: https://github.com/masci/roy/blob/main/_autodocs/configuration.md A comprehensive example combining multiple configuration options including port, response length range, error simulation, slowdown range, rate limits, and verbose logging. ```sh roy \ --port 8000 \ --response-length 200:500 \ --error-code 429 \ --error-rate 10 \ --slowdown 50:200 \ --rpm 200 \ --tpm 50000 \ -v ``` -------------------------------- ### Install Roy using Cargo Source: https://github.com/masci/roy/blob/main/README.md Install the Roy CLI tool from crates.io using the Rust package manager Cargo. ```sh cargo install roy-cli ``` -------------------------------- ### Example: Initializing ServerState Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/server-state.md Demonstrates how to create a ServerState instance with specific command-line arguments. ```rust use roy_cli::{Args, ServerState}; use std::net::{IpAddr, Ipv4Addr}; let args = Args { verbosity: Default::default(), port: 8000, address: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), response_length: Some("250".to_string()), error_code: Some(429), error_rate: Some(10), rpm: 500, tpm: 30000, slowdown: None, timeout: None, }; let state = ServerState::new(args); ``` -------------------------------- ### Streaming Request Example Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/responses.md Example cURL command for making a streaming request to the /v1/responses endpoint. ```APIDOC ## Streaming Request ### Description Example cURL command for a streaming request. ### Request Example ```bash curl -X POST http://localhost:8000/v1/responses \ -H "Content-Type: application/json" \ -d '{ "input": "Explain AI", "stream": true }' ``` ``` -------------------------------- ### Chat Completions Request Example Source: https://github.com/masci/roy/blob/main/_autodocs/README.md Example JSON payload for a non-streaming chat completions request to the Roy server. ```json { "messages": [{"role": "user", "content": "Hello"}], "model": "gpt-3.5-turbo", "stream": false } ``` -------------------------------- ### Streaming Request Example Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/responses.md Example of making a streaming POST request to the /v1/responses endpoint using curl. Sets the input and stream to true. ```bash curl -X POST http://localhost:8000/v1/responses \ -H "Content-Type: application/json" \ -d '{ "input": "Explain AI", "stream": true }' ``` -------------------------------- ### Streaming Chat Completion Events Example Source: https://github.com/masci/roy/blob/main/_autodocs/endpoints.md This example demonstrates the sequence of server-sent events for a streaming chat completion. It shows the initial role assignment, content deltas, and the final event with finish reason and usage. ```text data: {"id":"chatcmpl-1234567890","object":"chat.completion.chunk","created":1609459200,"model":"gpt-3.5-turbo","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]} data: {"id":"chatcmpl-1234567890","object":"chat.completion.chunk","created":1609459200,"model":"gpt-3.5-turbo","choices":[{"index":0,"delta":{"content":"Lorem "},"finish_reason":null}]} data: {"id":"chatcmpl-1234567890","object":"chat.completion.chunk","created":1609459200,"model":"gpt-3.5-turbo","choices":[{"index":0,"delta":{},"finish_reason":"stop","usage":{"prompt_tokens":12,"completion_tokens":18,"total_tokens":30}}]} data: [DONE] ``` -------------------------------- ### Chat Completions Response Example (Non-streaming) Source: https://github.com/masci/roy/blob/main/_autodocs/README.md Example JSON response for a non-streaming chat completions request from the Roy server. ```json { "id": "chatcmpl-வுகளை", "object": "chat.completion", "choices": [{"message": {"role": "assistant", "content": "..."}}], "usage": {"prompt_tokens": 5, "completion_tokens": 10, "total_tokens": 15} } ``` -------------------------------- ### Main Function Argument Parsing and Server Initialization Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/main.md Parses command-line arguments using the `Args` struct and initializes logging before starting the Roy HTTP server. ```rust #[tokio::main] async fn main() -> anyhow::Result<()> { let args = Args::parse(); let mut builder = env_logger::Builder::new(); let filter = args.verbosity.log_level_filter(); builder.filter_level(filter); builder.init(); run(args).await } ``` -------------------------------- ### run Function Signature Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/main.md The main asynchronous function that starts the Roy HTTP server with the provided configuration. ```rust pub async fn run(args: Args) -> anyhow::Result<()> ``` -------------------------------- ### Example ChatCompletionResponse JSON Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/chat-completions.md An example JSON response for a non-streaming chat completion, detailing the generated message, model, and token usage. ```json { "id": "chatcmpl-2c5f2d0c", "object": "chat.completion", "created": 1609459200, "model": "gpt-3.5-turbo", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 15, "completion_tokens": 24, "total_tokens": 39 } } ``` -------------------------------- ### Streaming Request Example Source: https://github.com/masci/roy/blob/main/_autodocs/endpoints.md This cURL command demonstrates how to initiate a streaming request by setting the 'stream' parameter to true. This enables server-sent events for real-time response delivery. ```bash curl -X POST http://localhost:8000/v1/responses \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-5-2025-08-07", "input": "Explain quantum computing", "stream": true }' ``` -------------------------------- ### Responses Endpoint Request Example Source: https://github.com/masci/roy/blob/main/_autodocs/README.md Example JSON payload for a non-streaming request to the /v1/responses endpoint. ```json { "input": "Explain quantum computing", "stream": false } ``` -------------------------------- ### Non-Streaming Request Example Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/responses.md Example cURL command for making a non-streaming request to the /v1/responses endpoint. ```APIDOC ## Non-Streaming Request ### Description Example cURL command for a non-streaming request. ### Request Example ```bash curl -X POST http://localhost:8000/v1/responses \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-5-2025-08-07", "input": "What is quantum computing?", "stream": false }' ``` ``` -------------------------------- ### Streaming Request Source: https://github.com/masci/roy/blob/main/_autodocs/endpoints.md Example of a POST request to the chat completions endpoint with streaming enabled. ```bash curl -X POST http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "messages": [{"role": "user", "content": "Hello"}], "stream": true }' ``` -------------------------------- ### Enable Logging via Environment Variable Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/main.md This is a shell command example showing how to enable detailed logging for the Roy application by setting the RUST_LOG environment variable. It allows controlling log levels for different components. ```sh RUST_LOG=debug roy --port 8000 # or RUST_LOG=roy=info roy --port 8000 ``` -------------------------------- ### Responses Endpoint Response Example (Non-streaming) Source: https://github.com/masci/roy/blob/main/_autodocs/README.md Example JSON response for a non-streaming request to the /v1/responses endpoint. ```json { "id": "resp_வுகளை", "object": "response", "output": [{"id": "msg_வுகளை", "content": [{"text": "..."}]}], "usage": {"input_tokens": 5, "output_tokens": 10, "total_tokens": 15} } ``` -------------------------------- ### Configure Logging Verbosity Source: https://github.com/masci/roy/blob/main/_autodocs/configuration.md Sets the RUST_LOG environment variable to 'roy=debug' to enable debug logging for the Roy application, then starts the server on port 8000. ```sh RUST_LOG=roy=debug roy --port 8000 ``` -------------------------------- ### Non-Streaming Request Example Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/responses.md Example of making a non-streaming POST request to the /v1/responses endpoint using curl. Sets the model, input, and stream to false. ```bash curl -X POST http://localhost:8000/v1/responses \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-5-2025-08-07", "input": "What is quantum computing?", "stream": false }' ``` -------------------------------- ### Configure Axum Router with Routes, Middleware, and Fallback Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/main.md This Rust code demonstrates the complete setup of an Axum router, including defining routes, applying middleware, setting up a fallback handler for 404s, and attaching application state. The timeout layer is conditionally added as the outermost layer. ```rust let mut app = Router::new() .route( "/v1/chat/completions", post(chat_completions::chat_completions), ) .route("/v1/responses", post(responses::responses)) .route_layer(middleware::from_fn_with_state(state.clone(), slowdown)) .fallback(not_found) .with_state(state); if let Some(timeout) = args.timeout { app = app.layer(TimeoutLayer::new(Duration::from_millis(timeout))); } ``` -------------------------------- ### Handling Address/Port Already in Use Error Source: https://github.com/masci/roy/blob/main/_autodocs/errors.md When Roy fails to start because the specified address and port are already in use, you can either kill the existing process or choose a different port. ```sh roy --port 8000 # Error: bind() failed - Address already in use ``` ```sh # Try different port roy --port 8001 # Kill process on port 8000 lsof -ti:8000 | xargs kill -9 ``` -------------------------------- ### Basic Non-Streaming Request Source: https://github.com/masci/roy/blob/main/_autodocs/endpoints.md Example of a basic POST request to the chat completions endpoint without streaming enabled. ```bash curl -X POST http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "messages": [{"role": "user", "content": "Hello"}], "model": "gpt-3.5-turbo" }' ``` -------------------------------- ### Basic Non-Streaming Request Example Source: https://github.com/masci/roy/blob/main/_autodocs/endpoints.md Use this cURL command for a standard, non-streaming POST request to the /v1/responses endpoint. Ensure the Content-Type is set to application/json. ```bash curl -X POST http://localhost:8000/v1/responses \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-5-2025-08-07", "input": "Explain quantum computing" }' ``` -------------------------------- ### Comprehensive Roy CLI Testing Configuration Source: https://github.com/masci/roy/blob/main/_autodocs/README.md Combine multiple flags for a comprehensive test setup, including port, response length, error simulation, slowdown, and rate limiting. ```sh roy \ --port 8000 \ --response-length 100:500 \ --error-code 500 \ --error-rate 5 \ --slowdown 50:200 \ --rpm 100 \ --tpm 50000 ``` -------------------------------- ### Streaming Chat Completions Request Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/chat-completions.md Example of making a streaming chat completion request to the API using reqwest. Processes and prints each chunk from the stream. ```rust use futures_util::StreamExt; let client = reqwest::Client::new(); let response = client .post("http://localhost:8000/v1/chat/completions") .json(&json!({ "messages": [{"role": "user", "content": "Hello"}], "stream": true })) .send() .await?; let mut stream = response.bytes_stream(); while let Some(chunk) = stream.next().await { let chunk = chunk?; println!("{}", String::from_utf8_lossy(&chunk)); } ``` -------------------------------- ### Get Rate Limit Headers Source: https://github.com/masci/roy/blob/main/_autodocs/INDEX.md Retrieves the rate limit headers to be included in the response. ```Rust pub fn get_rate_limit_headers(&self) -> Vec<(String, String)> ``` -------------------------------- ### Example Non-Streaming JSON Response Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/responses.md Illustrates a typical JSON response for a non-streaming API request. It includes fields like ID, creation timestamp, model, status, output messages, and token usage details. ```json { "id": "resp_1234567890abcdef", "created_at": 1609459200.123, "model": "gpt-5-2025-08-07", "object": "response", "status": "completed", "output": [ { "id": "msg_fedcba0987654321", "type": "message", "role": "assistant", "status": "completed", "content": [ { "type": "output_text", "text": "Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt" } ] } ], "usage": { "input_tokens": 10, "output_tokens": 20, "total_tokens": 30, "input_tokens_details": { "cached_tokens": 0 }, "output_tokens_details": { "reasoning_tokens": 0 } } } ``` -------------------------------- ### Run Main Entry Point Source: https://github.com/masci/roy/blob/main/_autodocs/INDEX.md The asynchronous main entry point for the server application. ```Rust pub async fn run() -> std::io::Result<()> ``` -------------------------------- ### ServerState::new Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/server-state.md Creates a new ServerState instance with the provided command-line arguments. This constructor initializes the state with empty tracking queues for requests and tokens. ```APIDOC ## ServerState::new ### Description Creates a new `ServerState` from command-line arguments. ### Method ```rust pub fn new(args: Args) -> Self ``` ### Parameters - **args** (`Args`) - Description: Configuration struct containing all server options ### Returns - `ServerState` - A new state instance with empty request and token tracking queues. ### Example ```rust use roy_cli::{Args, ServerState}; use std::net::{IpAddr, Ipv4Addr}; let args = Args { verbosity: Default::default(), port: 8000, address: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), response_length: Some("250".to_string()), error_code: Some(429), error_rate: Some(10), rpm: 500, tpm: 30000, slowdown: None, timeout: None, }; let state = ServerState::new(args); ``` ``` -------------------------------- ### Run Roy Server with Custom Arguments Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/main.md This snippet demonstrates how to configure and run the Roy server with specific arguments for port, address, response length, error codes, request rates, slowdown, and timeouts. It's useful for setting up a mock API server with precise control over its behavior. ```rust use roy_cli::{Args, run}; use std::net::IpAddr; #[tokio::main] async fn main() -> anyhow::Result<()> { let args = Args { port: 8000, address: "127.0.0.1".parse()?, response_length: Some("200:500".to_string()), error_code: Some(429), error_rate: Some(10), rpm: 100, tpm: 50000, slowdown: Some("0:100".to_string()), timeout: Some(5000), verbosity: Default::default(), }; run(args).await } ``` -------------------------------- ### Server State Constructor Source: https://github.com/masci/roy/blob/main/_autodocs/INDEX.md Demonstrates the constructor for the ServerState, used to initialize server-side data. ```Rust pub fn new() -> Self ``` -------------------------------- ### Get Response Length Source: https://github.com/masci/roy/blob/main/_autodocs/INDEX.md Calculates the length of the response in tokens. ```Rust pub fn get_response_length(&self, response: &ChatCompletionResponse) -> u32 ``` -------------------------------- ### Constructor for ServerState Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/server-state.md Creates a new ServerState instance. Requires configuration arguments to be passed. ```rust pub fn new(args: Args) -> Self> ``` -------------------------------- ### Get Slodown Milliseconds Source: https://github.com/masci/roy/blob/main/_autodocs/INDEX.md Retrieves the slowdown in milliseconds for rate limiting. ```Rust pub fn get_slodown_ms(&self) -> u64 ``` -------------------------------- ### Args Struct for Command-Line Arguments Source: https://github.com/masci/roy/blob/main/_autodocs/types.md Configuration structure derived from command-line arguments using clap. It defines various settings for the application's operation. ```rust pub struct Args { pub verbosity: Verbosity, pub port: u16, pub address: IpAddr, pub response_length: Option, pub error_code: Option, pub error_rate: Option, pub rpm: u32, pub tpm: u32, pub slowdown: Option, pub timeout: Option, } ``` -------------------------------- ### ID Generation Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/responses.md Helper function and examples for generating unique IDs for various API resources like responses, messages, and reasoning. ```APIDOC ## ID Generation ### Description Helper function generates unique IDs with a specified prefix. ### Function Signature ```rust fn generate_id(prefix: &str) -> String ``` ### Examples - `resp_1234567890abcdef1234567890abcdef` (response) - `msg_fedcba0987654321fedcba0987654321` (message) - `rs_abcdef1234567890abcdef1234567890` (reasoning) ``` -------------------------------- ### Get Slowdown Duration Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/server-state.md Returns the milliseconds to slow down a request. Returns a random number between 50 and 200 for each call if configured as a range. ```rust pub fn get_slodown_ms(&self) -> u64 ``` ```rust // With --slowdown 50:200 let state = /* initialized state */; let ms = state.get_slodown_ms(); // Each call returns a different random number between 50 and 200 ``` -------------------------------- ### Get Response Length Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/server-state.md Retrieves the response length based on configuration. Returns a random number between 100 and 500 for each call if configured as a range. ```rust pub fn get_response_length(&self) -> usize ``` ```rust // With --response-length 100:500 let state = /* initialized state */; let len = state.get_response_length(); // Each call returns a different random number between 100 and 500 ``` -------------------------------- ### Configure Custom Port and Address Source: https://github.com/masci/roy/blob/main/_autodocs/configuration.md Configures the server to listen on the IP address 127.0.0.1 and port 9000. ```sh roy --address 127.0.0.1 --port 9000 ``` -------------------------------- ### Non-Streaming Chat Completions Request Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/chat-completions.md Example of making a non-streaming chat completion request to the API using reqwest. Prints the pretty-printed JSON response. ```rust use reqwest::Client; use serde_json::json; #[tokio::main] async fn main() -> Result<(), Box> { let client = Client::new(); // Non-streaming request let response = client .post("http://localhost:8000/v1/chat/completions") .json(&json!({ "messages": [ {"role": "user", "content": "Hello"} ], "model": "gpt-3.5-turbo" })) .send() .await?; let body = response.json::().await?; println!("{}", serde_json::to_string_pretty(&body)?); Ok(()) } ``` -------------------------------- ### Define Reasoning Configuration Structure Source: https://github.com/masci/roy/blob/main/_autodocs/types.md Defines the configuration structure for reasoning in API responses. It includes fields for effort, and optional summary generation and content. ```rust pub struct Reasoning { pub effort: String, pub generate_summary: Option, pub summary: Option, } ``` -------------------------------- ### Endpoint Handler with ServerState Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/server-state.md Demonstrates a typical usage pattern for ServerState within an asynchronous endpoint handler, including checking and updating rate limits, simulating errors, and generating responses. ```rust pub async fn my_endpoint( State(state): State, Json(payload): Json, ) -> impl IntoResponse { // 1. Check request rate limit if state.check_request_limit_exceeded() { let headers = state.get_rate_limit_headers(); return (StatusCode::TOO_MANY_REQUESTS, headers, error_json).into_response(); } state.increment_request_count(); // 2. Check error simulation if let Some(error_code) = state.should_return_error() { let headers = state.get_rate_limit_headers(); let status = StatusCode::from_u16(error_code).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR); return (status, headers, error_json).into_response(); } // 3. Generate response let response_length = state.get_response_length(); let content = state.generate_lorem_content(response_length); // 4. Count tokens let tokens = state.count_tokens(&content).unwrap_or(0); // 5. Check token rate limit if state.check_token_limit_exceeded(tokens) { let headers = state.get_rate_limit_headers(); return (StatusCode::TOO_MANY_REQUESTS, headers, error_json).into_response(); } state.add_token_usage(tokens); // 6. Return response with rate limit headers let headers = state.get_rate_limit_headers(); (headers, response_json).into_response() } ``` -------------------------------- ### Roy Log Messages Source: https://github.com/masci/roy/blob/main/_autodocs/errors.md Examples of common log messages generated by Roy, including 404 Not Found, Slowdown warnings, and graceful shutdown notifications. ```text WARN: Path not found: /v1/invalid ``` ```text DEBUG: Slowing down request by 125ms ``` ```text INFO: Signal received, starting graceful shutdown ``` -------------------------------- ### Args Struct Definition Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/main.md Defines the command-line arguments and configuration options for the Roy HTTP server using the `clap` derive macro. ```rust #[derive(Parser, Clone)] #[command(name = "roy")] #[command(version = env!("CARGO_PKG_VERSION"))] #[command( about = "A HTTP server compatible with the OpenAI platform format that simulates errors and rate limit data" )] pub struct Args { #[command(flatten)] pub verbosity: Verbosity, #[arg(long, help = "Port to listen on", default_value = "8000")] pub port: u16, #[arg(long, help = "Address to listen on", default_value = "0.0.0.0")] pub address: IpAddr, #[arg( long, help = "Length of response (fixed number or range like '10:100')", default_value = "250" )] pub response_length: Option, #[arg(long, help = "HTTP error code to return")] pub error_code: Option, #[arg(long, help = "Error rate percentage (0-100)")] pub error_rate: Option, #[arg( long, help = "Maximum number of requests per minute", default_value = "500" )] pub rpm: u32, #[arg( long, help = "Maximum number of tokens per minute", default_value = "30000" )] pub tpm: u32, #[arg(long, help = "Slowdown in milliseconds (fixed number or range like '10:100')")] pub slowdown: Option, #[arg(long, help = "Timeout in milliseconds")] pub timeout: Option, } ``` -------------------------------- ### Define OutputTokensDetails Structure Source: https://github.com/masci/roy/blob/main/_autodocs/types.md Defines the structure for detailed output token usage, focusing on reasoning tokens. ```rust pub struct OutputTokensDetails { pub reasoning_tokens: u32, } ``` -------------------------------- ### Define ResponseTextConfig Structure Source: https://github.com/masci/roy/blob/main/_autodocs/types.md Defines the configuration structure for text responses, specifying format and verbosity. ```rust pub struct ResponseTextConfig { pub format: ResponseFormatText, pub verbosity: String, } ``` -------------------------------- ### Token Counting Algorithm Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/chat-completions.md Calculates the total number of tokens for a given prompt and content using the cl100k_base tokenizer. Defaults to 0 tokens if tokenization fails. ```rust let prompt_text = payload .messages .as_ref() .map(|msgs| serde_json::to_string(msgs).unwrap_or_default()) .unwrap_or_default(); let prompt_tokens = state.count_tokens(&prompt_text).unwrap_or(0); let completion_tokens = state.count_tokens(&content).unwrap_or(0); let total_tokens = prompt_tokens + completion_tokens; ``` -------------------------------- ### Generate Lorem Content Source: https://github.com/masci/roy/blob/main/_autodocs/INDEX.md A utility function to generate placeholder content. ```Rust pub fn generate_lorem_content(length: usize) -> String ``` -------------------------------- ### Test Slowness with Roy CLI Source: https://github.com/masci/roy/blob/main/_autodocs/README.md Configure request delays using the --slowdown flag to simulate network latency or slow server responses. ```sh roy --slowdown 100:500 # Each request delayed 100-500ms ``` -------------------------------- ### Configure Custom Rate Limits Source: https://github.com/masci/roy/blob/main/_autodocs/configuration.md Sets custom rate limits for requests per minute (RPM) to 100 and tokens per minute (TPM) to 10000. ```sh roy --rpm 100 --tpm 10000 ``` -------------------------------- ### Add Token Usage Source: https://github.com/masci/roy/blob/main/_autodocs/INDEX.md Method to add token usage to the server state. ```Rust pub fn add_token_usage(&mut self, input_tokens: u32, output_tokens: u32) ``` -------------------------------- ### Enable Roy Debug Logging Source: https://github.com/masci/roy/blob/main/_autodocs/README.md Configure the RUST_LOG environment variable to control the verbosity of Roy's logging output. ```sh # Enable debug logging RUST_LOG=debug roy # Specific modules RUST_LOG=roy=info roy # Show all debug logs RUST_LOG=debug roy --port 8000 ``` -------------------------------- ### POST /v1/chat/completions Source: https://github.com/masci/roy/blob/main/_autodocs/endpoints.md Handles chat completions by accepting messages and returning responses. It supports both standard JSON responses and streaming responses via server-sent events (SSE), mimicking OpenAI's chat completion API. ```APIDOC ## POST /v1/chat/completions ### Description Chat completions endpoint that accepts messages and returns responses. Compatible with OpenAI's chat completion API. Supports streaming responses via server-sent events (SSE). ### Method POST ### Endpoint /v1/chat/completions ### Parameters #### Request Body - **messages** (array) - Optional - Array of message objects. Each message typically has `role` and `content` fields. Processed as JSON values - **model** (string) - Optional - Model identifier (e.g., `gpt-3.5-turbo`, `gpt-4`). Defaults to `gpt-3.5-turbo` if omitted - **stream** (boolean) - Optional - If `true`, response is streamed via server-sent events. If `false` or omitted, single JSON response is returned Additional fields are accepted but ignored (captured in `_other` field). ### Response #### Success Response (200) **Content-Type:** `application/json` (non-streaming) or `text/event-stream` (streaming) **Non-Streaming Response Schema:** - **id** (string) - Unique completion ID, prefixed with `chatcmpl-` - **object** (string) - Always `chat.completion` - **created** (integer) - Unix timestamp of completion creation - **model** (string) - Model used for completion (from request or default) - **choices** (array) - Array of choice objects (always one choice with `index: 0`) - **choices[0].index** (integer) - Always `0` - **choices[0].message** (object) - Message object with `role` and `content` - **choices[0].message.role** (string) - Always `assistant` - **choices[0].message.content** (string) - Generated response content (Lorem Ipsum) - **choices[0].finish_reason** (string) - Always `stop` - **usage** (object) - Token usage statistics - **usage.prompt_tokens** (integer) - Token count of input messages - **usage.completion_tokens** (integer) - Token count of generated response - **usage.total_tokens** (integer) - Sum of prompt and completion tokens **Streaming Response Schema:** Server-sent events with data in `data:` field. Each line is a JSON object with this schema: - **id** (string) - Completion ID, same for all chunks - **object** (string) - Always `chat.completion.chunk` - **created** (integer) - Unix timestamp - **model** (string) - Model identifier - **choices** (array) - Array with one choice object - **choices[0].index** (integer) - Always `0` - **choices[0].delta** (object) - Delta object with `role` (first chunk) or `content` (subsequent chunks) - **choices[0].finish_reason** (string) - Only in final chunk, value `stop` - **usage** (object) - Only in final chunk, contains token counts **Streaming Events Sequence:** 1. First event: `delta.role = "assistant"` (indicates message start) 2. Content events: `delta.content = ""` (text deltas) 3. Final event: `finish_reason = "stop"` and `usage` object present 4. Stream termination: `data: [DONE]` ### Response Headers - `x-ratelimit-limit-requests`: Maximum requests per minute - `x-ratelimit-remaining-requests`: Requests remaining this minute - `x-ratelimit-reset-requests`: Duration until limit reset - `x-ratelimit-limit-tokens`: Maximum tokens per minute - `x-ratelimit-remaining-tokens`: Tokens remaining this minute - `x-ratelimit-reset-tokens`: Duration until token limit reset ### Request Example ```json { "messages": [ {"role": "user", "content": "Hello!"} ], "model": "gpt-3.5-turbo", "stream": false } ``` ### Response Example (Non-Streaming) ```json { "id": "chatcmpl-1234567890", "object": "chat.completion", "created": 1609459200, "model": "gpt-3.5-turbo", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "Lorem ipsum dolor sit amet consectetur adipiscing elit" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 12, "completion_tokens": 18, "total_tokens": 30 } } ``` ### Streaming Event Example Sequence ``` data: {"id":"chatcmpl-1234567890","object":"chat.completion.chunk","created":1609459200,"model":"gpt-3.5-turbo","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]} data: {"id":"chatcmpl-1234567890","object":"chat.completion.chunk","created":1609459200,"model":"gpt-3.5-turbo","choices":[{"index":0,"delta":{"content":"Lorem "},"finish_reason":null}]} data: {"id":"chatcmpl-1234567890","object":"chat.completion.chunk","created":1609459200,"model":"gpt-3.5-turbo","choices":[{"index":0,"delta":{},"finish_reason":"stop","usage":{"prompt_tokens":12,"completion_tokens":18,"total_tokens":30}}]} data: [DONE] ``` ``` -------------------------------- ### Test Timeouts with Roy CLI Source: https://github.com/masci/roy/blob/main/_autodocs/README.md Set a global timeout for all requests using the --timeout flag to test client-side timeout handling. ```sh roy --timeout 1000 # All requests timeout after 1 second ``` -------------------------------- ### Simulate Errors with Roy CLI Source: https://github.com/masci/roy/blob/main/_autodocs/README.md Use the --error-code and --error-rate flags to simulate specific HTTP errors for a percentage of requests. ```sh roy --error-code 429 --error-rate 30 # 30% of requests return 429 ``` -------------------------------- ### Simulate Fixed Slow Response Source: https://github.com/masci/roy/blob/main/README.md Configure Roy to introduce a fixed delay before responding to each request. This simulates network latency or server processing time. ```sh roy --slowdown 100 ``` -------------------------------- ### Differences from Chat Completions Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/responses.md Highlights key differences between the Responses API and the Chat Completions API, including default models, input fields, and streaming event structures. ```APIDOC ## Differences from Chat Completions ### Description Compares the Responses API with the Chat Completions API across several aspects. | Aspect | Chat Completions | Responses | |--------|------------------|-----------| | Default model | `gpt-3.5-turbo` | `gpt-5-2025-08-07` | | Input field | `messages` (array) | `input` (string) | | Instructions | Included in messages | Separate field, passed through | | Streaming events | Role → content chunks → finish | Created → reasoning → message → text deltas → completed | | Reasoning tokens | 0 (not included) | 128 (mocked in streaming) | | Message structure | Single choice | Multiple output items (reasoning + message) | | Content format | Simple text string | Structured with type and annotations | ``` -------------------------------- ### Roy Source Code Structure Source: https://github.com/masci/roy/blob/main/_autodocs/README.md Overview of the directory structure for the Roy project, indicating the purpose of key Rust files. ```text src/ ├── main.rs # Entry point (cli argument parsing) ├── lib.rs # run() function, Args, server setup ├── server_state.rs # ServerState: rate limiting and state tracking ├── chat_completions.rs # Chat completions endpoint handler └── responses.rs # Responses endpoint handler ``` -------------------------------- ### generate_lorem_content Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/server-state.md Generates Lorem Ipsum text of a specified length. It truncates the output to the exact length requested and uses the 'lipsum' crate for generation. ```APIDOC ## generate_lorem_content ### Description Generates Lorem Ipsum text of specified length. Returns an empty string if length is 0. The text is generated by word and then truncated to the exact specified length. ### Method `generate_lorem_content` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **length** (`usize`) - Required - Target length in characters ### Returns `String` - Generated Lorem Ipsum text, truncated to specified length ### Example ```rust let state = /* initialized state */; let content = state.generate_lorem_content(100); assert_eq!(content.len(), 100); println!("{}", content); // Output: "Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua ut enim ad..." ``` ``` -------------------------------- ### Define InputTokensDetails Structure Source: https://github.com/masci/roy/blob/main/_autodocs/types.md Defines the structure for detailed input token usage, specifically tracking cached tokens. ```rust pub struct InputTokensDetails { pub cached_tokens: u32, } ``` -------------------------------- ### Simulate Request Timeouts Source: https://github.com/masci/roy/blob/main/_autodocs/configuration.md Sets a timeout of 500 milliseconds for all requests. Requests exceeding this duration will be terminated. ```sh roy --timeout 500 ``` -------------------------------- ### Usage Structure Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/chat-completions.md Provides token usage information for a chat completion request. ```APIDOC ## Usage Structure ### Description Provides token usage information for a chat completion request, detailing prompt tokens, completion tokens, and total tokens. ### Fields - **prompt_tokens** (u32) - Tokens in serialized messages - **completion_tokens** (u32) - Tokens in generated response - **total_tokens** (u32) - Sum of prompt and completion tokens ``` -------------------------------- ### POST /v1/responses Source: https://github.com/masci/roy/blob/main/_autodocs/endpoints.md A flexible endpoint for text generation, compatible with the OpenAI API format. It supports optional streaming of responses via server-sent events. ```APIDOC ## POST /v1/responses **Handler:** `responses()` in `src/responses.rs` ### Description A flexible endpoint for text generation, compatible with the OpenAI API format. It supports optional streaming of responses via server-sent events. ### Method POST ### Endpoint /v1/responses ### Parameters #### Request Body - **model** (string) - Optional - Model identifier. Defaults to `gpt-5-2025-08-07`. - **input** (string) - Optional - Input text/prompt. - **instructions** (string) - Optional - System instructions. - **stream** (boolean) - Optional - If `true`, response is streamed via server-sent events. If `false` or omitted, single JSON response. Additional fields are accepted but ignored. ### Response **Content-Type:** `application/json` (non-streaming) or `text/event-stream` (streaming) #### Response Schema - Non-Streaming (stream: false) - **id** (string) - Unique response ID, prefixed with `resp_`. - **object** (string) - Always `response`. - **created_at** (number) - Unix timestamp with fractional seconds. - **model** (string) - Model used. - **status** (string) - Always `completed`. - **output** (array) - Array of output items (message objects). - **output[0]._type** (string) - Always `message`. - **output[0].id** (string) - Message ID, prefixed with `msg_`. - **output[0].role** (string) - Always `assistant`. - **output[0].status** (string) - Always `completed`. - **output[0].content** (array) - Array of content parts. - **output[0].content[0]._type** (string) - Always `output_text`. - **output[0].content[0].text** (string) - Generated response content. - **usage** (object) - Token usage statistics. - **usage.input_tokens** (integer) - Input token count. - **usage.output_tokens** (integer) - Output token count. - **usage.total_tokens** (integer) - Sum of tokens. - **temperature** (number) - Always `1.0`. - **top_p** (number) - Always `1.0`. - **service_tier** (string) - Always `auto`. ### Response Example - Non-Streaming ```json { "id": "resp_1234567890", "object": "response", "created_at": 1609459200.123, "model": "gpt-5-2025-08-07", "status": "completed", "output": [ { "id": "msg_1234567890", "type": "message", "role": "assistant", "status": "completed", "content": [ { "type": "output_text", "text": "Lorem ipsum dolor sit amet consectetur adipiscing elit" } ] } ], "usage": { "input_tokens": 10, "output_tokens": 20, "total_tokens": 30, "input_tokens_details": { "cached_tokens": 0 }, "output_tokens_details": { "reasoning_tokens": 0 } } } ``` ### Status Codes - `200 OK`: Request succeeded. - `204 No Content`: Successful request but response length is configured to 0. - `429 Too Many Requests`: Rate limit exceeded. - `4xx`: Simulated error. - `5xx`: Simulated server error. ``` -------------------------------- ### Usage Struct Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/chat-completions.md Represents token usage statistics for a chat completion request, detailing prompt, completion, and total tokens. ```rust #[derive(Serialize, Debug)] pub struct Usage { pub prompt_tokens: u32, pub completion_tokens: u32, pub total_tokens: u32, } ``` -------------------------------- ### Generate Lorem Ipsum Content Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/server-state.md Generates Lorem Ipsum text of a specified length. Truncates the output to the exact character count. Uses the 'lipsum' crate. ```rust let state = /* initialized state */; let content = state.generate_lorem_content(100); assert_eq!(content.len(), 100); println!("{}", content); // Output: "Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua ut enim ad..." ``` -------------------------------- ### ResponseUsage Structure Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/responses.md Details the token usage for an API request, including input, output, and total token counts. ```APIDOC ## ResponseUsage Structure ### Description Provides a breakdown of token usage for a given API request, encompassing input tokens, output tokens, and the total count. ### Fields - `input_tokens` (u32) - The total number of tokens in the input text. - `input_tokens_details` (InputTokensDetails) - Details about input token calculation, e.g., `{cached_tokens: 0}`. - `output_tokens` (u32) - The total number of tokens in the output. For streaming, this includes mock reasoning tokens. - `output_tokens_details` (OutputTokensDetails) - Details about output token calculation, e.g., `{reasoning_tokens: N}`. - `total_tokens` (u32) - The sum of all input and output tokens. ``` -------------------------------- ### Define ResponseUsage Structure Source: https://github.com/masci/roy/blob/main/_autodocs/types.md Defines the structure for token usage statistics in API responses. It tracks input, output, and total tokens, along with detailed breakdowns. ```rust pub struct ResponseUsage { pub input_tokens: u32, pub input_tokens_details: InputTokensDetails, pub output_tokens: u32, pub output_tokens_details: OutputTokensDetails, pub total_tokens: u32, } ``` -------------------------------- ### Set Request Rate Limit Source: https://github.com/masci/roy/blob/main/README.md Configure Roy to simulate request rate limiting by setting specific headers in the response. This helps test client behavior when API rate limits are enforced. ```sh roy --rpm 100 ``` -------------------------------- ### Set Tokens Per Minute Limit Source: https://github.com/masci/roy/blob/main/README.md Configure the tokens per minute limit for Roy. This command sets the maximum rate at which tokens can be processed. ```sh roy --tpm 45000 ``` -------------------------------- ### Simulate Fixed Slow Responses Source: https://github.com/masci/roy/blob/main/_autodocs/configuration.md Introduces a fixed delay of 200 milliseconds before sending a response for every request. ```sh roy --slowdown 200 ``` -------------------------------- ### Configure Fixed Response Length Source: https://github.com/masci/roy/blob/main/_autodocs/configuration.md Sets the response content length to exactly 500 characters for all responses. ```sh roy --response-length 500 ``` -------------------------------- ### ResponseReasoningItem Struct Source: https://github.com/masci/roy/blob/main/_autodocs/api-reference/responses.md Represents a reasoning block within the response output, containing details about the reasoning process. ```APIDOC ## ResponseReasoningItem Struct ### Description This struct defines the structure for a reasoning item within the `output` array. It includes fields for an ID, type, summary, and optional content. ### Fields | Field | Type | Example | |---|---|---| | `id` | `String` | `rs_abcdef1234567890` | | `_type` | `String` | Always `"reasoning"` | | `summary` | `Vec` | Empty array | | `content` | `Option` | Not set by Roy | | `encrypted_content` | `Option` | Not set by Roy | | `status` | `Option` | Not set by Roy | ### Source `src/responses.rs` ```rust #[derive(Serialize, Clone, Debug)] struct ResponseReasoningItem { id: String, #[serde(rename = "type")] _type: String, summary: Vec, content: Option, encrypted_content: Option, status: Option, } ``` ``` -------------------------------- ### ChoiceDelta Struct Source: https://github.com/masci/roy/blob/main/_autodocs/types.md Defines the incremental changes for a streaming chunk. Contains optional role and content fields. ```rust pub struct ChoiceDelta { pub role: Option, pub content: Option, } ``` -------------------------------- ### Simulate HTTP Errors Source: https://github.com/masci/roy/blob/main/_autodocs/configuration.md Configures the server to simulate HTTP 429 (Rate Limit) errors on 30% of incoming requests. Both --error-code and --error-rate must be specified together. ```sh roy --error-code 429 --error-rate 30 ```