ChatbotController.php 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Services\GeminiService;
  4. use Illuminate\Http\JsonResponse;
  5. use Illuminate\Http\Request;
  6. use Illuminate\Support\Facades\Auth;
  7. class ChatbotController extends Controller
  8. {
  9. private const MESSAGE_MAX_LENGTH = 4000;
  10. private const HISTORY_TEXT_MAX_LENGTH = 20000;
  11. private const HISTORY_MAX_ENTRIES = 200;
  12. private const HISTORY_TOTAL_MAX_LENGTH = 40000;
  13. public function __construct(
  14. private readonly GeminiService $geminiService,
  15. ) {}
  16. public function message(Request $request): JsonResponse
  17. {
  18. $this->applyHistoryWindow($request);
  19. $validated = $request->validate([
  20. 'message' => ['required', 'string', 'max:' . self::MESSAGE_MAX_LENGTH],
  21. 'history' => ['sometimes', 'array', 'max:' . self::HISTORY_MAX_ENTRIES],
  22. 'history.*.role' => ['required_with:history', 'string', 'in:user,model'],
  23. 'history.*.text' => ['required_with:history', 'string', 'max:' . self::HISTORY_TEXT_MAX_LENGTH],
  24. ]);
  25. $user = Auth::user();
  26. $reply = $this->geminiService->sendMessage(
  27. message: data_get($validated, 'message'),
  28. userType: $user->type,
  29. history: data_get($validated, 'history', []),
  30. );
  31. return $this->successResponse(payload: ['reply' => $reply]);
  32. }
  33. //
  34. private function applyHistoryWindow(Request $request): void
  35. {
  36. $history = $request->input('history');
  37. if (! is_array($history)) {
  38. return;
  39. }
  40. $window = [];
  41. $total = 0;
  42. foreach (array_reverse($history) as $entry) {
  43. $text = data_get($entry, 'text');
  44. $length = is_string($text) ? mb_strlen($text) : 0;
  45. $exceedsEntries = count($window) >= self::HISTORY_MAX_ENTRIES;
  46. $exceedsLength = $window !== [] && $total + $length > self::HISTORY_TOTAL_MAX_LENGTH;
  47. if ($exceedsEntries || $exceedsLength) {
  48. break;
  49. }
  50. $window[] = $entry;
  51. $total += $length;
  52. }
  53. $request->merge(['history' => array_reverse($window)]);
  54. }
  55. }