Conversation
|
Warning Review limit reached
Next review available in: 39 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughAdds the ChangesGemini 3.1 Flash Lite Image
Vertex Express Mode Endpoint
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
9bc4ccb to
29c59c1
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
apps/gateway/src/videos/videos.spec.ts (1)
1615-1670: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd one Mini reference-video billing case.
This test only locks the output-rate path. The new docs also promise a
reference_videossurcharge forseedance-2-0-mini, so a regression invideoInputCostwould still pass here. Please add one request withreference_videosand assert the billed input cost too.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/gateway/src/videos/videos.spec.ts` around lines 1615 - 1670, The Seedance 2.0 Mini billing test only covers output pricing, so it can miss regressions in the new reference-video surcharge path. Update the existing bytedance/seedance-2-0-mini case in videos.spec.ts to add a request that includes reference_videos, then verify the resulting videoJob/log billing includes the expected videoInputCost as well as the existing videoOutputCost. Use the same app.request, processPendingVideoJobs, and db query patterns already in the test to locate the affected billing assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/docs/content/features/video-generation.mdx`:
- Line 16: The shared Seedance capability summary still groups Seedance 2.0 Mini
with the 720p/1080p, 5s/10s models, which no longer matches the constraints in
bytedance model definitions. Update the documentation entry in
video-generation.mdx to give Seedance 2.0 Mini its own bullet/row and list its
actual supported settings (480p and 4–15s), while keeping the other Seedance
variants in the shared summary. Use the existing Seedance 2.0 / Seedance 2.0
Fast / Seedance 1.5 Pro wording as the anchor for the split.
In `@apps/playground/src/components/playground/chat-ui.tsx`:
- Around line 1055-1061: The availableSizes change in chat-ui only updates the
dropdown options and leaves an already-selected unsupported imageSize intact
when switching to gemini-3.1-flash-lite-image. Update the model-switching logic
around the image size state in playground/chat-ui.tsx so that when
isGemini31FlashLiteImage becomes true, the current imageSize is clamped or reset
to "1K" if it is not allowed. Use the existing availableSizes logic and the
imageSize state handler in the chat UI to ensure submitted sizes always match
the active model.
In `@packages/actions/src/get-provider-endpoint.spec.ts`:
- Around line 216-221: The test fixture in get-provider-endpoint.spec.ts is
using an AQ token that resembles a real credential; replace the hardcoded token
in the endpoint assertion setup with an obviously fake value like AQ.test-token.
Keep the same test path and branch coverage in getProviderEndpoint while
updating the expected URL string to match the fake token.
In `@packages/actions/src/get-provider-endpoint.ts`:
- Around line 49-55: The Vertex Express Mode URL builder in getProviderEndpoint
currently interpolates the token directly into the query string, which can break
when AQ.-prefixed keys contain reserved characters. Update the URL construction
in getProviderEndpoint to use URL and URLSearchParams for the token-based
branch, and apply the same fix to the other Vertex branches that use
key=${token} so the key value is encoded consistently.
---
Nitpick comments:
In `@apps/gateway/src/videos/videos.spec.ts`:
- Around line 1615-1670: The Seedance 2.0 Mini billing test only covers output
pricing, so it can miss regressions in the new reference-video surcharge path.
Update the existing bytedance/seedance-2-0-mini case in videos.spec.ts to add a
request that includes reference_videos, then verify the resulting videoJob/log
billing includes the expected videoInputCost as well as the existing
videoOutputCost. Use the same app.request, processPendingVideoJobs, and db query
patterns already in the test to locate the affected billing assertions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 0a941616-0807-426c-b7ce-482a85b2c4ff
📒 Files selected for processing (14)
apps/docs/content/features/video-generation.mdxapps/gateway/src/chat/chat.tsapps/gateway/src/chat/tools/messages-contain-audio.spec.tsapps/gateway/src/test-utils/mock-openai-server.tsapps/gateway/src/videos/videos.spec.tsapps/gateway/src/videos/videos.tsapps/playground/src/components/playground/chat-ui.tsxapps/playground/src/lib/image-gen.tsapps/playground/src/lib/video-gen.spec.tsapps/playground/src/lib/video-gen.tspackages/actions/src/get-provider-endpoint.spec.tspackages/actions/src/get-provider-endpoint.tspackages/models/src/models/bytedance.tspackages/models/src/models/google.ts
| @@ -13,7 +13,8 @@ LLMGateway supports asynchronous video generation through an OpenAI-compatible ` | |||
| Currently available models: | |||
|
|
|||
| - **Veo 3.1** through `avalanche` (1080p, 4k) and `google-vertex` (720p, 1080p, 4k) | |||
| - **Seedance 2.0**, **Seedance 2.0 Fast**, and **Seedance 1.5 Pro** through `bytedance` (720p, 1080p) | |||
| - **Seedance 2.0**, **Seedance 2.0 Fast**, **Seedance 2.0 Mini**, and **Seedance 1.5 Pro** through `bytedance` (720p, 1080p) | |||
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Split Seedance 2.0 Mini out of the shared capability summary.
These lines still describe Mini as a 720p/1080p, 5s/10s model, but packages/models/src/models/bytedance.ts now allows 480p and 4–15s for seedance-2-0-mini. Please give Mini its own bullet/row so the docs match the actual request constraints.
Also applies to: 52-57
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/docs/content/features/video-generation.mdx` at line 16, The shared
Seedance capability summary still groups Seedance 2.0 Mini with the 720p/1080p,
5s/10s models, which no longer matches the constraints in bytedance model
definitions. Update the documentation entry in video-generation.mdx to give
Seedance 2.0 Mini its own bullet/row and list its actual supported settings
(480p and 4–15s), while keeping the other Seedance variants in the shared
summary. Use the existing Seedance 2.0 / Seedance 2.0 Fast / Seedance 1.5 Pro
wording as the anchor for the split.
| const availableSizes = isSeedream | ||
| ? (["2K", "4K"] as const) | ||
| : isGemini31FlashImage | ||
| ? (["0.5K", "1K", "2K", "4K"] as const) | ||
| : (["1K", "2K", "4K"] as const); | ||
| : isGemini31FlashLiteImage | ||
| ? (["1K"] as const) | ||
| : isGemini31FlashImage | ||
| ? (["0.5K", "1K", "2K", "4K"] as const) | ||
| : (["1K", "2K", "4K"] as const); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Clamp imageSize when switching to the lite model.
This only narrows the dropdown options. It does not reset an existing "0.5K", "2K", or "4K" value, so switching models can keep submitting an unsupported size for gemini-3.1-flash-lite-image.
Suggested fix
const availableSizes = isSeedream
? (["2K", "4K"] as const)
: isGemini31FlashLiteImage
? (["1K"] as const)
: isGemini31FlashImage
? (["0.5K", "1K", "2K", "4K"] as const)
: (["1K", "2K", "4K"] as const);
+
+ useEffect(() => {
+ if (!availableSizes.includes(imageSize as (typeof availableSizes)[number])) {
+ setImageSize(availableSizes[0]);
+ }
+ }, [availableSizes, imageSize, setImageSize]);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const availableSizes = isSeedream | |
| ? (["2K", "4K"] as const) | |
| : isGemini31FlashImage | |
| ? (["0.5K", "1K", "2K", "4K"] as const) | |
| : (["1K", "2K", "4K"] as const); | |
| : isGemini31FlashLiteImage | |
| ? (["1K"] as const) | |
| : isGemini31FlashImage | |
| ? (["0.5K", "1K", "2K", "4K"] as const) | |
| : (["1K", "2K", "4K"] as const); | |
| const availableSizes = isSeedream | |
| ? (["2K", "4K"] as const) | |
| : isGemini31FlashLiteImage | |
| ? (["1K"] as const) | |
| : isGemini31FlashImage | |
| ? (["0.5K", "1K", "2K", "4K"] as const) | |
| : (["1K", "2K", "4K"] as const); | |
| useEffect(() => { | |
| if (!availableSizes.includes(imageSize as (typeof availableSizes)[number])) { | |
| setImageSize(availableSizes[0]); | |
| } | |
| }, [availableSizes, imageSize, setImageSize]); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/playground/src/components/playground/chat-ui.tsx` around lines 1055 -
1061, The availableSizes change in chat-ui only updates the dropdown options and
leaves an already-selected unsupported imageSize intact when switching to
gemini-3.1-flash-lite-image. Update the model-switching logic around the image
size state in playground/chat-ui.tsx so that when isGemini31FlashLiteImage
becomes true, the current imageSize is clamped or reset to "1K" if it is not
allowed. Use the existing availableSizes logic and the imageSize state handler
in the chat UI to ensure submitted sizes always match the active model.
| "AQ.Ab8RN9jgub3Gxb1PSi41S-vr5ycE7gMe8NTvapHpJxFZFx-g", | ||
| true, | ||
| ); | ||
|
|
||
| expect(endpoint).toBe( | ||
| "https://aiplatform.googleapis.com/v1/publishers/google/models/gemini-2.5-pro:streamGenerateContent?key=AQ.Ab8RN9jgub3Gxb1PSi41S-vr5ycE7gMe8NTvapHpJxFZFx-g&alt=sse", |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
Use an obviously fake AQ token in the test fixture.
This string looks like a real credential. Swapping it for something like AQ.test-token avoids secret-scanner noise while still covering the same branch.
Proposed fix
- "AQ.Ab8RN9jgub3Gxb1PSi41S-vr5ycE7gMe8NTvapHpJxFZFx-g",
+ "AQ.test-token",
...
- "https://aiplatform.googleapis.com/v1/publishers/google/models/gemini-2.5-pro:streamGenerateContent?key=AQ.Ab8RN9jgub3Gxb1PSi41S-vr5ycE7gMe8NTvapHpJxFZFx-g&alt=sse",
+ "https://aiplatform.googleapis.com/v1/publishers/google/models/gemini-2.5-pro:streamGenerateContent?key=AQ.test-token&alt=sse",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "AQ.Ab8RN9jgub3Gxb1PSi41S-vr5ycE7gMe8NTvapHpJxFZFx-g", | |
| true, | |
| ); | |
| expect(endpoint).toBe( | |
| "https://aiplatform.googleapis.com/v1/publishers/google/models/gemini-2.5-pro:streamGenerateContent?key=AQ.Ab8RN9jgub3Gxb1PSi41S-vr5ycE7gMe8NTvapHpJxFZFx-g&alt=sse", | |
| "AQ.test-token", | |
| ); | |
| expect(endpoint).toBe( | |
| "https://aiplatform.googleapis.com/v1/publishers/google/models/gemini-2.5-pro:streamGenerateContent?key=AQ.test-token&alt=sse", |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/actions/src/get-provider-endpoint.spec.ts` around lines 216 - 221,
The test fixture in get-provider-endpoint.spec.ts is using an AQ token that
resembles a real credential; replace the hardcoded token in the endpoint
assertion setup with an obviously fake value like AQ.test-token. Keep the same
test path and branch coverage in getProviderEndpoint while updating the expected
URL string to match the fake token.
| if (token?.startsWith("AQ.")) { | ||
| const baseEndpoint = `${url}/v1/publishers/google/models/${model}:${endpoint}`; | ||
| const queryParams = [`key=${token}`]; | ||
| if (stream) { | ||
| queryParams.push("alt=sse"); | ||
| } | ||
| return `${baseEndpoint}?${queryParams.join("&")}`; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
ast-grep outline packages/actions/src/get-provider-endpoint.ts --view expanded || true
echo '---'
sed -n '1,220p' packages/actions/src/get-provider-endpoint.ts
echo '--- SEARCH ---'
rg -n "startsWith\\(\"AQ\\.\"\\)|Express Mode|publishers/google/models|key=" packages/actions/src -SRepository: theopenco/llmgateway
Length of output: 9156
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- SPEC EXPRESS MODE ---'
sed -n '200,235p' packages/actions/src/get-provider-endpoint.spec.ts
echo '--- TOKEN SEARCH ---'
rg -n "encodeURIComponent|URLSearchParams|startsWith\\(\"AQ\\.\"\\)|google_vertex_project_id|key=\\$\\{token\\}" packages/actions/src packages/models/src -S
echo '--- PROVIDER KEY TYPES ---'
rg -n "type ProviderKeyOptions|interface ProviderKeyOptions|google_vertex_project_id|token" packages -g '!**/dist/**' -SRepository: theopenco/llmgateway
Length of output: 50377
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- EXPRESS MODE SPEC ---'
sed -n '206,225p' packages/actions/src/get-provider-endpoint.spec.ts
echo '--- TOKEN SHAPE / ENCODING ---'
rg -n "AQ\\.|Express Mode|API key|URLSearchParams|encodeURIComponent|searchParams" packages/actions/src/get-provider-endpoint.ts packages/actions/src/get-provider-endpoint.spec.ts -SRepository: theopenco/llmgateway
Length of output: 1598
🌐 Web query:
Google Vertex Express Mode API key AQ. URL encoding reserved characters
💡 Result:
Google has introduced a new format for API keys, often starting with the prefix AQ., which replaces the traditional AIza- prefix [1]. This change is part of an update to how authentication credentials are generated and managed for services like the Gemini Enterprise Agent Platform (Gemini API) [1][2][3]. Regarding URL encoding and reserved characters: 1. Standard Usage: When passing an API key in a URL query parameter (e.g.,?key=YOUR_API_KEY), the key must be properly URL-encoded if it contains any reserved characters [4]. Standard URL encoding rules apply, where characters such as &, =, +, and others are converted to their percent-encoded equivalents (e.g., & becomes %26) [4]. 2. Best Practices: Google strongly recommends avoiding the use of URL query parameters for API keys to prevent them from being exposed in server logs or browser history [5]. Instead, you should pass the API key using the x-goog-api-key HTTP request header [6][5]. When using this header, the key is sent as an opaque string and does not require URL encoding [6][4]. 3. Implementation: If you are using official Google Cloud client libraries or the Google Gen AI SDK, authentication is handled automatically [1][7]. These libraries manage the transmission of the API key, ensuring that it is passed correctly without you needing to manually perform URL encoding [8][1][7]. If you are manually constructing REST API requests, the safest approach is to use the HTTP header method rather than including the key in the URL string [6][5]. If you encounter authentication errors with an AQ.-prefixed key, ensure your application is sending the key to the correct native endpoint (e.g., generativelanguage.googleapis.com) rather than an OpenAI-compatible endpoint, which may reject the new key format depending on its implementation [1].
Citations:
- 1: https://dev.to/rapls/i-created-a-gemini-api-key-and-got-aq-instead-of-aiza-3dp3
- 2: https://cloud.google.com/vertex-ai/generative-ai/docs/start/api-keys
- 3: https://docs.cloud.google.com/vertex-ai/generative-ai/docs/start/express-mode/overview
- 4: https://cloud.google.com/apis/docs/system-parameters
- 5: https://docs.cloud.google.com/docs/authentication/api-keys-best-practices
- 6: https://cloud.google.com/docs/authentication/api-keys-use
- 7: https://cloud.google.com/vertex-ai/generative-ai/docs/start/express-mode/vertex-ai-express-mode-api-quickstart
- 8: https://docs.cloud.google.com/vertex-ai/docs/authentication
Encode the key query parameter in the Vertex Express Mode URL. Build this with URL/URLSearchParams instead of string interpolation so AQ.-prefixed keys with reserved characters don’t produce a broken endpoint. The same key=${token} pattern appears in the other Vertex branches too.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/actions/src/get-provider-endpoint.ts` around lines 49 - 55, The
Vertex Express Mode URL builder in getProviderEndpoint currently interpolates
the token directly into the query string, which can break when AQ.-prefixed keys
contain reserved characters. Update the URL construction in getProviderEndpoint
to use URL and URLSearchParams for the token-based branch, and apply the same
fix to the other Vertex branches that use key=${token} so the key value is
encoded consistently.
2ef2600 to
c81610e
Compare
Adds the new gemini-3.1-flash-lite-image model configuration with AI Studio and Vertex Express Mode authentication, and restricts its resolution to 1K in the playground.
Summary by CodeRabbit