Batch salvage group 5: 10 low-risk new-contributor PRs (codex-runtime-alias/qwen-1m/reload-skills/bedrock-lazy-deps/etc)#27382
Merged
Merged
Conversation
The restart-drain test previously asserted equality between two calls
to t("gateway.draining", count=1), which masked the original
xdist failure mode in #22266: if the locale catalog is not resolved
from the worker's import path, t() returns the bare key path and
both sides of the equality still match.
Add a guard that the resolved value is not the raw catalog key and
contains the English placeholder substitution. This keeps the test
loudly failing when locale resolution silently degrades.
qwen3.6-plus did not have an explicit entry in DEFAULT_CONTEXT_LENGTHS, so the longest-substring fallback matched the generic 'qwen': 131072 catch-all. That dropped the effective context limit from 1,048,576 tokens to 131,072, prematurely lowered the compression threshold, and produced misleading warnings about main/compression context mismatch in long sessions. Add an explicit 'qwen3.6-plus': 1048576 entry before the catch-all and cover it with a regression test (bare, qwen/, and dashscope/ prefixes). Note: PR #6599 also mentions touching model_metadata.py but the actual diff only edits hermes_cli/models.py, so this fix is independent and not duplicated by that PR. Closes #27008
… picks up new skills The Tab-completion lambda captured _skill_commands at startup, so newly installed skills were missing from Tab completion even after /reload-skills reported them as added. Two changes: 1. Tab-completion lambda now calls get_skill_commands() instead of reading the module-level _skill_commands snapshot — ensures the lambda always gets fresh data without needing to touch global state. 2. _reload_skills() now syncs cli.py's module-level _skill_commands via get_skill_commands() after reload, so help display, command dispatch, and any other direct _skill_commands readers also see the updated map. Closes #26441
…25720) The chat panel renders via xterm.js, and when the inner Hermes TUI enables mouse-events mode (CSI ?1000h family — used for nav inside Ink overlays/pickers) every drag/double-click/triple-click in the canvas is consumed by the terminal instead of producing a native text selection. The reporter (macOS, Brave) confirmed: - click-and-drag selects nothing - Cmd+C with no selection copies the entire visible buffer - existing CSS overrides and event handlers at the document layer have no effect — the issue is at xterm.js's mouse layer, not the DOM Fix: two xterm.js options the user can opt into without disabling mouse-events mode for the inner TUI: - `macOptionClickForcesSelection: true` — holding Option (macOS) or Alt (Linux/Windows) during a click-and-drag bypasses mouse-events mode and produces a native xterm selection. This is the documented xterm.js path for this exact scenario. Selected text is copyable via Cmd+C / Ctrl+C through the existing OSC 52 + manual handlers. - `rightClickSelectsWord: true` — right-click highlights the word under the pointer. Single-action path on top of the modifier-based bypass. The two options coexist with the existing `macOptionIsMeta: true` (which only affects keyboard, not mouse). No other code change needed. Fixes #25720.
…sent
_parse_response in agent/shell_hooks.py only forwarded a pre_tool_call
block directive if the hook also provided a non-empty message or reason.
When either field was missing the function returned None, causing Hermes
to treat the response as a no-op and execute the tool unconditionally.
This means a hook that outputs {"action": "block"} or {"decision": "block"}
without a reason string is silently ignored. The security boundary fails
open: tools the user intended to gate are executed anyway.
Fix: remove the message-presence guard. Honor the block unconditionally
and fall back to a default message when none is provided. Existing hooks
that already include a message or reason are unaffected.
… block handler Address code review feedback on _parse_response: 1. Restore isinstance(raw, str) guard so non-string message/reason values (e.g. integers, lists) from a malformed hook response fall back to the default rather than being forwarded as-is. This keeps the contract that message in the returned dict is always a string. 2. Extract the repeated literal 'Blocked by shell hook.' into a module-level constant _DEFAULT_BLOCK_MESSAGE to avoid duplication and make it easy to change in one place. Four new unit tests added to tests/agent/test_shell_hooks.py covering: - action block with no message (uses default) - decision block with no reason (uses default) - action block with empty string message (uses default) - action block with non-string message, e.g. integer (uses default)
…c in _parse_response Both the `action=block` and `decision=block` branches in _parse_response shared identical field-priority and type-validation logic. Extract it into a single _block_message(primary, secondary) helper so the two branches are one line each and the type guard lives in exactly one place. No functional change: existing tests (TestParseResponse, 14 tests) all pass unchanged, confirming identical behaviour.
…TERMINAL_SSH_KEY The SSH connectivity check in `run_doctor` only passed the host to ssh, using the current OS user and default port 22. When the target requires a different user (TERMINAL_SSH_USER), non-standard port (TERMINAL_SSH_PORT), or a specific identity file (TERMINAL_SSH_KEY), the check always failed with "Permission denied" — even though the agent itself connects fine. Fix: read all four TERMINAL_SSH_* env vars and build the ssh command with -p, -i, and user@host as appropriate, matching how the terminal tool actually establishes the connection.
Telegram clears the typing state when a new message is delivered. When the agent sends intermediate progress messages (like 'Checking:'), the '...typing' bubble disappears immediately and doesn't return until the next keepalive tick (up to 2s later). This makes Hermes appear unresponsive during multi-tool operations. Fix: call send_typing() immediately after successful message delivery to restart the typing indicator without waiting for the next keepalive tick. Fixes #25836
agent/bedrock_adapter.py now calls lazy_deps to install boto3 and botocore on first import, mirroring how other optional provider adapters defer their heavy AWS dependencies until actually used. Keeps the base install slim for users who don't run on Bedrock.
…tors Adds release-note attribution mappings for the contributors from group 5: - @haran2001 (PR #27070, #27068) - @ms-alan (PR #26443) - @godlin-gh (PR #26118) - @wesleysimplicio (PR #25777, ext-email form) - @Carry00 (PR #26851) - @alaamohanad169-ship-it (PR #26036) - @hawknewton (PR #26294) (YanzhongSu PR #25879 and flamiinngo PR #27231 already mapped.)
This was referenced May 17, 2026
Contributor
🔎 Lint report:
|
| Rule | Count |
|---|---|
unresolved-reference |
1 |
First entries
acp_adapter/tools.py:1117: [unresolved-reference] unresolved-reference: Name `json` used when not defined
Unchanged: 4583 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
This was referenced May 17, 2026
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Batch salvage group 5 — 10 low-risk new-contributor PRs onto current
mainwith per-commit contributor authorship preserved. Continues the LHF run (groups 1-4 = #27247, #27292, #27302, #27308).Salvaged PRs
codex_runtimeunderscore alias so Telegram autocomplete can expose the hyphenated/codex-runtimecommandqwen3.6-plushas a 1M context window (longest-substring lookup was downgrading to generic Qwen 128K)_skill_commandsafter/reload-skillsso Tab completion picks up new skillsimport jsonin ACP fallback branch so polished ACP start events emit forbrowser_navigateetc._block_messagehelper refactor) — 3 sequential commitsTERMINAL_SSH_USER/TERMINAL_SSH_PORT/TERMINAL_SSH_KEYenv vars instead of bare hostnamelazy_deps.ensure("provider.bedrock")at adapter import so boto3 auto-installs on first use (regression after #24220 / #24515 removed boto3 from[all]extras)Attribution
pandername), fix(webui): allow native text selection in chat via xterm.js bypass (#25720) #25777 (Siemens Energy work email), fix(bedrock): install boto3 on first use via lazy_deps #26294 (Vigo <vigo@hermes>placeholder).AUTHOR_MAPentries for the 7 contributors not already mapped. (@YanzhongSu and @flamiinngo were already in the map from earlier contributions.)Test plan
tests/hermes_cli/test_commands.py+test_doctor.py+tests/gateway/test_restart_drain.py+tests/agent/test_model_metadata.py+test_shell_hooks.py→ 353 passed in 5.12s.Rebase-merge so per-commit contributor authorship survives.