/* * Imixs-Workflow * * Copyright (C) 2001-2020 Imixs Software Solutions GmbH, * http://www.imixs.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You can receive a copy of the GNU General Public * License at http://www.gnu.org/licenses/gpl.html * * Project: * https://www.imixs.org * https://github.com/imixs/imixs-workflow * * Contributors: * Imixs Software Solutions GmbH - Project Management * Ralph Soika - Software Developer */ package ai.dynamixs.rag; import java.util.List; import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.imixs.ai.workflow.OpenAIAPIService; import org.imixs.workflow.ItemCollection; import org.imixs.workflow.SignalAdapter; import org.imixs.workflow.engine.WorkflowService; import org.imixs.workflow.exceptions.AdapterException; import org.imixs.workflow.exceptions.PluginException; import jakarta.inject.Inject; /** * The RAGAdapter is used for Retrieval-Augmented Generation workflows. *
* The adapter automatically index and embed text data. *
* The imixs-ai prompt definition defines the API endpoint and processing events * to adapt the indexing and the prompt template. *
* The Adapter can be configured by a event entity. *
* INDEX configuration - to add embeddings: * *
* {@code
llm.service.endpoint
true
* }
*
*
* The Endpoint defines the Rest API endpoint of the llama-cpp http server or
* any compatible OpenAI / Open API rest service endpoint.
* * Example Prompt Template: * * *
* {@code
{"n_predict": 4096, "temperature": 0}
$workflowgroup : $workflowstatus
# Summary
$workflowsummary
offer.summary
]]>
* }
*
*
* @author Ralph Soika
* @version 1.0
*
*/
public class RAGAdapter implements SignalAdapter {
public static final String ML_ENTITY = "entity";
public static final String API_ERROR = "API_ERROR";
public static final String LLM_PROMPT = "PROMPT";
public static final String LLM_SUGGEST = "SUGGEST";
public static final String LLM_INDEX = "INDEX";
public static final int API_EVENT_SUCCESS = 110;
public static final int API_EVENT_FAILURE = 90;
private static Logger logger = Logger.getLogger(RAGAdapter.class.getName());
@Inject
@ConfigProperty(name = OpenAIAPIService.ENV_LLM_SERVICE_ENDPOINT)
Optional* If not api endpoint is defined by the model the adapter uses the default api * endpoint. * * @param llmPrompt * @return * @throws PluginException */ private String parseLLMEndpointByBPMN(ItemCollection llmPrompt) throws PluginException { boolean debug = logger.isLoggable(Level.FINE); String llmAPIEndpoint = null; // Test if the model provides a API Endpoint. llmAPIEndpoint = null; if (llmPrompt != null) { llmAPIEndpoint = llmPrompt.getItemValueString("endpoint"); } // switch to default api endpoint? if (llmAPIEndpoint == null || llmAPIEndpoint.isEmpty()) { // set defautl api endpoint if defined if (serviceEndpoint.isPresent() && !serviceEndpoint.get().isEmpty()) { llmAPIEndpoint = serviceEndpoint.get(); } } if (debug) { logger.info("......llm api endpoint " + llmAPIEndpoint); } // adapt text... llmAPIEndpoint = workflowService.adaptText(llmAPIEndpoint, null); if (!llmAPIEndpoint.endsWith("/")) { llmAPIEndpoint = llmAPIEndpoint + "/"; } return llmAPIEndpoint; } }