mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-12 03:42:08 +00:00
fix(tui): close slash parity gaps with CLI (#20339)
* fix(tui): close slash parity gaps with CLI Route unsupported /skills subcommands through slash.exec, support /new <name> titles, and handle /redraw natively so TUI behavior matches classic CLI. Also filter gateway-only commands out of the TUI catalog while keeping /status discoverable. * fix(tui): run remaining CLI parity paths natively Forward chat launch flags into the TUI runtime and handle live-session status and skill reloads in the gateway process so TUI state no longer depends on the slash worker's stale CLI instance. * fix(tui): block stale snapshot restores Prevent snapshot restore from running through the isolated slash worker because it mutates disk state without refreshing the live TUI agent. * chore: uptick * fix(tui): guard async session title updates Handle failures from the fire-and-forget session.title RPC so title-setting errors do not surface as unhandled promise rejections while preserving session-scoped messaging.
This commit is contained in:
parent
acca3ec3af
commit
794f48766c
14 changed files with 1266 additions and 284 deletions
|
|
@ -1,5 +1,6 @@
|
|||
import { STARTUP_IMAGE, STARTUP_QUERY } from '../config/env.js'
|
||||
import { STREAM_BATCH_MS } from '../config/timing.js'
|
||||
import { buildSetupRequiredSections, SETUP_REQUIRED_TITLE } from '../content/setup.js'
|
||||
import { SETUP_REQUIRED_TITLE, buildSetupRequiredSections } from '../content/setup.js'
|
||||
import type {
|
||||
CommandsCatalogResponse,
|
||||
ConfigFullResponse,
|
||||
|
|
@ -64,6 +65,7 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
|||
|
||||
let pendingThinkingStatus = ''
|
||||
let thinkingStatusTimer: null | ReturnType<typeof setTimeout> = null
|
||||
let startupPromptSubmitted = false
|
||||
|
||||
// Inject the disk-save callback into turnController so recordMessageComplete
|
||||
// can fire-and-forget a persist without having to plumb a gateway ref around.
|
||||
|
|
@ -146,6 +148,36 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
|||
}, ms)
|
||||
}
|
||||
|
||||
const scheduleStartupPrompt = () => {
|
||||
if (startupPromptSubmitted || (!STARTUP_QUERY && !STARTUP_IMAGE)) {
|
||||
return
|
||||
}
|
||||
|
||||
startupPromptSubmitted = true
|
||||
setTimeout(async () => {
|
||||
let sid = getUiState().sid
|
||||
|
||||
for (let i = 0; !sid && i < 40; i += 1) {
|
||||
await new Promise(resolve => setTimeout(resolve, 100))
|
||||
sid = getUiState().sid
|
||||
}
|
||||
|
||||
if (!sid) {
|
||||
return sys('startup query skipped: no active session')
|
||||
}
|
||||
|
||||
if (STARTUP_IMAGE) {
|
||||
try {
|
||||
await rpc('image.attach', { path: STARTUP_IMAGE, session_id: sid })
|
||||
} catch (e) {
|
||||
sys(`startup image attach failed: ${rpcErrorMessage(e)}`)
|
||||
}
|
||||
}
|
||||
|
||||
submitRef.current(STARTUP_QUERY || 'What do you see in this image?')
|
||||
}, 0)
|
||||
}
|
||||
|
||||
// Terminal statuses are never overwritten by late-arriving live events —
|
||||
// otherwise a stale `subagent.start` / `spawn_requested` can clobber a
|
||||
// `failed` or `interrupted` terminal state (Copilot review #14045).
|
||||
|
|
@ -181,6 +213,7 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
|||
if (STARTUP_RESUME_ID) {
|
||||
patchUiState({ status: 'resuming…' })
|
||||
resumeById(STARTUP_RESUME_ID)
|
||||
scheduleStartupPrompt()
|
||||
|
||||
return
|
||||
}
|
||||
|
|
@ -196,6 +229,7 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
|||
if (!cfg?.config?.display?.tui_auto_resume_recent) {
|
||||
patchUiState({ status: 'forging session…' })
|
||||
newSession()
|
||||
scheduleStartupPrompt()
|
||||
|
||||
return
|
||||
}
|
||||
|
|
@ -206,17 +240,20 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
|||
if (target) {
|
||||
patchUiState({ status: 'resuming most recent…' })
|
||||
resumeById(target)
|
||||
scheduleStartupPrompt()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
patchUiState({ status: 'forging session…' })
|
||||
newSession()
|
||||
scheduleStartupPrompt()
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
patchUiState({ status: 'forging session…' })
|
||||
newSession()
|
||||
scheduleStartupPrompt()
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue