JBang Agent Runner

The JBang Agent Runner is the primary entry point for developers to try Spring AI Agents. It provides a lightweight, composable way to execute autonomous agents directly from the command line using JBang. Whether you’re exploring agents locally with LocalSandbox, integrating into CI/CD pipelines, or running benchmark programs, the JBang runner makes it easy to get started.

1. Overview

The JBang Agent Runner uses a clean three-component architecture:

  • AgentSpec: Immutable agent behavior definition (prompts, input schema, defaults)

  • RunSpec: Complete run configuration (agent selection + sandbox environment + task parameters + tweak)

  • LauncherSpec: Resolved execution context (AgentSpec + RunSpec + working directory)

This separation enables benchmark programs to generate arrays of RunSpec objects with different agent/sandbox/parameter combinations, while AgentSpec objects are cached and reused for performance.

2. Quick Start

The JBang Agent Runner is the easiest way for developers to try Spring AI Agents. Choose your approach based on your needs:

The catalog approach provides the best developer experience - no cloning, no building, just run:

# One-time setup: Add the catalog
jbang catalog add --name=springai \
  https://raw.githubusercontent.com/spring-ai-community/spring-ai-agents/main/jbang-catalog.json

# Verify catalog installation
jbang catalog list | grep springai
jbang alias list springai

# Run agents using catalog alias
jbang agents@springai hello-world path=test.txt content="Hello World!"

# AI-powered agent with Claude
export ANTHROPIC_API_KEY="your-key"
jbang agents@springai hello-world-agent-ai \
  path=ai-test.txt \
  content="a creative message" \
  provider=claude

2.2. Option 2: Direct URL Invocation

No catalog setup needed, but longer command:

jbang https://raw.githubusercontent.com/spring-ai-community/spring-ai-agents/main/jbang/launcher.java \
  hello-world \
  path=greeting.txt \
  content="Hello from Direct URL!"

2.3. Option 3: Local Development

Clone the repository for local development and testing:

git clone https://github.com/spring-ai-community/spring-ai-agents.git
cd spring-ai-agents

# Build all modules first
./mvnw clean install -DskipTests

# Run hello-world agent
jbang jbang/launcher.java hello-world path=test.txt content="Hello World!"

# Run coverage agent
jbang jbang/launcher.java \
  coverage \
  target_coverage=90 \
  module=core

2.4. Local Development with LocalSandbox

By default, agents run in LocalSandbox, which executes directly on your local machine. This is perfect for:

  • Trying agents for the first time - No Docker or complex setup required

  • Local development workflows - Agents can access your local files and environment

  • Rapid prototyping - Immediate feedback without containerization overhead

  • Learning and experimentation - See exactly what agents are doing on your system

# Run in current directory (LocalSandbox default)
jbang jbang/launcher.java hello-world path=local-test.txt content="Local development!"

# Specify custom working directory
jbang jbang/launcher.java coverage workdir=/path/to/project target_coverage=85

# Use LocalSandbox explicitly
jbang jbang/launcher.java hello-world sandbox=local path=test.txt
LocalSandbox executes commands directly on your host system with no isolation. Only use with trusted agents and inputs.
The JBang Agent Runner defaults to LocalSandbox for developer convenience and local experimentation. The Spring AI Agents library defaults to Docker sandbox for production safety. You can override the sandbox type with --sandbox docker when using JBang.

2.5. Development to Production Progression

The JBang Agent Runner is designed for the typical developer workflow:

  1. Local Experimentation (JBang + LocalSandbox) bash # Try agents locally with immediate feedback jbang jbang/launcher.java coverage target_coverage=80

  2. Enhanced Local Testing (JBang + Docker) bash # Test with isolation before production jbang jbang/launcher.java coverage sandbox=docker target_coverage=80

  3. Production Integration (Spring AI Agents library + Docker) java // Use in Spring Boot applications with Docker sandbox by default AgentClient.builder() .defaultOptions(ClaudeCodeAgentOptions.builder().build()) .build() .prompt("Increase test coverage to 80%") .call();

3. Architecture

3.1. AgentSpec

Defines the agent’s behavior and is loaded from YAML files in /agents/<id>.yaml:

id: coverage
version: 0.1
inputs:
  target_coverage:
    type: integer
    default: 80
  module:
    type: string
    default: "."
  focus:
    type: string
    default: "unit"

3.2. RunSpec

Contains the complete run configuration:

public record RunSpec(
    String agent,                    // Which agent to run
    Map<String, Object> inputs,      // Runtime input values
    String workingDirectory,         // Sandbox working directory
    Map<String, Object> env          // Environment settings
)

3.3. LauncherSpec

The resolved execution context passed to the agent:

public record LauncherSpec(
    AgentSpec agentSpec,            // Resolved agent definition
    Map<String, Object> inputs,     // Merged inputs (defaults + runtime)
    Path cwd,                       // Working directory
    Map<String, Object> env         // Environment variables
)

4. Configuration

4.1. CLI Arguments

jbang jbang/launcher.java <agentId> key=value [key2=value2 ...]

Format:
  <agentId>          Agent to run (hello-world, coverage)
  sandbox=<type>     Sandbox type (local, docker) [default: local]
  workdir=<path>     Working directory for sandbox
  <key>=<value>      Agent input parameters

4.2. Configuration File

Create a run.yaml file in your working directory:

agent: coverage
inputs:
  target_coverage: 85
  module: "core"
  focus: "integration tests"
workingDirectory: "/tmp/test-workspace"
env:
  sandbox: "local"

4.3. Precedence Rules

Configuration merging follows this precedence (most specific wins):

  1. AgentSpec defaults (from YAML)

  2. run.yaml configuration

  3. CLI flags (highest priority)

5. Built-in Agents

5.1. Hello World Agent

Creates files with specified content.

jbang jbang/launcher.java \
  hello-world \
  path=greeting.txt \
  content="Hello from JBang!"

Inputs: * path (string, required): File path to create * content (string, default: "HelloWorld"): File content

5.2. Coverage Agent

Generates prompts for test coverage improvement.

jbang jbang/launcher.java \
  coverage \
  target_coverage=90 \
  module=core \
  focus="unit tests"

Inputs: * target_coverage (integer, default: 80): Target coverage percentage * module (string, default: "."): Module to focus on * focus (string, default: "unit"): Type of tests to focus on

6. Template Rendering

Agents are implemented as black boxes that take typed inputs and produce outputs. They encapsulate their internal logic and prompts as implementation details.

Variables are resolved from agent inputs (merged with defaults).

7. Comprehensive Logging

The runner includes detailed info-level logging for debugging:

# Enable logging to see execution details
jbang jbang/launcher.java coverage target_coverage=90 module=core

Log output shows: * Configuration loading and merging * AgentSpec resolution * Input validation * Template rendering * Agent execution progress

8. Benchmark Program Integration

The architecture is optimized for benchmark programs:

// Generate multiple run configurations
List<RunSpec> runs = List.of(
    new RunSpec("coverage", Map.of("target_coverage", 80), "/tmp/test1", Map.of()),
    new RunSpec("coverage", Map.of("target_coverage", 90), "/tmp/test2", Map.of()),
    new RunSpec("hello-world", Map.of("path", "test.txt", "content", "Hello"), "/tmp/test3", Map.of())
);

// Execute all runs (AgentSpecs are cached and reused)
for (RunSpec runSpec : runs) {
    LauncherSpec launcher = LocalConfigLoader.resolve(runSpec);
    Result result = AgentRunner.execute(launcher);
    System.out.println("Result: " + result.message());
}

9. Error Handling

The runner provides structured error codes:

  • 0: Success

  • 1: Execution failure (agent failed)

  • 2: Usage error (missing inputs, unknown agent)

Scripts and CI systems can differentiate between user errors and agent failures.

10. Provider-Specific Limitations

Different agent providers have specific constraints you should be aware of:

10.1. Gemini CLI Workspace Restrictions

The Gemini CLI enforces workspace boundaries for security. It can only create or modify files within your current project directory.

What works:

# Relative paths within workspace
jbang agents@springai hello-world-agent-ai \
  path=myfile.txt \
  content="content" \
  provider=gemini

# Subdirectories within workspace
jbang agents@springai hello-world-agent-ai \
  path=output/data.txt \
  content="data" \
  provider=gemini

What doesn’t work:

# Absolute paths outside workspace
jbang agents@springai hello-world-agent-ai \
  path=/tmp/myfile.txt \
  content="content" \
  provider=gemini
# Error: Path must be within workspace directory
When using Gemini CLI, always use relative paths that stay within your project directory.

10.2. Claude Code Permissions

Claude Code has a flexible permissions model controlled by the yolo option:

  • yolo=true (default for JBang): Agent can make changes automatically

  • yolo=false: Agent will prompt for confirmation before changes

11. Next Steps

  • Wire coverage agent to real AgentModel from spring-ai-agent-model

  • Add Docker sandbox support for improved isolation

  • Extend with additional agent types (pr-review, dependency-upgrade)

  • Add multi-agent collaborative workflows

The JBang Agent Runner provides a foundation for embedding autonomous agents throughout the development workflow.