fix(oneshot): write response to stdout instead of silently dropping it - #23007
fix(oneshot): write response to stdout instead of silently dropping it#23007luyao618 wants to merge 1 commit into
Conversation
|
Reviewed this against the other two competing fixes for #22975 (#23033, and mine which I just closed). This is the most complete fix. The StringIO over devnull change removes the underlying proxy edge case rather than papering over the symptom — luyao618 correctly identified that devnull's missing The Compared to my approach ( One minor suggestion: the test coverage in #23007 could be strengthened with a test that specifically verifies |
7e7c4b2 to
0ecf53b
Compare
|
Rebased onto current main — all blocking checks now green (lint, e2e, Windows footguns, nix, builds). The original Windows footgun + ty-diff failures were baseline drift, not regressions from this change. Per @Bartok9's review above, this is the most complete of the three competing fixes for #22975: it uses |
Replace open(os.devnull) redirect target with io.StringIO() in run_oneshot(). The devnull file handle lacks text-stream attributes (.encoding, .buffer) that _SafeWriter and downstream SDK code rely on via __getattr__ forwarding — causing agent.chat() to silently return an empty string on some provider/platform combinations. Additionally set agent._print_fn to a no-op lambda so _safe_print / _vprint never interact with the redirected stream, eliminating a second vector for stdout interference during response capture. Closes NousResearch#22975
0ecf53b to
367c053
Compare
|
Closing — open too long, no longer relevant. |
Summary
Fixes #22975 —
hermes -z(oneshot mode) returns empty stdout despite a successful API response.Root Cause
run_oneshot()wraps the entire agent call tree inredirect_stdout(open(os.devnull, 'w'))to suppress diagnostic output. However,AIAgent.__init__calls_install_safe_stdio(), which wrapssys.stdoutin a_SafeWriterproxy. The proxy's__getattr__forwards attribute lookups to the inner stream — when that stream is a devnull file handle, it lacks text-stream attributes like.encoding(returnsNoneon some platforms) and.buffer(absent entirely). Downstream SDK code and logging formatters that inspect these attributes silently malfunction, causingagent.chat()to return an empty string.Fix
Replace
open(os.devnull)withio.StringIO()as the redirect target.StringIOis a well-behaved in-memory text stream that exposes all standard file-object attributes, avoiding the edge cases that devnull triggers through_SafeWriter's proxy.Set
agent._print_fn = lambda: Noneto route all agent-internal print calls (_safe_print,_vprint) through a no-op, eliminating a second vector for stdout interference during response capture.Testing
oneshottests pass (11 passed, 7 skipped)hermes_cli/oneshot.pyChecklist