Sluzba byla v katalogu bez pristupovych udaju a s appId 'ai-text', tedy mirila na aplikaci, ktera neexistuje. Konektor nemel co vyplnit a krok nemel co vykonat. - sluzba stoji na api.openai.com/v1 stejne jako OpenAI, overeni GET /models - model se bere z konektoru (ctx.config.model), ne z kazdeho kroku zvlast - skripty ai-text.classify, ai-text.extract, ai-text.generate Proc to neni jedna sluzba s OpenAI: tam se posila volny dotaz a vraci volny text. Tady je uloha pevna a vystup taky - category a confidence, objekt s popsanymi poli, text s poctem slov. Na to jde ve strome navazat podminkou, na volny text ne. Zjisteno u toho a zapsane do 21-realne-sluzby.md: proxy vraci na neznamou aplikaci 200 s prazdnym telem, takze overeni konektoru u sluzby bez verifyPath projde i tam, kde nic nebezi. Zatim neopraveno. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
115 lines
3.2 KiB
JavaScript
115 lines
3.2 KiB
JavaScript
/**
|
|
* 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,
|
|
};
|
|
}
|