22
33import com .embabel .agent .api .annotation .*;
44import com .embabel .agent .api .common .OperationContext ;
5+ import com .embabel .agent .config .models .OpenAiModels ;
56import com .embabel .agent .core .CoreToolGroups ;
67import com .embabel .agent .domain .library .ResearchReport ;
78import com .embabel .agent .prompt .persona .RoleGoalBackstory ;
1011import org .jetbrains .annotations .NotNull ;
1112import org .slf4j .Logger ;
1213import org .slf4j .LoggerFactory ;
13- import org .springframework .beans .factory .annotation .Value ;
1414import org .springframework .boot .context .properties .ConfigurationProperties ;
1515
1616import java .util .List ;
@@ -52,63 +52,73 @@ public String contribution() {
5252}
5353
5454/**
55- * Can be overridden in application.yml
55+ * All properties can be overridden in application.yml
5656 */
57- @ ConfigurationProperties (prefix = "book-writer" )
58- class Team {
59-
60- RoleGoalBackstory researcher = RoleGoalBackstory
61- .withRole ("Researcher" )
62- .andGoal ("""
63- Gather comprehensive information about a topic that will be used to create an organized and well-structured book outline.
64- Consider the author's desired goal for the book.
65- """ )
66- .andBackstory ("""
67- You're a seasoned researcher, known for gathering the best sources and understanding the key elements of any topic.\s
68- You aim to collect all relevant information so the book outline can be accurate and informative.
69- """ );
70-
71- RoleGoalBackstory outliner = RoleGoalBackstory
72- .withRole ("Outliner" )
73- .andGoal ("""
74- Based on research, generate a book outline about the given topic.
75- The generated outline should include all chapters in sequential order and provide a title and description for each chapter.
76- Consider the author's desired goal for the book
77- """ )
78- .andBackstory ("""
79- You are a skilled organizer, great at turning scattered information into a structured format.
80- Your goal is to create clear, concise chapter outlines with all key topics and subtopics covered.
81- """ );
82-
83- RoleGoalBackstory writer = RoleGoalBackstory
84- .withRole ("Chapter Writer" )
85- .andGoal ("""
86- Write a well-structured chapter for a book based on the provided chapter title, goal, and outline.
87- """ )
88- .andBackstory ("""
89- You are an exceptional writer, known for producing engaging, well-researched, and informative content.
90- You excel at transforming complex ideas into readable and well-organized chapters.
91- """ );
92-
57+ @ ConfigurationProperties ("examples.book-writer" )
58+ record BookWriterConfig (
59+ LlmOptions researcherLlm ,
60+ LlmOptions writerLlm ,
61+ int maxConcurrency ,
62+ RoleGoalBackstory researcher ,
63+ RoleGoalBackstory outliner ,
64+ RoleGoalBackstory writer
65+ ) {
66+ public BookWriterConfig {
67+ researcherLlm = (researcherLlm != null )
68+ ? researcherLlm
69+ : LlmOptions .withModel (OpenAiModels .GPT_41_MINI );
70+ writerLlm = (writerLlm != null )
71+ ? writerLlm
72+ : LlmOptions .withModel (OpenAiModels .GPT_41 );
73+ maxConcurrency = (maxConcurrency == 0 ) ? 8 : maxConcurrency ;
74+ researcher = researcher != null ? researcher : RoleGoalBackstory
75+ .withRole ("Researcher" )
76+ .andGoal ("""
77+ Gather comprehensive information about a topic that will be used to create an organized and well-structured book outline.
78+ Consider the author's desired goal for the book.
79+ """ )
80+ .andBackstory ("""
81+ You're a seasoned researcher, known for gathering the best sources and understanding the key elements of any topic.\s
82+ You aim to collect all relevant information so the book outline can be accurate and informative.
83+ """ );
84+ outliner = outliner != null ? outliner : RoleGoalBackstory
85+ .withRole ("Outliner" )
86+ .andGoal ("""
87+ Based on research, generate a book outline about the given topic.
88+ The generated outline should include all chapters in sequential order and provide a title and description for each chapter.
89+ Consider the author's desired goal for the book
90+ """ )
91+ .andBackstory ("""
92+ You are a skilled organizer, great at turning scattered information into a structured format.
93+ Your goal is to create clear, concise chapter outlines with all key topics and subtopics covered.
94+ """ );
95+ writer = writer != null ? writer : RoleGoalBackstory
96+ .withRole ("Chapter Writer" )
97+ .andGoal ("""
98+ Write a well-structured chapter for a book based on the provided chapter title, goal, and outline.
99+ """ )
100+ .andBackstory ("""
101+ You are an exceptional writer, known for producing engaging, well-researched, and informative content.
102+ You excel at transforming complex ideas into readable and well-organized chapters.
103+ """ );
104+ }
93105}
94106
107+
95108/**
96109 * Based on the Crew AI Book Writer example, this agent creates a book by first researching the topic,
97110 * then creating an outline, and finally writing the chapters.
98111 * See <a href="https://github.com/crewAIInc/crewAI-examples/tree/main/flows/write_a_book_with_flows">Write a book with flows</a>
99112 */
100113@ Agent (description = "Write a book, first creating an outline, then writing the chapters and combining them" )
101- public record BookWriter (
102- @ Value ("${book-writer.researcher-llm:gpt-4.1-mini}" )
103- String researchModel ,
104- @ Value ("${book-writer.writer-llm:gpt-4.1-mini}" )
105- String writerModel ,
106- @ Value ("${book-writer.max-concurrency:8}" )
107- int maxConcurrency ,
108- Team team ) {
114+ public record BookWriter (BookWriterConfig config ) {
109115
110116 static final Logger logger = LoggerFactory .getLogger (BookWriter .class );
111117
118+ public BookWriter {
119+ logger .info ("Initialized with configuration {}" , config );
120+ }
121+
112122 @ Action (cost = 100.0 )
113123 BookRequest askForBookRequest (OperationContext context ) {
114124 return WaitFor .formSubmission (
@@ -121,8 +131,8 @@ ResearchReport researchTopic(
121131 BookRequest bookRequest ,
122132 OperationContext context ) {
123133 return context .ai ()
124- .withLlm (LlmOptions . withModel ( researchModel ))
125- .withPromptElements (team .researcher , bookRequest )
134+ .withLlm (config . researcherLlm ( ))
135+ .withPromptElements (config .researcher () , bookRequest )
126136 .withToolGroup (CoreToolGroups .WEB )
127137 .createObject (
128138 """
@@ -139,8 +149,8 @@ BookOutline createOutline(
139149 ResearchReport researchReport ,
140150 OperationContext context ) {
141151 return context .ai ()
142- .withLlm (LlmOptions . withModel ( researchModel ))
143- .withPromptElements (team .outliner , bookRequest , researchReport )
152+ .withLlm (config . writerLlm ( ))
153+ .withPromptElements (config .outliner () , bookRequest , researchReport )
144154 .withToolGroup (CoreToolGroups .WEB )
145155 .createObject (
146156 """
@@ -160,7 +170,7 @@ Book writeBook(
160170 ) {
161171 var chapters = context .parallelMap (
162172 bookOutline .chapterOutlines (),
163- maxConcurrency ,
173+ config . maxConcurrency () ,
164174 chapterOutline -> writeChapter (
165175 bookRequest ,
166176 bookOutline ,
@@ -192,8 +202,8 @@ private Chapter writeChapter(
192202 OperationContext context ) {
193203 logger .info ("Researching chapter {}..." , chapterOutline .title ());
194204 var specificResearch = context .ai ()
195- .withLlm (LlmOptions . withModel ( researchModel ))
196- .withPromptElements (team .researcher , bookRequest , bookOutline )
205+ .withLlm (config . researcherLlm ( ))
206+ .withPromptElements (config .researcher () , bookRequest , bookOutline )
197207 .withToolGroup (CoreToolGroups .WEB )
198208 .createObject (
199209 """
@@ -208,8 +218,8 @@ private Chapter writeChapter(
208218 ResearchReport .class );
209219 logger .info ("Writing chapter {}..." , chapterOutline .title ());
210220 return context .ai ()
211- .withLlm (LlmOptions . withModel ( writerModel ))
212- .withPromptElements (bookRequest , team .writer , specificResearch , bookOutline )
221+ .withLlm (config . writerLlm ( ))
222+ .withPromptElements (bookRequest , config .writer () , specificResearch , bookOutline )
213223 .createObject (
214224 """
215225 Write a well-structured chapter for the book based on the provided chapter title, goal, and outline.
0 commit comments