41require
'../../main.inc.php';
51require_once DOL_DOCUMENT_ROOT .
'/core/lib/admin.lib.php';
52require_once DOL_DOCUMENT_ROOT .
'/core/class/html.form.class.php';
53require_once DOL_DOCUMENT_ROOT .
'/ai/lib/ai.lib.php';
54require_once DOL_DOCUMENT_ROOT .
'/ai/class/mcp.class.php';
55require_once DOL_DOCUMENT_ROOT .
'/core/lib/functions2.lib.php';
57$langs->loadLangs(array(
'admin',
'other',
'main'));
68$action =
GETPOST(
'action',
'aZ09');
69$toolcontext =
GETPOST(
'toolcontext',
'alpha');
70$toolname =
GETPOST(
'toolname',
'alpha');
71$mode =
GETPOST(
'mode',
'alpha');
72$backtopage =
GETPOST(
'backtopage',
'alpha');
76$unfilteredSchema = $mcpHandler->getToolsSchemaUnfiltered();
79$allDiscoveredTools = array();
80$groupedNormalTools = array();
81$groupedSystemTools = array();
83if (!empty($unfilteredSchema) && is_array($unfilteredSchema)) {
84 foreach ($unfilteredSchema as $def) {
86 $isSystem = !empty($def[
'is_system']);
87 $classNameKey = !empty($def[
'class_name']) ? (
string) $def[
'class_name'] :
'DefaultTools';
90 $allDiscoveredTools[] = $name;
91 $groupedNormalTools[$classNameKey][] = $def;
93 $groupedSystemTools[$classNameKey][] = $def;
107if ($action ==
'addrights' || $action ==
'delrights') {
108 if (
GETPOST(
'token',
'alpha') !== $_SESSION[
'token']) {
112 if (!empty($toolcontext) && !empty($toolname)) {
113 if ($toolcontext ===
'ast') {
114 if ($action ==
'addrights') {
115 if (!in_array($toolname, $astAllowed,
true)) {
116 $astAllowed[] = $toolname;
119 $astAllowed = array_values(array_diff($astAllowed, array($toolname)));
121 $val = empty($astAllowed) ?
'NONE' : implode(
',', $astAllowed);
125 if ($toolcontext ===
'mcp') {
126 if ($action ==
'addrights') {
127 if (!in_array($toolname, $mcpAllowed,
true)) {
128 $mcpAllowed[] = $toolname;
131 $mcpAllowed = array_values(array_diff($mcpAllowed, array($toolname)));
133 $val = empty($mcpAllowed) ?
'NONE' : implode(
',', $mcpAllowed);
138 header(
'Location: ' . $_SERVER[
'PHP_SELF']);
142if ($action ==
'apply_preset' && !empty($toolcontext) && !empty($mode)) {
143 if (
GETPOST(
'token',
'alpha') !== $_SESSION[
'token']) {
147 $resultSet = array();
149 if ($mode ===
'all') {
150 $resultSet = $allDiscoveredTools;
151 } elseif ($mode ===
'none') {
152 $resultSet = array();
153 } elseif ($mode ===
'readonly') {
154 foreach ($allDiscoveredTools as $tName) {
158 if (!preg_match(
'/^(create|update|delete|add|remove|change|write|edit|validate|pay|send)/i', $tName)) {
159 $resultSet[] = $tName;
164 $val = empty($resultSet) ?
'NONE' : implode(
',', $resultSet);
165 $constTarget = ($toolcontext ===
'mcp') ?
'AI_MCP_SERVER_ALLOWED_TOOLS' :
'AI_ASSISTANT_ALLOWED_TOOLS';
168 header(
'Location: ' . $_SERVER[
'PHP_SELF']);
178llxHeader(
'', $langs->trans($title),
'',
'', 0, 0, array(
dol_buildpath(
'/ai/js/ai.js', 1)), array(
dol_buildpath(
'/ai/css/ai.css', 1)),
'',
'mod-ai page-admin');
180$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>';
187print
'<span class="opacitymedium">' . $langs->trans(
"ToolAccessControlHelp") .
'</span><br><br>';
189print
'<div class="marginleftonly" style="display:flex; flex-wrap:wrap; gap:40px; margin-top:15px; padding-top:15px; border-top:1px solid #ddd;">';
193print
'<strong>' . $langs->trans(
'PresetsForChatAssistant') .
':</strong><br>';
194print
'<a class="button" href="' .
dolBuildUrl($_SERVER[
'PHP_SELF'], array(
'action' =>
'apply_preset',
'toolcontext' =>
'ast',
'mode' =>
'all'),
true) .
'" style="margin:4px 2px;">' . $langs->trans(
'AllTools') .
'</a>';
195print
'<a class="button" href="' .
dolBuildUrl($_SERVER[
'PHP_SELF'], array(
'action' =>
'apply_preset',
'toolcontext' =>
'ast',
'mode' =>
'readonly'),
true) .
'" style="margin:4px 2px;">' . $langs->trans(
'ViewOnly') .
'</a>';
196print
'<a class="button" href="' .
dolBuildUrl($_SERVER[
'PHP_SELF'], array(
'action' =>
'apply_preset',
'toolcontext' =>
'ast',
'mode' =>
'none'),
true) .
'" style="margin:4px 2px;">' . $langs->trans(
'None') .
'</a>';
201print
'<strong>' . $langs->trans(
'PresetsForMcpServer') .
':</strong><br>';
202print
'<a class="button" href="' .
dolBuildUrl($_SERVER[
'PHP_SELF'], array(
'action' =>
'apply_preset',
'toolcontext' =>
'mcp',
'mode' =>
'all'),
true) .
'" style="margin:4px 2px;">' . $langs->trans(
'AllTools') .
'</a>';
203print
'<a class="button" href="' .
dolBuildUrl($_SERVER[
'PHP_SELF'], array(
'action' =>
'apply_preset',
'toolcontext' =>
'mcp',
'mode' =>
'readonly'),
true) .
'" style="margin:4px 2px;">' . $langs->trans(
'ViewOnly') .
'</a>';
204print
'<a class="button" href="' .
dolBuildUrl($_SERVER[
'PHP_SELF'], array(
'action' =>
'apply_preset',
'toolcontext' =>
'mcp',
'mode' =>
'none'),
true) .
'" style="margin:4px 2px;">' . $langs->trans(
'None') .
'</a>';
211print
'<div class="div-table-responsive-no-min">';
212print
'<table class="noborder centpercent" id="toolsTable">';
213print
'<tr class="liste_titre">';
214print
'<td class="tdoverflowmax200" style="min-width: 130px;">' . $langs->trans(
'Tool') .
'</td>';
215print
'<td class="center" style="min-width: 60px;">' . $langs->trans(
'ToolActionType') .
'</td>';
216print
'<td class="hideonsmartphone">' . $langs->trans(
'ToolDescription') .
'</td>';
217print
'<td class="center nowraponall">' . $langs->trans(
'ChatAssistant') .
'</td>';
218print
'<td class="center nowraponall">' . $langs->trans(
'McpServer') .
'</td>';
221if (empty($groupedNormalTools) && empty($groupedSystemTools)) {
222 print
'<tr class="oddeven"><td colspan="5" class="opacitymedium">' . $langs->trans(
'NoMcpToolsDiscovered') .
'</td></tr>';
225 $finalGroupsList = array_merge($groupedNormalTools, $groupedSystemTools);
227 foreach ($finalGroupsList as $categoryName => $definitions) {
230 print
'<tr class="trgroup" data-group="group-' . $groupId .
'">';
231 print
'<td colspan="5" class="mcp-trigger-collapse" style="cursor:pointer;">';
236 foreach ($definitions as $def) {
237 $name = $def[
'name'];
238 $desc = !empty($def[
'description']) ? $def[
'description'] :
'-';
239 $isSystem = !empty($def[
'is_system']);
241 $isAstOn = $isSystem ? true : in_array($name, $astAllowed,
true);
242 $isMcpOn = $isSystem ? true : in_array($name, $mcpAllowed,
true);
244 if (preg_match(
'/^(create|update|delete|add|remove|change|write|edit|validate|pay|send)/i', $name)) {
246 $typeBadge =
'<span class="badge badge-status2" style="display: inline-block;">' . $langs->trans(
'Modify') .
'</span>';
249 $typeBadge =
'<span class="badge badge-status4" style="display: inline-block;">' . $langs->trans(
'ViewOnly') .
'</span>';
252 print
'<tr class="oddeven group-' . $groupId .
'" data-tool-name="' .
dol_escape_htmltag($name) .
'" data-tool-type="' . $type .
'">';
255 print
'<td style="padding-left:20px; min-width: 130px; word-break: break-all;" class="tdoverflowmax200">';
258 print
'<br><span class="badgeneutral">' . $langs->trans(
'System') .
'</span>';
263 print
'<td class="center">' . $typeBadge .
'</td>';
266 print
'<td class="small opacitymedium hideonsmartphone">' .
dol_escape_htmltag($desc) .
'</td>';
268 $lockCssClass = $isSystem ?
' opacitymedium disabled' :
'';
271 print
'<td class="center nowraponall">';
273 print
img_picto($langs->trans(
'Active'),
'switch_on',
'', 0, 0, 0,
'',
'opacitymedium');
275 $actAst = $isAstOn ?
'delrights' :
'addrights';
276 $pictoAst = $isAstOn ?
'switch_on'.($type ==
'write' ?
'_warning' :
'') :
'switch_off';
279 'toolcontext' =>
'ast',
283 print
'<a class="ctx-ast-link reposition' . $lockCssClass .
'" href="' . $urlAst .
'">';
284 print
img_picto($langs->trans($isAstOn ?
'Remove' :
'Add'), $pictoAst,
'', 0, 0, 0,
'', !$isAstOn ?
'font-status6' : ($type ==
'write' ?
'font-status2' :
'font-status4'));
290 print
'<td class="center nowraponall">';
292 print
img_picto($langs->trans(
'Active'),
'switch_on',
'', 0, 0, 0,
'',
'opacitymedium');
294 $actMcp = $isMcpOn ?
'delrights' :
'addrights';
295 $pictoMcp = $isMcpOn ?
'switch_on'.($type ==
'write' ?
'_warning' :
'') :
'switch_off';
298 'toolcontext' =>
'mcp',
302 print
'<a class="ctx-mcp-link reposition' . $lockCssClass .
'" href="' . $urlMcp .
'">';
303 print
img_picto($langs->trans($isMcpOn ?
'Remove' :
'Add'), $pictoMcp,
'', 0, 0, 0,
'', !$isMcpOn ?
'font-status6' : ($type ==
'write' ?
'font-status2' :
'font-status4'));
308 print
'</tr>' .
"\n";
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).
aiAdminPrepareHead()
Prepare admin pages header.
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 handle MCP (Model Context Protocol).
static resolveAllowList($raw, $allDiscoveredTools)
Resolves a raw allow-list constant value into an explicit PHP array of tool names.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
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.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.