Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: Bug report
about: Report a reproducible bug in af4j
about: Report a reproducible bug in AF4J
title: "[Bug]: "
labels: bug
assignees: ""
Expand All @@ -12,7 +12,7 @@ Describe the bug clearly and concisely.

## Version

- af4j version: <!-- e.g. v1.0.0 -->
- AF4J version: <!-- e.g. v1.0.0 -->
- Java version: <!-- Java 17+ -->
- Maven version:
- Spring Boot version: <!-- Spring Boot 3.x -->
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ assignees: ""

Why is this feature needed?

What problem does it solve for users of af4j?
What problem does it solve for users of AF4J?

## Proposal

Expand Down
2 changes: 1 addition & 1 deletion .github/releases/v0.10.0.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## OpenHands

v0.10.0 adds `agentflow4j-openhands`: a graph node that delegates a coding task to [OpenHands](https://docs.openhands.dev) and reports back like any other agent. af4j does not reimplement the coding agent, it governs it, so the coding run gets the approval gate, the budget, the checkpoint and the audit trail of every other node.
v0.10.0 adds `agentflow4j-openhands`: a graph node that delegates a coding task to [OpenHands](https://docs.openhands.dev) and reports back like any other agent. AF4J does not reimplement the coding agent, it governs it, so the coding run gets the approval gate, the budget, the checkpoint and the audit trail of every other node.

This release is additive: nothing to migrate.

Expand Down
4 changes: 2 additions & 2 deletions .github/releases/v1.0.0.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
## 1.0

af4j 1.0 is the first release with a stable API. It is the runtime the last four releases were building towards: a graph engine for multi-agent workflows on the JVM where governance is part of execution, not something bolted on top.
AF4J 1.0 is the first release with a stable API. It is the runtime the last four releases were building towards: a graph engine for multi-agent workflows on the JVM where governance is part of execution, not something bolted on top.

Coming from 0.10.0, nothing changes: this release freezes the API rather than reshaping it.

### What af4j gives you
### What AF4J gives you
- **Governed execution.** `ToolPolicy` on every tool call, `StatePolicy` on every state write, `ApprovalGate` before any node, `BudgetPolicy` capping a run, a node or a call. The same rules hold whether you `invoke` or `invokeStream`.
- **Durable runs.** Checkpoints in memory, JDBC or Redis; `resume(runId, ResumeOptions)` continues a paused or crashed run, and a rerun after a rejected approval skips the nodes that already ran instead of repeating their side effects.
- **Parallel branches.** Independent branches run concurrently with bounded concurrency, state merges deterministically, and an approval pauses only the branch it gates.
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# af4j
# AF4J

**Build AI agents you can trust in production.**

af4j is a framework and runtime for governed, stateful multi-agent systems on the JVM.
AF4J is a framework and runtime for governed, stateful multi-agent systems on the JVM.

Human approvals · Checkpoints · Budget controls · Tool policies · Durable execution

---

## Why af4j?
## Why AF4J?

- Build multi-agent workflows with explicit orchestration
- Persist execution across failures and restarts
Expand All @@ -19,7 +19,7 @@ Human approvals · Checkpoints · Budget controls · Tool policies · Durable ex
---

<p align="center">
<img width="1536" height="768" alt="af4j: Build · Govern · Run" src="docs/images/hero.jpg" />
<img width="1536" height="768" alt="AF4J: Build · Govern · Run" src="docs/images/hero.jpg" />
</p>

[![build](https://github.com/datallmhub/agentflow4j/actions/workflows/build.yml/badge.svg)](https://github.com/datallmhub/agentflow4j/actions)
Expand Down Expand Up @@ -77,7 +77,7 @@ See [all samples](docs/samples.md) to explore other demos.

## Core capabilities

| Capability | What it does | af4j |
| Capability | What it does | AF4J |
|---|---|---|
| **Multi-agent orchestration** | Build agent teams with routing and fan-out | `AgentGraph`, `CoordinatorAgent`, `ParallelAgent` |
| **Governance** | Control what agents can call, change, or spend | `ToolPolicy`, `StatePolicy`, `BudgetPolicy`, `ApprovalGate` |
Expand Down Expand Up @@ -122,7 +122,7 @@ See [Getting started](docs/getting-started.md) for Maven/Gradle setup and module
- [Samples](docs/samples.md): runnable examples shipped with the repo
- Migration guides: [0.7 to 0.8](docs/migration-0.8.md), [0.8 to 0.9](docs/migration-0.9.md)

**Cookbook:** [af4j Cookbook](https://github.com/datallmhub/agentflow4j-cookbook): eleven standalone, copy-paste recipes (RAG agent, ticket triage, web research, Slack bot, batch processing, cost-aware routing, governed MCP agent, self-correcting writer, LLM as a judge, parallel research squad, governed OpenHands workflow), each a self-contained Maven module that runs locally against Ollama.
**Cookbook:** [AF4J Cookbook](https://github.com/datallmhub/agentflow4j-cookbook): eleven standalone, copy-paste recipes (RAG agent, ticket triage, web research, Slack bot, batch processing, cost-aware routing, governed MCP agent, self-correcting writer, LLM as a judge, parallel research squad, governed OpenHands workflow), each a self-contained Maven module that runs locally against Ollama.

**Tutorial:** [Stop your AI agent from burning $1000 overnight](docs/tutorials/stop-your-agent-burning-money.md): governed execution end to end.

Expand Down
8 changes: 4 additions & 4 deletions docs/concepts.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
description: "af4j core concepts: agents, teams, rules and execution — how the four building blocks map to the Java API."
description: "AF4J core concepts: agents, teams, rules and execution — how the four building blocks map to the Java API."
---

# Core concepts

af4j is built around four ideas. Understanding them is enough to read any recipe or tutorial in the docs.
AF4J is built around four ideas. Understanding them is enough to read any recipe or tutorial in the docs.

---

Expand Down Expand Up @@ -33,7 +33,7 @@ ExecutorAgent analyst = ExecutorAgent.builder()

## Teams

A **team** is a group of agents that collaborate on a task. af4j provides two ways to organise them.
A **team** is a group of agents that collaborate on a task. AF4J provides two ways to organise them.

**Squad API** — dynamic routing, minimal setup. A `CoordinatorAgent` receives the task and decides which `ExecutorAgent` handles it:

Expand Down Expand Up @@ -86,7 +86,7 @@ See [Tool policy](tool-policy.md), [State policy](state-policy.md), [Budget poli

## Execution

**Execution** is how af4j makes runs reliable. Three mechanisms work together:
**Execution** is how AF4J makes runs reliable. Three mechanisms work together:

**Retry** — failed nodes are retried with backoff. The `FailureClassifier` distinguishes transient errors from permanent failures and over-budget conditions, so retries don't burn money:

Expand Down
6 changes: 3 additions & 3 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: "Get started with af4j: add the dependency to your Spring app, write your first agent, then compose a multi-agent graph. Java 17+, Spring Boot 3.x, Spring AI."
description: "Get started with AF4J: add the dependency to your Spring app, write your first agent, then compose a multi-agent graph. Java 17+, Spring Boot 3.x, Spring AI."
---

# Getting started
Expand All @@ -12,11 +12,11 @@ This page takes you from an empty Spring project to a running multi-agent graph.

- **Java 17+**
- **Spring Boot 3.x** (the project is built and tested on 3.5.x)
- **Spring AI 1.0+** — af4j builds on Spring AI's `ChatClient` and provider starters
- **Spring AI 1.0+** — AF4J builds on Spring AI's `ChatClient` and provider starters

## 1. Add the dependency

af4j is distributed via [JitPack](https://jitpack.io/#datallmhub/agentflow4j). Add the repository and the starter.
AF4J is distributed via [JitPack](https://jitpack.io/#datallmhub/agentflow4j). Add the repository and the starter.

=== "Maven"

Expand Down
12 changes: 6 additions & 6 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
description: "af4j is a framework and runtime for governed, stateful multi-agent systems on the JVM. Human approvals, checkpoints, budget controls, tool policies and durable execution built for Spring."
description: "AF4J is a framework and runtime for governed, stateful multi-agent systems on the JVM. Human approvals, checkpoints, budget controls, tool policies and durable execution built for Spring."
---

# af4j
# AF4J

**Build AI agents you can trust in production.**

af4j is a framework and runtime for governed, stateful multi-agent systems on the JVM.
AF4J is a framework and runtime for governed, stateful multi-agent systems on the JVM.

Human approvals · Checkpoints · Budget controls · Tool policies · Durable execution

Expand All @@ -16,7 +16,7 @@ Human approvals · Checkpoints · Budget controls · Tool policies · Durable ex

---

## Why af4j?
## Why AF4J?

- Build multi-agent workflows with explicit orchestration
- Persist execution across failures and restarts
Expand All @@ -28,7 +28,7 @@ Human approvals · Checkpoints · Budget controls · Tool policies · Durable ex

## Core capabilities

| Capability | What it does | af4j |
| Capability | What it does | AF4J |
|---|---|---|
| **Multi-agent orchestration** | Build agent teams with routing and fan-out | `AgentGraph`, `CoordinatorAgent`, `ParallelAgent` |
| **Governance** | Control what agents can call, change, or spend | `ToolPolicy`, `StatePolicy`, `BudgetPolicy`, `ApprovalGate` |
Expand Down Expand Up @@ -63,4 +63,4 @@ Runs `SupportTriageDemo`: a governed multi-agent workflow with `ToolPolicy` and
---

!!! note "Scope"
af4j is an independent open-source project. It is **not** an official Spring project.
AF4J is an independent open-source project. It is **not** an official Spring project.
10 changes: 5 additions & 5 deletions docs/llm-providers.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
---
description: "Swap LLM provider in af4j with two lines of config: Mistral, OpenAI (GPT), Anthropic Claude, Google Vertex Gemini or a local Ollama. Spring AI handles the auto-configuration; agent code stays unchanged."
description: "Swap LLM provider in AF4J with two lines of config: Mistral, OpenAI (GPT), Anthropic Claude, Google Vertex Gemini or a local Ollama. Spring AI handles the auto-configuration; agent code stays unchanged."
---

# LLM providers — swap freely

af4j builds on top of Spring AI. Anything Spring AI auto-configures as a `ChatModel` works as the brain of an `ExecutorAgent` — Mistral, OpenAI, Anthropic Claude, Google Gemini, a local Ollama, your own. Switching is just **two changes**: the starter dependency, and the API key property.
AF4J builds on top of Spring AI. Anything Spring AI auto-configures as a `ChatModel` works as the brain of an `ExecutorAgent` — Mistral, OpenAI, Anthropic Claude, Google Gemini, a local Ollama, your own. Switching is just **two changes**: the starter dependency, and the API key property.

The playground's `llm` bean is provider-agnostic. It receives whatever `ChatModel` Spring AI built; you decide which one.

## Getting an API key

Every paid provider follows the same flow: sign in to their console, create a key, export it as an environment variable. af4j **never reads the key from a file** — it stays in your shell, out of the repo.
Every paid provider follows the same flow: sign in to their console, create a key, export it as an environment variable. AF4J **never reads the key from a file** — it stays in your shell, out of the repo.

| Provider | Console URL | Environment variable |
|---|---|---|
Expand Down Expand Up @@ -148,7 +148,7 @@ Run `ollama serve` locally and `ollama pull llama3.1` first. No key, no rate lim

## Nothing else changes

Once the `ChatModel` bean is in the context, every part of af4j keeps working unchanged:
Once the `ChatModel` bean is in the context, every part of AF4J keeps working unchanged:

- `ExecutorAgent.builder().chatClient(ChatClient.builder(chatModel).build())` — same code, any provider
- `CoordinatorAgent` routing via `RoutingStrategy.llmDriven(chatClient)` — same code
Expand All @@ -159,4 +159,4 @@ This is the point of building on Spring AI: the provider is a swap, not a rewrit

## Multi-provider in one app

You can mix providers in the same graph — e.g., a cheap model for triage, a strong model for synthesis. Inject two distinct `ChatModel` beans (use Spring's `@Qualifier`) and pass each to the relevant `ExecutorAgent`. Spring AI's docs cover the multi-bean setup; from af4j's perspective each agent simply takes a `ChatClient`.
You can mix providers in the same graph — e.g., a cheap model for triage, a strong model for synthesis. Inject two distinct `ChatModel` beans (use Spring's `@Qualifier`) and pass each to the relevant `ExecutorAgent`. Spring AI's docs cover the multi-bean setup; from AF4J's perspective each agent simply takes a `ChatClient`.
6 changes: 3 additions & 3 deletions docs/llms.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# af4j
# AF4J

> af4j is a Java/Spring open-source runtime for stateful, multi-agent LLM workflows. It sits on top of Spring AI and provides graph-based execution, durable runs (JDBC/Redis checkpoints, crash-resume), and four built-in governance gates — tool access, state writes, cost budget, and human approval. Java-first, Spring-native, code-first DSL, no sidecar and no YAML policy files.
> AF4J is a Java/Spring open-source runtime for stateful, multi-agent LLM workflows. It sits on top of Spring AI and provides graph-based execution, durable runs (JDBC/Redis checkpoints, crash-resume), and four built-in governance gates — tool access, state writes, cost budget, and human approval. Java-first, Spring-native, code-first DSL, no sidecar and no YAML policy files.

The project's value proposition: where most agent frameworks treat agents as fully trusted, af4j treats them as **untrusted by default** and lets you compose governance into the runtime alongside orchestration, in idiomatic Java.
The project's value proposition: where most agent frameworks treat agents as fully trusted, AF4J treats them as **untrusted by default** and lets you compose governance into the runtime alongside orchestration, in idiomatic Java.

Audience: Java/Spring developers building production multi-agent systems that need observability, durable execution, and runtime governance.

Expand Down
4 changes: 2 additions & 2 deletions docs/mcp.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MCP tools

af4j does not implement MCP. It governs the tools that Spring AI's MCP client already exposes: hand them to an `ExecutorAgent` and they go through the same `ToolPolicy`, tool-call audit and lifecycle hooks as any other tool.
AF4J does not implement MCP. It governs the tools that Spring AI's MCP client already exposes: hand them to an `ExecutorAgent` and they go through the same `ToolPolicy`, tool-call audit and lifecycle hooks as any other tool.

## Wiring

Expand All @@ -27,7 +27,7 @@ Spring AI prefixes each MCP tool with the client name: tool `refund_order` serve
## Do not register MCP tools on the ChatClient

!!! warning
Tools registered on the `ChatClient` itself, for example with `ChatClient.builder(model).defaultToolCallbacks(mcpTools)`, are invisible to af4j: they bypass the `ToolPolicy`, are not recorded as `ToolCallRecord`s and do not reach `onToolCall`. Register them on the `ExecutorAgent` with `toolProviders(...)` instead.
Tools registered on the `ChatClient` itself, for example with `ChatClient.builder(model).defaultToolCallbacks(mcpTools)`, are invisible to AF4J: they bypass the `ToolPolicy`, are not recorded as `ToolCallRecord`s and do not reach `onToolCall`. Register them on the `ExecutorAgent` with `toolProviders(...)` instead.

## What you get

Expand Down
2 changes: 1 addition & 1 deletion docs/openhands.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# OpenHands

`OpenHandsAgent` delegates a coding task to [OpenHands](https://docs.openhands.dev) from a graph node. af4j does not reimplement the agent: it governs it, so the coding run gets an approval gate, a budget, a checkpoint and an audit trail like any other node.
`OpenHandsAgent` delegates a coding task to [OpenHands](https://docs.openhands.dev) from a graph node. AF4J does not reimplement the agent: it governs it, so the coding run gets an approval gate, a budget, a checkpoint and an audit trail like any other node.

```xml
<dependency>
Expand Down
2 changes: 1 addition & 1 deletion docs/recipes/durable-runs.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

The most common question about agent runtimes: *"what happens if a step fails in the middle?"*

af4j checkpoints after **every node**. If a step fails, the process crashes, or you deliberately pause for a human, you `resume(runId)` and execution continues **from the node that didn't finish** — the steps that already succeeded do not re-run (and their LLM calls aren't paid for again).
AF4J checkpoints after **every node**. If a step fails, the process crashes, or you deliberately pause for a human, you `resume(runId)` and execution continues **from the node that didn't finish** — the steps that already succeeded do not re-run (and their LLM calls aren't paid for again).

## The store

Expand Down
2 changes: 1 addition & 1 deletion docs/resilience.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: "Production error handling for Java multi-agent workflows in af4j: retry with backoff, circuit breakers per node, budget policy capping cost per run/node/call, and human-in-the-loop checkpoints."
description: "Production error handling for Java multi-agent workflows in AF4J: retry with backoff, circuit breakers per node, budget policy capping cost per run/node/call, and human-in-the-loop checkpoints."
---

# Resilience & Error Handling
Expand Down
2 changes: 1 addition & 1 deletion docs/run-log.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: "Structured, replayable execution timeline per run for af4j — node enter/exit timings, transitions, retries, and governance events (BUDGET_EXCEEDED, STATE_DENIED, APPROVAL_REQUIRED)."
description: "Structured, replayable execution timeline per run for AF4J — node enter/exit timings, transitions, retries, and governance events (BUDGET_EXCEEDED, STATE_DENIED, APPROVAL_REQUIRED)."
---

# Run log — structured execution timeline
Expand Down
2 changes: 1 addition & 1 deletion docs/state-policy.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: "Guard writes to specific StateKey<T> across an af4j multi-agent workflow. Prevent an LLM from flipping sensitive flags like payment.confirmed on its own — denials surface through the graph's error policy."
description: "Guard writes to specific StateKey<T> across an AF4J multi-agent workflow. Prevent an LLM from flipping sensitive flags like payment.confirmed on its own — denials surface through the graph's error policy."
---

# State Policy
Expand Down
2 changes: 1 addition & 1 deletion docs/state.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Typed state

Most agent frameworks store shared state as `Map<String, Object>` — fast to write, painful to debug. af4j uses `StateKey<T>` for compile-time typed access.
Most agent frameworks store shared state as `Map<String, Object>` — fast to write, painful to debug. AF4J uses `StateKey<T>` for compile-time typed access.

## Declaring keys

Expand Down
2 changes: 1 addition & 1 deletion docs/tool-policy.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: "Restrict which tools an AI agent may call in Java/Spring with af4j. Allow-lists, deny-lists and argument-aware rules — block shell.execute before the call leaves the agent's process."
description: "Restrict which tools an AI agent may call in Java/Spring with AF4J. Allow-lists, deny-lists and argument-aware rules — block shell.execute before the call leaves the agent's process."
---

# Tool Policy
Expand Down
Loading
Loading