feat(#441): add profile cloning and description editing (#463)

* feat(#441): add profile cloning and description editing

* feat(#441): add profile builder wizard and API enhancements

Introduce 5-step Profile Builder wizard into ProfilesScreen and add support for create/clone endpoints.

* fix(#441): restore imports and add ProfileInfo constructor defaults

* style: run ktlint format on codebase to fix styling errors

* fix(#441): address PR review comments including provider slug bug, validation, and strings

* fix(#441): remove unused McpServerConfigInput import

---------

Co-authored-by: Hermes Agent <hermes@agent.local>
This commit is contained in:
M57andHermes Agent authored and GitHub committed 2026-07-03 22:24:42 +03:00
1 parent 846a9380e2
commit d181851670
37 files changed
+2299 -448

No files matched your search

@@ -305,7 +305,8 @@ private fun ModelSettingsSection(
) {
val auxOverrideCount =
auxTasks?.let { tasks ->
tasks.filterIsInstance<com.m57.hermescontrol.data.model.AuxiliaryTaskAssignment>()
tasks
.filterIsInstance<com.m57.hermescontrol.data.model.AuxiliaryTaskAssignment>()
.count { a -> a.provider.isNotBlank() && a.provider != "auto" }
} ?: 0
@@ -700,7 +701,9 @@ private fun MoaConfigDialog(
}
private sealed class MoaPickerTarget {
data class Reference(val index: Int) : MoaPickerTarget()
data class Reference(
val index: Int,
) : MoaPickerTarget()
data object Aggregator : MoaPickerTarget()
}
@@ -947,14 +950,18 @@ private fun MoaSlotPicker(
com.m57.hermescontrol.data.model.MoaConfigPreset,
) -> com.m57.hermescontrol.data.model.MoaConfigPreset = { preset ->
when (pickerTarget) {
is MoaPickerTarget.Aggregator -> preset.copy(aggregator = slot)
is MoaPickerTarget.Reference ->
is MoaPickerTarget.Aggregator -> {
preset.copy(aggregator = slot)
}
is MoaPickerTarget.Reference -> {
preset.copy(
reference_models =
preset.reference_models.toMutableList().also {
it[pickerTarget.index] = slot
},
)
}
}
}
val preset = draft.presets[selectedPreset]
@@ -152,6 +152,7 @@ class ModelViewModel :
)
}
}
is NetworkResult.Failure -> {
_uiState.update {
it.copy(
@@ -224,6 +225,7 @@ class ModelViewModel :
loadAll()
}
}
is NetworkResult.Failure -> {
_uiState.update {
it.copy(
@@ -265,6 +267,7 @@ class ModelViewModel :
}
loadAll()
}
is NetworkResult.Failure -> {
_uiState.update {
it.copy(
@@ -340,6 +343,7 @@ class ModelViewModel :
}
loadAll()
}
is NetworkResult.Failure -> {
_uiState.update {
it.copy(
@@ -375,6 +379,7 @@ class ModelViewModel :
}
loadAll()
}
is NetworkResult.Failure -> {
_uiState.update {
it.copy(
@@ -417,6 +422,7 @@ class ModelViewModel :
)
}
}
is NetworkResult.Failure -> {
_uiState.update {
it.copy(
@@ -450,6 +456,7 @@ class ModelViewModel :
}
return@launch
}
is NetworkResult.Success -> {
val activeProfileName = activeProfileNameResResult.data.active
val updateResResult =
@@ -466,6 +473,7 @@ class ModelViewModel :
_uiState.update { it.copy(toastMessage = "Successfully set profile model to $modelName") }
loadAll()
}
is NetworkResult.Failure -> {
_uiState.update {
it.copy(