Skip to content

Commit 7a28178

Browse files
authored
Add UpdateChatCompletion method in ChatClient (#576)
This PR adds both protocol and convenience methods for `UpdateChatCompletion` in `ChatClient` to support updating the metadata of a previously stored chat completion.
1 parent 45f9ea5 commit 7a28178

File tree

9 files changed

+369
-63
lines changed

9 files changed

+369
-63
lines changed

api/OpenAI.net8.0.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,14 @@ public class ChatClient {
14661466
public virtual AsyncCollectionResult<ChatCompletion> GetChatCompletionsAsync(ChatCompletionCollectionOptions options = null, CancellationToken cancellationToken = default);
14671467
[Experimental("OPENAI001")]
14681468
public virtual AsyncCollectionResult GetChatCompletionsAsync(string after, int? limit, string order, IDictionary<string, string> metadata, string model, RequestOptions options);
1469+
[Experimental("OPENAI001")]
1470+
public virtual ClientResult UpdateChatCompletion(string completionId, BinaryContent content, RequestOptions options = null);
1471+
[Experimental("OPENAI001")]
1472+
public virtual ClientResult<ChatCompletion> UpdateChatCompletion(string completionId, IDictionary<string, string> metadata, CancellationToken cancellationToken = default);
1473+
[Experimental("OPENAI001")]
1474+
public virtual Task<ClientResult> UpdateChatCompletionAsync(string completionId, BinaryContent content, RequestOptions options = null);
1475+
[Experimental("OPENAI001")]
1476+
public virtual Task<ClientResult<ChatCompletion>> UpdateChatCompletionAsync(string completionId, IDictionary<string, string> metadata, CancellationToken cancellationToken = default);
14691477
}
14701478
public class ChatCompletion : IJsonModel<ChatCompletion>, IPersistableModel<ChatCompletion> {
14711479
[Experimental("OPENAI001")]
@@ -1534,19 +1542,34 @@ public class ChatCompletionDeletionResult : IJsonModel<ChatCompletionDeletionRes
15341542
[Experimental("OPENAI001")]
15351543
public class ChatCompletionMessageCollectionOptions : IJsonModel<ChatCompletionMessageCollectionOptions>, IPersistableModel<ChatCompletionMessageCollectionOptions> {
15361544
public string AfterId { get; set; }
1537-
public ChatCompletionCollectionOrder? Order { get; set; }
1545+
public ChatCompletionMessageCollectionOrder? Order { get; set; }
15381546
public int? PageSizeLimit { get; set; }
15391547
protected virtual ChatCompletionMessageCollectionOptions JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options);
15401548
protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options);
15411549
protected virtual ChatCompletionMessageCollectionOptions PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
15421550
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
15431551
}
15441552
[Experimental("OPENAI001")]
1553+
public readonly partial struct ChatCompletionMessageCollectionOrder : IEquatable<ChatCompletionMessageCollectionOrder> {
1554+
public ChatCompletionMessageCollectionOrder(string value);
1555+
public static ChatCompletionMessageCollectionOrder Ascending { get; }
1556+
public static ChatCompletionMessageCollectionOrder Descending { get; }
1557+
public readonly bool Equals(ChatCompletionMessageCollectionOrder other);
1558+
[EditorBrowsable(EditorBrowsableState.Never)]
1559+
public override readonly bool Equals(object obj);
1560+
[EditorBrowsable(EditorBrowsableState.Never)]
1561+
public override readonly int GetHashCode();
1562+
public static bool operator ==(ChatCompletionMessageCollectionOrder left, ChatCompletionMessageCollectionOrder right);
1563+
public static implicit operator ChatCompletionMessageCollectionOrder(string value);
1564+
public static bool operator !=(ChatCompletionMessageCollectionOrder left, ChatCompletionMessageCollectionOrder right);
1565+
public override readonly string ToString();
1566+
}
1567+
[Experimental("OPENAI001")]
15451568
public class ChatCompletionMessageListDatum : IJsonModel<ChatCompletionMessageListDatum>, IPersistableModel<ChatCompletionMessageListDatum> {
1546-
public IList<ChatMessageAnnotation> Annotations { get; }
1547-
public ChatOutputAudio Audio { get; }
1569+
public IReadOnlyList<ChatMessageAnnotation> Annotations { get; }
15481570
public string Content { get; }
15491571
public string Id { get; }
1572+
public ChatOutputAudio OutputAudio { get; }
15501573
public string Refusal { get; }
15511574
public IReadOnlyList<ChatToolCall> ToolCalls { get; }
15521575
protected virtual ChatCompletionMessageListDatum JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options);

api/OpenAI.netstandard2.0.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,6 +1305,10 @@ public class ChatClient {
13051305
public virtual CollectionResult GetChatCompletions(string after, int? limit, string order, IDictionary<string, string> metadata, string model, RequestOptions options);
13061306
public virtual AsyncCollectionResult<ChatCompletion> GetChatCompletionsAsync(ChatCompletionCollectionOptions options = null, CancellationToken cancellationToken = default);
13071307
public virtual AsyncCollectionResult GetChatCompletionsAsync(string after, int? limit, string order, IDictionary<string, string> metadata, string model, RequestOptions options);
1308+
public virtual ClientResult UpdateChatCompletion(string completionId, BinaryContent content, RequestOptions options = null);
1309+
public virtual ClientResult<ChatCompletion> UpdateChatCompletion(string completionId, IDictionary<string, string> metadata, CancellationToken cancellationToken = default);
1310+
public virtual Task<ClientResult> UpdateChatCompletionAsync(string completionId, BinaryContent content, RequestOptions options = null);
1311+
public virtual Task<ClientResult<ChatCompletion>> UpdateChatCompletionAsync(string completionId, IDictionary<string, string> metadata, CancellationToken cancellationToken = default);
13081312
}
13091313
public class ChatCompletion : IJsonModel<ChatCompletion>, IPersistableModel<ChatCompletion> {
13101314
public IReadOnlyList<ChatMessageAnnotation> Annotations { get; }
@@ -1363,18 +1367,32 @@ public class ChatCompletionDeletionResult : IJsonModel<ChatCompletionDeletionRes
13631367
}
13641368
public class ChatCompletionMessageCollectionOptions : IJsonModel<ChatCompletionMessageCollectionOptions>, IPersistableModel<ChatCompletionMessageCollectionOptions> {
13651369
public string AfterId { get; set; }
1366-
public ChatCompletionCollectionOrder? Order { get; set; }
1370+
public ChatCompletionMessageCollectionOrder? Order { get; set; }
13671371
public int? PageSizeLimit { get; set; }
13681372
protected virtual ChatCompletionMessageCollectionOptions JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options);
13691373
protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options);
13701374
protected virtual ChatCompletionMessageCollectionOptions PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
13711375
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
13721376
}
1377+
public readonly partial struct ChatCompletionMessageCollectionOrder : IEquatable<ChatCompletionMessageCollectionOrder> {
1378+
public ChatCompletionMessageCollectionOrder(string value);
1379+
public static ChatCompletionMessageCollectionOrder Ascending { get; }
1380+
public static ChatCompletionMessageCollectionOrder Descending { get; }
1381+
public readonly bool Equals(ChatCompletionMessageCollectionOrder other);
1382+
[EditorBrowsable(EditorBrowsableState.Never)]
1383+
public override readonly bool Equals(object obj);
1384+
[EditorBrowsable(EditorBrowsableState.Never)]
1385+
public override readonly int GetHashCode();
1386+
public static bool operator ==(ChatCompletionMessageCollectionOrder left, ChatCompletionMessageCollectionOrder right);
1387+
public static implicit operator ChatCompletionMessageCollectionOrder(string value);
1388+
public static bool operator !=(ChatCompletionMessageCollectionOrder left, ChatCompletionMessageCollectionOrder right);
1389+
public override readonly string ToString();
1390+
}
13731391
public class ChatCompletionMessageListDatum : IJsonModel<ChatCompletionMessageListDatum>, IPersistableModel<ChatCompletionMessageListDatum> {
1374-
public IList<ChatMessageAnnotation> Annotations { get; }
1375-
public ChatOutputAudio Audio { get; }
1392+
public IReadOnlyList<ChatMessageAnnotation> Annotations { get; }
13761393
public string Content { get; }
13771394
public string Id { get; }
1395+
public ChatOutputAudio OutputAudio { get; }
13781396
public string Refusal { get; }
13791397
public IReadOnlyList<ChatToolCall> ToolCalls { get; }
13801398
protected virtual ChatCompletionMessageListDatum JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options);

src/Custom/Chat/ChatClient.Protocol.cs

Lines changed: 0 additions & 53 deletions
This file was deleted.

src/Custom/Chat/ChatClient.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using OpenAI.Evals;
21
using OpenAI.Telemetry;
32
using System;
43
using System.ClientModel;
@@ -20,8 +19,6 @@ namespace OpenAI.Chat;
2019
[CodeGenSuppress("ChatClient", typeof(ClientPipeline), typeof(Uri))]
2120
[CodeGenSuppress("CompleteChat", typeof(ChatCompletionOptions), typeof(CancellationToken))]
2221
[CodeGenSuppress("CompleteChatAsync", typeof(ChatCompletionOptions), typeof(CancellationToken))]
23-
[CodeGenSuppress("UpdateChatCompletion", typeof(string), typeof(IDictionary<string, string>), typeof(CancellationToken))]
24-
[CodeGenSuppress("UpdateChatCompletionAsync", typeof(string), typeof(IDictionary<string, string>), typeof(CancellationToken))]
2522
public partial class ChatClient
2623
{
2724
private readonly string _model;
@@ -307,6 +304,32 @@ public virtual ClientResult<ChatCompletion> GetChatCompletion(string completionI
307304
return ClientResult.FromValue(ChatCompletion.FromClientResult(result), result.GetRawResponse());
308305
}
309306

307+
// CUSTOM:
308+
// - Call FromClientResult.
309+
[Experimental("OPENAI001")]
310+
public virtual ClientResult<ChatCompletion> UpdateChatCompletion(string completionId, IDictionary<string, string> metadata, CancellationToken cancellationToken = default)
311+
{
312+
Argument.AssertNotNullOrEmpty(completionId, nameof(completionId));
313+
Argument.AssertNotNull(metadata, nameof(metadata));
314+
315+
InternalUpdateChatCompletionRequest spreadModel = new InternalUpdateChatCompletionRequest(metadata, null);
316+
ClientResult result = this.UpdateChatCompletion(completionId, spreadModel, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null);
317+
return ClientResult.FromValue(ChatCompletion.FromClientResult(result), result.GetRawResponse());
318+
}
319+
320+
// CUSTOM:
321+
// - Call FromClientResult.
322+
[Experimental("OPENAI001")]
323+
public virtual async Task<ClientResult<ChatCompletion>> UpdateChatCompletionAsync(string completionId, IDictionary<string, string> metadata, CancellationToken cancellationToken = default)
324+
{
325+
Argument.AssertNotNullOrEmpty(completionId, nameof(completionId));
326+
Argument.AssertNotNull(metadata, nameof(metadata));
327+
328+
InternalUpdateChatCompletionRequest spreadModel = new InternalUpdateChatCompletionRequest(metadata, null);
329+
ClientResult result = await this.UpdateChatCompletionAsync(completionId, spreadModel, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false);
330+
return ClientResult.FromValue(ChatCompletion.FromClientResult(result), result.GetRawResponse());
331+
}
332+
310333
// CUSTOM:
311334
// - Added Experimental attribute.
312335
// - Call FromClientResult.

src/Custom/Chat/Internal/GeneratorStubs.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Runtime.InteropServices;
1+
using System.ClientModel;
22

33
namespace OpenAI.Chat;
44

@@ -50,6 +50,19 @@ internal partial class InternalChatCompletionRequestMessageContentPartRefusal {
5050
[CodeGenType("CreateChatCompletionRequestModel")]
5151
internal readonly partial struct InternalCreateChatCompletionRequestModel { }
5252

53+
[CodeGenType("UpdateChatCompletionRequest")]
54+
internal partial class InternalUpdateChatCompletionRequest
55+
{
56+
public static implicit operator BinaryContent(InternalUpdateChatCompletionRequest internalUpdateChatCompletionRequest)
57+
{
58+
if (internalUpdateChatCompletionRequest == null)
59+
{
60+
return null;
61+
}
62+
return BinaryContent.Create(internalUpdateChatCompletionRequest, ModelSerializationExtensions.WireOptions);
63+
}
64+
}
65+
5366
[CodeGenType("CreateChatCompletionRequestToolChoice")]
5467
internal readonly partial struct InternalCreateChatCompletionRequestToolChoice { }
5568

src/Generated/ChatClient.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,62 @@ public virtual async Task<ClientResult> CompleteChatAsync(BinaryContent content,
9191
return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false));
9292
}
9393

94+
[Experimental("OPENAI001")]
95+
public virtual ClientResult GetChatCompletion(string completionId, RequestOptions options)
96+
{
97+
Argument.AssertNotNullOrEmpty(completionId, nameof(completionId));
98+
99+
using PipelineMessage message = CreateGetChatCompletionRequest(completionId, options);
100+
return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options));
101+
}
102+
103+
[Experimental("OPENAI001")]
104+
public virtual async Task<ClientResult> GetChatCompletionAsync(string completionId, RequestOptions options)
105+
{
106+
Argument.AssertNotNullOrEmpty(completionId, nameof(completionId));
107+
108+
using PipelineMessage message = CreateGetChatCompletionRequest(completionId, options);
109+
return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false));
110+
}
111+
112+
[Experimental("OPENAI001")]
113+
public virtual ClientResult UpdateChatCompletion(string completionId, BinaryContent content, RequestOptions options = null)
114+
{
115+
Argument.AssertNotNullOrEmpty(completionId, nameof(completionId));
116+
Argument.AssertNotNull(content, nameof(content));
117+
118+
using PipelineMessage message = CreateUpdateChatCompletionRequest(completionId, content, options);
119+
return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options));
120+
}
121+
122+
[Experimental("OPENAI001")]
123+
public virtual async Task<ClientResult> UpdateChatCompletionAsync(string completionId, BinaryContent content, RequestOptions options = null)
124+
{
125+
Argument.AssertNotNullOrEmpty(completionId, nameof(completionId));
126+
Argument.AssertNotNull(content, nameof(content));
127+
128+
using PipelineMessage message = CreateUpdateChatCompletionRequest(completionId, content, options);
129+
return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false));
130+
}
131+
132+
[Experimental("OPENAI001")]
133+
public virtual ClientResult DeleteChatCompletion(string completionId, RequestOptions options)
134+
{
135+
Argument.AssertNotNullOrEmpty(completionId, nameof(completionId));
136+
137+
using PipelineMessage message = CreateDeleteChatCompletionRequest(completionId, options);
138+
return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options));
139+
}
140+
141+
[Experimental("OPENAI001")]
142+
public virtual async Task<ClientResult> DeleteChatCompletionAsync(string completionId, RequestOptions options)
143+
{
144+
Argument.AssertNotNullOrEmpty(completionId, nameof(completionId));
145+
146+
using PipelineMessage message = CreateDeleteChatCompletionRequest(completionId, options);
147+
return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false));
148+
}
149+
94150
[Experimental("OPENAI001")]
95151
public virtual CollectionResult GetChatCompletionMessages(string completionId, string after, int? limit, string order, RequestOptions options)
96152
{

0 commit comments

Comments
 (0)