Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(spec-parser): update to support type b ai-plugin #10972

Merged
merged 7 commits into from
Mar 7, 2024
Merged

Conversation

SLdragon
Copy link
Contributor

@SLdragon SLdragon commented Mar 4, 2024

Example:

Code sample:

  const testFolder = path.resolve("../", path.dirname(__dirname), "test-material");
  const manifest = testFolder + "/manifest.json";
  const spec = testFolder + "/petstore.yaml";
  const parser = new SpecParser(spec, {
    allowMultipleParameters: true,
    isCopilot: true,
  });
  const list = await parser.list();
  const validate = await parser.validate();
  const apis = list.map((item) => item.api);
  const result = await parser.generateForCopilot(manifest, apis, testFolder + "/" + "result.yaml", "ai-plugin.json");

OpenAPI spec file:

openapi: 3.0.0
info:
  title: Phone Service
  description: >-
    http service to operate phone via http request, such as send message, get
    contacts, etc
  version: 1.0.2
servers:
  - url: https://dcg.microsoft.com
paths:
  /DeviceDataConnector/devices/default/contacts:
    get:
      operationId: getContactList
      summary: Get contact list from device.
      description: Get contact list from device.
      parameters:
        - name: top
          in: query
          description: The top number of contacts to return, default is 100
          required: false
          schema:
            type: string
        - name: filter
          in: query
          description: >-
            The filter used to filter the contacts, currently support filter by
            name, company and location, such as `filter=name has $contactName`,
            also it supports `and` and `or` operator, such as `filter=name has
            $contactName or company has $company`
          required: false
          schema:
            type: string
        - name: name
          in: query
          description: The parameter to filter the contacts by name, such as `name=Tom`
          required: false
          schema:
            type: string
        - name: company
          in: query
          description: >-
            The parameter to filter the contacts by company, such as
            `company=Microsoft`
          required: false
          schema:
            type: string
      responses:
        '200':
         ...

Generated manifest file:

{
  "$schema": "https://raw.githubusercontent.com/OfficeDev/microsoft-teams-app-schema/preview/DevPreview/MicrosoftTeams.schema.json",
  "manifestVersion": "devPreview",
  "version": "1.0.0",
  "id": "${{TEAMS_APP_ID}}",
  "packageName": "com.microsoft.teams.extension",
  "developer": {
    "name": "Teams App, Inc.",
    "websiteUrl": "https://www.example.com",
    "privacyUrl": "https://www.example.com/termofuse",
    "termsOfUseUrl": "https://www.example.com/privacy"
  },
  "icons": {
    "color": "color.png",
    "outline": "outline.png"
  },
  "name": {
    "short": "Phone Service",
    "full": "Phone Service"
  },
  "description": {
    "short": "Phone Service",
    "full": "http service to operate phone via http request, such as send message, get contacts, etc"
  },
  "accentColor": "#FFFFFF",
  "composeExtensions": [],
  "permissions": [
    "identity",
    "messageTeamMembers"
  ],
  "validDomains": [],
  "apiPlugins": [
    {
      "pluginFile": "ai-plugin.json"
    }
  ]
}

Generated ai-plugin file:

{
  "schema_version": "v2",
  "name_for_human": "Phone Service",
  "description_for_human": "http service to operate phone via http request, such as send message, get contacts, etc",
  "functions": [
    {
      "name": "getContactList",
      "description": "Get contact list from device.",
      "parameters": {
        "type": "object",
        "properties": {
          "top": {
            "type": "string",
            "description": "The top number of contacts to return, default is 100"
          },
          "filter": {
            "type": "string",
            "description": "The filter used to filter the contacts, currently support filter by name, company and location, such as `filter=name has $contactName`, also it supports `and` and `or` operator, such as `filter=name has $contactName or company has $company`"
          },
          "name": {
            "type": "string",
            "description": "The parameter to filter the contacts by name, such as `name=Tom`"
          },
          "company": {
            "type": "string",
            "description": "The parameter to filter the contacts by company, such as `company=Microsoft`"
          }
        },
        "required": []
      },
      "states": {
        "reasoning": {
          "description": "",
          "instructions": []
        },
        "responding": {
          "description": "",
          "instructions": []
        }
      }
    }
  ],
  "runtimes": [
    {
      "type": "OpenApi",
      "auth": {
        "type": "none"
      },
      "spec": {
        "url": "result.yaml"
      },
      "run_for_functions": [
        "getContactList"
      ]
    }
  ]
}

Copy link

codecov bot commented Mar 4, 2024

Codecov Report

Attention: Patch coverage is 89.81481% with 11 lines in your changes are missing coverage. Please review.

Project coverage is 87.01%. Comparing base (fccd829) to head (d4b3fbb).
Report is 22 commits behind head on dev.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##              dev   #10972      +/-   ##
==========================================
+ Coverage   87.00%   87.01%   +0.01%     
==========================================
  Files         451      451              
  Lines       26779    26884     +105     
  Branches     5375     5401      +26     
==========================================
+ Hits        23299    23394      +95     
- Misses       1758     1760       +2     
- Partials     1722     1730       +8     
Files Coverage Δ
packages/spec-parser/src/constants.ts 100.00% <100.00%> (ø)
packages/spec-parser/src/interfaces.ts 100.00% <ø> (ø)
packages/spec-parser/src/specFilter.ts 100.00% <ø> (ø)
packages/spec-parser/src/specParser.ts 97.48% <100.00%> (+0.34%) ⬆️
packages/spec-parser/src/utils.ts 94.92% <88.88%> (-0.61%) ⬇️
packages/spec-parser/src/manifestUpdater.ts 88.99% <86.88%> (-1.01%) ⬇️

... and 3 files with indirect coverage changes

filter: string[],
outputSpecPath: string,
signal?: AbortSignal
): Promise<GenerateResult> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we also make ai-plugin.json as an input parameter? I think user may customize the file location when they want to use the codelens to add a new API?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

parameters: parameters,
states: {
reasoning: {
description: ConstantString.ReasoningDescription,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kind of curious why we use constant string here. sample value: https://spec-hub.azurewebsites.net/specifications/PluginManifest-draft.html#example-7 Should we leave it empty if we are not able to generate it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, we leave them empty

manifestPath: string,
filter: string[],
outputSpecPath: string,
apiPluginFileName: string,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just want to confirm if you hope to pass the file name. might be better if it is path?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will update to use path instead of name

@SLdragon SLdragon changed the title perf(spec-parser): update to support ai-plugin perf(spec-parser): update to support type b ai-plugin Mar 5, 2024
@SLdragon SLdragon merged commit b00041d into dev Mar 7, 2024
25 checks passed
@SLdragon SLdragon deleted the rentu-update34 branch March 7, 2024 02:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants