RAG: ночная пакетная индексация эмбеддингов, очередь embedding_queue, MCP get_organization_context, снижение OLLAMA_KEEP_ALIVE
This commit is contained in:
@@ -1,22 +1,10 @@
|
||||
import type { Request } from 'express';
|
||||
import { storage } from "../storage";
|
||||
import {
|
||||
buildFormText, generateFormSummary, upsertEmbedding, buildTaskText,
|
||||
} from "../services/embedding.service";
|
||||
import { generateFormSummary } from "../services/embedding.service";
|
||||
|
||||
async function indexFormAsync(formId: number, organizationId: number): Promise<void> {
|
||||
try {
|
||||
const [form, fields, statuses] = await Promise.all([
|
||||
storage.getForm(formId, organizationId),
|
||||
storage.getFormFields(formId, organizationId),
|
||||
storage.getFormStatuses(formId, organizationId),
|
||||
]);
|
||||
if (!form) return;
|
||||
const content = buildFormText(form, fields, statuses);
|
||||
await upsertEmbedding(organizationId, 'form', formId, content, {
|
||||
name: form.name,
|
||||
description: form.description,
|
||||
});
|
||||
await storage.enqueueEmbedding(organizationId, 'form', formId, 'upsert');
|
||||
} catch (err) {
|
||||
console.error('[RAG] indexFormAsync error:', err);
|
||||
}
|
||||
@@ -24,22 +12,20 @@ async function indexFormAsync(formId: number, organizationId: number): Promise<v
|
||||
|
||||
async function indexFormWithSummaryAsync(formId: number, organizationId: number): Promise<void> {
|
||||
try {
|
||||
// Summary generation uses external chat provider (Kimi), so it can stay synchronous.
|
||||
const [form, fields, statuses] = await Promise.all([
|
||||
storage.getForm(formId, organizationId),
|
||||
storage.getFormFields(formId, organizationId),
|
||||
storage.getFormStatuses(formId, organizationId),
|
||||
]);
|
||||
if (!form) return;
|
||||
const summary = await generateFormSummary(form, fields, statuses);
|
||||
if (summary) {
|
||||
await storage.updateForm(formId, organizationId, { aiSummary: summary, aiSummaryIsAuto: true });
|
||||
if (form) {
|
||||
const summary = await generateFormSummary(form, fields, statuses);
|
||||
if (summary) {
|
||||
await storage.updateForm(formId, organizationId, { aiSummary: summary, aiSummaryIsAuto: true });
|
||||
}
|
||||
}
|
||||
const indexedForm = summary ? { ...form, aiSummary: summary } : form;
|
||||
const content = buildFormText(indexedForm, fields, statuses);
|
||||
await upsertEmbedding(organizationId, 'form', formId, content, {
|
||||
name: form.name,
|
||||
description: form.description,
|
||||
});
|
||||
// Actual embedding is deferred to the nightly batch.
|
||||
await storage.enqueueEmbedding(organizationId, 'form', formId, 'upsert');
|
||||
} catch (err) {
|
||||
console.error('[RAG] indexFormWithSummaryAsync error:', err);
|
||||
}
|
||||
@@ -47,40 +33,7 @@ async function indexFormWithSummaryAsync(formId: number, organizationId: number)
|
||||
|
||||
async function indexTaskAsync(taskId: number, organizationId: number): Promise<void> {
|
||||
try {
|
||||
const task = await storage.getTask(taskId, organizationId);
|
||||
if (!task) return;
|
||||
const [form, statuses, users, fieldValues, formFields] = await Promise.all([
|
||||
storage.getForm(task.formId, organizationId),
|
||||
storage.getFormStatuses(task.formId, organizationId),
|
||||
storage.getUsersByOrganization(organizationId),
|
||||
storage.getTaskFieldValues(taskId, organizationId),
|
||||
storage.getFormFields(task.formId, organizationId),
|
||||
]);
|
||||
if (!form) return;
|
||||
const statusMap = new Map(statuses.map(s => [s.id, s.name]));
|
||||
const usersMap = new Map(users.map(u => [u.id, u]));
|
||||
const assigneeUser = task.assignedTo ? usersMap.get(task.assignedTo) : null;
|
||||
const assigneeName = assigneeUser
|
||||
? `${assigneeUser.firstName ?? ''} ${assigneeUser.middleName ?? ''} ${assigneeUser.lastName ?? ''}`.trim() || assigneeUser.email
|
||||
: null;
|
||||
const fieldMap = new Map(formFields.map(f => [f.id, f]));
|
||||
const enrichedFieldValues = fieldValues.map(fv => ({
|
||||
name: fieldMap.get(fv.fieldId)?.name ?? '',
|
||||
value: fv.value,
|
||||
type: fieldMap.get(fv.fieldId)?.type ?? 'text',
|
||||
}));
|
||||
const content = buildTaskText(
|
||||
task,
|
||||
form.name,
|
||||
statusMap.get(task.currentStatusId) ?? '',
|
||||
assigneeName,
|
||||
enrichedFieldValues
|
||||
);
|
||||
await upsertEmbedding(organizationId, 'task', taskId, content, {
|
||||
formId: task.formId,
|
||||
formName: form.name,
|
||||
title: task.title,
|
||||
});
|
||||
await storage.enqueueEmbedding(organizationId, 'task', taskId, 'upsert');
|
||||
} catch (err) {
|
||||
console.error('[RAG] indexTaskAsync error:', err);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user