Skip to content

Adding cea-techPulse-csharp sample#125

Open
AjayJ12-MSFT wants to merge 2 commits intopnp:mainfrom
AjayJ12-MSFT:cea-techPulse-csharp
Open

Adding cea-techPulse-csharp sample#125
AjayJ12-MSFT wants to merge 2 commits intopnp:mainfrom
AjayJ12-MSFT:cea-techPulse-csharp

Conversation

@AjayJ12-MSFT
Copy link
Copy Markdown
Contributor

No description provided.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a new TechPulse (C#) sample that demonstrates a Microsoft 365 Agents SDK + Semantic Kernel agent that retrieves real-time tech news via a local MCP server (NewsAPI-backed), along with Microsoft 365 Agents Toolkit project/configuration files to provision and run/debug it.

Changes:

  • Adds a C# agent app (bot) that uses Semantic Kernel function-calling to invoke tech-news tools.
  • Adds a C# MCP server (stdio) that implements NewsAPI-backed tools (latest news, search, trending, company news).
  • Adds Microsoft 365 Agents Toolkit provisioning/deployment assets (manifest, YAML, bicep, env templates) plus sample metadata/docs.

Reviewed changes

Copilot reviewed 34 out of 37 changed files in this pull request and generated 23 comments.

Show a summary per file
File Description
samples/cea-techPulse-csharp/README.md Sample documentation and quickstart instructions.
samples/cea-techPulse-csharp/assets/sample.json Sample catalog metadata (name/urls/dates/thumbnails).
samples/cea-techPulse-csharp/M365Agent/m365agents.yml Cloud provision + deploy workflow for the agent app.
samples/cea-techPulse-csharp/M365Agent/m365agents.local.yml Local provision workflow (Entra app, bot reg, config generation).
samples/cea-techPulse-csharp/M365Agent/M365Agent.atkproj Agents Toolkit project definition.
samples/cea-techPulse-csharp/M365Agent/M365Agent.atkproj.user Local VS debug profile selection (user-specific).
samples/cea-techPulse-csharp/M365Agent/launchSettings.json Launch profiles for Agents Toolkit (Playground/Teams/Copilot).
samples/cea-techPulse-csharp/M365Agent/appPackage/manifest.json Teams app manifest defining the custom engine agent bot.
samples/cea-techPulse-csharp/M365Agent/appPackage/color.png Teams app icon (color).
samples/cea-techPulse-csharp/M365Agent/appPackage/outline.png Teams app icon (outline).
samples/cea-techPulse-csharp/M365Agent/env/.env.local Local env placeholders generated/used by provisioning.
samples/cea-techPulse-csharp/M365Agent/env/.env.local.user Local secret placeholders for dev-time secrets.
samples/cea-techPulse-csharp/M365Agent/env/.env.dev Dev environment placeholders for Azure provisioning/deploy.
samples/cea-techPulse-csharp/M365Agent/env/.env.dev.user Dev secret placeholders.
samples/cea-techPulse-csharp/M365Agent/infra/azure.bicep Azure infra to host the bot (App Service, MSI, bot registration).
samples/cea-techPulse-csharp/M365Agent/infra/azure.parameters.json ARM parameters (resource base, SKU, OpenAI key, display name).
samples/cea-techPulse-csharp/M365Agent/infra/botRegistration/azurebot.bicep Module to create an Azure Bot Service registration.
samples/cea-techPulse-csharp/M365Agent/infra/botRegistration/readme.md Notes for bot registration module usage.
samples/cea-techPulse-csharp/cea-techPulse-csharp/cea-techPulse-csharp.csproj Main bot web app project (deps + publish behavior).
samples/cea-techPulse-csharp/cea-techPulse-csharp/cea-techPulse-csharp.csproj.user Local VS debug profile selection (user-specific).
samples/cea-techPulse-csharp/cea-techPulse-csharp/Program.cs ASP.NET Core host setup + agent/bot registration + SK setup.
samples/cea-techPulse-csharp/cea-techPulse-csharp/Config.cs Configuration option models for OpenAI + NewsAPI.
samples/cea-techPulse-csharp/cea-techPulse-csharp/AspNetExtensions.cs JWT bearer token validation/auth helper for bot endpoints.
samples/cea-techPulse-csharp/cea-techPulse-csharp/Bot/TechNewsBot.cs Bot/agent logic: chat loop + SK tool calling + streaming response.
samples/cea-techPulse-csharp/cea-techPulse-csharp/Bot/Plugins/TechNewsPlugin.cs SK plugin exposing tech-news functions (MCP-backed).
samples/cea-techPulse-csharp/cea-techPulse-csharp/Services/TechNewsMcpService.cs MCP client that spawns/connects to the MCP server via stdio.
samples/cea-techPulse-csharp/cea-techPulse-csharp/McpServer/TechNewsMcpServer.csproj MCP server project definition (ModelContextProtocol server).
samples/cea-techPulse-csharp/cea-techPulse-csharp/McpServer/TechNewsMcpServer.csproj.user Local VS debug profile selection (user-specific).
samples/cea-techPulse-csharp/cea-techPulse-csharp/McpServer/Program.cs MCP server host bootstrap with stdio transport + tool discovery.
samples/cea-techPulse-csharp/cea-techPulse-csharp/McpServer/TechNewsTools.cs MCP tools implementation calling NewsAPI and formatting results.
samples/cea-techPulse-csharp/cea-techPulse-csharp/appsettings.json Base configuration (agent options, auth, AI keys placeholders).
samples/cea-techPulse-csharp/cea-techPulse-csharp/appsettings.Development.json Dev overrides generated by local provision workflow.
samples/cea-techPulse-csharp/cea-techPulse-csharp/appsettings.Playground.json Playground overrides (bot connection + AI keys placeholders).
samples/cea-techPulse-csharp/cea-techPulse-csharp/Properties/launchSettings.json ASP.NET Core launch profiles (Playground vs Development).
samples/cea-techPulse-csharp/cea-techPulse-csharp.slnx Solution definition including bot + MCP server + toolkit project.
samples/cea-techPulse-csharp/cea-techPulse-csharp.slnLaunch.user Multi-project launch configuration (user-specific).
Comments suppressed due to low confidence (1)

samples/cea-techPulse-csharp/M365Agent/env/.env.dev.user:5

  • This dev env template is missing a SECRET_NEWS_API_KEY entry, but the sample requires a NewsAPI key for tech news. Add it here (and wire it through provisioning/app settings) so dev deployments don’t fail at runtime when calling the news tools.
# This file includes environment variables that will not be committed to git by default. You can set these environment variables in your CI/CD system for your project.

# Secrets. Keys prefixed with `SECRET_` will be masked in Microsoft 365 Agents Toolkit logs.
SECRET_OPENAI_API_KEY=


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread samples/cea-techPulse-csharp/README.md Outdated

TechPulse is an intelligent tech news companion that delivers the latest technology news, trends, and insights from trusted sources in the industry. Built with Microsoft 365 Agents SDK and Semantic Kernel, this agent provides real-time access to tech news across multiple categories including AI/ML, startups, cybersecurity, mobile technology, and gaming. The agent understands natural language queries and can search for specific topics, provide trending tech news, and deliver company-specific updates from major tech players like Microsoft, Apple, Google, and more.

![Tech Pulse News](../assets/techPulse.gif)
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

The image reference points to ../assets/techPulse.gif, but this README lives in samples/cea-techPulse-csharp/ and the GIF is in samples/cea-techPulse-csharp/assets/techPulse.gif. As written, the image link is broken; update it to a path relative to this README (e.g., ./assets/techPulse.gif).

Suggested change
![Tech Pulse News](../assets/techPulse.gif)
![Tech Pulse News](./assets/techPulse.gif)

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated

Comment on lines +117 to +120
We do not support samples, but this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.

You can try looking at [issues related to this sample](https://github.com/pnp/copilot-pro-dev-samples/issues?q=label%3A%22sample%3A%20cea-techpulse-csharp%22) to see if anybody else is having the same issues.

Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

The issue-label and visitor-stats links use cea-techpulse-csharp (lowercase p) but the actual sample folder is cea-techPulse-csharp. These URLs will 404 on GitHub/raw paths unless the casing matches; update the links to the correct folder casing (or rename the folder to match the canonical sample id).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated

Comment on lines +3 to +9
"name": "pnp-copilot-pro-dev-cea-techpulse-csharp",
"source": "pnp",
"title": "TechPulse - Custom Engine Agent for Real-Time Technology News (C#)",
"shortDescription": "An intelligent tech news companion powered by Microsoft 365 Agents SDK and Semantic Kernel",
"url": "https://github.com/pnp/copilot-pro-dev-samples/tree/main/samples/cea-techpulse-csharp",
"downloadUrl": "https://pnp.github.io/download-partial/?url=https://github.com/pnp/copilot-pro-dev-samples/tree/main/samples/cea-techpulse-csharp",
"longDescription": [
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

The url, downloadUrl, and thumbnail url all point at samples/cea-techpulse-csharp, but the folder committed is samples/cea-techPulse-csharp (different casing). This will break links (GitHub paths are case-sensitive); align the paths (or rename the folder) to a single canonical sample id.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated

Comment thread samples/cea-techPulse-csharp/M365Agent/launchSettings.json
Comment on lines +20 to +24
},
"hotReloadProfile": "aspnetcore"
},
}
} No newline at end of file
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

Trailing comma after the last profile makes this launchSettings.json invalid JSON. Some tooling is strict about JSON here; remove the trailing comma to avoid launch/profile loading failures.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated

Comment on lines +27 to +42
<!-- Exclude local settings from publish -->
<ItemGroup>
<Content Remove="appsettings.Development.json" />
<Content Include="appsettings.Development.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>None</CopyToPublishDirectory>
</Content>
<Content Remove="appsettings.Playground.json" />
<Content Include="appsettings.Playground.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>None</CopyToPublishDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<None Include="appsettings.Development.json" />
</ItemGroup>
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

appsettings.Development.json is included both as Content and again as None. This duplication can cause MSBuild warnings/errors about duplicate items. Keep a single item entry (typically the Content entry with the desired copy settings) and remove the redundant include.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated

Comment on lines +86 to +87
args: publish --configuration Release --runtime win-x86 --self-contained
cea-techPulse-csharp.csproj
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

In YAML, splitting args: across multiple indented lines relies on YAML scalar continuation rules and can be easy to break. To avoid parsing differences across tools, consider using a single-line string or an explicit folded scalar (>), ensuring the final command is exactly publish ... --self-contained cea-techPulse-csharp.csproj.

Suggested change
args: publish --configuration Release --runtime win-x86 --self-contained
cea-techPulse-csharp.csproj
args: publish --configuration Release --runtime win-x86 --self-contained cea-techPulse-csharp.csproj

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated

Comment on lines +28 to +52
### Debug agent in Microsoft 365 Agents Playground
1. Ensure your API keys are filled in `appsettings.Playground.json`:
```json
"OpenAI": {
"ApiKey": "<your-openai-api-key>"
},
"NewsApi": {
"ApiKey": "<your-newsapi-key>"
}
```
2. Set `Startup Item` as `Microsoft 365 Agents Playground (browser)`.
3. Press F5, or select the Debug > Start Debugging menu in Visual Studio.
4. In Microsoft 365 Agents Playground from the launched browser, try asking:
* "Latest AI news"
* "What's trending in tech?"
* "News about Microsoft"
* "Search for cybersecurity updates"

### Debug agent in Teams Web Client
1. Ensure your API keys are filled in `env/.env.local.user`:
```
SECRET_OPENAI_API_KEY="<your-openai-api-key>"
SECRET_NEWS_API_KEY="<your-newsapi-key>"
```
2. In the debug dropdown menu, select Dev Tunnels > Create A Tunnel (set authentication type to Public) or select an existing public dev tunnel.
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

The paths in Quick Start don’t match the repo layout: the secrets file is under M365Agent/env/.env.local.user (not env/.env.local.user), and appsettings.Playground.json lives under cea-techPulse-csharp/appsettings.Playground.json. As written, new users will edit the wrong files; update these paths to be relative to the sample root.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated

Comment on lines +3 to +16
public class ConfigOptions
{
public OpenAIConfigOptions OpenAI { get; set; }
public NewsApiConfigOptions NewsApi { get; set; }
}

/// <summary>
/// Options for OpenAI
/// </summary>
public class OpenAIConfigOptions
{
public string ApiKey { get; set; }
public string DefaultModel = "gpt-4o";
}
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

These options types use non-nullable reference properties without initialization (OpenAI, NewsApi, ApiKey), which can produce nullability warnings and runtime NREs when config is missing. Also DefaultModel is a field, so configuration binding won’t populate it. Prefer required/init properties (or nullable properties) and make DefaultModel a property with a default value so binding/validation behaves predictably.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated

Comment on lines +4 to +17
"parameters": {
"resourceBaseName": {
"value": "bot${{RESOURCE_SUFFIX}}"
},
"openAIApiKey": {
"value": "${{SECRET_OPENAI_API_KEY}}"
},
"webAppSKU": {
"value": "B1"
},
"botDisplayName": {
"value": "cea-techPulse-csharp"
}
}
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

azure.bicep doesn’t currently parameterize/set the NewsAPI key; correspondingly this parameters file has no newsApiKey value. Add a secure newsApiKey parameter here and pass it through to the web app’s settings (or Key Vault) so deployments have the required configuration.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated

@garrytrinder garrytrinder marked this pull request as draft April 13, 2026 10:51
@garrytrinder
Copy link
Copy Markdown
Member

@AjayJ12-MSFT thanks for your contribution, can you take a look at the review comments and mark the PR as ready for review when you resolved them, thanks.

@AjayJ12-MSFT AjayJ12-MSFT marked this pull request as ready for review April 14, 2026 11:10
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.

3 participants