First Commit
This commit is contained in:
Executable
+159
@@ -0,0 +1,159 @@
|
||||
<?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.'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user