Skip to content

Commit 45f9ea5

Browse files
authored
Generate GetChatCompletionMessages with pagination (#569)
1 parent 3613b6a commit 45f9ea5

30 files changed

+1161
-99
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);
@@ -1523,6 +1531,29 @@ public class ChatCompletionDeletionResult : IJsonModel<ChatCompletionDeletionRes
15231531
protected virtual ChatCompletionDeletionResult PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
15241532
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
15251533
}
1534+
[Experimental("OPENAI001")]
1535+
public class ChatCompletionMessageCollectionOptions : IJsonModel<ChatCompletionMessageCollectionOptions>, IPersistableModel<ChatCompletionMessageCollectionOptions> {
1536+
public string AfterId { get; set; }
1537+
public ChatCompletionCollectionOrder? Order { get; set; }
1538+
public int? PageSizeLimit { get; set; }
1539+
protected virtual ChatCompletionMessageCollectionOptions JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options);
1540+
protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options);
1541+
protected virtual ChatCompletionMessageCollectionOptions PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
1542+
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
1543+
}
1544+
[Experimental("OPENAI001")]
1545+
public class ChatCompletionMessageListDatum : IJsonModel<ChatCompletionMessageListDatum>, IPersistableModel<ChatCompletionMessageListDatum> {
1546+
public IList<ChatMessageAnnotation> Annotations { get; }
1547+
public ChatOutputAudio Audio { get; }
1548+
public string Content { get; }
1549+
public string Id { get; }
1550+
public string Refusal { get; }
1551+
public IReadOnlyList<ChatToolCall> ToolCalls { get; }
1552+
protected virtual ChatCompletionMessageListDatum JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options);
1553+
protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options);
1554+
protected virtual ChatCompletionMessageListDatum PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
1555+
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
1556+
}
15261557
public class ChatCompletionOptions : IJsonModel<ChatCompletionOptions>, IPersistableModel<ChatCompletionOptions> {
15271558
public bool? AllowParallelToolCalls { get; set; }
15281559
[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);
@@ -1357,6 +1361,27 @@ public class ChatCompletionDeletionResult : IJsonModel<ChatCompletionDeletionRes
13571361
protected virtual ChatCompletionDeletionResult PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
13581362
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
13591363
}
1364+
public class ChatCompletionMessageCollectionOptions : IJsonModel<ChatCompletionMessageCollectionOptions>, IPersistableModel<ChatCompletionMessageCollectionOptions> {
1365+
public string AfterId { get; set; }
1366+
public ChatCompletionCollectionOrder? Order { get; set; }
1367+
public int? PageSizeLimit { get; set; }
1368+
protected virtual ChatCompletionMessageCollectionOptions JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options);
1369+
protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options);
1370+
protected virtual ChatCompletionMessageCollectionOptions PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
1371+
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
1372+
}
1373+
public class ChatCompletionMessageListDatum : IJsonModel<ChatCompletionMessageListDatum>, IPersistableModel<ChatCompletionMessageListDatum> {
1374+
public IList<ChatMessageAnnotation> Annotations { get; }
1375+
public ChatOutputAudio Audio { get; }
1376+
public string Content { get; }
1377+
public string Id { get; }
1378+
public string Refusal { get; }
1379+
public IReadOnlyList<ChatToolCall> ToolCalls { get; }
1380+
protected virtual ChatCompletionMessageListDatum JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options);
1381+
protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options);
1382+
protected virtual ChatCompletionMessageListDatum PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
1383+
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
1384+
}
13601385
public class ChatCompletionOptions : IJsonModel<ChatCompletionOptions>, IPersistableModel<ChatCompletionOptions> {
13611386
public bool? AllowParallelToolCalls { get; set; }
13621387
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 & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +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");

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

src/Custom/Chat/ChatClient.Protocol.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
namespace OpenAI.Chat;
88

99
/// <summary> The service client for the OpenAI Chat Completions endpoint. </summary>
10-
[CodeGenSuppress("GetChatCompletionMessagesAsync", typeof(string), typeof(string), typeof(int?), typeof(string), typeof(RequestOptions))]
11-
[CodeGenSuppress("GetChatCompletionMessages", typeof(string), typeof(string), typeof(int?), typeof(string), typeof(RequestOptions))]
1210
[CodeGenSuppress("UpdateChatCompletionAsync", typeof(string), typeof(BinaryContent), typeof(RequestOptions))]
1311
[CodeGenSuppress("UpdateChatCompletion", typeof(string), typeof(BinaryContent), typeof(RequestOptions))]
1412
public partial class ChatClient

src/Custom/Chat/ChatClient.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ namespace OpenAI.Chat;
2020
[CodeGenSuppress("ChatClient", typeof(ClientPipeline), typeof(Uri))]
2121
[CodeGenSuppress("CompleteChat", typeof(ChatCompletionOptions), typeof(CancellationToken))]
2222
[CodeGenSuppress("CompleteChatAsync", typeof(ChatCompletionOptions), typeof(CancellationToken))]
23-
[CodeGenSuppress("GetChatCompletionMessages", typeof(string), typeof(string), typeof(int?), typeof(OpenAI.VectorStores.VectorStoreCollectionOrder?), typeof(CancellationToken))]
24-
[CodeGenSuppress("GetChatCompletionMessagesAsync", typeof(string), typeof(string), typeof(int?), typeof(OpenAI.VectorStores.VectorStoreCollectionOrder?), typeof(CancellationToken))]
2523
[CodeGenSuppress("UpdateChatCompletion", typeof(string), typeof(IDictionary<string, string>), typeof(CancellationToken))]
2624
[CodeGenSuppress("UpdateChatCompletionAsync", typeof(string), typeof(IDictionary<string, string>), typeof(CancellationToken))]
2725
public partial class ChatClient
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
}

0 commit comments

Comments
 (0)