NODEDC_1C/llm_normalizer/backend/dist/services/assistantLivingChatLlmRunti...

70 lines
4.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runAssistantLivingChatLlmRuntime = runAssistantLivingChatLlmRuntime;
const DEFAULT_LIVING_CHAT_TEMPERATURE = 0.35;
const DEFAULT_LIVING_CHAT_MAX_OUTPUT_TOKENS = 420;
const LIVING_CHAT_MAX_TOKENS_MIN = 120;
const LIVING_CHAT_MAX_TOKENS_MAX = 900;
const LIVING_CHAT_SYSTEM_PROMPT_PARTS = [
'Ты живой русскоязычный ассистент для чтения и анализа данных 1С.',
'Работай честно: не заявляй действия, которые недоступны в этом рантайме.',
'Разрешено: анализ и объяснение данных, формулировка запросов, подсказки по следующему шагу.',
'Запрещено: обещать настройку 1С, админ-действия, создание/проведение документов или любые изменения в базе.',
'Если пользователь спрашивает про возможности, отвечай только по этому контракту.'
];
const LIVING_CHAT_DEVELOPER_PROMPT = 'Формат: коротко и по сути, без JSON и без служебных блоков. Пиши человеко-понятно.';
const LIVING_CHAT_FALLBACK_REPLY = 'Понял. Сформулируйте, что именно нужно по данным 1С, и я помогу по шагам.';
function clampLivingChatMaxOutputTokens(value) {
const numeric = Number(value ?? DEFAULT_LIVING_CHAT_MAX_OUTPUT_TOKENS);
return Math.max(LIVING_CHAT_MAX_TOKENS_MIN, Math.min(numeric, LIVING_CHAT_MAX_TOKENS_MAX));
}
function compactWhitespace(value) {
return String(value ?? "")
.replace(/\s+/g, " ")
.trim();
}
function buildLivingChatContextWindow(items) {
const source = Array.isArray(items) ? items.slice(-6) : [];
const lines = [];
for (const item of source) {
if (!item || typeof item !== "object") {
continue;
}
const role = String(item.role ?? "").trim();
const text = compactWhitespace(String(item.text ?? ""));
if (!role || !text) {
continue;
}
const clipped = text.length > 220 ? `${text.slice(0, 220)}...` : text;
lines.push(`${role}: ${clipped}`);
}
return lines.join("\n");
}
function buildLivingChatPrompt(userMessage, conversationWindow) {
const contextBlock = conversationWindow ? `Контекст последних сообщений:\n${conversationWindow}\n\n` : "";
return `${contextBlock}Сообщение пользователя:\n${userMessage}`;
}
async function runAssistantLivingChatLlmRuntime(input) {
const conversationWindow = buildLivingChatContextWindow(input.sessionItems);
const userPrompt = buildLivingChatPrompt(input.userMessage, conversationWindow);
const canonExcerpt = input.loadAssistantCanonExcerpt(520);
const maxOutputTokens = clampLivingChatMaxOutputTokens(input.payload.maxOutputTokens);
const temperature = input.payload.temperature ?? DEFAULT_LIVING_CHAT_TEMPERATURE;
const systemPrompt = [...LIVING_CHAT_SYSTEM_PROMPT_PARTS, `Канон поведения: ${canonExcerpt}`].join(" ");
const chatResponse = await input.chatClient.chat({
llmProvider: input.payload.llmProvider,
apiKey: String(input.payload.apiKey ?? input.defaultApiKey ?? ""),
model: String(input.payload.model ?? input.defaultModel),
baseUrl: input.payload.baseUrl ?? input.defaultBaseUrl,
temperature,
maxOutputTokens
}, {
systemPrompt,
developerPrompt: LIVING_CHAT_DEVELOPER_PROMPT,
userMessage: userPrompt,
maxOutputTokens,
temperature
});
return input.sanitizeOutgoingAssistantText(chatResponse?.outputText ?? "", LIVING_CHAT_FALLBACK_REPLY);
}