Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
49d3439ec4
22 files changed
+1125
-61
No files matched your search
@@ -410,7 +410,10 @@ fun SessionScreen(
|
||||
val scope = rememberCoroutineScope()
|
||||
var items by remember { mutableStateOf(listOf<TranscriptItem>()) }
|
||||
var status by remember { mutableStateOf(summary.status) }
|
||||
var totalTokens by remember { mutableLongStateOf(0L) }
|
||||
// Seeded from the row this screen was opened from, so a conversation that has spent
|
||||
// something says so before any turn happens here. Zero used to mean "nothing yet" and
|
||||
// "nothing in the page I loaded" at once, and the second one is most of the long sessions.
|
||||
var totalTokens by remember(summary.id) { mutableLongStateOf(summary.totalTokens) }
|
||||
// When this screen saw the current compaction start, on this device's own clock, and how long
|
||||
// ago that is. See `compactingLabel`: null is the honest answer whenever the start was not
|
||||
// witnessed here, which is what opening a session that is already compacting looks like.
|
||||
@@ -495,7 +498,13 @@ fun SessionScreen(
|
||||
moreHistory = entry.seq > 1L
|
||||
}
|
||||
when (val event = entry.event) {
|
||||
is SessionEvent.UsageDelta -> totalTokens += event.tokens
|
||||
// Taken, not accumulated: the server's running total is on the event, and adding
|
||||
// up the deltas this screen happened to receive counted one page of a conversation
|
||||
// and called it the whole. `max` because pages arrive in no guaranteed order and an
|
||||
// older event's total is a smaller true answer, never a correction downwards; it
|
||||
// also leaves the seeded figure alone for transcripts recorded before the backend
|
||||
// sent a total at all.
|
||||
is SessionEvent.UsageDelta -> totalTokens = maxOf(totalTokens, event.total)
|
||||
else -> {
|
||||
// What the session says it is set to now, which is the only thing that
|
||||
// says it: picking from either menu asks, and the answer comes back here.
|
||||
@@ -839,15 +848,18 @@ fun SessionScreen(
|
||||
Spacer(Modifier.width(8.dp))
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text(title, style = MaterialTheme.typography.titleMedium)
|
||||
// Machine first, then what runs on it -- the same order and the same wording
|
||||
// everywhere this pair appears, so it reads as one fact rather than as two
|
||||
// sentences with different grammar. The "on" that used to sit in the middle
|
||||
// made it a phrase, which only works in one order and stops working the moment
|
||||
// the pair is shown anywhere else.
|
||||
//
|
||||
// No model. The picker in the footer already shows what this session is set to,
|
||||
// and showing it twice means two things to keep in step -- they disagreed for a
|
||||
// moment on every model change, since one follows the request and the other the
|
||||
// session's own answer.
|
||||
Text(
|
||||
listOfNotNull(
|
||||
summary.provider,
|
||||
"on ${summary.setupName}",
|
||||
// What the session says it is set to now, which is the same fact
|
||||
// the picker below shows and has to be the same answer.
|
||||
model?.let { modelLabel(it) },
|
||||
)
|
||||
.joinToString(" · "),
|
||||
"${summary.setupName} · ${summary.provider}",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -1344,16 +1356,25 @@ private fun SessionStatusRow(
|
||||
)
|
||||
Spacer(Modifier.weight(1f))
|
||||
}
|
||||
else -> {
|
||||
if (status == "exited") {
|
||||
Text(
|
||||
"exited",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.weight(1f))
|
||||
}
|
||||
// Every remaining state says which one it is, including the quiet one. The row used
|
||||
// to name only `exited` and leave the rest blank, so a session sitting idle and one
|
||||
// whose status nobody could read looked identical -- and a turn that had just been
|
||||
// stopped showed nothing at all, which reads as the app having lost the session
|
||||
// rather than as the stop having worked. The words are the session list's own, so
|
||||
// one state is not called two things depending which screen you are on.
|
||||
else ->
|
||||
Text(
|
||||
when (status) {
|
||||
"idle" -> "idle"
|
||||
"exited" -> "exited"
|
||||
"awaitingInput" -> "your turn"
|
||||
"unknown" -> "can't tell"
|
||||
else -> status
|
||||
},
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
}
|
||||
// Nothing rather than "0 tok" before anything has been spent: a total of zero is a fact
|
||||
// about a conversation that has not started, and it is the one reading nobody needs.
|
||||
|
||||
Reference in new issue
Block a user