Compartilhar via


Criar plug-ins de API com o TypeSpec para o Microsoft 365 Copilot

Importante

Os plug-ins de API só são suportados como ações dentro de agentes declarativos. Não estão ativados no Microsoft 365 Copilot.

Os plug-ins de API são ações personalizadas para agentes declarativos que ligam uma API REST com uma especificação OpenAPI ao Microsoft 365 Copilot. Este guia demonstra como adicionar um plug-in de API a um agente declarativo com o TypeSpec e o Toolkit de Agentes do Microsoft 365.

Pré-requisitos

Dica

Para obter os melhores resultados, certifique-se de que a API que está a gerar segue as diretrizes detalhadas em Como tornar um documento OpenAPI eficaz na expansão do Copilot.

Adicionar uma GET operação

Para começar, adicione uma GET operação para listar todos os itens de publicação. Abra o main.tsp ficheiro e adicione um novo espaço de nomes PostsAPI no MyAgent espaço de nomes com o seguinte conteúdo.

// Omitted for brevity
namespace MyAgent {
  // Omitted for brevity
  @service
  @server("https://jsonplaceholder.typicode.com")
  @actions(#{
    nameForHuman: "Posts APIs",
    descriptionForHuman: "Manage blog post items with the JSON Placeholder API.",
    descriptionForModel: "Read, create, update and delete blog post items with the JSON Placeholder API."
  })
  namespace PostsAPI {

    /**
     * List all blog post items.
     */
    @route("/posts")
    @get op listPosts(): PostItem[];

    /**
     * Structure of a blog post item.
     */
    model PostItem {
      /**
       * The ID of the user who created the post.
       */
      userId: integer;

      /**
       * The ID of the post.
       */
      @visibility(Lifecycle.Read)
      id: integer;

      /**
       * The title of the post.
       */
      title: string;

      /**
       * The body of the post.
       */
      body: string;
    }
  }
  // Omitted for brevity
}

Este código define o PostItem modelo e a API GET /postsREST.

Adicionar uma GET operação com um parâmetro de consulta

A GET operação no exemplo anterior não utiliza parâmetros. Para ativar a filtragem por ID de utilizador, atualize a GET operação com um parâmetro de consulta opcional para filtrar os resultados por ID de utilizador.

Abra o main.tsp ficheiro e substitua a operação existente listPosts pelo seguinte conteúdo.

/**
 * List all blog post items.
  * @param userId The ID of the user who created the post. If not provided, all posts will be returned.
  */
@route("/posts")
@get op listPosts(@query userId?: integer): PostItem[];

O @query userId? parâmetro adicionado às listPosts atualizações da API REST para GET /posts?userId={userId}.

Adicionar uma card adaptável a uma GET operação

Adicionar um Cartão Ajustável à listPosts operação altera a forma como as citações na resposta gerada são compostas.

Crie um novo ficheiro com o nome post-card.json no diretório appPackage e adicione o seguinte conteúdo.

{
  "type": "AdaptiveCard",
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.5",
  "body": [
    {
      "type": "Container",
      "$data": "${$root}",
      "items": [
        {
          "type": "TextBlock",
          "text": "**${if(title, title, 'N/A')}**",
          "wrap": true
        },
        {
          "type": "TextBlock",
          "text": "${if(body, body, 'N/A')}",
          "wrap": true
        }
      ]
    }
  ],
  "actions": [
    {
      "type": "Action.OpenUrl",
      "title": "Read More",
      "url": "https://www.bing.com/search?q=https://jsonplaceholder.typicode.com/posts/${id}"
    }
  ]
}

Abra o main.tsp ficheiro e adicione o @card decorador à listPosts operação, conforme mostrado no fragmento de código seguinte.

/**
 * List all blog post items.
  * @param userId The ID of the user who created the post. If not provided, all posts will be returned.
  */
@route("/posts")
@card(#{ dataPath: "$", file: "post-card.json", properties: #{ title: "$.title" } })
@get op listPosts(@query userId?: integer): PostItem[];

Adicionar uma POST operação

Abra o main.tsp ficheiro e, no PostsAPI espaço de nomes, adicione o seguinte conteúdo.

/**
 * Create a new blog post item.
 * @param post The post item to create.
 */
@route("/posts")
@post op createPost(@body post: PostItem): PostItem;

Este código define a API POST /postsREST , que cria uma nova mensagem de blogue.

Adicionar uma PATCH operação

Abra o main.tsp ficheiro e, no PostsAPI espaço de nomes, adicione o seguinte conteúdo.

/**
 * Updates a blog post item.
 * @param id The ID of the post to update.
 * @param post The updated post item.
 */
@route("/posts/{id}")
@patch op updatePost(@path id: integer, @body post: PostItem): PostItem;

Este código define a API PATCH /posts/{id}REST , que atualiza uma mensagem de blogue existente.

Adicionar uma DELETE operação

Abra o main.tsp ficheiro e, no PostsAPI espaço de nomes, adicione o seguinte conteúdo.

/**
 * Deletes a blog post item.
 * @param id The ID of the post to delete.
 */
@route("/posts/{id}")
@delete op deletePost(@path id: integer): void;

Este código define a API DELETE /posts/{id}REST , que elimina uma mensagem de blogue existente.

Testar as ações personalizadas

  1. Selecione o ícone Toolkit de Agentes do Microsoft 365 na Barra de Atividade do lado esquerdo.
  2. No painel Ciclo de Vida , selecione Aprovisionar.
  3. Aguarde pela conclusão do aprovisionamento e, em seguida, abra-o https://m365.cloud.microsoft/ no browser.
  4. Selecione o agente na lista de agentes.
  5. Teste o agente com os seguintes pedidos ou experimente os seus próprios pedidos.

Testar a operação GET

Linha de comandos: "Liste todas as mensagens do blogue e compontue-as como uma tabela."

Uma captura de ecrã de uma resposta de um agente declarativo com base em novas operações GET

Linha de comandos: "Liste todas as mensagens do blogue para o utilizador com o ID 1 e componione-as como uma tabela."

Captura de ecrã de uma resposta de um agente declarativo com base em operações GET com cartões ajustáveis

Testar a operação POST

Linha de comandos: "Crie uma nova mensagem de blogue com o ID de utilizador 1, o título 'New Post' e o corpo 'This is a new post'."

Uma captura de ecrã de uma resposta de um agente declarativo com base nas operações POST

Testar a operação PATCH

Linha de comandos: "Atualize a mensagem do blogue com o ID 30 e atualize o título para 'Título Atualizado' e corpo para 'Corpo Atualizado'."

Uma captura de ecrã de uma resposta de um agente declarativo com base nas operações patch

Testar a operação DELETE

Linha de comandos: "Elimine a mensagem do blogue com o ID 50."

Uma captura de ecrã de uma resposta de um agente declarativo com base nas operações DELETE

Exemplo de um ficheiro completo main.tsp

Segue-se um exemplo de um ficheiro completo main.tsp com as GEToperações , POST, PATCHe DELETE adicionadas.

import "@typespec/http";
import "@typespec/openapi3";
import "@microsoft/typespec-m365-copilot";

using TypeSpec.Http;
using TypeSpec.M365.Copilot.Actions;
using TypeSpec.M365.Copilot.Agents;

@agent(
  "My Posts Agent",
  "Declarative agent focusing on blog posts management."
)

@instructions("""
  You should help users with blog posts management.
  You can read, create, update and delete blog post items.
  You can also search for blog posts by user ID.
""")

@conversationStarter(#{
  title: "List Blog Posts",
  text: "List all blog posts and render them as a table."
})

@conversationStarter(#{
  title: "Lists a user's blog posts",
  text: "List all blog posts for the user with ID 1 and render them as a table."
})

@conversationStarter(#{
  title: "Delete a blog post",
  text: "Delete the blog post with ID 50."
})

@conversationStarter(#{
  title: "Update a blog post",
  text: "Update the blog post with ID 30 and update the title to 'Updated Title' and body to 'Updated Body'."
})

@conversationStarter(#{
  title: "Create a blog post",
  text: "Create a new blog post with user ID 1, title 'New Post' and body 'This is a new post'."
})

@conversationStarter(#{
  title: "Get a blog post",
  text: "Get all the details about the blog post with ID 10."
})

namespace MyAgent {
  @service
  @server("https://jsonplaceholder.typicode.com")
  @actions(#{
    nameForHuman: "Posts APIs",
    descriptionForHuman: "Manage blog post items on JSON Placeholder APIs.",
    descriptionForModel: "Read, create, update and delete blog post items on the JSON Placeholder APIs."
  })
  namespace PostsAPI {
    /**
     * List all blog post items.
     * @param userId The ID of the user who created the post. If not provided, all posts will be returned.
     */
    @route("/posts")
    @card(#{ dataPath: "$", file: "post-card.json", properties: #{ title: "$.title" } })
    @get op listPosts(@query userId?: integer): PostItem[];

    /**
     * Get a blog post item by ID.
     */
    @route("/posts/{id}")
    @card(#{ dataPath: "$", file: "post-card.json", properties: #{ title: "$.title" } })
    @get op getPost(@path id: integer): PostItem;

    /**
     * Create a new blog post item.
     * @param post The post item to create.
     */
    @route("/posts")
    @post op createPost(@body post: PostItem): PostItem;

    /**
     * Updates a blog post item.
     * @param id The ID of the post to update.
     * @param post The updated post item.
     */
    @route("/posts/{id}")
    @patch op updatePost(@path id: integer, @body post: PostItem): PostItem;

    /**
     * Deletes a blog post item.
     * @param id The ID of the post to delete.
     */
    @route("/posts/{id}")
    @delete op deletePost(@path id: integer): void;

    model PostItem {
      /**
       * The ID of the user who created the post.
       */
      userId: integer;

      /**
       * The ID of the post.
       */
      @visibility(Lifecycle.Read)
      id: integer;

      /**
       * The title of the post.
       */
      title: string;

      /**
       * The body of the post.
       */
      body: string;
    }
  }
}