Skip to content

Commit

Permalink
feat: add parameters to box ai ask and text gen (box/box-openapi#445)
Browse files Browse the repository at this point in the history
  • Loading branch information
box-sdk-build committed Aug 20, 2024
1 parent ad3e599 commit fcd712a
Show file tree
Hide file tree
Showing 13 changed files with 123 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .codegen.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{ "engineHash": "4ca165c", "specHash": "9919482", "version": "1.0.0" }
{ "engineHash": "4ca165c", "specHash": "871a814", "version": "1.0.0" }
6 changes: 3 additions & 3 deletions Box.Sdk.Gen.Tests.Integration/Test/Ai/AiManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public AiManagerTests() {
[TestMethod]
public async System.Threading.Tasks.Task TestAskAiSingleItem() {
FileFull fileToAsk = await new CommonsManager().UploadNewFileAsync();
AiResponse response = await client.Ai.CreateAiAskAsync(requestBody: new AiAsk(mode: AiAskModeField.SingleItemQa, prompt: "which direction sun rises", items: Array.AsReadOnly(new [] {new AiAskItemsField(id: fileToAsk.Id, type: AiAskItemsTypeField.File) { Content = "Sun rises in the East" }})));
AiAskResponse response = await client.Ai.CreateAiAskAsync(requestBody: new AiAsk(mode: AiAskModeField.SingleItemQa, prompt: "which direction sun rises", items: Array.AsReadOnly(new [] {new AiAskItemsField(id: fileToAsk.Id, type: AiAskItemsTypeField.File) { Content = "Sun rises in the East" }})));
Assert.IsTrue(response.Answer.Contains("East"));
Assert.IsTrue(response.CompletionReason == "done");
await client.Files.DeleteFileByIdAsync(fileId: fileToAsk.Id);
Expand All @@ -28,7 +28,7 @@ public async System.Threading.Tasks.Task TestAskAiSingleItem() {
public async System.Threading.Tasks.Task TestAskAiMultipleItems() {
FileFull fileToAsk1 = await new CommonsManager().UploadNewFileAsync();
FileFull fileToAsk2 = await new CommonsManager().UploadNewFileAsync();
AiResponse response = await client.Ai.CreateAiAskAsync(requestBody: new AiAsk(mode: AiAskModeField.MultipleItemQa, prompt: "Which direction sun rises?", items: Array.AsReadOnly(new [] {new AiAskItemsField(id: fileToAsk1.Id, type: AiAskItemsTypeField.File) { Content = "Earth goes around the sun" },new AiAskItemsField(id: fileToAsk2.Id, type: AiAskItemsTypeField.File) { Content = "Sun rises in the East in the morning" }})));
AiAskResponse response = await client.Ai.CreateAiAskAsync(requestBody: new AiAsk(mode: AiAskModeField.MultipleItemQa, prompt: "Which direction sun rises?", items: Array.AsReadOnly(new [] {new AiAskItemsField(id: fileToAsk1.Id, type: AiAskItemsTypeField.File) { Content = "Earth goes around the sun" },new AiAskItemsField(id: fileToAsk2.Id, type: AiAskItemsTypeField.File) { Content = "Sun rises in the East in the morning" }})));
Assert.IsTrue(response.Answer.Contains("East"));
Assert.IsTrue(response.CompletionReason == "done");
await client.Files.DeleteFileByIdAsync(fileId: fileToAsk1.Id);
Expand All @@ -38,7 +38,7 @@ public async System.Threading.Tasks.Task TestAskAiMultipleItems() {
[TestMethod]
public async System.Threading.Tasks.Task TestAiTextGenWithDialogueHistory() {
FileFull fileToAsk = await new CommonsManager().UploadNewFileAsync();
AiResponse response = await client.Ai.CreateAiTextGenAsync(requestBody: new AiTextGen(prompt: "Parapharse the document.s", items: Array.AsReadOnly(new [] {new AiTextGenItemsField() { Id = fileToAsk.Id, Type = AiTextGenItemsTypeField.File, Content = "The Earth goes around the sun. Sun rises in the East in the morning." }})) { DialogueHistory = Array.AsReadOnly(new [] {new AiTextGenDialogueHistoryField() { Prompt = "What does the earth go around?", Answer = "The sun", CreatedAt = Utils.DateTimeFromString(dateTime: "2021-01-01T00:00:00Z") },new AiTextGenDialogueHistoryField() { Prompt = "On Earth, where does the sun rise?", Answer = "East", CreatedAt = Utils.DateTimeFromString(dateTime: "2021-01-01T00:00:00Z") }}) });
AiResponse response = await client.Ai.CreateAiTextGenAsync(requestBody: new AiTextGen(prompt: "Parapharse the document.s", items: Array.AsReadOnly(new [] {new AiTextGenItemsField() { Id = fileToAsk.Id, Type = AiTextGenItemsTypeField.File, Content = "The Earth goes around the sun. Sun rises in the East in the morning." }})) { DialogueHistory = Array.AsReadOnly(new [] {new AiDialogueHistory() { Prompt = "What does the earth go around?", Answer = "The sun", CreatedAt = Utils.DateTimeFromString(dateTime: "2021-01-01T00:00:00Z") },new AiDialogueHistory() { Prompt = "On Earth, where does the sun rise?", Answer = "East", CreatedAt = Utils.DateTimeFromString(dateTime: "2021-01-01T00:00:00Z") }}) });
Assert.IsTrue(response.Answer.Contains("sun"));
Assert.IsTrue(response.CompletionReason == "done");
await client.Files.DeleteFileByIdAsync(fileId: fileToAsk.Id);
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 @@ -25,11 +25,11 @@ public AiManager(NetworkSession? networkSession = default) {
/// <param name="cancellationToken">
/// Token used for request cancellation.
/// </param>
public async System.Threading.Tasks.Task<AiResponse> CreateAiAskAsync(AiAsk requestBody, CreateAiAskHeaders? headers = default, System.Threading.CancellationToken? cancellationToken = null) {
public async System.Threading.Tasks.Task<AiAskResponse> CreateAiAskAsync(AiAsk requestBody, CreateAiAskHeaders? headers = default, System.Threading.CancellationToken? cancellationToken = null) {
headers = headers ?? new CreateAiAskHeaders();
Dictionary<string, string> headersMap = Utils.PrepareParams(map: DictionaryUtils.MergeDictionaries(new Dictionary<string, string?>() { }, headers.ExtraHeaders));
FetchResponse response = await HttpClientAdapter.FetchAsync(string.Concat(this.NetworkSession.BaseUrls.BaseUrl, "/2.0/ai/ask"), new FetchOptions(networkSession: this.NetworkSession) { Method = "POST", Headers = headersMap, Data = SimpleJsonSerializer.Serialize(requestBody), ContentType = "application/json", ResponseFormat = "json", Auth = this.Auth, CancellationToken = cancellationToken }).ConfigureAwait(false);
return SimpleJsonSerializer.Deserialize<AiResponse>(response.Data);
return SimpleJsonSerializer.Deserialize<AiAskResponse>(response.Data);
}

/// <summary>
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 @@ -18,7 +18,7 @@ public interface IAiManager {
/// <param name="cancellationToken">
/// Token used for request cancellation.
/// </param>
public System.Threading.Tasks.Task<AiResponse> CreateAiAskAsync(AiAsk requestBody, CreateAiAskHeaders? 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<AiAskResponse> CreateAiAskAsync(AiAsk requestBody, CreateAiAskHeaders? headers = default, System.Threading.CancellationToken? cancellationToken = null) => throw new System.NotImplementedException("This method needs to be implemented by the derived class before calling it.");

/// <summary>
/// Sends an AI request to supported LLMs and returns an answer specifically focused on the creation of new text.
Expand Down
11 changes: 8 additions & 3 deletions Box.Sdk.Gen/Schemas/AiAgentAsk/AiAgentAsk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class AiAgentAsk {
/// </summary>
[JsonPropertyName("type")]
[JsonConverter(typeof(StringEnumConverter<AiAgentAskTypeField>))]
public StringEnum<AiAgentAskTypeField>? Type { get; init; }
public StringEnum<AiAgentAskTypeField> Type { get; }

[JsonPropertyName("long_text")]
public AiAgentLongTextTool? LongText { get; init; }
Expand All @@ -24,8 +24,13 @@ public class AiAgentAsk {
[JsonPropertyName("basic_text_multi")]
public AiAgentBasicTextToolAsk? BasicTextMulti { get; init; }

public AiAgentAsk() {

public AiAgentAsk(AiAgentAskTypeField type = AiAgentAskTypeField.AiAgentAsk) {
Type = type;
}

[JsonConstructorAttribute]
internal AiAgentAsk(StringEnum<AiAgentAskTypeField> type) {
Type = AiAgentAskTypeField.AiAgentAsk;
}
}
}
11 changes: 8 additions & 3 deletions Box.Sdk.Gen/Schemas/AiAgentTextGen/AiAgentTextGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@ public class AiAgentTextGen {
/// </summary>
[JsonPropertyName("type")]
[JsonConverter(typeof(StringEnumConverter<AiAgentTextGenTypeField>))]
public StringEnum<AiAgentTextGenTypeField>? Type { get; init; }
public StringEnum<AiAgentTextGenTypeField> Type { get; }

[JsonPropertyName("basic_gen")]
public AiAgentBasicGenTool? BasicGen { get; init; }

public AiAgentTextGen() {

public AiAgentTextGen(AiAgentTextGenTypeField type = AiAgentTextGenTypeField.AiAgentTextGen) {
Type = type;
}

[JsonConstructorAttribute]
internal AiAgentTextGen(StringEnum<AiAgentTextGenTypeField> type) {
Type = AiAgentTextGenTypeField.AiAgentTextGen;
}
}
}
12 changes: 12 additions & 0 deletions Box.Sdk.Gen/Schemas/AiAsk/AiAsk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ public class AiAsk {
[JsonPropertyName("items")]
public IReadOnlyList<AiAskItemsField> Items { get; }

/// <summary>
/// The history of prompts and answers previously passed to the LLM. This provides additional context to the LLM in generating the response.
/// </summary>
[JsonPropertyName("dialogue_history")]
public IReadOnlyList<AiDialogueHistory>? DialogueHistory { get; init; }

/// <summary>
/// A flag to indicate whether citations should be returned.
/// </summary>
[JsonPropertyName("include_citations")]
public bool? IncludeCitations { get; init; }

[JsonPropertyName("ai_agent")]
public AiAgentAsk? AiAgent { get; init; }

Expand Down
39 changes: 39 additions & 0 deletions Box.Sdk.Gen/Schemas/AiAskResponse/AiAskResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Box.Sdk.Gen;
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Box.Sdk.Gen.Schemas;

namespace Box.Sdk.Gen.Schemas {
public class AiAskResponse {
/// <summary>
/// The answer provided by the LLM.
/// </summary>
[JsonPropertyName("answer")]
public string 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; }

/// <summary>
/// The citations of the LLM's answer reference.
/// </summary>
[JsonPropertyName("citations")]
public IReadOnlyList<AiCitation>? Citations { get; init; }

public AiAskResponse(string answer, System.DateTimeOffset createdAt) {
Answer = answer;
CreatedAt = createdAt;
}
}
}
36 changes: 36 additions & 0 deletions Box.Sdk.Gen/Schemas/AiCitation/AiCitation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Box.Sdk.Gen;
using System.Text.Json.Serialization;
using Box.Sdk.Gen.Internal;

namespace Box.Sdk.Gen.Schemas {
public class AiCitation {
/// <summary>
/// The specific content from where the answer was referenced.
/// </summary>
[JsonPropertyName("content")]
public string? Content { get; init; }

/// <summary>
/// The id of the item.
/// </summary>
[JsonPropertyName("id")]
public string? Id { get; init; }

/// <summary>
/// The type of the item.
/// </summary>
[JsonPropertyName("type")]
[JsonConverter(typeof(StringEnumConverter<AiCitationTypeField>))]
public StringEnum<AiCitationTypeField>? Type { get; init; }

/// <summary>
/// The name of the item.
/// </summary>
[JsonPropertyName("name")]
public string? Name { get; init; }

public AiCitation() {

}
}
}
8 changes: 8 additions & 0 deletions Box.Sdk.Gen/Schemas/AiCitation/AiCitationTypeField.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.ComponentModel;

namespace Box.Sdk.Gen.Schemas {
public enum AiCitationTypeField {
[Description("file")]
File
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
using Box.Sdk.Gen;
using System.Text.Json.Serialization;
using Box.Sdk.Gen.Internal;
using Box.Sdk.Gen.Schemas;

namespace Box.Sdk.Gen.Schemas {
public class AiTextGenDialogueHistoryField {
public class AiDialogueHistory {
/// <summary>
/// The prompt previously provided by the client and answered by the LLM.
/// </summary>
Expand All @@ -23,7 +21,7 @@ public class AiTextGenDialogueHistoryField {
[JsonPropertyName("created_at")]
public System.DateTimeOffset? CreatedAt { get; init; }

public AiTextGenDialogueHistoryField() {
public AiDialogueHistory() {

}
}
Expand Down
2 changes: 1 addition & 1 deletion Box.Sdk.Gen/Schemas/AiTextGen/AiTextGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class AiTextGen {
/// The history of prompts and answers previously passed to the LLM. This provides additional context to the LLM in generating the response.
/// </summary>
[JsonPropertyName("dialogue_history")]
public IReadOnlyList<AiTextGenDialogueHistoryField>? DialogueHistory { get; init; }
public IReadOnlyList<AiDialogueHistory>? DialogueHistory { get; init; }

[JsonPropertyName("ai_agent")]
public AiAgentTextGen? AiAgent { get; init; }
Expand Down
4 changes: 2 additions & 2 deletions docs/Ai.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ await client.Ai.CreateAiAskAsync(requestBody: new AiAsk(mode: AiAskModeField.Mul

### Returns

This function returns a value of type `AiResponse`.
This function returns a value of type `AiAskResponse`.

A successful response including the answer from the LLM.

Expand All @@ -47,7 +47,7 @@ See the endpoint docs at

<!-- sample post_ai_text_gen -->
```
await client.Ai.CreateAiTextGenAsync(requestBody: new AiTextGen(prompt: "Parapharse the document.s", items: Array.AsReadOnly(new [] {new AiTextGenItemsField() { Id = fileToAsk.Id, Type = AiTextGenItemsTypeField.File, Content = "The Earth goes around the sun. Sun rises in the East in the morning." }})) { DialogueHistory = Array.AsReadOnly(new [] {new AiTextGenDialogueHistoryField() { Prompt = "What does the earth go around?", Answer = "The sun", CreatedAt = Utils.DateTimeFromString(dateTime: "2021-01-01T00:00:00Z") },new AiTextGenDialogueHistoryField() { Prompt = "On Earth, where does the sun rise?", Answer = "East", CreatedAt = Utils.DateTimeFromString(dateTime: "2021-01-01T00:00:00Z") }}) });
await client.Ai.CreateAiTextGenAsync(requestBody: new AiTextGen(prompt: "Parapharse the document.s", items: Array.AsReadOnly(new [] {new AiTextGenItemsField() { Id = fileToAsk.Id, Type = AiTextGenItemsTypeField.File, Content = "The Earth goes around the sun. Sun rises in the East in the morning." }})) { DialogueHistory = Array.AsReadOnly(new [] {new AiDialogueHistory() { Prompt = "What does the earth go around?", Answer = "The sun", CreatedAt = Utils.DateTimeFromString(dateTime: "2021-01-01T00:00:00Z") },new AiDialogueHistory() { Prompt = "On Earth, where does the sun rise?", Answer = "East", CreatedAt = Utils.DateTimeFromString(dateTime: "2021-01-01T00:00:00Z") }}) });
```

### Arguments
Expand Down

0 comments on commit fcd712a

Please sign in to comment.