ai: gemini: files

This commit is contained in:
end-4
2025-08-21 22:53:11 +07:00
parent be1974a89e
commit 690e934a46
11 changed files with 353 additions and 47 deletions
+41 -7
View File
@@ -368,6 +368,9 @@ Singleton {
}
}
property string requestScriptFilePath: "/tmp/quickshell/ai/request.sh"
property string pendingFilePath: ""
Component.onCompleted: {
setModel(currentModelId, false, false); // Do necessary setup for model
}
@@ -617,9 +620,13 @@ Singleton {
root.tokenCount.total = -1;
}
FileView {
id: requesterScriptFile
}
Process {
id: requester
property list<string> baseCommand: ["bash", "-c"]
property list<string> baseCommand: ["bash"]
property AiMessageData message
property ApiStrategy currentStrategy
@@ -645,7 +652,7 @@ Singleton {
const endpoint = root.currentApiStrategy.buildEndpoint(model);
const messageArray = root.messageIDs.map(id => root.messageByID[id]);
const filteredMessageArray = messageArray.filter(message => message.role !== Ai.interfaceRole);
const data = root.currentApiStrategy.buildRequestData(model, filteredMessageArray, root.systemPrompt, root.temperature, root.tools[model.api_format][root.currentTool]);
const data = root.currentApiStrategy.buildRequestData(model, filteredMessageArray, root.systemPrompt, root.temperature, root.tools[model.api_format][root.currentTool], root.pendingFilePath);
// console.log("[Ai] Request data: ", JSON.stringify(data, null, 2));
let requestHeaders = {
@@ -677,14 +684,31 @@ Singleton {
/* Get authorization header from strategy */
const authHeader = requester.currentStrategy.buildAuthorizationHeader(root.apiKeyEnvVarName);
/* Script shebang */
const scriptShebang = "#!/usr/bin/env bash\n";
/* Create extra setup when there's an attached file */
let scriptFileSetupContent = ""
if (root.pendingFilePath && root.pendingFilePath.length > 0) {
requester.message.localFilePath = root.pendingFilePath;
scriptFileSetupContent = requester.currentStrategy.buildScriptFileSetup(root.pendingFilePath);
root.pendingFilePath = ""
}
/* Create command string */
const requestCommandString = `curl --no-buffer "${endpoint}"`
let scriptRequestContent = ""
scriptRequestContent += `curl --no-buffer "${endpoint}"`
+ ` ${headerString}`
+ (authHeader ? ` ${authHeader}` : "")
+ ` -d '${CF.StringUtils.shellSingleQuoteEscape(JSON.stringify(data))}'`
+ ` --data '${CF.StringUtils.shellSingleQuoteEscape(JSON.stringify(data))}'`
+ "\n"
/* Send the request */
requester.command = baseCommand.concat([requestCommandString]);
const scriptContent = requester.currentStrategy.finalizeScriptContent(scriptShebang + scriptFileSetupContent + scriptRequestContent)
const shellScriptPath = CF.FileUtils.trimFileProtocol(root.requestScriptFilePath)
requesterScriptFile.path = Qt.resolvedUrl(shellScriptPath)
requesterScriptFile.setText(scriptContent)
requester.command = baseCommand.concat([shellScriptPath]);
requester.running = true
}
@@ -698,7 +722,7 @@ Singleton {
try {
const result = requester.currentStrategy.parseResponseLine(data, requester.message);
// console.log("[Ai] Parsed response result: ", JSON.stringify(result, null, 2));
if (result.functionCall) {
requester.message.functionCall = result.functionCall;
root.handleFunctionCall(result.functionCall.name, result.functionCall.args, requester.message);
@@ -742,6 +766,10 @@ Singleton {
requester.makeRequest();
}
function attachFile(filePath: string) {
root.pendingFilePath = CF.FileUtils.trimFileProtocol(filePath);
}
function createFunctionOutputMessage(name, output, includeOutputInChat = true) {
return aiMessageComponent.createObject(root, {
"role": "user",
@@ -841,6 +869,9 @@ Singleton {
return ({
"role": message.role,
"rawContent": message.rawContent,
"fileMimeType": message.fileMimeType,
"fileUri": message.fileUri,
"localFilePath": message.localFilePath,
"model": message.model,
"thinking": false,
"done": true,
@@ -858,7 +889,7 @@ Singleton {
id: chatSaveFile
property string chatName: "chat"
path: `${Directories.aiChats}/${chatName}.json`
blockLoading: true
blockLoading: true // Prevent race conditions
}
/**
@@ -894,6 +925,9 @@ Singleton {
"role": message.role,
"rawContent": message.rawContent,
"content": message.rawContent,
"fileMimeType": message.fileMimeType,
"fileUri": message.fileUri,
"localFilePath": message.localFilePath,
"model": message.model,
"thinking": message.thinking,
"done": message.done,