import { config } from "../config/index.js"; import { embedTexts } from "../services/ollamaClient.js"; import { qdrant } from "../services/qdrantClient.js"; import fs from "node:fs"; function isRefusalText(text) { const t = String(text ?? "").toLowerCase(); return ( t.includes("desculpe") && (t.includes("não posso") || t.includes("nao posso") || t.includes("não posso fornecer") || t.includes("nao posso fornecer")) ); } export async function searchDocs({ query, topK }) { const collectionName = config.qdrant.collection; // #region debug-point C:image-rag-search-start (() => { let u = "http://127.0.0.1:7777/event"; let s = "image-rag-miss"; try { const e = fs.readFileSync(".dbg/image-rag-miss.env", "utf8"); u = e.match(/DEBUG_SERVER_URL=(.+)/)?.[1] || u; s = e.match(/DEBUG_SESSION_ID=(.+)/)?.[1] || s; } catch {} fetch(u, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ sessionId: s, runId: "post", hypothesisId: "C", location: "api/chat/searchChat.js", msg: "[DEBUG] searchDocs start", data: { collection: collectionName, topK: topK ?? config.rag.topK, queryHead: String(query ?? "").slice(0, 140) }, ts: Date.now() }) }).catch(() => {}); })(); // #endregion // #region debug-point B:search-start (() => { let u = "http://127.0.0.1:7777/event"; let s = "chat-502-gateway"; try { const e = fs.readFileSync(".dbg/chat-502-gateway.env", "utf8"); u = e.match(/DEBUG_SERVER_URL=(.+)/)?.[1] || u; s = e.match(/DEBUG_SESSION_ID=(.+)/)?.[1] || s; } catch {} fetch(u, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ sessionId: s, runId: "post-fix", hypothesisId: "B", location: "api/chat/searchChat.js", msg: "[DEBUG] searchDocs start", data: { collection: collectionName, topK: topK ?? config.rag.topK, queryLen: typeof query === "string" ? query.length : null, qdrantUrl: config.qdrant.url, ollamaUrl: config.ollama.url }, ts: Date.now() }) }).catch(() => {}); })(); // #endregion const [vector] = await embedTexts([query]); const result = await qdrant.search(collectionName, { vector, limit: topK ?? config.rag.topK, with_payload: true, with_vector: false }); // #region debug-point C:image-rag-search-result (() => { let u = "http://127.0.0.1:7777/event"; let s = "image-rag-miss"; try { const e = fs.readFileSync(".dbg/image-rag-miss.env", "utf8"); u = e.match(/DEBUG_SERVER_URL=(.+)/)?.[1] || u; s = e.match(/DEBUG_SESSION_ID=(.+)/)?.[1] || s; } catch {} const top = Array.isArray(result) && result.length ? result[0] : null; fetch(u, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ sessionId: s, runId: "post", hypothesisId: "C", location: "api/chat/searchChat.js", msg: "[DEBUG] qdrant.search result", data: { count: Array.isArray(result) ? result.length : null, topScore: top?.score ?? null, topSource: top?.payload?.source ?? null, topTextHead: typeof top?.payload?.text === "string" ? top.payload.text.slice(0, 160) : "" }, ts: Date.now() }) }).catch(() => {}); })(); // #endregion // #region debug-point B:search-result (() => { let u = "http://127.0.0.1:7777/event"; let s = "chat-502-gateway"; try { const e = fs.readFileSync(".dbg/chat-502-gateway.env", "utf8"); u = e.match(/DEBUG_SERVER_URL=(.+)/)?.[1] || u; s = e.match(/DEBUG_SESSION_ID=(.+)/)?.[1] || s; } catch {} fetch(u, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ sessionId: s, runId: "post-fix", hypothesisId: "B", location: "api/chat/searchChat.js", msg: "[DEBUG] qdrant.search ok", data: { count: Array.isArray(result) ? result.length : null }, ts: Date.now() }) }).catch(() => {}); })(); // #endregion return (result ?? []) .map((r) => ({ score: r.score, id: r.id, text: r.payload?.text ?? "", source: r.payload?.source ?? null, chunkIndex: r.payload?.chunkIndex ?? null, metadata: r.payload?.metadata ?? null })) .filter((h) => !isRefusalText(h.text)); }