Skip to content

Commit 4923a94

Browse files
com.openai.unity 8.0.2 (#251)
- Fixed Thread.Message.Attachement serialization - Fixed CreateAssistantRequest to properly copy all override assistant properties - Fixed some objects that are chunked, were not properly being appended to the final object - Added FileSearchOptions to Tool.FileSearch - Added some additional constructor overloads for CodeInterpreterResources - Added some additional constructor overloads for VectorStoreRequest - Thread.DeleteAsync and Assistant.DeleteAsync now fetch the latest before deleting when deleteToolResources is also requested - Refactored the way Function handles reflected invocations for both synchronous and asynchronous calls - Function.InvokeAsync will now properly also call synchronous invocations in the tool call collection - Refactored Threads/Assistant Unit Tests
1 parent eff564c commit 4923a94

38 files changed

+750
-513
lines changed

OpenAI/Packages/com.openai.unity/Documentation~/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ The recommended installation method is though the unity package manager and [Ope
4848

4949
---
5050

51-
## Documentation
51+
## [Documentation](https://rageagainstthepixel.github.io/OpenAI-DotNet)
52+
53+
> Check out our new api docs!
54+
55+
<https://rageagainstthepixel.github.io/OpenAI-DotNet> :new:
5256

5357
### Table of Contents
5458

OpenAI/Packages/com.openai.unity/Runtime/Assistants/AssistantExtensions.cs

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,18 @@ public static class AssistantExtensions
2424
public static async Task<AssistantResponse> ModifyAsync(this AssistantResponse assistant, CreateAssistantRequest request, CancellationToken cancellationToken = default)
2525
=> await assistant.Client.AssistantsEndpoint.ModifyAssistantAsync(
2626
assistantId: assistant.Id,
27-
request: new CreateAssistantRequest(
28-
assistant: assistant,
29-
model: request.Model,
30-
name: request.Name,
31-
description: request.Description,
32-
instructions: request.Instructions,
33-
toolResources: request.ToolResources,
34-
tools: request.Tools,
35-
metadata: request.Metadata,
36-
temperature: request.Temperature,
37-
topP: request.TopP,
38-
responseFormat: request.ResponseFormat),
27+
request: request ?? new CreateAssistantRequest(assistant),
3928
cancellationToken: cancellationToken);
4029

30+
/// <summary>
31+
/// Get the latest status of the assistant.
32+
/// </summary>
33+
/// <param name="assistant"><see cref="AssistantResponse"/>.</param>
34+
/// <param name="cancellationToken">Optional, <see cref="CancellationToken"/>.</param>
35+
/// <returns><see cref="AssistantResponse"/>.</returns>
36+
public static async Task<AssistantResponse> UpdateAsync(this AssistantResponse assistant, CancellationToken cancellationToken = default)
37+
=> await assistant.Client.AssistantsEndpoint.RetrieveAssistantAsync(assistant, cancellationToken);
38+
4139
/// <summary>
4240
/// Delete the assistant.
4341
/// </summary>
@@ -47,6 +45,11 @@ public static async Task<AssistantResponse> ModifyAsync(this AssistantResponse a
4745
/// <returns>True, if the <see cref="assistant"/> was successfully deleted.</returns>
4846
public static async Task<bool> DeleteAsync(this AssistantResponse assistant, bool deleteToolResources = false, CancellationToken cancellationToken = default)
4947
{
48+
if (deleteToolResources)
49+
{
50+
assistant = await assistant.UpdateAsync(cancellationToken);
51+
}
52+
5053
var deleteTasks = new List<Task<bool>> { assistant.Client.AssistantsEndpoint.DeleteAssistantAsync(assistant.Id, cancellationToken) };
5154

5255
if (deleteToolResources && assistant.ToolResources?.FileSearch?.VectorStoreIds is { Count: > 0 })
@@ -80,15 +83,16 @@ public static async Task<RunResponse> CreateThreadAndRunAsync(this AssistantResp
8083
/// <param name="assistant"><see cref="AssistantResponse"/>.</param>
8184
/// <param name="toolCall"><see cref="ToolCall"/>.</param>
8285
/// <returns>Tool output result as <see cref="string"/>.</returns>
86+
/// <remarks>Only call this directly on your <see cref="ToolCall"/> if you know the method is synchronous.</remarks>
8387
public static string InvokeToolCall(this AssistantResponse assistant, ToolCall toolCall)
8488
{
85-
if (toolCall.Type != "function")
89+
if (!toolCall.IsFunction)
8690
{
8791
throw new InvalidOperationException($"Cannot invoke built in tool {toolCall.Type}");
8892
}
8993

90-
var tool = assistant.Tools.FirstOrDefault(tool => tool.Type == "function" && tool.Function.Name == toolCall.FunctionCall.Name) ??
91-
throw new InvalidOperationException($"Failed to find a valid tool for [{toolCall.Id}] {toolCall.Type}");
94+
var tool = assistant.Tools.FirstOrDefault(tool => tool.IsFunction && tool.Function.Name == toolCall.FunctionCall.Name) ??
95+
throw new InvalidOperationException($"Failed to find a valid tool for [{toolCall.Id}] {toolCall.FunctionCall.Name}");
9296
tool.Function.Arguments = toolCall.FunctionCall.Arguments;
9397
return tool.InvokeFunction();
9498
}
@@ -102,13 +106,13 @@ public static string InvokeToolCall(this AssistantResponse assistant, ToolCall t
102106
/// <returns>Tool output result as <see cref="string"/>.</returns>
103107
public static async Task<string> InvokeToolCallAsync(this AssistantResponse assistant, ToolCall toolCall, CancellationToken cancellationToken = default)
104108
{
105-
if (toolCall.Type != "function")
109+
if (!toolCall.IsFunction)
106110
{
107111
throw new InvalidOperationException($"Cannot invoke built in tool {toolCall.Type}");
108112
}
109113

110114
var tool = assistant.Tools.FirstOrDefault(tool => tool.Type == "function" && tool.Function.Name == toolCall.FunctionCall.Name) ??
111-
throw new InvalidOperationException($"Failed to find a valid tool for [{toolCall.Id}] {toolCall.Type}");
115+
throw new InvalidOperationException($"Failed to find a valid tool for [{toolCall.Id}] {toolCall.FunctionCall.Name}");
112116
tool.Function.Arguments = toolCall.FunctionCall.Arguments;
113117
return await tool.InvokeFunctionAsync(cancellationToken);
114118
}
@@ -119,6 +123,7 @@ public static async Task<string> InvokeToolCallAsync(this AssistantResponse assi
119123
/// <param name="assistant"><see cref="AssistantResponse"/>.</param>
120124
/// <param name="toolCall"><see cref="ToolCall"/>.</param>
121125
/// <returns><see cref="ToolOutput"/>.</returns>
126+
/// <remarks>Only call this directly on your <see cref="ToolCall"/> if you know the method is synchronous.</remarks>
122127
public static ToolOutput GetToolOutput(this AssistantResponse assistant, ToolCall toolCall)
123128
=> new(toolCall.Id, assistant.InvokeToolCall(toolCall));
124129

@@ -128,6 +133,7 @@ public static ToolOutput GetToolOutput(this AssistantResponse assistant, ToolCal
128133
/// <param name="assistant"><see cref="AssistantResponse"/>.</param>
129134
/// <param name="toolCalls">A collection of <see cref="ToolCall"/>s.</param>
130135
/// <returns>A collection of <see cref="ToolOutput"/>s.</returns>
136+
[Obsolete("Use GetToolOutputsAsync instead.")]
131137
public static IReadOnlyList<ToolOutput> GetToolOutputs(this AssistantResponse assistant, IEnumerable<ToolCall> toolCalls)
132138
=> toolCalls.Select(assistant.GetToolOutput).ToList();
133139

OpenAI/Packages/com.openai.unity/Runtime/Assistants/CreateAssistantRequest.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public CreateAssistantRequest(
8080
IReadOnlyDictionary<string, string> metadata = null,
8181
double? temperature = null,
8282
double? topP = null,
83-
ChatResponseFormat responseFormat = ChatResponseFormat.Auto)
83+
ChatResponseFormat? responseFormat = null)
8484
: this(
8585
string.IsNullOrWhiteSpace(model) ? assistant.Model : model,
8686
string.IsNullOrWhiteSpace(name) ? assistant.Name : name,
@@ -89,22 +89,22 @@ public CreateAssistantRequest(
8989
tools ?? assistant.Tools,
9090
toolResources ?? assistant.ToolResources,
9191
metadata ?? assistant.Metadata,
92-
temperature,
93-
topP,
94-
responseFormat)
92+
temperature ?? assistant.Temperature,
93+
topP ?? assistant.TopP,
94+
responseFormat ?? assistant.ResponseFormat)
9595
{
9696
}
9797

9898
[Obsolete("use new .ctr")]
9999
public CreateAssistantRequest(
100100
AssistantResponse assistant,
101-
string model = null,
102-
string name = null,
103-
string description = null,
104-
string instructions = null,
105-
IEnumerable<Tool> tools = null,
106-
IEnumerable<string> files = null,
107-
IReadOnlyDictionary<string, string> metadata = null)
101+
string model,
102+
string name,
103+
string description,
104+
string instructions,
105+
IEnumerable<Tool> tools,
106+
IEnumerable<string> files,
107+
IReadOnlyDictionary<string, string> metadata)
108108
{
109109
}
110110

OpenAI/Packages/com.openai.unity/Runtime/Batch/BatchExtensions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public static class BatchExtensions
1515
/// <param name="cancellationToken">Optional, <see cref="CancellationToken"/>.</param>
1616
/// <returns><see cref="BatchResponse"/>.</returns>
1717
public static async Task<BatchResponse> UpdateAsync(this BatchResponse batchResponse, CancellationToken cancellationToken = default)
18-
=> await batchResponse.Client.BatchEndpoint.RetrieveBatchAsync(batchResponse.Id, cancellationToken).ConfigureAwait(false);
18+
=> await batchResponse.Client.BatchEndpoint.RetrieveBatchAsync(batchResponse.Id, cancellationToken);
1919

2020
/// <summary>
2121
/// Waits for <see cref="BatchResponse.Status"/> to change.
@@ -34,9 +34,9 @@ public static async Task<BatchResponse> WaitForStatusChangeAsync(this BatchRespo
3434
BatchResponse result;
3535
do
3636
{
37-
await Task.Delay(pollingInterval ?? 500, chainedCts.Token).ConfigureAwait(false);
37+
await Task.Delay(pollingInterval ?? 500, chainedCts.Token).ConfigureAwait(true);
3838
cancellationToken.ThrowIfCancellationRequested();
39-
result = await batchResponse.UpdateAsync(cancellationToken: chainedCts.Token).ConfigureAwait(false);
39+
result = await batchResponse.UpdateAsync(cancellationToken: chainedCts.Token);
4040
} while (result.Status is BatchStatus.NotStarted or BatchStatus.InProgress or BatchStatus.Cancelling);
4141
return result;
4242
}

OpenAI/Packages/com.openai.unity/Runtime/Batch/BatchResponse.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ internal BatchResponse(
7373
public string Endpoint { get; }
7474

7575
/// <summary>
76-
/// Errors that occured during the batch job.
76+
/// Errors that occurred during the batch job.
7777
/// </summary>
7878
[Preserve]
7979
[JsonProperty("errors")]
@@ -202,6 +202,7 @@ public DateTime? FailedAt
202202
[JsonProperty("expired_at")]
203203
public int? ExpiredAtUnixTimeSeconds { get; }
204204

205+
[Preserve]
205206
[JsonIgnore]
206207
public DateTime? ExpiredAt
207208
=> ExpiredAtUnixTimeSeconds.HasValue
@@ -215,6 +216,7 @@ public DateTime? ExpiredAt
215216
[JsonProperty("cancelled_at")]
216217
public int? CancelledAtUnixTimeSeconds { get; }
217218

219+
[Preserve]
218220
[JsonIgnore]
219221
public DateTime? CancelledAt
220222
=> CancelledAtUnixTimeSeconds.HasValue
@@ -237,8 +239,10 @@ public DateTime? CancelledAt
237239
[JsonProperty("metadata")]
238240
public IReadOnlyDictionary<string, object> Metadata { get; }
239241

242+
[Preserve]
240243
public override string ToString() => Id;
241244

245+
[Preserve]
242246
public static implicit operator string(BatchResponse response) => response?.ToString();
243247
}
244248
}

OpenAI/Packages/com.openai.unity/Runtime/Batch/CreateBatchRequest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public sealed class CreateBatchRequest
1212
private const string DefaultCompletionWindow = "24h";
1313

1414
/// <summary>
15-
///
15+
/// Constructor.
1616
/// </summary>
1717
/// <param name="inputFileId">
1818
/// The ID of an uploaded file that contains requests for the new batch.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
11
// Licensed under the MIT License. See LICENSE in the project root for license information.
22

3+
using UnityEngine.Scripting;
4+
35
namespace OpenAI.Batch
46
{
7+
[Preserve]
58
public sealed class Endpoint
69
{
710
public const string ChatCompletions = "/v1/chat/completions";
811
public const string Embeddings = "/v1/embeddings";
912
public const string Completions = "/v1/completions";
1013

14+
[Preserve]
1115
public Endpoint(string endpoint) => Value = endpoint;
1216

17+
[Preserve]
1318
public string Value { get; }
1419

20+
[Preserve]
1521
public override string ToString() => Value;
1622

23+
[Preserve]
1724
public static implicit operator string(Endpoint endpoint) => endpoint?.ToString();
1825

26+
[Preserve]
1927
public static implicit operator Endpoint(string endpoint) => new(endpoint);
2028
}
2129
}

OpenAI/Packages/com.openai.unity/Runtime/Chat/Choice.cs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ public Choice() { }
1616
/// A chat completion message generated by the model.
1717
/// </summary>
1818
[Preserve]
19-
[JsonProperty("message")]
19+
[JsonProperty("message", DefaultValueHandling = DefaultValueHandling.Ignore)]
2020
public Message Message { get; private set; }
2121

2222
/// <summary>
2323
/// A chat completion delta generated by streamed model responses.
2424
/// </summary>
2525
[Preserve]
26-
[JsonProperty("delta")]
26+
[JsonProperty("delta", DefaultValueHandling = DefaultValueHandling.Ignore)]
2727
public Delta Delta { get; private set; }
2828

2929
/// <summary>
@@ -34,25 +34,25 @@ public Choice() { }
3434
/// tool_calls if the model called a tool, or function_call (deprecated) if the model called a function.
3535
/// </summary>
3636
[Preserve]
37-
[JsonProperty("finish_reason")]
37+
[JsonProperty("finish_reason", DefaultValueHandling = DefaultValueHandling.Ignore)]
3838
public string FinishReason { get; private set; }
3939

4040
[Preserve]
41-
[JsonProperty("finish_details")]
41+
[JsonProperty("finish_details", DefaultValueHandling = DefaultValueHandling.Ignore)]
4242
public FinishDetails FinishDetails { get; private set; }
4343

4444
/// <summary>
4545
/// The index of the choice in the list of choices.
4646
/// </summary>
4747
[Preserve]
48-
[JsonProperty("index")]
48+
[JsonProperty("index", DefaultValueHandling = DefaultValueHandling.Ignore)]
4949
public int? Index { get; private set; }
5050

5151
/// <summary>
5252
/// Log probability information for the choice.
5353
/// </summary>
5454
[Preserve]
55-
[JsonProperty("logprobs")]
55+
[JsonProperty("logprobs", DefaultValueHandling = DefaultValueHandling.Ignore)]
5656
public LogProbs LogProbs { get; private set; }
5757

5858
[Preserve]
@@ -64,14 +64,19 @@ public Choice() { }
6464
[Preserve]
6565
public void AppendFrom(Choice other)
6666
{
67-
Index = other?.Index ?? 0;
67+
if (other == null) { return; }
6868

69-
if (other?.Message != null)
69+
if (other.Index.HasValue)
70+
{
71+
Index = other.Index.Value;
72+
}
73+
74+
if (other.Message != null)
7075
{
7176
Message = other.Message;
7277
}
7378

74-
if (other?.Delta != null)
79+
if (other.Delta != null)
7580
{
7681
if (Message == null)
7782
{
@@ -83,17 +88,17 @@ public void AppendFrom(Choice other)
8388
}
8489
}
8590

86-
if (other?.LogProbs != null)
91+
if (other.LogProbs != null)
8792
{
8893
LogProbs = other.LogProbs;
8994
}
9095

91-
if (!string.IsNullOrWhiteSpace(other?.FinishReason))
96+
if (!string.IsNullOrWhiteSpace(other.FinishReason))
9297
{
9398
FinishReason = other.FinishReason;
9499
}
95100

96-
if (other?.FinishDetails != null)
101+
if (other.FinishDetails != null)
97102
{
98103
FinishDetails = other.FinishDetails;
99104
}

OpenAI/Packages/com.openai.unity/Runtime/Common/Annotation.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ internal Annotation(
3333
}
3434

3535
[Preserve]
36-
[JsonProperty("index")]
36+
[JsonProperty("index", DefaultValueHandling = DefaultValueHandling.Ignore)]
3737
public int? Index { get; private set; }
3838

3939
[Preserve]
@@ -53,14 +53,14 @@ internal Annotation(
5353
/// Generated when the assistant uses the 'retrieval' tool to search files.
5454
/// </summary>
5555
[Preserve]
56-
[JsonProperty("file_citation")]
56+
[JsonProperty("file_citation", DefaultValueHandling = DefaultValueHandling.Ignore)]
5757
public FileCitation FileCitation { get; private set; }
5858

5959
/// <summary>
6060
/// A URL for the file that's generated when the assistant used the 'code_interpreter' tool to generate a file.
6161
/// </summary>
6262
[Preserve]
63-
[JsonProperty("file_path")]
63+
[JsonProperty("file_path", DefaultValueHandling = DefaultValueHandling.Ignore)]
6464
public FilePath FilePath { get; private set; }
6565

6666
[Preserve]
@@ -75,6 +75,11 @@ public void AppendFrom(Annotation other)
7575
{
7676
if (other == null) { return; }
7777

78+
if (other.Index.HasValue)
79+
{
80+
Index = other.Index.Value;
81+
}
82+
7883
if (!string.IsNullOrWhiteSpace(other.Text))
7984
{
8085
Text += other.Text;

0 commit comments

Comments
 (0)