Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>io.akka</groupId>
<artifactId>akka-javasdk-parent</artifactId>
<version>3.5.10</version>
<version>3.5.11</version>
</parent>

<groupId>io.akka.ai</groupId>
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/demo/multiagent/application/ActivityView.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<ActivityEntries> getActivities(String userId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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"
Expand All @@ -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"
);
});
}

Expand Down
Loading