-
Notifications
You must be signed in to change notification settings - Fork 846
feat(app): add chat component #7199
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
Conversation
Deploying windmill with
|
| Latest commit: |
36e2bff
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://e3348763.windmill.pages.dev |
| Branch Preview URL: | https://fg-chatcomponent.windmill.pages.dev |
06fa7c5 to
86cbe98
Compare
|
Claude finished @centdix's task —— View job Code Review Complete ✅I've completed a comprehensive review of the chat component implementation. Here's my detailed feedback: ✅ Positive Aspects1. Good Code Reuse & Refactoring
2. Well-Structured Component Design
3. Streaming Support
|
| </div> | ||
| {:else} | ||
| <div class="w-full space-y-4 xl:max-w-7xl mx-auto"> | ||
| {#each messages as message (message.timestamp)} |
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.
Critical: Non-unique key in #each block
Using message.timestamp as a key is problematic because:
- Multiple messages can have the same timestamp (especially in rapid succession)
- This violates Svelte's requirement for unique, stable keys
- Can cause incorrect DOM updates, animation issues, and component state loss
Recommendation: Add a unique id field to the Message interface:
interface Message {
id: string // Add this
role: 'user' | 'assistant'
content: string
timestamp: number
}Then use it in the loop:
{#each messages as message (message.id)}| } | ||
|
|
||
| // Auto-scroll to bottom when messages change | ||
| $effect(() => { |
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.
Performance Issue: Inefficient auto-scroll effect
This effect has several problems:
- Runs on EVERY reactive change, not just when messages change
- Uses arbitrary 50ms timeout
- No cleanup of the timeout
Better implementation:
$effect(() => {
if (messages.length > 0 && messagesContainer) {
const rafId = requestAnimationFrame(() => {
messagesContainer?.scrollTo({
top: messagesContainer.scrollHeight,
behavior: 'smooth'
})
})
return () => cancelAnimationFrame(rafId)
}
})| let accumulatedContent = $state('') | ||
|
|
||
| // Register component control for programmatic access | ||
| $componentControl[id] = { |
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.
Memory Leak: Missing cleanup for componentControl
The component registers itself in componentControl but never cleans up when destroyed. This can cause memory leaks.
Add cleanup:
import { onDestroy } from 'svelte'
$componentControl[id] = {
sendMessage: (message: string) => {
if (message && !loading) {
inputValue = message
handleSend()
}
}
}
onDestroy(() => {
delete $componentControl[id]
})| const error = e.detail.error | ||
|
|
||
| // Add error message | ||
| 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.
UX Issue: Errors shown as assistant messages
Displaying errors as regular assistant messages can be confusing for users. Consider:
- Adding an
errorfield to the Message type, or - Using a distinct message role like
'error' - Styling error messages differently (red border, warning icon, etc.)
Also be careful not to expose sensitive error details to end users.
| </script> | ||
|
|
||
| <div | ||
| class="flex items-center gap-2 rounded-lg border border-gray-200 dark:border-gray-600 bg-surface-input px-3 py-2 {customCss |
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.
Code Style: Prefer Svelte 5 class: directive
Instead of inline class concatenation, use Svelte's class: directive for cleaner code:
class="flex items-center gap-2 ... {customCss?.container?.class ?? ''}"
class="flex items-center gap-2 ..."
class={customCss?.container?.class}This applies to multiple locations in this file (lines 47, 59, 68, 79).
| ?.container?.class ?? ''}" | ||
| style={customCss?.container?.style} | ||
| > | ||
| <textarea |
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.
Accessibility: Missing ARIA label
The textarea should have an accessible label for screen readers:
<textarea
|| "Chat message input"}
bind:this={bindTextarea}
...
/>| } | ||
| if (parsed.type === 'token_delta' && parsed.content) { | ||
| content += parsed.content | ||
| } |
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.
Error Handling: Silent failure on parse errors
Parse errors are only logged to console. Consider:
- Returning parse errors so the caller can handle them
- Adding validation of the parsed structure
- Distinguishing between recoverable and fatal errors
Example:
try {
const parsed = JSON.parse(line)
if (!parsed.type) {
console.warn('Missing type in parsed line:', line)
continue
}
// ... rest of logic
} catch (e) {
// Could return error instead of just logging
console.error('Failed to parse stream line:', line, e)
}|
/updatesqlx |
|
Starting sqlx update... |
|
❌ SQLx update failed. Please check the workflow logs for details. |
|
Claude finished @centdix's task —— View job Comprehensive Code Review Complete ✅Todo List:
Executive SummaryThis PR adds a sophisticated chat component to the Windmill app platform, with both frontend (Svelte 5) and backend (Rust) changes. The implementation includes streaming support, agent memory persistence, and good code reuse through shared chat components. The previous review identified 7 important issues. My review adds 8 additional findings focusing on backend architecture, database patterns, and integration concerns not covered in the first review. Overall Assessment: Strong Implementation with Critical Issues to AddressStrengths:
Critical Issues:
Backend Review (Rust)1.
|
No description provided.