Simple lightweight PHP library for interacting with common AI models, that provides universal interface.
🤖 Multimodel support. Unified API for all models.
🔧 Tools support & agentic - autoresolve tool calls with callbacks.
🚀 Extendable - easy to add your own models and tools.
⚡ No dependencies, just native PHP. cURL required.
📦 No composer required! But composer compatible.
Quick links
- Setup
- Quick start
- Tools and Toolbox
- Constructors and common options
- Supported models
- Requests and support
You can choose to use the autoloader or include the full source at once.
Using the autoloader:
require_once 'src/autoload.php';
Or include full source at once:
require_once 'src/loadall.php';
Or using composer:
composer require skito/aipi
/* ******************** */
/* Let's start with GPT */
/* ******************** */
$thread = new AIpi\Thread('openai-gpt-4o', 'my_openai_key');
$thread->AddMessage(new AIpi\Message('Hi, who are you?'));
$message = $thread->Run();
if ($message)
{
echo $message->content."\r\n"; // Hello! I'm an AI language model created by OpenAI.
print_r($thread->GetUsage());
echo "\r\n\r\n";
}
else echo $thread->GetLastError();
/* ************************************* */
/* Now let's switch the Thread to Sonnet */
/* ************************************* */
$thread->ChangeModel('anthropic-claude-3-5-sonnet-latest', 'my_anthropic_key');
$thread->AddMessage(new AIpi\Message('Is that true?'));
$message = $thread->Run();
if ($message)
{
echo $message->content."\r\n"; // I want to be direct with you. I'm Claude, an AI created by Anthropic.
print_r($thread->GetUsage());
echo "\r\n\r\n";
}
else echo $thread->GetLastError();
// Debug full communication
// print_r($thread->messages);
COMMUNICATION SEQUENCE
1. [APP] (message)--> [AI MODEL]
2. [APP] <--(message) [AI MODEL]
Use tools for agentic behaviour.
use AIpi\Thread;
use AIpi\Message;
use AIpi\Tools\FunctionCall;
/** ************************** */
/** Define simple weather tool */
/** ************************** */
$weatherInfo = new FunctionCall(
// Name
'get_weather_info',
// Description
'Get weather info by city name and country code.',
// Accepted properties
[
'city' => 'string',
'countryCode' => 'string',
],
// Property attributes
[
'required' => ['city', 'countryCode'],
'descriptions' => [
'city' => 'The city name.',
'countryCode' => 'The country code.',
]
],
// Callback function
function($args) {
return ['weather' => 'sunny'];
}
);
/** ********************************** */
/** Create a new thread with the tool */
/** ********************************** */
$thread = new Thread('openai-gpt4o', 'my_openai_key');
$thread->AddTool($weatherInfo);
$thread->AddMessage(new Message('You are a helpful assistant that can get weather info.', MessageRole::SYSTEM));
$thread->AddMessage(new Message('What is the weather right now in LA?', MessageRole::USER));
$message = $thread->Run();
if ($message)
{
echo 'ASSISTANT: '.$message->content."\r\n";
print_r($thread->GetUsage());
}
else
{
echo $thread->GetLastError();
}
// Debug full communication
// print_r($thread->messages);
use AIpi\Thread;
use AIpi\Message;
use AIpi\Tools\FunctionCall;
/** ********************************** */
/** Create a new thread with the tool */
/** ********************************** */
$thread = new Thread('openai-gpt4o', 'my_openai_key');
// Load OpenMeto tool from the toolbox
$thread->AddTool(new AIpi\Toolbox\OpenMeteo());
$thread->AddMessage(new Message('You are a helpful assistant that can get weather info.', MessageRole::SYSTEM));
$thread->AddMessage(new Message('What is the weather right now in LA?', MessageRole::USER));
$message = $thread->Run();
if ($message)
{
echo 'ASSISTANT: '.$message->content."\r\n";
print_r($thread->GetUsage());
}
else
{
echo $thread->GetLastError();
}
// Debug full communication
// print_r($thread->messages);
COMMUNICATION SEQUENCE
1. [APP] (message)--> [AI MODEL]
2. [APP] <-----(call) [AI MODEL]
3. [APP] (result)---> [AI MODEL]
4. [APP] <--(message) [AI MODEL]
Depending on the model, you can work with binary data or links.
/* ************/
/* GPT vision */
/* ************/
use AIpi\Thread;
use AIpi\Message;
$thread = new Thread('openai-gpt-4o', 'my_openai_key');
$thread->AddMessage(new Message('What\'s on the photo?'));
// Send photo link
$url = 'https://onlinejpgtools.com/images/examples-onlinejpgtools/orange-tabby-cat.jpg';
$thread->AddMessage(new Message($url, ['type' => MessageType::LINK]));
// or alternatively send as binary data
// $src = file_get_contents($url);
// $thread->AddMessage(new Message($src, ['type' => MessageType::FILE, 'media_type' => 'image/jpeg']));
$message = $thread->Run();
if ($message)
{
echo $message->content."\r\n"; // The photo features a fluffy orange tabby cat sitting ...
print_r($thread->GetUsage());
echo "\r\n\r\n";
}
else echo $thread->GetLastError();
/* ***************/
/* Claude vision */
/* ***************/
use AIpi\Thread;
use AIpi\Message;
use AIpi\MessageType;
$thread = new Thread('anthropic-claude-3-5-sonnet-latest', 'my_anthropic_key');
$thread->AddMessage(new Message('What\'s on the photo?'));
// Claude work with file uploads
$src = file_get_contents('https://onlinejpgtools.com/images/examples-onlinejpgtools/orange-tabby-cat.jpg');
$thread->AddMessage(new Message($src, ['type' => MessageType::FILE]));
$message = $thread->Run();
if ($message)
{
echo $message->content."\r\n"; // This is a photo of a fluffy orange/ginger cat that appears to be covering its face...
print_r($thread->GetUsage());
echo "\r\n\r\n";
}
else echo $thread->GetLastError();
/* ***************/
/* Gemini vision */
/* ***************/
use AIpi\Thread;
use AIpi\Message;
use AIpi\MessageType;
$thread = new AIpi\Thread('google-gemini-1.5-flash', 'my_google_key');
$thread->AddMessage(new Message('What\'s on the photo?'));
// Gemini work with file uploads
$src = file_get_contents('https://onlinejpgtools.com/images/examples-onlinejpgtools/orange-tabby-cat.jpg');
$thread->AddMessage(new Message($src, ['type' => MessageType::FILE]));
$message = $thread->Run();
if ($message)
{
echo $message->content."\r\n"; // That's a fluffy ginger cat grooming itself...
print_r($thread->GetUsage());
echo "\r\n\r\n";
}
else echo $thread->GetLastError();
$thread = new AIpi\Thread('openai-text-embedding-3-large', 'my_openai_key');
$thread->AddMessage(new AIpi\Message('The quick brown fox jumps over the lazy dog.'));
$message = $thread->Run();
if ($message)
{
echo $message->content."\r\n";
print_r($thread->GetUsage());
echo "\r\n\r\n";
}
else echo $thread->GetLastError();
For more examples, please refer to the models docs and the demo folder.
Currently supported: chat/completitions
, vision
, image generation
, audio generation
, audio transcription
, document vision
, embeddings
, moderations
.
Tools are definitions of functions that can be called by the AI model. You can make your own tool definitions such as Tools/FunctionCall
to be used in the thread.
Toolbox is a collection of predefined tool configurations. You can use the ones that come with this package ormake your own.
Learn more here: Add Tools
You have different options to create a new thread and message.
/***************/
/* Constructor */
/***************/
$thread = new AIpi\Thread($model, $key, [$options]);
$thread = new AIpi\Thread('openai-gpt-4o', $key, ['temperature' => 0.5, 'top_p' => 1]); // According to the model options
/***********/
/* Running */
/***********/
// Returns Message object or null if error
$thread->Run();
// If there are tools and the model is requesting additional input,
// the thread will call the tools and continue with the iteration,
// until the model is ready with the response
$thread->Run($autocomplete=true);
/***************/
/* Constructors */
/***************/
$message = new AIpi\Message($content, [$roleOrAttributes]); // default role is user
$message = new AIpi\Message('Hello!', AIpi\MessageRole::USER);
$message = new AIpi\Message('Hello!', ['type' => AIpi\MessageType::TEXT]);
$message = new AIpi\Message('Hello!', ['role' => AIpi\MessageRole::USER, 'type' => AIpi\MessageType::TEXT]);
Supported models by vendors.
OpenAI (examples)
- openai-gpt-4o
- openai-gpt-4o-mini
- openai-chatgpt-4o-latest
- openai-o1-preview
- openai-o1-mini
- openai-gpt-4
- openai-gpt-4-turbo
- openai-gpt-4-turbo-preview
- openai-text-embedding-3-large
- openai-text-embedding-3-small
- openai-text-embedding-ada-002
- openai-dall-e-3
- openai-dall-e-2
- openai-tts-1
- openai-tts-1-hd
- openai-whisper-1
- openai-omni-moderation-latest
- openai-text-moderation-latest
- openai-text-moderation-stable
Anthropic (examples)
- anthropic-claude-3-5-sonnet-latest
- anthropic-claude-3-5-haiku-latest
- anthropic-claude-3-opus-latest
Google DeepMind (examples)
- google-gemini-1.5-flash
- google-gemini-1.5-flash-8b
- google-gemini-1.5-pro
- google-text-embedding-004
xAI (examples)
- xai-grok-beta
- xai-grok-vision-beta
- xai-embedding-beta
You can add your own models by creating a new class that extends AIpi\ModelBase
and implementing the Call
method.
Learn more here: Add Models
For any feedback, requests, questions or issues, please open an issue on GitHub.