Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PowerPage][Copilot] Nl2Site and Nl2Page Service Integration for Site Create #1053

Merged
merged 4 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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';
amitjoshi438 marked this conversation as resolved.
Show resolved Hide resolved

// Telemetry Event Names
export const VSCODE_EXTENSION_GITHUB_POWER_PAGES_AGENT_INVOKED = 'VSCodeExtensionGitHubPowerPagesAgentInvoked';
Expand All @@ -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';

Original file line number Diff line number Diff line change
@@ -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",
amitjoshi438 marked this conversation as resolved.
Show resolved Hide resolved
"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
amitjoshi438 marked this conversation as resolved.
Show resolved Hide resolved
"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",
amitjoshi438 marked this conversation as resolved.
Show resolved Hide resolved
"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);
}
Original file line number Diff line number Diff line change
@@ -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",
amitjoshi438 marked this conversation as resolved.
Show resolved Hide resolved
// "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",
amitjoshi438 marked this conversation as resolved.
Show resolved Hide resolved
"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;
}
}
Loading