forked from Shinonome/dots-hyprland
ai: cleaner message block delegate, add regen button
This commit is contained in:
@@ -105,7 +105,7 @@ Rectangle {
|
|||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 10
|
anchors.leftMargin: 10
|
||||||
anchors.rightMargin: 10
|
anchors.rightMargin: 10
|
||||||
spacing: 7
|
spacing: 12
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
@@ -177,6 +177,20 @@ Rectangle {
|
|||||||
ButtonGroup {
|
ButtonGroup {
|
||||||
spacing: 5
|
spacing: 5
|
||||||
|
|
||||||
|
AiMessageControlButton {
|
||||||
|
id: regenButton
|
||||||
|
buttonIcon: "refresh"
|
||||||
|
visible: messageData?.role === 'assistant'
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
Ai.regenerate(root.messageIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledToolTip {
|
||||||
|
text: Translation.tr("Regenerate")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AiMessageControlButton {
|
AiMessageControlButton {
|
||||||
id: copyButton
|
id: copyButton
|
||||||
buttonIcon: activated ? "inventory" : "content_copy"
|
buttonIcon: activated ? "inventory" : "content_copy"
|
||||||
@@ -254,28 +268,50 @@ Rectangle {
|
|||||||
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
Repeater {
|
Repeater {
|
||||||
model: root.messageBlocks.length
|
model: ScriptModel {
|
||||||
delegate: Loader {
|
values: Array.from({ length: root.messageBlocks.length }, (msg, i) => {
|
||||||
required property int index
|
return ({
|
||||||
property var thisBlock: root.messageBlocks[index]
|
type: root.messageBlocks[i].type
|
||||||
Layout.fillWidth: true
|
})
|
||||||
// property var segment: thisBlock
|
});
|
||||||
property var segmentContent: thisBlock.content
|
}
|
||||||
property var segmentLang: thisBlock.lang
|
|
||||||
property var messageData: root.messageData
|
|
||||||
property var editing: root.editing
|
|
||||||
property var renderMarkdown: root.renderMarkdown
|
|
||||||
property var enableMouseSelection: root.enableMouseSelection
|
|
||||||
property bool thinking: root.messageData?.thinking ?? true
|
|
||||||
property bool done: root.messageData?.done ?? false
|
|
||||||
property bool completed: thisBlock.completed ?? false
|
|
||||||
|
|
||||||
property bool forceDisableChunkSplitting: root.messageData.content.includes("```")
|
delegate: DelegateChooser {
|
||||||
|
id: messageDelegate
|
||||||
source: thisBlock.type === "code" ? "MessageCodeBlock.qml" :
|
role: "type"
|
||||||
thisBlock.type === "think" ? "MessageThinkBlock.qml" :
|
|
||||||
"MessageTextBlock.qml"
|
|
||||||
|
|
||||||
|
DelegateChoice { roleValue: "code"; MessageCodeBlock {
|
||||||
|
required property int index
|
||||||
|
property var thisBlock: root.messageBlocks[index]
|
||||||
|
editing: root.editing
|
||||||
|
renderMarkdown: root.renderMarkdown
|
||||||
|
enableMouseSelection: root.enableMouseSelection
|
||||||
|
segmentContent: thisBlock.content
|
||||||
|
segmentLang: thisBlock.lang
|
||||||
|
messageData: root.messageData
|
||||||
|
} }
|
||||||
|
DelegateChoice { roleValue: "think"; MessageThinkBlock {
|
||||||
|
required property int index
|
||||||
|
property var thisBlock: root.messageBlocks[index]
|
||||||
|
editing: root.editing
|
||||||
|
renderMarkdown: root.renderMarkdown
|
||||||
|
enableMouseSelection: root.enableMouseSelection
|
||||||
|
segmentContent: thisBlock.content
|
||||||
|
messageData: root.messageData
|
||||||
|
done: root.messageData?.done ?? false
|
||||||
|
completed: thisBlock.completed ?? false
|
||||||
|
} }
|
||||||
|
DelegateChoice { roleValue: "text"; MessageTextBlock {
|
||||||
|
required property int index
|
||||||
|
property var thisBlock: root.messageBlocks[index]
|
||||||
|
editing: root.editing
|
||||||
|
renderMarkdown: root.renderMarkdown
|
||||||
|
enableMouseSelection: root.enableMouseSelection
|
||||||
|
segmentContent: thisBlock.content
|
||||||
|
messageData: root.messageData
|
||||||
|
done: root.messageData?.done ?? false
|
||||||
|
forceDisableChunkSplitting: root.messageData.content.includes("```")
|
||||||
|
} }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,22 +13,20 @@ import org.kde.syntaxhighlighting
|
|||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
// These are needed on the parent loader
|
// These are needed on the parent loader
|
||||||
property bool editing: parent?.editing ?? false
|
property bool editing: false
|
||||||
property bool renderMarkdown: parent?.renderMarkdown ?? true
|
property bool renderMarkdown: true
|
||||||
property bool enableMouseSelection: parent?.enableMouseSelection ?? false
|
property bool enableMouseSelection: false
|
||||||
property var segmentContent: parent?.segmentContent ?? ({})
|
property var segmentContent: ({})
|
||||||
property var segmentLang: parent?.segmentLang ?? "txt"
|
property var segmentLang: "txt"
|
||||||
|
property var messageData: {}
|
||||||
property bool isCommandRequest: segmentLang === "command"
|
property bool isCommandRequest: segmentLang === "command"
|
||||||
property var displayLang: (isCommandRequest ? "bash" : segmentLang)
|
property var displayLang: (isCommandRequest ? "bash" : segmentLang)
|
||||||
property var messageData: parent?.messageData ?? {}
|
|
||||||
|
|
||||||
property real codeBlockBackgroundRounding: Appearance.rounding.small
|
property real codeBlockBackgroundRounding: Appearance.rounding.small
|
||||||
property real codeBlockHeaderPadding: 3
|
property real codeBlockHeaderPadding: 3
|
||||||
property real codeBlockComponentSpacing: 2
|
property real codeBlockComponentSpacing: 2
|
||||||
|
|
||||||
spacing: codeBlockComponentSpacing
|
spacing: codeBlockComponentSpacing
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
Rectangle { // Code background
|
Rectangle { // Code background
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|||||||
@@ -14,17 +14,17 @@ import Quickshell.Hyprland
|
|||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
// These are needed on the parent loader
|
// These are needed on the parent loader
|
||||||
property bool editing: parent?.editing ?? false
|
property bool editing: false
|
||||||
property bool renderMarkdown: parent?.renderMarkdown ?? true
|
property bool renderMarkdown: true
|
||||||
property bool enableMouseSelection: parent?.enableMouseSelection ?? false
|
property bool enableMouseSelection: false
|
||||||
property string segmentContent: parent?.segmentContent ?? ({})
|
property var segmentContent: ({})
|
||||||
property var messageData: parent?.messageData ?? {}
|
property var messageData: {}
|
||||||
property bool done: parent?.done ?? true
|
property bool done: true
|
||||||
property list<string> renderedLatexHashes: []
|
property bool forceDisableChunkSplitting: false
|
||||||
|
|
||||||
|
property list<string> renderedLatexHashes: []
|
||||||
property string renderedSegmentContent: ""
|
property string renderedSegmentContent: ""
|
||||||
property string shownText: ""
|
property string shownText: ""
|
||||||
property bool forceDisableChunkSplitting: parent?.forceDisableChunkSplitting ?? false
|
|
||||||
property bool fadeChunkSplitting: !forceDisableChunkSplitting && !editing && !/\n\|/.test(shownText) && Config.options.sidebar.ai.textFadeIn
|
property bool fadeChunkSplitting: !forceDisableChunkSplitting && !editing && !/\n\|/.test(shownText) && Config.options.sidebar.ai.textFadeIn
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ import Qt5Compat.GraphicalEffects
|
|||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
// These are needed on the parent loader
|
// These are needed on the parent loader
|
||||||
property bool editing: parent?.editing ?? false
|
property bool editing: false
|
||||||
property bool renderMarkdown: parent?.renderMarkdown ?? true
|
property bool renderMarkdown: true
|
||||||
property bool enableMouseSelection: parent?.enableMouseSelection ?? false
|
property bool enableMouseSelection: false
|
||||||
property string segmentContent: parent?.segmentContent ?? ({})
|
property var segmentContent: ({})
|
||||||
property var messageData: parent?.messageData ?? {}
|
property var messageData: {}
|
||||||
property bool done: parent?.done ?? true
|
property bool done: true
|
||||||
property bool completed: parent?.completed ?? false
|
property bool completed: false
|
||||||
|
|
||||||
property real thinkBlockBackgroundRounding: Appearance.rounding.small
|
property real thinkBlockBackgroundRounding: Appearance.rounding.small
|
||||||
property real thinkBlockHeaderPaddingVertical: 3
|
property real thinkBlockHeaderPaddingVertical: 3
|
||||||
|
|||||||
@@ -769,6 +769,18 @@ Singleton {
|
|||||||
root.pendingFilePath = CF.FileUtils.trimFileProtocol(filePath);
|
root.pendingFilePath = CF.FileUtils.trimFileProtocol(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function regenerate(messageIndex) {
|
||||||
|
if (messageIndex < 0 || messageIndex >= messageIDs.length) return;
|
||||||
|
const id = root.messageIDs[messageIndex];
|
||||||
|
const message = root.messageByID[id];
|
||||||
|
if (message.role !== "assistant") return;
|
||||||
|
// Remove all messages after this one
|
||||||
|
for (let i = root.messageIDs.length - 1; i >= messageIndex; i--) {
|
||||||
|
root.removeMessage(i);
|
||||||
|
}
|
||||||
|
requester.makeRequest();
|
||||||
|
}
|
||||||
|
|
||||||
function createFunctionOutputMessage(name, output, includeOutputInChat = true) {
|
function createFunctionOutputMessage(name, output, includeOutputInChat = true) {
|
||||||
return aiMessageComponent.createObject(root, {
|
return aiMessageComponent.createObject(root, {
|
||||||
"role": "user",
|
"role": "user",
|
||||||
|
|||||||
Reference in New Issue
Block a user