[Query Copilot] Adding feature flags for phoenix and Schema (#1583)

* Adding feature flags for phoenix and schema

* Feedback uri modified

* Additional Constant changes

* Reverting PriorityLevel

* Additional changes in tests

---------

Co-authored-by: Predrag Klepic <v-prklepic@microsoft.com>
This commit is contained in:
Predrag Klepic 2023-08-21 16:16:32 +02:00 committed by GitHub
parent 143f7d8f2c
commit 986dbe7d54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 108 additions and 17 deletions

View File

@ -430,6 +430,12 @@ export class JunoEndpoints {
public static readonly Stage = "https://tools-staging.cosmos.azure.com"; public static readonly Stage = "https://tools-staging.cosmos.azure.com";
} }
export class PriorityLevel {
public static readonly High = "high";
public static readonly Low = "low";
public static readonly Default = "low";
}
export const QueryCopilotSampleDatabaseId = "CopilotSampleDb"; export const QueryCopilotSampleDatabaseId = "CopilotSampleDb";
export const QueryCopilotSampleContainerId = "SampleContainer"; export const QueryCopilotSampleContainerId = "SampleContainer";
@ -601,8 +607,68 @@ export const QueryCopilotSampleContainerSchema = {
}, },
}; };
export class PriorityLevel { export const ShortenedQueryCopilotSampleContainerSchema = {
public static readonly High = "high"; containerSchema: {
public static readonly Low = "low"; product: {
public static readonly Default = "low"; sampleData: {
} categoryName: "Components, Saddles",
name: "LL Road Seat/Saddle",
price: 27.12,
tags: [
{
id: "0573D684-9140-4DEE-89AF-4E4A90E65666",
name: "Tag-113",
},
{
id: "6C2F05C8-1E61-4912-BE1A-C67A378429BB",
name: "Tag-5",
},
],
},
schema: {
properties: {
categoryName: {
type: "string",
},
name: {
type: "string",
},
price: {
type: "number",
},
tags: {
items: {
properties: {
id: {
type: "string",
},
name: {
type: "string",
},
},
type: "object",
},
type: "array",
},
},
type: "object",
},
},
},
userPrompt: "find all products",
};

View File

@ -17,7 +17,11 @@ import {
TextField, TextField,
} from "@fluentui/react"; } from "@fluentui/react";
import { useBoolean } from "@fluentui/react-hooks"; import { useBoolean } from "@fluentui/react-hooks";
import { QueryCopilotSampleContainerId, QueryCopilotSampleContainerSchema } from "Common/Constants"; import {
QueryCopilotSampleContainerId,
QueryCopilotSampleContainerSchema,
ShortenedQueryCopilotSampleContainerSchema,
} from "Common/Constants";
import { getErrorMessage, handleError } from "Common/ErrorHandlingUtils"; import { getErrorMessage, handleError } from "Common/ErrorHandlingUtils";
import { shouldEnableCrossPartitionKey } from "Common/HeadersUtility"; import { shouldEnableCrossPartitionKey } from "Common/HeadersUtility";
import { MinimalQueryIterator } from "Common/IteratorUtilities"; import { MinimalQueryIterator } from "Common/IteratorUtilities";
@ -186,7 +190,7 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({ explorer }: Qu
const generateSQLQuery = async (): Promise<void> => { const generateSQLQuery = async (): Promise<void> => {
try { try {
if (shouldAllocateContainer) { if (shouldAllocateContainer && userContext.features.enableCopilotPhoenixGateaway) {
await explorer.allocateContainer(); await explorer.allocateContainer();
setShouldAllocateContainer(false); setShouldAllocateContainer(false);
} }
@ -195,13 +199,17 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({ explorer }: Qu
useTabs.getState().setIsTabExecuting(true); useTabs.getState().setIsTabExecuting(true);
useTabs.getState().setIsQueryErrorThrown(false); useTabs.getState().setIsQueryErrorThrown(false);
const payload = { const payload = {
containerSchema: QueryCopilotSampleContainerSchema, containerSchema: userContext.features.enableCopilotFullSchema
? QueryCopilotSampleContainerSchema
: ShortenedQueryCopilotSampleContainerSchema,
userPrompt: userPrompt, userPrompt: userPrompt,
}; };
setShowDeletePopup(false); setShowDeletePopup(false);
useQueryCopilot.getState().refreshCorrelationId(); useQueryCopilot.getState().refreshCorrelationId();
const serverInfo = useNotebook.getState().notebookServerInfo; const serverInfo = useNotebook.getState().notebookServerInfo;
const queryUri = createUri(serverInfo.notebookServerEndpoint, "generateSQLQuery"); const queryUri = userContext.features.enableCopilotPhoenixGateaway
? createUri(serverInfo.notebookServerEndpoint, "generateSQLQuery")
: createUri("https://copilotorchestrater.azurewebsites.net/", "generateSQLQuery");
const response = await fetch(queryUri, { const response = await fetch(queryUri, {
method: "POST", method: "POST",
headers: { headers: {

View File

@ -1,11 +1,13 @@
import { FeedOptions } from "@azure/cosmos"; import { FeedOptions } from "@azure/cosmos";
import { QueryCopilotSampleContainerSchema } from "Common/Constants"; import { QueryCopilotSampleContainerSchema, ShortenedQueryCopilotSampleContainerSchema } from "Common/Constants";
import { handleError } from "Common/ErrorHandlingUtils"; import { handleError } from "Common/ErrorHandlingUtils";
import { sampleDataClient } from "Common/SampleDataClient"; import { sampleDataClient } from "Common/SampleDataClient";
import { createUri } from "Common/UrlUtility";
import * as commonUtils from "Common/dataAccess/queryDocuments"; import * as commonUtils from "Common/dataAccess/queryDocuments";
import Explorer from "Explorer/Explorer"; import Explorer from "Explorer/Explorer";
import { useNotebook } from "Explorer/Notebook/useNotebook"; import { useNotebook } from "Explorer/Notebook/useNotebook";
import DocumentId from "Explorer/Tree/DocumentId"; import DocumentId from "Explorer/Tree/DocumentId";
import { userContext } from "UserContext";
import { querySampleDocuments, readSampleDocument, submitFeedback } from "./QueryCopilotUtilities"; import { querySampleDocuments, readSampleDocument, submitFeedback } from "./QueryCopilotUtilities";
jest.mock("Explorer/Tree/DocumentId", () => { jest.mock("Explorer/Tree/DocumentId", () => {
@ -70,7 +72,9 @@ describe("QueryCopilotUtilities", () => {
userPrompt: "UserPrompt", userPrompt: "UserPrompt",
description: "Description", description: "Description",
contact: "Contact", contact: "Contact",
containerSchema: QueryCopilotSampleContainerSchema, containerSchema: userContext.features.enableCopilotFullSchema
? QueryCopilotSampleContainerSchema
: ShortenedQueryCopilotSampleContainerSchema,
}; };
const mockStore = useNotebook.getState(); const mockStore = useNotebook.getState();
@ -82,11 +86,14 @@ describe("QueryCopilotUtilities", () => {
}; };
}); });
const feedbackUri = userContext.features.enableCopilotPhoenixGateaway
? createUri(useNotebook.getState().notebookServerInfo.notebookServerEndpoint, "feedback")
: createUri("https://copilotorchestrater.azurewebsites.net/", "feedback");
it("should call fetch with the payload with like", async () => { it("should call fetch with the payload with like", async () => {
const mockFetch = jest.fn().mockResolvedValueOnce({}); const mockFetch = jest.fn().mockResolvedValueOnce({});
globalThis.fetch = mockFetch; globalThis.fetch = mockFetch;
await submitFeedback({ await submitFeedback({
params: { params: {
likeQuery: true, likeQuery: true,
@ -99,7 +106,7 @@ describe("QueryCopilotUtilities", () => {
}); });
expect(mockFetch).toHaveBeenCalledWith( expect(mockFetch).toHaveBeenCalledWith(
"mocked-endpoint/feedback", feedbackUri,
expect.objectContaining({ expect.objectContaining({
headers: expect.objectContaining({ headers: expect.objectContaining({
"x-ms-correlationid": "mocked-correlation-id", "x-ms-correlationid": "mocked-correlation-id",
@ -131,7 +138,7 @@ describe("QueryCopilotUtilities", () => {
}); });
expect(mockFetch).toHaveBeenCalledWith( expect(mockFetch).toHaveBeenCalledWith(
"mocked-endpoint/feedback", feedbackUri,
expect.objectContaining({ expect.objectContaining({
method: "POST", method: "POST",
headers: { headers: {

View File

@ -3,6 +3,7 @@ import {
QueryCopilotSampleContainerId, QueryCopilotSampleContainerId,
QueryCopilotSampleContainerSchema, QueryCopilotSampleContainerSchema,
QueryCopilotSampleDatabaseId, QueryCopilotSampleDatabaseId,
ShortenedQueryCopilotSampleContainerSchema,
} from "Common/Constants"; } from "Common/Constants";
import { handleError } from "Common/ErrorHandlingUtils"; import { handleError } from "Common/ErrorHandlingUtils";
import { sampleDataClient } from "Common/SampleDataClient"; import { sampleDataClient } from "Common/SampleDataClient";
@ -12,6 +13,7 @@ import { getCommonQueryOptions } from "Common/dataAccess/queryDocuments";
import Explorer from "Explorer/Explorer"; import Explorer from "Explorer/Explorer";
import { useNotebook } from "Explorer/Notebook/useNotebook"; import { useNotebook } from "Explorer/Notebook/useNotebook";
import DocumentId from "Explorer/Tree/DocumentId"; import DocumentId from "Explorer/Tree/DocumentId";
import { userContext } from "UserContext";
import { logConsoleProgress } from "Utils/NotificationConsoleUtils"; import { logConsoleProgress } from "Utils/NotificationConsoleUtils";
import { useQueryCopilot } from "hooks/useQueryCopilot"; import { useQueryCopilot } from "hooks/useQueryCopilot";
@ -34,19 +36,23 @@ export const submitFeedback = async ({
const { likeQuery, generatedQuery, userPrompt, description, contact } = params; const { likeQuery, generatedQuery, userPrompt, description, contact } = params;
const { correlationId, shouldAllocateContainer, setShouldAllocateContainer } = useQueryCopilot(); const { correlationId, shouldAllocateContainer, setShouldAllocateContainer } = useQueryCopilot();
const payload = { const payload = {
containerSchema: QueryCopilotSampleContainerSchema, containerSchema: userContext.features.enableCopilotFullSchema
? QueryCopilotSampleContainerSchema
: ShortenedQueryCopilotSampleContainerSchema,
like: likeQuery ? "like" : "dislike", like: likeQuery ? "like" : "dislike",
generatedSql: generatedQuery, generatedSql: generatedQuery,
userPrompt, userPrompt,
description: description || "", description: description || "",
contact: contact || "", contact: contact || "",
}; };
if (shouldAllocateContainer) { if (shouldAllocateContainer && userContext.features.enableCopilotPhoenixGateaway) {
await explorer.allocateContainer(); await explorer.allocateContainer();
setShouldAllocateContainer(false); setShouldAllocateContainer(false);
} }
const serverInfo = useNotebook.getState().notebookServerInfo; const serverInfo = useNotebook.getState().notebookServerInfo;
const feedbackUri = createUri(serverInfo.notebookServerEndpoint, "feedback"); const feedbackUri = userContext.features.enableCopilotPhoenixGateaway
? createUri(serverInfo.notebookServerEndpoint, "feedback")
: createUri("https://copilotorchestrater.azurewebsites.net/", "feedback");
const response = await fetch(feedbackUri, { const response = await fetch(feedbackUri, {
method: "POST", method: "POST",
headers: { headers: {

View File

@ -39,6 +39,8 @@ export type Features = {
readonly enablePriorityBasedThrottling: boolean; readonly enablePriorityBasedThrottling: boolean;
readonly enableNPSSurvey: boolean; readonly enableNPSSurvey: boolean;
readonly copilotVersion?: string; readonly copilotVersion?: string;
readonly enableCopilotPhoenixGateaway: boolean;
readonly enableCopilotFullSchema: boolean;
// can be set via both flight and feature flag // can be set via both flight and feature flag
autoscaleDefault: boolean; autoscaleDefault: boolean;
@ -110,6 +112,8 @@ export function extractFeatures(given = new URLSearchParams(window.location.sear
enableNPSSurvey: "true" === get("enablenpssurvey"), enableNPSSurvey: "true" === get("enablenpssurvey"),
enableCopilot: "true" === get("enablecopilot"), enableCopilot: "true" === get("enablecopilot"),
copilotVersion: get("copilotVersion") ? get("copilotVersion") : "v1.0", copilotVersion: get("copilotVersion") ? get("copilotVersion") : "v1.0",
enableCopilotPhoenixGateaway: "true" === get("enablecopilotphoenixgateaway"),
enableCopilotFullSchema: "true" === get("enablecopilotfullschema"),
}; };
} }