/** * AI zpracovani textu: napsani textu podle instrukce. * * Sluzba: https://api.openai.com/v1 * Endpoint: POST /chat/completions * * Typicky se z toho stava odpoved zakaznikovi nebo shrnuti do ticketu, takze * krok umi omezit delku a jazyk. Bez toho model odpovi, jak se mu zachce, * a odpoved se do e-mailu nebo do komentare nevejde. */ export const manifest = { id: 'ai-text.generate', name: 'Vygenerovat text', description: 'Napíše text podle instrukce a vstupních dat. Hodí se na odpověď ' + 'zákazníkovi, shrnutí do ticketu nebo popis incidentu.', inputs: [ { id: 'instruction', label: 'Co má napsat', type: 'string', required: true, multiline: true, hint: 'Například: Napiš zdvořilou odpověď zákazníkovi, že reklamaci přebíráme.', }, { id: 'input', label: 'Vstupní data', type: 'string', required: false, multiline: true, hint: 'Text, ze kterého má vycházet. Typicky obsah ticketu.', }, { id: 'tone', label: 'Tón', type: 'string', required: false, options: [ { value: 'vecny', label: 'Věcný' }, { value: 'vstricny', label: 'Vstřícný' }, { value: 'strucny', label: 'Stručný' }, { value: 'omluvny', label: 'Omluvný' }, ], }, { id: 'language', label: 'Jazyk', type: 'string', required: false, default: 'čeština', hint: 'Bez vyplnění čeština.', }, { id: 'maxWords', label: 'Nejvýše kolik slov', type: 'number', required: false, hint: 'Bez vyplnění rozhoduje model. Do e-mailu se hodí kolem 120.', }, ], outputs: [ { id: 'text', label: 'Text', type: 'string', required: true }, { id: 'words', label: 'Počet slov', type: 'number', required: true }, ], timeoutMs: 60000, }; const tones = { vecny: 'Piš věcně a bez zdobení.', vstricny: 'Piš vstřícně a lidsky, ale ne přehnaně.', strucny: 'Piš co nejstručněji, ideálně pár vět.', omluvny: 'Omluv se za potíže, ale neslibuj nic, co není v zadání.', }; export async function run(inputs, ctx) { const { pick, first, text, need } = ctx.util; const rules = [ `Piš v jazyce: ${inputs.language}.`, inputs.tone ? tones[inputs.tone] : '', inputs.maxWords !== null ? `Vejdi se do ${inputs.maxWords} slov.` : '', // Bez tohohle model rad pripoji "Jiste, tady je vas text:" a to jde // rovnou zakaznikovi do e-mailu. 'Vrať pouze výsledný text, žádný úvod ani komentář k zadání.', ].filter(Boolean); const { body } = await ctx.http.post('/chat/completions', { model: ctx.config.model || 'gpt-4o-mini', messages: [ { role: 'system', content: rules.join(' ') }, { role: 'user', content: inputs.input ? `${inputs.instruction}\n\nVstupní data:\n${inputs.input}` : inputs.instruction, }, ], }); const content = need( text(pick(pick(first(pick(body, 'choices')), 'message'), 'content')), 'vygenerovaný text', ); return { text: content, words: content.split(/\s+/).filter(Boolean).length, }; }