Skip to content

Commit 94de2d2

Browse files
committed
Improve config
1 parent 065bed3 commit 94de2d2

File tree

8 files changed

+128
-52
lines changed

8 files changed

+128
-52
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ embabel-agent-api/src/main/resources/mcp/**
88

99
.idea/workspace.xml
1010

11-
**/*.log
11+
**/*.log
12+
13+
.claude

pom.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@
4242
<version>${embabel-agent.version}</version>
4343
</dependency>
4444

45+
<dependency>
46+
<groupId>org.springframework.boot</groupId>
47+
<artifactId>spring-boot-configuration-processor</artifactId>
48+
<optional>true</optional>
49+
</dependency>
50+
4551
<dependency>
4652
<groupId>com.embabel.agent</groupId>
4753
<artifactId>embabel-agent-test</artifactId>
@@ -54,6 +60,11 @@
5460
<version>${embabel-agent.version}</version>
5561
</dependency>
5662

63+
<dependency>
64+
<groupId>org.springframework.boot</groupId>
65+
<artifactId>spring-boot-starter-validation</artifactId>
66+
</dependency>
67+
5768
<!-- Unit and Integration Testing -->
5869
<dependency>
5970
<groupId>org.springframework.boot</groupId>

src/main/kotlin/com/embabel/decker/PresentationMaker.kt renamed to src/main/kotlin/com/embabel/decker/Decker.kt

Lines changed: 28 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,22 @@
1616
package com.embabel.decker
1717

1818
import com.embabel.agent.api.annotation.*
19+
import com.embabel.agent.api.common.Ai
1920
import com.embabel.agent.api.common.OperationContext
2021
import com.embabel.agent.api.common.create
2122
import com.embabel.agent.api.dsl.parallelMap
22-
import com.embabel.agent.config.models.AnthropicModels
23-
import com.embabel.agent.config.models.OpenAiModels
24-
import com.embabel.agent.core.CoreToolGroups
2523
import com.embabel.agent.domain.io.FileArtifact
2624
import com.embabel.agent.domain.library.ResearchReport
2725
import com.embabel.agent.domain.library.ResearchTopics
26+
import com.embabel.agent.prompt.persona.Actor
2827
import com.embabel.agent.prompt.persona.CoStar
29-
import com.embabel.agent.tools.file.DefaultFileReadLog
30-
import com.embabel.agent.tools.file.FileReadLog
31-
import com.embabel.agent.tools.file.FileReadTools
32-
import com.embabel.agent.tools.file.WellKnownFileContentTransformers.removeApacheLicenseHeader
33-
import com.embabel.common.ai.model.LlmOptions
34-
import com.embabel.common.ai.model.ModelSelectionCriteria.Companion.byName
28+
import com.embabel.agent.prompt.persona.RoleGoalBackstory
3529
import com.embabel.common.ai.prompt.PromptContributor
36-
import com.embabel.common.util.StringTransformer
3730
import com.fasterxml.jackson.annotation.JsonIgnore
3831
import org.slf4j.LoggerFactory
3932
import org.springframework.boot.context.properties.ConfigurationProperties
33+
import org.springframework.boot.context.properties.NestedConfigurationProperty
34+
import org.springframework.validation.annotation.Validated
4035

4136
data class ImageInfo(val url: String, val useWhen: String)
4237

@@ -81,40 +76,37 @@ data class PresentationRequest(
8176
}
8277
}
8378

84-
@ConfigurationProperties(prefix = "embabel.presentation-maker")
85-
data class PresentationMakerProperties(
86-
val researchModel: String = OpenAiModels.GPT_41_MINI,
87-
val creationModel: String = AnthropicModels.CLAUDE_37_SONNET,
88-
) {
89-
90-
val researchLlm =
91-
LlmOptions(byName(researchModel))
92-
93-
val creationLlm =
94-
LlmOptions(byName(creationModel))
95-
}
79+
@Validated
80+
@ConfigurationProperties(prefix = "decker")
81+
data class DeckerConfig(
82+
@NestedConfigurationProperty val planner: Actor<RoleGoalBackstory>,
83+
@NestedConfigurationProperty val researcher: Actor<RoleGoalBackstory>,
84+
@NestedConfigurationProperty val creator: Actor<RoleGoalBackstory>,
85+
)
9686

9787

9888
/**
99-
* Naming agent that generates names for a company or project.
89+
* Agent that generates slide decks.
10090
*/
10191
@Agent(description = "Presentation maker. Build a presentation on a topic")
102-
class PresentationMaker(
92+
class Decker(
10393
private val slideFormatter: SlideFormatter,
10494
private val filePersister: FilePersister,
105-
private val properties: PresentationMakerProperties,
95+
private val config: DeckerConfig,
10696
) {
10797

108-
private val logger = LoggerFactory.getLogger(PresentationMaker::class.java)
98+
private val logger = LoggerFactory.getLogger(Decker::class.java)
99+
100+
init {
101+
logger.info("Decker initialized with config: {}", config)
102+
}
109103

110104
@Action
111105
fun identifyResearchTopics(
112106
presentationRequest: PresentationRequest,
113-
context: OperationContext
107+
ai: Ai
114108
): ResearchTopics =
115-
context.ai()
116-
.withLlm(properties.creationLlm)
117-
// toolGroups = setOf(CoreToolGroups.WEB),
109+
config.creator.promptRunner(ai)
118110
.create(
119111
"""
120112
Create a list of research topics for a presentation,
@@ -131,9 +123,7 @@ class PresentationMaker(
131123
context: OperationContext,
132124
): ResearchResult {
133125
val topicReports = researchTopics.topics.parallelMap(context) {
134-
context.ai()
135-
.withLlm(llm = properties.researchLlm)
136-
.withToolGroup(CoreToolGroups.WEB)
126+
config.researcher.promptRunner(context)
137127
.withToolObject(presentationRequest.project)
138128
.withPromptContributor(presentationRequest)
139129
.create<ResearchReport>(
@@ -158,11 +148,10 @@ class PresentationMaker(
158148
fun createDeck(
159149
presentationRequest: PresentationRequest,
160150
researchComplete: ResearchResult,
161-
context: OperationContext,
151+
ai: Ai,
162152
): SlideDeck {
163-
val slideDeck = context.promptRunner(llm = properties.creationLlm)
153+
val slideDeck = config.creator.promptRunner(ai)
164154
.withPromptContributor(presentationRequest)
165-
.withToolGroup(CoreToolGroups.WEB)
166155
.withToolObject(presentationRequest.project)
167156
.create<SlideDeck>(
168157
"""
@@ -253,9 +242,9 @@ class PresentationMaker(
253242
} else {
254243
logger.info("Asking LLM to add illustrations to this resource")
255244

256-
val illustrator = context.promptRunner(
257-
llm = properties.researchLlm.withTemperature(.3)
258-
).withToolGroup(CoreToolGroups.WEB)
245+
val illustrator = context.ai().withLlm(
246+
config.researcher.llm.withTemperature(.3)
247+
)
259248
val newSlides = withDiagrams.slides().map { slide ->
260249
val newContent = illustrator.generateText(
261250
"""
@@ -323,9 +312,3 @@ class PresentationMaker(
323312
}
324313

325314
}
326-
327-
class Project(override val root: String) : FileReadTools, SymbolSearch,
328-
FileReadLog by DefaultFileReadLog() {
329-
330-
override val fileContentTransformers: List<StringTransformer> = listOf(removeApacheLicenseHeader)
331-
}

src/main/kotlin/com/embabel/decker/DeckerApplication.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ import com.embabel.agent.config.annotation.EnableAgents
1919
import com.embabel.agent.config.annotation.LoggingThemes
2020
import com.embabel.agent.config.annotation.McpServers
2121
import org.springframework.boot.autoconfigure.SpringBootApplication
22-
import org.springframework.boot.context.properties.ConfigurationPropertiesScan
22+
import org.springframework.boot.context.properties.EnableConfigurationProperties
2323
import org.springframework.boot.runApplication
2424

2525
@SpringBootApplication
26-
@ConfigurationPropertiesScan
26+
@EnableConfigurationProperties(
27+
DeckerConfig::class,
28+
)
2729
@EnableAgents(
2830
loggingTheme = LoggingThemes.SEVERANCE,
2931
mcpServers = [McpServers.DOCKER_DESKTOP],
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.embabel.decker
2+
3+
import com.embabel.agent.tools.file.DefaultFileReadLog
4+
import com.embabel.agent.tools.file.FileReadLog
5+
import com.embabel.agent.tools.file.FileReadTools
6+
import com.embabel.agent.tools.file.WellKnownFileContentTransformers
7+
import com.embabel.common.util.StringTransformer
8+
9+
/**
10+
* Readonly access to a project on the local filesystem.
11+
*/
12+
class Project(override val root: String) : FileReadTools, SymbolSearch,
13+
FileReadLog by DefaultFileReadLog() {
14+
15+
override val fileContentTransformers: List<StringTransformer> =
16+
listOf(WellKnownFileContentTransformers.removeApacheLicenseHeader)
17+
}

src/main/resources/application.properties

Lines changed: 0 additions & 2 deletions
This file was deleted.

src/main/resources/application.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
embabel:
2+
3+
agent:
4+
platform:
5+
tools:
6+
includes:
7+
linked-in:
8+
tools:
9+
- get_person_profile
10+
- get_company_profile
11+
12+
models:
13+
llms:
14+
planner: claude-3-7-sonnet-latest
15+
researcher: gpt-4.1-mini
16+
creator: claude-3-7-sonnet-latest
17+
18+
decker:
19+
planner:
20+
llm:
21+
role: planner
22+
23+
24+
tool-groups:
25+
- web
26+
persona:
27+
role: Presentation planner
28+
goal: >
29+
Given the request and context, plan a presentation that meets the specified goals.
30+
backstory: >
31+
You are an imaginative planner, able to break down complex topics into
32+
manageable sections, ensuring the presentation is engaging and informative.
33+
You pride yourself on producing impactful and memorable slide decks
34+
that are easy to present.
35+
36+
researcher:
37+
llm:
38+
role: researcher
39+
tool-groups:
40+
- web
41+
persona:
42+
role: Research Specialist
43+
goal: >
44+
Conduct thorough research on the given topic given the context
45+
backstory: >
46+
You research thoroughly, priding yourself on accuracy and citations
47+
You care about the truth and about backing up your statements with facts
48+
49+
creator:
50+
llm:
51+
role: creator
52+
tool-groups:
53+
- web
54+
persona:
55+
role: Slide deck writer
56+
goal: >
57+
Produce compelling slide decks that are visually interesting and informative,
58+
accurate, backed by facts, and aligned with the specified topic and audience.
59+
backstory: >
60+
You write slides in the voice of Rod Johnson, the founder of Spring and Embabel.
61+

src/test/kotlin/com/embabel/decker/PresentationMakerIntegrationTest.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ class PresentationMakerIntegrationTest {
4141
every { mockSlideFormatter.createHtmlSlides(any(), any()) } returns "presentation.html"
4242
every { mockEnvironment.activeProfiles } returns arrayOf("test")
4343
val agent: Agent = AgentMetadataReader().createAgentMetadata(
44-
PresentationMaker(
45-
properties = PresentationMakerProperties(),
44+
Decker(
45+
config = DeckerConfig(
46+
mockk(), mockk(), mockk(),
47+
),
4648
filePersister = mockFilePersister,
4749
slideFormatter = mockSlideFormatter,
4850
),

0 commit comments

Comments
 (0)