Files
2026-09-01 07:49:48 -03:00

160 lines
5.0 KiB
PHP
Executable File

<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Http\Validation\ContentFilterRule;
use App\Models\ChatMessage;
use App\Models\TokenUsage;
use App\Services\AIService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule as ValidationRule;
use Illuminate\View\View;
/**
* Controller for the AI Chat feature.
* Allows users to chat with registered AI models.
*/
class ChatController extends Controller
{
/**
* Display the AI chat interface.
*/
public function index(): View
{
/** @var \App\Models\User $user */
$user = Auth::user();
// Get available AI providers from config
$providers = config('services.ai.providers', []);
// Get user's chat history
$chatHistory = ChatMessage::where('user_id', $user->id)
->orderBy('created_at', 'asc')
->take(50)
->get();
// Get chat default provider/model from DB, fallback to config
$defaultProvider = \App\Models\Setting::where('key', 'chat_default_provider')->value('value');
$defaultModel = \App\Models\Setting::where('key', 'chat_default_model')->value('value');
if (!$defaultProvider) {
$defaultProvider = config('services.ai.default_provider', 'openrouter');
}
if (!$defaultModel) {
$defaultModel = config('services.ai.providers.'.$defaultProvider.'.model', 'inclusionai/ling-3.0-tiny:free');
}
return view('dashboard.chat', compact(
'providers',
'chatHistory',
'defaultProvider',
'defaultModel'
));
}
/**
* Send a message to the AI and get a response.
*/
public function store(Request $request): \Illuminate\Http\RedirectResponse
{
/** @var \App\Models\User $user */
$user = Auth::user();
$validated = $request->validate([
'message' => ['required', 'string', 'max:4000', new ContentFilterRule()],
]);
$message = trim($validated['message']);
// Use chat default provider/model from DB
$defaultProvider = \App\Models\Setting::where('key', 'chat_default_provider')->value('value');
$defaultModel = \App\Models\Setting::where('key', 'chat_default_model')->value('value');
if (!$defaultProvider) {
$defaultProvider = config('services.ai.default_provider', 'openrouter');
}
if (!$defaultModel) {
$defaultModel = config('services.ai.providers.'.$defaultProvider.'.model', 'inclusionai/ling-3.0-tiny:free');
}
// Build conversation history for context
$recentMessages = ChatMessage::where('user_id', $user->id)
->orderByDesc('created_at')
->take(10)
->get()
->reverse()
->values();
$messages = [];
foreach ($recentMessages as $chat) {
$messages[] = ['role' => 'user', 'content' => $chat->message];
if ($chat->response) {
$messages[] = ['role' => 'assistant', 'content' => $chat->response];
}
}
$messages[] = ['role' => 'user', 'content' => $message];
// Initialize AI service with selected provider and model
$aiService = new AIService($defaultProvider, $defaultModel);
// Use the chat completion endpoint directly
$result = $aiService->chat($messages);
if (!$result['success']) {
return back()->with('error', __('Failed to get response: :error', [
'error' => $result['error'] ?? __('Unknown error'),
]));
}
$response = $result['content'];
$inputTokens = $result['input_tokens'] ?? 0;
$outputTokens = $result['output_tokens'] ?? 0;
$model = $defaultModel;
$provider = $defaultProvider;
// Save chat message
ChatMessage::create([
'user_id' => $user->id,
'message' => $message,
'response' => $response,
'provider' => $provider,
'model' => $model,
'input_tokens' => $inputTokens,
'output_tokens' => $outputTokens,
'sent_at' => now(),
]);
// Track token usage
if ($inputTokens > 0 || $outputTokens > 0) {
TokenUsage::create([
'user_id' => $user->id,
'input_tokens' => $inputTokens,
'output_tokens' => $outputTokens,
'total_tokens' => $inputTokens + $outputTokens,
'model' => $model,
'provider' => $provider,
]);
}
return back()->with('success', __('Message sent successfully!'));
}
/**
* Clear chat history.
*/
public function destroy(Request $request): \Illuminate\Http\RedirectResponse
{
/** @var \App\Models\User $user */
$user = Auth::user();
ChatMessage::where('user_id', $user->id)->delete();
return back()->with('success', __('Chat history cleared.'));
}
}