Merged
Conversation
Contributor
Reviewer's Guide重构了提示词编辑器的流式行为和布局:Lexical 编辑器现在支持通过受节流控制的文本追加、可控滚动行为以及高度类名属性来进行更新;提示词视图将聊天记录委托给新的可复用 带节流编辑器更新的流式提示词处理顺序图sequenceDiagram
actor User
participant Prompt as PromptComponent
participant SSE as ServerStream
participant Form as AntForm
participant Editor as EditorRef
participant Chat as PromptChatPanelRef
User->>Prompt: clickSend()
Prompt->>Form: validateFields()
Form-->>Prompt: values.message
Prompt->>Chat: append({ role: user, content: message })
Prompt->>Form: setFieldsValue(message undefined, current_prompt undefined)
Prompt->>SSE: startPromptSession(message)
loop streamEvents
SSE-->>Prompt: data[] (SSEMessage)
Prompt->>Prompt: handleStreamMessage(data)
alt event start
Prompt->>Prompt: currentPromptValueRef = ""
Prompt->>Prompt: isStreamingRef = true
Prompt->>Prompt: hasPrompt = true
Prompt->>Editor: clear()
else event message content
Prompt->>Prompt: currentPromptValueRef += content
alt editorRef available
Prompt->>Editor: appendText(content)
note over Editor: batches text via requestAnimationFrame
else fallback
Prompt->>Form: setFieldValue(current_prompt, currentPromptValueRef)
end
alt desc exists
Prompt->>Chat: append({ role: assistant, content: desc })
end
else event end
Prompt->>Prompt: isStreamingRef = false
Prompt->>Form: setFieldValue(current_prompt, currentPromptValueRef)
Prompt->>Prompt: setLoading(false)
end
end
User->>Editor: manual edits
Editor-->>Prompt: onChange(value)
Prompt->>Form: setFieldValue(current_prompt, value) [only if isStreamingRef is false]
Lexical 编辑器 append-text 滚动行为顺序图sequenceDiagram
participant Parent as PromptOrAiPromptModal
participant Editor as EditorContent
participant Lexical as LexicalEditor
participant Root as LexicalRoot
participant Scroll as scrollRefDiv
Parent->>Editor: appendText(text)
Editor->>Editor: pendingTextRef += text
alt firstTextInFrame
Editor->>Editor: requestAnimationFrame(callback)
else subsequentTextInFrame
Editor->>Editor: skip scheduling
end
rect rgb(230,230,230)
Editor->>Editor: animationFrame callback
Editor->>Editor: batch = pendingTextRef
Editor->>Editor: pendingTextRef = ""
Editor->>Scroll: read scrollTop into scrollTopRef
Editor->>Editor: isAppendingRef = true
Editor->>Lexical: update(fn, { tag: append-text, onUpdate })
Lexical->>Root: fn($getRoot())
Root-->>Lexical: lastChild paragraph and lastTextNode
alt lastTextNode exists
Lexical->>Root: setTextContent(lastTextNode + batch)
else noLastTextNode
Lexical->>Root: append paragraph or text node with batch
end
Lexical-->>Editor: onUpdate()
Editor->>Editor: isAppendingRef = false
end
Lexical->>Editor: registerUpdateListener({ tags })
Editor->>Scroll: onPointerDown store scrollTop when not appending
alt tags contains append-text
Editor->>Scroll: scrollTop = scrollHeight
else normalEdit
Editor->>Scroll: scrollTop = scrollTopRef
end
更新后的提示词编辑器与聊天面板组件类图classDiagram
class LexicalEditorProps {
+string value
+string placeholder
+Function onChange
+string height
+boolean disabled
}
class EditorRef {
+Function setValue(value string)
+Function appendText(text string)
+Function clear()
+Function scrollToBottom()
}
class EditorContent {
+string value
+string placeholder
+Function onChange
+string height
+boolean disabled
-HTMLDivElement scrollRef
-string pendingTextRef
-number rafRef
-boolean isAppendingRef
-number scrollTopRef
+Function appendText(text string)
+Function clear()
+Function scrollToBottom()
}
class PromptChatPanelRef {
+Function append(item ChatItem)
+Function clear()
}
class PromptChatPanel {
-ChatItem[] chatList
+Function append(item ChatItem)
+Function clear()
}
class ChatItem {
+string role
+string content
}
class Prompt {
-FormInstance form
-PromptChatPanelRef chatPanelRef
-EditorRef editorRef
-string currentPromptValueRef
-boolean isStreamingRef
-boolean hasPrompt
+Function handleSend()
+Function handleRefresh()
}
class AiPromptModal {
-FormInstance form
-PromptChatPanelRef chatPanelRef
-EditorRef editorRef
-string currentPromptValueRef
-boolean isStreamingRef
-boolean hasPrompt
+Function handleSend()
+Function handleClose()
}
EditorContent ..|> LexicalEditorProps
PromptChatPanel ..|> PromptChatPanelRef
Prompt --> PromptChatPanelRef : uses
Prompt --> EditorRef : uses
Prompt --> ChatItem : appends
AiPromptModal --> PromptChatPanelRef : uses
AiPromptModal --> EditorRef : uses
AiPromptModal --> ChatItem : appends
PromptChatPanel --> ChatItem : manages
文件级变更
Tips and commandsInteracting with Sourcery
Customizing Your Experience访问你的 dashboard 以:
Getting HelpOriginal review guide in EnglishReviewer's GuideRefactors the prompt editor streaming behavior and layout: the Lexical editor now supports throttled text appends with controlled scroll behavior and a height class prop, prompt views delegate chat history to a new reusable PromptChatPanel, and prompt text syncing to forms is disabled while streaming to avoid flicker. Sequence diagram for streaming prompt handling with throttled editor updatessequenceDiagram
actor User
participant Prompt as PromptComponent
participant SSE as ServerStream
participant Form as AntForm
participant Editor as EditorRef
participant Chat as PromptChatPanelRef
User->>Prompt: clickSend()
Prompt->>Form: validateFields()
Form-->>Prompt: values.message
Prompt->>Chat: append({ role: user, content: message })
Prompt->>Form: setFieldsValue(message undefined, current_prompt undefined)
Prompt->>SSE: startPromptSession(message)
loop streamEvents
SSE-->>Prompt: data[] (SSEMessage)
Prompt->>Prompt: handleStreamMessage(data)
alt event start
Prompt->>Prompt: currentPromptValueRef = ""
Prompt->>Prompt: isStreamingRef = true
Prompt->>Prompt: hasPrompt = true
Prompt->>Editor: clear()
else event message content
Prompt->>Prompt: currentPromptValueRef += content
alt editorRef available
Prompt->>Editor: appendText(content)
note over Editor: batches text via requestAnimationFrame
else fallback
Prompt->>Form: setFieldValue(current_prompt, currentPromptValueRef)
end
alt desc exists
Prompt->>Chat: append({ role: assistant, content: desc })
end
else event end
Prompt->>Prompt: isStreamingRef = false
Prompt->>Form: setFieldValue(current_prompt, currentPromptValueRef)
Prompt->>Prompt: setLoading(false)
end
end
User->>Editor: manual edits
Editor-->>Prompt: onChange(value)
Prompt->>Form: setFieldValue(current_prompt, value) [only if isStreamingRef is false]
Sequence diagram for Lexical editor append-text scroll behaviorsequenceDiagram
participant Parent as PromptOrAiPromptModal
participant Editor as EditorContent
participant Lexical as LexicalEditor
participant Root as LexicalRoot
participant Scroll as scrollRefDiv
Parent->>Editor: appendText(text)
Editor->>Editor: pendingTextRef += text
alt firstTextInFrame
Editor->>Editor: requestAnimationFrame(callback)
else subsequentTextInFrame
Editor->>Editor: skip scheduling
end
rect rgb(230,230,230)
Editor->>Editor: animationFrame callback
Editor->>Editor: batch = pendingTextRef
Editor->>Editor: pendingTextRef = ""
Editor->>Scroll: read scrollTop into scrollTopRef
Editor->>Editor: isAppendingRef = true
Editor->>Lexical: update(fn, { tag: append-text, onUpdate })
Lexical->>Root: fn($getRoot())
Root-->>Lexical: lastChild paragraph and lastTextNode
alt lastTextNode exists
Lexical->>Root: setTextContent(lastTextNode + batch)
else noLastTextNode
Lexical->>Root: append paragraph or text node with batch
end
Lexical-->>Editor: onUpdate()
Editor->>Editor: isAppendingRef = false
end
Lexical->>Editor: registerUpdateListener({ tags })
Editor->>Scroll: onPointerDown store scrollTop when not appending
alt tags contains append-text
Editor->>Scroll: scrollTop = scrollHeight
else normalEdit
Editor->>Scroll: scrollTop = scrollTopRef
end
Class diagram for updated prompt editor and chat panel componentsclassDiagram
class LexicalEditorProps {
+string value
+string placeholder
+Function onChange
+string height
+boolean disabled
}
class EditorRef {
+Function setValue(value string)
+Function appendText(text string)
+Function clear()
+Function scrollToBottom()
}
class EditorContent {
+string value
+string placeholder
+Function onChange
+string height
+boolean disabled
-HTMLDivElement scrollRef
-string pendingTextRef
-number rafRef
-boolean isAppendingRef
-number scrollTopRef
+Function appendText(text string)
+Function clear()
+Function scrollToBottom()
}
class PromptChatPanelRef {
+Function append(item ChatItem)
+Function clear()
}
class PromptChatPanel {
-ChatItem[] chatList
+Function append(item ChatItem)
+Function clear()
}
class ChatItem {
+string role
+string content
}
class Prompt {
-FormInstance form
-PromptChatPanelRef chatPanelRef
-EditorRef editorRef
-string currentPromptValueRef
-boolean isStreamingRef
-boolean hasPrompt
+Function handleSend()
+Function handleRefresh()
}
class AiPromptModal {
-FormInstance form
-PromptChatPanelRef chatPanelRef
-EditorRef editorRef
-string currentPromptValueRef
-boolean isStreamingRef
-boolean hasPrompt
+Function handleSend()
+Function handleClose()
}
EditorContent ..|> LexicalEditorProps
PromptChatPanel ..|> PromptChatPanelRef
Prompt --> PromptChatPanelRef : uses
Prompt --> EditorRef : uses
Prompt --> ChatItem : appends
AiPromptModal --> PromptChatPanelRef : uses
AiPromptModal --> EditorRef : uses
AiPromptModal --> ChatItem : appends
PromptChatPanel --> ChatItem : manages
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Contributor
There was a problem hiding this comment.
Hey - 我在这里给出了一些总体反馈:
- 在
EditorContent.appendText中,editor.update被传入了一个 Lexical 并不支持的onUpdate选项,因此isAppendingRef.current被设置为true后从未被重置;可以考虑在registerUpdateListener中监听到append-text标签时重置它,或者在editor.update完成后立即重置。 appendText中用于批处理的requestAnimationFrame被存储在rafRef中,但在组件卸载时从未被取消;增加一个清理 effect,在其中调用cancelAnimationFrame(rafRef.current)可以避免潜在的内存泄漏和意外的延迟更新。- 编辑器上的
height属性现在是一个类名字符串,但注释中仍然写着“height in pixels”;更新这个 prop 的说明会更清晰一些(并且可以考虑使用clsx来合并 height 类和rb:overflow-y-auto,而不是通过字符串拼接)。
给 AI Agent 的提示
Please address the comments from this code review:
## Overall Comments
- In `EditorContent.appendText`, `editor.update` is called with an `onUpdate` option that Lexical doesn’t support, so `isAppendingRef.current` is set to `true` but never reset; consider resetting it in the `registerUpdateListener` when the `append-text` tag is seen or immediately after `editor.update` resolves.
- The `requestAnimationFrame` used for batching in `appendText` is stored in `rafRef` but never canceled on unmount; adding a cleanup effect to `cancelAnimationFrame(rafRef.current)` will avoid potential leaks and unexpected late updates.
- The `height` prop on the editor is now a class name string but the comment still says 'height in pixels'; it would be clearer to update the prop description (and consider using `clsx` to merge the height class with `rb:overflow-y-auto` instead of string concatenation).帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的评审。
Original comment in English
Hey - I've left some high level feedback:
- In
EditorContent.appendText,editor.updateis called with anonUpdateoption that Lexical doesn’t support, soisAppendingRef.currentis set totruebut never reset; consider resetting it in theregisterUpdateListenerwhen theappend-texttag is seen or immediately aftereditor.updateresolves. - The
requestAnimationFrameused for batching inappendTextis stored inrafRefbut never canceled on unmount; adding a cleanup effect tocancelAnimationFrame(rafRef.current)will avoid potential leaks and unexpected late updates. - The
heightprop on the editor is now a class name string but the comment still says 'height in pixels'; it would be clearer to update the prop description (and consider usingclsxto merge the height class withrb:overflow-y-autoinstead of string concatenation).
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `EditorContent.appendText`, `editor.update` is called with an `onUpdate` option that Lexical doesn’t support, so `isAppendingRef.current` is set to `true` but never reset; consider resetting it in the `registerUpdateListener` when the `append-text` tag is seen or immediately after `editor.update` resolves.
- The `requestAnimationFrame` used for batching in `appendText` is stored in `rafRef` but never canceled on unmount; adding a cleanup effect to `cancelAnimationFrame(rafRef.current)` will avoid potential leaks and unexpected late updates.
- The `height` prop on the editor is now a class name string but the comment still says 'height in pixels'; it would be clearer to update the prop description (and consider using `clsx` to merge the height class with `rb:overflow-y-auto` instead of string concatenation).Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
由 Sourcery 总结
改进 Web 界面中提示词编辑器的流式行为和布局。
新功能:
PromptChatPanel组件,用于封装提示词会话的聊天列表状态和渲染。缺陷修复:
增强优化:
Editor组件的高度,并调整周围布局以使用基于视口的高度。PromptChatPanel组件,并简化本地状态。Original summary in English
Summary by Sourcery
Improve prompt editor streaming behavior and layout in the web UI.
New Features:
Bug Fixes:
Enhancements: