From de5b198570d34624b8444f7b544036d775ca984a Mon Sep 17 00:00:00 2001 From: amitjoshi Date: Fri, 25 Oct 2024 12:47:26 +0530 Subject: [PATCH] Refactor PowerPagesChatParticipantConstants and add NL2PAGE and NL2SITE constants --- .../PowerPagesChatParticipantConstants.ts | 7 +- .../commands/create-site/Nl2PageService.ts | 70 +++++++++++++++++++ .../commands/create-site/Nl2SiteService.ts | 55 +++++++++++++++ 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 src/common/chat-participants/powerpages/commands/create-site/Nl2PageService.ts create mode 100644 src/common/chat-participants/powerpages/commands/create-site/Nl2SiteService.ts diff --git a/src/common/chat-participants/powerpages/PowerPagesChatParticipantConstants.ts b/src/common/chat-participants/powerpages/PowerPagesChatParticipantConstants.ts index 969f5bc5..b46b0d84 100644 --- a/src/common/chat-participants/powerpages/PowerPagesChatParticipantConstants.ts +++ b/src/common/chat-participants/powerpages/PowerPagesChatParticipantConstants.ts @@ -42,6 +42,8 @@ export const DISCLAIMER_MESSAGE = vscode.l10n.t('Make sure AI-generated content export const NO_PROMPT_MESSAGE = vscode.l10n.t('Hi! Power Pages lets you build secure, professional websites that you can quickly configure and publish across web browsers and devices.\n\nTo create your website, visit the [Power Pages](https://powerpages.microsoft.com/).\nReturn to this chat and @powerpages can help you write and edit your website code.'); export const PAC_AUTH_INPUT = vscode.l10n.t("Checking for active auth profile..."); export const COPILOT_NOT_RELEASED_MSG = vscode.l10n.t("@PowerPages is not yet available in your region.") +export const NL2PAGE_REQUEST_FAILED = 'Request failed for page type:'; +export const NL2SITE_INVALID_RESPONSE = 'Invalid response structure'; // Telemetry Event Names export const VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_INVOKED = 'VSCodeExtensionGitHubPowerPagesAgentInvoked'; @@ -57,5 +59,8 @@ export const VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_NO_PROMPT = 'VSCodeExtens export const VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_WELCOME_PROMPT = 'VSCodeExtensionGitHubPowerPagesAgentWelcomePrompt'; export const VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_SUCCESSFUL_PROMPT = 'VSCodeExtensionGitHubPowerPagesAgentSuccessfulPrompt'; export const VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_NOT_AVAILABLE_ECS = 'VSCodeExtensionGitHubPowerPagesAgentNotAvailableECS'; - +export const VSCODE_EXTENSION_NL2PAGE_REQUEST_FAILED = 'VSCodeExtensionNL2PageRequestFailed'; +export const VSCODE_EXTENSION_NL2PAGE_REQUEST_SUCCESS = 'VSCodeExtensionNL2PageRequestSuccess'; +export const VSCODE_EXTENSION_NL2SITE_REQUEST_FAILED = 'VSCodeExtensionNL2SiteRequestFailed'; +export const VSCODE_EXTENSION_NL2SITE_REQUEST_SUCCESS = 'VSCodeExtensionNL2SiteRequestSuccess'; diff --git a/src/common/chat-participants/powerpages/commands/create-site/Nl2PageService.ts b/src/common/chat-participants/powerpages/commands/create-site/Nl2PageService.ts new file mode 100644 index 00000000..d139f519 --- /dev/null +++ b/src/common/chat-participants/powerpages/commands/create-site/Nl2PageService.ts @@ -0,0 +1,70 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import { ITelemetry } from "../../../../OneDSLoggerTelemetry/telemetry/ITelemetry"; +import { NL2PAGE_REQUEST_FAILED, VSCODE_EXTENSION_NL2PAGE_REQUEST_FAILED, VSCODE_EXTENSION_NL2PAGE_REQUEST_SUCCESS } from "../../PowerPagesChatParticipantConstants"; + +export async function getNL2PageData(aibEndpoint: string, aibToken: string, userPrompt: string, siteName: string, sitePagesList: string[], sessionId: string, telemetry: ITelemetry) { + const constructRequestBody = (pageType: string) => ({ + "crossGeoOptions": { + "enableCrossGeoCall": true + }, + "question": `${userPrompt} - ${pageType} page`, + "context": { + "shouldCheckBlockList": false, + "sessionId": sessionId, + "scenario": "NL2Page", + "subScenario": "GenerateNewPage", + "version": "V1", + "information": { + "scope": "Page", + "includeImages": true, + "pageType": pageType === 'FAQ' ? 'FAQ' : 'Home', + "title": siteName, + "pageName": pageType, + "colorNumber": 7, // Add a function to get a random number + "shuffleImages": false, + "exampleNumber": 2 // Add a function to get a random number + } + } + }); + + const requests = sitePagesList.map(async pageType => { + const requestBody = constructRequestBody(pageType); + + const requestInit: RequestInit = { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${aibToken}` + }, + body: JSON.stringify(requestBody) + }; + + try { + const response = await fetch(aibEndpoint, requestInit); + if (!response.ok) { + throw new Error(`${NL2PAGE_REQUEST_FAILED} ${pageType}`); + } + + const responseData = await response.json(); + + if (responseData && responseData.additionalData[0]) { + return responseData.additionalData[0].snippets[0]; + } + return null; + } catch (error) { + telemetry.sendTelemetryErrorEvent(VSCODE_EXTENSION_NL2PAGE_REQUEST_FAILED, { error: (error as Error)?.message, pageType }); + return null; + } + }); + + const responses = await Promise.all(requests); + + telemetry.sendTelemetryEvent(VSCODE_EXTENSION_NL2PAGE_REQUEST_SUCCESS, { sessionId }); + + // TODO: Home page is mandatory, so if it is not generated, return null + return responses.filter(response => response !== null); +} diff --git a/src/common/chat-participants/powerpages/commands/create-site/Nl2SiteService.ts b/src/common/chat-participants/powerpages/commands/create-site/Nl2SiteService.ts new file mode 100644 index 00000000..9b090ebe --- /dev/null +++ b/src/common/chat-participants/powerpages/commands/create-site/Nl2SiteService.ts @@ -0,0 +1,55 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import { ITelemetry } from "../../../../OneDSLoggerTelemetry/telemetry/ITelemetry"; +import { NL2SITE_INVALID_RESPONSE, VSCODE_EXTENSION_NL2SITE_REQUEST_FAILED, VSCODE_EXTENSION_NL2SITE_REQUEST_SUCCESS } from "../../PowerPagesChatParticipantConstants"; + +export async function getNL2SiteData(aibEndpoint: string, aibToken: string, userPrompt: string, sessionId: string, telemetry: ITelemetry) { + const requestBody = { + "crossGeoOptions": { + "enableCrossGeoCall": true + }, + "question": userPrompt, + "context": { + "sessionId": sessionId, + "scenario": "NL2Site", + "subScenario": "GenerateNewSite", + // "shouldCheckBlockList": false, //TODO: Check if this is needed + "version": "V1", + "information": { + "minPages": 7, + "maxPages": 7 + } + } + }; + + const requestInit: RequestInit = { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${aibToken}` + }, + body: JSON.stringify(requestBody) + }; + + try { + const response = await fetch(aibEndpoint, requestInit); + if (!response.ok) { + throw new Error(`${response.statusText} - ${response.status}`); + } + + const responseBody = await response.json(); + + if (responseBody && responseBody.additionalData[0]?.website) { + telemetry.sendTelemetryEvent(VSCODE_EXTENSION_NL2SITE_REQUEST_SUCCESS, {sessionId: sessionId}); + return responseBody.additionalData[0].website; // Contains the pages, siteName & site description + } else { + throw new Error(NL2SITE_INVALID_RESPONSE); + } + } catch (error) { + telemetry.sendTelemetryErrorEvent(VSCODE_EXTENSION_NL2SITE_REQUEST_FAILED, { error: (error as Error)?.message }); + return null; + } +}