diff --git a/server/routers/kfu-m-24-1/sber_mobile/initiatives-ai-agents/llm.ts b/server/routers/kfu-m-24-1/sber_mobile/initiatives-ai-agents/llm.ts new file mode 100644 index 0000000..a5a0e23 --- /dev/null +++ b/server/routers/kfu-m-24-1/sber_mobile/initiatives-ai-agents/llm.ts @@ -0,0 +1,22 @@ +import { GigaChat as GigaChatLang} from 'langchain-gigachat'; +import { GigaChat } from 'gigachat'; +import { Agent } from 'node:https'; + +const httpsAgent = new Agent({ + rejectUnauthorized: false, +}); + +export const llm_mod = (GIGA_AUTH) => + new GigaChatLang({ + credentials: GIGA_AUTH, + temperature: 0.2, + model: 'GigaChat-2-Max', + httpsAgent, +}); + +export const llm_gen = (GIGA_AUTH) => + new GigaChat({ + credentials: GIGA_AUTH, + model: 'GigaChat-2', + httpsAgent, +}); \ No newline at end of file diff --git a/server/routers/kfu-m-24-1/sber_mobile/initiatives-ai-agents/moderation.ts b/server/routers/kfu-m-24-1/sber_mobile/initiatives-ai-agents/moderation.ts new file mode 100644 index 0000000..48162c0 --- /dev/null +++ b/server/routers/kfu-m-24-1/sber_mobile/initiatives-ai-agents/moderation.ts @@ -0,0 +1,56 @@ +import { llm_mod } from './llm' +import { z } from "zod"; + + +// возвращаю комментарий + исправленное предложение + булево значение + +export const moderationText = async (title: string, description: string, GIGA_AUTH): Promise<[string, string | undefined, boolean]> => { + + const moderationLlm = llm_mod(GIGA_AUTH).withStructuredOutput(z.object({ + comment: z.string(), + fixedText: z.string().optional(), + isApproved: z.boolean(), + }) as any) + + const prompt = ` + Представь, что ты модерируешь предложения от жильцов многоквартирного дома (это личная инициатива по улучшения, + не имеющая отношения к Управляющей компании). + + Заголовок: ${title} + Основной текст: ${description} + + Твои задачи: + 1. Проверь предложение и заголовок на спам. + 2. Проверь, чтобы заголовок и текст были на одну тему. + 3. Проверь само предложение пользователя на отсутствие грубой лексики и пошлостей. + 4. Проверь грамматику. + 5. Проверь на бессмысленность предложения. Оно не должно содержать только случайные символы. + 6. Не должно быть рекламы, ссылок и т.д. + 7. Проверь предложение на информативность, предложение не может быть коротким, оно должно ясно отражжать суть инициативы. + 8. Предложение должно быть в вежливой форме. + + - Если все правила соблюдены, то предложение принимается! + + - Если предложение отклонено, всегда пиши комментарий и fixedText! + + Правила написания комментария: + - Если предложение отклоняется, пиши комментарий со следующей формулировкой: + "Предложение отклонено. Причина: (укажи проблему)" + + Правила написания fixedText: + - Если предложение отклонено, то верни в поле "fixedText" измененный текст, который будет соответствовать правилам. + - Если предложение отклонено и содержит запрещённый контент (рекламу, личные данные), удали всю информацию, + которая противоречит правилам, и верни в только подходящий фрагмент, сохраняя общий смысл. + - Если текст не представляет никакой ценности, возврати в поле "fixedText" правило, + по которому оно не прошло. + -Если предложение принимается, то ничего не возвращай в поле fixedText. + ` + + const result = await moderationLlm.invoke(prompt); + if(!result.isApproved && result.comment.trim() === '' && (!result.fixedText || result.fixedText.trim() === '')) { + result.comment = 'Предложение отклонено. Причина: несоблюдение требований к оформлению или содержанию.', + result.fixedText = description + } + + return [result.comment, result.fixedText, result.isApproved]; +}; \ No newline at end of file diff --git a/server/routers/kfu-m-24-1/sber_mobile/initiatives-ai-agents/picture.ts b/server/routers/kfu-m-24-1/sber_mobile/initiatives-ai-agents/picture.ts new file mode 100644 index 0000000..d216c5d --- /dev/null +++ b/server/routers/kfu-m-24-1/sber_mobile/initiatives-ai-agents/picture.ts @@ -0,0 +1,38 @@ +import { llm_gen } from './llm' +import { detectImage } from 'gigachat'; + +export const generatePicture = async (prompt: string, GIGA_AUTH) => { + const resp = await llm_gen(GIGA_AUTH).chat({ + messages: [ + { + "role": "system", + "content": "Ты — Василий Кандинский для жильцов многоквартирного дома" + }, + { + role: "user", + content: `Старайся передать атмосферу уюта и безопасности. + Нарисуй картинку подходящую для такого события: ${prompt} + В картинке не должно быть текста, только изображение.`, + }, + ], + function_call: 'auto', + }); + + // Получение изображения по идентификатору + const detectedImage = detectImage(resp.choices[0]?.message.content ?? ''); + + if (!detectedImage?.uuid) { + throw new Error('Не удалось получить UUID изображения из ответа GigaChat'); + } + + const image = await llm_gen(GIGA_AUTH).getImage(detectedImage.uuid); + + // Возвращаем содержимое изображения, убеждаясь что это Buffer + if (Buffer.isBuffer(image.content)) { + return image.content; + } else if (typeof image.content === 'string') { + return Buffer.from(image.content, 'binary'); + } else { + throw new Error('Unexpected image content type: ' + typeof image.content); + } +}