Skip to content

feat: update createArtist to call recoup-api endpoint#1458

Merged
sweetmantech merged 9 commits intomainfrom
sweetmantech/myc-3924-recoup-chatappapiartistcreateroutets-migrate-to-recoup-api
Jan 15, 2026
Merged

feat: update createArtist to call recoup-api endpoint#1458
sweetmantech merged 9 commits intomainfrom
sweetmantech/myc-3924-recoup-chatappapiartistcreateroutets-migrate-to-recoup-api

Conversation

@sweetmantech
Copy link
Collaborator

@sweetmantech sweetmantech commented Jan 15, 2026

Summary

  • Update lib/createArtist.tsx to call the migrated /api/artist/create endpoint on recoup-api
  • Use NEW_API_BASE_URL constant to route to correct environment (prod vs test)

Test plan

  • All 9 unit tests pass in Recoup-Chat
  • Build succeeds

Depends on Recoup-API PR #115 (recoup-api endpoint migration)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores

    • Removed legacy artist-creation tooling and its API endpoint; cleaned up related utilities and type imports.
    • Updated components/hooks to use centralized type locations.
    • Added configuration tokens for evaluation and SMS handling.
  • Bug Fixes

    • Propagates an optional access token through request setup to downstream tool calls.
    • Strengthened request/header validation to include and respect access tokens.

✏️ Tip: You can customize this high-level summary in your review settings.

Update lib/createArtist.tsx to call the migrated /api/artist/create
endpoint on recoup-api instead of the local endpoint.

Related to MYC-3924: Migrate /api/artist/create REST endpoint

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link
Contributor

vercel bot commented Jan 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
recoup-chat Ready Ready Preview Jan 15, 2026 9:22pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 15, 2026

📝 Walkthrough

Walkthrough

Removed the create-artist feature and related helpers; relocated type imports; and added optional accessToken extraction and propagation through header validation, chat request validation, and MCP transport initialization. (33 words)

Changes

Cohort / File(s) Summary
Client helper
lib/createArtist.tsx
Deleted the client-side createArtist helper and its default export.
Server API route
app/api/artist/create/route.ts
Removed the GET API route that parsed name/account_id, invoked createArtistInDb, returned responses, and exported route metadata.
Tool implementation & registry
lib/tools/createArtist.tsx, lib/tools/getMcpTools.ts
Removed the createArtist MCP tool and its CreateArtistResult type; dropped create_new_artist mapping from the ToolSet.
Supabase helper
lib/supabase/copyRoom.ts
Deleted copyRoom helper which duplicated rooms/conversations for a new artist.
Type import updates
components/VercelChat/ToolComponents.tsx, components/VercelChat/tools/CreateArtistToolResult.tsx, hooks/useCreateArtistTool.ts
Updated imports to @/types/createArtistResult (from removed lib/tools path); no runtime behavior changes.
Chat auth propagation
lib/chat/validateHeaders.ts, lib/chat/validateChatRequest.ts, lib/chat/setupToolsForRequest.ts, lib/evals/callChatFunctionsWithResult.ts
Add optional accessToken extraction from headers, include accessToken on validated ChatRequestBody, and pass it into MCP transport requestInit.headers.Authorization (and evals use EVAL_ACCESS_TOKEN).
Twilio SMS integration
lib/twilio/constants.ts, lib/twilio/handleIncomingSms.ts
Added SMS_ACCESS_TOKEN constant and include it as accessToken in the ChatRequestBody payload for incoming SMS handling.
Misc constants
lib/consts.ts
Added EVAL_ACCESS_TOKEN exported constant (from env).

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Edge as "API Route / Incoming SMS"
  participant Validator as "validateHeaders"
  participant ReqValidator as "validateChatRequest"
  participant Setup as "setupToolsForRequest"
  participant MCP as "MCP Transport/Client"

  Client->>Edge: sends request (headers or SMS)
  Edge->>Validator: extract accountId + accessToken
  Validator-->>Edge: { accountId, accessToken? }
  Edge->>ReqValidator: validate body + attach accessToken
  ReqValidator-->>Edge: validated ChatRequestBody (includes accessToken)
  Edge->>Setup: setupToolsForRequest(validated body)
  Setup->>MCP: initialize transport with requestInit.headers.Authorization = "Bearer <accessToken>"
  MCP-->>Setup: tools client ready
  Setup-->>Edge: ToolSet (with MCP client using auth)
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

A route and tool fade out of sight,
Tokens travel headers into the night.
Imports moved, quiet and neat,
Tools reshuffled, paths made sweet. ✨

🚥 Pre-merge checks | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Solid & Clean Code ⚠️ Warning Pull request uses empty-string fallbacks for access tokens instead of fail-fast validation, violating Clean Code and SOLID principles, with the anti-pattern duplicated across multiple files without addressing previous review feedback. Replace empty-string fallbacks with explicit environment variable checks that throw descriptive errors at startup to ensure misconfiguration fails fast and code requirements remain explicit and maintainable.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@lib/createArtist.tsx`:
- Around line 5-7: The request URL builds query params for name and account_id
but only encodes name; update the fetch call to URL-encode account_id as well
(e.g., use encodeURIComponent(account_id) or construct params with
URLSearchParams) so that
NEW_API_BASE_URL/.../?name=${encodeURIComponent(name)}&account_id=${encodeURIComponent(account_id)}
is used; adjust the code in the createArtist call where response is defined to
ensure both name and account_id are safely encoded.
🧹 Nitpick comments (1)
lib/createArtist.tsx (1)

8-13: Consider adding response validation and preserving error observability.

Two concerns with the current implementation:

  1. No response.ok check: A 4xx/5xx response will still attempt to parse JSON and may return undefined from data.artist rather than properly handling the error path.

  2. Silent error swallowing: Removing console.error entirely makes debugging production issues significantly harder. While the coding guidelines advise removing console.log statements, structured error logging (or at least optional observability) helps maintain the system.

♻️ Proposed improvement
   try {
     const response = await fetch(
       `${NEW_API_BASE_URL}/api/artist/create?name=${encodeURIComponent(name)}&account_id=${encodeURIComponent(account_id)}`,
     );
+
+    if (!response.ok) {
+      return null;
+    }
+
     const data = await response.json();
 
     return data.artist;
-  } catch (error) {
+  } catch {
     return null;
   }

If observability is desired, consider integrating with a logging service or error tracking tool rather than console.error.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 55cc45a and 0ef577c.

📒 Files selected for processing (1)
  • lib/createArtist.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{tsx,ts,jsx,js}

📄 CodeRabbit inference engine (.cursor/rules/component-design.mdc)

**/*.{tsx,ts,jsx,js}: Use semantic HTML elements appropriate to the component's role
Ensure keyboard navigation and focus management in UI components
Provide proper ARIA roles/states and test with screen readers
Start with semantic HTML first, then augment with ARIA if needed
Support both controlled and uncontrolled state in components
Wrap a single HTML element per component (no multiple root elements)
Favor composition over inheritance in component design
Expose clear APIs via props/slots for component customization
Use asChild pattern for flexible element types in components
Support polymorphism with as prop when appropriate
Use @radix-ui/react-* primitives for behavior and accessibility
Use class-variance-authority (CVA) for component variants
Use @radix-ui/react-slot for implementing asChild pattern
Use @radix-ui/react-use-controllable-state for state management
Follow shadcn/ui component structure and naming conventions
Use cn() utility combining clsx and tailwind-merge for class merging
Export both component and variant functions (e.g., Button, buttonVariants)
Use @radix-ui/react-icons for UI component icons (not Lucide React)
Use lucide-react for application icons and illustrations
Use framer-motion for animations and transitions
Use next-themes for theme management
Use tailwindcss-animate for CSS animations
Use sonner for toast notifications
Use embla-carousel-react for carousels
Use react-resizable-panels for resizable layouts
Provide defaultValue and onValueChange props for state management
Use data-state attribute for visual component states (open/closed, loading, etc.)
Use data-slot attribute for component identification
Use kebab-case naming for data attributes (e.g., data-slot="form-field")
Follow class order in Tailwind: base → variants → conditionals → user overrides
Define component variants outside components to avoid recreation on re-render
Implement focus trapping in modal/dialog components
Store...

Files:

  • lib/createArtist.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (.cursor/rules/component-design.mdc)

**/*.{tsx,ts}: Extend native HTML attributes using React.ComponentProps<"element"> pattern
Export component prop types with explicit ComponentNameProps naming convention

Files:

  • lib/createArtist.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/stagehand.mdc)

**/*.{ts,tsx}: Plan instructions using Stagehand observe method before executing actions (e.g., const results = await page.observe("Click the sign in button");)
Cache the results of observe to avoid unexpected DOM changes
Keep act actions atomic and specific (e.g., "Click the sign in button" not "Sign in to the website"). Avoid actions that are more than one step.
Use variable substitution with the variables parameter in act for dynamic form filling (e.g., action: "Enter Name: %name%", variables: { name: "John Doe" })
Always use Zod schemas for structured data extraction with the extract method (e.g., schema: z.object({ text: z.string() }))
Wrap array extractions in a single object when extracting multiple items using extract (e.g., schema: z.object({ buttons: z.array(z.string()) }))
Use explicit instruction and schema parameters when calling extract method
Import Stagehand types from @browserbasehq/stagehand package (e.g., import { Stagehand, Page, BrowserContext } from "@browserbasehq/stagehand";)
Initialize Stagehand with new Stagehand() constructor and call await stagehand.init() before using page automation methods
Implement main automation logic in functions that accept { page, context, stagehand } parameters
Provide specific instructions to agents instead of vague ones (e.g., "Navigate to products page and filter by 'Electronics'" not "Do some stuff on this page")
Break down complex agent tasks into smaller steps for better execution
Use error handling with try/catch blocks when executing agent tasks
Combine agents for navigation with traditional methods for precise data extraction

**/*.{ts,tsx}: Create single-responsibility components with obvious data flow
Use strict TypeScript types with zero 'any' types
Follow Next.js optimization guides for performance

Files:

  • lib/createArtist.tsx
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

**/*.{ts,tsx,js}: Write minimal code - use only the absolute minimum code needed
Ensure code is self-documenting through precise naming with verbs for functions and nouns for variables
Add short comments only when necessary to clarify non-obvious logic
Implement built-in security practices for authentication and data handling
Consider if code can be split into smaller functions before implementing
Avoid unnecessary abstractions during implementation
Ensure code clarity is suitable for understanding by junior developers

Files:

  • lib/createArtist.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Use Single Responsibility Principle: One function per file with clear naming
Remove all console.log statements before merging to production
Write comments to explain 'why', not 'what'; prefer self-documenting code

Files:

  • lib/createArtist.tsx
🧬 Code graph analysis (1)
lib/createArtist.tsx (1)
lib/consts.ts (1)
  • NEW_API_BASE_URL (4-6)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Vercel Agent Review
  • GitHub Check: Run evaluations
🔇 Additional comments (1)
lib/createArtist.tsx (1)

1-2: Good use of centralized configuration.

Importing NEW_API_BASE_URL from a constants module follows the Single Responsibility Principle nicely - environment-specific URL logic is encapsulated in one place, making future changes straightforward.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

try {
const response = await fetch(
`/api/artist/create?name=${encodeURIComponent(name)}&account_id=${account_id}`,
`${NEW_API_BASE_URL}/api/artist/create?name=${encodeURIComponent(name)}&account_id=${account_id}`,
Copy link
Contributor

@vercel vercel bot Jan 15, 2026

Choose a reason for hiding this comment

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

The fetch response is not checked for HTTP errors before parsing JSON. This breaks the established pattern used throughout the codebase and will mask API errors by silently returning null even when the server returns an error status code.

View Details
📝 Patch Details
diff --git a/lib/createArtist.tsx b/lib/createArtist.tsx
index dcfa17f0..5b40e729 100644
--- a/lib/createArtist.tsx
+++ b/lib/createArtist.tsx
@@ -5,6 +5,11 @@ const createArtist = async (name: string, account_id: string) => {
     const response = await fetch(
       `${NEW_API_BASE_URL}/api/artist/create?name=${encodeURIComponent(name)}&account_id=${account_id}`,
     );
+    
+    if (!response.ok) {
+      throw new Error(`API request failed with status ${response.status}`);
+    }
+    
     const data = await response.json();
 
     return data.artist;

Analysis

Missing HTTP error check in createArtist() allows errors to be silently masked

What fails: The createArtist() function in lib/createArtist.tsx calls response.json() without first checking response.ok, which masks HTTP error responses and breaks the established error-handling pattern used throughout the codebase.

How to reproduce: Call createArtist() when the API returns an error status (e.g., 400, 500):

const result = await createArtist("test", "invalid_id");
// Returns null even though API returned 400 error

Result:

  • When API returns 400 with JSON error body: Function silently returns null (because error response has no artist field)
  • When API returns 500 with HTML error body: Function catches JSON parse error and returns null, masking the actual HTTP 500 error
  • Developers cannot distinguish between "artist not created" and "API error" without additional logging

Expected: Should check response.ok before parsing JSON and throw a descriptive error, following the established pattern used in 38+ other API calls throughout lib/ (e.g., lib/api/artist/getArtistSocials.ts, lib/files/fetchFileContent.ts, lib/getConversations.tsx)

Fix applied: Added if (!response.ok) throw new Error() check immediately after fetch, before calling response.json(), consistent with the codebase-wide error handling pattern.

- Change from GET with query params to POST with JSON body
- Add x-api-key header for authentication
- Support optional accountId and organizationId params
- Match new API contract per docs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use Authorization: Bearer header with Privy access token
to match the pattern used in useVercelChat.ts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@lib/createArtist.tsx`:
- Around line 29-33: In createArtist (lib/createArtist.tsx) don't call
response.json() before checking response.ok; instead first check response.ok on
the fetch response and only parse JSON for successful responses (or attempt to
parse JSON for error bodies inside a safe try/catch to include API error
messages), and when response.ok is false throw an Error including status and any
parsed error message; update the code paths around response, response.json(),
and the throw to validate response.ok first and safely extract error details.
🧹 Nitpick comments (1)
lib/createArtist.tsx (1)

36-38: Silent null return may obscure errors during debugging.

Returning null on failure follows a valid pattern, but without any error propagation mechanism, callers cannot distinguish between "artist not created due to conflict" and "network failure" or "server error." This aligns with the coding guideline to remove console.log statements, but consider whether a more explicit error-handling strategy (e.g., throwing or returning a result object with error info) would improve debuggability.

💡 Alternative: Return a result object
interface CreateArtistResult {
  artist: Artist | null;
  error?: string;
}

// Then in catch block:
} catch (error) {
  return { artist: null, error: error instanceof Error ? error.message : 'Unknown error' };
}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0ef577c and 751d6d6.

📒 Files selected for processing (1)
  • lib/createArtist.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{tsx,ts,jsx,js}

📄 CodeRabbit inference engine (.cursor/rules/component-design.mdc)

**/*.{tsx,ts,jsx,js}: Use semantic HTML elements appropriate to the component's role
Ensure keyboard navigation and focus management in UI components
Provide proper ARIA roles/states and test with screen readers
Start with semantic HTML first, then augment with ARIA if needed
Support both controlled and uncontrolled state in components
Wrap a single HTML element per component (no multiple root elements)
Favor composition over inheritance in component design
Expose clear APIs via props/slots for component customization
Use asChild pattern for flexible element types in components
Support polymorphism with as prop when appropriate
Use @radix-ui/react-* primitives for behavior and accessibility
Use class-variance-authority (CVA) for component variants
Use @radix-ui/react-slot for implementing asChild pattern
Use @radix-ui/react-use-controllable-state for state management
Follow shadcn/ui component structure and naming conventions
Use cn() utility combining clsx and tailwind-merge for class merging
Export both component and variant functions (e.g., Button, buttonVariants)
Use @radix-ui/react-icons for UI component icons (not Lucide React)
Use lucide-react for application icons and illustrations
Use framer-motion for animations and transitions
Use next-themes for theme management
Use tailwindcss-animate for CSS animations
Use sonner for toast notifications
Use embla-carousel-react for carousels
Use react-resizable-panels for resizable layouts
Provide defaultValue and onValueChange props for state management
Use data-state attribute for visual component states (open/closed, loading, etc.)
Use data-slot attribute for component identification
Use kebab-case naming for data attributes (e.g., data-slot="form-field")
Follow class order in Tailwind: base → variants → conditionals → user overrides
Define component variants outside components to avoid recreation on re-render
Implement focus trapping in modal/dialog components
Store...

Files:

  • lib/createArtist.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (.cursor/rules/component-design.mdc)

**/*.{tsx,ts}: Extend native HTML attributes using React.ComponentProps<"element"> pattern
Export component prop types with explicit ComponentNameProps naming convention

Files:

  • lib/createArtist.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/stagehand.mdc)

**/*.{ts,tsx}: Plan instructions using Stagehand observe method before executing actions (e.g., const results = await page.observe("Click the sign in button");)
Cache the results of observe to avoid unexpected DOM changes
Keep act actions atomic and specific (e.g., "Click the sign in button" not "Sign in to the website"). Avoid actions that are more than one step.
Use variable substitution with the variables parameter in act for dynamic form filling (e.g., action: "Enter Name: %name%", variables: { name: "John Doe" })
Always use Zod schemas for structured data extraction with the extract method (e.g., schema: z.object({ text: z.string() }))
Wrap array extractions in a single object when extracting multiple items using extract (e.g., schema: z.object({ buttons: z.array(z.string()) }))
Use explicit instruction and schema parameters when calling extract method
Import Stagehand types from @browserbasehq/stagehand package (e.g., import { Stagehand, Page, BrowserContext } from "@browserbasehq/stagehand";)
Initialize Stagehand with new Stagehand() constructor and call await stagehand.init() before using page automation methods
Implement main automation logic in functions that accept { page, context, stagehand } parameters
Provide specific instructions to agents instead of vague ones (e.g., "Navigate to products page and filter by 'Electronics'" not "Do some stuff on this page")
Break down complex agent tasks into smaller steps for better execution
Use error handling with try/catch blocks when executing agent tasks
Combine agents for navigation with traditional methods for precise data extraction

**/*.{ts,tsx}: Create single-responsibility components with obvious data flow
Use strict TypeScript types with zero 'any' types
Follow Next.js optimization guides for performance

Files:

  • lib/createArtist.tsx
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

**/*.{ts,tsx,js}: Write minimal code - use only the absolute minimum code needed
Ensure code is self-documenting through precise naming with verbs for functions and nouns for variables
Add short comments only when necessary to clarify non-obvious logic
Implement built-in security practices for authentication and data handling
Consider if code can be split into smaller functions before implementing
Avoid unnecessary abstractions during implementation
Ensure code clarity is suitable for understanding by junior developers

Files:

  • lib/createArtist.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Use Single Responsibility Principle: One function per file with clear naming
Remove all console.log statements before merging to production
Write comments to explain 'why', not 'what'; prefer self-documenting code

Files:

  • lib/createArtist.tsx
🧬 Code graph analysis (1)
lib/createArtist.tsx (1)
lib/consts.ts (1)
  • NEW_API_BASE_URL (4-6)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Vercel Agent Review
  • GitHub Check: Run evaluations
🔇 Additional comments (3)
lib/createArtist.tsx (3)

1-8: Clean interface definition with proper TypeScript typing.

The CreateArtistParams interface follows the Single Responsibility Principle well—it clearly defines the contract for creating an artist. Required vs. optional properties are appropriately designated. Good use of strict types with no any usage.

Minor note: The file uses .tsx extension but contains no JSX. Consider renaming to .ts for clarity, though this is non-blocking.


17-28: Solid POST request implementation with proper headers and JSON body.

The migration from GET with query parameters to POST with a JSON body is cleaner and eliminates the previous URL encoding concerns. The x-api-key header for authentication and snake_case field names in the body align well with typical REST API conventions.


10-15: Parameter name mismatch in review comment:

The code snippet provided shows apiKey as a parameter, but the actual function signature uses accessToken. The object destructuring pattern is well-chosen for maintainability, but verify that the parameter documentation reflects the correct name (accessToken, not apiKey).

Likely an incorrect or invalid review comment.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +29 to +33
const data = await response.json();

if (!response.ok) {
throw new Error(data.error || "Failed to create artist");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Reorder error check: response.ok should be validated before parsing JSON.

The current implementation parses JSON before checking response.ok. If the server returns a non-JSON response on error (e.g., a 502 with an HTML error page), response.json() will throw a SyntaxError, which gets swallowed by the outer catch block. This masks the actual HTTP error and makes debugging difficult—the caller receives null with no indication of what went wrong.

🔧 Proposed fix
-    const data = await response.json();
-
     if (!response.ok) {
-      throw new Error(data.error || "Failed to create artist");
+      const errorText = await response.text();
+      throw new Error(
+        `Failed to create artist: ${response.status} ${errorText}`
+      );
     }
+
+    const data = await response.json();

     return data.artist;

Alternatively, if you want to preserve JSON error messages from the API when available:

-    const data = await response.json();
-
     if (!response.ok) {
-      throw new Error(data.error || "Failed to create artist");
+      let errorMessage = `Failed to create artist: ${response.status}`;
+      try {
+        const errorData = await response.json();
+        errorMessage = errorData.error || errorMessage;
+      } catch {
+        // Response body is not JSON, use status-based message
+      }
+      throw new Error(errorMessage);
     }
+
+    const data = await response.json();

     return data.artist;
📝 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.

Suggested change
const data = await response.json();
if (!response.ok) {
throw new Error(data.error || "Failed to create artist");
}
if (!response.ok) {
const errorText = await response.text();
throw new Error(
`Failed to create artist: ${response.status} ${errorText}`
);
}
const data = await response.json();
return data.artist;
🤖 Prompt for AI Agents
In `@lib/createArtist.tsx` around lines 29 - 33, In createArtist
(lib/createArtist.tsx) don't call response.json() before checking response.ok;
instead first check response.ok on the fetch response and only parse JSON for
successful responses (or attempt to parse JSON for error bodies inside a safe
try/catch to include API error messages), and when response.ok is false throw an
Error including status and any parsed error message; update the code paths
around response, response.json(), and the throw to validate response.ok first
and safely extract error details.

File was orphaned - not imported anywhere.
Artist creation is handled by lib/tools/createArtist.tsx (MCP tool)
and lib/supabase/createArtistInDb.ts (direct DB access).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change from GET to POST to match new API contract
- Forward request to POST /api/artists on recoup-api
- Pass through Authorization header for Privy auth
- Remove direct Supabase dependency

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Route was not called from anywhere in the codebase.
Artist creation is handled by recoup-api POST /api/artists.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tool is now provided by recoup-api MCP server.

- Remove create_new_artist from getMcpTools.ts
- Delete lib/tools/createArtist.tsx
- Delete orphaned lib/supabase/copyRoom.ts
- Move CreateArtistResult type to types/createArtistResult.ts
- Update imports in components that use the type

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extract accessToken from request headers in validateHeaders
- Pass accessToken through ChatRequestBody
- Configure MCP client with Authorization: Bearer header

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove conditional logic - accessToken is always required
- Add EVAL_ACCESS_TOKEN constant for evals
- Add SMS_ACCESS_TOKEN constant for Twilio SMS handler
- Update ChatRequestBody to require accessToken

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/chat/validateChatRequest.ts (1)

95-104: Update the 401 message to mention access token.

Line 103 still says “x-api-key header required” even when the failure is due to a missing accessToken, which is misleading for clients.

🔧 Suggested fix
       {
         status: "error",
-        message: "x-api-key header required",
+        message: "x-api-key and Authorization headers required",
       },
🤖 Fix all issues with AI agents
In `@lib/consts.ts`:
- Around line 1879-1880: The EVAL_ACCESS_TOKEN constant currently falls back to
an empty string which can silently allow unauthenticated eval runs; update the
definition of EVAL_ACCESS_TOKEN (in lib/consts.ts) to require the env var be
present and fail fast if missing—for example, read process.env.EVAL_ACCESS_TOKEN
and if it is undefined or empty throw an Error (or assert) with a clear message
referencing EVAL_ACCESS_TOKEN so startup fails loudly rather than defaulting to
"". Ensure any code that uses EVAL_ACCESS_TOKEN still imports the constant and
relies on the fail-fast behavior.

In `@lib/twilio/constants.ts`:
- Around line 6-8: The module currently masks a missing SMS_ACCESS_TOKEN by
defaulting to "", so change the constant SMS_ACCESS_TOKEN to require the
environment variable at module load and throw a clear error if
process.env.SMS_ACCESS_TOKEN is unset or empty; update the module-level
initialization (where SMS_ACCESS_TOKEN is defined) to validate and throw (with a
descriptive message) so the app fails fast rather than allowing downstream
unauthenticated calls that use SMS_ACCOUNT_ID and SMS_ROOM_ID.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 91a6488 and 2404cab.

📒 Files selected for processing (6)
  • lib/chat/setupToolsForRequest.ts
  • lib/chat/validateChatRequest.ts
  • lib/consts.ts
  • lib/evals/callChatFunctionsWithResult.ts
  • lib/twilio/constants.ts
  • lib/twilio/handleIncomingSms.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/chat/setupToolsForRequest.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{tsx,ts,jsx,js}

📄 CodeRabbit inference engine (.cursor/rules/component-design.mdc)

**/*.{tsx,ts,jsx,js}: Use semantic HTML elements appropriate to the component's role
Ensure keyboard navigation and focus management in UI components
Provide proper ARIA roles/states and test with screen readers
Start with semantic HTML first, then augment with ARIA if needed
Support both controlled and uncontrolled state in components
Wrap a single HTML element per component (no multiple root elements)
Favor composition over inheritance in component design
Expose clear APIs via props/slots for component customization
Use asChild pattern for flexible element types in components
Support polymorphism with as prop when appropriate
Use @radix-ui/react-* primitives for behavior and accessibility
Use class-variance-authority (CVA) for component variants
Use @radix-ui/react-slot for implementing asChild pattern
Use @radix-ui/react-use-controllable-state for state management
Follow shadcn/ui component structure and naming conventions
Use cn() utility combining clsx and tailwind-merge for class merging
Export both component and variant functions (e.g., Button, buttonVariants)
Use @radix-ui/react-icons for UI component icons (not Lucide React)
Use lucide-react for application icons and illustrations
Use framer-motion for animations and transitions
Use next-themes for theme management
Use tailwindcss-animate for CSS animations
Use sonner for toast notifications
Use embla-carousel-react for carousels
Use react-resizable-panels for resizable layouts
Provide defaultValue and onValueChange props for state management
Use data-state attribute for visual component states (open/closed, loading, etc.)
Use data-slot attribute for component identification
Use kebab-case naming for data attributes (e.g., data-slot="form-field")
Follow class order in Tailwind: base → variants → conditionals → user overrides
Define component variants outside components to avoid recreation on re-render
Implement focus trapping in modal/dialog components
Store...

Files:

  • lib/consts.ts
  • lib/twilio/constants.ts
  • lib/chat/validateChatRequest.ts
  • lib/evals/callChatFunctionsWithResult.ts
  • lib/twilio/handleIncomingSms.ts
**/*.{tsx,ts}

📄 CodeRabbit inference engine (.cursor/rules/component-design.mdc)

**/*.{tsx,ts}: Extend native HTML attributes using React.ComponentProps<"element"> pattern
Export component prop types with explicit ComponentNameProps naming convention

Files:

  • lib/consts.ts
  • lib/twilio/constants.ts
  • lib/chat/validateChatRequest.ts
  • lib/evals/callChatFunctionsWithResult.ts
  • lib/twilio/handleIncomingSms.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/stagehand.mdc)

**/*.{ts,tsx}: Plan instructions using Stagehand observe method before executing actions (e.g., const results = await page.observe("Click the sign in button");)
Cache the results of observe to avoid unexpected DOM changes
Keep act actions atomic and specific (e.g., "Click the sign in button" not "Sign in to the website"). Avoid actions that are more than one step.
Use variable substitution with the variables parameter in act for dynamic form filling (e.g., action: "Enter Name: %name%", variables: { name: "John Doe" })
Always use Zod schemas for structured data extraction with the extract method (e.g., schema: z.object({ text: z.string() }))
Wrap array extractions in a single object when extracting multiple items using extract (e.g., schema: z.object({ buttons: z.array(z.string()) }))
Use explicit instruction and schema parameters when calling extract method
Import Stagehand types from @browserbasehq/stagehand package (e.g., import { Stagehand, Page, BrowserContext } from "@browserbasehq/stagehand";)
Initialize Stagehand with new Stagehand() constructor and call await stagehand.init() before using page automation methods
Implement main automation logic in functions that accept { page, context, stagehand } parameters
Provide specific instructions to agents instead of vague ones (e.g., "Navigate to products page and filter by 'Electronics'" not "Do some stuff on this page")
Break down complex agent tasks into smaller steps for better execution
Use error handling with try/catch blocks when executing agent tasks
Combine agents for navigation with traditional methods for precise data extraction

**/*.{ts,tsx}: Create single-responsibility components with obvious data flow
Use strict TypeScript types with zero 'any' types
Follow Next.js optimization guides for performance

Files:

  • lib/consts.ts
  • lib/twilio/constants.ts
  • lib/chat/validateChatRequest.ts
  • lib/evals/callChatFunctionsWithResult.ts
  • lib/twilio/handleIncomingSms.ts
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

**/*.{ts,tsx,js}: Write minimal code - use only the absolute minimum code needed
Ensure code is self-documenting through precise naming with verbs for functions and nouns for variables
Add short comments only when necessary to clarify non-obvious logic
Implement built-in security practices for authentication and data handling
Consider if code can be split into smaller functions before implementing
Avoid unnecessary abstractions during implementation
Ensure code clarity is suitable for understanding by junior developers

Files:

  • lib/consts.ts
  • lib/twilio/constants.ts
  • lib/chat/validateChatRequest.ts
  • lib/evals/callChatFunctionsWithResult.ts
  • lib/twilio/handleIncomingSms.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Use Single Responsibility Principle: One function per file with clear naming
Remove all console.log statements before merging to production
Write comments to explain 'why', not 'what'; prefer self-documenting code

Files:

  • lib/consts.ts
  • lib/twilio/constants.ts
  • lib/chat/validateChatRequest.ts
  • lib/evals/callChatFunctionsWithResult.ts
  • lib/twilio/handleIncomingSms.ts
**/lib/consts.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Store shared constants in lib/consts.ts including RECOUP_FROM_EMAIL for email sender address and platform-specific configurations

Files:

  • lib/consts.ts
lib/**/*.ts

⚙️ CodeRabbit configuration file

lib/**/*.ts: For utility functions, ensure:

  • Pure functions when possible
  • Single responsibility per function
  • Proper error handling
  • Use TypeScript for type safety
  • Avoid side effects
  • Keep functions under 50 lines
  • DRY: Consolidate similar logic into shared utilities
  • KISS: Prefer simple, readable implementations over clever optimizations

Files:

  • lib/consts.ts
  • lib/twilio/constants.ts
  • lib/chat/validateChatRequest.ts
  • lib/evals/callChatFunctionsWithResult.ts
  • lib/twilio/handleIncomingSms.ts
🧠 Learnings (2)
📚 Learning: 2026-01-07T17:34:21.923Z
Learnt from: CR
Repo: Recoupable-com/Recoup-Chat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-07T17:34:21.923Z
Learning: Applies to **/lib/consts.ts : Store shared constants in `lib/consts.ts` including `RECOUP_FROM_EMAIL` for email sender address and platform-specific configurations

Applied to files:

  • lib/consts.ts
  • lib/twilio/constants.ts
📚 Learning: 2026-01-07T17:34:21.923Z
Learnt from: CR
Repo: Recoupable-com/Recoup-Chat PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-07T17:34:21.923Z
Learning: Use Vercel AI SDK (`ai` package) for AI/LLM integrations in `lib/ai/` directory

Applied to files:

  • lib/evals/callChatFunctionsWithResult.ts
🧬 Code graph analysis (2)
lib/evals/callChatFunctionsWithResult.ts (1)
lib/consts.ts (1)
  • EVAL_ACCESS_TOKEN (1880-1880)
lib/twilio/handleIncomingSms.ts (1)
lib/twilio/constants.ts (1)
  • SMS_ACCESS_TOKEN (8-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Vercel Agent Review
  • GitHub Check: Run evaluations
🔇 Additional comments (3)
lib/chat/validateChatRequest.ts (1)

42-45: Good: ChatRequestBody now enforces accessToken.

lib/evals/callChatFunctionsWithResult.ts (1)

2-2: LGTM: eval payload now includes accessToken.

Also applies to: 27-32

lib/twilio/handleIncomingSms.ts (1)

5-10: Nice: SMS chat requests now send accessToken.

Also applies to: 39-44

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines 1879 to +1880
export const EVAL_ACCOUNT_ID = "fb678396-a68f-4294-ae50-b8cacf9ce77b";
export const EVAL_ACCESS_TOKEN = process.env.EVAL_ACCESS_TOKEN || "";
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid empty-string fallback for EVAL_ACCESS_TOKEN.

Line 1880 uses || "", which can silently run evals without auth and make failures harder to diagnose. Prefer a required env check.

🔧 Suggested fix
 export const EVAL_ACCOUNT_ID = "fb678396-a68f-4294-ae50-b8cacf9ce77b";
-export const EVAL_ACCESS_TOKEN = process.env.EVAL_ACCESS_TOKEN || "";
+const evalAccessToken = process.env.EVAL_ACCESS_TOKEN;
+if (!evalAccessToken) {
+  throw new Error("EVAL_ACCESS_TOKEN is required for eval auth");
+}
+export const EVAL_ACCESS_TOKEN = evalAccessToken;
📝 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.

Suggested change
export const EVAL_ACCOUNT_ID = "fb678396-a68f-4294-ae50-b8cacf9ce77b";
export const EVAL_ACCESS_TOKEN = process.env.EVAL_ACCESS_TOKEN || "";
export const EVAL_ACCOUNT_ID = "fb678396-a68f-4294-ae50-b8cacf9ce77b";
const evalAccessToken = process.env.EVAL_ACCESS_TOKEN;
if (!evalAccessToken) {
throw new Error("EVAL_ACCESS_TOKEN is required for eval auth");
}
export const EVAL_ACCESS_TOKEN = evalAccessToken;
🤖 Prompt for AI Agents
In `@lib/consts.ts` around lines 1879 - 1880, The EVAL_ACCESS_TOKEN constant
currently falls back to an empty string which can silently allow unauthenticated
eval runs; update the definition of EVAL_ACCESS_TOKEN (in lib/consts.ts) to
require the env var be present and fail fast if missing—for example, read
process.env.EVAL_ACCESS_TOKEN and if it is undefined or empty throw an Error (or
assert) with a clear message referencing EVAL_ACCESS_TOKEN so startup fails
loudly rather than defaulting to "". Ensure any code that uses EVAL_ACCESS_TOKEN
still imports the constant and relies on the fail-fast behavior.

Comment on lines 6 to +8
export const SMS_ACCOUNT_ID = "fb678396-a68f-4294-ae50-b8cacf9ce77b";
export const SMS_ROOM_ID = "e7d76987-9654-4fa0-a641-e1b4fbd4e91d";
export const SMS_ACCESS_TOKEN = process.env.SMS_ACCESS_TOKEN || "";
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fail fast when SMS_ACCESS_TOKEN is unset.

Line 8 defaults to an empty string, which masks misconfiguration and can lead to unauthenticated downstream calls now that accessToken is required. Prefer a required env check so failures are explicit.

🔧 Suggested fix
 export const SMS_ACCOUNT_ID = "fb678396-a68f-4294-ae50-b8cacf9ce77b";
 export const SMS_ROOM_ID = "e7d76987-9654-4fa0-a641-e1b4fbd4e91d";
-export const SMS_ACCESS_TOKEN = process.env.SMS_ACCESS_TOKEN || "";
+const smsAccessToken = process.env.SMS_ACCESS_TOKEN;
+if (!smsAccessToken) {
+  throw new Error("SMS_ACCESS_TOKEN is required for SMS auth");
+}
+export const SMS_ACCESS_TOKEN = smsAccessToken;
📝 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.

Suggested change
export const SMS_ACCOUNT_ID = "fb678396-a68f-4294-ae50-b8cacf9ce77b";
export const SMS_ROOM_ID = "e7d76987-9654-4fa0-a641-e1b4fbd4e91d";
export const SMS_ACCESS_TOKEN = process.env.SMS_ACCESS_TOKEN || "";
export const SMS_ACCOUNT_ID = "fb678396-a68f-4294-ae50-b8cacf9ce77b";
export const SMS_ROOM_ID = "e7d76987-9654-4fa0-a641-e1b4fbd4e91d";
const smsAccessToken = process.env.SMS_ACCESS_TOKEN;
if (!smsAccessToken) {
throw new Error("SMS_ACCESS_TOKEN is required for SMS auth");
}
export const SMS_ACCESS_TOKEN = smsAccessToken;
🤖 Prompt for AI Agents
In `@lib/twilio/constants.ts` around lines 6 - 8, The module currently masks a
missing SMS_ACCESS_TOKEN by defaulting to "", so change the constant
SMS_ACCESS_TOKEN to require the environment variable at module load and throw a
clear error if process.env.SMS_ACCESS_TOKEN is unset or empty; update the
module-level initialization (where SMS_ACCESS_TOKEN is defined) to validate and
throw (with a descriptive message) so the app fails fast rather than allowing
downstream unauthenticated calls that use SMS_ACCOUNT_ID and SMS_ROOM_ID.

@sweetmantech sweetmantech merged commit 9a3a8e6 into main Jan 15, 2026
4 of 6 checks passed
@sweetmantech sweetmantech deleted the sweetmantech/myc-3924-recoup-chatappapiartistcreateroutets-migrate-to-recoup-api branch January 15, 2026 21:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant