openai/openai-dotnet

Public

mirrored from https://github.com/openai/openai-dotnetAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
OpenAI_2.0.0-beta.1

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/Custom/Chat/ChatClient.cs

161lines · modecode

1using System;
2using System.ClientModel;
3using System.ClientModel.Primitives;
4using System.Collections.Generic;
5using System.Linq;
6using System.Threading.Tasks;
7
8namespace OpenAI.Chat;
9
10[CodeGenClient("Chat")]
11[CodeGenSuppress("CreateChatCompletionAsync", typeof(ChatCompletionOptions))]
12[CodeGenSuppress("CreateChatCompletion", typeof(ChatCompletionOptions))]
13public partial class ChatClient
14{
15 private readonly string _model;
16
17 /// <summary>
18 /// Initializes a new instance of <see cref="ChatClient"/> that will use an API key when authenticating.
19 /// </summary>
20 /// <param name="model"> The model name for chat completions that the client should use. </param>
21 /// <param name="credential"> The API key used to authenticate with the service endpoint. </param>
22 /// <param name="options"> Additional options to customize the client. </param>
23 /// <exception cref="ArgumentNullException"> The provided <paramref name="credential"/> was null. </exception>
24 public ChatClient(string model, ApiKeyCredential credential, OpenAIClientOptions options = null)
25 : this(
26 OpenAIClient.CreatePipeline(OpenAIClient.GetApiKey(credential, requireExplicitCredential: true), options),
27 model,
28 OpenAIClient.GetEndpoint(options),
29 options)
30 { }
31
32 /// <summary>
33 /// Initializes a new instance of <see cref="ChatClient"/> that will use an API key from the OPENAI_API_KEY
34 /// environment variable when authenticating.
35 /// </summary>
36 /// <remarks>
37 /// To provide an explicit credential instead of using the environment variable, use an alternate constructor like
38 /// <see cref="ChatClient(string,ApiKeyCredential,OpenAIClientOptions)"/>.
39 /// </remarks>
40 /// <param name="model"> The model name for chat completions that the client should use. </param>
41 /// <param name="options"> Additional options to customize the client. </param>
42 /// <exception cref="InvalidOperationException"> The OPENAI_API_KEY environment variable was not found. </exception>
43 public ChatClient(string model, OpenAIClientOptions options = null)
44 : this(
45 OpenAIClient.CreatePipeline(OpenAIClient.GetApiKey(), options),
46 model,
47 OpenAIClient.GetEndpoint(options),
48 options)
49 { }
50
51 /// <summary>
52 /// Initializes a new instance of <see cref="ChatClient"/>.
53 /// </summary>
54 /// <param name="pipeline"> The <see cref="ClientPipeline"/> instance to use. </param>
55 /// <param name="model"> The model name to use. </param>
56 /// <param name="endpoint"> The endpoint to use. </param>
57 protected internal ChatClient(ClientPipeline pipeline, string model, Uri endpoint, OpenAIClientOptions options)
58 {
59 Argument.AssertNotNullOrEmpty(model, nameof(model));
60
61 _model = model;
62 _pipeline = pipeline;
63 _endpoint = endpoint;
64 }
65
66 /// <summary>
67 /// Generates a single chat completion result for a provided set of input chat messages.
68 /// </summary>
69 /// <param name="messages"> The messages to provide as input and history for chat completion. </param>
70 /// <param name="options"> Additional options for the chat completion request. </param>
71 /// <returns> A result for a single chat completion. </returns>
72 public virtual async Task<ClientResult<ChatCompletion>> CompleteChatAsync(IEnumerable<ChatMessage> messages, ChatCompletionOptions options = null)
73 {
74 Argument.AssertNotNullOrEmpty(messages, nameof(messages));
75
76 options ??= new();
77 CreateChatCompletionOptions(messages, ref options);
78
79 using BinaryContent content = options.ToBinaryContent();
80 ClientResult result = await CompleteChatAsync(content, null).ConfigureAwait(false);
81 return ClientResult.FromValue(ChatCompletion.FromResponse(result.GetRawResponse()), result.GetRawResponse());
82 }
83
84 /// <summary>
85 /// Generates a single chat completion result for a provided set of input chat messages.
86 /// </summary>
87 /// <param name="messages"> The messages to provide as input and history for chat completion. </param>
88 /// <param name="options"> Additional options for the chat completion request. </param>
89 /// <returns> A result for a single chat completion. </returns>
90 public virtual ClientResult<ChatCompletion> CompleteChat(IEnumerable<ChatMessage> messages, ChatCompletionOptions options = null)
91 {
92 Argument.AssertNotNullOrEmpty(messages, nameof(messages));
93
94 options ??= new();
95 CreateChatCompletionOptions(messages, ref options);
96
97 using BinaryContent content = options.ToBinaryContent();
98 ClientResult result = CompleteChat(content, null);
99 return ClientResult.FromValue(ChatCompletion.FromResponse(result.GetRawResponse()), result.GetRawResponse());
100
101 }
102
103 /// <summary>
104 /// Begins a streaming response for a chat completion request using the provided chat messages as input and
105 /// history.
106 /// </summary>
107 /// <remarks>
108 /// <see cref="AsyncResultCollection{T}"/> can be enumerated over using the <c>await foreach</c> pattern using the
109 /// <see cref="IAsyncEnumerable{T}"/> interface.
110 /// </remarks>
111 /// <param name="messages"> The messages to provide as input for chat completion. </param>
112 /// <param name="options"> Additional options for the chat completion request. </param>
113 /// <returns> A streaming result with incremental chat completion updates. </returns>
114 public virtual AsyncResultCollection<StreamingChatCompletionUpdate> CompleteChatStreamingAsync(IEnumerable<ChatMessage> messages, ChatCompletionOptions options = null)
115 {
116 Argument.AssertNotNull(messages, nameof(messages));
117
118 options ??= new();
119 CreateChatCompletionOptions(messages, ref options, stream: true);
120
121 using BinaryContent content = options.ToBinaryContent();
122 RequestOptions requestOptions = new() { BufferResponse = false };
123 async Task<ClientResult> getResultAsync() =>
124 await CompleteChatAsync(content, requestOptions).ConfigureAwait(false);
125 return new AsyncStreamingChatCompletionUpdateCollection(getResultAsync);
126 }
127
128 /// <summary>
129 /// Begins a streaming response for a chat completion request using the provided chat messages as input and
130 /// history.
131 /// </summary>
132 /// <remarks>
133 /// <see cref="ResultCollection{T}"/> can be enumerated over using the <c>foreach</c> pattern using the
134 /// <see cref="IEnumerable{T}"/> interface.
135 /// </remarks>
136 /// <param name="messages"> The messages to provide as input for chat completion. </param>
137 /// <param name="options"> Additional options for the chat completion request. </param>
138 /// <returns> A streaming result with incremental chat completion updates. </returns>
139 public virtual ResultCollection<StreamingChatCompletionUpdate> CompleteChatStreaming(IEnumerable<ChatMessage> messages, ChatCompletionOptions options = null)
140 {
141 Argument.AssertNotNull(messages, nameof(messages));
142
143 options ??= new();
144 CreateChatCompletionOptions(messages, ref options, stream: true);
145
146 using BinaryContent content = options.ToBinaryContent();
147 RequestOptions requestOptions = new() { BufferResponse = false };
148 ClientResult getResult() => CompleteChat(content, requestOptions);
149 return new StreamingChatCompletionUpdateCollection(getResult);
150 }
151
152 private void CreateChatCompletionOptions(IEnumerable<ChatMessage> messages, ref ChatCompletionOptions options, bool stream = false)
153 {
154 options.Messages = messages.ToList();
155 options.Model = _model;
156 options.Stream = stream
157 ? true
158 : null;
159 options.StreamOptions = stream ? options.StreamOptions : null;
160 }
161}