diff --git a/.codegen.json b/.codegen.json index 564b1d05..6972015e 100644 --- a/.codegen.json +++ b/.codegen.json @@ -1 +1 @@ -{ "engineHash": "cf82faa", "specHash": "3dc3f1e", "version": "1.11.0" } +{ "engineHash": "a74691d", "specHash": "1fdcbef", "version": "1.11.0" } diff --git a/docs/ai.md b/docs/ai.md index a120da17..5f532285 100644 --- a/docs/ai.md +++ b/docs/ai.md @@ -204,6 +204,6 @@ await client.ai.createAiExtractStructured({ ### 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. diff --git a/package-lock.json b/package-lock.json index e1e23235..b3955e4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2674,9 +2674,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", + "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -3313,9 +3313,9 @@ } }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", + "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -3569,9 +3569,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", + "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -4466,9 +4466,9 @@ } }, "node_modules/ts-jest/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", + "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", "dev": true, "bin": { "semver": "bin/semver.js" diff --git a/src/internal/utils.ts b/src/internal/utils.ts index 3a074181..38a9306c 100644 --- a/src/internal/utils.ts +++ b/src/internal/utils.ts @@ -453,10 +453,10 @@ export async function delayInSeconds(seconds: number): Promise { * @returns Value from object raw data. */ export function getValueFromObjectRawData(obj: any, key: string): any { - if (obj && typeof obj === 'object' && obj.rawData) { - return obj.rawData[key]; + if (!obj || typeof obj !== 'object' || !obj.rawData) { + return undefined; } - return undefined; + return key.split('.').reduce((value, k) => value?.[k], obj.rawData); } /** diff --git a/src/managers/ai.generated.ts b/src/managers/ai.generated.ts index fa459de5..f67ee9db 100644 --- a/src/managers/ai.generated.ts +++ b/src/managers/ai.generated.ts @@ -12,8 +12,8 @@ import { serializeAiAgentAskOrAiAgentExtractOrAiAgentExtractStructuredOrAiAgentT import { deserializeAiAgentAskOrAiAgentExtractOrAiAgentExtractStructuredOrAiAgentTextGen } from '../schemas/aiAgentAskOrAiAgentExtractOrAiAgentExtractStructuredOrAiAgentTextGen.generated.js'; import { serializeAiExtract } from '../schemas/aiExtract.generated.js'; import { deserializeAiExtract } from '../schemas/aiExtract.generated.js'; -import { serializeAiExtractResponse } from '../schemas/aiExtractResponse.generated.js'; -import { deserializeAiExtractResponse } from '../schemas/aiExtractResponse.generated.js'; +import { serializeAiExtractStructuredResponse } from '../schemas/aiExtractStructuredResponse.generated.js'; +import { deserializeAiExtractStructuredResponse } from '../schemas/aiExtractStructuredResponse.generated.js'; import { serializeAiExtractStructured } from '../schemas/aiExtractStructured.generated.js'; import { deserializeAiExtractStructured } from '../schemas/aiExtractStructured.generated.js'; import { ResponseFormat } from '../networking/fetchOptions.generated.js'; @@ -24,7 +24,7 @@ import { AiResponse } from '../schemas/aiResponse.generated.js'; import { AiTextGen } from '../schemas/aiTextGen.generated.js'; import { AiAgentAskOrAiAgentExtractOrAiAgentExtractStructuredOrAiAgentTextGen } from '../schemas/aiAgentAskOrAiAgentExtractOrAiAgentExtractStructuredOrAiAgentTextGen.generated.js'; import { AiExtract } from '../schemas/aiExtract.generated.js'; -import { AiExtractResponse } from '../schemas/aiExtractResponse.generated.js'; +import { AiExtractStructuredResponse } from '../schemas/aiExtractStructuredResponse.generated.js'; import { AiExtractStructured } from '../schemas/aiExtractStructured.generated.js'; import { BoxSdkError } from '../box/errors.js'; import { Authentication } from '../networking/auth.generated.js'; @@ -496,12 +496,12 @@ export class AiManager { * or use the [metadata template API](g://metadata/templates/create). * @param {AiExtractStructured} requestBody Request body of createAiExtractStructured method * @param {CreateAiExtractStructuredOptionalsInput} optionalsInput - * @returns {Promise} + * @returns {Promise} */ async createAiExtractStructured( requestBody: AiExtractStructured, optionalsInput: CreateAiExtractStructuredOptionalsInput = {}, - ): Promise { + ): Promise { const optionals: CreateAiExtractStructuredOptionals = new CreateAiExtractStructuredOptionals({ headers: optionalsInput.headers, @@ -530,7 +530,7 @@ export class AiManager { }), ); return { - ...deserializeAiExtractResponse(response.data!), + ...deserializeAiExtractStructuredResponse(response.data!), rawData: response.data!, }; } diff --git a/src/schemas/aiExtractStructuredResponse.generated.ts b/src/schemas/aiExtractStructuredResponse.generated.ts new file mode 100644 index 00000000..e0be2cb0 --- /dev/null +++ b/src/schemas/aiExtractStructuredResponse.generated.ts @@ -0,0 +1,91 @@ +import { serializeAiExtractResponse } from './aiExtractResponse.generated.js'; +import { deserializeAiExtractResponse } from './aiExtractResponse.generated.js'; +import { serializeAiAgentInfo } from './aiAgentInfo.generated.js'; +import { deserializeAiAgentInfo } from './aiAgentInfo.generated.js'; +import { serializeDateTime } from '../internal/utils.js'; +import { deserializeDateTime } from '../internal/utils.js'; +import { AiExtractResponse } from './aiExtractResponse.generated.js'; +import { AiAgentInfo } from './aiAgentInfo.generated.js'; +import { BoxSdkError } from '../box/errors.js'; +import { DateTime } from '../internal/utils.js'; +import { SerializedData } from '../serialization/json.js'; +import { sdIsEmpty } from '../serialization/json.js'; +import { sdIsBoolean } from '../serialization/json.js'; +import { sdIsNumber } from '../serialization/json.js'; +import { sdIsString } from '../serialization/json.js'; +import { sdIsList } from '../serialization/json.js'; +import { sdIsMap } from '../serialization/json.js'; +export interface AiExtractStructuredResponse { + readonly answer: AiExtractResponse; + /** + * The ISO date formatted timestamp of when the answer to the prompt was created. */ + readonly createdAt: DateTime; + /** + * The reason the response finishes. */ + readonly completionReason?: string; + readonly aiAgentInfo?: AiAgentInfo; + readonly rawData?: SerializedData; +} +export function serializeAiExtractStructuredResponse( + val: AiExtractStructuredResponse, +): SerializedData { + return { + ['answer']: serializeAiExtractResponse(val.answer), + ['created_at']: serializeDateTime(val.createdAt), + ['completion_reason']: val.completionReason, + ['ai_agent_info']: + val.aiAgentInfo == void 0 + ? val.aiAgentInfo + : serializeAiAgentInfo(val.aiAgentInfo), + }; +} +export function deserializeAiExtractStructuredResponse( + val: SerializedData, +): AiExtractStructuredResponse { + if (!sdIsMap(val)) { + throw new BoxSdkError({ + message: 'Expecting a map for "AiExtractStructuredResponse"', + }); + } + if (val.answer == void 0) { + throw new BoxSdkError({ + message: + 'Expecting "answer" of type "AiExtractStructuredResponse" to be defined', + }); + } + const answer: AiExtractResponse = deserializeAiExtractResponse(val.answer); + if (val.created_at == void 0) { + throw new BoxSdkError({ + message: + 'Expecting "created_at" of type "AiExtractStructuredResponse" to be defined', + }); + } + if (!sdIsString(val.created_at)) { + throw new BoxSdkError({ + message: + 'Expecting string for "created_at" of type "AiExtractStructuredResponse"', + }); + } + const createdAt: DateTime = deserializeDateTime(val.created_at); + if ( + !(val.completion_reason == void 0) && + !sdIsString(val.completion_reason) + ) { + throw new BoxSdkError({ + message: + 'Expecting string for "completion_reason" of type "AiExtractStructuredResponse"', + }); + } + const completionReason: undefined | string = + val.completion_reason == void 0 ? void 0 : val.completion_reason; + const aiAgentInfo: undefined | AiAgentInfo = + val.ai_agent_info == void 0 + ? void 0 + : deserializeAiAgentInfo(val.ai_agent_info); + return { + answer: answer, + createdAt: createdAt, + completionReason: completionReason, + aiAgentInfo: aiAgentInfo, + } satisfies AiExtractStructuredResponse; +} diff --git a/src/test/ai.generated.test.ts b/src/test/ai.generated.test.ts index 68c66de7..72ce1092 100644 --- a/src/test/ai.generated.test.ts +++ b/src/test/ai.generated.test.ts @@ -32,8 +32,8 @@ import { serializeUploadFileRequestBodyAttributesParentField } from '../managers import { deserializeUploadFileRequestBodyAttributesParentField } from '../managers/uploads.generated.js'; import { serializeAiExtract } from '../schemas/aiExtract.generated.js'; import { deserializeAiExtract } from '../schemas/aiExtract.generated.js'; -import { serializeAiExtractResponse } from '../schemas/aiExtractResponse.generated.js'; -import { deserializeAiExtractResponse } from '../schemas/aiExtractResponse.generated.js'; +import { serializeAiExtractStructuredResponse } from '../schemas/aiExtractStructuredResponse.generated.js'; +import { deserializeAiExtractStructuredResponse } from '../schemas/aiExtractStructuredResponse.generated.js'; import { serializeAiExtractStructured } from '../schemas/aiExtractStructured.generated.js'; import { deserializeAiExtractStructured } from '../schemas/aiExtractStructured.generated.js'; import { serializeAiExtractStructuredFieldsField } from '../schemas/aiExtractStructured.generated.js'; @@ -82,7 +82,7 @@ import { UploadFileRequestBody } from '../managers/uploads.generated.js'; import { UploadFileRequestBodyAttributesField } from '../managers/uploads.generated.js'; import { UploadFileRequestBodyAttributesParentField } from '../managers/uploads.generated.js'; import { AiExtract } from '../schemas/aiExtract.generated.js'; -import { AiExtractResponse } from '../schemas/aiExtractResponse.generated.js'; +import { AiExtractStructuredResponse } from '../schemas/aiExtractStructuredResponse.generated.js'; import { AiExtractStructured } from '../schemas/aiExtractStructured.generated.js'; import { AiExtractStructuredFieldsField } from '../schemas/aiExtractStructured.generated.js'; import { AiExtractStructuredFieldsOptionsField } from '../schemas/aiExtractStructured.generated.js'; @@ -337,8 +337,8 @@ test('testAIExtractStructuredWithFields', async function testAIExtractStructured } satisfies UploadFileRequestBody); const file: FileFull = uploadedFiles.entries![0]; await delayInSeconds(5); - const response: AiExtractResponse = await client.ai.createAiExtractStructured( - { + const response: AiExtractStructuredResponse = + await client.ai.createAiExtractStructured({ fields: [ { key: 'firstName', @@ -381,20 +381,21 @@ test('testAIExtractStructuredWithFields', async function testAIExtractStructured } satisfies AiExtractStructuredFieldsField, ], items: [new AiItemBase({ id: file.id })], - } satisfies AiExtractStructured, - ); + } satisfies AiExtractStructured); if ( !( - (toString(getValueFromObjectRawData(response, 'firstName')) as string) == - 'John' + (toString( + getValueFromObjectRawData(response, 'answer.hobby'), + ) as string) == (['guitar'].map(toString).join(',') as string) ) ) { throw new Error('Assertion failed'); } if ( !( - (toString(getValueFromObjectRawData(response, 'lastName')) as string) == - 'Doe' + (toString( + getValueFromObjectRawData(response, 'answer.firstName'), + ) as string) == 'John' ) ) { throw new Error('Assertion failed'); @@ -402,25 +403,32 @@ test('testAIExtractStructuredWithFields', async function testAIExtractStructured if ( !( (toString( - getValueFromObjectRawData(response, 'dateOfBirth'), - ) as string) == '1990-07-04' + getValueFromObjectRawData(response, 'answer.lastName'), + ) as string) == 'Doe' ) ) { throw new Error('Assertion failed'); } if ( - !((toString(getValueFromObjectRawData(response, 'age')) as string) == '34') + !( + (toString( + getValueFromObjectRawData(response, 'answer.dateOfBirth'), + ) as string) == '1990-07-04' + ) ) { throw new Error('Assertion failed'); } if ( !( - (toString(getValueFromObjectRawData(response, 'hobby')) as string) == - (['guitar'].map(toString).join(',') as string) + (toString(getValueFromObjectRawData(response, 'answer.age')) as string) == + '34' ) ) { throw new Error('Assertion failed'); } + if (!(response.completionReason == 'done')) { + throw new Error('Assertion failed'); + } await client.files.deleteFileById(file.id); }); test('testAIExtractStructuredWithMetadataTemplate', async function testAIExtractStructuredWithMetadataTemplate(): Promise { @@ -482,27 +490,28 @@ test('testAIExtractStructuredWithMetadataTemplate', async function testAIExtract } satisfies CreateMetadataTemplateRequestBodyFieldsField, ], } satisfies CreateMetadataTemplateRequestBody); - const response: AiExtractResponse = await client.ai.createAiExtractStructured( - { + const response: AiExtractStructuredResponse = + await client.ai.createAiExtractStructured({ metadataTemplate: { templateKey: templateKey, scope: 'enterprise', } satisfies AiExtractStructuredMetadataTemplateField, items: [new AiItemBase({ id: file.id })], - } satisfies AiExtractStructured, - ); + } satisfies AiExtractStructured); if ( !( - (toString(getValueFromObjectRawData(response, 'firstName')) as string) == - 'John' + (toString( + getValueFromObjectRawData(response, 'answer.firstName'), + ) as string) == 'John' ) ) { throw new Error('Assertion failed'); } if ( !( - (toString(getValueFromObjectRawData(response, 'lastName')) as string) == - 'Doe' + (toString( + getValueFromObjectRawData(response, 'answer.lastName'), + ) as string) == 'Doe' ) ) { throw new Error('Assertion failed'); @@ -510,25 +519,32 @@ test('testAIExtractStructuredWithMetadataTemplate', async function testAIExtract if ( !( (toString( - getValueFromObjectRawData(response, 'dateOfBirth'), + getValueFromObjectRawData(response, 'answer.dateOfBirth'), ) as string) == '1990-07-04T00:00:00Z' ) ) { throw new Error('Assertion failed'); } if ( - !((toString(getValueFromObjectRawData(response, 'age')) as string) == '34') + !( + (toString(getValueFromObjectRawData(response, 'answer.age')) as string) == + '34' + ) ) { throw new Error('Assertion failed'); } if ( !( - (toString(getValueFromObjectRawData(response, 'hobby')) as string) == - (['guitar'].map(toString).join(',') as string) + (toString( + getValueFromObjectRawData(response, 'answer.hobby'), + ) as string) == (['guitar'].map(toString).join(',') as string) ) ) { throw new Error('Assertion failed'); } + if (!(response.completionReason == 'done')) { + throw new Error('Assertion failed'); + } await client.metadataTemplates.deleteMetadataTemplate( 'enterprise' as DeleteMetadataTemplateScope, template.templateKey!,