Skip to content

Commit

Permalink
CAMEL-21503: remove the tools feature from the chat component
Browse files Browse the repository at this point in the history
  • Loading branch information
orpiske committed Dec 26, 2024
1 parent 6690a1d commit ac62bba
Show file tree
Hide file tree
Showing 8 changed files with 2 additions and 496 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,12 @@
package org.apache.camel.component.langchain4j.chat;

import java.util.Map;
import java.util.stream.Collectors;

import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.annotations.Component;
import org.apache.camel.support.DefaultComponent;
import org.apache.camel.util.PropertiesHelper;

import static org.apache.camel.component.langchain4j.chat.LangChain4jChat.SCHEME;

Expand Down Expand Up @@ -60,11 +58,7 @@ protected Endpoint createEndpoint(String uri, String remaining, Map<String, Obje

LangChain4jChatConfiguration langchain4jChatConfiguration = this.configuration.copy();

Map<String, Object> toolParameters = PropertiesHelper.extractProperties(parameters, "parameter.");
Endpoint endpoint = new LangChain4jChatEndpoint(uri, this, remaining, langchain4jChatConfiguration);
((LangChain4jChatEndpoint) endpoint).setParameters(toolParameters.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> (String) e.getValue())));

setProperties(endpoint, parameters);
return endpoint;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,16 @@
package org.apache.camel.component.langchain4j.chat;

import java.util.Map;
import java.util.UUID;

import dev.langchain4j.agent.tool.JsonSchemaProperty;
import dev.langchain4j.agent.tool.ToolSpecification;
import org.apache.camel.Category;
import org.apache.camel.Consumer;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.component.langchain4j.chat.tool.CamelSimpleToolParameter;
import org.apache.camel.component.langchain4j.chat.tool.CamelToolExecutorCache;
import org.apache.camel.component.langchain4j.chat.tool.CamelToolSpecification;
import org.apache.camel.component.langchain4j.chat.tool.NamedJsonSchemaProperty;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.UriEndpoint;
import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriPath;
import org.apache.camel.support.DefaultEndpoint;
import org.apache.camel.util.StringHelper;

import static org.apache.camel.component.langchain4j.chat.LangChain4jChat.SCHEME;

Expand All @@ -51,19 +43,6 @@ public class LangChain4jChatEndpoint extends DefaultEndpoint {
@UriParam
private LangChain4jChatConfiguration configuration;

@Metadata(label = "consumer")
@UriParam(description = "Tool description")
private String description;

@Metadata(label = "consumer")
@UriParam(description = "List of Tool parameters in the form of parameter.<name>=<type>", prefix = "parameter.",
multiValue = true, enums = "string,integer,number,object,array,boolean,null")
private Map<String, String> parameters;

@Metadata(label = "consumer,advanced")
@UriParam(description = "Tool's Camel Parameters, programmatically define Tool description and parameters")
private CamelSimpleToolParameter camelToolParameter;

public LangChain4jChatEndpoint(String uri, LangChain4jChatComponent component, String chatId,
LangChain4jChatConfiguration configuration) {
super(uri, component);
Expand All @@ -78,44 +57,7 @@ public Producer createProducer() throws Exception {

@Override
public Consumer createConsumer(Processor processor) throws Exception {
ToolSpecification.Builder toolSpecificationBuilder = ToolSpecification.builder();
toolSpecificationBuilder.name(UUID.randomUUID().toString());
if (camelToolParameter != null) {
toolSpecificationBuilder.description(camelToolParameter.getDescription());

for (NamedJsonSchemaProperty namedJsonSchemaProperty : camelToolParameter.getProperties()) {
toolSpecificationBuilder.addParameter(namedJsonSchemaProperty.getName(),
namedJsonSchemaProperty.getProperties());
}
} else if (description != null) {
toolSpecificationBuilder.description(description);

if (parameters != null) {
parameters.forEach((name, type) -> toolSpecificationBuilder.addParameter(name, JsonSchemaProperty.type(type)));
}
} else {
// Consumer without toolParameter or description
throw new IllegalArgumentException(
"In order to use the langchain4j component as a consumer, you need to specify at least description, or a camelToolParameter");
}

String simpleDescription = null;
if (description != null) {
simpleDescription = StringHelper.dashToCamelCase(description.replace(" ", "-"));
}

ToolSpecification toolSpecification = toolSpecificationBuilder
.name(simpleDescription)
.build();

final LangChain4jChatConsumer langChain4jChatConsumer = new LangChain4jChatConsumer(this, processor);
configureConsumer(langChain4jChatConsumer);

CamelToolSpecification camelToolSpecification
= new CamelToolSpecification(toolSpecification, langChain4jChatConsumer);
CamelToolExecutorCache.getInstance().put(chatId, camelToolSpecification);

return camelToolSpecification.getConsumer();
throw new UnsupportedOperationException("Consumer not supported");
}

/**
Expand All @@ -131,34 +73,8 @@ public LangChain4jChatConfiguration getConfiguration() {
return configuration;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public Map<String, String> getParameters() {
return parameters;
}

public void setParameters(Map<String, String> parameters) {
this.parameters = parameters;
}

public CamelSimpleToolParameter getCamelToolParameter() {
return camelToolParameter;
}

public void setCamelToolParameter(CamelSimpleToolParameter camelToolParameter) {
this.camelToolParameter = camelToolParameter;
}

@Override
protected void doStop() throws Exception {
super.doStop();

CamelToolExecutorCache.getInstance().getTools().clear();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,10 @@

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import dev.langchain4j.agent.tool.ToolExecutionRequest;
import dev.langchain4j.agent.tool.ToolSpecification;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.ToolExecutionResultMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.input.Prompt;
Expand All @@ -39,8 +33,6 @@
import org.apache.camel.Exchange;
import org.apache.camel.InvalidPayloadException;
import org.apache.camel.NoSuchHeaderException;
import org.apache.camel.component.langchain4j.chat.tool.CamelToolExecutorCache;
import org.apache.camel.component.langchain4j.chat.tool.CamelToolSpecification;
import org.apache.camel.support.DefaultProducer;
import org.apache.camel.util.ObjectHelper;

Expand Down Expand Up @@ -171,52 +163,7 @@ private String sendListChatMessage(List<ChatMessage> chatMessages, Exchange exch

}

final Map<String, Set<CamelToolSpecification>> tools = CamelToolExecutorCache.getInstance().getTools();
if (tools.containsKey(langChain4jChatEndpoint.getChatId())) {
final Set<CamelToolSpecification> camelToolSpecificationSet = tools
.get(langChain4jChatEndpoint.getChatId());

final List<ToolSpecification> toolSpecifications = camelToolSpecificationSet.stream()
.map(camelToolSpecification -> camelToolSpecification.getToolSpecification())
.collect(Collectors.toList());

response = this.chatLanguageModel.generate(chatMessages, toolSpecifications);
} else {
response = this.chatLanguageModel.generate(chatMessages);
}

if (response.content().hasToolExecutionRequests()) {
chatMessages.add(response.content());

for (ToolExecutionRequest toolExecutionRequest : response.content().toolExecutionRequests()) {
String toolName = toolExecutionRequest.name();
CamelToolSpecification camelToolSpecification = CamelToolExecutorCache.getInstance().getTools()
.get(langChain4jChatEndpoint.getChatId()).stream()
.filter(cts -> cts.getToolSpecification().name().equals(toolName))
.findFirst().orElseThrow(() -> new RuntimeException("Tool " + toolName + " not found"));
try {
// Map Json to Header
JsonNode jsonNode = objectMapper.readValue(toolExecutionRequest.arguments(), JsonNode.class);

jsonNode.fieldNames()
.forEachRemaining(name -> exchange.getMessage().setHeader(name, jsonNode.get(name)));

// Execute the consumer route
camelToolSpecification.getConsumer().getProcessor().process(exchange);
} catch (Exception e) {
// How to handle this exception?
exchange.setException(e);
}

chatMessages.add(new ToolExecutionResultMessage(
toolExecutionRequest.id(),
toolExecutionRequest.name(),
exchange.getIn().getBody(String.class)));
}

response = this.chatLanguageModel.generate(chatMessages);
}

response = this.chatLanguageModel.generate(chatMessages);
return extractAiResponse(response);
}

Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit ac62bba

Please sign in to comment.