chatChain.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import { config } from "../src/config/index.js";
  2. import { chatCompletion, chatCompletionStream } from "../src/services/ollamaClient.js";
  3. import { searchDocs } from "../chat/searchChat.js";
  4. function buildContextBlock(hits) {
  5. const lines = [];
  6. hits.forEach((h, i) => {
  7. const header = `# Fonte ${i + 1}${h.source ? ` (${h.source})` : ""}`;
  8. lines.push(header);
  9. lines.push(h.text);
  10. lines.push("");
  11. });
  12. return lines.join("\n").trim();
  13. }
  14. function buildMessages(message, context, sessionId) {
  15. const system = [
  16. "Você é um assistente de atendimento interno de uma empresa.",
  17. "Responda apenas com base no CONTEXTO quando ele estiver disponível.",
  18. "Se o CONTEXTO não tiver a informação, diga que não encontrou na base da empresa e sugira o que solicitar ao time responsável.",
  19. "Seja direto e em português."
  20. ].join("\n");
  21. return [
  22. { role: "system", content: system },
  23. ...(context ? [{ role: "system", content: `CONTEXTO:\n${context}` }] : []),
  24. ...(sessionId ? [{ role: "system", content: `session_id:${sessionId}` }] : []),
  25. { role: "user", content: message }
  26. ];
  27. }
  28. function hitsToSources(hits) {
  29. return hits.map((h) => ({
  30. id: h.id,
  31. source: h.source,
  32. score: h.score,
  33. chunkIndex: h.chunkIndex,
  34. metadata: h.metadata
  35. }));
  36. }
  37. export async function answerWithContext({ message, sessionId }) {
  38. const hits = await searchDocs({ query: message, topK: config.rag.topK });
  39. const context = buildContextBlock(hits);
  40. const messages = buildMessages(message, context, sessionId);
  41. const completion = await chatCompletion({ messages });
  42. return {
  43. answer: completion.content,
  44. sources: hitsToSources(hits)
  45. };
  46. }
  47. export async function answerWithContextStream({ message, sessionId, onChunk, signal }) {
  48. const hits = await searchDocs({ query: message, topK: config.rag.topK });
  49. const context = buildContextBlock(hits);
  50. const messages = buildMessages(message, context, sessionId);
  51. const sources = hitsToSources(hits);
  52. const completion = await chatCompletionStream({ messages, onChunk, signal });
  53. return {
  54. answer: completion.content,
  55. sources
  56. };
  57. }