Skip to content

Commit 7c73cea

Browse files
feat: Update /ai/extract_structured response schema (box/box-codegen#641) (#459)
1 parent a9732bc commit 7c73cea

File tree

7 files changed

+79
-23
lines changed

7 files changed

+79
-23
lines changed

.codegen.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ "engineHash": "cf82faa", "specHash": "3dc3f1e", "version": "1.10.0" }
1+
{ "engineHash": "a74691d", "specHash": "1fdcbef", "version": "1.10.0" }

box_sdk_gen/internal/utils.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,11 @@ def get_epoch_time_in_seconds() -> int:
263263

264264

265265
def get_value_from_object_raw_data(obj: BaseObject, key: str) -> Any:
266-
return obj.raw_data.get(key, None)
266+
keys = key.split('.')
267+
value: dict = obj.raw_data
268+
for k in keys:
269+
value = value.get(k, {})
270+
return value
267271

268272

269273
class JwtAlgorithm(str, Enum):

box_sdk_gen/managers/ai.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@
4242

4343
from box_sdk_gen.schemas.ai_extract import AiExtract
4444

45-
from box_sdk_gen.schemas.ai_extract_response import AiExtractResponse
45+
from box_sdk_gen.schemas.ai_extract_structured_response import (
46+
AiExtractStructuredResponse,
47+
)
4648

4749
from box_sdk_gen.schemas.ai_extract_structured import AiExtractStructured
4850

@@ -411,7 +413,7 @@ def create_ai_extract_structured(
411413
fields: Optional[List[CreateAiExtractStructuredFields]] = None,
412414
ai_agent: Optional[AiAgentExtractStructured] = None,
413415
extra_headers: Optional[Dict[str, Optional[str]]] = None
414-
) -> AiExtractResponse:
416+
) -> AiExtractStructuredResponse:
415417
"""
416418
Sends an AI request to supported Large Language Models (LLMs) and returns extracted metadata as a set of key-value pairs.
417419
@@ -463,4 +465,4 @@ def create_ai_extract_structured(
463465
network_session=self.network_session,
464466
)
465467
)
466-
return deserialize(response.data, AiExtractResponse)
468+
return deserialize(response.data, AiExtractStructuredResponse)

box_sdk_gen/schemas/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
from box_sdk_gen.schemas.ai_extract_response import *
1212

13+
from box_sdk_gen.schemas.ai_extract_structured_response import *
14+
1315
from box_sdk_gen.schemas.ai_item_base import *
1416

1517
from box_sdk_gen.schemas.ai_llm_endpoint_params_aws import *
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from typing import Optional
2+
3+
from box_sdk_gen.internal.base_object import BaseObject
4+
5+
from box_sdk_gen.schemas.ai_extract_response import AiExtractResponse
6+
7+
from box_sdk_gen.schemas.ai_agent_info import AiAgentInfo
8+
9+
from box_sdk_gen.box.errors import BoxSDKError
10+
11+
from box_sdk_gen.internal.utils import DateTime
12+
13+
14+
class AiExtractStructuredResponse(BaseObject):
15+
def __init__(
16+
self,
17+
answer: AiExtractResponse,
18+
created_at: DateTime,
19+
*,
20+
completion_reason: Optional[str] = None,
21+
ai_agent_info: Optional[AiAgentInfo] = None,
22+
**kwargs
23+
):
24+
"""
25+
:param created_at: The ISO date formatted timestamp of when the answer to the prompt was created.
26+
:type created_at: DateTime
27+
:param completion_reason: The reason the response finishes., defaults to None
28+
:type completion_reason: Optional[str], optional
29+
"""
30+
super().__init__(**kwargs)
31+
self.answer = answer
32+
self.created_at = created_at
33+
self.completion_reason = completion_reason
34+
self.ai_agent_info = ai_agent_info

docs/ai.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,6 @@ client.ai.create_ai_extract_structured(
233233

234234
### Returns
235235

236-
This function returns a value of type `AiExtractResponse`.
236+
This function returns a value of type `AiExtractStructuredResponse`.
237237

238238
A successful response including the answer from the LLM.

test/ai.py

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030

3131
from box_sdk_gen.managers.uploads import UploadFileAttributesParentField
3232

33-
from box_sdk_gen.schemas.ai_extract_response import AiExtractResponse
33+
from box_sdk_gen.schemas.ai_extract_structured_response import (
34+
AiExtractStructuredResponse,
35+
)
3436

3537
from box_sdk_gen.managers.ai import CreateAiExtractStructuredFields
3638

@@ -266,7 +268,7 @@ def testAIExtractStructuredWithFields():
266268
)
267269
file: FileFull = uploaded_files.entries[0]
268270
delay_in_seconds(5)
269-
response: AiExtractResponse = client.ai.create_ai_extract_structured(
271+
response: AiExtractStructuredResponse = client.ai.create_ai_extract_structured(
270272
[AiItemBase(id=file.id)],
271273
fields=[
272274
CreateAiExtractStructuredFields(
@@ -311,16 +313,22 @@ def testAIExtractStructuredWithFields():
311313
],
312314
ai_agent=agent_ignoring_overriding_embeddings_model,
313315
)
314-
assert to_string(get_value_from_object_raw_data(response, 'firstName')) == 'John'
315-
assert to_string(get_value_from_object_raw_data(response, 'lastName')) == 'Doe'
316+
assert to_string(
317+
get_value_from_object_raw_data(response, 'answer.hobby')
318+
) == to_string(['guitar'])
316319
assert (
317-
to_string(get_value_from_object_raw_data(response, 'dateOfBirth'))
318-
== '1990-07-04'
320+
to_string(get_value_from_object_raw_data(response, 'answer.firstName'))
321+
== 'John'
319322
)
320-
assert to_string(get_value_from_object_raw_data(response, 'age')) == '34'
321-
assert to_string(get_value_from_object_raw_data(response, 'hobby')) == to_string(
322-
['guitar']
323+
assert (
324+
to_string(get_value_from_object_raw_data(response, 'answer.lastName')) == 'Doe'
323325
)
326+
assert (
327+
to_string(get_value_from_object_raw_data(response, 'answer.dateOfBirth'))
328+
== '1990-07-04'
329+
)
330+
assert to_string(get_value_from_object_raw_data(response, 'answer.age')) == '34'
331+
assert response.completion_reason == 'done'
324332
client.files.delete_file_by_id(file.id)
325333

326334

@@ -378,22 +386,28 @@ def testAIExtractStructuredWithMetadataTemplate():
378386
),
379387
],
380388
)
381-
response: AiExtractResponse = client.ai.create_ai_extract_structured(
389+
response: AiExtractStructuredResponse = client.ai.create_ai_extract_structured(
382390
[AiItemBase(id=file.id)],
383391
metadata_template=CreateAiExtractStructuredMetadataTemplate(
384392
template_key=template_key, scope='enterprise'
385393
),
386394
)
387-
assert to_string(get_value_from_object_raw_data(response, 'firstName')) == 'John'
388-
assert to_string(get_value_from_object_raw_data(response, 'lastName')) == 'Doe'
389395
assert (
390-
to_string(get_value_from_object_raw_data(response, 'dateOfBirth'))
391-
== '1990-07-04T00:00:00Z'
396+
to_string(get_value_from_object_raw_data(response, 'answer.firstName'))
397+
== 'John'
398+
)
399+
assert (
400+
to_string(get_value_from_object_raw_data(response, 'answer.lastName')) == 'Doe'
392401
)
393-
assert to_string(get_value_from_object_raw_data(response, 'age')) == '34'
394-
assert to_string(get_value_from_object_raw_data(response, 'hobby')) == to_string(
395-
['guitar']
402+
assert (
403+
to_string(get_value_from_object_raw_data(response, 'answer.dateOfBirth'))
404+
== '1990-07-04T00:00:00Z'
396405
)
406+
assert to_string(get_value_from_object_raw_data(response, 'answer.age')) == '34'
407+
assert to_string(
408+
get_value_from_object_raw_data(response, 'answer.hobby')
409+
) == to_string(['guitar'])
410+
assert response.completion_reason == 'done'
397411
client.metadata_templates.delete_metadata_template(
398412
DeleteMetadataTemplateScope.ENTERPRISE, template.template_key
399413
)

0 commit comments

Comments
 (0)