embabel/embabel-agentPublic

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

AI summary: An intelligent agent framework for the JVM, bringing high-level composability and testing to LLM applications.

Stars
4.5K
+6 today
Forks
438
Watchers
63
Open issues
62
Open PRs
19
Contributors
~68
Commits
2.9K
Branches
162

KotlinApache-2.0Created Apr 10, 2025Last push 2d agoLatest release v1.5.2+20 stars this week+70 this month

Quick answers

What is embabel-agent?
An intelligent agent framework for the JVM, bringing high-level composability and testing to LLM applications.
What does embabel-agent do?
Embabel is a Java/Kotlin framework for building robust, composable AI agents, conceptually similar to Spring MVC but for agentic workflows. It provides higher-level abstractions over direct LLM calls and basic wrappers like Spring AI, allowing developers to break complex interactions into focused, reusable, and testable actions. The framework embraces the Spring component model while adding workflow management, automatic retries, and comprehensive state management to prevent runaway costs or errors. By targeting the JVM ecosystem, it allows organizations to leverage their existing Java enterprise codebases, services, and infrastructure rather than rebuilding them in Python.
Who is embabel-agent for?
Enterprise Java and Kotlin developers looking to build maintainable, testable, and robust AI agents within the JVM ecosystem.
How do I get started with embabel-agent?
Visit the repository README on GitHub for complete dependency management instructions and starter templates.
How popular is embabel-agent on GitHub?
embabel/embabel-agent has 4,482 stars and 438 forks on GitHub, and gained 20 stars in the last 7 days.
What license does embabel-agent use?
embabel/embabel-agent is released under the Apache-2.0 license.

Star history

since Aug 7, 2026
02K4KAug 2026Aug 2026Sep 2026Oct 2026
4.5K stars as of Oct 2, 2026. Measured daily since Aug 7, 2026; GitHub no longer exposes earlier star timestamps.

Contribution activity

commits per day, last 52 weeks
OctNovDecJanFebMarAprMayJunJulAugSepMonWedFri2025-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: 3 commits2026-08-08: 2 commits2026-08-09: 1 commit2026-08-10: 6 commits2026-08-11: 12 commits2026-08-12: 2 commits2026-08-13: 2 commits2026-08-14: 4 commits2026-08-15: 2 commits2026-08-16: 1 commit2026-08-17: 1 commit2026-08-18: 2 commits2026-08-19: 2 commits2026-08-20: 1 commit2026-08-21: 1 commit2026-08-22: 4 commits2026-08-23: 3 commits2026-08-24: 3 commits2026-08-25: 0 commits2026-08-26: 5 commits2026-08-27: 3 commits2026-08-28: 4 commits2026-08-29: 1 commit2026-08-30: 1 commit2026-08-31: 0 commits2026-09-01: 5 commits2026-09-02: 1 commit2026-09-03: 1 commit2026-09-04: 2 commits2026-09-05: 1 commit2026-09-06: 1 commit2026-09-07: 0 commits2026-09-08: 0 commits2026-09-09: 0 commits2026-09-10: 2 commits2026-09-11: 0 commits2026-09-12: 1 commit2026-09-13: 0 commits2026-09-14: 0 commits2026-09-15: 3 commits2026-09-16: 5 commits2026-09-17: 0 commits2026-09-18: 0 commits2026-09-19: 1 commit2026-09-20: 0 commits2026-09-21: 0 commits2026-09-22: 3 commits2026-09-23: 2 commits2026-09-24: 2 commits2026-09-25: 0 commits2026-09-26: 1 commit2026-09-27: 4 commits2026-09-28: 0 commits2026-09-29: 3 commits2026-09-30: 0 commits2026-10-01: 0 commits2026-10-02: 0 commits2026-10-03: 0 commits
1,207 commits in the last yearLessMore

Signals and awards

derived from tracked data
  • Very active

    1,207 commits in 52 weeks

  • Permissive license

    Apache-2.0

  • Continuous integration

    Automated checks passing

  • Repeat trending

    7 trending appearances

What embabel-agent does

Embabel is a Java/Kotlin framework for building robust, composable AI agents, conceptually similar to Spring MVC but for agentic workflows. It provides higher-level abstractions over direct LLM calls and basic wrappers like Spring AI, allowing developers to break complex interactions into focused, reusable, and testable actions. The framework embraces the Spring component model while adding workflow management, automatic retries, and comprehensive state management to prevent runaway costs or errors. By targeting the JVM ecosystem, it allows organizations to leverage their existing Java enterprise codebases, services, and infrastructure rather than rebuilding them in Python.

Enterprise Java and Kotlin developers looking to build maintainable, testable, and robust AI agents within the JVM ecosystem.

  • Agent Abstractions: Define agents and actions using intuitive Java/Kotlin annotations like @Agent and @Action.
  • Workflow Management: Built-in capabilities to control execution flow, maintain previous state, and retry operations securely.
  • Spring AI Integration: Builds upon Spring AI while offering a higher-level, more expressive API for complex requirements.
  • Action Composability: Break down large LLM interactions into smaller, reusable subflows to minimize cost and reduce errors.
  • Type-Safe Tool Injection: Leverage Spring's dependency injection to seamlessly provide backend services directly to agent actions.

Where teams use it

Enterprise AI Orchestration

Building complex, stateful LLM applications that seamlessly integrate with existing Java enterprise services and databases.

Test-Driven Agent Development

Facilitating unit and integration testing of LLM logic by decoupling the raw API calls from business workflows.

Cost-Optimized Subflows

Routing simple, deterministic tasks to smaller, cheaper LLMs while preserving larger models for complex reasoning within the same application.

Robust Action Execution

Applying declarative guardrails and retry policies to prevent flaky AI actions from crashing mission-critical enterprise systems.

Getting started: Visit the repository README on GitHub for complete dependency management instructions and starter templates.

README

main branch

Docs Maven Central 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.

Remote Streamable HTTP MCP Connection

Embabel applications can also conn

(README truncated)

View on GitHub

Recent activity

commits and pull requests

Releases and announcements

19 total
  1. Embabel Agent 1.5.2v1.5.2Sep 16, 2026

    ## What's Changed * Boot 4.1.1 by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1983 * Fix/llm retry policy and rate limit detection by @azanux in https://github.com/embabel/embabel-agent/pull/1982 * Remove httpcomponents and bouncycastle BOM(s) by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1984 * fix: avoid search filter extension shadowing by @arnabnandy7 in https://github.com/embabel/embabel-agent/pull/1973 * refactor: remove no-op entity filtering by @arnabnandy7 in https://github.com/embabel/embabel-agent/pull/1972 * Configure exit policy of AgentValidationManager using a property by @deleSerna in https://github.com/embabel/embabel-agent/pull/1801 * Move OCI BOM to embabel-build by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1986 * Configure nested Jinjava interpretation by @arnabnandy7 in https://github.com/embabel/embabel-agent/pull/1978 * feat: improve Java native structured output API by @arnabnandy7 in https://github.com/embabel/embabel-agent/pull/1980 * Improve shell command message when agent is empty by @deleSerna in https://github.com/embabel/embabel-agent/pull/1987 * Add agent process snapshot/restore

  2. Embabel Agent 1.5.1v1.5.1Aug 24, 2026

    ## What's Changed * Update POM(s) for Next Dev Cycle by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1922 * Fix Bedrock chat options conversion by @arnabnandy7 in https://github.com/embabel/embabel-agent/pull/1924 * Resolve LLM roles through an SPI so a role is not tied to one provider by @jasperblues in https://github.com/embabel/embabel-agent/pull/1894 * Update POM(s) version to 1.5.1 Release by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1926 * RAG enhancement: Add `SectionReader` to navigate document sections by name by @johnsonr in https://github.com/embabel/embabel-agent/pull/1928 * Add embedding-driven skills by @johnsonr in https://github.com/embabel/embabel-agent/pull/1934 * Enhance streaming test for Object as String by @igordayen in https://github.com/embabel/embabel-agent/pull/1932 * Document a remote Streamable HTTP MCP connection by @georgeatparallel in https://github.com/embabel/embabel-agent/pull/1865 * feat: add Atlas Cloud BYOK support by @binyangzhu000-sudo in https://github.com/embabel/embabel-agent/pull/1908 * Restore the AgentProcess a thread already held, rather than clearing it by @jasperblues in https://github.co

  3. Embabel Agent 1.5.0v1.5.0Aug 11, 2026

    ## What's Changed * Sync 2.0.0-061326 with 2.0.0: port native structured output to SB4 / Spring AI 2 / Jackson 3 by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1719 * Spring AI 2.0.0 GA Migration by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1722 * Synchronize with 1.0 06222026 by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1738 * 1.5.0 by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1765 * 1.5.0 synchup 1.0.x by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1807 * 2.0.0 by @alexheifetz in https://github.com/embabel/embabel-agent/pull/1697 * Include authors page on hub by @jasperblues in https://github.com/embabel/embabel-agent/pull/1820 * Netty Upgrade to 4.2.15 by @igordayen in https://github.com/embabel/embabel-agent/pull/1824 * test: add unit coverage for uncovered utilities by @tuannx in https://github.com/embabel/embabel-agent/pull/1823 * Prove multi-level RunSubagent composition by @Stuckya in https://github.com/embabel/embabel-agent/pull/1825 * Fix model binding broken by Spring AI 2.0 options merge removal by @igordayen in https://github.com/embabel/embabel-agent/pull/1818 *

  4. 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

  5. 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

Code frequency

additions and deletions
+30.9K-30.9KWeek of 2025-09-21: +2,285 linesWeek of 2025-09-21: -1,560 linesWeek of 2025-09-28: +787 linesWeek of 2025-09-28: -3,414 linesWeek of 2025-10-05: +6,591 linesWeek of 2025-10-05: -3,080 linesWeek of 2025-10-12: +2,455 linesWeek of 2025-10-12: -1,109 linesWeek of 2025-10-19: +6,559 linesWeek of 2025-10-19: -3,811 linesWeek of 2025-10-26: +3,209 linesWeek of 2025-10-26: -2,183 linesWeek of 2025-11-02: +1,371 linesWeek of 2025-11-02: -823 linesWeek of 2025-11-09: +3,865 linesWeek of 2025-11-09: -1,891 linesWeek of 2025-11-16: +26,252 linesWeek of 2025-11-16: -19,804 linesWeek of 2025-11-23: +11,086 linesWeek of 2025-11-23: -6,138 linesWeek of 2025-11-30: +8,925 linesWeek of 2025-11-30: -2,053 linesWeek of 2025-12-07: +9,558 linesWeek of 2025-12-07: -4,173 linesWeek of 2025-12-14: +17,891 linesWeek of 2025-12-14: -4,722 linesWeek of 2025-12-21: +7,909 linesWeek of 2025-12-21: -1,183 linesWeek of 2025-12-28: +5,971 linesWeek of 2025-12-28: -3,374 linesWeek of 2026-01-04: +17,970 linesWeek of 2026-01-04: -4,977 linesWeek of 2026-01-11: +16,917 linesWeek of 2026-01-11: -4,885 linesWeek of 2026-01-18: +15,959 linesWeek of 2026-01-18: -2,783 linesWeek of 2026-01-25: +17,415 linesWeek of 2026-01-25: -16,045 linesWeek of 2026-02-01: +16,262 linesWeek of 2026-02-01: -7,415 linesWeek of 2026-02-08: +30,862 linesWeek of 2026-02-08: -5,613 linesWeek of 2026-02-15: +4,494 linesWeek of 2026-02-15: -772 linesWeek of 2026-02-22: +3,094 linesWeek of 2026-02-22: -1,027 linesWeek of 2026-03-01: +2,875 linesWeek of 2026-03-01: -250 linesWeek of 2026-03-08: +6,304 linesWeek of 2026-03-08: -2,338 linesWeek of 2026-03-15: +5,762 linesWeek of 2026-03-15: -869 linesWeek of 2026-03-22: +12,222 linesWeek of 2026-03-22: -7,157 linesWeek of 2026-03-29: +4,595 linesWeek of 2026-03-29: -1,070 linesWeek of 2026-04-05: +3,734 linesWeek of 2026-04-05: -1,181 linesWeek of 2026-04-12: +10,689 linesWeek of 2026-04-12: -391 linesWeek of 2026-04-19: +2,090 linesWeek of 2026-04-19: -464 linesWeek of 2026-04-26: +7,669 linesWeek of 2026-04-26: -810 linesWeek of 2026-05-03: +5,118 linesWeek of 2026-05-03: -90 linesWeek of 2026-05-10: +4,504 linesWeek of 2026-05-10: -71 linesWeek of 2026-05-17: +2,180 linesWeek of 2026-05-17: -965 linesWeek of 2026-05-24: +2,310 linesWeek of 2026-05-24: -2,902 linesWeek of 2026-05-31: +15,749 linesWeek of 2026-05-31: -284 linesWeek of 2026-06-07: +3,526 linesWeek of 2026-06-07: -269 linesWeek of 2026-06-14: +11,334 linesWeek of 2026-06-14: -8,074 linesWeek of 2026-06-21: +1,577 linesWeek of 2026-06-21: -399 linesWeek of 2026-06-28: +3,244 linesWeek of 2026-06-28: -3,731 linesWeek of 2026-07-05: +5,508 linesWeek of 2026-07-05: -348 linesWeek of 2026-07-12: +2,302 linesWeek of 2026-07-12: -533 linesWeek of 2026-07-19: +2,225 linesWeek of 2026-07-19: -359 linesWeek of 2026-07-26: +2,746 linesWeek of 2026-07-26: -240 linesWeek of 2026-08-02: +6,255 linesWeek of 2026-08-02: -1,264 linesWeek of 2026-08-09: +11,879 linesWeek of 2026-08-09: -788 linesWeek of 2026-08-16: +4,977 linesWeek of 2026-08-16: -984 linesWeek of 2026-08-23: +2,618 linesWeek of 2026-08-23: -857 linesWeek of 2026-08-30: +7,215 linesWeek of 2026-08-30: -125 linesWeek of 2026-09-06: +4,149 linesWeek of 2026-09-06: -589 linesWeek of 2026-09-13: +1,173 linesWeek of 2026-09-13: -365 linesSep 21, 2025Sep 13, 2026
+394.2K lines added, -140.6K removed over the last year.

Commits per week

last 52 weeks
640Week 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: 16 commitsWeek of 2026-08-09: 29 commitsWeek of 2026-08-16: 12 commitsWeek of 2026-08-23: 19 commitsWeek of 2026-08-30: 11 commitsWeek of 2026-09-06: 4 commitsWeek of 2026-09-13: 9 commitsWeek of 2026-09-20: 8 commitsWeek of 2026-09-27: 7 commitsOct 5, 2025Sep 27, 2026
1.2K commits in the last 52 weeks.

When work happens

weekday and hour
SunMonTueWedThuFriSat036912151821Sun 0:00 — 8 commitsSun 1:00 — 16 commitsSun 2:00 — 9 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 — 19 commitsSun 10:00 — 36 commitsSun 11:00 — 30 commitsSun 12:00 — 31 commitsSun 13:00 — 18 commitsSun 14:00 — 21 commitsSun 15:00 — 24 commitsSun 16:00 — 21 commitsSun 17:00 — 17 commitsSun 18:00 — 26 commitsSun 19:00 — 19 commitsSun 20:00 — 17 commitsSun 21:00 — 10 commitsSun 22:00 — 11 commitsSun 23:00 — 17 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 — 35 commitsMon 14:00 — 32 commitsMon 15:00 — 27 commitsMon 16:00 — 30 commitsMon 17:00 — 32 commitsMon 18:00 — 38 commitsMon 19:00 — 18 commitsMon 20:00 — 26 commitsMon 21:00 — 17 commitsMon 22:00 — 19 commitsMon 23:00 — 16 commitsTue 0:00 — 21 commitsTue 1:00 — 15 commitsTue 2:00 — 9 commitsTue 3:00 — 15 commitsTue 4:00 — 2 commitsTue 5:00 — 3 commitsTue 6:00 — 3 commitsTue 7:00 — 2 commitsTue 8:00 — 4 commitsTue 9:00 — 26 commitsTue 10:00 — 38 commitsTue 11:00 — 22 commitsTue 12:00 — 19 commitsTue 13:00 — 25 commitsTue 14:00 — 21 commitsTue 15:00 — 30 commitsTue 16:00 — 37 commitsTue 17:00 — 16 commitsTue 18:00 — 34 commitsTue 19:00 — 25 commitsTue 20:00 — 24 commitsTue 21:00 — 24 commitsTue 22:00 — 15 commitsTue 23:00 — 15 commitsWed 0:00 — 15 commitsWed 1:00 — 18 commitsWed 2:00 — 11 commitsWed 3:00 — 18 commitsWed 4:00 — 5 commitsWed 5:00 — 4 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 — 32 commitsWed 14:00 — 21 commitsWed 15:00 — 24 commitsWed 16:00 — 31 commitsWed 17:00 — 28 commitsWed 18:00 — 20 commitsWed 19:00 — 16 commitsWed 20:00 — 15 commitsWed 21:00 — 22 commitsWed 22:00 — 13 commitsWed 23:00 — 13 commitsThu 0:00 — 6 commitsThu 1:00 — 6 commitsThu 2:00 — 7 commitsThu 3:00 — 7 commitsThu 4:00 — 1 commitsThu 5:00 — 2 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 — 16 commitsThu 13:00 — 29 commitsThu 14:00 — 17 commitsThu 15:00 — 38 commitsThu 16:00 — 26 commitsThu 17:00 — 25 commitsThu 18:00 — 16 commitsThu 19:00 — 12 commitsThu 20:00 — 6 commitsThu 21:00 — 12 commitsThu 22:00 — 16 commitsThu 23:00 — 5 commitsFri 0:00 — 6 commitsFri 1:00 — 15 commitsFri 2:00 — 18 commitsFri 3:00 — 7 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 — 30 commitsFri 11:00 — 25 commitsFri 12:00 — 24 commitsFri 13:00 — 23 commitsFri 14:00 — 24 commitsFri 15:00 — 18 commitsFri 16:00 — 27 commitsFri 17:00 — 24 commitsFri 18:00 — 27 commitsFri 19:00 — 21 commitsFri 20:00 — 20 commitsFri 21:00 — 13 commitsFri 22:00 — 10 commitsFri 23:00 — 7 commitsSat 0:00 — 7 commitsSat 1:00 — 12 commitsSat 2:00 — 5 commitsSat 3:00 — 8 commitsSat 4:00 — 2 commitsSat 5:00 — 6 commitsSat 6:00 — 3 commitsSat 7:00 — 2 commitsSat 8:00 — 7 commitsSat 9:00 — 20 commitsSat 10:00 — 31 commitsSat 11:00 — 30 commitsSat 12:00 — 22 commitsSat 13:00 — 27 commitsSat 14:00 — 20 commitsSat 15:00 — 22 commitsSat 16:00 — 20 commitsSat 17:00 — 25 commitsSat 18:00 — 33 commitsSat 19:00 — 26 commitsSat 20:00 — 9 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 14, 2026daily#13+40
Aug 13, 2026daily#13+40
Aug 11, 2026weekly#12+195
Aug 10, 2026weekly#12+195
Aug 9, 2026weekly#12+188
Aug 8, 2026weekly#10+176
Aug 7, 2026weekly#9+154
  • openclaw/openclaw

    The AI that really does things. Any OS. Any Platform. The lobster way. 🦞

    391.3K stars · TypeScript

  • obra/superpowers

    An agentic skills framework & software development methodology that works.

    295.2K 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.

    272.8K stars · JavaScript

  • NousResearch/hermes-agent

    The agent that grows with you

    251.2K stars · Python

  • n8n-io/n8n

    Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.

    206.7K stars · TypeScript

  • firecrawl/firecrawl

    Supercharge your AI agents with data from the web and beyond. Building the library for superintelligence. 🔥

    188.6K stars · TypeScript