fix(cli,gateway): surface title errors from /new <name>

The contributor's PR silently swallowed ValueError from
SessionDB.set_session_title() with bare except Exception: pass.
Users typing /new <title> with an already-in-use title got an
untitled session and no feedback.

Changes:
- cli.py: catch ValueError from both sanitize_title() and
  set_session_title(); print the error and mark the session
  untitled in the banner (never echo the rejected title back).
- gateway/run.py: append a warning note to the reset reply on
  title rejection; reflect the accepted title in the header.
- Add regression tests for the duplicate-title path in CLI and
  gateway.

Also map exx@example.com -> @exxmen in scripts/release.py.
This commit is contained in:
Teknium 2026-05-04 02:38:24 -07:00
parent f720751d79
commit 5b6d413476
5 changed files with 136 additions and 8 deletions

View file

@ -238,3 +238,40 @@ def test_new_session_with_title(capsys):
captured = capsys.readouterr()
assert "My Test Session" in captured.out
def test_new_session_with_duplicate_title_surfaces_error(capsys):
"""new_session(title=...) handles ValueError from a duplicate-title conflict.
The session is still created; the title assignment fails; the success banner
must not claim the rejected title as the session name.
"""
cli = _make_cli()
cli._session_db = MagicMock()
cli._session_db.set_session_title.side_effect = ValueError(
"Title 'Dup' is already in use by session abc-123"
)
cli.agent = _FakeAgent("old_session_id", datetime.now())
cli.conversation_history = []
# Capture warnings printed via cli._cprint. After importlib.reload(),
# the method's __globals__ dict is the one from the live module — patch
# the exact dict the method will read.
warnings: list[str] = []
method_globals = cli.new_session.__globals__
original = method_globals["_cprint"]
method_globals["_cprint"] = lambda msg: warnings.append(msg)
try:
cli.new_session(title="Dup")
finally:
method_globals["_cprint"] = original
cli._session_db.set_session_title.assert_called_once()
joined = "\n".join(warnings)
assert "already in use" in joined
assert "session started untitled" in joined
# The success banner must NOT claim the rejected title as the session name.
captured = capsys.readouterr()
assert "New session started: Dup" not in captured.out
assert "New session started!" in captured.out