opentui(phase3): launcher integration — HERMES_TUI_ENGINE dual-engine

hermes --tui launches the native OpenTUI engine (Bun) when
HERMES_TUI_ENGINE=opentui (env) or display.tui_engine=opentui (config);
Ink stays the default and the shipping path is untouched.

- _resolve_tui_engine() (env > config > ink); refuses opentui on
  Windows/Termux (no Bun) -> falls back to ink with a notice.
- _make_opentui_argv() -> [bun, src/entry.real.tsx] (no build step).
- _bun_bin() with HERMES_BUN override.
- Branch at top of _make_tui_argv BEFORE _ensure_tui_node (Bun-only host
  must not bootstrap Node).
- Gate _launch_tui NODE_OPTIONS/--max-old-space-size on engine==ink (Bun
  is JSC; the V8 flag errors/ignores).

Verified end-to-end via tmux: real hermes --tui -> Bun -> OpenTUI ->
real Python gateway streamed a real reply. No-flag default still ink.
This commit is contained in:
alt-glitch
2026-06-08 11:11:54 +00:00
parent 24f74eb888
commit 2bd9c9b881
741 changed files with 17733 additions and 79889 deletions
-84
View File
@@ -1573,87 +1573,3 @@ class TestCopilotACPStreamingDecision:
_use_streaming = False
assert _use_streaming is True
class TestBedrockIamStreamingFallback:
"""bedrock_converse streaming branch: IAM denial of
InvokeModelWithResponseStream falls back to converse() inline and sets
_disable_streaming for the rest of the session."""
def _make_bedrock_agent(self):
from run_agent import AIAgent
agent = AIAgent(
api_key="test-key",
base_url="https://openrouter.ai/api/v1",
model="anthropic.claude-3-sonnet-20240229-v1:0",
quiet_mode=True,
skip_context_files=True,
skip_memory=True,
)
agent.api_mode = "bedrock_converse"
agent._interrupt_requested = False
return agent
def test_iam_denial_falls_back_inline_and_disables_streaming(self):
pytest.importorskip("botocore", reason="botocore required for Bedrock tests")
from botocore.exceptions import ClientError
agent = self._make_bedrock_agent()
client = MagicMock()
client.converse_stream.side_effect = ClientError(
error_response={
"Error": {
"Code": "AccessDeniedException",
"Message": (
"User is not authorized to perform: "
"bedrock:InvokeModelWithResponseStream"
),
}
},
operation_name="ConverseStream",
)
client.converse.return_value = {
"output": {"message": {"role": "assistant", "content": [{"text": "hi"}]}},
"stopReason": "end_turn",
"usage": {"inputTokens": 1, "outputTokens": 1, "totalTokens": 2},
}
with patch(
"agent.bedrock_adapter._get_bedrock_runtime_client",
return_value=client,
):
response = agent._interruptible_streaming_api_call(
{"modelId": agent.model, "messages": []}
)
client.converse.assert_called_once()
assert response.choices[0].message.content == "hi"
assert getattr(agent, "_disable_streaming", False) is True
def test_other_bedrock_errors_still_propagate(self):
pytest.importorskip("botocore", reason="botocore required for Bedrock tests")
from botocore.exceptions import ClientError
agent = self._make_bedrock_agent()
client = MagicMock()
client.converse_stream.side_effect = ClientError(
error_response={
"Error": {"Code": "ThrottlingException", "Message": "slow down"}
},
operation_name="ConverseStream",
)
with patch(
"agent.bedrock_adapter._get_bedrock_runtime_client",
return_value=client,
):
with pytest.raises(ClientError):
agent._interruptible_streaming_api_call(
{"modelId": agent.model, "messages": []}
)
client.converse.assert_not_called()
assert getattr(agent, "_disable_streaming", False) is False