Core domain type definitions for the Embabel Agent Framework, providing foundational data classes and interfaces for agent-based AI workflows including content assets, research entities, and person types with Jackson serialization and PromptContributor capabilities.
Common patterns for using domain types together in agent workflows.
import com.embabel.agent.domain.library.*
// Function accepting any ContentAsset
fun processContentAsset(asset: ContentAsset) {
println("Content: ${asset.content.take(100)}...")
println("Timestamp: ${asset.timestamp}")
println("For LLM: ${asset.contribution()}")
}
// Works with Blog
val blog = Blog("Title", "Author", "Content")
processContentAsset(blog)
// Works with ResearchReport
val report = ResearchReport("Topic", "Content", listOf())
processContentAsset(report)
// Collections
val assets: List<ContentAsset> = listOf(
Blog("Blog Title", "Author", "Blog content"),
ResearchReport("Research Topic", "Research content", listOf())
)
assets.forEach { processContentAsset(it) }import com.embabel.agent.domain.library.*
// Function accepting any HasContent
fun extractText(item: HasContent): String {
return item.content
}
// Works with multiple types
extractText(Summary("Summary text"))
extractText(Blog("Title", "Author", "Blog content"))
extractText(ResearchReport("Topic", "Report content", listOf()))import com.embabel.agent.domain.library.*
fun createBlogFromResearch(
report: ResearchReport,
author: String
): Blog {
val linksSection = report.links.joinToString("\n") { link ->
"- [${link.summary}](${link.url})"
}
val content = """
${report.content}
## References
$linksSection
""".trimIndent()
return Blog(
title = report.topic,
author = author,
content = content,
keywords = setOf("research", report.topic.lowercase())
)
}
// Usage
val research = ResearchReport(
topic = "AI Ethics",
content = "AI ethics encompasses...",
links = listOf(
InternetResource(
url = "https://example.com/ethics",
summary = "Ethics guide"
)
)
)
val blog = createBlogFromResearch(research, "Dr. Smith")import com.embabel.agent.domain.library.*
fun createBlogFromNews(
news: RelevantNewsStories,
author: String,
title: String = "This Week in AI"
): Blog {
val newsContent = news.items.joinToString("\n\n") { story ->
"## ${story.title}\n\n${story.summary}\n\n[Read more](${story.url})"
}
return Blog(
title = title,
author = author,
content = "# Latest News\n\n$newsContent",
keywords = setOf("news", "ai", "weekly-roundup")
)
}
// Usage
val news = RelevantNewsStories(
items = listOf(
NewsStory(
"https://ex.com/1",
"AI Breakthrough",
"New algorithm..."
),
NewsStory(
"https://ex.com/2",
"Industry Adoption",
"Companies embrace..."
)
)
)
val blog = createBlogFromNews(news, "News Editor")import com.embabel.agent.domain.library.*
fun summarizeContentAsset(asset: ContentAsset): Summary {
return when (asset) {
is Blog -> Summary(
"Blog '${asset.title}' by ${asset.author}: ${asset.content.take(100)}..."
)
is ResearchReport -> Summary(
"Research on '${asset.topic}': ${asset.content.take(200)}... " +
"References ${asset.links.size} sources."
)
else -> Summary(
"Content from ${asset.timestamp}: ${asset.content.take(100)}..."
)
}
}
// Usage
val blog = Blog("Title", "Author", "Long content...")
val blogSummary = summarizeContentAsset(blog)
val report = ResearchReport("Topic", "Long report...", listOf())
val reportSummary = summarizeContentAsset(report)import com.embabel.agent.domain.library.*
fun enrichResearchWithNews(
report: ResearchReport,
news: RelevantNewsStories
): String {
return """
${report.contribution()}
## Recent News
${news.contribution()}
""".trimIndent()
}
// Usage in LLM prompt
val report = ResearchReport(
topic = "AI Agent Frameworks",
content = "Frameworks landscape...",
links = listOf()
)
val news = RelevantNewsStories(
items = listOf(
NewsStory(
"https://ex.com/news",
"Framework Update",
"New version released..."
)
)
)
val enrichedContext = enrichResearchWithNews(report, news)
val prompt = """
Context:
$enrichedContext
Based on this, recommend...
""".trimIndent()import com.embabel.agent.domain.library.*
data class BlogAuthor(
override val name: String,
val bio: String,
val expertise: List<String>
) : Person
data class ContentWithAuthor(
val content: ContentAsset,
val author: Person
)
fun createBlogWithAuthor(
author: BlogAuthor,
title: String,
content: String
): ContentWithAuthor {
val blog = Blog(
title = title,
author = author.name,
content = content,
keywords = author.expertise.map { it.lowercase() }.toSet()
)
return ContentWithAuthor(blog, author)
}
// Usage
val author = BlogAuthor(
name = "Dr. Jane Smith",
bio = "AI researcher",
expertise = listOf("AI", "Machine Learning", "Ethics")
)
val contentWithAuthor = createBlogWithAuthor(
author = author,
title = "AI Ethics Principles",
content = "Ethics are crucial..."
)import com.embabel.agent.domain.library.*
data class AgentContext(
val research: ResearchReport?,
val news: RelevantNewsStories?,
val relatedBlogs: List<Blog>,
val summary: Summary?
)
fun buildContextPrompt(context: AgentContext): String {
val parts = mutableListOf<String>()
context.research?.let {
parts.add("# Research\n${it.contribution()}")
}
context.news?.let {
if (it.items.isNotEmpty()) {
parts.add("# Recent News\n${it.contribution()}")
}
}
if (context.relatedBlogs.isNotEmpty()) {
val blogs = context.relatedBlogs.joinToString("\n\n") { it.contribution() }
parts.add("# Related Content\n$blogs")
}
context.summary?.let {
parts.add("# Summary\n${it.content}")
}
return parts.joinToString("\n\n")
}
// Usage
val context = AgentContext(
research = ResearchReport("Topic", "Content...", listOf()),
news = RelevantNewsStories(listOf(
NewsStory("https://ex.com", "Title", "Summary")
)),
relatedBlogs = listOf(
Blog("Related Post", "Author", "Content...")
),
summary = Summary("Context summary...")
)
val prompt = """
${buildContextPrompt(context)}
Based on this context, analyze...
""".trimIndent()import com.embabel.agent.domain.library.*
data class ResearchWorkflow(
val topics: ResearchTopics,
val reports: List<ResearchReport>,
val news: RelevantNewsStories,
val summaries: List<Summary>
)
fun conductResearch(topics: ResearchTopics): ResearchWorkflow {
// 1. Collect news for each topic
val allNews = mutableListOf<NewsStory>()
topics.topics.forEach { topic ->
// In real agent: search news for topic.topic
allNews.add(NewsStory(
url = "https://ex.com/${topic.topic}",
title = "News about ${topic.topic}",
summary = "Latest developments..."
))
}
// 2. Create research reports
val reports = topics.topics.map { topic ->
ResearchReport(
topic = topic.topic,
content = "Research findings for ${topic.topic}...",
links = listOf(
InternetResource(
url = "https://ex.com/${topic.topic}/research",
summary = "Research source"
)
)
)
}
// 3. Create summaries
val summaries = reports.map { report ->
Summary("Summary of ${report.topic}: ${report.content.take(100)}...")
}
return ResearchWorkflow(
topics = topics,
reports = reports,
news = RelevantNewsStories(allNews),
summaries = summaries
)
}
// Usage
val topics = ResearchTopics(
topics = listOf(
ResearchTopic(
topic = "AI Ethics",
questions = listOf("What are key concerns?")
),
ResearchTopic(
topic = "Agent Frameworks",
questions = listOf("What frameworks exist?")
)
)
)
val workflow = conductResearch(topics)import com.embabel.agent.domain.library.*
class ContentAggregator {
private val blogs = mutableListOf<Blog>()
private val reports = mutableListOf<ResearchReport>()
private val news = mutableListOf<NewsStory>()
fun addBlog(blog: Blog) {
blogs.add(blog)
}
fun addReport(report: ResearchReport) {
reports.add(report)
}
fun addNews(story: NewsStory) {
news.add(story)
}
fun getAllContent(): List<ContentAsset> {
return blogs + reports
}
fun buildPrompt(): String {
val sections = mutableListOf<String>()
if (reports.isNotEmpty()) {
sections.add("# Research Reports\n" +
reports.joinToString("\n\n") { it.contribution() }
)
}
if (blogs.isNotEmpty()) {
sections.add("# Blog Posts\n" +
blogs.joinToString("\n\n") { it.contribution() }
)
}
if (news.isNotEmpty()) {
sections.add("# News Stories\n" +
RelevantNewsStories(news).contribution()
)
}
return sections.joinToString("\n\n")
}
fun getSummary(): Summary {
return Summary(
"Aggregated ${blogs.size} blogs, ${reports.size} reports, " +
"${news.size} news stories"
)
}
}
// Usage
val aggregator = ContentAggregator()
aggregator.addBlog(Blog("Title 1", "Author 1", "Content 1"))
aggregator.addReport(ResearchReport("Topic 1", "Content 1", listOf()))
aggregator.addNews(NewsStory("https://ex.com", "News 1", "Summary 1"))
val prompt = aggregator.buildPrompt()
val summary = aggregator.getSummary()import com.embabel.agent.domain.library.*
import java.time.Instant
import java.time.temporal.ChronoUnit
fun filterRecentContent(
assets: List<ContentAsset>,
daysBack: Long = 7
): List<ContentAsset> {
val cutoff = Instant.now().minus(daysBack, ChronoUnit.DAYS)
return assets.filter { it.timestamp.isAfter(cutoff) }
}
fun groupByTimeRange(
assets: List<ContentAsset>
): Map<String, List<ContentAsset>> {
val now = Instant.now()
val oneDayAgo = now.minus(1, ChronoUnit.DAYS)
val oneWeekAgo = now.minus(7, ChronoUnit.DAYS)
return mapOf(
"today" to assets.filter { it.timestamp.isAfter(oneDayAgo) },
"this_week" to assets.filter {
it.timestamp.isAfter(oneWeekAgo) && it.timestamp.isBefore(oneDayAgo)
},
"older" to assets.filter { it.timestamp.isBefore(oneWeekAgo) }
)
}
// Usage
val assets: List<ContentAsset> = listOf(
Blog("Recent", "Author", "Content"),
Blog("Old", "Author", "Content",
timestamp = Instant.now().minus(30, ChronoUnit.DAYS)),
ResearchReport("Recent Research", "Content", listOf())
)
val recent = filterRecentContent(assets, daysBack = 7)
val grouped = groupByTimeRange(assets)import com.embabel.agent.domain.library.*
fun findRelatedBlogs(
targetBlog: Blog,
allBlogs: List<Blog>,
minKeywordOverlap: Int = 1
): List<Blog> {
return allBlogs
.filter { it != targetBlog }
.filter { blog ->
val overlap = blog.keywords.intersect(targetBlog.keywords)
overlap.size >= minKeywordOverlap
}
.sortedByDescending { blog ->
blog.keywords.intersect(targetBlog.keywords).size
}
}
fun createRelatedContentPrompt(
mainContent: Blog,
related: List<Blog>
): String {
return """
Main Content:
${mainContent.contribution()}
Related Content:
${related.joinToString("\n\n") { it.contribution() }}
""".trimIndent()
}
// Usage
val mainBlog = Blog(
title = "AI Ethics",
author = "Author",
content = "Ethics content...",
keywords = setOf("ai", "ethics", "fairness")
)
val allBlogs = listOf(
Blog("ML Fairness", "Author", "Content",
keywords = setOf("ai", "fairness", "ml")),
Blog("Unrelated Topic", "Author", "Content",
keywords = setOf("databases", "sql"))
)
val related = findRelatedBlogs(mainBlog, allBlogs)
val prompt = createRelatedContentPrompt(mainBlog, related)ContentAsset, HasContent, Person for flexibilitywhen expressions with is checkstessl i tessl/maven-com-embabel-agent--embabel-agent-domain@0.3.0