validate([ 'message' => ['required', 'string', 'max:2000'], 'history' => ['nullable', 'array', 'max:20'], 'history.*.role' => ['nullable', 'string'], 'history.*.text' => ['nullable', 'string'], ]); if (! $afia->enabled()) { return response()->json(['message' => 'Afia is not available right now.'], 503); } try { $reply = $afia->chat(trim($validated['message']), $validated['history'] ?? [], $this->context()); } catch (\Throwable $e) { report($e); return response()->json(['message' => 'Afia could not respond right now. Please try again.'], 502); } return response()->json(['reply' => $reply]); } /** @return array */ private function context(): array { $user = auth()->user(); if (! $user) { return ['signed_in' => 'no']; } $sharedTypes = [ HostingProduct::TYPE_SINGLE_DOMAIN, HostingProduct::TYPE_MULTI_DOMAIN, HostingProduct::TYPE_WORDPRESS, ]; $sharedAccountIds = HostingAccountMember::query() ->where('user_id', $user->id) ->pluck('hosting_account_id'); $accounts = HostingAccount::query() ->where(function ($query) use ($user, $sharedAccountIds) { $query->where('user_id', $user->id); if ($sharedAccountIds->isNotEmpty()) { $query->orWhereIn('id', $sharedAccountIds); } }) ->whereHas('product', fn ($q) => $q->whereIn('type', $sharedTypes)) ->with('sites') ->get(); $ctx = [ 'signed_in' => 'yes', 'hosting_accounts_total' => $accounts->count(), 'hosting_accounts_active' => $accounts->where('status', HostingAccount::STATUS_ACTIVE)->count(), 'linked_domains' => HostedSite::query() ->whereIn('hosting_account_id', $accounts->pluck('id')) ->count(), 'pending_orders' => CustomerHostingOrder::query() ->forUser($user->id) ->whereIn('status', [ CustomerHostingOrder::STATUS_PENDING_PAYMENT, CustomerHostingOrder::STATUS_PENDING_APPROVAL, CustomerHostingOrder::STATUS_APPROVED, CustomerHostingOrder::STATUS_PROVISIONING, ]) ->count(), ]; $account = ladill_account(); if ($account?->public_id) { try { $ctx['wallet_balance_ghs'] = number_format(app(BillingClient::class)->balanceMinor((string) $account->public_id) / 100, 2); } catch (\Throwable) { } } return $ctx; } }