fix(amp): enable OAuth fallback for Gemini v1beta1 routes

AMP CLI sends Gemini requests to non-standard paths that were being
directly proxied to ampcode.com without checking for local OAuth.

This fix adds:
- GeminiBridge handler to transform AMP CLI paths to standard format
- Enhanced model extraction from AMP's /publishers/google/models/* paths
- FallbackHandler wrapper to check for local OAuth before proxying

Flow:
- If user has local Google OAuth → use it (free tier)
- If no local OAuth → fallback to ampcode.com (charges credits)

Fixes issue where gemini-3-pro-preview requests always charged AMP
credits even when user had valid Google Cloud OAuth configured.
This commit is contained in:
Ben Vargas
2025-11-19 15:44:55 -07:00
parent 1fb96f5379
commit 7ae00320dc
4 changed files with 72 additions and 6 deletions

View File

@@ -102,8 +102,8 @@ func extractModelFromRequest(body []byte, c *gin.Context) string {
}
}
// For Gemini requests, model is in the URL path: /models/{model}:generateContent
// Extract from :action parameter (e.g., "gemini-pro:generateContent")
// For Gemini requests, model is in the URL path
// Standard format: /models/{model}:generateContent -> :action parameter
if action := c.Param("action"); action != "" {
// Split by colon to get model name (e.g., "gemini-pro:generateContent" -> "gemini-pro")
parts := strings.Split(action, ":")
@@ -112,5 +112,18 @@ func extractModelFromRequest(body []byte, c *gin.Context) string {
}
}
// AMP CLI format: /publishers/google/models/{model}:method -> *path parameter
// Example: /publishers/google/models/gemini-3-pro-preview:streamGenerateContent
if path := c.Param("path"); path != "" {
// Look for /models/{model}:method pattern
if idx := strings.Index(path, "/models/"); idx >= 0 {
modelPart := path[idx+8:] // Skip "/models/"
// Split by colon to get model name
if colonIdx := strings.Index(modelPart, ":"); colonIdx > 0 {
return modelPart[:colonIdx]
}
}
}
return ""
}