Skip to content

Commit

Permalink
[sc-11278] Allow to store prompts for multiple providers (#1873)
Browse files Browse the repository at this point in the history
* [sc-11278] Allow to store prompts for multiple providers

* Fix build
  • Loading branch information
operramon authored Dec 16, 2024
1 parent 484d16e commit 84411cd
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 54 deletions.
23 changes: 23 additions & 0 deletions libs/common/common.babel
Original file line number Diff line number Diff line change
Expand Up @@ -13061,6 +13061,29 @@
</concept_node>
</children>
</folder_node>
<concept_node>
<name>set-prompt</name>
<description/>
<comment/>
<translations>
<translation>
<language>ca-ES</language>
<approved>false</approved>
</translation>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-ES</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
</children>
</folder_node>
<folder_node>
Expand Down
5 changes: 3 additions & 2 deletions libs/common/src/assets/i18n/ca.json
Original file line number Diff line number Diff line change
Expand Up @@ -537,14 +537,15 @@
"kb.ai-models.anonymization.toggle.label": "Anonimatització",
"kb.ai-models.answer-generation.behavior.description": "Definiu els trets de personalitat de l’assistent, com s’ha de comportar quan respon a preguntes o durant una conversa. Per exemple, podríeu definir que el sistema respondrà com a professional de la salut.",
"kb.ai-models.answer-generation.behavior.label": "Descriu el comportament",
"kb.ai-models.answer-generation.behavior.title": "Personalitzar el comportament",
"kb.ai-models.answer-generation.behavior.title": "Establir un prompt de sistema per a {{provider}}",
"kb.ai-models.answer-generation.prompt.description": "Defineix la manera com voleu que actuï el sistema quan feu una pregunta. Aquí podeu definir regles més específiques, que fins i tot podrien anul·lar el comportament definit. Per exemple, podríeu establir un prompt que faci que el sistema només doni resultats en llistes, o fins i tot demanar que respongui en un idioma determinat.",
"kb.ai-models.answer-generation.prompt.title": "Establiu un prompt",
"kb.ai-models.answer-generation.prompt.title": "Establiu un prompt per {{provider}}",
"kb.ai-models.answer-generation.select-llm.description": "Trieu el LLM que funcioni millor per respondre les preguntes dels vostres usuaris.",
"kb.ai-models.answer-generation.select-llm.help.chatgpt-vision": "Aquest model és millor per respondre preguntes sobre el contingut de les imatges.",
"kb.ai-models.answer-generation.select-llm.own-key.label": "Utilitzeu la vostra pròpia clau {{provider}}",
"kb.ai-models.answer-generation.select-llm.own-key.title": "Emplena la teva clau de {{provider}} ",
"kb.ai-models.answer-generation.select-llm.title": "Seleccioneu el LLM utilitzat per generar respostes",
"kb.ai-models.answer-generation.set-prompt": "Establir un prompt",
"kb.ai-models.common.examples": "Exemples",
"kb.ai-models.common.prompt.label": "La teva prompt",
"kb.ai-models.common.prompt.warning": "L’ús del prompt pot produir resultats inesperats.",
Expand Down
5 changes: 3 additions & 2 deletions libs/common/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -537,14 +537,15 @@
"kb.ai-models.anonymization.toggle.label": "Anonymization",
"kb.ai-models.answer-generation.behavior.description": "Define the personality traits of the assistant, how it should behave when answering questions or during a conversation. For example, you could define that the system will answer as a health professional.",
"kb.ai-models.answer-generation.behavior.label": "Describe behavior",
"kb.ai-models.answer-generation.behavior.title": "Customize behavior",
"kb.ai-models.answer-generation.behavior.title": "Set a system prompt for {{provider}}",
"kb.ai-models.answer-generation.prompt.description": "Defines the way you want the system to act when you ask a question. Here you can define more specific rules, that could even override the defined behavior. For example, you could set a prompt that makes the system only give results in lists, or even ask to answer in a given language.",
"kb.ai-models.answer-generation.prompt.title": "Set a prompt",
"kb.ai-models.answer-generation.prompt.title": "Set a prompt for {{provider}}",
"kb.ai-models.answer-generation.select-llm.description": "Choose the LLM that will work the best to answer your user’s questions.",
"kb.ai-models.answer-generation.select-llm.help.chatgpt-vision": "This model is best at answering questions regarding the content of images.",
"kb.ai-models.answer-generation.select-llm.own-key.label": "Use your own {{provider}} key",
"kb.ai-models.answer-generation.select-llm.own-key.title": "Fill in your {{provider}} key",
"kb.ai-models.answer-generation.select-llm.title": "Select the LLM used to generate answers",
"kb.ai-models.answer-generation.set-prompt": "Set a prompt",
"kb.ai-models.common.examples": "Examples",
"kb.ai-models.common.prompt.label": "Your prompt",
"kb.ai-models.common.prompt.warning": "Using prompt may produce unexpected results.",
Expand Down
5 changes: 3 additions & 2 deletions libs/common/src/assets/i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -537,14 +537,15 @@
"kb.ai-models.anonymization.toggle.label": "Anonimización",
"kb.ai-models.answer-generation.behavior.description": "Defina los rasgos de personalidad del asistente, cómo debe comportarse al responder preguntas o durante una conversación. Por ejemplo, podrías definir que el sistema responderá como un profesional de la salud.",
"kb.ai-models.answer-generation.behavior.label": "Describir el comportamiento",
"kb.ai-models.answer-generation.behavior.title": "Personalizar comportamiento",
"kb.ai-models.answer-generation.behavior.title": "Establecer el prompt de sistema para {{provider}}",
"kb.ai-models.answer-generation.prompt.description": "Define la forma en que desea que actúe el sistema cuando hace una pregunta. Aquí puede definir reglas más específicas, que incluso podrían anular el comportamiento definido. Por ejemplo, podría configurar un prompt que haga que el sistema solo proporcione resultados en listas, o incluso solicite responder en un idioma determinado.",
"kb.ai-models.answer-generation.prompt.title": "Establecer un prompt",
"kb.ai-models.answer-generation.prompt.title": "Establecer un prompt para {{provider}}",
"kb.ai-models.answer-generation.select-llm.description": "Elija el LLM que funcione mejor para responder las preguntas de sus usuarios.",
"kb.ai-models.answer-generation.select-llm.help.chatgpt-vision": "Este modelo es mejor para responder preguntas sobre el contenido de las imágenes.",
"kb.ai-models.answer-generation.select-llm.own-key.label": "Utilice su propia clave de {{provider}}",
"kb.ai-models.answer-generation.select-llm.own-key.title": "Rellena tu clave de {{provider}} ",
"kb.ai-models.answer-generation.select-llm.title": "Seleccione el LLM utilizado para generar respuestas",
"kb.ai-models.answer-generation.set-prompt": "Establecer un prompt",
"kb.ai-models.common.examples": "Ejemplos",
"kb.ai-models.common.prompt.label": "Su prompt",
"kb.ai-models.common.prompt.warning": "El uso del prompt puede producir resultados inesperados.",
Expand Down
5 changes: 3 additions & 2 deletions libs/common/src/assets/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -537,14 +537,15 @@
"kb.ai-models.anonymization.toggle.label": "Anonymisation",
"kb.ai-models.answer-generation.behavior.description": "Définissez les traits de personnalité de l’assistant, comment il doit se comporter lorsqu’il répond à des questions ou lors d’une conversation. Par exemple, vous pourriez définir que le système répondra en tant que professionnel de santé.",
"kb.ai-models.answer-generation.behavior.label": "Décrire le comportement",
"kb.ai-models.answer-generation.behavior.title": "Personnaliser le comportement",
"kb.ai-models.answer-generation.behavior.title": "Définir un prompt système pour {{provider}}",
"kb.ai-models.answer-generation.prompt.description": "Définit la manière dont vous souhaitez que le système agisse lorsque vous posez une question. Ici, vous pouvez définir des règles plus spécifiques, qui pourraient même remplacer le comportement défini. Par exemple, vous pouvez définir un prompt qui oblige le système à donner uniquement des résultats sous forme de listes, ou même à demander de répondre dans une langue donnée.",
"kb.ai-models.answer-generation.prompt.title": "Définir un prompt",
"kb.ai-models.answer-generation.prompt.title": "Définir un prompt pour {{provider}}",
"kb.ai-models.answer-generation.select-llm.description": "Choisissez le LLM qui fonctionnera le mieux pour répondre aux questions de vos utilisateurs.",
"kb.ai-models.answer-generation.select-llm.help.chatgpt-vision": "Ce modèle est le meilleur pour répondre aux questions concernant le contenu des images.",
"kb.ai-models.answer-generation.select-llm.own-key.label": "Utilisez votre propre clé {{provider}}",
"kb.ai-models.answer-generation.select-llm.own-key.title": "Remplissez votre clé {{provider}} ",
"kb.ai-models.answer-generation.select-llm.title": "Sélectionner le LLM utilisé pour générer des réponses",
"kb.ai-models.answer-generation.set-prompt": "Définir un prompt",
"kb.ai-models.common.examples": "Exemples",
"kb.ai-models.common.prompt.label": "Votre prompt",
"kb.ai-models.common.prompt.warning": "L’utilisation du prompt peut produire des résultats inattendus.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,26 +86,27 @@
</div>
</nsi-two-columns-configuration-item>

@if (currentGenerativeModel?.user_prompt) {
<ng-container [formGroup]="userPromptForm">
@if (
currentGenerativeModel?.user_prompt &&
learningConfig['user_prompts'].schemas?.[currentGenerativeModel?.user_prompt || ''];
as userPrompt
) {
@if (userPrompt.properties['prompt']; as prompt) {
<ng-container [formGroup]="userPromptForm">
@for (userPrompt of userPromptSchemas || {} | keyvalue; track userPrompt.key) {
<div
[formGroupName]="userPrompt.key"
[hidden]="userPrompt.key !== currentGenerativeModel?.user_prompt">
@if (userPrompt.value.properties['prompt']; as prompt) {
<nsi-two-columns-configuration-item
badge="generic.badge.optional"
itemTitle="kb.ai-models.answer-generation.prompt.title"
[itemTitle]="
'kb.ai-models.answer-generation.prompt.title'
| translate: { provider: keyProviders[userPrompt.key] || userPrompt.key }
"
description="kb.ai-models.answer-generation.prompt.description"
[unauthorized]="(isUserPromptsAuthorized | async) === false"
(clickOnUnauthorized)="openUnauthorizedModal('kb.ai-models.answer-generation.prompt.title')">
(clickOnUnauthorized)="openUnauthorizedModal('kb.ai-models.answer-generation.set-prompt')">
<div class="form-container small-gap">
<nsi-info-card>{{ prompt.info }}</nsi-info-card>
<pa-select
formControlName="prompt_examples"
[label]="'kb.ai-models.common.examples' | translate"
(valueChange)="setPrompt('prompt', $event)">
(valueChange)="setPrompt(userPrompt.key, 'prompt', $event)">
@for (option of prompt.examples || []; track option) {
<pa-option [value]="option">
{{ option }}
Expand All @@ -129,18 +130,21 @@
</div>
</nsi-two-columns-configuration-item>
}
@if (userPrompt.properties['system']; as system) {
@if (userPrompt.value.properties['system']; as system) {
<nsi-two-columns-configuration-item
badge="generic.badge.optional"
itemTitle="kb.ai-models.answer-generation.behavior.title"
[itemTitle]="
'kb.ai-models.answer-generation.behavior.title'
| translate: { provider: keyProviders[userPrompt.key] || userPrompt.key }
"
description="kb.ai-models.answer-generation.behavior.description"
[unauthorized]="(isUserPromptsAuthorized | async) === false"
(clickOnUnauthorized)="openUnauthorizedModal('kb.ai-models.answer-generation.behavior.title')">
(clickOnUnauthorized)="openUnauthorizedModal('kb.ai-models.answer-generation.set-prompt')">
<div class="form-container small-gap">
<pa-select
formControlName="system_examples"
[label]="'kb.ai-models.common.examples' | translate"
(valueChange)="setPrompt('system', $event)">
(valueChange)="setPrompt(userPrompt.key, 'system', $event)">
@for (option of system.examples || []; track option) {
<pa-option [value]="option">
{{ option }}
Expand All @@ -158,9 +162,9 @@
</div>
</nsi-two-columns-configuration-item>
}
}
</ng-container>
}
</div>
}
</ng-container>
<nsi-sticky-footer>
<pa-button
aspect="basic"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,7 @@ export class AnswerGenerationComponent extends LearningConfigurationDirective im
configForm = new FormGroup({
generative_model: new FormControl<string>('', { nonNullable: true, validators: [Validators.required] }),
user_keys: new FormGroup({}),
user_prompts: new FormGroup({
prompt: new FormControl<string>(''),
prompt_examples: new FormControl<string>(''),
system: new FormControl<string>(''),
system_examples: new FormControl<string>(''),
}),
user_prompts: new FormGroup({}),
});
currentGenerativeModel?: LearningConfigurationOption;
userKeyToggle = new FormControl<boolean>(false);
Expand All @@ -75,12 +70,15 @@ export class AnswerGenerationComponent extends LearningConfigurationDirective im
get userPromptForm() {
return this.configForm.controls.user_prompts;
}
get userPromptSchemas() {
return this.learningConfigurations?.['user_prompts']?.schemas;
}

constructor() {
super();
this.userKeyToggle.valueChanges.pipe(takeUntil(this.unsubscribeAll)).subscribe(() => {
this.updateValidators();
})
});
}

ngOnDestroy() {
Expand All @@ -104,15 +102,23 @@ export class AnswerGenerationComponent extends LearningConfigurationDirective im
this.userPromptForm.disable();
});

if (this.learningConfigurations && Object.keys(this.userPromptForm.controls).length === 0) {
Object.keys(this.userPromptSchemas || {}).forEach((key) => {
this.userPromptForm.addControl(
key,
new FormGroup({
prompt: new FormControl<string>(''),
prompt_examples: new FormControl<string>(''),
system: new FormControl<string>(''),
system_examples: new FormControl<string>(''),
}),
);
});
}

if (kbConfig) {
this.configForm.patchValue(kbConfig);

this.updateCurrentGenerativeModel();
if (this.currentGenerativeModel?.user_prompt) {
if (kbConfig['user_prompts']) {
this.userPromptForm.patchValue(kbConfig['user_prompts'][this.currentGenerativeModel?.user_prompt]);
}
}
if (this.currentGenerativeModel?.user_key) {
if (kbConfig['user_keys']) {
const ownKey = !!kbConfig['user_keys'][this.currentGenerativeModel?.user_key];
Expand Down Expand Up @@ -140,15 +146,18 @@ export class AnswerGenerationComponent extends LearningConfigurationDirective im
this.currentGenerativeModel?.user_key && this.hasOwnKey
? { [this.currentGenerativeModel?.user_key]: kbConfig['user_keys'] }
: {};
kbConfig['user_prompts'] = this.currentGenerativeModel?.user_prompt
? {
[this.currentGenerativeModel?.user_prompt]: {
...kbConfig['user_prompts'],
prompt: kbConfig['user_prompts'].prompt?.trim(),
system: kbConfig['user_prompts'].system?.trim(),
},
}
: {};

kbConfig['user_prompts'] = Object.entries(kbConfig['user_prompts']).reduce(
(acc, curr: [string, any]) => {
const prompts = {
prompt: curr[1].prompt?.trim(),
system: curr[1].system?.trim(),
};
acc[curr[0]] = prompts.prompt || prompts.system ? prompts : undefined;
return acc;
},
{} as { [key: string]: any },
);

this.kb
.setConfiguration(kbConfig)
Expand Down Expand Up @@ -183,10 +192,6 @@ export class AnswerGenerationComponent extends LearningConfigurationDirective im
);
if (generativeOption) {
this.currentGenerativeModel = generativeOption;
this.userPromptForm.patchValue({
prompt: '',
system: '',
});
}
if (this.currentGenerativeModel?.user_key) {
// add user_keys controls corresponding to generative model if any
Expand Down Expand Up @@ -225,9 +230,9 @@ export class AnswerGenerationComponent extends LearningConfigurationDirective im
});
}

setPrompt(field: string, value: string) {
setPrompt(key: string, promptType: string, value: string) {
if (value) {
const formValue = { [field]: value, [`${field}_examples`]: '' };
const formValue = { [key]: { [promptType]: value, [`${promptType}_examples`]: '' } };
this.userPromptForm.patchValue(formValue);
this.cdr.markForCheck();
}
Expand Down

0 comments on commit 84411cd

Please sign in to comment.