givanz / Vvveb

Powerful and easy to use cms to build websites, blogs or ecommerce stores.
https://www.vvveb.com
GNU Affero General Public License v3.0
239 stars 49 forks source link

ChatGPT not working #75

Closed oleteacher closed 5 months ago

oleteacher commented 5 months ago

Hey @givanz

Thought it best to start a new issue since this in no way related to sqlite :)

I download the lastest.zip from your site. Replaced the chatgpt plugin with new code and still get same error. Cleared cache locally and also at Cloudflare, no change:

image

I am certain my api key is good and correct. Looking at network tab, the response from is:

{
  "error": {
    "message": "'200' is not of type 'integer' - 'max_tokens'",
    "type": "invalid_request_error",
    "param": null,
    "code": null
  }
}

More info that may help:

POST https://api.openai.com/v1/completions 400 (Bad Request)
aiAssistantSendQuery @ chatgpt-tinymce.js:113
(anonymous) @ chatgpt-tinymce.js:37
dispatch @ jquery.min.js:2
v.handle @ jquery.min.js:2
givanz commented 5 months ago

Hi

From the error message it looks like the code changes are not there.

Can you please search max_tokens: in chatgpt-tinymce.js from your site, replace demo.vvveb.com with your domain https://demo.vvveb.com/plugins/chatgpt/chatgpt-tinymce.js

The line should have parseInt like this

max_tokens: parseInt(chatgptOptions["max_tokens"] ?? 300),

If the file on the server /public/plugins/chatgpt/chatgpt-vvvebjs.js has the changes but the file loaded in the browser does not then it's probably another cache layer.

Or maybe the file on the server has not been overwritten.

oleteacher commented 5 months ago

Thanks @givanz

I have verified that both .js files have:

max_tokens: parseInt(chatgptOptions["max_tokens"] ?? 300),

I am not sure about any other caches. Working daily with these types of files, normally have to clear app and Cloudflare , nothing else. I have directly loaded the .js files and verified the functions are also correct:

function aiAssistantSendQuery(text, editor)  {
        if (!chatgptOptions["key"] ) {
            displayToast("bg-danger", "Error", 'No ChatGPT key configured! Enter a valid key in the plugin settings page.');
            return;
        }

        let selection = $("textarea", aiModal).val();

        const ChatGPT = {
            //api_key: chatgptOptions["key"] ?? null,
            model: chatgptOptions["model"] ?? "gpt-3.5-turbo-instruct",
            /*
            messages: [
              {
                role: "user",
                content: prompt
              },
              {
                role: "system",
                content: "You are a Bootstrap 5 Html expert."
              },
            ],
            */
            temperature: parseInt(chatgptOptions["temperature"] ?? 0),
            max_tokens: parseInt(chatgptOptions["max_tokens"] ?? 300),
            prompt: selection,
            //format: "html"
        };

Not totally clear with demo.vvveb.com:

Can you please search max_tokens: in chatgpt-tinymce.js from your site, replace demo.vvveb.com with your domain

givanz commented 5 months ago

normally have to clear app and Cloudflare , nothing else.

Did you also clear browser cache? static files are usually cached for long periods.

Another thing that I noticed that confirms that the old code is loaded is that in your screenshot save button is visible in the modal dialog, in the new code this button is removed as you can see in the demo

http://demo.vvveb.com/admin/?module=content/post&post_id=14&type=page

chatgpt

If you open https://yoursite.com/plugins/chatgpt/chatgpt-tinymce.js in your browser the code has parseInt for max_tokens?

oleteacher commented 5 months ago

Have tired it in 4 browsers. Opera, Edge, Chrome and Brave. Have been working in Edge so the other 3 browsers had never loaded the site. They all 4 show the same error in red box as shown in screenshot.

I think you missed the code I pasted above showing the function from your plugin when I directly visit the .js file:

function aiAssistantSendQuery(text, editor)  {
        if (!chatgptOptions["key"] ) {
            displayToast("bg-danger", "Error", 'No ChatGPT key configured! Enter a valid key in the plugin settings page.');
            return;
        }

        let selection = $("textarea", aiModal).val();

        const ChatGPT = {
            //api_key: chatgptOptions["key"] ?? null,
            model: chatgptOptions["model"] ?? "gpt-3.5-turbo-instruct",
            /*
            messages: [
              {
                role: "user",
                content: prompt
              },
              {
                role: "system",
                content: "You are a Bootstrap 5 Html expert."
              },
            ],
            */
            temperature: parseInt(chatgptOptions["temperature"] ?? 0),
            max_tokens: parseInt(chatgptOptions["max_tokens"] ?? 300),
            prompt: selection,
            //format: "html"
        };

As for the modal save button, I do not know. All I did was download the "latest.zip" from https://vvveb.com/download.php, unzip and replace the chatgpt folder in plugins. image

Where i s the cache folder located, and I will do a manual cleaning.

givanz commented 5 months ago

This is strange.

When testing with these new browsers is the save button visible?

Can you check at the beginning of the file, is the html code for save button commented also?

      <div class="modal-footer">
        <!-- <button type="button" class="btn btn-primary btn-lg btn-save" data-bs-dismiss="modal"><i class="la la-save"></i> Save</button> -->
        <button type="button" class="btn btn-secondary btn-lg close-btn" data-bs-dismiss="modal"><i class="la la-times"></i> Close</button>
      </div>

If it is then why does the save button show in the modal?

If the new code is loaded the save button should not be visible and max_tokens should not be (string) but (int) and chatgpt api should not complain.

I don't know what is happening, with the new code save button is not visible and chatgpt does not complain in my tests.

oleteacher commented 5 months ago

This all beats me. Work with code all day (not on your level) and understand pretty well. Below is a screencap from Opera and have never used it to visit site until this morning, so not browser cache: image

I have deleted the vvveb cache (all), browser cache and at Cloudflare. The current install is on a cPanel account and server is located in school IT center. Never had a problem like this.

givanz commented 5 months ago

Hope we can solve the mystery how that button is still there :)

If you click on the js file in the elements tab to open it and view the code is the save button commented and parseInt present?

oleteacher commented 5 months ago

Below is the chatgpt-tinymce.js directly from server and below that is the plugin code from the latest.zip

The more I look, the crazier it gets. I see the button commented out. There must be a cache somewhere? Never in my years seen this.

on server:


$(window).on("vvveb.tinymce.options", function (e, tinyMceOptions) { 
    tinyMceOptions.quickbars_insert_toolbar += '| AskChatGPT';
    tinyMceOptions.toolbar += '| AskChatGPT';

    return tinyMceOptions;
});

let aiResponseTemplate = `
<div class="response">
    <div class="content">

        <div class="card">
          <div class="card-body">
            <h5 class="card-title">Welcome to our website!</h5>
            <p class="card-text">Thank you for visiting our site. We hope you find everything you need.</p>
            <button class="btn btn-primary">Learn More</button>
          </div>
        </div>

    </div>

    <div class="ai-actions">
        <button type="button" class="btn btn-sm btn-outline-primary btn-insert"><i class="icon-arrow-up"></i>Insert content</button>
        <!-- <button type="button" class="btn btn-sm btn-outline-primary btn-replace"><i class="icon-swap-horizontal-outline"></i> Replace with</button> -->
    </div>
</div>  
`;

let aiModalTemplate = `<div class="modal fade" id="ai-assistant-modal" tabindex="-1" role="dialog" aria-labelledby="textarea-modal" aria-hidden="true">
  <div class="modal-dialog modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <p class="modal-title text-primary"><i class="icon-color-wand"></i> Ai assistant</p>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
        </button>
      </div>
      <div class="modal-body">

        <textarea rows="3" cols="150" class="form-control mb-3"></textarea>

        <button type="button" class="btn btn-success btn-ask-ai"><i class="icon-color-wand la-lg"></i> Ask AI</button>
        <button type="button" class="btn btn-light border btn-insert-content"><i class="icon-arrow-up la-lg"></i> Insert element content</button>

        <div class="spinner-border spinner-border-sm mx-3" role="status" style="display:none">
          <span class="visually-hidden">Loading...</span>
        </div>

        <div class="responses mt-3 pt-3 border-top" style="display:none">
        </div>

      </div>
      <div class="modal-footer">
        <!-- <button type="button" class="btn btn-primary btn-lg btn-save" data-bs-dismiss="modal"><i class="la la-save"></i> Save</button> -->
        <button type="button" class="btn btn-secondary btn-lg close-btn" data-bs-dismiss="modal"><i class="la la-times"></i> Close</button>
      </div>
    </div>
  </div>
</div>
<style>
.responses {
    overflow-y: auto;
    resize: vertical;
    height:300px;
    border-top:1px solid var(--bs-border-color);
}

.response {
    margin-top:1rem;
    padding-top:1rem;
    border-bottom:1px solid var(--bs-border-color);
}
.response .ai-actions{
    margin:1rem;    
    text-align:right;
}

.response .ai-actions i {
    font-size: 1.15rem;
    line-height: 1;
    vertical-align: text-top;
}
`;

$("body").append(aiModalTemplate);

let aiModal = $("#ai-assistant-modal");

$(".btn-ask-ai", aiModal).on("click", function(event) {
    aiAssistantSendQuery();
    return false;
});

$(".btn-insert-content", aiModal).on("click", function(event) {
    let selectedEl = Vvveb.Builder.selectedEl.get(0);
    let text = selectedEl.innerHTML.trim();

    $("textarea", aiModal).val(function( index, value ) {
        return value + "\n" + text;
    });

    return false;
});

$(".btn-save", aiModal).on("click", function(event) {
    let selectedEl = Vvveb.Builder.selectedEl.get(0);
    selectedEl.innerHTML = $("textarea", aiModal).val();
    $("textarea", aiModal).val("")
});

$(".close-btn", aiModal).on("click", function(event) {
    $("textarea", aiModal).val("")
    $(".responses", aiModal).html("").hide();
});

$("#ai-assistant-btn").on("click", function(event) {
    aiModal.modal("show");

    return false;
});

$("#ai-assistant-modal").on("click", ".btn-insert",function(event) {
    let response = $(this).parents(".response:first");
    tinyMceInstance.insertContent($(".content", response).html());

    return false;
});

$("#ai-assistant-modal").on("click", ".btn-replace",function(event) {
    let response    = $(this).parents(".response:first")
    let selectedEl  = Vvveb.Builder.selectedEl;

    var node = $( $(".content", response).html() );

    node = node.get(0);

    Vvveb.Undo.addMutation({type: 'childList', 
                            target: selectedEl[0].parentNode, 
                            addedNodes: [node], 
                            removedNodes: [selectedEl[0]], 
                            nextSibling: selectedEl[0].nextSibling});

    selectedEl.replaceWith(node);

    return false;
});

$(window).on("vvveb.tinymce.setup", function (e, editor) { 

    editor.ui.registry.addButton('AskChatGPT', {
        text: "Ask ChatGPT",
        icon: 'highlight-bg-color',
        tooltip: 'Highlight text and click this button to query ChatGPT',
        //enabled: true,
        onAction: (_) => {
            tinyMceInstance = editor;

            if (!chatgptOptions["key"] ) {
                alert('No ChatGPT key configured! Enter a valid key in the plugin settings page.');
                return;
            }

            let selection = tinymce.activeEditor.selection.getContent();
            $("textarea", aiModal).val(selection);
            aiModal.modal("show");
        }
    });
});

function aiAssistantSendQuery(text, editor)  {
        if (!chatgptOptions["key"] ) {
            displayToast("bg-danger", "Error", 'No ChatGPT key configured! Enter a valid key in the plugin settings page.');
            return;
        }

        let selection = $("textarea", aiModal).val();

        const ChatGPT = {
            //api_key: chatgptOptions["key"] ?? null,
            model: chatgptOptions["model"] ?? "gpt-3.5-turbo-instruct",
            /*
            messages: [
              {
                role: "user",
                content: prompt
              },
              {
                role: "system",
                content: "You are a Bootstrap 5 Html expert."
              },
            ],
            */
            temperature: parseInt(chatgptOptions["temperature"] ?? 0),
            max_tokens: parseInt(chatgptOptions["max_tokens"] ?? 300),
            prompt: selection,
            //format: "html"
        };

        fetch("https://api.openai.com/v1/completions", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: `Bearer ${chatgptOptions["key"]}`
            },
            body: JSON.stringify(ChatGPT)
        }).then(res => res.json()).then(data => {
            $(".spinner-border", aiModal).hide();
            if (data.error) {
                let message = '';
                for (name in data.error) {
                    message += name +":" + data.error[name] + "\n";
                }
                //alert(message);
                displayToast("bg-danger", "Error", message);
                return;
            }

            let reply = '';
            for (let i = 0; i < data.choices.length; i++) {
                reply += data.choices[i].text + "\n";
            }

            let responses = $(".responses");    
            let response = $(aiResponseTemplate);

            $(".content", response).html(reply);
            responses.append(response);
            responses.show();
            response[0].scrollIntoViewIfNeeded();
        }).catch(error => {
            $(".spinner-border", aiModal).hide();
            displayToast("bg-danger", "Error", error);
            console.log("something went wrong", error);
        })
}

from latest.zip:

($(window).on("vvveb.tinymce.options", function (e, tinyMceOptions) { 
    tinyMceOptions.quickbars_insert_toolbar += '| AskChatGPT';
    tinyMceOptions.toolbar += '| AskChatGPT';

    return tinyMceOptions;
});

let aiResponseTemplate = `
<div class="response">
    <div class="content">

        <div class="card">
          <div class="card-body">
            <h5 class="card-title">Welcome to our website!</h5>
            <p class="card-text">Thank you for visiting our site. We hope you find everything you need.</p>
            <button class="btn btn-primary">Learn More</button>
          </div>
        </div>

    </div>

    <div class="ai-actions">
        <button type="button" class="btn btn-sm btn-outline-primary btn-insert"><i class="icon-arrow-up"></i>Insert content</button>
        <!-- <button type="button" class="btn btn-sm btn-outline-primary btn-replace"><i class="icon-swap-horizontal-outline"></i> Replace with</button> -->
    </div>
</div>  
`;

let aiModalTemplate = `<div class="modal fade" id="ai-assistant-modal" tabindex="-1" role="dialog" aria-labelledby="textarea-modal" aria-hidden="true">
  <div class="modal-dialog modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <p class="modal-title text-primary"><i class="icon-color-wand"></i> Ai assistant</p>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
        </button>
      </div>
      <div class="modal-body">

        <textarea rows="3" cols="150" class="form-control mb-3"></textarea>

        <button type="button" class="btn btn-success btn-ask-ai"><i class="icon-color-wand la-lg"></i> Ask AI</button>
        <button type="button" class="btn btn-light border btn-insert-content"><i class="icon-arrow-up la-lg"></i> Insert element content</button>

        <div class="spinner-border spinner-border-sm mx-3" role="status" style="display:none">
          <span class="visually-hidden">Loading...</span>
        </div>

        <div class="responses mt-3 pt-3 border-top" style="display:none">
        </div>

      </div>
      <div class="modal-footer">
        <!-- <button type="button" class="btn btn-primary btn-lg btn-save" data-bs-dismiss="modal"><i class="la la-save"></i> Save</button> -->
        <button type="button" class="btn btn-secondary btn-lg close-btn" data-bs-dismiss="modal"><i class="la la-times"></i> Close</button>
      </div>
    </div>
  </div>
</div>
<style>
.responses {
    overflow-y: auto;
    resize: vertical;
    height:300px;
    border-top:1px solid var(--bs-border-color);
}

.response {
    margin-top:1rem;
    padding-top:1rem;
    border-bottom:1px solid var(--bs-border-color);
}
.response .ai-actions{
    margin:1rem;    
    text-align:right;
}

.response .ai-actions i {
    font-size: 1.15rem;
    line-height: 1;
    vertical-align: text-top;
}
`;

$("body").append(aiModalTemplate);

let aiModal = $("#ai-assistant-modal");

$(".btn-ask-ai", aiModal).on("click", function(event) {
    aiAssistantSendQuery();
    return false;
});

$(".btn-insert-content", aiModal).on("click", function(event) {
    let selectedEl = Vvveb.Builder.selectedEl.get(0);
    let text = selectedEl.innerHTML.trim();

    $("textarea", aiModal).val(function( index, value ) {
        return value + "\n" + text;
    });

    return false;
});

$(".btn-save", aiModal).on("click", function(event) {
    let selectedEl = Vvveb.Builder.selectedEl.get(0);
    selectedEl.innerHTML = $("textarea", aiModal).val();
    $("textarea", aiModal).val("")
});

$(".close-btn", aiModal).on("click", function(event) {
    $("textarea", aiModal).val("")
    $(".responses", aiModal).html("").hide();
});

$("#ai-assistant-btn").on("click", function(event) {
    aiModal.modal("show");

    return false;
});

$("#ai-assistant-modal").on("click", ".btn-insert",function(event) {
    let response = $(this).parents(".response:first");
    tinyMceInstance.insertContent($(".content", response).html());

    return false;
});

$("#ai-assistant-modal").on("click", ".btn-replace",function(event) {
    let response    = $(this).parents(".response:first")
    let selectedEl  = Vvveb.Builder.selectedEl;

    var node = $( $(".content", response).html() );

    node = node.get(0);

    Vvveb.Undo.addMutation({type: 'childList', 
                            target: selectedEl[0].parentNode, 
                            addedNodes: [node], 
                            removedNodes: [selectedEl[0]], 
                            nextSibling: selectedEl[0].nextSibling});

    selectedEl.replaceWith(node);

    return false;
});

$(window).on("vvveb.tinymce.setup", function (e, editor) { 

    editor.ui.registry.addButton('AskChatGPT', {
        text: "Ask ChatGPT",
        icon: 'highlight-bg-color',
        tooltip: 'Highlight text and click this button to query ChatGPT',
        //enabled: true,
        onAction: (_) => {
            tinyMceInstance = editor;

            if (!chatgptOptions["key"] ) {
                alert('No ChatGPT key configured! Enter a valid key in the plugin settings page.');
                return;
            }

            let selection = tinymce.activeEditor.selection.getContent();
            $("textarea", aiModal).val(selection);
            aiModal.modal("show");
        }
    });
});

function aiAssistantSendQuery(text, editor)  {
        if (!chatgptOptions["key"] ) {
            displayToast("bg-danger", "Error", 'No ChatGPT key configured! Enter a valid key in the plugin settings page.');
            return;
        }

        let selection = $("textarea", aiModal).val();

        const ChatGPT = {
            //api_key: chatgptOptions["key"] ?? null,
            model: chatgptOptions["model"] ?? "gpt-3.5-turbo-instruct",
            /*
            messages: [
              {
                role: "user",
                content: prompt
              },
              {
                role: "system",
                content: "You are a Bootstrap 5 Html expert."
              },
            ],
            */
            temperature: parseInt(chatgptOptions["temperature"] ?? 0),
            max_tokens: parseInt(chatgptOptions["max_tokens"] ?? 300),
            prompt: selection,
            //format: "html"
        };

        fetch("https://api.openai.com/v1/completions", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: `Bearer ${chatgptOptions["key"]}`
            },
            body: JSON.stringify(ChatGPT)
        }).then(res => res.json()).then(data => {
            $(".spinner-border", aiModal).hide();
            if (data.error) {
                let message = '';
                for (name in data.error) {
                    message += name +":" + data.error[name] + "\n";
                }
                //alert(message);
                displayToast("bg-danger", "Error", message);
                return;
            }

            let reply = '';
            for (let i = 0; i < data.choices.length; i++) {
                reply += data.choices[i].text + "\n";
            }

            let responses = $(".responses");    
            let response = $(aiResponseTemplate);

            $(".content", response).html(reply);
            responses.append(response);
            responses.show();
            response[0].scrollIntoViewIfNeeded();
        }).catch(error => {
            $(".spinner-border", aiModal).hide();
            displayToast("bg-danger", "Error", error);
            console.log("something went wrong", error);
        })
}
)
givanz commented 5 months ago

If you click in on ../../plugins/chatgpt/chatgpt-tinymce.js in opera in the elements tab from the screenshot, what code will opera load?

oleteacher commented 5 months ago

I think I must not be communicating very well. The code above and below is loaded via url from server using Opera.


$(window).on("vvveb.tinymce.options", function (e, tinyMceOptions) { 
    tinyMceOptions.quickbars_insert_toolbar += '| AskChatGPT';
    tinyMceOptions.toolbar += '| AskChatGPT';

    return tinyMceOptions;
});

let aiResponseTemplate = `
<div class="response">
    <div class="content">

        <div class="card">
          <div class="card-body">
            <h5 class="card-title">Welcome to our website!</h5>
            <p class="card-text">Thank you for visiting our site. We hope you find everything you need.</p>
            <button class="btn btn-primary">Learn More</button>
          </div>
        </div>

    </div>

    <div class="ai-actions">
        <button type="button" class="btn btn-sm btn-outline-primary btn-insert"><i class="icon-arrow-up"></i>Insert content</button>
        <!-- <button type="button" class="btn btn-sm btn-outline-primary btn-replace"><i class="icon-swap-horizontal-outline"></i> Replace with</button> -->
    </div>
</div>  
`;

let aiModalTemplate = `<div class="modal fade" id="ai-assistant-modal" tabindex="-1" role="dialog" aria-labelledby="textarea-modal" aria-hidden="true">
  <div class="modal-dialog modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <p class="modal-title text-primary"><i class="icon-color-wand"></i> Ai assistant</p>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
        </button>
      </div>
      <div class="modal-body">

        <textarea rows="3" cols="150" class="form-control mb-3"></textarea>

        <button type="button" class="btn btn-success btn-ask-ai"><i class="icon-color-wand la-lg"></i> Ask AI</button>
        <button type="button" class="btn btn-light border btn-insert-content"><i class="icon-arrow-up la-lg"></i> Insert element content</button>

        <div class="spinner-border spinner-border-sm mx-3" role="status" style="display:none">
          <span class="visually-hidden">Loading...</span>
        </div>

        <div class="responses mt-3 pt-3 border-top" style="display:none">
        </div>

      </div>
      <div class="modal-footer">
        <!-- <button type="button" class="btn btn-primary btn-lg btn-save" data-bs-dismiss="modal"><i class="la la-save"></i> Save</button> -->
        <button type="button" class="btn btn-secondary btn-lg close-btn" data-bs-dismiss="modal"><i class="la la-times"></i> Close</button>
      </div>
    </div>
  </div>
</div>
<style>
.responses {
    overflow-y: auto;
    resize: vertical;
    height:300px;
    border-top:1px solid var(--bs-border-color);
}

.response {
    margin-top:1rem;
    padding-top:1rem;
    border-bottom:1px solid var(--bs-border-color);
}
.response .ai-actions{
    margin:1rem;    
    text-align:right;
}

.response .ai-actions i {
    font-size: 1.15rem;
    line-height: 1;
    vertical-align: text-top;
}
`;

$("body").append(aiModalTemplate);

let aiModal = $("#ai-assistant-modal");

$(".btn-ask-ai", aiModal).on("click", function(event) {
    aiAssistantSendQuery();
    return false;
});

$(".btn-insert-content", aiModal).on("click", function(event) {
    let selectedEl = Vvveb.Builder.selectedEl.get(0);
    let text = selectedEl.innerHTML.trim();

    $("textarea", aiModal).val(function( index, value ) {
        return value + "\n" + text;
    });

    return false;
});

$(".btn-save", aiModal).on("click", function(event) {
    let selectedEl = Vvveb.Builder.selectedEl.get(0);
    selectedEl.innerHTML = $("textarea", aiModal).val();
    $("textarea", aiModal).val("")
});

$(".close-btn", aiModal).on("click", function(event) {
    $("textarea", aiModal).val("")
    $(".responses", aiModal).html("").hide();
});

$("#ai-assistant-btn").on("click", function(event) {
    aiModal.modal("show");

    return false;
});

$("#ai-assistant-modal").on("click", ".btn-insert",function(event) {
    let response = $(this).parents(".response:first");
    tinyMceInstance.insertContent($(".content", response).html());

    return false;
});

$("#ai-assistant-modal").on("click", ".btn-replace",function(event) {
    let response    = $(this).parents(".response:first")
    let selectedEl  = Vvveb.Builder.selectedEl;

    var node = $( $(".content", response).html() );

    node = node.get(0);

    Vvveb.Undo.addMutation({type: 'childList', 
                            target: selectedEl[0].parentNode, 
                            addedNodes: [node], 
                            removedNodes: [selectedEl[0]], 
                            nextSibling: selectedEl[0].nextSibling});

    selectedEl.replaceWith(node);

    return false;
});

$(window).on("vvveb.tinymce.setup", function (e, editor) { 

    editor.ui.registry.addButton('AskChatGPT', {
        text: "Ask ChatGPT",
        icon: 'highlight-bg-color',
        tooltip: 'Highlight text and click this button to query ChatGPT',
        //enabled: true,
        onAction: (_) => {
            tinyMceInstance = editor;

            if (!chatgptOptions["key"] ) {
                alert('No ChatGPT key configured! Enter a valid key in the plugin settings page.');
                return;
            }

            let selection = tinymce.activeEditor.selection.getContent();
            $("textarea", aiModal).val(selection);
            aiModal.modal("show");
        }
    });
});

function aiAssistantSendQuery(text, editor)  {
        if (!chatgptOptions["key"] ) {
            displayToast("bg-danger", "Error", 'No ChatGPT key configured! Enter a valid key in the plugin settings page.');
            return;
        }

        let selection = $("textarea", aiModal).val();

        const ChatGPT = {
            //api_key: chatgptOptions["key"] ?? null,
            model: chatgptOptions["model"] ?? "gpt-3.5-turbo-instruct",
            /*
            messages: [
              {
                role: "user",
                content: prompt
              },
              {
                role: "system",
                content: "You are a Bootstrap 5 Html expert."
              },
            ],
            */
            temperature: parseInt(chatgptOptions["temperature"] ?? 0),
            max_tokens: parseInt(chatgptOptions["max_tokens"] ?? 300),
            prompt: selection,
            //format: "html"
        };

        fetch("https://api.openai.com/v1/completions", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: `Bearer ${chatgptOptions["key"]}`
            },
            body: JSON.stringify(ChatGPT)
        }).then(res => res.json()).then(data => {
            $(".spinner-border", aiModal).hide();
            if (data.error) {
                let message = '';
                for (name in data.error) {
                    message += name +":" + data.error[name] + "\n";
                }
                //alert(message);
                displayToast("bg-danger", "Error", message);
                return;
            }

            let reply = '';
            for (let i = 0; i < data.choices.length; i++) {
                reply += data.choices[i].text + "\n";
            }

            let responses = $(".responses");    
            let response = $(aiResponseTemplate);

            $(".content", response).html(reply);
            responses.append(response);
            responses.show();
            response[0].scrollIntoViewIfNeeded();
        }).catch(error => {
            $(".spinner-border", aiModal).hide();
            displayToast("bg-danger", "Error", error);
            console.log("something went wrong", error);
        })
}
givanz commented 5 months ago

But why the save button is visible if the code has the save button commented

<!-- <button type="button" class="btn btn-primary btn-lg btn-save" data-bs-dismiss="modal"><i class="la la-save"></i> Save</button> -->

and also Insert element content button is not visible in the screenshot although this is present in the code

<button type="button" class="btn btn-success btn-ask-ai"><i class="icon-color-wand la-lg"></i> Ask AI</button>
<button type="button" class="btn btn-light border btn-insert-content"><i class="icon-arrow-up la-lg"></i> Insert element content</button>

This is a mystery for me, the screenshot does not reflect what is in the code.

In some rare similar cases with chrome I was using empty cache and hard reload to fix it.

ClearCache-Chrome

oleteacher commented 5 months ago

Mystery solved!

I am very confused though. In the latest.zip there is a plugins folder in root. Then there is a plugin folder in /public/plugins/

I have been using the pugins folder from root level. I assumed this was correct and the when you showed https://demo.vvveb.com/plugins/chatgpt/chatgpt-tinymce.js assumed true.

I uploaded the /public/plugins/chatgpt/ and it works.

I am so sorry for causing you extra work. Had no clue there were two different locations.

oleteacher commented 5 months ago

I have one more question and hope it is not as hard on you :)

Currently working with main site on subdomain like sites.example.com. When I wish to add a new site like tools.example.com, what exactly do I need to do? Have added but not working. Any DNS changes needed? Need to point tools.example.com to server IP?

If better for you, I can open a new issue...

givanz commented 5 months ago

Sorry for the confusion.

Plugins are located in root folder but by design and also for better security all files that are accessible through the web server are located in /public folder.

And because of this when a plugin is activated all files from /plugins/plugin-name/public are copied to /public/plugins/plugin-name and this is why public plugin files are in two places after a plugin is activated.

I am so sorry for causing you extra work. Had no clue there were two different locations.

No problem, there was no extra work, only mystery :) let me know if there are any issues with the plugin as it's still new.


Any DNS changes needed? Need to point tools.example.com to server IP?

This is the only thing required and it should work.

If your dns server configuration allows it you can use a wildcard like *.domain.com to point all subdomains to the server in order to do this only once for all subdomains.

oleteacher commented 5 months ago

Current install is in a subdomain and trying to add new sites is not working out. We use Cloudflare and adding a subdomain is very straight forward, but not working for us on vvveb. We cannot even delete existing addon site, choosing Delete has no effect and no errors in dev console.

Looks like I have some research to do.

oleteacher commented 5 months ago

Would this message on page be from vvveb?

WHOST SERVER: 22

givanz commented 5 months ago

When loading the new subdomain address is the default site displayed or something else? does the request reach vvveb but it does not display the proper site for the subdomain or it goes to some other place?

If everything is configured properly then the request must reach vvveb.

We cannot even delete existing addon site, choosing Delete has no effect and no errors in dev console.

Thanks for the bug report, I will fix it now and release it in the next update.


WHOST SERVER: 22

This message is not coming from vvveb, it looks like is generated by windows server.

Probably your windows server is not configured for the subdomain.

oleteacher commented 5 months ago

No, not windows server. Linux infrastructure for all web related.

Something flaky with the cPanel setup though, doing some testing and do not like what I see. Turning the results over to IT department:)

Going to close this. I thank you very much Givan.