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

Expand to EU and AU geos for copilot #781

Merged
merged 11 commits into from
Feb 12, 2024
106 changes: 55 additions & 51 deletions src/common/ArtemisService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,29 @@
*/

import fetch, { RequestInit } from "node-fetch";
import { COPILOT_UNAVAILABLE, US_GEO } from "./copilot/constants";
import { AUSTRALIA_GEO, COPILOT_UNAVAILABLE, EUROPE_GEO, UK_GEO, 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 artemisResponse = await fetchArtemisResponse(orgId, telemetry, sessionID);
const artemisResponse = await fetchArtemisResponse(orgId, telemetry, sessionID);

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

const { geoName, environment, clusterNumber } = 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 (!isGeoSupported(geoName)) {
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;

}

Expand All @@ -38,35 +38,35 @@ export async function fetchArtemisResponse(orgId: string, telemetry: ITelemetry,
const artemisResponse = await fetchIslandInfo(endpoints, telemetry, sessionID);

return artemisResponse;
}
}

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) {
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 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;
}
});

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 @@ -79,18 +79,22 @@ 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
};
}

export function isGeoSupported(geoName: string) {
return geoName === US_GEO || geoName === AUSTRALIA_GEO || geoName === EUROPE_GEO || geoName === UK_GEO;
}
29 changes: 16 additions & 13 deletions src/common/copilot/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ export const sendIconSvg = ` <svg width="16px" height="16px" viewBox="0 0 16 16"
export const CodiconStylePathSegments = ['src', 'common', 'copilot', 'assets', 'styles', 'codicon.css'];
export const CopilotStylePathSegments = ['src', 'common', 'copilot', 'assets', 'styles', 'copilot.css'];
export const US_GEO = 'us';
export const AUSTRALIA_GEO = 'au';
export const EUROPE_GEO = 'eu';
export const UK_GEO = 'uk';
export const COPILOT_UNAVAILABLE = 'copilotunavailable';
export const AUTH_CREATE_MESSAGE = vscode.l10n.t('Creating new Auth Profile');
export const AUTH_CREATE_FAILED = vscode.l10n.t("Error creating auth profile for org")
Expand All @@ -31,9 +34,9 @@ export const SELECTED_CODE_INFO = "selectedCodeInfo";
export const SELECTED_CODE_INFO_ENABLED = false;

export type WebViewMessage = {
type: string;
value?: string | number | boolean | object;
envName?: string;
type: string;
value?: string | number | boolean | object;
envName?: string;
};

export interface UserPrompt {
Expand All @@ -42,22 +45,22 @@ export interface UserPrompt {
}

export const DataverseEntityNameMap = new Map<string, string>([
['webpage', 'adx_webpage'],
['list', 'adx_entitylist'],
['webtemplate', 'adx_webtemplate'],
['basicform', 'adx_entityform'],
['advancedformstep', 'adx_entityform'],
['webpage', 'adx_webpage'],
['list', 'adx_entitylist'],
['webtemplate', 'adx_webtemplate'],
['basicform', 'adx_entityform'],
['advancedformstep', 'adx_entityform'],
]);

export const EntityFieldMap = new Map<string, string>([
['custom_javascript', 'adx_customjavascript'],
['source', 'adx_source'],
['copy', 'adx_copy']
['custom_javascript', 'adx_customjavascript'],
['source', 'adx_source'],
['copy', 'adx_copy']
]);

export const FieldTypeMap = new Map<string, string>([
['js', 'JavaScript'],
['html', 'html']
['js', 'JavaScript'],
['html', 'html']
]);

export const AuthProfileNotFound = [{ displayText: "Active auth profile is not found or has expired. Create an Auth profile to start chatting with Copilot again.", code: '' }];
Expand Down