microsoft/teams.net

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
87729f780a04a94c40e3816a99f39edf8c0379b7

Branches

Tags

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

Clone

HTTPS

Download ZIP

Samples/Samples.AI/Program.cs

162lines · modecode

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