summaryrefslogtreecommitdiffhomepage
path: root/internal/app
diff options
context:
space:
mode:
authoradamdottv <[email protected]>2025-05-28 15:36:31 -0500
committeradamdottv <[email protected]>2025-05-28 15:36:36 -0500
commit9d7c5efb9b0b60c62aef3777b65b458a31ebbc88 (patch)
tree0f5acb5b8093d872b30178ded53df719be40cf44 /internal/app
parent8863a499a9e311a48d6ab8bc05d267fb2a01f060 (diff)
downloadopencode-9d7c5efb9b0b60c62aef3777b65b458a31ebbc88.tar.gz
opencode-9d7c5efb9b0b60c62aef3777b65b458a31ebbc88.zip
wip: refactoring tui
Diffstat (limited to 'internal/app')
-rw-r--r--internal/app/app.go180
-rw-r--r--internal/app/app_new.go203
-rw-r--r--internal/app/interfaces.go42
-rw-r--r--internal/app/lsp.go134
-rw-r--r--internal/app/services_bridge.go245
5 files changed, 0 insertions, 804 deletions
diff --git a/internal/app/app.go b/internal/app/app.go
deleted file mode 100644
index 7aed6fb10..000000000
--- a/internal/app/app.go
+++ /dev/null
@@ -1,180 +0,0 @@
-package app
-
-import (
- "context"
- "maps"
- "sync"
- "time"
-
- "log/slog"
-
- "github.com/sst/opencode/internal/config"
- "github.com/sst/opencode/internal/fileutil"
- "github.com/sst/opencode/internal/lsp"
- "github.com/sst/opencode/internal/session"
- "github.com/sst/opencode/internal/status"
- "github.com/sst/opencode/internal/tui/theme"
- "github.com/sst/opencode/pkg/client"
-)
-
-type App struct {
- State map[string]any
-
- CurrentSession *session.Session
- Logs any // TODO: Define LogService interface when needed
- Sessions SessionService
- Messages MessageService
- History any // TODO: Define HistoryService interface when needed
- Permissions any // TODO: Define PermissionService interface when needed
- Status status.Service
- Client *client.ClientWithResponses
- Events *client.Client
-
- PrimaryAgent AgentService
-
- LSPClients map[string]*lsp.Client
-
- clientsMutex sync.RWMutex
-
- watcherCancelFuncs []context.CancelFunc
- cancelFuncsMutex sync.Mutex
- watcherWG sync.WaitGroup
-
- // UI state
- filepickerOpen bool
- completionDialogOpen bool
-}
-
-func New(ctx context.Context) (*App, error) {
- // Initialize status service (still needed for UI notifications)
- err := status.InitService()
- if err != nil {
- slog.Error("Failed to initialize status service", "error", err)
- return nil, err
- }
-
- // Initialize file utilities
- fileutil.Init()
-
- // Create HTTP client
- url := "http://localhost:16713"
- httpClient, err := client.NewClientWithResponses(url)
- if err != nil {
- slog.Error("Failed to create client", "error", err)
- return nil, err
- }
- eventClient, err := client.NewClient(url)
- if err != nil {
- slog.Error("Failed to create event client", "error", err)
- return nil, err
- }
-
- // Create service bridges
- sessionBridge := NewSessionServiceBridge(httpClient)
- messageBridge := NewMessageServiceBridge(httpClient)
- agentBridge := NewAgentServiceBridge(httpClient)
-
- app := &App{
- State: make(map[string]any),
- Client: httpClient,
- Events: eventClient,
- CurrentSession: &session.Session{},
- Sessions: sessionBridge,
- Messages: messageBridge,
- PrimaryAgent: agentBridge,
- Status: status.GetService(),
- LSPClients: make(map[string]*lsp.Client),
-
- // TODO: These services need API endpoints:
- Logs: nil, // logging.GetService(),
- History: nil, // history.GetService(),
- Permissions: nil, // permission.GetService(),
- }
-
- // Initialize theme based on configuration
- app.initTheme()
-
- // Initialize LSP clients in the background
- go app.initLSPClients(ctx)
-
- // TODO: Remove this once agent is fully replaced by API
- // app.PrimaryAgent, err = agent.NewAgent(
- // config.AgentPrimary,
- // app.Sessions,
- // app.Messages,
- // agent.PrimaryAgentTools(
- // app.Permissions,
- // app.Sessions,
- // app.Messages,
- // app.History,
- // app.LSPClients,
- // ),
- // )
- // if err != nil {
- // slog.Error("Failed to create primary agent", "error", err)
- // return nil, err
- // }
-
- return app, nil
-}
-
-// initTheme sets the application theme based on the configuration
-func (app *App) initTheme() {
- cfg := config.Get()
- if cfg == nil || cfg.TUI.Theme == "" {
- return // Use default theme
- }
-
- // Try to set the theme from config
- err := theme.SetTheme(cfg.TUI.Theme)
- if err != nil {
- slog.Warn("Failed to set theme from config, using default theme", "theme", cfg.TUI.Theme, "error", err)
- } else {
- slog.Debug("Set theme from config", "theme", cfg.TUI.Theme)
- }
-}
-
-// IsFilepickerOpen returns whether the filepicker is currently open
-func (app *App) IsFilepickerOpen() bool {
- return app.filepickerOpen
-}
-
-// SetFilepickerOpen sets the state of the filepicker
-func (app *App) SetFilepickerOpen(open bool) {
- app.filepickerOpen = open
-}
-
-// IsCompletionDialogOpen returns whether the completion dialog is currently open
-func (app *App) IsCompletionDialogOpen() bool {
- return app.completionDialogOpen
-}
-
-// SetCompletionDialogOpen sets the state of the completion dialog
-func (app *App) SetCompletionDialogOpen(open bool) {
- app.completionDialogOpen = open
-}
-
-// Shutdown performs a clean shutdown of the application
-func (app *App) Shutdown() {
- // Cancel all watcher goroutines
- app.cancelFuncsMutex.Lock()
- for _, cancel := range app.watcherCancelFuncs {
- cancel()
- }
- app.cancelFuncsMutex.Unlock()
- app.watcherWG.Wait()
-
- // Perform additional cleanup for LSP clients
- app.clientsMutex.RLock()
- clients := make(map[string]*lsp.Client, len(app.LSPClients))
- maps.Copy(clients, app.LSPClients)
- app.clientsMutex.RUnlock()
-
- for name, client := range clients {
- shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- if err := client.Shutdown(shutdownCtx); err != nil {
- slog.Error("Failed to shutdown LSP client", "name", name, "error", err)
- }
- cancel()
- }
-}
diff --git a/internal/app/app_new.go b/internal/app/app_new.go
deleted file mode 100644
index 1568b4d57..000000000
--- a/internal/app/app_new.go
+++ /dev/null
@@ -1,203 +0,0 @@
-package app
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "sync"
-
- "log/slog"
-
- "github.com/sst/opencode/pkg/client"
-)
-
-// AppNew is the new app structure that uses the TypeScript backend
-type AppNew struct {
- Client *client.Client
- CurrentSession *client.SessionInfo
-
- // Event handling
- eventCtx context.Context
- eventCancel context.CancelFunc
- eventChan <-chan any
-
- // UI state
- filepickerOpen bool
- completionDialogOpen bool
-
- // Mutex for thread-safe operations
- mu sync.RWMutex
-}
-
-// NewApp creates a new app instance connected to the TypeScript backend
-func NewApp(ctx context.Context) (*AppNew, error) {
- httpClient, err := client.NewClient("http://localhost:16713")
- if err != nil {
- slog.Error("Failed to create client", "error", err)
- return nil, err
- }
-
- app := &AppNew{
- Client: httpClient,
- }
-
- // Start event listener
- if err := app.startEventListener(ctx); err != nil {
- return nil, err
- }
-
- return app, nil
-}
-
-// startEventListener connects to the SSE endpoint and processes events
-func (a *AppNew) startEventListener(ctx context.Context) error {
- a.eventCtx, a.eventCancel = context.WithCancel(ctx)
-
- eventChan, err := a.Client.Event(a.eventCtx)
- if err != nil {
- return err
- }
-
- a.eventChan = eventChan
-
- // Start processing events in background
- go a.processEvents()
-
- return nil
-}
-
-// processEvents handles incoming SSE events
-func (a *AppNew) processEvents() {
- for event := range a.eventChan {
- switch e := event.(type) {
- case *client.EventStorageWrite:
- // Handle storage write events
- slog.Debug("Storage write event", "key", e.Key)
- // TODO: Update local state based on storage events
- default:
- slog.Debug("Unknown event type", "event", e)
- }
- }
-}
-
-// CreateSession creates a new session via the API
-func (a *AppNew) CreateSession(ctx context.Context) error {
- resp, err := a.Client.PostSessionCreate(ctx)
- if err != nil {
- return err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != 200 {
- return fmt.Errorf("failed to create session: %d", resp.StatusCode)
- }
-
- var session client.SessionInfo
- if err := json.NewDecoder(resp.Body).Decode(&session); err != nil {
- return err
- }
-
- a.mu.Lock()
- a.CurrentSession = &session
- a.mu.Unlock()
-
- return nil
-}
-
-// SendMessage sends a message to the current session
-func (a *AppNew) SendMessage(ctx context.Context, text string) error {
- if a.CurrentSession == nil {
- if err := a.CreateSession(ctx); err != nil {
- return err
- }
- }
-
- a.mu.RLock()
- sessionID := a.CurrentSession.Id
- a.mu.RUnlock()
-
- parts := interface{}([]map[string]interface{}{
- {
- "type": "text",
- "text": text,
- },
- })
-
- resp, err := a.Client.PostSessionChat(ctx, client.PostSessionChatJSONRequestBody{
- SessionID: sessionID,
- Parts: &parts,
- })
- if err != nil {
- return err
- }
- defer resp.Body.Close()
-
- // The response will be streamed via SSE
- return nil
-}
-
-// GetSessions retrieves all sessions
-func (a *AppNew) GetSessions(ctx context.Context) ([]client.SessionInfo, error) {
- resp, err := a.Client.PostSessionList(ctx)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- var sessions []client.SessionInfo
- if err := json.NewDecoder(resp.Body).Decode(&sessions); err != nil {
- return nil, err
- }
-
- return sessions, nil
-}
-
-// GetMessages retrieves messages for a session
-func (a *AppNew) GetMessages(ctx context.Context, sessionID string) (interface{}, error) {
- resp, err := a.Client.PostSessionMessages(ctx, client.PostSessionMessagesJSONRequestBody{
- SessionID: sessionID,
- })
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- var messages interface{}
- if err := json.NewDecoder(resp.Body).Decode(&messages); err != nil {
- return nil, err
- }
-
- return messages, nil
-}
-
-// Close shuts down the app and its connections
-func (a *AppNew) Close() {
- if a.eventCancel != nil {
- a.eventCancel()
- }
-}
-
-// UI state methods
-func (a *AppNew) SetFilepickerOpen(open bool) {
- a.mu.Lock()
- defer a.mu.Unlock()
- a.filepickerOpen = open
-}
-
-func (a *AppNew) IsFilepickerOpen() bool {
- a.mu.RLock()
- defer a.mu.RUnlock()
- return a.filepickerOpen
-}
-
-func (a *AppNew) SetCompletionDialogOpen(open bool) {
- a.mu.Lock()
- defer a.mu.Unlock()
- a.completionDialogOpen = open
-}
-
-func (a *AppNew) IsCompletionDialogOpen() bool {
- a.mu.RLock()
- defer a.mu.RUnlock()
- return a.completionDialogOpen
-} \ No newline at end of file
diff --git a/internal/app/interfaces.go b/internal/app/interfaces.go
deleted file mode 100644
index 2f4287078..000000000
--- a/internal/app/interfaces.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package app
-
-import (
- "context"
- "time"
-
- "github.com/sst/opencode/internal/message"
- "github.com/sst/opencode/internal/pubsub"
- "github.com/sst/opencode/internal/session"
-)
-
-// SessionService defines the interface for session operations
-type SessionService interface {
- Create(ctx context.Context, title string) (session.Session, error)
- Get(ctx context.Context, id string) (session.Session, error)
- List(ctx context.Context) ([]session.Session, error)
- Update(ctx context.Context, id, title string) error
- Delete(ctx context.Context, id string) error
-}
-
-// MessageService defines the interface for message operations
-type MessageService interface {
- pubsub.Subscriber[message.Message]
-
- GetBySession(ctx context.Context, sessionID string) ([]message.Message, error)
- List(ctx context.Context, sessionID string) ([]message.Message, error)
- Create(ctx context.Context, sessionID string, params message.CreateMessageParams) (message.Message, error)
- Update(ctx context.Context, msg message.Message) (message.Message, error)
- Delete(ctx context.Context, id string) error
- DeleteSessionMessages(ctx context.Context, sessionID string) error
- Get(ctx context.Context, id string) (message.Message, error)
- ListAfter(ctx context.Context, sessionID string, timestamp time.Time) ([]message.Message, error)
-}
-
-// AgentService defines the interface for agent operations
-type AgentService interface {
- Run(ctx context.Context, sessionID string, text string, attachments ...message.Attachment) (string, error)
- Cancel(sessionID string) error
- IsBusy() bool
- IsSessionBusy(sessionID string) bool
- CompactSession(ctx context.Context, sessionID string, force bool) error
-} \ No newline at end of file
diff --git a/internal/app/lsp.go b/internal/app/lsp.go
deleted file mode 100644
index 214f104b8..000000000
--- a/internal/app/lsp.go
+++ /dev/null
@@ -1,134 +0,0 @@
-package app
-
-import (
- "context"
- "time"
-
- "log/slog"
-
- "github.com/sst/opencode/internal/config"
- "github.com/sst/opencode/internal/logging"
- "github.com/sst/opencode/internal/lsp"
- "github.com/sst/opencode/internal/lsp/watcher"
-)
-
-func (app *App) initLSPClients(ctx context.Context) {
- cfg := config.Get()
-
- // Initialize LSP clients
- for name, clientConfig := range cfg.LSP {
- // Start each client initialization in its own goroutine
- go app.createAndStartLSPClient(ctx, name, clientConfig.Command, clientConfig.Args...)
- }
- slog.Info("LSP clients initialization started in background")
-}
-
-// createAndStartLSPClient creates a new LSP client, initializes it, and starts its workspace watcher
-func (app *App) createAndStartLSPClient(ctx context.Context, name string, command string, args ...string) {
- // Create a specific context for initialization with a timeout
- slog.Info("Creating LSP client", "name", name, "command", command, "args", args)
-
- // Create the LSP client
- lspClient, err := lsp.NewClient(ctx, command, args...)
- if err != nil {
- slog.Error("Failed to create LSP client for", name, err)
- return
- }
-
- // Create a longer timeout for initialization (some servers take time to start)
- initCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
- defer cancel()
-
- // Initialize with the initialization context
- _, err = lspClient.InitializeLSPClient(initCtx, config.WorkingDirectory())
- if err != nil {
- slog.Error("Initialize failed", "name", name, "error", err)
- // Clean up the client to prevent resource leaks
- lspClient.Close()
- return
- }
-
- // Wait for the server to be ready
- if err := lspClient.WaitForServerReady(initCtx); err != nil {
- slog.Error("Server failed to become ready", "name", name, "error", err)
- // We'll continue anyway, as some functionality might still work
- lspClient.SetServerState(lsp.StateError)
- } else {
- slog.Info("LSP server is ready", "name", name)
- lspClient.SetServerState(lsp.StateReady)
- }
-
- slog.Info("LSP client initialized", "name", name)
-
- // Create a child context that can be canceled when the app is shutting down
- watchCtx, cancelFunc := context.WithCancel(ctx)
-
- // Create a context with the server name for better identification
- watchCtx = context.WithValue(watchCtx, "serverName", name)
-
- // Create the workspace watcher
- workspaceWatcher := watcher.NewWorkspaceWatcher(lspClient)
-
- // Store the cancel function to be called during cleanup
- app.cancelFuncsMutex.Lock()
- app.watcherCancelFuncs = append(app.watcherCancelFuncs, cancelFunc)
- app.cancelFuncsMutex.Unlock()
-
- // Add the watcher to a WaitGroup to track active goroutines
- app.watcherWG.Add(1)
-
- // Add to map with mutex protection before starting goroutine
- app.clientsMutex.Lock()
- app.LSPClients[name] = lspClient
- app.clientsMutex.Unlock()
-
- go app.runWorkspaceWatcher(watchCtx, name, workspaceWatcher)
-}
-
-// runWorkspaceWatcher executes the workspace watcher for an LSP client
-func (app *App) runWorkspaceWatcher(ctx context.Context, name string, workspaceWatcher *watcher.WorkspaceWatcher) {
- defer app.watcherWG.Done()
- defer logging.RecoverPanic("LSP-"+name, func() {
- // Try to restart the client
- app.restartLSPClient(ctx, name)
- })
-
- workspaceWatcher.WatchWorkspace(ctx, config.WorkingDirectory())
- slog.Info("Workspace watcher stopped", "client", name)
-}
-
-// restartLSPClient attempts to restart a crashed or failed LSP client
-func (app *App) restartLSPClient(ctx context.Context, name string) {
- // Get the original configuration
- cfg := config.Get()
- clientConfig, exists := cfg.LSP[name]
- if !exists {
- slog.Error("Cannot restart client, configuration not found", "client", name)
- return
- }
-
- // Clean up the old client if it exists
- app.clientsMutex.Lock()
- oldClient, exists := app.LSPClients[name]
- if exists {
- delete(app.LSPClients, name) // Remove from map before potentially slow shutdown
- }
- app.clientsMutex.Unlock()
-
- if exists && oldClient != nil {
- // Try to shut it down gracefully, but don't block on errors
- shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- _ = oldClient.Shutdown(shutdownCtx)
- cancel()
-
- // Ensure we close the client to free resources
- _ = oldClient.Close()
- }
-
- // Wait a moment before restarting to avoid rapid restart cycles
- time.Sleep(1 * time.Second)
-
- // Create a new client using the shared function
- app.createAndStartLSPClient(ctx, name, clientConfig.Command, clientConfig.Args...)
- slog.Info("Successfully restarted LSP client", "client", name)
-}
diff --git a/internal/app/services_bridge.go b/internal/app/services_bridge.go
deleted file mode 100644
index d3f2e9a23..000000000
--- a/internal/app/services_bridge.go
+++ /dev/null
@@ -1,245 +0,0 @@
-package app
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "time"
-
- "github.com/sst/opencode/internal/message"
- "github.com/sst/opencode/internal/pubsub"
- "github.com/sst/opencode/internal/session"
- "github.com/sst/opencode/pkg/client"
-)
-
-// SessionServiceBridge adapts the HTTP API to the old session.Service interface
-type SessionServiceBridge struct {
- client *client.ClientWithResponses
-}
-
-// NewSessionServiceBridge creates a new session service bridge
-func NewSessionServiceBridge(client *client.ClientWithResponses) *SessionServiceBridge {
- return &SessionServiceBridge{client: client}
-}
-
-// Create creates a new session
-func (s *SessionServiceBridge) Create(ctx context.Context, title string) (session.Session, error) {
- resp, err := s.client.PostSessionCreateWithResponse(ctx)
- if err != nil {
- return session.Session{}, err
- }
- if resp.StatusCode() != 200 {
- return session.Session{}, fmt.Errorf("failed to create session: %d", resp.StatusCode)
- }
- info := resp.JSON200
-
- // Convert to old session type
- return session.Session{
- ID: info.Id,
- Title: info.Title,
- CreatedAt: time.Now(), // API doesn't provide this yet
- UpdatedAt: time.Now(), // API doesn't provide this yet
- }, nil
-}
-
-// Get retrieves a session by ID
-func (s *SessionServiceBridge) Get(ctx context.Context, id string) (session.Session, error) {
- // TODO: API doesn't have a get by ID endpoint yet
- // For now, list all and find the one we want
- sessions, err := s.List(ctx)
- if err != nil {
- return session.Session{}, err
- }
-
- for _, sess := range sessions {
- if sess.ID == id {
- return sess, nil
- }
- }
-
- return session.Session{}, fmt.Errorf("session not found: %s", id)
-}
-
-// List retrieves all sessions
-func (s *SessionServiceBridge) List(ctx context.Context) ([]session.Session, error) {
- resp, err := s.client.PostSessionListWithResponse(ctx)
- if err != nil {
- return nil, err
- }
-
- if resp.StatusCode() != 200 {
- return nil, fmt.Errorf("failed to list sessions: %d", resp.StatusCode())
- }
-
- if resp.JSON200 == nil {
- return []session.Session{}, nil
- }
-
- infos := *resp.JSON200
-
- // Convert to old session type
- sessions := make([]session.Session, len(infos))
- for i, info := range infos {
- sessions[i] = session.Session{
- ID: info.Id,
- Title: info.Title,
- CreatedAt: time.Now(), // API doesn't provide this yet
- UpdatedAt: time.Now(), // API doesn't provide this yet
- }
- }
-
- return sessions, nil
-}
-
-// Update updates a session - NOT IMPLEMENTED IN API YET
-func (s *SessionServiceBridge) Update(ctx context.Context, id, title string) error {
- // TODO: Not implemented in TypeScript API yet
- return fmt.Errorf("session update not implemented in API")
-}
-
-// Delete deletes a session - NOT IMPLEMENTED IN API YET
-func (s *SessionServiceBridge) Delete(ctx context.Context, id string) error {
- // TODO: Not implemented in TypeScript API yet
- return fmt.Errorf("session delete not implemented in API")
-}
-
-// AgentServiceBridge provides a minimal agent service that sends messages to the API
-type AgentServiceBridge struct {
- client *client.ClientWithResponses
-}
-
-// NewAgentServiceBridge creates a new agent service bridge
-func NewAgentServiceBridge(client *client.ClientWithResponses) *AgentServiceBridge {
- return &AgentServiceBridge{client: client}
-}
-
-// Run sends a message to the chat API
-func (a *AgentServiceBridge) Run(ctx context.Context, sessionID string, text string, attachments ...message.Attachment) (string, error) {
- // TODO: Handle attachments when API supports them
- if len(attachments) > 0 {
- // For now, ignore attachments
- // return "", fmt.Errorf("attachments not supported yet")
- }
-
- parts := any([]map[string]any{
- {
- "type": "text",
- "text": text,
- },
- })
-
- go a.client.PostSessionChatWithResponse(ctx, client.PostSessionChatJSONRequestBody{
- SessionID: sessionID,
- Parts: &parts,
- })
-
- // The actual response will come through SSE
- // For now, just return success
- return "", nil
-}
-
-// Cancel cancels the current generation - NOT IMPLEMENTED IN API YET
-func (a *AgentServiceBridge) Cancel(sessionID string) error {
- // TODO: Not implemented in TypeScript API yet
- return nil
-}
-
-// IsBusy checks if the agent is busy - NOT IMPLEMENTED IN API YET
-func (a *AgentServiceBridge) IsBusy() bool {
- // TODO: Not implemented in TypeScript API yet
- return false
-}
-
-// IsSessionBusy checks if the agent is busy for a specific session - NOT IMPLEMENTED IN API YET
-func (a *AgentServiceBridge) IsSessionBusy(sessionID string) bool {
- // TODO: Not implemented in TypeScript API yet
- return false
-}
-
-// CompactSession compacts a session - NOT IMPLEMENTED IN API YET
-func (a *AgentServiceBridge) CompactSession(ctx context.Context, sessionID string, force bool) error {
- // TODO: Not implemented in TypeScript API yet
- return fmt.Errorf("session compaction not implemented in API")
-}
-
-// MessageServiceBridge provides a minimal message service that fetches from the API
-type MessageServiceBridge struct {
- client *client.ClientWithResponses
- broker *pubsub.Broker[message.Message]
-}
-
-// NewMessageServiceBridge creates a new message service bridge
-func NewMessageServiceBridge(client *client.ClientWithResponses) *MessageServiceBridge {
- return &MessageServiceBridge{
- client: client,
- broker: pubsub.NewBroker[message.Message](),
- }
-}
-
-// GetBySession retrieves messages for a session
-func (m *MessageServiceBridge) GetBySession(ctx context.Context, sessionID string) ([]message.Message, error) {
- return m.List(ctx, sessionID)
-}
-
-// List retrieves messages for a session
-func (m *MessageServiceBridge) List(ctx context.Context, sessionID string) ([]message.Message, error) {
- resp, err := m.client.PostSessionMessages(ctx, client.PostSessionMessagesJSONRequestBody{
- SessionID: sessionID,
- })
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- // The API returns a different format, we'll need to adapt it
- var rawMessages any
- if err := json.NewDecoder(resp.Body).Decode(&rawMessages); err != nil {
- return nil, err
- }
-
- // TODO: Convert the API message format to our internal format
- // For now, return empty to avoid compilation errors
- return []message.Message{}, nil
-}
-
-// Create creates a new message - NOT NEEDED, handled by chat API
-func (m *MessageServiceBridge) Create(ctx context.Context, sessionID string, params message.CreateMessageParams) (message.Message, error) {
- // Messages are created through the chat API
- return message.Message{}, fmt.Errorf("use chat API to send messages")
-}
-
-// Update updates a message - NOT IMPLEMENTED IN API YET
-func (m *MessageServiceBridge) Update(ctx context.Context, msg message.Message) (message.Message, error) {
- // TODO: Not implemented in TypeScript API yet
- return message.Message{}, fmt.Errorf("message update not implemented in API")
-}
-
-// Delete deletes a message - NOT IMPLEMENTED IN API YET
-func (m *MessageServiceBridge) Delete(ctx context.Context, id string) error {
- // TODO: Not implemented in TypeScript API yet
- return fmt.Errorf("message delete not implemented in API")
-}
-
-// DeleteSessionMessages deletes all messages for a session - NOT IMPLEMENTED IN API YET
-func (m *MessageServiceBridge) DeleteSessionMessages(ctx context.Context, sessionID string) error {
- // TODO: Not implemented in TypeScript API yet
- return fmt.Errorf("delete session messages not implemented in API")
-}
-
-// Get retrieves a message by ID - NOT IMPLEMENTED IN API YET
-func (m *MessageServiceBridge) Get(ctx context.Context, id string) (message.Message, error) {
- // TODO: Not implemented in TypeScript API yet
- return message.Message{}, fmt.Errorf("get message by ID not implemented in API")
-}
-
-// ListAfter retrieves messages after a timestamp - NOT IMPLEMENTED IN API YET
-func (m *MessageServiceBridge) ListAfter(ctx context.Context, sessionID string, timestamp time.Time) ([]message.Message, error) {
- // TODO: Not implemented in TypeScript API yet
- return []message.Message{}, fmt.Errorf("list messages after timestamp not implemented in API")
-}
-
-// Subscribe subscribes to message events
-func (m *MessageServiceBridge) Subscribe(ctx context.Context) <-chan pubsub.Event[message.Message] {
- return m.broker.Subscribe(ctx)
-}
-