30require
'../../main.inc.php';
39require_once DOL_DOCUMENT_ROOT .
"/core/lib/admin.lib.php";
40require_once DOL_DOCUMENT_ROOT .
"/core/class/html.form.class.php";
41require_once DOL_DOCUMENT_ROOT .
"/core/class/doleditor.class.php";
42require_once DOL_DOCUMENT_ROOT .
"/ai/lib/ai.lib.php";
43require_once DOL_DOCUMENT_ROOT .
"/core/lib/functions2.lib.php";
44require_once DOL_DOCUMENT_ROOT .
"/core/lib/security.lib.php";
47$langs->loadLangs(array(
"admin",
"website",
"other"));
58$action =
GETPOST(
'action',
'aZ09');
59$backtopage =
GETPOST(
'backtopage',
'alpha');
67if ($action ==
'update') {
72 if ($res <= 0) $error++;
104 setEventMessages($langs->trans(
"ErrorSavingSettings"),
null,
'errors');
106 setEventMessages($langs->trans(
"SetupSaved"),
null,
'mesgs');
109 header(
"Location: ".$_SERVER[
"PHP_SELF"].
"?mainmenu=home");
114if ($action ==
'test_provider') {
115 $service =
GETPOST(
'service_key',
'aZ09');
121 if (preg_match(
'/^crypted:/', $credential)) {
122 $credential =
dol_decode(substr($credential, 8));
123 } elseif (preg_match(
'/^dolcrypt:/', $credential)) {
128 if ($credential !==
null) {
131 if ($res[
'success']) {
132 setEventMessages($langs->trans(
"ConnectionSuccessful") . $res[
'message'],
null,
'mesgs');
134 setEventMessages($langs->trans(
"ConnectionFailed") . $res[
'message'],
null,
'errors');
141if ($action ==
'update_external') {
153 setEventMessages($langs->trans(
"ErrorSavingSettings"),
null,
'errors');
155 setEventMessages($langs->trans(
"SetupSaved"),
null,
'mesgs');
158 header(
"Location: ".$_SERVER[
"PHP_SELF"].
"?mainmenu=home");
163if ($action ==
'generate_key') {
166 if (empty($newKey)) {
167 setEventMessages($langs->trans(
"KeyGenerationFailed"),
null,
'errors');
170 setEventMessages($langs->trans(
"KeyGenerationSuccessfull"),
null,
'mesgs');
172 setEventMessages($langs->trans(
"KeySaveFailed"),
null,
'errors');
185llxHeader(
'', $langs->trans($title),
$help_url,
'', 0, 0,
'',
'',
'',
'mod-ai page-admin');
187$linkback =
'<a href="'.($backtopage ? $backtopage : DOL_URL_ROOT.
'/admin/modules.php?restore_lastsearch_values=1').
'">'.img_picto($langs->trans(
"BackToModuleList"),
'back',
'class="pictofixedwidth"').
'<span class="hideonsmartphone">'.$langs->trans(
"BackToModuleList").
'</span></a>';
197$form =
new Form($db);
203$defaultPromptText =
" ROLE: Dolibarr ERP AI.
204GOAL: Map user intent to specific JSON commands.
2071. OUTPUT: Single valid JSON object ONLY. No Markdown. No text.
208 Format: {\"tool\": \"tool_name\", \"arguments\": {\"argument_name\": \"argument_value\", ...}}
2092. TOOLS: Use ONLY provided tools. If no tool or thirdparty fits, you must first use 'respond_to_user' to inform user.
2103. ARGS: strict adherence to schema. Do not invent parameters.
2114. MISSING INFO: If a required argument (like an ID) is missing, use 'ask_for_clarification'.
2125. SAFETY: For DELETE/UPDATE actions, you MUST use 'ask_for_confirmation'.";
217print
'<div class="neutral">';
223print $form->textwithpicto($langs->trans(
'EnableAssistant'), $langs->trans(
'DisableAssistant'));
227print ajax_constantonoff(
'AI_ASSISTANT_ENABLED', array(),
null, 0, 0, 1);
239 print
load_fiche_titre($langs->trans(
"PrivateModeTitle"),
'',
'fas fa-lock');
241 print
'<form method="POST" action="'.$_SERVER[
"PHP_SELF"].
'">';
242 print
'<input type="hidden" name="token" value="'.newToken().
'">';
243 print
'<input type="hidden" name="action" value="update">';
245 print
'<div class="div-table-responsive-no-min">';
246 print
'<table class="noborder centpercent">';
249 print
'<tr class="oddeven">';
251 print $form->textwithpicto(
'Default Interface', $langs->trans(
"InputMethodHelp"));
255 'text' => $langs->trans(
'OptionTextOnly'),
256 'native' => $langs->trans(
'OptionCloudFast') .
' - ' . $langs->trans(
'OptionCloudFasthelp'),
257 'whisper' => $langs->trans(
'OptionWhisperLocal') .
' - ' . $langs->trans(
'OptionWhisperLocalhelp')
259 print $form->selectarray(
'AI_DEFAULT_INPUT_MODE', $input_modes,
getDolGlobalString(
'AI_DEFAULT_INPUT_MODE'), 0, 0, 0);
264 print
'<tr class="oddeven">';
265 print
'<td>' . $langs->trans(
'ObfuscatePIIData') .
'</td>';
267 print ajax_constantonoff(
'AI_PRIVACY_REDACTION');
268 print
' <span class="opacitymedium">' . $langs->trans(
"RedactionHelp") .
'</span>';
273 print
'<tr class="oddeven">';
274 print
'<td>' . $form->textwithpicto($langs->trans(
"AskConfirmation"), $langs->trans(
"AskConfirmationHelp")).
'</td>';
276 $confirmation_options = [
277 '0' => $langs->trans(
"ConfirmNever"),
278 '1' => $langs->trans(
"ConfirmWriteOnly"),
279 '2' => $langs->trans(
"ConfirmAlways")
281 print $form->selectarray(
'AI_ASK_FOR_CONFIRMATION', $confirmation_options,
getDolGlobalInt(
'AI_ASK_FOR_CONFIRMATION', 1), 0, 0, 0);
286 print
'<tr class="oddeven">';
287 print
'<td>' . $form->textwithpicto($langs->trans(
"AIChatTwoStepWrite"), $langs->trans(
"AIChatTwoStepWriteHelp")) .
'</td>';
289 print ajax_constantonoff(
'AI_CHAT_TWO_STEP_WRITE');
294 print
'<tr class="oddeven">';
295 print
'<td>' . $form->textwithpicto($langs->trans(
"AIContextAutoExchanges"), $langs->trans(
"AIContextAutoExchangesHelp")) .
'</td>';
296 print
'<td><input class="width50" type="number" min="0" name="AI_CHAT_CONTEXT_AUTO_EXCHANGES" value="' .
getDolGlobalInt(
'AI_CHAT_CONTEXT_AUTO_EXCHANGES', 0) .
'"></td>';
300 print
'<tr class="oddeven">';
301 print
'<td>' . $langs->trans(
'EnableLogging') .
'</td>';
303 print ajax_constantonoff(
'AI_LOG_REQUESTS');
304 print
' <a href="' . DOL_URL_ROOT .
'/ai/admin/log_viewer.php" target="_blank" style="padding-top: 4px; padding-bottom: 4px;">'.$langs->trans(
"ViewLogs").
'</a>';
308 print
'<tr class="oddeven">';
309 print
'<td>' . $langs->trans(
"LogRetention") .
'</td>';
310 print
'<td><input class="width50" type="number" name="AI_LOG_RETENTION" value="' .
getDolGlobalInt(
'AI_LOG_RETENTION', 30) .
'"> (0 = Forever)</td>';
314 print
'<tr class="oddeven">';
315 print
'<td colspan="2">';
316 print $form->textwithpicto($langs->trans(
"SystemPrompt"), $langs->trans(
"SystemPromptHelp")) .
'<br><br>';
317 $doleditor =
new DolEditor(
'AI_INTENT_PROMPT', $currentPrompt,
'', 250,
'dolibarr_notes',
'In',
false,
false,
true, ROWS_8,
'90%');
318 $doleditor->Create();
325 print
'<div class="center"><input type="submit" class="button" value="'.$langs->trans(
"Save").
'"></div>';
336 print
load_fiche_titre($langs->trans(
"AIProviderConfigTitle"),
'',
'fa fa-plug');
338 if ((
string) $currentService ==
'-1') {
339 print
'<div class="warning">'.$langs->trans(
"NoAIProviderSelected").
' <a href="'.
dol_buildpath(
'/ai/admin/setup.php', 1).
'">'.$langs->trans(
"ConfigureHere").
'</a></div>';
341 print
'<div class="div-table-responsive-no-min">';
342 print
'<table class="noborder centpercent">';
344 print
'<tr class="oddeven"><td class="titlefield">'.$langs->trans(
"AIProvider").
'</td><td>'.$services[$currentService][
'label'].
'</td></tr>';
346 $prefix =
'AI_API_'.strtoupper($currentService);
347 $modelVal =
getDolGlobalString($prefix.
'_MODEL_TEXT', $services[$currentService][
'textgeneration'][
'default']);
349 print
'<tr class="oddeven"><td>'.$langs->trans(
"AI_API_MODEL").
'</td><td>'.$modelVal.
'</td></tr>';
350 print
'</table></div>';
352 print
'<div class="center">';
354 if ($currentService && $currentService !==
'-1') {
355 print
'<a class="reposition button smallpaddingimp" href="'.$_SERVER[
'PHP_SELF'].
'?action=test_provider&token='.
newToken().
'&service_key='.urlencode($currentService).
'">'.$langs->trans(
'TestConnection').
'</a>';
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
testAIConnection(string $service, string $key, string $url)
Tests the connection to an AI service using its API key and URL by sending message "Hello".
aiAdminPrepareHead()
Prepare admin pages header.
getListOfAIServices()
Get list of available ai services.
if( $action=='update') if($action=='test_provider') if( $action=='update_external') if($action=='generate_key') $help_url
ACTIONS.
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Class to manage a WYSIWYG editor.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
dolGetRandomBytes($length)
Return a string of random bytes (hexa string) with length = $length for cryptographic purposes.
dol_decode($chain, $key='1')
Decode a base 64 encoded + specific delta change.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
dolDecrypt($chain, $key='', $patterntotest='')
Decode a string with a symmetric encryption.