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 @@ -37,7 +37,7 @@ public static void main(String[] args) throws IOException {
CvGenerator cvGenerator = AgenticServices
.agentBuilder(CvGenerator.class)
.chatModel(CHAT_MODEL)
.outputName("masterCv") // we can optionally define the name of the output object
.outputKey("masterCv") // we can optionally define the key of the output object
.build();

// 4. Load text file from resources/documents/user_life_story.txt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ public static void main(String[] args) throws IOException {
CvGenerator cvGenerator = AgenticServices
.agentBuilder(CvGenerator.class)
.chatModel(CHAT_MODEL)
.outputName("masterCv") // if you want to pass this variable from agent 1 to agent 2,
// then make sure the output name here matches the input variable name
.outputKey("masterCv") // if you want to pass this variable from agent 1 to agent 2,
// then make sure the output key here matches the input variable name
// specified in the second agent interface agent_interfaces/CvTailor.java
.build();
CvTailor cvTailor = AgenticServices
.agentBuilder(CvTailor.class)
.chatModel(CHAT_MODEL) // note that it is also possible to use a different model for a different agent
.outputName("tailoredCv") // we need to define the name of the output object
.outputKey("tailoredCv") // we need to define the key of the output object
// if we would put "masterCv" here, the original master CV would be overwritten
// by the second agent. In this case we don't want this, but it's a useful feature.
.build();
Expand All @@ -59,7 +59,7 @@ public static void main(String[] args) throws IOException {
UntypedAgent tailoredCvGenerator = AgenticServices // use UntypedAgent unless you define the resulting composed agent, see below
.sequenceBuilder()
.subAgents(cvGenerator, cvTailor) // this can be as many as you want, order matters
.outputName("tailoredCv") // this is the final output of the composed agent
.outputKey("tailoredCv") // this is the final output of the composed agent
// note that you can use as output any field that is part of the AgenticScope
// for example you could output 'masterCv' instead of tailoredCv (even if in this case that makes no sense)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ public static void main(String[] args) throws IOException {
CvGenerator cvGenerator = AgenticServices
.agentBuilder(CvGenerator.class)
.chatModel(CHAT_MODEL)
.outputName("masterCv") // if you want to pass this variable from agent 1 to agent 2,
// then make sure the output name here matches the input variable name
.outputKey("masterCv") // if you want to pass this variable from agent 1 to agent 2,
// then make sure the output key here matches the input variable name
// specified in the second agent interface agent_interfaces/CvTailor.java
.build();
CvTailor cvTailor = AgenticServices
.agentBuilder(CvTailor.class)
.chatModel(CHAT_MODEL) // note that it is also possible to use a different model for a different agent
.outputName("tailoredCv") // we need to define the name of the output object
.outputKey("tailoredCv") // we need to define the key of the output object
// if we would put "masterCv" here, the original master CV would be overwritten
// by the second agent. In this case we don't want this, but it's a useful feature.
.build();
Expand All @@ -66,7 +66,7 @@ public static void main(String[] args) throws IOException {
SequenceCvGenerator sequenceCvGenerator = AgenticServices
.sequenceBuilder(SequenceCvGenerator.class) // here we specify the typed interface
.subAgents(cvGenerator, cvTailor)
.outputName("bothCvsAndLifeStory")
.outputKey("bothCvsAndLifeStory")
.output(agenticScope -> { // any method is possible, but we collect some internal variables.
Map<String, String> bothCvsAndLifeStory = Map.of(
"lifeStory", agenticScope.readState("lifeStory", ""),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ public static void main(String[] args) throws IOException {
// 3. Create all agents using AgenticServices
CvReviewer cvReviewer = AgenticServices.agentBuilder(CvReviewer.class)
.chatModel(CHAT_MODEL)
.outputName("cvReview") // this gets updated in every iteration with new feedback for the next tailoring
.outputKey("cvReview") // this gets updated in every iteration with new feedback for the next tailoring
.build();
ScoredCvTailor scoredCvTailor = AgenticServices.agentBuilder(ScoredCvTailor.class)
.chatModel(CHAT_MODEL)
.outputName("cv") // this will be updated in every iteration, continuously improving the CV
.outputKey("cv") // this will be updated in every iteration, continuously improving the CV
.build();

// 4. Build the sequence
UntypedAgent reviewedCvGenerator = AgenticServices // use UntypedAgent unless you define the resulting composed agent, see _2_Sequential_Agent_Example
.loopBuilder().subAgents(cvReviewer, scoredCvTailor) // this can be as many as you want, order matters
.outputName("cv") // this is the final output we want to observe (the improved CV)
.outputKey("cv") // this is the final output we want to observe (the improved CV)
.exitCondition(agenticScope -> {
CvReview review = (CvReview) agenticScope.readState("cvReview");
System.out.println("Checking exit condition with score=" + review.score); // we log intermediary scores
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ public static void main(String[] args) throws IOException {
// 1. Create all sub-agents (same as before)
CvReviewer cvReviewer = AgenticServices.agentBuilder(CvReviewer.class)
.chatModel(CHAT_MODEL)
.outputName("cvReview") // this gets updated in every iteration with new feedback for the next tailoring
.outputKey("cvReview") // this gets updated in every iteration with new feedback for the next tailoring
.build();
ScoredCvTailor scoredCvTailor = AgenticServices.agentBuilder(ScoredCvTailor.class)
.chatModel(CHAT_MODEL)
.outputName("cv") // this will be updated in every iteration, continuously improving the CV
.outputKey("cv") // this will be updated in every iteration, continuously improving the CV
.build();

// 2. Build the sequence and store the reviews on each exit condition check
Expand All @@ -53,7 +53,7 @@ public static void main(String[] args) throws IOException {

UntypedAgent reviewedCvGenerator = AgenticServices // use UntypedAgent unless you define the resulting composed agent, see below
.loopBuilder().subAgents(cvReviewer, scoredCvTailor) // this can be as many as you want, order matters
.outputName("cvAndReview") // this is the final output we want to observe
.outputKey("cvAndReview") // this is the final output we want to observe
.output(agenticScope -> {
Map<String, Object> cvAndReview = Map.of(
"cv", agenticScope.readState("cv"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@ public static void main(String[] args) throws IOException {
// 3. Create all agents using AgenticServices
HrCvReviewer hrCvReviewer = AgenticServices.agentBuilder(HrCvReviewer.class)
.chatModel(CHAT_MODEL)
.outputName("hrReview") // this will be overwritten in every iteration, and also be used as the final output we want to observe
.outputKey("hrReview") // this will be overwritten in every iteration, and also be used as the final output we want to observe
.build();

ManagerCvReviewer managerCvReviewer = AgenticServices.agentBuilder(ManagerCvReviewer.class)
.chatModel(CHAT_MODEL)
.outputName("managerReview") // this overwrites the original input instructions, and is overwritten in every iteration and used as new instructions for the CvTailor
.outputKey("managerReview") // this overwrites the original input instructions, and is overwritten in every iteration and used as new instructions for the CvTailor
.build();

TeamMemberCvReviewer teamMemberCvReviewer = AgenticServices.agentBuilder(TeamMemberCvReviewer.class)
.chatModel(CHAT_MODEL)
.outputName("teamMemberReview") // this overwrites the original input instructions, and is overwritten in every iteration and used as new instructions for the CvTailor
.outputKey("teamMemberReview") // this overwrites the original input instructions, and is overwritten in every iteration and used as new instructions for the CvTailor
.build();

// 4. Build the sequence
Expand All @@ -63,7 +63,7 @@ public static void main(String[] args) throws IOException {
.parallelBuilder()
.subAgents(hrCvReviewer, managerCvReviewer, teamMemberCvReviewer) // this can be as many as you want
.executor(executor) // optional, by default an internal cached thread pool is used which will automatically shut down after execution is completed
.outputName("fullCvReview") // this is the final output we want to observe
.outputKey("fullCvReview") // this is the final output we want to observe
.output(agenticScope -> {
// read the outputs of each reviewer from the agentic scope
CvReview hrReview = (CvReview) agenticScope.readState("hrReview");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

public interface EmailAssistant {

@Agent("Sends rejection emails to candidates that didn't pass")
@Agent("Sends rejection emails to candidates that didn't pass, returns the sent email ID or 0 if no email could be sent")
@SystemMessage("""
You send a kind email to application candidates that did not pass the first review round.
You also update the application status to 'rejected'.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,19 @@ public static void main(String[] args) throws IOException {
ManagerCvReviewer managerCvReviewer = AgenticServices.agentBuilder(ManagerCvReviewer.class)
.chatModel(CHAT_MODEL)
.async(true) // async agent
.outputName("managerReview")
.outputKey("managerReview")
.build();
EmailAssistant emailAssistant = AgenticServices.agentBuilder(EmailAssistant.class)
.chatModel(CHAT_MODEL)
.async(true)
.tools(new OrganizingTools())
.outputName("sentEmailId")
.outputKey("sentEmailId")
.build();
InfoRequester infoRequester = AgenticServices.agentBuilder(InfoRequester.class)
.chatModel(CHAT_MODEL)
.async(true)
.tools(new OrganizingTools())
.outputName("sentEmailId")
.outputKey("sentEmailId")
.build();

// 2. Build async conditional workflow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,26 @@ public static void main(String[] args) throws IOException {
CvGenerator cvGenerator = AgenticServices
.agentBuilder(CvGenerator.class)
.chatModel(CHAT_MODEL)
.outputName("cv")
.outputKey("cv")
.build();

ScoredCvTailor scoredCvTailor = AgenticServices
.agentBuilder(ScoredCvTailor.class)
.chatModel(CHAT_MODEL)
.outputName("cv")
.outputKey("cv")
.build();

CvReviewer cvReviewer = AgenticServices
.agentBuilder(CvReviewer.class)
.chatModel(CHAT_MODEL)
.outputName("cvReview")
.outputKey("cvReview")
.build();

// 2. Create the loop workflow for CV improvement
UntypedAgent cvImprovementLoop = AgenticServices
.loopBuilder()
.subAgents(scoredCvTailor, cvReviewer)
.outputName("cv")
.outputKey("cv")
.exitCondition(agenticScope -> {
CvReview review = (CvReview) agenticScope.readState("cvReview");
System.out.println("CV Review Score: " + review.score);
Expand All @@ -87,7 +87,7 @@ public static void main(String[] args) throws IOException {
.subAgents(cvGenerator, cvReviewer, cvImprovementLoop)
// here we use the composed agent cvImprovementLoop inside the sequenceBuilder
// we also need the cvReviewer in order to generate a first review before entering the loop
.outputName("cv")
.outputKey("cv")
.build();

// 4. Load input data
Expand All @@ -112,19 +112,19 @@ public static void main(String[] args) throws IOException {
HrCvReviewer hrCvReviewer = AgenticServices
.agentBuilder(HrCvReviewer.class)
.chatModel(CHAT_MODEL)
.outputName("hrReview")
.outputKey("hrReview")
.build();

ManagerCvReviewer managerCvReviewer = AgenticServices
.agentBuilder(ManagerCvReviewer.class)
.chatModel(CHAT_MODEL)
.outputName("managerReview")
.outputKey("managerReview")
.build();

TeamMemberCvReviewer teamMemberCvReviewer = AgenticServices
.agentBuilder(TeamMemberCvReviewer.class)
.chatModel(CHAT_MODEL)
.outputName("teamMemberReview")
.outputKey("teamMemberReview")
.build();

EmailAssistant emailAssistant = AgenticServices
Expand All @@ -144,7 +144,7 @@ public static void main(String[] args) throws IOException {
.parallelBuilder()
.subAgents(hrCvReviewer, managerCvReviewer, teamMemberCvReviewer)
.executor(Executors.newFixedThreadPool(3))
.outputName("combinedCvReview")
.outputKey("combinedCvReview")
.output(agenticScope -> {
CvReview hrReview = (CvReview) agenticScope.readState("hrReview");
CvReview managerReview = (CvReview) agenticScope.readState("managerReview");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,20 @@ public static void main(String[] args) throws IOException {
// 1. Define all sub-agents
HrCvReviewer hrReviewer = AgenticServices.agentBuilder(HrCvReviewer.class)
.chatModel(CHAT_MODEL)
.outputName("hrReview")
.outputKey("hrReview")
.build();
// importantly, if we use the same method names for multiple agents
// (in this case: 'reviewCv' for all reviewers) we best name our agents, like this:
// @Agent(name = "managerReviewer", description = "Reviews a CV based on a job description, gives feedback and a score")

ManagerCvReviewer managerReviewer = AgenticServices.agentBuilder(ManagerCvReviewer.class)
.chatModel(CHAT_MODEL)
.outputName("managerReview")
.outputKey("managerReview")
.build();

TeamMemberCvReviewer teamReviewer = AgenticServices.agentBuilder(TeamMemberCvReviewer.class)
.chatModel(CHAT_MODEL)
.outputName("teamMemberReview")
.outputKey("teamMemberReview")
.build();

InterviewOrganizer interviewOrganizer = AgenticServices.agentBuilder(InterviewOrganizer.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ public static void main(String[] args) throws IOException {
InterviewOrganizer interviewOrganizer = AgenticServices.agentBuilder(InterviewOrganizer.class)
.chatModel(CHAT_MODEL)
.tools(new OrganizingTools())
.outputName("response")
.outputKey("response")
.build();
EmailAssistant emailAssistant = AgenticServices.agentBuilder(EmailAssistant.class)
.chatModel(CHAT_MODEL)
.tools(new OrganizingTools())
.outputName("response")
.outputKey("response")
.build();

// 2. Build supervisor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*/
public class ScoreAggregator {

@Agent(description = "Aggregates HR/Manager/Team reviews into a combined review", outputName = "combinedCvReview")
@Agent(description = "Aggregates HR/Manager/Team reviews into a combined review", outputKey = "combinedCvReview")
public CvReview aggregate(@V("hrReview") CvReview hr,
@V("managerReview") CvReview mgr,
@V("teamMemberReview") CvReview team) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,17 @@ public static void main(String[] args) throws IOException {
// 2. Build the AI sub-agents for the parallel review step
HrCvReviewer hrReviewer = AgenticServices.agentBuilder(HrCvReviewer.class)
.chatModel(CHAT_MODEL)
.outputName("hrReview")
.outputKey("hrReview")
.build();

ManagerCvReviewer managerReviewer = AgenticServices.agentBuilder(ManagerCvReviewer.class)
.chatModel(CHAT_MODEL)
.outputName("managerReview")
.outputKey("managerReview")
.build();

TeamMemberCvReviewer teamReviewer = AgenticServices.agentBuilder(TeamMemberCvReviewer.class)
.chatModel(CHAT_MODEL)
.outputName("teamMemberReview")
.outputKey("teamMemberReview")
.build();

// 3. Build the composed parallel agent
Expand All @@ -75,14 +75,14 @@ public static void main(String[] args) throws IOException {
.sequenceBuilder()
.subAgents(
parallelReviewWorkflow,
new ScoreAggregator(), // no AgenticServices builder needed for non-AI agents. outputname 'combinedCvReview' is defined in the class
new ScoreAggregator(), // no AgenticServices builder needed for non-AI agents. outputKey 'combinedCvReview' is defined in the class
new StatusUpdate(), // takes 'combinedCvReview' as input, no output needed
AgenticServices.agentAction(agenticScope -> { // another way to add non-AI agents that can operate on the AgenticScope
CvReview review = (CvReview) agenticScope.readState("combinedCvReview");
agenticScope.writeState("scoreAsPercentage", review.score * 100); // when agents from different systems communicate, output conversion is often needed
})
)
.outputName("scoreAsPercentage") // outputName defined on the non-AI agent annotation in ScoreAggregator.java
.outputKey("scoreAsPercentage") // outputKey defined on the non-AI agent annotation in ScoreAggregator.java
.build();

// 5. Load input data
Expand Down
Loading