fix(gateway): reject multi-line /model with clear error - #23300
Open
dockerpaula wants to merge 2 commits into
Open
fix(gateway): reject multi-line /model with clear error#23300dockerpaula wants to merge 2 commits into
/model with clear error#23300dockerpaula wants to merge 2 commits into
Conversation
When a user sent a single message that began with `/model X` followed by
a newline and additional text — e.g. via Element/Matrix's Shift+Enter —
the gateway forwarded the entire remainder into the model name parser.
The parser then replied with the misleading error
"Model names cannot contain spaces", even though the input contained no
spaces (just a newline). The follow-up question was silently dropped and
no model switch happened.
Refuse the multi-line form early in `_handle_model_command` with an
accurate, copy-paste-ready hint:
/model is a single-line command. Send `/model openai/gpt-5.5` first,
then send your follow-up message separately.
Detection uses a new `MessageEvent.get_command_remainder()` helper that
returns the text after the first newline of a command message. Other
single-line commands (`/topic`, `/style`, `/voice`, …) can adopt the
same idiom in follow-up patches; `get_command_args()` is intentionally
unchanged so multi-line-friendly commands like `/queue`, `/steer` and
`/agent` keep working as before.
Both forms are covered:
* `/model X\nFoo` — newline survives `split(maxsplit=1)` inside args
* `/model\nFoo` — newline is consumed as the arg separator
Refs NousResearch#22716.
Adds an AUTHOR_MAP entry so the contributor-attribution check in scripts/release.py can resolve dockerpaula@gmail.com to the GitHub login dockerpaula when generating release notes. Refs the multi-line /model fix in this PR (issue NousResearch#22716).
dockerpaula
force-pushed
the
devin/1778349866-model-multiline-error
branch
from
May 10, 2026 16:48
9c60b56 to
16f820d
Compare
19 tasks
teknium1
reviewed
Jul 13, 2026
teknium1
left a comment
Contributor
There was a problem hiding this comment.
Thanks for the focused regression coverage. The underlying bug still exists on current main: gateway/platforms/base.py:1804 retains the multi-line argument tail, and the current handler at gateway/slash_commands.py:1420 passes it into flag parsing and model validation.
Problems
tests/gateway/test_model_command_multiline.py:90only proves that a trailing newline does not return the new guidance text. It also passes for an unrelated model-switch error, so it does not establish the documented “switch must proceed” behavior.
Suggested changes
- During salvage, place the early guard in the current handler at
gateway/slash_commands.py:1420;619bd782moved_handle_model_commandout ofgateway/run.py. - Make the trailing-newline test control or mock the normal switch pipeline and assert that it receives the first-line model name.
This is an automated hermes-sweeper review.
| # assert that the response is NOT the new multi-line guidance error. | ||
| result = await _make_runner()._handle_model_command(event) | ||
|
|
||
| assert result is None or "single-line command" not in result.lower() |
Contributor
There was a problem hiding this comment.
This assertion accepts any non-guidance failure, including a validation or provider error, so it does not prove the stated contract that a trailing newline reaches the normal successful switch path. Please control the switch dependency and assert the first-line model argument is used.
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.
What does this PR do?
Fixes #22716 — a multi-line
/modelcommand (e.g.Shift+Enterin Element/Matrix produces/model openai/gpt-5.5\nFollow-up questionin a single send) is currently rejected with the misleading errorModel names cannot contain spaces, and the user's follow-up text is silently swallowed. The error message is wrong in two ways: there are no spaces in the model name, and the real problem is that\nwas forwarded into the model-name parser at all.This PR detects the multi-line form early in
_handle_model_commandand returns a clear, actionable message that quotes the intended single-line command back to the user, e.g.:The fix is intentionally surgical — no behavior change for legitimate single-line
/modelinvocations, and no change to other commands that do accept multi-line text (/queue,/steer,/agent, etc.) because the new helper only short-circuits when called from the/modelhandler.Related Issue
Fixes #22716
Type of Change
Changes Made
gateway/platforms/base.py— addedMessageEvent.get_command_remainder()helper. Returns the text that follows the first newline of a command message (e.g./model X\nFoo→"Foo"), with strip semantics; returns""for non-commands, single-line commands, command-only messages, or messages whose remainder is whitespace-only. Sits next to the existingget_command_args()/is_command()helpers.gateway/run.py— added an early multi-line detection block in_handle_model_command()that usesget_command_remainder()to short-circuit before reaching the model-name parser. Handles two distinct multi-line shapes:/model X\nFoo—get_command_args()returns"X\nFoo", so the suggestion is`/model X`./model\nFoo—get_command_args()consumes the\nas the arg separator and returns"Foo", so the suggestion falls back to`/model <name>`.tests/gateway/test_platform_base.py— addedTestMessageEventGetCommandRemainder(8 tests) covering: single-line no-remainder, command-only no-remainder, multi-line returns remainder, remainder is stripped, inner newlines in remainder preserved, blank-only remainder returns"", non-command returns"", and a non-regression check thatget_command_args()still returns the full multi-line tail for commands like/queue line1\nline2\nline3that legitimately accept multi-line text.tests/gateway/test_model_command_multiline.py(new file, 4 tests) — async regression tests for_handle_model_command()covering: the canonical/model X\nFoocase, multi-line with flags (/model X --global\nFoo), benign trailing-newline (/model X\nwith no follow-up — should NOT trigger the multi-line error), and the empty-first-line fallback (/model\nFoo— should suggest the generic/model <name>form).scripts/release.py— addsdockerpaula@gmail.com → dockerpaulatoAUTHOR_MAPso the contributor-attribution check resolves the email when generating release notes.How to Test
Reproduction (before the fix):
Before — the gateway replies:
Model names cannot contain spaces(and the question is dropped).After — the gateway replies:
`/model` is a single-line command. Send `/model openai/gpt-5.5` first, then send your follow-up message separately.Automated:
All green locally.
Checklist
Code
fix(gateway): …,chore(release): …)Documentation & Housekeeping
str.partition,str.split); no platform-specific callsScreenshots / Logs