Refactor token handling and update dependencies; add AzureAIConfig for response timeout customization
This commit is contained in:
9
pom.xml
9
pom.xml
@@ -29,7 +29,7 @@
|
||||
<properties>
|
||||
<java.version>21</java.version>
|
||||
<!--<spring-ai.version>1.0.0-SNAPSHOT</spring-ai.version>-->
|
||||
<spring-ai.version>1.0.0-M2</spring-ai.version>
|
||||
<spring-ai.version>1.0.0-M6</spring-ai.version>
|
||||
<spring-cloud.version>2023.0.3</spring-cloud.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
@@ -48,6 +48,13 @@
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.json/json -->
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>20250107</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
|
||||
26
src/main/java/com/olympus/hermione/config/AzureAIConfig.java
Normal file
26
src/main/java/com/olympus/hermione/config/AzureAIConfig.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package com.olympus.hermione.config;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAIClientBuilderCustomizer;
|
||||
import com.azure.core.http.HttpClient;
|
||||
import com.azure.core.util.HttpClientOptions;
|
||||
|
||||
|
||||
@Configuration
|
||||
public class AzureAIConfig {
|
||||
|
||||
@Bean
|
||||
public AzureOpenAIClientBuilderCustomizer responseTimeoutCustomizer() {
|
||||
return openAiClientBuilder -> {
|
||||
HttpClientOptions clientOptions = new HttpClientOptions()
|
||||
.setResponseTimeout(Duration.ofMinutes(5));
|
||||
openAiClientBuilder.httpClient(HttpClient.createDefault(clientOptions));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -43,7 +43,8 @@ public class VectorStoreConfig {
|
||||
fields.add(AzureVectorStore.MetadataField.text("KsFileSource"));
|
||||
fields.add(AzureVectorStore.MetadataField.text("KsDocumentId"));
|
||||
|
||||
return new AzureVectorStore(searchIndexClient, embeddingModel,initSchema, fields);
|
||||
//return new AzureVectorStore(searchIndexClient, embeddingModel,initSchema, fields);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
package com.olympus.hermione.models;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.DocumentReference;
|
||||
|
||||
import com.olympus.hermione.dto.ScenarioExecutionInput;
|
||||
import com.olympus.hermione.models.Scenario;
|
||||
import com.olympus.hermione.security.entity.User;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -38,6 +35,6 @@ public class ScenarioExecution {
|
||||
|
||||
private Date startDate;
|
||||
private Date endDate;
|
||||
private Long usedTokens;
|
||||
private Integer usedTokens;
|
||||
private String rating;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class CanvasExecutionService {
|
||||
Prompt prompt = new Prompt(List.of(userMessage,systemMessage));
|
||||
List<Generation> response = chatModel.call(prompt).getResults();
|
||||
|
||||
canvasOutput.setStringOutput(response.get(0).getOutput().getContent());
|
||||
canvasOutput.setStringOutput(response.get(0).getOutput().getText());
|
||||
return canvasOutput;
|
||||
} else{
|
||||
logger.error("Input is not correct");
|
||||
@@ -61,7 +61,7 @@ public class CanvasExecutionService {
|
||||
Prompt prompt = new Prompt(List.of(userMessage,systemMessage));
|
||||
List<Generation> response = chatModel.call(prompt).getResults();
|
||||
|
||||
canvasOutput.setStringOutput(response.get(0).getOutput().getContent());
|
||||
canvasOutput.setStringOutput(response.get(0).getOutput().getText());
|
||||
return canvasOutput;
|
||||
} else{
|
||||
logger.error("Input is not correct");
|
||||
@@ -79,7 +79,7 @@ public class CanvasExecutionService {
|
||||
Prompt prompt = new Prompt(List.of(userMessage,systemMessage));
|
||||
List<Generation> response = chatModel.call(prompt).getResults();
|
||||
|
||||
canvasOutput.setStringOutput(response.get(0).getOutput().getContent());
|
||||
canvasOutput.setStringOutput(response.get(0).getOutput().getText());
|
||||
return canvasOutput;
|
||||
} else{
|
||||
logger.error("Input is not correct");
|
||||
|
||||
@@ -34,7 +34,6 @@ import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.olympus.hermione.client.OlympusChatClient;
|
||||
import com.olympus.hermione.dto.ScenarioExecutionInput;
|
||||
import com.olympus.hermione.dto.ScenarioOutput;
|
||||
import com.olympus.hermione.models.AiModel;
|
||||
@@ -210,7 +209,7 @@ public class ScenarioExecutionService {
|
||||
ScenarioStep startStep = steps.stream().filter(step -> step.getStepId().equals(startStepId)).findFirst().orElse(null);
|
||||
|
||||
executeScenarioStep(startStep, scenarioExecution);
|
||||
Long usedTokens = (scenarioExecution.getUsedTokens() != null) ? scenarioExecution.getUsedTokens() : Long.valueOf(0);
|
||||
Integer usedTokens = (scenarioExecution.getUsedTokens() != null) ? scenarioExecution.getUsedTokens() : 0;
|
||||
|
||||
while (scenarioExecution.getNextStepId()!=null) {
|
||||
ScenarioStep step = steps.stream().filter(s -> s.getStepId().equals(scenarioExecution.getNextStepId())).findFirst().orElse(null);
|
||||
@@ -219,7 +218,7 @@ public class ScenarioExecutionService {
|
||||
if (scenarioExecution.getUsedTokens() != null && scenarioExecution.getUsedTokens() != 0) {
|
||||
usedTokens += scenarioExecution.getUsedTokens();
|
||||
|
||||
scenarioExecution.setUsedTokens(Long.valueOf(0)); //resetting value for next step if is not an AI step
|
||||
scenarioExecution.setUsedTokens(0); //resetting value for next step if is not an AI step
|
||||
}
|
||||
|
||||
if(scenarioExecution.getLatestStepStatus() != null && scenarioExecution.getLatestStepStatus().equals("ERROR")){
|
||||
@@ -426,17 +425,19 @@ public class ScenarioExecutionService {
|
||||
private ChatModel createChatModel(AiModel aiModel){
|
||||
switch(aiModel.getApiProvider()){
|
||||
case "AzureOpenAI":
|
||||
OpenAIClient openAIClient = new OpenAIClientBuilder()
|
||||
OpenAIClientBuilder openAIClient = new OpenAIClientBuilder()
|
||||
.credential(new AzureKeyCredential(aiModel.getApiKey()))
|
||||
.endpoint(aiModel.getEndpoint())
|
||||
.buildClient();
|
||||
.endpoint(aiModel.getEndpoint());
|
||||
|
||||
|
||||
AzureOpenAiChatOptions openAIChatOptions = AzureOpenAiChatOptions.builder()
|
||||
.withDeploymentName(aiModel.getModel())
|
||||
.withTemperature(aiModel.getTemperature())
|
||||
.withMaxTokens(aiModel.getMaxTokens())
|
||||
.deploymentName(aiModel.getModel())
|
||||
.maxTokens(aiModel.getMaxTokens())
|
||||
.temperature(Double.valueOf(aiModel.getTemperature()))
|
||||
.build();
|
||||
|
||||
AzureOpenAiChatModel azureOpenaichatModel = new AzureOpenAiChatModel(openAIClient, openAIChatOptions);
|
||||
|
||||
logger.info("AI model used: " + aiModel.getModel());
|
||||
return azureOpenaichatModel;
|
||||
|
||||
@@ -445,9 +446,9 @@ public class ScenarioExecutionService {
|
||||
case "OpenAI":
|
||||
OpenAiApi openAiApi = new OpenAiApi(aiModel.getApiKey());
|
||||
OpenAiChatOptions openAiChatOptions = OpenAiChatOptions.builder()
|
||||
.withModel(aiModel.getModel())
|
||||
.withTemperature(aiModel.getTemperature())
|
||||
.withMaxTokens(aiModel.getMaxTokens())
|
||||
.model(aiModel.getModel())
|
||||
.temperature(Double.valueOf(aiModel.getTemperature()))
|
||||
.maxTokens(aiModel.getMaxTokens())
|
||||
.build();
|
||||
|
||||
OpenAiChatModel openaichatModel = new OpenAiChatModel(openAiApi,openAiChatOptions);
|
||||
@@ -456,19 +457,21 @@ public class ScenarioExecutionService {
|
||||
|
||||
|
||||
case "GoogleGemini":
|
||||
OpenAIClient tempopenAIClient = new OpenAIClientBuilder()
|
||||
OpenAIClientBuilder openAIClient2 = new OpenAIClientBuilder()
|
||||
.credential(new AzureKeyCredential(aiModel.getApiKey()))
|
||||
.endpoint(aiModel.getEndpoint())
|
||||
.buildClient();
|
||||
AzureOpenAiChatOptions tempopenAIChatOptions = AzureOpenAiChatOptions.builder()
|
||||
.withDeploymentName(aiModel.getModel())
|
||||
.withTemperature(aiModel.getTemperature())
|
||||
.withMaxTokens(aiModel.getMaxTokens())
|
||||
.endpoint(aiModel.getEndpoint());
|
||||
|
||||
|
||||
AzureOpenAiChatOptions openAIChatOptions2 = AzureOpenAiChatOptions.builder()
|
||||
.deploymentName(aiModel.getModel())
|
||||
.maxTokens(aiModel.getMaxTokens())
|
||||
.temperature(Double.valueOf(aiModel.getTemperature()))
|
||||
.build();
|
||||
|
||||
AzureOpenAiChatModel tempazureOpenaichatModel = new AzureOpenAiChatModel(tempopenAIClient, tempopenAIChatOptions);
|
||||
logger.info("AI model used: GoogleGemini");
|
||||
return tempazureOpenaichatModel;
|
||||
AzureOpenAiChatModel azureOpenaichatModel2 = new AzureOpenAiChatModel(openAIClient2, openAIChatOptions2);
|
||||
|
||||
logger.info("AI model used : " + aiModel.getModel());
|
||||
return azureOpenaichatModel2;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported AI model: " + aiModel.getName());
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ public class AdvancedAIPromptSolver extends StepSolver {
|
||||
|
||||
Usage usage = resp.chatResponse().getMetadata().getUsage();
|
||||
if (usage != null) {
|
||||
Long usedTokens = usage.getTotalTokens();
|
||||
Integer usedTokens = usage.getTotalTokens();
|
||||
this.scenarioExecution.setUsedTokens(usedTokens);
|
||||
} else {
|
||||
logger.info("Token usage information is not available.");
|
||||
|
||||
@@ -65,7 +65,7 @@ public class BasicAIPromptSolver extends StepSolver {
|
||||
|
||||
Usage usage = resp.chatResponse().getMetadata().getUsage();
|
||||
if (usage != null) {
|
||||
Long usedTokens = usage.getTotalTokens();
|
||||
Integer usedTokens = usage.getTotalTokens();
|
||||
this.scenarioExecution.setUsedTokens(usedTokens);
|
||||
} else {
|
||||
logger.info("Token usage information is not available.");
|
||||
|
||||
@@ -6,8 +6,7 @@ import java.util.ArrayList;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.vectorstore.SearchRequest;
|
||||
|
||||
|
||||
import org.springframework.ai.vectorstore.SearchRequest.Builder;
|
||||
|
||||
import com.olympus.hermione.models.ScenarioExecution;
|
||||
import com.olympus.hermione.utility.AttributeParser;
|
||||
@@ -72,22 +71,29 @@ public class BasicQueryRagSolver extends StepSolver {
|
||||
loadParameters();
|
||||
logParameters();
|
||||
|
||||
SearchRequest request = SearchRequest.defaults()
|
||||
.withQuery(this.query)
|
||||
.withTopK(this.topk)
|
||||
.withSimilarityThreshold(this.threshold);
|
||||
|
||||
|
||||
Builder request_builder = SearchRequest.builder()
|
||||
.query(this.query)
|
||||
.topK(this.topk)
|
||||
.similarityThreshold(this.threshold);
|
||||
|
||||
|
||||
|
||||
if(this.rag_filter != null && !this.rag_filter.isEmpty()){
|
||||
request.withFilterExpression(this.rag_filter);
|
||||
request_builder.filterExpression(this.rag_filter);
|
||||
logger.info("Using Filter expression: " + this.rag_filter);
|
||||
}
|
||||
|
||||
|
||||
SearchRequest request = request_builder.build();
|
||||
List<Document> docs = this.vectorStore.similaritySearch(request);
|
||||
|
||||
logger.info("Number of VDB retrieved documents: " + docs.size());
|
||||
|
||||
List<String> result = new ArrayList<String>();
|
||||
for (Document doc : docs) {
|
||||
result.add(doc.getContent());
|
||||
result.add(doc.getText());
|
||||
}
|
||||
|
||||
//concatenate the content of the results into a single string
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.List;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.vectorstore.SearchRequest;
|
||||
import org.springframework.ai.vectorstore.filter.Filter;
|
||||
|
||||
public class DeleteDocTempSolver extends StepSolver {
|
||||
|
||||
@@ -56,16 +57,22 @@ public class DeleteDocTempSolver extends StepSolver {
|
||||
this.scenarioExecution.setCurrentStepId(this.step.getStepId());
|
||||
|
||||
loadParameters();
|
||||
SearchRequest searchRequest = SearchRequest.defaults()
|
||||
|
||||
|
||||
|
||||
vectorStore.delete(rag_filter);
|
||||
|
||||
|
||||
/*SearchRequest searchRequest = SearchRequest.defaults()
|
||||
.withQuery(this.query)
|
||||
.withTopK(this.topk)
|
||||
.withSimilarityThreshold(this.threshold)
|
||||
.withFilterExpression(this.rag_filter);
|
||||
|
||||
|
||||
|
||||
List<Document> docs = vectorStore.similaritySearch(searchRequest);
|
||||
List<String> ids = docs.stream().map(Document::getId).toList();
|
||||
vectorStore.delete(ids);
|
||||
vectorStore.delete(ids);*/
|
||||
|
||||
this.scenarioExecution.setNextStepId(this.step.getNextStepId());
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ public class OlynmpusChatClientSolver extends StepSolver{
|
||||
private String qai_system_prompt_template;
|
||||
private String qai_user_input;
|
||||
private String qai_output_variable;
|
||||
private boolean qai_load_graph_schema=false;
|
||||
|
||||
|
||||
Logger logger = (Logger) LoggerFactory.getLogger(BasicQueryRagSolver.class);
|
||||
@@ -73,8 +72,7 @@ public class OlynmpusChatClientSolver extends StepSolver{
|
||||
|
||||
|
||||
|
||||
Long usedTokens = (long) resp.getTotalTokens();
|
||||
this.scenarioExecution.setUsedTokens(usedTokens);
|
||||
this.scenarioExecution.setUsedTokens(resp.getTotalTokens());
|
||||
|
||||
this.scenarioExecution.setNextStepId(this.step.getNextStepId());
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ public class SummarizeDocSolver extends StepSolver {
|
||||
// Creazione dei messaggi per il modello AI
|
||||
Message userMessage = new UserMessage(summarizedText);
|
||||
Message systemMessage = new SystemMessage(content);
|
||||
logger.info("template: " + systemMessage.getContent().toString());
|
||||
logger.info("template: " + systemMessage.getText());
|
||||
CallResponseSpec resp = chatClient.prompt()
|
||||
.messages(userMessage, systemMessage)
|
||||
.advisors(advisor -> advisor
|
||||
@@ -138,7 +138,7 @@ public class SummarizeDocSolver extends StepSolver {
|
||||
// Gestione del conteggio token usati
|
||||
Usage usage = resp.chatResponse().getMetadata().getUsage();
|
||||
if (usage != null) {
|
||||
Long usedTokens = usage.getTotalTokens();
|
||||
Integer usedTokens = usage.getTotalTokens();
|
||||
this.scenarioExecution.setUsedTokens(usedTokens);
|
||||
} else {
|
||||
logger.info("Token usage information is not available.");
|
||||
|
||||
@@ -1,73 +1,77 @@
|
||||
spring.application.name=hermione
|
||||
server.port=8081
|
||||
|
||||
|
||||
# spring.data.mongodb.uri=mongodb+srv://olympus_adm:26111979@olympus.l6qor4p.mongodb.net/?retryWrites=true&w=majority&appName=Olympus
|
||||
# spring.data.mongodb.database=olympus
|
||||
# spring.data.mongodb.username=olympus_adm
|
||||
# spring.data.mongodb.password=26111979
|
||||
|
||||
|
||||
spring.data.mongodb.uri=mongodb+srv://olympusadmin:Camilla123!@db-olympus.global.mongocluster.cosmos.azure.com/?tls=true&authMechanism=SCRAM-SHA-256&retrywrites=false&maxIdleTimeMS=120000
|
||||
spring.data.mongodb.database=olympus
|
||||
spring.data.mongodb.username=olympusadmin
|
||||
spring.data.mongodb.password=Camilla123!
|
||||
|
||||
|
||||
spring.ai.vectorstore.mongodb.indexName=vector_index
|
||||
spring.ai.vectorstore.mongodb.collection-name=vector_store
|
||||
spring.ai.vectorstore.mongodb.initialize-schema=false
|
||||
|
||||
|
||||
spring.ai.vectorstore.azure.api-key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
spring.ai.vectorstore.azure.url=https://search-olympus.search.windows.net_old
|
||||
spring.ai.vectorstore.azure.initialize-schema =false
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
spring.ai.openai.api-key=sk-proj-j3TFJ0h348DIzMrYYfyUT3BlbkFJjk4HMc8A2ux2Asg8Y7H1
|
||||
spring.ai.openai.chat.options.model=gpt-4o-mini
|
||||
spring.main.allow-circular-references=true
|
||||
|
||||
|
||||
spring.ai.azure.openai.api-key=4eHwvw6h7vHxTmI2870cR3EpEBs5L9sXZabr9nz37y39TXtk0xY5JQQJ99AKAC5RqLJXJ3w3AAABACOGLdow
|
||||
spring.ai.azure.openai.endpoint=https://ai-olympus-new.openai.azure.com/
|
||||
|
||||
#spring.ai.azure.openai.api-key=9fb33cc69d914d4c8225b974876510b5
|
||||
#spring.ai.azure.openai.endpoint=https://ai-olympus.openai.azure.com/
|
||||
spring.ai.azure.openai.chat.options.deployment-name=gpt-4o-mini
|
||||
spring.ai.azure.openai.chat.options.temperature=0.7
|
||||
|
||||
|
||||
# neo4j.uri=neo4j+s://e17e6f08.databases.neo4j.io:7687
|
||||
# neo4j.username=neo4j
|
||||
# neo4j.password=8SrSqQ3q6q9PQNWtN9ozqSQfGce4lfh_n6kKz2JIubQ
|
||||
|
||||
|
||||
neo4j.uri=bolt://57.153.162.67:7687
|
||||
neo4j.username=neo4j
|
||||
neo4j.password=01J5h56IsTyyKt
|
||||
|
||||
|
||||
# spring.neo4j.uri=neo4j+s://e17e6f08.databases.neo4j.io:7687
|
||||
# spring.neo4j.authentication.username=neo4j
|
||||
# spring.neo4j.authentication.password=8SrSqQ3q6q9PQNWtN9ozqSQfGce4lfh_n6kKz2JIubQ
|
||||
|
||||
|
||||
spring.neo4j.uri=bolt://57.153.162.67:7687
|
||||
spring.neo4j.authentication.username=neo4j
|
||||
spring.neo4j.authentication.password=01J5h56IsTyyKt
|
||||
|
||||
|
||||
spring.main.allow-bean-definition-overriding=true
|
||||
logging.level.org.springframework.ai.chat.client.advisor=INFO
|
||||
|
||||
|
||||
eureka.client.serviceUrl.defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}
|
||||
eureka.instance.preferIpAddress: true
|
||||
|
||||
|
||||
hermione.fe.url = http://localhost:5173
|
||||
|
||||
|
||||
java-parser-module.url: http://java-parser-module-service.olympus.svc.cluster.local:8080
|
||||
java-re-module.url: http://java-re-module-service.olympus.svc.cluster.local:8080
|
||||
jsp-parser-module.url: http://jsp-parser-module-service.olympus.svc.cluster.local:8080
|
||||
|
||||
|
||||
spring.ai.vectorstore.chroma.client.host=http://108.142.74.161
|
||||
spring.ai.vectorstore.chroma.client.port=8000
|
||||
spring.ai.vectorstore.chroma.client.key-token=tKAJfN1Yv5lP7pKorJHGfHMQhNEcM9uu
|
||||
spring.ai.vectorstore.chroma.initialize-schema=true
|
||||
spring.ai.vectorstore.chroma.collection-name=olympus
|
||||
file.upload-dir=/mnt/hermione_storage/documents/file_input_scenarios/
|
||||
|
||||
|
||||
spring.servlet.multipart.max-file-size=10MB
|
||||
spring.servlet.multipart.max-request-size=10MB
|
||||
generic-file-parser-module.url=http://generic-file-parser-module-service.olympus.svc.cluster.local:8080
|
||||
|
||||
file.upload-dir=C:\\mnt\\hermione_storage\\documents\\file_input_scenarios\\
|
||||
|
||||
|
||||
|
||||
generic-file-parser-module.url=http://generic-file-parser-module-service.olympus.svc.cluster.local:8080
|
||||
java-parser-module.url: http://java-parser-module-service.olympus.svc.cluster.local:8080
|
||||
java-re-module.url: http://java-re-module-service.olympus.svc.cluster.local:8080
|
||||
jsp-parser-module.url: http://jsp-parser-module-service.olympus.svc.cluster.local:8080
|
||||
Reference in New Issue
Block a user