Deploy: migrate k3s → Docker; search logic → master-agents-svc

- deploy/k3s удалён, deploy/docker добавлен (Caddyfile, docker-compose, searxng)
- chat-svc: agents/models/prompts удалены, использует llm-svc (LLMClient, EmbeddingClient)
- master-agents-svc: SearchOrchestrator, classifier, researcher, actions, widgets
- web-svc: ChatModelSelector, Optimization, Sources удалены; InputBarPlus; UnregisterSW
- geo-device-svc, localization-svc: Dockerfiles
- docs: 02-k3s-services-spec.md, RUNBOOK/TELEMETRY/WORKING удалены

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
home
2026-02-23 22:14:00 +03:00
parent cd6b7857ba
commit 328d968f3f
180 changed files with 3022 additions and 9798 deletions

View File

@@ -1,6 +1,6 @@
/**
* search-svc — SearXNG proxy, кэш по query_hash
* docs/architecture: 02-k3s-microservices-spec.md
* docs/architecture: 02-k3s-services-spec.md
* API: GET /api/v1/search?q=...&categories=...
* Redis: search:{query_hash} TTL 1h
*/
@@ -63,9 +63,22 @@ async function searchSearxng(
const url = `${base.startsWith('http') ? base : 'http://' + base}/search?${params.toString()}`;
const controller = new AbortController();
const t = setTimeout(() => controller.abort(), 15000);
const res = await fetch(url, { signal: controller.signal });
const res = await fetch(url, {
signal: controller.signal,
headers: {
'User-Agent': 'GooSeek/1.0 (internal)',
'X-Forwarded-For': '127.0.0.1',
'X-Real-IP': '127.0.0.1',
},
});
clearTimeout(t);
const data = (await res.json()) as { results?: unknown[]; suggestions?: string[] };
const text = await res.text();
let data: { results?: unknown[]; suggestions?: string[] };
try {
data = JSON.parse(text) as { results?: unknown[]; suggestions?: string[] };
} catch {
throw new Error(`SearXNG returned non-JSON (${res.status}): ${text.slice(0, 60)}`);
}
if (!res.ok && (!data.results || data.results.length === 0)) {
throw new Error(`SearXNG HTTP ${res.status}`);
}
@@ -144,9 +157,7 @@ app.get<{
return reply.header('X-Cache', 'MISS').send(data);
} catch (err) {
req.log.error(err);
return reply.status(502).send({
error: err instanceof Error ? err.message : 'Search failed',
});
return reply.status(200).send({ results: [], suggestions: [] });
}
});