feat(chat): in-app platform instructor assistant - #163
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
🚧 Files skipped from review as they are similar to previous changes (5)
📝 WalkthroughWalkthroughAdds an authenticated ChangesInstructor assistant chat
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install timed out. The project may have too many dependencies for the sandbox. 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.
Actionable comments posted: 3
🧹 Nitpick comments (2)
apps/api/src/chat/chat.controller.ts (1)
20-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider returning 200 OK instead of 201 Created.
By default, NestJS
@Post()handlers return201 Created. Since this endpoint generates a conversational completion without persisting a new RESTful resource, returning200 OKis semantically more appropriate and aligns with common AI API conventions.♻️ Proposed refactor
- `@Post`() + `@Post`() + `@HttpCode`(200) chat((You will also need to import
HttpCodefrom@nestjs/common)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/api/src/chat/chat.controller.ts` around lines 20 - 24, Update the chat method in the controller to explicitly return HTTP 200 OK by applying NestJS’s HttpCode decorator and importing HttpCode from `@nestjs/common`. Keep the existing POST route, validation pipe, parameters, and response type unchanged.apps/api/src/chat/chat.service.ts (1)
104-111: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winAdd an explicit timeout to the Anthropic API call.
Since this is a synchronous endpoint and LLM generation can occasionally hang or be heavily delayed under load, a slow response might silently exceed your upstream load balancer or frontend's API timeout limit (which are often set between 10 to 60 seconds). This results in an opaque 504 error for the end-user.
Setting a reasonable explicit timeout on the SDK request ensures you can catch the timeout internally and gracefully return your
ServiceUnavailableExceptionfallback.♻️ Proposed refactor
const response = await this.client.messages.create({ model: CHAT_MODEL, max_tokens: CHAT_MAX_TOKENS, system, messages: conversation, tools: toolDefs.length > 0 ? toolDefs : undefined, - }); + }, { timeout: 15000 }); // Adjust threshold as needed🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/api/src/chat/chat.service.ts` around lines 104 - 111, Update the Anthropic request in the chat iteration loop around client.messages.create to pass an explicit SDK timeout appropriate for the synchronous endpoint. Ensure timeout errors flow through the existing error handling so the ServiceUnavailableException fallback is returned rather than allowing the request to hang.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/web/components/chat/chat-widget.tsx`:
- Around line 83-99: Update the chat widget’s dismissal flow around the
open-state useEffect to keep a ref for the launcher and focus that element after
Escape, outside-pointer dismissal, and close-button dismissal. Attach the ref to
the launcher, and reuse a single close handler so every path sets open false and
restores launcher focus after the panel becomes hidden.
In `@apps/web/hooks/use-chat.ts`:
- Around line 41-46: Update the error path in the chat submission flow around
the catch block to remove or mark the failed optimistic user message so it is
not treated as a completed conversation turn or resent on the next submission.
Preserve the unsent draft for retry, and ensure manual retries do not append a
duplicate user message; use the existing messages state and submission symbols.
In `@turbo.json`:
- Around line 14-16: Remove ANTHROPIC_API_KEY from the shared environment
variable list in turbo.json, while preserving it in the API package or
task-specific environment configuration so only API tasks receive the secret.
---
Nitpick comments:
In `@apps/api/src/chat/chat.controller.ts`:
- Around line 20-24: Update the chat method in the controller to explicitly
return HTTP 200 OK by applying NestJS’s HttpCode decorator and importing
HttpCode from `@nestjs/common`. Keep the existing POST route, validation pipe,
parameters, and response type unchanged.
In `@apps/api/src/chat/chat.service.ts`:
- Around line 104-111: Update the Anthropic request in the chat iteration loop
around client.messages.create to pass an explicit SDK timeout appropriate for
the synchronous endpoint. Ensure timeout errors flow through the existing error
handling so the ServiceUnavailableException fallback is returned rather than
allowing the request to hang.
🪄 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 Plus
Run ID: 0417b98e-0b5e-4239-ac1b-a4f83c3b33cc
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (18)
apps/api/.env.exampleapps/api/package.jsonapps/api/src/app.module.tsapps/api/src/chat/chat.constants.tsapps/api/src/chat/chat.controller.tsapps/api/src/chat/chat.module.tsapps/api/src/chat/chat.service.tsapps/api/src/stats/stats.module.tsapps/web/app/(authenticated)/layout.tsxapps/web/components/chat/chat-widget.tsxapps/web/components/chat/markdown.tsxapps/web/hooks/use-chat.tsapps/web/package.jsonpackages/contracts/src/chat/chat.request.tspackages/contracts/src/chat/chat.response.tspackages/contracts/src/chat/index.tspackages/contracts/src/index.tsturbo.json
Summary
Adds an in-app instructor assistant — a floating chatbot that helps the
logged-in user understand and use MedFind. It explains pages, features, roles,
and statuses, walks through tasks, and answers questions about the user's own
data using live, tenant-scoped tools. It stays in scope and never invents numbers.
What's included
Contracts (
@repo/contracts)chatrequest/response schemas shared by API and web.API (
apps/api/src/chat)POST /chat(auth-guarded,@CurrentUser) running an Anthropic tool-use loopon
claude-sonnet-5(overridable viaANTHROPIC_MODEL).StatsService(platform / pharmacy / branch).Web (
apps/web)ChatWidget+useChathook, mounted in the authenticated layout.click-outside + Escape dismiss, and scroll-to-start-of-reply for long answers.
Tenant safety
Every data tool derives the tenant from the session user, never from model
input, and tools are filtered by role before the model sees them — mirroring
the authorization the existing stats endpoints already enforce. The assistant
cannot request or reveal another organization's data.
Configuration
ANTHROPIC_API_KEYinapps/api/.env(see.env.example). Without it,POST /chatreturns a clean 503 and the widget shows an "unavailable" toast —nothing else breaks.
ANTHROPIC_*vars are declared inturbo.json.Notes
no data tool; their starter prompts are how-to/concept only, so the bot never
reaches for a number it can't fetch.
Summary by CodeRabbit