forked from Shinonome/dots-hyprland
ai: load/save
This commit is contained in:
@@ -33,14 +33,16 @@ Singleton {
|
|||||||
property string wallpaperSwitchScriptPath: FileUtils.trimFileProtocol(`${Directories.scriptPath}/colors/switchwall.sh`)
|
property string wallpaperSwitchScriptPath: FileUtils.trimFileProtocol(`${Directories.scriptPath}/colors/switchwall.sh`)
|
||||||
property string defaultAiPrompts: FileUtils.trimFileProtocol(`${Directories.config}/quickshell/defaults/ai/prompts`)
|
property string defaultAiPrompts: FileUtils.trimFileProtocol(`${Directories.config}/quickshell/defaults/ai/prompts`)
|
||||||
property string userAiPrompts: FileUtils.trimFileProtocol(`${Directories.shellConfig}/ai/prompts`)
|
property string userAiPrompts: FileUtils.trimFileProtocol(`${Directories.shellConfig}/ai/prompts`)
|
||||||
|
property string aiChats: FileUtils.trimFileProtocol(`${Directories.state}/user/ai/chats`)
|
||||||
// Cleanup on init
|
// Cleanup on init
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
Quickshell.execDetached(["bash", "-c", `mkdir -p '${shellConfig}'`])
|
Quickshell.execDetached(["mkdir", "-p", `${shellConfig}`])
|
||||||
Quickshell.execDetached(["bash", "-c", `mkdir -p '${favicons}'`])
|
Quickshell.execDetached(["mkdir", "-p", `${favicons}`])
|
||||||
Quickshell.execDetached(["bash", "-c", `rm -rf '${coverArt}'; mkdir -p '${coverArt}'`])
|
Quickshell.execDetached(["bash", "-c", `rm -rf '${coverArt}'; mkdir -p '${coverArt}'`])
|
||||||
Quickshell.execDetached(["bash", "-c", `rm -rf '${booruPreviews}'; mkdir -p '${booruPreviews}'`])
|
Quickshell.execDetached(["bash", "-c", `rm -rf '${booruPreviews}'; mkdir -p '${booruPreviews}'`])
|
||||||
Quickshell.execDetached(["bash", "-c", `mkdir -p '${booruDownloads}' && mkdir -p '${booruDownloadsNsfw}'`])
|
Quickshell.execDetached(["bash", "-c", `mkdir -p '${booruDownloads}' && mkdir -p '${booruDownloadsNsfw}'`])
|
||||||
Quickshell.execDetached(["bash", "-c", `rm -rf '${latexOutput}'; mkdir -p '${latexOutput}'`])
|
Quickshell.execDetached(["bash", "-c", `rm -rf '${latexOutput}'; mkdir -p '${latexOutput}'`])
|
||||||
Quickshell.execDetached(["bash", "-c", `rm -rf '${cliphistDecode}'; mkdir -p '${cliphistDecode}'`])
|
Quickshell.execDetached(["bash", "-c", `rm -rf '${cliphistDecode}'; mkdir -p '${cliphistDecode}'`])
|
||||||
|
Quickshell.execDetached(["mkdir", "-p", `${aiChats}`])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,30 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "save",
|
||||||
|
description: qsTr("Save chat"),
|
||||||
|
execute: (args) => {
|
||||||
|
const joinedArgs = args.join(" ")
|
||||||
|
if (joinedArgs.trim().length == 0) {
|
||||||
|
Ai.addMessage(`Usage: ${root.commandPrefix}save CHAT_NAME`, Ai.interfaceRole);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Ai.saveChat(joinedArgs)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "load",
|
||||||
|
description: qsTr("Load chat"),
|
||||||
|
execute: (args) => {
|
||||||
|
const joinedArgs = args.join(" ")
|
||||||
|
if (joinedArgs.trim().length == 0) {
|
||||||
|
Ai.addMessage(`Usage: ${root.commandPrefix}load CHAT_NAME`, Ai.interfaceRole);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Ai.loadChat(joinedArgs)
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "clear",
|
name: "clear",
|
||||||
description: qsTr("Clear chat history"),
|
description: qsTr("Clear chat history"),
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ Singleton {
|
|||||||
readonly property string apiKeyEnvVarName: "API_KEY"
|
readonly property string apiKeyEnvVarName: "API_KEY"
|
||||||
property Component aiMessageComponent: AiMessageData {}
|
property Component aiMessageComponent: AiMessageData {}
|
||||||
property string systemPrompt: Config.options?.ai?.systemPrompt ?? ""
|
property string systemPrompt: Config.options?.ai?.systemPrompt ?? ""
|
||||||
property var messages: []
|
// property var messages: []
|
||||||
property var messageIDs: []
|
property var messageIDs: []
|
||||||
property var messageByID: ({})
|
property var messageByID: ({})
|
||||||
readonly property var apiKeys: KeyringStorage.keyringData?.apiKeys ?? {}
|
readonly property var apiKeys: KeyringStorage.keyringData?.apiKeys ?? {}
|
||||||
@@ -317,6 +317,7 @@ Singleton {
|
|||||||
const aiMessage = aiMessageComponent.createObject(root, {
|
const aiMessage = aiMessageComponent.createObject(root, {
|
||||||
"role": role,
|
"role": role,
|
||||||
"content": message,
|
"content": message,
|
||||||
|
"rawContent": message,
|
||||||
"thinking": false,
|
"thinking": false,
|
||||||
"done": true,
|
"done": true,
|
||||||
});
|
});
|
||||||
@@ -533,6 +534,7 @@ Singleton {
|
|||||||
"role": "assistant",
|
"role": "assistant",
|
||||||
"model": currentModelId,
|
"model": currentModelId,
|
||||||
"content": "",
|
"content": "",
|
||||||
|
"rawContent": "",
|
||||||
"thinking": true,
|
"thinking": true,
|
||||||
"done": false,
|
"done": false,
|
||||||
});
|
});
|
||||||
@@ -719,6 +721,7 @@ Singleton {
|
|||||||
const aiMessage = aiMessageComponent.createObject(root, {
|
const aiMessage = aiMessageComponent.createObject(root, {
|
||||||
"role": "user",
|
"role": "user",
|
||||||
"content": `[[ Output of ${name} ]]`,
|
"content": `[[ Output of ${name} ]]`,
|
||||||
|
"rawContent": `[[ Output of ${name} ]]`,
|
||||||
"functionName": name,
|
"functionName": name,
|
||||||
"functionResponse": output,
|
"functionResponse": output,
|
||||||
"thinking": false,
|
"thinking": false,
|
||||||
@@ -771,4 +774,75 @@ Singleton {
|
|||||||
else root.addMessage(qsTr("Unknown function call: {0}"), "assistant");
|
else root.addMessage(qsTr("Unknown function call: {0}"), "assistant");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function chatToJson() {
|
||||||
|
return root.messageIDs.map(id => {
|
||||||
|
const message = root.messageByID[id]
|
||||||
|
return ({
|
||||||
|
"role": message.role,
|
||||||
|
"rawContent": message.rawContent,
|
||||||
|
"model": message.model,
|
||||||
|
"thinking": false,
|
||||||
|
"done": true,
|
||||||
|
"annotations": message.annotations,
|
||||||
|
"annotationSources": message.annotationSources,
|
||||||
|
"functionName": message.functionName,
|
||||||
|
"functionCall": message.functionCall,
|
||||||
|
"functionResponse": message.functionResponse,
|
||||||
|
"visibleToUser": message.visibleToUser,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
FileView {
|
||||||
|
id: chatSaveFile
|
||||||
|
property string chatName: "chat"
|
||||||
|
path: `${Directories.aiChats}/${chatName}.json`
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves chat to a JSON list of message objects.
|
||||||
|
* @param chatName name of the chat
|
||||||
|
*/
|
||||||
|
function saveChat(chatName) {
|
||||||
|
chatSaveFile.chatName = chatName
|
||||||
|
const saveContent = JSON.stringify(root.chatToJson())
|
||||||
|
chatSaveFile.setText(saveContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads chat from a JSON list of message objects.
|
||||||
|
* @param chatName name of the chat
|
||||||
|
*/
|
||||||
|
function loadChat(chatName) {
|
||||||
|
try {
|
||||||
|
chatSaveFile.chatName = chatName
|
||||||
|
const saveContent = chatSaveFile.text()
|
||||||
|
console.log(saveContent)
|
||||||
|
const saveData = JSON.parse(saveContent)
|
||||||
|
root.clearMessages()
|
||||||
|
root.messageIDs = saveData.map((_, i) => {
|
||||||
|
return i
|
||||||
|
})
|
||||||
|
console.log(JSON.stringify(messageIDs))
|
||||||
|
for (let i = 0; i < saveData.length; i++) {
|
||||||
|
const message = saveData[i];
|
||||||
|
root.messageByID[i] = root.aiMessageComponent.createObject(root, {
|
||||||
|
"role": message.role,
|
||||||
|
"rawContent": message.rawContent,
|
||||||
|
"content": message.rawContent,
|
||||||
|
"model": message.model,
|
||||||
|
"thinking": message.thinking,
|
||||||
|
"done": message.done,
|
||||||
|
"annotations": message.annotations,
|
||||||
|
"annotationSources": message.annotationSources,
|
||||||
|
"functionName": message.functionName,
|
||||||
|
"functionCall": message.functionCall,
|
||||||
|
"functionResponse": message.functionResponse,
|
||||||
|
"visibleToUser": message.visibleToUser,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log("[AI] Could not load chat: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import QtQuick;
|
|||||||
QtObject {
|
QtObject {
|
||||||
property string role
|
property string role
|
||||||
property string content
|
property string content
|
||||||
|
property string rawContent
|
||||||
property string model
|
property string model
|
||||||
property bool thinking: true
|
property bool thinking: true
|
||||||
property bool done: false
|
property bool done: false
|
||||||
|
|||||||
Reference in New Issue
Block a user