chore: Update version to 1.6.6 and refactor agentType method for context handling

This commit is contained in:
extio-de
2025-07-10 00:20:16 +02:00
parent df3034e6ca
commit d9fae7eebd
5 changed files with 55 additions and 26 deletions

View File

@@ -27,6 +27,14 @@ public record Agent(String name,
throw new IllegalArgumentException("Agent type cannot be null");
}
}
@Override
public AgentType agentType(final AgentContext context) {
if (agentType != null) {
return agentType;
}
return BaseAgent.super.agentType(context);
}
@Override
public void preProcess(final AgentContext context) {

View File

@@ -67,7 +67,7 @@ public class AgentExecutorService implements InitializingBean, DisposableBean {
LOGGER.debug("Agent: {}", agent.name());
Client client = null;
if (agent.agentType() != AgentType.PROCESSING_ONLY) {
if (agent.agentType(context) != AgentType.PROCESSING_ONLY) {
client = this.clientService.getClient(agent.modelCategory());
}
context.setAgentContextUpdateConsumer(agentContextUpdateConsumer);

View File

@@ -34,10 +34,6 @@ public interface BaseAgent {
throw new UnsupportedOperationException("Name must be implemented in the agent");
}
default AgentType agentType() {
throw new UnsupportedOperationException("Agent type must be implemented in the agent");
}
default ModelCategory modelCategory() {
return ModelCategory.MEDIUM;
}
@@ -53,6 +49,10 @@ public interface BaseAgent {
default AgentResponseHandler responseHandler() {
return new TextAgentResponseHandler("response");
}
default AgentType agentType(final AgentContext context) {
throw new UnsupportedOperationException("Agent type must be implemented in the agent");
}
default void preProcess(final AgentContext context) {
@@ -82,7 +82,7 @@ public interface BaseAgent {
for (final var split : splits) {
tasks.add(CompletableFuture.runAsync(() -> {
try {
final boolean skipCompletion = split.context().isSkipNextCompletion() || this.agentType() == AgentType.PROCESSING_ONLY;
final boolean skipCompletion = split.context().isSkipNextCompletion() || this.agentType(split.context()) == AgentType.PROCESSING_ONLY;
if (skipCompletion) {
split.context().setSkipNextCompletion(false);
split.context().getGraph().add("○");
@@ -263,13 +263,23 @@ public interface BaseAgent {
conversation = Conversation.create(this.systemPrompt(), split.text());
split.context().setConversation(conversation);
}
else if (this.agentType() == AgentType.START_CONVERSATION) {
conversation = Conversation.create(this.systemPrompt() + "\n" + split.text());
else if (this.agentType(split.context()) == AgentType.START_CONVERSATION) {
if (this.systemPrompt() == null || this.systemPrompt().isEmpty()) {
conversation = Conversation.create(split.text());
}
else {
conversation = Conversation.create(this.systemPrompt() + "\n" + split.text());
}
split.context().setConversation(conversation);
}
else {
if (conversation.getConversation().get(0).type() == TurnType.SYSTEM && this.agentType() != AgentType.CONVERSATION_WITH_SYSTEM_PROMPT) {
final var mergedSysAndUser = conversation.getConversation().get(0).text() + "\n" + conversation.getConversation().get(1).text();
if (conversation.getConversation().get(0).type() == TurnType.SYSTEM && this.agentType(split.context()) != AgentType.CONVERSATION_WITH_SYSTEM_PROMPT) {
final String mergedSysAndUser;
if (conversation.getConversation().size() > 1) {
mergedSysAndUser = conversation.getConversation().get(0).text() + "\n" + conversation.getConversation().get(1).text();
} else {
mergedSysAndUser = conversation.getConversation().get(0).text();
}
final var newConversation = Conversation.create(mergedSysAndUser);
for (int n = 2; n < conversation.getConversation().size(); n++) {
@@ -280,7 +290,12 @@ public interface BaseAgent {
conversation = newConversation;
}
if (conversation.getConversation().get(conversation.getConversation().size() - 1).type() == TurnType.ASSISTANT) {
conversation.addTurn(new Conversation.Turn(TurnType.USER, String.join("\n", this.systemPrompt(), split.text())));
if (this.systemPrompt() == null || this.systemPrompt().isEmpty() ||conversation.getConversation().size() > 1) {
conversation.addTurn(new Conversation.Turn(TurnType.USER, split.text()));
}
else {
conversation.addTurn(new Conversation.Turn(TurnType.USER, String.join("\n", this.systemPrompt(), split.text())));
}
}
}
return conversation;
@@ -312,30 +327,30 @@ public interface BaseAgent {
context.setNextAgent(null);
}
case final BaseAgent a when a.agentType() == AgentType.COMPLETION -> {
case final BaseAgent a when a.agentType(context) == AgentType.COMPLETION -> {
context.getGraph().add("→");
context.setConversation(null);
}
case final BaseAgent a when a.agentType() == AgentType.START_CONVERSATION -> {
case final BaseAgent a when a.agentType(context) == AgentType.START_CONVERSATION -> {
context.getGraph().add("🗨");
context.setConversation(null);
}
case final BaseAgent a when a.agentType() == AgentType.CONVERSATION || a.agentType() == AgentType.CONVERSATION_WITH_SYSTEM_PROMPT -> {
case final BaseAgent a when a.agentType(context) == AgentType.CONVERSATION || a.agentType(context) == AgentType.CONVERSATION_WITH_SYSTEM_PROMPT -> {
context.getGraph().add("↴");
if (context.getConversation().getConversation().getLast().type() != TurnType.ASSISTANT) {
context.getConversation().addTurn(new Conversation.Turn(TurnType.ASSISTANT, context.getLastCompletion().response()));
}
}
case final BaseAgent a when a.agentType() == AgentType.PROCESSING_ONLY -> {
case final BaseAgent a when a.agentType(context) == AgentType.PROCESSING_ONLY -> {
}
default -> {
context.getGraph().add("☢");
LOGGER.error("Unknown agent type: {}", nextAgent.agentType());
LOGGER.error("Unknown agent type: {}", nextAgent.agentType(context));
context.setNextAgent(null);
}
}

View File

@@ -10,7 +10,6 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
@@ -126,6 +125,7 @@ public class AgentTest {
@Test
void streamedAgenticFlow() throws IOException {
final var lastStreamedSummary = new AtomicReference<String>();
final var agents = Map.of(
"CodeSummarizer",
new Agent("CodeSummarizer",
@@ -133,7 +133,17 @@ public class AgentTest {
ModelCategory.MEDIUM,
"Generate a summary of the following Java source code.",
"The source code is:\n{{code}}",
new TextAgentResponseHandler("summary"),
new TextAgentResponseHandler("summary",
null,
null,
null,
context -> {
if ("summary".equals(context.getStringValue(TextAgentResponseHandler.UPDATE_KEY))) { // UPDATE_KEY helps you to identify the streamed chunk
System.out.print(context.getStringValue("summary_chunk")); // Single chunks can be accessed via _chunk suffix, depends on the StreamedAgentResponseHandler implementation
lastStreamedSummary.set(context.getStringValue("summary")); // The current key value can also be accessed (e.g. concatenated, depends on the StreamedAgentResponseHandler implementation)
}
}
),
null,
context -> {
context.setStringValue("summary", context.getStringValue("summary") + "\npostprocessed");
@@ -145,16 +155,12 @@ public class AgentTest {
context.setStreaming(true);
context.getContext().put("code", List.of(Files.readString(Path.of("src/main/java/de/extio/lmlib/agent/BaseAgent.java"))));
final var lastStreamedSummary = new AtomicReference<String>();
final var resultContexts = this.agentExecutor.walk(agents.get("CodeSummarizer"), context, contextUpdate -> {
if ("summary".equals(contextUpdate.getStringValue(TextAgentResponseHandler.UPDATE_KEY))) { // UPDATE_KEY helps you to identify the streamed chunk
System.out.print(contextUpdate.getStringValue("summary_chunk")); // Single chunks can be accessed via _chunk suffix, depends on the StreamedAgentResponseHandler implementation
lastStreamedSummary.set(contextUpdate.getStringValue("summary")); // The current key value can also be accessed (e.g. concatenated, depends on the StreamedAgentResponseHandler implementation)
}
// This is an optional consumer that can be used to receive updates from the agent context
});
assertEquals(1, resultContexts.size());
assertEquals(lastStreamedSummary.get(), resultContexts.getFirst().getStringValue("summary"));
assertEquals(lastStreamedSummary.get() + "\npostprocessed", resultContexts.getFirst().getStringValue("summary"));
assertTrue(resultContexts.getFirst().getStringValue("summary").endsWith("postprocessed"));
System.out.println();