';
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 .= '';
} else {
$out .= $langs->trans("FeatureNotYetAvailable").'
';
$functioncode = '';
diff --git a/htdocs/ai/ajax/generate_content.php b/htdocs/ai/ajax/generate_content.php
index 0f1e1f76a92..0cd6a125970 100644
--- a/htdocs/ai/ajax/generate_content.php
+++ b/htdocs/ai/ajax/generate_content.php
@@ -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 ' '.$langs->trans('ErrorGoToModuleSetup').'';
- } 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') {
diff --git a/htdocs/ai/class/ai.class.php b/htdocs/ai/class/ai.class.php
index 922df84dcbb..3f6a5d6eb78 100644
--- a/htdocs/ai/class/ai.class.php
+++ b/htdocs/ai/class/ai.class.php
@@ -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
diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php
index 81efbf470a7..ce57b90a4c7 100644
--- a/htdocs/core/class/CMailFile.class.php
+++ b/htdocs/core/class/CMailFile.class.php
@@ -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'));
+ }
}
}
}
diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php
index 6eac18f33e0..c3904969a64 100644
--- a/htdocs/core/class/html.formmail.class.php
+++ b/htdocs/core/class/html.formmail.class.php
@@ -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 = '
';
+ $out = '
';
$out .= '';
$out .= '';
$out .= '
';
@@ -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 = '