You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
4.9 KiB
145 lines
4.9 KiB
<?php |
|
|
|
namespace App\Http\Controllers; |
|
|
|
use App\Services\AuditLogService; |
|
use App\Services\ProjectSearchChatService; |
|
use App\Services\ProjectSearchService; |
|
use Illuminate\Http\JsonResponse; |
|
use Illuminate\Http\Request; |
|
use Illuminate\View\View; |
|
use RuntimeException; |
|
use Throwable; |
|
|
|
class ProjectSearchController extends Controller |
|
{ |
|
public function __construct( |
|
private readonly ProjectSearchService $projectSearch, |
|
private readonly ProjectSearchChatService $chat, |
|
private readonly AuditLogService $audit |
|
) { |
|
} |
|
|
|
public function index(Request $request): View |
|
{ |
|
$username = (string) $request->session()->get('ldap_username', ''); |
|
$indexRuns = $this->projectSearch->isAvailable() |
|
? $this->projectSearch->indexStatus() |
|
: []; |
|
|
|
$activeSession = $username !== '' && $this->chat->isAvailable() |
|
? $this->chat->activeSession($username) |
|
: null; |
|
|
|
$messages = $activeSession !== null |
|
? $this->chat->messagesForSessionId((int) $activeSession['id']) |
|
: []; |
|
|
|
$chatHistory = $username !== '' && $this->chat->isAvailable() |
|
? $this->chat->recentEndedSessions($username, 8) |
|
: []; |
|
|
|
return view('project-search.index', [ |
|
'sources' => $this->projectSearch->listSources(), |
|
'indexRuns' => array_slice($indexRuns, 0, 5), |
|
'indexAvailable' => $this->projectSearch->isAvailable(), |
|
'chatAvailable' => $this->chat->isAvailable(), |
|
'ollamaConfigured' => (string) config('ollama.base_url') !== '', |
|
'oauthClientId' => (string) config('project_search.oauth_client_id'), |
|
'oauthScope' => (string) config('project_search.oauth_scope'), |
|
'oauthTokenUrl' => rtrim((string) config('app.url'), '/').'/oauth/token', |
|
'activeSession' => $activeSession, |
|
'messages' => $messages, |
|
'chatHistory' => $chatHistory, |
|
]); |
|
} |
|
|
|
public function ask(Request $request): JsonResponse |
|
{ |
|
$validated = $request->validate([ |
|
'query' => ['required', 'string', 'min:3', 'max:500'], |
|
'sources' => ['sometimes', 'array'], |
|
'sources.*' => ['string', 'max:64'], |
|
'limit' => ['sometimes', 'integer', 'min:1', 'max:50'], |
|
]); |
|
|
|
$username = (string) $request->session()->get('ldap_username', ''); |
|
if ($username === '') { |
|
return response()->json(['message' => 'Sesi login tidak valid.'], 401); |
|
} |
|
|
|
try { |
|
$sources = $validated['sources'] ?? []; |
|
$session = $this->chat->getOrCreateActiveSession($username, $sources); |
|
$sessionId = (int) $session['id']; |
|
|
|
$history = $this->chat->conversationHistoryForOllama($sessionId); |
|
$userMessage = $this->chat->addUserMessage($sessionId, $validated['query']); |
|
|
|
$result = $this->projectSearch->ask( |
|
$validated['query'], |
|
$sources, |
|
(int) ($validated['limit'] ?? config('project_search.default_limit', 20)), |
|
$history |
|
); |
|
|
|
$assistantMessage = $this->chat->addAssistantMessage( |
|
$sessionId, |
|
$result['answer'], |
|
$result['results'], |
|
$result['meta'] |
|
); |
|
|
|
$this->audit->log( |
|
'project_search.chat.ask', |
|
'web', |
|
$username, |
|
null, |
|
'project_search', |
|
$request, |
|
200, |
|
[ |
|
'session_id' => $sessionId, |
|
'query' => $validated['query'], |
|
'result_count' => $result['meta']['result_count'] ?? 0, |
|
'sources' => $result['meta']['sources'] ?? [], |
|
] |
|
); |
|
|
|
return response()->json([ |
|
'session' => $session, |
|
'user_message' => $userMessage, |
|
'assistant_message' => $assistantMessage, |
|
]); |
|
} catch (RuntimeException $e) { |
|
return response()->json(['message' => $e->getMessage()], 422); |
|
} catch (Throwable) { |
|
return response()->json(['message' => 'Gagal memproses pencarian proyek.'], 500); |
|
} |
|
} |
|
|
|
public function endChat(Request $request): JsonResponse |
|
{ |
|
$username = (string) $request->session()->get('ldap_username', ''); |
|
if ($username === '') { |
|
return response()->json(['message' => 'Sesi login tidak valid.'], 401); |
|
} |
|
|
|
$ended = $this->chat->endActiveSession($username); |
|
|
|
if ($ended) { |
|
$this->audit->log( |
|
'project_search.chat.end', |
|
'web', |
|
$username, |
|
null, |
|
'project_search', |
|
$request, |
|
200, |
|
[] |
|
); |
|
} |
|
|
|
return response()->json(['ended' => $ended]); |
|
} |
|
}
|
|
|