Skip to main content
alexanderp3125138
Inspiring
March 13, 2024
Answered

Script to integrate local LLM for proofreading

  • March 13, 2024
  • 1 reply
  • 9632 views

Hey folks,

I'm thinking of writing a script to add local LLM api support to FrameMaker. I basically want to get AI assisted proofreading/text correction by doing the following (using a local lightweight Mistral-7B model):

1. Select text, then send it via button press to an LLM client  running on my computer (LM Studio or ollama) for proofreading
2. Receive & process the proofreading results
3. Apply the suggestions to the text in FrameMaker

 

Before I dive into what might just be an impossible task due to ExtendScript limitations (I'd have to do quite a lot of digging, I'm not a real coder), do you think this is doable? I'd be very grateful for any insights, or tips where to start. 🙂🙏

    Correct answer frameexpert

    Thanks for your reply, I really appreciate it. 🙂


    I'm looking for a way to actually select a paragraph with Extendscript. The idea is that I want the user to be able to either select text with the mouse, or, if nothing is selected, simply select the whole next paragraph. This kind of advanced either/or functionality will be reserved for later though. I'll stitch it together once both parts are working independently. 

     

    Right now, option 1 is working fine, the text is sent over to the llm via api, connection is staying alive as long as needed, corrected text is received and pasted back into the document, overwriting the previous (selected) text. 

     

    Now for option 2, if the text gets copied and sent over automatically without selecting it first, it gets corrected, too, but then inserted into the paragraph at insertion point, so I end up with the old and new text.

     

    So all I need is a way to select the next paragraph relative to the cursor position. I think I could integrate this easily with the getText function that's already working. I could also paste my whole script text here, but that would probably just unnecessarily blow up my post, and I don't want to bother you guys even more with walls of text. 😉


    These two short videos will explain text locations and text ranges:

    https://youtu.be/6ywYWU4VC7g?si=pA7llQ5vS8nIlqwt

    https://youtu.be/fH5giAcDp6Q?si=lerkUNDTWdSoLKjO

    If you are in a hurry, the second one will show you how to select a paragraph.

    1 reply

    frameexpert
    Braniac
    March 13, 2024

    How can your LLM receive inputs? You could send text via a commandline from ExtendScript. ExtendScript does allow some integration with other programs via C++.

    alexanderp3125138
    Inspiring
    March 13, 2024

    Input is received via local api (LM Studio = http://localhost:1234/, ollama = http://localhost:11434/). I'm wondering if it's possible to create some sort of automated "roundtrip", with text pushed to the api, and completion received automatically.

    alexanderp3125138
    Inspiring
    April 15, 2024

    Here is a function I use to get text from a text object such as a Pgf, Cell, etc. For example to get the text from paragraph containing the cursor, use something like this:

     

    var doc, pgf, text;

     

    doc = app.ActiveDoc;

    pgf = doc.TextSelection.beg.obj;

    text = getText (pgf, doc);

    alert (text);

    function getText (textObj, doc) {
    
        // Gets the text from the text object.
    
        var textItems, text, count, i;
        
        // Get a list of the strings in the text object or text range.
        if (textObj.constructor.name !== "TextRange") {
            textItems = textObj.GetText (Constants.FTI_String);
        } 
        else {
             textItems = doc.GetTextForRange (textObj, Constants.FTI_String);
        }
        
        // Concatenate the strings.
        text = "";
        count = textItems.length;
        for (i = 0; i < count; i += 1) {
            text += (textItems[i].sdata);
        }
        
        return text;
    }

     


    Thanks for your reply, I really appreciate it. 🙂


    I'm looking for a way to actually select a paragraph with Extendscript. The idea is that I want the user to be able to either select text with the mouse, or, if nothing is selected, simply select the whole next paragraph. This kind of advanced either/or functionality will be reserved for later though. I'll stitch it together once both parts are working independently. 

     

    Right now, option 1 is working fine, the text is sent over to the llm via api, connection is staying alive as long as needed, corrected text is received and pasted back into the document, overwriting the previous (selected) text. 

     

    Now for option 2, if the text gets copied and sent over automatically without selecting it first, it gets corrected, too, but then inserted into the paragraph at insertion point, so I end up with the old and new text.

     

    So all I need is a way to select the next paragraph relative to the cursor position. I think I could integrate this easily with the getText function that's already working. I could also paste my whole script text here, but that would probably just unnecessarily blow up my post, and I don't want to bother you guys even more with walls of text. 😉