Show live background task counts
This commit is contained in:
1 parent
9fd21af4e8
commit
8262ceb786
16 files changed
+160
-29
No files matched your search
@@ -225,6 +225,8 @@ data class SessionSummary(
|
||||
val usageProvider: String?,
|
||||
val status: String,
|
||||
val lastActivity: Double,
|
||||
/** Latest measured number of live background tasks; zero also covers older servers. */
|
||||
val backgroundTasks: Int,
|
||||
/**
|
||||
* How many subagents this session has, however their own status now reads.
|
||||
*
|
||||
@@ -263,6 +265,7 @@ private fun parseSession(session: JSONObject) =
|
||||
usageProvider = session.optString("usageProvider").ifEmpty { null },
|
||||
status = session.getString("status"),
|
||||
lastActivity = session.getDouble("lastActivity"),
|
||||
backgroundTasks = session.optInt("backgroundTasks", 0),
|
||||
subagents = session.optInt("subagents", 0),
|
||||
)
|
||||
|
||||
|
||||
@@ -140,6 +140,9 @@ sealed class SessionEvent {
|
||||
/** The same command, handed to the session. */
|
||||
data class CommandSent(val id: String, val text: String) : SessionEvent()
|
||||
|
||||
/** Provider-reported number of background tasks alive now. */
|
||||
data class BackgroundTasks(val count: Int) : SessionEvent()
|
||||
|
||||
data class Status(val state: String) : SessionEvent()
|
||||
|
||||
/**
|
||||
@@ -283,6 +286,7 @@ fun parseSeqEvent(json: String): SeqEvent {
|
||||
"commandQueued" ->
|
||||
SessionEvent.CommandQueued(body.getString("id"), body.getString("text"))
|
||||
"commandSent" -> SessionEvent.CommandSent(body.getString("id"), body.getString("text"))
|
||||
"backgroundTasks" -> SessionEvent.BackgroundTasks(body.getInt("count"))
|
||||
"status" -> SessionEvent.Status(body.getString("state"))
|
||||
"settings" ->
|
||||
SessionEvent.Settings(
|
||||
|
||||
@@ -554,6 +554,14 @@ private fun SessionCard(
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
StatusText(session.status)
|
||||
if (session.backgroundTasks > 0) {
|
||||
Text(
|
||||
backgroundTaskLabel(session.backgroundTasks),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(start = 8.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.height(4.dp))
|
||||
Row(modifier = Modifier.fillMaxWidth()) {
|
||||
|
||||
@@ -256,6 +256,8 @@ fun SessionScreen(
|
||||
val topEdgeHeld = remember { TopEdgeHold() }
|
||||
var items by remember { mutableStateOf(listOf<TranscriptItem>()) }
|
||||
var status by remember { mutableStateOf(subagent?.status ?: summary.status) }
|
||||
var backgroundTasks by
|
||||
remember(address) { mutableIntStateOf(if (isSubagent) 0 else summary.backgroundTasks) }
|
||||
// Seeded from the row this screen was opened from, so a conversation already under way says how
|
||||
// much it is holding before any turn happens here. Null is "nobody has measured it", which is a
|
||||
// different answer from an empty context and is drawn differently.
|
||||
@@ -538,6 +540,9 @@ fun SessionScreen(
|
||||
}
|
||||
status = event.state
|
||||
}
|
||||
if (event is SessionEvent.BackgroundTasks && !isSubagent) {
|
||||
backgroundTasks = event.count
|
||||
}
|
||||
if (!isSubagent) loginOpen = authenticationPromptAfter(loginOpen, event)
|
||||
// In order, always: one late event recorded ahead of the backlog would fold a
|
||||
// streamed delta into whatever row happened to be last by then.
|
||||
@@ -1842,6 +1847,7 @@ fun SessionScreen(
|
||||
status = status,
|
||||
compactingFor = compactingFor,
|
||||
contextTokens = contextTokens,
|
||||
backgroundTasks = backgroundTasks,
|
||||
subagent = isSubagent,
|
||||
)
|
||||
|
||||
@@ -2362,6 +2368,8 @@ private fun SessionStatusRow(
|
||||
compactingFor: Long?,
|
||||
/** Context the session is holding, or null where nothing has measured it. */
|
||||
contextTokens: Long?,
|
||||
/** Provider-reported live background work; zero is deliberately not drawn. */
|
||||
backgroundTasks: Int,
|
||||
modifier: Modifier = Modifier,
|
||||
/**
|
||||
* Whether this row is for a subagent rather than a session, which changes only one word:
|
||||
@@ -2395,6 +2403,14 @@ private fun SessionStatusRow(
|
||||
// its own contrast, since the surface under it will not change to rescue it.
|
||||
color = commandColor,
|
||||
)
|
||||
if (backgroundTasks > 0) {
|
||||
Text(
|
||||
backgroundTaskLabel(backgroundTasks),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(start = 8.dp),
|
||||
)
|
||||
}
|
||||
LinearProgressIndicator(
|
||||
color = commandColor,
|
||||
trackColor = MaterialTheme.colorScheme.surfaceContainerHigh,
|
||||
@@ -2415,6 +2431,14 @@ private fun SessionStatusRow(
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(start = 8.dp),
|
||||
)
|
||||
if (backgroundTasks > 0) {
|
||||
Text(
|
||||
backgroundTaskLabel(backgroundTasks),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(start = 8.dp),
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.weight(1f))
|
||||
}
|
||||
// Every remaining state says which one it is, including the quiet one. The row used to
|
||||
@@ -2423,13 +2447,22 @@ private fun SessionStatusRow(
|
||||
// showed nothing at all. The words and the colour are `sessionStatusWord`'s and
|
||||
// `sessionStatusColour`'s, shared with the session list so one state is not called two
|
||||
// things -- or drawn two colours -- depending which screen you are on.
|
||||
else ->
|
||||
else -> {
|
||||
Text(
|
||||
sessionStatusWord(status, subagent),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = sessionStatusColour(status),
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
if (backgroundTasks > 0) {
|
||||
Text(
|
||||
backgroundTaskLabel(backgroundTasks),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(start = 8.dp),
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.weight(1f))
|
||||
}
|
||||
}
|
||||
// How full the session is, which is the number a reader is asking about -- how much room is
|
||||
// left before the next compaction -- rather than what has been spent getting here.
|
||||
|
||||
@@ -38,6 +38,8 @@ fun sessionStatusWord(status: String, subagent: Boolean = false): String =
|
||||
else -> status
|
||||
}
|
||||
|
||||
fun backgroundTaskLabel(count: Int): String = "$count bg ${if (count == 1) "task" else "tasks"}"
|
||||
|
||||
/**
|
||||
* The colour that goes with [sessionStatusWord]: the accent is spent on the states that are about
|
||||
* to do something or want something, and every quiet one shares the muted colour.
|
||||
|
||||
@@ -517,6 +517,7 @@ fun foldEvent(items: List<TranscriptItem>, entry: SeqEvent): List<TranscriptItem
|
||||
// nothing it belongs above.
|
||||
is SessionEvent.MessageDropped -> items
|
||||
is SessionEvent.Settings -> items
|
||||
is SessionEvent.BackgroundTasks -> items
|
||||
is SessionEvent.Status -> settleReply(items, event.state)
|
||||
is SessionEvent.AuthenticationRequired ->
|
||||
items + TranscriptItem.ErrorMsg(entry.seq, event.message)
|
||||
|
||||
Reference in new issue
Block a user