Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update /ai/extract_structured response schema (box/box-openapi#505) #390

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .codegen.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{ "engineHash": "cf82faa", "specHash": "3dc3f1e", "version": "1.6.0" }
{ "engineHash": "cf82faa", "specHash": "1fdcbef", "version": "1.6.0" }
4 changes: 2 additions & 2 deletions Box.Sdk.Gen.Tests.Integration/Test/Ai/AiManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public async System.Threading.Tasks.Task TestAiExtractStructuredWithFields() {
Files uploadedFiles = await client.Uploads.UploadFileAsync(requestBody: new UploadFileRequestBody(attributes: new UploadFileRequestBodyAttributesField(name: string.Concat(Utils.GetUUID(), ".txt"), parent: new UploadFileRequestBodyAttributesParentField(id: "0")), file: Utils.StringToByteStream(text: "My name is John Doe. I was born in 4th July 1990. I am 34 years old. My hobby is guitar.")));
FileFull file = NullableUtils.Unwrap(uploadedFiles.Entries)[0];
await Utils.DelayInSecondsAsync(seconds: 5);
AiExtractResponse response = await client.Ai.CreateAiExtractStructuredAsync(requestBody: new AiExtractStructured(items: Array.AsReadOnly(new [] {new AiItemBase(id: file.Id)})) { Fields = Array.AsReadOnly(new [] {new AiExtractStructuredFieldsField(key: "firstName") { DisplayName = "First name", Description = "Person first name", Prompt = "What is the your first name?", Type = "string" },new AiExtractStructuredFieldsField(key: "lastName") { DisplayName = "Last name", Description = "Person last name", Prompt = "What is the your last name?", Type = "string" },new AiExtractStructuredFieldsField(key: "dateOfBirth") { DisplayName = "Birth date", Description = "Person date of birth", Prompt = "What is the date of your birth?", Type = "date" },new AiExtractStructuredFieldsField(key: "age") { DisplayName = "Age", Description = "Person age", Prompt = "How old are you?", Type = "float" },new AiExtractStructuredFieldsField(key: "hobby") { DisplayName = "Hobby", Description = "Person hobby", Prompt = "What is your hobby?", Type = "multiSelect", Options = Array.AsReadOnly(new [] {new AiExtractStructuredFieldsOptionsField(key: "guitar"),new AiExtractStructuredFieldsOptionsField(key: "books")}) }}) });
AiExtractStructuredResponse response = await client.Ai.CreateAiExtractStructuredAsync(requestBody: new AiExtractStructured(items: Array.AsReadOnly(new [] {new AiItemBase(id: file.Id)})) { Fields = Array.AsReadOnly(new [] {new AiExtractStructuredFieldsField(key: "firstName") { DisplayName = "First name", Description = "Person first name", Prompt = "What is the your first name?", Type = "string" },new AiExtractStructuredFieldsField(key: "lastName") { DisplayName = "Last name", Description = "Person last name", Prompt = "What is the your last name?", Type = "string" },new AiExtractStructuredFieldsField(key: "dateOfBirth") { DisplayName = "Birth date", Description = "Person date of birth", Prompt = "What is the date of your birth?", Type = "date" },new AiExtractStructuredFieldsField(key: "age") { DisplayName = "Age", Description = "Person age", Prompt = "How old are you?", Type = "float" },new AiExtractStructuredFieldsField(key: "hobby") { DisplayName = "Hobby", Description = "Person hobby", Prompt = "What is your hobby?", Type = "multiSelect", Options = Array.AsReadOnly(new [] {new AiExtractStructuredFieldsOptionsField(key: "guitar"),new AiExtractStructuredFieldsOptionsField(key: "books")}) }}) });
Assert.IsTrue(StringUtils.ToStringRepresentation(Utils.GetValueFromObjectRawData(obj: response, key: "firstName")) == "John");
Assert.IsTrue(StringUtils.ToStringRepresentation(Utils.GetValueFromObjectRawData(obj: response, key: "lastName")) == "Doe");
Assert.IsTrue(StringUtils.ToStringRepresentation(Utils.GetValueFromObjectRawData(obj: response, key: "dateOfBirth")) == "1990-07-04");
Expand All @@ -87,7 +87,7 @@ public async System.Threading.Tasks.Task TestAiExtractStructuredWithMetadataTemp
await Utils.DelayInSecondsAsync(seconds: 5);
string templateKey = string.Concat("key", Utils.GetUUID());
MetadataTemplate template = await client.MetadataTemplates.CreateMetadataTemplateAsync(requestBody: new CreateMetadataTemplateRequestBody(scope: "enterprise", displayName: templateKey) { TemplateKey = templateKey, Fields = Array.AsReadOnly(new [] {new CreateMetadataTemplateRequestBodyFieldsField(key: "firstName", displayName: "First name", type: CreateMetadataTemplateRequestBodyFieldsTypeField.String) { Description = "Person first name" },new CreateMetadataTemplateRequestBodyFieldsField(key: "lastName", displayName: "Last name", type: CreateMetadataTemplateRequestBodyFieldsTypeField.String) { Description = "Person last name" },new CreateMetadataTemplateRequestBodyFieldsField(key: "dateOfBirth", displayName: "Birth date", type: CreateMetadataTemplateRequestBodyFieldsTypeField.Date) { Description = "Person date of birth" },new CreateMetadataTemplateRequestBodyFieldsField(key: "age", displayName: "Age", type: CreateMetadataTemplateRequestBodyFieldsTypeField.Float) { Description = "Person age" },new CreateMetadataTemplateRequestBodyFieldsField(key: "hobby", displayName: "Hobby", type: CreateMetadataTemplateRequestBodyFieldsTypeField.MultiSelect) { Description = "Person hobby", Options = Array.AsReadOnly(new [] {new CreateMetadataTemplateRequestBodyFieldsOptionsField(key: "guitar"),new CreateMetadataTemplateRequestBodyFieldsOptionsField(key: "books")}) }}) });
AiExtractResponse response = await client.Ai.CreateAiExtractStructuredAsync(requestBody: new AiExtractStructured(items: Array.AsReadOnly(new [] {new AiItemBase(id: file.Id)})) { MetadataTemplate = new AiExtractStructuredMetadataTemplateField() { TemplateKey = templateKey, Scope = "enterprise" } });
AiExtractStructuredResponse response = await client.Ai.CreateAiExtractStructuredAsync(requestBody: new AiExtractStructured(items: Array.AsReadOnly(new [] {new AiItemBase(id: file.Id)})) { MetadataTemplate = new AiExtractStructuredMetadataTemplateField() { TemplateKey = templateKey, Scope = "enterprise" } });
Assert.IsTrue(StringUtils.ToStringRepresentation(Utils.GetValueFromObjectRawData(obj: response, key: "firstName")) == "John");
Assert.IsTrue(StringUtils.ToStringRepresentation(Utils.GetValueFromObjectRawData(obj: response, key: "lastName")) == "Doe");
Assert.IsTrue(StringUtils.ToStringRepresentation(Utils.GetValueFromObjectRawData(obj: response, key: "dateOfBirth")) == "1990-07-04T00:00:00Z");
Expand Down
4 changes: 2 additions & 2 deletions Box.Sdk.Gen/Managers/Ai/AiManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,11 @@ public async System.Threading.Tasks.Task<AiResponse> CreateAiExtractAsync(AiExtr
/// <param name="cancellationToken">
/// Token used for request cancellation.
/// </param>
public async System.Threading.Tasks.Task<AiExtractResponse> CreateAiExtractStructuredAsync(AiExtractStructured requestBody, CreateAiExtractStructuredHeaders? headers = default, System.Threading.CancellationToken? cancellationToken = null) {
public async System.Threading.Tasks.Task<AiExtractStructuredResponse> CreateAiExtractStructuredAsync(AiExtractStructured requestBody, CreateAiExtractStructuredHeaders? headers = default, System.Threading.CancellationToken? cancellationToken = null) {
headers = headers ?? new CreateAiExtractStructuredHeaders();
Dictionary<string, string> headersMap = Utils.PrepareParams(map: DictionaryUtils.MergeDictionaries(new Dictionary<string, string?>() { }, headers.ExtraHeaders));
FetchResponse response = await this.NetworkSession.NetworkClient.FetchAsync(options: new FetchOptions(url: string.Concat(this.NetworkSession.BaseUrls.BaseUrl, "/2.0/ai/extract_structured"), method: "POST", contentType: "application/json", responseFormat: Box.Sdk.Gen.ResponseFormat.Json) { Headers = headersMap, Data = SimpleJsonSerializer.Serialize(requestBody), Auth = this.Auth, NetworkSession = this.NetworkSession, CancellationToken = cancellationToken }).ConfigureAwait(false);
return SimpleJsonSerializer.Deserialize<AiExtractResponse>(NullableUtils.Unwrap(response.Data));
return SimpleJsonSerializer.Deserialize<AiExtractStructuredResponse>(NullableUtils.Unwrap(response.Data));
}

}
Expand Down
2 changes: 1 addition & 1 deletion Box.Sdk.Gen/Managers/Ai/IAiManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public interface IAiManager {
/// <param name="cancellationToken">
/// Token used for request cancellation.
/// </param>
public System.Threading.Tasks.Task<AiExtractResponse> CreateAiExtractStructuredAsync(AiExtractStructured requestBody, CreateAiExtractStructuredHeaders? headers = default, System.Threading.CancellationToken? cancellationToken = null) => throw new System.NotImplementedException("This method needs to be implemented by the derived class before calling it.");
public System.Threading.Tasks.Task<AiExtractStructuredResponse> CreateAiExtractStructuredAsync(AiExtractStructured requestBody, CreateAiExtractStructuredHeaders? headers = default, System.Threading.CancellationToken? cancellationToken = null) => throw new System.NotImplementedException("This method needs to be implemented by the derived class before calling it.");

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Box.Sdk.Gen;
using System.Text.Json.Serialization;
using System.Collections.Generic;
using Box.Sdk.Gen.Internal;
using Box.Sdk.Gen.Schemas;

namespace Box.Sdk.Gen.Schemas {
public class AiExtractStructuredResponse : ISerializable {
[JsonPropertyName("answer")]
public AiExtractResponse Answer { get; }

/// <summary>
/// The ISO date formatted timestamp of when the answer to the prompt was created.
/// </summary>
[JsonPropertyName("created_at")]
public System.DateTimeOffset CreatedAt { get; }

/// <summary>
/// The reason the response finishes.
/// </summary>
[JsonPropertyName("completion_reason")]
public string? CompletionReason { get; init; }

[JsonPropertyName("ai_agent_info")]
public AiAgentInfo? AiAgentInfo { get; init; }

public AiExtractStructuredResponse(AiExtractResponse answer, System.DateTimeOffset createdAt) {
Answer = answer;
CreatedAt = createdAt;
}
internal string? RawJson { get; set; } = default;

void ISerializable.SetJson(string json) {
RawJson = json;
}

string? ISerializable.GetJson() {
return RawJson;
}

/// <summary>
/// Returns raw json response returned from the API.
/// </summary>
public Dictionary<string, object?>? GetRawData() {
return SimpleJsonSerializer.GetAllFields(this);
}

}
}
2 changes: 1 addition & 1 deletion docs/Ai.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ await client.Ai.CreateAiExtractStructuredAsync(requestBody: new AiExtractStructu

### Returns

This function returns a value of type `AiExtractResponse`.
This function returns a value of type `AiExtractStructuredResponse`.

A successful response including the answer from the LLM.

Expand Down
Loading