hermes-agent/ui-opentui/src/test/env.test.ts
alt-glitch 38eb9bb19a opentui(v6): tool output uncapped by default (env restores a cap)
User feedback: "for all tools, i'd want all their output viewing enabled
to be infinite by default."

Flip envOutputLines (HERMES_TUI_TOOL_OUTPUT_LINES): unset -> Infinity
(was 200); a positive integer RESTORES a cap (e.g. =200); 0 stays
Infinity for back-compat with the old opt-in-unlimited value; garbage ->
Infinity (unrecognized = no cap asked for). The semantic is now "cap
only when the user asked for one".

The store's raw-result preference follows the same rule: envOutputLinesSet
becomes envOutputUnlimited — whenever the cap is unlimited (the default
now) and a gateway tail-capped result_text (omittedNote) arrives with the
always-full raw result on the wire, the raw result wins, since an
uncapped view of a tail would silently miss the head. With an explicit
finite cap the gateway tail + honest omitted note are kept.

Memory safety is unchanged: tool bodies mount only while EXPANDED (rows
default collapsed and free their Yoga nodes on collapse/unmount), and the
rolling HERMES_TUI_MAX_MESSAGES cap bounds the transcript's high-water
mark.

Tests: env.test.ts expectations flipped (unset/garbage -> Infinity, 0
documented as back-compat); tools.test.tsx "flag unset caps at 200"
becomes "unset renders all 250 lines", plus an explicit =50 cap (+note)
test and =200 restored-cap test; the store preference matrix covers
unset/0 (raw wins), =50 (tail+note kept), and no-raw (tail+note, no
crash). Verified live: seq 1 220 expanded renders rows 201-220 with no
"+N more lines" note.
2026-06-10 22:38:49 +05:30

68 lines
2.6 KiB
TypeScript

import { describe, expect, test } from 'vitest'
import { envFlag, envOutputLines, envOutputUnlimited } from '../logic/env.ts'
describe('envFlag', () => {
test('recognizes truthy values regardless of case/whitespace', () => {
for (const v of ['1', 'true', 'yes', 'on', 'TRUE', 'Yes', ' on ']) {
expect(envFlag(v, false)).toBe(true)
}
})
test('recognizes falsy values regardless of case/whitespace', () => {
for (const v of ['0', 'false', 'no', 'off', 'FALSE', 'No', ' off ']) {
expect(envFlag(v, true)).toBe(false)
}
})
test('returns fallback when unset', () => {
expect(envFlag(undefined, true)).toBe(true)
expect(envFlag(undefined, false)).toBe(false)
expect(envFlag('', true)).toBe(true)
expect(envFlag(' ', false)).toBe(false)
})
test('returns fallback for unrecognized garbage', () => {
expect(envFlag('maybe', true)).toBe(true)
expect(envFlag('maybe', false)).toBe(false)
expect(envFlag('2', true)).toBe(true)
expect(envFlag('enabled', false)).toBe(false)
})
})
describe('envOutputLines (HERMES_TUI_TOOL_OUTPUT_LINES)', () => {
test('unset → Infinity (UNLIMITED by default — the env var RESTORES a cap)', () => {
expect(envOutputLines(undefined)).toBe(Number.POSITIVE_INFINITY)
expect(envOutputLines('')).toBe(Number.POSITIVE_INFINITY)
expect(envOutputLines(' ')).toBe(Number.POSITIVE_INFINITY)
})
test('a positive integer → that cap (whitespace-tolerant)', () => {
expect(envOutputLines('50')).toBe(50)
expect(envOutputLines(' 50 ')).toBe(50)
expect(envOutputLines('1')).toBe(1)
expect(envOutputLines('200')).toBe(200)
expect(envOutputLines('1000')).toBe(1000)
})
test('"0" → Infinity too (back-compat with the old opt-in "unlimited" value)', () => {
expect(envOutputLines('0')).toBe(Number.POSITIVE_INFINITY)
})
test('garbage → Infinity (unrecognized ≙ no cap asked for)', () => {
expect(envOutputLines('unlimited')).toBe(Number.POSITIVE_INFINITY)
expect(envOutputLines('-5')).toBe(Number.POSITIVE_INFINITY)
expect(envOutputLines('1.5')).toBe(Number.POSITIVE_INFINITY)
expect(envOutputLines('50 lines')).toBe(Number.POSITIVE_INFINITY)
})
test('envOutputUnlimited: true unless an explicit finite cap was asked for', () => {
expect(envOutputUnlimited(undefined)).toBe(true)
expect(envOutputUnlimited('')).toBe(true)
expect(envOutputUnlimited(' ')).toBe(true)
expect(envOutputUnlimited('0')).toBe(true)
expect(envOutputUnlimited('garbage')).toBe(true)
expect(envOutputUnlimited('50')).toBe(false)
expect(envOutputUnlimited('200')).toBe(false)
})
})