Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions internal/api/modules/amp/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ func (m *AmpModule) registerManagementRoutes(engine *gin.Engine, baseHandler *ha
ampAPI.Any("/threads/*path", proxyHandler)
ampAPI.Any("/otel", proxyHandler)
ampAPI.Any("/otel/*path", proxyHandler)
ampAPI.Any("/tab", proxyHandler)
ampAPI.Any("/tab/*path", proxyHandler)
Comment on lines +113 to +114

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

With the addition of these routes, the list of proxy routes is getting long and repetitive. This pattern of registering a base path and a /*path variant is used for many routes in this block (lines 98-114). To improve maintainability and reduce code duplication, consider refactoring this block to register these routes in a loop. For example:

proxyPaths := []string{
    "/internal",
    "/user",
    "/auth",
    "/meta",
    "/telemetry",
    "/threads",
    "/otel",
    "/tab",
}
for _, path := range proxyPaths {
    ampAPI.Any(path, proxyHandler)
    ampAPI.Any(path+"/*path", proxyHandler)
}
ampAPI.Any("/ads", proxyHandler) // /ads doesn't have a /*path variant


// Root-level routes that AMP CLI expects without /api prefix
// These need the same security middleware as the /api/* routes
Expand All @@ -119,6 +121,12 @@ func (m *AmpModule) registerManagementRoutes(engine *gin.Engine, baseHandler *ha
}
engine.GET("/threads.rss", append(rootMiddleware, proxyHandler)...)

// Root-level auth routes for CLI login flow
// Amp uses multiple auth routes: /auth/cli-login, /auth/callback, /auth/sign-in, /auth/logout
// We proxy all /auth/* to support the complete OAuth flow
engine.Any("/auth", append(rootMiddleware, proxyHandler)...)
engine.Any("/auth/*path", append(rootMiddleware, proxyHandler)...)

// Google v1beta1 passthrough with OAuth fallback
// AMP CLI uses non-standard paths like /publishers/google/models/...
// We bridge these to our standard Gemini handler to enable local OAuth.
Expand Down
5 changes: 5 additions & 0 deletions internal/api/modules/amp/routes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ func TestRegisterManagementRoutes(t *testing.T) {
{"/api/threads", http.MethodGet},
{"/threads.rss", http.MethodGet}, // Root-level route (no /api prefix)
{"/api/otel", http.MethodGet},
{"/api/tab", http.MethodGet},
{"/api/tab/some/path", http.MethodGet},
{"/auth", http.MethodGet}, // Root-level auth route
{"/auth/cli-login", http.MethodGet}, // CLI login flow
{"/auth/callback", http.MethodGet}, // OAuth callback
// Google v1beta1 bridge should still proxy non-model requests (GET) and allow POST
{"/api/provider/google/v1beta1/models", http.MethodGet},
{"/api/provider/google/v1beta1/models", http.MethodPost},
Expand Down
8 changes: 7 additions & 1 deletion internal/logging/global_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@ func (m *LogFormatter) Format(entry *log.Entry) ([]byte, error) {

timestamp := entry.Time.Format("2006-01-02 15:04:05")
message := strings.TrimRight(entry.Message, "\r\n")
formatted := fmt.Sprintf("[%s] [%s] [%s:%d] %s\n", timestamp, entry.Level, filepath.Base(entry.Caller.File), entry.Caller.Line, message)

var formatted string
if entry.Caller != nil {
formatted = fmt.Sprintf("[%s] [%s] [%s:%d] %s\n", timestamp, entry.Level, filepath.Base(entry.Caller.File), entry.Caller.Line, message)
} else {
formatted = fmt.Sprintf("[%s] [%s] %s\n", timestamp, entry.Level, message)
}
buffer.WriteString(formatted)

return buffer.Bytes(), nil
Expand Down