# QFOXAI Laravel Package Starter

Use this as the starting point for an official `qfoxai/laravel` integration package or copy the service class directly into an app.

## Install Plan

```bash
composer require openai-php/client
php artisan vendor:publish --tag=qfoxai-config
```

## Environment

```env
QFOXAI_API_KEY=qf_your_full_secret_key
QFOXAI_BASE_URL=https://qfoxai.com/v1
QFOXAI_MODEL=QFOXAI
```

## config/qfoxai.php

```php
return [
    'api_key' => env('QFOXAI_API_KEY'),
    'base_url' => rtrim(env('QFOXAI_BASE_URL', 'https://qfoxai.com/v1'), '/'),
    'model' => env('QFOXAI_MODEL', 'QFOXAI'),
    'timeout' => (int) env('QFOXAI_TIMEOUT', 90),
];
```

## app/Services/Qfoxai.php

```php
namespace App\Services;

use Illuminate\Support\Facades\Http;
use RuntimeException;

class Qfoxai
{
    public function chat(string $prompt, array $options = []): string
    {
        $payload = array_merge([
            'model' => config('qfoxai.model'),
            'messages' => [
                ['role' => 'user', 'content' => $prompt],
            ],
            'max_tokens' => 600,
        ], $options);

        $response = Http::withToken(config('qfoxai.api_key'))
            ->acceptJson()
            ->timeout(config('qfoxai.timeout'))
            ->retry(2, 300)
            ->post(config('qfoxai.base_url') . '/chat/completions', $payload);

        if ($response->failed()) {
            throw new RuntimeException($response->json('error.message') ?: 'QFOXAI request failed.');
        }

        return (string) data_get($response->json(), 'choices.0.message.content', '');
    }
}
```

## Controller Example

```php
use App\Services\Qfoxai;
use Illuminate\Http\Request;

Route::post('/ai/reply', function (Request $request, Qfoxai $qfoxai) {
    $request->validate(['message' => 'required|string|max:4000']);

    return [
        'answer' => $qfoxai->chat($request->string('message')->toString()),
    ];
});
```

## Production Checklist

- Store the `qf_...` API key server-side only.
- Use `/v1` as the base URL; do not append `/chat/completions` twice.
- Log `X-QFOXAI-Request-ID` when support debugging is needed.
- Use `GET /v1/key` to show quota and upgrade messages.
- Add a queue job for long-running background AI tasks.
- Use public aliases from `GET /v1/models`, never private provider model names. An unavailable alias returns `403 model_not_allowed`.