bridge.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. package app
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "time"
  7. "github.com/sst/opencode/internal/message"
  8. "github.com/sst/opencode/internal/pubsub"
  9. "github.com/sst/opencode/internal/session"
  10. "github.com/sst/opencode/pkg/client"
  11. )
  12. // SessionServiceBridge adapts the HTTP API to the old session.Service interface
  13. type SessionServiceBridge struct {
  14. client *client.ClientWithResponses
  15. }
  16. // NewSessionServiceBridge creates a new session service bridge
  17. func NewSessionServiceBridge(client *client.ClientWithResponses) *SessionServiceBridge {
  18. return &SessionServiceBridge{client: client}
  19. }
  20. // Create creates a new session
  21. func (s *SessionServiceBridge) Create(ctx context.Context, title string) (session.Session, error) {
  22. // Moved to app.CreateSession
  23. return session.Session{}, fmt.Errorf("don't use this")
  24. }
  25. // Get retrieves a session by ID
  26. func (s *SessionServiceBridge) Get(ctx context.Context, id string) (session.Session, error) {
  27. // Moved to app.GetSession
  28. return session.Session{}, fmt.Errorf("don't use this")
  29. }
  30. // List retrieves all sessions
  31. func (s *SessionServiceBridge) List(ctx context.Context) ([]session.Session, error) {
  32. // Moved to app.ListSessions
  33. return []session.Session{}, fmt.Errorf("don't use this")
  34. }
  35. // Update updates a session - NOT IMPLEMENTED IN API YET
  36. func (s *SessionServiceBridge) Update(ctx context.Context, id, title string) error {
  37. // TODO: Not implemented in TypeScript API yet
  38. return fmt.Errorf("session update not implemented in API")
  39. }
  40. // Delete deletes a session - NOT IMPLEMENTED IN API YET
  41. func (s *SessionServiceBridge) Delete(ctx context.Context, id string) error {
  42. // TODO: Not implemented in TypeScript API yet
  43. return fmt.Errorf("session delete not implemented in API")
  44. }
  45. // AgentServiceBridge provides a minimal agent service that sends messages to the API
  46. type AgentServiceBridge struct {
  47. client *client.ClientWithResponses
  48. }
  49. // NewAgentServiceBridge creates a new agent service bridge
  50. func NewAgentServiceBridge(client *client.ClientWithResponses) *AgentServiceBridge {
  51. return &AgentServiceBridge{client: client}
  52. }
  53. // Run sends a message to the chat API
  54. func (a *AgentServiceBridge) Run(ctx context.Context, sessionID string, text string, attachments ...message.Attachment) (string, error) {
  55. // TODO: Handle attachments when API supports them
  56. if len(attachments) > 0 {
  57. // For now, ignore attachments
  58. // return "", fmt.Errorf("attachments not supported yet")
  59. }
  60. part := client.MessagePart{}
  61. part.FromMessagePartText(client.MessagePartText{
  62. Type: "text",
  63. Text: text,
  64. })
  65. parts := []client.MessagePart{part}
  66. go a.client.PostSessionChatWithResponse(ctx, client.PostSessionChatJSONRequestBody{
  67. SessionID: sessionID,
  68. Parts: parts,
  69. ProviderID: "anthropic",
  70. ModelID: "claude-sonnet-4-20250514",
  71. })
  72. // The actual response will come through SSE
  73. // For now, just return success
  74. return "", nil
  75. }
  76. // Cancel cancels the current generation - NOT IMPLEMENTED IN API YET
  77. func (a *AgentServiceBridge) Cancel(sessionID string) error {
  78. // TODO: Not implemented in TypeScript API yet
  79. return nil
  80. }
  81. // IsBusy checks if the agent is busy - NOT IMPLEMENTED IN API YET
  82. func (a *AgentServiceBridge) IsBusy() bool {
  83. // TODO: Not implemented in TypeScript API yet
  84. return false
  85. }
  86. // IsSessionBusy checks if the agent is busy for a specific session - NOT IMPLEMENTED IN API YET
  87. func (a *AgentServiceBridge) IsSessionBusy(sessionID string) bool {
  88. // TODO: Not implemented in TypeScript API yet
  89. return false
  90. }
  91. // CompactSession compacts a session - NOT IMPLEMENTED IN API YET
  92. func (a *AgentServiceBridge) CompactSession(ctx context.Context, sessionID string, force bool) error {
  93. // TODO: Not implemented in TypeScript API yet
  94. return fmt.Errorf("session compaction not implemented in API")
  95. }
  96. // MessageServiceBridge provides a minimal message service that fetches from the API
  97. type MessageServiceBridge struct {
  98. client *client.ClientWithResponses
  99. broker *pubsub.Broker[message.Message]
  100. }
  101. // NewMessageServiceBridge creates a new message service bridge
  102. func NewMessageServiceBridge(client *client.ClientWithResponses) *MessageServiceBridge {
  103. return &MessageServiceBridge{
  104. client: client,
  105. broker: pubsub.NewBroker[message.Message](),
  106. }
  107. }
  108. // GetBySession retrieves messages for a session
  109. func (m *MessageServiceBridge) GetBySession(ctx context.Context, sessionID string) ([]message.Message, error) {
  110. return m.List(ctx, sessionID)
  111. }
  112. // List retrieves messages for a session
  113. func (m *MessageServiceBridge) List(ctx context.Context, sessionID string) ([]message.Message, error) {
  114. resp, err := m.client.PostSessionMessages(ctx, client.PostSessionMessagesJSONRequestBody{
  115. SessionID: sessionID,
  116. })
  117. if err != nil {
  118. return nil, err
  119. }
  120. defer resp.Body.Close()
  121. // The API returns a different format, we'll need to adapt it
  122. var rawMessages any
  123. if err := json.NewDecoder(resp.Body).Decode(&rawMessages); err != nil {
  124. return nil, err
  125. }
  126. // TODO: Convert the API message format to our internal format
  127. // For now, return empty to avoid compilation errors
  128. return []message.Message{}, nil
  129. }
  130. // Create creates a new message - NOT NEEDED, handled by chat API
  131. func (m *MessageServiceBridge) Create(ctx context.Context, sessionID string, params message.CreateMessageParams) (message.Message, error) {
  132. // Messages are created through the chat API
  133. return message.Message{}, fmt.Errorf("use chat API to send messages")
  134. }
  135. // Update updates a message - NOT IMPLEMENTED IN API YET
  136. func (m *MessageServiceBridge) Update(ctx context.Context, msg message.Message) (message.Message, error) {
  137. // TODO: Not implemented in TypeScript API yet
  138. return message.Message{}, fmt.Errorf("message update not implemented in API")
  139. }
  140. // Delete deletes a message - NOT IMPLEMENTED IN API YET
  141. func (m *MessageServiceBridge) Delete(ctx context.Context, id string) error {
  142. // TODO: Not implemented in TypeScript API yet
  143. return fmt.Errorf("message delete not implemented in API")
  144. }
  145. // DeleteSessionMessages deletes all messages for a session - NOT IMPLEMENTED IN API YET
  146. func (m *MessageServiceBridge) DeleteSessionMessages(ctx context.Context, sessionID string) error {
  147. // TODO: Not implemented in TypeScript API yet
  148. return fmt.Errorf("delete session messages not implemented in API")
  149. }
  150. // Get retrieves a message by ID - NOT IMPLEMENTED IN API YET
  151. func (m *MessageServiceBridge) Get(ctx context.Context, id string) (message.Message, error) {
  152. // TODO: Not implemented in TypeScript API yet
  153. return message.Message{}, fmt.Errorf("get message by ID not implemented in API")
  154. }
  155. // ListAfter retrieves messages after a timestamp - NOT IMPLEMENTED IN API YET
  156. func (m *MessageServiceBridge) ListAfter(ctx context.Context, sessionID string, timestamp time.Time) ([]message.Message, error) {
  157. // TODO: Not implemented in TypeScript API yet
  158. return []message.Message{}, fmt.Errorf("list messages after timestamp not implemented in API")
  159. }
  160. // Subscribe subscribes to message events
  161. func (m *MessageServiceBridge) Subscribe(ctx context.Context) <-chan pubsub.Event[message.Message] {
  162. return m.broker.Subscribe(ctx)
  163. }