From a8c178ef1eb7c440242cbcc5e79d5663b70298b5 Mon Sep 17 00:00:00 2001 From: lhl Date: Sat, 12 Sep 2026 14:27:53 +0800 Subject: [PATCH] =?UTF-8?q?feat(server):=20PATCH=20/api/sessions/{sid}=20?= =?UTF-8?q?=E4=BC=9A=E8=AF=9D=E9=87=8D=E5=91=BD=E5=90=8D=20+=20service.ren?= =?UTF-8?q?ame=5Fsession?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/genesis/server/app.py | 15 +++++++++++++++ src/genesis/server/service.py | 4 ++++ tests/test_server_api.py | 20 ++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/genesis/server/app.py b/src/genesis/server/app.py index f15e9b3..256b129 100644 --- a/src/genesis/server/app.py +++ b/src/genesis/server/app.py @@ -56,6 +56,10 @@ class SessionCreate(BaseModel): project: str | None = None +class SessionRename(BaseModel): + name: str + + class ProjectCreate(BaseModel): name: str display_name: str = "" @@ -189,6 +193,17 @@ def create_app( raise _error(404, "SESSION_NOT_FOUND", f"会话不存在: {sid}") return rec.to_dict + @app.patch("/api/sessions/{sid}") + def rename_session(sid: str, body: SessionRename): + name = (body.name or "").strip() + if not name: + raise _error(400, "INVALID_NAME", "会话名不能为空") + try: + rec = service.rename_session(sid, name) + except SessionNotFoundError: + raise _error(404, "SESSION_NOT_FOUND", f"会话不存在: {sid}") + return {"session_id": rec.session_id, "name": rec.name} + @app.delete("/api/sessions/{sid}") def delete_session(sid: str): ok = service.store.delete_session(sid) diff --git a/src/genesis/server/service.py b/src/genesis/server/service.py index dbf7523..7341d65 100644 --- a/src/genesis/server/service.py +++ b/src/genesis/server/service.py @@ -122,6 +122,10 @@ class GenesisService: def get_session(self, session_id: str) -> SessionRecord: return self.store.get_session(session_id) + def rename_session(self, session_id: str, name: str) -> SessionRecord: + """重命名会话(历史项「重命名」)。name 由调用方保证非空。""" + return self.store.update_session(session_id, name=name) + def rag_stats(self, session_id: str) -> dict: """仅读返回 RAG 索引状态:片段数 / 是否启用。供前端 RAG 开关徽标使用。""" chunks = 0 diff --git a/tests/test_server_api.py b/tests/test_server_api.py index cabae4c..cc31bbf 100644 --- a/tests/test_server_api.py +++ b/tests/test_server_api.py @@ -357,3 +357,23 @@ def test_api_list_sessions_filter_by_project(client): ids = {x["session_id"] for x in res.json()} assert r0.json()["session_id"] in ids assert r1.json()["session_id"] not in ids + +def test_api_rename_session(client): + sid = client.post("/api/sessions", json={"user_id": "u1"}).json()["session_id"] + r = client.patch("/api/sessions/" + sid, json={"name": "股票系统需求"}) + assert r.status_code == 200 + assert r.json()["name"] == "股票系统需求" + assert client.get("/api/sessions/" + sid).json()["name"] == "股票系统需求" + + +def test_api_rename_session_empty_name(client): + sid = client.post("/api/sessions", json={"user_id": "u1"}).json()["session_id"] + r = client.patch("/api/sessions/" + sid, json={"name": " "}) + assert r.status_code == 400 + assert r.json()["detail"]["code"] == "INVALID_NAME" + + +def test_api_rename_session_not_found(client): + r = client.patch("/api/sessions/nope", json={"name": "x"}) + assert r.status_code == 404 + assert r.json()["detail"]["code"] == "SESSION_NOT_FOUND"