Java SDK for controlling Autohand code agents through the CLI JSON-RPC mode.
Beta: this SDK is actively evolving while the Agent SDK APIs stabilize. Pin versions in production and review release notes before upgrading.
Official documentation: https://autohand.ai/docs/agent-sdk/
The Agent SDK is available in multiple beta language packages. Use the same Autohand code-agent model from another programming language:
- TypeScript -
Agent,Run, streaming, and JSON helpers for Node and Bun hosts. - Go - idiomatic Go package with
context.Context, typed events, and channel-based streaming. - Python - async Python package with
async forevent streams and typed Pydantic models. - Java - this package, with Java 21 records, sealed events, and virtual-thread-ready APIs.
- Swift - SwiftPM package with
Agent,Runner, async streams, tools, hooks, and permissions. - Rust - async Rust crate with Tokio, typed events, and stream-based runs.
- C++ - modern C++20 package with CMake targets and typed event callbacks.
- C# - .NET package with
IAsyncEnumerable,CancellationToken, andSystem.Text.Json.
- Java 21+ (uses virtual threads and sealed interfaces)
- Maven 3.9+
- Autohand CLI binary
Add to your pom.xml:
<dependency>
<groupId>ai.autohand</groupId>
<artifactId>code-agent-sdk-java</artifactId>
<version>1.0.0</version>
</dependency>Maven Central releases are produced by the GitHub Actions release workflow. See Publishing To Maven Central for the release checklist and required repository secrets.
Or build locally:
mvn clean installUse Agent for application code. It gives you an explicit run lifecycle while keeping CLI subprocess and JSON-RPC details out of your app.
import ai.autohand.sdk.sdk.Agent;
import ai.autohand.sdk.sdk.AgentOptions;
import ai.autohand.sdk.sdk.RunResult;
import ai.autohand.sdk.types.*;
Agent agent = Agent.create(AgentOptions.builder()
.cwd(".")
.instructions("Review code with Staff-level Java judgement.")
.permissionMode(PermissionMode.INTERACTIVE)
.build());
var run = agent.send("Review this repository for release readiness");
run.stream(event -> {
if (event instanceof Events.MessageUpdateEvent mue) {
System.out.print(mue.delta());
}
});
RunResult result = run.waitForResult();
System.out.println(result.text());
agent.close();For simple one-shot tasks:
RunResult result = agent.run("Summarize the API surface");Current CLIs also expose command helpers and the typed replayable autoresearch ledger:
if (agent.supportsCommand("/autoresearch")) {
Autoresearch.StartResult start = agent.startAutoresearch(
Autoresearch.StartParams.builder("Reduce test runtime")
.metricName("test_ms")
.metricUnit("ms")
.direction(Autoresearch.OptimizationDirection.LOWER)
.measureCommand("mvn test")
.build()
);
if (start.success() && start.instruction() != null) {
agent.send(start.instruction()).waitForResult();
}
Autoresearch.HistoryResult history = agent.getAutoresearchHistory();
agent.stopAutoresearch();
}Read the replayable autoresearch guide for replay, rescore, comparison, Pareto, pinning, and retention APIs.
Persistent goals are also typed end to end: getGoal, createGoal,
updateGoal, clearGoal, queueGoal, startQueuedGoal, and
listGoalTemplates. See the persistent goals guide
for feature startup and nullable budget updates.
Community skills and MCP discovery are typed as well: getSkillsRegistry,
installSkill, listMcpServers, listMcpTools, and
getMcpServerConfigs. See the skills and MCP guide.
Use reset() to replace the active conversation and receive its new session ID.
Create an expiring browser attachment URL with createBrowserHandoff(...).
Attach one by token with attachBrowserHandoff(...).
Use attachLatestBrowserHandoff() when the newest handoff should be selected automatically.
Start a bounded autonomous run with typed limits through startAutoMode(...).
Inspect progress and checkpoint metadata with getAutoModeStatus().
Pause an active autonomous run with pauseAutoMode().
Resume it with resumeAutoMode().
Cancel with an optional audit reason through cancelAutoMode(...).
Read typed iteration history with getAutoModeLog(...).
For JSON output:
public record ReleaseRisk(String summary, List<Risk> risks) {}
public record Risk(String title, String severity) {}
ReleaseRisk risk = agent.runJson(
"Assess publish readiness",
ReleaseRisk.class,
"ReleaseRisk",
Map.of("summary", "string", "risks", List.of(Map.of("title", "string", "severity", "low | medium | high"))),
null
);Use AutohandSDK when you need direct control over the CLI subprocess.
import ai.autohand.sdk.sdk.AutohandSDK;
import ai.autohand.sdk.types.*;
AutohandSDK sdk = new AutohandSDK(new SDKConfig(
".", // cwd
null, // cliPath (auto-detected)
false, // debug
300_000 // timeout ms
));
sdk.start();
sdk.prompt(new PromptParams("Hello, Autohand!"));
sdk.streamPrompt(new PromptParams("Analyze the codebase"), event -> {
System.out.println(event);
});
sdk.stop();All 16 autohand.hook.* notifications have typed Java events. Unknown
notifications and malformed known hooks remain observable as
Events.UnknownEvent, whose params() preserves the original JSON value,
including array, null, and scalar top-level shapes. See
Event Streaming for the
complete method-to-record map and numeric validation rules.
User -> Java SDK -> CLI Subprocess (RPC mode) -> Provider -> HTTP
The SDK:
- Spawns the Autohand CLI with
--mode rpc - Communicates via JSON-RPC 2.0 over stdin/stdout
- Provides an idiomatic Java API with builders, records, and sealed event types
- Streams events through Java callbacks while preserving typed permission replies
- Keeps future CLI notifications inspectable with
Events.UnknownEvent
src/main/java/ai/autohand/sdk/
AutohandAgentSdk.java # Entry point and version
types/ # Records, enums, sealed event types
Event.java # Sealed event interface
Events.java # Concrete event records
SDKConfig.java # Configuration builder and compatibility constructor
PromptParams.java # Prompt parameters
...
transport/
Transport.java # Subprocess spawning and I/O
TransportConfig.java # Transport configuration
rpc/
RPCClient.java # JSON-RPC client
sdk/
AutohandSDK.java # Main SDK class
Agent.java # High-level agent API
Run.java # Run lifecycle
RunResult.java # Run result record
JsonParser.java # JSON parsing utilities
StructuredOutputError.java # Structured output error
# Compile
mvn clean compile
# Run tests
mvn test
# Compile every example against the public API
scripts/validate-examples.sh
# Package
mvn package
# Enforce public-load and usable getState startup p95 < 50 ms
mvn -q -Dtest=StartupBenchmarkTest test
# Build Maven Central release artifacts locally (requires GPG)
mvn -P release verify