Skip to content

Commit

Permalink
Merge branch 'main' into users/nityagi/CompleteNavigationLoop
Browse files Browse the repository at this point in the history
  • Loading branch information
tyaginidhi committed Sep 19, 2023
2 parents cb5a088 + e2504dd commit 5cc2f13
Show file tree
Hide file tree
Showing 34 changed files with 871 additions and 218 deletions.
21 changes: 19 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,16 @@
"type": "boolean",
"markdownDescription": "Enable multiple file view in Visual Studio Code (Web extension only)",
"default": true
},
"powerPlatform.experimental.enableWebCopilot": {
"type": "boolean",
"markdownDescription": "Enable copilot in Visual Studio Code (Web extension)",
"default": true
},
"powerPlatform.experimental.enableCoPresenceFeature": {
"type": "boolean",
"markdownDescription": "Enable co-presence in Visual Studio Code (Web extension only)",
"default": false
}
}
},
Expand Down Expand Up @@ -755,7 +765,7 @@
},
{
"command": "powerpages.copilot.clearConversation",
"when": "!virtualWorkspace && view == powerpages.copilot",
"when": "view == powerpages.copilot",
"group": "navigation"
}
],
Expand Down Expand Up @@ -853,7 +863,14 @@
"name": "Copilot In Power Pages",
"initialSize": 6,
"visibility": "visible",
"when": "!virtualWorkspace && powerpages.websiteYmlExists && config.powerPlatform.experimental.copilotEnabled"
"when": "(!virtualWorkspace && powerpages.websiteYmlExists && config.powerPlatform.experimental.copilotEnabled) || (isWeb && config.powerPlatform.experimental.enableWebCopilot)"
}
],
"explorer": [
{
"id": "powerpages.treeWebView",
"name": "Power Pages Actions",
"when": "isWeb && config.powerPlatform.experimental.enableCoPresenceFeature"
}
],
"explorer": [
Expand Down
3 changes: 3 additions & 0 deletions public/images/codicon-arrow-rightarrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 18 additions & 19 deletions src/client/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ import { readUserSettings } from "./telemetry/localfileusersettings";
import { initializeGenerator } from "./power-pages/create/CreateCommandWrapper";
import { disposeDiagnostics } from "./power-pages/validationDiagnostics";
import { bootstrapDiff } from "./power-pages/bootstrapdiff/BootstrapDiff";
import { CopilotNotificationShown, CopilotTryNotificationClickedEvent } from "../common/copilot/telemetry/telemetryConstants";
import { CopilotNotificationShown } from "../common/copilot/telemetry/telemetryConstants";
import { copilotNotificationPanel, disposeNotificationPanel } from "../common/copilot/welcome-notification/CopilotNotificationPanel";
import { COPILOT_NOTIFICATION_DISABLED } from "../common/copilot/constants";

let client: LanguageClient;
let _context: vscode.ExtensionContext;
Expand Down Expand Up @@ -161,18 +163,18 @@ export async function activate(
vscode.workspace.workspaceFolders?.map(
(fl) => ({ ...fl, uri: fl.uri.fsPath } as WorkspaceFolder)
) || [];

// TODO: Handle for VSCode.dev also
if (workspaceContainsPortalConfigFolder(workspaceFolders)) {
if (workspaceContainsPortalConfigFolder(workspaceFolders)) {
let telemetryData = '';
let listOfActivePortals = [];
try {
listOfActivePortals = getPortalsOrgURLs(workspaceFolders, _telemetry);
telemetryData = JSON.stringify(listOfActivePortals);
_telemetry.sendTelemetryEvent("VscodeDesktopUsage", {listOfActivePortals: telemetryData, countOfActivePortals: listOfActivePortals.length.toString()});
}catch(exception){
_telemetry.sendTelemetryException(exception as Error, {eventName: 'VscodeDesktopUsage'});
}
_telemetry.sendTelemetryEvent("VscodeDesktopUsage", { listOfActivePortals: telemetryData, countOfActivePortals: listOfActivePortals.length.toString() });
} catch (exception) {
_telemetry.sendTelemetryException(exception as Error, { eventName: 'VscodeDesktopUsage' });
}
_telemetry.sendTelemetryEvent("PowerPagesWebsiteYmlExists"); // Capture's PowerPages Users
vscode.commands.executeCommand('setContext', 'powerpages.websiteYmlExists', true);
initializeGenerator(_context, cliContext, _telemetry); // Showing the create command only if website.yml exists
Expand Down Expand Up @@ -208,6 +210,7 @@ export async function deactivate(): Promise<void> {

disposeDiagnostics();
deactivateDebugger();
disposeNotificationPanel();
}

function didOpenTextDocument(document: vscode.TextDocument): void {
Expand Down Expand Up @@ -351,22 +354,18 @@ function handleWorkspaceFolderChange() {
}
}

function showNotificationForCopilot(telemetry: TelemetryReporter, telemetryData:string, countOfActivePortals: string) {
if(vscode.workspace.getConfiguration('powerPlatform').get('experimental.copilotEnabled') === false) {
function showNotificationForCopilot(telemetry: TelemetryReporter, telemetryData: string, countOfActivePortals: string) {
if (vscode.workspace.getConfiguration('powerPlatform').get('experimental.copilotEnabled') === false) {
return;
}
const message = vscode.l10n.t('Get help writing code in HTML, CSS, and JS languages for Power Pages sites with Copilot.');
const actionTitle = vscode.l10n.t('Try Copilot for Power Pages');

telemetry.sendTelemetryEvent(CopilotNotificationShown, {listOfOrgs: telemetryData, countOfActivePortals});
const isCopilotNotificationDisabled = _context.globalState.get(COPILOT_NOTIFICATION_DISABLED, false);

if (!isCopilotNotificationDisabled) {
telemetry.sendTelemetryEvent(CopilotNotificationShown, { listOfOrgs: telemetryData, countOfActivePortals });
copilotNotificationPanel(_context, telemetry, telemetryData, countOfActivePortals);
}

vscode.window.showInformationMessage(message, actionTitle).then((selection) => {
if (selection === actionTitle) {
telemetry.sendTelemetryEvent(CopilotTryNotificationClickedEvent, {listOfOrgs: telemetryData, countOfActivePortals});

vscode.commands.executeCommand('powerpages.copilot.focus')
}
});
}

// allow for DI without direct reference to vscode's d.ts file: that definintions file is being generated at VS Code runtime
Expand Down
106 changes: 53 additions & 53 deletions src/common/ArtemisService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,63 +3,63 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*/

import fetch, {RequestInit} from "node-fetch";
import fetch, { RequestInit } from "node-fetch";
import { COPILOT_UNAVAILABLE, US_GEO } from "./copilot/constants";
import { ITelemetry } from "../client/telemetry/ITelemetry";
import { sendTelemetryEvent } from "./copilot/telemetry/copilotTelemetry";
import { CopilotArtemisFailureEvent, CopilotArtemisSuccessEvent } from "./copilot/telemetry/telemetryConstants";

export async function getIntelligenceEndpoint (orgId: string, telemetry:ITelemetry, sessionID:string) {
const { tstUrl, preprodUrl, prodUrl } = convertGuidToUrls(orgId);
const endpoints = [tstUrl, preprodUrl, prodUrl];
export async function getIntelligenceEndpoint(orgId: string, telemetry: ITelemetry, sessionID: string) {
const { tstUrl, preprodUrl, prodUrl } = convertGuidToUrls(orgId);
const endpoints = [tstUrl, preprodUrl, prodUrl];

const artemisResponse = await fetchIslandInfo(endpoints, telemetry, sessionID);
const artemisResponse = await fetchIslandInfo(endpoints, telemetry, sessionID);

if (!artemisResponse) {
return null;
}
if (!artemisResponse) {
return null;
}

const { clusterNumber, geoName, environment } = artemisResponse[0];
sendTelemetryEvent(telemetry, {eventName: CopilotArtemisSuccessEvent, copilotSessionId: sessionID, geoName: String(geoName), orgId: orgId})
const { geoName, environment, clusterNumber } = artemisResponse[0];
sendTelemetryEvent(telemetry, { eventName: CopilotArtemisSuccessEvent, copilotSessionId: sessionID, geoName: String(geoName), orgId: orgId });

if(geoName !== US_GEO) {
return COPILOT_UNAVAILABLE;
}
if (geoName !== US_GEO) {
return COPILOT_UNAVAILABLE;
}

const intelligenceEndpoint = `https://aibuildertextapiservice.${geoName}-il${clusterNumber}.gateway.${environment}.island.powerapps.com/v1.0/${orgId}/appintelligence/chat`
const intelligenceEndpoint = `https://aibuildertextapiservice.${geoName}-${'il' + clusterNumber}.gateway.${environment}.island.powerapps.com/v1.0/${orgId}/appintelligence/chat`

return intelligenceEndpoint;
return intelligenceEndpoint;

}

async function fetchIslandInfo(endpoints: string[], telemetry: ITelemetry, sessionID: string) {

const requestInit: RequestInit = {
method: 'GET',
redirect: 'follow'
};

try {
const promises = endpoints.map(async endpoint => {
try {
const response = await fetch(endpoint, requestInit);
if (!response.ok) {
throw new Error('Request failed');
}
return response.json();
} catch (error) {
return null;
const requestInit: RequestInit = {
method: 'GET',
redirect: 'follow'
};

try {
const promises = endpoints.map(async endpoint => {
try {
const response = await fetch(endpoint, requestInit);
if (!response.ok) {
throw new Error('Request failed');
}
});

const responses = await Promise.all(promises);
const successfulResponses = responses.filter(response => response !== null);
return successfulResponses;
} catch (error) {
sendTelemetryEvent(telemetry, {eventName: CopilotArtemisFailureEvent, copilotSessionId: sessionID, error: error as Error})
return null;
}
return response.json();
} catch (error) {
return null;
}
});

const responses = await Promise.all(promises);
const successfulResponses = responses.filter(response => response !== null);
return successfulResponses;
} catch (error) {
sendTelemetryEvent(telemetry, { eventName: CopilotArtemisFailureEvent, copilotSessionId: sessionID, error: error as Error })
return null;
}
}


/**
Expand All @@ -71,18 +71,18 @@ async function fetchIslandInfo(endpoints: string[], telemetry: ITelemetry, sessi
* Prod: https:// c7809087d9b84a00a78aa4b901caa2.3f.organization.api.powerplatform.com/artemis
*/
export function convertGuidToUrls(orgId: string) {
const updatedOrgId = orgId.replace(/-/g, "");
const domain = updatedOrgId.slice(0, -1);
const domainProd = updatedOrgId.slice(0, -2);
const nonProdSegment = updatedOrgId.slice(-1);
const prodSegment = updatedOrgId.slice(-2);
const tstUrl = `https://${domain}.${nonProdSegment}.organization.api.test.powerplatform.com/gateway/cluster?api-version=1`;
const preprodUrl = `https://${domain}.${nonProdSegment}.organization.api.preprod.powerplatform.com/gateway/cluster?api-version=1`;
const prodUrl = `https://${domainProd}.${prodSegment}.organization.api.powerplatform.com/gateway/cluster?api-version=1`;

return {
tstUrl,
preprodUrl,
prodUrl
};
const updatedOrgId = orgId.replace(/-/g, "");
const domain = updatedOrgId.slice(0, -1);
const domainProd = updatedOrgId.slice(0, -2);
const nonProdSegment = updatedOrgId.slice(-1);
const prodSegment = updatedOrgId.slice(-2);
const tstUrl = `https://${domain}.${nonProdSegment}.organization.api.test.powerplatform.com/gateway/cluster?api-version=1`;
const preprodUrl = `https://${domain}.${nonProdSegment}.organization.api.preprod.powerplatform.com/gateway/cluster?api-version=1`;
const prodUrl = `https://${domainProd}.${prodSegment}.organization.api.powerplatform.com/gateway/cluster?api-version=1`;

return {
tstUrl,
preprodUrl,
prodUrl
};
}
5 changes: 5 additions & 0 deletions src/common/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,8 @@ export function getExtensionVersion(): string {
export function getExtensionType(): string {
return vscode.env.uiKind === vscode.UIKind.Desktop ? "Desktop" : "Web";
}

export function openWalkthrough(extensionUri: vscode.Uri) {
const walkthroughUri = vscode.Uri.joinPath(extensionUri, 'src', 'common', 'copilot', 'assets', 'walkthrough', 'Copilot-In-PowerPages.md');
vscode.commands.executeCommand("markdown.showPreview", walkthroughUri);
}
10 changes: 3 additions & 7 deletions src/common/copilot/IntelligenceApiService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,10 @@ const clientVersion = getExtensionVersion();

export async function sendApiRequest(userPrompt: string, activeFileParams: IActiveFileParams, orgID: string, apiToken: string, sessionID: string, entityName: string, entityColumns: string[], telemetry: ITelemetry, aibEndpoint: string | null) {


if (!aibEndpoint) {
return NetworkError;
}




const requestBody = {
"question": userPrompt,
"top": 1,
Expand All @@ -40,8 +36,8 @@ export async function sendApiRequest(userPrompt: string, activeFileParams: IActi
"activeFileContent": '',
"targetEntity": entityName,
"targetColumns": entityColumns,
"clientType" : clientType,
"clientVersion" : clientVersion,
"clientType": clientType,
"clientVersion": clientVersion,
}
}
};
Expand Down Expand Up @@ -107,7 +103,7 @@ export async function sendApiRequest(userPrompt: string, activeFileParams: IActi
}
else if (errorCode === RELEVANCY_CHECK_FAILED || errorCode === INAPPROPRIATE_CONTENT || errorCode === INPUT_CONTENT_FILTERED) {
return MalaciousScenerioResponse;
} else if(errorCode === PROMPT_LIMIT_EXCEEDED || errorCode === INVALID_INFERENCE_INPUT) {
} else if (errorCode === PROMPT_LIMIT_EXCEEDED || errorCode === INVALID_INFERENCE_INPUT) {
return PromptLimitExceededResponse;
}
else if (errorMessage) {
Expand Down
Loading

0 comments on commit 5cc2f13

Please sign in to comment.