fix(chat): preserve usage baseline across local aborts
This commit is contained in:
1 parent
d16a2ea35c
commit
22b948f671
4 files changed
+80
-13
No files matched your search
@@ -1883,7 +1883,7 @@ class ChatViewModelTest {
|
||||
@Test
|
||||
fun sendMessage_oversizedDuringSnapshotLeavesNoPersistedGhostMessage() =
|
||||
runTest {
|
||||
val (viewModel, _) = createViewModelWithSession()
|
||||
val (viewModel, sessionId) = createViewModelWithSession()
|
||||
val persistedBeforeSend = fakeRepo.dao.count()
|
||||
val uriString = "content://unknown/growing-file"
|
||||
val mockUri = mockk<Uri>()
|
||||
@@ -1920,6 +1920,7 @@ class ChatViewModelTest {
|
||||
viewModel.sendMessage("Inspect changing file")
|
||||
advanceUntilIdle()
|
||||
|
||||
assertFalse(viewModel.streamingState.value.turnUsageBaselineCaptured)
|
||||
assertEquals(persistedBeforeSend, fakeRepo.dao.count())
|
||||
assertFalse(
|
||||
fakeRepo.dao
|
||||
@@ -1931,6 +1932,24 @@ class ChatViewModelTest {
|
||||
viewModel.uiState.value.messages
|
||||
.any { it.content == "Inspect changing file" },
|
||||
)
|
||||
|
||||
mockEventsFlow.emit(
|
||||
WsEvent.SessionUsage(
|
||||
data = mapOf("usage" to mapOf("output" to 1300L)),
|
||||
sessionId = sessionId,
|
||||
),
|
||||
)
|
||||
advanceUntilIdle()
|
||||
viewModel.removeAttachment(0)
|
||||
viewModel.sendMessage("Retry without attachment")
|
||||
advanceUntilIdle()
|
||||
|
||||
assertEquals(
|
||||
1300L,
|
||||
viewModel.streamingState.value.turnUsageBaseline
|
||||
?.outputTokens,
|
||||
)
|
||||
assertTrue(viewModel.streamingState.value.turnUsageBaselineCaptured)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -4191,6 +4210,7 @@ class ChatViewModelTest {
|
||||
advanceUntilIdle()
|
||||
|
||||
viewModel.sendMessage("prompt")
|
||||
advanceUntilIdle()
|
||||
|
||||
assertEquals(
|
||||
1000L,
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.m57.hermescontrol.data.model.UsageSnapshotResponse
|
||||
import com.m57.hermescontrol.data.ws.WsEvent
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
@@ -1185,6 +1186,46 @@ class ChatWsEventReducerTest {
|
||||
assertTrue(!result.streamingState.turnUsageBaselineCaptured)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMessageComplete_invalidFinalTpsFallsBackToLatestValidTps() {
|
||||
fun complete(
|
||||
finalTps: Double?,
|
||||
latestTps: Double?,
|
||||
): Double? {
|
||||
val state =
|
||||
ChatUiState(
|
||||
currentSessionId = "session-1",
|
||||
latestTps = latestTps,
|
||||
sessionUsage = UsageSnapshotResponse(outputTokens = 1000),
|
||||
)
|
||||
val start =
|
||||
ChatWsEventReducer.reduce(
|
||||
state,
|
||||
StreamingState(),
|
||||
WsEvent.MessageStart("session-1"),
|
||||
"session-1",
|
||||
)
|
||||
val usage = mutableMapOf<String, Any?>("output" to 1250L)
|
||||
if (finalTps != null) usage["avg_tps"] = finalTps
|
||||
return ChatWsEventReducer
|
||||
.reduce(
|
||||
state,
|
||||
start.streamingState,
|
||||
WsEvent.MessageComplete("reply", "session-1", rawPayload = mapOf("usage" to usage)),
|
||||
"session-1",
|
||||
).state.messages
|
||||
.single()
|
||||
.tps
|
||||
}
|
||||
|
||||
assertEquals(42.5, complete(42.5, 30.0) ?: 0.0, 0.001)
|
||||
assertEquals(37.5, complete(0.0, 37.5) ?: 0.0, 0.001)
|
||||
assertEquals(37.5, complete(-2.0, 37.5) ?: 0.0, 0.001)
|
||||
assertEquals(37.5, complete(null, 37.5) ?: 0.0, 0.001)
|
||||
assertNull(complete(-2.0, null))
|
||||
assertNull(complete(0.0, -1.0))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMessageComplete_withoutBaselineFallsBackToVisibleTextEstimate() {
|
||||
val result =
|
||||
|
||||
Reference in new issue
Block a user