返回 DeepSeek-Reasonix
session_bundle_heads.go
根目录 / internal / doctor / session_bundle_heads.go
1 package doctor
2
3 import (
4 "time"
5
6 "reasonix/internal/agent"
7 )
8
9 // SessionBundleHead is one head of a schema-2 session log as the bundle
10 // manifest lists it. Names are user text and stay; previews are left out
11 // because the transcript files themselves travel in the bundle.
12 type SessionBundleHead struct {
13 ID string `json:"id"`
14 Kind string `json:"kind"`
15 Name string `json:"name,omitempty"`
16 ParentHead string `json:"parent_head,omitempty"`
17 ForkFrom string `json:"fork_from,omitempty"`
18 Writer string `json:"writer,omitempty"`
19 CreatedAt time.Time `json:"created_at"`
20 LastActivity time.Time `json:"last_activity"`
21 MessageCount int `json:"message_count"`
22 Turns int `json:"turns,omitempty"`
23 Selected bool `json:"selected,omitempty"`
24 Covered bool `json:"covered,omitempty"`
25 Retired bool `json:"retired,omitempty"`
26 }
27
28 // describeSessionBundleHeads fills the head fields of a manifest entry from
29 // the session's own log. A schema-1 session leaves them empty; an unreadable
30 // schema-2 log is reported to the caller and still bundled as files.
31 func describeSessionBundleHeads(entry *SessionBundleEntry, path string) error {
32 heads, err := agent.ListSessionHeads(path)
33 if err != nil {
34 return err
35 }
36 if len(heads) == 0 {
37 return nil
38 }
39 entry.LogFormat = 2
40 entry.Heads = make([]SessionBundleHead, 0, len(heads))
41 for _, head := range heads {
42 if head.Selected {
43 entry.SelectedHead = head.ID
44 }
45 entry.Heads = append(entry.Heads, SessionBundleHead{
46 ID: head.ID, Kind: head.Kind, Name: head.Name, ParentHead: head.ParentHead, ForkFrom: head.ForkFrom,
47 Writer: head.Writer, CreatedAt: head.CreatedAt, LastActivity: head.LastActivity,
48 MessageCount: head.MessageCount, Turns: head.Turns,
49 Selected: head.Selected, Covered: head.Covered, Retired: head.Retired,
50 })
51 }
52 return nil
53 }
54
54 lines GO