NAME
Langertha::Role::OpenAICompatible - Role for OpenAI-compatible API format
VERSION
version 0.202
SYNOPSIS
# This role is not used directly - it's composed by engines
# that implement the OpenAI-compatible API format.
package My::Engine;
use Moose;
with 'Langertha::Role::'.$_ for (qw(
JSON HTTP OpenAICompatible OpenAPI Models Temperature
ResponseSize SystemPrompt Streaming Chat
));
with 'Langertha::Role::Tools';
sub _build_api_key { $ENV{MY_API_KEY} || die "needs api_key" }
sub default_model { 'my-model' }
__PACKAGE__->meta->make_immutable;
DESCRIPTION
This role provides the OpenAI API format methods for chat completions, embeddings, transcription, streaming, and tool calling. Engines that use the OpenAI-compatible API format (whether OpenAI itself, Ollama's /v1 endpoint, or other compatible providers) can compose this role instead of inheriting from Langertha::Engine::OpenAI.
The role provides default implementations for all OpenAI-format operations. Engines can override individual methods to customize behavior (e.g., different operation IDs for Mistral, or disabling unsupported features).
Engines should also compose these roles:
Langertha::Role::JSON - JSON encoding/decoding
Langertha::Role::HTTP - HTTP request handling
Langertha::Role::OpenAPI - OpenAPI spec-driven request generation
Langertha::Role::Models - Model management
Engines using this role: Langertha::Engine::OpenAI, Langertha::Engine::DeepSeek, Langertha::Engine::Groq, Langertha::Engine::Mistral, Langertha::Engine::vLLM, Langertha::Engine::NousResearch, Langertha::Engine::Perplexity, Langertha::Engine::OllamaOpenAI, Langertha::Engine::AKIOpenAI.
api_key
Optional API key for Bearer token authentication. Override _build_api_key in engines that require authentication (typically from an environment variable). When undef, no Authorization header is sent.
update_request
$role->update_request($http_request);
Adds Authorization: Bearer {api_key} header to outgoing requests when an API key is configured. Skipped when api_key is undef (e.g. for local servers like vLLM or llama.cpp).
openapi_file
my ($type, $path) = $role->openapi_file;
Returns the OpenAI OpenAPI spec file path used for request generation. Override in an engine to use a provider-specific spec (e.g., Mistral).
list_models_request
my $request = $engine->list_models_request;
Generates an HTTP GET request for the /v1/models endpoint. Returns an HTTP request object.
list_models_response
my $models = $engine->list_models_response($http_response);
Parses the /v1/models response. Returns an ArrayRef of model objects (each with at least an id field).
list_models
my $model_ids = $engine->list_models;
# Returns: ['gpt-4o', 'gpt-4o-mini', ...]
my $models = $engine->list_models(full => 1);
# Returns: [{id => 'gpt-4o', created => ..., ...}, ...]
my $fresh = $engine->list_models(force_refresh => 1);
Fetches available models from the /v1/models endpoint with caching. By default returns an ArrayRef of model ID strings. Pass full => 1 for full model objects. Results are cached for models_cache_ttl seconds (default: 3600). Pass force_refresh => 1 to bypass the cache.
embedding_request
my $request = $engine->embedding_request($input, %extra);
Generates an OpenAI-format embedding request for the given $input string. Uses embedding_model (default: text-embedding-3-large). Returns an HTTP request object.
embedding_response
my $vector = $engine->embedding_response($http_response);
Parses an OpenAI-format embedding response. Returns an ArrayRef of floats representing the embedding vector.
chat_request
my $request = $engine->chat_request($messages, %extra);
Generates an OpenAI-format chat completion request. Includes model, messages, max_tokens, temperature, response_format (if set), and stream => false. Returns an HTTP request object.
chat_response
my $response = $engine->chat_response($http_response);
Parses an OpenAI-format chat completion response. Returns a Langertha::Response object with content, model, finish_reason, usage, created, and raw.
transcription_request
my $request = $engine->transcription_request($file_path, %extra);
Generates an OpenAI-format transcription request for the given audio file. Uses transcription_model (default: whisper-1). Returns an HTTP request object.
transcription_response
my $text = $engine->transcription_response($http_response);
Parses an OpenAI-format transcription response. Returns the transcribed text as a string.
stream_format
my $format = $engine->stream_format;
Returns 'sse' (Server-Sent Events), indicating the streaming format used by OpenAI-compatible APIs. Used by Langertha::Role::Chat to select the correct stream parser.
chat_stream_request
my $request = $engine->chat_stream_request($messages, %extra);
Generates an OpenAI-format streaming chat request (stream => true). Returns an HTTP request object for use with streaming execution.
parse_stream_chunk
my $chunk = $engine->parse_stream_chunk($data, $event);
Parses a single SSE data payload from an OpenAI-format stream. Returns a Langertha::Stream::Chunk with content, is_final, finish_reason, model, and usage, or undef if the chunk has no content.
format_tools
my $tools = $engine->format_tools($mcp_tools);
Converts an ArrayRef of MCP tool definitions to OpenAI function calling format. Each tool becomes { type => 'function', function => { name, description, parameters } }.
response_tool_calls
my $tool_calls = $engine->response_tool_calls($raw_data);
Extracts the tool call objects from a raw OpenAI-format response hashref. Returns an ArrayRef of tool call objects (may be empty).
extract_tool_call
my ($name, $args) = $engine->extract_tool_call($tool_call);
Extracts the function name and decoded argument hashref from a single OpenAI tool call object. JSON-decodes the arguments string if needed.
response_text_content
my $text = $engine->response_text_content($raw_data);
Extracts the assistant message text content from a raw OpenAI-format response hashref. Returns an empty string if no content.
format_tool_results
my @messages = $engine->format_tool_results($raw_data, $results);
Converts tool execution results into OpenAI-format messages to append to the conversation. Returns a list: first the assistant message (with tool calls), then one role => 'tool' message per result.
SEE ALSO
Langertha::Engine::OpenAI - OpenAI engine
Langertha::Engine::DeepSeek - DeepSeek engine
Langertha::Engine::Groq - Groq engine
Langertha::Engine::Mistral - Mistral engine
Langertha::Engine::vLLM - vLLM inference server
Langertha::Engine::NousResearch - Nous Research Hermes engine
Langertha::Engine::Perplexity - Perplexity Sonar engine
Langertha::Engine::OllamaOpenAI - Ollama OpenAI-compatible engine
Langertha::Engine::AKIOpenAI - AKI.IO OpenAI-compatible engine
SUPPORT
Issues
Please report bugs and feature requests on GitHub at https://github.com/Getty/langertha/issues.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHOR
Torsten Raudssus <torsten@raudssus.de> https://raudss.us/
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.