Skip to content

Commit 25ce1ec

Browse files
committed
Improve externalization
1 parent 5c0f7dd commit 25ce1ec

File tree

5 files changed

+96
-80
lines changed

5 files changed

+96
-80
lines changed

examples-java/src/main/java/com/embabel/example/AgentShellMcpClientApplication.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,40 +15,42 @@
1515
*/
1616
package com.embabel.example;
1717

18+
import com.embabel.agent.config.annotation.EnableAgentShell;
19+
import com.embabel.agent.config.annotation.EnableAgents;
1820
import com.embabel.agent.config.annotation.LoggingThemes;
1921
import com.embabel.agent.config.annotation.McpServers;
2022
import org.springframework.boot.SpringApplication;
2123
import org.springframework.boot.autoconfigure.SpringBootApplication;
22-
import com.embabel.agent.config.annotation.EnableAgentShell;
23-
import com.embabel.agent.config.annotation.EnableAgents;
24+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
2425

2526
/**
2627
* Spring Boot application that provides an interactive command-line shell for Embabel agents
2728
* with Star Wars themed logging and Docker Desktop integration.
28-
*
29+
*
2930
* <p>This application runs in interactive shell mode, allowing developers to test and interact
3031
* with agents through a REPL-like interface. It combines the development-friendly shell
3132
* environment with fun Star Wars themed logging messages and Docker container capabilities.
32-
*
33+
*
34+
* @author Embabel Team
3335
* @see EnableAgentShell
3436
* @see EnableAgents
3537
* @since 1.0
36-
* @author Embabel Team
3738
*/
3839
@SpringBootApplication
40+
@EnableConfigurationProperties
3941
@EnableAgentShell
4042
@EnableAgents(
41-
loggingTheme = LoggingThemes.STAR_WARS,
42-
mcpServers = {McpServers.DOCKER_DESKTOP}
43+
loggingTheme = LoggingThemes.STAR_WARS,
44+
mcpServers = {McpServers.DOCKER_DESKTOP}
4345
)
4446
public class AgentShellMcpClientApplication {
45-
47+
4648
/**
4749
* Application entry point.
48-
*
50+
*
4951
* <p>Starts the Spring Boot application with an interactive shell interface,
5052
* Star Wars themed logging, and Docker Desktop integration.
51-
*
53+
*
5254
* @param args command line arguments passed to the application
5355
*/
5456
public static void main(String[] args) {

examples-java/src/main/java/com/embabel/example/bookwriter/BookWriter.java

Lines changed: 65 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.embabel.agent.api.annotation.*;
44
import com.embabel.agent.api.common.OperationContext;
5+
import com.embabel.agent.config.models.OpenAiModels;
56
import com.embabel.agent.core.CoreToolGroups;
67
import com.embabel.agent.domain.library.ResearchReport;
78
import com.embabel.agent.prompt.persona.RoleGoalBackstory;
@@ -10,7 +11,6 @@
1011
import org.jetbrains.annotations.NotNull;
1112
import org.slf4j.Logger;
1213
import org.slf4j.LoggerFactory;
13-
import org.springframework.beans.factory.annotation.Value;
1414
import org.springframework.boot.context.properties.ConfigurationProperties;
1515

1616
import 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.

examples-java/src/main/java/com/embabel/example/wikipedia/WikiAgent.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import com.embabel.agent.api.annotation.*;
1919
import com.embabel.agent.api.common.OperationContext;
2020
import com.embabel.agent.core.CoreToolGroups;
21-
import com.embabel.common.ai.model.BuildableLlmOptions;
2221
import com.embabel.common.ai.model.LlmOptions;
2322
import org.springframework.beans.factory.annotation.Value;
2423

@@ -41,13 +40,13 @@ record ResearchReport(String subject, String summary) {
4140
public class WikiAgent {
4241

4342
private final int wordCount;
44-
private final BuildableLlmOptions llm;
43+
private final LlmOptions llm;
4544

4645
public WikiAgent(
4746
@Value("${wiki.wordcount:200}") int wordCount,
4847
@Value("${wiki.llm:gpt-4.1-nano}") String model) {
4948
this.wordCount = wordCount;
50-
this.llm = LlmOptions.fromModel(model);
49+
this.llm = LlmOptions.withModel(model);
5150
}
5251

5352
@Action

examples-java/src/main/resources/application.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ embabel.shell.chat.temperature=0.3
1515
embabel.agent-platform.ranking.llm=gpt-4.1-mini
1616

1717

18-
1918
embabel.fact-checker.models=gpt-4.1-mini,gpt-5-nano,gpt-5-mini
2019
embabel.fact-checker.max-concurrency=8
2120

@@ -24,3 +23,4 @@ embabel.fact-checker.deduplication-model=gpt-4.1
2423
embabel.fact-checker.reasoning-word-count=50
2524
embabel.fact-checker.trusted-sources=Wikipedia,Wikidata,Britannica,BBC,Reuters,NY Times,ABC Australia
2625
embabel.fact-checker.untrusted-sources=reddit,4chan,twitter
26+
Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
book-writer:
1+
examples:
2+
book-writer:
23

3-
researcher:
4-
role: >
5-
Researcher
6-
goal: >
7-
Gather comprehensive information about a topic that will be used
8-
to create an organized and well-structured book outline.
9-
Consider the author's desired goal for the book.
4+
researcher-llm:
5+
model: gpt-4.1-nano
6+
temperature: 0.7
107

11-
backstory: >
12-
You are an experienced researcher skilled in finding the most relevant and up-to-date information on any given topic.
13-
Your job is to provide insightful data that supports and enriches the writing process for the chapter.
8+
researcher:
9+
role: >
10+
Researcher
11+
goal: >
12+
Gather comprehensive information about a topic that will be used
13+
to create an organized and well-structured book outline.
14+
Consider the author's desired goal for the book.
1415
16+
backstory: >
17+
You are an experienced researcher skilled in finding the most relevant and up-to-date information on any given topic.
18+
Your job is to provide insightful data that supports and enriches the writing process for the chapter.
19+

0 commit comments

Comments
 (0)