Skip to content

Commit e372f59

Browse files
committed
Support custom acp JsonRpc error codes (AUTH_REQUIRED and RESOURCE_NOT_FOUND)
1 parent 99dcc7c commit e372f59

4 files changed

Lines changed: 56 additions & 30 deletions

File tree

acp-ktor-test/src/commonTest/kotlin/com/agentclientprotocol/ProtocolTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ abstract class ProtocolTest(protocolDriver: ProtocolDriver) : ProtocolDriver by
241241
}
242242
catch (e: JsonRpcException) {
243243
assertEquals(errorMessage, e.message, "Error message should be propagated to client")
244-
assertEquals(JsonRpcErrorCode.INTERNAL_ERROR, e.code, "Error code should be INTERNAL_ERROR")
244+
assertEquals(JsonRpcErrorCode.INTERNAL_ERROR.code, e.code, "Error code should be INTERNAL_ERROR")
245245
}
246246
}
247247

@@ -290,7 +290,7 @@ abstract class ProtocolTest(protocolDriver: ProtocolDriver) : ProtocolDriver by
290290
fail("Expected JsonRpcException to be thrown")
291291
}
292292
catch (e: JsonRpcException) {
293-
assertEquals(JsonRpcErrorCode.METHOD_NOT_FOUND, e.code, "Error code should be METHOD_NOT_FOUND")
293+
assertEquals(JsonRpcErrorCode.METHOD_NOT_FOUND.code, e.code, "Error code should be METHOD_NOT_FOUND")
294294
}
295295
}
296296
}

acp-model/api/acp-model.api

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3101,14 +3101,20 @@ public final class com/agentclientprotocol/rpc/JsonRpcError$Companion {
31013101
public final fun serializer ()Lkotlinx/serialization/KSerializer;
31023102
}
31033103

3104-
public final class com/agentclientprotocol/rpc/JsonRpcErrorCode {
3105-
public static final field CANCELLED I
3106-
public static final field INSTANCE Lcom/agentclientprotocol/rpc/JsonRpcErrorCode;
3107-
public static final field INTERNAL_ERROR I
3108-
public static final field INVALID_PARAMS I
3109-
public static final field INVALID_REQUEST I
3110-
public static final field METHOD_NOT_FOUND I
3111-
public static final field PARSE_ERROR I
3104+
public final class com/agentclientprotocol/rpc/JsonRpcErrorCode : java/lang/Enum {
3105+
public static final field AUTH_REQUIRED Lcom/agentclientprotocol/rpc/JsonRpcErrorCode;
3106+
public static final field CANCELLED Lcom/agentclientprotocol/rpc/JsonRpcErrorCode;
3107+
public static final field INTERNAL_ERROR Lcom/agentclientprotocol/rpc/JsonRpcErrorCode;
3108+
public static final field INVALID_PARAMS Lcom/agentclientprotocol/rpc/JsonRpcErrorCode;
3109+
public static final field INVALID_REQUEST Lcom/agentclientprotocol/rpc/JsonRpcErrorCode;
3110+
public static final field METHOD_NOT_FOUND Lcom/agentclientprotocol/rpc/JsonRpcErrorCode;
3111+
public static final field PARSE_ERROR Lcom/agentclientprotocol/rpc/JsonRpcErrorCode;
3112+
public static final field RESOURCE_NOT_FOUND Lcom/agentclientprotocol/rpc/JsonRpcErrorCode;
3113+
public final fun getCode ()I
3114+
public static fun getEntries ()Lkotlin/enums/EnumEntries;
3115+
public final fun getMessage ()Ljava/lang/String;
3116+
public static fun valueOf (Ljava/lang/String;)Lcom/agentclientprotocol/rpc/JsonRpcErrorCode;
3117+
public static fun values ()[Lcom/agentclientprotocol/rpc/JsonRpcErrorCode;
31123118
}
31133119

31143120
public final class com/agentclientprotocol/rpc/JsonRpcKt {

acp-model/src/commonMain/kotlin/com/agentclientprotocol/rpc/JsonRpc.kt

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,34 @@ public data class JsonRpcError(
7676
/**
7777
* Standard JSON-RPC error codes.
7878
*/
79-
public object JsonRpcErrorCode {
80-
public const val PARSE_ERROR: Int = -32700
81-
public const val INVALID_REQUEST: Int = -32600
82-
public const val METHOD_NOT_FOUND: Int = -32601
83-
public const val INVALID_PARAMS: Int = -32602
84-
public const val INTERNAL_ERROR: Int = -32603
85-
// The same code as in LSP
86-
public const val CANCELLED: Int = -32800
79+
public enum class JsonRpcErrorCode(public val code: Int, public val message: String) {
80+
/** Invalid JSON was received by the server.
81+
* An error occurred on the server while parsing the JSON text. */
82+
PARSE_ERROR(-32700, "Parse error"),
83+
84+
/** The JSON sent is not a valid Request object. */
85+
INVALID_REQUEST(-32600, "Invalid Request"),
86+
87+
/** The method does not exist or is not available. */
88+
METHOD_NOT_FOUND(-32601, "Method not found"),
89+
90+
/** Invalid method parameter(s). */
91+
INVALID_PARAMS(-32602, "Invalid params"),
92+
93+
/** Internal JSON-RPC error.
94+
* Reserved for implementation-defined server errors. */
95+
INTERNAL_ERROR(-32603, "Internal error"),
96+
97+
/** The same code as in LSP */
98+
CANCELLED(-32800, "Request cancelled"),
99+
100+
/** Authentication is required before this operation can be performed.
101+
* This is an ACP-specific error code in the reserved range. */
102+
AUTH_REQUIRED(-32000, "Authentication required"),
103+
104+
/** A given resource, such as a file, was not found.
105+
* This is an ACP-specific error code in the reserved range. */
106+
RESOURCE_NOT_FOUND(-32002, "Resource not found")
87107
}
88108

89109
@OptIn(ExperimentalSerializationApi::class)

acp/src/commonMain/kotlin/com/agentclientprotocol/protocol/Protocol.kt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public class AcpExpectedError(override val message: String) : Exception(message)
4444
public fun acpFail(message: String): Nothing = throw AcpExpectedError(message)
4545

4646
public fun jsonRpcMethodNotFound(message: String): Nothing =
47-
throw JsonRpcException(JsonRpcErrorCode.METHOD_NOT_FOUND, message)
47+
throw JsonRpcException(JsonRpcErrorCode.METHOD_NOT_FOUND.code, message)
4848

4949
/**
5050
* Exception thrown for JSON-RPC protocol errors.
@@ -380,17 +380,17 @@ public class Protocol(
380380
logger.trace(e) { "Expected error on '${request.method}'" }
381381
sendResponse(
382382
request.id, null, JsonRpcError(
383-
code = JsonRpcErrorCode.INVALID_PARAMS, message = e.message ?: "Invalid params"
383+
code = JsonRpcErrorCode.INVALID_PARAMS.code, message = e.message
384384
)
385385
)
386386
} catch (e: JsonRpcException) {
387387
logger.trace(e) { "JsonRpcException on '${request.method}'" }
388-
sendResponse(request.id, null, JsonRpcError(code = e.code, message = e.message ?: "Internal error", data = e.data))
388+
sendResponse(request.id, null, JsonRpcError(code = e.code, message = e.message, data = e.data))
389389
} catch (e: SerializationException) {
390390
logger.trace(e) { "Serialization error on ${request.method}" }
391391
sendResponse(
392392
request.id, null, JsonRpcError(
393-
code = JsonRpcErrorCode.PARSE_ERROR, message = e.message ?: "Serialization error"
393+
code = JsonRpcErrorCode.PARSE_ERROR.code, message = e.message ?: "Serialization error"
394394
)
395395
)
396396
} catch (ce: CancellationException) {
@@ -399,7 +399,7 @@ public class Protocol(
399399
sendResponse(
400400
request.id, null,
401401
JsonRpcError(
402-
code = JsonRpcErrorCode.CANCELLED,
402+
code = JsonRpcErrorCode.CANCELLED.code,
403403
message = ce.message ?: "Cancelled"
404404
)
405405
)
@@ -408,13 +408,13 @@ public class Protocol(
408408
logger.error(e) { "Exception on ${request.method}" }
409409
sendResponse(
410410
request.id, null, JsonRpcError(
411-
code = JsonRpcErrorCode.INTERNAL_ERROR, message = e.message ?: "Internal error"
411+
code = JsonRpcErrorCode.INTERNAL_ERROR.code, message = e.message ?: "Internal error"
412412
)
413413
)
414414
}
415415
} else {
416416
val error = JsonRpcError(
417-
code = JsonRpcErrorCode.METHOD_NOT_FOUND, message = "Method not supported: ${request.method}"
417+
code = JsonRpcErrorCode.METHOD_NOT_FOUND.code, message = "Method not supported: ${request.method}"
418418
)
419419
sendResponse(request.id, null, error)
420420
}
@@ -483,17 +483,17 @@ public class Protocol(
483483

484484
private fun convertJsonRpcExceptionIfPossible(jsonRpcException: JsonRpcException): Exception {
485485
when (jsonRpcException.code) {
486-
JsonRpcErrorCode.PARSE_ERROR -> {
486+
JsonRpcErrorCode.PARSE_ERROR.code -> {
487487
return SerializationException(jsonRpcException.message, jsonRpcException)
488488
}
489489

490-
JsonRpcErrorCode.INVALID_PARAMS -> {
491-
return AcpExpectedError(jsonRpcException.message ?: "Invalid params")
490+
JsonRpcErrorCode.INVALID_PARAMS.code -> {
491+
return AcpExpectedError(jsonRpcException.message)
492492
}
493493

494-
JsonRpcErrorCode.CANCELLED -> {
494+
JsonRpcErrorCode.CANCELLED.code -> {
495495
return CancellationException(
496-
jsonRpcException.message ?: "Cancelled on the counterpart side",
496+
jsonRpcException.message,
497497
jsonRpcException
498498
)
499499
}

0 commit comments

Comments
 (0)