UNPKG

@microsoft/agents-copilotstudio-client

Version:

Microsoft Copilot Studio Client for JavaScript. Copilot Studio Client.

246 lines 13 kB
"use strict"; /** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.getCopilotStudioConnectionUrl = getCopilotStudioConnectionUrl; exports.getTokenAudience = getTokenAudience; const agentType_1 = require("./agentType"); const logger_1 = require("@microsoft/agents-activity/logger"); const powerPlatformCloud_1 = require("./powerPlatformCloud"); const prebuiltBotStrategy_1 = require("./strategies/prebuiltBotStrategy"); const publishedBotStrategy_1 = require("./strategies/publishedBotStrategy"); const logger = (0, logger_1.debug)('copilot-studio:power-platform'); /** * Generates the connection URL for Copilot Studio. * @param settings - The connection settings. * @param conversationId - Optional conversation ID. * @returns The connection URL. * @throws Will throw an error if required settings are missing or invalid. */ function getCopilotStudioConnectionUrl(settings, conversationId) { var _a, _b, _c, _d, _e, _f; if ((_a = settings.directConnectUrl) === null || _a === void 0 ? void 0 : _a.trim()) { logger.debug(`Using direct connection: ${settings.directConnectUrl}`); if (!isValidUri(settings.directConnectUrl)) { throw new Error('directConnectUrl must be a valid URL'); } // FIX for Missing Tenant ID if (settings.directConnectUrl.toLowerCase().includes('tenants/00000000-0000-0000-0000-000000000000')) { logger.debug(`Direct connection cannot be used, forcing default settings flow. Tenant ID is missing in the URL: ${settings.directConnectUrl}`); // Direct connection cannot be used, ejecting and forcing the normal settings flow: return getCopilotStudioConnectionUrl({ ...settings, directConnectUrl: '' }, conversationId); } return createURL(settings.directConnectUrl, conversationId).href; } const cloudSetting = (_b = settings.cloud) !== null && _b !== void 0 ? _b : powerPlatformCloud_1.PowerPlatformCloud.Prod; const agentType = (_c = settings.copilotAgentType) !== null && _c !== void 0 ? _c : agentType_1.AgentType.Published; logger.debug(`Using cloud setting: ${cloudSetting}`); logger.debug(`Using agent type: ${agentType}`); if (!((_d = settings.environmentId) === null || _d === void 0 ? void 0 : _d.trim())) { throw new Error('EnvironmentId must be provided'); } if (!((_e = settings.agentIdentifier) === null || _e === void 0 ? void 0 : _e.trim())) { throw new Error('AgentIdentifier must be provided'); } if (cloudSetting === powerPlatformCloud_1.PowerPlatformCloud.Other) { if (!((_f = settings.customPowerPlatformCloud) === null || _f === void 0 ? void 0 : _f.trim())) { throw new Error('customPowerPlatformCloud must be provided when PowerPlatformCloud is Other'); } else if (isValidUri(settings.customPowerPlatformCloud)) { logger.debug(`Using custom Power Platform cloud: ${settings.customPowerPlatformCloud}`); } else { throw new Error('customPowerPlatformCloud must be a valid URL'); } } const host = getEnvironmentEndpoint(cloudSetting, settings.environmentId, settings.customPowerPlatformCloud); const strategy = { [agentType_1.AgentType.Published]: () => new publishedBotStrategy_1.PublishedBotStrategy({ host, schema: settings.agentIdentifier, }), [agentType_1.AgentType.Prebuilt]: () => new prebuiltBotStrategy_1.PrebuiltBotStrategy({ host, identifier: settings.agentIdentifier, }), }[agentType](); const url = strategy.getConversationUrl(conversationId); logger.debug(`Generated Copilot Studio connection URL: ${url}`); return url; } /** * Returns the Power Platform API Audience. * @param settings - Configuration Settings to use. * @param cloud - Optional Power Platform Cloud Hosting Agent. * @param cloudBaseAddress - Optional Power Platform API endpoint to use if Cloud is configured as "other". * @param directConnectUrl - Optional DirectConnection URL to a given Copilot Studio agent, if provided all other settings are ignored. * @returns The Power Platform Audience. * @throws Will throw an error if required settings are missing or invalid. */ function getTokenAudience(settings, cloud = powerPlatformCloud_1.PowerPlatformCloud.Unknown, cloudBaseAddress = '', directConnectUrl = '') { var _a, _b; if (!directConnectUrl && !(settings === null || settings === void 0 ? void 0 : settings.directConnectUrl)) { if (cloud === powerPlatformCloud_1.PowerPlatformCloud.Other && !cloudBaseAddress) { throw new Error('cloudBaseAddress must be provided when PowerPlatformCloudCategory is Other'); } if (!settings && cloud === powerPlatformCloud_1.PowerPlatformCloud.Unknown) { throw new Error('Either settings or cloud must be provided'); } if (settings && settings.cloud && settings.cloud !== powerPlatformCloud_1.PowerPlatformCloud.Unknown) { cloud = settings.cloud; } if (cloud === powerPlatformCloud_1.PowerPlatformCloud.Other) { if (cloudBaseAddress && isValidUri(cloudBaseAddress)) { cloud = powerPlatformCloud_1.PowerPlatformCloud.Other; } else if ((settings === null || settings === void 0 ? void 0 : settings.customPowerPlatformCloud) && isValidUri(settings.customPowerPlatformCloud)) { cloud = powerPlatformCloud_1.PowerPlatformCloud.Other; cloudBaseAddress = settings.customPowerPlatformCloud; } else { throw new Error('Either CustomPowerPlatformCloud or cloudBaseAddress must be provided when PowerPlatformCloudCategory is Other'); } } cloudBaseAddress !== null && cloudBaseAddress !== void 0 ? cloudBaseAddress : (cloudBaseAddress = 'api.unknown.powerplatform.com'); return `https://${getEndpointSuffix(cloud, cloudBaseAddress)}/.default`; } else { if (!directConnectUrl) { directConnectUrl = (_a = settings === null || settings === void 0 ? void 0 : settings.directConnectUrl) !== null && _a !== void 0 ? _a : ''; } if (directConnectUrl && isValidUri(directConnectUrl)) { if (decodeCloudFromURI(new URL(directConnectUrl)) === powerPlatformCloud_1.PowerPlatformCloud.Unknown) { const cloudToTest = (_b = settings === null || settings === void 0 ? void 0 : settings.cloud) !== null && _b !== void 0 ? _b : cloud; if (cloudToTest === powerPlatformCloud_1.PowerPlatformCloud.Other || cloudToTest === powerPlatformCloud_1.PowerPlatformCloud.Unknown) { throw new Error('Unable to resolve the PowerPlatform Cloud from DirectConnectUrl. The Token Audience resolver requires a specific PowerPlatformCloudCategory.'); } if (cloudToTest !== powerPlatformCloud_1.PowerPlatformCloud.Unknown) { return `https://${getEndpointSuffix(cloudToTest, '')}/.default`; } else { throw new Error('Unable to resolve the PowerPlatform Cloud from DirectConnectUrl. The Token Audience resolver requires a specific PowerPlatformCloudCategory.'); } } return `https://${getEndpointSuffix(decodeCloudFromURI(new URL(directConnectUrl)), '')}/.default`; } else { throw new Error('DirectConnectUrl must be provided when DirectConnectUrl is set'); } } } function isValidUri(uri) { try { const absoluteUrl = uri.startsWith('http') ? uri : `https://${uri}`; const newUri = new URL(absoluteUrl); return !!newUri; } catch { return false; } } function createURL(base, conversationId) { const url = new URL(base); if (!url.searchParams.has('api-version')) { url.searchParams.append('api-version', '2022-03-01-preview'); } if (url.pathname.endsWith('/')) { url.pathname = url.pathname.slice(0, -1); } if (url.pathname.includes('/conversations')) { url.pathname = url.pathname.substring(0, url.pathname.indexOf('/conversations')); } url.pathname = `${url.pathname}/conversations`; if (conversationId) { url.pathname = `${url.pathname}/${conversationId}`; } return url; } function getEnvironmentEndpoint(cloud, environmentId, cloudBaseAddress) { if (cloud === powerPlatformCloud_1.PowerPlatformCloud.Other && (!cloudBaseAddress || !cloudBaseAddress.trim())) { throw new Error('cloudBaseAddress must be provided when PowerPlatformCloud is Other'); } cloudBaseAddress = cloudBaseAddress !== null && cloudBaseAddress !== void 0 ? cloudBaseAddress : 'api.unknown.powerplatform.com'; const normalizedResourceId = environmentId.toLowerCase().replaceAll('-', ''); const idSuffixLength = getIdSuffixLength(cloud); const hexPrefix = normalizedResourceId.substring(0, normalizedResourceId.length - idSuffixLength); const hexSuffix = normalizedResourceId.substring(normalizedResourceId.length - idSuffixLength); return new URL(`https://${hexPrefix}.${hexSuffix}.environment.${getEndpointSuffix(cloud, cloudBaseAddress)}`); } function getEndpointSuffix(category, cloudBaseAddress) { switch (category) { case powerPlatformCloud_1.PowerPlatformCloud.Local: return 'api.powerplatform.localhost'; case powerPlatformCloud_1.PowerPlatformCloud.Exp: return 'api.exp.powerplatform.com'; case powerPlatformCloud_1.PowerPlatformCloud.Dev: return 'api.dev.powerplatform.com'; case powerPlatformCloud_1.PowerPlatformCloud.Prv: return 'api.prv.powerplatform.com'; case powerPlatformCloud_1.PowerPlatformCloud.Test: return 'api.test.powerplatform.com'; case powerPlatformCloud_1.PowerPlatformCloud.Preprod: return 'api.preprod.powerplatform.com'; case powerPlatformCloud_1.PowerPlatformCloud.FirstRelease: case powerPlatformCloud_1.PowerPlatformCloud.Prod: return 'api.powerplatform.com'; case powerPlatformCloud_1.PowerPlatformCloud.GovFR: return 'api.gov.powerplatform.microsoft.us'; case powerPlatformCloud_1.PowerPlatformCloud.Gov: return 'api.gov.powerplatform.microsoft.us'; case powerPlatformCloud_1.PowerPlatformCloud.High: return 'api.high.powerplatform.microsoft.us'; case powerPlatformCloud_1.PowerPlatformCloud.DoD: return 'api.appsplatform.us'; case powerPlatformCloud_1.PowerPlatformCloud.Mooncake: return 'api.powerplatform.partner.microsoftonline.cn'; case powerPlatformCloud_1.PowerPlatformCloud.Ex: return 'api.powerplatform.eaglex.ic.gov'; case powerPlatformCloud_1.PowerPlatformCloud.Rx: return 'api.powerplatform.microsoft.scloud'; case powerPlatformCloud_1.PowerPlatformCloud.Other: return cloudBaseAddress; default: throw new Error(`Invalid cluster category value: ${category}`); } } function getIdSuffixLength(cloud) { switch (cloud) { case powerPlatformCloud_1.PowerPlatformCloud.FirstRelease: case powerPlatformCloud_1.PowerPlatformCloud.Prod: return 2; default: return 1; } } function decodeCloudFromURI(uri) { const host = uri.host.toLowerCase(); switch (host) { case 'api.powerplatform.localhost': return powerPlatformCloud_1.PowerPlatformCloud.Local; case 'api.exp.powerplatform.com': return powerPlatformCloud_1.PowerPlatformCloud.Exp; case 'api.dev.powerplatform.com': return powerPlatformCloud_1.PowerPlatformCloud.Dev; case 'api.prv.powerplatform.com': return powerPlatformCloud_1.PowerPlatformCloud.Prv; case 'api.test.powerplatform.com': return powerPlatformCloud_1.PowerPlatformCloud.Test; case 'api.preprod.powerplatform.com': return powerPlatformCloud_1.PowerPlatformCloud.Preprod; case 'api.powerplatform.com': return powerPlatformCloud_1.PowerPlatformCloud.Prod; case 'api.gov.powerplatform.microsoft.us': return powerPlatformCloud_1.PowerPlatformCloud.GovFR; case 'api.high.powerplatform.microsoft.us': return powerPlatformCloud_1.PowerPlatformCloud.High; case 'api.appsplatform.us': return powerPlatformCloud_1.PowerPlatformCloud.DoD; case 'api.powerplatform.partner.microsoftonline.cn': return powerPlatformCloud_1.PowerPlatformCloud.Mooncake; default: return powerPlatformCloud_1.PowerPlatformCloud.Unknown; } } //# sourceMappingURL=powerPlatformEnvironment.js.map