> ## Documentation Index
> Fetch the complete documentation index at: https://learn.nextedy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# AI Action Configuration

> Reference for the AI Assistant action configuration file in Nextedy RISKSHEET — file location and resolution, every action field with its default, and the context properties that configure the assistant.

export const LastReviewed = ({date}) => {
  if (!date) return null;
  const formatted = new Date(`${date}T00:00:00Z`).toLocaleDateString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric",
    timeZone: "UTC"
  });
  return <p className="mt-10 text-sm text-gray-400 dark:text-zinc-500 not-prose">
      Last reviewed on {formatted}
    </p>;
};

AI Assistant actions are defined in a YAML file held in Polarion's configuration repository. This page is the field-by-field reference. For how the pieces fit together, see [Configure the AI Assistant](/risksheet/guides/administration/configure-the-ai-assistant).

## File location and resolution

Action files live in the configuration folder `.polarion/nextedy/ai/` — either under a project, or globally so that several projects can share one file. **Administration → Nextedy AI → AI Assistant Actions** lists the files found there.

A sheet selects its file through the `assistantConfig` property in the `global` block of the Risksheet configuration:

```yaml theme={null}
global:
  assistantConfig: actions
```

| Form                   | Resolves to                                                     |
| ---------------------- | --------------------------------------------------------------- |
| `actions`              | `actions.yaml` in the current project's `.polarion/nextedy/ai/` |
| `actions.yaml`         | the same file — the extension is optional                       |
| `OtherProject/actions` | `actions.yaml` in another project's folder                      |

When `assistantConfig` is unset, the assistant offers no actions.

## File structure

The file has exactly two top-level keys, and both are optional.

```yaml theme={null}
globals:
  <key>: <string>

actions:
  <action-id>:
    ...
```

| Key       | Type                       | Description                                                            |
| --------- | -------------------------- | ---------------------------------------------------------------------- |
| `globals` | map of string to string    | Reusable strings, substituted into prompts through `${globals.<key>}`. |
| `actions` | map of action id to action | The actions offered on a sheet. The map key is the action id.          |

## Action fields

### Required

| Field     | Type   | Description                                                                                       |
| --------- | ------ | ------------------------------------------------------------------------------------------------- |
| `label`   | string | The entry text in the cell context menu and in the assistant panel's action list. Shown verbatim. |
| `message` | string | The prompt title displayed above the results, describing to the analyst what was asked.           |

The action **id** is the map key, not a field inside the action body.

### `scope`

| Field           | Type               | Default | Description                                                                                                         |
| --------------- | ------------------ | ------- | ------------------------------------------------------------------------------------------------------------------- |
| `scope.columns` | list of column ids | absent  | Restricts the action to these columns in the cell context menu. When absent, the action is offered on every column. |

`scope` never filters the assistant panel's own list — that always shows every configured action for the sheet.

### `contextSources`

| Field                            | Type                                        | Default | Description                                                                                                                                                                           |
| -------------------------------- | ------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `contextSources.row.fields`      | map of Risksheet column id to label         | absent  | Sheet fields to send with the action. The **key** is the sheet field id; the **value** is the label the assistant sees that value under. Fields with no value on the row are skipped. |
| `contextSources.document.fields` | map of document field id to label           | absent  | Document fields to send with the action. The **key** is the document field id; the **value** is the label the assistant sees that value under.                                        |
| `contextSources.project.fields`  | map of context property name field to label | absent  | Context property values to send with the action. The **key** is the property name (whether project- or global-level); the **value** is the label the assistant sees that value under. |

```yaml theme={null}
contextSources:
  row:
    fields:
      item_title: "Characteristic"
      failureMode: "Failure Mode"
      effectOfFailure: "Effect(s) of Failure"
      causes: "Cause(s) of Failure"
  document:
    fields:
      name: "Document name"
      projectName: "Project"
      customFields.riskLevel: "Risk level"
  project:
    fields:
      ai.context.industry: "Industry domain"
      ai.context.standards: "Applicable standards"
```

<Note>
  The labels are prose read by the assistant, not identifiers. `"Hazardous situation"` describes the value usefully; `"hs_col_2"` does not. This is the main lever over how well an action performs.

  An action sends the values you map here together with the selected row's id and title. A project script can add further values at run time through the `customAiContext` hook — see [Customize the Top Panel](/risksheet/guides/customization/top-panel).

  Other `contextSources` blocks exist for context beyond the current row; they are not covered on this page.
</Note>

### `discover`

| Field                           | Type    | Default | Description                                                                                                               |
| ------------------------------- | ------- | ------- | ------------------------------------------------------------------------------------------------------------------------- |
| `discover.keywordPrompt`        | string  | absent  | Tells the assistant what to look for. Describe the *kind of item* the action should propose.                              |
| `discover.rankPrompt`           | string  | absent  | Tells the assistant which of the items it finds to propose, and on what grounds. When absent, a built-in default applies. |
| `discover.search.maxCandidates` | integer | none    | How many work items an action may consider. Always set it explicitly — an action without it proposes nothing.             |

<Warning>
  **30 is the highest value `maxCandidates` accepts.** A larger number behaves the same as `30`.
</Warning>

Both prompts support `${globals.<key>}` substitution. An unknown key resolves to an empty string.

### `output`

| Field           | Type    | Default | Description                                                                                       |
| --------------- | ------- | ------- | ------------------------------------------------------------------------------------------------- |
| `output.limit`  | integer | none    | How many recommendations to ask for at most. Omit it and the assistant decides how many to offer. |
| `output.sortBy` | string  | absent  | How the recommendations should be ordered, for example `relevance`.                               |

Both are asked of the assistant rather than enforced — a result may not honour them exactly.

### `apply`

| Field         | Type      | Default | Description                                                                                       |
| ------------- | --------- | ------- | ------------------------------------------------------------------------------------------------- |
| `apply.field` | column id | absent  | The sheet column a recommendation is written into. With no `apply.field`, nothing can be applied. |

`apply.field` does double duty: it also determines **which work-item types an action can propose**. Those types come from the column's own configuration — the task data type for a task-link column, the column's link types for an item-link column — so a recommendation is always something the column can legitimately hold.

| Target column type | Applying to an empty cell               | Applying to a filled cell                             |
| ------------------ | --------------------------------------- | ----------------------------------------------------- |
| Task link          | Written into the current row, undoable. | A new task row is created and the link written there. |
| Item link          | Written into the current row, undoable. | A new row is added at the level owning the column.    |
| Multi item link    | Added to the cell.                      | Appended to the existing values.                      |

## What a recommendation contains

| Field         | Description                                                                       |
| ------------- | --------------------------------------------------------------------------------- |
| `id`          | The work-item id. A suggestion that does not match a real work item is discarded. |
| `title`       | Always the title Polarion holds, so an invented title cannot reach the analyst.   |
| `description` | A one-sentence rationale for the match.                                           |
| `source`      | The origin of the item.                                                           |

## Context properties

All of these are Polarion context properties. The `nextedy.ai.*` properties are read from the **global** context only and cannot be varied per project.

### Model connection

| Property             | Default                     | Description                              |
| -------------------- | --------------------------- | ---------------------------------------- |
| `nextedy.ai.baseUrl` | `https://api.openai.com/v1` | Base URL of the model API.               |
| `nextedy.ai.model`   | `gpt-4o-mini`               | Model identifier sent with each request. |

The API key is taken from the first of these that holds a value: the Polarion User Account Vault credential `nextedy-openai-apikey`, the JVM system property `nextedy-openai-apikey`, then the environment variable `OPENAI_API_KEY`. If none resolves, the assistant reports itself unavailable. All three are re-read per request, so a change applies to the next action without restarting Polarion.

### Feature switches

| Property                           | Default | Description                                                                                                                          |
| ---------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `nextedy.risksheet.aiAssistant`    | `true`  | The in-sheet AI Assistant in Risksheet documents. `false` removes it from that project — no toolbar button and no cell-menu entries. |
| `nextedy.risksheet.adminAssistant` | `true`  | The assistant in the Risksheet configuration editor.                                                                                 |
| `nextedy.risksheet.promotions`     | `true`  | Whether the toolbar advertises the assistant on installations not licensed for it. Only has an effect while unlicensed.              |

### Prompt overrides

Each replaces one of the assistant's built-in instructions, for every action. Leave unset to keep the default.

| Property                     | Replaces                                                                                                     |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `nextedy.ai.keywordPrompt`   | The built-in counterpart of an action's `discover.keywordPrompt`.                                            |
| `nextedy.ai.processorPrompt` | The built-in counterpart of `discover.rankPrompt`, used when an action sets none.                            |
| `nextedy.ai.relevancePrompt` | The built-in wording that keeps loosely related items out of the results.                                    |
| `nextedy.ai.jsonPrompt`      | The built-in wording that fixes the shape of the assistant's answer. Changing it can stop results appearing. |

### Logging

| Property               | Default | Description                                                   |
| ---------------------- | ------- | ------------------------------------------------------------- |
| `nextedy.ai.telemetry` | `false` | Logs action requests and results at INFO. Safe in production. |

Warnings and errors are logged regardless of both switches.

## Complete example

```yaml actions.yaml theme={null}
globals:
  systemContext: "An infusion pump delivering medication intravenously in a clinical setting."

actions:
  find-harms:
    label: "Find Harms"
    message: "Suggest potential harms for this hazardous situation"
    scope:
      columns:
        - hazardousSituation
        - hazard_title
    contextSources:
      row:
        fields:
          useStep: "Use step"
          hazardousSituation: "Hazardous situation"
          hazard_title: "Hazard"
    discover:
      keywordPrompt: >
        ${globals.systemContext}
        Generate keywords naming the types of harm a patient or operator could suffer
        as a consequence of the hazardous situation described in the context.
      rankPrompt: >
        Select the harms that could plausibly result from this hazardous situation.
        If none of the candidates applies, return none rather than the closest match.
      search:
        maxCandidates: 30
    output:
      limit: 5
      sortBy: "relevance"
    apply:
      field: harm

  find-risk-controls:
    label: "Find Risk Control Measures"
    message: "Suggest existing risk control measures for this failure mode"
    scope:
      columns:
        - failureMode
        - cause
    contextSources:
      row:
        fields:
          failureMode: "Failure mode"
          cause: "Cause"
          effect: "Effect"
    discover:
      keywordPrompt: >
        ${globals.systemContext}
        Generate keywords naming control measures that would reduce or detect the
        failure mode described in the context.
      rankPrompt: >
        Select the control measures that address this specific failure mode and cause.
        Return none rather than a generic measure.
      search:
        maxCandidates: 30
    output:
      limit: 5
    apply:
      field: mitigationTask
```

## See Also

* [Configure the AI Assistant](/risksheet/guides/administration/configure-the-ai-assistant) — the setup task, in order
* [AI Assistant](/risksheet/concepts/ai-assistant) — how an action runs and how suggestions are verified
* [Use the AI Assistant](/risksheet/guides/risk-management/use-the-ai-assistant) — the analyst's task
* [Risksheet JSON Format](/risksheet/reference/configuration/risksheet-json-format) — where `assistantConfig` sits in the sheet configuration
* [Properties Index](/risksheet/reference/configuration/properties-index) — all Risksheet configuration properties
* [Item Link Columns](/risksheet/reference/columns/item-link-columns) — the column types an action can apply into
* [Task Link Columns](/risksheet/reference/columns/task-link-columns) — task-link column reference

<LastReviewed date="2026-08-27" />
