Skip to content

Commit 3bc2b33

Browse files
committed
Add Module.md and update main README.md to include ACP
1 parent 26c95e7 commit 3bc2b33

File tree

4 files changed

+213
-5
lines changed

4 files changed

+213
-5
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Key features of Koog include:
3636
- **LLM switching and seamless history adaptation**: Switch to a different LLM at any point without losing the existing conversation history, or reroute between multiple LLM providers.
3737
- **Integration with JVM and Kotlin applications**: Build AI agents with an idiomatic, type-safe Kotlin DSL designed specifically for JVM and Kotlin developers.
3838
- **Model Context Protocol integration**: Use Model Context Protocol (MCP) tools in AI agents.
39+
- **Agent Client Protocol integration**: Build ACP-compliant agents that can communicate with standardized client applications using the Agent Client Protocol (ACP).
3940
- **Knowledge retrieval and memory**: Retain and retrieve knowledge across conversations using vector embeddings, ranked document storage, and shared agent memory.
4041
- **Powerful Streaming API**: Process responses in real-time with streaming support and parallel tool calls.
4142
- **Modular feature system**: Customize agent capabilities through a composable architecture.
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,212 @@
11
# Module agents-features-acp
2+
3+
A module provides integration with [Agent Client Protocol (ACP)](https://agentclientprotocol.com/).
4+
The main components of the ACP integration in Koog are:
5+
6+
- [**AcpAgent**](src/jvmMain/kotlin/ai/koog/agents/features/acp/AcpAgent.kt): A feature that enables communication
7+
between Koog agents and ACP-compliant client applications
8+
- [**MessageConverters**](src/jvmMain/kotlin/ai/koog/agents/features/acp/MessageConverters.kt): Utilities for converting
9+
messages between Koog and ACP formats
10+
11+
## Overview
12+
13+
### What is ACP?
14+
15+
The Agent Client Protocol (ACP) is a standardized protocol that enables AI agents to communicate with client
16+
applications through a consistent interface.
17+
ACP provides a bidirectional communication channel where agents can:
18+
19+
- Receive prompts from clients
20+
- Send events and updates back to clients in real-time
21+
- Report tool call status and progress
22+
- Share reasoning and thoughts with clients
23+
- Manage session lifecycle and state
24+
25+
To read more about ACP visit [https://agentclientprotocol.com](https://agentclientprotocol.com)
26+
27+
### How is ACP integrated with Koog?
28+
29+
The Koog framework integrates with ACP using the [ACP Kotlin SDK](https://github.com/agentclientprotocol/kotlin-sdk)
30+
with the additional API extensions presented in the `agents-features-acp` module.
31+
This integration allows Koog agents to:
32+
33+
1. Communicate with ACP-compliant client applications
34+
2. Convert between Koog message formats and ACP content blocks
35+
3. Send real-time updates about agent execution (tool calls, thoughts, completions)
36+
4. Handle standard ACP events and notifications
37+
38+
### How to Use ACP with Koog?
39+
40+
#### Setting Up an ACP-Enabled Agent
41+
42+
To use ACP with Koog, you need to:
43+
44+
1. Implement the `AgentSupport` and `AgentSession` interface from the ACP SDK
45+
2. In `AgentSession.prompt` method initialize Koog agent with `AcpAgent` feature installed
46+
3. Configure the feature with session ID, protocol instance, and events producer
47+
4. Handle incoming prompts and convert them to Koog messages
48+
49+
Here's a basic example of setting up an ACP-enabled agent:
50+
51+
```kotlin
52+
class KoogAgentSession(
53+
override val sessionId: SessionId,
54+
private val promptExecutor: PromptExecutor,
55+
private val protocol: Protocol,
56+
private val clock: Clock,
57+
) : AgentSession {
58+
59+
private var agentJob: Deferred<Unit>? = null
60+
private val agentMutex = Mutex()
61+
62+
override suspend fun prompt(
63+
content: List<ContentBlock>,
64+
_meta: JsonElement?
65+
): Flow<Event> = channelFlow {
66+
val agentConfig = AIAgentConfig(
67+
prompt = prompt("acp") {
68+
system("You are a helpful assistant.")
69+
}.appendPrompt(content),
70+
model = OpenAIModels.Chat.GPT4o,
71+
maxAgentIterations = 1000
72+
)
73+
74+
agentMutex.withLock {
75+
val agent = AIAgent(
76+
promptExecutor = promptExecutor,
77+
agentConfig = agentConfig,
78+
strategy = yourStrategy(),
79+
toolRegistry = toolRegistry,
80+
) {
81+
install(AcpAgent) {
82+
this.sessionId = this@KoogAgentSession.sessionId.value
83+
this.protocol = this@KoogAgentSession.protocol
84+
this.eventsProducer = this@channelFlow
85+
this.setDefaultNotifications = true
86+
}
87+
}
88+
89+
agentJob = async { agent.run(Unit) }
90+
agentJob?.await()
91+
}
92+
}
93+
94+
private fun Prompt.appendPrompt(content: List<ContentBlock>): Prompt {
95+
return withMessages { messages ->
96+
messages + listOf(content.toKoogMessage(clock))
97+
}
98+
}
99+
}
100+
```
101+
102+
Important notes:
103+
104+
* Use `channelFlow` to allow sending events from different corutines
105+
* Set `this.setDefaultNotifications = true` to automatically handle standard ACP notifications using agent pipeline
106+
interseption. In case manual notification handling, please set `this.setDefaultNotifications = false` and process all
107+
the agents events accoring to the spesificaion using vai protocal `AcpAgent` feature.
108+
* To convert ACP content blocks to Koog messages use `toKoogMessage` extension function and append recieved user message
109+
to the prompt.
110+
* Run the agent in a separate coroutine to allow canceling in `AgentSession.cancel` method
111+
* Use mutex` to synchronize access to the agent instance, as by current protocol prompt should not trigger new execution
112+
until previous is finished
113+
114+
#### Configuration Options
115+
116+
The `AcpAgent` feature can be configured through `AcpConfig`:
117+
118+
- `sessionId`: The unique session identifier for the ACP connection
119+
- `protocol`: The protocol instance used for sending requests and notifications to ACP clients
120+
- `eventsProducer`: A coroutine-based producer scope for sending events
121+
- `setDefaultNotifications`: Whether to register default notification handlers (default: `true`)
122+
123+
#### Default Notification Handlers
124+
125+
When `setDefaultNotifications` is enabled, the AcpAgent feature automatically handles:
126+
127+
1. **Agent Completion**: Sends `PromptResponseEvent` with `StopReason.END_TURN` when the agent completes successfully
128+
2. **Agent Execution Failures**: Sends `PromptResponseEvent` with appropriate stop reasons:
129+
- `StopReason.MAX_TURN_REQUESTS` for max iterations exceeded
130+
- `StopReason.REFUSAL` for other execution failures
131+
3. **LLM Responses**: Converts and sends LLM responses as ACP events (text, tool calls, reasoning)
132+
4. **Tool Call Lifecycle**: Reports tool call status changes:
133+
- `ToolCallStatus.IN_PROGRESS` when a tool call starts
134+
- `ToolCallStatus.COMPLETED` when a tool call succeeds
135+
- `ToolCallStatus.FAILED` when a tool call fails
136+
137+
#### Sending Custom Events
138+
139+
You can send custom events to the ACP client using the `sendEvent` method:
140+
141+
```kotlin
142+
val agent = AIAgent(...) {
143+
install(AcpAgent) { ... }
144+
}
145+
146+
// Later in your code, access the ACP feature
147+
withAcpAgent {
148+
sendEvent(
149+
Event.SessionUpdateEvent(
150+
SessionUpdate.PlanUpdate(planEntries)
151+
)
152+
)
153+
}
154+
```
155+
156+
#### Message Conversion
157+
158+
The module provides utilities for converting between Koog and ACP message formats:
159+
160+
**ACP to Koog:**
161+
162+
```kotlin
163+
// Convert ACP content blocks to Koog message
164+
val koogMessage = acpContentBlocks.toKoogMessage(clock)
165+
166+
// Convert single ACP content block to Koog content part
167+
val contentPart = acpContentBlock.toKoogContentPart()
168+
```
169+
170+
**Koog to ACP:**
171+
172+
```kotlin
173+
// Convert Koog response message to ACP events
174+
val acpEvents = koogResponseMessage.toAcpEvents()
175+
176+
// Convert Koog content part to ACP content block
177+
val acpContentBlock = koogContentPart.toAcpContentBlock()
178+
```
179+
180+
### Supported Content Types
181+
182+
The ACP integration supports the following content types:
183+
184+
- **Text**: Plain text content
185+
- **Image**: Image data with MIME type
186+
- **Audio**: Audio data with MIME type
187+
- **File**: File attachments (embedded or linked)
188+
- Base64-encoded binary data
189+
- Plain text data
190+
- URL references
191+
- **Resource**: Embedded resources with URI and content
192+
- **Resource Link**: Links to external resources
193+
194+
### Platform Support
195+
196+
The ACP feature is currently available only on the JVM platform, as it depends on the ACP Kotlin SDK which is
197+
JVM-specific.
198+
199+
### Examples
200+
201+
Complete working examples can be found in `examples/simple-examples/src/main/kotlin/ai/koog/agents/example/acp/`.
202+
203+
How to run the example:
204+
1. Run the AcpApp.kt file
205+
```shell
206+
./gradlew :examples:simple-examples:run
207+
```
208+
2. Enter the request for ACP Agent
209+
```shell
210+
Move file `my-file.md` to folder `my-folder` and appent title `## My File` to the file content
211+
```
212+
3. Check the events traces in the console

agents/agents-features/agents-features-acp/README.md

Lines changed: 0 additions & 3 deletions
This file was deleted.

settings.gradle.kts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ pluginManagement {
1212
include(":agents:agents-core")
1313
include(":agents:agents-ext")
1414

15+
include(":agents:agents-features:agents-features-acp")
1516
include(":agents:agents-features:agents-features-event-handler")
1617
include(":agents:agents-features:agents-features-memory")
17-
include(":agents:agents-features:agents-features-acp")
1818
include(":agents:agents-features:agents-features-opentelemetry")
1919
include(":agents:agents-features:agents-features-sql")
2020
include(":agents:agents-features:agents-features-trace")
@@ -23,7 +23,6 @@ include(":agents:agents-features:agents-features-snapshot")
2323
include(":agents:agents-features:agents-features-a2a-core")
2424
include(":agents:agents-features:agents-features-a2a-server")
2525
include(":agents:agents-features:agents-features-a2a-client")
26-
include("agents:agents-features:agents-features-acp")
2726

2827
include(":agents:agents-mcp")
2928
include(":agents:agents-mcp-server")

0 commit comments

Comments
 (0)