feat(plugins): memory provider config & setup management (issue #783) (#834)

* feat(plugins): memory provider config & setup management (issue #783)

* fix(memory): remove top padding on provider detail screen

---------

Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
M57andM57 authored and GitHub committed 2026-08-07 04:18:50 +03:00
1 parent 4645a2b6e7
commit fd5d851405
10 files changed
+1144

No files matched your search

@@ -0,0 +1,101 @@
package com.m57.hermescontrol.data.model
import kotlinx.serialization.Serializable
/** A memory provider row as reported by `GET /api/memory` (issue #783). */
@Serializable
data class MemoryProviderStatusRow(
val name: String = "",
val description: String = "",
val available: Boolean = false,
val configured: Boolean = false,
val status: String = "",
val setup: MemoryProviderSetupInfo? = null,
)
/** Setup manifest for a memory provider (pip deps, external deps, env). */
@Serializable
data class MemoryProviderSetupInfo(
val pip_dependencies: List<String> = emptyList(),
val external_dependencies: List<MemoryProviderExternalDependency> = emptyList(),
val required_env: List<String> = emptyList(),
val dependencies_installed: Boolean? = null,
)
@Serializable
data class MemoryProviderExternalDependency(
val name: String = "",
val install: String = "",
val check: String = "",
)
/** Per-provider config surface from `GET /api/memory/providers/{name}/config`. */
@Serializable
data class MemoryProviderConfigResponse(
val name: String = "",
val label: String = "",
val docs_url: String = "",
val fields: List<MemoryProviderField> = emptyList(),
val setup: MemoryProviderSetupInfo? = null,
)
@Serializable
data class MemoryProviderField(
val description: String = "",
val group: String = "",
val info: String? = null,
val inline: Boolean = false,
val is_set: Boolean = false,
val key: String = "",
val kind: String = "text",
val label: String = "",
val options: List<MemoryProviderFieldOption> = emptyList(),
val placeholder: String = "",
val value: String = "",
)
@Serializable
data class MemoryProviderFieldOption(
val description: String = "",
val label: String = "",
val value: String = "",
)
@Serializable
data class MemoryProviderConfigUpdateRequest(
val values: Map<String, String> = emptyMap(),
)
@Serializable
data class MemoryProviderConfigUpdateResponse(
val ok: Boolean = false,
val active: String? = null,
)
@Serializable
data class MemoryProviderSetupRequest(
val values: Map<String, String> = emptyMap(),
)
/** Result of `POST /api/memory/providers/{name}/setup` — synchronous, no polling. */
@Serializable
data class MemoryProviderSetupResponse(
val ok: Boolean = false,
val provider: String = "",
val results: List<MemoryProviderSetupResult> = emptyList(),
val status: MemoryProviderStatusRow? = null,
)
@Serializable
data class MemoryProviderSetupResult(
val kind: String = "",
val name: String = "",
val status: String = "",
val command: String = "",
val returncode: Int? = null,
val stdout: String = "",
val stderr: String = "",
) {
val succeeded: Boolean
get() = status != "failed"
}
@@ -5,6 +5,7 @@ import kotlinx.serialization.Serializable
data class MemoryResponse(
val active: String? = null,
val builtin_files: BuiltinFileSizes? = null,
val providers: List<MemoryProviderStatusRow> = emptyList(),
)
@Serializable
@@ -50,6 +50,11 @@ import com.m57.hermescontrol.data.model.McpOAuthFlowResponse
import com.m57.hermescontrol.data.model.McpServer
import com.m57.hermescontrol.data.model.McpServerToggleRequest
import com.m57.hermescontrol.data.model.McpServersResponse
import com.m57.hermescontrol.data.model.MemoryProviderConfigResponse
import com.m57.hermescontrol.data.model.MemoryProviderConfigUpdateRequest
import com.m57.hermescontrol.data.model.MemoryProviderConfigUpdateResponse
import com.m57.hermescontrol.data.model.MemoryProviderSetupRequest
import com.m57.hermescontrol.data.model.MemoryProviderSetupResponse
import com.m57.hermescontrol.data.model.MemoryResponse
import com.m57.hermescontrol.data.model.MessagingPlatformResponse
import com.m57.hermescontrol.data.model.MessagingPlatformTestResult
@@ -806,6 +811,23 @@ interface HermesApiService {
@GET("api/memory")
suspend fun getMemory(): Response<MemoryResponse>
@GET("api/memory/providers/{name}/config")
suspend fun getMemoryProviderConfig(
@Path("name") name: String,
): Response<MemoryProviderConfigResponse>
@PUT("api/memory/providers/{name}/config")
suspend fun updateMemoryProviderConfig(
@Path("name") name: String,
@Body body: MemoryProviderConfigUpdateRequest,
): Response<MemoryProviderConfigUpdateResponse>
@POST("api/memory/providers/{name}/setup")
suspend fun setupMemoryProvider(
@Path("name") name: String,
@Body body: MemoryProviderSetupRequest,
): Response<MemoryProviderSetupResponse>
@POST("api/memory/reset")
suspend fun resetMemory(
@Body body: Map<String, String>,