Skip to content

Commit 9f39eae

Browse files
committed
Merge branch 'main' of https://github.com/openai/openai-dotnet into shreja/Add_UpdateChatCompletion
2 parents 87b240d + 45f9ea5 commit 9f39eae

25 files changed

+1410
-43
lines changed

api/OpenAI.net8.0.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,14 @@ public class ChatClient {
14511451
[Experimental("OPENAI001")]
14521452
public virtual Task<ClientResult<ChatCompletion>> GetChatCompletionAsync(string completionId, CancellationToken cancellationToken = default);
14531453
[Experimental("OPENAI001")]
1454+
public virtual CollectionResult<ChatCompletionMessageListDatum> GetChatCompletionMessages(string completionId, ChatCompletionCollectionOptions options = null, CancellationToken cancellationToken = default);
1455+
[Experimental("OPENAI001")]
1456+
public virtual CollectionResult GetChatCompletionMessages(string completionId, string after, int? limit, string order, RequestOptions options);
1457+
[Experimental("OPENAI001")]
1458+
public virtual AsyncCollectionResult<ChatCompletionMessageListDatum> GetChatCompletionMessagesAsync(string completionId, ChatCompletionMessageCollectionOptions options = null, CancellationToken cancellationToken = default);
1459+
[Experimental("OPENAI001")]
1460+
public virtual AsyncCollectionResult GetChatCompletionMessagesAsync(string completionId, string after, int? limit, string order, RequestOptions options);
1461+
[Experimental("OPENAI001")]
14541462
public virtual CollectionResult<ChatCompletion> GetChatCompletions(ChatCompletionCollectionOptions options = null, CancellationToken cancellationToken = default);
14551463
[Experimental("OPENAI001")]
14561464
public virtual CollectionResult GetChatCompletions(string after, int? limit, string order, IDictionary<string, string> metadata, string model, RequestOptions options);
@@ -1531,6 +1539,29 @@ public class ChatCompletionDeletionResult : IJsonModel<ChatCompletionDeletionRes
15311539
protected virtual ChatCompletionDeletionResult PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
15321540
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
15331541
}
1542+
[Experimental("OPENAI001")]
1543+
public class ChatCompletionMessageCollectionOptions : IJsonModel<ChatCompletionMessageCollectionOptions>, IPersistableModel<ChatCompletionMessageCollectionOptions> {
1544+
public string AfterId { get; set; }
1545+
public ChatCompletionCollectionOrder? Order { get; set; }
1546+
public int? PageSizeLimit { get; set; }
1547+
protected virtual ChatCompletionMessageCollectionOptions JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options);
1548+
protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options);
1549+
protected virtual ChatCompletionMessageCollectionOptions PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
1550+
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
1551+
}
1552+
[Experimental("OPENAI001")]
1553+
public class ChatCompletionMessageListDatum : IJsonModel<ChatCompletionMessageListDatum>, IPersistableModel<ChatCompletionMessageListDatum> {
1554+
public IList<ChatMessageAnnotation> Annotations { get; }
1555+
public ChatOutputAudio Audio { get; }
1556+
public string Content { get; }
1557+
public string Id { get; }
1558+
public string Refusal { get; }
1559+
public IReadOnlyList<ChatToolCall> ToolCalls { get; }
1560+
protected virtual ChatCompletionMessageListDatum JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options);
1561+
protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options);
1562+
protected virtual ChatCompletionMessageListDatum PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
1563+
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
1564+
}
15341565
public class ChatCompletionOptions : IJsonModel<ChatCompletionOptions>, IPersistableModel<ChatCompletionOptions> {
15351566
public bool? AllowParallelToolCalls { get; set; }
15361567
[Experimental("OPENAI001")]

api/OpenAI.netstandard2.0.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,6 +1297,10 @@ public class ChatClient {
12971297
public virtual ClientResult<ChatCompletion> GetChatCompletion(string completionId, CancellationToken cancellationToken = default);
12981298
public virtual Task<ClientResult> GetChatCompletionAsync(string completionId, RequestOptions options);
12991299
public virtual Task<ClientResult<ChatCompletion>> GetChatCompletionAsync(string completionId, CancellationToken cancellationToken = default);
1300+
public virtual CollectionResult<ChatCompletionMessageListDatum> GetChatCompletionMessages(string completionId, ChatCompletionCollectionOptions options = null, CancellationToken cancellationToken = default);
1301+
public virtual CollectionResult GetChatCompletionMessages(string completionId, string after, int? limit, string order, RequestOptions options);
1302+
public virtual AsyncCollectionResult<ChatCompletionMessageListDatum> GetChatCompletionMessagesAsync(string completionId, ChatCompletionMessageCollectionOptions options = null, CancellationToken cancellationToken = default);
1303+
public virtual AsyncCollectionResult GetChatCompletionMessagesAsync(string completionId, string after, int? limit, string order, RequestOptions options);
13001304
public virtual CollectionResult<ChatCompletion> GetChatCompletions(ChatCompletionCollectionOptions options = null, CancellationToken cancellationToken = default);
13011305
public virtual CollectionResult GetChatCompletions(string after, int? limit, string order, IDictionary<string, string> metadata, string model, RequestOptions options);
13021306
public virtual AsyncCollectionResult<ChatCompletion> GetChatCompletionsAsync(ChatCompletionCollectionOptions options = null, CancellationToken cancellationToken = default);
@@ -1361,6 +1365,27 @@ public class ChatCompletionDeletionResult : IJsonModel<ChatCompletionDeletionRes
13611365
protected virtual ChatCompletionDeletionResult PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
13621366
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
13631367
}
1368+
public class ChatCompletionMessageCollectionOptions : IJsonModel<ChatCompletionMessageCollectionOptions>, IPersistableModel<ChatCompletionMessageCollectionOptions> {
1369+
public string AfterId { get; set; }
1370+
public ChatCompletionCollectionOrder? Order { get; set; }
1371+
public int? PageSizeLimit { get; set; }
1372+
protected virtual ChatCompletionMessageCollectionOptions JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options);
1373+
protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options);
1374+
protected virtual ChatCompletionMessageCollectionOptions PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
1375+
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
1376+
}
1377+
public class ChatCompletionMessageListDatum : IJsonModel<ChatCompletionMessageListDatum>, IPersistableModel<ChatCompletionMessageListDatum> {
1378+
public IList<ChatMessageAnnotation> Annotations { get; }
1379+
public ChatOutputAudio Audio { get; }
1380+
public string Content { get; }
1381+
public string Id { get; }
1382+
public string Refusal { get; }
1383+
public IReadOnlyList<ChatToolCall> ToolCalls { get; }
1384+
protected virtual ChatCompletionMessageListDatum JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options);
1385+
protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options);
1386+
protected virtual ChatCompletionMessageListDatum PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
1387+
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
1388+
}
13641389
public class ChatCompletionOptions : IJsonModel<ChatCompletionOptions>, IPersistableModel<ChatCompletionOptions> {
13651390
public bool? AllowParallelToolCalls { get; set; }
13661391
public ChatAudioOptions AudioOptions { get; set; }

codegen/generator/src/Visitors/PaginationVisitor.cs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
namespace OpenAILibraryPlugin.Visitors;
1313

1414
/// <summary>
15-
/// This visitor modifies GetRawPagesAsync methods to consider HasMore in addition to LastId when deciding whether to continue pagination.
15+
/// This visitor modifies GetRawPagesAsync and GetRawPages methods to consider HasMore in addition to LastId when deciding whether to continue pagination.
1616
/// It also replaces specific parameters with an options type for pagination methods.
1717
/// </summary>
1818
public class PaginationVisitor : ScmLibraryVisitor
@@ -37,6 +37,14 @@ public class PaginationVisitor : ScmLibraryVisitor
3737
{
3838
"GetChatCompletionsAsync",
3939
("ChatCompletion", "ChatCompletionCollectionOptions", _chatParamsToReplace)
40+
},
41+
{
42+
"GetChatCompletionMessages",
43+
("ChatCompletionMessageListDatum", "ChatCompletionCollectionOptions", _chatParamsToReplace)
44+
},
45+
{
46+
"GetChatCompletionMessagesAsync",
47+
("ChatCompletionMessageListDatum", "ChatCompletionMessageCollectionOptions", _chatParamsToReplace)
4048
}
4149
};
4250

@@ -174,10 +182,11 @@ nullConditional.Inner is VariableExpression varExpr2 &&
174182
/// <returns>True if the method was handled, false otherwise.</returns>
175183
private bool TryHandleGetRawPagesAsyncMethod(MethodProvider method)
176184
{
177-
// If the method is GetRawPagesAsync and is internal, we will modify the body statements to add a check for hasMore == false.
185+
// If the method is GetRawPagesAsync or GetRawPages and is internal, we will modify the body statements to add a check for hasMore == false.
178186
// This is to ensure that pagination stops when hasMore is false, in addition to checking LastId.
179-
if (method.Signature.Name == "GetRawPagesAsync" && method.EnclosingType.DeclarationModifiers.HasFlag(TypeSignatureModifiers.Internal))
187+
if ((method.Signature.Name == "GetRawPagesAsync" || method.Signature.Name == "GetRawPages") && method.EnclosingType.DeclarationModifiers.HasFlag(TypeSignatureModifiers.Internal))
180188
{
189+
VariableExpression? hasMoreVariable = null;
181190
var statements = method.BodyStatements?.ToList() ?? new List<MethodBodyStatement>();
182191
VisitExplodedMethodBodyStatements(
183192
statements!,
@@ -198,14 +207,12 @@ private bool TryHandleGetRawPagesAsyncMethod(MethodProvider method)
198207
binaryExpr.Right is KeywordExpression rightKeyword &&
199208
rightKeyword.Keyword == "null")
200209
{
201-
// Create "hasMore == null" condition
202-
var hasMoreNullCheck = new BinaryOperatorExpression(
203-
"==",
204-
new MemberExpression(null, "hasMore"),
205-
Snippet.False);
210+
// Create "!hasMore" condition. Note the hasMoreVariable gets assigned earlier in the method statements
211+
// in the WhileStatement handler below.
212+
var hasMoreNullCheck = Snippet.Not(hasMoreVariable);
206213

207-
// Return "nextToken == null || hasMore == null"
208-
return new BinaryOperatorExpression("||", binaryExpr, hasMoreNullCheck);
214+
// Return "nextToken == null || !hasMore"
215+
return BoolSnippets.Or(binaryExpr.As<bool>(), hasMoreNullCheck);
209216
}
210217
}
211218
return expression;
@@ -230,7 +237,7 @@ assignmentExpression.Value is MemberExpression memberExpression &&
230237
{
231238
// Create a new assignment for hasMore
232239
var hasMoreAssignment = new AssignmentExpression(
233-
new DeclarationExpression(typeof(bool), "hasMore"),
240+
Snippet.Declare("hasMore", typeof(bool), out hasMoreVariable),
234241
new MemberExpression(memberExpression.Inner, "HasMore"));
235242

236243
// Insert the new assignment before the existing one

specification/client/chat.client.tsp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ using Azure.ClientGenerator.Core;
1414
@@usage(CreateChatCompletionStreamResponse, Usage.output);
1515

1616
@@visibility(ChatCompletionResponseMessage.tool_calls, Lifecycle.Read);
17+
@@visibility(ChatCompletionResponseMessage.annotations, Lifecycle.Read);
1718
@@visibility(ChatCompletionStreamResponseDelta.tool_calls, Lifecycle.Read);
1819

1920
@@clientName(Chat.createChatCompletion, "CompleteChat");
20-
21-
@@scope(Chat.getChatCompletionMessages, "!csharp");

specification/client/models/chat.models.tsp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,26 @@ model ChatCompletionCollectionOptions {
3131
@query `model`?: string,
3232
}
3333

34+
alias ChatCompletionMessageCollectionOrderQueryParameter = {
35+
/**
36+
* Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc`
37+
* for descending order.
38+
*/
39+
@query order?: ChatCompletionMessageCollectionOrder;
40+
};
41+
42+
union ChatCompletionMessageCollectionOrder {
43+
string,
44+
Ascending: "asc",
45+
Descending: "desc",
46+
}
47+
48+
@access(Access.public)
49+
@usage(Usage.input)
50+
model ChatCompletionMessageCollectionOptions {
51+
...CollectionAfterQueryParameter,
52+
...CollectionLimitQueryParameter,
53+
...ChatCompletionMessageCollectionOrderQueryParameter,
54+
}
55+
3456

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace OpenAI.Chat;
2+
3+
// CUSTOM: Use the correct namespace.
4+
[CodeGenType("ChatCompletionMessageCollectionOptions")]
5+
public partial class ChatCompletionMessageCollectionOptions {}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace OpenAI.Chat;
2+
3+
// CUSTOM: Use the correct namespace.
4+
[CodeGenType("ChatCompletionMessageCollectionOrder")]
5+
public readonly partial struct ChatCompletionMessageCollectionOrder {}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
namespace OpenAI.Chat;
22

33
[CodeGenType("ChatCompletionMessageListDatum")]
4-
internal partial class InternalChatCompletionMessageListDatum
4+
public partial class ChatCompletionMessageListDatum
55
{
66
// CUSTOM: Ensure enumerated value is used.
77
[CodeGenMember("Role")]
88
internal ChatMessageRole Role { get; set; } = ChatMessageRole.Assistant;
9+
10+
// CUSTOM: Rename
11+
[CodeGenMember("Audio")]
12+
public ChatOutputAudio OutputAudio { get; }
913
}

src/Generated/ChatClient.RestClient.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,5 +122,34 @@ internal virtual PipelineMessage CreateDeleteChatCompletionRequest(string comple
122122
message.Apply(options);
123123
return message;
124124
}
125+
126+
internal virtual PipelineMessage CreateGetChatCompletionMessagesRequest(string completionId, string after, int? limit, string order, RequestOptions options)
127+
{
128+
PipelineMessage message = Pipeline.CreateMessage();
129+
message.ResponseClassifier = PipelineMessageClassifier200;
130+
PipelineRequest request = message.Request;
131+
request.Method = "GET";
132+
ClientUriBuilder uri = new ClientUriBuilder();
133+
uri.Reset(_endpoint);
134+
uri.AppendPath("/chat/completions/", false);
135+
uri.AppendPath(completionId, true);
136+
uri.AppendPath("/messages", false);
137+
if (after != null)
138+
{
139+
uri.AppendQuery("after", after, true);
140+
}
141+
if (limit != null)
142+
{
143+
uri.AppendQuery("limit", TypeFormatters.ConvertToString(limit, null), true);
144+
}
145+
if (order != null)
146+
{
147+
uri.AppendQuery("order", order, true);
148+
}
149+
request.Uri = uri.ToUri();
150+
request.Headers.Set("Accept", "application/json");
151+
message.Apply(options);
152+
return message;
153+
}
125154
}
126155
}

src/Generated/ChatClient.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Threading;
1111
using System.Threading.Tasks;
1212
using OpenAI;
13+
using OpenAI.VectorStores;
1314

1415
namespace OpenAI.Chat
1516
{
@@ -146,5 +147,41 @@ public virtual async Task<ClientResult> DeleteChatCompletionAsync(string complet
146147
using PipelineMessage message = CreateDeleteChatCompletionRequest(completionId, options);
147148
return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false));
148149
}
150+
151+
[Experimental("OPENAI001")]
152+
public virtual ClientResult GetChatCompletionMessages(string completionId, string after, int? limit, string order, RequestOptions options)
153+
{
154+
Argument.AssertNotNullOrEmpty(completionId, nameof(completionId));
155+
156+
using PipelineMessage message = CreateGetChatCompletionMessagesRequest(completionId, after, limit, order, options);
157+
return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options));
158+
}
159+
160+
[Experimental("OPENAI001")]
161+
public virtual async Task<ClientResult> GetChatCompletionMessagesAsync(string completionId, string after, int? limit, string order, RequestOptions options)
162+
{
163+
Argument.AssertNotNullOrEmpty(completionId, nameof(completionId));
164+
165+
using PipelineMessage message = CreateGetChatCompletionMessagesRequest(completionId, after, limit, order, options);
166+
return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false));
167+
}
168+
169+
[Experimental("OPENAI001")]
170+
public virtual ClientResult<InternalChatCompletionMessageList> GetChatCompletionMessages(string completionId, string after = default, int? limit = default, VectorStoreCollectionOrder? order = default, CancellationToken cancellationToken = default)
171+
{
172+
Argument.AssertNotNullOrEmpty(completionId, nameof(completionId));
173+
174+
ClientResult result = GetChatCompletionMessages(completionId, after, limit, order?.ToString(), cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null);
175+
return ClientResult.FromValue((InternalChatCompletionMessageList)result, result.GetRawResponse());
176+
}
177+
178+
[Experimental("OPENAI001")]
179+
public virtual async Task<ClientResult<InternalChatCompletionMessageList>> GetChatCompletionMessagesAsync(string completionId, string after = default, int? limit = default, VectorStoreCollectionOrder? order = default, CancellationToken cancellationToken = default)
180+
{
181+
Argument.AssertNotNullOrEmpty(completionId, nameof(completionId));
182+
183+
ClientResult result = await GetChatCompletionMessagesAsync(completionId, after, limit, order?.ToString(), cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false);
184+
return ClientResult.FromValue((InternalChatCompletionMessageList)result, result.GetRawResponse());
185+
}
149186
}
150187
}

0 commit comments

Comments
 (0)