返回 DeepSeek-Reasonix
session_catalog_routes.go
根目录 / desktop / session_catalog_routes.go
1 package main
2
3 import (
4 "context"
5 "sort"
6 "strings"
7
8 "reasonix/desktop/internal/workspacestate"
9 "reasonix/internal/config"
10 "reasonix/internal/session"
11 )
12
13 func sessionRoute(id string) string {
14 id = strings.TrimSpace(id)
15 if id == "" {
16 return ""
17 }
18 return remoteSessionIDRoutePrefix + id
19 }
20
21 func parseSessionRoute(route string) (string, bool) {
22 locator := classifySessionLocator(route)
23 if locator.kind != sessionLocatorCanonical {
24 return "", false
25 }
26 return locator.ref.SessionID, true
27 }
28
29 func (a *App) listCanonicalSessionsFromDir(dir, active string) []SessionMeta {
30 service := a.desktopSessionService(dir)
31 if service == nil {
32 return []SessionMeta{}
33 }
34 activeID, _ := parseSessionRoute(active)
35 state, err := a.workspaceRegistry().Load(a.bootContext())
36 if err != nil {
37 return []SessionMeta{{Error: "workspace_registry_unavailable", TurnsState: "corrupt"}}
38 }
39 allowed := map[string]bool{}
40 for _, workspace := range state.Workspaces {
41 matches := sameDesktopPath(dir, desktopSessionDir(workspace.Root))
42 if workspace.ID == workspacestate.GlobalWorkspaceID {
43 matches = matches || sameDesktopPath(dir, config.SessionDir())
44 }
45 if matches {
46 for _, id := range workspace.SessionIDs {
47 if state.SessionStates[id].Lifecycle == workspacestate.Active {
48 allowed[id] = true
49 }
50 }
51 }
52 }
53 query := service.Query()
54 result := make([]SessionMeta, 0)
55 cursor := ""
56 for {
57 page, err := query.List(context.Background(), cursor, 100)
58 if err != nil {
59 return result
60 }
61 for _, info := range page.Sessions {
62 if !allowed[info.SessionID] {
63 continue
64 }
65 delete(allowed, info.SessionID)
66 meta := SessionMeta{
67 Path: sessionRoute(info.SessionID), SessionID: info.SessionID,
68 HostID: service.HostID(), Codec: info.Codec, Error: info.Error,
69 Title: info.Title, Turns: info.Turns, TurnsState: "valid",
70 CreatedAt: info.CreatedAt.UnixMilli(), LastActivityAt: info.UpdatedAt.UnixMilli(),
71 ModTime: info.UpdatedAt.UnixMilli(), Current: info.SessionID == activeID,
72 }
73 if info.Error != "" {
74 meta.TurnsState = "corrupt"
75 } else {
76 meta.Preview = info.Preview
77 }
78 a.mu.RLock()
79 _, meta.Open = a.runtimeBySessionKey[sessionRuntimeKey(meta.Path)]
80 a.mu.RUnlock()
81 result = append(result, meta)
82 }
83 if page.NextCursor == "" {
84 break
85 }
86 cursor = page.NextCursor
87 }
88 for id := range allowed {
89 result = append(result, SessionMeta{Path: sessionRoute(id), SessionID: id, HostID: localDesktopHostID, Error: "session_content_unavailable", TurnsState: "corrupt"})
90 }
91 sort.SliceStable(result, func(i, j int) bool { return result[i].LastActivityAt > result[j].LastActivityAt })
92 return result
93 }
94
95 func sessionRefForRoute(service *session.Service, route string) (session.SessionRef, bool) {
96 id, ok := parseSessionRoute(route)
97 if !ok || service == nil {
98 return session.SessionRef{}, false
99 }
100 return session.SessionRef{HostID: service.HostID(), SessionID: id}, true
101 }
102
102 lines GO