This commit is contained in:
7 files changed
+164
-82
No files matched your search
@@ -0,0 +1,16 @@
|
||||
package com.m57.hermescontrol.data.ws.contract
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
|
||||
/**
|
||||
* `profiles.configure` params for the sections the app writes: `ui_meta` and the bot `soul`.
|
||||
* `profile` is not a field: WsProfileParams injects it when the method is profile scoped.
|
||||
*/
|
||||
@Serializable
|
||||
data class ProfilesConfigureParams(
|
||||
@SerialName("name") val name: String? = null,
|
||||
@SerialName("ui_meta") val uiMeta: JsonObject? = null,
|
||||
@SerialName("soul") val soul: String? = null,
|
||||
)
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.m57.hermescontrol.data.ws.contract
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/** `profiles.list` takes no explicit params here; the active profile is injected by WsProfileParams. */
|
||||
@Serializable
|
||||
data object ProfilesListParams
|
||||
@@ -379,6 +379,22 @@ object RpcMethods {
|
||||
JsonElement.serializer(),
|
||||
)
|
||||
|
||||
// Passthrough JsonElement results: callers keep their existing legacy decoders.
|
||||
val PROFILES_LIST: RpcMethod<ProfilesListParams, JsonElement> =
|
||||
RpcMethod(
|
||||
WsMethods.PROFILES_LIST,
|
||||
ProfilesListParams.serializer(),
|
||||
JsonElement.serializer(),
|
||||
)
|
||||
|
||||
// Passthrough JsonElement results: callers keep their existing legacy decoders.
|
||||
val PROFILES_CONFIGURE: RpcMethod<ProfilesConfigureParams, JsonElement> =
|
||||
RpcMethod(
|
||||
WsMethods.PROFILES_CONFIGURE,
|
||||
ProfilesConfigureParams.serializer(),
|
||||
JsonElement.serializer(),
|
||||
)
|
||||
|
||||
/** Every typed method. GatewayContractTest iterates this; future migrations append here. */
|
||||
val all: List<RpcMethod<*, *>> =
|
||||
listOf(
|
||||
@@ -428,5 +444,7 @@ object RpcMethods {
|
||||
PROCESS_KILL,
|
||||
PLUGINS_MANAGE,
|
||||
PROJECTS_LIST,
|
||||
PROFILES_LIST,
|
||||
PROFILES_CONFIGURE,
|
||||
)
|
||||
}
|
||||
@@ -16,7 +16,9 @@ import com.m57.hermescontrol.data.remote.OkHttpProvider
|
||||
import com.m57.hermescontrol.data.remote.safeApiCall
|
||||
import com.m57.hermescontrol.data.session.ProfileSwitchCoordinator
|
||||
import com.m57.hermescontrol.data.ws.HermesWsClient
|
||||
import com.m57.hermescontrol.data.ws.WsMethods
|
||||
import com.m57.hermescontrol.data.ws.contract.ProfilesConfigureParams
|
||||
import com.m57.hermescontrol.data.ws.contract.ProfilesListParams
|
||||
import com.m57.hermescontrol.data.ws.contract.RpcMethods
|
||||
import com.m57.hermescontrol.data.ws.toJsonElement
|
||||
import com.m57.hermescontrol.ui.common.ToastHost
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
@@ -29,6 +31,8 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.JsonNull
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import kotlinx.serialization.json.decodeFromJsonElement
|
||||
|
||||
@@ -243,14 +247,8 @@ class BotsViewModel(
|
||||
// First try fetching profiles via WebSocket RPC (profiles.list) which includes ui_meta (groups, custom avatars).
|
||||
var profilesWithMeta: List<ProfileInfo>? = null
|
||||
try {
|
||||
val rpcResult = HermesWsClient.request(WsMethods.PROFILES_LIST).await()
|
||||
val jsonElement =
|
||||
when (rpcResult) {
|
||||
is JsonElement -> rpcResult
|
||||
null -> null
|
||||
else -> rpcResult.toJsonElement()
|
||||
}
|
||||
if (jsonElement != null) {
|
||||
val jsonElement = HermesWsClient.call(RpcMethods.PROFILES_LIST, ProfilesListParams)
|
||||
if (jsonElement !is JsonNull) {
|
||||
val resp = OkHttpProvider.json.decodeFromJsonElement<ProfilesResponse>(jsonElement)
|
||||
if (!resp.profiles.isNullOrEmpty()) {
|
||||
profilesWithMeta = resp.profiles
|
||||
@@ -362,7 +360,13 @@ class BotsViewModel(
|
||||
),
|
||||
)
|
||||
val botSoul = composeBotSoul(name, title, description)
|
||||
wsClientConfigureBot(name, botMeta, soul = botSoul)
|
||||
// Fire-and-forget as before: the metadata write never gated the reload or onSuccess.
|
||||
launch {
|
||||
try {
|
||||
wsClientConfigureBot(name, botMeta, soul = botSoul)
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
}
|
||||
loadBots()
|
||||
onSuccess()
|
||||
} else {
|
||||
@@ -396,7 +400,7 @@ class BotsViewModel(
|
||||
),
|
||||
)
|
||||
try {
|
||||
wsClientConfigureBot(name, updatedMeta).await()
|
||||
wsClientConfigureBot(name, updatedMeta)
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
loadBots()
|
||||
@@ -440,7 +444,7 @@ class BotsViewModel(
|
||||
group = existingGroups.firstOrNull() ?: groupName,
|
||||
)
|
||||
try {
|
||||
wsClientConfigureBot(name, updatedMeta).await()
|
||||
wsClientConfigureBot(name, updatedMeta)
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
}
|
||||
@@ -475,14 +479,13 @@ class BotsViewModel(
|
||||
rooms = updatedRooms,
|
||||
deleted = updatedDeleted,
|
||||
)
|
||||
HermesWsClient
|
||||
.request(
|
||||
WsMethods.PROFILES_CONFIGURE,
|
||||
mapOf(
|
||||
"name" to defaultProfile.name,
|
||||
"ui_meta" to mapOf("hermes-bots-groups" to newSnapshot.toMap()),
|
||||
),
|
||||
).await()
|
||||
HermesWsClient.call(
|
||||
RpcMethods.PROFILES_CONFIGURE,
|
||||
ProfilesConfigureParams(
|
||||
name = defaultProfile.name,
|
||||
uiMeta = mapOf("hermes-bots-groups" to newSnapshot.toMap()).toJsonObject(),
|
||||
),
|
||||
)
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
@@ -509,7 +512,7 @@ class BotsViewModel(
|
||||
group = filtered.firstOrNull(),
|
||||
)
|
||||
try {
|
||||
wsClientConfigureBot(bot.name, updatedMeta).await()
|
||||
wsClientConfigureBot(bot.name, updatedMeta)
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
}
|
||||
@@ -540,14 +543,13 @@ class BotsViewModel(
|
||||
rooms = updatedRooms,
|
||||
deleted = deletedMap,
|
||||
)
|
||||
HermesWsClient
|
||||
.request(
|
||||
WsMethods.PROFILES_CONFIGURE,
|
||||
mapOf(
|
||||
"name" to defaultProfile.name,
|
||||
"ui_meta" to mapOf("hermes-bots-groups" to newSnapshot.toMap()),
|
||||
),
|
||||
).await()
|
||||
HermesWsClient.call(
|
||||
RpcMethods.PROFILES_CONFIGURE,
|
||||
ProfilesConfigureParams(
|
||||
name = defaultProfile.name,
|
||||
uiMeta = mapOf("hermes-bots-groups" to newSnapshot.toMap()).toJsonObject(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
@@ -575,11 +577,11 @@ class BotsViewModel(
|
||||
return lines.joinToString("\n")
|
||||
}
|
||||
|
||||
private fun wsClientConfigureBot(
|
||||
private suspend fun wsClientConfigureBot(
|
||||
name: String,
|
||||
meta: BotRosterMeta,
|
||||
soul: String? = null,
|
||||
): kotlinx.coroutines.CompletableDeferred<Any?> {
|
||||
) {
|
||||
val metaMap =
|
||||
buildMap<String, Any> {
|
||||
meta.title?.let { put("title", it) }
|
||||
@@ -599,16 +601,15 @@ class BotsViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
val params =
|
||||
buildMap<String, Any> {
|
||||
put("name", name)
|
||||
put("ui_meta", mapOf("hermes-bots" to metaMap))
|
||||
soul?.let { put("soul", it) }
|
||||
}
|
||||
|
||||
return HermesWsClient.request(
|
||||
WsMethods.PROFILES_CONFIGURE,
|
||||
params,
|
||||
HermesWsClient.call(
|
||||
RpcMethods.PROFILES_CONFIGURE,
|
||||
ProfilesConfigureParams(
|
||||
name = name,
|
||||
uiMeta = mapOf("hermes-bots" to metaMap).toJsonObject(),
|
||||
soul = soul,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun Map<String, Any?>.toJsonObject(): JsonObject = toJsonElement() as JsonObject
|
||||
}
|
||||
@@ -16,7 +16,8 @@ import com.m57.hermescontrol.data.remote.safeApiCall
|
||||
import com.m57.hermescontrol.data.session.ActiveSessionHolder
|
||||
import com.m57.hermescontrol.data.ws.HermesWsClient
|
||||
import com.m57.hermescontrol.data.ws.WsEvent
|
||||
import com.m57.hermescontrol.data.ws.WsMethods
|
||||
import com.m57.hermescontrol.data.ws.contract.ProfilesConfigureParams
|
||||
import com.m57.hermescontrol.data.ws.contract.ProfilesListParams
|
||||
import com.m57.hermescontrol.data.ws.contract.PromptSubmitParams
|
||||
import com.m57.hermescontrol.data.ws.contract.RpcMethods
|
||||
import com.m57.hermescontrol.data.ws.contract.SessionCreateParams
|
||||
@@ -34,6 +35,8 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.JsonNull
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import kotlinx.serialization.json.decodeFromJsonElement
|
||||
import java.util.UUID
|
||||
@@ -327,14 +330,8 @@ class GroupChatViewModel(
|
||||
|
||||
private suspend fun fetchProfiles(): List<ProfileInfo> {
|
||||
try {
|
||||
val rpcResult = HermesWsClient.request(WsMethods.PROFILES_LIST).await()
|
||||
val jsonElement =
|
||||
when (rpcResult) {
|
||||
is JsonElement -> rpcResult
|
||||
null -> null
|
||||
else -> rpcResult.toJsonElement()
|
||||
}
|
||||
if (jsonElement != null) {
|
||||
val jsonElement = HermesWsClient.call(RpcMethods.PROFILES_LIST, ProfilesListParams)
|
||||
if (jsonElement !is JsonNull) {
|
||||
val resp = json.decodeFromJsonElement<ProfilesResponse>(jsonElement)
|
||||
if (!resp.profiles.isNullOrEmpty()) {
|
||||
return resp.profiles
|
||||
@@ -534,14 +531,13 @@ class GroupChatViewModel(
|
||||
|
||||
val uiMetaPayload = mapOf("hermes-bots-groups" to newSnapshot.toMap())
|
||||
|
||||
HermesWsClient
|
||||
.request(
|
||||
WsMethods.PROFILES_CONFIGURE,
|
||||
mapOf(
|
||||
"name" to defaultProfile.name,
|
||||
"ui_meta" to uiMetaPayload,
|
||||
),
|
||||
).await()
|
||||
HermesWsClient.call(
|
||||
RpcMethods.PROFILES_CONFIGURE,
|
||||
ProfilesConfigureParams(
|
||||
name = defaultProfile.name,
|
||||
uiMeta = uiMetaPayload.toJsonElement() as JsonObject,
|
||||
),
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.w("GroupChatViewModel", "updateGroupLimits failed: ${e.message}")
|
||||
}
|
||||
@@ -636,14 +632,13 @@ class GroupChatViewModel(
|
||||
val newSnapshot = existingSnapshot.copy(version = 3, updatedAt = now, rooms = updatedRooms)
|
||||
val uiMetaPayload = mapOf("hermes-bots-groups" to newSnapshot.toMap())
|
||||
|
||||
HermesWsClient
|
||||
.request(
|
||||
WsMethods.PROFILES_CONFIGURE,
|
||||
mapOf(
|
||||
"name" to defaultProfile.name,
|
||||
"ui_meta" to uiMetaPayload,
|
||||
),
|
||||
).await()
|
||||
HermesWsClient.call(
|
||||
RpcMethods.PROFILES_CONFIGURE,
|
||||
ProfilesConfigureParams(
|
||||
name = defaultProfile.name,
|
||||
uiMeta = uiMetaPayload.toJsonElement() as JsonObject,
|
||||
),
|
||||
)
|
||||
|
||||
return true
|
||||
} catch (e: Exception) {
|
||||
@@ -1193,14 +1188,13 @@ class GroupChatViewModel(
|
||||
|
||||
val uiMetaPayload = mapOf("hermes-bots-groups" to newSnapshot.toMap())
|
||||
|
||||
HermesWsClient
|
||||
.request(
|
||||
WsMethods.PROFILES_CONFIGURE,
|
||||
mapOf(
|
||||
"name" to defaultProfile.name,
|
||||
"ui_meta" to uiMetaPayload,
|
||||
),
|
||||
).await()
|
||||
HermesWsClient.call(
|
||||
RpcMethods.PROFILES_CONFIGURE,
|
||||
ProfilesConfigureParams(
|
||||
name = defaultProfile.name,
|
||||
uiMeta = uiMetaPayload.toJsonElement() as JsonObject,
|
||||
),
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.w("GroupChatViewModel", "persistSyncSnapshot failed: ${e.message}")
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user