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 { $account = ladill_account(); if (! $account) { return ['signed_in' => 'no']; } $links = $account->shortLinks(); $ctx = [ 'signed_in' => 'yes', 'links_total' => (clone $links)->count(), 'links_active' => (clone $links)->where('is_active', true)->count(), 'clicks_total' => (int) (clone $links)->sum('clicks_total'), 'custom_domains' => $account->linkCustomDomains()->count(), 'price_per_link_ghs' => number_format(LinkWallet::pricePerLink(), 2), 'default_public_domain' => (string) config('link.public_domain', 'ladl.link'), ]; if ($account->public_id) { try { $ctx['wallet_balance_ghs'] = number_format(app(BillingClient::class)->balanceMinor((string) $account->public_id) / 100, 2); } catch (\Throwable) { } } $recent = $account->shortLinks() ->latest('updated_at') ->limit(3) ->get(['slug', 'label', 'clicks_total', 'source_app', 'is_managed_here']); if ($recent->isNotEmpty()) { $ctx['recent_links'] = $recent->map(fn (ShortLink $link): string => sprintf( '%s → %s (%d clicks%s)', $link->label ?: $link->slug, $link->publicUrl($account), $link->clicks_total, $link->is_managed_here ? '' : ', managed in '.$link->sourceAppLabel(), ))->implode('; '); } return $ctx; } }