Say when a session is working, and what it was told
Three things a phone could not see, all of them the same shape: the session was doing something and nothing on screen said so. A turn nobody here started never reported itself. `Running` was sent where a message was *sent*, so a session picked up mid-turn, one compacting on its own, or one another agent wrote to sat there reading as idle until it finished. The driver now says it from what it observes -- output that could only come from a turn in flight -- which is the same set of events that already announced a steer, with the ends swapped. An imported session had it worse: nothing but replayed lines ever reaches it, and a status was not among them, so it was permanently whatever it was when it was adopted. Its file does not record a turn ending, but it does record why each assistant message stopped, and `tool_use` versus anything else answers it. A record that says nothing leaves the status alone rather than voting for idle. Messages from other agents were dropped outright: the CLI marks them meta, and this replayed everything except meta. They are now a row of their own, closed by default like a tool call, named for the session that sent it -- not the reader's own bubble, because they did not say it, and a session working on something this phone never asked for is exactly what one of these explains. Measured against a real session file rather than guessed: the peer record carries the sender's name and the message body in `origin`, beside a copy wrapped for the model to read.
This commit is contained in:
1 parent
f18639e4b1
commit
404066fa7d
11 files changed
+577
-29
No files matched your search
@@ -1,7 +1,9 @@
|
||||
package com.example.aiapp
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -51,3 +53,56 @@ fun compactionSummary(item: TranscriptItem.CompactedNote): String {
|
||||
}
|
||||
|
||||
private fun tokens(count: Long): String = "%,d".format(count)
|
||||
|
||||
/**
|
||||
* Where the working indicator goes while a compaction is running.
|
||||
*
|
||||
* A bar across the whole row rather than the spinner an ordinary turn gets, because a compaction is
|
||||
* not an ordinary turn: nothing arrives in the transcript while it runs, so the row it occupies is
|
||||
* the only thing on screen that is moving, and at the width of a spinner that reads as a session
|
||||
* that might have hung.
|
||||
*
|
||||
* The bar is indeterminate, and that is a statement rather than an omission. The CLI says a
|
||||
* compaction has started and then says nothing at all until it has finished -- measured, not
|
||||
* assumed -- so there is no fraction to fill, and a bar that crept along at the pace of the last
|
||||
* compaction would be this screen inventing the part nobody sent it. What it can honestly say is
|
||||
* that work is happening and for how long, which is [compactingLabel].
|
||||
*/
|
||||
@Composable
|
||||
fun CompactingRow(seconds: Long?, modifier: Modifier = Modifier) {
|
||||
Column(modifier.fillMaxWidth()) {
|
||||
Text(
|
||||
compactingLabel(seconds),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
// The colour is stated beside the fill rather than inherited: a semantic colour has
|
||||
// to carry its own contrast, since the surface under it will not change to rescue it.
|
||||
color = compactingColor,
|
||||
)
|
||||
LinearProgressIndicator(
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 6.dp),
|
||||
color = compactingColor,
|
||||
trackColor = MaterialTheme.colorScheme.surfaceContainerHigh,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* What the working indicator says while a compaction is running.
|
||||
*
|
||||
* Elapsed time and nothing else, because elapsed time is all there is: the CLI announces that a
|
||||
* compaction has begun and then says nothing until it has finished, so any bar, percentage or
|
||||
* estimate here would be this screen's guess wearing a measurement's clothes. Knowing it has been
|
||||
* going forty seconds is what a reader actually wants -- it is the difference between waiting and
|
||||
* going to look at why.
|
||||
*
|
||||
* [seconds] is null when this device did not see the compaction start, which is what opening a
|
||||
* session that is already compacting looks like. That case says only "compacting": no number is the
|
||||
* honest answer, and a number counted from the moment the screen opened would be wrong in the
|
||||
* direction that matters, since a compaction somebody is asking about is a long one.
|
||||
*/
|
||||
fun compactingLabel(seconds: Long?): String =
|
||||
when {
|
||||
seconds == null -> "compacting"
|
||||
seconds < 60 -> "compacting ${seconds}s"
|
||||
else -> "compacting ${seconds / 60}m ${seconds % 60}s"
|
||||
}
|
||||
Reference in new issue
Block a user