Agent: skipNextCompletion; Better cache keys; XL category; Fix ModelProfileService concurrency;

This commit is contained in:
extio-de
2025-06-22 13:28:22 +02:00
parent 04cde2558a
commit dc455165c8
7 changed files with 34 additions and 22 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/target/
/.classpath
/.project
/.settings/

View File

@@ -43,12 +43,17 @@ public record Agent(String name, AgentType agentType, ModelCategory modelCategor
for (final var split : splits) { for (final var split : splits) {
tasks.add(CompletableFuture.runAsync(() -> { tasks.add(CompletableFuture.runAsync(() -> {
try { try {
if (this.agentType() != AgentType.PROCESSING_ONLY) { boolean skipCompletion = split.context().isSkipNextCompletion() || this.agentType() == AgentType.PROCESSING_ONLY;
if (skipCompletion) {
split.context().setSkipNextCompletion(false);
split.context().getGraph().add("○");
}
else {
split.context().getGraph().add(this.modelCategory.getShortName()); split.context().getGraph().add(this.modelCategory.getShortName());
} }
split.context().getGraph().add(this.name()); split.context().getGraph().add(this.name());
if (this.agentType != AgentType.PROCESSING_ONLY) { if (!skipCompletion) {
final var conversation = this.setupConversation(split); final var conversation = this.setupConversation(split);
LOGGER.debug("Conversation: {}", conversation); LOGGER.debug("Conversation: {}", conversation);
@@ -270,7 +275,7 @@ public record Agent(String name, AgentType agentType, ModelCategory modelCategor
} }
case final Agent a when a.agentType() == AgentType.PROCESSING_ONLY -> { case final Agent a when a.agentType() == AgentType.PROCESSING_ONLY -> {
context.getGraph().add("○");
} }
default -> { default -> {

View File

@@ -30,6 +30,8 @@ public final class AgentContext {
private volatile boolean error; private volatile boolean error;
private volatile boolean skipNextCompletion;
public AgentContext(final Map<String, Agent> agents) { public AgentContext(final Map<String, Agent> agents) {
this.agents = agents; this.agents = agents;
this.context = new ConcurrentHashMap<>(); this.context = new ConcurrentHashMap<>();
@@ -48,6 +50,7 @@ public final class AgentContext {
this.requestStatistic = other.requestStatistic; this.requestStatistic = other.requestStatistic;
this.lastCompletion = other.lastCompletion; this.lastCompletion = other.lastCompletion;
this.error = other.error; this.error = other.error;
this.skipNextCompletion = other.skipNextCompletion;
synchronized (other.graph) { synchronized (other.graph) {
this.graph.addAll(other.graph); this.graph.addAll(other.graph);
} }
@@ -125,4 +128,12 @@ public final class AgentContext {
this.error = error; this.error = error;
} }
public boolean isSkipNextCompletion() {
return this.skipNextCompletion;
}
public void setSkipNextCompletion(final boolean skipNextCompletion) {
this.skipNextCompletion = skipNextCompletion;
}
} }

View File

@@ -46,7 +46,7 @@ public class AgentExecutorService implements InitializingBean, DisposableBean {
} }
public List<AgentContext> walkGraph(final Agent agent, final AgentContext context) { public List<AgentContext> walkGraph(final Agent agent, final AgentContext context) {
LOGGER.info("Agent: {}", agent.name()); LOGGER.debug("Agent: {}", agent.name());
Client client = null; Client client = null;
if (agent.agentType() != AgentType.PROCESSING_ONLY) { if (agent.agentType() != AgentType.PROCESSING_ONLY) {

View File

@@ -69,35 +69,26 @@ public class CachedClient implements Client {
throw new IllegalArgumentException("ModelProfile " + modelCategory.getModelProfile()); throw new IllegalArgumentException("ModelProfile " + modelCategory.getModelProfile());
} }
final var key = new StringBuilder();
key.append(Objects.requireNonNullElse(modelProfile.modelName(), modelCategory.name()));
key.append("_");
key.append(modelProfile.maxTokens());
key.append("_");
key.append(modelProfile.maxContextLength());
key.append("_");
key.append(modelProfile.maxContinuations());
key.append("_");
key.append(modelProfile.temperature());
key.append("_");
key.append(modelProfile.topP());
key.append("_");
MessageDigest digest; MessageDigest digest;
try { try {
digest = MessageDigest.getInstance("SHA-256"); digest = MessageDigest.getInstance("SHA-256");
digest.update(Objects.requireNonNullElse(modelProfile.modelName(), modelCategory.name()).getBytes());
digest.update(String.valueOf(modelProfile.modelProvider()).getBytes());
digest.update(String.valueOf(modelProfile.maxTokens()).getBytes());
digest.update(String.valueOf(modelProfile.maxContextLength()).getBytes());
digest.update(String.valueOf(modelProfile.maxContinuations()).getBytes());
digest.update(String.valueOf(modelProfile.temperature()).getBytes());
digest.update(String.valueOf(modelProfile.topP()).getBytes());
for (final var k : keys) { for (final var k : keys) {
if (k != null && !k.isEmpty()) { if (k != null && !k.isEmpty()) {
digest.update(k.getBytes()); digest.update(k.getBytes());
} }
} }
key.append(HexFormat.of().formatHex(digest.digest())); return HexFormat.of().formatHex(digest.digest());
} }
catch (final NoSuchAlgorithmException e) { catch (final NoSuchAlgorithmException e) {
throw new RuntimeException("Error calculating hash", e); throw new RuntimeException("Error calculating hash", e);
} }
return key.toString();
} }
} }

View File

@@ -5,6 +5,7 @@ public enum ModelCategory {
SMALL("profile.model.s", "S"), SMALL("profile.model.s", "S"),
MEDIUM("profile.model.m", "M"), MEDIUM("profile.model.m", "M"),
LARGE("profile.model.l", "L"), LARGE("profile.model.l", "L"),
XLARGE("profile.model.xl", "XL"),
HOT("profile.model.hot", "HOT"), HOT("profile.model.hot", "HOT"),
COLD("profile.model.cold", "COLD"); COLD("profile.model.cold", "COLD");

View File

@@ -94,7 +94,7 @@ public class ModelProfileService {
String apiKey = null; String apiKey = null;
synchronized (this.environment) { synchronized (this.environment) {
if (this.environment instanceof ConfigurableEnvironment configurableEnvironment) { if (this.environment instanceof ConfigurableEnvironment configurableEnvironment) {
configurableEnvironment.getPropertySources().addLast(resource); configurableEnvironment.getPropertySources().addFirst(resource);
} }
apiKey = Optional.ofNullable(this.environment.getProperty("apiKey")) apiKey = Optional.ofNullable(this.environment.getProperty("apiKey"))
.map(Object::toString) .map(Object::toString)