Modelos de resposta do Cartão Adaptável para plug-ins de API do Microsoft 365 Copilot

Importante

Plugins só são suportados como ações em agentes declarativos. Eles não estão habilitados no Microsoft 365 Copilot.

Os plug-ins de API podem usar modelos de resposta de Cartão Adaptável para aprimorar a resposta gerada pelo Microsoft 365 Copilot com base na resposta recebida da API. O Cartão Adaptável renderiza citações dentro da resposta gerada.

Os plug-ins de API podem definir um modelo de resposta de Cartão Adaptável de duas maneiras: como um modelo estático definido no manifesto do plug-in ou como um modelo dinâmico retornado como parte da resposta da API. Os desenvolvedores de plug-ins definem modelos usando o esquema do Cartão Adaptável em combinação com a linguagem de modelo de Cartões Adaptáveis.

Modelos de resposta estáticos

Os modelos de resposta estática são uma boa opção se sua API sempre retornar itens do mesmo tipo e o formato do Cartão Adaptável não precisar mudar com frequência. Defina um modelo estático na static_template propriedade do response_semantics objeto no manifesto do plug-in, conforme mostrado no exemplo a seguir.

"functions": [
  {
    "name": "GetBudgets",
    "description": "Returns details including name and available funds of budgets, optionally filtered by budget name",
    "capabilities": {
      "response_semantics": {
        "data_path": "$",
        "properties": {
          "title": "$.name",
          "subtitle": "$.availableFunds"
        },
        "static_template": {
          "type": "AdaptiveCard",
          "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
          "version": "1.5",
          "body": [
            {
              "type": "Container",
              "$data": "${$root}",
              "items": [
                {
                  "type": "TextBlock",
                  "text": "Name: ${if(name, name, 'N/A')}",
                  "wrap": true
                },
                {
                  "type": "TextBlock",
                  "text": "Available funds: ${if(availableFunds, formatNumber(availableFunds, 2), 'N/A')}",
                  "wrap": true
                }
              ]
            }
          ]
        }
      }
    }
  },
]
  • Defina a response_semantics.data_path propriedade como . This value is a [JSONPath query](https://www.rfc-editor.org/rfc/rfc9535) that indicates that the root of the JSON response contains the relevant data. The static_template.body["$data"]property value is${$root}, which is Adaptive Card template language syntax to override any prior data scoping and break back to the root. Setting this value isn't strictly needed, since the data_path' já está definida como raiz.
  • A text propriedade do primeiro TextBlock usa a sintaxe ${if(name, name, 'N/A')}do modelo de Cartão Adaptável. Isso faz referência à name propriedade na resposta da API. A if função especifica que se name tiver um valor, use esse valor, caso contrário, use N/A.
  • A text propriedade do segundo TextBlock usa a sintaxe ${if(availableFunds, formatNumber(availableFunds, 2), 'N/A')}do modelo de Cartão Adaptável. Isso faz referência à availableFunds propriedade na resposta da API. A formatNumber função renderiza o número como uma cadeia de caracteres com duas casas decimais.

Considere este modelo estático e a resposta da API a seguir.

[
    {
        "name": "Fourth Coffee lobby renovation",
        "availableFunds": 12000
    }
]

Essa combinação resulta no seguinte Cartão Adaptável.

Um Cartão Adaptável renderizando uma citação no Microsoft 365 Copilot

Modelos de resposta dinâmica

Os modelos de resposta dinâmica são uma boa opção se sua API retornar vários tipos. Com modelos dinâmicos, você pode atribuir um modelo de resposta a cada item retornado. Um ou mais modelos dinâmicos são retornados como parte da resposta da API, e os itens de dados na resposta indicam qual modelo usar.

Para usar modelos dinâmicos, indique qual propriedade nos itens de dados especifica o response_semantics.properties.template_selector modelo na propriedade no manifesto do plug-in da API, conforme mostrado neste exemplo.

{
  "name": "GetTransactions",
  "description": "Returns details of transactions identified from filters like budget name or category. Multiple filters can be used in combination to refine the list of transactions returned",
  "capabilities": {
    "response_semantics": {
      "data_path": "$.transactions",
      "properties": {
        "template_selector": "$.displayTemplate"
      }
    }
  }
}

Neste exemplo, a data_path propriedade é definida como $.transactions, indicando que os dados dos cartões são encontrados na transactions propriedade na raiz da resposta da API. A template_selector propriedade é definida como $.displayTemplate, indicando que a propriedade em cada item na transactions matriz que especifica o modelo a ser usado é a displayTemplate propriedade.

A propriedade indicada template_selector pela propriedade contém uma consulta JSONPath para localizar o modelo para o item na resposta.

Considere este modelo e a resposta da API a seguir.

{
  "transactions": [
    {
      "budgetName": "Fourth Coffee lobby renovation",
      "amount": -2000,
      "description": "Property survey for permit application",
      "expenseCategory": "permits",
      "displayTemplate": "$.templates.debit"
    },
    {
      "budgetName": "Fourth Coffee lobby renovation",
      "amount": -7200,
      "description": "Lumber and drywall for lobby",
      "expenseCategory": "materials",
      "displayTemplate": "$.templates.debit"
    },
    {
      "budgetName": "Fourth Coffee lobby renovation",
      "amount": 5000,
      "description": "Additional funds to cover cost overruns",
      "expenseCategory": null,
      "displayTemplate": "$.templates.credit"
    }
  ],
  "templates": {
    "debit": {
      "type": "AdaptiveCard",
      "version": "1.5",
      "body": [
        {
          "type": "TextBlock",
          "size": "medium",
          "weight": "bolder",
          "color": "attention",
          "text": "Debit"
        },
        {
          "type": "FactSet",
          "facts": [
            {
              "title": "Budget",
              "value": "${budgetName}"
            },
            {
              "title": "Amount",
              "value": "${formatNumber(amount, 2)}"
            },
            {
              "title": "Category",
              "value": "${if(expenseCategory, expenseCategory, 'N/A')}"
            },
            {
              "title": "Description",
              "value": "${if(description, description, 'N/A')}"
            }
          ]
        }
      ],
      "$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
    },
    "credit": {
      "type": "AdaptiveCard",
      "version": "1.5",
      "body": [
        {
          "type": "TextBlock",
          "size": "medium",
          "weight": "bolder",
          "color": "good",
          "text": "Credit"
        },
        {
          "type": "FactSet",
          "facts": [
            {
              "title": "Budget",
              "value": "${budgetName}"
            },
            {
              "title": "Amount",
              "value": "${formatNumber(amount, 2)}"
            },
            {
              "title": "Description",
              "value": "${if(description, description, 'N/A')}"
            }
          ]
        }
      ],
      "$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
    }
  }
}
  • A transactions propriedade na resposta contém uma matriz de itens.
  • A templates propriedade é um objeto, com cada propriedade nesse objeto contendo um modelo de Cartão Adaptável.
  • O displayTemplate em cada objeto na transactions matriz é definido como ou $.templates.debit$.templates.credit.

A combinação desse manifesto de plug-in e a resposta da API resulta nos seguintes Cartões Adaptáveis.

Um Cartão Adaptável renderizando uma transação de débito.

Um Cartão Adaptável renderizando uma transação de crédito.

Evitar Cartões Adaptáveis em branco quando uma matriz na resposta da API estiver vazia

Os Cartões Adaptáveis podem ser renderizados em branco quando uma propriedade de matriz na resposta da API está vazia e o modelo não inclui lógica condicional para lidar com esse cenário.

O exemplo a seguir mostra uma resposta de API em que a recommendations matriz não contém itens:

{"answer":"","recommendations":[],"followUpMessage":""}

Nesse caso:

  1. A matriz de recomendações não tem itens.
  2. O modelo de Cartão Adaptável tenta iterar na matriz sem verificar se os dados estão disponíveis.

Para evitar que um card em branco seja renderizado, vincule o modelo à propriedade de matriz correta e adicione lógica condicional para controlar a renderização.

Associe-se à matriz usando data_path:

"data_path": "$.recommendations"

Iterar sobre objetos somente quando houver dados:

{ "type": "ColumnSet", "$data": "${$root}", "$when": "${title != null && title != ''}" }

Opcionalmente, forneça texto de fallback quando a matriz estiver vazia:

{ "type": "TextBlock", "text": "No recommendations available", "$when": "${length($root) == 0}" }

Dica

Sempre valide data_path e inclua $when condições para matrizes vazias para evitar Cartões Adaptáveis em branco.

Usar modelos estáticos e dinâmicos juntos

Os plug-ins podem combinar o uso de modelos estáticos e dinâmicos. Nesse cenário, o modelo estático atua como um modelo padrão que é usado se o item não tiver a template_selector propriedade presente ou se seu valor não for resolvido para um modelo na resposta da API.

Adicionar domínios ao manifesto do aplicativo

Adicione todos os domínios que seu Cartão Adaptável usa à seção validDomains do manifesto do aplicativo.

  • Ao usar Action.OpenUrlo , certifique-se de incluir o domínio da URL de destino na validDomains propriedade. Se o domínio não estiver listado, o Teams exibirá a URL da mensagem que pode levar a conteúdo não confiável.
  • Os URLs de imagem retornados pelo plug-in de API ou pelo agente declarativo em uma resposta de Cartão Adaptável devem ter o domínio listado validDomains na propriedade. Se o domínio não estiver listado, o Microsoft 365 Copilot não renderizará a imagem.

Garanta que os Cartões Adaptáveis sejam responsivos nos hubs do Microsoft 365 Copilot

Os cartões adaptáveis devem ser projetados para serem responsivos em vários tamanhos de superfície. Esse design garante uma experiência de usuário perfeita, independentemente do dispositivo ou plataforma usada. Para atingir essa meta, valide os Cartões Adaptáveis em diferentes hubs do Microsoft 365 Copilot, incluindo Teams, Word e PowerPoint. Além disso, valide várias larguras de visor contraindo e expandindo a interface do usuário do Copilot. Esse processo garante que os Cartões Adaptáveis funcionem de maneira ideal e forneçam uma experiência consistente em todas as plataformas. Aplicar as seguintes práticas:

  • Evite usar layouts de várias colunas sempre que possível. Layouts de coluna única tendem a renderizar bem, mesmo nas larguras de janela de visualização mais estreitas.
  • Evite colocar elementos de texto e imagem na mesma linha, a menos que a imagem seja um pequeno ícone ou avatar.
  • Evite atribuir uma largura fixa aos elementos dentro do Cartão Adaptável; Em vez disso, permita que eles sejam redimensionados de acordo com a largura do visor. No entanto, você pode atribuir uma largura fixa a imagens pequenas, como ícones e avatares.