package handler /* 真实删除会话的 Web API(2026-10-03)。 # 为什么放在 admin 组而不是 UserAuth 组 会话是**协作记录**:里面有多个 Agent 与人类的多轮往来,删除后不可恢复, 且其中任何一方的历史都会随之消失。而 UserAuth 组里的任何登录用户都能 看到自己的全部会话 —— 把「删掉别人的协作记录」放在那里,等于让任何一个 登录用户都能删别人的东西。 所以路由挂在 `AdminOnly` 下(见 cmd/server/main.go),与 `DELETE /admin/users/{id}`、`DELETE /admin/agent-keys/{id}` 同一档。 # 为什么不提供 Agent 侧的删除工具 MCP 工具面(server/internal/mcp)**刻意**没有暴露删除: · 删除不可撤销,而 MCP 的调用方是模型 —— 模型误判一次就是真丢数据 · 现有 MCP 工具里最接近破坏性的 `forward_mail` 也只是发信,撤销成本很低 · `connect_to_server` 已经刻意不提供改坐标的参数,同一条原则: **不可逆的运维动作不进模型可及的面** Agent 要「结束」一条线索,走归档(`ArchiveSession`)—— 那才是协作语义里 对应的操作。 */ import ( "errors" "net/http" "github.com/agentmail/gateway/internal/repo" ) // AdminDeleteSession 真实删除一条会话及其全部从属数据。 // // 返回实际删掉的行数,调用方可以核对「删干净了」—— // 只回 200 的话,一个漏删 mails 的实现看起来同样成功。 func AdminDeleteSession(w http.ResponseWriter, r *http.Request) { id, ok := pathUUID(w, r, "id") if !ok { return } res, err := repo.DeleteSession(r.Context(), id.String()) if err != nil { if errors.Is(err, repo.ErrSessionNotFound) { Error(w, http.StatusNotFound, "会话不存在") return } Error(w, http.StatusInternalServerError, "删除会话失败") return } JSON(w, http.StatusOK, map[string]any{ "status": "deleted", "id": res.SessionID, "deleted": map[string]int{ "mails": res.Mails, "attachments": res.Attachments, "mail_reads": res.MailReads, "relayed_mails": res.Related, "permission_requests": res.Permissions, "session_agent_locks": res.Locks, }, "total": res.Total(), }) }