AI
object
%AI
/phlo/resources/AI/AI.phlo
prop
%AI -> model
line 10
This item defines an AI model with the identifier 'gpt-5.4-mini'.
'gpt-5.4-mini'const
AI :: engines
line 11
Defines a mapping of AI engine identifiers to their respective names, allowing for easy reference and integration within Phlo applications.
['claude' => 'Claude', 'gpt' => 'OpenAI', 'chatgpt' => 'OpenAI', 'o1' => 'OpenAI', 'o3' => 'OpenAI', 'o4' => 'OpenAI', 'deepseek' => 'DeepSeek', 'gemini' => 'Gemini', 'grok' => 'Grok']static
AI :: http (string $url, array $headers, bool $json = true, mixed $post = null):string
line 12
Sends an HTTP request to the specified URL with optional headers, JSON payload, and POST data, allowing for a customizable timeout period.
HTTP($url, $headers, $json, $post, timeout: 300)method
%AI -> resolve (...$args):array
line 13
Resolves the AI engine to be used based on the provided arguments, defaulting to 'OpenAI' if no specific engine is specified.
$via = $args['via'] ?? void
unset($args['via'])
$args['model'] ??= $this->model
if ($via) $via = static::engines[strtolower($via)] ?? $via
elseif (isset($args['model'])) $via = static::engines[strtolower(explode(dash, $args['model'])[0])] ?? void
return [$via ?: 'OpenAI', $args]method
%AI -> chat (...$args)
line 21
This method initiates a chat session using the specified AI engine and arguments.
[$engine, $args] = $this->resolve(...$args)
return phlo($engine)->chat(...$args)method
%AI -> stream (...$args):Generator
line 25
Streams data from an AI engine using the provided arguments.
[$engine, $args] = $this->resolve(...$args)
return phlo($engine)->stream(...$args)method
%AI -> embedding (...$args)
line 29
This function resolves the engine and arguments, then calls the embedding method on the specified engine with the provided arguments.
[$engine, $args] = $this->resolve(...$args)
return phlo($engine)->embedding(...$args)method
%AI -> vision (...$args)
line 33
This function resolves the AI engine and arguments, then invokes the vision method of the specified engine with the provided arguments.
[$engine, $args] = $this->resolve(...$args)
return phlo($engine)->vision(...$args)method
%AI -> transcribe (...$args)
line 37
Transcribes audio input using the specified AI engine and arguments.
[$engine, $args] = $this->resolve(...$args)
return phlo($engine)->transcribe(...$args)object
%Claude
/phlo/resources/AI/Claude.phlo
const
Claude :: model
line 10
Defines a model using the 'claude-opus-4-8' source, which can be utilized for various AI tasks within Phlo.
'claude-opus-4-8'static
Claude :: context (...$args)
line 12
Initializes the context for Claude by setting up messages and system parameters, ensuring that user and assistant messages are properly formatted and stored.
$args['messages'] ??= []
if (isset($args['system'])){
$args['system'] = [['type' => 'text', 'text' => $args['system']]]
}
if (isset($args['assistant']) && array_push($args['messages'], ['role' => 'assistant', 'content' => $args['assistant']])) unset($args['assistant'])
if (isset($args['user']) && array_push($args['messages'], ['role' => 'user', 'content' => $args['user']])) unset($args['user'])
return $argsstatic
Claude :: tool ($tool):array
line 22
This constructs an associative array containing the name and description of a tool, along with its input schema, which defines the properties and required arguments for the tool.
[
'name' => $tool->name,
'description' => $tool->desc,
'input_schema' => [
'type' => 'object',
'properties' => loop($tool->args, fn($data, $arg) => array_filter($data, fn($key) => in_array($key, ['type', 'enum', 'description']), ARRAY_FILTER_USE_KEY)),
'required' => array_keys($tool->args),
],
]method
%Claude -> embedding ($input, $model = 'text-embedding-3-small')
line 32
Generates an embedding for the given input using the specified model, defaulting to 'text-embedding-3-small'.
%OpenAI->embedding($input, $model)method
%Claude -> vision ($text, $image, $stream = false, ...$args)
line 34
This function sends a text and an image to a vision model, optionally streaming the response or returning it in a chat format.
$data = is_string($image) && str_starts_with($image, 'http') ? file_get_contents($image) : $image
$messages = [['role' => 'user', 'content' => [['type' => 'text', 'text' => $text], ['type' => 'image', 'source' => ['type' => 'base64', 'media_type' => 'image/jpeg', 'data' => base64_encode($data)]]]]]
if ($stream) return $this->stream(...$args, messages: $messages)
else return $this->chat(...$args, messages: $messages)method
%Claude -> chat (...$args)
line 41
This function interacts with the Claude API to send a chat request and process the response, returning an object containing the answer, model information, token usage, and any tools used during the interaction.
$args['model'] ??= static::model
$args['max_tokens'] ??= 4096
$token = $args['token'] ?? null
unset($args['token'])
$args = static::context(...$args)
$res = $this->request('messages', token: $token, POST: $args)
$return = new obj(answer: void, model: $res->model, finish: $res->stop_reason, tokens: ($res->usage->input_tokens ?? 0) + ($res->usage->output_tokens ?? 0), tokens_in: $res->usage->input_tokens ?? 0, tokens_out: $res->usage->output_tokens ?? 0)
$tools = []
foreach ($res->content AS $block){
if ($block->type === 'text') $return->answer = $block->text
elseif ($block->type === 'tool_use') $tools[] = new obj(name: $block->name, args: (array)$block->input)
}
if ($tools) $return->tools = $tools
return $returnmethod
%Claude -> parseSSE (string $url, array $headers, array $payload):Generator
line 58
Parses Server-Sent Events (SSE) from a given URL, sending a JSON payload and handling responses, including error management and yielding data as it is received.
$json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
$ctx = stream_context_create(['http' => ['method' => 'POST', 'header' => implode(nl, [...$headers, 'Content-Type: application/json', 'Content-Length: '.strlen($json)]), 'content' => $json, 'timeout' => 300, 'ignore_errors' => true]])
$stream = fopen($url, 'r', false, $ctx)
$stream || error('SSE connection failed')
$status = (int)explode(space, $http_response_header[0] ?? 'HTTP/1.1 200')[1]
if ($status >= 400){
$err = json_decode((string)stream_get_contents($stream))
fclose($stream)
error('Claude error '.$status.': '.($err->error->message ?? 'unknown'))
}
$finish = null
$usage = null
while (!feof($stream)){
$line = fgets($stream)
if ($line === false) break
$line = rtrim($line, nl)
if (!str_starts_with($line, 'data:')) continue
$data = ltrim(substr($line, 5))
if ($data === void) continue
$p = json_decode($data)
if (!$p) continue
if (isset($p->error)) error('Claude stream error: '.$p->error->message)
if (($p->type ?? null) === 'message_delta'){
$finish = $p->delta->stop_reason ?? $finish
if (isset($p->usage)) $usage = $p->usage
}
if (($p->type ?? null) === 'content_block_delta' && ($p->delta->type ?? null) === 'text_delta' && isset($p->delta->text)) yield obj(text: $p->delta->text)
}
fclose($stream)
yield obj(done: true, finish: $finish, tokens_in: $usage?->input_tokens, tokens_out: $usage?->output_tokens)method
%Claude -> stream (...$args):Generator
line 90
Streams messages from the Claude API using Server-Sent Events (SSE), allowing for real-time interaction with the model.
%res->streaming = true
$args['model'] ??= static::model
$args['max_tokens'] ??= 4096
$token = $args['token'] ?? null
unset($args['token'], $args['cb'])
$args = static::context(...$args)
$args['stream'] = true
if ($token) $headers = ['anthropic-version: 2023-06-01', 'anthropic-beta: oauth-2025-04-20', 'Authorization: Bearer '.$token]
else $headers = ['anthropic-version: 2023-06-01', 'x-api-key: '.%creds->Claude]
return $this->parseSSE('https://api.anthropic.com/v1/messages', $headers, $args)method
%Claude -> request ($uri, ...$args)
line 103
Sends a request to the Claude API using the specified URI and arguments, handling authentication with a token or API key, and returns the decoded JSON response.
$token = $args['token'] ?? null
if ($token) $headers = ['anthropic-version: 2023-06-01', 'anthropic-beta: oauth-2025-04-20', 'Authorization: Bearer '.$token]
else $headers = ['anthropic-version: 2023-06-01', 'x-api-key: '.%creds->Claude]
$res = json_decode(AI::http("https://api.anthropic.com/v1/$uri", $headers, true, $args['POST'] ?? null))
if (isset($res->error)) error('Claude Request error: '.$res->error->message)
return $resobject
%DeepSeek
/phlo/resources/AI/DeepSeek.phlo
const
DeepSeek :: model
line 11
DeepSeek::model is a component that facilitates the creation and management of models within the DeepSeek framework, allowing for efficient data handling and interaction.
'deepseek-chat'const
DeepSeek :: endpoint
line 12
Defines the endpoint URL for accessing the DeepSeek API version 1.
'https://api.deepseek.com/v1/'const
DeepSeek :: cred
line 13
DeepSeek::cred retrieves credentials for accessing resources within the DeepSeek framework.
'DeepSeek'const
DeepSeek :: label
line 14
DeepSeek::label is used to define a label for a DeepSeek resource, allowing for better organization and identification within the system.
'DeepSeek'method
%DeepSeek -> embedding ($input, $model = 'text-embedding-3-small')
line 16
Generates an embedding for the given input using the specified model, defaulting to 'text-embedding-3-small'.
%OpenAI->embedding($input, $model)object
%Gemini
/phlo/resources/AI/Gemini.phlo
const
Gemini :: model
line 10
Creates a model in the Gemini framework, allowing for the definition and manipulation of data structures.
'gemini-2.0-flash'const
Gemini :: endpoint
line 11
Defines an endpoint for accessing the Gemini API, allowing interaction with the specified model at the given URL.
'https://generativelanguage.googleapis.com/v1beta/models/'static
Gemini :: context (...$args)
line 13
Gemini::$context processes input arguments to construct a structured context for a conversation, organizing system, assistant, and user messages into a contents array.
$args['contents'] ??= []
if (isset($args['system'])){
$args['systemInstruction'] = ['parts' => [['text' => $args['system']]]]
unset($args['system'])
}
if (isset($args['assistant']) && array_push($args['contents'], ['role' => 'model', 'parts' => [['text' => $args['assistant']]]])) unset($args['assistant'])
if (isset($args['user']) && array_push($args['contents'], ['role' => 'user', 'parts' => [['text' => $args['user']]]])) unset($args['user'])
return $argsstatic
Gemini :: tool ($tool):array
line 24
Gemini::$tool retrieves the name and description of a tool, along with its parameters, which include type, properties, and required arguments.
[
'name' => $tool->name,
'description' => $tool->desc,
'parameters' => [
'type' => 'object',
'properties' => loop($tool->args, fn($data, $arg) => array_filter($data, fn($key) => in_array($key, ['type', 'enum', 'description']), ARRAY_FILTER_USE_KEY)),
'required' => array_keys($tool->args),
],
]method
%Gemini -> embedding ($input, $model = 'text-embedding-004')
line 34
Generates embeddings for the given input text using the specified model, defaulting to 'text-embedding-004'.
$this->request($model.':embedContent', POST: ['content' => ['parts' => [['text' => $input]]]])->embedding->valuesmethod
%Gemini -> vision ($text, $image, $stream = false, ...$args)
line 36
Generates a vision response by combining text and an image, with an optional streaming feature for real-time output.
$model = $args['model'] ?? static::model
unset($args['model'])
$contents = [['role' => 'user', 'parts' => [['text' => $text], ['inline_data' => ['mime_type' => 'image/jpeg', 'data' => base64_encode(is_string($image) && str_starts_with($image, 'http') ? file_get_contents($image) : $image)]]]]]
if ($stream) return $this->stream(...$args, model: $model, contents: $contents)
else return $this->chat(...$args, model: $model, contents: $contents)method
%Gemini -> chat (...$args)
line 44
Generates content based on the specified model and arguments, returning an object that includes the generated answer, model used, finish reason, and token usage details.
$model = $args['model'] ?? static::model
unset($args['model'])
$args = static::context(...$args)
$res = $this->request($model.':generateContent', POST: $args)
$return = new obj(answer: void, model: $model, finish: $res->candidates[0]->finishReason ?? void, tokens: ($res->usageMetadata->promptTokenCount ?? 0) + ($res->usageMetadata->candidatesTokenCount ?? 0), tokens_in: $res->usageMetadata->promptTokenCount ?? 0, tokens_out: $res->usageMetadata->candidatesTokenCount ?? 0)
$tools = []
foreach ($res->candidates[0]->content->parts ?? [] AS $part){
if (isset($part->text)) $return->answer = $part->text
elseif (isset($part->functionCall)) $tools[] = new obj(name: $part->functionCall->name, args: (array)$part->functionCall->args)
}
if ($tools) $return->tools = $tools
return $returnmethod
%Gemini -> parseSSE (string $url, array $headers, array $payload):Generator
line 59
Parses Server-Sent Events (SSE) from a specified URL, sending a JSON payload and handling the response, yielding text data and usage metadata.
$json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
$ctx = stream_context_create(['http' => ['method' => 'POST', 'header' => implode(nl, [...$headers, 'Content-Type: application/json', 'Content-Length: '.strlen($json)]), 'content' => $json, 'timeout' => 300, 'ignore_errors' => true]])
$stream = fopen($url, 'r', false, $ctx)
$stream || error('SSE connection failed')
$status = (int)explode(space, $http_response_header[0] ?? 'HTTP/1.1 200')[1]
if ($status >= 400){
$err = json_decode((string)stream_get_contents($stream))
fclose($stream)
error('Gemini error '.$status.': '.($err->error->message ?? 'unknown'))
}
$finish = null
$usage = null
while (!feof($stream)){
$line = fgets($stream)
if ($line === false) break
$line = rtrim($line, nl)
if (!str_starts_with($line, 'data:')) continue
$data = ltrim(substr($line, 5))
if ($data === void) continue
$p = json_decode($data)
if (!$p) continue
if (isset($p->error)) error('Gemini stream error: '.$p->error->message)
if (isset($p->usageMetadata)) $usage = $p->usageMetadata
if ($p->candidates[0]->finishReason ?? null) $finish = $p->candidates[0]->finishReason
$text = $p->candidates[0]->content->parts[0]->text ?? null
if (!is_null($text)) yield obj(text: $text)
}
fclose($stream)
yield obj(done: true, finish: $finish, tokens_in: $usage?->promptTokenCount, tokens_out: $usage?->candidatesTokenCount)method
%Gemini -> stream (...$args):Generator
line 90
Enables streaming for the specified model in Gemini, preparing the necessary arguments and returning a parsed Server-Sent Events response.
%res->streaming = true
$model = $args['model'] ?? static::model
unset($args['model'], $args['cb'])
$args = static::context(...$args)
return $this->parseSSE(static::endpoint.$model.':streamGenerateContent?alt=sse', ['x-goog-api-key: '.%creds->Gemini], $args)method
%Gemini -> request ($path, ...$args)
line 98
Sends a request to the Gemini API at the specified path with optional arguments, handling errors and returning the decoded JSON response.
$res = json_decode(AI::http(static::endpoint.$path, ['x-goog-api-key: '.%creds->Gemini], true, $args['POST'] ?? null))
if (isset($res->error)) error('Gemini Request error: '.$res->error->message)
return $resobject
%Grok
/phlo/resources/AI/Grok.phlo
const
Grok :: model
line 11
Grok::model is a component in the Grok framework that facilitates the creation and management of data models, allowing for easy interaction with databases and ORM functionality.
'grok-4'const
Grok :: endpoint
line 12
Defines an endpoint for making API requests to the specified URL.
'https://api.x.ai/v1/'const
Grok :: cred
line 13
Grok::cred is a module that provides credential management functionalities within the Grok framework.
'Grok'const
Grok :: label
line 14
Creates a label for a Grok pattern, allowing for better organization and identification of patterns in your code.
'Grok'method
%Grok -> embedding ($input, $model = 'text-embedding-3-small')
line 16
Generates an embedding for the given input using the specified model, defaulting to 'text-embedding-3-small'.
%OpenAI->embedding($input, $model)object
%OpenAI
/phlo/resources/AI/OpenAI.phlo
const
OpenAI :: model
line 10
This item specifies the OpenAI model to be used, in this case, 'gpt-5.4-mini'.
'gpt-5.4-mini'const
OpenAI :: endpoint
line 11
Defines the endpoint for accessing the OpenAI API, specifically the base URL for API requests.
'https://api.openai.com/v1/'const
OpenAI :: cred
line 12
This item represents the OpenAI credential used for authentication and access to OpenAI services.
'OpenAI'const
OpenAI :: label
line 13
This function is used to label data using OpenAI's models for various applications.
'OpenAI'const
OpenAI :: voices
line 14
OpenAI::voices is a predefined list of voice options available for use in Phlo applications, including 'alloy', 'echo', 'fable', 'onyx', 'nova', and 'shimmer'.
['alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer']static
OpenAI :: context (...$args):array
line 15
This function initializes the 'messages' array in the context of OpenAI, adding system, assistant, and user messages as specified in the input arguments.
$args['messages'] ??= []
if (isset($args['system']) && array_unshift($args['messages'], ['role' => 'system', 'content' => $args['system']])) unset($args['system'])
if (isset($args['assistant']) && array_push($args['messages'], ['role' => 'assistant', 'content' => $args['assistant']])) unset($args['assistant'])
if (isset($args['user']) && array_push($args['messages'], ['role' => 'user', 'content' => $args['user']])) unset($args['user'])
return $argsstatic
OpenAI :: tool ($tool):array
line 22
Defines a function in OpenAI with specified parameters, including type, enum, and description, while enforcing strict validation of the arguments.
[
'type' => 'function',
'function' => [
'name' => $tool->name,
'description' => $tool->desc,
'parameters' => [
'type' => 'object',
'properties' => loop($tool->args, fn($data, $arg) => array_filter($data, fn($key) => in_array($key, ['type', 'enum', 'desc']), ARRAY_FILTER_USE_KEY)),
'additionalProperties' => false,
'required' => array_keys($tool->args),
],
'strict' => true,
],
]method
%OpenAI -> chat (...$args):obj
line 36
This function interacts with the OpenAI API to generate chat completions based on the provided arguments, returning an object containing the response details such as the generated answer, model used, and token usage statistics.
$args['model'] ??= static::model
$token = $args['token'] ?? null
unset($args['token'])
$args = static::context(...$args)
$res = $this->request('chat/completions', token: $token, POST: $args)
$return = new obj(answer: $res->choices[0]->message->content, model: $res->model, finish: $res->choices[0]->finish_reason, tokens: $res->usage->total_tokens, tokens_in: $res->usage->prompt_tokens, tokens_out: $res->usage->completion_tokens)
if (isset($res->choices[0]->message->tool_calls)) $return->tools = array_map(fn($tool) => new obj(name: $tool->function->name, args: json_decode($tool->function->arguments, true)), (array)$res->choices[0]->message->tool_calls)
return $returnmethod
%OpenAI -> embedding ($input, $model = 'text-embedding-3-small')
line 46
Generates an embedding for the given input using the specified model from OpenAI.
$this->request('embeddings', POST: ['input' => $input, 'model' => $model])->data[0]->embeddingmethod
%OpenAI -> parseSSE (string $url, array $headers, array $payload):Generator
line 47
Establishes a Server-Sent Events (SSE) connection to the specified URL, sending a JSON payload and headers, and yields data received from the stream.
$json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
$ctx = stream_context_create(['http' => ['method' => 'POST', 'header' => implode(nl, [...$headers, 'Content-Type: application/json', 'Content-Length: '.strlen($json)]), 'content' => $json, 'timeout' => 300, 'ignore_errors' => true]])
$stream = fopen($url, 'r', false, $ctx)
$stream || error('SSE connection failed')
$status = (int)explode(space, $http_response_header[0] ?? 'HTTP/1.1 200')[1]
if ($status >= 400){
$err = json_decode((string)stream_get_contents($stream))
fclose($stream)
error(static::label.' error '.$status.': '.($err->error->message ?? 'unknown'))
}
$finish = null
$usage = null
while (!feof($stream)){
$line = fgets($stream)
if ($line === false) break
$line = rtrim($line, nl)
if (!str_starts_with($line, 'data:')) continue
$data = ltrim(substr($line, 5))
if ($data === '[DONE]' || $data === void) continue
$p = json_decode($data)
if (!$p) continue
if (isset($p->error)) error(static::label.' stream error: '.$p->error->message)
if (isset($p->usage)) $usage = $p->usage
$text = $p->choices[0]->delta->content ?? null
if (!is_null($text)) yield obj(text: $text)
if ($p->choices[0]->finish_reason ?? null) $finish = $p->choices[0]->finish_reason
}
fclose($stream)
yield obj(done: true, finish: $finish, tokens_in: $usage?->prompt_tokens, tokens_out: $usage?->completion_tokens)method
%OpenAI -> stream (...$args):Generator
line 78
Streams responses from the OpenAI API using Server-Sent Events (SSE), allowing for real-time interaction with the model.
%res->streaming = true
$args['model'] ??= static::model
$token = $args['token'] ?? null
unset($args['token'], $args['cb'])
$args = static::context(...$args)
$args['stream'] = true
$bearer = $token ?? %creds->{static::cred};
return $this->parseSSE(static::endpoint.'chat/completions', ['Authorization: Bearer '.$bearer], $args)method
%OpenAI -> transcribe ($file, $model = 'whisper-1', ...$args):obj
line 88
Transcribes audio from a given file using the specified model, returning details such as duration, language, and transcribed text.
if (is_string($file)) $file = new CURLFile($file)
elseif (is_a($file, 'file')) $file = $file->curl
$res = $this->request('audio/transcriptions', false, POST: [...$args, 'model' => $model, 'file' => $file, 'response_format' => 'verbose_json'])
return obj (
model: $model,
duration: $res->duration,
lang: $res->language,
text: $res->text,
)method
%OpenAI -> vision ($text, $image, $stream = false, ...$args):obj
line 99
This function sends a text and an image to the OpenAI vision model, optionally streaming the response or returning it in a chat format.
$args['model'] ??= static::model
$messages = [['role' => 'user', 'content' => [['type' => 'text', 'text' => $text], ['type' => 'image_url', 'image_url' => ['url' => $image]]]]]
if ($stream) return $this->stream(...$args, messages: $messages)
else return $this->chat(...$args, messages: $messages)method
%OpenAI -> request ($uri, $JSON = true, $token = null, ...$args)
line 105
Sends a request to the OpenAI API at the specified URI, optionally including a JSON payload and an authorization token, and returns the decoded response.
$bearer = $token ?? %creds->{static::cred};
$res = json_decode(AI::http(static::endpoint.$uri, ['Authorization: Bearer '.$bearer], $JSON, $args['POST'] ?? null))
if (isset($res->error)) error(static::label.' Request error: '.$res->error->message)
return $resFunctions
function
answer($question, ...$options)
/phlo/resources/AI/answer.phlo line 10
Generates a short, direct answer to a given question, either from specified options or by providing a concise response without additional text.
$prompt = 'You are an AI answer machine. '
$prompt .= 'You give short, direct answers without repeating the subject. '
$prompt .= 'You add no explanation, no extra text, and no quotation marks. '
$prompt .= 'Always answer in the same language as the question.'.lf
if ($options){
$prompt .= 'The user asks a question. You choose exactly one of the options below as the answer. '
$prompt .= 'Your answer matches exactly one of the options, with no extra words or punctuation. '
$prompt .= 'If none of the options apply, answer with "-".'.lf.lf
$prompt .= 'Question:'.lf.$question.lf.lf
$prompt .= 'Options:'.lf
$prompt .= implode(lf, $options)
}
else {
$prompt .= 'Give a short and precise answer to the question. '
$prompt .= 'No introduction, no explanation, no list, and no final period.'.lf.lf
$prompt .= 'Question:'.lf.$question
}
$answer = %AI->chat(user: $prompt, temperature: .1)->answer
return $answer === dash ? null : $answer