98 lines
2.5 KiB
PHP
Executable File
98 lines
2.5 KiB
PHP
Executable File
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\AiModel;
|
|
use App\Models\AiProvider;
|
|
use App\Services\Ai\AiServiceFactory;
|
|
use Illuminate\Http\Client\ConnectionException;
|
|
use Illuminate\Support\Facades\Log;
|
|
use RuntimeException;
|
|
|
|
class ChatService
|
|
{
|
|
private const SESSION_KEY = 'chat_conversation';
|
|
|
|
public function __construct(
|
|
private readonly AiServiceFactory $aiServiceFactory
|
|
) {}
|
|
|
|
/**
|
|
* Get conversation history from session.
|
|
*
|
|
* @return array<int, array{role: string, content: string}>
|
|
*/
|
|
public function getHistory(): array
|
|
{
|
|
return session()->get(self::SESSION_KEY, []);
|
|
}
|
|
|
|
/**
|
|
* Reset conversation history.
|
|
*/
|
|
public function reset(): void
|
|
{
|
|
session()->forget(self::SESSION_KEY);
|
|
}
|
|
|
|
/**
|
|
* Send a message and get AI response.
|
|
*
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function sendMessage(
|
|
string $userMessage,
|
|
AiProvider $provider,
|
|
AiModel $model,
|
|
float $temperature = 0.7,
|
|
int $maxTokens = 8192
|
|
): array {
|
|
$history = $this->getHistory();
|
|
|
|
$history[] = ['role' => 'user', 'content' => $userMessage];
|
|
|
|
$startTime = microtime(true);
|
|
|
|
try {
|
|
$service = $this->aiServiceFactory->make($provider);
|
|
$result = $service->chat($history, [
|
|
'temperature' => $temperature,
|
|
'max_tokens' => $maxTokens,
|
|
'model' => $model->slug,
|
|
'api_key' => $provider->api_key,
|
|
'base_url' => $provider->base_url,
|
|
]);
|
|
} catch (ConnectionException|RuntimeException $e) {
|
|
Log::error('Chat API error: ' . $e->getMessage());
|
|
|
|
return [
|
|
'success' => false,
|
|
'error' => $e->getMessage(),
|
|
'content' => '',
|
|
'role' => 'assistant',
|
|
'tokens_used' => null,
|
|
'generation_time' => round(microtime(true) - $startTime, 3),
|
|
];
|
|
}
|
|
|
|
$assistantMessage = [
|
|
'role' => 'assistant',
|
|
'content' => $result['content'] ?? '',
|
|
];
|
|
|
|
$history[] = $assistantMessage;
|
|
|
|
session()->put(self::SESSION_KEY, $history);
|
|
|
|
return [
|
|
'success' => true,
|
|
'content' => $result['content'] ?? '',
|
|
'role' => 'assistant',
|
|
'tokens_used' => $result['tokens_used'] ?? null,
|
|
'generation_time' => round(microtime(true) - $startTime, 3),
|
|
];
|
|
}
|
|
}
|