From c7a092f22b8b95388bf66f2eeba9257035767732 Mon Sep 17 00:00:00 2001 From: Minh Nguyen Cong Date: Fri, 11 Oct 2024 01:01:22 +0200 Subject: [PATCH] Update code --- doc/ai.md | 9 +++-- src/intTest/java/com/box/sdk/BoxAIIT.java | 36 +++++++++--------- src/main/java/com/box/sdk/BoxAI.java | 4 +- .../java/com/box/sdk/BoxAIExtractField.java | 8 ++-- .../com/box/sdk/BoxAIExtractFieldOption.java | 27 +++++++++++++ .../sdk/BoxAIExtractStructuredResponse.java | 38 +++++++++++++++++++ src/test/java/com/box/sdk/BoxAITest.java | 10 ++--- 7 files changed, 101 insertions(+), 31 deletions(-) create mode 100644 src/main/java/com/box/sdk/BoxAIExtractFieldOption.java create mode 100644 src/main/java/com/box/sdk/BoxAIExtractStructuredResponse.java diff --git a/doc/ai.md b/doc/ai.md index 4ed501842..d457bf291 100644 --- a/doc/ai.md +++ b/doc/ai.md @@ -11,6 +11,8 @@ an answer based on the provided prompt and items. - [Send AI request](#send-ai-request) - [Send AI text generation request](#send-ai-text-generation-request) - [Get AI Agent default configuration](#get-ai-agent-default-configuration) + - [Extract metadata freeform](#extract-metadata-freeform) + - [Extract metadata structured](#extract-metadata-structured) @@ -92,7 +94,7 @@ BoxAIAgentConfig config = BoxAI.getAiAgentDefaultConfig( Extract metadata freeform -------------------------- -To send an AI request to supported Large Language Models (LLMs) and extracts metadata in form of key-value pairs, call static +To send an AI request to supported Large Language Models (LLMs) and extract metadata in form of key-value pairs, call static [` extractMetadataFreeform(BoxAPIConnection api, String prompt, List items, BoxAIAgentExtract agent)`][extract-metadata-freeform] method. In the request you have to provide a prompt, a list of items that your prompt refers to and an optional agent configuration. @@ -114,7 +116,7 @@ BoxAIResponse response = BoxAI.extractMetadataFreeform( Extract metadata structured -------------------------- -Sends an AI request to supported Large Language Models (LLMs) and returns extracted metadata as a set of key-value pairs. For this request, you need to use an already defined metadata template or a define a schema yourself. +Sends an AI request to supported Large Language Models (LLMs) and returns extracted metadata as a set of key-value pairs. For this request, you need to use an already defined metadata template or define a schema yourself. To send an AI request to extract metadata from files, call static [`extractMetadataStructured extractMetadataStructured(BoxAPIConnection api, List items, BoxAIExtractMetadataTemplate template, List fields, BoxAIAgentExtractStructured agent)`][extract-metadata-structured] method. @@ -124,13 +126,14 @@ BoxAIAgent agent = BoxAI.getAiAgentDefaultConfig(api, BoxAIAgent.Mode.EXTRACT_ST BoxAIAgentExtractStructured agentExtractStructured = (BoxAIAgentExtractStructured) agent; BoxAIExtractMetadataTemplate template = new BoxAIExtractMetadataTemplate("templateKey", "enterprise"); -JsonObject result = BoxAI.extractMetadataStructured( +BoxAIExtractStructuredResponse result = BoxAI.extractMetadataStructured( api, Collections.singletonList(new BoxAIItem("123456", BoxAIItem.Type.FILE)), template, null, agentExtractStructured ); +JsonObject sourceJson = result.getSourceJson(); ``` [extract-metadata-structured]: https://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxAI.html#extractMetadataStructured-com.box.sdk.BoxAPIConnection-java.util.List-com.box.sdk.ai.BoxAIExtractMetadataTemplate-java.util.List-com.box.sdk.ai.BoxAIAgentExtractStructured- \ No newline at end of file diff --git a/src/intTest/java/com/box/sdk/BoxAIIT.java b/src/intTest/java/com/box/sdk/BoxAIIT.java index dd5afdfa2..6ddb80dd8 100644 --- a/src/intTest/java/com/box/sdk/BoxAIIT.java +++ b/src/intTest/java/com/box/sdk/BoxAIIT.java @@ -233,7 +233,7 @@ public void aiExtractStructuredWithFields() throws InterruptedException { // When a file has been just uploaded, AI service may not be ready to return text response // and 412 is returned retry(() -> { - JsonObject response = BoxAI.extractMetadataStructured(api, + BoxAIExtractStructuredResponse response = BoxAI.extractMetadataStructured(api, Collections.singletonList(new BoxAIItem(uploadedFile.getID(), BoxAIItem.Type.FILE)), null, new ArrayList() {{ @@ -261,19 +261,20 @@ public void aiExtractStructuredWithFields() throws InterruptedException { "Person hobby", "Hobby", "hobby", - new ArrayList() {{ - add("guitar"); - add("books"); + new ArrayList() {{ + add(new BoxAIExtractFieldOption("guitar")); + add(new BoxAIExtractFieldOption("books")); }}, "What is your hobby?")); }}, agentExtractStructured); - assertThat(response.get("firstName").asString(), is(equalTo("John"))); - assertThat(response.get("lastName").asString(), is(equalTo("Doe"))); - assertThat(response.get("dateOfBirth").asString(), is(equalTo("1990-07-04"))); - assertThat(response.get("age").asInt(), is(equalTo(34))); - assertThat(response.get("hobby").asArray().get(0).asString(), is(equalTo("guitar"))); - assertThat(response.get("hobby").asArray().get(1).asString(), is(equalTo("books"))); + JsonObject sourceJson = response.getSourceJson(); + assertThat(sourceJson.get("firstName").asString(), is(equalTo("John"))); + assertThat(sourceJson.get("lastName").asString(), is(equalTo("Doe"))); + assertThat(sourceJson.get("dateOfBirth").asString(), is(equalTo("1990-07-04"))); + assertThat(sourceJson.get("age").asInt(), is(equalTo(34))); + assertThat(sourceJson.get("hobby").asArray().get(0).asString(), is(equalTo("guitar"))); + assertThat(sourceJson.get("hobby").asArray().get(1).asString(), is(equalTo("books"))); }, 2, 2000); } finally { deleteFile(uploadedFile); @@ -316,17 +317,18 @@ public void aiExtractStructuredWithMetadataTemplate() throws InterruptedExceptio // When a file has been just uploaded, AI service may not be ready to return text response // and 412 is returned retry(() -> { - JsonObject response = BoxAI.extractMetadataStructured(api, + BoxAIExtractStructuredResponse response = BoxAI.extractMetadataStructured(api, Collections.singletonList(new BoxAIItem(uploadedFile.getID(), BoxAIItem.Type.FILE)), new BoxAIExtractMetadataTemplate(templateKey, "enterprise"), null, agentExtractStructured); - assertThat(response.get("firstName").asString(), is(equalTo("John"))); - assertThat(response.get("lastName").asString(), is(equalTo("Doe"))); - assertThat(response.get("dateOfBirth").asString(), is(equalTo("1990-07-04"))); - assertThat(response.get("age").asInt(), is(equalTo(34))); - assertThat(response.get("hobby").asArray().get(0).asString(), is(equalTo("guitar"))); - assertThat(response.get("hobby").asArray().get(1).asString(), is(equalTo("books"))); + JsonObject sourceJson = response.getSourceJson(); + assertThat(sourceJson.get("firstName").asString(), is(equalTo("John"))); + assertThat(sourceJson.get("lastName").asString(), is(equalTo("Doe"))); + assertThat(sourceJson.get("dateOfBirth").asString(), is(equalTo("1990-07-04"))); + assertThat(sourceJson.get("age").asInt(), is(equalTo(34))); + assertThat(sourceJson.get("hobby").asArray().get(0).asString(), is(equalTo("guitar"))); + assertThat(sourceJson.get("hobby").asArray().get(1).asString(), is(equalTo("books"))); }, 2, 2000); } finally { deleteFile(uploadedFile); diff --git a/src/main/java/com/box/sdk/BoxAI.java b/src/main/java/com/box/sdk/BoxAI.java index 32d1ac741..f63de014c 100644 --- a/src/main/java/com/box/sdk/BoxAI.java +++ b/src/main/java/com/box/sdk/BoxAI.java @@ -284,7 +284,7 @@ public static BoxAIResponse extractMetadataFreeform(BoxAPIConnection api, } } - public static JsonObject extractMetadataStructured(BoxAPIConnection api, List items, + public static BoxAIExtractStructuredResponse extractMetadataStructured(BoxAPIConnection api, List items, BoxAIExtractMetadataTemplate template, List fields, BoxAIAgentExtractStructured agent) { @@ -317,7 +317,7 @@ public static JsonObject extractMetadataStructured(BoxAPIConnection api, List options; + private List options; /** * The prompt of the field. */ @@ -45,7 +45,7 @@ public class BoxAIExtractField extends BoxJSONObject { public BoxAIExtractField(String type, String description, String displayName, - String key, List options, + String key, List options, String prompt) { this.type = type; this.description = description; @@ -63,8 +63,8 @@ public JsonObject getJSONObject() { JsonUtils.addIfNotNull(jsonObject, "key", this.key); if (this.options != null) { JsonArray options = new JsonArray(); - for (String option : this.options) { - options.add(new JsonObject().add("key", option)); + for (BoxAIExtractFieldOption option : this.options) { + options.add(option.getJSONObject()); } jsonObject.add("options", options); } diff --git a/src/main/java/com/box/sdk/BoxAIExtractFieldOption.java b/src/main/java/com/box/sdk/BoxAIExtractFieldOption.java new file mode 100644 index 000000000..1597f663e --- /dev/null +++ b/src/main/java/com/box/sdk/BoxAIExtractFieldOption.java @@ -0,0 +1,27 @@ +package com.box.sdk; + + +import com.box.sdk.internal.utils.JsonUtils; +import com.eclipsesource.json.JsonObject; + +public class BoxAIExtractFieldOption extends BoxJSONObject { + /** + * A unique identifier for the option. + */ + final String key; + + /** + * Constructs a BoxAIExtractFieldOption object with a given key. + * + * @param key the key of the field option. + */ + public BoxAIExtractFieldOption(String key) { + this.key = key; + } + + public JsonObject getJSONObject() { + JsonObject jsonObject = new JsonObject(); + JsonUtils.addIfNotNull(jsonObject, "key", this.key); + return jsonObject; + } +} diff --git a/src/main/java/com/box/sdk/BoxAIExtractStructuredResponse.java b/src/main/java/com/box/sdk/BoxAIExtractStructuredResponse.java new file mode 100644 index 000000000..662244fa5 --- /dev/null +++ b/src/main/java/com/box/sdk/BoxAIExtractStructuredResponse.java @@ -0,0 +1,38 @@ +package com.box.sdk; + +import com.eclipsesource.json.Json; +import com.eclipsesource.json.JsonObject; + +/** + * AI response to a user request. + */ +public class BoxAIExtractStructuredResponse extends BoxJSONObject { + private final JsonObject sourceJson; + + /** + * Constructs a BoxAIResponse object. + */ + public BoxAIExtractStructuredResponse(String json) { + super(json); + this.sourceJson = Json.parse(json).asObject(); + } + + /** + * Constructs an BoxAIResponse object using an already parsed JSON object. + * + * @param jsonObject the parsed JSON object. + */ + BoxAIExtractStructuredResponse(JsonObject jsonObject) { + super(jsonObject); + this.sourceJson = jsonObject; + } + + /** + * Gets the source JSON of the AI response. + * + * @return the source JSON of the AI response. + */ + public JsonObject getSourceJson() { + return sourceJson; + } +} diff --git a/src/test/java/com/box/sdk/BoxAITest.java b/src/test/java/com/box/sdk/BoxAITest.java index 5302119f1..7607f9088 100644 --- a/src/test/java/com/box/sdk/BoxAITest.java +++ b/src/test/java/com/box/sdk/BoxAITest.java @@ -327,9 +327,9 @@ public void testExtractMetadataStructuredSuccess() { "The name of the file", "Name", "name", - new ArrayList() {{ - add("option 1"); - add("option 2"); + new ArrayList() {{ + add(new BoxAIExtractFieldOption("option 1")); + add(new BoxAIExtractFieldOption("option 2")); }}, "What is the name of the file?"); @@ -352,7 +352,7 @@ public void testExtractMetadataStructuredSuccess() { .withHeader("Content-Type", APPLICATION_JSON) .withBody(result))); - JsonObject response = BoxAI.extractMetadataStructured( + BoxAIExtractStructuredResponse response = BoxAI.extractMetadataStructured( api, items, template, @@ -361,6 +361,6 @@ public void testExtractMetadataStructuredSuccess() { ); assertThat(response, equalTo(Json.parse(result).asObject())); - assertThat(response.get("firstName").asString(), equalTo("John")); + assertThat(response.getSourceJson().get("firstName").asString(), equalTo("John")); } }