fix: move artist redirect to live client tool handling#1642
fix: move artist redirect to live client tool handling#1642arpitgupta1214 wants to merge 1 commit intotestfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (4)
💤 Files with no reviewable changes (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThis pull request refactors the artist creation workflow by removing client-side message-copying logic ( Changes
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly Related PRs
Suggested Reviewers
Poem
🚥 Pre-merge checks | ✅ 1✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3445471abc
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
lib/api/getClientApiBaseUrl.ts
Outdated
| if (apiParam) { | ||
| return new URL(apiParam).toString().replace(/\/+$/, ""); |
There was a problem hiding this comment.
Block untrusted api query overrides
Accepting any ?api= URL here allows a crafted link to reroute authenticated client requests to an attacker-controlled origin. Chat requests attach a bearer token (useChatTransport adds Authorization), so a logged-in user who opens such a URL and sends a message can leak credentials cross-origin. Restrict this override to trusted hosts (or dev-only) before using it as the API base.
Useful? React with 👍 / 👎.
hooks/useVercelChat.ts
Outdated
| if (pendingRedirectPathRef.current) { | ||
| const redirectPath = pendingRedirectPathRef.current; | ||
| pendingRedirectPathRef.current = null; | ||
| window.history.replaceState({}, "", redirectPath); |
There was a problem hiding this comment.
Refresh conversations before applying redirect path
This redirect flow updates the URL but never refreshes the conversations query, so after a create_new_artist redirect the sidebar can continue showing stale chat data until a manual refresh/focus-triggered refetch. The previous create-artist flow explicitly refetched conversations; without an equivalent invalidation here, recent chats can lag behind the new room state.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib/api/getClientApiBaseUrl.ts (1)
11-24:⚠️ Potential issue | 🟠 MajorKeep the sessionStorage fallback when
?api=is malformed.If
new URL(apiParam)throws, the outercatchskips Lines 20-25 and falls straight back to the default base URL. That means an invalid query param disables an existing stored override instead of ignoring the bad param and continuing with the session fallback. Split query parsing and storage access into separatetry/catchblocks.🩹 Suggested fix
if (typeof window !== "undefined") { - try { - const apiParam = new URLSearchParams(window.location.search).get("api"); - if (apiParam === "clear") { - return defaultApiBaseUrl; - } - - if (apiParam) { - return new URL(apiParam).toString().replace(/\/+$/, ""); - } - - const storedApiOverride = window.sessionStorage.getItem( - API_OVERRIDE_STORAGE_KEY, - ); - if (storedApiOverride) { - return storedApiOverride.replace(/\/+$/, ""); - } - } catch { - // Ignore storage failures and fall back to default. + const apiParam = new URLSearchParams(window.location.search).get("api"); + if (apiParam === "clear") { + return defaultApiBaseUrl; + } + + if (apiParam) { + try { + return new URL(apiParam).toString().replace(/\/+$/, ""); + } catch { + // Ignore invalid query overrides and continue to sessionStorage. + } + } + + try { + const storedApiOverride = window.sessionStorage.getItem( + API_OVERRIDE_STORAGE_KEY, + ); + if (storedApiOverride) { + return storedApiOverride.replace(/\/+$/, ""); + } + } catch { + // Ignore storage failures and fall back to default. } }As per coding guidelines,
lib/**/*.ts: For utility functions, ensure: Proper error handling.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/api/getClientApiBaseUrl.ts` around lines 11 - 24, The current parsing of the ?api= query param uses new URL(apiParam) inside a try/catch that, on failure, bypasses the sessionStorage fallback; split the logic so URL parsing and sessionStorage access have independent error handling: first safely read apiParam and handle the "clear" case, then try to construct new URL(apiParam) in its own try/catch and only return a normalized URL if parsing succeeds, but if parsing throws do not return default immediately — proceed to retrieve API_OVERRIDE_STORAGE_KEY from window.sessionStorage (its own try/catch) and return its normalized value if present, otherwise fall back to defaultApiBaseUrl; references: apiParam, new URL(apiParam), API_OVERRIDE_STORAGE_KEY, storedApiOverride.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@components/VercelChat/ToolComponents.tsx`:
- Around line 346-349: The code unconditionally JSON.parse's dynamic-tool output
into result, which throws for empty/non-JSON redirect outputs; change the logic
so parsing is guarded: either defer JSON.parse until after you inspect the tool
branch (e.g., check for redirect tool type/name) or wrap the parse of (output as
CallToolResult).content[0].text in a safe path that verifies content exists and
is valid JSON (or try/catch) before assigning to result; adjust the logic around
the variables type, output, CallToolResult and the redirect handling so lines
handling redirect (around the current branching at/after where result is used)
never see an unguarded JSON.parse (also apply same guard to the code at the
other occurrence noted).
In `@hooks/useVercelChat.ts`:
- Around line 189-196: The pending redirect handling inside onToolCall currently
only completes if refetchCredits() resolves, so a rejected refetch can leave
pendingRedirectPathRef.current set and prevent navigation; update onToolCall to
always perform the redirect navigation and reset pendingRedirectPathRef.current
regardless of refetchCredits() outcome by moving the redirect nav/cleanup into a
finally block or by catching errors from refetchCredits() and then executing the
redirect and clearing pendingRedirectPathRef; refer to onToolCall,
pendingRedirectPathRef, and refetchCredits() in the change.
In `@lib/api/getClientApiBaseUrl.ts`:
- Around line 11-18: The current getClientApiBaseUrl logic allows any ?api=
absolute URL which can redirect production traffic; change it to only accept
overrides if the origin is trusted or when running in a non-production/dev mode.
Specifically, update the code around apiParam (in getClientApiBaseUrl) to: 1)
parse apiParam and validate its origin against a hardcoded allowlist of trusted
origins or check a runtime feature flag/ENV (e.g., NODE_ENV !== 'production' or
an ALLOW_API_OVERRIDE flag) before returning it; 2) if validation fails, fall
back to defaultApiBaseUrl; and 3) keep the trimming of trailing slashes but do
not accept raw hostnames/paths without explicit allowlist/flag; also ensure any
persistent use in providers/ApiOverrideSync.tsx and hooks/useChatTransport.ts
respects the same validation function to avoid leaking requests to untrusted
origins.
---
Outside diff comments:
In `@lib/api/getClientApiBaseUrl.ts`:
- Around line 11-24: The current parsing of the ?api= query param uses new
URL(apiParam) inside a try/catch that, on failure, bypasses the sessionStorage
fallback; split the logic so URL parsing and sessionStorage access have
independent error handling: first safely read apiParam and handle the "clear"
case, then try to construct new URL(apiParam) in its own try/catch and only
return a normalized URL if parsing succeeds, but if parsing throws do not return
default immediately — proceed to retrieve API_OVERRIDE_STORAGE_KEY from
window.sessionStorage (its own try/catch) and return its normalized value if
present, otherwise fall back to defaultApiBaseUrl; references: apiParam, new
URL(apiParam), API_OVERRIDE_STORAGE_KEY, storedApiOverride.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 3e65dcd8-1e7a-4a6a-b542-60b307c63ba0
📒 Files selected for processing (8)
components/VercelChat/ToolComponents.tsxcomponents/VercelChat/tools/CreateArtistToolResult.tsxhooks/useChatTransport.tshooks/useCreateArtistTool.tshooks/useVercelChat.tslib/api/getClientApiBaseUrl.tslib/messages/copyMessages.tsproviders/VercelChatProvider.tsx
💤 Files with no reviewable changes (2)
- lib/messages/copyMessages.ts
- hooks/useCreateArtistTool.ts
| const result = | ||
| type === "dynamic-tool" | ||
| ? JSON.parse((output as CallToolResult).content[0].text) | ||
| : output; |
There was a problem hiding this comment.
Prevent pre-branch parse crashes for redirect dynamic-tool outputs.
result is parsed before tool-specific branching, so a non-JSON/empty redirect output can throw before Line 441 is reached.
💡 Proposed fix
export function getToolResultComponent(part: ToolUIPart | DynamicToolUIPart) {
const { toolCallId, output, type } = part;
- const result =
- type === "dynamic-tool"
- ? JSON.parse((output as CallToolResult).content[0].text)
- : output;
const toolName = getToolOrDynamicToolName(part);
+
+ if (toolName === "redirect") {
+ return null;
+ }
+
+ const result =
+ type === "dynamic-tool"
+ ? (() => {
+ const text = (output as CallToolResult)?.content?.[0]?.text;
+ if (!text) return output;
+ try {
+ return JSON.parse(text);
+ } catch {
+ return output;
+ }
+ })()
+ : output;
const isSearchWebTool = toolName === "search_web";
const isDeepResearchTool = toolName === "web_deep_research";
@@
- } else if (toolName === "redirect") {
- return null;
} else if (toolName === "get_youtube_channels") {Also applies to: 441-442
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@components/VercelChat/ToolComponents.tsx` around lines 346 - 349, The code
unconditionally JSON.parse's dynamic-tool output into result, which throws for
empty/non-JSON redirect outputs; change the logic so parsing is guarded: either
defer JSON.parse until after you inspect the tool branch (e.g., check for
redirect tool type/name) or wrap the parse of (output as
CallToolResult).content[0].text in a safe path that verifies content exists and
is valid JSON (or try/catch) before assigning to result; adjust the logic around
the variables type, output, CallToolResult and the redirect handling so lines
handling redirect (around the current branching at/after where result is used)
never see an unguarded JSON.parse (also apply same guard to the code at the
other occurrence noted).
hooks/useVercelChat.ts
Outdated
| onToolCall: async ({ toolCall }) => { | ||
| if ("toolName" in toolCall && toolCall.toolName === "redirect") { | ||
| const path = (toolCall.input as { path?: string } | undefined)?.path; | ||
| if (path?.startsWith("/")) { | ||
| pendingRedirectPathRef.current = path; | ||
| } | ||
| } | ||
| }, |
There was a problem hiding this comment.
Make redirect cleanup independent of refetchCredits() success.
Right now, a rejected refetchCredits() prevents both redirect execution and ref reset, so stale redirect state can leak into a later response.
💡 Proposed fix
onToolCall: async ({ toolCall }) => {
if ("toolName" in toolCall && toolCall.toolName === "redirect") {
const path = (toolCall.input as { path?: string } | undefined)?.path;
- if (path?.startsWith("/")) {
+ if (path && /^\/(?!\/)/.test(path)) {
pendingRedirectPathRef.current = path;
}
}
},
onFinish: async () => {
- // Update credits after AI response completes
- await refetchCredits();
-
- if (pendingRedirectPathRef.current) {
- const redirectPath = pendingRedirectPathRef.current;
- pendingRedirectPathRef.current = null;
- window.history.replaceState({}, "", redirectPath);
- }
+ const redirectPath = pendingRedirectPathRef.current;
+ pendingRedirectPathRef.current = null;
+
+ try {
+ // Update credits after AI response completes
+ await refetchCredits();
+ } finally {
+ if (redirectPath && /^\/(?!\/)/.test(redirectPath)) {
+ window.history.replaceState({}, "", redirectPath);
+ }
+ }
},Also applies to: 197-205
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@hooks/useVercelChat.ts` around lines 189 - 196, The pending redirect handling
inside onToolCall currently only completes if refetchCredits() resolves, so a
rejected refetch can leave pendingRedirectPathRef.current set and prevent
navigation; update onToolCall to always perform the redirect navigation and
reset pendingRedirectPathRef.current regardless of refetchCredits() outcome by
moving the redirect nav/cleanup into a finally block or by catching errors from
refetchCredits() and then executing the redirect and clearing
pendingRedirectPathRef; refer to onToolCall, pendingRedirectPathRef, and
refetchCredits() in the change.
lib/api/getClientApiBaseUrl.ts
Outdated
| const apiParam = new URLSearchParams(window.location.search).get("api"); | ||
| if (apiParam === "clear") { | ||
| return defaultApiBaseUrl; | ||
| } | ||
|
|
||
| if (apiParam) { | ||
| return new URL(apiParam).toString().replace(/\/+$/, ""); | ||
| } |
There was a problem hiding this comment.
Block arbitrary ?api= overrides from steering production traffic.
Accepting any absolute URL here lets a shared link reroute all chat and stream requests to an attacker-controlled origin. Because providers/ApiOverrideSync.tsx persists the same value and hooks/useChatTransport.ts Lines 15-25 uses it for request routing, this can leak prompts and any auth headers attached by callers. Please gate query-param overrides behind a trusted allowlist or a development-only switch before shipping this.
As per coding guidelines, **/*.{ts,tsx,js}: Implement built-in security practices for authentication and data handling.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@lib/api/getClientApiBaseUrl.ts` around lines 11 - 18, The current
getClientApiBaseUrl logic allows any ?api= absolute URL which can redirect
production traffic; change it to only accept overrides if the origin is trusted
or when running in a non-production/dev mode. Specifically, update the code
around apiParam (in getClientApiBaseUrl) to: 1) parse apiParam and validate its
origin against a hardcoded allowlist of trusted origins or check a runtime
feature flag/ENV (e.g., NODE_ENV !== 'production' or an ALLOW_API_OVERRIDE flag)
before returning it; 2) if validation fails, fall back to defaultApiBaseUrl; and
3) keep the trimming of trailing slashes but do not accept raw hostnames/paths
without explicit allowlist/flag; also ensure any persistent use in
providers/ApiOverrideSync.tsx and hooks/useChatTransport.ts respects the same
validation function to avoid leaking requests to untrusted origins.
There was a problem hiding this comment.
5 issues found across 8 files
Confidence score: 2/5
- There are multiple concrete user-impact risks at severity 7/10, including a potential client-side request hijack path in
lib/api/getClientApiBaseUrl.tswhere?api=can point requests at an untrusted origin. components/VercelChat/ToolComponents.tsxcan crash rendering ifJSON.parseruns on empty/non-JSON tool output before the redirect branch, which makes this a likely runtime regression.- In
hooks/useVercelChat.ts, the redirect flow is fragile (history.replaceStatedoes not actually navigate) and the new tool-triggered redirect behavior shipped without a regression test, increasing the chance of breakage. - Pay close attention to
hooks/useVercelChat.ts,lib/api/getClientApiBaseUrl.ts, andcomponents/VercelChat/ToolComponents.tsx- navigation correctness, API-origin validation, and defensive parsing are the highest-risk areas.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="hooks/useVercelChat.ts">
<violation number="1" location="hooks/useVercelChat.ts:64">
P1: Custom agent: **Flag AI Slop and Fabricated Changes**
This behavior change (tool-triggered redirect via `onToolCall`/`onFinish`) ships without a regression test, which Rule 3 explicitly flags for bug-fix/behavior-change PRs.</violation>
<violation number="2" location="hooks/useVercelChat.ts:189">
P1: Custom agent: **Code Structure and Size Limits for Readability and Single Responsibility**
This adds more behavior to an already far-over-limit hook file instead of splitting responsibilities; Rule 1 requires files to stay under 100 LOC.</violation>
<violation number="3" location="hooks/useVercelChat.ts:204">
P2: `history.replaceState` only changes the address bar, so the redirect tool won’t navigate to the new route and the chat will keep using the old `id`. Use a real navigation call (e.g., `window.location.replace` or the Next router) so the redirect actually takes effect.</violation>
</file>
<file name="lib/api/getClientApiBaseUrl.ts">
<violation number="1" location="lib/api/getClientApiBaseUrl.ts:17">
P1: Validate or restrict the `api` query param before using it as the API base URL. As written, any link can set `?api=...` to an arbitrary origin, which can redirect client API requests to an untrusted host and potentially leak auth headers or user data.</violation>
</file>
<file name="components/VercelChat/ToolComponents.tsx">
<violation number="1" location="components/VercelChat/ToolComponents.tsx:346">
P1: Handle the `redirect` case before parsing dynamic-tool output, or parse defensively. `JSON.parse` here can throw on empty/non-JSON output and crash rendering before the redirect branch runs.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
| @@ -61,6 +61,7 @@ export function useVercelChat({ | |||
| const { refetchCredits } = usePaymentProvider(); | |||
There was a problem hiding this comment.
P1: Custom agent: Flag AI Slop and Fabricated Changes
This behavior change (tool-triggered redirect via onToolCall/onFinish) ships without a regression test, which Rule 3 explicitly flags for bug-fix/behavior-change PRs.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At hooks/useVercelChat.ts, line 64:
<comment>This behavior change (tool-triggered redirect via `onToolCall`/`onFinish`) ships without a regression test, which Rule 3 explicitly flags for bug-fix/behavior-change PRs.</comment>
<file context>
@@ -61,6 +61,7 @@ export function useVercelChat({
const { refetchCredits } = usePaymentProvider();
const { transport, getHeaders } = useChatTransport();
const { authenticated } = usePrivy();
+ const pendingRedirectPathRef = useRef<string | null>(null);
// Load artist files for mentions (from Supabase)
</file context>
| @@ -61,6 +61,7 @@ export function useVercelChat({ | |||
| const { refetchCredits } = usePaymentProvider(); | |||
There was a problem hiding this comment.
P1: Custom agent: Code Structure and Size Limits for Readability and Single Responsibility
This adds more behavior to an already far-over-limit hook file instead of splitting responsibilities; Rule 1 requires files to stay under 100 LOC.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At hooks/useVercelChat.ts, line 189:
<comment>This adds more behavior to an already far-over-limit hook file instead of splitting responsibilities; Rule 1 requires files to stay under 100 LOC.</comment>
<file context>
@@ -181,12 +182,27 @@ export function useVercelChat({
console.error("An error occurred, please try again!", e);
toast.error("An error occurred, please try again!");
},
+ onToolCall: async ({ toolCall }) => {
+ if ("toolName" in toolCall && toolCall.toolName === "redirect") {
+ const path = (toolCall.input as { path?: string } | undefined)?.path;
</file context>
lib/api/getClientApiBaseUrl.ts
Outdated
| } | ||
|
|
||
| if (apiParam) { | ||
| return new URL(apiParam).toString().replace(/\/+$/, ""); |
There was a problem hiding this comment.
P1: Validate or restrict the api query param before using it as the API base URL. As written, any link can set ?api=... to an arbitrary origin, which can redirect client API requests to an untrusted host and potentially leak auth headers or user data.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lib/api/getClientApiBaseUrl.ts, line 17:
<comment>Validate or restrict the `api` query param before using it as the API base URL. As written, any link can set `?api=...` to an arbitrary origin, which can redirect client API requests to an untrusted host and potentially leak auth headers or user data.</comment>
<file context>
@@ -8,6 +8,15 @@ export function getClientApiBaseUrl(): string {
+ }
+
+ if (apiParam) {
+ return new URL(apiParam).toString().replace(/\/+$/, "");
+ }
+
</file context>
| return new URL(apiParam).toString().replace(/\/+$/, ""); | |
| const parsedApiUrl = new URL(apiParam, defaultApiBaseUrl); | |
| if (parsedApiUrl.origin !== new URL(defaultApiBaseUrl).origin) { | |
| return defaultApiBaseUrl; | |
| } | |
| return parsedApiUrl.toString().replace(/\/+$/, ""); |
| const result = | ||
| type === "dynamic-tool" | ||
| ? JSON.parse((output as CallToolResult).content[0].text) | ||
| : output; | ||
| const toolName = getToolOrDynamicToolName(part); |
There was a problem hiding this comment.
P1: Handle the redirect case before parsing dynamic-tool output, or parse defensively. JSON.parse here can throw on empty/non-JSON output and crash rendering before the redirect branch runs.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At components/VercelChat/ToolComponents.tsx, line 346:
<comment>Handle the `redirect` case before parsing dynamic-tool output, or parse defensively. `JSON.parse` here can throw on empty/non-JSON output and crash rendering before the redirect branch runs.</comment>
<file context>
@@ -335,10 +343,10 @@ export function getToolCallComponent(part: ToolUIPart) {
- const result = isMcp
- ? JSON.parse((output as CallToolResult).content[0].text)
- : output;
+ const result =
+ type === "dynamic-tool"
+ ? JSON.parse((output as CallToolResult).content[0].text)
</file context>
| const result = | |
| type === "dynamic-tool" | |
| ? JSON.parse((output as CallToolResult).content[0].text) | |
| : output; | |
| const toolName = getToolOrDynamicToolName(part); | |
| const toolName = getToolOrDynamicToolName(part); | |
| if (toolName === "redirect") { | |
| return null; | |
| } | |
| const result = | |
| type === "dynamic-tool" | |
| ? (() => { | |
| const text = (output as CallToolResult)?.content?.[0]?.text; | |
| if (!text) return output; | |
| try { | |
| return JSON.parse(text); | |
| } catch { | |
| return output; | |
| } | |
| })() | |
| : output; |
| if (pendingRedirectPathRef.current) { | ||
| const redirectPath = pendingRedirectPathRef.current; | ||
| pendingRedirectPathRef.current = null; | ||
| window.history.replaceState({}, "", redirectPath); |
There was a problem hiding this comment.
P2: history.replaceState only changes the address bar, so the redirect tool won’t navigate to the new route and the chat will keep using the old id. Use a real navigation call (e.g., window.location.replace or the Next router) so the redirect actually takes effect.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At hooks/useVercelChat.ts, line 204:
<comment>`history.replaceState` only changes the address bar, so the redirect tool won’t navigate to the new route and the chat will keep using the old `id`. Use a real navigation call (e.g., `window.location.replace` or the Next router) so the redirect actually takes effect.</comment>
<file context>
@@ -181,12 +182,27 @@ export function useVercelChat({
+ if (pendingRedirectPathRef.current) {
+ const redirectPath = pendingRedirectPathRef.current;
+ pendingRedirectPathRef.current = null;
+ window.history.replaceState({}, "", redirectPath);
+ }
},
</file context>
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="hooks/useChatTransport.ts">
<violation number="1">
P1: API base URL is frozen at render time, so request-time API override changes are not reliably applied to send/reconnect requests.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
| import { getClientApiBaseUrl } from "@/lib/api/getClientApiBaseUrl"; | ||
| import { usePrivy } from "@privy-io/react-auth"; | ||
|
|
||
| export function useChatTransport() { |
There was a problem hiding this comment.
P1: API base URL is frozen at render time, so request-time API override changes are not reliably applied to send/reconnect requests.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At hooks/useChatTransport.ts, line 16:
<comment>API base URL is frozen at render time, so request-time API override changes are not reliably applied to send/reconnect requests.</comment>
<file context>
@@ -5,27 +5,17 @@ import { usePrivy } from "@privy-io/react-auth";
- headers: request.headers,
- credentials: request.credentials,
- }),
+ api: `${baseUrl}/api/chat`,
});
- }, []);
</file context>
| export function useChatTransport() { | |
| api: `${baseUrl}/api/chat`, | |
| prepareSendMessagesRequest: async (request) => ({ | |
| api: `${getClientApiBaseUrl()}/api/chat`, | |
| headers: request.headers, | |
| body: request.body ?? {}, | |
| credentials: request.credentials, | |
| }), | |
| prepareReconnectToStreamRequest: async (request) => ({ | |
| api: `${getClientApiBaseUrl()}/api/chat/${request.id}/stream`, | |
| headers: request.headers, | |
| credentials: request.credentials, | |
| }), |
a674243 to
7602294
Compare
Summary
Testing
Summary by cubic
Moves artist-creation redirect to client-side handling using the live completion event, removing the message-copy flow and redirecting after streaming completes. Also keeps the
?apioverride preferred and resolved per request.useVercelChat: capturedata-redirectpath inonData, apply inonFinish, and reset on errors.useCreateArtistToolandlib/messages/copyMessages; simplify success UI to “Artist created successfully”.newRoomIdfromCreateArtistResult.Written for commit 7602294. Summary will update on new commits.
Summary by CodeRabbit