Debug ai v22

This commit is contained in:
ldestailleur 2025-03-20 23:54:24 +01:00
parent 5f211c64ec
commit 65496604b4
8 changed files with 117 additions and 65 deletions

View file

@ -192,31 +192,35 @@ if (getDolGlobalString("AI_API_SERVICE")) {
$functioncode = GETPOST('functioncode');
$out = '';
if ($functioncode) {
$labeloffeature = empty($arrayofaifeatures[GETPOST('functioncode')]['label']) ? 'Undefined' : $arrayofaifeatures[GETPOST('functioncode')]['label'];
//if ($functioncode) {
$key = 'textgenerationother'; // The HTML ID of field to fill
$labeloffeature = empty($arrayofaifeatures[$key]['label']) ? 'Undefined' : $arrayofaifeatures[$key]['label'];
//$out .= $langs->trans("Test").' '.$labeloffeature.'...<br><br>';
if (GETPOST('functioncode') == 'textgenerationemail') {
$key = 'textgenerationemail'; // The HTML ID of field to fill
//if (GETPOST('functioncode') == 'textgenerationemail') {
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
$showlinktoai = $key; // 'textgeneration', 'imagegeneration', ...
$showlinktoailabel = $langs->trans("Test").' '.$labeloffeature;
$showlinktolayout = 0;
$formmail = new FormMail($db);
$htmlname = $key;
print '<br>';
//print '<hr>';
// Fill $out
include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php';
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
include_once DOL_DOCUMENT_ROOT."/core/class/html.formai.class.php";
$formai = new FormAI($db);
$formmail = new FormMail($db);
$out .= '<div id="'.$key.'"></div>';
} else {
$out .= $langs->trans("FeatureNotYetAvailable").'<br><br>';
$functioncode = '';
}
}
$showlinktoai = $key; // 'textgeneration', 'imagegeneration', ...
$showlinktoailabel = $langs->trans("AITestText");
$showlinktolayout = 0;
$htmlname = $key;
// Fill $out
include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php';
$out .= '<br><textarea id="'.$key.'" placeholder="Lore ipsum..." class="quatrevingtpercent" rows="4"></textarea>'; // The div
//}
/*
if (!$functioncode) {
// Combo list of AI features
$out .= '<select name="functioncode" id="functioncode" class="flat minwidth300" placeholder="Test feature">';
@ -233,6 +237,8 @@ if (getDolGlobalString("AI_API_SERVICE")) {
$out .= '<input class="button small" type="submit" name="testmode" value="'.$langs->trans("Test").'">';
}
*/
print $out;
print '</form>';

View file

@ -77,7 +77,7 @@ $ai = new Ai($db);
// Get parameters
$function = empty($jsonData['function']) ? 'textgeneration' : $jsonData['function']; // Default value. Can also be 'textgeneration', 'textgenerationemail', 'textgenerationwebpage', 'imagegeneration', 'videogeneration', ...
$instructions = dol_string_nohtmltag($jsonData['instructions'], 1, 'UTF-8');
$format = empty($jsonData['format']) ? '' : $jsonData['format'];
$format = empty($jsonData['format']) ? '' : $jsonData['format']; // Can be '' for text, 'html', ...
if ($function == 'texttranslation') {
$instructions = $jsonData['instructions'];

View file

@ -82,7 +82,7 @@ class Ai
{
global $dolibarr_main_data_root;
if (empty($this->apiKey)) {
if (empty($this->apiKey) && in_array($this->apiService, array('chatgpt', 'groq'))) {
return array('error' => true, 'message' => 'API key is not defined for the AI enabled service ('.$this->apiService.')');
}
@ -293,12 +293,20 @@ class Ai
}
}
// Decode JSON response
$decodedResponse = json_decode($response['content'], true);
// Extraction content
$generatedContent = $decodedResponse['choices'][0]['message']['content'];
if (!empty($decodedResponse['error'])) {
if (is_scalar($decodedResponse['error'])) {
$generatedContent = $decodedResponse['error'];
} else {
$generatedContent = var_export($decodedResponse['error'], true);
}
} else {
$generatedContent = $decodedResponse['choices'][0]['message']['content'];
}
dol_syslog("generatedContent=".dol_trunc($generatedContent, 50));
// If content is not HTML, we convert it into HTML

View file

@ -91,12 +91,12 @@ class FormAI extends Form
}
/**
* Return Html code for AI instruction of message and autofill result
* Return Html code for AI instructions of message and autofill result
*
* @param string $function Function ('textgenerationmail', 'textgenerationwebpage', ...)
* @param string $format Format for output ('', 'html', ...)
* @param string $htmlContent HTML name of WYSIWYG field
* @return string HTML code to ask AI instruction and autofill result
* @return string HTML code to ask AI instructions and autofill result
*/
public function getSectionForAIEnhancement($function = 'textgeneration', $format = '', $htmlContent = 'message')
{
@ -108,17 +108,18 @@ class FormAI extends Form
$htmlContent = preg_replace('/[^a-z0-9_]/', '', $htmlContent);
$out = '<div id="ai_dropdown'.$htmlContent.'" class="dropdown-menu ai_dropdown ai_dropdown'.$htmlContent.' paddingtop paddingbottom">';
$out = '<!-- getSectionForAIEnhancement -->';
$out .= '<div id="ai_dropdown'.$htmlContent.'" class="dropdown-menu ai_dropdown ai_dropdown'.$htmlContent.' paddingtop paddingbottom">';
$out .= '<div id="ai_textgeneration'.$htmlContent.'" class="ai_textgeneration'.$htmlContent.' paddingtop paddingbottom ai_feature">';
$out .= '<span>'.$langs->trans("FillMessageWithAIContent").'</span>';
$out .= '<textarea class="quatrevingtpercent" data-functionai="textgeneration" id="ai_instructions'.$htmlContent.'" name="instruction" placeholder="'.$langs->trans("EnterYourAIPromptHere").'..." /></textarea>';
//$out .= '<span>'.$langs->trans("FillMessageWithAIContent").'</span>';
$out .= '<textarea class="centpercent" data-functionai="textgeneration" id="ai_instructions'.$htmlContent.'" name="instruction" placeholder="'.$langs->trans("EnterYourAIPromptHere").'..." /></textarea>';
$out .= '<input id="generate_button'.$htmlContent.'" type="button" class="button smallpaddingimp" disabled data-functionai="textgeneration" value="'.$langs->trans('Generate').'"/>';
$out .= '</div>';
$out .= '<br>';
$out .= '<div id="ai_translation'.$htmlContent.'" class="ai_translation'.$htmlContent.' paddingtop paddingbottom ai_feature">';
$out .= img_picto('', 'language', 'class="paddingrightonly"').$langs->trans("TranslateByAI").' ';
$out .= $formadmin->select_language("", "ai_translation".$htmlContent."_select", 0, array(), 1, 0, 0, 'ai_translation'.$htmlContent.'_select');
$out .= img_picto('', 'language', 'class="pictofixedwidth paddingrightonly"');
$out .= $formadmin->select_language("", "ai_translation".$htmlContent."_select", 0, array(), $langs->trans("TranslateByAI").'...', 0, 0, 'minwidth250 ai_translation'.$htmlContent.'_select');
$out .= '</div>';
$out .= '<div id="ai_status_message'.$htmlContent.'" class="fieldrequired hideobject marginrightonly margintoponly">';
@ -135,7 +136,8 @@ class FormAI extends Form
$('#ai_translation".$htmlContent."_select').data('functionai', 'texttranslation')
$('#ai_instructions".$htmlContent."').keyup(function(){
if ($(this).val() != ''){
console.log('We type a key up on #ai_instructions".$htmlContent."');
if ($(this).val() != '') {
$('#generate_button".$htmlContent."').prop('disabled', false);
} else {
$('#generate_button".$htmlContent."').prop('disabled', true);
@ -145,23 +147,26 @@ class FormAI extends Form
// for keydown
$('#ai_instructions".$htmlContent."').keydown(function(event) {
if (event.keyCode === 13 && $(this).val() != '') {
console.log('We type enter on #ai_instructions".$htmlContent."');
event.preventDefault();
$('#generate_button".$htmlContent."').click();
}
});
$('#generate_button".$htmlContent."').click(function() {
console.log('We click on #generate_button".$htmlContent."');
prepareCallAIGenerator($(this));
});
$('#ai_translation".$htmlContent."_select').on('change', function() {
if ($(this).val() != 0){
console.log('We change #ai_translation".$htmlContent."_select with lang '+$(this).val());
if ($(this).val() != null && $(this).val() != '' && $(this).val() != '-1') {
prepareCallAIGenerator($(this));
}
});
function prepareCallAIGenerator(element) {
console.log('We prepare call to AI, so we make an ajax on url /ai/ajax/generate_content.php');
console.log('We prepare ajax call to AI to url /ai/ajax/generate_content.php function=".dol_escape_js($function)." format=".dol_escape_js($format)."');
var userprompt = $('#ai_instructions".$htmlContent."').val();
var timeoutfinished = 0;
@ -171,30 +176,38 @@ class FormAI extends Form
format = '".dol_escape_js($format)."';
functionai = $(element).data('functionai');
if (functionai == 'texttranslation'){
if (functionai == 'texttranslation') {
console.log('htmlname='+htmlname);
/*
if (CKEDITOR.instances) {
editorInstance = CKEDITOR.instances[htmlname];
if (editorInstance) {
texttomodify = editorInstance.getData();
} else {
texttomodify = $('#'+htmlname).html();
}
} else {
texttomodify = $('#'+htmlname).val();
}
*/
if ($('#'+htmlname).is('div')) {
texttomodify = $('#'+htmlname).html(); /* for div */
} else {
texttomodify = $('#'+htmlname).val(); /* for input or textarea */
}
lang = $('#ai_translation'+htmlname+'_select').val();
instruction = 'translate the following text to ' + lang + ': ';
instructions = instruction + texttomodify
instructions = 'Translate the following text to ' + lang + ': ' + texttomodify;
} else {
instructions = userprompt;
}
$('#ai_status_message".$htmlContent."').show();
$('.icon-container .loader').show();
setTimeout(function() {
timeoutfinished = 1;
$('#ai_status_message".$htmlContent."').hide();
}, 30000);
console.log(instructions);
callAIGenerator(functionai, instructions, format, htmlname);
}
});
@ -206,7 +219,7 @@ class FormAI extends Form
/**
* Return javascript code for call to AI function callAIGenerator()
*
* @return string HTML code to ask AI instruction and autofill result
* @return string HTML code to ask AI instructions and autofill result
*/
public function getAjaxAICallFunction()
{
@ -279,7 +292,7 @@ class FormAI extends Form
console.log('Add response into field \'#'+htmlname+'\': '+response);
jQuery('#'+htmlname).val(response); // If #htmlcontent is a input name or textarea
jQuery('#'+htmlname).html(response); // If #htmlContent is a div
jQuery('#'+htmlname).html(response); // If #htmlContent is a div
//jQuery('#'+htmlname+'preview').val(response);
if (CKEDITOR.instances) {
@ -296,7 +309,7 @@ class FormAI extends Form
// remove readonly
$('#ai_instructions'+htmlname).val('');
$('#ai_translation'+htmlname+'_select').val('0');
$('#ai_translation'+htmlname+'_select').val('-1');
$('#ai_translation'+htmlname+'_select').trigger('change'); ;
$('#ai_status_message'+htmlname).hide();
$('#ai_dropdown'+htmlname).hide();

View file

@ -407,6 +407,7 @@ DescWeather=The following images will be shown on the dashboard when the number
KeyForWebServicesAccess=Key to use Web Services (parameter "dolibarrkey" in webservices)
TestSubmitForm=Input test form
ThisForceAlsoTheme=Using this menu manager will also use its own theme whatever the user choice. Also this menu manager specialized for smartphones does not work on all smartphone. Use another menu manager if you experience problems with yours.
AITestText=AI Test (text generation or transformation)
ThemeDir=Skins directory
ConnectionTimeout=Connection timeout
ResponseTimeout=Response timeout

View file

@ -357,5 +357,5 @@ Post-Prompt=Post-prompt
AIProcessingPleaseWait=AI (%s) is processing your request, please wait...
PayOfBankTransferInvoice=You are going to make an online payment for this invoice. However, this invoice has been set up to be paid in "Credit Transfer" mode, so to avoid paying twice, please verify that no current bank transfer has already been initiated before continuing.
Exceptions=Exceptions
TranslateByAI=Translate message by AI into
AIEnhancements=AI Enhancements
TranslateByAI=Translate message into
AIEnhancements=AI Enhancements

View file

@ -8600,41 +8600,41 @@ table.jPicker {
margin-bottom: 15px;
}
.topmenuimage {
background-size: 22px auto;
top: 2px;
}
/* ============================================================================== */
/* CSS style used for AI */
/* ============================================================================== */
.ai_dropdown{
min-width:300px;
padding: 5px;
left:inherit !important;
top:inherit !important;
.ai_dropdown {
min-width: 400px !important;
padding: 12px;
left: inherit !important;
top: inherit !important;
}
.ai_feature{
background-color: #ddd;
padding-left: 5px;
.ai_feature {
background-color: var(--colorbackgrey);
padding: 10px;
padding-bottom: 6px;
padding-top: 6px;
border-radius: 4px;
}
/* ============================================================================== */
/* CSS style used for small screen */
/* ============================================================================== */
@media only screen
{
.ai_dropdown{
min-width : 250px !important;
}
}
.topmenuimage {
background-size: 22px auto;
top: 2px;
}
@media only screen and (max-width: 768px)
{
.ai_dropdown{
min-width : 280px !important;
}
.imgopensurveywizard, .imgautosize { width:95%; height: auto; }
.fiche > .listactionsfilter .table-fiche-title .col-title .titre {

View file

@ -8443,12 +8443,36 @@ table.jPicker {
}
/* ============================================================================== */
/* CSS style used for AI */
/* ============================================================================== */
.ai_dropdown {
min-width: 400px;
padding: 12px;
left: inherit !important;
top: inherit !important;
}
.ai_feature {
background-color: var(--colorbackgrey);
padding: 10px;
padding-bottom: 6px;
padding-top: 6px;
border-radius: 4px;
}
/* ============================================================================== */
/* CSS style used for small screen */
/* ============================================================================== */
@media only screen and (max-width: 767px)
{
.ai_dropdown{
min-width : 280px !important;
}
.imgopensurveywizard, .imgautosize { width:95%; height: auto; }
#tooltip {