providerInfo = $providerInfo;
$this->settingsService = $settingsService;
add_action('admin_bar_menu', [$this, 'addToolbarNode'], 100);
add_action('admin_enqueue_scripts', [$this, 'enqueueAssets']);
add_action('admin_footer', [$this, 'renderRoot']);
}
/**
* Adds the chat icon to the admin bar.
*
* @param WP_Admin_Bar $wp_admin_bar The admin bar instance.
*
* @return void
* @since 1.0.0
*/
public function addToolbarNode(WP_Admin_Bar $wp_admin_bar): void
{
if (! is_admin() || ! current_user_can('manage_options')) {
return;
}
// Hide the icon on the AgentMod admin page itself.
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only URL parameter check to determine current admin page; no form data is processed.
$current_page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : '';
if ('agent-mod' === $current_page) {
return;
}
$iconUrl = esc_url(AGENT_MOD_URL . 'includes/Presentation/Admin/Assets/img/agent_mod_icon.png');
$title = '
'
. '' . esc_html__('Assistant', 'agent-mod') . '';
$wp_admin_bar->add_node(
[
'id' => self::NODE_ID,
'title' => $title,
'href' => '#',
'meta' => [
'title' => esc_attr__('Open AgentMod Assistant', 'agent-mod'),
],
]
);
}
/**
* Enqueues the widget script and styles, plus localized config.
*
* @return void
* @since 1.0.0
*/
public function enqueueAssets(): void
{
if (! current_user_can('manage_options')) {
return;
}
$asset_path = AGENT_MOD_PATH . 'build/admin-chat/index.asset.php';
// Silently bail if the widget has not been built yet.
if (! is_readable($asset_path)) {
return;
}
$asset = require $asset_path;
wp_enqueue_script(
self::HANDLE,
AGENT_MOD_URL . 'build/admin-chat/index.js',
$asset['dependencies'],
$asset['version'],
true
);
wp_enqueue_style('wp-components');
wp_enqueue_style(
self::HANDLE,
AGENT_MOD_URL . 'build/admin-chat/style-index.css',
['wp-components'],
$asset['version']
);
$defaultModel = $this->settingsService->getDefaultModel();
wp_localize_script(
self::HANDLE,
'agentModChat',
[
'restPath' => Constants::REST_NAMESPACE . '/chat',
'restNamespace' => Constants::REST_NAMESPACE,
'connectorsUrl' => SetupController::pageUrl('provider'),
'defaultAgent' => [
'id' => null,
'name' => __('AgentMod Assistant', 'agent-mod'),
'description' => __('Uses the AgentMod settings configuration.', 'agent-mod'),
'avatar' => AGENT_MOD_URL . 'includes/Presentation/Admin/Assets/img/agent_mod_colored_icon.png',
],
'attachments' => [
'maxBytes' => $this->settingsService->getAttachmentMaxBytes(),
'maxCount' => $this->settingsService->getAttachmentMaxCount(),
'mimeTypes' => $this->settingsService->getAttachmentMimeTypes(),
],
'defaults' => [
'siteContextEnabled' => $this->settingsService->isSiteContextEnabled(),
'abilitySource' => $this->settingsService->getAbilitySource(),
'selectedAbilities' => $this->settingsService->getAllowedAbilitiesDetailed(),
// Split into two keys so the model picker can pre-select the
// pair without re-parsing the stored ":".
'defaultProvider' => $defaultModel['provider'],
'defaultModel' => $defaultModel['model'],
],
'presetPrompts' => $this->settingsService->getPresetPrompts(),
'strings' => [
'title' => __('AgentMod Chat', 'agent-mod'),
'placeholder' => __('Type your messageā¦', 'agent-mod'),
'send' => __('Send', 'agent-mod'),
'stop' => __('Stop', 'agent-mod'),
'error' => __('An unexpected error occurred.', 'agent-mod'),
'attach' => __('Attach files', 'agent-mod'),
'removeAttachment' => __('Remove attachment', 'agent-mod'),
/* translators: %s: file name. */
'fileTooLarge' => __('"%s" is too large.', 'agent-mod'),
/* translators: %s: file name. */
'fileTypeNotAllowed' => __('"%s" is not an allowed file type.', 'agent-mod'),
/* translators: %d: maximum number of files allowed. */
'tooManyFiles' => __('You can attach up to %d files.', 'agent-mod'),
],
]
);
}
/**
* Renders the React root container in the admin footer.
*
* @return void
* @since 1.0.0
*/
public function renderRoot(): void
{
if (! current_user_can('manage_options')) {
return;
}
echo '';
}
}