import QtQuick ApiStrategy { property bool isReasoning: false function buildEndpoint(model: AiModel): string { // console.log("[AI] Endpoint: " + model.endpoint); return model.endpoint; } function buildRequestData(model: AiModel, messages, systemPrompt: string, temperature: real, tools: list) { let baseData = { "model": model.model, "messages": [ {role: "system", content: systemPrompt}, ...messages.map(message => { return { "role": message.role, "content": message.rawContent, } }), ], "stream": true, "temperature": temperature, }; return model.extraParams ? Object.assign({}, baseData, model.extraParams) : baseData; } function buildAuthorizationHeader(apiKeyEnvVarName: string): string { return `-H "Authorization: Bearer \$\{${apiKeyEnvVarName}\}"`; } function parseResponseLine(line, message) { // Remove 'data: ' prefix if present and trim whitespace let cleanData = line.trim(); if (cleanData.startsWith("data:")) { cleanData = cleanData.slice(5).trim(); } // Handle special cases if (!cleanData || cleanData.startsWith(":")) return {}; if (cleanData === "[DONE]") { return { finished: true }; } // Real stuff try { const dataJson = JSON.parse(cleanData); let newContent = ""; const responseContent = dataJson.choices[0]?.delta?.content || dataJson.message?.content; const responseReasoning = dataJson.choices[0]?.delta?.reasoning || dataJson.choices[0]?.delta?.reasoning_content; if (responseContent && responseContent.length > 0) { if (isReasoning) { isReasoning = false; const endBlock = "\n\n\n\n"; message.content += endBlock; message.rawContent += endBlock; } newContent = responseContent; } else if (responseReasoning && responseReasoning.length > 0) { if (!isReasoning) { isReasoning = true; const startBlock = "\n\n\n\n"; message.rawContent += startBlock; message.content += startBlock; } newContent = responseReasoning; } message.content += newContent; message.rawContent += newContent; if (dataJson.done) { return { finished: true }; } } catch (e) { console.log("[AI] OpenAI: Could not parse line: ", e); message.rawContent += line; message.content += line; } return {}; } function onRequestFinished(message) { // OpenAI format doesn't need special finish handling return {}; } function reset() { isReasoning = false; } }