on a58e607 help sign in
crush/internal/session/session.go
150 lines 4.0 kB history raw
1package session
3import (
4 "context"
5 "database/sql"
7 "github.com/google/uuid"
8 "github.com/opencode-ai/opencode/internal/db"
9 "github.com/opencode-ai/opencode/internal/pubsub"
12type Session struct {
13 ID string
14 ParentSessionID string
15 Title string
16 MessageCount int64
17 PromptTokens int64
18 CompletionTokens int64
19 Cost float64
20 CreatedAt int64
21 UpdatedAt int64
24type Service interface {
25 pubsub.Suscriber[Session]
26 Create(ctx context.Context, title string) (Session, error)
27 CreateTitleSession(ctx context.Context, parentSessionID string) (Session, error)
28 CreateTaskSession(ctx context.Context, toolCallID, parentSessionID, title string) (Session, error)
29 Get(ctx context.Context, id string) (Session, error)
30 List(ctx context.Context) ([]Session, error)
31 Save(ctx context.Context, session Session) (Session, error)
32 Delete(ctx context.Context, id string) error
35type service struct {
36 *pubsub.Broker[Session]
37 q db.Querier
40func (s *service) Create(ctx context.Context, title string) (Session, error) {
41 dbSession, err := s.q.CreateSession(ctx, db.CreateSessionParams{
42 ID: uuid.New().String(),
43 Title: title,
44 })
45 if err != nil {
46 return Session{}, err
47 }
48 session := s.fromDBItem(dbSession)
49 s.Publish(pubsub.CreatedEvent, session)
50 return session, nil
53func (s *service) CreateTaskSession(ctx context.Context, toolCallID, parentSessionID, title string) (Session, error) {
54 dbSession, err := s.q.CreateSession(ctx, db.CreateSessionParams{
55 ID: toolCallID,
56 ParentSessionID: sql.NullString{String: parentSessionID, Valid: true},
57 Title: title,
58 })
59 if err != nil {
60 return Session{}, err
61 }
62 session := s.fromDBItem(dbSession)
63 s.Publish(pubsub.CreatedEvent, session)
64 return session, nil
67func (s *service) CreateTitleSession(ctx context.Context, parentSessionID string) (Session, error) {
68 dbSession, err := s.q.CreateSession(ctx, db.CreateSessionParams{
69 ID: "title-" + parentSessionID,
70 ParentSessionID: sql.NullString{String: parentSessionID, Valid: true},
71 Title: "Generate a title",
72 })
73 if err != nil {
74 return Session{}, err
75 }
76 session := s.fromDBItem(dbSession)
77 s.Publish(pubsub.CreatedEvent, session)
78 return session, nil
81func (s *service) Delete(ctx context.Context, id string) error {
82 session, err := s.Get(ctx, id)
83 if err != nil {
84 return err
85 }
86 err = s.q.DeleteSession(ctx, session.ID)
87 if err != nil {
88 return err
89 }
90 s.Publish(pubsub.DeletedEvent, session)
91 return nil
94func (s *service) Get(ctx context.Context, id string) (Session, error) {
95 dbSession, err := s.q.GetSessionByID(ctx, id)
96 if err != nil {
97 return Session{}, err
98 }
99 return s.fromDBItem(dbSession), nil
102func (s *service) Save(ctx context.Context, session Session) (Session, error) {
103 dbSession, err := s.q.UpdateSession(ctx, db.UpdateSessionParams{
104 ID: session.ID,
105 Title: session.Title,
106 PromptTokens: session.PromptTokens,
107 CompletionTokens: session.CompletionTokens,
108 Cost: session.Cost,
109 })
110 if err != nil {
111 return Session{}, err
112 }
113 session = s.fromDBItem(dbSession)
114 s.Publish(pubsub.UpdatedEvent, session)
115 return session, nil
118func (s *service) List(ctx context.Context) ([]Session, error) {
119 dbSessions, err := s.q.ListSessions(ctx)
120 if err != nil {
121 return nil, err
122 }
123 sessions := make([]Session, len(dbSessions))
124 for i, dbSession := range dbSessions {
125 sessions[i] = s.fromDBItem(dbSession)
126 }
127 return sessions, nil
130func (s service) fromDBItem(item db.Session) Session {
131 return Session{
132 ID: item.ID,
133 ParentSessionID: item.ParentSessionID.String,
134 Title: item.Title,
135 MessageCount: item.MessageCount,
136 PromptTokens: item.PromptTokens,
137 CompletionTokens: item.CompletionTokens,
138 Cost: item.Cost,
139 CreatedAt: item.CreatedAt,
140 UpdatedAt: item.UpdatedAt,
141 }
144func NewService(q db.Querier) Service {
145 broker := pubsub.NewBroker[Session]()
146 return &service{
147 broker,
148 q,
149 }