feat: add setting to toggle model provider visibility in chat composer (#1194)
This commit is contained in:
20 files changed
+204
-32
No files matched your search
@@ -2,6 +2,7 @@ package com.m57.hermescontrol.data.config
|
||||
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
@@ -16,6 +17,7 @@ class ServerStoreTest {
|
||||
assertTrue(state.autoReconnect)
|
||||
assertEquals("token", state.wsAuthParam)
|
||||
assertEquals(1.0f, state.chatFontScale)
|
||||
assertFalse(state.showModelProvider)
|
||||
assertTrue(state.connectionProfiles.isEmpty())
|
||||
assertNull(state.selectedProfileId)
|
||||
}
|
||||
@@ -67,4 +69,12 @@ class ServerStoreTest {
|
||||
assertEquals("127.0.0.1", unselectedState.resolvedHost)
|
||||
assertEquals(9119, unselectedState.resolvedPort)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testShowModelProviderUpdate() {
|
||||
val state = ServerStoreState()
|
||||
assertFalse(state.showModelProvider)
|
||||
val updated = state.copy(showModelProvider = true)
|
||||
assertTrue(updated.showModelProvider)
|
||||
}
|
||||
}
|
||||
@@ -93,6 +93,7 @@ class ChatUpdateCommandTest {
|
||||
every { AuthManager.isUserMessageTokensEnabled() } returns true
|
||||
every { AuthManager.isAssistantMessageTokensEnabled() } returns true
|
||||
every { AuthManager.isTokensPerSecondEnabled() } returns true
|
||||
every { AuthManager.isModelProviderShown() } returns false
|
||||
every { AuthManager.isAutoReconnect() } returns false
|
||||
every { AuthManager.isRestoreLastSession() } returns false
|
||||
every { AuthManager.getLastOpenedSessionId() } returns null
|
||||
|
||||
@@ -171,6 +171,7 @@ class ChatViewModelTest {
|
||||
every { AuthManager.isUserMessageTokensEnabled() } returns true
|
||||
every { AuthManager.isAssistantMessageTokensEnabled() } returns true
|
||||
every { AuthManager.isTokensPerSecondEnabled() } returns true
|
||||
every { AuthManager.isModelProviderShown() } returns false
|
||||
every { AuthManager.isAutoReconnect() } returns false
|
||||
every { AuthManager.isRestoreLastSession() } returns false
|
||||
every { AuthManager.getLastOpenedSessionId() } returns null
|
||||
@@ -4335,6 +4336,7 @@ class ChatViewModelTest {
|
||||
assertTrue(showUserMessageTokens)
|
||||
assertTrue(showAssistantMessageTokens)
|
||||
assertTrue(showTokensPerSecond)
|
||||
assertFalse(showModelProvider)
|
||||
}
|
||||
|
||||
// When settings change after construction and refreshSettings() is re-invoked,
|
||||
@@ -4346,6 +4348,7 @@ class ChatViewModelTest {
|
||||
every { AuthManager.isUserMessageTokensEnabled() } returns false
|
||||
every { AuthManager.isAssistantMessageTokensEnabled() } returns false
|
||||
every { AuthManager.isTokensPerSecondEnabled() } returns false
|
||||
every { AuthManager.isModelProviderShown() } returns true
|
||||
viewModel.refreshSettings()
|
||||
advanceUntilIdle()
|
||||
|
||||
@@ -4357,6 +4360,7 @@ class ChatViewModelTest {
|
||||
assertFalse(state.showUserMessageTokens)
|
||||
assertFalse(state.showAssistantMessageTokens)
|
||||
assertFalse(state.showTokensPerSecond)
|
||||
assertTrue(state.showModelProvider)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -5,31 +5,37 @@ import org.junit.Test
|
||||
|
||||
/**
|
||||
* Unit tests for [composerModelLabel] — the label shown in the composer's
|
||||
* model/reasoning pill. Only the "custom:" provider marker is dropped; the
|
||||
* provider stays so the same model from different providers never collides.
|
||||
* model/reasoning pill.
|
||||
* By default ([showProvider] = false), only the model name is shown.
|
||||
* When [showProvider] = true, the provider is kept (with "custom:" stripped).
|
||||
*/
|
||||
class ComposerToolbarTest {
|
||||
@Test
|
||||
fun composerModelLabel_keepsProviderToDisambiguateSameModel() {
|
||||
assertEquals("openai/gpt-5.5", composerModelLabel("openai/gpt-5.5"))
|
||||
assertEquals("copilot/gpt-5.5", composerModelLabel("copilot/gpt-5.5"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun composerModelLabel_dropsOnlyTheCustomMarker() {
|
||||
assertEquals("my-provider/glm-5.3", composerModelLabel("custom:my-provider/glm-5.3"))
|
||||
assertEquals("openrouter/openai/gpt-5.5", composerModelLabel("openrouter/openai/gpt-5.5"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun composerModelLabel_leavesModelTagsAndPlainIdsAlone() {
|
||||
assertEquals("ollama/llama3:8b", composerModelLabel("ollama/llama3:8b"))
|
||||
fun composerModelLabel_defaultsToModelOnly() {
|
||||
assertEquals("gpt-5.5", composerModelLabel("openai/gpt-5.5"))
|
||||
assertEquals("gpt-5.5", composerModelLabel("copilot/gpt-5.5"))
|
||||
assertEquals("glm-5.3", composerModelLabel("custom:my-provider/glm-5.3"))
|
||||
assertEquals("gpt-5.5", composerModelLabel("openrouter/openai/gpt-5.5"))
|
||||
assertEquals("gpt-5", composerModelLabel("openrouter/openai/gpt-5"))
|
||||
assertEquals("llama3:8b", composerModelLabel("ollama/llama3:8b"))
|
||||
assertEquals("llama3:8b", composerModelLabel("llama3:8b"))
|
||||
assertEquals("gpt-5", composerModelLabel("gpt-5"))
|
||||
assertEquals("custom:/glm-5.3", composerModelLabel("custom:/glm-5.3"))
|
||||
assertEquals("openai/", composerModelLabel("openai/"))
|
||||
assertEquals("/gpt-5", composerModelLabel("/gpt-5"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun composerModelLabel_bareCustomMarker_fallsBackToFullId() {
|
||||
assertEquals("custom:/glm-5.3", composerModelLabel("custom:/glm-5.3"))
|
||||
fun composerModelLabel_keepsProviderWhenEnabled() {
|
||||
assertEquals("openai/gpt-5.5", composerModelLabel("openai/gpt-5.5", showProvider = true))
|
||||
assertEquals("copilot/gpt-5.5", composerModelLabel("copilot/gpt-5.5", showProvider = true))
|
||||
assertEquals("my-provider/glm-5.3", composerModelLabel("custom:my-provider/glm-5.3", showProvider = true))
|
||||
assertEquals("openrouter/openai/gpt-5.5", composerModelLabel("openrouter/openai/gpt-5.5", showProvider = true))
|
||||
assertEquals("ollama/llama3:8b", composerModelLabel("ollama/llama3:8b", showProvider = true))
|
||||
assertEquals("llama3:8b", composerModelLabel("llama3:8b", showProvider = true))
|
||||
assertEquals("gpt-5", composerModelLabel("gpt-5", showProvider = true))
|
||||
assertEquals("custom:/glm-5.3", composerModelLabel("custom:/glm-5.3", showProvider = true))
|
||||
assertEquals("openai/", composerModelLabel("openai/", showProvider = true))
|
||||
assertEquals("/gpt-5", composerModelLabel("/gpt-5", showProvider = true))
|
||||
}
|
||||
}
|
||||
@@ -98,6 +98,7 @@ class SlashCommandDispatchRpcTest {
|
||||
every { AuthManager.isUserMessageTokensEnabled() } returns true
|
||||
every { AuthManager.isAssistantMessageTokensEnabled() } returns true
|
||||
every { AuthManager.isTokensPerSecondEnabled() } returns true
|
||||
every { AuthManager.isModelProviderShown() } returns false
|
||||
every { AuthManager.isAutoReconnect() } returns false
|
||||
every { AuthManager.isRestoreLastSession() } returns false
|
||||
every { AuthManager.getLastOpenedSessionId() } returns null
|
||||
|
||||
@@ -77,6 +77,7 @@ class SettingsViewModelTest {
|
||||
every { AuthManager.isUserMessageTokensEnabled() } returns true
|
||||
every { AuthManager.isAssistantMessageTokensEnabled() } returns true
|
||||
every { AuthManager.isTokensPerSecondEnabled() } returns true
|
||||
every { AuthManager.isModelProviderShown() } returns false
|
||||
every { AuthManager.getConnectionProfiles() } returns emptyList()
|
||||
every { AuthManager.getSelectedProfileId() } answers { storedSelectedProfileId }
|
||||
every { AuthManager.baseUrl() } returns "http://127.0.0.1:9119/"
|
||||
@@ -93,6 +94,7 @@ class SettingsViewModelTest {
|
||||
every { AuthManager.setUserMessageTokensEnabled(any()) } returns Unit
|
||||
every { AuthManager.setAssistantMessageTokensEnabled(any()) } returns Unit
|
||||
every { AuthManager.setTokensPerSecondEnabled(any()) } returns Unit
|
||||
every { AuthManager.setModelProviderShown(any()) } returns Unit
|
||||
every { AuthManager.setSelectedProfileId(any()) } answers {
|
||||
storedSelectedProfileId = firstArg()
|
||||
}
|
||||
@@ -327,4 +329,37 @@ class SettingsViewModelTest {
|
||||
|
||||
verify { AuthManager.clearLastOpenedSessionIdsForConnection("prof-1") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testShowModelProvider_loadsAndTogglesImmediately() =
|
||||
runTest {
|
||||
every { AuthManager.isModelProviderShown() } returns false
|
||||
|
||||
val viewModel = SettingsViewModel(ioDispatcher = testDispatcher)
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
assertEquals(false, viewModel.uiState.value.showModelProvider)
|
||||
|
||||
viewModel.onShowModelProviderChange(true)
|
||||
assertEquals(true, viewModel.uiState.value.showModelProvider)
|
||||
assertEquals(false, viewModel.uiState.value.isSaved)
|
||||
verify { AuthManager.setModelProviderShown(true) }
|
||||
|
||||
viewModel.onShowModelProviderChange(false)
|
||||
assertEquals(false, viewModel.uiState.value.showModelProvider)
|
||||
verify { AuthManager.setModelProviderShown(false) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSave_persistsShowModelProvider() =
|
||||
runTest {
|
||||
val viewModel = SettingsViewModel(ioDispatcher = testDispatcher)
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
|
||||
viewModel.onShowModelProviderChange(true)
|
||||
viewModel.save()
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
|
||||
verify { AuthManager.setModelProviderShown(true) }
|
||||
assertEquals(true, viewModel.uiState.value.isSaved)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user