diff --git a/experimental/fluent/agentic-langchain4j/src/main/java/io/serverlessworkflow/fluent/agentic/langchain4j/AbstractAgentService.java b/experimental/fluent/agentic-langchain4j/src/main/java/io/serverlessworkflow/fluent/agentic/langchain4j/AbstractAgentService.java index 8abc54b1c..7f830cf2e 100644 --- a/experimental/fluent/agentic-langchain4j/src/main/java/io/serverlessworkflow/fluent/agentic/langchain4j/AbstractAgentService.java +++ b/experimental/fluent/agentic-langchain4j/src/main/java/io/serverlessworkflow/fluent/agentic/langchain4j/AbstractAgentService.java @@ -66,7 +66,7 @@ public S beforeCall(Consumer beforeCall) { } @SuppressWarnings("unchecked") - public S outputName(String outputName) { + public S outputKey(String outputName) { Function outputFunction = cog -> cog.readState(outputName); this.workflowBuilder.outputAs(outputFunction, DefaultAgenticScope.class); this.workflowBuilder.document( diff --git a/experimental/fluent/agentic-langchain4j/src/main/java/io/serverlessworkflow/fluent/agentic/langchain4j/WorkflowInvocationHandler.java b/experimental/fluent/agentic-langchain4j/src/main/java/io/serverlessworkflow/fluent/agentic/langchain4j/WorkflowInvocationHandler.java index 33c9a9745..c3ba1f429 100644 --- a/experimental/fluent/agentic-langchain4j/src/main/java/io/serverlessworkflow/fluent/agentic/langchain4j/WorkflowInvocationHandler.java +++ b/experimental/fluent/agentic-langchain4j/src/main/java/io/serverlessworkflow/fluent/agentic/langchain4j/WorkflowInvocationHandler.java @@ -65,7 +65,7 @@ private static void writeAgenticScopeState( } } - private String outputName() { + private String outputKey() { Object outputName = this.workflow .getDocument() @@ -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()); @@ -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) diff --git a/experimental/fluent/agentic-langchain4j/src/test/java/io/serverlessworkflow/fluent/agentic/langchain4j/SequentialAgentServiceImplTest.java b/experimental/fluent/agentic-langchain4j/src/test/java/io/serverlessworkflow/fluent/agentic/langchain4j/SequentialAgentServiceImplTest.java index 1902f2cea..02ea8e66e 100644 --- a/experimental/fluent/agentic-langchain4j/src/test/java/io/serverlessworkflow/fluent/agentic/langchain4j/SequentialAgentServiceImplTest.java +++ b/experimental/fluent/agentic-langchain4j/src/test/java/io/serverlessworkflow/fluent/agentic/langchain4j/SequentialAgentServiceImplTest.java @@ -64,7 +64,7 @@ void shouldSetOutputName_inDocumentMetadata() { String outputName = "myOutputName"; SequentialAgentServiceImpl service = (SequentialAgentServiceImpl) - SequentialAgentServiceImpl.builder(DummyAgent.class).outputName(outputName); + SequentialAgentServiceImpl.builder(DummyAgent.class).outputKey(outputName); // when Workflow wf = service.getDefinition(); diff --git a/experimental/fluent/agentic-langchain4j/src/test/java/io/serverlessworkflow/fluent/agentic/langchain4j/WorkflowAgentsIT.java b/experimental/fluent/agentic-langchain4j/src/test/java/io/serverlessworkflow/fluent/agentic/langchain4j/WorkflowAgentsIT.java index 52e4d86f2..32be899b4 100644 --- a/experimental/fluent/agentic-langchain4j/src/test/java/io/serverlessworkflow/fluent/agentic/langchain4j/WorkflowAgentsIT.java +++ b/experimental/fluent/agentic-langchain4j/src/test/java/io/serverlessworkflow/fluent/agentic/langchain4j/WorkflowAgentsIT.java @@ -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 input = diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/AgentWorkflowBuilderTest.java b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/AgentWorkflowBuilderTest.java index 63477fba3..b659f5709 100644 --- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/AgentWorkflowBuilderTest.java +++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/AgentWorkflowBuilderTest.java @@ -44,7 +44,7 @@ public void verifyAgentCall() { Agents.MovieExpert movieExpert = spy( AgenticServices.agentBuilder(Agents.MovieExpert.class) - .outputName("movies") + .outputKey("movies") .chatModel(BASE_MODEL) .build()); diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/AgenticWorkflowHelperIT.java b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/AgenticWorkflowHelperIT.java index 3ecc0fe79..a6ca6a5cf 100644 --- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/AgenticWorkflowHelperIT.java +++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/AgenticWorkflowHelperIT.java @@ -191,7 +191,6 @@ public void errorHandling() { assertThat(result).containsKey("story"); } - @SuppressWarnings("unchecked") @Test @DisplayName("Conditional agents via choice(...)") public void conditionalWorkflow() { diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/AgentsUtils.java b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/AgentsUtils.java index 81823e369..2404d1c12 100644 --- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/AgentsUtils.java +++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/AgentsUtils.java @@ -29,7 +29,7 @@ private AgentsUtils() {} public static Agents.MovieExpert newMovieExpert() { return spy( AgenticServices.agentBuilder(Agents.MovieExpert.class) - .outputName("movies") + .outputKey("movies") .chatModel(BASE_MODEL) .build()); } @@ -37,7 +37,7 @@ public static Agents.MovieExpert newMovieExpert() { public static Agents.MovieExpert newMovieExpert2() { return spy( AgenticServices.agentBuilder(Agents.MovieExpert.class) - .outputName("movies") + .outputKey("movies") .name("findMovie2") .chatModel(BASE_MODEL) .build()); @@ -46,7 +46,7 @@ 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()); } @@ -54,7 +54,7 @@ public static Agents.CreativeWriter newCreativeWriter() { public static Agents.AudienceEditor newAudienceEditor() { return spy( AgenticServices.agentBuilder(Agents.AudienceEditor.class) - .outputName("story") + .outputKey("story") .chatModel(BASE_MODEL) .build()); } @@ -62,7 +62,7 @@ public static Agents.AudienceEditor newAudienceEditor() { public static Agents.StyleEditor newStyleEditor() { return spy( AgenticServices.agentBuilder(Agents.StyleEditor.class) - .outputName("story") + .outputKey("story") .chatModel(BASE_MODEL) .build()); } @@ -70,7 +70,7 @@ public static Agents.StyleEditor newStyleEditor() { public static Agents.SummaryStory newSummaryStory() { return spy( AgenticServices.agentBuilder(Agents.SummaryStory.class) - .outputName("story") + .outputKey("story") .chatModel(BASE_MODEL) .build()); } @@ -78,7 +78,7 @@ public static Agents.SummaryStory newSummaryStory() { public static Agents.StyleScorer newStyleScorer() { return spy( AgenticServices.agentBuilder(Agents.StyleScorer.class) - .outputName("score") + .outputKey("score") .chatModel(BASE_MODEL) .build()); } @@ -87,7 +87,7 @@ public static Agents.FoodExpert newFoodExpert() { return spy( AgenticServices.agentBuilder(Agents.FoodExpert.class) .chatModel(BASE_MODEL) - .outputName("meals") + .outputKey("meals") .build()); } @@ -95,7 +95,7 @@ public static Agents.AstrologyAgent newAstrologyAgent() { return spy( AgenticServices.agentBuilder(Agents.AstrologyAgent.class) .chatModel(BASE_MODEL) - .outputName("horoscope") + .outputKey("horoscope") .build()); } @@ -103,7 +103,7 @@ public static Agents.CategoryRouter newCategoryRouter() { return spy( AgenticServices.agentBuilder(Agents.CategoryRouter.class) .chatModel(BASE_MODEL) - .outputName("category") + .outputKey("category") .build()); } @@ -111,7 +111,7 @@ public static Agents.MedicalExpert newMedicalExpert() { return spy( AgenticServices.agentBuilder(Agents.MedicalExpert.class) .chatModel(BASE_MODEL) - .outputName("response") + .outputKey("response") .build()); } @@ -119,7 +119,7 @@ public static Agents.TechnicalExpert newTechnicalExpert() { return spy( AgenticServices.agentBuilder(Agents.TechnicalExpert.class) .chatModel(BASE_MODEL) - .outputName("response") + .outputKey("response") .build()); } @@ -127,7 +127,7 @@ public static Agents.LegalExpert newLegalExpert() { return spy( AgenticServices.agentBuilder(Agents.LegalExpert.class) .chatModel(BASE_MODEL) - .outputName("response") + .outputKey("response") .build()); } diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/ChatBotIT.java b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/ChatBotIT.java index 74e4c417d..717f84944 100644 --- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/ChatBotIT.java +++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/ChatBotIT.java @@ -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 replyEvents = new LinkedBlockingQueue<>(); BlockingQueue finishedEvents = new LinkedBlockingQueue<>(); diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/EmailDrafterIT.java b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/EmailDrafterIT.java index 1e6069c46..4925ed649 100644 --- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/EmailDrafterIT.java +++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/EmailDrafterIT.java @@ -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 finishedEvents = new LinkedBlockingQueue<>(); diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/MixedWorkflowIT.java b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/MixedWorkflowIT.java index 067c7d379..a91cfe967 100644 --- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/MixedWorkflowIT.java +++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/MixedWorkflowIT.java @@ -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 = diff --git a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/WorkflowTests.java b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/WorkflowTests.java index 3d4118888..ed834ded1 100644 --- a/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/WorkflowTests.java +++ b/experimental/fluent/agentic/src/test/java/io/serverlessworkflow/fluent/agentic/WorkflowTests.java @@ -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 = @@ -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 = @@ -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 = @@ -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 = @@ -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") @@ -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 request = new AtomicReference<>(); @@ -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( diff --git a/pom.xml b/pom.xml index 8a0d64342..ce6c6f42e 100644 --- a/pom.xml +++ b/pom.xml @@ -93,7 +93,7 @@ 9.0.1.Final 6.0.0 - 1.7.1-beta14 + 1.8.0-beta15 1.8.0