Detail bar shows real percent + tone once progress > 0
With milestone-backed progress the number is truthful, so replace the indeterminate 'working' bar with a determinate one labeled 'Summarizing <tone>… N%' (indeterminate spinner only while waiting for the first token).
This commit is contained in:
parent
61f2124b1c
commit
f258470a6a
1 changed files with 34 additions and 13 deletions
|
|
@ -777,11 +777,15 @@ fun DetailScreen(state: DesktopState) {
|
||||||
}
|
}
|
||||||
val sJob = detail.jobs.firstOrNull { it.jobType == "summarize" }
|
val sJob = detail.jobs.firstOrNull { it.jobType == "summarize" }
|
||||||
sJob?.takeIf { it.status == "running" || it.status == "queued" }?.let {
|
sJob?.takeIf { it.status == "running" || it.status == "queued" }?.let {
|
||||||
|
// Honest milestone progress: the engine counts completed
|
||||||
|
// contract units (JSON keys/items finished), so the number
|
||||||
|
// means real work done — a determinate bar is truthful now.
|
||||||
|
val toneWord = sJob.tone?.lowercase()?.replace(",", "")
|
||||||
|
?.takeIf { it.isNotBlank() && it != "neutral" }
|
||||||
val label = when {
|
val label = when {
|
||||||
// Streaming summarize shows elapsed time, not the backend
|
it.status == "running" && it.progress != null && it.progress > 0 ->
|
||||||
// number: it pins at 99% the moment tokens start.
|
"Summarizing" + (toneWord?.let { t -> " $t" } ?: "") +
|
||||||
it.status == "running" && it.progress != null ->
|
"… ${it.progress}%" +
|
||||||
"Summarizing… working" +
|
|
||||||
DesktopState.waitSuffix(it.startedAt, System.currentTimeMillis())
|
DesktopState.waitSuffix(it.startedAt, System.currentTimeMillis())
|
||||||
it.status == "running" -> "Summarizing… 0% waiting for model" +
|
it.status == "running" -> "Summarizing… 0% waiting for model" +
|
||||||
DesktopState.waitSuffix(it.startedAt, System.currentTimeMillis())
|
DesktopState.waitSuffix(it.startedAt, System.currentTimeMillis())
|
||||||
|
|
@ -792,11 +796,18 @@ fun DetailScreen(state: DesktopState) {
|
||||||
color = MaterialTheme.colorScheme.primary)
|
color = MaterialTheme.colorScheme.primary)
|
||||||
if (it.status == "running") {
|
if (it.status == "running") {
|
||||||
Spacer(Modifier.height(4.dp))
|
Spacer(Modifier.height(4.dp))
|
||||||
|
if (it.progress != null && it.progress > 0) {
|
||||||
|
LinearProgressIndicator(
|
||||||
|
progress = { it.progress / 100f },
|
||||||
|
modifier = Modifier.fillMaxWidth().height(4.dp),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
LinearProgressIndicator(
|
LinearProgressIndicator(
|
||||||
modifier = Modifier.fillMaxWidth().height(4.dp),
|
modifier = Modifier.fillMaxWidth().height(4.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Rescue-swap note: the engine succeeded but had to switch
|
// Rescue-swap note: the engine succeeded but had to switch
|
||||||
// summarizers mid-job. Tell the user in plain words, not the raw
|
// summarizers mid-job. Tell the user in plain words, not the raw
|
||||||
// provider ids.
|
// provider ids.
|
||||||
|
|
@ -989,23 +1000,33 @@ fun DetailScreen(state: DesktopState) {
|
||||||
val sStatus = sJob?.status
|
val sStatus = sJob?.status
|
||||||
val sProg = sJob?.progress
|
val sProg = sJob?.progress
|
||||||
val sAttempt = sJob?.attempt ?: 0
|
val sAttempt = sJob?.attempt ?: 0
|
||||||
// Bar stays indeterminate while running: backend summarize
|
// Determinate bar once real units complete: the engine
|
||||||
// progress pins at 99 as soon as tokens start, so a
|
// counts finished JSON contract units, so the percent
|
||||||
// determinate bar would freeze near-full for minutes.
|
// means work done, not vibes. Indeterminate only while
|
||||||
|
// queued or pre-first-token.
|
||||||
|
if (sProg != null && sProg > 0) {
|
||||||
|
LinearProgressIndicator(progress = { sProg / 100f },
|
||||||
|
modifier = Modifier.fillMaxWidth())
|
||||||
|
} else {
|
||||||
LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
|
LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
|
||||||
|
}
|
||||||
Text(buildString {
|
Text(buildString {
|
||||||
append(when {
|
append(when {
|
||||||
sStatus == "queued" -> "Queued…" +
|
sStatus == "queued" -> "Queued…" +
|
||||||
DesktopState.waitSuffix(sJob?.createdAt,
|
DesktopState.waitSuffix(sJob?.createdAt,
|
||||||
System.currentTimeMillis())
|
System.currentTimeMillis())
|
||||||
sProg != null && sProg > 0 -> "Summarizing… working" +
|
sProg != null && sProg > 0 ->
|
||||||
|
"Summarizing" + (sJob?.tone?.lowercase()
|
||||||
|
?.replace(",", "")
|
||||||
|
?.takeIf { it.isNotBlank() && it != "neutral" }
|
||||||
|
?.let { " $it" } ?: "") +
|
||||||
|
"… $sProg%" +
|
||||||
DesktopState.waitSuffix(sJob?.startedAt,
|
DesktopState.waitSuffix(sJob?.startedAt,
|
||||||
System.currentTimeMillis())
|
System.currentTimeMillis())
|
||||||
else -> "Summarizing… 0% waiting for model" +
|
else -> "Summarizing… 0% waiting for model" +
|
||||||
DesktopState.waitSuffix(sJob?.startedAt,
|
DesktopState.waitSuffix(sJob?.startedAt,
|
||||||
System.currentTimeMillis())
|
System.currentTimeMillis())
|
||||||
})
|
})
|
||||||
sumTone?.let { append(" · $it") }
|
|
||||||
if (sAttempt > 0)
|
if (sAttempt > 0)
|
||||||
append(" (attempt $sAttempt/${sJob?.maxAttempts})")
|
append(" (attempt $sAttempt/${sJob?.maxAttempts})")
|
||||||
}, style = MaterialTheme.typography.bodySmall,
|
}, style = MaterialTheme.typography.bodySmall,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue