### Basic Text Completion Example Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/completions.md Demonstrates a typical workflow for getting a text completion using the `create/2` function. Ensure the client is initialized with your API key. ```elixir client = OpenaiEx.new("sk-...") request = OpenaiEx.Completion.new( model: "text-davinci-003", prompt: "The answer to everything is" ) {:ok, response} = OpenaiEx.Completion.create(client, request) completion = response["choices"] |> List.first() |> Map.get("text") IO.puts(completion) ``` -------------------------------- ### Full Assistant Workflow Example Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/assistants.md This comprehensive example shows the complete lifecycle of using an assistant: creating it, setting up a thread, adding messages, running the assistant, and retrieving the response. ```elixir # 1. Create assistant request = OpenaiEx.Beta.Assistants.new( model: "gpt-4o", name: "Helpful Assistant", instructions: "Be concise and helpful" ) {:ok, assistant} = OpenaiEx.Beta.Assistants.create(client, request) assistant_id = assistant["id"] # 2. Create thread for conversation thread_request = OpenaiEx.Beta.Threads.new() {:ok, thread} = OpenaiEx.Beta.Threads.create(client, thread_request) thread_id = thread["id"] # 3. Add messages to thread message_request = %{ role: "user", content: "Hello!" } {:ok, message} = OpenaiEx.Beta.ThreadsMessages.create(client, thread_id, message_request) # 4. Run the assistant run_request = %{assistant_id: assistant_id} {:ok, run} = OpenaiEx.Beta.ThreadsRuns.create(client, thread_id, run_request) run_id = run["id"] # 5. Poll until complete run_final = wait_for_completion(client, thread_id, run_id) # 6. Get response messages {:ok, messages} = OpenaiEx.Beta.ThreadsMessages.list(client, thread_id) ``` -------------------------------- ### With Instructions Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/responses.md Shows how to provide specific instructions to guide the model's output and limit token usage. ```APIDOC ## With Instructions ### Description This example demonstrates how to include specific instructions to guide the model's response and set a limit on the maximum output tokens. ### Method POST ### Endpoint /v1/responses ### Parameters #### Request Body - **model** (string) - Required - The model to use (e.g., "gpt-4o"). - **input** (string) - Required - The user's input. - **instructions** (string) - Optional - Specific instructions for the model. - **max_output_tokens** (integer) - Optional - The maximum number of tokens to generate for the output. ### Request Example ```elixir request = OpenaiEx.Responses.new( model: "gpt-4o", input: "Calculate 2+2", instructions: "Provide only the numeric answer", max_output_tokens: 10 ) {:ok, response} = OpenaiEx.Responses.create(client, request) ``` ### Response #### Success Response (200) (See Response Structure in Simple Question-Answer example) #### Response Example ```json { "id": "resp-...", "object": "response", "created": 1234567891, "model": "gpt-4o", "output": "4", "usage": { "input_tokens": 12, "output_tokens": 1, "total_tokens": 13 } } ``` ``` -------------------------------- ### Common Patterns - With Tool Use Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/chat-completions.md An example illustrating how to use tools with the chat completions API for function calling. ```APIDOC ### With Tool Use ```elixir request = OpenaiEx.Chat.Completions.new( model: "gpt-4o", messages: [OpenaiEx.ChatMessage.user("What's the weather?")], tools: [ %{ type: "function", function: %{ name: "get_weather", description: "Get weather for a location", parameters: %{ type: "object", properties: %{ location: %{type: "string"} }, required: ["location"] } } } ], tool_choice: "auto" ) {:ok, response} = OpenaiEx.Chat.Completions.create(client, request) ``` ``` -------------------------------- ### Common Pattern: Create Assistant with Tools Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/assistants.md An example demonstrating how to create an assistant configured with multiple tools, including code interpreter and a custom function. ```APIDOC ## Create Assistant with Tools ### Description This example illustrates the creation of an assistant that is equipped with both the `code_interpreter` tool and a custom `function` tool named `query_database`. ### Example ```elixir # Assuming 'client' is an authenticated OpenaiEx client request = OpenaiEx.Beta.Assistants.new( model: "gpt-4o", name: "Data Analyst", instructions: "Analyze data and create visualizations", tools: [ %{type: "code_interpreter"}, %{ type: "function", function: %{ name: "query_database", description: "Query the company database", parameters: %{ type: "object", properties: %{ query: %{type: "string", description: "SQL query"} }, required: ["query"] } } } ] ) {:ok, assistant} = OpenaiEx.Beta.Assistants.create(client, request) ``` ``` -------------------------------- ### Code Generation Example Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/completions.md Shows how to use the Completions API for code generation by providing a code-related prompt and setting parameters like `max_tokens` and `temperature`. ```elixir request = OpenaiEx.Completion.new( model: "text-davinci-003", prompt: "# Generate a function to calculate factorial\ndef factorial(n):", max_tokens: 100, temperature: 0.2 ) {:ok, response} = OpenaiEx.Completion.create(client, request) ``` -------------------------------- ### Building Complex Messages Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/types.md Example demonstrating how to construct complex messages with system and user prompts, including text and image content. ```elixir messages = [ OpenaiEx.ChatMessage.system("You are helpful"), OpenaiEx.ChatMessage.user([ OpenaiEx.MsgContent.text("What's in this?"), OpenaiEx.MsgContent.image_url("https://...") ]) ] ``` -------------------------------- ### Create Assistant with Code Interpreter and Function Tools Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/assistants.md This example demonstrates creating an assistant with both the `code_interpreter` and a custom `function` tool. The function tool requires a name, description, and parameter schema. ```elixir request = OpenaiEx.Beta.Assistants.new( model: "gpt-4o", name: "Data Analyst", instructions: "Analyze data and create visualizations", tools: [ %{type: "code_interpreter"}, %{ type: "function", function: %{ name: "query_database", description: "Query the company database", parameters: %{ type: "object", properties: %{ query: %{type: "string", description: "SQL query"} }, required: ["query"] } } } ] ) {:ok, assistant} = OpenaiEx.Beta.Assistants.create(client, request) ``` -------------------------------- ### Fine-Tuning JSONL Format Example Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/files.md Illustrates the required JSONL format for fine-tuning training data, showing message-based conversation structure. ```json {"messages": [{"role": "system", "content": "..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]} {"messages": [...]} ``` -------------------------------- ### Upload File using API Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/client.md Example of using the `new_file/2` function to create a file parameter and then uploading it via the Files API for fine-tuning. ```elixir client = OpenaiEx.new("sk-...") file = OpenaiEx.new_file(path: "./training_data.jsonl") OpenaiEx.Files.create(client, %{ file: file, purpose: "fine-tune" }) ``` -------------------------------- ### Response Structure Example Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/responses.md Provides an example of the expected JSON structure for a successful response from the Responses API, including ID, model, output, and usage tokens. ```elixir %{ "id" => "resp-…", "object" => "response", "created" => 1234567890, "model" => "gpt-4o", "output" => "Response text here", "usage" => %{ "input_tokens" => 10, "output_tokens" => 50, "total_tokens" => 60 } } ``` -------------------------------- ### Responses API with Specific Instructions Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/responses.md Shows how to provide specific instructions to guide the model's output and set a maximum token limit for the response. ```elixir request = OpenaiEx.Responses.new( model: "gpt-4o", input: "Calculate 2+2", instructions: "Provide only the numeric answer", max_output_tokens: 10 ) {:ok, response} = OpenaiEx.Responses.create(client, request) ``` -------------------------------- ### Standard Timestamp Example Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/types.md Illustrates the format for standard timestamps, which are Unix timestamps in seconds. ```elixir created_at: 1234567890 # Time.from_unix!(1234567890) ``` -------------------------------- ### Common Patterns - Simple Question-Answer Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/chat-completions.md An example demonstrating a simple question-and-answer interaction with the chat completions API. ```APIDOC ## Common Patterns ### Simple Question-Answer ```elixir client = OpenaiEx.new("sk-...") request = OpenaiEx.Chat.Completions.new( model: "gpt-4o", messages: [ OpenaiEx.ChatMessage.system("You are a helpful assistant."), OpenaiEx.ChatMessage.user("What is the capital of France?") ] ) {:ok, response} = OpenaiEx.Chat.Completions.create(client, request) answer = response["choices"] |> List.first() |> Map.get("message") |> Map.get("content") IO.puts(answer) ``` ``` -------------------------------- ### Initialize OpenaiEx Client Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/INDEX.md All API calls require an OpenaiEx client struct initialized with an API token. This is the basic setup for using the library. ```elixir client = OpenaiEx.new("sk-...") ``` -------------------------------- ### Create and queue a fine-tuning job Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/fine-tuning-jobs.md Use `create/2` to submit a fine-tuning job request. This function requires an initialized `OpenaiEx` client and the fine-tuning job request map. It returns `{:ok, job_map}` on success or `{:error, OpenaiEx.Error.t}` on failure. The example demonstrates uploading training data first, then creating the job. ```elixir client = OpenaiEx.new("sk-...") # First, upload training data train_data = read_jsonl_file("training.jsonl") file_request = OpenaiEx.Files.new_upload( file: OpenaiEx.new_file(name: "training.jsonl", content: train_data), purpose: "fine-tune" ) {:ok, file} = OpenaiEx.Files.create(client, file_request) # Create fine-tuning job job_request = OpenaiEx.FineTuning.Jobs.new( model: "gpt-3.5-turbo", training_file: file["id"] ) {:ok, job} = OpenaiEx.FineTuning.Jobs.create(client, job_request) IO.puts("Job ID: #{job["id"]}") ``` -------------------------------- ### Nested Maps and Lists Example Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/types.md Illustrates how to structure nested maps and lists, such as for tool resources with code interpreter and file search configurations. ```elixir %{ tool_resources: %{ code_interpreter: %{ file_ids: ["file-1", "file-2"] }, file_search: %{ vector_store_ids: ["vs-1"] } } } ``` -------------------------------- ### Azure OpenAI Client Setup Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/client.md Configure the OpenAI client for Azure OpenAI services. This includes setting the API key, base URL, and additional headers. ```elixir client = OpenaiEx.new(System.get_env("AZURE_OPENAI_API_KEY")) |> OpenaiEx.with_base_url("https://myresource.openai.azure.com/openai/deployments/mydeployment") |> OpenaiEx.with_additional_headers([{"api-key", System.get_env("AZURE_OPENAI_API_KEY")}]) ``` -------------------------------- ### Production OpenAI Client Setup Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/client.md Configure the OpenAI client for production use with a receive timeout and stream timeout. Ensure the API key is set as an environment variable. ```elixir client = OpenaiEx.new(System.get_env("OPENAI_API_KEY")) |> OpenaiEx.with_receive_timeout(30_000) |> OpenaiEx.with_stream_timeout(60_000) ``` -------------------------------- ### List fine-tuning jobs Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/fine-tuning-jobs.md Use `list/1` or `list/2` to retrieve a list of fine-tuning jobs. You can optionally provide parameters like `after` for pagination and `limit` to control the number of results per page. The example iterates through the returned jobs and prints their IDs and statuses. ```elixir {:ok, response} = OpenaiEx.FineTuning.Jobs.list(client, %{limit: 10}) Enum.each(response["data"], fn job -> IO.puts("#{job["id"]} - #{job["status"]}") end) ``` -------------------------------- ### Batch Request Format Example Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/batches.md Illustrates the JSONL format for a single request within a batch job, specifying method, URL, and body for chat completions. ```json { "custom_id": "unique-id-1", "method": "POST", "url": "/v1/chat/completions", "body": { "model": "gpt-4o", "messages": [ {"role": "user", "content": "Hello"} ] } } ``` -------------------------------- ### Tool Use Flow Example Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/chat-message.md Illustrates the flow for enabling tool use in chat completions. It involves an initial request with defined tools, processing the assistant's tool call, and adding it back to the conversation for subsequent steps. ```elixir # 1. Initial request with tools messages = [ OpenaiEx.ChatMessage.user("What's the weather in Paris?") ] request = OpenaiEx.Chat.Completions.new( model: "gpt-4o", messages: messages, tools: [%{type: "function", function: %{name: "get_weather", ...}}] ) {:ok, response} = OpenaiEx.Chat.Completions.create(client, request) assistant_msg = response["choices"] |> List.first() |> Map.get("message") # 2. Add assistant's tool call to conversation messages = messages ++ [assistant_msg] ``` -------------------------------- ### Multi-turn Conversation Example Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/chat-message.md Demonstrates how to construct a list of messages for a multi-turn conversation. This pattern is used to maintain context across multiple user and assistant interactions. ```elixir messages = [ OpenaiEx.ChatMessage.system("You are a friendly assistant."), OpenaiEx.ChatMessage.user("What's the weather?"), OpenaiEx.ChatMessage.assistant("I can help with weather information."), OpenaiEx.ChatMessage.user("How about in Seattle?") ] request = OpenaiEx.Chat.Completions.new( model: "gpt-4o", messages: messages ) OpenaiEx.Chat.Completions.create(client, request) ``` -------------------------------- ### Use Fine-Tuned Model Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/fine-tuning-jobs.md This example demonstrates how to retrieve a fine-tuned model after training completes and then use it for chat completions. It shows the process of integrating a custom model into the chat API. ```elixir # After fine-tuning completes: {:ok, job} = OpenaiEx.FineTuning.Jobs.retrieve(client, fine_tuning_job_id: "ftjob-abc123") fine_tuned_model = job["fine_tuned_model"] # Use in chat completion request = OpenaiEx.Chat.Completions.new( model: fine_tuned_model, messages: [OpenaiEx.ChatMessage.user("Hello!")] ) {:ok, response} = OpenaiEx.Chat.Completions.create(client, request) ``` -------------------------------- ### Elixir Container Structure Example Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/containers.md Illustrates the expected structure of a container object returned by the API, including its ID, name, associated file IDs, and creation timestamp. ```elixir %{ "id" => "cont-...", "object" => "organization.files.containers.container", "created_at" => 1234567890, "name" => "Container Name", "file_ids" => ["file-abc123", "file-xyz789"], "expires_at" => 1234567890 # or null if no expiration } ``` -------------------------------- ### Error Handling for Job Creation Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/fine-tuning-jobs.md This example demonstrates how to handle potential errors when creating a fine-tuning job. It includes specific error kinds like `:bad_request` for invalid data and `:rate_limit` for API usage limits. ```elixir case OpenaiEx.FineTuning.Jobs.create(client, request) do {:ok, job} -> IO.puts("Job created: #{job["id"]}") {:error, error} -> case error.kind do :bad_request -> IO.puts("Invalid training data format") :rate_limit -> IO.puts("Rate limited, try again later") _ -> IO.inspect(error) end end ``` -------------------------------- ### Example Moderation API Response Structure Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/moderations.md This is an example of the JSON response structure returned by the Moderations API, detailing flagged status, categories, and category scores. ```json %{ "id" => "modr-...", "model" => "text-moderation-latest", "results" => [ %{ "flagged" => true, "categories" => %{ "hate" => false, "hate/threatening" => false, "harassment" => false, "harassment/threatening" => true, "self-harm" => false, "self-harm/intent" => false, "self-harm/instructions" => false, "sexual" => false, "sexual/minors" => false, "violence" => true, "violence/graphic" => false, "spam" => false, "illegal" => false }, "category_scores" => %{ "hate" => 0.001, "hate/threatening" => 0.95, "harassment" => 0.2, "harassment/threatening" => 0.88, "self-harm" => 0.0, "self-harm/intent" => 0.0, "self-harm/instructions" => 0.0, "sexual" => 0.0, "sexual/minors" => 0.0, "violence" => 0.92, "violence/graphic" => 0.8, "spam" => 0.0, "illegal" => 0.15 } } ] } ``` -------------------------------- ### Create a completion (streaming, raises on error) Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/completions.md Use `create!/3` with `stream: true` for streaming completions where errors should raise an exception. ```elixir def create!(openai :: %OpenaiEx{}, completion :: map, stream: true) :: stream_map ``` -------------------------------- ### Method Chaining for Client Configuration Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/client.md Demonstrates chaining multiple configuration functions to build a fully customized OpenAI client. All configuration functions return an updated client. ```elixir client = OpenaiEx.new("sk-...") |> OpenaiEx.with_base_url("https://api.example.com/v1") |> OpenaiEx.with_receive_timeout(30_000) |> OpenaiEx.with_additional_headers([{"X-Custom", "value"}]) |> OpenaiEx.with_stream_timeout(:infinity) ``` -------------------------------- ### Chat Completions API Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/SUMMARY.md Documentation for the Chat Completions API, including function signatures, parameters, return values, and examples. ```APIDOC ## Chat Completions API ### Description Provides access to the Chat Completions API for generating conversational responses. ### Method [HTTP method or SDK function signature] ### Endpoint [Full endpoint path or SDK module/function] ### Parameters [Details on parameters, types, and descriptions] ### Request Example [Example of a request payload or function call] ### Response #### Success Response [Details on the success response structure and fields] #### Response Example [Example of a successful response] ``` -------------------------------- ### Create Assistant Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/assistants.md Creates a new assistant with the specified parameters. The `request` map should be built using `OpenaiEx.Beta.Assistants.new/1` or `OpenaiEx.Beta.Assistants.new/2`. ```APIDOC ## create/2 Creates a new assistant. ### Description This function creates a new assistant using the provided OpenAI client and assistant configuration. ### Method ```elixir def create(openai :: %OpenaiEx{}, assistant :: map) :: {:ok, map} | {:error, OpenaiEx.Error.t} ``` ### Parameters - `openai`: An authenticated `OpenaiEx` client. - `assistant`: A map representing the assistant configuration, typically created using `OpenaiEx.Beta.Assistants.new/1` or `OpenaiEx.Beta.Assistants.new/2`. ### Returns - `{:ok, assistant_map}`: On success, returns a map containing the created assistant's details, including its ID and creation timestamp. - `{:error, OpenaiEx.Error.t}`: On failure, returns an error tuple with an `OpenaiEx.Error` struct. ### Example ```elixir client = OpenaiEx.new("sk-...") # Replace with your actual API key request = OpenaiEx.Beta.Assistants.new( model: "gpt-4o", name: "Code Reviewer", instructions: "Review Python code and provide feedback." ) {:ok, assistant} = OpenaiEx.Beta.Assistants.create(client, request) IO.puts("Assistant ID: #{assistant["id"]}") ``` ``` -------------------------------- ### Get Fastest Model ID Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/models.md Retrieves the ID of the fastest available model by filtering for models containing 'mini' in their ID. ```elixir defmodule ModelSelector do def get_fastest_model(client) do {:ok, response} = OpenaiEx.Models.list(client) response["data"] |> Enum.filter(fn m -> String.contains?(m["id"], "mini") end) |> List.first() |> Map.get("id") end def get_most_capable_model(client) do {:ok, response} = OpenaiEx.Models.list(client) # Assuming newer/larger models are listed later response["data"] |> Enum.reverse() |> Enum.find(fn m -> String.starts_with?(m["id"], "gpt-4") end) |> Map.get("id") end end ``` -------------------------------- ### Create an Assistant Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/assistants.md Use `create/2` to send a new assistant request to the API. This function returns `{:ok, assistant_map}` on success or `{:error, OpenaiEx.Error.t}` on failure. Ensure you have a valid OpenAI client initialized. ```elixir client = OpenaiEx.new("sk-...") request = OpenaiEx.Beta.Assistants.new( model: "gpt-4o", name: "Code Reviewer", instructions: "Review Python code and provide feedback." ) {:ok, assistant} = OpenaiEx.Beta.Assistants.create(client, request) IO.puts("Assistant ID: #{assistant["id"]}") ``` -------------------------------- ### With Tool Use Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/responses.md Demonstrates how to integrate tool use, allowing the model to call external functions. ```APIDOC ## With Tool Use ### Description This example shows how to define and use tools (functions) that the model can call to perform specific actions, like fetching weather data. ### Method POST ### Endpoint /v1/responses ### Parameters #### Request Body - **model** (string) - Required - The model to use (e.g., "gpt-4o"). - **input** (string) - Required - The user's input. - **tools** (array) - Optional - A list of tool definitions the model can use. - Each tool object should have a `type` (e.g., "function"), and a `function` definition including `name`, `description`, and `parameters`. ### Request Example ```elixir request = OpenaiEx.Responses.new( model: "gpt-4o", input: "What's the weather?", tools: [ %{ type: "function", function: %{ name: "get_weather", description: "Get weather for a location", parameters: %{ type: "object", properties: %{ location: %{type: "string"} }, required: ["location"] } } } ] ) {:ok, response} = OpenaiEx.Responses.create(client, request) ``` ### Response #### Success Response (200) - The response may contain a `tool_calls` field if the model decides to use a tool. Otherwise, it will contain an `output` field. #### Response Example (Tool Call) ```json { "id": "resp-...", "object": "response", "created": 1234567892, "model": "gpt-4o", "tool_calls": [ { "id": "call_...", "type": "function", "function": { "name": "get_weather", "arguments": "{\"location\": \"Paris\"}" } } ], "usage": { "input_tokens": 100, "output_tokens": 20, "total_tokens": 120 } } ``` ``` -------------------------------- ### Error Handling Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/completions.md Provides an example of how to handle potential errors that may occur during the completion request, such as authentication or rate limiting issues. ```APIDOC ## Error Handling This example demonstrates how to handle various error types returned by the `OpenaiEx.Completion.create/2` function. ### Method Pattern matching on the `{:ok, response}` or `{:error, error}` tuple returned by `OpenaiEx.Completion.create/2`. ### Error Handling Example ```elixir case OpenaiEx.Completion.create(client, request) do {:ok, response} -> # Process response {:error, error} -> case error.kind do :authentication -> IO.puts("Invalid API key") :rate_limit -> IO.puts("Rate limited, retry later") :invalid_request_error -> IO.puts("Invalid request: #{error.message}") _ -> IO.inspect(error) end end ``` ### Error Kinds - **:authentication**: Invalid API key. - **:rate_limit**: Request exceeds rate limits. - **:invalid_request_error**: The request was malformed or invalid. ``` -------------------------------- ### Elixir Container Cleanup by Prefix Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/containers.md Cleans up containers by deleting those whose names start with a specified prefix. Requires an initialized client. ```elixir defmodule ContainerCleanup do def cleanup_by_prefix(client, prefix) do {:ok, response} = OpenaiEx.Containers.list(client) response["data"] |> Enum.filter(fn c -> String.starts_with?(c["name"], prefix) end) |> Enum.each(fn c -> OpenaiEx.Containers.delete(client, c["id"]) end) end def list_containers_summary(client) do {:ok, response} = OpenaiEx.Containers.list(client) %{ total: length(response["data"]), containers: Enum.map(response["data"], fn c -> %{ id: c["id"], name: c["name"], file_count: length(c["file_ids"] || []), created_at: c["created_at"] } end) } end end ``` -------------------------------- ### Client Initialization Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/client.md Creates a new OpenaiEx client with authentication credentials. You can initialize the client with just a token, or with a token and an organization ID, or with a token, organization ID, and project ID. ```APIDOC ## Client Initialization ### Description Creates a new OpenaiEx client with authentication credentials. ### Function Signature ```elixir def new(token :: String.t()) :: %OpenaiEx{} def new(token :: String.t(), organization :: String.t() | nil) :: %OpenaiEx{} def new(token :: String.t(), organization :: String.t() | nil, project :: String.t() | nil) :: %OpenaiEx{} ``` ### Parameters #### Path Parameters * **token** (string) - Required - OpenAI API key (required) * **organization** (string) - Optional - Organization ID header for requests * **project** (string) - Optional - Project ID header for resource isolation ### Returns `%OpenaiEx{}` client struct with initialized authentication headers ### Example ```elixir # Basic client client = OpenaiEx.new("sk-proj-abcd1234...") # With organization client = OpenaiEx.new("sk-...", "org-12345") # With organization and project client = OpenaiEx.new("sk-...", "org-12345", "proj-xyz789") ``` ``` -------------------------------- ### Get File Statistics Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/files.md Calculates and returns statistics about uploaded files, including total count, total bytes, and files grouped by purpose. ```elixir def get_file_stats(client) do {:ok, response} = OpenaiEx.Files.list(client) files = response["data"] %{ total_files: length(files), total_bytes: Enum.reduce(files, 0, fn f, acc -> acc + f["bytes"] end), by_purpose: Enum.group_by(files, & &1["purpose"]) } end ``` -------------------------------- ### Detailed Transcription with Segments Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/audio-transcription.md Transcribe audio and retrieve detailed information including segments with start and end times. The response format is 'verbose_json'. ```elixir defmodule DetailedTranscription do def transcribe_with_segments(client, audio_path) do request = OpenaiEx.Audio.Transcription.new( file: OpenaiEx.new_file(path: audio_path), model: "whisper-1", response_format: "verbose_json", timestamp_granularities: ["segment"] ) case OpenaiEx.Audio.Transcription.create(client, request) do {:ok, response} -> segments = response["segments"] || [] segments |> Enum.map(fn seg -> %{ start: seg["start"], end: seg["end"], text: seg["text"] } end) {:error, error} -> {:error, error} end end def transcribe_with_words(client, audio_path) do request = OpenaiEx.Audio.Transcription.new( file: OpenaiEx.new_file(path: audio_path), model: "whisper-1", response_format: "verbose_json", timestamp_granularities: ["word"] ) {:ok, response} = OpenaiEx.Audio.Transcription.create(client, request) response["segments"] |> Enum.flat_map(fn seg -> seg["words"] || [] end) |> Enum.map(fn word -> %{ word: word["word"], start: word["start"], end: word["end"] } end) end end ``` -------------------------------- ### With Caching Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/responses.md Demonstrates how to use built-in caching to store and retrieve responses for identical queries. ```APIDOC ## With Caching ### Description This example shows how to leverage the built-in caching mechanism by providing a `prompt_cache_key` and `prompt_cache_retention` to store and reuse responses for identical inputs. ### Method POST ### Endpoint /v1/responses ### Parameters #### Request Body - **model** (string) - Required - The model to use (e.g., "gpt-4o"). - **input** (string) - Required - The query input. - **prompt_cache_key** (string) - Optional - A unique key to identify and cache the response. - **prompt_cache_retention** (string) - Optional - The duration for which the cache should be retained (e.g., "5m" for 5 minutes). ### Request Example ```elixir request = OpenaiEx.Responses.new( model: "gpt-4o", input: "Query with long context", prompt_cache_key: "my-cache-key", prompt_cache_retention: "5m" ) {:ok, response} = OpenaiEx.Responses.create(client, request) ``` ### Response #### Success Response (200) (See Response Structure in Simple Question-Answer example. If cached, the response will be served from cache.) #### Response Example ```json { "id": "resp-...", "object": "response", "created": 1234567894, "model": "gpt-4o", "output": "Cached response text.", "usage": { "input_tokens": 1000, "output_tokens": 50, "total_tokens": 1050 } } ``` ``` -------------------------------- ### Transcription with Prompt for Context Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/audio-transcription.md Enhances transcription accuracy by providing a prompt that guides the model with relevant context. This is useful for technical terms or specific jargon. ```elixir request = OpenaiEx.Audio.Transcription.new( file: OpenaiEx.new_file(path: "technical_discussion.wav"), model: "whisper-1", prompt: "The speakers are discussing machine learning, deep learning, transformers, and neural networks.", response_format: "json" ) {:ok, response} = OpenaiEx.Audio.Transcription.create(client, request) ``` -------------------------------- ### Image Content Error Handling Examples Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/message-content.md Demonstrates common errors when using image content, such as invalid file IDs, non-HTTPS URLs, and unsupported models. ```elixir # Invalid file ID OpenaiEx.MsgContent.image_file("invalid-id") # Error: File not found ``` ```elixir # Invalid URL OpenaiEx.MsgContent.image_url("not-https://...") # Error: Must use HTTPS URLs ``` ```elixir # Unsupported model request = OpenaiEx.Chat.Completions.new( model: "gpt-3.5-turbo", # Doesn't support vision messages: [ OpenaiEx.ChatMessage.user([ OpenaiEx.MsgContent.text("Text"), OpenaiEx.MsgContent.image_url("https://...") ]) ] ) # Error: Model doesn't support images ``` -------------------------------- ### Create Simple Text Assistant Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/assistants.md This snippet demonstrates creating a basic assistant focused on text-based tasks like improving writing. No special tools or resources are configured. ```elixir request = OpenaiEx.Beta.Assistants.new( model: "gpt-4o", name: "Writing Assistant", instructions: "Help improve writing and suggest edits" ) {:ok, assistant} = OpenaiEx.Beta.Assistants.create(client, request) ``` -------------------------------- ### Create Assistant with Knowledge Base Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/assistants.md Use this snippet to create an assistant that can access a knowledge base via file search. Ensure you have a vector store ID ready. ```elixir request = OpenaiEx.Beta.Assistants.new( model: "gpt-4o", name: "Documentation Assistant", instructions: "Answer questions about our API documentation", tools: [%{type: "file_search"}], tool_resources: % file_search: %{ vector_store_ids: ["vs-abc123"] } ) {:ok, assistant} = OpenaiEx.Beta.Assistants.create(client, request) ``` -------------------------------- ### Upload Training File for Fine-Tuning Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/files.md Uploads a local JSONL file for use in a fine-tuning job. Ensure the file is correctly formatted. ```elixir client = OpenaiEx.new("sk-...") # 1. Upload training file training_data = read_jsonl_file("training_data.jsonl") request = OpenaiEx.Files.new_upload( file: OpenaiEx.new_file(name: "training.jsonl", content: training_data), purpose: "fine-tune" ) {:ok, file_response} = OpenaiEx.Files.create(client, request) training_file_id = file_response["id"] # 2. Use in fine-tuning job job_request = OpenaiEx.FineTuning.Jobs.new( model: "gpt-3.5-turbo", training_file: training_file_id ) {:ok, job} = OpenaiEx.FineTuning.Jobs.create(client, job_request) ``` -------------------------------- ### Completions API Response Structure Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/completions.md Example of the JSON structure returned by the Completions API. This includes details like the completion text, finish reason, and token usage. ```elixir %{ "id" => "cmpl-...", ``` ```elixir "object" => "text_completion", ``` ```elixir "created" => 1234567890, ``` ```elixir "model" => "text-davinci-003", ``` ```elixir "choices" => [ %{ "text" => " completion text", "index" => 0, "finish_reason" => "stop", "logprobs" => nil } ], ``` ```elixir "usage" => %{ "prompt_tokens" => 5, "completion_tokens" => 10, "total_tokens" => 15 } } ``` -------------------------------- ### Create Batch from Chat Completions Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/batches.md Prepares a JSONL file from a list of chat completion requests and uploads it to create a batch job. ```elixir defmodule BatchHelper do def prepare_batch_file(requests) do jsonl_content = requests |> Enum.map(fn req -> %{ custom_id: req.id, method: "POST", url: "/v1/chat/completions", body: %{ model: "gpt-4o", messages: req.messages } } end) |> Enum.map(&Jason.encode!/1) |> Enum.join("\n") {jsonl_content} end def create_batch(client, requests) do jsonl = prepare_batch_file(requests) # Upload file file_request = OpenaiEx.Files.new_upload( file: OpenaiEx.new_file(name: "batch.jsonl", content: jsonl), purpose: "batch" ) {:ok, file} = OpenaiEx.Files.create(client, file_request) # Create batch batch_request = OpenaiEx.Batches.new( input_file_id: file["id"], endpoint: "/v1/chat/completions", completion_window: "24h" ) OpenaiEx.Batches.create(client, batch_request) end end ``` -------------------------------- ### create/2 Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/containers.md Creates a new container using the provided OpenAI client and request parameters. Returns the created container details on success. ```APIDOC ## create/2 ### Description Creates a new container. This operation uses the provided OpenAI client and a pre-built request map to create a container. ### Method `POST` (inferred from typical API patterns for creation) ### Endpoint `/v1/containers` (inferred from typical API patterns) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **name** (string) - Required - Container name. - **file_ids** (list) - Optional - List of file IDs to include. - **expires_after** (map) - Optional - Expiration configuration. ### Request Example ```elixir client = OpenaiEx.new("sk-...") request = OpenaiEx.Containers.new(name: "Vision Project") {:ok, container} = OpenaiEx.Containers.create(client, request) IO.puts("Container ID: #{container["id"]}") ``` ### Response #### Success Response (200) - **id** (string) - The unique identifier for the container. - **created_at** (integer) - Timestamp of container creation. - **name** (string) - The name of the container. - **file_ids** (list) - List of file IDs associated with the container. - **expires_after** (map) - Expiration configuration. #### Response Example ```json { "id": "cont-xxxxxxxxxxxx", "created_at": 1678886400, "name": "Vision Project", "file_ids": [], "expires_after": null } ``` ``` -------------------------------- ### Simple Audio Transcription Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/audio-transcription.md A straightforward example of transcribing an audio file using the default JSON response format. Assumes the client is initialized and the audio file exists. ```elixir client = OpenaiEx.new("sk-...") request = OpenaiEx.Audio.Transcription.new( file: OpenaiEx.new_file(path: "meeting_recording.mp3"), model: "whisper-1" ) {:ok, response} = OpenaiEx.Audio.Transcription.create(client, request) transcript = response["text"] IO.puts(transcript) ``` -------------------------------- ### Create Batch from Chat Completions Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/batches.md Prepares a JSONL file from a list of chat completion requests and creates a batch job with the OpenAI API. ```APIDOC ## Create Batch from Chat Completions ### Description Prepares a JSONL file from a list of chat completion requests and uploads it to create a batch job. ### Method `OpenaiEx.Batches.create/2` ### Parameters - `client`: The OpenAI API client. - `requests`: A list of requests, where each request contains an `id` and `messages`. ### Request Body (Implicit) The function constructs a JSONL file suitable for batch API calls. ### Response - `{:ok, batch}`: On success, returns the created batch object. - `{:error, error}`: On failure, returns an error tuple. ### Example ```elixir client = OpenaiEx.new_client(api_key: "YOUR_API_KEY") requests = [ %{id: "req1", messages: [{"role", "content", "Hello"}]}, %{id: "req2", messages: [{"role", "content", "World"}]} ] OpenaiEx.Batches.create(client, requests) ``` ``` -------------------------------- ### create!/2 Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/containers.md Creates a container and raises an exception if an error occurs. ```APIDOC ## create!/2 ### Description Creates a container. This is a non-tolerant version of `create/2` that raises an exception upon encountering an error. ### Method `POST` (inferred) ### Endpoint `/v1/containers` (inferred) ### Parameters - **openai** (%OpenaiEx{}) - The OpenAI client instance. - **request** (map) - The container creation request map. ### Returns - `map` - A map containing the details of the created container. ``` -------------------------------- ### Create a completion (non-streaming, raises on error) Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/completions.md Use `create!/2` for convenience when you want the function to raise an `OpenaiEx.Error` on failure instead of returning an error tuple. ```elixir def create!(openai :: %OpenaiEx{}, completion :: map) :: map ``` -------------------------------- ### Tool Use with Responses API Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/responses.md Demonstrates configuring the API to use tools, specifically a function call for getting weather information. This requires defining the tool's schema. ```elixir request = OpenaiEx.Responses.new( model: "gpt-4o", input: "What's the weather?", tools: [ %{ type: "function", function: %{ name: "get_weather", description: "Get weather for a location", parameters: %{ type: "object", properties: %{ location: %{type: "string"} }, required: ["location"] } } } ] ) {:ok, response} = OpenaiEx.Responses.create(client, request) ``` -------------------------------- ### Create a completion (streaming) Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/completions.md Use `create/3` with `stream: true` to receive completions as a stream of chunks. This is useful for interactive applications. The response includes a `body_stream` and a `task_pid` for cancellation. ```elixir def create(openai :: %OpenaiEx{}, completion :: map, stream: true) :: {:ok, stream_map} | {:error, OpenaiEx.Error.t} ``` ```elixir request = OpenaiEx.Completion.new( model: "text-davinci-003", prompt: "Once upon a time" ) case OpenaiEx.Completion.create(client, request, stream: true) do {:ok, response} -> response.body_stream |> Stream.each(fn chunk -> text = chunk["choices"] |> List.first() |> Map.get("text") IO.write(text || "") end) |> Stream.run() {:error, error} -> IO.inspect(error) end ``` -------------------------------- ### Custom Proxy or Local LLM Setup Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/client.md Configure the OpenAI client to use a custom proxy or a local LLM. Set the base URL to your local endpoint and adjust the receive timeout. ```elixir client = OpenaiEx.new("any-key") |> OpenaiEx.with_base_url("http://localhost:8000/v1") |> OpenaiEx.with_receive_timeout(120_000) ``` -------------------------------- ### Low Vision Detail Example Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/message-content.md Illustrates how to prompt for high detail analysis in vision tasks by including specific text alongside the image content. This can improve the quality of responses for complex images. ```elixir content = [ OpenaiEx.MsgContent.text("Analyze this with high detail:"), OpenaiEx.MsgContent.image_url("https://example.com/complex.jpg") ] ``` -------------------------------- ### Create a New Assistant Request Source: https://github.com/cyberchitta/openai_ex/blob/main/_autodocs/api-reference/assistants.md Use `new/1` or `new/2` to create a map representing a new assistant request. Specify parameters like model, name, instructions, and tools. ```elixir request = OpenaiEx.Beta.Assistants.new( model: "gpt-4o", name: "Math Tutor", instructions: "You are a helpful math tutor.", tools: [%{type: "code_interpreter"}] ) ```