Skip to content

AI Assistant API

When to Use

Use this guide when creating AI assistants, writing custom action plugins, or calling the runner programmatically. Use AI Chatbot for the frontend chatbot configuration.

Decision

Situation Choose Why
Add capability to assistant Action plugin Actions are composable and config-driven
Use tool calling vs prompts use_function_calling: true Requires action to implement getFunctionCallSchema()
Allow conversation history allow_history: session Persists thread in PrivateTempStore
Delegate to an agent Set ai_agent on entity AgentRunner handles the autonomous loop

Pattern

$runner = \Drupal::service('ai_assistant_api.runner');
$assistant = \Drupal::entityTypeManager()->getStorage('ai_assistant')->load('my_assistant');

$runner->setAssistant($assistant);
$runner->setUserMessage(new UserMessage('Hello'));
$runner->setContext(['route' => '/node/1']);
$runner->streamedOutput(FALSE);

$output = $runner->process(); // ChatOutput
$text = $output->getNormalized()->getText();

Config Entity: ai_assistant

Admin UI: /admin/config/ai/ai-assistant

Field Description
llm_provider Provider plugin ID or __default__
system_prompt Final system prompt (supports tokens)
allow_history none, session, session_one_thread
history_context_length Messages to include in context
use_function_calling Use tool calling instead of prompt-based action selection
ai_agent Optional agent plugin ID (delegates to AgentRunner)
roles Roles that can use this assistant

System Prompt Tokens

[instructions], [pre_action_prompt], [is_logged_in], [user_roles], [user_id], [user_name], [page_title], [page_path], [site_name]

Writing a Custom Action

use Drupal\ai_assistant_api\Attribute\AiAssistantAction;
use Drupal\ai_assistant_api\Base\AiAssistantActionBase;

#[AiAssistantAction(
  id: 'my_module_search',
  label: new TranslatableMarkup('My Search Action'),
)]
class MySearchAction extends AiAssistantActionBase {

  public function listActions(): array {
    return [[
      'id' => 'search',
      'label' => 'Search',
      'description' => 'Search the knowledge base',
      'plugin' => 'my_module_search',
    ]];
  }

  public function triggerAction(string $action_id, array $params = []): void {
    $results = $this->doSearch($params);
    $this->setOutputContext('my_module_search', json_encode($results));
  }

  public function listContexts(): array { return []; }
  public function listUsageInstructions(): array {
    return ['Use search to find relevant content.'];
  }
  public function provideFewShotLearningExample(): array { return []; }
}

Runner Methods

Method Purpose
setVerboseMode(TRUE) Show intermediate agent steps in output
setThrowException(TRUE) Throw exceptions instead of returning error messages
getMessageHistory() Returns current thread's conversation history
resetThread() Clears the current thread from PrivateTempStore

Events

Event Purpose
AiAssistantSystemRoleEvent Alter final system prompt
PrepromptSystemRoleEvent Alter pre-action prompt
AiAssistantPassContextToAgentEvent Inject context into agent

Common Mistakes

  • Wrong: Missing id, label, description, plugin keys in listActions()Right: All four keys are required
  • Wrong: Setting allow_history: session with a large history_context_lengthRight: Large histories consume tokens; set conservatively
  • Wrong: Using use_function_calling with providers that don't support tools → Right: Falls back to prompt-based selection, which may be unreliable

See Also