mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-27 11:22:03 +00:00
Merge pull request #52210 from helix4u/fix/desktop-update-progress-visibility
fix(desktop): surface update progress lines
This commit is contained in:
parent
7157b213f5
commit
284be6cc24
3 changed files with 72 additions and 1 deletions
|
|
@ -382,6 +382,8 @@ function ApplyingView({ apply, isBackend }: { apply: UpdateApplyState; isBackend
|
|||
const u = t.updates
|
||||
const label = u.stages[apply.stage as DesktopUpdateStage] ?? u.stages.idle
|
||||
const body = isBackend ? u.applyingBodyBackend : u.applyingBody
|
||||
const currentMessage = apply.message.trim()
|
||||
const recentLog = apply.log.slice(-4)
|
||||
|
||||
const percent =
|
||||
typeof apply.percent === 'number' && Number.isFinite(apply.percent)
|
||||
|
|
@ -397,6 +399,12 @@ function ApplyingView({ apply, isBackend }: { apply: UpdateApplyState; isBackend
|
|||
<DialogDescription className="text-center text-sm">
|
||||
{body}
|
||||
</DialogDescription>
|
||||
|
||||
{currentMessage ? (
|
||||
<p className="max-w-lg break-words text-center text-xs leading-5 text-muted-foreground">
|
||||
{currentMessage}
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div className="h-2 overflow-hidden rounded-full bg-muted">
|
||||
|
|
@ -409,6 +417,16 @@ function ApplyingView({ apply, isBackend }: { apply: UpdateApplyState; isBackend
|
|||
/>
|
||||
</div>
|
||||
|
||||
{recentLog.length > 1 ? (
|
||||
<div className="max-h-24 overflow-hidden rounded-md border border-border/70 bg-muted/35 px-3 py-2 text-left font-mono text-[11px] leading-4 text-muted-foreground">
|
||||
{recentLog.map((entry, index) => (
|
||||
<div className="truncate" key={`${entry.at}-${index}`}>
|
||||
{entry.message}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<p className="text-center text-xs text-muted-foreground">{u.applyingClose}</p>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -370,6 +370,40 @@ describe('applyBackendUpdate recovery', () => {
|
|||
expect($backendUpdateApply.get().applying).toBe(false)
|
||||
})
|
||||
|
||||
it('surfaces backend update action log lines while the action is running', async () => {
|
||||
updateHermesSpy.mockResolvedValue({ ok: true, name: 'update', pid: 1 })
|
||||
getActionStatusSpy
|
||||
.mockResolvedValueOnce({
|
||||
exit_code: null,
|
||||
lines: ['Pulling updates...', 'Installing dependencies...'],
|
||||
name: 'update',
|
||||
pid: 1,
|
||||
running: true
|
||||
})
|
||||
.mockRejectedValueOnce(new Error('ECONNREFUSED'))
|
||||
checkHermesUpdateSpy.mockResolvedValue({
|
||||
install_method: 'git',
|
||||
current_version: '0.16.0',
|
||||
behind: 0,
|
||||
update_available: false,
|
||||
can_apply: true,
|
||||
update_command: 'hermes update',
|
||||
message: null
|
||||
})
|
||||
|
||||
const promise = applyBackendUpdate()
|
||||
await vi.advanceTimersByTimeAsync(1500)
|
||||
|
||||
expect($backendUpdateApply.get().message).toBe('Installing dependencies...')
|
||||
expect($backendUpdateApply.get().log.map(entry => entry.message)).toEqual([
|
||||
'Pulling updates...',
|
||||
'Installing dependencies...'
|
||||
])
|
||||
|
||||
await vi.advanceTimersByTimeAsync(5000)
|
||||
await promise
|
||||
})
|
||||
|
||||
it('surfaces an error when the backend never comes back after the restart', async () => {
|
||||
updateHermesSpy.mockResolvedValue({ ok: true, name: 'update', pid: 1 })
|
||||
getActionStatusSpy.mockRejectedValue(new Error('ECONNREFUSED'))
|
||||
|
|
@ -383,4 +417,3 @@ describe('applyBackendUpdate recovery', () => {
|
|||
expect($backendUpdateApply.get().stage).toBe('error')
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -455,6 +455,25 @@ function finishBackendApply(returned: boolean): DesktopUpdateApplyResult {
|
|||
return { ok: false, error: 'apply-failed', message: 'Backend did not come back online.' }
|
||||
}
|
||||
|
||||
function ingestBackendActionStatus(status: Awaited<ReturnType<typeof getActionStatus>>): void {
|
||||
const current = $backendUpdateApply.get()
|
||||
const log = status.lines
|
||||
.filter(line => line.trim().length > 0)
|
||||
.map(line => ({ at: Date.now(), message: line, stage: current.stage }))
|
||||
.slice(-50)
|
||||
const latest = log.at(-1)?.message
|
||||
|
||||
if (log.length === 0 && !latest) {
|
||||
return
|
||||
}
|
||||
|
||||
$backendUpdateApply.set({
|
||||
...current,
|
||||
log,
|
||||
message: latest ?? current.message
|
||||
})
|
||||
}
|
||||
|
||||
export async function applyBackendUpdate(): Promise<DesktopUpdateApplyResult> {
|
||||
dismissNotification(UPDATE_TOAST_ID)
|
||||
$backendUpdateApply.set({ ...IDLE, applying: true, stage: 'prepare', message: translateNow('updates.applyStatus.preparing') })
|
||||
|
|
@ -477,6 +496,7 @@ export async function applyBackendUpdate(): Promise<DesktopUpdateApplyResult> {
|
|||
await new Promise(resolve => globalThis.setTimeout(resolve, 1500))
|
||||
try {
|
||||
last = await getActionStatus(started.name, 200)
|
||||
ingestBackendActionStatus(last)
|
||||
} catch {
|
||||
// The dashboard restarts mid-update, dropping this connection — expected, not a failure.
|
||||
$backendUpdateApply.set({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue