as('web_search') ->for('Sucht im Web via SearXNG (Meta-Suchmaschine, lokal) und gibt die besten Treffer zurück.') ->withStringParameter('query', 'Die Suchanfrage') ->using(fn (string $query) => $this->execute($query)); } public function execute(string $query): string { try { $response = Http::timeout(15) ->acceptJson() ->get(rtrim(config('services.searxng.url'), '/').'/search', [ 'q' => $query, 'format' => 'json', 'language' => 'de', 'pageno' => 1, ]); } catch (\Throwable $e) { Log::warning('SearXNG nicht erreichbar', ['error' => $e->getMessage()]); return 'Suche fehlgeschlagen: '.$e->getMessage(); } if (! $response->successful()) { return 'Suche fehlgeschlagen (HTTP '.$response->status().').'; } $results = $response->json('results', []); if (empty($results)) { return 'Keine Treffer für: '.$query; } $lines = []; foreach (array_slice($results, 0, 5) as $i => $hit) { $lines[] = sprintf( "%d. %s\n %s\n %s", $i + 1, $hit['title'] ?? '(ohne Titel)', $hit['url'] ?? '', trim((string) ($hit['content'] ?? '')), ); } return implode("\n\n", $lines); } }