Skip to content
119 changes: 119 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# The Joomla! AI Package

## Installation via Composer

Add `"joomla/ai": "~4.0"` to the require block in your composer.json and then run `composer install`.

```json
{
"require": {
"joomla/ai": "~4.0"
}
}
```

Alternatively, you can simply run the following from the command line:

```sh
composer require joomla/ai "~4.0"
```

If you want to include the test sources and docs, use

```sh
composer require --prefer-source joomla/ai "~4.0"
```

## Using the AI Framework
The AI Framework provides a straightforward, provider-agnostic interface for working with three main AI providers: OpenAI, Anthropic and Ollama. Instead of writing separate code for each provider’s SDK, developers write once and simply switch providers by changing configuration.

You can find the official provider APIs documentation here:
- OpenAI API: https://platform.openai.com/docs/api-reference
- Anthropic API: https://docs.anthropic.com/claude/docs
- Ollama API: https://github.com/ollama/ollama/blob/main/docs/api.md

The AI framework is built upon the Http package which provides an easy way to consume URLs and web services in a transport independent way. Joomla\Http currently supports streams, sockets and cURL. The framework centralizes HTTP handling in the Abstract Provider. Providers encapsulate:
- Base URLs, headers, and auth (API keys/tokens)
- Request building (JSON/multipart)
- Response normalization and error mapping into framework exceptions

## Instantiating a Provider

Each provider is instantiated with its configuration (API key, defaults such as model or base URL). You can override these defaults per call when needed.

### OpenAI:
```php
use Joomla\AI\Provider\OpenAIProvider;

$openai = new OpenAIProvider([
'api_key' => getenv('OPENAI_API_KEY'),
// Optional defaults:
// 'model' => 'gpt-4o',
// 'base_url' => 'https://api.openai.com/v1',
]);
```

### Anthropic:
```php
use Joomla\AI\Provider\AnthropicProvider;

$anthropic = new AnthropicProvider([
'api_key' => getenv('ANTHROPIC_API_KEY'),
// 'model' => 'claude-3-5-sonnet',
]);
```

### Ollama (local):
```php
use Joomla\AI\Provider\OllamaProvider;

$ollama = new OllamaProvider([
// 'base_url' => 'http://localhost:11434',
// 'model' => 'llama3',
]);
```

## Supported Methods

| Provider | Methods |
| --- | --- |
| OpenAI | `chat`, `vision`, `generateImage`, `createImageVariation`, `editImage`, `speech`, `transcribe`, `translate`, `createEmbeddings`, `moderate`, `isContentFlagged`|
| Anthropic | `chat`, `vision`, `getModel`|
| Ollama | `chat`, `generate`, `pullModel`, `copyModel`, `deleteModel`, `checkModelExists`, `getRunningModels`|

Not all providers implement every capability. The framework exposes capabilities via interfaces (e.g. ChatInterface, ImageInterface). Developers can use what each provider supports.

## Making your first request
All providers implement a shared set of capability interfaces (e.g., Chat, Images, Audio). Invoke these methods directly, passing per-call options to override defaults.

```php
// Chat example (OpenAI)
$response = $openai->chat("Write a haiku about Joomla.", [
'model' => 'gpt-4o-mini', // overrides constructor default if set
]);
echo $response->getContent(); // primary content (e.g. text)
$meta = $response->getMetadata(); // metadata content (e.g. model, usage)
```

## Error handling
Provider HTTP errors are mapped to framework exceptions (e.g. auth, rate limit, invalid arguments). Catch and handle them as needed.
```php
try {
$response = $openai->chat("Hello!");
} catch (\Throwable $e) {
// Log and surface a friendly message
}
```

## Documentation

- **[Overview](guides/overview.md)**
Architecture & goals

- **[Getting Started](guides/index.md)**
Install, configure, first provider

- **[Guides](guides/)**
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still in planning or do you want to replace that with a link to the providers folder? I think you would have to provide an index.md for that folder then as well.

Copy link
Collaborator Author

@charvimehradu charvimehradu Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey,
Thank you for reviewing the PR. I have replaced the link with the providers folder. I have also added the index.md file for that folder as well.

Task-specific guides (Chat, Images, Audio, etc.)

---
273 changes: 273 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
# Getting Started

This guide will help you install the AI Framework and make your first request in just a few minutes.

## Requirements

- PHP 8.3.0 or higher
- Composer
- API keys for the providers you want to use

## Installation

### Via Composer

Add the AI package to your project:

```json
{
"require": {
"joomla/ai": "~4.0"
}
}
```

Then run:
```bash
composer install
```

Alternatively, install directly:
```bash
composer require joomla/ai "~4.0"
```

For development with test sources:
```bash
composer require --prefer-source joomla/ai "~4.0"
```

## Configuration

### API Keys

You will need API keys from the providers you want to use:

- **OpenAI**: Get your key at https://platform.openai.com/api-keys
- **Anthropic**: Get your key at https://console.anthropic.com/
- **Ollama**: Runs locally, no API key needed

### Storing API Keys

**It is recommended to store API keys in environment variables** for security reasons. Never commit API keys to version control.

**Windows (Command Prompt):**
```cmd
setx OPENAI_API_KEY "sk-your-openai-key-here"
setx ANTHROPIC_API_KEY "sk-ant-your-anthropic-key-here"
```

**Windows (PowerShell):**
```powershell
[Environment]::SetEnvironmentVariable("OPENAI_API_KEY", "sk-your-openai-key-here", "User")
[Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", "sk-ant-your-anthropic-key-here", "User")
```

> **Note**: Restart your terminal or web server after setting environment variables to ensure they are loaded.
## Your First Request

### Basic Chat Example

```php
<?php
require_once 'vendor/autoload.php';

use Joomla\AI\Provider\OpenAIProvider;

// Create provider instance
$openai = new OpenAIProvider([
'api_key' => getenv('OPENAI_API_KEY')
]);

// Make your first chat request
$response = $openai->chat("Hello! Tell me about Joomla in one sentence.");

// Display the result
echo "Response: " . $response->getContent() . "\n";
echo "Model used: " . $response->getMetadata()['model'] . "\n";
echo "Provider: " . $response->getProvider() . "\n";
```

### Multi-Provider Example

```php
<?php
require_once 'vendor/autoload.php';

use Joomla\AI\Provider\OpenAIProvider;
use Joomla\AI\Provider\AnthropicProvider;
use Joomla\AI\Provider\OllamaProvider;

// Configure multiple providers
$providers = [
'openai' => new OpenAIProvider(['api_key' => getenv('OPENAI_API_KEY')]),
'anthropic' => new AnthropicProvider(['api_key' => getenv('ANTHROPIC_API_KEY')]),
'ollama' => new OllamaProvider() // Local server, no API key needed
];

$question = "What is Joomla?";

foreach ($providers as $name => $provider) {
try {
$response = $provider->chat($question);
echo "\n=== {$name} ===\n";
echo $response->getContent() . "\n";
} catch (Exception $e) {
echo "{$name}: Error - " . $e->getMessage() . "\n";
}
}
```

## Working with Different Capabilities

### Image Generation

```php
use Joomla\AI\Provider\OpenAIProvider;

$openai = new OpenAIProvider(['api_key' => getenv('OPENAI_API_KEY')]);

// Generate an image
$image = $openai->generateImage("A beautiful sunset over mountains", [
'model' => 'dall-e-3',
'size' => '1024x1024',
'response_format' => 'b64_json'
]);

// Save the image
$image->saveFile('my_sunset.png');
echo "Image saved as my_sunset.png\n";
```

### Text-to-Speech

```php
$audio = $openai->speech("Welcome to Joomla! This is a text-to-speech demo.", [
'model' => 'tts-1',
'voice' => 'alloy',
'response_format' => 'mp3'
]);

$audio->saveFile('welcome.mp3');
echo "Audio saved as welcome.mp3\n";
```

### Vision (Image Analysis)

```php
$vision = $openai->vision(
"What do you see in this image?",
"https://example.com/your-image.jpg"
);

echo "Vision analysis: " . $vision->getContent() . "\n";
```

## Setting Default Models

Avoid repeating model names by setting defaults:

```php
$openai = new OpenAIProvider(['api_key' => getenv('OPENAI_API_KEY')]);

// Set a default model for all chat requests
$openai->setDefaultModel('gpt-4o-mini');

// These will use gpt-4o-mini
$response1 = $openai->chat("Hello!");
$response2 = $openai->chat("How are you?");

// Override the default for one request
$response3 = $openai->chat("Complex task", ['model' => 'gpt-4o']);

// Back to default
$response4 = $openai->chat("Simple task");

// Clear the default
$openai->unsetDefaultModel();
```

## Error Handling

The framework provides specific exceptions that are inherited from [`AIException`](../src/Exception/AIException.php):

```php
use Joomla\AI\Exception\AuthenticationException;
use Joomla\AI\Exception\RateLimitException;
use Joomla\AI\Exception\QuotaExceededException;
use Joomla\AI\Exception\InvalidArgumentException;
use Joomla\AI\Exception\ProviderException;

try {
$response = $openai->chat("Hello!");
echo $response->getContent();
} catch (AuthenticationException $e) {
echo "Authentication failed: Check your API key\n";
} catch (RateLimitException $e) {
echo "Rate limited: Please wait before trying again\n";
} catch (QuotaExceededException $e) {
echo "Quota exceeded: Check your billing\n";
} catch (InvalidArgumentException $e) {
echo "Invalid input: " . $e->getMessage() . "\n";
} catch (ProviderException $e) {
echo "Provider error: " . $e->getMessage() . "\n";
} catch (Exception $e) {
echo "Unexpected error: " . $e->getMessage() . "\n";
}
```

## Local Development with Ollama

For local AI without API costs:

1. **Install Ollama**: Download from https://ollama.ai/
2. **Pull a model**: `ollama pull llama3`
3. **Use in your code**:

```php
use Joomla\AI\Provider\OllamaProvider;

$ollama = new OllamaProvider();

$response = $ollama->chat("Hello!", ['model' => 'llama3']);
echo $response->getContent();
```

## Response Object

All methods return a unified [`Response`](../src/Response/Response.php) object:

```php
$response = $provider->chat("Hello!");

// Primary content
echo $response->getContent();

// Provider metadata (model, usage, etc.)
$metadata = $response->getMetadata();
print_r($metadata);

// Provider name
echo $response->getProvider(); // "OpenAI", "Anthropic", or "Ollama"

// Save files (for images, audio)
$response->saveFile('output.png');
```

## Next Steps

Now that you have the basics working:

- **[Provider Guides](providers/)** - Provider-specific features and limitations

## Troubleshooting

**API Key Issues:**
- Ensure environment variables are set correctly
- Restart your terminal/web server after setting environment variables
- Check that your API keys have sufficient credits/permissions

**Model Issues:**
- Verify the model name is correct and available
- Some models may require special access or billing setup
4 changes: 4 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
* [Overview](overview.md)
* [Getting Started](getting-started.md)
* [Open AI Provider](providers/openai.md)
* [Anthropic Provider](providers/anthropic.md)
* [Ollama](providers/ollama.md)
Loading
Loading