CtrlK
CommunityDocumentationLog inGet started
Tessl Logo

tessl/maven-com-embabel-agent--embabel-agent-shell

Interactive Spring Shell-based command-line interface for the Embabel Agent platform, providing terminal interaction, chat sessions, and agent management commands.

Overview
Eval results
Files

customization.mddocs/guides/

Customization Guide

Learn how to customize the Embabel Agent Shell appearance and behavior.

Prompt Customization

Using Built-in Personalities

Select a personality theme in configuration:

embabel:
  agent:
    logging:
      personality: starwars  # or severance, hitchhiker, colossus, montypython

Available personalities:

PersonalityPromptColorTheme
starwarsstarwars>Gold yellow (0xFFD700)Star Wars universe
severanceRandom deptSky blue (0x87CEEB)Lumon Industries
hitchhikerRandom entryLime green (0x32CD32)Hitchhiker's Guide
colossusColossus>Orange-red (0xFF4500)Colossus computer
montypythonpythons>Pure red (0xFF0000)Monty Python

Prompt Behavior

Star Wars Prompt

import com.embabel.agent.shell.personality.starwars.StarWarsPromptProvider

// Configuration
embabel.agent.logging.personality=starwars

// Prompt: "starwars> " in gold yellow
// Messages: Random Star Wars quotes from logging/starwars.txt

Severance Prompt

import com.embabel.agent.shell.personality.severance.SeverancePromptProvider

// Configuration
embabel.agent.logging.personality=severance

// Prompt: Random department name in sky blue
// Departments: MDR, Lumon, Choreography and Merriment, etc.
// Messages: Random Severance quotes from logging/severance.txt

Hitchhiker Prompt

import com.embabel.agent.shell.personality.hitchhiker.HitchhikerPromptProvider

// Configuration
embabel.agent.logging.personality=hitchhiker

// Prompt: Random Guide entry in lime green
// Entries: DON'T PANIC, Mostly Harmless, 42, etc.
// Messages: Random Hitchhiker quotes from logging/hitchhiker.txt

Colossus Prompt

import com.embabel.agent.shell.personality.colossus.ColossusPromptProvider

// Configuration
embabel.agent.logging.personality=colossus

// Prompt: "Colossus> " in orange-red
// Messages: Random Colossus quotes from logging/colossus.txt

Monty Python Prompt

import com.embabel.agent.shell.personality.montypython.MontyPythonPromptProvider

// Configuration
embabel.agent.logging.personality=montypython

// Prompt: "pythons> " in pure red
// Messages: Random Monty Python quotes from logging/montypython.txt

Creating Custom Prompts

Option 1: Simple Static Prompt

Create a simple prompt without dynamic messages:

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.shell.jline.PromptProvider
import org.jline.utils.AttributedString
import org.jline.utils.AttributedStyle

@Configuration
class CustomPromptConfiguration {
    @Bean
    fun customPromptProvider(): PromptProvider {
        return PromptProvider {
            AttributedString(
                "custom> ",
                AttributedStyle.DEFAULT.foreground(AttributedStyle.MAGENTA)
            )
        }
    }
}

Result: custom> prompt in magenta

Option 2: Dynamic Message-Based Prompt

Create a prompt with dynamic messages:

import com.embabel.agent.shell.MessageGeneratorPromptProvider
import com.embabel.common.util.RandomFromFileMessageGenerator
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.stereotype.Component

@Component
@ConditionalOnProperty(name = ["embabel.agent.logging.personality"], havingValue = "custom")
class CustomPromptProvider : MessageGeneratorPromptProvider(
    prompt = "custom",
    color = 0xFF00FF, // Magenta
    messageGenerator = RandomFromFileMessageGenerator(
        url = "logging/custom.txt"
    )
)

Configuration:

embabel:
  agent:
    logging:
      personality: custom

Message File (src/main/resources/logging/custom.txt):

Character: Welcome message
Character: Another message
Character: Yet another message

Messages with ":" are split into character and text parts, formatted with personality styling.

Option 3: Custom Message Generator

Implement your own message generator:

import com.embabel.common.util.MessageGenerator

class CustomMessageGenerator : MessageGenerator {
    private val messages = listOf(
        "Ready for action",
        "Standing by",
        "Awaiting orders"
    )

    override fun generate(): String {
        return messages.random()
    }
}

@Component
@ConditionalOnProperty(name = ["embabel.agent.logging.personality"], havingValue = "custom")
class CustomPromptProvider : MessageGeneratorPromptProvider(
    prompt = "bot",
    color = 0x00FF00,
    messageGenerator = CustomMessageGenerator()
)

Color Palette Customization

Using Built-in Palettes

Each personality has an associated color palette:

import com.embabel.agent.shell.personality.starwars.StarWarsColorPalette
import com.embabel.agent.shell.personality.severance.LumonColorPalette
import com.embabel.agent.shell.personality.hitchhiker.HitchhikerColorPalette
import com.embabel.agent.shell.personality.colossus.ColossusColorPalette
import com.embabel.agent.shell.personality.montypython.MontyPythonColorPalette

// Use in output formatting
val palette = StarWarsColorPalette()

Creating Custom Color Palettes

Implement the ColorPalette interface:

import com.embabel.agent.spi.logging.ColorPalette
import org.springframework.stereotype.Component

@Component
class MyCustomColorPalette : ColorPalette {
    // Define your color scheme methods
    // Implementation depends on ColorPalette interface
}

Use your custom palette:

@Component
class MyService(
    private val customPalette: MyCustomColorPalette
) {
    fun formatOutput(result: AgentProcessExecution) {
        val formatted = formatProcessOutput(
            result = result,
            colorPalette = customPalette,
            objectMapper = objectMapper,
            lineLength = 140
        )
    }
}

Configuration Customization

Shell Properties

Customize shell behavior:

embabel:
  agent:
    shell:
      # Maximum line length for text wrapping
      lineLength: 140

      # Redirect logs to file during chat
      redirectLogToFile: false

Line Length

Controls text wrapping in:

  • Terminal output
  • Chat sessions
  • Formatted process output

Default: 140 Range: Any positive integer (typically 80-200)

embabel:
  agent:
    shell:
      lineLength: 120  # More compact

Log Redirection

Controls whether logs are redirected to file during chat sessions:

Default: false Values: true | false

embabel:
  agent:
    shell:
      redirectLogToFile: true  # Cleaner chat UI

When enabled:

  • Logs written to logs/chat-session.log
  • Console output remains clean during chat
  • Original logging restored after chat ends

Accessing Properties Programmatically

Inject ShellProperties to access configuration:

import com.embabel.agent.shell.config.ShellProperties
import org.springframework.stereotype.Component

@Component
class MyComponent(
    private val shellProperties: ShellProperties
) {
    fun processText(text: String) {
        val maxLength = shellProperties.lineLength
        val shouldRedirect = shellProperties.redirectLogToFile

        // Use configuration values
    }
}

Spring Shell Integration

Custom Shell Commands

Add your own shell commands:

import org.springframework.shell.standard.ShellComponent
import org.springframework.shell.standard.ShellMethod
import org.springframework.shell.standard.ShellOption

@ShellComponent
class MyCustomCommands {
    @ShellMethod("My custom command")
    fun myCommand(
        @ShellOption(help = "Input parameter") input: String
    ): String {
        return "Processed: $input"
    }
}

Usage:

embabel> myCommand "test"
Processed: test

Command Aliases

Use aliases for convenience:

@ShellMethod(
    value = "Execute task",
    key = ["execute", "x", "run"]  // Multiple aliases
)
fun execute(@ShellOption(help = "task") task: String): String {
    // Implementation
}

Usage:

embabel> execute "task"
embabel> x "task"
embabel> run "task"

Shell Configuration

Configure Spring Shell behavior:

spring:
  shell:
    interactive:
      enabled: true
    noninteractive:
      enabled: false
    command:
      version:
        enabled: false  # Disable version command

Terminal Customization

Terminal Services

The terminal services can be customized through dependency injection:

import com.embabel.agent.shell.TerminalServices
import com.embabel.agent.shell.config.ShellProperties
import org.jline.terminal.Terminal
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Primary

@Configuration
class TerminalCustomization {
    @Bean
    @Primary
    fun customTerminalServices(
        terminal: Terminal,
        shellProperties: ShellProperties
    ): TerminalServices {
        // Create custom terminal services
        return TerminalServices(terminal, shellProperties)
    }
}

JLine Terminal

Customize the JLine terminal:

import org.jline.terminal.Terminal
import org.jline.terminal.TerminalBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class TerminalConfiguration {
    @Bean
    fun terminal(): Terminal {
        return TerminalBuilder.builder()
            .system(true)
            .encoding(Charsets.UTF_8)
            .build()
    }
}

Advanced Customization

Custom Autonomy Configuration

Customize the autonomy service:

import com.embabel.agent.api.common.autonomy.Autonomy
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class AutonomyCustomization {
    @Bean
    fun customAutonomy(): Autonomy {
        // Create and configure custom autonomy implementation
    }
}

Custom Model Provider

Provide custom LLM models:

import com.embabel.agent.model.ModelProvider
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class ModelConfiguration {
    @Bean
    fun customModelProvider(): ModelProvider {
        // Create and configure custom model provider
    }
}

Custom Chatbot

Implement a custom chatbot:

import com.embabel.chat.Chatbot
import com.embabel.chat.ChatSession
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class ChatbotConfiguration {
    @Bean
    fun customChatbot(): Chatbot {
        return object : Chatbot {
            override fun createSession(): ChatSession {
                // Return custom chat session implementation
            }
        }
    }
}

Personality Message Files

Message File Format

Create custom message files in src/main/resources/logging/:

Character: Message text
Character: Another message
Single line message without character
Character: Multi-word message text here

Messages can:

  • Include character names with ":" separator
  • Be single-line without character
  • Contain any text (quotes, references, etc.)

Example Message Files

logging/starwars.txt:

Yoda: Do or do not, there is no try
Obi-Wan: May the Force be with you
Vader: I find your lack of faith disturbing

logging/custom.txt:

Bot: Ready to assist
Bot: Processing your request
Bot: Standing by for commands
System: All systems operational

Random Selection

Messages are randomly selected on each prompt display using RandomFromFileMessageGenerator:

import com.embabel.common.util.RandomFromFileMessageGenerator

val generator = RandomFromFileMessageGenerator(
    url = "logging/custom.txt"
)

val message = generator.generate()  // Random message from file

Conditional Bean Registration

Using @ConditionalOnProperty

Personality providers use conditional registration:

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty

@Component
@ConditionalOnProperty(
    name = ["embabel.agent.logging.personality"],
    havingValue = "custom"
)
class CustomPromptProvider : MessageGeneratorPromptProvider(...)

Only loads when:

embabel:
  agent:
    logging:
      personality: custom

Using @ConditionalOnMissingBean

Default providers use missing bean condition:

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean

@Bean
@ConditionalOnMissingBean(PromptProvider::class)
fun defaultPromptProvider(): PromptProvider {
    return DefaultPromptProvider()
}

Only loads when no other PromptProvider bean exists.

Prompt Provider Selection Logic

Spring loads prompt providers in this order:

  1. Property-based personality (if configured):

    embabel.agent.logging.personality: starwars

    → Loads StarWarsPromptProvider

  2. Custom PromptProvider bean (if defined):

    @Bean
    fun customPromptProvider(): PromptProvider { ... }

    → Uses your custom provider

  3. Default provider (fallback): → Loads DefaultPromptProvider ("embabel> " in yellow)

Only one prompt provider is active at a time.

Complete Customization Example

Putting it all together:

// 1. Custom message generator
class RobotMessageGenerator : MessageGenerator {
    override fun generate(): String {
        return listOf(
            "Robot: Beep boop",
            "Robot: Analyzing data",
            "Robot: Ready to serve"
        ).random()
    }
}

// 2. Custom prompt provider
@Component
@ConditionalOnProperty(name = ["embabel.agent.logging.personality"], havingValue = "robot")
class RobotPromptProvider : MessageGeneratorPromptProvider(
    prompt = "robot",
    color = 0x00FFFF, // Cyan
    messageGenerator = RobotMessageGenerator()
)

// 3. Custom color palette
@Component
class RobotColorPalette : ColorPalette {
    // Implement color palette methods
}

// 4. Configuration

application.yaml:

embabel:
  agent:
    shell:
      lineLength: 120
      redirectLogToFile: true
    logging:
      personality: robot

Result: Cyan "robot>" prompt with random robot messages

Related Documentation

  • Task Execution: Task Execution Guide
  • Chat Sessions: Chat Sessions Guide
  • Output Handling: Output Handling Guide
  • Full API: Configuration Reference
  • Prompt Providers: Prompt Providers Reference
tessl i tessl/maven-com-embabel-agent--embabel-agent-shell@0.3.0

docs

guides

chat-sessions.md

customization.md

output-handling.md

task-execution.md

examples.md

index.md

quickstart.md

troubleshooting.md

tile.json