diff --git a/use-cases/agents/3p-tool/PartnerContributingGuide.md b/use-cases/agents/3p-tool/PartnerContributingGuide.md new file mode 100644 index 000000000..3ccc00c2d --- /dev/null +++ b/use-cases/agents/3p-tool/PartnerContributingGuide.md @@ -0,0 +1,38 @@ +# 3p Tool Partner Contributing Guide + +## Who should read this? +This contributing guide is designed for partners who want to bring their APIs as part of the **Azure AI Foundry Tool Catalog** so that customers can integrate your APIs with Azure AI Agent service through a tool to retrieve data or integrating with a workflow. + +## Prepare your PR +Your PR needs to create a new folder with the tool name and include the following information: +- `README.md` (required): follow this [template](./README_template_for_parter.md) as an example and this README file will serve as public documentation for help customers set up and use the tool with your API through Azure AI Agent service + - The name, logo, and description in this README file will be used in the Azure AI Foundry Portal user experience and marketing materials. + - It must include how customers set up an account with your API directly and your customer support contact or website. + - Customers should be able to follow this README file and successfully use the tool with Azure AI Agent service. +- `sample code` (required): using at least one of the SDK below + - (recommended) Python: [Azure AI Projects client library for Python | Microsoft Learn](https://learn.microsoft.com/en-us/python/api/overview/azure/ai-projects-readme?view=azure-python-preview#create-agent-with-openapi) + - .NET/C#: [Azure AI Projects client library for .NET - Azure for .NET Developers | Microsoft Learn](https://learn.microsoft.com/en-us/dotnet/api/overview/azure/ai.projects-readme?view=azure-dotnet-preview) + - JavaScript: [Azure AI Projects client library for JavaScript | Microsoft Learn](https://learn.microsoft.com/en-us/javascript/api/overview/azure/ai-projects-readme?view=azure-node-preview) + - Requirements fot the code sample: + - you should have tested the code sample works end to end with the OpenAPI spec in this PR before submitting + - include the process of creating an `openApi` tool with your OpenAPI spec + - for `agent creation`, provide a user-friendly name and useful instructions customized for your API + - for `message creation`, provide an example of a user query that can be used with your API and expected response in comments +- `OpenAPI spec` (required): the OpenAPI spec for your API + - Your OpenAPI should be updated based on the requirements [here](https://learn.microsoft.com/en-us/azure/ai-services/agents/how-to/tools/openapi-spec?tabs=python&pivots=overview#authenticating-with-api-key) to support appropriate authentication method + - If you require customers to update the OpenAPI spec, please provide **clear** instructions and **placeholder** on where they should update in the OpenAPI spec file and the README.file. + - This OpenAPI spec will also be used in the Azure AI Foundry Portal user experience. +- `media` folder (optional): if you need to include any screenshots, please add the screenshots in this folder and refer to them. + +## Submit your PR +Before you submit the PR, please double check: +- you have **everything** required above ready +- you have **fully** tested your code sample + +Then, you can go ahead and create a PR. By creating a PR, you automatically agree to the Contributor License Agreement and see more details [here](../../../CONTRIBUTING.md). + +When creating the PR, please make sure you give your PR a reviewer-friendly name. We will come back to you within 10 business days. + +## Once your PR is approved +- customers will see a folder for the tool in `main` branch +- Azure AI Foundry Portal team will work to bring your tool to the Portal user experience. diff --git a/use-cases/agents/3p-tool/README.md b/use-cases/agents/3p-tool/README.md new file mode 100644 index 000000000..4879cfb82 --- /dev/null +++ b/use-cases/agents/3p-tool/README.md @@ -0,0 +1,34 @@ +# Connect with partner-authored tools in Azure AI Agent Service + +## Overview +The tool catalog in Azure AI Foundry portal is the hub to discover and use a wide range of tools for building AI agents with Azure AI Agent Service. The tool catalog features tools for extending your agents' abilities using hosted tools, and ones offered from partners such as Tripadvisor, and Morningstar. You can discover all tools offered by **partners** in this folder. + +> [!IMPORTANT] +> * Your use of connected non-Microsoft services is subject to the terms between you and the service provider. By connecting to a non-Microsoft service, you acknowledge that some of your data, such as prompt content, is passed to the non-Microsoft service, and/or your application might receive data from the non-Microsoft service. You're responsible for your use of non-Microsoft data. +> * Using tools from tool catalog may incur usage with tool providers, review the pricing plan with your selected tool data providers. +> * Code samples and OpenAPI spec are provided by partners as-is. **need help from CELA to rewrite this** + +## Get Started +1. Create an Azure AI Agent following the [documentation](https://learn.microsoft.com/en-us/azure/ai-services/agents/quickstart) + +1. Select tools provided by our partners for your agent + +|Tool |Description | +|---------|---------| +| [Tripadvisor](./Tripadvisor/README.md) | This tool lets you access Tripadvisor's useful travel platform that can, for example, provide travel guidance and reviews. | + +1. Review the README file provided by the partner and get started! + +## Frequently Asked Questions +1. Can I set up an account through Microsoft with the tool provided by a partner? + + No, you have to create an account with the partner directly. + +1. I am running into issues with the code sample, how should I troubleshoot? + + If this is an issue with Azure AI Agent service, please refer to your [support plan](https://support.microsoft.com/en-us). If this is an issue with the OpenAPI spec, code sample or authentication, please refer to the `customer support contact` provided by each partner in the README file. + +1. I want to learn more about Azure AI Agent service, where should I go? + + Please visit the public documentation [here](https://learn.microsoft.com/en-us/azure/ai-services/agents/) + diff --git a/use-cases/agents/3p-tool/README_template_for_partner.md b/use-cases/agents/3p-tool/README_template_for_partner.md new file mode 100644 index 000000000..48c5cae6c --- /dev/null +++ b/use-cases/agents/3p-tool/README_template_for_partner.md @@ -0,0 +1,48 @@ +# + will be used in Azure AI Foundry Portal experience and marketing materials. + +Requirement: +- Must exist and be written in English. +- Must be unique and distinguishable from any existing tool/agent template. +- Should be the name of your product or organization. +- Can't be longer than 30 characters. +- Can't contain the words *API*, *Tool*, *Azure AI Agent Service*, *Azure AI*, *Agent*, or any of our other Azure AI Foundry product names (for example, Document Intelligence). +- Can't end in a nonalphanumeric character, including carriage return, new line, or blank space. +- Good example: Tripadvisor +- Bad example: Tripadvisor Tool + +## Description + + + will be used in Azure AI Foundry Portal experience and marketing materials. + +Requirement: +- Ensure your description complies with the [Marketplace guidelines](https://learn.microsoft.com/en-us/legal/marketplace/certification-policies#10013-description). +- Must exist and be written in English. +- Must be free of grammatical and spelling errors. +- Length should be within 1 sentence, under 10 words +- Cannot contain *Azure AI Agent Service* or other Azure AI Foundry product names (such as Document Intelligence) +- If your tool includes multiple operations, the description should cover all operations. + +## Prerequisites + + +Requirement: +- Must include how to create a new account with your service +- Include any other requirements to set up the account, such as uploading data, etc +- Recommend including screenshots if possible to help customers understand. Store the screenshots in `media` folder + +## Setup + + +Requirement: +- If you require customers to use `connection` as authentication methods, walk customers from step by step to retrieve the secret (API key, token etc) and how to create a `customKeys` connection to store the secret +- Recommend including screenshots if possible to help customers understand. Store the screenshots in `media` folder + +## Use + + +## Customer Support Contact + + +By providing this customer support contact or website, customers will reach out to you directly if they run into issues with the OpenAPI spec, code sample, authentication etc. Customers will reach out to Microsoft if they run into issues with Azure AI Agent service. diff --git a/use-cases/agents/3p-tool/Tripadvisor/README.md b/use-cases/agents/3p-tool/Tripadvisor/README.md new file mode 100644 index 000000000..b9a42af15 --- /dev/null +++ b/use-cases/agents/3p-tool/Tripadvisor/README.md @@ -0,0 +1,58 @@ +# Tripadvisor + +## Description +Get travel data, guidance and reviews + +## Prerequisites + +* Obtain an API key for your [Tripadvisor developer account](https://www.tripadvisor.com/developers?screen=credentials). +* Make sure when you put 0.0.0.0/0 for the IP address restriction to allow traffic from Azure AI Agent Service. + +## Setup +1. Go to [Azure AI Foundry portal](https://ai.azure.com/) and select your AI Project. Select **Management Center**. + + :::image type="content" source="../../media/tools/licensed-data/project-assets.png" alt-text="A screenshot showing the selectors for the management center for an AI project." lightbox="../../media/tools/licensed-data/project-assets.png"::: + +1. Select **+new connection** in the settings page. + + :::image type="content" source="./media/connected-resources.png" alt-text="A screenshot showing the connections for the selected AI project." lightbox="../../media/tools/licensed-data/connected-resources.png"::: + +1. Select **custom keys** in **other resource types**. + + :::image type="content" source="./media/custom-keys.png" alt-text="A screenshot showing the custom key option in the settings page." lightbox="../../media/tools/licensed-data/custom-keys.png"::: + +1. Enter the following information to create a connection to store your Tripadvisor key: + 1. Set **Custom keys** to "key", with the value being your Tripadvisor API key. + 1. Make sure **is secret** is checked. + 1. Set the connection name to your connection name. You use this connection name in your sample code or Foundry Portal later. + 1. For the **Access** setting, you can choose either *this project only* or *shared to all projects*. Just make sure in your code, the connection string of the project you entered has access to this connection. + + :::image type="content" source="./media/connect-custom-resource.png" alt-text="A screenshot showing the screen for adding Tripadvisor connection information." lightbox="../../media/tools/licensed-data/connect-custom-resource.png"::: + +## Use Tripadvisor tool through Foundry portal + +1. To use the Tripadvisor tool in the Azure AI Foundry, in the **Create and debug** screen for your agent, scroll down the **Setup** pane on the right to **action**. Then select **Add**. + +1. Select **Tripadvisor** and follow the prompts to add the tool. + +1. Give a name for your Tripadvisor tool and provide an optional description. + + :::image type="content" source="./media/add-data-source.png" alt-text="A screenshot showing the Tripadvisor data source." lightbox="../../media/tools/licensed-data/add-data-source.png"::: + +1. Select the custom key connection you just created. + + :::image type="content" source="./media/add-connection.png" alt-text="A screenshot showing the connection for your Tripadvisor tool, and a JSON example." lightbox="../../media/tools/licensed-data/add-connection.png"::: + +1. Finish and start chatting. + +## Connect Tripadvisor through code-first experience + +You can follow the [code sample](./tripadvisor.py) to use Tripadvisor through Agent SDK. + +1. Remember to store and import Tripadvisor [OpenAPI spec](./tripadvisor.json). + +1. Make sure you have updated the authentication method to be `connection` and fill in the connection ID of your custom key connection. + ``` python + auth = OpenApiConnectionAuthDetails(security_scheme=OpenApiConnectionSecurityScheme(connection_id="your_connection_id")) + ``` +## Customer Support Contact diff --git a/use-cases/agents/3p-tool/Tripadvisor/media/add-connection.png b/use-cases/agents/3p-tool/Tripadvisor/media/add-connection.png new file mode 100644 index 000000000..0acd49844 Binary files /dev/null and b/use-cases/agents/3p-tool/Tripadvisor/media/add-connection.png differ diff --git a/use-cases/agents/3p-tool/Tripadvisor/media/add-data-source.png b/use-cases/agents/3p-tool/Tripadvisor/media/add-data-source.png new file mode 100644 index 000000000..c1cf70306 Binary files /dev/null and b/use-cases/agents/3p-tool/Tripadvisor/media/add-data-source.png differ diff --git a/use-cases/agents/3p-tool/Tripadvisor/media/connect-custom-resource.png b/use-cases/agents/3p-tool/Tripadvisor/media/connect-custom-resource.png new file mode 100644 index 000000000..d4b5c0aeb Binary files /dev/null and b/use-cases/agents/3p-tool/Tripadvisor/media/connect-custom-resource.png differ diff --git a/use-cases/agents/3p-tool/Tripadvisor/media/connected-resources.png b/use-cases/agents/3p-tool/Tripadvisor/media/connected-resources.png new file mode 100644 index 000000000..04e7aeb7d Binary files /dev/null and b/use-cases/agents/3p-tool/Tripadvisor/media/connected-resources.png differ diff --git a/use-cases/agents/3p-tool/Tripadvisor/media/custom-keys.png b/use-cases/agents/3p-tool/Tripadvisor/media/custom-keys.png new file mode 100644 index 000000000..8134c34a0 Binary files /dev/null and b/use-cases/agents/3p-tool/Tripadvisor/media/custom-keys.png differ diff --git a/use-cases/agents/3p-tool/Tripadvisor/media/project-assets.png b/use-cases/agents/3p-tool/Tripadvisor/media/project-assets.png new file mode 100644 index 000000000..0b5a6969a Binary files /dev/null and b/use-cases/agents/3p-tool/Tripadvisor/media/project-assets.png differ diff --git a/use-cases/agents/3p-tool/Tripadvisor/tripadvisor.json b/use-cases/agents/3p-tool/Tripadvisor/tripadvisor.json new file mode 100644 index 000000000..83c5e0e61 --- /dev/null +++ b/use-cases/agents/3p-tool/Tripadvisor/tripadvisor.json @@ -0,0 +1,1606 @@ +{ + "openapi": "3.0.1", + "servers": [ + { + "url": "https://api.content.tripadvisor.com/api" + } + ], + "info": { + "version": "1.0.0", + "title": "Content API - TripAdvisor(Knowledge)", + "description": "SSP includes Locations Details, Locations Photos, Locations Reviews, Location Search" + }, + "paths": { + "/v1/location/{locationId}/details": { + "get": { + "summary": "Location Details", + "description": "A Location Details request returns comprehensive information about a location (hotel, restaurant, or an attraction) such as name, address, rating, and URLs for the listing on Tripadvisor.", + "operationId": "getLocationDetails", + "tags": [ + "Location Details" + ], + "parameters": [ + { + "name": "locationId", + "in": "path", + "description": "A unique identifier for a location on Tripadvisor. The location ID can be obtained using the Location Search.", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "language", + "in": "query", + "description": "The language in which to return results (e.g. \"en\" for English or \"es\" for Spanish) from the list of our Supported Languages.", + "required": false, + "schema": { + "default": "en", + "type": "string", + "enum": [ + "ar", + "zh", + "zh_TW", + "da", + "nl", + "en_AU", + "en_CA", + "en_HK", + "en_IN", + "en_IE", + "en_MY", + "en_NZ", + "en_PH", + "en_SG", + "en_ZA", + "en_UK", + "en", + "fr", + "fr_BE", + "fr_CA", + "fr_CH", + "de_AT", + "de", + "el", + "iw", + "in", + "it", + "it_CH", + "ja", + "ko", + "no", + "pt_PT", + "pt", + "ru", + "es_AR", + "es_CO", + "es_MX", + "es_PE", + "es", + "es_VE", + "es_CL", + "sv", + "th", + "tr", + "vi" + ] + } + }, + { + "name": "currency", + "in": "query", + "description": "The currency code to use for request and response (should follow ISO 4217).", + "required": false, + "schema": { + "type": "string", + "default": "USD" + } + } + ], + "responses": { + "200": { + "description": "Details for the location", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "location_id": { + "description": "Unique Tripadvisor location ID of the destination or POI", + "type": "integer", + "format": "int32" + }, + "name": { + "description": "Name of the POI as listed on Tripadvisor", + "type": "string" + }, + "description": { + "description": "Description of the POI as listed on Tripadvisor", + "type": "string" + }, + "web_url": { + "description": "Link to the POI detail page on Tripadvisor. Link is localized to the correct domain if a language other than English is requested.", + "type": "string" + }, + "address_obj": { + "description": "Object containing address data for this location", + "type": "object", + "properties": { + "street1": { + "type": "string", + "description": "The street name" + }, + "street2": { + "type": "string", + "description": "The street name continuation" + }, + "city": { + "type": "string", + "description": "The city name" + }, + "state": { + "type": "string", + "description": "The state" + }, + "country": { + "type": "string", + "description": "The country" + }, + "postalcode": { + "type": "string", + "description": "The address postal code" + }, + "address_string": { + "type": "string", + "description": "The address in one single sentence" + } + } + }, + "ancestors": { + "description": "Ancestors describe where the POI or destination lives within the Tripadvisor destination or geo hierarchy.From this, you can derive the city where a POI is located, as well as state/province/region and country.", + "type": "array", + "items": { + "type": "object", + "properties": { + "abbrv": { + "description": "The ancestor location abbreviation", + "type": "string" + }, + "level": { + "description": "The ancestor location level in relation to the location", + "type": "string" + }, + "name": { + "description": "The ancestor location name", + "type": "string" + }, + "location_id": { + "description": "The ancestor location location identifier", + "type": "integer", + "format": "int32" + } + } + } + }, + "latitude": { + "description": "The latitude of this location in degrees, if available", + "type": "number" + }, + "longitude": { + "description": "The longitude of this location in degrees, if available", + "type": "number" + }, + "timezone": { + "description": "The timezone of the location", + "type": "string" + }, + "email": { + "description": "The email of the location, if available", + "type": "string" + }, + "phone": { + "description": "The phone number of the location, if available", + "type": "string" + }, + "website": { + "description": "The website of the location, if available", + "type": "string" + }, + "write_review": { + "description": "Link to the review form for this specific POI on Tripadvisor. Link is localized to the correct domain if a language other than English is requested.", + "type": "string" + }, + "ranking_data": { + "description": "Describes a POI's Popularity Index ranking on Tripadvisor, which compares places of interest (accomodations, restaurants, and attractions) within the same destination based on their popularity.This is measured by the quality, quantity, and recency of their review content on Tripadvisor.", + "type": "object", + "properties": { + "geo_location_id": { + "description": "The destination id", + "type": "integer", + "format": "int32" + }, + "ranking_string": { + "description": "The description of the ranking", + "type": "string" + }, + "geo_location_name": { + "description": "The destination name", + "type": "string" + }, + "ranking_out_of": { + "description": "The total number of locations on the ranking score", + "type": "integer", + "format": "int32" + }, + "ranking": { + "description": "The location ranking", + "type": "integer", + "format": "int32" + } + } + }, + "rating": { + "description": "Overall rating for this POI. Not applicable to geographic locations. Rating levels are defined as follows:5: Excellent4: Very good3: Average2: Poor1: Terrible", + "type": "number" + }, + "rating_image_url": { + "description": "URL to the bubble rating image for this location. Overall Bubble Ratings must be displayed using the Tripadvisor bubble rating image with the owl icon.", + "type": "string" + }, + "num_reviews": { + "description": "Count of total reviews published for this location", + "type": "string" + }, + "review_rating_count": { + "description": "Count of reviews for this location at each traveler rating level (1,2,3,4,5)", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "subratings": { + "type": "object", + "additionalProperties": { + "allOf": [ + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "localized_name": { + "type": "string" + } + } + }, + { + "type": "object", + "properties": { + "rating_image_url": { + "type": "string" + }, + "value": { + "type": "number", + "format": "float" + } + } + } + ] + } + }, + "photo_count": { + "description": "The count of photos for this POI published on Tripadvisor", + "type": "integer", + "format": "int32" + }, + "see_all_photos": { + "description": "Link to open all photos posted for this POI in a photo viewer on Tripadvisor. Link is localized to the correct domain if a language other than English is requested.", + "type": "string" + }, + "price_level": { + "description": "The relative price level for the POI. Not available for all POIs. This string is localized to other currency symbols (e.g. ££££ or €€€€) if a language other than English (en_US) is requested or if a specific currency is selected.", + "type": "string" + }, + "hours": { + "description": "Provides localized opening hours for Restaurants and Attractions, using ISO 8601 format", + "type": "object", + "properties": { + "periods": { + "type": "array", + "items": { + "type": "object", + "properties": { + "open": { + "description": "The day and times intervals in which the location is open", + "type": "object", + "properties": { + "day": { + "type": "integer", + "format": "int32" + }, + "time": { + "type": "string" + } + } + }, + "close": { + "description": "The day and times intervals in which the location is closed", + "type": "object", + "properties": { + "day": { + "type": "integer", + "format": "int32" + }, + "time": { + "type": "string" + } + } + } + } + } + }, + "weekday_text": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "amenities": { + "description": "The amenities provided by this hotel", + "type": "array", + "items": { + "type": "string" + } + }, + "features": { + "description": "The features provided by this restaurant", + "type": "array", + "items": { + "type": "string" + } + }, + "cuisine": { + "description": "The cuisines of this restaurant", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "localized_name": { + "type": "string" + } + } + } + }, + "parent_brand": { + "description": "The parent brand of this hotel", + "type": "string" + }, + "brand": { + "description": "The brand of this hotel", + "type": "string" + }, + "category": { + "description": "Each POI on Tripadvisor is classified under a \"category\" and \"subcategory\", which is included in the API response.", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "localized_name": { + "type": "string" + } + } + }, + "subcategory": { + "description": "Listings that are accommodations/hotels or restaurants are assigned a single subcategory.Deprecated as of February 2017 for Attractions. Refer to the \"groups\" object for the most up to date classifications.", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "localized_name": { + "type": "string" + } + } + } + }, + "groups": { + "description": "Hierarchical display of Attraction Groups and Categories. These fields are only applicable for location type \"attraction\".", + "type": "array", + "items": { + "allOf": [ + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "localized_name": { + "type": "string" + } + } + }, + { + "type": "object", + "properties": { + "categories": { + "description": "Attraction Categories", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "localized_name": { + "type": "string" + } + } + } + } + } + } + ] + } + }, + "styles": { + "description": "The styles of the hotel", + "type": "array", + "items": { + "type": "string" + } + }, + "neighborhood_info": { + "description": "List of neighborhoods close to the location", + "type": "array", + "items": { + "type": "object", + "properties": { + "location_id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + } + }, + "trip_types": { + "description": "Each review submitted on Tripadvisor is tagged with a trip type, as designated by the reviewer.For each POI location, a breakdown of the total review count by trip type is included in the \"trip_types\" object.", + "type": "array", + "items": { + "allOf": [ + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "localized_name": { + "type": "string" + } + } + }, + { + "type": "object", + "properties": { + "value": { + "type": "string" + } + } + } + ] + } + }, + "awards": { + "description": "Returns a list of all of the awards for this location, which could include Certificate of Excellence, Travelers' Choice, and Green Leader.For each award, a small and large image will be returned as well.", + "type": "array", + "items": { + "type": "object", + "properties": { + "award_type": { + "description": "Award type name", + "type": "string" + }, + "year": { + "description": "The year in which the award was awarded", + "type": "integer", + "format": "int32" + }, + "images": { + "description": "The award image in its different sizes", + "type": "object", + "properties": { + "tiny": { + "type": "string" + }, + "small": { + "type": "string" + }, + "large": { + "type": "string" + } + } + }, + "categories": { + "description": "The categories in which the award was awarded", + "type": "array", + "items": { + "type": "string" + } + }, + "display_name": { + "type": "string" + } + } + } + }, + "error": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "type": { + "type": "string" + }, + "code": { + "type": "integer", + "format": "int32" + } + } + } + } + } + } + } + } + }, + "security": [ + { + "cosoLocationApiLambdaAuthorizer": [] + } + ] + } + }, + "/v1/location/{locationId}/photos": { + "get": { + "summary": "Location Photos", + "description": "The Location Photos request returns up to 5 high-quality photos for a specific location. Please note that the limits are different for the beta subscribers. You need to upgrade to get the higher limits mentioned here.The photos are ordered by recency.Sizes (height x width) for each photo type are as follows:Thumbnail: Fixed 50x50px, cropped, resized, and optimized by TripadvisorSmall: Fixed 150x150px, cropped, resized, and optimized by TripadvisorMedium: Max dimension 250px (can be height or width, depending on photo orientation), the other dimension is resized to maintain the aspect ratioLarge: Max dimension 550px (same rules as Medium, resized to maintain aspect ratio)Original: This is the photo in its original resolution and aspect ratio as provided by the user who submitted it.", + "operationId": "getLocationPhotos", + "tags": [ + "Location Photos" + ], + "parameters": [ + { + "name": "locationId", + "in": "path", + "description": "A unique identifier for a location on Tripadvisor. The location ID can be obtained using the Location Search.", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "language", + "in": "query", + "description": "The language in which to return results (e.g. \"en\" for English or \"es\" for Spanish) from the list of our Supported Languages.", + "required": false, + "schema": { + "default": "en", + "type": "string", + "enum": [ + "ar", + "zh", + "zh_TW", + "da", + "nl", + "en_AU", + "en_CA", + "en_HK", + "en_IN", + "en_IE", + "en_MY", + "en_NZ", + "en_PH", + "en_SG", + "en_ZA", + "en_UK", + "en", + "fr", + "fr_BE", + "fr_CA", + "fr_CH", + "de_AT", + "de", + "el", + "iw", + "in", + "it", + "it_CH", + "ja", + "ko", + "no", + "pt_PT", + "pt", + "ru", + "es_AR", + "es_CO", + "es_MX", + "es_PE", + "es", + "es_VE", + "es_CL", + "sv", + "th", + "tr", + "vi" + ] + } + }, + { + "name": "limit", + "in": "query", + "description": "The number of results to return", + "required": false, + "schema": { + "type": "number", + "format": "int32" + } + }, + { + "name": "offset", + "in": "query", + "description": "The index of the first result", + "required": false, + "schema": { + "type": "number", + "format": "int32" + } + }, + { + "name": "source", + "in": "query", + "description": "A comma-separated list of allowed photo sources. Allowed values are 'Expert', 'Management', 'Traveler'. If not specified, allow photos from all sources.", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Details for the location", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "description": "A unique ID for this photo", + "type": "integer", + "format": "int32" + }, + "is_blessed": { + "description": "Boolean whether or not this photo is blessed, i.e. reviewed at Tripadvisor as being a photo of exceptional quality", + "type": "boolean" + }, + "album": { + "description": "Name of the album the photo is featured in", + "type": "string" + }, + "caption": { + "description": "Caption of the photo", + "type": "string" + }, + "published_date": { + "description": "Date when this photo was published to Tripadvisor", + "type": "string" + }, + "images": { + "description": "Links to the photo in various sizes, along with the dimensions in pixels of each size", + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "width": { + "type": "number" + }, + "url": { + "type": "string" + }, + "height": { + "type": "number" + } + } + } + }, + "source": { + "description": "Origin of the photo (Traveler, Expert, Management)", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "localized_name": { + "type": "string" + } + } + }, + "user": { + "type": "object", + "properties": { + "username": { + "description": "The username that appears on the Tripadvisor website for the user", + "type": "string" + }, + "user_location": { + "type": "object", + "properties": { + "name": { + "description": "The name of the user's location", + "type": "string" + }, + "id": { + "description": "The location ID of the user's location", + "type": "string" + } + } + }, + "review_count": { + "description": "The Review Count that appears on the Tripadvisor website for the user", + "type": "integer", + "format": "int32" + }, + "reviewer_badge": { + "description": "The Reviewer Badge that appears on the Tripadvisor website for the user", + "type": "string" + }, + "avatar": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + } + }, + "paging": { + "type": "object", + "properties": { + "next": { + "type": "string" + }, + "previous": { + "type": "string" + }, + "results": { + "type": "integer", + "format": "int32" + }, + "total_results": { + "type": "integer", + "format": "int32" + }, + "skipped": { + "type": "integer", + "format": "int32" + } + } + }, + "error": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "type": { + "type": "string" + }, + "code": { + "type": "integer", + "format": "int32" + } + } + } + } + } + } + } + } + }, + "security": [ + { + "cosoLocationApiLambdaAuthorizer": [] + } + ] + } + }, + "/v1/location/{locationId}/reviews": { + "get": { + "summary": "Location Reviews", + "description": "The Location Reviews request returns up to 5 of the most recent reviews for a specific location. Please note that the limits are different for the beta subscribers. You need to upgrade to get the higher limits mentioned here.", + "operationId": "getLocationReviews", + "tags": [ + "Location Reviews" + ], + "parameters": [ + { + "name": "locationId", + "in": "path", + "description": "A unique identifier for a location on Tripadvisor. The location ID can be obtained using the Location Search.", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "language", + "in": "query", + "description": "The language in which to return results (e.g. \"en\" for English or \"es\" for Spanish) from the list of our Supported Languages.", + "required": false, + "schema": { + "default": "en", + "type": "string", + "enum": [ + "ar", + "zh", + "zh_TW", + "da", + "nl", + "en_AU", + "en_CA", + "en_HK", + "en_IN", + "en_IE", + "en_MY", + "en_NZ", + "en_PH", + "en_SG", + "en_ZA", + "en_UK", + "en", + "fr", + "fr_BE", + "fr_CA", + "fr_CH", + "de_AT", + "de", + "el", + "iw", + "in", + "it", + "it_CH", + "ja", + "ko", + "no", + "pt_PT", + "pt", + "ru", + "es_AR", + "es_CO", + "es_MX", + "es_PE", + "es", + "es_VE", + "es_CL", + "sv", + "th", + "tr", + "vi" + ] + } + }, + { + "name": "limit", + "in": "query", + "description": "The number of results to return", + "required": false, + "schema": { + "type": "number", + "format": "int32" + } + }, + { + "name": "offset", + "in": "query", + "description": "The index of the first result", + "required": false, + "schema": { + "type": "number", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "Details for the location", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "description": "The Tripadvisor ID for the review.", + "type": "integer", + "format": "int32" + }, + "lang": { + "description": "The language of the review.", + "type": "string" + }, + "location_id": { + "description": "Unique Tripadvisor location ID of the destination or POI.", + "type": "integer", + "format": "int32" + }, + "published_date": { + "description": "The date the review was published to Tripadvisor.", + "type": "string" + }, + "rating": { + "description": "Overall rating for this POI. Not applicable to geographic locations. Rating levels are defined as follows:5: Excellent4: Very good3: Average2: Poor1: Terrible", + "type": "integer", + "format": "int32" + }, + "helpful_votes": { + "description": "The number of helpful votes", + "type": "integer", + "format": "int32" + }, + "rating_image_url": { + "description": "The URL to the bubble rating image for this location.", + "type": "string" + }, + "url": { + "description": "The URL to the review", + "type": "string" + }, + "trip_type": { + "description": "The Trip type of the review (Business, Couples, Family, Friends, Solo).", + "type": "string" + }, + "travel_date": { + "description": "The travel date of the review", + "type": "string" + }, + "text": { + "description": "The full text of the review.", + "type": "string" + }, + "title": { + "description": "The title of this review.", + "type": "string" + }, + "owner_response": { + "description": "The Management Response to this review, if one exists.", + "type": "object", + "properties": { + "id": { + "description": "The Tripadvisor ID for the owner respose.", + "type": "integer", + "format": "int32" + }, + "lang": { + "description": "The language of the review.", + "type": "string" + }, + "text": { + "description": "The full text of the review.", + "type": "string" + }, + "title": { + "description": "The title of this review.", + "type": "string" + }, + "author": { + "description": "The owners name.", + "type": "string" + }, + "published_date": { + "description": "The date the review response was published to Tripadvisor.", + "type": "string" + } + } + }, + "is_machine_translated": { + "description": "True or false depending on whether this is a machine-translated review. (Outputs only if partner configured for inclusion of machine-translated reviews)", + "type": "boolean" + }, + "user": { + "type": "object", + "properties": { + "username": { + "description": "The username that appears on the Tripadvisor website for the user", + "type": "string" + }, + "user_location": { + "type": "object", + "properties": { + "name": { + "description": "The name of the user's location", + "type": "string" + }, + "id": { + "description": "The location ID of the user's location", + "type": "string" + } + } + }, + "review_count": { + "description": "The Review Count that appears on the Tripadvisor website for the user", + "type": "integer", + "format": "int32" + }, + "reviewer_badge": { + "description": "The Reviewer Badge that appears on the Tripadvisor website for the user", + "type": "string" + }, + "avatar": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "subratings": { + "type": "object", + "additionalProperties": { + "allOf": [ + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "localized_name": { + "type": "string" + } + } + }, + { + "type": "object", + "properties": { + "rating_image_url": { + "type": "string" + }, + "value": { + "type": "number", + "format": "float" + } + } + } + ] + } + } + } + } + }, + "paging": { + "type": "object", + "properties": { + "next": { + "type": "string" + }, + "previous": { + "type": "string" + }, + "results": { + "type": "integer", + "format": "int32" + }, + "total_results": { + "type": "integer", + "format": "int32" + }, + "skipped": { + "type": "integer", + "format": "int32" + } + } + }, + "error": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "type": { + "type": "string" + }, + "code": { + "type": "integer", + "format": "int32" + } + } + } + } + } + } + } + } + }, + "security": [ + { + "cosoLocationApiLambdaAuthorizer": [] + } + ] + } + }, + "/v1/location/search": { + "get": { + "summary": "Find Search", + "description": "The Location Search request returns up to 10 locations found by the given search query.You can use category (\"hotels\", \"attractions\", \"restaurants\", \"geos\"), phone number, address, and latitude/longtitude to search with more accuracy.", + "operationId": "searchForLocations", + "tags": [ + "Location Search" + ], + "parameters": [ + { + "name": "searchQuery", + "in": "query", + "description": "Text to use for searching based on the name of the location", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "category", + "in": "query", + "description": "Filters result set based on property type. Valid options are \"hotels\", \"attractions\", \"restaurants\", and \"geos\"", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "phone", + "in": "query", + "description": "Phone number to filter the search results by (this can be in any format with spaces and dashes but without the \"+\" sign at the beginning)", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "address", + "in": "query", + "description": "Address to filter the search results by", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "latLong", + "in": "query", + "description": "Latitude/Longitude pair to scope down the search around a specifc point - eg. \"42.3455,-71.10767\"", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "radius", + "in": "query", + "description": "Length of the radius from the provided latitude/longitude pair to filter results.", + "required": false, + "schema": { + "type": "number", + "minimum": 0, + "exclusiveMinimum": true + } + }, + { + "name": "radiusUnit", + "in": "query", + "description": "Unit for length of the radius. Valid options are \"km\", \"mi\", \"m\" (km=kilometers, mi=miles, m=meters)", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "language", + "in": "query", + "description": "The language in which to return results (e.g. \"en\" for English or \"es\" for Spanish) from the list of our Supported Languages.", + "required": false, + "schema": { + "default": "en", + "type": "string", + "enum": [ + "ar", + "zh", + "zh_TW", + "da", + "nl", + "en_AU", + "en_CA", + "en_HK", + "en_IN", + "en_IE", + "en_MY", + "en_NZ", + "en_PH", + "en_SG", + "en_ZA", + "en_UK", + "en", + "fr", + "fr_BE", + "fr_CA", + "fr_CH", + "de_AT", + "de", + "el", + "iw", + "in", + "it", + "it_CH", + "ja", + "ko", + "no", + "pt_PT", + "pt", + "ru", + "es_AR", + "es_CO", + "es_MX", + "es_PE", + "es", + "es_VE", + "es_CL", + "sv", + "th", + "tr", + "vi" + ] + } + } + ], + "responses": { + "200": { + "description": "Location Search Results", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "location_id": { + "description": "A unique identifier for a location on Tripadvisor. This is to be used in the other endpoints that require a location ID.", + "type": "integer", + "format": "int32" + }, + "name": { + "description": "Name of the location", + "type": "string" + }, + "distance": { + "description": "Distance, in miles, this location is from the passed in LatLong parameters", + "type": "string" + }, + "bearing": { + "description": "Direction this location is from the passed in LatLong parameters", + "type": "string" + }, + "address_obj": { + "description": "Object consisting of various address data", + "type": "object", + "properties": { + "street1": { + "type": "string", + "description": "The street name" + }, + "street2": { + "type": "string", + "description": "The street name continuation" + }, + "city": { + "type": "string", + "description": "The city name" + }, + "state": { + "type": "string", + "description": "The state" + }, + "country": { + "type": "string", + "description": "The country" + }, + "postalcode": { + "type": "string", + "description": "The address postal code" + }, + "address_string": { + "type": "string", + "description": "The address in one single sentence" + } + } + } + } + } + }, + "error": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "type": { + "type": "string" + }, + "code": { + "type": "integer", + "format": "int32" + } + } + } + } + } + } + } + } + }, + "security": [ + { + "cosoLocationApiLambdaAuthorizer": [] + } + ] + } + }, + "/v1/location/nearby_search": { + "get": { + "summary": "Nearby Search", + "description": "The Nearby Location Search request returns up to 10 locations found near the given latitude/longtitude.You can use category (\"hotels\", \"attractions\", \"restaurants\", \"geos\"), phone number, address to search with more accuracy.", + "operationId": "searchForNearbyLocations", + "tags": [ + "Nearby Location Search" + ], + "parameters": [ + { + "name": "latLong", + "in": "query", + "description": "Latitude/Longitude pair to scope down the search around a specifc point - eg. \"42.3455,-71.10767\"", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "category", + "in": "query", + "description": "Filters result set based on property type. Valid options are \"hotels\", \"attractions\", \"restaurants\", and \"geos\"", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "phone", + "in": "query", + "description": "Phone number to filter the search results by (this can be in any format with spaces and dashes but without the \"+\" sign at the beginning)", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "address", + "in": "query", + "description": "Address to filter the search results by", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "radius", + "in": "query", + "description": "Length of the radius from the provided latitude/longitude pair to filter results.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "radiusUnit", + "in": "query", + "description": "Unit for length of the radius. Valid options are \"km\", \"mi\", \"m\" (km=kilometers, mi=miles, m=meters)", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "language", + "in": "query", + "description": "The language in which to return results (e.g. \"en\" for English or \"es\" for Spanish) from the list of our Supported Languages.", + "required": false, + "schema": { + "default": "en", + "type": "string", + "enum": [ + "ar", + "zh", + "zh_TW", + "da", + "nl", + "en_AU", + "en_CA", + "en_HK", + "en_IN", + "en_IE", + "en_MY", + "en_NZ", + "en_PH", + "en_SG", + "en_ZA", + "en_UK", + "en", + "fr", + "fr_BE", + "fr_CA", + "fr_CH", + "de_AT", + "de", + "el", + "iw", + "in", + "it", + "it_CH", + "ja", + "ko", + "no", + "pt_PT", + "pt", + "ru", + "es_AR", + "es_CO", + "es_MX", + "es_PE", + "es", + "es_VE", + "es_CL", + "sv", + "th", + "tr", + "vi" + ] + } + } + ], + "responses": { + "200": { + "description": "Nearby Location Search Results", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "location_id": { + "description": "A unique identifier for a location on Tripadvisor. This is to be used in the other endpoints that require a location ID.", + "type": "integer", + "format": "int32" + }, + "name": { + "description": "Name of the location", + "type": "string" + }, + "distance": { + "description": "Distance, in miles, this location is from the passed in LatLong parameters", + "type": "string" + }, + "bearing": { + "description": "Direction this location is from the passed in LatLong parameters", + "type": "string" + }, + "address_obj": { + "description": "Object consisting of various address data", + "type": "object", + "properties": { + "street1": { + "type": "string", + "description": "The street name" + }, + "street2": { + "type": "string", + "description": "The street name continuation" + }, + "city": { + "type": "string", + "description": "The city name" + }, + "state": { + "type": "string", + "description": "The state" + }, + "country": { + "type": "string", + "description": "The country" + }, + "postalcode": { + "type": "string", + "description": "The address postal code" + }, + "address_string": { + "type": "string", + "description": "The address in one single sentence" + } + } + } + } + } + }, + "error": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "type": { + "type": "string" + }, + "code": { + "type": "integer", + "format": "int32" + } + } + } + } + } + } + } + } + }, + "security": [ + { + "cosoLocationApiLambdaAuthorizer": [] + } + ] + } + } + }, + "components": { + "securitySchemes": { + "cosoLocationApiLambdaAuthorizer": { + "type": "apiKey", + "name": "key", + "in": "query" + } + } + } + } diff --git a/use-cases/agents/3p-tool/Tripadvisor/tripadvisor.py b/use-cases/agents/3p-tool/Tripadvisor/tripadvisor.py new file mode 100644 index 000000000..f41483c99 --- /dev/null +++ b/use-cases/agents/3p-tool/Tripadvisor/tripadvisor.py @@ -0,0 +1,95 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates how to use Tripadvisor from + the Azure AI Agent service using a synchronous client. + +USAGE: + python tripadvisor.py + + Before running the sample: + + pip install azure-ai-projects azure-ai-agents azure-identity + + Set these environment variables with your own values: + 1) PROJECT_ENDPOINT - the Azure AI Agent endpoint. + 2) MODEL_DEPLOYMENT_NAME - The deployment name of the AI model, as found under the "Name" column in + the "Models + endpoints" tab in your Azure AI Foundry project. +""" + +# +import os +import jsonref +from azure.identity import DefaultAzureCredential +from pathlib import Path +from azure.ai.projects import AIProjectClient +from azure.ai.agents.models import MessageRole, OpenApiTool, OpenApiConnectionAuthDetails, OpenApiConnectionSecurityScheme + + +# Format of the project_endpoint is https://.services.ai.azure.com/api/projects/ +project_endpoint = "YOUR_ENDPOINT" +# Change if you deployed a different model +model_deployment_name = "gpt-4o" + +# 1RP update: create a project client in the following way +project_client = AIProjectClient( + endpoint=project_endpoint, + credential=DefaultAzureCredential(), +) + +with project_client: + agents_client = project_client.agents.get_client() + + # Upload OpenAPI spec and wait for it to be processed + # [START create_agent_with_openapi] + # Update the file path to the correct location + with open('./tripadvisor.json', 'r', encoding='utf-8') as f: + openapi_spec = jsonref.loads(f.read()) # Update this to your file path + + # Create Auth object for the OpenApiTool (note that connection or managed identity auth setup requires additional setup in Azure) + # Your connection id should be in this format if you created under project scope: /subscriptions/SUBSCRIPTION_ID/resourceGroups/RESOURCE_GROUP_NAME/providers/Microsoft.CognitiveServices/accounts/AI_SERVICE_NAME/projects/PROJECT_NAME/connections/CONNECTION_NAME + auth = OpenApiConnectionAuthDetails(security_scheme=OpenApiConnectionSecurityScheme(connection_id="YOUR_CONNECTION_ID")) + + # Initialize agent OpenApi tool using the read in OpenAPI spec + openapi = OpenApiTool(name="tripadvisor", spec=openapi_spec, description="get reviews for restaurants and hotels given locations", auth=auth) + + # Create agent th openapi spec tool + agent = agents_client.create_agent( + model=model_deployment_name, + name="my-agent", + instructions="You are helpful agent", + tools=openapi.definitions, + ) + # [END create_agent_with_openapi] + print(f"Created agent, agent ID: {agent.id}") + + thread = agents_client.create_thread() + print(f"Created thread, thread ID: {thread.id}") + + # Create a message + message = agents_client.create_message( + thread_id=thread.id, + role="user", + content="top 5 hotels in paris and their review links", + ) + print(f"Created message, message ID: {message.id}") + + run = agents_client.create_and_process_run(thread_id=thread.id, agent_id=agent.id) + print(f"Run finished with status: {run.status}") + + if run.status == "failed": + # Check if you got "Rate limit is exceeded.", then you want to get more quota + print(f"Run failed: {run.last_error}") + + # Delete the agent when done + agents_client.delete_agent(agent.id) + print("Deleted agent") + + # Fetch and log all messages + messages = agents_client.list_messages(thread_id=thread.id) + print(f"Messages: {messages}") diff --git a/use-cases/agents/3p-tool/Tripadvisor/tripadvisor_new_sdk.py b/use-cases/agents/3p-tool/Tripadvisor/tripadvisor_new_sdk.py new file mode 100644 index 000000000..8e93e7e32 --- /dev/null +++ b/use-cases/agents/3p-tool/Tripadvisor/tripadvisor_new_sdk.py @@ -0,0 +1,134 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates how to use agent operations with the + OpenAPI tool from the Azure Agents service using a synchronous client. + To learn more about OpenAPI specs, visit https://learn.microsoft.com/openapi + +USAGE: + python openapi.py + + Before running the sample: + + pip install azure-ai-agents azure-identity jsonref + + Set these environment variables with your own values: + 1) PROJECT_ENDPOINT - the Azure AI Agents endpoint. + 2) MODEL - The deployment name of the AI model, as found under the "Name" column in + the "Models + endpoints" tab in your Azure AI Foundry project. +""" +# +# Import necessary libraries +import os +import jsonref +from azure.ai.projects import AIProjectClient +from azure.identity import DefaultAzureCredential +from azure.ai.agents.models import OpenApiTool, OpenApiConnectionAuthDetails, OpenApiConnectionSecurityScheme + +# endpoint should be in the format "https://.services.ai.azure.com/api/projects/" +endpoint = os.environ["PROJECT_ENDPOINT"] +model = os.environ["MODEL"] +# connection id should be in the format "/subscriptions//resourceGroups//providers/Microsoft.CognitiveServices/accounts//projects//connections/" +conn_id = os.environ["CONNECTION_ID"] + +# Initialize the project client using the endpoint and default credentials +with AIProjectClient( + endpoint=endpoint, + credential=DefaultAzureCredential(exclude_interactive_browser_credential=False), +) as project_client: + # + + # Load the OpenAPI specification for the service from a local JSON file using jsonref to handle references + with open("./tripadvisor.json", "r") as f: + openapi_spec = jsonref.loads(f.read()) + + # Create Auth object for the OpenApiTool (note that connection or managed identity auth setup requires additional setup in Azure) + auth = OpenApiConnectionAuthDetails(security_scheme=OpenApiConnectionSecurityScheme(connection_id=conn_id)) + + # Initialize the main OpenAPI tool definition for weather + openapi_tool = OpenApiTool( + name="tripadvisor", + spec=openapi_spec, + description="retrieve travel review, guidance and recommendation", + auth=auth + ) + + # + # --- Agent Creation --- + # Create an agent configured with the combined OpenAPI tool definitions + agent = project_client.agents.create_agent( + model=model, # Specify the model deployment + name="my-agent", # Give the agent a name + instructions="You are a helpful travel planning agent. Your job is to retrieve relevant travel reviews about hotels, restaurants from Tripadvisor and generate travel recommendations", # Define agent's role + tools=openapi_tool.definitions, # Provide the list of tool definitions + ) + print(f"Created agent, ID: {agent.id}") + # + + # + # --- Thread Management --- + # Create a new conversation thread for the interaction + thread = project_client.agents.threads.create() + print(f"Created thread, ID: {thread.id}") + + # Create the initial user message in the thread + message = project_client.agents.messages.create( + thread_id=thread.id, + role="user", + # give an example of a user message that the agent can respond to + content="top 5 hotels in Paris and their review links", + ) + print(f"Created message, ID: {message.id}") + # + + # + # --- Message Processing (Run Creation and Auto-processing) --- + # Create and automatically process the run, handling tool calls internally + # Note: This differs from the function_tool example where tool calls are handled manually + run = project_client.agents.runs.create_and_process(thread_id=thread.id, agent_id=agent.id) + print(f"Run finished with status: {run.status}") + # + + # # Note: This section now processes completed steps, as create_and_process_run handles execution + # --- Post-Run Step Analysis --- + if run.status == "failed": + print(f"Run failed: {run.last_error}") + + # Retrieve the steps taken during the run for analysis + run_steps = project_client.agents.run_steps.list(thread_id=thread.id, run_id=run.id) + + # Loop through each step to display information + for step in run_steps.data: + print(f"Step {step['id']} status: {step['status']}") + + # Check if there are tool calls recorded in the step details + step_details = step.get("step_details", {}) + tool_calls = step_details.get("tool_calls", []) + + if tool_calls: + print(" Tool calls:") + for call in tool_calls: + print(f" Tool Call ID: {call.get('id')}") + print(f" Type: {call.get('type')}") + + function_details = call.get("function", {}) + if function_details: + print(f" Function name: {function_details.get('name')}") + print() # Add an extra newline between steps for readability + # + + # + # --- Cleanup --- + # Delete the agent resource to clean up + project_client.agents.delete_agent(agent.id) + print("Deleted agent") + + # Fetch and log all messages exchanged during the conversation thread + messages = project_client.agents.messages.list(thread_id=thread.id) + print(f"Messages: {messages}") + # \ No newline at end of file diff --git a/use-cases/agents/3p-tools/Tripadvisor.py b/use-cases/agents/agent-code-samples/3p-agent-code-samples/README.md similarity index 100% rename from use-cases/agents/3p-tools/Tripadvisor.py rename to use-cases/agents/agent-code-samples/3p-agent-code-samples/README.md diff --git a/use-cases/agents/agent-code-samples/README.md b/use-cases/agents/agent-code-samples/README.md new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/use-cases/agents/agent-code-samples/README.md @@ -0,0 +1 @@ + diff --git a/use-cases/agents/agent-code-samples/msft-agent-code-samples/README.md b/use-cases/agents/agent-code-samples/msft-agent-code-samples/README.md new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/use-cases/agents/agent-code-samples/msft-agent-code-samples/README.md @@ -0,0 +1 @@ +