CtrlK
CommunityDocumentationLog inGet started
Tessl Logo

tessl/maven-com-embabel-agent--embabel-agent-domain

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.

Overview
Eval results
Files

json-serialization.mddocs/

JSON Serialization

All domain types support Jackson JSON serialization with proper annotations.

Jackson Setup

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule

val mapper = jacksonObjectMapper()
    .registerModule(JavaTimeModule())  // For Instant serialization

The JavaTimeModule is required for Instant serialization in types with timestamps (Blog, ResearchReport).

Jackson Annotations

@JsonClassDescription

Provides class-level descriptions for schema generation:

@JsonClassDescription("Research report, containing a topic, content and links")
open class ResearchReport(...)

@JsonPropertyDescription

Provides property-level descriptions:

open class ResearchTopic(
    @get:JsonPropertyDescription("topic to research")
    val topic: String,
    @get:JsonPropertyDescription("specific questions")
    val questions: List<String>
)

@JsonDeserialize

Specifies implementation classes for interfaces:

@JsonDeserialize(as = PersonImpl::class)
interface Person {
    val name: String
}

When deserializing JSON to Person interface, Jackson automatically uses PersonImpl.

Serialization Examples

Blog

import com.embabel.agent.domain.library.Blog
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import java.time.Instant

val mapper = jacksonObjectMapper().registerModule(JavaTimeModule())

val blog = Blog(
    title = "Getting Started",
    author = "Jane Developer",
    content = "# Introduction\n\nContent here...",
    timestamp = Instant.parse("2026-02-06T12:00:00Z"),
    keywords = setOf("embabel", "ai"),
    format = "markdown"
)

// Serialize
val json = mapper.writeValueAsString(blog)

// Deserialize
val deserialized = mapper.readValue(json, Blog::class.java)

JSON:

{
  "title": "Getting Started",
  "author": "Jane Developer",
  "content": "# Introduction\n\nContent here...",
  "timestamp": "2026-02-06T12:00:00Z",
  "keywords": ["embabel", "ai"],
  "format": "markdown"
}

Summary

import com.embabel.agent.domain.library.Summary

val mapper = jacksonObjectMapper()

val summary = Summary("Document covers agent fundamentals")

// Serialize
val json = mapper.writeValueAsString(summary)

// Deserialize
val deserialized = mapper.readValue(json, Summary::class.java)

JSON:

{
  "summary": "Document covers agent fundamentals"
}

Person / PersonImpl

import com.embabel.agent.domain.library.Person
import com.embabel.agent.domain.library.PersonImpl

val mapper = jacksonObjectMapper()

val person = PersonImpl("Jane Doe")

// Serialize
val json = mapper.writeValueAsString(person)

// Deserialize to PersonImpl
val asImpl = mapper.readValue(json, PersonImpl::class.java)

// Deserialize to Person interface (uses PersonImpl automatically)
val asInterface: Person = mapper.readValue(json, Person::class.java)
println(asInterface::class.simpleName)  // "PersonImpl"

JSON:

{
  "name": "Jane Doe"
}

NewsStory

import com.embabel.agent.domain.library.NewsStory

val mapper = jacksonObjectMapper()

val story = NewsStory(
    url = "https://example.com/article",
    title = "Breaking News",
    summary = "Important developments"
)

// Serialize
val json = mapper.writeValueAsString(story)

// Deserialize
val deserialized = mapper.readValue(json, NewsStory::class.java)

JSON:

{
  "url": "https://example.com/article",
  "title": "Breaking News",
  "summary": "Important developments"
}

RelevantNewsStories

import com.embabel.agent.domain.library.RelevantNewsStories
import com.embabel.agent.domain.library.NewsStory

val mapper = jacksonObjectMapper()

val stories = RelevantNewsStories(
    items = listOf(
        NewsStory("https://ex.com/1", "Title 1", "Summary 1"),
        NewsStory("https://ex.com/2", "Title 2", "Summary 2")
    )
)

// Serialize
val json = mapper.writeValueAsString(stories)

// Deserialize
val deserialized = mapper.readValue(json, RelevantNewsStories::class.java)

JSON:

{
  "items": [
    {
      "url": "https://ex.com/1",
      "title": "Title 1",
      "summary": "Summary 1"
    },
    {
      "url": "https://ex.com/2",
      "title": "Title 2",
      "summary": "Summary 2"
    }
  ]
}

ResearchTopic

import com.embabel.agent.domain.library.ResearchTopic

val mapper = jacksonObjectMapper()

val topic = ResearchTopic(
    topic = "Quantum Computing",
    questions = listOf("What is quantum supremacy?", "Practical applications?")
)

// Serialize
val json = mapper.writeValueAsString(topic)

// Deserialize
val deserialized = mapper.readValue(json, ResearchTopic::class.java)

JSON:

{
  "topic": "Quantum Computing",
  "questions": [
    "What is quantum supremacy?",
    "What are practical applications?"
  ]
}

ResearchTopics

import com.embabel.agent.domain.library.ResearchTopics
import com.embabel.agent.domain.library.ResearchTopic

val mapper = jacksonObjectMapper()

val topics = ResearchTopics(
    topics = listOf(
        ResearchTopic("Machine Learning", listOf("Latest developments?")),
        ResearchTopic("Distributed Systems", listOf("Ensure consistency?"))
    )
)

// Serialize
val json = mapper.writeValueAsString(topics)

// Deserialize
val deserialized = mapper.readValue(json, ResearchTopics::class.java)

JSON:

{
  "topics": [
    {
      "topic": "Machine Learning",
      "questions": ["Latest developments?"]
    },
    {
      "topic": "Distributed Systems",
      "questions": ["Ensure consistency?"]
    }
  ]
}

ResearchReport

import com.embabel.agent.domain.library.ResearchReport
import com.embabel.agent.domain.library.InternetResource
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule

val mapper = jacksonObjectMapper().registerModule(JavaTimeModule())

val report = ResearchReport(
    topic = "Cloud Security",
    content = "Cloud security encompasses...",
    links = listOf(
        InternetResource(
            url = "https://cloud.google.com/security",
            summary = "GCP security best practices"
        )
    )
)

// Serialize
val json = mapper.writeValueAsString(report)

// Deserialize
val deserialized = mapper.readValue(json, ResearchReport::class.java)

JSON:

{
  "topic": "Cloud Security",
  "content": "Cloud security encompasses...",
  "links": [
    {
      "url": "https://cloud.google.com/security",
      "summary": "GCP security best practices"
    }
  ],
  "timestamp": "2026-02-06T12:00:00Z"
}

Collections

import com.embabel.agent.domain.library.Blog

val mapper = jacksonObjectMapper().registerModule(JavaTimeModule())

val blogs = listOf(
    Blog("Title 1", "Author 1", "Content 1"),
    Blog("Title 2", "Author 2", "Content 2")
)

// Serialize list
val json = mapper.writeValueAsString(blogs)

// Deserialize list
val deserialized = mapper.readValue(
    json,
    mapper.typeFactory.constructCollectionType(List::class.java, Blog::class.java)
)

Polymorphic Serialization

ContentAsset Polymorphism

import com.embabel.agent.domain.library.*

val mapper = jacksonObjectMapper().registerModule(JavaTimeModule())

val assets: List<ContentAsset> = listOf(
    Blog("Title", "Author", "Content"),
    ResearchReport("Topic", "Content", listOf())
)

// Serialize - includes type information if configured
val json = mapper.writeValueAsString(assets)

// Note: To deserialize polymorphic types, configure Jackson with type information:
// mapper.activateDefaultTyping(...)

Pretty Printing

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper

val mapper = jacksonObjectMapper()
    .writerWithDefaultPrettyPrinter()

val blog = Blog("Title", "Author", "Content")
val prettyJson = mapper.writeValueAsString(blog)
println(prettyJson)

Custom Serialization

For custom types extending domain types, Jackson will serialize all properties:

class CategorizedNewsStory(
    url: String,
    title: String,
    summary: String,
    val category: String,
    val source: String
) : NewsStory(url, title, summary)

val mapper = jacksonObjectMapper()

val story = CategorizedNewsStory(
    url = "https://ex.com",
    title = "Title",
    summary = "Summary",
    category = "Tech",
    source = "TechCrunch"
)

val json = mapper.writeValueAsString(story)
// Includes url, title, summary, category, source

Error Handling

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException

val mapper = jacksonObjectMapper()

try {
    val json = """{"title": "No Author"}"""  // Missing required field
    val blog = mapper.readValue(json, Blog::class.java)
} catch (e: MissingKotlinParameterException) {
    println("Missing required parameter: ${e.parameter.name}")
}

Best Practices

  1. Register JavaTimeModule - Required for types with Instant (Blog, ResearchReport)
  2. Use type-safe deserialization - Specify exact class: Blog::class.java
  3. Handle collections properly - Use typeFactory.constructCollectionType() for lists
  4. Validate input - Catch deserialization exceptions for invalid JSON
  5. Pretty print for debugging - Use writerWithDefaultPrettyPrinter() when needed
tessl i tessl/maven-com-embabel-agent--embabel-agent-domain@0.3.0

docs

content-types.md

core-concepts.md

external-types.md

index.md

installation.md

integration-patterns.md

json-serialization.md

news-types.md

person-types.md

quick-reference.md

research-types.md

summary-type.md

tile.json