Included in the box

Let your AI write the agents.

jOpenAgent ships with a skill file that teaches your AI coding assistant the framework: the rules, the strategies, the project constraints and the mistakes people actually make. Drop it in, describe the agent you want in plain English, and get back Java that compiles and follows the conventions.

you, to your assistantplain English
Write me a jOpenAgent agent that reads a support
ticket, classifies it as billing / technical /
account, and looks up the customer's plan from
our CustomerRepository before answering.
TriageAgent.javawhat comes back
@SystemPrompt("You triage incoming support tickets.")
public class TriageAgent extends Agent {

    private final CustomerRepository customers;

    @Doc("Returns the plan name for a customer id.")
    public String planFor(String customerId) {
        return customers.find(customerId).plan();
    }

    @Generative(value = "Classify the ticket and answer it, "
                      + "using self.planFor when the plan matters.",
                strategy = StrategyKind.TOOL_CALLING)
    public Triage triage(String ticket) {
        return generate(ticket);
    }
}

Why a skill, and not just good docs

Your assistant has never seen this framework

Ask any coding assistant to write a Java agent today and you will get one of two things: a LangChain4j AiServices interface, or a Spring AI ChatClient builder chain. Both are perfectly good libraries. Neither is jOpenAgent, and neither compiles against it.

Even when you paste in the README, models get the one mechanic that matters wrong. They write a @Generative method with a real implementation in the body, or they put the prompt in a javadoc comment where Java throws it away at compile time, or they call generate() from a helper method so the stack walk resolves the wrong caller. These are not silly mistakes. They are exactly what you would guess if you were reasoning from every other Java framework you had ever read.

So we wrote the rules down in the format assistants actually load. The skill is about 270 lines. It covers the trampoline rule first, because that is the thing everyone gets wrong on the first try.

The rule the skill leads with

Rule 1the trampoline
@Generative("Classify the ticket.")
protected Category classify(String ticketText) {
    return generate(ticketText);   // interception point
}

A @Generative method has a real body, and that body must end in return generate(...). No proxy, no bytecode generation. The stack walk resolves the immediate caller, so wrapping it behind a helper breaks it.

Statements before the generate(...) call run as ordinary Java, which is where setup and validation go.

What is in the file

Everything an assistant needs, nothing it can infer

The skill is not a copy of the manual. It is the subset a model gets wrong without help, written as rules and tables instead of prose.

The two core rules

The trampoline (return generate(...), argument-to-parameter-name binding, what runs before the call) and structured output (the declared return type is the schema, no registration, bounded retry, GenerationException rather than null).

A strategy decision table

All four strategies with a “use when” column, so the assistant picks TOOL_CALLING for a lookup and CODE_ACT for multi-step computation instead of defaulting to PREDICT for everything.

Tools and visibility

How @Doc turns a method into a described tool, and how @Hidden, @Shown and @NoTrace control what the model sees. Visible by default, which is the opposite of what most assistants assume.

The built-in facilities

context, memory, skills, history and MCP, with the exact call shapes. Including the detail that prompt templating supports two forms only, {self.field} and {doc(self)}, not arbitrary evaluation.

Hard project constraints

Nine of them, flagged as non-negotiable: no lambdas or method references anywhere, no external dependencies, JDK 21, -parameters stays on, no stub methods or TODO placeholders in delivered code.

A symptom-to-cause table

Six failure modes with their real cause, so the assistant can debug its own output instead of guessing. This is the section that saves the most time in practice.

Installation

Thirty seconds, whichever assistant you use

The skill is a single markdown file with YAML frontmatter, sitting in skills/jopenagent/SKILL.md in the repository. Where it goes depends on your tool, but it is a copy either way.

1

Assistants with native skill support

Claude Code and anything else that reads SKILL.md bundles: copy the folder into your skills directory. Project-scoped keeps it with the codebase, which is usually what you want on a team.

2

Assistants with a rules or instructions file

Cursor, Copilot, Windsurf, Continue and friends all read some project file with a different name. Paste the body of SKILL.md into whichever one yours uses, or point at it from there.

whichever appliespaste the body
.cursor/rules/jopenagent.mdc
.github/copilot-instructions.md
AGENTS.md
3

Everything else

Paste it into the chat as context before you ask for code. It is a plain markdown file with no tooling requirements, so this works in a browser tab if that is all you have.

4

Then just ask

Describe the agent in the terms of your domain. The assistant now knows which strategy fits, that tools are ordinary methods with @Doc, and that the method body ends in generate(...).

prompts that work wellexamples
Add a @Generative method to InvoiceAgent that extracts line items
into a record, and retry twice on invalid output.

Convert this batch job into a CODE_ACT agent that reads
self.ledgerEntries() and reports discrepancies.

Review this agent class against the jOpenAgent conventions.

Not only for writing

It reviews as well as it writes

Because the skill contains the constraints and the failure table, it works just as well pointed at code that already exists. Ask your assistant to review an agent class and it will flag the prompt that ended up in a javadoc comment, the lambda that violates the project rule, the @Generative method that forgot its return type, or the tool the model can never call because it is @Hidden.

That turns out to be where most of the value sits. Writing the first version of an agent is quick either way. Finding out why the model keeps ignoring your instruction is not.

A detail we like

Same format, both ends

jOpenAgent has its own skills subsystem: self.skills loads SKILL.md bundles at runtime so your agents can pull in procedures on demand. The file that teaches your assistant to write agents uses the identical format.

So the house style your agent follows in production and the conventions your assistant follows while writing it are the same kind of document. Write one, and you already know how to write the other.

More on the skills subsystem →

Get the skill, then get building

It ships in the repository, under the same Apache 2.0 license as the rest.