PHP Luminova: AI Models BackedEnum Helper
Optional Luminova PHP enum for AI models. Provides type-safe access, API-ready values, and full enum features like cases(), from(), and match checking. Works with PHP 8.1+.
The Luminova\AI\Model is an optional Luminova enum component. Each enum case has a readable PHP identifier, and its ->value holds the exact API string required by the AI client.
The Model class extends native PHP enum features: exhaustive match checking, built-in from(), tryFrom(), cases(), type-safe function signatures, and instance methods that let you inspect any case directly.
Installation
Install via Composer:
composer require luminovang/php-ai-models-enumRequires PHP 8.1 or higher. No additional dependencies are needed.
Luminova\AI\Model — a final PHP enum class with constant-like behavior.
Naming Conventions
| Rule | Example |
|---|---|
| Replace hyphens and dots with underscores | gpt-4.1-mini → GPT_4_1_MINI |
Append size tags (:8b) | llama3.1:8b → LLAMA_3_1_8B |
Append MoE tags (8x7b) | mixtral:8x7b → MIXTRAL_8X7B |
| Versioned snapshots | claude-opus-4-5-20251101 → CLAUDE_OPUS_4_5_SNAP |
| Clean alias for snapshot | claude-opus-4-5 → CLAUDE_OPUS_4_5 |
Usages
Setting Model
Every client method that accepts a model parameter expects a plain string. Use ->value to extract the API string from a case:
use Luminova\AI\Model;
// Correct — pass ->value to the client
AI::message('Hello!', ['model' => Model::GPT_4_1_MINI->value]);
// Also correct when your method accepts Model directly and extracts ->value internally
AI::message('Hello!', ['model' => Model::GPT_4_1_MINI]);
Luminova\Funcs\ask('Hello!', Model::GPT_4_1_MINI);Built-in Enum Methods
These are standard PHP 8.1 backed-enum methods available on every string-backed enum automatically.
from
Resolve a case from its API string value. Throws \ValueError when the string is not a known case — use this when the input is trusted.
use Luminova\AI\Model;
$model = Model::from('gpt-4.1-mini'); // Model::GPT_4_1_MINI
$model = Model::from('unknown'); // throws \ValueErrortryFrom
Resolve a case from its API string value. Returns null when the string is not known — use this for user or config input.
use Luminova\AI\Model;
$model = Model::tryFrom('gpt-4.1-mini'); // Model::GPT_4_1_MINI
$model = Model::tryFrom('unknown'); // nullcases
Return all cases as an array of enum instances. The order matches declaration order in the source file.
use Luminova\AI\Model;
foreach (Model::cases() as $model) {
echo $model->name . ' => ' . $model->value . PHP_EOL;
}
// GPT_5 => gpt-5
// GPT_5_MINI => gpt-5-mini
// ...
// ALL_MINILM => all-minilmNote:
cases()returns only enum cases, never private constants likePROVIDER_MAPorCAPABILITY_MAP.
Instance Methods
Called directly on a case — no arguments needed.
client
Return the client short-name. Matches the key registered in AI::$clients: 'openai', 'anthropic', or 'ollama'.
use Luminova\AI\Model;
Model::GPT_4_1_MINI->client(); // 'openai'
Model::CLAUDE_SONNET_4_6->client(); // 'anthropic'
Model::LLAVA->client(); // 'ollama'
Model::DEEPSEEK_R1->client(); // 'ollama'capabilities
Return all capability tags this case supports.
Available tags: chat, vision, image, embedding, speech, transcription, reasoning, coding, fine-tuning, moderation.
use Luminova\AI\Model;
Model::O3->capabilities();
// ['chat', 'vision', 'reasoning', 'coding']
Model::GPT_4_1_MINI->capabilities();
// ['chat', 'vision', 'coding', 'fine-tuning']
Model::NOMIC_EMBED_TEXT->capabilities();
// ['embedding']
Model::DALL_E_3->capabilities();
// ['image']
Model::WHISPER_1->capabilities();
// ['transcription']isVision
Whether this case accepts image input.
use Luminova\AI\Model;
Model::GPT_4_1->isVision(); // true
Model::WHISPER_1->isVision(); // falseisReasoning
Whether this is a reasoning / chain-of-thought model.
use Luminova\AI\Model;
Model::O3_PRO->isReasoning(); // true
Model::GPT_4_1_MINI->isReasoning(); // falseisEmbedding
Whether this case produces vector embeddings.
use Luminova\AI\Model;
Model::TEXT_EMBEDDING_3_SMALL->isEmbedding(); // true
Model::GPT_4_1->isEmbedding(); // falseisChat
Whether this case supports chat / completion.
use Luminova\AI\Model;
Model::GPT_4_1_MINI->isChat(); // true
Model::WHISPER_1->isChat(); // falseisCoding
Whether this case is optimized for code generation or completion.
use Luminova\AI\Model;
Model::DEEPSEEK_CODER->isCoding(); // true
Model::LLAVA->isCoding(); // falseisFineTunable
Whether this case supports fine-tuning via the client API.
use Luminova\AI\Model;
Model::GPT_4_1->isFineTunable(); // true
Model::CLAUDE_SONNET_4_6->isFineTunable(); // falseStatic Methods
forClient
Return all cases belonging to a specific client as an array of enum instances.
use Luminova\AI\Model;
$cases = Model::forClient('openai');
// [Model::GPT_5, Model::GPT_5_MINI, ..., Model::TEXT_MODERATION]
$cases = Model::forClient('anthropic');
// [Model::CLAUDE_OPUS_4_6, Model::CLAUDE_SONNET_4_6, ...]
$cases = Model::forClient('ollama');
// [Model::LLAMA_3, Model::LLAMA_3_1, ..., Model::ALL_MINILM]
foreach (Model::forClient('ollama') as $model) {
echo $model->name . ' = ' . $model->value . PHP_EOL;
}forCapability
Return all cases that support a given capability tag as an array of enum instances.
Available tags: chat, vision, image, embedding, speech, transcription, reasoning, coding, fine-tuning, moderation.
use Luminova\AI\Model;
$visionModels = Model::forCapability('vision');
$embeddingModels = Model::forCapability('embedding');
$reasoningModels = Model::forCapability('reasoning');
$codingModels = Model::forCapability('coding');
$imageModels = Model::forCapability('image');
foreach (Model::forCapability('reasoning') as $model) {
echo $model->value . ' (' . $model->client() . ')' . PHP_EOL;
}
// o3 (openai)
// o3-pro (openai)
// deepseek-r1 (ollama)
// claude-sonnet-3-7 (anthropic)
// ...resolve
A readable alias for Model::tryFrom(). Returns the matching case or null — never throws. Intended to make call-site intent explicit when validating external input.
use Luminova\AI\Model;
$model = Model::resolve('gpt-4.1-mini'); // Model::GPT_4_1_MINI
$model = Model::resolve('bad-string'); // null
// Safe fallback pattern
$model = Model::resolve($config['model']) ?? Model::GPT_4_1_MINI;Resolving from Config or User Input
use Luminova\AI\Model;
// From a config file
$configured = env('ai.model', 'gpt-4.1-mini');
$model = Model::resolve($configured) ?? Model::GPT_4_1_MINI;
echo "Using: {$model->value} ({$model->client()})";
// From a web request — reject unknown values
$userModel = $_POST['model'] ?? '';
$model = Model::tryFrom($userModel);
if ($model === null) {
http_response_code(400);
exit("Unknown model: {$userModel}");
}
$reply = $ai->message($prompt, ['model' => $model->value]);Exhaustive Match on Cases
PHP enforces that all cases in a match are handled when matching on an enum. This prevents silent omissions as you add new cases:
use Luminova\AI\Model;
$model = Model::CLAUDE_SONNET_4_6;
$tier = match ($model) {
Model::GPT_5, Model::CLAUDE_OPUS_4_6, Model::O3_PRO => 'flagship',
Model::GPT_4_1, Model::CLAUDE_SONNET_4_6, Model::O3 => 'standard',
Model::GPT_4_1_MINI, Model::CLAUDE_HAIKU_4_5, Model::O4_MINI => 'efficient',
default => 'other',
};Routing by Provider
use Luminova\AI\AI;
use Luminova\AI\Model;
function chat(string $prompt, Model $model): array
{
return match ($model->client()) {
'openai' => AI::Openai($_ENV['OPENAI_KEY'])->message($prompt, ['model' => $model->value]),
'anthropic' => AI::Anthropic($_ENV['ANTHROPIC_KEY'])->message($prompt, ['model' => $model->value]),
'ollama' => AI::Ollama()->message($prompt, ['model' => $model->value]),
};
}
chat('Tell me a joke.', Model::GPT_4_1_MINI); // OpenAI
chat('Tell me a joke.', Model::CLAUDE_SONNET_4_6); // Anthropic
chat('Tell me a joke.', Model::LLAMA_3_2); // OllamaBuilding UI Select Lists
use Luminova\AI\Model;
// All available models grouped by client for a settings page
$grouped = [];
foreach (Model::cases() as $model) {
$grouped[$model->client()][] = [
'value' => $model->value,
'label' => str_replace('_', ' ', ucfirst(strtolower($model->name))),
'tags' => $model->capabilities(),
];
}
// Only offer vision-capable models in a vision task dropdown
$visionOptions = array_map(
fn(Model $m): array => ['value' => $m->value, 'label' => $m->name],
Model::forCapability('vision')
);