Skip to content

skito/aipi-php

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AIpi - Universal API client for common AI models

GitHub release (latest by date) GitHub release (latest by date) GitHub release (latest by date) GitHub release (latest by date) GitHub release (latest by date)

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

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

Quick start

[BASIC USAGE]

/* ******************** */
/* 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]

[WITH TOOLS]

Use tools for agentic behaviour.

Custom tool example

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);

Toolbox example

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]

[VISION]

Depending on the model, you can work with binary data or links.

GPT

/* ************/
/* 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

/* ***************/
/* 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

/* ***************/
/* 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();

[Embeddings]

$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();

[MORE EXAMPLES]

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 and Toolbox

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


Constructors and common options

You have different options to create a new thread and message.

Thread

/***************/
/* 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); 

Message

/***************/
/* 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

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

Add Models

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


Requests and support

For any feedback, requests, questions or issues, please open an issue on GitHub.