Simplify agent conversation handling and update AgentType enum

This commit is contained in:
extio-de
2026-08-23 15:22:44 +02:00
parent 328432921e
commit a71d506679
4 changed files with 18 additions and 44 deletions

View File

@@ -786,7 +786,7 @@ public class BlogPostAgent implements BaseAgent {
@Override @Override
public AgentType agentType(final AgentContext ctx) { public AgentType agentType(final AgentContext ctx) {
return AgentType.START_CONVERSATION_WITH_SYSTEM_PROMPT; return AgentType.START_CONVERSATION;
} }
@Override @Override
@@ -839,7 +839,7 @@ public class BlogPostAgent implements BaseAgent {
```java ```java
final var blogPostAgent = new Agent( final var blogPostAgent = new Agent(
"BlogPostAgent", "BlogPostAgent",
AgentType.START_CONVERSATION_WITH_SYSTEM_PROMPT, AgentType.START_CONVERSATION,
ModelCategory.MEDIUM, ModelCategory.MEDIUM,
null, null,
"You are a concise technical blog writer.", "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 | | Type | Behavior | Typical Use |
|------|----------|-------------| |------|----------|-------------|
| `START_CONVERSATION` | Starts a fresh conversation without forcing a system prompt. | New thread | | `START_CONVERSATION` | Starts a fresh conversation with `systemPrompt()` as a dedicated system turn (when present). | New thread |
| `START_CONVERSATION_WITH_SYSTEM_PROMPT` | Starts a fresh conversation with `systemPrompt()`. | Controlled resets | | `CONVERSATION` | Continues an existing conversation, keeping the system turn at index 0. | Iterative refinement, persistent system role |
| `CONVERSATION` | Continues an existing conversation. | Iterative refinement |
| `CONVERSATION_WITH_SYSTEM_PROMPT` | Continues with a dedicated system turn at index 0. | Persistent system role |
| `COMPLETION` | Stateless single-shot completion. | Transformations and one-off generation | | `COMPLETION` | Stateless single-shot completion. | Transformations and one-off generation |
| `PROCESSING_ONLY` | Skips LLM calls entirely. | Pure context manipulation | | `PROCESSING_ONLY` | Skips LLM calls entirely. | Pure context manipulation |

View File

@@ -1,5 +1,5 @@
package de.extio.lmlib.agent; package de.extio.lmlib.agent;
public enum AgentType { public enum AgentType {
COMPLETION, START_CONVERSATION, START_CONVERSATION_WITH_SYSTEM_PROMPT, CONVERSATION, CONVERSATION_WITH_SYSTEM_PROMPT, PROCESSING_ONLY; COMPLETION, START_CONVERSATION, CONVERSATION, PROCESSING_ONLY;
} }

View File

@@ -413,42 +413,11 @@ public interface BaseAgent {
private Conversation setupConversation(final Split split) { private Conversation setupConversation(final Split split) {
var conversation = split.context().getConversation(); var conversation = split.context().getConversation();
if (conversation == null || conversation.getConversation().isEmpty()) { 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 (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) {
conversation = this.createConversation(this.systemPrompt(), split.text()); conversation = this.createConversation(this.systemPrompt(), split.text());
split.context().setConversation(conversation); split.context().setConversation(conversation);
} }
else { 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) { if (conversation.getConversation().getLast().type() != TurnType.USER) {
conversation.addTurn(new Conversation.Turn(TurnType.USER, split.text())); conversation.addTurn(new Conversation.Turn(TurnType.USER, split.text()));
} }
@@ -530,13 +499,13 @@ public interface BaseAgent {
this.clearRememberedToolCallData(context); 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.getGraph().add("🗨");
context.setConversation(null); context.setConversation(null);
this.clearRememberedToolCallData(context); 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) { if (context.getConversation() == null) {
context.getGraph().add("🗨"); context.getGraph().add("🗨");
context.setConversation(null); context.setConversation(null);

View File

@@ -37,7 +37,7 @@ import de.extio.lmlib.profile.ModelCategory;
import de.extio.lmlib.profile.ModelProfileService; 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") @Disabled("This test requires a running Llama server or a cloud subscription")
@SpringBootTest(webEnvironment = WebEnvironment.NONE) @SpringBootTest(webEnvironment = WebEnvironment.NONE)
@@ -163,7 +163,7 @@ public class AgentTest {
context.setStringValue("summary_chunk", chunk.content()); context.setStringValue("summary_chunk", chunk.content());
} }
if (chunk.reasoningContent() != null) { 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) 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 -> { 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 // 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()); assertEquals(1, resultContexts.size());