diff --git a/README.md b/README.md index cd73108..a9d2ebf 100644 --- a/README.md +++ b/README.md @@ -786,7 +786,7 @@ public class BlogPostAgent implements BaseAgent { @Override public AgentType agentType(final AgentContext ctx) { - return AgentType.START_CONVERSATION_WITH_SYSTEM_PROMPT; + return AgentType.START_CONVERSATION; } @Override @@ -839,7 +839,7 @@ public class BlogPostAgent implements BaseAgent { ```java final var blogPostAgent = new Agent( "BlogPostAgent", - AgentType.START_CONVERSATION_WITH_SYSTEM_PROMPT, + AgentType.START_CONVERSATION, ModelCategory.MEDIUM, null, "You are a concise technical blog writer.", @@ -955,10 +955,8 @@ If you do not want the current agent to resolve tool calls itself, the conversat | Type | Behavior | Typical Use | |------|----------|-------------| -| `START_CONVERSATION` | Starts a fresh conversation without forcing a system prompt. | New thread | -| `START_CONVERSATION_WITH_SYSTEM_PROMPT` | Starts a fresh conversation with `systemPrompt()`. | Controlled resets | -| `CONVERSATION` | Continues an existing conversation. | Iterative refinement | -| `CONVERSATION_WITH_SYSTEM_PROMPT` | Continues with a dedicated system turn at index 0. | Persistent system role | +| `START_CONVERSATION` | Starts a fresh conversation with `systemPrompt()` as a dedicated system turn (when present). | New thread | +| `CONVERSATION` | Continues an existing conversation, keeping the system turn at index 0. | Iterative refinement, persistent system role | | `COMPLETION` | Stateless single-shot completion. | Transformations and one-off generation | | `PROCESSING_ONLY` | Skips LLM calls entirely. | Pure context manipulation | diff --git a/src/main/java/de/extio/lmlib/agent/AgentType.java b/src/main/java/de/extio/lmlib/agent/AgentType.java index ef05cbe..10c75f7 100755 --- a/src/main/java/de/extio/lmlib/agent/AgentType.java +++ b/src/main/java/de/extio/lmlib/agent/AgentType.java @@ -1,5 +1,5 @@ package de.extio.lmlib.agent; public enum AgentType { - COMPLETION, START_CONVERSATION, START_CONVERSATION_WITH_SYSTEM_PROMPT, CONVERSATION, CONVERSATION_WITH_SYSTEM_PROMPT, PROCESSING_ONLY; + COMPLETION, START_CONVERSATION, CONVERSATION, PROCESSING_ONLY; } diff --git a/src/main/java/de/extio/lmlib/agent/BaseAgent.java b/src/main/java/de/extio/lmlib/agent/BaseAgent.java index 8aa6b33..9c57f56 100644 --- a/src/main/java/de/extio/lmlib/agent/BaseAgent.java +++ b/src/main/java/de/extio/lmlib/agent/BaseAgent.java @@ -413,42 +413,11 @@ public interface BaseAgent { private Conversation setupConversation(final Split split) { var conversation = split.context().getConversation(); - if (conversation == null || conversation.getConversation().isEmpty()) { - conversation = this.createConversation(this.systemPrompt(), split.text()); - split.context().setConversation(conversation); - } - else if (this.agentType(split.context()) == AgentType.START_CONVERSATION) { - final var system = this.systemPrompt(); - if (system == null || system.isEmpty()) { - conversation = this.createConversation(null, split.text()); - } - else { - conversation = this.createConversation(null, system + "\n" + split.text()); - } - split.context().setConversation(conversation); - } - else if (this.agentType(split.context()) == AgentType.START_CONVERSATION_WITH_SYSTEM_PROMPT) { + if (conversation == null || conversation.getConversation().isEmpty() || this.agentType(split.context()) == AgentType.START_CONVERSATION) { conversation = this.createConversation(this.systemPrompt(), split.text()); split.context().setConversation(conversation); } else { - 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 = this.createConversation(null, mergedSysAndUser); - for (int n = 2; n < conversation.getConversation().size(); n++) { - newConversation.addTurn(conversation.getConversation().get(n)); - } - - split.context().setConversation(newConversation); - conversation = newConversation; - } - if (conversation.getConversation().getLast().type() != TurnType.USER) { conversation.addTurn(new Conversation.Turn(TurnType.USER, split.text())); } @@ -530,13 +499,13 @@ public interface BaseAgent { this.clearRememberedToolCallData(context); } - case final BaseAgent a when a.agentType(context) == AgentType.START_CONVERSATION || a.agentType(context) == AgentType.START_CONVERSATION_WITH_SYSTEM_PROMPT -> { + case final BaseAgent a when a.agentType(context) == AgentType.START_CONVERSATION -> { context.getGraph().add("🗨"); context.setConversation(null); this.clearRememberedToolCallData(context); } - case final BaseAgent a when a.agentType(context) == AgentType.CONVERSATION || a.agentType(context) == AgentType.CONVERSATION_WITH_SYSTEM_PROMPT -> { + case final BaseAgent a when a.agentType(context) == AgentType.CONVERSATION -> { if (context.getConversation() == null) { context.getGraph().add("🗨"); context.setConversation(null); diff --git a/src/test/java/de/extio/lmlib/agent/AgentTest.java b/src/test/java/de/extio/lmlib/agent/AgentTest.java index ffb265d..a0e16bc 100644 --- a/src/test/java/de/extio/lmlib/agent/AgentTest.java +++ b/src/test/java/de/extio/lmlib/agent/AgentTest.java @@ -37,7 +37,7 @@ import de.extio.lmlib.profile.ModelCategory; import de.extio.lmlib.profile.ModelProfileService; /** - * These tests have been verified with Llama 3.1 8B, Gemma2 27B, Gemma3 27B, GPT-OSS 20B, and Qwen3.5 9B models + * These tests have been verified with Llama 3.1 8B, Gemma2 27B, Gemma3 27B, GPT-OSS 20B, Qwen3.5 9B, and Qwen 3.6 35B A3B models */ @Disabled("This test requires a running Llama server or a cloud subscription") @SpringBootTest(webEnvironment = WebEnvironment.NONE) @@ -163,7 +163,7 @@ public class AgentTest { context.setStringValue("summary_chunk", chunk.content()); } if (chunk.reasoningContent() != null) { - // System.out.print(chunk.reasoningContent()); // The reasoning can also be accessed if available + context.setStringValue("reasoning_chunk", chunk.reasoningContent()); } lastStreamedSummary.set(context.getStringValue("summary")); // The current key value can also be accessed (e.g. concatenated, depends on the StreamedAgentResponseHandler implementation) } @@ -181,7 +181,14 @@ public class AgentTest { final var resultContexts = this.agentExecutor.walk(agents.get("CodeSummarizer"), context, contextUpdate -> { // This is an optional consumer that can be used to receive updates from the agent context - System.out.print(contextUpdate.getStringValue("summary_chunk")); + final var summaryChunk = contextUpdate.getStringValue("summary_chunk"); + if (summaryChunk != null) { + System.out.print(summaryChunk); + } + final var reasoningChunk = contextUpdate.getStringValue("reasoning_chunk"); + if (reasoningChunk != null) { + System.out.print(reasoningChunk); + } }); assertEquals(1, resultContexts.size());