forked from Shinonome/dots-hyprland
ai use message ids to point to data
i thought it would give cleaner updates...
This commit is contained in:
@@ -18,7 +18,6 @@ Item {
|
|||||||
id: root
|
id: root
|
||||||
property var panelWindow
|
property var panelWindow
|
||||||
property var inputField: messageInputField
|
property var inputField: messageInputField
|
||||||
readonly property var messages: Ai.messages
|
|
||||||
property string commandPrefix: "/"
|
property string commandPrefix: "/"
|
||||||
property string faviconDownloadPath: FileUtils.trimFileProtocol(`${XdgDirectories.cache}/media/favicons`)
|
property string faviconDownloadPath: FileUtils.trimFileProtocol(`${XdgDirectories.cache}/media/favicons`)
|
||||||
|
|
||||||
@@ -31,7 +30,7 @@ Item {
|
|||||||
|
|
||||||
onFocusChanged: (focus) => {
|
onFocusChanged: (focus) => {
|
||||||
if (focus) {
|
if (focus) {
|
||||||
messageInputField.forceActiveFocus()
|
root.inputField.forceActiveFocus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,18 +193,22 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model: ScriptModel {
|
model: ScriptModel {
|
||||||
values: root.messages
|
values: Ai.messageIDs
|
||||||
}
|
}
|
||||||
delegate: AiMessage {
|
delegate: AiMessage {
|
||||||
|
required property var modelData
|
||||||
|
required property int index
|
||||||
messageIndex: index
|
messageIndex: index
|
||||||
messageData: modelData
|
messageData: {
|
||||||
|
Ai.messageByID[modelData]
|
||||||
|
}
|
||||||
messageInputField: root.inputField
|
messageInputField: root.inputField
|
||||||
faviconDownloadPath: root.faviconDownloadPath
|
faviconDownloadPath: root.faviconDownloadPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item { // Placeholder when list is empty
|
Item { // Placeholder when list is empty
|
||||||
opacity: root.messages.length === 0 ? 1 : 0
|
opacity: Ai.messageIDs.length === 0 ? 1 : 0
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,20 @@ Singleton {
|
|||||||
property Component aiMessageComponent: AiMessageData {}
|
property Component aiMessageComponent: AiMessageData {}
|
||||||
property string systemPrompt: ConfigOptions?.ai?.systemPrompt ?? ""
|
property string systemPrompt: ConfigOptions?.ai?.systemPrompt ?? ""
|
||||||
property var messages: []
|
property var messages: []
|
||||||
|
property var messageIDs: []
|
||||||
|
property var messageByID: ({})
|
||||||
readonly property var apiKeys: KeyringStorage.keyringData?.apiKeys ?? {}
|
readonly property var apiKeys: KeyringStorage.keyringData?.apiKeys ?? {}
|
||||||
readonly property var apiKeysLoaded: KeyringStorage.loaded
|
readonly property var apiKeysLoaded: KeyringStorage.loaded
|
||||||
|
|
||||||
|
function idForMessage(message) {
|
||||||
|
// Generate a unique ID using timestamp and random value
|
||||||
|
return Date.now().toString(36) + Math.random().toString(36).substr(2, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
function safeModelName(modelName) {
|
||||||
|
return modelName.replace(/:/g, "_").replace(/\./g, "_")
|
||||||
|
}
|
||||||
|
|
||||||
// Model properties:
|
// Model properties:
|
||||||
// - name: Name of the model
|
// - name: Name of the model
|
||||||
// - icon: Icon name of the model
|
// - icon: Icon name of the model
|
||||||
@@ -115,7 +126,8 @@ Singleton {
|
|||||||
const dataJson = JSON.parse(data);
|
const dataJson = JSON.parse(data);
|
||||||
root.modelList = [...root.modelList, ...dataJson];
|
root.modelList = [...root.modelList, ...dataJson];
|
||||||
dataJson.forEach(model => {
|
dataJson.forEach(model => {
|
||||||
root.models[model] = {
|
const safeModelName = root.safeModelName(model);
|
||||||
|
root.models[safeModelName] = {
|
||||||
"name": guessModelName(model),
|
"name": guessModelName(model),
|
||||||
"icon": guessModelLogo(model),
|
"icon": guessModelLogo(model),
|
||||||
"description": StringUtils.format(qsTr("Local Ollama model | {0}"), model),
|
"description": StringUtils.format(qsTr("Local Ollama model | {0}"), model),
|
||||||
@@ -142,13 +154,17 @@ Singleton {
|
|||||||
"thinking": false,
|
"thinking": false,
|
||||||
"done": true,
|
"done": true,
|
||||||
});
|
});
|
||||||
root.messages = [...root.messages, aiMessage];
|
const id = idForMessage(aiMessage);
|
||||||
|
root.messageIDs = [...root.messageIDs, id];
|
||||||
|
root.messageByID[id] = aiMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeMessage(index) {
|
function removeMessage(index) {
|
||||||
if (index < 0 || index >= messages.length) return;
|
if (index < 0 || index >= messageIDs.length) return;
|
||||||
root.messages.splice(index, 1);
|
const id = root.messageIDs[index];
|
||||||
root.messages = [...root.messages];
|
root.messageIDs.splice(index, 1);
|
||||||
|
root.messageIDs = [...root.messageIDs];
|
||||||
|
delete root.messageByID[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
function addApiKeyAdvice(model) {
|
function addApiKeyAdvice(model) {
|
||||||
@@ -160,6 +176,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getModel() {
|
function getModel() {
|
||||||
|
console.log("MODEL:", currentModelId);
|
||||||
return models[currentModelId];
|
return models[currentModelId];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +230,8 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function clearMessages() {
|
function clearMessages() {
|
||||||
messages = [];
|
root.messageIDs = [];
|
||||||
|
root.messageByID = ({});
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
@@ -275,7 +293,8 @@ Singleton {
|
|||||||
|
|
||||||
/* Build endpoint, request data */
|
/* Build endpoint, request data */
|
||||||
const endpoint = (apiFormat === "gemini") ? buildGeminiEndpoint(model) : buildOpenAIEndpoint(model);
|
const endpoint = (apiFormat === "gemini") ? buildGeminiEndpoint(model) : buildOpenAIEndpoint(model);
|
||||||
const data = (apiFormat === "gemini") ? buildGeminiRequestData(model, root.messages) : buildOpenAIRequestData(model, root.messages);
|
const messageArray = root.messageIDs.map(id => root.messageByID[id]);
|
||||||
|
const data = (apiFormat === "gemini") ? buildGeminiRequestData(model, messageArray) : buildOpenAIRequestData(model, messageArray);
|
||||||
|
|
||||||
let requestHeaders = {
|
let requestHeaders = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -289,7 +308,9 @@ Singleton {
|
|||||||
"thinking": true,
|
"thinking": true,
|
||||||
"done": false,
|
"done": false,
|
||||||
});
|
});
|
||||||
root.messages = [...root.messages, requester.message];
|
const id = idForMessage(requester.message);
|
||||||
|
root.messageIDs = [...root.messageIDs, id];
|
||||||
|
root.messageByID[id] = requester.message;
|
||||||
|
|
||||||
/* Build header string for curl */
|
/* Build header string for curl */
|
||||||
let headerString = Object.entries(requestHeaders)
|
let headerString = Object.entries(requestHeaders)
|
||||||
@@ -447,15 +468,7 @@ Singleton {
|
|||||||
|
|
||||||
function sendUserMessage(message) {
|
function sendUserMessage(message) {
|
||||||
if (message.length === 0) return;
|
if (message.length === 0) return;
|
||||||
|
root.addMessage(message, "user");
|
||||||
const userMessage = aiMessageComponent.createObject(root, {
|
|
||||||
"role": "user",
|
|
||||||
"content": message,
|
|
||||||
"thinking": false,
|
|
||||||
"done": true,
|
|
||||||
});
|
|
||||||
root.messages = [...root.messages, userMessage];
|
|
||||||
|
|
||||||
requester.makeRequest();
|
requester.makeRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user