refactor(#1375): typed params for approval.* and session.active_list (#1385)

This commit is contained in:
m57 authored and GitHub committed 2026-09-29 18:51:02 +03:00
1 parent c5b34ff471
commit 717b5b0361
11 files changed
+611 -63

No files matched your search

@@ -3,6 +3,8 @@ package com.m57.hermescontrol.data.ws
import com.m57.hermescontrol.data.model.ActiveSessionsResponse
import com.m57.hermescontrol.data.model.LiveSessionSnapshot
import com.m57.hermescontrol.data.model.SessionLiveStatus
import com.m57.hermescontrol.data.ws.contract.RpcMethods
import com.m57.hermescontrol.data.ws.contract.SessionActiveListParams
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
@@ -148,8 +150,8 @@ object SessionLiveStatusDecoder {
* Production implementation of [SessionLiveStatusSource] backed by [HermesWsClient].
*/
class HermesSessionLiveStatusSource(
private val rpcRequest: suspend (method: String, params: Map<String, Any>) -> Any? = { method, params ->
HermesWsClient.request(method, params).await()
private val rpcRequest: suspend () -> Any? = {
HermesWsClient.call(RpcMethods.SESSION_ACTIVE_LIST, SessionActiveListParams())
},
eventsProvider: () -> Flow<WsEvent> = { HermesWsClient.events },
connectionStatusProvider: () -> StateFlow<ConnectionStatus> = { HermesWsClient.connectionStatus },
@@ -159,7 +161,7 @@ class HermesSessionLiveStatusSource(
override suspend fun fetchActiveSessionsSnapshot(): LiveSessionSnapshot? =
try {
val raw = rpcRequest(WsMethods.SESSION_ACTIVE_LIST, emptyMap())
val raw = rpcRequest()
SessionLiveStatusDecoder.decodeSnapshot(raw)
} catch (e: CancellationException) {
throw e
@@ -0,0 +1,28 @@
package com.m57.hermescontrol.data.ws.contract
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class ApprovalPendingParams(
@SerialName("session_id") val sessionId: String,
)
@Serializable
data class ApprovalReceivedParams(
@SerialName("session_id") val sessionId: String,
@SerialName("request_id") val requestId: String,
)
@Serializable
data class ApprovalRespondParams(
@SerialName("session_id") val sessionId: String,
@SerialName("choice") val choice: String? = null,
@SerialName("all") val all: Boolean? = null,
@SerialName("request_id") val requestId: String? = null,
)
@Serializable
data class SessionActiveListParams(
@SerialName("current_session_id") val currentSessionId: String? = null,
)
@@ -10,6 +10,14 @@ class RpcMethod<P, R>(
val result: KSerializer<R>,
)
interface TypedRpcSender {
fun <P> send(
method: RpcMethod<P, *>,
params: P,
onSent: ((String) -> Unit)? = null,
): String
}
object RpcMethods {
val SESSION_EVENTS_SINCE: RpcMethod<SessionEventsSinceParams, SessionEventsSinceResult> =
RpcMethod(
@@ -110,6 +118,38 @@ object RpcMethods {
PromptBtwResult.serializer(),
)
// Passthrough JsonElement results: callers keep their existing legacy parsers.
val APPROVAL_PENDING: RpcMethod<ApprovalPendingParams, JsonElement> =
RpcMethod(
WsMethods.APPROVAL_PENDING,
ApprovalPendingParams.serializer(),
JsonElement.serializer(),
)
// Passthrough JsonElement results: callers keep their existing legacy parsers.
val APPROVAL_RECEIVED: RpcMethod<ApprovalReceivedParams, JsonElement> =
RpcMethod(
WsMethods.APPROVAL_RECEIVED,
ApprovalReceivedParams.serializer(),
JsonElement.serializer(),
)
// Passthrough JsonElement results: callers keep their existing legacy parsers.
val APPROVAL_RESPOND: RpcMethod<ApprovalRespondParams, JsonElement> =
RpcMethod(
WsMethods.APPROVAL_RESPOND,
ApprovalRespondParams.serializer(),
JsonElement.serializer(),
)
// Passthrough JsonElement results: callers keep their existing legacy parsers.
val SESSION_ACTIVE_LIST: RpcMethod<SessionActiveListParams, JsonElement> =
RpcMethod(
WsMethods.SESSION_ACTIVE_LIST,
SessionActiveListParams.serializer(),
JsonElement.serializer(),
)
/** Every typed method. GatewayContractTest iterates this; future migrations append here. */
val all: List<RpcMethod<*, *>> =
listOf(
@@ -127,5 +167,9 @@ object RpcMethods {
SESSION_CONTEXT_BREAKDOWN,
SESSION_USAGE,
PROMPT_BTW,
APPROVAL_PENDING,
APPROVAL_RECEIVED,
APPROVAL_RESPOND,
SESSION_ACTIVE_LIST,
)
}