From 65f75dafec5e61ba0e7b0a0f86ed4d3c9a80acee Mon Sep 17 00:00:00 2001 From: Lyon <88232613+pikasTech@users.noreply.github.com> Date: Tue, 23 Jun 2026 07:53:07 +0800 Subject: [PATCH] fix(workbench): expose session list titles (#1957) --- internal/workbenchruntime/service.go | 32 +++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/internal/workbenchruntime/service.go b/internal/workbenchruntime/service.go index b805250e..ef7857e0 100644 --- a/internal/workbenchruntime/service.go +++ b/internal/workbenchruntime/service.go @@ -1486,15 +1486,16 @@ func (s *Server) querySessionSummariesAttempt(ctx context.Context, stage string, } defer rows.Close() for rows.Next() { - var sessionID, ownerUserID, projectID, conversationID, threadID, status, lastTraceID sql.NullString + var sessionID, ownerUserID, projectID, conversationID, threadID, status, lastTraceID, sessionJSON sql.NullString var projectedSeq sql.NullInt64 var createdAt, updatedAt sql.NullString - if err := rows.Scan(&sessionID, &ownerUserID, &projectID, &conversationID, &threadID, &status, &lastTraceID, &projectedSeq, &createdAt, &updatedAt); err != nil { + if err := rows.Scan(&sessionID, &ownerUserID, &projectID, &conversationID, &threadID, &status, &lastTraceID, &projectedSeq, &createdAt, &updatedAt, &sessionJSON); err != nil { return err } if !sessionID.Valid || strings.TrimSpace(sessionID.String) == "" { continue } + sessionPayload := sessionJSONMap(sessionJSON) item := map[string]any{ "id": sessionID.String, "sessionId": sessionID.String, @@ -1507,6 +1508,7 @@ func (s *Server) querySessionSummariesAttempt(ctx context.Context, stage string, "projectedSeq": nullableInt(projectedSeq), "createdAt": nullableTimeText(createdAt), "updatedAt": first(nullableTimeText(updatedAt), nullableTimeText(createdAt)), + "sessionJson": sessionPayload, "valuesPrinted": false, "valuesRedacted": true, } @@ -1887,9 +1889,21 @@ func sessionSummarySelectClause() string { "projected_seq", "created_at", "updated_at", + "session_json", }, ", ") } +func sessionJSONMap(raw sql.NullString) map[string]any { + if !raw.Valid || strings.TrimSpace(raw.String) == "" { + return map[string]any{} + } + var payload map[string]any + if err := json.Unmarshal([]byte(raw.String), &payload); err != nil { + return map[string]any{} + } + return payload +} + func providerProfileFromSessionJSON(raw sql.NullString) string { if !raw.Valid || strings.TrimSpace(raw.String) == "" { return "" @@ -1969,7 +1983,19 @@ func sessionSummary(session map[string]any, facts map[string][]any) map[string]a if len(turn) > 0 { turnSummary = map[string]any{"turnId": first(text(turn["turnId"]), traceID), "traceId": traceID, "status": status, "running": isRunning(status), "terminal": isTerminal(status), "eventCount": projection["lastProjectedSeq"], "projection": projection, "projectionStatus": projection["projectionStatus"], "projectionHealth": projection["projectionHealth"], "staleMs": projection["staleMs"], "blocker": projection["blocker"], "timing": timing, "startedAt": timing["startedAt"], "lastEventAt": timing["lastEventAt"], "finishedAt": timing["finishedAt"], "durationMs": timing["durationMs"], "updatedAt": updatedAt(turn)} } - return map[string]any{"sessionId": sid, "threadId": nullableText(session["threadId"]), "agentId": first(text(session["agentId"]), "hwlab-code-agent"), "status": status, "running": isRunning(status), "terminal": isTerminal(status), "lastTraceId": nullableText(traceID), "projection": projection, "projectionStatus": projection["projectionStatus"], "projectionHealth": projection["projectionHealth"], "staleMs": projection["staleMs"], "blocker": projection["blocker"], "providerProfile": nullableText(first(text(session["providerProfile"]), text(objectMap(session["sessionJson"])["providerProfile"]))), "messageCount": messageCount, "firstUserMessagePreview": firstUserMessagePreview, "updatedAt": updatedAt(session), "turnSummary": turnSummary, "valuesRedacted": true} + title := sessionDisplayTitle(session, firstUserMessagePreview) + return map[string]any{"sessionId": sid, "threadId": nullableText(session["threadId"]), "agentId": first(text(session["agentId"]), "hwlab-code-agent"), "title": title, "name": title, "status": status, "running": isRunning(status), "terminal": isTerminal(status), "lastTraceId": nullableText(traceID), "projection": projection, "projectionStatus": projection["projectionStatus"], "projectionHealth": projection["projectionHealth"], "staleMs": projection["staleMs"], "blocker": projection["blocker"], "providerProfile": nullableText(first(text(session["providerProfile"]), text(objectMap(session["sessionJson"])["providerProfile"]))), "messageCount": messageCount, "firstUserMessagePreview": firstUserMessagePreview, "updatedAt": updatedAt(session), "turnSummary": turnSummary, "valuesRedacted": true} +} + +func sessionDisplayTitle(session map[string]any, firstUserMessagePreview any) string { + sessionJSON := objectMap(session["sessionJson"]) + if title := first(text(session["title"]), text(session["name"]), text(session["displayName"]), text(sessionJSON["title"]), text(sessionJSON["name"]), text(sessionJSON["displayName"])); title != "" { + return title + } + if preview := text(firstUserMessagePreview); preview != "" { + return preview + } + return "新建会话" } func messageSummaryForSession(facts map[string][]any, sid string) map[string]any {