> For the complete documentation index, see [llms.txt](https://docs.realmjoin.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.realmjoin.com/pt/automacao/runbooks/runbook-customization.md).

# Personalização do Runbook

## Visão geral

A implementação de runbook do RealmJoin oferece capacidades de personalização ao autor de um runbook ou ao administrador de um ambiente, para que possam:

* Alojar parâmetros e modelos específicos do cliente/tenant
* Oferecer elementos de IU como seletores de utilizador ou seleções em lista suspensa
* Apresentar explicações legíveis por humanos dos parâmetros
* Ocultar elementos de IU desnecessários

<figure><img src="/files/fc10f116696800198ba3d0f0bf0012c61f38abbc" alt=""><figcaption></figcaption></figure>

As personalizações podem ser incluídas no próprio runbook e/ou armazenadas na instância do RealmJoin Portal do cliente. Por omissão, tentaremos oferecer predefinições sensatas nos runbooks oferecidos em [GitHub](https://github.com/realmjoin/realmjoin-runbooks).

Alguns runbooks virão com exemplos de como configurar modelos específicos do cliente, como especificar localizações de escritório para a integração do utilizador.

### Formatar

A personalização pode ser definida (por ordem decrescente de prioridade)

* Bloco de JSON em [definições do RealmJoin Portal](https://portal.realmjoin.com/settings/runbooks-customizations), substituindo o comportamento predefinido do runbook
* Bloco de JSON no cabeçalho de um runbook

Além disso (com a menor prioridade)

* por parâmetro no cabeçalho do runbook
* por parâmetro no bloco de parâmetros do runbook (usando o módulo RJRb Helper)

Algumas funcionalidades (como modelos) só estão disponíveis em formato JSON. Algumas funcionalidades (como criar um seletor de utilizador) só estão disponíveis ao especificar um tipo de dados no bloco de parâmetros. Pode combinar vários tipos de personalização para obter os melhores resultados.

## Bloco de Parâmetros do Runbook

O RealmJoin Portal analisa o bloco de parâmetros PowerShell de um runbook para determinar quais campos de entrada renderizar. Sempre que possível, também validará as entradas de acordo com o tipo .NET dado para uma variável.

Os seguintes tipos de dados são atualmente reconhecidos:

* `[bool]`, `[boolean]` - apresentará um alternador binário
* `[string]` - apresentará uma caixa de texto para introduzir qualquer entrada alfanumérica
* `[int]` - apresentará uma caixa de texto, permitindo apenas entradas numéricas
* `[DateTime]`, `[DateTimeOffset]` - Apresentará um seletor de data/hora

Pode aplicar modificadores padrão do PowerShell aos parâmetros. O RealmJoin Portal, em particular, compreenderá se especificar `[Parameter(Mandatory = $true)]` para indicar um parâmetro obrigatório e exigir que estes parâmetros sejam preenchidos.

Sempre que possível, o RealmJoin Portal também lerá e apresentará os valores predefinidos dados na IU.

Tenha em atenção que os valores predefinidos do runbook podem ser substituídos por personalizações. Além disso, os parâmetros podem ser completamente ocultados por personalizações.

### Personalização de Parâmetros

Para poder personalizar parâmetros, certifique-se de incluir o módulo PS RealmJoin Runbook Helper no seu runbook:

`#Requires -Modules @{ModuleName = "RealmJoin.RunbookHelper"; ModuleVersion = "0.6.0" }`

Pode então incluir `[ValidateScript( { Use-RJInterface ... } )]` instruções nas definições dos parâmetros. Por exemplo, o seguinte criará um seletor de utilizador, permitindo escolher um utilizador do Entra ID e passará o respetivo ID de objeto como string para o runbook.

```powershell
param(
    [ValidateScript( { Use-RJInterface -DisplayName "Atribuir dispositivo a este utilizador (opcional)" -Type Graph -Entity User } )]
    [string] $AssignedUserId = ""
)
```

Vamos analisar isto peça por peça. `[ValidateScript...]` é um modificador para o próximo parâmetro definido no bloco param. Neste caso, a variável `$AssignedUserId`.

`Use-RJInterface` faz parte do nosso [RealmJoin Runbook Helper](https://github.com/realmjoin/RealmJoin.RunbookHelper) módulo PowerShell. Permite especificar que tipo de entrada espera usando `-Type` e `-Entity`, se isso ainda não estiver totalmente definido pelo tipo de variável.

`-DisplayName` permite-lhe passar uma indicação/descrição legível por humanos para este parâmetro ao RealmJoin Portal.

#### Recursos Graph

No exemplo acima, a origem da informação é o MS Graph, conforme descrito por `-Type Graph`. Para MS Graph, use `-Entity` para especificar que tipo de recurso espera. As entidades disponíveis são `de utilizadores`, `Grupo`, `Dispositivo`. Isto produzirá um seletor para utilizadores, grupos ou dispositivos no Entra ID fornecido.

O seletor inclui uma pesquisa rápida, para localizar facilmente o recurso necessário.

![Exemplo de Seletor](/files/fd8e7a08510ba33d9ad8bc27ed96b9401be94849)

Atualmente, não é possível selecionar vários itens com um seletor.

Por predefinição, um seletor MS Graph devolverá o ID do objeto. Se precisar, por exemplo, do nome principal do utilizador em vez disso, certifique-se de incluir "name" como sufixo no nome da sua variável. Assim, basicamente, para obter o ID de um utilizador, nomeie o parâmetro `$userid`. Se quiser um UPN, dê-lhe o nome `$username`.

#### Filtragem Graph

Se estiver a usar um seletor baseado em MS Graph, também pode especificar `-Filter` e usar um [ODATA-Filter](https://docs.microsoft.com/en-us/graph/query-parameters?context=graph%2Fapi%2F1.0\&view=graph-rest-1.0#filter-parameter) para limitar os objetos apresentados no seletor.

O exemplo seguinte listará apenas grupos do Entra ID que começam com "LIC\_".

```powershell
param(
    [Parameter(Mandatory = $true)]
    [ValidateScript( { Use-RJInterface -Type Graph -Entity Group -Filter "startswith(DisplayName, 'LIC_')" -DisplayName "Grupo de licenças" } )]
    [String] $GroupID_License
)
```

Pode preparar filtros e reutilizá-los em vários scripts usando o [datastore central](#graph-filters). Neste caso, basta referenciar o filtro pelo nome usando `-Filter "ref:LicenseGroup"`, onde `ref:` indica para procurar um filtro armazenado.

```powershell
param(
    [Parameter(Mandatory = $true)]
    [ValidateScript( { Use-RJInterface -Type Graph -Entity Group -Filter "ref:LicenseGroup" } )]
    [String] $GroupID_License
)
```

Este exemplo específico `ref:LicenseGroup` está disponível por predefinição sem configuração adicional.

![filtro ODATA](/files/af67c2f470082ec3fe983dfbd473ab0da74f6b0f)

## Cabeçalho do Runbook

O Portal pode analisar o [ajuda baseada em comentários](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comment_based_help?view=powershell-5.1) secção, se presente.

Aqui está um exemplo:

```powershell
<#
  .SYNOPSIS
  (Des)atribuir uma licença a um utilizador através da associação a um grupo.

  .DESCRIPTION
  (Des)atribuir uma licença a um utilizador através da associação a um grupo. Descrição mais detalhada...

  .PARAMETER DefaultGroups
  Lista de grupos a atribuir separada por vírgulas. p. ex. "DL Sales,LIC Internal Product"

  .NOTES
  Permissões:
  MS Graph (API):
  - User.Read.All
  - GroupMember.ReadWrite.All 
  - Group.ReadWrite.All

  .INPUTS
  RunbookCustomization: {
        "Parameters": {
            "UserName": {
                "Hide": true
            },
            "Remove": {
                "DisplayName": "Atribuir ou Remover Licença",
                "SelectSimple": {
                    "Atribuir Licença ao Utilizador": false,
                    "Remover Licença do Utilizador": true
                }
            }
        }
    }
#>
```

`.SYNOPSIS` - Dê uma descrição muito breve da função do seu runbook. Isto será apresentado na lista de runbooks disponíveis.

`.DESCRIPTION` - Dê uma descrição da função do seu runbook. Pode conter um pouco mais de detalhe, pois será apresentado dentro da caixa de diálogo de execução/parâmetros dos runbooks.

`.PARAMETER` - Tem de ser seguido pelo nome de um parâmetro. Permite-lhe dar uma explicação detalhada da entrada esperada para o parâmetro em questão.

`.INPUTS` - Pode conter um bloco de Personalização de Runbook baseada em JSON.

`.NOTES` - Não é analisado/renderizado. Use este espaço para anotar quais as permissões e requisitos existentes para o seu runbook.

`.EXAMPLE` - Não é analisado/renderizado. Pode conter um exemplo de Personalização baseada em JSON para usar no Datastore do RealmJoin no seu tenant. Estes podem ser exemplos de como criar modelos, por ex. para diferentes fluxos de trabalho ou classes de utilizadores.

## Personalização baseada em JSON

### Datastore Central

Cada tenant Azure pode alojar um datastore "Runbook Customizations", encontrado em <https://portal.realmjoin.com/settings/runbooks-customizations> .

O formato é JSON com comentários, permitindo vírgulas finais. Atualmente, existem três secções relevantes, `Configurações`, `Modelos`, `Runbooks`.

```json
{
    "Settings": {
    },
    "Templates": {
    },
    "Runbooks": {
    }
}
```

### Secção Runbooks

`Runbooks` é analisada pelo portal ao iniciar um runbook. Se existir uma secção com o nome do Runbook de Automatização do Azure atual, o seu conteúdo será usado para personalizar a interface apresentada ao utilizador.

Suponha o seguinte runbook simples de demonstração, chamado `rjgit-device_demo-runbook-customizing`.

```powershell
<#
  .SYNOPSIS
  Demonstração de Personalização de Runbook

  .DESCRIPTION
  Demonstração de Personalização de Runbook, como dropdown/seletor
#>

#Requires -Modules @{ModuleName = "RealmJoin.RunbookHelper"; ModuleVersion = "0.6.0" }

param(
    [string] $DeviceId,
    [bool] $ExtraWorkflow = $true,
    [int] $ExtraWorkflowTime = 15
)

"## A executar ações no dispositivo '$DeviceID'"

# Fluxo de trabalho complicado altamente opcional
if ($ExtraWorkflow) {
    "## A executar meditação..."
    Start-Sleep -Seconds $ExtraWorkflowTime
}
```

Se não for personalizada, será apresentada assim na interface:

![Demonstração - antes](/files/1bbf7a0209bf21af95d610cb26d298976c221f5c)

Ideias:

* Como este runbook é iniciado no contexto de um dispositivo no portal, o `$DeviceId` é informação redundante para um utilizador. Já sei em que dispositivo estou a trabalhar.
* O que acontece se eu ativar ou desativar o "Extra Workflow"? Preciso de pensar no "Extra Workflow Time" se desativar o "Extra Workflow"?

Vamos melhorar isso. O seguinte exemplo de JSON no datastore central irá modificar a IU do runbook.

```json
{
    "Runbooks": {
        "rjgit-device_demo-runbook-customizing": {
            "ParameterList": [
                {
                    "Name": "DeviceId",
                    "Hide": true
                }, 
                {
                    "Name": "ExtraWorkflow",
                    "Hide": true
                },
                {
                    "Name": "ExtraWorkflowTime",
                    "DisplayName": "Quanto tempo para meditar?",
                },
                {
                    "DisplayName": "Executar Fluxo de Trabalho Adicional",
                    "DisplayBefore": "ExtraWorkflowTime",
                    "Select": {
                        "Options": [
                            {
                                "Display": "Executar Meditação (opcional)",
                                "Customization": {
                                    "Default": {
                                        "ExtraWorkflow": true
                                    }
                                }
                            },
                            {
                                "Display": "Ignorar a Atenção Plena do Dispositivo",
                                "Customization": {
                                    "Default": {
                                        "ExtraWorkflow": false
                                    },
                                    "Hide": [
                                        "ExtraWorkflowTime"
                                    ]
                                }
                            }
                        ],
                        
                    },
                    "Default": "Ignorar a Atenção Plena do Dispositivo"
                }
            ]
        }
    }
}
```

Pode usar a mesma notação / funcionalidades no seu [cabeçalho do runbook](#runbook-header).

#### ParameterList

Cada parâmetro tem a sua própria secção em `ParameterList`. [Modifiers](#modifiers) permitem alterar o comportamento desse parâmetro.

O resultado será o seguinte:

![Demonstração - após ocultar](/files/13056fe34a28a7dd86d5a404c992058d0fcfbf5a)

Escolher o fluxo de trabalho adicional apresentará (desocultará) mais parâmetros:

![Demonstração - após desocultar](/files/0fade93442f6dcac041b2e83099d5de301ceabd5)

Isto mostra menos desordem em comparação com antes de aplicar a personalização. Ao mesmo tempo, mais informação sobre as alternativas de "Extra Workflow" está disponível para o utilizador. Além disso, o utilizador só se preocupará com "Extra Workflow Time" se isso for relevante.

A alteração da visibilidade desse campo foi feita usando um `"Customization"` bloco dentro de uma das `"Select"` opções. Atualmente, só pode haver no máximo um bloco desse tipo ativo de cada vez. `"Customization"` Como pode ver, o parâmetro

está completamente oculto. Isto é feito definindo o `$DeviceId` para este parâmetro. `"Hide": true` Os parâmetros podem ter um

. Oferecemos uma `DisplayName`explicação legível por humanos para substituir `DisplayName` para substituir `$ExtraWorkflowTime` na IU. Veja outros [modificadores](#modifiers) para mais informações.

Pode inserir parâmetros "sem nome" (em falta o `Nome` instrução) como a secção "Execute Extra Workflow", se quiser oferecer elementos de IU sem devolver diretamente um valor. Isto normalmente só é usado em conjunto com `Selecione`.

#### Selecione

Usámos `Selecione`, para apresentar uma lista de `Opções` num menu suspenso. Cada opção pode `Exibição` conter texto, ou acionar uma `Personalização`ação, como definir `Hide` ou um `Padrão` valor noutros parâmetros. No nosso exemplo, usámo-lo para (des)ocultar `$ExtraWorkflowTime` e substituir `$ExtraWorkflow`o seu valor.

`$ExtraWorkflowTime` é assim mostrado apenas quando relevante e o interruptor binário `$ExtraWorkflow` é agora substituído por alternativas significativas do ponto de vista do utilizador.

No caso de um `Selecione` para um parâmetro nomeado, cada opção deve ter um `"ParameterValue": "..."` para passar para o runbook. Pode colocar um `"ShowValue: false"` dentro do `Selecione` bloco para mostrar apenas o menu suspenso e não um campo para o valor resultante do parâmetro.

Exemplo de parâmetro nomeado:

```json
{
    "Name": "ExtraWorkflow",
    "DefaultValue": true,
    "DisplayName": "Executar Fluxo de Trabalho Adicional",
    "DisplayBefore": "ExtraWorkflowTime",
    "Select": {
        "Options": [
            {
                "Display": "Executar Meditação (opcional)",
                "ParameterValue": true
            },
            {
                "Display": "Ignorar a Atenção Plena do Dispositivo",
                "ParameterValue": false,
                "Customization": {
                    "Hide": [
                        "ExtraWorkflowTime"
                    ]
                }
            }
        ],
        "ShowValue": false
    }
}
```

A `Padrão` / `DefaultValue` instrução no parâmetro também especifica o estado inicial do menu suspenso. No caso de um parâmetro sem nome, use o `DisplayName` da opção pretendida, caso contrário forneça um valor de retorno predefinido, como "true" ou "false" ou alguma string.

#### Parâmetros

Se tiver apenas parâmetros nomeados, pode usar o formato ligeiramente mais curto `Parâmetros` em vez de `ParameterList`.

Para um exemplo, consulte SelectSimple

#### SelectSimple

Se o poder total de um `Selecione` não for necessário e quiser apenas oferecer uma lista de valores possíveis num menu suspenso (sem aplicar personalização adicional), pode usar `SelectSimple`.

`SelectSimple` só é utilizável para parâmetros nomeados.

Exemplo:

```json
{
    "Runbooks": {
        "rjgit-device_demo-runbook-customizing": {
            "Parameters": {
                "DeviceId": {
                    "Hide": true
                }, 
                "ExtraWorkflow": {
                    "Name": "ExtraWorkflow",
                    "DisplayName": "Executar Fluxo de Trabalho Adicional",
                    "Default": false,
                    "SelectSimple": {
                        "Executar Meditação (opcional)": true,
                        "Ignorar a Atenção Plena do Dispositivo": false
                    }
                },
                "ExtraWorkflowTime": {
                    "DisplayName": "Quanto tempo para meditar?"
                }
            }
        }
    }
}
```

A maior diferença (para além de ser muito mais curto) em relação ao nosso exemplo anterior é que `$ExtraWorkflowTime` está sempre visível.

#### Modifiers

Cada parâmetro pode ter um ou mais dos seguintes modificadores:

* `"DisplayName": "text"` - Apresentar "text" como nome do parâmetro na IU
* `"Hide": true / false` - Ocultar este parâmetro
* `"Mandatory": true / false` - Exigir que este parâmetro seja preenchido
* `"ReadOnly": true / false` - Impedir que este parâmetro seja alterado em relação ao seu valor predefinido
* `"DefaultValue": "..."` - Definir um valor predefinido para este parâmetro. (Também pode usar `Padrão` em vez disso.)
* `"GraphFilter": "startswith(DisplayName, 'LIC_')"` - veja [Filtragem Graph](#graph-filtering)
* `"AllowEdit": true / false` - Impedir a edição manual deste parâmetro. (combine isto com modelos)

### Configurações

`Configurações` permite-lhe armazenar dados de configuração como nomes de Storage Account Azure num local central, mantendo-os separados dos seus runbooks.

Pode aceder a valores individuais de um bloco de parâmetros de um runbook usando `Use-RJInterface`.

Tomemos este exemplo de bloco de parâmetros de um runbook:

```powershell
param(
    [ValidateScript( { Use-RJInterface -Type Setting -Attribute "CaPoliciesExport.Container" } )]
    [string] $ContainerName,
    [ValidateScript( { Use-RJInterface -Type Setting -Attribute "CaPoliciesExport.ResourceGroup" } )]
    [string] $ResourceGroupName,
    [ValidateScript( { Use-RJInterface -Type Setting -Attribute "CaPoliciesExport.StorageAccount.Name" } )]
    [string] $StorageAccountName,
    [ValidateScript( { Use-RJInterface -Type Setting -Attribute "CaPoliciesExport.StorageAccount.Location" } )]
    [string] $StorageAccountLocation,
    [ValidateScript( { Use-RJInterface -Type Setting -Attribute "CaPoliciesExport.StorageAccount.Sku" } )]
    [string] $StorageAccountSku
)
```

O Portal tentará preencher previamente cada parâmetro com valores do datastore central - se estiverem presentes. Isto também funciona se o parâmetro tiver sido ocultado na IU.

Um possível JSON no datastore para este runbook seria:

```json
{
    "Settings": {
        "CaPoliciesExport": {
            "ResourceGroup": "rj-runbooks-01",
            "StorageAccount": {
                "Name": "rjrbexports01",
                "Location": "West Europe",
                "Sku": "Standard_LRS"
            }
        }
    }
}
```

O elemento em falta `Container` não será simplesmente preenchido previamente na IU.

### Modelos

`Modelos` usar referências JSON para importar dados - por exemplo, uma longa lista de localizações de escritório - ao usar uma `Selecione` instrução.

Isto permite manter uma personalização neutra/reutilizável/separada dos dados reais.

Tomemos o exemplo da integração de novos utilizadores. Pode ter várias opções para departamentos ou localizações de escritório, em que atribuir uma localização de escritório também exige uma determinada morada, país, estado, etc.

O exemplo seguinte de personalização de runbook usa a `$ref` dentro do `Runbooks` secção para referenciar/importar uma subárvore da `Modelos` secção. Repare nas `$id`/`$values` palavras-chave. Tenha em atenção que `$id`/`$values` têm de ser definidas antes de serem referenciadas usando `$ref`. É por isso que `Modelos` está definido antes de `Runbooks` neste exemplo.

Neste exemplo, dizemos ao portal para obter a subárvore com o `$id` chamado `LocationOptions` e incluir os seus `$values`, substituindo a `$ref` instrução. Assim, o portal irá renderizar um `Selecione` tal como descrito na `Runbooks` secção, mas incluir as opções reais de `Modelos`.

Um modelo pode conter qualquer instrução suportada no local de referência. Neste exemplo, usamos uma `Personalização` instrução para modificar outros parâmetros como `StreetAddress`.

Assim, podemos ter uma personalização específica do runbook em `Runbooks` reutilizável em vários ambientes, mantendo os dados reais separados.

```json
{
    "Templates": {
        "Options": [
            {
                "$id": "LocationOptions",
                "$values": [
                    {
                        "Display": "DE-OF",
                        "Customization": {
                            "Default": {
                                "StreetAddress": "Kaiserstraße 39",
                                "PostalCode": "63065",
                                "City": "Offenbach",
                                "Country": "Alemanha"
                            }
                        }
                    },
                    {
                        "Display": "DE-DEG",
                        "Customization": {
                            "Default": {
                                "StreetAddress": "Lateinschulgassse 24-26",
                                "PostalCode": "94469",
                                "City": "Deggendorf",
                                "Country": "Alemanha"
                            }
                        }
                    },
                    {
                        "Display": "DE-HH",
                        "Customization": {
                            "Default": {
                                "StreetAddress": "Hans-Henny-Jahnn-Weg 53",
                                "PostalCode": "22085",
                                "City": "Hamburgo",
                                "Country": "Alemanha"
                            }
                        }
                    },
                    {
                        "Display": "FI-HS",
                        "Customization": {
                            "Default": {
                                "StreetAddress": "Somewhere 42",
                                "PostalCode": "12345",
                                "City": "Helsínquia",
                                "Country": "Finlândia"
                            }
                        }
                    }
                ]
            },
            {
                "$id": "CompanyOptions",
                "$values": [
                    {
                        "Id": "gkg",
                        "Display": "glueckkanja",
                        "Value": "glueckkanja AG"
                    },
                    {
                        "Id": "pp",
                        "Display": "PRIMEPULSE",
                        "Value": "PRIMEPULSE SE"
                    }
                ]
            }
        ]
    },
    "Runbooks": {
        "rjgit-org_general_add-user": {
            "ParameterList": [
                {
                    "DisplayName": "Localização do Office",
                    "DisplayAfter": "CompanyName",
                    "Select": {
                        "Options": {
                            "$ref": "LocationOptions"
                        }
                    }
                },
                {
                    "Name": "CompanyName",
                    "Select": {
                        "Options": {
                            "$ref": "CompanyOptions"
                        },
                        "AllowEdit": false
                    }
                }
            ],
            "ReadOnly": [
                "StreetAddress",
                "PostalCode",
                "City",
                "Country"
            ]
        }
    }
}
```

Isto criará a seguinte interface:

![Demonstração - ref-location](/files/717595c867fde31c038d5dfdaae7050099a19769)

![Demonstração - ref-address](/files/e4bdfb7b2cfc908c189034499e2393bf9c868b7d)

### Filtros do Graph

Você pode preparar [Filtros de Graph ODATA](https://docs.microsoft.com/en-us/graph/query-parameters?context=graph%2Fapi%2F1.0\&view=graph-rest-1.0#filter-parameter) para serem usados em vários runbooks. Armazene-os numa secção chamada `GraphFilters`.

Os exemplos seguintes filtram por um certo prefixo no `DisplayName` de um grupo, para mostrar apenas grupos relacionados com licenciamento num seletor de grupos.

```json
"GraphFilters": {
    "LicenseGroup": "startswith(DisplayName, 'LIC_')" // também incluído no código RJ como padrão
  }
```

Ver [Filtragem do Graph](#graph-filtering) sobre como usar isto a partir de um runbook.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.realmjoin.com/pt/automacao/runbooks/runbook-customization.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
