embabel/embabel-agentPublic

Agent framework for the JVM. Pronounced Em-BAY-bel /ɛmˈbeɪbəl/

Stars
4K
Forks
398
Watchers
61
Open issues
51
Open PRs
12
Contributors
~65
Commits
2.8K
Branches
113

KotlinApache-2.0Created Apr 10, 2025Last push todayLatest release v1.0.0

Star history

since Sep 21, 2025
02K4KSep 2025Jan 2026Apr 2026Aug 2026
4K stars as of Aug 7, 2026, tracked back to Sep 21, 2025. Historical curve reconstructed from public GitHub event archives, calibrated to the current total.

Contribution activity

commits per day, last 52 weeks
AugSepOctNovDecJanFebMarAprMayJunJulAugMonWedFri2025-08-10: 12 commits2025-08-11: 8 commits2025-08-12: 11 commits2025-08-13: 10 commits2025-08-14: 4 commits2025-08-15: 3 commits2025-08-16: 3 commits2025-08-17: 6 commits2025-08-18: 9 commits2025-08-19: 11 commits2025-08-20: 3 commits2025-08-21: 3 commits2025-08-22: 8 commits2025-08-23: 12 commits2025-08-24: 6 commits2025-08-25: 20 commits2025-08-26: 5 commits2025-08-27: 13 commits2025-08-28: 5 commits2025-08-29: 4 commits2025-08-30: 9 commits2025-08-31: 10 commits2025-09-01: 13 commits2025-09-02: 14 commits2025-09-03: 12 commits2025-09-04: 3 commits2025-09-05: 5 commits2025-09-06: 13 commits2025-09-07: 9 commits2025-09-08: 13 commits2025-09-09: 7 commits2025-09-10: 13 commits2025-09-11: 8 commits2025-09-12: 16 commits2025-09-13: 2 commits2025-09-14: 1 commit2025-09-15: 12 commits2025-09-16: 3 commits2025-09-17: 12 commits2025-09-18: 10 commits2025-09-19: 9 commits2025-09-20: 4 commits2025-09-21: 1 commit2025-09-22: 5 commits2025-09-23: 7 commits2025-09-24: 6 commits2025-09-25: 5 commits2025-09-26: 7 commits2025-09-27: 4 commits2025-09-28: 2 commits2025-09-29: 3 commits2025-09-30: 3 commits2025-10-01: 1 commit2025-10-02: 3 commits2025-10-03: 8 commits2025-10-04: 4 commits2025-10-05: 5 commits2025-10-06: 2 commits2025-10-07: 8 commits2025-10-08: 2 commits2025-10-09: 0 commits2025-10-10: 2 commits2025-10-11: 6 commits2025-10-12: 3 commits2025-10-13: 3 commits2025-10-14: 5 commits2025-10-15: 1 commit2025-10-16: 2 commits2025-10-17: 1 commit2025-10-18: 2 commits2025-10-19: 0 commits2025-10-20: 3 commits2025-10-21: 2 commits2025-10-22: 5 commits2025-10-23: 5 commits2025-10-24: 2 commits2025-10-25: 15 commits2025-10-26: 6 commits2025-10-27: 4 commits2025-10-28: 8 commits2025-10-29: 3 commits2025-10-30: 5 commits2025-10-31: 2 commits2025-11-01: 2 commits2025-11-02: 4 commits2025-11-03: 1 commit2025-11-04: 3 commits2025-11-05: 4 commits2025-11-06: 0 commits2025-11-07: 6 commits2025-11-08: 3 commits2025-11-09: 0 commits2025-11-10: 6 commits2025-11-11: 8 commits2025-11-12: 2 commits2025-11-13: 2 commits2025-11-14: 0 commits2025-11-15: 7 commits2025-11-16: 6 commits2025-11-17: 10 commits2025-11-18: 6 commits2025-11-19: 14 commits2025-11-20: 3 commits2025-11-21: 16 commits2025-11-22: 4 commits2025-11-23: 3 commits2025-11-24: 8 commits2025-11-25: 8 commits2025-11-26: 10 commits2025-11-27: 4 commits2025-11-28: 6 commits2025-11-29: 3 commits2025-11-30: 1 commit2025-12-01: 9 commits2025-12-02: 8 commits2025-12-03: 3 commits2025-12-04: 8 commits2025-12-05: 5 commits2025-12-06: 4 commits2025-12-07: 3 commits2025-12-08: 6 commits2025-12-09: 2 commits2025-12-10: 1 commit2025-12-11: 3 commits2025-12-12: 11 commits2025-12-13: 12 commits2025-12-14: 11 commits2025-12-15: 17 commits2025-12-16: 2 commits2025-12-17: 6 commits2025-12-18: 5 commits2025-12-19: 6 commits2025-12-20: 4 commits2025-12-21: 4 commits2025-12-22: 17 commits2025-12-23: 7 commits2025-12-24: 2 commits2025-12-25: 1 commit2025-12-26: 4 commits2025-12-27: 1 commit2025-12-28: 4 commits2025-12-29: 0 commits2025-12-30: 5 commits2025-12-31: 3 commits2026-01-01: 3 commits2026-01-02: 6 commits2026-01-03: 3 commits2026-01-04: 12 commits2026-01-05: 4 commits2026-01-06: 8 commits2026-01-07: 7 commits2026-01-08: 12 commits2026-01-09: 9 commits2026-01-10: 12 commits2026-01-11: 3 commits2026-01-12: 7 commits2026-01-13: 4 commits2026-01-14: 2 commits2026-01-15: 4 commits2026-01-16: 3 commits2026-01-17: 7 commits2026-01-18: 10 commits2026-01-19: 5 commits2026-01-20: 8 commits2026-01-21: 5 commits2026-01-22: 7 commits2026-01-23: 8 commits2026-01-24: 5 commits2026-01-25: 5 commits2026-01-26: 4 commits2026-01-27: 12 commits2026-01-28: 10 commits2026-01-29: 10 commits2026-01-30: 10 commits2026-01-31: 6 commits2026-02-01: 7 commits2026-02-02: 7 commits2026-02-03: 5 commits2026-02-04: 5 commits2026-02-05: 3 commits2026-02-06: 4 commits2026-02-07: 4 commits2026-02-08: 13 commits2026-02-09: 6 commits2026-02-10: 8 commits2026-02-11: 13 commits2026-02-12: 1 commit2026-02-13: 7 commits2026-02-14: 5 commits2026-02-15: 4 commits2026-02-16: 2 commits2026-02-17: 7 commits2026-02-18: 2 commits2026-02-19: 4 commits2026-02-20: 4 commits2026-02-21: 3 commits2026-02-22: 3 commits2026-02-23: 1 commit2026-02-24: 2 commits2026-02-25: 2 commits2026-02-26: 2 commits2026-02-27: 4 commits2026-02-28: 1 commit2026-03-01: 0 commits2026-03-02: 2 commits2026-03-03: 1 commit2026-03-04: 3 commits2026-03-05: 2 commits2026-03-06: 1 commit2026-03-07: 8 commits2026-03-08: 1 commit2026-03-09: 1 commit2026-03-10: 5 commits2026-03-11: 6 commits2026-03-12: 1 commit2026-03-13: 1 commit2026-03-14: 2 commits2026-03-15: 0 commits2026-03-16: 5 commits2026-03-17: 4 commits2026-03-18: 1 commit2026-03-19: 5 commits2026-03-20: 6 commits2026-03-21: 1 commit2026-03-22: 4 commits2026-03-23: 1 commit2026-03-24: 5 commits2026-03-25: 0 commits2026-03-26: 0 commits2026-03-27: 5 commits2026-03-28: 7 commits2026-03-29: 0 commits2026-03-30: 3 commits2026-03-31: 7 commits2026-04-01: 0 commits2026-04-02: 0 commits2026-04-03: 2 commits2026-04-04: 4 commits2026-04-05: 3 commits2026-04-06: 7 commits2026-04-07: 1 commit2026-04-08: 3 commits2026-04-09: 0 commits2026-04-10: 3 commits2026-04-11: 1 commit2026-04-12: 1 commit2026-04-13: 0 commits2026-04-14: 6 commits2026-04-15: 0 commits2026-04-16: 4 commits2026-04-17: 3 commits2026-04-18: 3 commits2026-04-19: 2 commits2026-04-20: 1 commit2026-04-21: 1 commit2026-04-22: 1 commit2026-04-23: 0 commits2026-04-24: 0 commits2026-04-25: 1 commit2026-04-26: 5 commits2026-04-27: 2 commits2026-04-28: 2 commits2026-04-29: 2 commits2026-04-30: 2 commits2026-05-01: 4 commits2026-05-02: 3 commits2026-05-03: 1 commit2026-05-04: 1 commit2026-05-05: 1 commit2026-05-06: 2 commits2026-05-07: 1 commit2026-05-08: 2 commits2026-05-09: 2 commits2026-05-10: 4 commits2026-05-11: 2 commits2026-05-12: 0 commits2026-05-13: 0 commits2026-05-14: 1 commit2026-05-15: 1 commit2026-05-16: 0 commits2026-05-17: 1 commit2026-05-18: 5 commits2026-05-19: 0 commits2026-05-20: 0 commits2026-05-21: 2 commits2026-05-22: 3 commits2026-05-23: 0 commits2026-05-24: 1 commit2026-05-25: 0 commits2026-05-26: 3 commits2026-05-27: 4 commits2026-05-28: 0 commits2026-05-29: 5 commits2026-05-30: 9 commits2026-05-31: 2 commits2026-06-01: 2 commits2026-06-02: 2 commits2026-06-03: 5 commits2026-06-04: 7 commits2026-06-05: 3 commits2026-06-06: 5 commits2026-06-07: 2 commits2026-06-08: 1 commit2026-06-09: 3 commits2026-06-10: 0 commits2026-06-11: 0 commits2026-06-12: 0 commits2026-06-13: 3 commits2026-06-14: 3 commits2026-06-15: 7 commits2026-06-16: 1 commit2026-06-17: 0 commits2026-06-18: 0 commits2026-06-19: 0 commits2026-06-20: 2 commits2026-06-21: 3 commits2026-06-22: 0 commits2026-06-23: 0 commits2026-06-24: 0 commits2026-06-25: 0 commits2026-06-26: 1 commit2026-06-27: 2 commits2026-06-28: 2 commits2026-06-29: 1 commit2026-06-30: 2 commits2026-07-01: 1 commit2026-07-02: 1 commit2026-07-03: 0 commits2026-07-04: 0 commits2026-07-05: 4 commits2026-07-06: 1 commit2026-07-07: 2 commits2026-07-08: 3 commits2026-07-09: 3 commits2026-07-10: 3 commits2026-07-11: 2 commits2026-07-12: 0 commits2026-07-13: 8 commits2026-07-14: 1 commit2026-07-15: 4 commits2026-07-16: 0 commits2026-07-17: 2 commits2026-07-18: 1 commit2026-07-19: 5 commits2026-07-20: 1 commit2026-07-21: 0 commits2026-07-22: 0 commits2026-07-23: 0 commits2026-07-24: 4 commits2026-07-25: 3 commits2026-07-26: 0 commits2026-07-27: 2 commits2026-07-28: 3 commits2026-07-29: 0 commits2026-07-30: 0 commits2026-07-31: 4 commits2026-08-01: 3 commits2026-08-02: 6 commits2026-08-03: 3 commits2026-08-04: 1 commit2026-08-05: 0 commits2026-08-06: 1 commit2026-08-07: 2 commits2026-08-08: 0 commits
1,518 commits in the last yearLessMore

Signals and awards

derived from tracked data
  • Very active

    1,518 commits in 52 weeks

  • Permissive license

    Apache-2.0

  • Continuous integration

    Automated checks passing

README

main branch

Docs MvnRepository Build YourKit JProfiler Quality Gate Status Discord

Kotlin Java Spring Spring Boot Apache Tomcat Apache Maven JUnit ChatGPT Jinja JSON GitHub Actions SonarQube Docker IntelliJ IDEA License Commits

    

Embabel (Em-BAY-bel) is a framework for authoring agentic flows on the JVM that seamlessly mix LLM-prompted interactions with code and domain models. Supports intelligent path finding towards goals. Written in Kotlin but offers a natural usage model from Java. From the creator of Spring.

 

Talk to the Docs

Have questions? Talk to the docs via the Embabel-powered hub — an Embabel agent that answers your questions about the framework in natural language.

Key Concepts

Models agentic flows in terms of:

  • Actions: Steps an agent takes
  • Goals: What an agent is trying to achieve
  • Conditions: Conditions to assess before executing an action or determining that a goal has been achieved. Conditions are reassessed after each action is executed.
  • Domain model: Objects underpinning the flow and informing Actions, Goals and Conditions.
  • Plan: A sequence of actions to achieve a goal. Plans are dynamically formulated by the system, not the programmer. The system replans after the completion of each action, allowing it to adapt to new information as well as observe the effects of the previous action. This is effectively an OODA loop.

Application developers don't usually have to deal with these concepts directly, as most conditions result from data flow defined in code, allowing the system to infer pre and post conditions.

These concepts underpin these differentiators versus other agent frameworks:

  • Sophisticated planning. Goes beyond a finite state machine or sequential execution with nesting by introducing a true planning step, using a non-LLM AI algorithm. This enables the system to perform tasks it wasn’t programmed to do by combining known steps in a novel order, as well as make decisions about parallelization and other runtime behavior.
  • Superior extensibility and reuse: Because of dynamic planning, adding more domain objects, actions, goals and conditions can extend the capability of the system, without editing FSM definitions or existing code.
  • Strong typing and the benefits of object orientation: Actions, goals and conditions are informed by a domain model, which can include behavior. Everything is strongly typed and prompts and manually authored code interact cleanly. No more magic maps. Enjoy full refactoring support.

Other benefits:

  • Platform abstraction: Clean separation between programming model and platform internals allows running locally while potentially offering higher QoS in production without changing application code.
  • Designed for LLM mixing: It is easy to build applications that mix LLMs, ensuring the most cost-effective yet capable solution. This enables the system to leverage the strengths of different models for different tasks. In particular, it facilitates the use of local models for point tasks. This can be important for cost and privacy.
  • Built on Spring and the JVM, making it easy to access existing enterprise functionality and capabilities. For example:
    • Spring can inject and manage agents, including using Spring AOP to decorate functions.
    • Robust persistence and transaction management solutions are available.
  • Designed for testability from the ground up. Both unit testing and agent end to end testing are easy.

Flows can be authored in one of two ways:

  • An annotation-based model similar to Spring MVC, with types annotated with the Spring stereotype @Agent, using @Goal, @Condition and @Action methods.
  • Idiomatic Kotlin DSL with agent { and action { blocks.

Either way, flows are backed by a domain model of objects that can have rich behavior.

We are working toward allowing natural language actions and goals to be deployed.

The planning step is pluggable.

The default planning approach is Goal Oriented Action Planning. GOAP is a popular AI planning algorithm used in gaming. It allows for dynamic decision-making and action selection based on the current state of the world and the goals of the agent.

Goals, actions and plans are independent of GOAP. Embabel also supports Utility AI out of the box, which can run the same actions but chooses actions based on (potentially dynamic) utility scores rather than strict preconditions and postconditions. This is valuable for exploration and open-ended tasks, when we do not need to achieve a specific goal but want to maximize overall utility.

The framework executes via an AgentPlatform implementation.

An agent platform supports the following modes of execution:

  • Focused, where user code requests particular functionality: User code calls a method to run a particular agent, passing in input. This is ideal for code-driven flows such as a flow invoked in response to an incoming event.
  • Closed, where user intent (or another incoming event) is classified to choose an agent. The platform tries to find a suitable agent among all the agents it knows about. Agent choice is dynamic, but only actions defined within the particular agent will run.
  • Open, where the user's intent is assessed and the platform uses all its resources to try to achieve it. The platform tries to find a suitable goal among all the goals it knows about and builds a custom agent to achieve it from the start state, including relevant actions and conditions. The platform will not proceed if it is unconvinced as to the applicability of any goal. The GoalChoiceApprover interface provides developers a way to limit goal choice further.

Open mode is the most powerful, but least deterministic.

In open mode, the platform is capable of finding novel paths that were not envisioned by developers, and even combining functionality from multiple providers.

Even in open mode, the platform will only perform individual steps that have been specified. (Of course, steps may themselves be LLM transforms, in which case the prompts are controlled by user code but the results are still non-deterministic.)

Possible future modes:

  • Evolving mode: Where the platform can work with multiple goals in the same process and modify a running process to add further goals and agents. For example, an action can realize that it has become important to achieve additional goals.

Embabel agent systems will also support federation, both with other Embabel systems (allowing planning to incorporate remote actions and goals) and third party agent frameworks.

Quick Start

Get an agent running in under 5 minutes.

Create your own agent repo from our Java or Kotlin GitHub template by clicking the "Use this template" button.

You'll have an agent running in under a minute if you already have an OPENAI_API_KEY and have Maven installed.

📚 For examples and tutorials, see the Embabel Agent Examples Repository

🚗 For a sophisticated, realistic example application, see the Tripper travel planner agent

Travel Planner Output

AI-generated travel itinerary with detailed recommendations

Interactive map

Map link included in output

Why Is Embabel Needed?

TL;DR Because the evolution of agent frameworks is early and there's a lot of room for improvement; because an agent framework on the JVM will deliver great business value.

  • Why do we need an agent framework at all? We can write code without higher level abstractions, directly invoking LLMs and controlling flow directly in code. However, a higher level agent framework offers compelling benefits. For example:
    • Breaking up LLM interactions, making them simpler and more focused. This maximizes reuse and minimizes cost and errors. It often allows us to use cheaper models for point interactions.
    • Facilitating both unit and integration testing, which remain as important with agentic systems as with any other software systems.
    • Increasing composability where subflows and individual actions can be reused
    • Making applications more manageable and robust, enabling a workflow manager to control their execution and retry operations while maintaining previous state
    • Enhancing safety through the ability to apply guardrails in many places
  • Why do we need an agent framework for the JVM when solutions exist in Python?: While agent frameworks initially appeared predominantly Python, it's early and there's plenty of room for novel and superior approaches. The key adjacency is not the LLM--which is a simple HTTP call away--but existing code and infrastructure assets that are more valuable on the JVM than in Python.
  • Why not use just Spring AI? Spring AI is great. We build on it, and embrace the Spring component model. However, we believe that most applications should work with higher level APIs. An analogy: Spring AI exists at the level of the Servlet API, while Embabel is more like Spring MVC. Complex requirements are much easier to express and test in Embabel than with direct use of Spring AI.
  • Why not attempt to contribute this project to Spring? This project requires different governance from Spring, where most projects exist in stable environments and dependability and stability outweighs rapid innovation. Second, the concepts are not JVM-specific. We hope that Embabel will become the leading agent framework across platforms. While the Spring brand is valuable in Java, it is not in TypeScript or Python.

Show Me The Code

In Java or Kotlin, agent implementation code is intuitive and easy to test.

Java
@Agent(description = "Find news based on a person's star sign")
public class StarNewsFinder {

    private final HoroscopeService horoscopeService;
    private final int storyCount;

    // Services are injected by Spring
    public StarNewsFinder(
            HoroscopeService horoscopeService,
            @Value("${star-news-finder.story.count:5}") int storyCount) {
        this.horoscopeService = horoscopeService;
        this.storyCount = storyCount;
    }

    @Action
    public StarPerson extractStarPerson(UserInput userInput, Ai ai) {
        return ai
                .withLlm(OpenAiModels.GPT_41)
                .createObjectIfPossible(
                        """
                                Create a person from this user input, extracting their name and star sign:
                                %s""".formatted(userInput.getContent()),
                        StarPerson.class
                );
    }

    @Action
    public Horoscope retrieveHoroscope(StarPerson starPerson) {
        return new Horoscope(horoscopeService.dailyHoroscope(starPerson.sign()));
    }

    // toolGroups specifies tools that are required for this action to run
    @Action(toolGroups = {CoreToolGroups.WEB})
    public RelevantNewsStories findNewsStories(
            StarPerson person,
            Horoscope horoscope,
            Ai ai) {
        var prompt = """
                %s is an astrology believer with the sign %s.
                Their horoscope for today is:
                    <horoscope>%s</horoscope>
                Given this, use web tools and generate search queries
                to find %d relevant news stories summarize them in a few sentences.
                Include the URL for each story.
                Do not look for another horoscope reading or return results directly about astrology;
                find stories relevant to the reading above.
                
                For example:
                - If the horoscope says that they may
                want to work on relationships, you could find news stories about
                novel gifts
                - If the horoscope says that they may want to work on their career,
                find news stories about training courses.""".formatted(
                person.name(), person.sign(), horoscope.summary(), storyCount);
        return ai
                .withDefaultLlm()
                .createObject(prompt, RelevantNewsStories.class);
    }

    // The @AchievesGoal annotation indicates that completing this action
    // achieves the given goal, so the agent can be complete
    @AchievesGoal(
            description = "Write an amusing writeup for the target person based on their horoscope and current news stories",
            export = @Export(
                    remote = true,
                    name = "starNewsWriteupJava",
                    startingInputTypes = {StarPerson.class, UserInput.class})
    )
    @Action
    public Writeup writeup(
            StarPerson person,
            RelevantNewsStories relevantNewsStories,
            Horoscope horoscope,
            Ai ai) {
        var llm = LlmOptions
                .withModel(OpenAiModels.GPT_41_MINI)
                // High temperature for creativity
                .withTemperature(0.9);

        var newsItems = relevantNewsStories.getItems().stream()
                .map(item -> "- " + item.getUrl() + ": " + item.getSummary())
                .collect(Collectors.joining("\n"));

        var prompt = """
                Take the following news stories and write up something
                amusing for the target person.
                
                Begin by summarizing their horoscope in a concise, amusing way, then
                talk about the news. End with a surprising signoff.
                
                %s is an astrology believer with the sign %s.
                Their horoscope for today is:
                    <horoscope>%s</horoscope>
                Relevant news stories are:
                %s
                
                Format it as Markdown with links.""".formatted(
                person.name(), person.sign(), horoscope.summary(), newsItems);
        return ai
                .withLlm(llm)
                .createObject(prompt, Writeup.class);
    }
}
Kotlin
@Agent(description = "Find news based on a person's star sign")
class StarNewsFinder(
    // Services such as Horoscope are injected by Spring
    private val horoscopeService: HoroscopeService,
    // Potentially externalized by Spring
    @param:Value("\${star-news-finder.story.count:5}")
    private val storyCount: Int = 5,
) {

    @Action
    fun extractPerson(
        userInput: UserInput,
        ai: Ai
    ): StarPerson =
        // All prompts are typesafe
        ai.withDefaultLlm()
            .createObject("Create a person from this user input, extracting their name and star sign: $userInput")

    // This action doesn't use an LLM
    // Embabel makes it easy to mix LLM use with regular code
    @Action
    fun retrieveHoroscope(starPerson: StarPerson) =
        Horoscope(horoscopeService.dailyHoroscope(starPerson.sign))

    // This action uses tools
    // "toolGroups" specifies tools that are required for this action to run
    @Action(toolGroups = [ToolGroup.WEB])
    fun findNewsStories(
        person: StarPerson,
        horoscope: Horoscope,
        ai: Ai,
    ): RelevantNewsStories =
        ai.withDefaultLlm().createObject(
            """
            ${person.name} is an astrology believer with the sign ${person.sign}.
            Their horoscope for today is:
                <horoscope>${horoscope.summary}</horoscope>
            Given this, use web tools and generate search queries
            to find $storyCount relevant news stories summarize them in a few sentences.
            Include the URL for each story.
            Do not look for another horoscope reading or return results directly about astrology;
            find stories relevant to the reading above.

            For example:
            - If the horoscope says that they may
            want to work on relationships, you could find news stories about
            novel gifts
            - If the horoscope says that they may want to work on their career,
            find news stories about training courses.
        """.trimIndent()
        )

    // The @AchievesGoal annotation indicates that completing this action
    // achieves the given goal, so the agent run will be complete
    @AchievesGoal(
        description = "Write an amusing writeup for the target person based on their horoscope and current news stories",
    )
    @Action
    fun writeup(
        person: StarPerson,
        relevantNewsStories: RelevantNewsStories,
        horoscope: Horoscope,
        ai: Ai,
    ): Writeup =
        ai
            .withLlm(
                LlmOptions
                    .withModel(model)
                    .withTemperature(0.9)
            )
            .createObject(
                """
            Take the following news stories and write up something
            amusing for the target person.

            Begin by summarizing their horoscope in a concise, amusing way, then
            talk about the news. End with a surprising signoff.

            ${person.name} is an astrology believer with the sign ${person.sign}.
            Their horoscope for today is:
                <horoscope>${horoscope.summary}</horoscope>
            Relevant news stories are:
            ${relevantNewsStories.items.joinToString("\n") { "- ${it.url}: ${it.summary}" }}

            Format it as Markdown with links.
        """.trimIndent()
            )

}

The following domain classes ensure type safety:

Java
@JsonClassDescription("Person with astrology details")
@JsonDeserialize(as = StarPerson.class)
public record StarPerson(
        String name,
        @JsonPropertyDescription("Star sign") String sign
) implements Person {

    @JsonCreator
    public StarPerson(
            @JsonProperty("name") String name,
            @JsonProperty("sign") String sign
    ) {
        this.name = name;
        this.sign = sign;
    }

    @Override
    public String getName() {
        return name;
    }
}

public record Horoscope(String summary) {
}

@JsonClassDescription("Writeup relating to a person's horoscope and relevant news")
public record Writeup(String text) implements HasContent {

    @JsonCreator
    public Writeup(@JsonProperty("text") String text) {
        this.text = text;
    }

    @Override
    public String getContent() {
        return text;
    }
}
Kotlin
data class RelevantNewsStories(
    val items: List<NewsStory>
)

data class NewsStory(
    val url: String,

    val summary: String,
)

data class Subject(
    val name: String,
    val sign: String,
)

data class Horoscope(
    val summary: String,
)

data class FunnyWriteup(
    override val text: String,
) : HasContent

It's easy to unit test your agents to ensure that they correctly execute logic and pass the correct prompts and hyperparameters to LLMs. For example:

public class StarNewsFinderTest {

    @Test
    void writeupPromptMustContainKeyData() {
        HoroscopeService horoscopeService = mock(HoroscopeService.class);
        StarNewsFinder starNewsFinder = new StarNewsFinder(horoscopeService, 5);
        var context = new FakeOperationContext();
        context.expectResponse(new com.embabel.example.horoscope.Writeup("Gonna be a good day"));

        NewsStory cockatoos = new NewsStory(
                "https://fake.com.au",
                "Cockatoo behavior",
                "Cockatoos are eating cabbages"
        );

        NewsStory emus = new NewsStory(
                "https://morefake.com.au",
                "Emu movements",
                "Emus are massing"
        );

        StarPerson starPerson = new StarPerson("Lynda", "Scorpio");
        RelevantNewsStories relevantNewsStories = new RelevantNewsStories(Arrays.asList(cockatoos, emus));
        Horoscope horoscope = new Horoscope("This is a good day for you");

        starNewsFinder.writeup(starPerson, relevantNewsStories, horoscope, context);

        var prompt = context.getLlmInvocations().getFirst().getPrompt();
        var toolGroups = context.getLlmInvocations().getFirst().getInteraction().getToolGroups();


        assertTrue(prompt.contains(starPerson.getName()));
        assertTrue(prompt.contains(starPerson.sign()));
        assertTrue(prompt.contains(cockatoos.getSummary()));
        assertTrue(prompt.contains(emus.getSummary()));

        assertTrue(toolGroups.isEmpty(), "The LLM should not have been given any tool groups");
    }
}

Dog Food Policy

We believe that all aspects of software development and business can and should be greatly accelerated through the use of AI agents. The ultimate decision makers remain human, but they can and should be greatly augmented.

This project practices extreme dogfooding.

Our key principles:

  1. We will use AI agents to help every aspect of the project: coding, documentation, community management, producing marketing copy etc. Any human performing a task should ask why it cannot be automated, and strive toward maximum automation.
  2. Developers retain ultimate control. Developers are responsible for guiding agents toward the solution and iterating as necessary. A developer who commits or merges an agent contribution is responsible for ensuring that it meets the project coding standards, which are independent of the use of agents. For example, code must be human-readable.
  3. We will favour open source agents built on the Embabel platform, and contribute improvements. While commercial agents may be more advanced in some areas, we believe that our platform is the best general solution for automation and by dogfooding we will improve it fastest. By open sourcing agents used on our open source projects, we will maximize benefit to the community.
  4. We will prioritize agents that help accelerate our progress. Per the flight safety advice to fit your own mask before helping others, we will prioritize agents that help us accelerate our own progress. This will not only produce useful examples, but increase overall project velocity.

Developers must carefully read all code they commit and improve generated code if possible.

Coding agents are a special case. While the embabel-agent-code submodule offers support for project modification that is useful for project bootstrapping, coding agents are the most mature of commercial agents, and their vendors are heavily subsidising their users, making it economically irrational to insist on our own platform.

Getting Started

  • Get the bits
  • Set up your environment
  • Run the application

Getting the bits

Choose one of the following:

  • Clone the repository via git clone https://github.com/embabel/embabel-agent
  • Create a new Spring Boot project and add the necessary dependencies (see "Using Embabel Agent Framework in Your Project" below)

Environment variables

Environment variables are consistent with common usage, rather than Spring AI. For example, we prefer OPENAI_API_KEY to SPRING_AI_OPENAI_API_KEY.

Required:

  • OPENAI_API_KEY: For the OpenAI API

Optional:

  • ANTHROPIC_API_KEY: For the Anthropic API. Necessary for the coding agent.
  • MINIMAX_API_KEY: For the MiniMax API. Supports MiniMax-M3, MiniMax-M2.7 and MiniMax-M2.7-highspeed models.
  • ZAI_API_KEY: For the Z.ai (Zhipu AI) API. Supports GLM-5.2, GLM-4.7, GLM-4.6, GLM-4.5-Air and GLM-4.7-Flash models.
  • OCI Generative AI uses OCI SDK authentication providers. Add embabel-agent-starter-oci-genai and set embabel.agent.platform.models.ocigenai.compartment-id; OCI config file, instance principal, resource principal, workload identity, session token and simple key authentication are supported.

We strongly recommend providing both an OpenAI and Anthropic key, as some examples require both. And it's important to try to find the best LLM for a given task, rather than automatically choose a familiar provider.

Services

You will need a Docker Desktop version >4.43.2. Be sure to activate the following MCP tools from the catalog:

  • Brave Search
  • Fetch
  • Puppeteer
  • Wikipedia

You can also set up your own MCP tools using Spring AI conventions. See the application-docker-desktop.yml file for an example.

If you're running Ollama locally, include the embabel ollama starter and Embabel will automatically connect to your Ollama endpoint and make all models available.

<dependency>
    <groupId>com.embabel.agent</groupId>
    <artifactId>embabel-agent-starter-ollama</artifactId>
</dependency>

Running

Create your own agent project with

uvx --from git+https://github.com/embabel/project-creator.git project-creator

Example Agents

📚 For examples and tutorials, see the Embabel Agent Examples Repository

# Clone and run examples
git clone https://github.com/embabel/embabel-agent-examples
cd embabel-agent-examples/scripts/kotlin
./shell.sh

Shell Commands

Spring Shell is an easy way to interact with the Embabel agent framework, especially during development.

Type help to see available commands. Use execute or x to run an agent:

execute "Lynda is a Scorpio, find news for her" -p -r

This will look for an agent, choose the star finder agent and run the flow. -p will log prompts -r will log LLM responses. Omit these for less verbose logging.

Options:

  • -p logs prompts
  • -r logs LLM responses

Use the chat command to enter an interactive chat with the agent. It will attempt to run the most appropriate agent for each command.

Spring Shell supports history. Type !! to repeat the last command. This will survive restarts, so is handy when iterating on an agent.

Further examples

Example commands within the shell:

# Perplexity style deep research
# Requires both OpenAI and Anthropic keys and Docker Desktop with the MCP extension (or your own web tools)
execute "research the recent australian federal election. what is the position of the greens party?"

# x is a shortcut for execute
x "fact check the following: holden cars are still made in australia; the koel is a bird native only to australia; fidel castro is justin trudeau's father"

Bringing in additional LLMs

Local models with well-known providers

The Embabel Agent Framework supports local models from:

  • Ollama: Simply add embabel-agent-starter-ollama starter to your pom.xml and your local Ollama endpoint will be queries. All local models will be available.
  • Docker: Add the embabel-agent-starter-dockermodels starter to your pom.xml and your local Docker endpoint will be queried. All local models will be available.
  • LMStudio: This uses the openAI compatible client. Just include LMStudio as a dependency and make sure your LMStudio server is running.

OCI Generative AI

Add embabel-agent-starter-oci-genai to use OCI Generative AI chat and embedding models.

<dependency>
    <groupId>com.embabel.agent</groupId>
    <artifactId>embabel-agent-starter-oci-genai</artifactId>
</dependency>

Configure embabel.agent.platform.models.ocigenai.compartment-id and, if needed, set embabel.agent.platform.models.ocigenai.authentication-type to FILE, INSTANCE_PRINCIPAL, RESOURCE_PRINCIPAL, WORKLOAD_IDENTITY, SESSION_TOKEN or SIMPLE. When the standard OpenAI provider is not on the classpath, the OCI starter supplies OCI defaults for Embabel's default LLM and embedding model:

embabel.models.default-llm=cohere.command-a-03-2025
embabel.models.default-embedding-model=cohere.embed-v4.0

Override those values in application configuration if you want another OCI model. Use OCI model ids such as cohere.command-a-03-2025 or meta.llama-3.3-70b-instruct for Embabel model selection. The Spring bean names registered by the starter are Java-friendly aliases such as cohere_command_a and llama_33_70b. If your application exposes Spring Boot Actuator env or configprops values, keep those endpoints secured and ensure OCI credential fields such as pass-phrase, session-token and private-key are sanitized.

Custom LLMs

You can define an LLM for any provider for which a Spring AI ChatModel is available.

Simply define Spring beans of type Llm. See the OpenAiConfiguration class as an example.

Remember:

  • Provide the knowledge cutoff date if you know it
  • Make the configuration class conditional on any required API key.

Roadmap

This project is in its early stages, but we have big plans. The milestones and issues in this repository are a good reference. Our key goals:

  • Become the natural way to Gen AI-enable Java applications, and especially those built on Spring.
  • Prove the power of the approach. Demonstrate that this approach is the best way to build safe, dependable, Gen AI applications. In particular:
    • Demonstrate the power of extensibility without modification, by adding goals and actions
    • Demonstrate the potential to become the PaaS for natural language
    • Demonstrate the potential of agent federation within the GOAP model
    • Demonstrate budget-aware agents, such as "Research the following topic, spending up to 20c if you are still learning"
    • Integrate with data stores and demonstrate the power of surfacing existing functionality inside an organization
  • Take the model to other platforms: The conceptual framework is not JVM specific. Once established, we intend to create TypeScript and Python projects.

There is a lot to do, and you are awesome. We look forward to your contribution!

Application Design

Domain objects

Applications center around domain objects. These can be instantiated by LLMs or user code, and manipulated by user code.

Use Jackson annotations to help LLMs with descriptions as well as mark fields to ignore. For example:

@JsonClassDescription("Person with astrology details")
data class StarPerson(
    override val name: String,
    @get:JsonPropertyDescription("Star sign")
    val sign: String,
) : Person

See Java Json Schema Generation - Module Jackson for documentation of the library used.

Domain objects can have behaviors that are automatically exposed to LLMs when they are in scope. Simply annotate methods with the Spring AI @Tool annotation.

When exposing @Tool methods on domain objects, be sure that the tool is safe to invoke. Even the best LLMs can get trigger-happy. For example, be careful about methods that can mutate or delete data. This is likely better modeled via an explicit call to a non-tool method on the same domain class, in a code action.

Using Embabel as an MCP server

You can use the Embabel agent platform as an MCP server from a UI like Claude Desktop. The Embabel MCP server is available over SSE.

Configure Claude Desktop as follows in your claude_desktop_config.yml:

{
  "mcpServers": {
    "embabel": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "http://localhost:8080/sse"
      ]
    }
  }
}

See MCP Quickstart for Claude Desktop Users for how to configure Claude Desktop.

The MCP Inspector is a helpful tool for interacting with your Embabel SSE server, manually invoking tools and checking the exposed prompts and resources.

Start the MCP Inspector with:

npx @modelcontextprotocol/inspector

Consuming MCP Servers

The Embabel Agent Framework provides built-in support for consuming Model Context Protocol (MCP) servers, allowing you to extend your applications with powerful AI capabilities through standardized interfaces.

What is MCP?

Model Context Protocol (MCP) is an open protocol that standardizes how applications provide context and extra functionality to large language models. Introduced by Anthropic, MCP has emerged as the de facto standard for connecting AI agents to tools, functioning as a client-server protocol where:

  • Clients (like Embabel Agent) send requests to servers
  • Servers process those requests to deliver necessary context to the AI model

MCP simplifies integration between AI applications and external tools, transforming an "M×N problem" into an "M+N problem" through standardization - similar to what USB did for hardware peripherals.

Configuring MCP in Embabel Agent

To configure MCP servers in your Embabel Agent application, add the following to your application.yml:

spring:
  ai:
    mcp:
      client:
        enabled: true
        name: embabel
        version: 1.0.0
        request-timeout: 30s
        type: SYNC
        stdio:
          connections:
            docker-mcp:
              command: docker
              args:
                - run
                - -i
                - --rm
                - alpine/socat
                - STDIO
                - TCP:host.docker.internal:8811

This configuration sets up an MCP client that connects to a Docker-based MCP server. The connection uses STDIO transport through Docker's socat utility to connect to a TCP endpoint.

Docker Desktop MCP Integration

Docker has embraced MCP with the

(README truncated)

View on GitHub

Recent activity

commits and pull requests

Recent open issues

view all

Discussions

all 111

Releases and announcements

16 total
  1. Embabel Agent 1.0.0v1.0.0Jul 20, 2026

    ## What's Changed * Prepare for 1.0.0-RC1 development by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1734 * Introduce Generic Media and Document support by @igordayen in https://github.com/embabel/embabel-agent/pull/1737 * Improve error message when default llm is not available by @poutsma in https://github.com/embabel/embabel-agent/pull/1736 * Remove references to deprecated features in Asciidoc and KDOC by @igordayen in https://github.com/embabel/embabel-agent/pull/1743 * Netty High Vilnerability Jun-26 by @igordayen in https://github.com/embabel/embabel-agent/pull/1745 * Sonar blockers - missing asserts in tests by @igordayen in https://github.com/embabel/embabel-agent/pull/1748 * update for new DeepSeek model names by @zhangjessey in https://github.com/embabel/embabel-agent/pull/1749 * Remove deprecated methods by @poutsma in https://github.com/embabel/embabel-agent/pull/1750 * refactor(anthropic): extract AnthropicModelFactory into plain embabel… by @jasperblues in https://github.com/embabel/embabel-agent/pull/1752 * Promote Experimental APIs and update docs by @igordayen in https://github.com/embabel/embabel-agent/pull/1753 * fix: remove unreachab

  2. Euroav1.0.0-RC1Jul 13, 2026pre-release

    ## What's Changed * Prepare for 1.0.0-RC1 development by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1734 * Introduce Generic Media and Document support by @igordayen in https://github.com/embabel/embabel-agent/pull/1737 * Improve error message when default llm is not available by @poutsma in https://github.com/embabel/embabel-agent/pull/1736 * Remove references to deprecated features in Asciidoc and KDOC by @igordayen in https://github.com/embabel/embabel-agent/pull/1743 * Netty High Vilnerability Jun-26 by @igordayen in https://github.com/embabel/embabel-agent/pull/1745 * Sonar blockers - missing asserts in tests by @igordayen in https://github.com/embabel/embabel-agent/pull/1748 * update for new DeepSeek model names by @zhangjessey in https://github.com/embabel/embabel-agent/pull/1749 * Remove deprecated methods by @poutsma in https://github.com/embabel/embabel-agent/pull/1750 * refactor(anthropic): extract AnthropicModelFactory into plain embabel… by @jasperblues in https://github.com/embabel/embabel-agent/pull/1752 * Promote Experimental APIs and update docs by @igordayen in https://github.com/embabel/embabel-agent/pull/1753 * fix: remove unreachab

  3. Darwinv0.5.0Jun 21, 2026pre-release

    ## What's Changed * Update version numbers in pom.xml by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1680 * Upgrade Build Deps Parent to 0.1.14-SNAPSHOT by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1681 * Reject @AchievesGoal on void action methods by @poutsma in https://github.com/embabel/embabel-agent/pull/1682 * Don't depend on Spring AI being on classpath to handle tool annotations by @johnsonr in https://github.com/embabel/embabel-agent/pull/1676 * OllamaOptionsConverter now forwards LlmOptions regarding thinking. by @jorander in https://github.com/embabel/embabel-agent/pull/1684 * StreamingJacksonOutputConverter.getFormat() respects disabled thinking by @jorander in https://github.com/embabel/embabel-agent/pull/1687 * Fixes #1298, resolving inconsistency in Lucene search syntax by @johnsonr in https://github.com/embabel/embabel-agent/pull/1653 * Recognize @Nullable annotation when resolving action parameters by @poutsma in https://github.com/embabel/embabel-agent/pull/1686 * Allow unescaped CTRL characters by @deleSerna in https://github.com/embabel/embabel-agent/pull/1688 * #1467 - Removed explicitely setting the ArchUnit versi

  4. Curdimurkav0.4.0May 18, 2026pre-release

    ## What's Changed * Prepare 0.4.0 Iteration by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1559 * #1427 : Remove Spring AI tool loop path option by @azanux in https://github.com/embabel/embabel-agent/pull/1560 * Use RestClient.Builder instead of request factory for model clients by @poutsma in https://github.com/embabel/embabel-agent/pull/1567 * Fix SlidingWindowTransformer to preserve tool call/result message grouping by @igordayen in https://github.com/embabel/embabel-agent/pull/1569 * Fixes #1562 apply platform action-qos properties to DSL and workflow-built actions by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1572 * Bring up the model list and pricing up to date by @simeshev in https://github.com/embabel/embabel-agent/pull/1568 * Point at 0.1.13-SNAPSHOT of embabel-build by @jasperblues in https://github.com/embabel/embabel-agent/pull/1576 * Fix JaCoCo coverage reporting for SonarCloud by @jasperblues in https://github.com/embabel/embabel-agent/pull/1575 * Fix ONNX model download redirect handling in OnnxModelLoader by @jasperblues in https://github.com/embabel/embabel-agent/pull/1578 * Prepare IT tests for automation execution by

  5. Bendigov0.3.5Mar 31, 2026pre-release

    ## What's Changed * Update version numbers in pom.xml by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1422 * Update version to 0.1.12-SNAPSHOT in pom.xml by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1423 * fix(docs): remove unclosed example block in llms/page.adoc by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1424 * Fix Guide Issue 31 - don't call out for vector dimensions if already … by @jasperblues in https://github.com/embabel/embabel-agent/pull/1429 * ToolLoop Callbacks by @igordayen in https://github.com/embabel/embabel-agent/pull/1428 * Use Asyncer for async LLM operations instead of raw CompletableFuture… by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1433 * Fix NPE when LLM API key lacks model access by @jasperblues in https://github.com/embabel/embabel-agent/pull/1435 * Fixes # 1430 by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1437 * Decommision claude-3-7-sonnet-latest by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1443 * Add event triggers feature by @jasperblues in https://github.com/embabel/embabel-agent/pull/1439 * Add build failure notification

Commits per week

last 52 weeks
700Week of 2025-08-10: 51 commitsWeek of 2025-08-17: 52 commitsWeek of 2025-08-24: 62 commitsWeek of 2025-08-31: 70 commitsWeek of 2025-09-07: 68 commitsWeek of 2025-09-14: 51 commitsWeek of 2025-09-21: 35 commitsWeek of 2025-09-28: 24 commitsWeek of 2025-10-05: 25 commitsWeek of 2025-10-12: 17 commitsWeek of 2025-10-19: 32 commitsWeek of 2025-10-26: 30 commitsWeek of 2025-11-02: 21 commitsWeek of 2025-11-09: 25 commitsWeek of 2025-11-16: 59 commitsWeek of 2025-11-23: 42 commitsWeek of 2025-11-30: 38 commitsWeek of 2025-12-07: 38 commitsWeek of 2025-12-14: 51 commitsWeek of 2025-12-21: 36 commitsWeek of 2025-12-28: 24 commitsWeek of 2026-01-04: 64 commitsWeek of 2026-01-11: 30 commitsWeek of 2026-01-18: 48 commitsWeek of 2026-01-25: 57 commitsWeek of 2026-02-01: 35 commitsWeek of 2026-02-08: 53 commitsWeek of 2026-02-15: 26 commitsWeek of 2026-02-22: 15 commitsWeek of 2026-03-01: 17 commitsWeek of 2026-03-08: 17 commitsWeek of 2026-03-15: 22 commitsWeek of 2026-03-22: 22 commitsWeek of 2026-03-29: 16 commitsWeek of 2026-04-05: 18 commitsWeek of 2026-04-12: 17 commitsWeek of 2026-04-19: 6 commitsWeek of 2026-04-26: 20 commitsWeek of 2026-05-03: 10 commitsWeek of 2026-05-10: 8 commitsWeek of 2026-05-17: 11 commitsWeek of 2026-05-24: 22 commitsWeek of 2026-05-31: 26 commitsWeek of 2026-06-07: 9 commitsWeek of 2026-06-14: 13 commitsWeek of 2026-06-21: 6 commitsWeek of 2026-06-28: 7 commitsWeek of 2026-07-05: 18 commitsWeek of 2026-07-12: 16 commitsWeek of 2026-07-19: 13 commitsWeek of 2026-07-26: 12 commitsWeek of 2026-08-02: 13 commitsAug 10, 2025Aug 2, 2026
1.5K commits in the last 52 weeks.

When work happens

weekday and hour
SunMonTueWedThuFriSat036912151821Sun 0:00 — 8 commitsSun 1:00 — 16 commitsSun 2:00 — 8 commitsSun 3:00 — 5 commitsSun 4:00 — 3 commitsSun 5:00 — 1 commitsSun 6:00 — 1 commitsSun 7:00 — 0 commitsSun 8:00 — 8 commitsSun 9:00 — 17 commitsSun 10:00 — 36 commitsSun 11:00 — 30 commitsSun 12:00 — 31 commitsSun 13:00 — 18 commitsSun 14:00 — 21 commitsSun 15:00 — 23 commitsSun 16:00 — 20 commitsSun 17:00 — 17 commitsSun 18:00 — 26 commitsSun 19:00 — 19 commitsSun 20:00 — 17 commitsSun 21:00 — 7 commitsSun 22:00 — 10 commitsSun 23:00 — 15 commitsMon 0:00 — 3 commitsMon 1:00 — 20 commitsMon 2:00 — 8 commitsMon 3:00 — 5 commitsMon 4:00 — 2 commitsMon 5:00 — 1 commitsMon 6:00 — 2 commitsMon 7:00 — 0 commitsMon 8:00 — 13 commitsMon 9:00 — 37 commitsMon 10:00 — 37 commitsMon 11:00 — 32 commitsMon 12:00 — 22 commitsMon 13:00 — 33 commitsMon 14:00 — 28 commitsMon 15:00 — 26 commitsMon 16:00 — 29 commitsMon 17:00 — 32 commitsMon 18:00 — 38 commitsMon 19:00 — 18 commitsMon 20:00 — 26 commitsMon 21:00 — 17 commitsMon 22:00 — 17 commitsMon 23:00 — 16 commitsTue 0:00 — 20 commitsTue 1:00 — 15 commitsTue 2:00 — 9 commitsTue 3:00 — 15 commitsTue 4:00 — 0 commitsTue 5:00 — 3 commitsTue 6:00 — 2 commitsTue 7:00 — 2 commitsTue 8:00 — 3 commitsTue 9:00 — 26 commitsTue 10:00 — 38 commitsTue 11:00 — 21 commitsTue 12:00 — 19 commitsTue 13:00 — 23 commitsTue 14:00 — 20 commitsTue 15:00 — 29 commitsTue 16:00 — 28 commitsTue 17:00 — 16 commitsTue 18:00 — 34 commitsTue 19:00 — 24 commitsTue 20:00 — 23 commitsTue 21:00 — 22 commitsTue 22:00 — 12 commitsTue 23:00 — 13 commitsWed 0:00 — 15 commitsWed 1:00 — 16 commitsWed 2:00 — 8 commitsWed 3:00 — 17 commitsWed 4:00 — 5 commitsWed 5:00 — 2 commitsWed 6:00 — 4 commitsWed 7:00 — 1 commitsWed 8:00 — 5 commitsWed 9:00 — 19 commitsWed 10:00 — 20 commitsWed 11:00 — 25 commitsWed 12:00 — 24 commitsWed 13:00 — 31 commitsWed 14:00 — 21 commitsWed 15:00 — 23 commitsWed 16:00 — 31 commitsWed 17:00 — 28 commitsWed 18:00 — 20 commitsWed 19:00 — 16 commitsWed 20:00 — 14 commitsWed 21:00 — 17 commitsWed 22:00 — 13 commitsWed 23:00 — 12 commitsThu 0:00 — 6 commitsThu 1:00 — 6 commitsThu 2:00 — 6 commitsThu 3:00 — 6 commitsThu 4:00 — 1 commitsThu 5:00 — 1 commitsThu 6:00 — 4 commitsThu 7:00 — 2 commitsThu 8:00 — 6 commitsThu 9:00 — 24 commitsThu 10:00 — 33 commitsThu 11:00 — 17 commitsThu 12:00 — 15 commitsThu 13:00 — 27 commitsThu 14:00 — 17 commitsThu 15:00 — 38 commitsThu 16:00 — 24 commitsThu 17:00 — 24 commitsThu 18:00 — 16 commitsThu 19:00 — 12 commitsThu 20:00 — 6 commitsThu 21:00 — 10 commitsThu 22:00 — 16 commitsThu 23:00 — 5 commitsFri 0:00 — 5 commitsFri 1:00 — 15 commitsFri 2:00 — 18 commitsFri 3:00 — 5 commitsFri 4:00 — 2 commitsFri 5:00 — 1 commitsFri 6:00 — 1 commitsFri 7:00 — 2 commitsFri 8:00 — 12 commitsFri 9:00 — 27 commitsFri 10:00 — 29 commitsFri 11:00 — 25 commitsFri 12:00 — 24 commitsFri 13:00 — 22 commitsFri 14:00 — 23 commitsFri 15:00 — 17 commitsFri 16:00 — 27 commitsFri 17:00 — 24 commitsFri 18:00 — 26 commitsFri 19:00 — 19 commitsFri 20:00 — 20 commitsFri 21:00 — 13 commitsFri 22:00 — 10 commitsFri 23:00 — 5 commitsSat 0:00 — 6 commitsSat 1:00 — 12 commitsSat 2:00 — 5 commitsSat 3:00 — 8 commitsSat 4:00 — 1 commitsSat 5:00 — 4 commitsSat 6:00 — 2 commitsSat 7:00 — 2 commitsSat 8:00 — 7 commitsSat 9:00 — 19 commitsSat 10:00 — 31 commitsSat 11:00 — 29 commitsSat 12:00 — 22 commitsSat 13:00 — 27 commitsSat 14:00 — 20 commitsSat 15:00 — 22 commitsSat 16:00 — 18 commitsSat 17:00 — 25 commitsSat 18:00 — 33 commitsSat 19:00 — 24 commitsSat 20:00 — 7 commitsSat 21:00 — 10 commitsSat 22:00 — 13 commitsSat 23:00 — 9 commits
Commit volume by weekday and hour (UTC). Larger dots mean more commits.
DateListRankStars gained
Aug 7, 2026weekly#9+154
  • openclaw/openclaw

    Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞

    385.5K stars · TypeScript

  • openclaw/openclaw

    Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞

    384.4K stars · TypeScript

  • openclaw/openclaw

    Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞

    384.4K stars · TypeScript

  • openclaw/openclaw

    Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞

    384.4K stars · TypeScript

  • obra/superpowers

    An agentic skills framework & software development methodology that works.

    268.6K stars · Shell

  • affaan-m/ECC

    The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.

    238.5K stars · JavaScript