Skip to content
Draft
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
12 changes: 11 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### Maven/Gradle Builds ###
target/
.m2repo/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
Expand Down Expand Up @@ -46,6 +47,12 @@ build.log
shell.log
derby.log

### Environment Files ###
.env
.env.*
**/.env
**/.env.*

### Compiled Files ###
*.class

Expand All @@ -57,6 +64,7 @@ derby.log
*.zip
*.tar.gz
*.rar
node_modules/

### Claude Code ###
.claude/
Expand All @@ -68,5 +76,7 @@ hs_err_pid*
replay_pid*

### Planning and Internal Documentation ###
plans/
plans/*
!plans/STREAMABLE-HTTP-TRANSPORT.md
!plans/STREAMABLE-HTTP-AGENT-TRANSPORT.md
learnings/
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ For WebSocket server support (agents accepting WebSocket connections):
</dependency>
```

For Streamable HTTP server support (agents accepting remote HTTP/SSE connections):
```xml
<dependency>
<groupId>com.agentclientprotocol</groupId>
<artifactId>acp-streamable-http-jetty</artifactId>
<version>0.11.0</version>
</dependency>
```

---

## Getting Started
Expand Down Expand Up @@ -368,7 +377,8 @@ agent.start().block(); // Starts WebSocket server on port 8080

| Artifact | Description |
|----------|-------------|
| [`acp-core`](https://central.sonatype.com/artifact/com.agentclientprotocol/acp-core) | Client and Agent SDKs, stdio and WebSocket client transports |
| [`acp-core`](https://central.sonatype.com/artifact/com.agentclientprotocol/acp-core) | Client and Agent SDKs, stdio, WebSocket, and Streamable HTTP client transports |
| `acp-streamable-http-jetty` | Jetty-backed Streamable HTTP agent transport for listener-backed remote agents |
| [`acp-annotations`](https://central.sonatype.com/artifact/com.agentclientprotocol/acp-annotations) | `@AcpAgent`, `@Prompt`, and other annotations |
| [`acp-agent-support`](https://central.sonatype.com/artifact/com.agentclientprotocol/acp-agent-support) | Annotation-based agent runtime |
| [`acp-test`](https://central.sonatype.com/artifact/com.agentclientprotocol/acp-test) | In-memory transport and mock utilities for testing |
Expand All @@ -380,6 +390,18 @@ agent.start().block(); // Starts WebSocket server on port 8080
|-----------|--------|-------|--------|
| Stdio | `StdioAcpClientTransport` | `StdioAcpAgentTransport` | acp-core |
| WebSocket | `WebSocketAcpClientTransport` | `WebSocketAcpAgentTransport` | acp-core / acp-websocket-jetty |
| Streamable HTTP | `StreamableHttpAcpClientTransport` | `StreamableHttpAcpAgentTransport` | acp-core / acp-streamable-http-jetty |

### Streamable HTTP Demo Server

Build and run a local demo ACP agent over HTTP/SSE:

```bash
./mvnw -q -pl test-fixtures/streamable-http-agent-server -am -DskipTests package
java -jar test-fixtures/streamable-http-agent-server/target/acp-streamable-http-agent-server.jar --port 8080
```

The endpoint will be available at `http://127.0.0.1:8080/acp`.

---

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright 2025-2026 the original author or authors.
*/

package com.agentclientprotocol.sdk.agent;

import java.util.function.Function;

import com.agentclientprotocol.sdk.spec.AcpAgentTransport;
import com.agentclientprotocol.sdk.util.Assert;

/**
* Factory for creating one ACP agent runtime for one agent-side transport.
*
* <p>
* Listener-backed transports such as remote HTTP transports accept multiple client
* connections over their lifetime. Each accepted connection needs its own
* connection-bound agent runtime while reusing the same agent definition. This factory
* is the explicit public seam for that relationship.
* </p>
*
* @author Kaiser Dandangi
*/
@FunctionalInterface
public interface AcpAgentFactory {

/**
* Creates a new asynchronous agent runtime for the supplied transport.
* @param transport per-connection transport
* @return a fresh asynchronous agent runtime
*/
AcpAsyncAgent create(AcpAgentTransport transport);

/**
* Creates a factory from an asynchronous agent builder function.
* @param factory function that creates a fresh asynchronous agent per transport
* @return an agent factory
*/
static AcpAgentFactory async(Function<AcpAgentTransport, AcpAsyncAgent> factory) {
Assert.notNull(factory, "The async factory can not be null");
return factory::apply;
}

/**
* Creates a factory from a synchronous agent builder function.
*
* <p>
* Synchronous agents are wrappers around asynchronous agents in this SDK, so the
* transport seam remains asynchronous underneath while callers may still author
* agents with the blocking API.
* </p>
* @param factory function that creates a fresh synchronous agent per transport
* @return an agent factory
*/
static AcpAgentFactory sync(Function<AcpAgentTransport, AcpSyncAgent> factory) {
Assert.notNull(factory, "The sync factory can not be null");
return transport -> factory.apply(transport).async();
}

}
Loading