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
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public S beforeCall(Consumer<AgenticScope> beforeCall) {
}

@SuppressWarnings("unchecked")
public S outputName(String outputName) {
public S outputKey(String outputName) {
Function<DefaultAgenticScope, Object> outputFunction = cog -> cog.readState(outputName);
this.workflowBuilder.outputAs(outputFunction, DefaultAgenticScope.class);
this.workflowBuilder.document(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ private static void writeAgenticScopeState(
}
}

private String outputName() {
private String outputKey() {
Object outputName =
this.workflow
.getDocument()
Expand All @@ -81,12 +81,12 @@ private String outputName() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
AgenticScopeRegistry registry = registry();
// outputName
// outputKey
if (method.getDeclaringClass() == AgentSpecification.class) {
return switch (method.getName()) {
case "name" -> this.workflow.getDocument().getName();
case "description" -> this.workflow.getDocument().getSummary();
case "outputName" -> outputName();
case "outputKey" -> outputKey();
default ->
throw new UnsupportedOperationException(
"Unknown method on AgentInstance class : " + method.getName());
Expand Down Expand Up @@ -135,7 +135,7 @@ private Object executeWorkflow(AgenticScope agenticScope, Method method, Object[
() ->
new IllegalArgumentException(
"Workflow hasn't returned a AgenticScope object."));
Object result = output.readState(outputName());
Object result = output.readState(outputKey());

return method.getReturnType().equals(ResultWithAgenticScope.class)
? new ResultWithAgenticScope<>(output, result)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void shouldSetOutputName_inDocumentMetadata() {
String outputName = "myOutputName";
SequentialAgentServiceImpl<DummyAgent> service =
(SequentialAgentServiceImpl<DummyAgent>)
SequentialAgentServiceImpl.builder(DummyAgent.class).outputName(outputName);
SequentialAgentServiceImpl.builder(DummyAgent.class).outputKey(outputName);

// when
Workflow wf = service.getDefinition();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,28 @@ void sequential_agents_tests() {
spy(
AgenticServices.agentBuilder(CreativeWriter.class)
.chatModel(BASE_MODEL)
.outputName("story")
.outputKey("story")
.build());

AudienceEditor audienceEditor =
spy(
AgenticServices.agentBuilder(AudienceEditor.class)
.chatModel(BASE_MODEL)
.outputName("story")
.outputKey("story")
.build());

StyleEditor styleEditor =
spy(
AgenticServices.agentBuilder(StyleEditor.class)
.chatModel(BASE_MODEL)
.outputName("story")
.outputKey("story")
.build());

UntypedAgent novelCreator =
builder
.sequenceBuilder()
.subAgents(creativeWriter, audienceEditor, styleEditor)
.outputName("story")
.outputKey("story")
.build();

Map<String, Object> input =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void verifyAgentCall() {
Agents.MovieExpert movieExpert =
spy(
AgenticServices.agentBuilder(Agents.MovieExpert.class)
.outputName("movies")
.outputKey("movies")
.chatModel(BASE_MODEL)
.build());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,6 @@ public void errorHandling() {
assertThat(result).containsKey("story");
}

@SuppressWarnings("unchecked")
@Test
@DisplayName("Conditional agents via choice(...)")
public void conditionalWorkflow() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ private AgentsUtils() {}
public static Agents.MovieExpert newMovieExpert() {
return spy(
AgenticServices.agentBuilder(Agents.MovieExpert.class)
.outputName("movies")
.outputKey("movies")
.chatModel(BASE_MODEL)
.build());
}

public static Agents.MovieExpert newMovieExpert2() {
return spy(
AgenticServices.agentBuilder(Agents.MovieExpert.class)
.outputName("movies")
.outputKey("movies")
.name("findMovie2")
.chatModel(BASE_MODEL)
.build());
Expand All @@ -46,39 +46,39 @@ public static Agents.MovieExpert newMovieExpert2() {
public static Agents.CreativeWriter newCreativeWriter() {
return spy(
AgenticServices.agentBuilder(Agents.CreativeWriter.class)
.outputName("story")
.outputKey("story")
.chatModel(BASE_MODEL)
.build());
}

public static Agents.AudienceEditor newAudienceEditor() {
return spy(
AgenticServices.agentBuilder(Agents.AudienceEditor.class)
.outputName("story")
.outputKey("story")
.chatModel(BASE_MODEL)
.build());
}

public static Agents.StyleEditor newStyleEditor() {
return spy(
AgenticServices.agentBuilder(Agents.StyleEditor.class)
.outputName("story")
.outputKey("story")
.chatModel(BASE_MODEL)
.build());
}

public static Agents.SummaryStory newSummaryStory() {
return spy(
AgenticServices.agentBuilder(Agents.SummaryStory.class)
.outputName("story")
.outputKey("story")
.chatModel(BASE_MODEL)
.build());
}

public static Agents.StyleScorer newStyleScorer() {
return spy(
AgenticServices.agentBuilder(Agents.StyleScorer.class)
.outputName("score")
.outputKey("score")
.chatModel(BASE_MODEL)
.build());
}
Expand All @@ -87,47 +87,47 @@ public static Agents.FoodExpert newFoodExpert() {
return spy(
AgenticServices.agentBuilder(Agents.FoodExpert.class)
.chatModel(BASE_MODEL)
.outputName("meals")
.outputKey("meals")
.build());
}

public static Agents.AstrologyAgent newAstrologyAgent() {
return spy(
AgenticServices.agentBuilder(Agents.AstrologyAgent.class)
.chatModel(BASE_MODEL)
.outputName("horoscope")
.outputKey("horoscope")
.build());
}

public static Agents.CategoryRouter newCategoryRouter() {
return spy(
AgenticServices.agentBuilder(Agents.CategoryRouter.class)
.chatModel(BASE_MODEL)
.outputName("category")
.outputKey("category")
.build());
}

public static Agents.MedicalExpert newMedicalExpert() {
return spy(
AgenticServices.agentBuilder(Agents.MedicalExpert.class)
.chatModel(BASE_MODEL)
.outputName("response")
.outputKey("response")
.build());
}

public static Agents.TechnicalExpert newTechnicalExpert() {
return spy(
AgenticServices.agentBuilder(Agents.TechnicalExpert.class)
.chatModel(BASE_MODEL)
.outputName("response")
.outputKey("response")
.build());
}

public static Agents.LegalExpert newLegalExpert() {
return spy(
AgenticServices.agentBuilder(Agents.LegalExpert.class)
.chatModel(BASE_MODEL)
.outputName("response")
.outputKey("response")
.build());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void chat_bot() {
AgenticServices.agentBuilder(Agents.ChatBot.class)
.chatModel(Models.BASE_MODEL)
.chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10))
.outputName("conversation")
.outputKey("conversation")
.build());
BlockingQueue<CloudEvent> replyEvents = new LinkedBlockingQueue<>();
BlockingQueue<CloudEvent> finishedEvents = new LinkedBlockingQueue<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void email_drafter_agent() {
Agents.EmailDrafter emailDrafter =
AgenticServices.agentBuilder(Agents.EmailDrafter.class)
.chatModel(Models.BASE_MODEL)
.outputName("email_draft")
.outputKey("email_draft")
.build();

BlockingQueue<CloudEvent> finishedEvents = new LinkedBlockingQueue<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ void mixed_workflow() {
AgenticServices.agentBuilder(Agents.ChatBot.class)
.chatModel(Models.BASE_MODEL)
.chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10))
.outputName("userInput")
.outputKey("userInput")
.build());

final Workflow mixedWorkflow =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public void testAgent() throws ExecutionException, InterruptedException {
final StorySeedAgent storySeedAgent = mock(StorySeedAgent.class);

when(storySeedAgent.invoke(eq("A Great Story"))).thenReturn("storySeedAgent");
when(storySeedAgent.outputName()).thenReturn("premise");
when(storySeedAgent.outputKey()).thenReturn("premise");
when(storySeedAgent.name()).thenReturn("storySeedAgent");

Workflow workflow =
Expand Down Expand Up @@ -72,15 +72,15 @@ public void testAgents() throws ExecutionException, InterruptedException {
final SceneAgent sceneAgent = mock(SceneAgent.class);

when(storySeedAgent.invoke(eq("A Great Story"))).thenReturn("storySeedAgent");
when(storySeedAgent.outputName()).thenReturn("premise");
when(storySeedAgent.outputKey()).thenReturn("premise");
when(storySeedAgent.name()).thenReturn("storySeedAgent");

when(plotAgent.invoke(eq("storySeedAgent"))).thenReturn("plotAgent");
when(plotAgent.outputName()).thenReturn("plot");
when(plotAgent.outputKey()).thenReturn("plot");
when(plotAgent.name()).thenReturn("plotAgent");

when(sceneAgent.invoke(eq("plotAgent"))).thenReturn("sceneAgent");
when(sceneAgent.outputName()).thenReturn("story");
when(sceneAgent.outputKey()).thenReturn("story");
when(sceneAgent.name()).thenReturn("sceneAgent");

Workflow workflow =
Expand Down Expand Up @@ -115,15 +115,15 @@ public void testSequence() throws ExecutionException, InterruptedException {
final SceneAgent sceneAgent = mock(SceneAgent.class);

when(storySeedAgent.invoke(eq("A Great Story"))).thenReturn("storySeedAgent");
when(storySeedAgent.outputName()).thenReturn("premise");
when(storySeedAgent.outputKey()).thenReturn("premise");
when(storySeedAgent.name()).thenReturn("storySeedAgent");

when(plotAgent.invoke(eq("storySeedAgent"))).thenReturn("plotAgent");
when(plotAgent.outputName()).thenReturn("plot");
when(plotAgent.outputKey()).thenReturn("plot");
when(plotAgent.name()).thenReturn("plotAgent");

when(sceneAgent.invoke(eq("plotAgent"))).thenReturn("sceneAgent");
when(sceneAgent.outputName()).thenReturn("story");
when(sceneAgent.outputKey()).thenReturn("story");
when(sceneAgent.name()).thenReturn("sceneAgent");

Workflow workflow =
Expand Down Expand Up @@ -155,15 +155,15 @@ public void testParallel() throws ExecutionException, InterruptedException {
final ConflictAgent conflict = mock(ConflictAgent.class);

when(setting.invoke(eq("sci-fi"))).thenReturn("Fake conflict response");
when(setting.outputName()).thenReturn("setting");
when(setting.outputKey()).thenReturn("setting");
when(setting.name()).thenReturn("setting");

when(hero.invoke(eq("sci-fi"))).thenReturn("Fake hero response");
when(hero.outputName()).thenReturn("hero");
when(hero.outputKey()).thenReturn("hero");
when(hero.name()).thenReturn("hero");

when(conflict.invoke(eq("sci-fi"))).thenReturn("Fake setting response");
when(conflict.outputName()).thenReturn("conflict");
when(conflict.outputKey()).thenReturn("conflict");
when(conflict.name()).thenReturn("conflict");

Workflow workflow =
Expand Down Expand Up @@ -211,15 +211,15 @@ public void testSeqAndThenParallel() throws ExecutionException, InterruptedExcep
List.of("Alien Technology Trait 1", "Alien Technology Trait 2", "Alien Technology Trait 3");

when(factAgent.invoke(eq("alien"))).thenReturn("Some Fact about aliens");
when(factAgent.outputName()).thenReturn("fact");
when(factAgent.outputKey()).thenReturn("fact");
when(factAgent.name()).thenReturn("fact");

when(cultureAgent.invoke(eq("Some Fact about aliens"))).thenReturn(cultureTraits);
when(cultureAgent.outputName()).thenReturn("culture");
when(cultureAgent.outputKey()).thenReturn("culture");
when(cultureAgent.name()).thenReturn("culture");

when(technologyAgent.invoke(eq("Some Fact about aliens"))).thenReturn(technologyTraits);
when(technologyAgent.outputName()).thenReturn("technology");
when(technologyAgent.outputKey()).thenReturn("technology");
when(technologyAgent.name()).thenReturn("technology");
Workflow workflow =
AgentWorkflowBuilder.workflow("alienCultureFlow")
Expand Down Expand Up @@ -266,13 +266,13 @@ public void humanInTheLoop() throws ExecutionException, InterruptedException {
eq("London"),
eq("Discuss project updates")))
.thenReturn("Drafted meeting invitation for John Doe");
when(meetingInvitationDraft.outputName()).thenReturn("draft");
when(meetingInvitationDraft.outputKey()).thenReturn("draft");
when(meetingInvitationDraft.name()).thenReturn("draft");

final MeetingInvitationStyle meetingInvitationStyle = mock(MeetingInvitationStyle.class);
when(meetingInvitationStyle.invoke(eq("Drafted meeting invitation for John Doe"), eq("formal")))
.thenReturn("Styled meeting invitation for John Doe");
when(meetingInvitationStyle.outputName()).thenReturn("styled");
when(meetingInvitationStyle.outputKey()).thenReturn("styled");
when(meetingInvitationStyle.name()).thenReturn("styled");

AtomicReference<String> request = new AtomicReference<>();
Expand All @@ -281,8 +281,8 @@ public void humanInTheLoop() throws ExecutionException, InterruptedException {
AgenticServices.humanInTheLoopBuilder()
.description(
"What level of formality would you like? (please reply with “formal”, “casual”, or “friendly”)")
.inputName("style")
.outputName("style")
.inputKey("style")
.outputKey("style")
.requestWriter(
q ->
request.set(
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
<version.org.hibernate.validator>9.0.1.Final</version.org.hibernate.validator>
<version.org.glassfish.expressly>6.0.0</version.org.glassfish.expressly>
<!-- Experimental modules from langchain4j -->
<version.dev.langchain4j.beta>1.7.1-beta14</version.dev.langchain4j.beta>
<version.dev.langchain4j.beta>1.8.0-beta15</version.dev.langchain4j.beta>
<!-- Base langchain4j version -->
<version.dev.langchain4j>1.8.0</version.dev.langchain4j>
<!-- Swagger Parser -->
Expand Down