All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fi.evolver.ai.vaadin.component.form.ChatPromptForm Maven / Gradle / Ivy

The newest version!
package fi.evolver.ai.vaadin.component.form;

import java.io.Serial;
import java.util.*;

import org.vaadin.lineawesome.LineAwesomeIcon;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.details.Details;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.theme.lumo.LumoUtility;

import fi.evolver.ai.spring.chat.function.FunctionSpec;
import fi.evolver.ai.spring.chat.prompt.ChatPrompt;
import fi.evolver.ai.vaadin.entity.HasValueGetterSetter;
import fi.evolver.utils.string.StringUtils;

public class ChatPromptForm extends VerticalLayout implements HasValueGetterSetter {
	@Serial
	private static final long serialVersionUID = 1L;

	private final TextField modelInput = new TextField();
	private final PromptMessagesForm messagesForm = new PromptMessagesForm();
	private final KeyValueMapForm parametersForm = new KeyValueMapForm();
	private final VerticalLayout functionCallsContent = new VerticalLayout();
	private final List functionCallInputs = new ArrayList<>();

	private List stopList = new ArrayList<>();
	private Map logitBias = new HashMap<>();
	private ChatPrompt value;

	public ChatPromptForm() {
		setWidthFull();
		addFields();
	}

	@Override
	public void setValue(ChatPrompt prompt) {
		value = prompt;
		modelInput.setValue(prompt.model().name());
		messagesForm.setValue(prompt.messages());
		parametersForm.setValue(prompt.parameters());
		setFunctionInputsValue(prompt.functions(), prompt.requiredFunction());
		stopList = prompt.stopList();
		logitBias = prompt.logitBias();
	}

	@Override
	public ChatPrompt getValue() {
		if (value == null)
			return null;
		ChatPrompt.Builder result = ChatPrompt.builder(value.model().withName(modelInput.getValue()));
		if (messagesForm != null)
			result.addAll(messagesForm.getValue());
		if (parametersForm != null)
		for (Map.Entry param : parametersForm.getValue().entrySet())
			if (StringUtils.hasText(param.getKey()))
				result.setParameter(param.getKey(), param.getValue());
		for (FunctionCallInput functionCallInput : functionCallInputs)
			result.add(functionCallInput.getFunction(), functionCallInput.getIsRequired());
		result.addStopList(stopList);
		result.addLogitBias(logitBias);
		return result.build();
	}

	private void addFields() {
		modelInput.setLabel(getTranslation("component.form.chatPrompt.model"));
		modelInput.setWidthFull();
		add(modelInput);
		
		Details messageDetails = new Details(getTranslation("component.form.chatPrompt.messages"), messagesForm);
		messageDetails.setWidthFull();
		add(messageDetails);
		
		Details parametersDetails = new Details(getTranslation("component.form.chatPrompt.parameters"), parametersForm);
		parametersDetails.setWidthFull();
		add(parametersDetails);
		
		Details functionCallDetails = new Details(getTranslation("component.form.chatPrompt.functions"), functionCallsContent);
		functionCallDetails.setWidthFull();
		functionCallsContent.setWidthFull();
		add(functionCallDetails);
	}

	private void setFunctionInputsValue(List> functions, Optional> requiredFunction) {
		functionCallsContent.removeAll();
		if (functions.size() == 0) {
			functionCallsContent.add(new Paragraph(getTranslation("component.form.chatPrompt.functions.none")));
			return;
		}
		for (FunctionSpec function : functions) {
			FunctionCallInput FunctionCallInput = new FunctionCallInput(function, requiredFunction.filter(function::equals).isPresent());
			functionCallInputs.add(FunctionCallInput);
			functionCallsContent.add(FunctionCallInput);
			FunctionCallInput.addRemoveHandler(() -> {
				functionCallInputs.remove(FunctionCallInput);
				functionCallsContent.remove(FunctionCallInput);
			});
		}
	}

	private static class FunctionCallInput extends HorizontalLayout {
		private final Span functionName = new Span();
		private final Checkbox isRequired = new Checkbox();

		private final FunctionSpec functionSpec;
		private Runnable onRemove;


		public FunctionCallInput(FunctionSpec func, boolean required) {
			functionSpec = func;
			setWidthFull();
			addClassName(LumoUtility.AlignItems.CENTER);

			functionName.setWidth("65%");
			functionName.setText(func.getFunctionName());
			add(functionName);
			
			Div div = new Div();
			div.setWidth("35%");
			div.addClassNames(LumoUtility.Display.FLEX, LumoUtility.JustifyContent.BETWEEN, LumoUtility.AlignItems.CENTER);
			add(div);

			isRequired.setLabel(getTranslation("component.form.chatPrompt.functions.isRequired"));
			isRequired.setValue(required);
			div.add(isRequired);

			Button removeBtn = new Button(LineAwesomeIcon.TRASH_ALT.create());
			removeBtn.addClickListener(e -> {
				if (onRemove != null)
					onRemove.run();
			});
			div.add(removeBtn);
		}

		public void addRemoveHandler(Runnable onRemove) {
			this.onRemove = onRemove;
		}

		public FunctionSpec getFunction() {
			return functionSpec;
		}

		public boolean getIsRequired() {
			return isRequired.getValue();
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy