microsoft/teams.net

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
fix/msal-cache

Branches

Tags

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

Clone

HTTPS

Download ZIP

Libraries/Microsoft.Teams.AI/Prompts/ChatPrompt/ChatPrompt.cs

238lines · modecode

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT License.
3
4using System.Reflection;
5
6using Microsoft.Teams.AI.Annotations;
7using Microsoft.Teams.AI.Messages;
8using Microsoft.Teams.AI.Models;
9using Microsoft.Teams.Common.Extensions;
10using Microsoft.Teams.Common.Logging;
11
12namespace Microsoft.Teams.AI.Prompts;
13
14/// <summary>
15/// a prompt that can send/receive text
16/// messages and expose chat model specific
17/// features like streaming/functions
18/// </summary>
19[Obsolete("Microsoft.Teams.AI is deprecated and will be removed by end of summer 2026.")]
20public interface IChatPrompt : IPrompt
21{
22 /// <summary>
23 /// the message history
24 /// </summary>
25 public IList<IMessage> Messages { get; }
26
27 /// <summary>
28 /// the collection of registered functions
29 /// </summary>
30 public FunctionCollection Functions { get; }
31}
32
33/// <summary>
34/// a prompt that can send/receive text
35/// messages and expose chat model specific
36/// features like streaming/functions
37/// </summary>
38[Obsolete("Microsoft.Teams.AI is deprecated and will be removed by end of summer 2026.")]
39public interface IChatPrompt<TOptions> : IChatPrompt
40{
41 /// <summary>
42 /// register an error handler
43 /// </summary>
44 public IChatPrompt<TOptions> OnError(Action<Exception> onError);
45
46 /// <summary>
47 /// register an error handler
48 /// </summary>
49 public IChatPrompt<TOptions> OnError(Func<Exception, Task> onError);
50
51 /// <summary>
52 /// send a message via the prompt using string content
53 /// </summary>
54 /// <param name="text">the message text</param>
55 /// <param name="options">the request options</param>
56 /// <param name="onChunk">
57 /// the stream chunk handler (if notnull streaming is enabled)
58 /// </param>
59 /// <returns>the models response</returns>
60 public Task<ModelMessage<string>> Send(string text, RequestOptions? options = null, OnStreamChunk? onChunk = null, CancellationToken cancellationToken = default);
61
62 /// <summary>
63 /// send a message via the prompt using content blocks
64 /// </summary>
65 /// <param name="content">the message content</param>
66 /// <param name="options">the request options</param>
67 /// <param name="onChunk">
68 /// the stream chunk handler (if notnull streaming is enabled)
69 /// </param>
70 /// <returns>the models response</returns>
71 public Task<ModelMessage<string>> Send(IContent[] content, RequestOptions? options = null, OnStreamChunk? onChunk = null, CancellationToken cancellationToken = default);
72
73 /// <summary>
74 /// send a message via the prompt
75 /// </summary>
76 /// <param name="message">the message to send</param>
77 /// <param name="options">the request options</param>
78 /// <param name="onChunk">
79 /// the stream chunk handler (if notnull streaming is enabled)
80 /// </param>
81 /// <returns>the models response</returns>
82 public Task<ModelMessage<string>> Send(UserMessage<string> message, RequestOptions? options = null, OnStreamChunk? onChunk = null, CancellationToken cancellationToken = default);
83
84 /// <summary>
85 /// send a message via the prompt
86 /// </summary>
87 /// <param name="message">the message to send</param>
88 /// <param name="options">the request options</param>
89 /// <param name="onChunk">
90 /// the stream chunk handler (if notnull streaming is enabled)
91 /// </param>
92 /// <returns>the models response</returns>
93 public Task<ModelMessage<string>> Send(UserMessage<IEnumerable<IContent>> message, RequestOptions? options = null, OnStreamChunk? onChunk = null, CancellationToken cancellationToken = default);
94
95 /// <summary>
96 /// options to send when invoking a prompt
97 /// </summary>
98 public class RequestOptions
99 {
100 /// <summary>
101 /// the conversation history
102 /// </summary>
103 public IList<IMessage>? Messages { get; set; }
104
105 /// <summary>
106 /// the model request options
107 /// </summary>
108 public TOptions? Request { get; set; }
109 }
110}
111
112/// <summary>
113/// a prompt that can send/receive text
114/// messages and expose chat model specific
115/// features like streaming/functions
116/// </summary>
117[Obsolete("Microsoft.Teams.AI is deprecated and will be removed by end of summer 2026.")]
118public partial class ChatPrompt<TOptions> : IChatPrompt<TOptions>
119{
120 public string Name { get; private set; }
121 public string Description { get; private set; }
122 public IList<IMessage> Messages { get; private set; }
123 public FunctionCollection Functions { get; private set; }
124
125 protected IChatModel<TOptions> Model { get; }
126 protected ITemplate? Template { get; }
127 protected ILogger Logger { get; }
128 protected IList<IChatPlugin> Plugins { get; }
129 protected event EventHandler<Exception> ErrorEvent;
130
131 public ChatPrompt(IChatModel<TOptions> model, ChatPromptOptions? options = null)
132 {
133 options ??= new();
134 Name = options.Name ?? "Chat";
135 Description = options.Description ?? "an agent you can chat with";
136 Model = model;
137 Template = options.Instructions;
138 Messages = options.Messages ?? [];
139 Functions = new();
140 Logger = (options.Logger ?? new ConsoleLogger()).Child($"AI.{Name}");
141 Plugins = [];
142 ErrorEvent = (_, ex) => Logger.Error(ex);
143 }
144
145 public ChatPrompt(ChatPrompt<TOptions> prompt)
146 {
147 Name = prompt.Name;
148 Description = prompt.Description;
149 Messages = prompt.Messages;
150 Functions = prompt.Functions;
151 Model = prompt.Model;
152 Template = prompt.Template;
153 Logger = prompt.Logger;
154 Plugins = prompt.Plugins;
155 ErrorEvent = prompt.ErrorEvent;
156 }
157
158 public ChatPrompt(string name, ChatPrompt<TOptions> prompt)
159 {
160 Name = name;
161 Description = prompt.Description;
162 Messages = prompt.Messages;
163 Functions = prompt.Functions;
164 Model = prompt.Model;
165 Template = prompt.Template;
166 Logger = prompt.Logger.Peer(name);
167 Plugins = prompt.Plugins;
168 ErrorEvent = prompt.ErrorEvent;
169 }
170
171 /// <summary>
172 /// create a ChatPrompt from any class
173 /// utilizing the ChatPromptAttribute
174 /// </summary>
175 /// <param name="model">the model to use</param>
176 /// <param name="value">the class instance to use</param>
177 /// <returns>a ChatPrompt</returns>
178 public static ChatPrompt<TOptions> From<T>(IChatModel<TOptions> model, T value, ChatPromptOptions? options = null) where T : class
179 {
180 var type = value.GetType();
181 var promptAttribute = type.GetCustomAttribute<PromptAttribute>();
182 var nameAttribute = type.GetCustomAttribute<Prompt.NameAttribute>();
183 var descriptionAttribute = type.GetCustomAttribute<Prompt.DescriptionAttribute>();
184 var instructionsAttribute = type.GetCustomAttribute<Prompt.InstructionsAttribute>();
185
186 if (promptAttribute is null)
187 {
188 throw new Exception("only types utilizing the ChatPromptAttribute can be turned into a ChatPrompt");
189 }
190
191 var name = promptAttribute.Name ?? nameAttribute?.Name ?? type.Name;
192 var description = promptAttribute.Description ?? descriptionAttribute?.Description;
193 var instructions = promptAttribute.Instructions ?? instructionsAttribute?.Instructions;
194 options ??= new();
195 options.WithName(name);
196
197 if (description is not null)
198 {
199 options = options.WithDescription(description);
200 }
201
202 if (instructions is not null)
203 {
204 options = options.WithInstructions(instructions);
205 }
206
207 var prompt = new ChatPrompt<TOptions>(model, options);
208
209 foreach (var method in type.GetMethods())
210 {
211 var functionAttribute = method.GetCustomAttribute<FunctionAttribute>();
212 var functionDescriptionAttribute = method.GetCustomAttribute<Annotations.Function.DescriptionAttribute>();
213
214 if (functionAttribute is null) continue;
215
216 var function = new Function(
217 functionAttribute.Name ?? method.Name,
218 functionAttribute.Description ?? functionDescriptionAttribute?.Description,
219 method.CreateDelegate(value)
220 );
221
222 prompt.Function(function);
223 }
224
225 foreach (var fields in type.GetFields())
226 {
227 var chatPluginAttribute = fields.GetCustomAttribute<ChatPluginAttribute>();
228 if (chatPluginAttribute is null) continue;
229 var plugin = fields.GetValue(value);
230 if (plugin is IChatPlugin chatPlugin)
231 {
232 prompt.Plugin(chatPlugin);
233 }
234 }
235
236 return prompt;
237 }
238}