mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-08 03:01:47 +00:00
fix(tui): surface gateway stderr tail in start_timeout activity (#17112)
* fix(tui): append gateway stderr tail to start_timeout activity `gateway.start_timeout` previously published only `cwd` + `python`, which made TUI startup failures hard to disambiguate. The user saw `gateway startup timed out · /path/to/python /repo · /logs to inspect` with no signal whether the actual cause was a wrong python interpreter, a missing dependency, or a config parse failure. Plumb a 20-line stderr tail through the event so the most useful lines land directly in the TUI activity feed, capped to the last 8 non-empty lines for readability: * `gatewayClient.ts` — collect `getLogTail(20)` when the readyTimer fires and attach it as `payload.stderr_tail`. * `gatewayTypes.ts` — extend the `gateway.start_timeout` event union with the new optional field. * `createGatewayEventHandler.ts` — emit the trimmed lines after the existing `gateway startup timed out` activity entry, classified `error`. Tests: regression test in `createGatewayEventHandler.test.ts` checks that `ModuleNotFoundError` / `FileNotFoundError` lines from the tail land in `getTurnState().activity` so they show up in the UI immediately. Validation: `npm run type-check` clean, `npm test --run` 390/390. * review(copilot): filter blanks before slice and cap stderr tail at 120 chars
This commit is contained in:
parent
0d957a8d48
commit
a830f25f71
4 changed files with 52 additions and 3 deletions
|
|
@ -321,12 +321,30 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
|||
}
|
||||
|
||||
case 'gateway.start_timeout': {
|
||||
const { cwd, python } = ev.payload ?? {}
|
||||
const { cwd, python, stderr_tail: stderrTail } = ev.payload ?? {}
|
||||
const trace = python || cwd ? ` · ${String(python || '')} ${String(cwd || '')}`.trim() : ''
|
||||
|
||||
setStatus('gateway startup timeout')
|
||||
turnController.pushActivity(`gateway startup timed out${trace} · /logs to inspect`, 'error')
|
||||
|
||||
// Surface the most useful stderr lines inline so users can tell
|
||||
// "wrong python", "missing dep", and "config parse failure"
|
||||
// apart without leaving the TUI. Filter blank rows BEFORE
|
||||
// taking the last N so trailing empty lines in the buffer
|
||||
// don't crowd out actual content; truncate to match the
|
||||
// 120-char clip used for `gateway.stderr` activity entries.
|
||||
const STDERR_LINE_CAP = 120
|
||||
const STDERR_LINES_MAX = 8
|
||||
const tailLines = (stderrTail ?? '')
|
||||
.split('\n')
|
||||
.map(l => l.trim())
|
||||
.filter(Boolean)
|
||||
.slice(-STDERR_LINES_MAX)
|
||||
|
||||
for (const line of tailLines) {
|
||||
turnController.pushActivity(line.slice(0, STDERR_LINE_CAP), 'error')
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue