Adding new sample da-ristorante-api-csharp#140
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new sample (da-ristorante-api-csharp) that demonstrates a declarative agent for Microsoft 365 Copilot backed by an anonymous API implemented as a C# Azure Function (.NET 10 isolated worker), including the agent packaging, infra provisioning, and sample assets/metadata.
Changes:
- Introduces a new C# Azure Functions API implementing menu browsing and order placement endpoints.
- Adds an M365 Agent project with manifest, declarative agent config, plugin definition, and OpenAPI specification.
- Adds provisioning/deployment configuration (m365agents + Bicep) and sample assets/metadata for documentation/cataloging.
Reviewed changes
Copilot reviewed 26 out of 46 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| samples/da-ristorante-api-csharp/README.md | Sample documentation and getting-started steps. |
| samples/da-ristorante-api-csharp/.gitignore | Sample-scoped ignore rules for TeamsFx/env and build outputs. |
| samples/da-ristorante-api-csharp/DaRistoranteApi.slnx | Solution container wiring up API + agent projects. |
| samples/da-ristorante-api-csharp/assets/sample.json | Sample catalog metadata (title/description/thumbnails/authors). |
| samples/da-ristorante-api-csharp/M365Agent/M365Agent.atkproj | Declarative agent project definition for Visual Studio tooling. |
| samples/da-ristorante-api-csharp/M365Agent/launchSettings.json | Local launch profiles to open Copilot in browser. |
| samples/da-ristorante-api-csharp/M365Agent/m365agents.yml | Provision/deploy pipeline for Azure-hosted API + agent package. |
| samples/da-ristorante-api-csharp/M365Agent/m365agents.local.yml | Local provision pipeline (dev tunnel + local settings generation). |
| samples/da-ristorante-api-csharp/M365Agent/env/.env.dev | Dev environment variables template for provisioned Azure resources. |
| samples/da-ristorante-api-csharp/M365Agent/env/.env.local | Local environment variables template for dev-tunnel based testing. |
| samples/da-ristorante-api-csharp/M365Agent/infra/azure.bicep | Azure infra definition for the Functions host used by the plugin. |
| samples/da-ristorante-api-csharp/M365Agent/infra/azure.parameters.json | Parameter defaults for Azure deployment (name/SKU). |
| samples/da-ristorante-api-csharp/M365Agent/appPackage/manifest.json | Teams/M365 app manifest for the declarative agent. |
| samples/da-ristorante-api-csharp/M365Agent/appPackage/declarativeAgent.json | Declarative agent definition (instructions/starters/actions). |
| samples/da-ristorante-api-csharp/M365Agent/appPackage/instruction.txt | Agent instruction prompt describing how to use the API. |
| samples/da-ristorante-api-csharp/M365Agent/appPackage/ai-plugin.json | Plugin contract, function declarations, and response semantics. |
| samples/da-ristorante-api-csharp/M365Agent/appPackage/apiSpecificationFile/ristorante.yml | OpenAPI spec describing the API exposed to the plugin runtime. |
| samples/da-ristorante-api-csharp/DaRistoranteApi/Program.cs | Azure Functions isolated worker host bootstrap. |
| samples/da-ristorante-api-csharp/DaRistoranteApi/RistoranteApi.cs | HTTP-trigger functions implementing /dishes and /orders. |
| samples/da-ristorante-api-csharp/DaRistoranteApi/MenuData.cs | Static loader for menu data from data.json. |
| samples/da-ristorante-api-csharp/DaRistoranteApi/Models/DishModels.cs | JSON-serializable models for dishes and orders. |
| samples/da-ristorante-api-csharp/DaRistoranteApi/data.json | Menu dataset backing the sample API. |
| samples/da-ristorante-api-csharp/DaRistoranteApi/DaRistoranteApi.csproj | Functions project configuration and package references. |
| samples/da-ristorante-api-csharp/DaRistoranteApi/host.json | Functions host runtime configuration. |
| samples/da-ristorante-api-csharp/DaRistoranteApi/local.settings.json | Local Functions settings template for isolated worker runtime. |
| samples/da-ristorante-api-csharp/DaRistoranteApi/Properties/launchSettings.json | Local debug profile for running Functions host on a fixed port. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| type: array | ||
| items: | ||
| $ref: '#/components/schemas/Dish' |
There was a problem hiding this comment.
Updated as suggested.
| - Politely offer the suggestion: *"Would you like to add a beverage to your order? I recommend [beverage] for [course]."* | ||
|
|
||
| ### Placing the Order: | ||
| - Once the user has finalized their order, use the `POST /order` API to submit the order. |
| filtered = filtered.Where(d => d.Course == course); | ||
| } | ||
|
|
||
| var type = req.Query["type"]; | ||
| if (!string.IsNullOrEmpty(type)) | ||
| { | ||
| filtered = filtered.Where(d => d.Type == type); |
There was a problem hiding this comment.
Updated to compare using OrdinalIgnoreCase
| var allergens = allergensParam.Split(',', StringSplitOptions.RemoveEmptyEntries); | ||
| filtered = filtered.Where(d => allergens.All(a => !d.Allergens.Contains(a))); |
There was a problem hiding this comment.
Updated- allergen values are now trimmed and compared case-insensitively
| foreach (var orderedDish in order.Dishes) | ||
| { | ||
| var match = allDishes.FirstOrDefault(d => | ||
| d.Name.Contains(orderedDish.Name, StringComparison.OrdinalIgnoreCase)); | ||
|
|
||
| if (match == null) | ||
| { | ||
| _logger.LogError("Invalid dish: {DishName}", orderedDish.Name); | ||
| var badResponse = req.CreateResponse(HttpStatusCode.BadRequest); | ||
| await badResponse.WriteAsJsonAsync(new { message = "One or more invalid dishes" }); | ||
| return badResponse; | ||
| } | ||
|
|
||
| totalPrice += match.Price * orderedDish.Quantity; | ||
| } |
There was a problem hiding this comment.
Added the validation logic for null/empty/whitespace.
| "description_for_human": "See the today's menu and place orders", | ||
| "description_for_model": "Plugin for getting the today's menu, optionally filtered by course and allergens, and placing orders", |
| }, | ||
| "name": { | ||
| "short": "Il Ristorante", | ||
| "full": "See the today's menu and place orders" |
garrytrinder
left a comment
There was a problem hiding this comment.
Thanks for the contribution @YugalPradhan31 can you address the comments and we will get this merged.
No description provided.