Conversation
WalkthroughThis update introduces a chat bot feature to the application, including a new chat UI with session management, streaming assistant responses, and Markdown rendering. Supporting changes include new API routes, service modules, React Query hooks, Zustand state for user info, new icons, TypeScript models, and Tailwind CSS enhancements. Several dependencies are added or updated. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ChatBotUI
participant API_Route
participant ExternalAI
User->>ChatBotUI: Opens chat, submits message or starts session
ChatBotUI->>API_Route: POST /api/chat with userId, message, session_id
API_Route->>ExternalAI: Forwards request to external AI API
ExternalAI-->>API_Route: Streams assistant response
API_Route-->>ChatBotUI: Streams response to UI
ChatBotUI-->>User: Displays streaming assistant message in chat
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (8)
apps/www/src/lib/tanstack/mutation/chat.ts (1)
7-17: Consider enhancing error handling for better user experience.The mutation hook follows React Query best practices with proper cache invalidation. However, consider providing user-facing error feedback instead of just console logging.
onError: (error) => { - console.error("onError", error); + console.error("Failed to create chat session:", error); + // Consider adding toast notification or error state management + // toast.error("Failed to create chat session. Please try again."); },apps/www/src/components/bookmarks/sidebar/index.tsx (1)
212-212: Minor CSS change noted.The removal of the
w-fullclass reduces the width of the color input. Ensure this aligns with the intended design.apps/www/src/app/api/chat/route.ts (1)
5-66: Consider adding rate limiting and request size limits.The API endpoint should have rate limiting and request size limits to prevent abuse.
Consider implementing:
- Rate limiting per user/IP
- Request body size limits
- Timeout handling for the external API call
- Logging for monitoring and debugging
apps/www/src/components/bookmarks/graph/graph-detail.tsx (1)
215-391: Consider accessibility and mobile responsiveness.While the implementation is functionally correct, consider these enhancements:
- Add ARIA labels for screen readers
- Test mobile responsiveness as fixed positioning might cause issues on smaller screens
- Consider z-index conflicts with other fixed/absolute elements
- <div className="fixed bottom-5 text-white" style={{ right: open ? "23.75rem" : "1.25rem" }}> + <div + className="fixed bottom-5 text-white z-50" + style={{ right: open ? "23.75rem" : "1.25rem" }} + role="complementary" + aria-label="Chatbot" + > <ChatBot /> </div>apps/www/src/lib/tanstack/query/chat.ts (1)
13-18: Consider making pagination configurable.The
useGetAllChatSessionshook hardcodes pagination parameters (limit: 20, offset: 0). For better reusability, consider making these configurable:-export const useGetAllChatSessions = () => { +export const useGetAllChatSessions = (params = { limit: 20, offset: 0 }) => { return useQuery({ queryKey: [CHAT.GET_ALL_CHAT_SESSIONS], - queryFn: () => getAllChatSessions({ limit: 20, offset: 0 }), + queryFn: () => getAllChatSessions(params), }); };This would enable future pagination features while maintaining backward compatibility.
apps/www/src/components/bookmarks/graph/chat-bot/index.tsx (1)
25-37: Consider keyboard navigation support.The session list lacks keyboard navigation support. For better accessibility, consider adding keyboard event handlers.
<button className={cn( "w-full max-w-52 truncate rounded-md p-1 text-start", currentSession === session.sessionId && "bg-[#e8e8e8]" )} onClick={() => setCurrentSession(session.sessionId)} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + setCurrentSession(session.sessionId); + } + }} > {session.title} </button>apps/www/src/service/chat.ts (1)
1-24: Consider adding request/response logging for debugging.For a new chat feature, consider adding logging to help with debugging and monitoring API interactions.
You could add a simple logging wrapper or use the existing API instance's interceptors to log chat-related requests. This would be valuable during the initial rollout phase.
apps/www/src/components/bookmarks/graph/chat-bot/chat.tsx (1)
66-100: Consider more specific error handling for streaming.The streaming implementation looks good. Consider adding more context to error messages to help with debugging.
} catch (error) { - console.error("JSON parsing error:", error, "line:", line); + console.error("[Chat Stream] JSON parsing error:", { + error, + line, + sessionId, + chunk: line.substring(0, 100) // Log first 100 chars for debugging + }); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (17)
apps/extension/src/pages/create-bookmark.tsx(1 hunks)apps/www/package.json(1 hunks)apps/www/src/app/api/chat/route.ts(1 hunks)apps/www/src/components/bookmarks/graph/chat-bot/chat.tsx(1 hunks)apps/www/src/components/bookmarks/graph/chat-bot/index.tsx(1 hunks)apps/www/src/components/bookmarks/graph/graph-detail.tsx(2 hunks)apps/www/src/components/bookmarks/sidebar/index.tsx(4 hunks)apps/www/src/components/common/icon.tsx(1 hunks)apps/www/src/constants/chat.ts(1 hunks)apps/www/src/hooks/use-user-info.ts(1 hunks)apps/www/src/lib/tanstack/mutation/chat.ts(1 hunks)apps/www/src/lib/tanstack/query/chat.ts(1 hunks)apps/www/src/lib/zustand/user.ts(1 hunks)apps/www/src/models/chat.ts(1 hunks)apps/www/src/models/user.ts(1 hunks)apps/www/src/service/chat.ts(1 hunks)apps/www/tailwind.config.mts(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (7)
apps/www/src/components/bookmarks/sidebar/index.tsx (1)
apps/www/src/hooks/use-user-info.ts (1)
useUserInfo(6-20)
apps/www/src/lib/tanstack/query/chat.ts (1)
apps/www/src/service/chat.ts (2)
getChatMessages(12-16)getAllChatSessions(18-23)
apps/www/src/lib/zustand/user.ts (1)
apps/www/src/models/user.ts (1)
UserInfoDTO(1-5)
apps/www/src/lib/tanstack/mutation/chat.ts (1)
apps/www/src/service/chat.ts (1)
createChatSession(6-10)
apps/www/src/components/bookmarks/graph/chat-bot/chat.tsx (4)
apps/www/src/hooks/use-user-info.ts (1)
useUserInfo(6-20)apps/www/src/lib/tanstack/query/chat.ts (1)
useGetChatMessages(5-11)apps/www/src/service/chat.ts (1)
createChatSession(6-10)apps/www/src/lib/tanstack/mutation/chat.ts (1)
useCreateChatSession(7-17)
apps/www/src/service/chat.ts (1)
apps/www/src/models/chat.ts (3)
ChatSessionDTO(1-3)ChatMessageDTO(14-27)ChatSessionListDTO(5-12)
apps/www/src/hooks/use-user-info.ts (1)
apps/www/src/lib/tanstack/query/user.ts (1)
useGetUserInfo(5-10)
🪛 Biome (1.9.4)
apps/www/src/components/bookmarks/graph/chat-bot/chat.tsx
[error] 29-29: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
🔇 Additional comments (19)
apps/www/package.json (1)
13-17: Verify dependency versions and security.The added dependencies support the chat feature's Markdown rendering capabilities. Please ensure these versions are the latest stable releases and free from known vulnerabilities.
#!/bin/bash # Check for latest versions and security advisories for the new dependencies echo "Checking @tailwindcss/typography..." npm view @tailwindcss/typography versions --json | jq -r '.[-1]' echo "Checking dompurify..." npm view dompurify versions --json | jq -r '.[-1]' echo "Checking marked..." npm view marked versions --json | jq -r '.[-1]' # Check for security advisories echo "Checking for security advisories..." npm audit --json | jq '.vulnerabilities | length'apps/www/src/constants/chat.ts (1)
1-4: LGTM! Clean implementation of query key constants.The enum provides type safety and centralizes chat-related query keys, following good naming conventions and maintainability practices.
apps/www/src/models/user.ts (1)
2-2: I’ll inspect alluserInfo.idusages and pull in the surrounding code to confirm they handle the newnumbertype correctly.#!/bin/bash echo "Inspecting all userInfo.id occurrences with context:" rg -n "userInfo\.id" -g "*.ts" -g "*.tsx" -A 2 -B 2 echo -e "\nExtracting chat.tsx around line 119 and 150:" sed -n '115,130p' apps/www/src/components/bookmarks/graph/chat-bot/chat.tsx sed -n '145,160p' apps/www/src/components/bookmarks/graph/chat-bot/chat.tsx echo -e "\nExtracting route.ts around userId handling:" sed -n '1,30p' apps/www/src/app/api/chat/route.tsapps/extension/src/pages/create-bookmark.tsx (1)
201-205: Good defensive programming practice.The conditional rendering prevents the graph from displaying when there's no relevant data (
id), which improves the user experience by avoiding empty or invalid graph states.apps/www/src/components/bookmarks/sidebar/index.tsx (1)
12-12: LGTM! Proper integration with new user state management.The changes correctly integrate with the new centralized user state management using the
useUserInfohook, maintaining consistency across the application.Also applies to: 31-31, 144-144
apps/www/src/lib/zustand/user.ts (1)
1-13: LGTM! Clean Zustand store implementation.The store follows Zustand best practices with a clear interface and focused responsibility for user state management.
apps/www/src/components/common/icon.tsx (1)
100-131: LGTM! Consistent icon implementations.The new
chatBotandsendicons follow the established pattern and interface of existing icons in the component.apps/www/src/components/bookmarks/graph/graph-detail.tsx (2)
17-17: Import statement looks correct.The ChatBot component import follows the expected relative path pattern and is properly typed.
215-219: ChatBot positioning logic is well implemented.The dynamic positioning based on the sidebar's
openstate is elegant:
- When sidebar is open: positioned at
right: 23.75rem(accounting for sidebar width)- When sidebar is closed: positioned at
right: 1.25rem(standard margin from edge)The fixed positioning ensures the chatbot remains accessible regardless of scroll position.
apps/www/tailwind.config.mts (3)
9-9: Content pattern expansion is appropriate.Expanding from just
.tsxto include.js,.ts,.jsx, and.tsxfiles ensures Tailwind processes all relevant UI package files. This is necessary for proper style generation across the component library.
38-46: Typography configuration is well-structured.The custom typography configuration properly:
- Uses theme function to access colors consistently
- Sets prose bullets and counters to gray.500 for visual consistency
- Follows Tailwind's typography plugin conventions
This supports the Markdown rendering in the chat components.
48-48: Plugin addition is correct.Adding the
@tailwindcss/typographyplugin enables enhanced typography utilities needed for the chat Markdown rendering.apps/www/src/lib/tanstack/query/chat.ts (1)
5-11: Chat messages hook implementation is solid.The
useGetChatMessageshook correctly:
- Uses sessionId in query key for proper caching per session
- Enables query only when sessionId exists (prevents unnecessary requests)
- Follows React Query best practices
apps/www/src/components/bookmarks/graph/chat-bot/index.tsx (1)
11-16: State management is appropriate.The component correctly manages:
isOpenfor toggle functionalitycurrentSessionfor active session tracking- Uses React Query hook for data fetching
apps/www/src/service/chat.ts (1)
6-10: Chat session creation function is well-typed.The
createChatSessionfunction correctly:
- Accepts a typed body parameter
- Returns properly typed promise
- Uses consistent API pattern
apps/www/src/models/chat.ts (1)
1-27: Well-structured type definitions!The interfaces are properly typed and follow TypeScript best practices. The use of
Partial<>for optional metadata fields is appropriate.apps/www/src/components/bookmarks/graph/chat-bot/chat.tsx (3)
24-36: Proper security implementation for HTML rendering.Good use of DOMPurify to sanitize the HTML output from marked. This properly mitigates XSS risks when using dangerouslySetInnerHTML.
165-275: Excellent UI implementation with good UX considerations.The component handles all states gracefully with proper loading indicators, auto-resizing textarea, and keyboard shortcuts. The conditional rendering logic is clean and easy to follow.
52-56: Add safety check for array access.The code assumes
chatHistory.resulthas at least one element when accessingchatHistory.result[0]. This could throw an error if the array is empty.Apply this fix:
- if (chatHistory?.result && chatHistory.result.length > 0 && messages.length === 0) { + if (chatHistory?.result && chatHistory.result.length > 0 && messages.length === 0) { + const firstSession = chatHistory.result[0]; + if (firstSession && firstSession.messages) { - setMessages(chatHistory.result[0].messages); + setMessages(firstSession.messages); + } }Likely an incorrect or invalid review comment.
| useEffect(() => { | ||
| if (data?.result && !isLoading && !userInfo) { | ||
| setUserInfo(data.result); | ||
| } | ||
| }, [data, isLoading]); |
There was a problem hiding this comment.
Fix missing dependencies in useEffect.
The useEffect hook is missing userInfo and setUserInfo in its dependency array, which could lead to stale closures or unexpected behavior.
useEffect(() => {
if (data?.result && !isLoading && !userInfo) {
setUserInfo(data.result);
}
- }, [data, isLoading]);
+ }, [data, isLoading, userInfo, setUserInfo]);📝 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.
| useEffect(() => { | |
| if (data?.result && !isLoading && !userInfo) { | |
| setUserInfo(data.result); | |
| } | |
| }, [data, isLoading]); | |
| useEffect(() => { | |
| if (data?.result && !isLoading && !userInfo) { | |
| setUserInfo(data.result); | |
| } | |
| }, [data, isLoading, userInfo, setUserInfo]); |
🤖 Prompt for AI Agents
In apps/www/src/hooks/use-user-info.ts around lines 10 to 14, the useEffect
hook's dependency array is missing userInfo and setUserInfo, which can cause
stale closures or unexpected behavior. Add userInfo and setUserInfo to the
dependency array to ensure the effect runs correctly when these values change.
| body: JSON.stringify({ | ||
| userId, | ||
| message, | ||
| session_id, | ||
| }), |
There was a problem hiding this comment.
Sanitize user input before forwarding.
User input should be sanitized before forwarding to external APIs to prevent injection attacks.
Consider adding input sanitization:
body: JSON.stringify({
- userId,
- message,
+ userId: String(userId).trim(),
+ message: String(message).trim().slice(0, 1000), // Limit message length
session_id,
}),📝 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.
| body: JSON.stringify({ | |
| userId, | |
| message, | |
| session_id, | |
| }), | |
| body: JSON.stringify({ | |
| userId: String(userId).trim(), | |
| message: String(message).trim().slice(0, 1000), // Limit message length | |
| session_id, | |
| }), |
🤖 Prompt for AI Agents
In apps/www/src/app/api/chat/route.ts around lines 15 to 19, the user input
fields userId, message, and session_id are directly included in the JSON payload
without sanitization. To fix this, sanitize these inputs by removing or escaping
any potentially harmful characters or scripts before including them in the
JSON.stringify call. Use a suitable sanitization method or library to clean the
inputs and ensure no injection attacks can occur when forwarding data to
external APIs.
| } catch (error: unknown) { | ||
| return NextResponse.json( | ||
| { | ||
| code: "BAD_REQUEST", | ||
| message: `Error: ${(error as Error).message}`, | ||
| data: null, | ||
| }, | ||
| { status: 400 } | ||
| ); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Avoid exposing internal error details.
The error response may expose internal implementation details that could be used maliciously.
} catch (error: unknown) {
return NextResponse.json(
{
code: "BAD_REQUEST",
- message: `Error: ${(error as Error).message}`,
+ message: "Failed to process chat request",
data: null,
},
{ status: 400 }
);
}📝 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.
| } catch (error: unknown) { | |
| return NextResponse.json( | |
| { | |
| code: "BAD_REQUEST", | |
| message: `Error: ${(error as Error).message}`, | |
| data: null, | |
| }, | |
| { status: 400 } | |
| ); | |
| } catch (error: unknown) { | |
| return NextResponse.json( | |
| { | |
| code: "BAD_REQUEST", | |
| message: "Failed to process chat request", | |
| data: null, | |
| }, | |
| { status: 400 } | |
| ); | |
| } |
🤖 Prompt for AI Agents
In apps/www/src/app/api/chat/route.ts around lines 56 to 64, the error response
currently includes the internal error message, which may expose sensitive
implementation details. Modify the catch block to return a generic error message
instead of the actual error message, such as "An unexpected error occurred,"
while keeping the status code 400. This prevents leaking internal details while
still informing the client of the failure.
| const body = await req.json(); | ||
| const { userId, message, session_id } = body; |
There was a problem hiding this comment.
Add input validation and authentication.
The API endpoint lacks input validation and authentication checks, which are critical for security.
export async function POST(req: NextRequest) {
try {
const body = await req.json();
const { userId, message, session_id } = body;
+
+ // Validate required fields
+ if (!userId || !message) {
+ return NextResponse.json(
+ { code: "BAD_REQUEST", message: "Missing required fields: userId, message", data: null },
+ { status: 400 }
+ );
+ }
+
+ // TODO: Add authentication check
+ // Verify that the requesting user has permission to use this userId📝 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 body = await req.json(); | |
| const { userId, message, session_id } = body; | |
| export async function POST(req: NextRequest) { | |
| try { | |
| const body = await req.json(); | |
| const { userId, message, session_id } = body; | |
| // Validate required fields | |
| if (!userId || !message) { | |
| return NextResponse.json( | |
| { code: "BAD_REQUEST", message: "Missing required fields: userId, message", data: null }, | |
| { status: 400 } | |
| ); | |
| } | |
| // TODO: Add authentication check | |
| // Verify that the requesting user has permission to use this userId | |
| // ...rest of your handler logic... | |
| } catch (error) { | |
| // existing error handling | |
| } | |
| } |
🤖 Prompt for AI Agents
In apps/www/src/app/api/chat/route.ts around lines 7 to 8, the code extracts
userId, message, and session_id from the request body without validating the
input or checking authentication. Add input validation to ensure these fields
are present and of the expected type, and implement authentication checks to
verify the user's identity before processing the request. Return appropriate
error responses if validation or authentication fails.
| @@ -0,0 +1,66 @@ | |||
| import { NextRequest, NextResponse } from "next/server"; | |||
|
|
|||
| const baseUrl = process.env.AI_API_URL; | |||
There was a problem hiding this comment.
🛠️ Refactor suggestion
Validate environment variable on startup.
The AI_API_URL environment variable should be validated to ensure it's properly configured.
const baseUrl = process.env.AI_API_URL;
+
+if (!baseUrl) {
+ throw new Error('AI_API_URL environment variable is required');
+}📝 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 baseUrl = process.env.AI_API_URL; | |
| const baseUrl = process.env.AI_API_URL; | |
| if (!baseUrl) { | |
| throw new Error('AI_API_URL environment variable is required'); | |
| } |
🤖 Prompt for AI Agents
In apps/www/src/app/api/chat/route.ts at line 3, the environment variable
AI_API_URL is used without validation. Add a check during application startup to
verify that AI_API_URL is defined and not empty. If the variable is missing or
invalid, throw an error or log a critical message to prevent the app from
running with a misconfiguration.
| <button | ||
| type="submit" | ||
| className="sticky bottom-0 flex w-full items-center justify-center rounded-md bg-black py-2 text-white" | ||
| onClick={() => setCurrentSession("")} | ||
| > | ||
| 새로운 대화 시작하기 | ||
| </button> |
There was a problem hiding this comment.
"새로운 대화 시작하기" button has incorrect type.
The button has type="submit" but it's not inside a form. This should be type="button" to prevent any unintended form submission behavior.
<button
- type="submit"
+ type="button"
className="sticky bottom-0 flex w-full items-center justify-center rounded-md bg-black py-2 text-white"
onClick={() => setCurrentSession("")}
>📝 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.
| <button | |
| type="submit" | |
| className="sticky bottom-0 flex w-full items-center justify-center rounded-md bg-black py-2 text-white" | |
| onClick={() => setCurrentSession("")} | |
| > | |
| 새로운 대화 시작하기 | |
| </button> | |
| <button | |
| type="button" | |
| className="sticky bottom-0 flex w-full items-center justify-center rounded-md bg-black py-2 text-white" | |
| onClick={() => setCurrentSession("")} | |
| > | |
| 새로운 대화 시작하기 | |
| </button> |
🤖 Prompt for AI Agents
In apps/www/src/components/bookmarks/graph/chat-bot/index.tsx around lines 38 to
44, the button currently has type="submit" but is not inside a form, which can
cause unintended form submissions. Change the button's type attribute from
"submit" to "button" to prevent this behavior.
| {isOpen && ( | ||
| <div className="absolute bottom-0 right-full mr-2 flex h-96 gap-5 rounded-lg bg-white p-2 text-black"> | ||
| <ul className="relative flex flex-col gap-2 overflow-y-auto"> | ||
| {chatSessions?.result.map((session) => ( | ||
| <li key={session.sessionId}> | ||
| <button | ||
| className={cn( | ||
| "w-full max-w-52 truncate rounded-md p-1 text-start", | ||
| currentSession === session.sessionId && "bg-[#e8e8e8]" | ||
| )} | ||
| onClick={() => setCurrentSession(session.sessionId)} | ||
| > | ||
| {session.title} | ||
| </button> | ||
| </li> | ||
| ))} | ||
| <button | ||
| type="submit" | ||
| className="sticky bottom-0 flex w-full items-center justify-center rounded-md bg-black py-2 text-white" | ||
| onClick={() => setCurrentSession("")} | ||
| > | ||
| 새로운 대화 시작하기 | ||
| </button> | ||
| </ul> | ||
| <Chat sessionId={currentSession} onSessionCreated={setCurrentSession} /> | ||
| </div> | ||
| )} |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add error handling and loading states.
The component doesn't handle loading or error states from the useGetAllChatSessions hook. This could lead to poor UX when the API is slow or fails.
- const { data: chatSessions } = useGetAllChatSessions();
+ const { data: chatSessions, isLoading, error } = useGetAllChatSessions();
return (
<div className="relative text-sm">
<button className="rounded-lg bg-white p-2" onClick={() => setIsOpen(!isOpen)}>
<Icon.chatBot />
</button>
{isOpen && (
<div className="absolute bottom-0 right-full mr-2 flex h-96 gap-5 rounded-lg bg-white p-2 text-black">
<ul className="relative flex flex-col gap-2 overflow-y-auto">
+ {isLoading && <li className="p-2 text-gray-500">Loading sessions...</li>}
+ {error && <li className="p-2 text-red-500">Failed to load sessions</li>}
{chatSessions?.result.map((session) => (📝 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.
| {isOpen && ( | |
| <div className="absolute bottom-0 right-full mr-2 flex h-96 gap-5 rounded-lg bg-white p-2 text-black"> | |
| <ul className="relative flex flex-col gap-2 overflow-y-auto"> | |
| {chatSessions?.result.map((session) => ( | |
| <li key={session.sessionId}> | |
| <button | |
| className={cn( | |
| "w-full max-w-52 truncate rounded-md p-1 text-start", | |
| currentSession === session.sessionId && "bg-[#e8e8e8]" | |
| )} | |
| onClick={() => setCurrentSession(session.sessionId)} | |
| > | |
| {session.title} | |
| </button> | |
| </li> | |
| ))} | |
| <button | |
| type="submit" | |
| className="sticky bottom-0 flex w-full items-center justify-center rounded-md bg-black py-2 text-white" | |
| onClick={() => setCurrentSession("")} | |
| > | |
| 새로운 대화 시작하기 | |
| </button> | |
| </ul> | |
| <Chat sessionId={currentSession} onSessionCreated={setCurrentSession} /> | |
| </div> | |
| )} | |
| // before | |
| - const { data: chatSessions } = useGetAllChatSessions(); | |
| // after | |
| const { data: chatSessions, isLoading, error } = useGetAllChatSessions(); | |
| return ( | |
| <div className="relative text-sm"> | |
| <button | |
| className="rounded-lg bg-white p-2" | |
| onClick={() => setIsOpen(!isOpen)} | |
| > | |
| <Icon.chatBot /> | |
| </button> | |
| {isOpen && ( | |
| <div className="absolute bottom-0 right-full mr-2 flex h-96 gap-5 rounded-lg bg-white p-2 text-black"> | |
| <ul className="relative flex flex-col gap-2 overflow-y-auto"> | |
| {isLoading && ( | |
| <li className="p-2 text-gray-500">Loading sessions...</li> | |
| )} | |
| {error && ( | |
| <li className="p-2 text-red-500">Failed to load sessions</li> | |
| )} | |
| {chatSessions?.result.map((session) => ( | |
| <li key={session.sessionId}> | |
| <button | |
| className={cn( | |
| "w-full max-w-52 truncate rounded-md p-1 text-start", | |
| currentSession === session.sessionId && "bg-[#e8e8e8]" | |
| )} | |
| onClick={() => setCurrentSession(session.sessionId)} | |
| > | |
| {session.title} | |
| </button> | |
| </li> | |
| ))} | |
| <button | |
| type="submit" | |
| className="sticky bottom-0 flex w-full items-center justify-center rounded-md bg-black py-2 text-white" | |
| onClick={() => setCurrentSession("")} | |
| > | |
| 새로운 대화 시작하기 | |
| </button> | |
| </ul> | |
| <Chat | |
| sessionId={currentSession} | |
| onSessionCreated={setCurrentSession} | |
| /> | |
| </div> | |
| )} | |
| </div> | |
| ); |
🤖 Prompt for AI Agents
In apps/www/src/components/bookmarks/graph/chat-bot/index.tsx around lines 22 to
48, the component currently does not handle loading or error states from the
useGetAllChatSessions hook. To fix this, add conditional rendering to display a
loading indicator while data is being fetched and an error message if the API
call fails. This involves checking the loading and error states returned by the
hook and rendering appropriate UI elements before attempting to map over
chatSessions.result.
| export const getChatMessages = async ( | ||
| sessionId: string | ||
| ): Promise<BaseResponseDTO<ChatMessageDTO[]>> => { | ||
| return api.get(`/chat/sessions/${sessionId}/messages`); | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add input validation for sessionId.
The getChatMessages function should validate the sessionId parameter to prevent API calls with invalid or empty values.
export const getChatMessages = async (
sessionId: string
): Promise<BaseResponseDTO<ChatMessageDTO[]>> => {
+ if (!sessionId || sessionId.trim() === '') {
+ throw new Error('Session ID is required');
+ }
return api.get(`/chat/sessions/${sessionId}/messages`);
};📝 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.
| export const getChatMessages = async ( | |
| sessionId: string | |
| ): Promise<BaseResponseDTO<ChatMessageDTO[]>> => { | |
| return api.get(`/chat/sessions/${sessionId}/messages`); | |
| }; | |
| export const getChatMessages = async ( | |
| sessionId: string | |
| ): Promise<BaseResponseDTO<ChatMessageDTO[]>> => { | |
| if (!sessionId || sessionId.trim() === '') { | |
| throw new Error('Session ID is required'); | |
| } | |
| return api.get(`/chat/sessions/${sessionId}/messages`); | |
| }; |
🤖 Prompt for AI Agents
In apps/www/src/service/chat.ts around lines 12 to 16, the getChatMessages
function lacks validation for the sessionId parameter. Add a check at the start
of the function to ensure sessionId is not empty or invalid (e.g., null,
undefined, or an empty string). If the validation fails, throw an error or
return a rejected promise to prevent making an API call with an invalid
sessionId.
| export const getAllChatSessions = async (params: { | ||
| limit: number; | ||
| offset: number; | ||
| }): Promise<BaseResponseDTO<ChatSessionListDTO[]>> => { | ||
| return api.get(`/chat/sessions?limit=${params.limit}&offset=${params.offset}`); | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add parameter validation for pagination.
The getAllChatSessions function should validate pagination parameters to prevent invalid API requests.
export const getAllChatSessions = async (params: {
limit: number;
offset: number;
}): Promise<BaseResponseDTO<ChatSessionListDTO[]>> => {
+ if (params.limit <= 0 || params.offset < 0) {
+ throw new Error('Invalid pagination parameters');
+ }
return api.get(`/chat/sessions?limit=${params.limit}&offset=${params.offset}`);
};📝 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.
| export const getAllChatSessions = async (params: { | |
| limit: number; | |
| offset: number; | |
| }): Promise<BaseResponseDTO<ChatSessionListDTO[]>> => { | |
| return api.get(`/chat/sessions?limit=${params.limit}&offset=${params.offset}`); | |
| }; | |
| export const getAllChatSessions = async (params: { | |
| limit: number; | |
| offset: number; | |
| }): Promise<BaseResponseDTO<ChatSessionListDTO[]>> => { | |
| if (params.limit <= 0 || params.offset < 0) { | |
| throw new Error('Invalid pagination parameters'); | |
| } | |
| return api.get(`/chat/sessions?limit=${params.limit}&offset=${params.offset}`); | |
| }; |
🤖 Prompt for AI Agents
In apps/www/src/service/chat.ts around lines 18 to 23, the getAllChatSessions
function lacks validation for the pagination parameters limit and offset. Add
checks to ensure limit and offset are valid numbers and within acceptable ranges
before making the API call. If the parameters are invalid, throw an error or
handle it appropriately to prevent sending invalid requests to the API.
🛠️ 구현한 부분
🖼️ 실행 화면(선택)
챗봇 열기 전
첫 대화 시작
세션(채팅 내역) 조회
🔥 어려웠던 부분(선택)
🔍 참고(선택)
Summary by CodeRabbit
New Features
Improvements
Bug Fixes
Chores