Skip to content

Commit 1c40de6

Browse files
Added helper APIs to simplify the basic getting-started usage (#17)
* simplified the basic getting-started usage * added similar helpers for assistants
1 parent bd11859 commit 1c40de6

14 files changed

+121
-79
lines changed

README.md

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,9 @@ using OpenAI.Chat;
5252

5353
ChatClient client = new(model: "gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
5454

55-
ChatCompletion chatCompletion = client.CompleteChat(
56-
[
57-
new UserChatMessage("Say 'this is a test.'"),
58-
]);
55+
ChatCompletion completion = client.CompleteChat("Say 'this is a test.'");
56+
57+
Console.WriteLine($"[ASSISTANT]: {completion}");
5958
```
6059

6160
While you can pass your API key directly as a string, it is highly recommended to keep it in a secure location and instead access it via an environment variable or configuration file as shown above to avoid storing it in source control.
@@ -83,10 +82,7 @@ The library is organized into several namespaces corresponding to OpenAI feature
8382
Every client method that performs a synchronous API call has an asynchronous variant in the same client class. For instance, the asynchronous variant of the `ChatClient`'s `CompleteChat` method is `CompleteChatAsync`. To rewrite the call above using the asynchronous counterpart, simply `await` the call to the corresponding async variant:
8483

8584
```csharp
86-
ChatCompletion chatCompletion = await client.CompleteChatAsync(
87-
[
88-
new UserChatMessage("Say 'this is a test.'"),
89-
]);
85+
ChatCompletion completion = await client.CompleteChatAsync("Say 'this is a test.'");
9086
```
9187

9288
### Using the `OpenAIClient` class
@@ -119,41 +115,35 @@ When you request a chat completion, the default behavior is for the server to ge
119115
The client library offers a convenient approach to working with streaming chat completions. If you wanted to re-write the example from the previous section using streaming, rather than calling the `ChatClient`'s `CompleteChat` method, you would call its `CompleteChatStreaming` method instead:
120116

121117
```csharp
122-
ResultCollection<StreamingChatCompletionUpdate> chatUpdates
123-
= client.CompleteChatStreaming(
124-
[
125-
new UserChatMessage("Say 'this is a test.'"),
126-
]);
118+
ResultCollection<StreamingChatCompletionUpdate> updates
119+
= client.CompleteChatStreaming("Say 'this is a test.'");
127120
```
128121

129122
Notice that the returned value is a `ResultCollection<StreamingChatCompletionUpdate>` instance, which can be enumerated to process the streaming response chunks as they arrive:
130123

131124
```csharp
132125
Console.WriteLine($"[ASSISTANT]:");
133-
foreach (StreamingChatCompletionUpdate chatUpdate in chatUpdates)
126+
foreach (StreamingChatCompletionUpdate update in updates)
134127
{
135-
foreach (ChatMessageContentPart contentPart in chatUpdate.ContentUpdate)
128+
foreach (ChatMessageContentPart updatePart in update.ContentUpdate)
136129
{
137-
Console.Write(contentPart.Text);
130+
Console.Write(updatePart);
138131
}
139132
}
140133
```
141134

142135
Alternatively, you can do this asynchronously by calling the `CompleteChatStreamingAsync` method to get an `AsyncResultCollection<StreamingChatCompletionUpdate>` and enumerate it using `await foreach`:
143136

144137
```csharp
145-
AsyncResultCollection<StreamingChatCompletionUpdate> asyncChatUpdates
146-
= client.CompleteChatStreamingAsync(
147-
[
148-
new UserChatMessage("Say 'this is a test.'"),
149-
]);
138+
AsyncResultCollection<StreamingChatCompletionUpdate> updates
139+
= client.CompleteChatStreamingAsync("Say 'this is a test.'");
150140

151141
Console.WriteLine($"[ASSISTANT]:");
152-
await foreach (StreamingChatCompletionUpdate chatUpdate in asyncChatUpdates)
142+
await foreach (StreamingChatCompletionUpdate update in updates)
153143
{
154-
foreach (ChatMessageContentPart contentPart in chatUpdate.ContentUpdate)
144+
foreach (ChatMessageContentPart updatePart in update.ContentUpdate)
155145
{
156-
Console.Write(contentPart.Text);
146+
Console.Write(updatePart.Text);
157147
}
158148
}
159149
```
@@ -515,13 +505,7 @@ Next, create a new thread. For illustrative purposes, you could include an initi
515505
```csharp
516506
ThreadCreationOptions threadOptions = new()
517507
{
518-
InitialMessages =
519-
{
520-
new ThreadInitializationMessage(new List<MessageContent>()
521-
{
522-
MessageContent.FromText("How well did product 113045 sell in February? Graph its trend over time."),
523-
}),
524-
},
508+
InitialMessages = { "How well did product 113045 sell in February? Graph its trend over time." }
525509
};
526510

527511
ThreadRun threadRun = assistantClient.CreateThreadAndRun(assistant.Id, threadOptions);

examples/Assistants/Example01_RetrievalAugmentedGeneration.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,7 @@ public void Example01_RetrievalAugmentedGeneration()
8585
// Now we'll create a thread with a user query about the data already associated with the assistant, then run it
8686
ThreadCreationOptions threadOptions = new()
8787
{
88-
InitialMessages =
89-
{
90-
new ThreadInitializationMessage(new List<MessageContent>()
91-
{
92-
MessageContent.FromText("How well did product 113045 sell in February? Graph its trend over time."),
93-
}),
94-
},
88+
InitialMessages = { "How well did product 113045 sell in February? Graph its trend over time." }
9589
};
9690

9791
ThreadRun threadRun = assistantClient.CreateThreadAndRun(assistant.Id, threadOptions);

examples/Assistants/Example02_FunctionCalling.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ string GetCurrentWeather(string location, string unit = "celsius")
8282
// Create a thread with an initial user message and run it.
8383
ThreadCreationOptions threadOptions = new()
8484
{
85-
InitialMessages = { new ThreadInitializationMessage(["What's the weather like today?"]), },
85+
InitialMessages = { "What's the weather like today?" }
8686
};
8787

8888
ThreadRun run = client.CreateThreadAndRun(assistant.Id, threadOptions);

examples/Assistants/Example02_FunctionCallingAsync.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ string GetCurrentWeather(string location, string unit = "celsius")
8282
// Create a thread with an initial user message and run it.
8383
ThreadCreationOptions threadOptions = new()
8484
{
85-
InitialMessages = { new ThreadInitializationMessage(["What's the weather like today?"]), },
85+
InitialMessages = { "What's the weather like today?" }
8686
};
8787

8888
ThreadRun run = await client.CreateThreadAndRunAsync(assistant.Id, threadOptions);

examples/Assistants/Example04_AllTheTools.cs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,10 @@ static string GetNameOfFamilyMember(string relation)
8383
{
8484
InitialMessages =
8585
{
86-
new ThreadInitializationMessage(
87-
[
88-
"Create a graph of a line with a slope that's my father's favorite number "
89-
+ "and an offset that's my mother's favorite number.",
90-
"Include people's names in your response and cite where you found them."
91-
]),
92-
},
86+
"Create a graph of a line with a slope that's my father's favorite number "
87+
+ "and an offset that's my mother's favorite number.",
88+
"Include people's names in your response and cite where you found them."
89+
}
9390
});
9491

9592
ThreadRun run = client.CreateRun(thread, assistant);

examples/Chat/Example01_SimpleChat.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,10 @@ public partial class ChatExamples
99
[Test]
1010
public void Example01_SimpleChat()
1111
{
12-
ChatClient client = new("gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
12+
ChatClient client = new(model: "gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
1313

14-
ChatCompletion chatCompletion = client.CompleteChat(
15-
[
16-
new UserChatMessage("Say 'this is a test.'"),
17-
]);
14+
ChatCompletion completion = client.CompleteChat("Say 'this is a test.'");
1815

19-
Console.WriteLine($"[ASSISTANT]:");
20-
Console.WriteLine($"{chatCompletion.Content[0].Text}");
16+
Console.WriteLine($"[ASSISTANT]: {completion}");
2117
}
2218
}

examples/Chat/Example01_SimpleChatAsync.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,10 @@ public partial class ChatExamples
1010
[Test]
1111
public async Task Example01_SimpleChatAsync()
1212
{
13-
ChatClient client = new("gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
13+
ChatClient client = new(model: "gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
1414

15-
ChatCompletion chatCompletion = await client.CompleteChatAsync(
16-
[
17-
new UserChatMessage("Say 'this is a test.'"),
18-
]);
15+
ChatCompletion completion = await client.CompleteChatAsync("Say 'this is a test.'");
1916

20-
Console.WriteLine($"[ASSISTANT]:");
21-
Console.WriteLine($"{chatCompletion.Content[0].Text}");
17+
Console.WriteLine($"{completion}");
2218
}
2319
}

examples/Chat/Example02_SimpleChatStreaming.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,17 @@ public partial class ChatExamples
1010
[Test]
1111
public void Example02_SimpleChatStreaming()
1212
{
13-
ChatClient client = new("gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
13+
ChatClient client = new(model: "gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
1414

15-
ResultCollection<StreamingChatCompletionUpdate> chatUpdates
16-
= client.CompleteChatStreaming(
17-
[
18-
new UserChatMessage("Say 'this is a test.'"),
19-
]);
15+
ResultCollection<StreamingChatCompletionUpdate> updates
16+
= client.CompleteChatStreaming("Say 'this is a test.'");
2017

2118
Console.WriteLine($"[ASSISTANT]:");
22-
foreach (StreamingChatCompletionUpdate chatUpdate in chatUpdates)
19+
foreach (StreamingChatCompletionUpdate update in updates)
2320
{
24-
foreach (ChatMessageContentPart contentPart in chatUpdate.ContentUpdate)
21+
foreach (ChatMessageContentPart updatePart in update.ContentUpdate)
2522
{
26-
Console.Write(contentPart.Text);
23+
Console.Write(updatePart);
2724
}
2825
}
2926
}

examples/Chat/Example02_SimpleChatStreamingAsync.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,17 @@ public partial class ChatExamples
1111
[Test]
1212
public async Task Example02_SimpleChatStreamingAsync()
1313
{
14-
ChatClient client = new("gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
14+
ChatClient client = new(model: "gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
1515

16-
AsyncResultCollection<StreamingChatCompletionUpdate> asyncChatUpdates
17-
= client.CompleteChatStreamingAsync(
18-
[
19-
new UserChatMessage("Say 'this is a test.'"),
20-
]);
16+
AsyncResultCollection<StreamingChatCompletionUpdate> updates
17+
= client.CompleteChatStreamingAsync("Say 'this is a test.'");
2118

2219
Console.WriteLine($"[ASSISTANT]:");
23-
await foreach (StreamingChatCompletionUpdate chatUpdate in asyncChatUpdates)
20+
await foreach (StreamingChatCompletionUpdate update in updates)
2421
{
25-
foreach (ChatMessageContentPart contentPart in chatUpdate.ContentUpdate)
22+
foreach (ChatMessageContentPart updatePart in update.ContentUpdate)
2623
{
27-
Console.Write(contentPart.Text);
24+
Console.Write(updatePart.Text);
2825
}
2926
}
3027
}

src/Custom/Assistants/ThreadInitializationMessage.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,15 @@ public ThreadInitializationMessage(IEnumerable<MessageContent> content) : base(c
1616
internal ThreadInitializationMessage(MessageCreationOptions baseOptions)
1717
: base(baseOptions.Role, baseOptions.Content, baseOptions.Attachments, baseOptions.Metadata, null)
1818
{ }
19+
20+
/// <summary>
21+
/// Implicitly creates a new instance of <see cref="ThreadInitializationMessage"/> from a single item of plain text
22+
/// content.
23+
/// </summary>
24+
/// <remarks>
25+
/// Using a <see cref="string"/> in the position of a <see cref="ThreadInitializationMessage"/> is equivalent to
26+
/// using the <see cref="ThreadInitializationMessage(IEnumerable{MessageContent})"/> constructor with a single
27+
/// <see cref="MessageContent.FromText(string)"/> content instance.
28+
/// </remarks>
29+
public static implicit operator ThreadInitializationMessage(string initializationMessage) => new([initializationMessage]);
1930
}

0 commit comments

Comments
 (0)