P1 bugs for copilot

This commit is contained in:
Sung-Hyun Kang (from Dev Box)
2023-11-09 20:36:26 -06:00
parent 0e124f4881
commit a12e8b050f
8 changed files with 42 additions and 664 deletions

View File

@@ -79,7 +79,7 @@ let configContext: Readonly<ConfigContext> = {
ARCADIA_LIVY_ENDPOINT_DNS_ZONE: "dev.azuresynapse.net",
GITHUB_CLIENT_ID: "6cb2f63cf6f7b5cbdeca", // Registered OAuth app: https://github.com/organizations/AzureCosmosDBNotebooks/settings/applications/1189306
GITHUB_TEST_ENV_CLIENT_ID: "b63fc8cbf87fd3c6e2eb", // Registered OAuth app: https://github.com/organizations/AzureCosmosDBNotebooks/settings/applications/1777772
JUNO_ENDPOINT: JunoEndpoints.Prod,
JUNO_ENDPOINT: JunoEndpoints.Stage,
BACKEND_ENDPOINT: "https://main.documentdb.ext.azure.com",
isTerminalEnabled: false,
isPhoenixEnabled: false,

View File

@@ -1388,8 +1388,9 @@ export default class Explorer {
if (userContext.apiType !== "SQL") {
return;
}
const copilotEnabled = await getCopilotEnabled();
const copilotUserDBEnabled = await isCopilotFeatureRegistered(userContext.subscriptionId);
const copilotEnabledPromise = getCopilotEnabled();
const copilotUserDBEnabledPromise = isCopilotFeatureRegistered(userContext.subscriptionId);
const [copilotEnabled, copilotUserDBEnabled] = await Promise.all([copilotEnabledPromise, copilotUserDBEnabledPromise])
useQueryCopilot.getState().setCopilotEnabled(copilotEnabled);
useQueryCopilot.getState().setCopilotUserDBEnabled(copilotUserDBEnabled);
}

View File

@@ -1,4 +1,4 @@
import { Checkbox, ChoiceGroup, DefaultButton, IconButton, PrimaryButton, TextField } from "@fluentui/react";
import { Checkbox, DefaultButton, IconButton, PrimaryButton, TextField } from "@fluentui/react";
import Explorer from "Explorer/Explorer";
import { QueryCopilotFeedbackModal } from "Explorer/QueryCopilot/Modal/QueryCopilotFeedbackModal";
import { useCopilotStore } from "Explorer/QueryCopilot/QueryCopilotContext";
@@ -83,42 +83,6 @@ describe("Query Copilot Feedback Modal snapshot test", () => {
expect(wrapper).toMatchSnapshot();
});
it("should record user contact choice no", () => {
const wrapper = shallow(
<QueryCopilotFeedbackModal
explorer={new Explorer()}
databaseId="CopilotUserDb"
containerId="CopilotUserContainer"
mode="User"
/>,
);
const contactAllowed = wrapper.find(ChoiceGroup);
contactAllowed.simulate("change", {}, { key: "no" });
expect(getUserEmail).toHaveBeenCalledTimes(3);
expect(wrapper.find(ChoiceGroup).props().selectedKey).toEqual("no");
expect(wrapper).toMatchSnapshot();
});
it("should record user contact choice yes", () => {
const wrapper = shallow(
<QueryCopilotFeedbackModal
explorer={new Explorer()}
databaseId="CopilotUserDb"
containerId="CopilotUserContainer"
mode="User"
/>,
);
const contactAllowed = wrapper.find(ChoiceGroup);
contactAllowed.simulate("change", {}, { key: "yes" });
expect(getUserEmail).toHaveBeenCalledTimes(4);
expect(wrapper.find(ChoiceGroup).props().selectedKey).toEqual("yes");
expect(wrapper).toMatchSnapshot();
});
it("should not render dont show again button", () => {
const wrapper = shallow(
<QueryCopilotFeedbackModal
@@ -219,7 +183,6 @@ describe("Query Copilot Feedback Modal snapshot test", () => {
generatedQuery: "test query",
userPrompt: "test prompt",
description: "",
contact: getUserEmail(),
},
explorer: explorer,
});

View File

@@ -1,6 +1,5 @@
import {
Checkbox,
ChoiceGroup,
DefaultButton,
IconButton,
Link,
@@ -8,13 +7,12 @@ import {
PrimaryButton,
Stack,
Text,
TextField,
TextField
} from "@fluentui/react";
import Explorer from "Explorer/Explorer";
import { useCopilotStore } from "Explorer/QueryCopilot/QueryCopilotContext";
import { SubmitFeedback } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
import React from "react";
import { getUserEmail } from "../../../Utils/UserUtils";
export const QueryCopilotFeedbackModal = ({
explorer,
@@ -35,16 +33,14 @@ export const QueryCopilotFeedbackModal = ({
closeFeedbackModal,
setHideFeedbackModalForLikedQueries,
} = useCopilotStore();
const [isContactAllowed, setIsContactAllowed] = React.useState<boolean>(false);
const [description, setDescription] = React.useState<string>("");
const [doNotShowAgainChecked, setDoNotShowAgainChecked] = React.useState<boolean>(false);
const [contact, setContact] = React.useState<string>(getUserEmail());
const handleSubmit = () => {
closeFeedbackModal();
setHideFeedbackModalForLikedQueries(doNotShowAgainChecked);
SubmitFeedback({
params: { generatedQuery, likeQuery, description, userPrompt, contact },
params: { generatedQuery, likeQuery, description, userPrompt },
explorer,
databaseId,
containerId,
@@ -77,30 +73,6 @@ export const QueryCopilotFeedbackModal = ({
defaultValue={generatedQuery}
readOnly
/>
<ChoiceGroup
styles={{
root: {
marginBottom: 14,
},
flexContainer: {
selectors: {
".ms-ChoiceField-field::before": { marginTop: 4 },
".ms-ChoiceField-field::after": { marginTop: 4 },
".ms-ChoiceFieldLabel": { paddingLeft: 6 },
},
},
}}
label="May we contact you about your feedback?"
options={[
{ key: "yes", text: "Yes, you may contact me." },
{ key: "no", text: "No, do not contact me." },
]}
selectedKey={isContactAllowed ? "yes" : "no"}
onChange={(_, option) => {
setIsContactAllowed(option.key === "yes");
setContact(option.key === "yes" ? getUserEmail() : "");
}}
></ChoiceGroup>
<Text style={{ fontSize: 12, marginBottom: 14 }}>
By pressing submit, your feedback will be used to improve Microsoft products and services. Please see the{" "}
{

View File

@@ -76,43 +76,6 @@ exports[`Query Copilot Feedback Modal snapshot test shoud render and match snaps
}
}
/>
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text
style={
Object {
@@ -235,43 +198,6 @@ exports[`Query Copilot Feedback Modal snapshot test should cancel submission 1`]
}
}
/>
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text
style={
Object {
@@ -394,43 +320,6 @@ exports[`Query Copilot Feedback Modal snapshot test should close on cancel click
}
}
/>
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text
style={
Object {
@@ -553,43 +442,6 @@ exports[`Query Copilot Feedback Modal snapshot test should get user unput 1`] =
}
}
/>
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text
style={
Object {
@@ -712,361 +564,6 @@ exports[`Query Copilot Feedback Modal snapshot test should not render dont show
}
}
/>
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text
style={
Object {
"fontSize": 12,
"marginBottom": 14,
}
}
>
By pressing submit, your feedback will be used to improve Microsoft products and services. Please see the
<StyledLinkBase
href="https://privacy.microsoft.com/privacystatement"
target="_blank"
>
Privacy statement
</StyledLinkBase>
for more information.
</Text>
<Stack
horizontal={true}
horizontalAlign="end"
>
<CustomizedPrimaryButton
styles={
Object {
"root": Object {
"marginRight": 8,
},
}
}
type="submit"
>
Submit
</CustomizedPrimaryButton>
<CustomizedDefaultButton
onClick={[Function]}
>
Cancel
</CustomizedDefaultButton>
</Stack>
</Stack>
</form>
</Modal>
`;
exports[`Query Copilot Feedback Modal snapshot test should record user contact choice no 1`] = `
<Modal
isOpen={false}
>
<form
onSubmit={[Function]}
>
<Stack
style={
Object {
"padding": 24,
}
}
>
<Stack
horizontal={true}
horizontalAlign="space-between"
>
<Text
style={
Object {
"fontSize": 20,
"fontWeight": 600,
"marginBottom": 20,
}
}
>
Send feedback to Microsoft
</Text>
<CustomizedIconButton
iconProps={
Object {
"iconName": "Cancel",
}
}
onClick={[Function]}
/>
</Stack>
<Text
style={
Object {
"fontSize": 14,
"marginBottom": 14,
}
}
>
Your feedback will help improve the experience.
</Text>
<StyledTextFieldBase
label="Description"
multiline={true}
onChange={[Function]}
placeholder="Provide more details"
required={true}
rows={3}
styles={
Object {
"root": Object {
"marginBottom": 14,
},
}
}
value=""
/>
<StyledTextFieldBase
defaultValue="test query"
label="Query generated"
readOnly={true}
styles={
Object {
"root": Object {
"marginBottom": 14,
},
}
}
/>
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text
style={
Object {
"fontSize": 12,
"marginBottom": 14,
}
}
>
By pressing submit, your feedback will be used to improve Microsoft products and services. Please see the
<StyledLinkBase
href="https://privacy.microsoft.com/privacystatement"
target="_blank"
>
Privacy statement
</StyledLinkBase>
for more information.
</Text>
<Stack
horizontal={true}
horizontalAlign="end"
>
<CustomizedPrimaryButton
styles={
Object {
"root": Object {
"marginRight": 8,
},
}
}
type="submit"
>
Submit
</CustomizedPrimaryButton>
<CustomizedDefaultButton
onClick={[Function]}
>
Cancel
</CustomizedDefaultButton>
</Stack>
</Stack>
</form>
</Modal>
`;
exports[`Query Copilot Feedback Modal snapshot test should record user contact choice yes 1`] = `
<Modal
isOpen={false}
>
<form
onSubmit={[Function]}
>
<Stack
style={
Object {
"padding": 24,
}
}
>
<Stack
horizontal={true}
horizontalAlign="space-between"
>
<Text
style={
Object {
"fontSize": 20,
"fontWeight": 600,
"marginBottom": 20,
}
}
>
Send feedback to Microsoft
</Text>
<CustomizedIconButton
iconProps={
Object {
"iconName": "Cancel",
}
}
onClick={[Function]}
/>
</Stack>
<Text
style={
Object {
"fontSize": 14,
"marginBottom": 14,
}
}
>
Your feedback will help improve the experience.
</Text>
<StyledTextFieldBase
label="Description"
multiline={true}
onChange={[Function]}
placeholder="Provide more details"
required={true}
rows={3}
styles={
Object {
"root": Object {
"marginBottom": 14,
},
}
}
value=""
/>
<StyledTextFieldBase
defaultValue="test query"
label="Query generated"
readOnly={true}
styles={
Object {
"root": Object {
"marginBottom": 14,
},
}
}
/>
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="yes"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text
style={
Object {
@@ -1189,43 +686,6 @@ exports[`Query Copilot Feedback Modal snapshot test should render dont show agai
}
}
/>
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text
style={
Object {
@@ -1363,43 +823,6 @@ exports[`Query Copilot Feedback Modal snapshot test should submit submission 1`]
}
}
/>
<StyledChoiceGroup
label="May we contact you about your feedback?"
onChange={[Function]}
options={
Array [
Object {
"key": "yes",
"text": "Yes, you may contact me.",
},
Object {
"key": "no",
"text": "No, do not contact me.",
},
]
}
selectedKey="no"
styles={
Object {
"flexContainer": Object {
"selectors": Object {
".ms-ChoiceField-field::after": Object {
"marginTop": 4,
},
".ms-ChoiceField-field::before": Object {
"marginTop": 4,
},
".ms-ChoiceFieldLabel": Object {
"paddingLeft": 6,
},
},
},
"root": Object {
"marginBottom": 14,
},
}
}
/>
<Text
style={
Object {

View File

@@ -19,6 +19,7 @@ import {
TextField,
} from "@fluentui/react";
import { useBoolean } from "@fluentui/react-hooks";
import { HttpStatusCodes } from "Common/Constants";
import { handleError } from "Common/ErrorHandlingUtils";
import { createUri } from "Common/UrlUtility";
import { WelcomeModal } from "Explorer/QueryCopilot/Modal/WelcomeModal";
@@ -53,7 +54,15 @@ type QueryCopilotPromptProps = QueryCopilotProps & {
const promptStyles: IButtonStyles = {
root: { border: 0, selectors: { ":hover": { outline: "1px dashed #605e5c" } } },
label: { fontWeight: 400, textAlign: "left", paddingLeft: 8 },
label: {
fontWeight: 400,
textAlign: "left",
paddingLeft: 8,
overflow: "hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
},
textContainer: { overflow: "hidden" },
};
export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
@@ -98,6 +107,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
setGeneratedQueryComments,
setQueryResults,
setErrorMessage,
errorMessage
} = useCopilotStore();
const sampleProps: SamplePromptsProps = {
@@ -230,6 +240,16 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
responseCode: response.status,
});
}
} else if (response?.status === HttpStatusCodes.TooManyRequests) {
handleError(JSON.stringify(generateSQLQueryResponse), "copilotTooManyRequestError");
useTabs.getState().setIsQueryErrorThrown(true);
setShowErrorMessageBar(true);
setErrorMessage("Ratelimit exceeded 5 per 1 minute. Please try again after sometime")
TelemetryProcessor.traceFailure(Action.QueryGenerationFromCopilotPrompt, {
databaseName: databaseId,
collectionId: containerId,
responseCode: response.status,
});
} else {
handleError(JSON.stringify(generateSQLQueryResponse), "copilotInternalServerError");
useTabs.getState().setIsQueryErrorThrown(true);
@@ -361,7 +381,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
{isGeneratingQuery && <Spinner style={{ marginLeft: 8 }} />}
{showSamplePrompts && (
<Callout
styles={{ root: { minWidth: 400 } }}
styles={{ root: { minWidth: 400, maxWidth: "70vw" } }}
target="#naturalLanguageInput"
isBeakVisible={false}
onDismiss={() => setShowSamplePrompts(false)}
@@ -393,7 +413,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
setShowSamplePrompts(false);
inputEdited.current = true;
}}
onRenderIcon={() => <Image src={RecentIcon} />}
onRenderIcon={() => <Image src={RecentIcon} styles={{ root: { overflow: "unset" } }} />}
styles={promptStyles}
>
{history}
@@ -469,7 +489,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
</Link>
{showErrorMessageBar && (
<MessageBar messageBarType={MessageBarType.error}>
We ran into an error and were not able to execute query.
{errorMessage ? errorMessage : "We ran into an error and were not able to execute query."}
</MessageBar>
)}
{showInvalidQueryMessageBar && (

View File

@@ -443,7 +443,7 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
onCommandClick: () => {
this._toggleCopilot(!this.state.copilotActive);
},
commandButtonLabel: "Copilot",
commandButtonLabel: this.state.copilotActive ? "Disable Copilot" : "Enable Copilot",
ariaLabel: "Copilot",
hasPopup: false,
};

View File

@@ -58,19 +58,21 @@ export function useKnockoutExplorer(platform: Platform): Explorer {
userContext.features.phoenixNotebooks = true;
userContext.features.phoenixFeatures = true;
}
let explorer: Explorer;
if (platform === Platform.Hosted) {
const explorer = await configureHosted();
setExplorer(explorer);
explorer = await configureHosted();
} else if (platform === Platform.Emulator) {
const explorer = configureEmulator();
setExplorer(explorer);
explorer = configureEmulator();
} else if (platform === Platform.Portal) {
const explorer = await configurePortal();
setExplorer(explorer);
explorer = await configurePortal();
} else if (platform === Platform.Fabric) {
const explorer = await configureFabric();
setExplorer(explorer);
explorer = await configureFabric();
}
if (explorer && userContext.features.enableCopilot) {
await updateContextForCopilot(explorer);
await updateContextForSampleData(explorer);
}
setExplorer(explorer);
}
};
effect();
@@ -79,9 +81,6 @@ export function useKnockoutExplorer(platform: Platform): Explorer {
useEffect(() => {
if (explorer) {
applyExplorerBindings(explorer);
if (userContext.features.enableCopilot) {
updateContextForCopilot(explorer).then(() => updateContextForSampleData(explorer));
}
}
}, [explorer]);