NAME
    RT-Extension-AI - Add various AI Features to Request Tracker

DESCRIPTION
    This RT extension introduces various AI-powered features to RT. AI
    assistance is added via scrips and also interactively through the RT
    editor.

RT VERSION
    Works with RT 6.

INSTALLATION
    perl Makefile.PL
    make
    make install
        May need root permissions

    make initdb
        Only run this the first time you install this module.

        If you run this twice, you may end up with duplicate data in your
        database.

        If you are upgrading this module, check for upgrading instructions
        in case changes need to be made to your database.

    Edit your /opt/rt6/etc/RT_SiteConfig.pm
        Add this line:

            Plugin('RT::Extension::AI');

        See below for additional configuration details.

    Clear your mason cache
            rm -rf /opt/rt6/var/mason_data/obj

    Restart your webserver

CONFIGURATION
    An example configuration file is provided in etc/RT_AI_Config.pm. The
    configuration defines both the details of the service you want to
    connect to and details of the specific features, like prompts for
    different features.

    Here is a sample configuration with Gemini:

        Set( %RT_AI_Provider,
              'Default' => {
                 name    => 'Gemini',
                 api_key => 'YOUR_API_KEY',
                 timeout => 15,
                 url     => 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent',
                 prompts => {
                    summarize_ticket => 'You are a helpdesk assistant. Summarize the ticket conversation precisely. Focus on key points, decisions made, and any follow-up actions required.',
                    assess_sentiment => 'Classify the overall sentiment as Satisfied, Dissatisfied, or Neutral. Provide reasoning if possible.',
                    adjust_tone => 'Paraphrase the text for clarity and professionalism. Ensure the tone is polite, concise, and customer-friendly.',
                    suggest_response => 'Provide clear, practical advice or suggestions based on the given question or scenario.',
                    translate_content => 'Translate the provided text, maintaining accuracy and idiomatic expressions.',
                    autocomplete_text => 'Predict the next three words based on the input text without explanations.',
                    generate_ticketsql => 'You are an expert in Request Tracker (RT) search. Given a natural language description, generate a TicketSQL query to find tickets. If the request references desired columns in the output, also generate a Format string to display the results appropriately. Use the provided TicketSQL and Format grammar references to ensure correctness. Consider what columns would be most useful to display based on the user request.',
                 },
                 editor_features => [ 'adjust_tone', 'suggest_response', 'translate_content', 'autocomplete_text' ],
                 queue_creation_assistant => 1,  # Set to 0 to disable the AI queue creation assistant
                 use_context_files => 0,  # Set to 1 to enable context file usage for suggest_response
                 context_file_path => "$RT::EtcPath/ai/context",  # Directory containing context files
                 suggest_response_context_prompt => "Here are examples of similar previous conversations for context:",  # Text that introduces the context
              },
        );

    Below shows a sample configuration with OpenAI:

        Set( %RT_AI_Provider,
              'Default' => {
                name    => 'OpenAI',
                api_key => 'YOUR_API_KEY',
                timeout => 15,
                url     => 'https://api.openai.com/v1/chat/completions',
                default_model => {
                    name        => 'gpt-4',
                    max_tokens  => 300,
                    temperature => 0.5,
                },
                autocomplete_model => {
                    name        => 'gpt-3.5-turbo',
                    max_tokens  => 20,
                    temperature => 0.7,
                },
                prompts => {
                    summarize_ticket => 'You are a helpdesk assistant. Summarize the ticket conversation precisely. Focus on key points, decisions made, and any follow-up actions required.',
                    assess_sentiment => 'Classify the overall sentiment as Satisfied, Dissatisfied, or Neutral. Provide reasoning if possible.',
                    adjust_tone => 'Paraphrase the text for clarity and professionalism. Ensure the tone is polite, concise, and customer-friendly.',
                    suggest_response => 'Provide clear, practical advice or suggestions based on the given question or scenario.',
                    translate_content => 'Translate the provided text, maintaining accuracy and idiomatic expressions.',
                    autocomplete_text => 'Predict the next three words based on the input text without explanations.',
                    generate_ticketsql => 'You are an expert in Request Tracker (RT) search. Given a natural language description, generate a TicketSQL query to find tickets. If the request references desired columns in the output, also generate a Format string to display the results appropriately. Use the provided TicketSQL and Format grammar references to ensure correctness. Consider what columns would be most useful to display based on the user request.',
                },
                editor_features => [ 'adjust_tone', 'suggest_response', 'translate_content', 'autocomplete_text' ],
                queue_creation_assistant => 1,  # Set to 0 to disable the AI queue creation assistant
                use_context_files => 0,  # Set to 1 to enable context file usage for suggest_response
                context_file_path => "$RT::EtcPath/ai/context",  # Directory containing context files
                suggest_response_context_prompt => "Context: The following are complete conversation histories from similar resolved support tickets. Use these examples to understand typical issue patterns, effective troubleshooting approaches, and professional response tone. Each <Ticket> contains chronological messages between users (customers/requesters) and support staff (privileged users). Apply these patterns to craft an appropriate response:",  # Text that introduces the context
              },
        );

    Below shows a sample configuration with Claude (Anthropic):

        Set( %RT_AI_Provider,
              'Default' => {
                name    => 'Claude',
                api_key => 'YOUR_API_KEY',
                timeout => 30,
                url     => 'https://api.anthropic.com/v1/messages',
                default_model => {
                    name       => 'claude-opus-4-8',
                    max_tokens => 1024,
                    # temperature => 0.5,   # Omit for frontier models (Opus 4.7+),
                                            # which reject temperature with a 400.
                },
                autocomplete_model => {
                    name       => 'claude-haiku-4-5',
                    max_tokens => 20,
                },
                prompts => {
                    summarize_ticket => 'You are a helpdesk assistant. Summarize the ticket conversation precisely. Focus on key points, decisions made, and any follow-up actions required.',
                    assess_sentiment => 'Classify the overall sentiment as Satisfied, Dissatisfied, or Neutral. Provide reasoning if possible.',
                    adjust_tone => 'Paraphrase the text for clarity and professionalism. Ensure the tone is polite, concise, and customer-friendly.',
                    suggest_response => 'Provide clear, practical advice or suggestions based on the given question or scenario.',
                    translate_content => 'Translate the provided text, maintaining accuracy and idiomatic expressions.',
                    autocomplete_text => 'Predict the next three words based on the input text without explanations.',
                    generate_ticketsql => 'You are an expert in Request Tracker (RT) search. Given a natural language description, generate a TicketSQL query to find tickets. If the request references desired columns in the output, also generate a Format string to display the results appropriately. Use the provided TicketSQL and Format grammar references to ensure correctness. Consider what columns would be most useful to display based on the user request.',
                },
                editor_features => [ 'adjust_tone', 'suggest_response', 'translate_content', 'autocomplete_text' ],
                queue_creation_assistant => 1,  # Set to 0 to disable the AI queue creation assistant
                use_context_files => 0,  # Set to 1 to enable context file usage for suggest_response
                context_file_path => "$RT::EtcPath/ai/context",  # Directory containing context files
                suggest_response_context_prompt => "Context: The following are complete conversation histories from similar resolved support tickets. Use these examples to understand typical issue patterns, effective troubleshooting approaches, and professional response tone. Each <Ticket> contains chronological messages between users (customers/requesters) and support staff (privileged users). Apply these patterns to craft an appropriate response:",  # Text that introduces the context
              },
        );

    The Anthropic Messages API requires max_tokens, so always set it in
    default_model (and autocomplete_model). temperature is sent only when
    you set it explicitly, because the frontier models (Opus 4.7 and later)
    reject it. To pin a specific API version, add an anthropic_version key
    to the provider configuration; it defaults to 2023-06-01.

  Global and Queue-specific Configuration
    The block of configuration defined for the "Default" key, as shown
    above, is used as the default global settings for your RT. You can
    define per-queue configuration by adding sections with queue names as
    keys. In any context where RT can associate the AI action with a ticket
    or queue, it will load the matching queue configuration, if available.

    Some features, like the editor autocomplete, may call the AI service
    many times. To limit AI features to selected queues only, do not provide
    a Default configuration and only add configuration for the queues you
    want. The AI menu in the editor will only appear for configured queues
    and autocomplete will also run only for configured queues.

  Using Different AI Providers
    This extension is designed to work with any AI provider with a REST API.
    The features currently all use the conversation AI feature. To interface
    with a system, you need the REST API URL for the conversation endpoint.

    Authentication can be different for different providers and may require
    some custom coding. Most require a token as indicated in the
    configuration. We have tested with the following providers.

    *   OpenAPI, URL: https://api.openai.com/v1/chat/completions

    *   Gemini, URL:
        https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-f
        lash:generateContent

    *   Claude (Anthropic), URL: https://api.anthropic.com/v1/messages

  Models
    Some API providers have different models that are optimized for
    different tasks. Currently most AI features use the general model. The
    autocomplete feature, however, requires fast responses, so we provide a
    way to set a different model for that feature. ChatGPT, for example, has
    a turbo model that is optimized for speed and makes the autocomplete
    work much better.

  Token Usage and Costs
    AI providers bill based on the number of tokens they process, counting
    both the input you send (your prompts, the ticket content, and any
    reference material) and the output they return. Providers differ in
    their default input token limits and in how they price input tokens, so
    a feature that runs well and costs little with one provider may hit a
    limit or cost more with another.

    In our testing, Google Gemini accepted large inputs by default and at
    low cost. Claude (Anthropic), by contrast, applies tiered rate limits,
    and we had to move the account up to "Tier 1" to raise the default input
    token limit enough for the heavier features to run. Your own provider
    may behave differently and will be influenced by your usage of different
    features.

    Some features send much larger inputs than others. These tend to use the
    most input tokens:

    *   The natural language search sends the TicketSQL and Format grammar
        references with every request, which makes each call large.

    *   The Queue Creation Assistant carries the full chat history with each
        turn, so the input grows as the conversation continues.

    *   suggest_response, when context files are enabled, includes
        conversation histories from similar tickets, which can add
        substantial input.

    Before enabling these features in full production, test them with your
    provider and watch your token usage for both input and output. Confirm
    that your account's limits and budget can absorb the volume you expect.
    Refer to your AI provider's documentation for the details of their token
    limits, pricing, and policies.

  Prompts
    You can define different prompts for different AI features. The keys in
    the prompts section describe what they are used for. These prompts are
    sent with every request to the AI for the defined feature. You will
    likely need to experiment with your selected AI to find wording that
    correctly processes the prompt along with the content sent in each
    request.

  Context Files
    The AI response suggestion feature can optionally use context files
    generated by the rt-build-context-files utility. These files contain
    structured conversation data from similar tickets to help the AI
    generate more contextually appropriate responses.

    To enable context file usage:

        use_context_files => 1,
        context_file_path => "$RT::EtcPath/ai/context",
        suggest_response_context_prompt => "Context: The following are complete conversation histories from similar resolved support tickets. Use these examples to understand typical issue patterns, effective troubleshooting approaches, and professional response tone. Each <Ticket> contains chronological messages between users (customers/requesters) and support staff (privileged users). Apply these patterns to craft an appropriate response:",

    When enabled, the suggest_response feature will look for relevant
    context files in the specified directory and include that information in
    AI requests to improve response quality. The
    suggest_response_context_prompt setting allows you to customize the
    introductory text that explains the context to the AI for
    suggest_response requests.

  Queue Creation Assistant
    To enable the queue creation assistant, add the following to your
    provider configuration:

        queue_creation_assistant => 1,

    See "Queue Creation Assistant" under FEATURES below for details.

  CKEditor Integration
    Some AI features are integrated into RT's editor and are accessible via
    buttons in the editor toolbar. To load the editor features, some
    additional configuration is needed. It is provided in the sample
    etc/RT_AI_Config.pm file and should be loaded automatically when you
    enable the extension. If you don't see the AI button, you can copy the
    configuration into your local site configuration.

    The AI Suggestion feature works directly within the editor, inserting
    responses at the end of existing content rather than replacing it. This
    allows users to quote parts of incoming messages and have AI suggestions
    appended appropriately.

FEATURES
  Scrips
    The following scrips are provided to update information on tickets when
    configured with whatever conditions you prefer. The sample scrips are
    configured with "On Correspond" conditions. These are just examples and
    you can use the actions in any new scrips you want to create.

    These scrips are applied globally as part of the installation. If you
    are just testing, you may want to update the scrips and limit them to
    just one queue.

    On Correspond Summarize Ticket History
    On Correspond Assess Reply Sentiment

   Scrip Actions
    The actions below are included with the extension and can be used with
    any conditions to create scrips that make sense for your system.

    Analyze Ticket Sentiment
        Content from the ticket is sent to the AI provider and analyzed to
        assess the sentiment of the end user. Responses are Satisfied,
        Dissatisfied, or Neutral and the value is saved in the "Ticket
        Summary" custom field on the ticket.

    Generate Ticket Summary
        Content from the ticket is sent to the AI provider and a concise
        summary is requested. The result is saved in the "Ticket Sentiment"
        custom field on the ticket.

  Editor Features
    The following features are available in RT's editor.

    Autocomplete
        As you type, suggestions are provided for the next few words. The
        behavior of the suggestions can be modified with the prompt.

    Adjust Tone
        You can submit a block of text to your AI provider and ask it to
        change the tone to something different.

    AI Suggestion
        Your AI provider can suggest a response to the current question on
        the ticket. The AI response is inserted directly into the editor at
        the end of any existing content, preserving paragraph structure and
        newlines.

    Translate
        Translate the provided content from the current language to another
        selected language.

  Queue Creation Assistant
    An interactive chat interface under Admin > Queues > Create with AI that
    guides administrators through setting up a new queue. Through a
    multi-turn conversation, the AI gathers workflow details and generates a
    complete configuration including a custom lifecycle, queue, groups,
    custom fields, ACL rights, and queue watchers. The admin reviews a
    summary of the proposed configuration and creates all objects with a
    single click. See "Queue Creation Assistant" above for configuration
    details.

  Natural Language Search (beta)
    A natural language search form on the advanced search page (Search >
    Tickets > Natural Language (AI), or directly at /Search/Edit.html).
    Describe the tickets you want to find in plain language and the AI
    provider generates the corresponding TicketSQL query and display columns
    for you. Click "Generate Search" to create the search, then click
    "Apply" to confirm it and return to the Query Builder. The form is shown
    whenever an AI provider is configured.

    This feature is currently in beta and has the following limitation: the
    AI does not yet know the specific queue names, statuses, custom fields,
    and other object names defined in your RT. If your question depends on
    any of these, include the correct names in your request so the AI can
    generate an accurate search.

DEVELOPER
  CKEditor Plugin RtExtensionAi
    A new custom CKEditor plugin RtExtensionAi provides the AI integration
    with the RT editor.

  Updating the plugin
    The plugin uses Vite to build the assets loaded into RT. Information on
    working with CKEditor plugins can be found on the CKEditor website
    <https://ckeditor.com/docs/ckeditor5/latest/framework/tutorials/creating
    -simple-plugin-timestamp.html>.

    We use Vite to build the CKEditor plugin.

        npm install
        npm run build

AUTHOR
    Best Practical Solutions, LLC <modules@bestpractical.com>

  Initial Prototype
    Parag Shah <paragsha@buffalo.edu>

    Neel Patel <neelvish@buffalo.edu>

    Abhinandan Vijan <abhinandanvijan98@gmail.com>

    Ayush Goel <ayushgoe@buffalo.edu>

    Shivan Mathur <shivanmthr18@gmail.com>

BUGS
    All bugs should be reported via email to:
    bug-RT-Extension-AI@rt.cpan.org <mailto:bug-RT-Extension-AI@rt.cpan.org>

    Or via the web at: rt.cpan.org
    <http://rt.cpan.org/Public/Dist/Display.html?Name=RT-Extension-AI>.

COPYRIGHT
    This extension is Copyright (C) 2013-2026 Best Practical Solutions, LLC.

    This is free software, licensed under:

      The GNU General Public License, Version 2, June 1991

INTERNAL METHODS AND FUNCTIONS
  GenerateTicketSummary
    Generate a formatted summary of ticket conversations for AI processing.
    This function extracts Create and Correspond transactions from a ticket
    and formats them using XML-like tags similar to the context file format.

  CleanTransactionContent
    Clean up transaction content by removing RT email headers, signatures,
    and excessive whitespace. Also escapes XML characters for safe inclusion
    in XML output.

  LoadContextFile
    Load and return the contents of a context file for AI processing. This
    function searches for relevant context files in the configured directory
    and returns the content for inclusion in AI API requests.

  LoadQueueCreationPrompt
    Load the system prompt for the queue creation assistant from
    etc/ai/prompts/create-queue.md. Searches the local etc directory, the
    default etc directory, and installed plugin paths.

