Skip to content

Commit 002d496

Browse files
greg-in-a-boxrustam-emergify[bot]
authored
feat(content-answers): Upgrade Content Answers (#3658)
* fix(docgen-sidebar): add collapsible component to hide nested tags (#3626) * fix(docgen-sidebar): add collapsible component to hide nested tags * fix(docgen-sidebar): nesting of tags in tag tree * fix(docgen-tags): update styles to use blueprint tokens * fix(docgen-tags): replace bdl tokens with blueprint tokens * fix(docgen-tags): convert test from enzyme to rtl * fix(docgen-tags): remove snapshots, reuse blueprint loader * fix(docgen-tags): address code review comments * fix(docgen-tags): remove the sidebar test file * fix(docgen-tags): file with updated name * Update src/elements/content-sidebar/__tests__/DocGenSidebar.test.tsx Co-authored-by: greg-in-a-box <103291617+greg-in-a-box@users.noreply.github.com> * Update src/elements/content-sidebar/__tests__/DocGenSidebar.test.tsx Co-authored-by: greg-in-a-box <103291617+greg-in-a-box@users.noreply.github.com> * fix(docgen-sidebar): address code review comments * fix(docgen-sidebar): address code review comments * fix(docgen-sidebar): remove unused mock --------- Co-authored-by: greg-in-a-box <103291617+greg-in-a-box@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * chore(storybook): Added global types for storybook * feat(content-answers): Upgrade Content Answers * feat(content-answers): fix tests * feat(content-answers): Enabled some new features * feat(content-answers): Feedback * chore(content-answers): feedback * feat(content-answers): Feedback * feat(content-answers): Feedback * feat(content-answers): Feedback * feat(content-answers): vrt width * feat(content-answers): Feedback * feat(content-answers): Feedback * feat(content-answers): Providers * feat(content-answers): Providers * feat(content-answers): Feedback * feat(content-answers): Feedback * feat(content-answers): tests * feat(content-answers): Feedback * feat(content-answers): Feedback --------- Co-authored-by: rustam-e <6816931+rustam-e@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent d2e59c8 commit 002d496

File tree

69 files changed

+1335
-1789
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1335
-1789
lines changed

.storybook/preview-body.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@
1616
}
1717

1818
.be.bcpr {
19-
height: 600px;
19+
height: 900px;
2020
}
2121

2222
.be.bcs {
23+
width: 1000px;
2324
height: 900px;
2425
}
2526
</style>

.storybook/preview.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,18 @@ initialize();
1919

2020
const preview = {
2121
parameters: {
22-
chromatic: { disableSnapshot: true },
22+
chromatic: {
23+
disableSnapshot: true,
24+
cropToViewport: true,
25+
modes: {
26+
specific: {
27+
viewport: {
28+
height: 1000,
29+
width: 1200,
30+
},
31+
},
32+
},
33+
},
2334
controls: {
2435
matchers: {
2536
color: /(background|color)$/i,

flow-typed/box-ui-elements.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type FileAPI from '../src/api/File';
1212
import type WebLinkAPI from '../src/api/WebLink';
1313
import type MultiputUploadAPI from '../src/api/uploads/MultiputUpload';
1414
import type PlainUploadAPI from '../src/api/uploads/PlainUpload';
15-
import type { ContentAnswersProps } from '../src/features/content-answers';
15+
import type { ContentAnswersProps } from '../src/elements/common/content-answers';
1616
import type { ContentSidebarProps } from '../src/elements/content-sidebar';
1717
import type { ContentOpenWithProps } from '../src/elements/content-open-with';
1818
import type { ContentPreviewProps } from '../src/elements/content-preview';

i18n/en-US.properties

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -942,38 +942,34 @@ boxui.collaboratorAvatars.viewAdditionalPeopleText = View additional people
942942
boxui.collapsiblesidebar.collapseBtnLabel = Collapse
943943
# Aria label for toggle button that expands/collapses sidebar (collapsed state)
944944
boxui.collapsiblesidebar.expandBtnLabel = Expand
945-
# Content Answers submit input button text
946-
boxui.contentAnswers.ask = Ask
947-
# Content Answers submit input button disabled tooltip text when answer is generating
948-
boxui.contentAnswers.askDisabledTooltip = You can submit another question once Box AI has finished responding
949-
# Content Answers modal input placeholder
950-
boxui.contentAnswers.askQuestionPlaceholder = Ask anything about this document
951945
# Content Answers feature name shown on menu item and modal title
952946
boxui.contentAnswers.contentAnswersTitle = Box AI
953947
# Default tooltip message for Content Answers entry point button
954948
boxui.contentAnswers.defaultTooltip = Get instant answers about this document using Box AI
955949
# Disabled tooltip message for Content Answers entry point button when the file type is not supported
956950
boxui.contentAnswers.disabledTooltipFileNotCompatible = Box AI is not currently supported for this file type
951+
# Text inside the chip for the first suggested question for documents
952+
boxui.contentAnswers.documentSuggestedQuestionLabel1 = Summarize this document
953+
# Text inside the chip for the second suggested question for documents
954+
boxui.contentAnswers.documentSuggestedQuestionLabel2 = What are the key takeaways?
955+
# Text inside the chip for the third suggested question for documents
956+
boxui.contentAnswers.documentSuggestedQuestionLabel3 = How can this document be improved?
957+
# Text inside the chip for the fourth suggested question for documents
958+
boxui.contentAnswers.documentSuggestedQuestionLabel4 = Are there any next steps defined?
959+
# Actual prompt for the first suggested question for documents
960+
boxui.contentAnswers.documentSuggestedQuestionPrompt1 = Summarize this document
961+
# Actual prompt for the second suggested question for documents
962+
boxui.contentAnswers.documentSuggestedQuestionPrompt2 = What are the key takeaways?
963+
# Actual prompt for the third suggested question for documents
964+
boxui.contentAnswers.documentSuggestedQuestionPrompt3 = How can this document be improved?
965+
# Actual prompt for the fourth suggested question for documents
966+
boxui.contentAnswers.documentSuggestedQuestionPrompt4 = Are there any next steps defined?
957967
# Existing questions tooltip message for Content Answers entry point button
958968
boxui.contentAnswers.hasQuestionsTooltip = Return to Box AI
959-
# Content Answers error message when the service fails
960-
boxui.contentAnswers.inlineErrorText = The Box AI service was unavailable.
961-
# Box AI Q&A service unavailable error description
962-
boxui.contentAnswers.intelligenceUnavailableDescription = The Box AI service is not responding.
963-
# Box AI Q&A service unavailable error title
964-
boxui.contentAnswers.intelligenceUnavailableHeading = Box AI is unavailable
965-
# Box AI Q&A service unavailable error try again later description
966-
boxui.contentAnswers.intelligenceUnavailableTryAgain = Please try again later.
967-
# Error tooltip to show inside text area if the user reached the character limit
968-
boxui.contentAnswers.maxCharactersReachedError = Maximum of {characterLimit} characters reached
969-
# Retry button label to send again the question to the service
970-
boxui.contentAnswers.retryResponse = Retry
971-
# Content Answers welcome message for asking questions
972-
boxui.contentAnswers.welcomeAskQuestionText = Ask questions about {name}
973-
# Content Answers welcome message for clearing the chat
974-
boxui.contentAnswers.welcomeClearChatText = This chat will be cleared when you close this document
975-
# Content Answers welcome message title
976-
boxui.contentAnswers.welcomeMessageTitle = Welcome to Box AI
969+
# Content Answers welcome message spreadsheet notification
970+
boxui.contentAnswers.welcomeMessageSpreadsheetNotice = Spreadsheet support works best for text dense files
971+
# Aria label for the icon inside spreadsheet notification
972+
boxui.contentAnswers.welcomeMessageSpreadsheetNoticeAriaLabel = spreadsheet support notification banner
977973
# Aria label for the folder breadcrumb
978974
boxui.contentExplorer.breadcrumb = Breadcrumb
979975
# Text shown on button used to close the content explorer

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
"@babel/types": "^7.24.7",
125125
"@box/blueprint-web": "^7.30.1",
126126
"@box/blueprint-web-assets": "^4.21.0",
127-
"@box/box-ai-content-answers": "^0.49.1",
127+
"@box/box-ai-content-answers": "^0.50.5",
128128
"@box/cldr-data": "^34.2.0",
129129
"@box/frontend": "^10.0.0",
130130
"@box/languages": "^1.0.0",
@@ -222,6 +222,7 @@
222222
"flow-typed": "^2.6.2",
223223
"form-serialize": "^0.7.2",
224224
"formik": "^2.0.3",
225+
"highlight.js": "^11.10.0",
225226
"husky": "^4.0.10",
226227
"ilib-tree-node": "^1.2.0",
227228
"immutable": "^3.7.4",
@@ -271,6 +272,7 @@
271272
"react-tether": "^1.0.5",
272273
"react-textarea-autosize": "^8.5.3",
273274
"regenerator-runtime": "^0.14.1",
275+
"remarkable": "^2.0.1",
274276
"sanitize-html": "^1.21.1",
275277
"sass": "^1.34.1",
276278
"sass-lint": "^1.13.1",
@@ -302,7 +304,7 @@
302304
"peerDependencies": {
303305
"@box/blueprint-web": "^7.30.1",
304306
"@box/blueprint-web-assets": "^4.21.0",
305-
"@box/box-ai-content-answers": "^0.49.1",
307+
"@box/box-ai-content-answers": "^0.50.5",
306308
"@box/cldr-data": ">=34.2.0",
307309
"@box/metadata-editor": "^0.54.0",
308310
"@box/react-virtualized": "9.22.3-rc-box.9",
@@ -314,6 +316,7 @@
314316
"filesize": "^4.1.2",
315317
"form-serialize": "^0.7.2",
316318
"formik": "^2.0.0",
319+
"highlight.js": "^11.10.0",
317320
"ilib-tree-node": "^1.2.0",
318321
"immutable": "^3.7.4",
319322
"intl-messageformat": "^7.8.4",
@@ -341,6 +344,7 @@
341344
"react-tether": "^1.0.5",
342345
"react-textarea-autosize": "^8.5.3",
343346
"regenerator-runtime": "^0.13.2",
347+
"remarkable": "^2.0.1",
344348
"sanitize-html": "^1.21.1",
345349
"sass": "^1.34.1",
346350
"scroll-into-view-if-needed": "^2.2.20",

scripts/jest/jest-setup.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,9 @@ global.setImmediate = cb => {
2323
Object.defineProperty(global, 'TextEncoder', {
2424
value: util.TextEncoder,
2525
});
26+
27+
global.ResizeObserver = jest.fn().mockImplementation(() => ({
28+
observe: jest.fn(),
29+
unobserve: jest.fn(),
30+
disconnect: jest.fn(),
31+
}));

scripts/jest/jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ module.exports = {
2626
testMatch: ['**/__tests__/**/*.test.+(js|jsx|ts|tsx)'],
2727
testPathIgnorePatterns: ['stories.test.js$', 'stories.test.tsx$', 'stories.test.d.ts'],
2828
transformIgnorePatterns: [
29-
'node_modules/(?!(@box/react-virtualized/dist/es|@box/cldr-data|@box/blueprint-web|@box/blueprint-web-assets|@box/metadata-editor)/)',
29+
'node_modules/(?!(@box/react-virtualized/dist/es|@box/cldr-data|@box/blueprint-web|@box/blueprint-web-assets|@box/metadata-editor|@box/box-ai-content-answers)/)',
3030
],
3131
};

scripts/styleguide.styles.scss

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,46 @@
1-
.be {
2-
&.bce,
3-
&.bcp {
4-
height: 600px;
5-
}
1+
#rsg-root {
2+
.be {
3+
&.bce,
4+
&.bcp {
5+
height: 600px;
6+
}
67

7-
&.bcpr {
8-
.bcs {
9-
box-shadow: initial;
8+
&.bcpr {
9+
.bcs {
10+
box-shadow: initial;
11+
}
1012
}
11-
}
1213

13-
&.bcu {
14-
height: 400px;
15-
}
14+
&.bcu {
15+
height: 400px;
16+
}
1617

17-
&.bcow {
18-
width: 100px;
19-
}
18+
&.bcow {
19+
width: 100px;
20+
}
2021

21-
&.bce,
22-
&.bcp,
23-
&.bcpr,
24-
&.bcs,
25-
&.bcu {
26-
box-shadow: 0 0 20px 0 rgba(85, 85, 85, .42);
22+
&.bce,
23+
&.bcp,
24+
&.bcpr,
25+
&.bcs,
26+
&.bcu {
27+
box-shadow: 0 0 20px 0 rgba(85, 85, 85, .42);
28+
}
2729
}
28-
}
2930

30-
[data-preview='ContentSidebar'] {
31-
> div {
32-
display: inline-block;
33-
}
31+
[data-preview='ContentSidebar'] {
32+
> div {
33+
display: inline-block;
34+
}
3435

35-
.bcs {
36-
height: 1000px;
36+
.bcs {
37+
height: 1000px;
38+
}
3739
}
38-
}
3940

40-
[data-preview='ContentPreview'] {
41-
.bcpr {
42-
height: 600px;
41+
[data-preview='ContentPreview'] {
42+
.bcpr {
43+
height: 600px;
44+
}
4345
}
4446
}

src/api/Intelligence.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
import getProp from 'lodash/get';
8+
import { QuestionType } from '@box/box-ai-content-answers';
89
import type { BoxItem } from '../common/types/core';
910
import { ERROR_CODE_EXTRACT_STRUCTURED } from '../constants';
1011
import { isUserCorrectableError } from '../utils/error';
@@ -16,11 +17,19 @@ class Intelligence extends Base {
1617
/**
1718
* API endpoint to ask ai a question
1819
*
19-
* @param {string} prompt - Question
20+
* @param {QuestionType} question - Object should at least contain the prompt, which is the question to ask
2021
* @param {Array<object>} items - Array of items to ask about
22+
* @param {Array<QuestionType>} dialogueHistory - Array of previous questions object that already have answers
23+
* @param {{ include_citations?: boolean }} options - Optional parameters
2124
* @return {Promise}
2225
*/
23-
async ask(prompt: string, items: Array<BoxItem>) {
26+
async ask(
27+
question: QuestionType,
28+
items: Array<BoxItem>,
29+
dialogueHistory: Array<QuestionType> = [],
30+
options: { include_citations?: boolean } = {},
31+
): Promise<any> {
32+
const { prompt } = question;
2433
if (!prompt) {
2534
throw new Error('Missing prompt!');
2635
}
@@ -44,6 +53,8 @@ class Intelligence extends Base {
4453
mode: 'single_item_qa',
4554
prompt,
4655
items,
56+
dialogue_history: dialogueHistory,
57+
...options,
4758
},
4859
});
4960
}

src/api/__tests__/Intelligence.test.js

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ describe('api/Intelligence', () => {
66

77
const mockItems = [{ id: '123', type: 'file' }];
88
const mockPrompt = 'summarize';
9+
const mockQuestion = { prompt: mockPrompt };
910

1011
beforeEach(() => {
1112
intelligence = new Intelligence({});
@@ -14,7 +15,7 @@ describe('api/Intelligence', () => {
1415
test('should return promise with data', async () => {
1516
const data = { data: 'foo' };
1617
intelligence.xhr.post = jest.fn().mockReturnValueOnce(Promise.resolve(data));
17-
const response = await intelligence.ask(mockPrompt, mockItems);
18+
const response = await intelligence.ask(mockQuestion, mockItems);
1819
expect(response).toEqual(data);
1920
});
2021

@@ -24,13 +25,32 @@ describe('api/Intelligence', () => {
2425
items: mockItems,
2526
mode: 'single_item_qa',
2627
prompt: mockPrompt,
28+
dialogue_history: [],
2729
},
2830
id: 'file_123',
2931
url: 'https://api.box.com/2.0/ai/ask',
3032
};
3133
const postMock = jest.fn();
3234
intelligence.xhr.post = postMock.mockReturnValueOnce(Promise.resolve({}));
33-
await intelligence.ask(mockPrompt, mockItems);
35+
await intelligence.ask(mockQuestion, mockItems);
36+
expect(postMock).toBeCalledWith(data);
37+
});
38+
39+
test('should make post to xhr with citations', async () => {
40+
const data = {
41+
data: {
42+
items: mockItems,
43+
mode: 'single_item_qa',
44+
prompt: mockPrompt,
45+
dialogue_history: [],
46+
include_citations: true,
47+
},
48+
id: 'file_123',
49+
url: 'https://api.box.com/2.0/ai/ask',
50+
};
51+
const postMock = jest.fn();
52+
intelligence.xhr.post = postMock.mockReturnValueOnce(Promise.resolve({}));
53+
await intelligence.ask(mockQuestion, mockItems, [], { include_citations: true });
3454
expect(postMock).toBeCalledWith(data);
3555
});
3656

@@ -44,7 +64,7 @@ describe('api/Intelligence', () => {
4464
}),
4565
);
4666
try {
47-
await intelligence.ask(mockPrompt, mockItems);
67+
await intelligence.ask(mockQuestion, mockItems);
4868
} catch (e) {
4969
expect(e).toEqual({
5070
response: {
@@ -60,7 +80,7 @@ describe('api/Intelligence', () => {
6080
${mockPrompt} | ${[{}]} | ${'Invalid item!'} | ${'item'}
6181
`('should throw error if $missing is missing ', async ({ prompt, items, message }) => {
6282
try {
63-
await intelligence.ask(prompt, items);
83+
await intelligence.ask({ prompt }, items);
6484
expect(true).toEqual(false); // should never hit this line, if it does then the test fails
6585
} catch (e) {
6686
expect(e.message).toEqual(message);
@@ -73,7 +93,7 @@ describe('api/Intelligence', () => {
7393
${[]} | ${'an empty array'}
7494
`('should throw error if items is $description ', async ({ badItems }) => {
7595
try {
76-
await intelligence.ask(prompt, badItems);
96+
await intelligence.ask(mockQuestion, badItems);
7797
expect(true).toEqual(false); // should never hit this line, if it does then the test fails
7898
} catch (e) {
7999
expect(e.message).toEqual('Missing items!');

src/components/media-query/__tests__/useMediaQuery.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// @flow
2-
32
import * as React from 'react';
43
import { mount } from 'enzyme';
4+
55
import useMediaQuery from '../useMediaQuery';
66

77
const WIDTH = 999;

src/elements/common/Providers.js.flow

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// @flow
2+
import * as React from 'react';
3+
import { Notification, TooltipProvider } from '@box/blueprint-web';
4+
5+
export interface ProvideProps {
6+
children: React.Node;
7+
hasProviders: ?boolean;
8+
}
9+
10+
const Provide = ({ children, hasProviders }: ProvideProps) => {
11+
if (hasProviders) {
12+
return (
13+
<Notification.Provider>
14+
<Notification.Viewport />
15+
<TooltipProvider>{children}</TooltipProvider>
16+
</Notification.Provider>
17+
);
18+
}
19+
20+
return React.Children.only(children);
21+
};
22+
23+
export default Provide;

0 commit comments

Comments
 (0)