Creating Custom AI Actions

Custom AI actions for the AI Positron can be created in the Actions, Agents, and Skills Preferences page.

The New Document wizard in Oxygen can be used to create either a new AI Positron Custom Action file that contains a custom action definition in JSON format or an AI Positron Custom Actions List that contains a JSON array with multiple defined actions. Validation and content completion are automatically provided for these custom action files. To edit multi-line parameter values, you can switch the edited action JSON definition file to the Author visual editing mode.

Various examples of custom AI actions can be found here and can be used as starting points for your own similar AI actions.

An AI action definition may contain the following properties:
id

A unique ID for the action. If the ID of the action starts with agent.hidden.action., then the action is not visible to be invoked directly but can be called by using the invoke_ai_action tool.

Example:
{
        "id": "improve.grammar.custom.styles",
        "title": "...",
        ...
}
Note:
An Oxygen XML desktop plugin can contribute an extra translation.xml file that contains translations. Such a plugin may translate titles and descriptions for AI actions using the action ID as part of the key.

Example:

	<key value="improve.grammar.custom.styles.title"> 
		<val lang="en_US">Improve Styles</val> 
		<val lang="de_DE">...</val> 
		... 
	</key>
	<key value="improve.grammar.custom.styles.description">
		<val lang="en_US">Analyze and improve styles.</val>
		<val lang="de_DE">...</val>
		...
	</key>
title

The action name/title that gets presented in the UI.

Example:
{
        "id": "improve.grammar.custom.styles",
        "title": "Improve Grammar and Styles",
        ...
}
description

A longer description of what the AI action does, usually used as a tooltip.

Example:
{
        "id": "...",
        "title": "Improve Grammar and Styles",
        "description": "Improve the grammar and styles based on the company's style guide."
}
short-description

A shorter description for the AI action that usually appears under the action title in the chat view. If not specified, it defaults to the description value.

Example:
{
    "id": "action.translate.to.english",
    "title": "English",
    "short-description": "Translate to English",
    "description": "Translate the selected content to English while preserving its 
    original DITA XML markup.",
    ....
}
categoryId

The optional category in which the AI action is visually grouped, if not specified it defaults to Other.

Example:
{
        "id": "improve.grammar.custom.styles",
        "title": "Improve Grammar and Styles",
        "categoryId": "Rewrite"
}
framework

A framework pattern (like 'DITA*') or content type name (like 'text/css') that, when matched, presents the action when the document belonging to the framework is opened.

Example:
{
    "id": "generate.img.alternate.text",
    "title": "Generate Image Alternate Text",
    "framework": "*DITA*",
    ...
}

An example of an AI action that shows this for any edited XML document (as it matches the text/xml content type) can be found here.

prompt_ref
A reference to a separate file (usually encoded in Markdown) that defines the entire action prompt.
Tip:
You can use Oxygen editor variables in the file path when defining the prompt_ref and the content will be automatically expanded.
Example:
{
    "id": "action.update.title.based.on.content",
    ....
    "prompt_ref": "prompts/action_update_title.md"
  }
Important:

The prompt is the most important part of the AI action. A prompt must be as precise and detailed as possible, including examples. Some companies may adopt prompt methodologies like COSTAR to specify the prompt value. The context prompt defined in the AI Positron Preferences page is used as a prefix for all AI action prompts.

Here are some custom prompt examples..

A custom AI action can expand the context prompt in a specific part of its prompt by using the ${contextPrompt} variable in its own prompt.

To define a custom AI action that does not use the context prompt in any way, in the AI action's JSON configuration file, you can expand the context prompt to an empty value like this:
{
    "id": "improve.grammar.custom",
    "title": "..",
     ....
    "expand-params": [
        {
         "name": "contextPrompt",
         "value": ""
        }
    ]
}
prompt
Multi-line parameter value that defines inline the prompt that is sent to the AI along with the content to be processed.
Tip:
You can use Oxygen editor variables when defining the prompt property and the content will be automatically expanded.
Example:
{
    "id": "action.review.logical.mistakes",
    "title": "Logical Inconsistencies",
    "output-action": "none",
    "prompt": "# CONTEXT #\n\nYou will act as a reviewer interested in finding inconsistency 
    and logical mistakes.\n\n# OBJECTIVE #\n\nYou are tasked with reviewing the given content.
    \nFind logical and inconsistency mistakes in the content and return a report."
}
Important:

The prompt is the most important part of the AI action. A prompt must be as precise and detailed as possible, including examples. Some companies may adopt prompt methodologies like COSTAR to specify the prompt value. The context prompt defined in the AI Positron Preferences page is used as a prefix for all AI action prompts.

Here is an example of a prompt file.

A custom AI action can expand the context prompt in a specific part of its prompt by using the ${contextPrompt} variable in its own prompt.

To define a custom AI action that does not use the context prompt in any way, in the AI action's JSON configuration file, you can expand the context prompt to an empty value like this:
{
    "id": "improve.grammar.custom",
    "title": "..",
     ....
    "expand-params": [
        {
         "name": "contextPrompt",
         "value": ""
        }
    ]
}
expand-params
A JSON array that can define values for parameters that should be expanded in the context content.
You can define parameters that can be configured by the end user when hovering over the AI action in the UI.
Example:
{
  "id": "thesaurus",
  "title": "Thesaurus/Synonyms",
  "output-action": "replace",
  "prompt": "Provide a max of ${number} synonyms for:",
  "expand-params": [
    ...
    {
      "name": "number",
      "label": "Number of synonyms",
      "value": "10",
      "choice-type": "single-choice",
      "alternate-values": [
        "10",
        "20",
        "30"
      ]
    }
  ]
}
The following properties are available for a defined parameter:
name
The parameter name. It can be referenced multiple times with the syntax ${param_name} in the context parameter or in the external prompt file referenced using prompt_ref.
label
The label that appears in the UI when the parameter's value is configured by the end user.
value

The value of the parameter. It can contain various editor variables that get automatically expanded.

Example:
{
        "id": "action.update.prolog",
        ...
        "prompt": "Update the DITA XML topic prolog with the current date ${currentDate}...",
        "expand-params": [
            {
                "name": "currentDate",
                "value": "${date(yyyy-MM-dd)}"
            }
        ]
    }
alternate-values
An optional array of alternate values that are available to be configured by the end user when hovering over the AI action.
choice-type
An optional choice type that defines how the end user can configure the alternate values (combo box, check boxes, radio buttons).
editable-combo-choice
An editable combo box. Example:
{
    "id": "action.translate.to.lang",
    ...
    "title": "Other...",
    .....
    "expand-params": [
      {
        "name": "translationLanguage",
        "label": "Language",
        "choice-type": "editable-combo-choice",
        "alternate-values": [
          "Arabic",
          "Bulgarian",
          "Chinese (Simplified)"
        ]
      }
    ],
    ...
  }
multi-choice
A list of checkboxes. Example:
{
    "id": "action.short.description",
    ...
    "title": "Short description",
    ...
    "insert-modes": [
      {
        "xpath-condition": "(//shortdesc)[1]",
        "target-location": "(//shortdesc)[1]",
        "action": "replace"
      },
      {
        "target-location": "(//title)[1]",
        "action": "insert-after"
      }
    ],
    "expand-params": [
      {
        "name": "style",
        "label": "Style",
        "choice-type": "multi-choice",
        "alternate-values": [
          "The description must be clear",
          "The description must be engaging"
        ],
        "alternate-value-labels": [
          "Clear",
          "Engaging"
        ]
      },
      {
        "name": "length",
        "label": "Maximum number of sentences",
        "value": "2-3",
        "choice-type": "single-choice",
        "alternate-values": [
          "1",
          "2-3",
          "3-5"
        ]
      }
    ],
    ....
  }
single-choice
Radio buttons. A usage example can be found in the code block above.
prefix
The optional prefix value to be used for each expansion of the parameter's value.
parameters
An array of parameters that can be used to specify an engine name, temperature, or the available tool definitions. Some of the most commonly set parameters:
engine
Specifies which AI model to use for the action. You can specify the AI model to use in two ways:
  • By providing only the model ID (for example, gpt-5).
  • By providing a structure that includes the connection ID for the AI service, followed by the :: separator, and then the model ID (for example, openai::gpt-5).
The connection ID for the built-in AI Positron Service is aips. A list of available models for the AI Positron Service can be found at https://aipositron.oxygenxml.com#models.
Example:
{
    "id": "action.review.logical.mistakes",
    ...,
    "parameters": {
        "engine": {"name": "aips::gpt-5-minimal-reasoning"}
    }
} 
Fallback Mechanism:
If the specified connection ID does not exist, the AI Positron service is disabled, or no connection ID is provided, the system will:
  1. Search for the model in all available external connections.
  2. If not found, attempt to use the AI Positron service.
  3. If still not found or the AI Positron service is disabled, fall back to the default model selected in the combo box from the view.
temperature
Temperature is an optional parameter that governs the randomness and thus the creativity of the responses. It is always a number between 0 (more deterministic) and 1 (more random). The default value is 0 and it should, in general, remain unspecified when your AI actions are intended for technical documentation that is precise in nature.
function_refs

An optional JSON array that describes which tools can be used when executing this action. For the list of available tools, see Tool Calls.

Example of an AI action that uses Retrieval Augmented Generation (RAG) tools to find related content in the project (the search_project_resources tool is available only in Destkop and Content Fusion Positron installation):
{
    "id": "find.add.related.links",
    ...
    "parameters": {
    "function_refs": [
        {"ref": "search_project_resources"},
        {"ref": "get_document_content"}
    ]
}
}
Example of an AI action that uses the get_document_content tool to retrieve content from a web site:
{
    "id": "action.get.oxygen.version.web.site",
    "output-action": "insert",
    "title": "Insert Latest Oxygen Version",
    "prompt": "Obtain the latest version of Oxygen from the 
    'https://www.oxygenxml.com/xml_editor/whats_new.html' web site by calling the tool 
    'get_document_content' and return it.",
    "parameters": {
        "function_refs": [
            {"ref": "get_document_content"}
        ]
    }
  }
Important:
There are specific actions that can be called to invoke other AI actions from an AI action, thus creating an agenting mechanism where various parts of the work is done by various actions. An example can be found here.
input
Defines which part of the current document should be sent to be processed by the AI engine.
selection, document [default]
Prefers sending the selected content. If there is no selection, it selects and sends the entire document.
selection
Prefers sending the selected content. If no content is selected, either no content is sent or an error message is received (depending on the action's output-action).
document
Always sends the entire document for processing, regardless if there is content selected inside it.
none
Does not send any content from the current document. See this example.
input-type
Describes how the XML content from the document that is sent to the platform should be processed:
markup (default)
Sent as regular XML including markup tags.
markup-with-images
Sent as regular XML including markup tags and all referenced images for vision processing as part of the content. See an example.
plain-text
Sent without the XML tags and with all DITA XML content references and key references expanded.
An example of an AI action that requires the input to be sent without any markup tags and with the DITA XML conrefs and keyrefs expanded:
{
    "id": "action.answer.questions",
    "output-action": "none",
    "description": "Generate answers to questions you ask based on the selected text or on the 
    entire document content.",
    "input-type": "markup",
    ....
  }
output-action
Defines the type of change the AI action performs on the opened document. Some of the most commonly used type values are listed below:
replace

The most common type of action. Sends the selected content to the AI platform and proposes to replace the selection with the received response. If there is no selected content automatically, the entire document is selected when the action is invoked.

Example:
{
  "id" : "replace.bold.with.uicontrol",
  "title" : "Replace bold with uicontrol",
  "output-action" : "replace",
  "prompt" : "Replace the bold element with the uicontrol element (<uicontrol>)....",
}
insert

Inserts the content received from the AI engine in the current document at the cursor position or at an offset specified by the insert-modes. If the inserted content is invalid at the proposed offset, the application attempts to find a proper location for it.

Example:
{
    "id": "action.update.title.based.on.content",
    "title": "Update Title",
    "output-action": "insert",
    "prompt": "You are tasked with creating a title for the given text, summarizing it and 
    focusing on its main points:"
}
none

Sends the selected content or the entire document to the AI platform and shows the response to the end user.

Example:
{
    "id": "action.review.logical.mistakes",
    "title": "Logical Inconsistencies",
    "output-action": "none",
    "prompt": "Find logical and inconsistency mistakes in the content and return a report.",
}
create-new-document

Shows a dialog box that asks for a context and then creates a new document based on the received server response. The "additional_info"/"properties"/"file_extension" property can be set to impose an extension for the newly created document.

Example:
{
    "id": "action.create.schematron.rules",
    "title": "Schematron Rules from Style Guide",
    "output-action": "create-new-document",
    "additional_info": {
        "properties": {"file_extension": "sch"}
    },
    "prompt_ref": "prompts/create-schematron-rules.md"
}
insert-modes

A JSON array that defines places for inserting the content in an XML document. The first mode for which the XPath condition becomes true is run. Such modes are used when the AI action output-action is insert. An insertion mode has an xpath-condition parameter that, when activated, allows the mode to be run. It also has a target-location parameter, which specifies an anchor node relative to where the insertion is done. Also, it has an action parameter (with the possible values insert-after/insert-before/replace), which specifies where the content should be inserted relative to the target element.

Example:
{
    "id": "action.update.title.based.on.content",
    ...
    "output-action": "insert",
    ...
    "insert-modes": [
      {
        "xpath-condition": "(//title)[1]",
        "target-location": "(//title)[1]",
        "action": "replace"
      },
      {
        "target-location": "(//shortdesc)[1]",
        "action": "insert-before"
      }
    ]...
  }
visibility
visible (default)
Action appears in the UI and is accessible for tools that invoke actions (e.g. 'invoke_ai_agent' or 'invoke_ai_action').
visible-only-in-ui
Action appears in the UI but cannot be invoked by tools.
visible-only-for-tools
Action does not appear in the UI but can be invoked by tools.
hidden
Action does not appear in the UI and cannot be invoked by tools.
embed-assist
Set this optional boolean parameter to true to add the AI action to the top right AI Positron drop-down menu that appears when editing content in the Author visual editing mode.
quick-assist
Set this optional boolean parameter to true to add the AI action to the quick assist bulb drop-down menu that appears in the left vertical stripe.