microsoft/teams.net

Public

mirrored fromhttps://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
5c4075027232b28388ab1e973b9d2407df669d63

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

Samples/Samples.AI/Program.cs

159lines · modecode

1using System.Text.RegularExpressions;
2using Microsoft.Teams.Apps.Extensions;
3using Microsoft.Teams.Apps.Activities;
4using Microsoft.Teams.Apps.Activities.Invokes;
5using Microsoft.Teams.Plugins.AspNetCore.Extensions;
6using Microsoft.Teams.Plugins.AspNetCore.DevTools.Extensions;
7using Microsoft.Teams.AI.Models.OpenAI;
8using Microsoft.Teams.AI.Prompts;
9using Microsoft.Teams.AI.Templates;
10using Azure.AI.OpenAI;
11using System.ClientModel;
12using Microsoft.Teams.Api.Activities;
13using Samples.AI.Handlers;
14
15var builder = WebApplication.CreateBuilder(args);
16
17// Configuration
18var azureOpenAIModel = builder.Configuration["AzureOpenAIModel"] ?? throw new InvalidOperationException("AzureOpenAIModel not configured");
19var azureOpenAIEndpoint = builder.Configuration["AzureOpenAIEndpoint"] ?? throw new InvalidOperationException("AzureOpenAIEndpoint not configured");
20var azureOpenAIKey = builder.Configuration["AzureOpenAIKey"] ?? throw new InvalidOperationException("AzureOpenAIKey not configured");
21
22var azureOpenAI = new AzureOpenAIClient(
23 new Uri(azureOpenAIEndpoint),
24 new ApiKeyCredential(azureOpenAIKey)
25);
26
27// Register AI Model as singleton
28var aiModel = new OpenAIChatModel(azureOpenAIModel, azureOpenAI);
29
30builder.AddTeams().AddTeamsDevTools();
31var app = builder.Build();
32
33var teamsApp = app.UseTeams();
34
35// Simple chat handler - "hi" command
36teamsApp.OnMessage(@"^hi$", async (context) =>
37{
38 context.Log.Info($"[COMMAND] 'hi' command invoked by user: {context.Activity.From.Name}");
39
40 var prompt = new OpenAIChatPrompt(aiModel, new ChatPromptOptions
41 {
42 Instructions = new StringTemplate("You are a friendly assistant who talks like a pirate")
43 });
44
45 context.Log.Info("[COMMAND] Sending 'hi' message to AI with pirate personality...");
46 var result = await prompt.Send(context.Activity.Text);
47 if (result.Content != null)
48 {
49 context.Log.Info($"[COMMAND] AI response: {result.Content}");
50 var messageActivity = new MessageActivity
51 {
52 Text = result.Content,
53 }.AddAIGenerated();
54 await context.Send(messageActivity);
55 }
56});
57
58// Pokemon command handler
59teamsApp.OnMessage(@"^pokemon\s+(.+)", async (context) =>
60{
61 context.Log.Info($"[COMMAND] 'pokemon' command invoked: {context.Activity.Text}");
62 var match = Regex.Match(context.Activity.Text ?? "", @"^pokemon\s+(.+)", RegexOptions.IgnoreCase);
63 if (match.Success)
64 {
65 var pokemonName = match.Groups[1].Value.Trim();
66 context.Log.Info($"[COMMAND] Extracted pokemon name: '{pokemonName}'");
67 context.Activity.Text = pokemonName;
68 await FunctionCallingHandler.HandlePokemonSearch(aiModel, context);
69 }
70});
71
72
73// Streaming handler
74teamsApp.OnMessage(@"^stream\s+(.+)", async (context) =>
75{
76 context.Log.Info($"[COMMAND] 'stream' command invoked: {context.Activity.Text}");
77 var match = Regex.Match(context.Activity.Text ?? "", @"^stream\s+(.+)", RegexOptions.IgnoreCase);
78 if (match.Success)
79 {
80 var query = match.Groups[1].Value.Trim();
81 context.Log.Info($"[COMMAND] Extracted query for streaming: '{query}'");
82 var prompt = new OpenAIChatPrompt(aiModel, new ChatPromptOptions
83 {
84 Instructions = new StringTemplate("You are a friendly assistant who responds in extremely verbose language")
85 });
86
87 context.Log.Info("[COMMAND] Sending streaming request to AI...");
88 var result = await prompt.Send(query, (chunk) =>
89 {
90 context.Log.Info($"[STREAM] Chunk received: {chunk}");
91 context.Stream.Emit(chunk);
92 return Task.CompletedTask;
93 });
94 }
95});
96
97// Citations handler
98teamsApp.OnMessage(@"^citations?\b", async (context) =>
99{
100 context.Log.Info($"[COMMAND] 'citations' command invoked: {context.Activity.Text}");
101 await CitationsHandler.HandleCitationsDemo(context);
102});
103
104// Feedback loop handler
105teamsApp.OnMessage(@"^feedback\s+(.+)", async (context) =>
106{
107 context.Log.Info($"[COMMAND] 'feedback' command invoked: {context.Activity.Text}");
108 var match = Regex.Match(context.Activity.Text ?? "", @"^feedback\s+(.+)", RegexOptions.IgnoreCase);
109 if (match.Success)
110 {
111 var query = match.Groups[1].Value.Trim();
112 context.Log.Info($"[COMMAND] Extracted query for feedback: '{query}'");
113 context.Activity.Text = query;
114 await FeedbackHandler.HandleFeedbackLoop(aiModel, context);
115 }
116});
117
118// Memory clear handler
119teamsApp.OnMessage(@"^memory\s+clear\b", async (context) =>
120{
121 context.Log.Info($"[COMMAND] 'memory clear' command invoked for conversation: {context.Activity.Conversation.Id}");
122 await MemoryManagementHandler.ClearConversationMemory(context.Activity.Conversation.Id);
123 await context.Reply("🧠 Memory cleared!");
124});
125
126// Prompt-based handler (declarative style)
127teamsApp.OnMessage(@"^/weather\b", async (context) =>
128{
129 context.Log.Info($"[COMMAND] '/weather' command invoked: {context.Activity.Text}");
130 var prompt = OpenAIChatPrompt.From(aiModel, new Samples.AI.Prompts.WeatherPrompt(context.ToActivityType()));
131 var result = await prompt.Send(context.Activity.Text);
132 if (!string.IsNullOrEmpty(result.Content))
133 {
134 context.Log.Info($"[COMMAND] AI response: {result.Content}");
135 var messageActivity = new MessageActivity { Text = result.Content }.AddAIGenerated();
136 await context.Send(messageActivity);
137 }
138 else
139 {
140 await context.Reply("Sorry I could not figure it out");
141 }
142});
143
144// Feedback submission handler
145teamsApp.OnFeedback((context) =>
146{
147 context.Log.Info($"[HANDLER] Feedback submission received");
148 FeedbackHandler.HandleFeedbackSubmission(context);
149 return Task.CompletedTask;
150});
151
152// Fallback stateful conversation handler
153teamsApp.OnMessage(async (context) =>
154{
155 context.Log.Info($"[FALLBACK] Fallback handler invoked (no command matched): {context.Activity.Text}");
156 await MemoryManagementHandler.HandleStatefulConversation(aiModel, context);
157});
158
159app.Run();