-
Notifications
You must be signed in to change notification settings - Fork 127
Feature/suggestion pills #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- Add SuggestionPills component showing clickable follow-up suggestions - Update ChatSection to display suggestions above text input - Add suggestions field to Content and ParametricArtifact types - Update chat function to generate 3 short suggestions after creating artifact - Uses Claude Haiku for fast, cheap suggestion generation
- Add suggestion-generator Supabase function - ChatSection calls suggestion-generator after model is created - Base suggestions on what user asked for, not assistant response - Remove backend suggestion generation from chat function
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile OverviewGreptile SummaryThis PR adds AI-powered suggestion pills that appear after the assistant generates a 3D model, offering users contextual follow-up prompts like "Add handle" or "Add mounting holes". Key Changes:
Observations:
Confidence Score: 4/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant User
participant ChatSection
participant SuggestionPills
participant EdgeFunction as suggestion-generator
participant OpenRouter
User->>ChatSection: Send message (e.g., "create a box")
ChatSection->>EdgeFunction: POST /chat (via useSendContentMutation)
Note over ChatSection: isLoading = true, suggestions cleared
EdgeFunction-->>ChatSection: Assistant message with artifact (code)
Note over ChatSection: isLoading = false
ChatSection->>ChatSection: useEffect triggered (loading done + artifact exists)
ChatSection->>EdgeFunction: POST /suggestion-generator<br/>{userPrompt, generatedCode}
EdgeFunction->>EdgeFunction: Authenticate user via JWT
EdgeFunction->>OpenRouter: Generate 2 suggestions<br/>(claude-3.5-haiku)
OpenRouter-->>EdgeFunction: Suggestions in XML tags
EdgeFunction->>EdgeFunction: Parse <suggestion> tags
EdgeFunction-->>ChatSection: {suggestions: ["Add handle", "Add lid"]}
ChatSection->>SuggestionPills: Render pills (suggestions)
SuggestionPills-->>User: Display suggestion buttons
User->>SuggestionPills: Click "Add handle"
SuggestionPills->>ChatSection: onSelect("Add handle")
ChatSection->>EdgeFunction: POST /chat with "Add handle"
Note over ChatSection: Process repeats
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5 files reviewed, 3 comments
| Deno.serve(async (req) => { | ||
| if (req.method === 'OPTIONS') { | ||
| return new Response('ok', { headers: corsHeaders }); | ||
| } | ||
|
|
||
| if (req.method !== 'POST') { | ||
| return new Response('Method not allowed', { status: 405 }); | ||
| } | ||
|
|
||
| try { | ||
| const { userPrompt } = await req.json(); | ||
|
|
||
| if (!userPrompt) { | ||
| return new Response(JSON.stringify({ suggestions: [] }), { | ||
| headers: { ...corsHeaders, 'Content-Type': 'application/json' }, | ||
| }); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: no authentication check - unlike title-generator/index.ts which validates the user. anyone with the function URL can call this and consume API credits
Prompt To Fix With AI
This is a comment left during a code review.
Path: supabase/functions/suggestion-generator/index.ts
Line: 7:23
Comment:
**logic:** no authentication check - unlike `title-generator/index.ts` which validates the user. anyone with the function URL can call this and consume API credits
How can I resolve this? If you propose a fix, please make it concise.| useEffect(() => { | ||
| // Don't generate while loading | ||
| if (isLoading) { | ||
| setSuggestions([]); | ||
| return; | ||
| } | ||
|
|
||
| // Need a user message to base suggestions on | ||
| const userPrompt = lastUserMessage?.content?.text; | ||
| if (!userPrompt) { | ||
| setSuggestions([]); | ||
| return; | ||
| } | ||
|
|
||
| // Check if the last message is an assistant message with an artifact (model was generated) | ||
| const lastMsg = messages[messages.length - 1]; | ||
| if (lastMsg?.role !== 'assistant' || !lastMsg?.content?.artifact) { | ||
| setSuggestions([]); | ||
| return; | ||
| } | ||
|
|
||
| // Generate suggestions | ||
| const generateSuggestions = async () => { | ||
| try { | ||
| const { data, error } = await supabase.functions.invoke( | ||
| 'suggestion-generator', | ||
| { | ||
| body: { userPrompt }, | ||
| }, | ||
| ); | ||
|
|
||
| if (error) throw error; | ||
| if (data?.suggestions) { | ||
| setSuggestions(data.suggestions); | ||
| } | ||
| } catch (err) { | ||
| console.error('Failed to generate suggestions:', err); | ||
| setSuggestions([]); | ||
| } | ||
| }; | ||
|
|
||
| generateSuggestions(); | ||
| }, [isLoading, lastUserMessage, messages]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: effect triggers on every messages change, but only generates suggestions when specific conditions are met. this causes unnecessary re-evaluation
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/chat/ChatSection.tsx
Line: 81:123
Comment:
**style:** effect triggers on every `messages` change, but only generates suggestions when specific conditions are met. this causes unnecessary re-evaluation
How can I resolve this? If you propose a fix, please make it concise.| return ( | ||
| <div className="scrollbar-hide flex gap-2 overflow-x-auto pb-2 [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"> | ||
| {suggestions.map((suggestion, index) => ( | ||
| <Button |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: using array index as key can cause rendering issues if suggestions change. use the suggestion text itself as the key since suggestions are unique
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/chat/SuggestionPills.tsx
Line: 20:20
Comment:
**style:** using array index as `key` can cause rendering issues if suggestions change. use the suggestion text itself as the key since suggestions are unique
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5 files reviewed, 3 comments
| const generateSuggestions = async () => { | ||
| try { | ||
| const { data, error } = await supabase.functions.invoke( | ||
| 'suggestion-generator', | ||
| { | ||
| body: { | ||
| userPrompt, | ||
| generatedCode, | ||
| parameters, | ||
| }, | ||
| }, | ||
| ); | ||
|
|
||
| if (error) throw error; | ||
| if (data?.suggestions) { | ||
| setSuggestions(data.suggestions); | ||
| } | ||
| } catch (err) { | ||
| console.error('Failed to generate suggestions:', err); | ||
| setSuggestions([]); | ||
| } | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: no retry logic if suggestion generation fails - users won't see suggestions after a transient network error. consider persisting failure state to avoid repeated failed calls
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/chat/ChatSection.tsx
Line: 107:128
Comment:
**style:** no retry logic if suggestion generation fails - users won't see suggestions after a transient network error. consider persisting failure state to avoid repeated failed calls
How can I resolve this? If you propose a fix, please make it concise.| const paramSummary = parameters | ||
| ?.map( | ||
| (p: { name: string; value: string | number | boolean }) => | ||
| `${p.name}=${p.value}`, | ||
| ) | ||
| .join(', '); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: parameters is typed inline - consider using the Parameter type from @shared/types.ts for consistency with the rest of the codebase
Prompt To Fix With AI
This is a comment left during a code review.
Path: supabase/functions/suggestion-generator/index.ts
Line: 26:31
Comment:
**style:** `parameters` is typed inline - consider using the `Parameter` type from `@shared/types.ts` for consistency with the rest of the codebase
How can I resolve this? If you propose a fix, please make it concise.| Deno.serve(async (req) => { | ||
| if (req.method === 'OPTIONS') { | ||
| return new Response('ok', { headers: corsHeaders }); | ||
| } | ||
|
|
||
| if (req.method !== 'POST') { | ||
| return new Response('Method not allowed', { status: 405 }); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: add function registration to config.toml with verify_jwt = true per backend architecture guidelines
Prompt To Fix With AI
This is a comment left during a code review.
Path: supabase/functions/suggestion-generator/index.ts
Line: 7:14
Comment:
**style:** add function registration to `config.toml` with `verify_jwt = true` per backend architecture guidelines
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5 files reviewed, 1 comment
| const generateSuggestions = async () => { | ||
| try { | ||
| const { data, error } = await supabase.functions.invoke( | ||
| 'suggestion-generator', | ||
| { | ||
| body: { | ||
| userPrompt, | ||
| generatedCode, | ||
| }, | ||
| }, | ||
| ); | ||
|
|
||
| if (error) throw error; | ||
| if (data?.suggestions) { | ||
| setSuggestions(data.suggestions); | ||
| } | ||
| } catch (err) { | ||
| console.error('Failed to generate suggestions:', err); | ||
| setSuggestions([]); | ||
| } | ||
| }; | ||
|
|
||
| generateSuggestions(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: generateSuggestions doesn't cancel ongoing requests - if messages change rapidly while a suggestion request is pending, multiple requests fire and the last to complete wins. race conditions may show stale suggestions
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/chat/ChatSection.tsx
Line: 106:128
Comment:
**logic:** `generateSuggestions` doesn't cancel ongoing requests - if messages change rapidly while a suggestion request is pending, multiple requests fire and the last to complete wins. race conditions may show stale suggestions
How can I resolve this? If you propose a fix, please make it concise.- Add authentication to suggestion-generator (prevents unauthorized API usage) - Register suggestion-generator in config.toml with verify_jwt=true - Use suggestion text as key instead of array index in SuggestionPills - Add cancellation flag to prevent race conditions in suggestion generation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
6 files reviewed, no comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
6 files reviewed, no comments
No description provided.