Skip to content

Commit 6361d74

Browse files
committed
fix: refactor web
1 parent 7f93d95 commit 6361d74

File tree

11 files changed

+301
-209
lines changed

11 files changed

+301
-209
lines changed

internal/app/app.go

Lines changed: 31 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import (
1111
"github.com/co-browser/agent-browser/internal/events"
1212
"github.com/co-browser/agent-browser/internal/log"
1313
"github.com/co-browser/agent-browser/internal/mcp"
14-
"github.com/co-browser/agent-browser/internal/mcp/config"
14+
mcpConfig "github.com/co-browser/agent-browser/internal/mcp/config"
1515
"github.com/co-browser/agent-browser/internal/web"
1616
"github.com/co-browser/agent-browser/internal/web/client"
17+
webConfig "github.com/co-browser/agent-browser/internal/web/config"
1718
"github.com/co-browser/agent-browser/internal/web/handlers"
1819

1920
"go.uber.org/fx"
@@ -61,7 +62,7 @@ var DatabaseModule = fx.Module("database",
6162
// Currently loads MCP configuration.
6263
var ConfigModule = fx.Module("config",
6364
fx.Provide(
64-
config.NewConfig,
65+
mcpConfig.NewConfig,
6566
),
6667
)
6768

@@ -94,44 +95,42 @@ var BackendModule = fx.Module("backend",
9495
*/
9596
)
9697

97-
// MCPClientModule provides the components responsible for connecting *to* remote MCP servers.
98-
// This includes the ConnectionManager and the API client used by the ConnectionManager
99-
// to update this agent's status and sync tools via its own web API.
98+
// MCPClientModule provides the components responsible for connecting to remote MCP servers.
10099
var MCPClientModule = fx.Module("mcp_client",
101100
fx.Provide(
102-
// Provide the web API client used by MCP components
101+
// Provide the web API client
103102
func(logger log.Logger) *client.Client {
104-
// TODO: Make API client base URL configurable
105-
config := client.DefaultConfig()
106-
// DefaultConfig likely points to localhost, which is correct for the agent
107-
// calling its own API.
103+
config := webConfig.ClientConfig{
104+
BaseURL: "http://localhost:8080",
105+
TimeoutSec: 10,
106+
MaxRetries: 3,
107+
RetryDelaySec: 1,
108+
}
108109
return client.NewClient(config, logger)
109110
},
110-
// Provide MCP components (like ConnectionManager)
111+
// Provide MCP components
111112
mcp.NewMCPComponents,
112113
),
113-
// Register lifecycle hooks for starting/stopping the MCP ConnectionManager
114+
// Register lifecycle hooks
114115
fx.Invoke(mcp.RegisterMCPServerHooks),
115-
// Register event subscribers for the ConnectionManager
116+
// Register event subscribers
116117
fx.Invoke(mcp.RegisterEventSubscribers),
117118
)
118119

119120
// WebModule provides the HTTP server, API handlers, UI handlers, and SSE handler.
120121
var WebModule = fx.Module("web",
121122
fx.Provide(
122-
// Provide UI handler struct (depends on Logger, BackendService)
123+
// Provide UI handler struct
123124
handlers.NewUIHandler,
124-
// Provide API handlers (depends on BackendService, Logger)
125+
126+
// Provide API handlers
125127
func(bs backend.Service, logger log.Logger) *handlers.APIHandlers {
126128
return handlers.NewAPIHandlers(bs, logger)
127129
},
128-
// Provide SSE handler (depends on Logger, EventBus, BackendService)
129-
// Note: Fx automatically provides context.Background() if context.Context is needed.
130+
131+
// Provide SSE handler
130132
func(lc fx.Lifecycle, logger log.Logger, bus events.Bus, bs backend.Service) *handlers.SSEHandler {
131-
// Create handler with background context
132-
// The handler manages its own internal context cancellation via Stop().
133133
sseHandler := handlers.NewSSEHandler(context.Background(), logger, bus, bs)
134-
// Register Stop hook
135134
lc.Append(fx.Hook{
136135
OnStop: func(_ context.Context) error {
137136
logger.Info().Msg("Stopping SSE handler...")
@@ -141,42 +140,33 @@ var WebModule = fx.Module("web",
141140
})
142141
return sseHandler
143142
},
144-
// Provide the HTTP request router (ServeMux)
145-
// Pass apiHandler and uiHandler explicitly if NewMux requires them.
146-
// Assuming NewMux takes no arguments for now as per web/server.go structure.
147-
// We register handlers via fx.Invoke later.
143+
144+
// Provide the HTTP router
148145
func() *http.ServeMux {
149146
return http.NewServeMux()
150147
},
151-
// Provide the HTTP server itself (depends on ServeMux)
148+
149+
// Provide the HTTP server
152150
web.NewServer,
153151
),
152+
154153
// Register handlers with the router
155154
fx.Invoke(func(mux *http.ServeMux, apiHandlers *handlers.APIHandlers, uiHandler *handlers.UIHandler, sseHandler *handlers.SSEHandler) {
156-
// API Routes (includes Swagger/OpenAPI docs)
155+
// API Routes
157156
apiHandlers.RegisterRoutes(mux)
158157

159-
// --- UI Routes (Registered directly) ---
160-
mux.HandleFunc("/ui/", uiHandler.ServeIndex) // Note trailing slash
161-
// mux.HandleFunc("/ui/add", uiHandler.ServeAddPage) // Removed
162-
// mux.HandleFunc("/ui/success", uiHandler.ServeSuccessPage) // Removed
163-
// mux.HandleFunc("/ui/error", uiHandler.ServeErrorPage) // Removed
158+
// UI Routes
159+
mux.HandleFunc("/ui/", uiHandler.ServeIndex)
164160

165-
// --- Root Redirect ---
166-
// Use mux.Handle for http.RedirectHandler as it returns an http.Handler
161+
// Root Redirect
167162
mux.Handle("/", http.RedirectHandler("/ui/", http.StatusMovedPermanently))
168163

169-
// --- SSE Route ---
164+
// SSE Route
170165
mux.HandleFunc("/api/events", sseHandler.ServeHTTP)
171-
172-
// Metrics Route (example, if needed)
173-
// mux.Handle("/metrics", promhttp.Handler())
174166
}),
175-
// Register web server lifecycle hooks for starting/stopping the server
167+
168+
// Register web server lifecycle hooks
176169
fx.Invoke(web.RegisterWebServerHooks),
177-
// Invoke the SSE handler's event listener setup explicitly if needed,
178-
// but NewSSEHandler already starts the listener goroutine.
179-
// fx.Invoke(func(sse *handlers.SSEHandler) { /* SSE Listener already started in New */ }),
180170
)
181171

182172
// CursorModule manages interaction with the ~/.cursor/mcp.json file.

internal/web/client/client.go

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// Package client provides HTTP client functionality for API interactions.
12
package client
23

34
import (
@@ -10,39 +11,22 @@ import (
1011

1112
"github.com/co-browser/agent-browser/internal/backend/models"
1213
"github.com/co-browser/agent-browser/internal/log"
14+
"github.com/co-browser/agent-browser/internal/web/config"
1315
)
1416

15-
// Config holds configuration for the API client
16-
type Config struct {
17-
BaseURL string
18-
Timeout time.Duration
19-
MaxRetries int
20-
RetryDelay time.Duration
21-
}
22-
23-
// DefaultConfig returns a default configuration
24-
func DefaultConfig() Config {
25-
return Config{
26-
BaseURL: "http://localhost:8080",
27-
Timeout: 10 * time.Second,
28-
MaxRetries: 3,
29-
RetryDelay: time.Second,
30-
}
31-
}
32-
3317
// Client provides methods to interact with the agent-browser API
3418
type Client struct {
35-
config Config
19+
config config.ClientConfig
3620
http *http.Client
3721
logger log.Logger
3822
}
3923

4024
// NewClient creates a new API client instance
41-
func NewClient(config Config, logger log.Logger) *Client {
25+
func NewClient(config config.ClientConfig, logger log.Logger) *Client {
4226
return &Client{
4327
config: config,
4428
http: &http.Client{
45-
Timeout: config.Timeout,
29+
Timeout: time.Duration(config.TimeoutSec) * time.Second,
4630
},
4731
logger: logger,
4832
}
@@ -126,15 +110,15 @@ func (c *Client) do(req *http.Request, response interface{}) error {
126110
if err != nil {
127111
lastErr = err
128112
c.logger.Warn().Err(err).Int("attempt", attempt).Msg("Request failed, retrying...")
129-
time.Sleep(c.config.RetryDelay)
113+
time.Sleep(time.Duration(c.config.RetryDelaySec) * time.Second)
130114
continue
131115
}
132116
defer resp.Body.Close()
133117

134118
if resp.StatusCode >= 400 {
135119
lastErr = fmt.Errorf("request failed with status %d", resp.StatusCode)
136120
c.logger.Warn().Int("statusCode", resp.StatusCode).Int("attempt", attempt).Msg("Request failed, retrying...")
137-
time.Sleep(c.config.RetryDelay)
121+
time.Sleep(time.Duration(c.config.RetryDelaySec) * time.Second)
138122
continue
139123
}
140124

internal/web/config/config.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Package config provides configuration structures for the web server.
2+
package config
3+
4+
import (
5+
"github.com/co-browser/agent-browser/internal/log"
6+
"go.uber.org/fx"
7+
)
8+
9+
// ServerConfig holds the configuration for the HTTP server
10+
type ServerConfig struct {
11+
Address string `json:"address" default:":8080"`
12+
}
13+
14+
// ClientConfig holds the configuration for the API client
15+
type ClientConfig struct {
16+
BaseURL string `json:"base_url" default:"http://localhost:8080"`
17+
TimeoutSec int `json:"timeout_sec" default:"10"`
18+
MaxRetries int `json:"max_retries" default:"3"`
19+
RetryDelaySec int `json:"retry_delay_sec" default:"1"`
20+
}
21+
22+
// ConfigParams contains the parameters needed for configuration
23+
type ConfigParams struct {
24+
fx.In
25+
26+
Logger log.Logger
27+
}
28+
29+
// ConfigResult contains the configuration output
30+
type ConfigResult struct {
31+
fx.Out
32+
33+
ServerConfig ServerConfig
34+
ClientConfig ClientConfig
35+
}
36+
37+
// NewConfig creates a new web configuration
38+
func NewConfig(p ConfigParams) (ConfigResult, error) {
39+
serverConfig := ServerConfig{
40+
Address: ":8080",
41+
}
42+
43+
clientConfig := ClientConfig{
44+
BaseURL: "http://localhost:8080",
45+
TimeoutSec: 10,
46+
MaxRetries: 3,
47+
RetryDelaySec: 1,
48+
}
49+
50+
p.Logger.Info().
51+
Str("address", serverConfig.Address).
52+
Str("base_url", clientConfig.BaseURL).
53+
Msg("Web configuration loaded")
54+
55+
return ConfigResult{
56+
ServerConfig: serverConfig,
57+
ClientConfig: clientConfig,
58+
}, nil
59+
}

0 commit comments

Comments
 (0)