Skip to content

Commit 4f85465

Browse files
committed
Refactor connection subsystem manually
1 parent 4871383 commit 4f85465

18 files changed

Lines changed: 274 additions & 274 deletions

File tree

kotlin/kotlin-acp/src/commonMain/kotlin/io/agentclientprotocol/agent/AgentSideConnection.kt

Lines changed: 26 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,14 @@
22

33
package io.agentclientprotocol.agent
44

5-
import io.agentclientprotocol.model.ACPJson
6-
import io.agentclientprotocol.agent.Agent
7-
import io.agentclientprotocol.model.AgentMethods
8-
import io.agentclientprotocol.model.AuthenticateRequest
9-
import io.agentclientprotocol.model.CancelNotification
105
import io.agentclientprotocol.client.Client
11-
import io.agentclientprotocol.model.ClientMethods
12-
import io.agentclientprotocol.model.InitializeRequest
13-
import io.agentclientprotocol.model.LATEST_PROTOCOL_VERSION
14-
import io.agentclientprotocol.model.LoadSessionRequest
15-
import io.agentclientprotocol.model.NewSessionRequest
16-
import io.agentclientprotocol.model.PromptRequest
17-
import io.agentclientprotocol.model.ReadTextFileRequest
18-
import io.agentclientprotocol.model.ReadTextFileResponse
19-
import io.agentclientprotocol.model.RequestPermissionRequest
20-
import io.agentclientprotocol.model.RequestPermissionResponse
21-
import io.agentclientprotocol.model.SessionNotification
22-
import io.agentclientprotocol.model.WriteTextFileRequest
6+
import io.agentclientprotocol.model.*
237
import io.agentclientprotocol.protocol.Protocol
248
import io.agentclientprotocol.protocol.ProtocolOptions
9+
import io.agentclientprotocol.rpc.ACPJson
2510
import io.agentclientprotocol.transport.Transport
2611
import io.github.oshai.kotlinlogging.KotlinLogging
12+
import kotlinx.coroutines.CoroutineScope
2713
import kotlinx.serialization.json.JsonNull
2814
import kotlinx.serialization.json.decodeFromJsonElement
2915
import kotlinx.serialization.json.encodeToJsonElement
@@ -41,95 +27,98 @@ private val logger = KotlinLogging.logger {}
4127
* See protocol docs: [Agent](https://agentclientprotocol.com/protocol/overview#agent)
4228
*/
4329
public class AgentSideConnection(
30+
private val parentScope: CoroutineScope,
4431
private val agent: Agent,
32+
private val transport: Transport,
4533
options: ProtocolOptions = ProtocolOptions()
46-
) : Protocol(options), Client {
34+
) : Client {
35+
private val protocol = Protocol(parentScope, transport, options)
36+
37+
public fun start() {
4738

48-
override suspend fun connect(transport: Transport) {
49-
super.connect(transport)
50-
5139
// Set up request handlers for incoming client requests
52-
setRequestHandler(AgentMethods.INITIALIZE) { request ->
40+
protocol.setRequestHandler(AgentMethods.INITIALIZE) { request ->
5341
val params = if (request.params != null) {
54-
ACPJson.decodeFromJsonElement<InitializeRequest>(request.params!!)
42+
ACPJson.decodeFromJsonElement<InitializeRequest>(request.params)
5543
} else {
5644
InitializeRequest(LATEST_PROTOCOL_VERSION)
5745
}
5846
val response = agent.initialize(params)
5947
ACPJson.encodeToJsonElement(response)
6048
}
6149

62-
setRequestHandler(AgentMethods.AUTHENTICATE) { request ->
50+
protocol.setRequestHandler(AgentMethods.AUTHENTICATE) { request ->
6351
val params = if (request.params != null) {
64-
ACPJson.decodeFromJsonElement<AuthenticateRequest>(request.params!!)
52+
ACPJson.decodeFromJsonElement<AuthenticateRequest>(request.params)
6553
} else {
6654
throw IllegalArgumentException("authenticate requires parameters")
6755
}
6856
agent.authenticate(params)
6957
JsonNull // No response body for authenticate
7058
}
7159

72-
setRequestHandler(AgentMethods.SESSION_NEW) { request ->
60+
protocol.setRequestHandler(AgentMethods.SESSION_NEW) { request ->
7361
val params = if (request.params != null) {
74-
ACPJson.decodeFromJsonElement<NewSessionRequest>(request.params!!)
62+
ACPJson.decodeFromJsonElement<NewSessionRequest>(request.params)
7563
} else {
7664
throw IllegalArgumentException("session/new requires parameters")
7765
}
7866
val response = agent.newSession(params)
7967
ACPJson.encodeToJsonElement(response)
8068
}
8169

82-
setRequestHandler(AgentMethods.SESSION_LOAD) { request ->
70+
protocol.setRequestHandler(AgentMethods.SESSION_LOAD) { request ->
8371
val params = if (request.params != null) {
84-
ACPJson.decodeFromJsonElement<LoadSessionRequest>(request.params!!)
72+
ACPJson.decodeFromJsonElement<LoadSessionRequest>(request.params)
8573
} else {
8674
throw IllegalArgumentException("session/load requires parameters")
8775
}
8876
agent.loadSession(params)
8977
JsonNull // No response body for loadSession
9078
}
9179

92-
setRequestHandler(AgentMethods.SESSION_PROMPT) { request ->
80+
protocol.setRequestHandler(AgentMethods.SESSION_PROMPT) { request ->
9381
val params = if (request.params != null) {
94-
ACPJson.decodeFromJsonElement<PromptRequest>(request.params!!)
82+
ACPJson.decodeFromJsonElement<PromptRequest>(request.params)
9583
} else {
9684
throw IllegalArgumentException("session/prompt requires parameters")
9785
}
9886
val response = agent.prompt(params)
9987
ACPJson.encodeToJsonElement(response)
10088
}
10189

102-
setNotificationHandler(AgentMethods.SESSION_CANCEL) { notification ->
90+
protocol.setNotificationHandler(AgentMethods.SESSION_CANCEL) { notification ->
10391
val params = if (notification.params != null) {
104-
ACPJson.decodeFromJsonElement<CancelNotification>(notification.params!!)
92+
ACPJson.decodeFromJsonElement<CancelNotification>(notification.params)
10593
} else {
10694
throw IllegalArgumentException("session/cancel requires parameters")
10795
}
10896
agent.cancel(params)
10997
}
11098

99+
protocol.start()
111100
logger.info { "Agent-side connection established" }
112101
}
113102

114103
override suspend fun sessionUpdate(notification: SessionNotification) {
115104
val params = ACPJson.encodeToJsonElement(notification)
116-
sendNotification(ClientMethods.SESSION_UPDATE, params)
105+
protocol.sendNotification(ClientMethods.SESSION_UPDATE, params)
117106
}
118107

119108
override suspend fun requestPermission(request: RequestPermissionRequest): RequestPermissionResponse {
120109
val params = ACPJson.encodeToJsonElement(request)
121-
val responseJson = sendRequest(ClientMethods.SESSION_REQUEST_PERMISSION, params)
110+
val responseJson = protocol.sendRequest(ClientMethods.SESSION_REQUEST_PERMISSION, params)
122111
return ACPJson.decodeFromJsonElement(responseJson)
123112
}
124113

125114
override suspend fun readTextFile(request: ReadTextFileRequest): ReadTextFileResponse {
126115
val params = ACPJson.encodeToJsonElement(request)
127-
val responseJson = sendRequest(ClientMethods.FS_READ_TEXT_FILE, params)
116+
val responseJson = protocol.sendRequest(ClientMethods.FS_READ_TEXT_FILE, params)
128117
return ACPJson.decodeFromJsonElement(responseJson)
129118
}
130119

131120
override suspend fun writeTextFile(request: WriteTextFileRequest) {
132121
val params = ACPJson.encodeToJsonElement(request)
133-
sendRequest(ClientMethods.FS_WRITE_TEXT_FILE, params)
122+
protocol.sendRequest(ClientMethods.FS_WRITE_TEXT_FILE, params)
134123
}
135124
}

kotlin/kotlin-acp/src/commonMain/kotlin/io/agentclientprotocol/client/ClientSideConnection.kt

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22

33
package io.agentclientprotocol.client
44

5-
import io.agentclientprotocol.model.ACPJson
65
import io.agentclientprotocol.agent.Agent
76
import io.agentclientprotocol.model.AgentMethods
87
import io.agentclientprotocol.model.AuthenticateRequest
98
import io.agentclientprotocol.model.CancelNotification
10-
import io.agentclientprotocol.client.Client
119
import io.agentclientprotocol.model.ClientMethods
1210
import io.agentclientprotocol.model.InitializeRequest
1311
import io.agentclientprotocol.model.InitializeResponse
@@ -22,8 +20,10 @@ import io.agentclientprotocol.model.SessionNotification
2220
import io.agentclientprotocol.model.WriteTextFileRequest
2321
import io.agentclientprotocol.protocol.Protocol
2422
import io.agentclientprotocol.protocol.ProtocolOptions
23+
import io.agentclientprotocol.rpc.ACPJson
2524
import io.agentclientprotocol.transport.Transport
2625
import io.github.oshai.kotlinlogging.KotlinLogging
26+
import kotlinx.coroutines.CoroutineScope
2727
import kotlinx.serialization.json.JsonNull
2828
import kotlinx.serialization.json.decodeFromJsonElement
2929
import kotlinx.serialization.json.encodeToJsonElement
@@ -41,78 +41,80 @@ private val logger = KotlinLogging.logger {}
4141
* See protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)
4242
*/
4343
public class ClientSideConnection(
44+
parentScope: CoroutineScope,
45+
private val transport: Transport,
4446
private val client: Client,
4547
options: ProtocolOptions = ProtocolOptions()
46-
) : Protocol(options), Agent {
48+
) : Agent {
49+
private val protocol = Protocol(parentScope, transport, options)
4750

48-
override suspend fun connect(transport: Transport) {
49-
super.connect(transport)
50-
51+
public fun start() {
5152
// Set up request handlers for incoming agent requests
52-
setRequestHandler(ClientMethods.FS_READ_TEXT_FILE) { request ->
53+
protocol.setRequestHandler(ClientMethods.FS_READ_TEXT_FILE) { request ->
5354
val params = ACPJson.decodeFromString<ReadTextFileRequest>(
5455
request.params?.toString() ?: "{}"
5556
)
5657
val response = client.readTextFile(params)
5758
ACPJson.encodeToJsonElement(response)
5859
}
5960

60-
setRequestHandler(ClientMethods.FS_WRITE_TEXT_FILE) { request ->
61+
protocol.setRequestHandler(ClientMethods.FS_WRITE_TEXT_FILE) { request ->
6162
val params = ACPJson.decodeFromString<WriteTextFileRequest>(
6263
request.params?.toString() ?: "{}"
6364
)
6465
client.writeTextFile(params)
6566
JsonNull // No response body for writeTextFile
6667
}
6768

68-
setRequestHandler(ClientMethods.SESSION_REQUEST_PERMISSION) { request ->
69+
protocol.setRequestHandler(ClientMethods.SESSION_REQUEST_PERMISSION) { request ->
6970
val params = ACPJson.decodeFromString<RequestPermissionRequest>(
7071
request.params?.toString() ?: "{}"
7172
)
7273
val response = client.requestPermission(params)
7374
ACPJson.encodeToJsonElement(response)
7475
}
7576

76-
setNotificationHandler(ClientMethods.SESSION_UPDATE) { notification ->
77+
protocol.setNotificationHandler(ClientMethods.SESSION_UPDATE) { notification ->
7778
val params = ACPJson.decodeFromString<SessionNotification>(
7879
notification.params?.toString() ?: "{}"
7980
)
8081
client.sessionUpdate(params)
8182
}
8283

84+
protocol.start()
8385
logger.info { "Client-side connection established" }
8486
}
8587

8688
override suspend fun initialize(request: InitializeRequest): InitializeResponse {
8789
val params = ACPJson.encodeToJsonElement(request)
88-
val responseJson = sendRequest(AgentMethods.INITIALIZE, params)
90+
val responseJson = protocol.sendRequest(AgentMethods.INITIALIZE, params)
8991
return ACPJson.decodeFromJsonElement(responseJson)
9092
}
9193

9294
override suspend fun authenticate(request: AuthenticateRequest) {
9395
val params = ACPJson.encodeToJsonElement(request)
94-
sendRequest(AgentMethods.AUTHENTICATE, params)
96+
protocol.sendRequest(AgentMethods.AUTHENTICATE, params)
9597
}
9698

9799
override suspend fun newSession(request: NewSessionRequest): NewSessionResponse {
98100
val params = ACPJson.encodeToJsonElement(request)
99-
val responseJson = sendRequest(AgentMethods.SESSION_NEW, params)
101+
val responseJson = protocol.sendRequest(AgentMethods.SESSION_NEW, params)
100102
return ACPJson.decodeFromJsonElement(responseJson)
101103
}
102104

103105
override suspend fun loadSession(request: LoadSessionRequest) {
104106
val params = ACPJson.encodeToJsonElement(request)
105-
sendRequest(AgentMethods.SESSION_LOAD, params)
107+
protocol.sendRequest(AgentMethods.SESSION_LOAD, params)
106108
}
107109

108110
override suspend fun prompt(request: PromptRequest): PromptResponse {
109111
val params = ACPJson.encodeToJsonElement(request)
110-
val responseJson = sendRequest(AgentMethods.SESSION_PROMPT, params)
112+
val responseJson = protocol.sendRequest(AgentMethods.SESSION_PROMPT, params)
111113
return ACPJson.decodeFromJsonElement(responseJson)
112114
}
113115

114116
override suspend fun cancel(notification: CancelNotification) {
115117
val params = ACPJson.encodeToJsonElement(notification)
116-
sendNotification(AgentMethods.SESSION_CANCEL, params)
118+
protocol.sendNotification(AgentMethods.SESSION_CANCEL, params)
117119
}
118120
}

kotlin/kotlin-acp/src/commonMain/kotlin/io/agentclientprotocol/model/Types.kt

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,4 @@ public data class Annotations(
104104
val audience: List<Role>? = null,
105105
val priority: Double? = null,
106106
val lastModified: String? = null
107-
)
108-
109-
@OptIn(ExperimentalSerializationApi::class)
110-
public val ACPJson: Json by lazy {
111-
Json {
112-
ignoreUnknownKeys = true
113-
encodeDefaults = true
114-
isLenient = true
115-
classDiscriminatorMode = ClassDiscriminatorMode.POLYMORPHIC
116-
explicitNulls = false
117-
}
118-
}
107+
)

0 commit comments

Comments
 (0)