diff --git a/README.md b/README.md
index fdcb2d5..ad97c93 100644
--- a/README.md
+++ b/README.md
@@ -71,9 +71,23 @@ Note that the agents selected depend on the user's query and the available agent
### Prerequisites
- Java 21 or higher
- Maven 3.6 or higher
+- A [Secure Repository Token](https://account.akka.io/token)
### Build and run
+---
+
+### Secure Repository Token
+
+Building requires a secure repository token, which is set up as part of [Akka CLI](https://doc.akka.io/getting-started/quick-install-cli.html)'s `akka code init` command.
+
+If you still need to configure your system with the token there are two additional ways:
+
+1. Use the Akka CLI's `akka code token` command and follow the instructions.
+2. Set up the token manually as described [here](https://account.akka.io/token).
+
+---
+
To run the application, you need to provide the following environment variables:
- `OPENAI_API_KEY`: Your OpenAI API key. If you prefer to use a different LLM model, follow the instructions in `application.conf` to change it.
- `WEATHER_API_KEY`: (Optional) API key for the weather service
diff --git a/pom.xml b/pom.xml
index 4fdcfe3..2991f12 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
io.akka
akka-javasdk-parent
- 3.5.10
+ 3.5.11
io.akka.ai
diff --git a/src/main/java/demo/multiagent/application/ActivityView.java b/src/main/java/demo/multiagent/application/ActivityView.java
index 323fd3f..327ca59 100644
--- a/src/main/java/demo/multiagent/application/ActivityView.java
+++ b/src/main/java/demo/multiagent/application/ActivityView.java
@@ -18,7 +18,11 @@ public record ActivityEntry(
String sessionId,
String userQuestion,
String finalAnswer
- ) {}
+ ) {
+ public boolean hasFinalAnswer() {
+ return finalAnswer != null && !finalAnswer.isEmpty();
+ }
+ }
@Query("SELECT * AS entries FROM activities WHERE userId = :userId")
public QueryEffect getActivities(String userId) {
diff --git a/src/main/java/demo/multiagent/application/PreferencesConsumer.java b/src/main/java/demo/multiagent/application/PreferencesConsumer.java
index a22824a..cbffe8a 100644
--- a/src/main/java/demo/multiagent/application/PreferencesConsumer.java
+++ b/src/main/java/demo/multiagent/application/PreferencesConsumer.java
@@ -32,7 +32,7 @@ public Effect onPreferenceAdded(PreferencesEvent.PreferenceAdded event) {
// Call EvaluatorAgent for each session
for (var activity : activities.entries()) {
- if (activity.finalAnswer() != null && !activity.finalAnswer().isEmpty()) {
+ if (activity.hasFinalAnswer()) {
var evaluationRequest = new EvaluatorAgent.EvaluationRequest(
userId,
activity.userQuestion(),
diff --git a/src/test/java/demo/multiagent/api/ActivityEndpointIntegrationTest.java b/src/test/java/demo/multiagent/api/ActivityEndpointIntegrationTest.java
index 98ed1ca..e4285b5 100644
--- a/src/test/java/demo/multiagent/api/ActivityEndpointIntegrationTest.java
+++ b/src/test/java/demo/multiagent/api/ActivityEndpointIntegrationTest.java
@@ -9,7 +9,12 @@
import akka.javasdk.testkit.TestKit;
import akka.javasdk.testkit.TestKitSupport;
import akka.javasdk.testkit.TestModelProvider;
-import demo.multiagent.application.*;
+import demo.multiagent.application.ActivityAgent;
+import demo.multiagent.application.EvaluatorAgent;
+import demo.multiagent.application.PlannerAgent;
+import demo.multiagent.application.SelectorAgent;
+import demo.multiagent.application.SummarizerAgent;
+import demo.multiagent.application.WeatherAgent;
import demo.multiagent.domain.AgentSelection;
import demo.multiagent.domain.Plan;
import demo.multiagent.domain.PlanStep;
@@ -52,10 +57,14 @@ public void shouldHandleFullActivitySuggestionWorkflowWithPreferenceUpdate() {
// Setup initial AI model responses
setupInitialModelResponses();
+ //debug id for correlating tracing information
+ String debugId = "12345";
+
// 1. Call suggestActivities endpoint
var suggestResponse = httpClient
.POST("/activities/" + userId)
.withRequestBody(new ActivityEndpoint.Request(query))
+ .addHeader("akka-debug-id", debugId)
.invoke();
assertThat(suggestResponse.status()).isEqualTo(StatusCodes.CREATED);
@@ -103,13 +112,35 @@ public void shouldHandleFullActivitySuggestionWorkflowWithPreferenceUpdate() {
var suggestion = activitiesList.suggestions().getFirst();
assertThat(suggestion.userQuestion()).isEqualTo(query);
assertThat(suggestion.answer()).contains("bike tour");
+
+ var steps = telemetryReader.getWorkflowSteps(debugId);
+ assertThat(steps).containsOnly(
+ "select-agents",
+ "create-plan",
+ "execute-plan",
+ "execute-plan",
+ "summarize"
+ );
+
+ var agents = telemetryReader.getAgents(debugId);
+ assertThat(agents).containsOnly(
+ "selector-agent",
+ "planner-agent",
+ "weather-agent",
+ "activity-agent",
+ "summarizer-agent",
+ "toxicity-evaluator",
+ "summarization-evaluator"
+ );
});
// 4. Add preference that invalidates previous suggestion
setupUpdatedModelResponsesForPreference();
+ var nextDebugId = "67890";
var preferenceResponse = httpClient
.POST("/preferences/" + userId)
+ .addHeader("akka-debug-id", nextDebugId)
.withRequestBody(
new ActivityEndpoint.AddPreference(
"I hate outdoor activities and prefer indoor museums"
@@ -135,6 +166,17 @@ public void shouldHandleFullActivitySuggestionWorkflowWithPreferenceUpdate() {
assertThat(updatedAnswer).contains("Vasa Museum");
assertThat(updatedAnswer).contains("indoor");
assertThat(updatedAnswer).doesNotContain("bike tour");
+
+ assertThat(telemetryReader.getAgents(nextDebugId)).containsOnly(
+ "evaluator-agent",
+ "selector-agent",
+ "planner-agent",
+ "weather-agent",
+ "activity-agent",
+ "summarizer-agent",
+ "toxicity-evaluator",
+ "summarization-evaluator"
+ );
});
}