mirror of
https://github.com/Dolibarr/dolibarr.git
synced 2025-02-20 13:46:52 +01:00
NEW Add a test mode for AI setup
This commit is contained in:
parent
bc1dbae6b0
commit
47d59c7938
|
|
@ -305,6 +305,7 @@ if ($action == 'edit' || $action == 'deleteproperty') {
|
|||
|
||||
$out .= $form->buttonsSaveCancel("Add", "");
|
||||
$out .= '</form>';
|
||||
|
||||
$out .= '<br><br><br>';
|
||||
|
||||
print $out;
|
||||
|
|
@ -365,7 +366,7 @@ if ($action == 'edit' || $action == 'create' || $action == 'deleteproperty') {
|
|||
$out .= '<tr>';
|
||||
$out .= '<td></td>';
|
||||
$out .= '<td>';
|
||||
$out .= '<input type="submit" class="button small submitBtn reposition" name="modify" data-index="'.$key.'" value="'.dol_escape_htmltag($langs->trans("Modify")).'"/>';
|
||||
$out .= '<input type="submit" class="button small submitBtn reposition" name="modify" data-index="'.$key.'" value="'.dol_escape_htmltag($langs->trans("Save")).'"/>';
|
||||
$out .= ' ';
|
||||
|
||||
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
|
||||
|
|
|
|||
|
|
@ -176,17 +176,22 @@ $out = '';
|
|||
if ($functioncode) {
|
||||
$labeloffeature = empty($arrayofaifeatures[GETPOST('functioncode')]['label']) ? 'Undefined' : $arrayofaifeatures[GETPOST('functioncode')]['label'];
|
||||
|
||||
$out .= $langs->trans("Test").' '.$labeloffeature.'...<br><br>';
|
||||
//$out .= $langs->trans("Test").' '.$labeloffeature.'...<br><br>';
|
||||
|
||||
if (GETPOST('functioncode') == 'textgenerationemail') {
|
||||
$showlinktoai = 1;
|
||||
$key = 'textgenerationemail'; // The HTML ID of field to fill
|
||||
|
||||
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;
|
||||
|
||||
// Fill $out
|
||||
include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php';
|
||||
|
||||
$neweditor = new DolEditor('aicontenttotest', $content);
|
||||
$out .= $neweditor->Create(1);
|
||||
|
||||
$out .= $form->buttonsSaveCancel("Test");
|
||||
$out .= '<div id="'.$key.'"></div>';
|
||||
} else {
|
||||
$out .= $langs->trans("FeatureNotYetAvailable").'<br><br>';
|
||||
$functioncode = '';
|
||||
|
|
|
|||
|
|
@ -81,15 +81,17 @@ $format = empty($jsonData['format']) ? '' : $jsonData['format'];
|
|||
|
||||
$generatedContent = $ai->generateContent($instructions, 'auto', $function, $format);
|
||||
|
||||
if (is_array($generatedContent) && $generatedContent['error']) {
|
||||
if (is_null($generatedContent) || (is_array($generatedContent) && $generatedContent['error'])) {
|
||||
// Output error
|
||||
if (!empty($generatedContent['code']) && $generatedContent['code'] == 429) {
|
||||
print "Quota or allowed period exceeded. Retry Later !";
|
||||
} elseif ($generatedContent['code'] >= 400) {
|
||||
} elseif (!empty($generatedContent['code']) && $generatedContent['code'] >= 400) {
|
||||
print "Error : " . $generatedContent['message'];
|
||||
print '<br><a href="'.DOL_MAIN_URL_ROOT.'/ai/admin/setup.php">'.$langs->trans('ErrorGoToModuleSetup').'</a>';
|
||||
} else {
|
||||
} elseif (!empty($generatedContent['message'])) {
|
||||
print "Error returned by API call: " . $generatedContent['message'];
|
||||
} else {
|
||||
print "Error API returned no answer";
|
||||
}
|
||||
} else {
|
||||
if ($function == 'textgenerationemail' || $function == 'textgenerationwebpage') {
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ class Ai
|
|||
*/
|
||||
public function generateContent($instructions, $model = 'auto', $function = 'textgeneration', $format = '')
|
||||
{
|
||||
global $dolibarr_main_data_root;
|
||||
|
||||
if (empty($this->apiKey)) {
|
||||
return array('error' => true, 'message' => 'API key is not defined for the AI enabled service ('.$this->apiService.')');
|
||||
}
|
||||
|
|
@ -199,7 +201,7 @@ class Ai
|
|||
$postPrompt = $configurations[$function]['postPrompt'];
|
||||
}
|
||||
}
|
||||
$fullInstructions = ($prePrompt ? $prePrompt.' ' : '').$instructions.($postPrompt ? '. '.$postPrompt : '');
|
||||
$fullInstructions = $instructions.($postPrompt ? (preg_match('/[\.\!\?]$/', $instructions) ? '' : '.').' '.$postPrompt : '');
|
||||
|
||||
// Set payload string
|
||||
/*{
|
||||
|
|
@ -224,18 +226,46 @@ class Ai
|
|||
"temperature": 0.7,
|
||||
"top_p": 0.95
|
||||
}*/
|
||||
$payload = json_encode([
|
||||
'messages' => [
|
||||
['role' => 'user', 'content' => $fullInstructions]
|
||||
],
|
||||
'model' => $model,
|
||||
//'stream' => false
|
||||
]);
|
||||
|
||||
$headers = ([
|
||||
$arrayforpayload = array(
|
||||
'messages' => array(array('role' => 'user', 'content' => $fullInstructions)),
|
||||
'model' => $model,
|
||||
);
|
||||
|
||||
// Add a system message
|
||||
$addDateTimeContext = 0;
|
||||
if ($addDateTimeContext) {
|
||||
$prePrompt = ($prePrompt ? $prePrompt.(preg_match('/[\.\!\?]$/', $prePrompt) ? '' : '.').' ' : '').'Today we are '.dol_print_date(dol_now(), 'dayhourtext');
|
||||
}
|
||||
$arrayforpayload['messages'][] = array('role' => 'system', 'content' => $prePrompt);
|
||||
|
||||
/*
|
||||
$arrayforpayload['temperature'] = 0.7;
|
||||
$arrayforpayload['max_tokens'] = -1;
|
||||
$arrayforpayload['stream'] = false;
|
||||
*/
|
||||
|
||||
$payload = json_encode($arrayforpayload);
|
||||
|
||||
$headers = array(
|
||||
'Authorization: Bearer ' . $this->apiKey,
|
||||
'Content-Type: application/json'
|
||||
]);
|
||||
);
|
||||
|
||||
if (getDolGlobalString("AI_DEBUG")) {
|
||||
if (@is_writable($dolibarr_main_data_root)) { // Avoid fatal error on fopen with open_basedir
|
||||
$outputfile = $dolibarr_main_data_root."/dolibarr_ai.log";
|
||||
$fp = fopen($outputfile, "w"); // overwrite
|
||||
|
||||
if ($fp) {
|
||||
fwrite($fp, var_export($headers, true)."\n");
|
||||
fwrite($fp, var_export($payload, true)."\n");
|
||||
|
||||
fclose($fp);
|
||||
dolChmod($outputfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$localurl = 2; // Accept both local and external endpoints
|
||||
$response = getURLContent($this->apiEndpoint, 'POST', $payload, 1, $headers, array('http', 'https'), $localurl);
|
||||
|
|
@ -248,7 +278,17 @@ class Ai
|
|||
}
|
||||
|
||||
if (getDolGlobalString("AI_DEBUG")) {
|
||||
dol_syslog("response content = ".var_export($response['content'], true));
|
||||
if (@is_writable($dolibarr_main_data_root)) { // Avoid fatal error on fopen with open_basedir
|
||||
$outputfile = $dolibarr_main_data_root."/dolibarr_ai.log";
|
||||
$fp = fopen($outputfile, "a");
|
||||
|
||||
if ($fp) {
|
||||
fwrite($fp, var_export((empty($response['content']) ? 'No content result' : $response['content']), true)."\n");
|
||||
|
||||
fclose($fp);
|
||||
dolChmod($outputfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Decode JSON response
|
||||
|
|
|
|||
|
|
@ -1483,24 +1483,26 @@ class CMailFile
|
|||
$outputfile = $dolibarr_main_data_root."/dolibarr_mail.log";
|
||||
$fp = fopen($outputfile, "w"); // overwrite
|
||||
|
||||
if ($this->sendmode == 'mail') {
|
||||
fwrite($fp, $this->headers);
|
||||
fwrite($fp, $this->eol); // This eol is added by the mail function, so we add it in log
|
||||
fwrite($fp, $this->message);
|
||||
} elseif ($this->sendmode == 'smtps') {
|
||||
fwrite($fp, $this->smtps->log); // this->smtps->log is filled only if MAIN_MAIL_DEBUG was set to on
|
||||
} elseif ($this->sendmode == 'swiftmailer') {
|
||||
fwrite($fp, "smtpheader=\n".$this->message->getHeaders()->toString()."\n");
|
||||
fwrite($fp, $this->logger->dump()); // this->logger is filled only if MAIN_MAIL_DEBUG was set to on
|
||||
}
|
||||
if ($fp) {
|
||||
if ($this->sendmode == 'mail') {
|
||||
fwrite($fp, $this->headers);
|
||||
fwrite($fp, $this->eol); // This eol is added by the mail function, so we add it in log
|
||||
fwrite($fp, $this->message);
|
||||
} elseif ($this->sendmode == 'smtps') {
|
||||
fwrite($fp, $this->smtps->log); // this->smtps->log is filled only if MAIN_MAIL_DEBUG was set to on
|
||||
} elseif ($this->sendmode == 'swiftmailer') {
|
||||
fwrite($fp, "smtpheader=\n".$this->message->getHeaders()->toString()."\n");
|
||||
fwrite($fp, $this->logger->dump()); // this->logger is filled only if MAIN_MAIL_DEBUG was set to on
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
dolChmod($outputfile);
|
||||
fclose($fp);
|
||||
dolChmod($outputfile);
|
||||
|
||||
// Move dolibarr_mail.log into a dolibarr_mail.log.v123456789
|
||||
if (getDolGlobalInt('MAIN_MAIL_DEBUG_LOG_WITH_DATE')) {
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
||||
archiveOrBackupFile($outputfile, getDolGlobalInt('MAIN_MAIL_DEBUG_LOG_WITH_DATE'));
|
||||
// Move dolibarr_mail.log into a dolibarr_mail.log.v123456789
|
||||
if (getDolGlobalInt('MAIN_MAIL_DEBUG_LOG_WITH_DATE')) {
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
||||
archiveOrBackupFile($outputfile, getDolGlobalInt('MAIN_MAIL_DEBUG_LOG_WITH_DATE'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1493,6 +1493,7 @@ class FormMail extends Form
|
|||
* @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
|
||||
* TODO Move into a file html.formai.class.php
|
||||
*/
|
||||
public function getSectionForAIPrompt($function = 'textgeneration', $format = '', $htmlContent = 'message')
|
||||
{
|
||||
|
|
@ -1502,7 +1503,7 @@ class FormMail extends Form
|
|||
|
||||
$htmlContent = preg_replace('/[^a-z0-9_]/', '', $htmlContent);
|
||||
|
||||
$out = '<div id="ai_input'.$htmlContent.'" class="hidden paddingtop paddingbottom">';
|
||||
$out = '<div id="ai_input'.$htmlContent.'" class="ai_input'.$htmlContent.' hidden paddingtop paddingbottom">';
|
||||
$out .= '<input type="text" class="quatrevingtpercent" id="ai_instructions'.$htmlContent.'" name="instruction" placeholder="'.$langs->trans("EnterYourAIPromptHere").'..." />';
|
||||
$out .= '<input id="generate_button'.$htmlContent.'" type="button" class="button smallpaddingimp" value="'.$langs->trans('Generate').'"/>';
|
||||
$out .= '<div id="ai_status_message'.$htmlContent.'" class="fieldrequired hideobject marginrightonly margintoponly">';
|
||||
|
|
@ -1526,7 +1527,7 @@ class FormMail extends Form
|
|||
});
|
||||
|
||||
$('#generate_button".$htmlContent."').click(function() {
|
||||
console.log('We click on generate_button".$htmlContent." ai button');
|
||||
console.log('We click on generate_button".$htmlContent." ai button, so we make an ajax on url /ai/ajax/generate_content.php');
|
||||
|
||||
var instructions = $('#ai_instructions".$htmlContent."').val();
|
||||
var timeoutfinished = 0;
|
||||
|
|
@ -1659,7 +1660,7 @@ class FormMail extends Form
|
|||
$websitepage = new WebsitePage($this->db);
|
||||
$arrayofblogs = $websitepage->fetchAll('', 'DESC', 'date_creation', 0, 0, array('type_container' => 'blogpost'));
|
||||
|
||||
$out = '<div id="template-selector" class="email-layout-container hidden" style="display:none;">';
|
||||
$out = '<div id="template-selector" class="template-selector email-layout-container hidden" style="display:none;">';
|
||||
|
||||
// Define list of email layouts to use
|
||||
$layouts = array(
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ if (!isset($out)) { // Init to empty string if not defined
|
|||
}
|
||||
|
||||
// Add link to add layout
|
||||
if ($showlinktolayout) {
|
||||
if ($showlinktolayout) { // May be set only if MAIN_EMAIL_USE_LAYOUT is set
|
||||
$out .= '<a href="#" id="linkforlayouttemplates" class="notasortlink inline-block alink marginrightonly">';
|
||||
$out .= img_picto($showlinktolayoutlabel, 'layout', 'class="paddingrightonly"');
|
||||
$out .= $showlinktolayoutlabel.'...';
|
||||
|
|
@ -69,10 +69,10 @@ if ($showlinktolayout) {
|
|||
$out .= '<script>
|
||||
$(document).ready(function() {
|
||||
$("#linkforlayouttemplates").click(function() {
|
||||
console.log("We click on linkforlayouttemplates");
|
||||
console.log("We click on linkforlayouttemplates, we toggle .template-selector");
|
||||
event.preventDefault();
|
||||
jQuery("#template-selector").toggle();
|
||||
jQuery("#ai_input'.$htmlname.'").hide();
|
||||
jQuery(".template-selector").toggle();
|
||||
jQuery(".ai_input'.$htmlname.'").hide();
|
||||
jQuery("#pageContent").show(); // May exists for website page only
|
||||
});
|
||||
});
|
||||
|
|
@ -89,10 +89,10 @@ if ($showlinktoai) {
|
|||
$out .= '<script>
|
||||
$(document).ready(function() {
|
||||
$("#linkforaiprompt'.$showlinktoai.'").click(function() {
|
||||
console.log("formlayoutai.tpl: We click on linkforaiprompt'.$showlinktoai.', we toggle #ai_input'.$showlinktoai.'");
|
||||
console.log("formlayoutai.tpl: We click on linkforaiprompt'.$showlinktoai.', we toggle .ai_input'.$showlinktoai.'");
|
||||
event.preventDefault();
|
||||
jQuery("#ai_input'.$htmlname.'").toggle();
|
||||
jQuery("#template-selector").hide();
|
||||
jQuery(".ai_input'.$htmlname.'").toggle();
|
||||
jQuery(".template-selector").hide();
|
||||
jQuery(".email-layout-container").hide();
|
||||
if (!jQuery("#ai_input'.$htmlname.'").is(":hidden")) {
|
||||
console.log("Set focus on input field #ai_instructions'.$htmlname.'");
|
||||
|
|
|
|||
|
|
@ -2614,3 +2614,4 @@ Privileges=Privileges
|
|||
FieldsLinked=Fields Linked
|
||||
PDF_XXX_SHOW_PRICE_INCL_TAX=Show column Price including tax
|
||||
AvailableWithSomePDFTemplatesOnly=Feature not supported on old PDF templates
|
||||
SelectFeatureToTest=Select the feature to test
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user