SOLVE-SMART Posted May 12 Posted May 12 Okay, now I need your help @argumentum. I need to understand your scenario/data which lead to a problem. I didn't test/use it (Ollama) yet. What data needs to be adjusted/escaped? 19 hours ago, argumentum said: ... ... $sRequest &= '"system": "' & $sSystem & '", ' $sPrompt = StringReplace($sPrompt, @CRLF, "\r\n") $sPrompt = StringReplace($sPrompt, @TAB, "\t") $sPrompt = StringReplace($sPrompt, '"', "\""") $sRequest &= '"prompt": "' & $sPrompt & '", ' ... ... ..it needed to escape stuff. All good __JSON_FormatString($sPrompt) is the issue as far as I understood. Am I right, that this version of the function is good in your case (for your data) ... ; before Func __JSON_FormatString(ByRef $s_String) $s_String = _ StringReplace( _ StringReplace( _ StringReplace( _ StringReplace( _ StringReplace( _ StringReplace( _ StringReplace( _ StringReplace($s_String, '\', '\\', 0, 1) _ , Chr(8), "\b", 0, 1) _ , Chr(12), "\f", 0, 1) _ , @CRLF, "\n", 0, 1) _ , @LF, "\n", 0, 1) _ , @CR, "\r", 0, 1) _ , @TAB, "\t", 0, 1) _ , '"', '\"', 0, 1) EndFunc ;==>__JSON_FormatString ... and the current version of the function not, right? ; current version Func __JSON_FormatString(ByRef $sString) Return StringLen($sString) < 50 ? _ StringTrimRight(StringRegExpReplace($sString & '\\\b\f\n\r\t\"', '(?s)(?|\\(?=.*(\\\\))|[\b](?=.*(\\b))|\f(?=.*(\\f))|\r\n(?=.*(\\n))|\n(?=.*(\\n))|\r(?=.*(\\r))|\t(?=.*(\\t))|"(?=.*(\\")))', '\1'), 15) : _ StringReplace( _ StringReplace( _ StringReplace( _ StringReplace( _ StringReplace( _ StringReplace( _ StringReplace( _ StringReplace($sString, '\', '\\', 0, 1) _ , Chr(8), "\b", 0, 1) _ , Chr(12), "\f", 0, 1) _ , @CRLF, "\n", 0, 1) _ , @LF, "\n", 0, 1) _ , @CR, "\r", 0, 1) _ , @TAB, "\t", 0, 1) _ , '"', '\"', 0, 1) EndFunc Depending on your scenario, I am sure @AspirinJunkie can help to fix that. Best regards Sven ==> AutoIt related: 🔗 GitHub, 🔗 Discord Server, 🔗 Cheat Sheet, 🔗 autoit-webdriver-boilerplate Spoiler 🌍 Au3Forums 🎲 AutoIt (en) Cheat Sheet 📊 AutoIt limits/defaults 💎 Code Katas: [...] (comming soon) 🎭 Collection of GitHub users with AutoIt projects 🐞 False-Positives 🔮 Me on GitHub 💬 Opinion about new forum sub category 📑 UDF wiki list ✂ VSCode-AutoItSnippets 📑 WebDriver FAQs 👨🏫 WebDriver Tutorial (coming soon)
argumentum Posted May 12 Posted May 12 14 minutes ago, SOLVE-SMART said: Okay, now I need your help @argumentum. I need to understand your scenario/data which lead to a problem. I didn't test/use it (Ollama) yet. What data needs to be adjusted/escaped? I wrote this: Spoiler expandcollapse popupGlobal $__g_OllamaAssistant_DefaultURL = "http://localhost:11434" Func OllamaAssistant_DefaultURL($sStr = Default) If $sStr <> Default Then $__g_OllamaAssistant_DefaultURL = $sStr Return $__g_OllamaAssistant_DefaultURL EndFunc Local $apiEndpoint = OllamaAssistant_DefaultURL() & "/api/generate" ; Define your question as JSON ;~ Local $jsonQuestion = '{ "model": "qwen2.5-coder:3b", "prompt": "What is the capital of France?' & @CRLF & 'What language is spoken there ?", "stream": false}' ; Response: {"error":"invalid character '\\r' in string literal"} Local $jsonQuestion = '{ "model": "qwen2.5-coder:3b", "prompt": "What is the capital of Spain?\r\nWhat \"language\" is spoken there ?", "stream": false}' ; it likes it Local $jsonQuestion = '{ "model": "qwen2.5-coder:3b", "role": "user", "prompt": "What is the capital of Spain?\r\nWhat \"language\" is spoken there ?", "stream": false}' ; it likes it ; Create an instance of WinHttpRequest ;~ Local $oHTTP = ObjCreate("WinHttp.WinHttpRequest") Local $oHTTP = ObjCreate("WinHttp.WinHttpRequest.5.1") ; Connect to the API endpoint and set headers $oHTTP.Open("POST", $apiEndpoint, False) $oHTTP.setRequestHeader("Content-Type", "application/json") ; Send the JSON data as POST body $oHTTP.send($jsonQuestion) ; Check for errors If @error Then MsgBox(0, "Error", "Failed to send request: " & @error) $oHTTP = 0 Exit Else ; Check for errors in HTTP response If $oHttp.Status <> 200 Then ConsoleWrite('! Error: $oHttp.Status:' & $oHttp.Status & @CRLF) ; Output the response from the API ConsoleWrite("Response: " & $oHTTP.ResponseText & @CRLF) EndIf ; Clean up $oHTTP = 0 and ollama will tells why it failed. So I added code to fix those 3 events. @ioa747 said (in not so many words) that those lines were not needed and it all took off from there. I posted in @AspirinJunkie's thread, and once his coded gets fixed, these 2 past pages can be removed. ( ...well, disregarded ) 23 minutes ago, SOLVE-SMART said: Depending on your scenario, 24 minutes ago, SOLVE-SMART said: ; current version Func __JSON_FormatString(ByRef $sString) Return StringLen($sString) < 50 ? _ StringTrimRight(StringRegExpReplace($sString & ...that byRef and return would not fly as is. Am sure he'll fix it once he sees it. SOLVE-SMART 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
ioa747 Posted May 13 Author Posted May 13 18 hours ago, argumentum said: So I added code to fix those 3 events. @ioa747 said (in not so many words) that those lines were not needed and it all took off from there. I apologize, 😔 I still didn't understand what had happened and it wasn't working for you. Then when I saw here that you started escaping control characters, I was surprised. (I still didn't understand what had happened) That's why I passed you just '__JSON_FormatString($sPrompt) ' I thought you just removed the __JSON_FormatString($sPrompt) Even after you showed me here with the scary StringRegExpReplace($sString & '\\\b\f\n\r\t\"', '(?s)(?|\\(?=.*(\\\\))|[\b](?=.*(\\b))|\f(?=.*(\\f))|\r\n(?=.*(\\n))|\n(?=.*(\\n))|\r(?=.*(\\r))|\t(?=.*(\\t))|"(?=.*(\\")))', '\1'), I thought it was your addition because something didn't work for you, or you have some old version of JSON.au3 and that's why I asked you (and which is the right one? ; Version .......: 0.10 ? ) because I checked on github what the current version is, and it was 10, which is the one I had (I didn't go and see if the function was the same, I just looked at the header) I got the full picture today when I read all the relevant posts. I concluded that, I was misusing a UDF function, which is intended for internal use only. After all this I came to the conclusion. That I need to make an internal function for escaping control characters, so that I have better control. and since my JSON parser requirements are basic, for a specific JSON format, I will also make a fake JSON parser, so that I can extract the data I need from JSON, without external additions (at least until needed) This will also help me to better understand the JSON format thanks for understanding I apologize to everyone for the upset I caused you, it was not my intention. argumentum and SOLVE-SMART 2 I know that I know nothing
SOLVE-SMART Posted May 13 Posted May 13 You are such a nice person @ioa747. In my opinion there is no apology necessary at all. There was a misunderstanding and that's it. But thanks for the clarification - no worries and thanks for your effort regarding this LLM <==> AutoIt thingy 😁 . Best regards Sven ioa747 and argumentum 2 ==> AutoIt related: 🔗 GitHub, 🔗 Discord Server, 🔗 Cheat Sheet, 🔗 autoit-webdriver-boilerplate Spoiler 🌍 Au3Forums 🎲 AutoIt (en) Cheat Sheet 📊 AutoIt limits/defaults 💎 Code Katas: [...] (comming soon) 🎭 Collection of GitHub users with AutoIt projects 🐞 False-Positives 🔮 Me on GitHub 💬 Opinion about new forum sub category 📑 UDF wiki list ✂ VSCode-AutoItSnippets 📑 WebDriver FAQs 👨🏫 WebDriver Tutorial (coming soon)
ioa747 Posted May 13 Author Posted May 13 On 5/11/2025 at 7:37 PM, ioa747 said: update to Version: 0.6 With internal JSON functions (at least until needed) argumentum 1 I know that I know nothing
ioa747 Posted May 14 Author Posted May 14 On 5/11/2025 at 7:37 PM, ioa747 said: update to Version: 0.7 basic changes: I changed the Timeouts, to WinHttp.WinHttpRequest.5.1 , because it ended unexpectedly, in larger models ; ResolveTimeout: 5 sec ; ConnectTimeout: 10 sec ; SendTimeout: 30 sec ; ReceiveTimeout: 120 sec I added an additional Unescape, because some models return it like this ; Unescape \u00XX characters $sString = StringReplace($sString, '\u003c', '<', 0, 1) $sString = StringReplace($sString, '\u003e', '>', 0, 1) I expanded Unescape to Json_EscapeString($sAssistant) Json_EscapeString($sSystem) argumentum 1 I know that I know nothing
ioa747 Posted May 22 Author Posted May 22 On 5/11/2025 at 7:37 PM, ioa747 said: update to Version: 0.8 I changed the approach, and made it as SciTE tool. This way, the selection process, and console writing, is handled internally by SciTE. To do this you need to add the following to SciTEUser.properties (Adding_utilities_to_the_SciTE_Tools_menu) #------------------------------------------------------------------------------ # 41 SciTE_AI_Assistant command.41.$(au3)="$(SciteDefaultHome)\..\AutoIt3.exe" "D:\i\Pro\.AutoIT\SciTE_AI_Assistant\SciTE_AI_Assistant.au3" command.subsystem.41.$(au3)=0 command.name.41.$(au3)=SciTE AI Assistant command.shortcut.41.*.au3=F10 command.save.before.41.$(au3)=2 # command.replace.selection.41.$(au3)=1 command.quiet.41.$(au3)=0 command.input.41.$(au3)=$(CurrentSelection) #------------------------------------------------------------------------------ #---------------------- Contex Menu ------------------------------------------- user.context.menu=\ ||\ >>> SciTE AI Assistant <<< |1141|\ ||\ Execute Selected Path|IDM_OPENSELECTED|\ #------------------------------------------------------------------------------ and make the necessary adjustments e.g. in command.41.$(au3)="$(SciteDefaultHome)\..\AutoIt3.exe" "D:\i\Pro\.AutoIT\SciTE_AI_Assistant\SciTE_AI_Assistant.au3" your path for the d:\your\location\SciTE_AI_Assistant\SciTE_AI_Assistant.au3 You may need to adjust the 41 to the first tool number available to you. in this case, change the >>> SciTE AI Assistant <<< |1141|\ as well in the Context Menu After that, select the text in the SciTE, right-click and select 'instruction' from the context menu '>>> SciTE AI Assistant <<<' argumentum 1 I know that I know nothing
argumentum Posted May 22 Posted May 22 (edited) 11 hours ago, ioa747 said: your path for the d:\your\location\SciTE_AI_Assistant\SciTE_AI_Assistant.au3 My path is where SciTE is at because this is for SciTE. So I made a folder under that path and put it there ( $(SciteDefaultHome)\SciTE_AI_Assistant\SciTE_AI_Assistant.au3 ) But am (a) forgetful, (b) lazy and (c) have VMs running SciTE everywhere. And I'll have to add the new command everywhere !. Solution ?. A script to get it done for me !. expandcollapse popupmain(0) Func main($iRemoveTheCommand = 0) Local $sPath_Scite = StringLeft(@AutoItExe, StringInStr(@AutoItExe, "\", 0, -1)) & 'SciTE' Local $iIsSciteThere = (FileGetSize($sPath_Scite & '\SciTE.exe') ? 1 : 0) ConsoleWrite('--- SciTE exists ? >' & ($iIsSciteThere ? "YES" : "NO") & '<' & @CRLF) Local $iIsScriptThere = (FileGetSize($sPath_Scite & '\SciTE_AI_Assistant\SciTE_AI_Assistant.au3') ? 1 : 0) ConsoleWrite('--- AI_Assistant script exists ? >' & ($iIsScriptThere ? "YES" : "NO") & '<' & @CRLF) If Not $iIsScriptThere Then ConsoleWriteEm('+++ Nothing to do, script is not at "' & $sPath_Scite & '\SciTE_AI_Assistant\SciTE_AI_Assistant.au3' & @CRLF) Return EndIf If Not StringInStr($CmdLineRaw, "/ErrorStdOut ") Then Local $iRet = MsgBox(262144 + 32 + 3 + 512, @ScriptName, "" & _ "Click Yes to add it" & @LF & _ "No to remove it" & @LF & _ ; in case you jusy click-click the script "Cancel to cancel it" & @LF & _ ; outside SciTE "..you have 60 seconds to decide. Tic-toc =P", 60) Switch $iRet Case 6 ; $IDYES (6) $iRemoveTheCommand = 0 Case 7 ; $IDNO (7) $iRemoveTheCommand = 1 Case Else Return EndSwitch EndIf Local $sPropertiesFilename = $sPath_Scite & "\Properties\au3.properties" Local $aProperties = FileReadToArray($sPropertiesFilename) If @error Then ConsoleWriteEm('!!! Error reading the file, bye.' & @CRLF) Return EndIf If $iRemoveTheCommand Then $sNewPropertiesFile = sciteAiAssistant_CommandSnippet_Remove($aProperties) If @error Then ConsoleWriteEm('!!! Nothing to do, the entry was not found !' & @CRLF) Return EndIf Local $hFileOpen = FileOpen($sPropertiesFilename, 2) ; $FO_OVERWRITE (2) = Write mode (erase previous contents) If $hFileOpen = -1 Then ConsoleWriteEm('!!! FAILED to open file for re-write !' & @CRLF) Return EndIf FileWrite($hFileOpen, $sNewPropertiesFile) FileClose($hFileOpen) ConsoleWriteEm('+++ Done. All good.' & @CRLF) Return EndIf Local $iLastCommand = findLastCommand($aProperties) Local $iError = @error Local $iExtended = @extended ConsoleWrite('--- LastEntryNumber , $nArrayIndex , existed >' & $iLastCommand & ' , ' & $iExtended & ' , ' & $iError & '<' & @CRLF) If $iError Then ConsoleWriteEm('+++ Nothing to do, entry already there' & @CRLF) Return EndIf $aProperties[$iExtended] &= @CRLF & sciteAiAssistant_CommandSnippet($iLastCommand + 1) If @error Then ; not gonna happen but the AI feels better with this here =D ConsoleWriteEm('+++ something went wrong, bye.' & @CRLF) Return EndIf Local $sNewPropertiesFile = "" For $n = 0 To UBound($aProperties) - 1 $sNewPropertiesFile &= $aProperties[$n] & @CRLF Next ;~ Exit ConsoleWrite($sNewPropertiesFile) Local $hFileOpen = FileOpen($sPropertiesFilename, 2) ; $FO_OVERWRITE (2) = Write mode (erase previous contents) If $hFileOpen = -1 Then ConsoleWriteEm('!!! FAILED to open file for re-write !' & @CRLF) Return EndIf FileWrite($hFileOpen, $sNewPropertiesFile) FileClose($hFileOpen) ConsoleWriteEm('+++ Done. All good.' & @CRLF) EndFunc ;==>main Func sciteAiAssistant_CommandSnippet_Remove($aProperties) Local $iError = 0, $iSkip = 0, $sRet = "" For $n = 0 To UBound($aProperties) - 1 If $iSkip = 0 And _ StringInStr($aProperties[$n], "SciTE_AI_Assistant") And _ StringInStr($aProperties[$n], "-8<-") Then ; start $iSkip = 1 $iError += 1 ContinueLoop EndIf If $iSkip = 1 And _ StringInStr($aProperties[$n], "SciTE_AI_Assistant") And _ StringInStr($aProperties[$n], "->8-") Then ; end $iSkip = 0 $iError += 1 ContinueLoop EndIf If Not $iSkip Then $sRet &= $aProperties[$n] & @CRLF Next ;~ ConsoleWrite(@CRLF & '$iError = ' & $iError & @CRLF & $sRet & @CRLF) Return SetError(($iError = 2 ? 0 : 1), 0, $sRet) EndFunc ;==>sciteAiAssistant_CommandSnippet_Remove Func findLastCommand($aProperties) Local $aTemp, $iError = 0, $iRet = -1, $iExtended = -1 For $n = 0 To UBound($aProperties) - 1 If StringInStr($aProperties[$n], "\SciTE_AI_Assistant.au3") Then $iError += 1 If Not StringInStr($aProperties[$n], "command.") = 1 Then ContinueLoop If Not StringInStr($aProperties[$n], "=") Then ContinueLoop $aTemp = StringSplit($aProperties[$n], ".$(au3)=", 1) $aTemp = StringSplit($aTemp[1], ".", 0) For $m = $aTemp[0] To 1 Step -1 If $aTemp[$m] = Int($aTemp[$m]) And $aTemp[$m] > 0 And $iRet <= $aTemp[$m] Then $iRet = Int($aTemp[$m]) $iExtended = $n ExitLoop EndIf Next Next Return SetError($iError, $iExtended, $iRet) EndFunc ;==>findLastCommand ; ( all the comments in this function aids the AI to make sense of how it work ) Func sciteAiAssistant_CommandSnippet($iCommandIndexNumber, $sFileIsAt = "$(SciteDefaultHome)\SciTE_AI_Assistant\SciTE_AI_Assistant.au3") If Int($iCommandIndexNumber) < 5 Then Return SetError(1, 0, "") Local $sRet = "" ; string to be crated andf formated to be added to a SciTE properties file $sRet &= "# ---------- SciTE_AI_Assistant ----8<---------" & @CRLF $sRet &= "# " & $iCommandIndexNumber & " SciTE_AI_Assistant" & @CRLF ; comment line entry $sRet &= "command." & $iCommandIndexNumber & ".$(au3)=""$(SciteDefaultHome)\..\AutoIt3.exe"" """ & $sFileIsAt & """" & @CRLF $sRet &= "command.subsystem." & $iCommandIndexNumber & ".$(au3)=0" & @CRLF $sRet &= "command.name." & $iCommandIndexNumber & ".$(au3)=SciTE AI Assistant" & @CRLF ; $sFileIsAt = a full filename. Can have a SciTE constant in it. $sRet &= "command.shortcut." & $iCommandIndexNumber & ".*.au3=F10" & @CRLF ; $iCommandIndexNumber = next unused integer value to use in SciTE's menu system $sRet &= "command.save.before." & $iCommandIndexNumber & ".$(au3)=2" & @CRLF $sRet &= "# command.replace.selection." & $iCommandIndexNumber & ".$(au3)=1" & @CRLF $sRet &= "command.quiet." & $iCommandIndexNumber & ".$(au3)=0" & @CRLF $sRet &= "command.input." & $iCommandIndexNumber & ".$(au3)=$(CurrentSelection)" & @CRLF $sRet &= "# ----------->8--- SciTE_AI_Assistant ---------" Return SetError(0, 0, $sRet) ; https://www.scintilla.org/SciTEDoc.html EndFunc ;==>sciteAiAssistant_CommandSnippet Func ConsoleWriteEm($sStr) If StringInStr($CmdLineRaw, "/ErrorStdOut ") Then ConsoleWrite($sStr) Else MsgBox(262144, @ScriptName, StringTrimRight($sStr, 2), 60) EndIf EndFunc ;==>ConsoleWriteEm ..close SciTE, open SciTE. and enjoy {F10} Edit: Changed the entry a bit to be able to add or remove the entry more easily. Edited May 23 by argumentum English ioa747 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
ioa747 Posted June 1 Author Posted June 1 (edited) On 5/11/2025 at 7:37 PM, ioa747 said: update to Version: 0.9 I divide the project into parts for easier management. AI_Assistant.au3 which is included in SciTE_AI_Assistant.au3, but can also be used as a standalone UDF in which I #include "StringSize.au3" ; "https://www.autoitscript.com/forum/topic/114034-stringsize-m23-bugfix-version-27-dec-23" by Melba23 - thanks for that So that it folds the console output, and is visible within its boundaries (especially when it is on the side and is slim) for more comfortable reading SciTE_AI_Assistant.au3 changed the approach (again) , and made it as SciTE tool. This way, the selection process, and console writing, is handled internally by SciTE. To do this you need to add the following to SciTEUser.properties (Adding_utilities_to_the_SciTE_Tools_menu) #------------------------------------------------------------------------------ # 41 SciTE_AI_Assistant command.41.$(au3)="$(SciteDefaultHome)\..\AutoIt3.exe" "D:\i\Pro\.AutoIT\SciTE_AI_Assistant\SciTE_AI_Assistant.au3" command.subsystem.41.$(au3)=0 command.name.41.$(au3)=SciTE AI Assistant command.shortcut.41.*.au3=F10 command.save.before.41.$(au3)=2 # command.replace.selection.41.$(au3)=1 # command.quiet.41.$(au3)=0 # command.input.41.$(au3)=$(CurrentSelection) #------------------------------------------------------------------------------ #---------------------- Contex Menu ------------------------------------------- user.context.menu=\ ||\ >>> SciTE AI Assistant <<< |1141|\ ||\ Execute Selected Path|IDM_OPENSELECTED|\ #------------------------------------------------------------------------------ and make the necessary adjustments e.g. in command.41.$(au3)="$(SciteDefaultHome)\..\AutoIt3.exe" "D:\i\Pro\.AutoIT\SciTE_AI_Assistant\SciTE_AI_Assistant.au3" your path for the d:\your\location\SciTE_AI_Assistant\SciTE_AI_Assistant.au3 You may need to adjust the 41 to the first tool number available to you. in this case, change the >>> SciTE AI Assistant <<< |1141|\ as well in the Context Menu I added: Prompt Builder GUI The script described is an advanced AI prompt builder tool The tool provides a user-friendly interface that allows users to create, manage, and execute AI prompts based on predefined templates or customizable settings from .ini file. macros in the Prompt Builder GUI @Selection@ = the Selection of SciTE @ScriptName@ = the Script Name (useful as title) @ScriptFullPath@ = all the content of Script @ClipGet@ = the content of Clipboard @FileRead(FilePath)@ = the content of FilePath FIM (Fill-in-the-Middle <??> ) when it comes to FIM (Fill-in-the-Middle <??> ), the '<??>' tag is to specify the-Middle e.g. as in the example below, highlight the text , right click , and select, >>> SciTE AI Assistant <<< , FIM (Fill-in-the-Middle <??> ) Func SumNumbers($aNumbers) Local $iTotal = 0 For $i = 0 To UBound($aNumbers) - 1 <??> Next Return $iTotal EndFunc Edited June 1 by ioa747 argumentum 1 I know that I know nothing
Solution ioa747 Posted June 9 Author Solution Posted June 9 On 5/11/2025 at 7:37 PM, ioa747 said: update to Version: 0.12 I added a new function: _AI_Request which asynchronously sends a request to _AI_Call() and waits for the response. I also added a new parameter $iThink - Enable or disable thinking if Model supporting (0=none, 1=yes/not visible, 2=yes/visible). (Default is 0) to conform with the new ability to enable or disable thinking. (feature since version 0.9.0) Ollama now has the ability to enable or disable thinking. This gives users the flexibility to choose the model’s thinking behavior for different applications and use cases. When thinking is enabled, the output will separate the model’s thinking from the model’s output. When thinking is disabled, the model will not think and directly output the content. Models that support thinking: DeepSeek R1 Qwen 3 more will be added under thinking models. argumentum 1 I know that I know nothing
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now