Skip to content
Merged
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
83 changes: 78 additions & 5 deletions acp-model/api/acp-model.api
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ public final class com/agentclientprotocol/model/AcpMethod$AgentMethods$SessionP
public static final field INSTANCE Lcom/agentclientprotocol/model/AcpMethod$AgentMethods$SessionPrompt;
}

public final class com/agentclientprotocol/model/AcpMethod$AgentMethods$SessionResume : com/agentclientprotocol/model/AcpMethod$AcpSessionRequestResponseMethod {
public static final field INSTANCE Lcom/agentclientprotocol/model/AcpMethod$AgentMethods$SessionResume;
}

public final class com/agentclientprotocol/model/AcpMethod$AgentMethods$SessionSetMode : com/agentclientprotocol/model/AcpMethod$AcpSessionRequestResponseMethod {
public static final field INSTANCE Lcom/agentclientprotocol/model/AcpMethod$AgentMethods$SessionSetMode;
}
Expand Down Expand Up @@ -2005,6 +2009,73 @@ public final class com/agentclientprotocol/model/ResourceLink$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class com/agentclientprotocol/model/ResumeSessionRequest : com/agentclientprotocol/model/AcpRequest, com/agentclientprotocol/model/AcpWithSessionId {
public static final field Companion Lcom/agentclientprotocol/model/ResumeSessionRequest$Companion;
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lkotlinx/serialization/json/JsonElement;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1-7EW-EgU ()Ljava/lang/String;
public final fun component2 ()Ljava/lang/String;
public final fun component3 ()Ljava/util/List;
public final fun component4 ()Lkotlinx/serialization/json/JsonElement;
public final fun copy-wPMwmcM (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lkotlinx/serialization/json/JsonElement;)Lcom/agentclientprotocol/model/ResumeSessionRequest;
public static synthetic fun copy-wPMwmcM$default (Lcom/agentclientprotocol/model/ResumeSessionRequest;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lkotlinx/serialization/json/JsonElement;ILjava/lang/Object;)Lcom/agentclientprotocol/model/ResumeSessionRequest;
public fun equals (Ljava/lang/Object;)Z
public final fun getCwd ()Ljava/lang/String;
public final fun getMcpServers ()Ljava/util/List;
public fun getSessionId-7EW-EgU ()Ljava/lang/String;
public fun get_meta ()Lkotlinx/serialization/json/JsonElement;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final synthetic class com/agentclientprotocol/model/ResumeSessionRequest$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Lcom/agentclientprotocol/model/ResumeSessionRequest$$serializer;
public final fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/agentclientprotocol/model/ResumeSessionRequest;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/agentclientprotocol/model/ResumeSessionRequest;)V
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}

public final class com/agentclientprotocol/model/ResumeSessionRequest$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class com/agentclientprotocol/model/ResumeSessionResponse : com/agentclientprotocol/model/AcpCreatedSessionResponse, com/agentclientprotocol/model/AcpResponse {
public static final field Companion Lcom/agentclientprotocol/model/ResumeSessionResponse$Companion;
public fun <init> ()V
public fun <init> (Lcom/agentclientprotocol/model/SessionModeState;Lcom/agentclientprotocol/model/SessionModelState;Lkotlinx/serialization/json/JsonElement;)V
public synthetic fun <init> (Lcom/agentclientprotocol/model/SessionModeState;Lcom/agentclientprotocol/model/SessionModelState;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lcom/agentclientprotocol/model/SessionModeState;
public final fun component2 ()Lcom/agentclientprotocol/model/SessionModelState;
public final fun component3 ()Lkotlinx/serialization/json/JsonElement;
public final fun copy (Lcom/agentclientprotocol/model/SessionModeState;Lcom/agentclientprotocol/model/SessionModelState;Lkotlinx/serialization/json/JsonElement;)Lcom/agentclientprotocol/model/ResumeSessionResponse;
public static synthetic fun copy$default (Lcom/agentclientprotocol/model/ResumeSessionResponse;Lcom/agentclientprotocol/model/SessionModeState;Lcom/agentclientprotocol/model/SessionModelState;Lkotlinx/serialization/json/JsonElement;ILjava/lang/Object;)Lcom/agentclientprotocol/model/ResumeSessionResponse;
public fun equals (Ljava/lang/Object;)Z
public fun getModels ()Lcom/agentclientprotocol/model/SessionModelState;
public fun getModes ()Lcom/agentclientprotocol/model/SessionModeState;
public fun get_meta ()Lkotlinx/serialization/json/JsonElement;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final synthetic class com/agentclientprotocol/model/ResumeSessionResponse$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Lcom/agentclientprotocol/model/ResumeSessionResponse$$serializer;
public final fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/agentclientprotocol/model/ResumeSessionResponse;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/agentclientprotocol/model/ResumeSessionResponse;)V
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}

public final class com/agentclientprotocol/model/ResumeSessionResponse$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class com/agentclientprotocol/model/Role : java/lang/Enum {
public static final field ASSISTANT Lcom/agentclientprotocol/model/Role;
public static final field Companion Lcom/agentclientprotocol/model/Role$Companion;
Expand All @@ -2021,12 +2092,14 @@ public final class com/agentclientprotocol/model/Role$Companion {
public final class com/agentclientprotocol/model/SessionCapabilities : com/agentclientprotocol/model/AcpWithMeta {
public static final field Companion Lcom/agentclientprotocol/model/SessionCapabilities$Companion;
public fun <init> ()V
public fun <init> (Lkotlinx/serialization/json/JsonElement;)V
public synthetic fun <init> (Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lkotlinx/serialization/json/JsonElement;
public final fun copy (Lkotlinx/serialization/json/JsonElement;)Lcom/agentclientprotocol/model/SessionCapabilities;
public static synthetic fun copy$default (Lcom/agentclientprotocol/model/SessionCapabilities;Lkotlinx/serialization/json/JsonElement;ILjava/lang/Object;)Lcom/agentclientprotocol/model/SessionCapabilities;
public fun <init> (ZLkotlinx/serialization/json/JsonElement;)V
public synthetic fun <init> (ZLkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Z
public final fun component2 ()Lkotlinx/serialization/json/JsonElement;
public final fun copy (ZLkotlinx/serialization/json/JsonElement;)Lcom/agentclientprotocol/model/SessionCapabilities;
public static synthetic fun copy$default (Lcom/agentclientprotocol/model/SessionCapabilities;ZLkotlinx/serialization/json/JsonElement;ILjava/lang/Object;)Lcom/agentclientprotocol/model/SessionCapabilities;
public fun equals (Ljava/lang/Object;)Z
public final fun getResume ()Z
public fun get_meta ()Lkotlinx/serialization/json/JsonElement;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public data class McpCapabilities(
*/
@Serializable
public data class SessionCapabilities(
@EncodeDefault val resume: Boolean = false,
override val _meta: JsonElement? = null
) : AcpWithMeta

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public open class AcpMethod(public val methodName: MethodName) {
public object Authenticate : AcpRequestResponseMethod<AuthenticateRequest, AuthenticateResponse>("authenticate", AuthenticateRequest.serializer(), AuthenticateResponse.serializer())
public object SessionNew : AcpRequestResponseMethod<NewSessionRequest, NewSessionResponse>("session/new", NewSessionRequest.serializer(), NewSessionResponse.serializer())
public object SessionLoad : AcpRequestResponseMethod<LoadSessionRequest, LoadSessionResponse>("session/load", LoadSessionRequest.serializer(), LoadSessionResponse.serializer())
@UnstableApi
public object SessionResume : AcpSessionRequestResponseMethod<ResumeSessionRequest, ResumeSessionResponse>("session/resume", ResumeSessionRequest.serializer(), ResumeSessionResponse.serializer())

// session specific
public object SessionPrompt : AcpSessionRequestResponseMethod<PromptRequest, PromptResponse>("session/prompt", PromptRequest.serializer(), PromptResponse.serializer())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,27 @@ public data class LoadSessionRequest(
override val _meta: JsonElement? = null
) : AcpRequest, AcpWithSessionId

/**
* **UNSTABLE**
*
* This capability is not part of the spec yet, and may be removed or changed at any point.
*
* Request parameters for resuming an existing session.
*
* Resumes an existing session without returning previous messages (unlike `session/load`).
* This is useful for agents that can resume sessions but don't implement full session loading.
*
* Only available if the Agent supports the `session.resume` capability.
*/
@UnstableApi
@Serializable
public data class ResumeSessionRequest(
override val sessionId: SessionId,
val cwd: String,
val mcpServers: List<McpServer>,
override val _meta: JsonElement? = null
) : AcpRequest, AcpWithSessionId

/**
* Request parameters for sending a user prompt to the agent.
*
Expand Down Expand Up @@ -398,6 +419,21 @@ public data class LoadSessionResponse(
override val _meta: JsonElement? = null
) : AcpCreatedSessionResponse, AcpResponse

/**
* **UNSTABLE**
*
* This capability is not part of the spec yet, and may be removed or changed at any point.
*
* Response from resuming an existing session.
*/
@UnstableApi
@Serializable
public data class ResumeSessionResponse(
override val modes: SessionModeState? = null,
override val models: SessionModelState? = null,
override val _meta: JsonElement? = null
) : AcpCreatedSessionResponse, AcpResponse

/**
* Response containing the contents of a text file.
*/
Expand Down
4 changes: 4 additions & 0 deletions acp/api/acp.api
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,13 @@ public abstract interface class com/agentclientprotocol/agent/AgentSupport {
public abstract fun createSession (Lcom/agentclientprotocol/common/SessionCreationParameters;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public abstract fun initialize (Lcom/agentclientprotocol/client/ClientInfo;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public abstract fun loadSession-nk3TnMc (Ljava/lang/String;Lcom/agentclientprotocol/common/SessionCreationParameters;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun resumeSession-nk3TnMc (Ljava/lang/String;Lcom/agentclientprotocol/common/SessionCreationParameters;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun resumeSession-nk3TnMc$suspendImpl (Lcom/agentclientprotocol/agent/AgentSupport;Ljava/lang/String;Lcom/agentclientprotocol/common/SessionCreationParameters;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

public final class com/agentclientprotocol/agent/AgentSupport$DefaultImpls {
public static fun authenticate-fMnwWJU (Lcom/agentclientprotocol/agent/AgentSupport;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static fun resumeSession-nk3TnMc (Lcom/agentclientprotocol/agent/AgentSupport;Ljava/lang/String;Lcom/agentclientprotocol/common/SessionCreationParameters;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

public final class com/agentclientprotocol/client/Client {
Expand All @@ -91,6 +94,7 @@ public final class com/agentclientprotocol/client/Client {
public static synthetic fun initialize$default (Lcom/agentclientprotocol/client/Client;Lcom/agentclientprotocol/client/ClientInfo;Lkotlinx/serialization/json/JsonElement;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public final fun loadSession-wPMwmcM (Ljava/lang/String;Lcom/agentclientprotocol/common/SessionCreationParameters;Lcom/agentclientprotocol/client/ClientOperationsFactory;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun newSession (Lcom/agentclientprotocol/common/SessionCreationParameters;Lcom/agentclientprotocol/client/ClientOperationsFactory;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun resumeSession-wPMwmcM (Ljava/lang/String;Lcom/agentclientprotocol/common/SessionCreationParameters;Lcom/agentclientprotocol/client/ClientOperationsFactory;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

public final class com/agentclientprotocol/client/ClientInfo {
Expand Down
10 changes: 10 additions & 0 deletions acp/src/commonMain/kotlin/com/agentclientprotocol/agent/Agent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,16 @@ public class Agent(
models = session.asModelState()
)
}

protocol.setRequestHandler(AcpMethod.AgentMethods.SessionResume) { params: ResumeSessionRequest ->
val sessionParameters = SessionCreationParameters(params.cwd, params.mcpServers, params._meta)
val session = createSession(sessionParameters) { agentSupport.resumeSession(params.sessionId, sessionParameters) }
return@setRequestHandler ResumeSessionResponse(
modes = session.asModeState(),
models = session.asModelState()
)
}

protocol.setRequestHandler(AcpMethod.AgentMethods.SessionSetMode) { params: SetSessionModeRequest ->
val session = getSessionOrThrow(params.sessionId)
return@setRequestHandler session.executeWithSession {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.agentclientprotocol.agent

import com.agentclientprotocol.annotations.UnstableApi
import com.agentclientprotocol.client.ClientInfo
import com.agentclientprotocol.common.SessionCreationParameters
import com.agentclientprotocol.model.AuthMethodId
Expand All @@ -12,4 +13,18 @@ public interface AgentSupport {
public suspend fun authenticate(methodId: AuthMethodId, _meta: JsonElement?): AuthenticateResponse = AuthenticateResponse()
public suspend fun createSession(sessionParameters: SessionCreationParameters): AgentSession
public suspend fun loadSession(sessionId: SessionId, sessionParameters: SessionCreationParameters): AgentSession

/**
* **UNSTABLE**
*
* This capability is not part of the spec yet, and may be removed or changed at any point.
*
* Resumes an existing session without returning previous messages.
*
* This method is only available if the agent advertises the `session.resume` capability.
*/
@UnstableApi
public suspend fun resumeSession(sessionId: SessionId, sessionParameters: SessionCreationParameters): AgentSession {
throw NotImplementedError("Must be implemented by agent when advertising session.resume capability")
}
}
31 changes: 31 additions & 0 deletions acp/src/commonMain/kotlin/com/agentclientprotocol/client/Client.kt
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,37 @@ public class Client(
}
}

/**
* **UNSTABLE**
*
* This capability is not part of the spec yet, and may be removed or changed at any point.
*
* Resume an existing session without returning previous messages.
*
* This method is only available if the agent advertises the `session.resume` capability.
*
* @param sessionId the id of the existing session to resume
* @param sessionParameters parameters for resuming the session
* @param operationsFactory a factory for creating [com.agentclientprotocol.common.ClientSessionOperations] for the session.
* A created object must also implement the necessary interfaces in the case when the client declares extra capabilities like file system or terminal support.
* See [ClientOperationsFactory.createClientOperations] for more details.
* @return a [ClientSession] instance for the resumed session
*/
public suspend fun resumeSession(sessionId: SessionId, sessionParameters: SessionCreationParameters, operationsFactory: ClientOperationsFactory): ClientSession {
return withInitializingSession {
val resumeSessionResponse = AcpMethod.AgentMethods.SessionResume(
protocol,
ResumeSessionRequest(
sessionId,
sessionParameters.cwd,
sessionParameters.mcpServers,
sessionParameters._meta
)
)
return@withInitializingSession createSession(sessionId, sessionParameters, resumeSessionResponse, operationsFactory)
}
}

private suspend fun createSession(sessionId: SessionId, sessionParameters: SessionCreationParameters, sessionResponse: AcpCreatedSessionResponse, factory: ClientOperationsFactory): ClientSession {
val sessionDeferred = CompletableDeferred<ClientSessionImpl>()
return runCatching {
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {
private val buildNumber: String? = System.getenv("GITHUB_RUN_NUMBER")
private val isReleasePublication = System.getenv("RELEASE_PUBLICATION")?.toBoolean() ?: false

private val baseVersion = "0.10.5"
private val baseVersion = "0.11.0"

allprojects {
group = "com.agentclientprotocol"
Expand Down
Loading