fix(desktop): add missing PATCH /api/sessions/{id} so rename works (#36249)
The desktop rename dialog sent PATCH /api/sessions/{id}, but the backend
only defined GET and DELETE for that path — FastAPI returned 405 Method
Not Allowed, surfaced to the user as "Rename failed". Add the PATCH route
backed by SessionDB.set_session_title (handles sanitization, uniqueness,
and clearing the title when empty).
Also fix a misleading notification: any 405 was summarized as an unrelated
"does not support that audio endpoint" message. Make it a generic 405 hint.
This commit is contained in:
@ -68,7 +68,8 @@ const ERROR_SUMMARIES: { test: (msg: string) => boolean; summarize: (msg: string
|
||||
},
|
||||
{
|
||||
test: msg => /method not allowed/i.test(msg),
|
||||
summarize: () => 'The desktop backend does not support that audio endpoint yet. Restart Hermes Desktop.'
|
||||
summarize: () =>
|
||||
'The desktop backend rejected that request (405 Method Not Allowed). Try restarting Hermes Desktop.'
|
||||
},
|
||||
{
|
||||
test: msg => /microphone permission/i.test(msg),
|
||||
|
||||
@ -3657,6 +3657,31 @@ async def delete_session_endpoint(session_id: str):
|
||||
db.close()
|
||||
|
||||
|
||||
class SessionRename(BaseModel):
|
||||
title: Optional[str] = None
|
||||
|
||||
|
||||
@app.patch("/api/sessions/{session_id}")
|
||||
async def rename_session_endpoint(session_id: str, body: SessionRename):
|
||||
"""Rename a session (or clear its title when ``title`` is empty/null)."""
|
||||
from hermes_state import SessionDB
|
||||
db = SessionDB()
|
||||
try:
|
||||
sid = db.resolve_session_id(session_id)
|
||||
if not sid:
|
||||
raise HTTPException(status_code=404, detail="Session not found")
|
||||
try:
|
||||
updated = db.set_session_title(sid, body.title or "")
|
||||
except ValueError as e:
|
||||
# Title too long, invalid characters, or already in use.
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
if not updated:
|
||||
raise HTTPException(status_code=404, detail="Session not found")
|
||||
return {"ok": True, "title": db.get_session_title(sid) or ""}
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Log viewer endpoint
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@ -205,6 +205,51 @@ class TestWebServerEndpoints:
|
||||
assert captured["list"] == 3
|
||||
assert captured["count"] == 3
|
||||
|
||||
def test_rename_session_updates_title(self):
|
||||
"""PATCH /api/sessions/{id} renames a session (regression: the route
|
||||
was missing entirely, so the desktop rename dialog got a 405)."""
|
||||
from hermes_state import SessionDB
|
||||
|
||||
db = SessionDB()
|
||||
try:
|
||||
db.create_session(session_id="rename-me", source="cli")
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
resp = self.client.patch("/api/sessions/rename-me", json={"title": "My Chat"})
|
||||
assert resp.status_code == 200
|
||||
assert resp.json() == {"ok": True, "title": "My Chat"}
|
||||
|
||||
db = SessionDB()
|
||||
try:
|
||||
assert db.get_session_title("rename-me") == "My Chat"
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
def test_rename_session_clears_title_when_empty(self):
|
||||
from hermes_state import SessionDB
|
||||
|
||||
db = SessionDB()
|
||||
try:
|
||||
db.create_session(session_id="clear-me", source="cli")
|
||||
db.set_session_title("clear-me", "Has A Title")
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
resp = self.client.patch("/api/sessions/clear-me", json={"title": ""})
|
||||
assert resp.status_code == 200
|
||||
assert resp.json() == {"ok": True, "title": ""}
|
||||
|
||||
db = SessionDB()
|
||||
try:
|
||||
assert db.get_session_title("clear-me") is None
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
def test_rename_session_not_found(self):
|
||||
resp = self.client.patch("/api/sessions/does-not-exist", json={"title": "x"})
|
||||
assert resp.status_code == 404
|
||||
|
||||
def test_audio_transcription_endpoint(self, monkeypatch):
|
||||
import tools.transcription_tools as transcription_tools
|
||||
|
||||
|
||||
Reference in New Issue
Block a user