@microsoft/agents-hosting 1.10.0-beta.8.g158a2c07ad → 1.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -2
- package/dist/package.json +3 -3
- package/dist/src/activityHandler.js +6 -3
- package/dist/src/activityHandler.js.map +1 -1
- package/dist/src/agent-client/agentResponseHandler.d.ts +7 -0
- package/dist/src/agent-client/agentResponseHandler.js.map +1 -1
- package/dist/src/agent-client/createAgentResponseHandler.d.ts +2 -0
- package/dist/src/agent-client/createAgentResponseHandler.js.map +1 -1
- package/dist/src/app/adaptiveCards/adaptiveCardsActions.d.ts +1 -0
- package/dist/src/app/adaptiveCards/adaptiveCardsActions.js +1 -0
- package/dist/src/app/adaptiveCards/adaptiveCardsActions.js.map +1 -1
- package/dist/src/app/attachmentDownloadHttpClient.d.ts +13 -0
- package/dist/src/app/attachmentDownloadHttpClient.js +80 -0
- package/dist/src/app/attachmentDownloadHttpClient.js.map +1 -0
- package/dist/src/app/attachmentDownloader.d.ts +2 -0
- package/dist/src/app/attachmentDownloader.js +6 -11
- package/dist/src/app/attachmentDownloader.js.map +1 -1
- package/dist/src/app/auth/authorization.d.ts +58 -0
- package/dist/src/app/auth/authorization.js.map +1 -1
- package/dist/src/app/proactive/conversation.d.ts +18 -0
- package/dist/src/app/proactive/conversation.js +6 -0
- package/dist/src/app/proactive/conversation.js.map +1 -1
- package/dist/src/app/proactive/conversationBuilder.js +2 -1
- package/dist/src/app/proactive/conversationBuilder.js.map +1 -1
- package/dist/src/app/proactive/conversationReferenceBuilder.js +8 -4
- package/dist/src/app/proactive/conversationReferenceBuilder.js.map +1 -1
- package/dist/src/app/proactive/createConversationOptionsBuilder.d.ts +1 -0
- package/dist/src/app/proactive/createConversationOptionsBuilder.js +2 -1
- package/dist/src/app/proactive/createConversationOptionsBuilder.js.map +1 -1
- package/dist/src/app/proactive/proactive.d.ts +6 -0
- package/dist/src/app/proactive/proactive.js +32 -1
- package/dist/src/app/proactive/proactive.js.map +1 -1
- package/dist/src/app/routeList.d.ts +21 -0
- package/dist/src/app/routeList.js +27 -3
- package/dist/src/app/routeList.js.map +1 -1
- package/dist/src/app/teamsAttachmentDownloader.d.ts +8 -0
- package/dist/src/app/teamsAttachmentDownloader.js +17 -12
- package/dist/src/app/teamsAttachmentDownloader.js.map +1 -1
- package/dist/src/auth/authConfiguration.d.ts +1 -0
- package/dist/src/auth/authConfiguration.js.map +1 -1
- package/dist/src/auth/authConstants.d.ts +7 -0
- package/dist/src/auth/authConstants.js +7 -0
- package/dist/src/auth/authConstants.js.map +1 -1
- package/dist/src/auth/authProvider.d.ts +36 -0
- package/dist/src/auth/connectionManager.js +2 -1
- package/dist/src/auth/connectionManager.js.map +1 -1
- package/dist/src/auth/connections.d.ts +1 -0
- package/dist/src/auth/msal/msalConnectionManager.d.ts +7 -0
- package/dist/src/auth/msal/msalConnectionManager.js +7 -0
- package/dist/src/auth/msal/msalConnectionManager.js.map +1 -1
- package/dist/src/auth/msal/msalTokenProvider.d.ts +44 -0
- package/dist/src/auth/msal/msalTokenProvider.js +43 -0
- package/dist/src/auth/msal/msalTokenProvider.js.map +1 -1
- package/dist/src/auth/settings.d.ts +28 -0
- package/dist/src/auth/settings.js +23 -0
- package/dist/src/auth/settings.js.map +1 -1
- package/dist/src/auth/sidecar/sidecarAuthProvider.d.ts +3 -0
- package/dist/src/auth/sidecar/sidecarAuthProvider.js.map +1 -1
- package/dist/src/auth/sidecar/sidecarHttpClient.d.ts +0 -8
- package/dist/src/auth/sidecar/sidecarHttpClient.js +2 -68
- package/dist/src/auth/sidecar/sidecarHttpClient.js.map +1 -1
- package/dist/src/cards/taskModuleAction.d.ts +6 -0
- package/dist/src/cards/taskModuleAction.js +6 -0
- package/dist/src/cards/taskModuleAction.js.map +1 -1
- package/dist/src/cloudAdapter.js +16 -8
- package/dist/src/cloudAdapter.js.map +1 -1
- package/dist/src/configuration/configuration.d.ts +1 -0
- package/dist/src/configuration/configuration.js +2 -1
- package/dist/src/configuration/configuration.js.map +1 -1
- package/dist/src/configuration/environmentConfiguration.js +1 -1
- package/dist/src/configuration/environmentConfiguration.js.map +1 -1
- package/dist/src/connector-client/connectorClient.d.ts +8 -0
- package/dist/src/connector-client/connectorClient.js +8 -0
- package/dist/src/connector-client/connectorClient.js.map +1 -1
- package/dist/src/createCloudAdapter.d.ts +2 -0
- package/dist/src/createCloudAdapter.js.map +1 -1
- package/dist/src/errorHelper.d.ts +1 -0
- package/dist/src/errorHelper.js +9 -0
- package/dist/src/errorHelper.js.map +1 -1
- package/dist/src/headerPropagation.d.ts +38 -0
- package/dist/src/headerPropagation.js +33 -0
- package/dist/src/headerPropagation.js.map +1 -1
- package/dist/src/httpClient.d.ts +58 -0
- package/dist/src/httpClient.js +40 -0
- package/dist/src/httpClient.js.map +1 -1
- package/dist/src/interfaces/webResponse.d.ts +7 -0
- package/dist/src/middlewareSet.d.ts +6 -0
- package/dist/src/middlewareSet.js.map +1 -1
- package/dist/src/oauth/userTokenClient.d.ts +6 -0
- package/dist/src/oauth/userTokenClient.js +12 -0
- package/dist/src/oauth/userTokenClient.js.map +1 -1
- package/dist/src/outboundHostValidator.d.ts +33 -1
- package/dist/src/outboundHostValidator.js +60 -25
- package/dist/src/outboundHostValidator.js.map +1 -1
- package/dist/src/storage/fileStorage.d.ts +26 -0
- package/dist/src/storage/fileStorage.js +35 -6
- package/dist/src/storage/fileStorage.js.map +1 -1
- package/dist/src/storage/memoryStorage.d.ts +34 -0
- package/dist/src/storage/memoryStorage.js +41 -4
- package/dist/src/storage/memoryStorage.js.map +1 -1
- package/dist/src/storage/storage.d.ts +20 -0
- package/dist/src/storage/storage.js +7 -0
- package/dist/src/storage/storage.js.map +1 -1
- package/dist/src/storage/storageCompatibility.js +12 -6
- package/dist/src/storage/storageCompatibility.js.map +1 -1
- package/dist/src/storage/storageExpiry.d.ts +7 -0
- package/dist/src/storage/storageExpiry.js +7 -0
- package/dist/src/storage/storageExpiry.js.map +1 -1
- package/dist/src/turnContext.d.ts +10 -0
- package/dist/src/turnContext.js +5 -0
- package/dist/src/turnContext.js.map +1 -1
- package/dist/src/utils/env.js +22 -11
- package/dist/src/utils/env.js.map +1 -1
- package/dist/src/utils/ipAddress.d.ts +6 -0
- package/dist/src/utils/ipAddress.js +64 -0
- package/dist/src/utils/ipAddress.js.map +1 -0
- package/dist/src/utils/outboundUrl.d.ts +7 -0
- package/dist/src/utils/outboundUrl.js +52 -0
- package/dist/src/utils/outboundUrl.js.map +1 -0
- package/dist/src/utils.js +2 -1
- package/dist/src/utils.js.map +1 -1
- package/package.json +3 -3
- package/src/activityHandler.ts +9 -3
- package/src/agent-client/agentResponseHandler.ts +7 -0
- package/src/agent-client/createAgentResponseHandler.ts +2 -0
- package/src/app/adaptiveCards/adaptiveCardsActions.ts +1 -0
- package/src/app/attachmentDownloadHttpClient.ts +80 -0
- package/src/app/attachmentDownloader.ts +6 -9
- package/src/app/auth/authorization.ts +58 -0
- package/src/app/proactive/conversation.ts +24 -0
- package/src/app/proactive/conversationBuilder.ts +3 -1
- package/src/app/proactive/conversationReferenceBuilder.ts +12 -4
- package/src/app/proactive/createConversationOptionsBuilder.ts +5 -1
- package/src/app/proactive/proactive.ts +33 -1
- package/src/app/routeList.ts +30 -3
- package/src/app/teamsAttachmentDownloader.ts +17 -10
- package/src/auth/authConfiguration.ts +1 -0
- package/src/auth/authConstants.ts +7 -0
- package/src/auth/authProvider.ts +36 -0
- package/src/auth/connectionManager.ts +3 -1
- package/src/auth/connections.ts +1 -0
- package/src/auth/msal/msalConnectionManager.ts +7 -0
- package/src/auth/msal/msalTokenProvider.ts +59 -0
- package/src/auth/settings.ts +28 -0
- package/src/auth/sidecar/sidecarAuthProvider.ts +4 -0
- package/src/auth/sidecar/sidecarHttpClient.ts +2 -62
- package/src/cards/taskModuleAction.ts +6 -0
- package/src/cloudAdapter.ts +30 -10
- package/src/configuration/configuration.ts +4 -2
- package/src/configuration/environmentConfiguration.ts +7 -1
- package/src/connector-client/connectorClient.ts +8 -0
- package/src/createCloudAdapter.ts +2 -0
- package/src/errorHelper.ts +11 -0
- package/src/headerPropagation.ts +38 -0
- package/src/httpClient.ts +58 -0
- package/src/interfaces/webResponse.ts +7 -0
- package/src/middlewareSet.ts +6 -0
- package/src/oauth/userTokenClient.ts +13 -0
- package/src/outboundHostValidator.ts +84 -23
- package/src/storage/fileStorage.ts +46 -6
- package/src/storage/memoryStorage.ts +45 -4
- package/src/storage/storage.ts +20 -0
- package/src/storage/storageCompatibility.ts +18 -6
- package/src/storage/storageExpiry.ts +7 -0
- package/src/turnContext.ts +11 -0
- package/src/utils/env.ts +33 -11
- package/src/utils/ipAddress.ts +63 -0
- package/src/utils/outboundUrl.ts +50 -0
- package/src/utils.ts +3 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
* Licensed under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.isPrivateOrLoopbackAddress = isPrivateOrLoopbackAddress;
|
|
8
|
+
exports.isBlockedOutboundAddress = isBlockedOutboundAddress;
|
|
9
|
+
const node_net_1 = require("node:net");
|
|
10
|
+
function normalizeAddress(address) {
|
|
11
|
+
const unwrapped = address.startsWith('[') && address.endsWith(']') ? address.slice(1, -1) : address;
|
|
12
|
+
const version = (0, node_net_1.isIP)(unwrapped);
|
|
13
|
+
if (version === 0) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
return version === 6 ? new URL(`http://[${unwrapped}]`).hostname.slice(1, -1) : unwrapped;
|
|
17
|
+
}
|
|
18
|
+
function mappedIPv4(address) {
|
|
19
|
+
const match = address.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);
|
|
20
|
+
if (!match) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
const high = parseInt(match[1], 16);
|
|
24
|
+
const low = parseInt(match[2], 16);
|
|
25
|
+
return `${high >> 8}.${high & 0xff}.${low >> 8}.${low & 0xff}`;
|
|
26
|
+
}
|
|
27
|
+
function isPrivateOrLoopbackAddress(address) {
|
|
28
|
+
var _a;
|
|
29
|
+
const normalized = normalizeAddress(address);
|
|
30
|
+
if (!normalized) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
const ipv4 = (_a = mappedIPv4(normalized)) !== null && _a !== void 0 ? _a : normalized;
|
|
34
|
+
if ((0, node_net_1.isIP)(ipv4) === 4) {
|
|
35
|
+
const bytes = ipv4.split('.').map(Number);
|
|
36
|
+
return bytes[0] === 127 ||
|
|
37
|
+
bytes[0] === 10 ||
|
|
38
|
+
(bytes[0] === 172 && bytes[1] >= 16 && bytes[1] <= 31) ||
|
|
39
|
+
(bytes[0] === 192 && bytes[1] === 168) ||
|
|
40
|
+
(bytes[0] === 169 && bytes[1] === 254);
|
|
41
|
+
}
|
|
42
|
+
if (normalized === '::1') {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
const firstHextet = parseInt(normalized.split(':')[0], 16);
|
|
46
|
+
return (firstHextet & 0xfe00) === 0xfc00 ||
|
|
47
|
+
(firstHextet & 0xffc0) === 0xfe80 ||
|
|
48
|
+
(firstHextet & 0xffc0) === 0xfec0;
|
|
49
|
+
}
|
|
50
|
+
function isBlockedOutboundAddress(address) {
|
|
51
|
+
var _a;
|
|
52
|
+
const normalized = normalizeAddress(address);
|
|
53
|
+
if (!normalized) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
const ipv4 = (_a = mappedIPv4(normalized)) !== null && _a !== void 0 ? _a : normalized;
|
|
57
|
+
const [first, second] = ipv4.split('.').map(Number);
|
|
58
|
+
// RFC 6598 shared space is outbound-only; it must not become trusted sidecar space.
|
|
59
|
+
return normalized === '::' ||
|
|
60
|
+
ipv4 === '0.0.0.0' ||
|
|
61
|
+
(first === 100 && second >= 64 && second <= 127) ||
|
|
62
|
+
isPrivateOrLoopbackAddress(normalized);
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=ipAddress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipAddress.js","sourceRoot":"","sources":["../../../src/utils/ipAddress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getHttpsUrl(input: string | URL | null | undefined): URL | undefined;
|
|
6
|
+
export declare function isLocalOrBlockedHost(host: string): boolean;
|
|
7
|
+
export declare function hasAllowedOutboundAddresses(url: URL, allowPrivateNetworkAddresses?: boolean): Promise<boolean>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
* Licensed under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.getHttpsUrl = getHttpsUrl;
|
|
8
|
+
exports.isLocalOrBlockedHost = isLocalOrBlockedHost;
|
|
9
|
+
exports.hasAllowedOutboundAddresses = hasAllowedOutboundAddresses;
|
|
10
|
+
const node_dns_1 = require("node:dns");
|
|
11
|
+
const node_net_1 = require("node:net");
|
|
12
|
+
const agents_telemetry_1 = require("@microsoft/agents-telemetry");
|
|
13
|
+
const ipAddress_1 = require("./ipAddress");
|
|
14
|
+
const logger = (0, agents_telemetry_1.debug)('agents:outboundHostValidator');
|
|
15
|
+
function getHttpsUrl(input) {
|
|
16
|
+
if (!input) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const url = input instanceof URL ? input : new URL(input);
|
|
21
|
+
return url.protocol === 'https:' && !url.username && !url.password ? url : undefined;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function isLocalOrBlockedHost(host) {
|
|
28
|
+
const unwrapped = host.startsWith('[') && host.endsWith(']') ? host.slice(1, -1) : host;
|
|
29
|
+
return host === 'localhost' || host.endsWith('.localhost') ||
|
|
30
|
+
((0, node_net_1.isIP)(unwrapped) !== 0 && (0, ipAddress_1.isBlockedOutboundAddress)(unwrapped));
|
|
31
|
+
}
|
|
32
|
+
async function hasAllowedOutboundAddresses(url, allowPrivateNetworkAddresses = false) {
|
|
33
|
+
if (allowPrivateNetworkAddresses) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
const host = url.hostname.replace(/^\[|\]$/g, '').replace(/\.$/, '');
|
|
37
|
+
if (isLocalOrBlockedHost(host)) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
if ((0, node_net_1.isIP)(host) !== 0) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const addresses = await node_dns_1.promises.lookup(host, { all: true });
|
|
45
|
+
return addresses.length > 0 && addresses.every(({ address }) => !(0, ipAddress_1.isBlockedOutboundAddress)(address));
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
logger.warn(`Attachment destination DNS lookup failed. Host='${host}'`);
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=outboundUrl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outboundUrl.js","sourceRoot":"","sources":["../../../src/utils/outboundUrl.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;AAEH,uCAA0C;AAC1C,uCAA+B;AAC/B,kEAAmD;AACnD,2CAAsD;AAEtD,MAAM,MAAM,GAAG,IAAA,wBAAK,EAAC,8BAA8B,CAAC,CAAA;AAEpD,qBAA6B,KAAsC;IACjE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,KAAK,YAAY,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAA;QACzD,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAA;IACtF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,8BAAsC,IAAY;IAChD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACvF,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;QACxD,CAAC,IAAA,eAAI,EAAC,SAAS,CAAC,KAAK,CAAC,IAAI,IAAA,oCAAwB,EAAC,SAAS,CAAC,CAAC,CAAA;AAClE,CAAC;AAEM,KAAK,sCAAuC,GAAQ,EAAE,4BAA4B,GAAG,KAAK;IAC/F,IAAI,4BAA4B,EAAE,CAAC;QACjC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IACpE,IAAI,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,IAAA,eAAI,EAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,mBAAG,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAA;QACvD,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,IAAA,oCAAwB,EAAC,OAAO,CAAC,CAAC,CAAA;IACrG,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,CAAC,mDAAmD,IAAI,GAAG,CAAC,CAAA;QACvE,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC"}
|
package/dist/src/utils.js
CHANGED
package/dist/src/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;;;GAIG;AACI,MAAM,KAAK,GAAG,CAAgC,GAAM,EAAE,EAAE;IAC7D,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAA;IAC9E,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,CAAM,CAAA;AACzC,CAAC,CAAA;AAHY,QAAA,KAAK,GAAL,KAAK,CAGjB;AAEM,MAAM,YAAY,GAAG,CAC1B,GAAG,MAA2C,EAC3C,EAAE;IACL,MAAM,MAAM,GAAe,EAAE,CAAA;IAC7B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;;;GAIG;AACI,MAAM,KAAK,GAAG,CAAgC,GAAM,EAAE,EAAE;IAC7D,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAA;IAC9E,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,CAAM,CAAA;AACzC,CAAC,CAAA;AAHY,QAAA,KAAK,GAAL,KAAK,CAGjB;AAEM,MAAM,YAAY,GAAG,CAC1B,GAAG,MAA2C,EAC3C,EAAE;IACL,MAAM,MAAM,GAAe,EAAE,CAAA;IAC7B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAA,QAAA,KAAK,EAAC,KAAK,CAAC,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IACD,OAAO,MAAW,CAAA;AACpB,CAAC,CAAA;AAVY,QAAA,YAAY,GAAZ,YAAY,CAUxB"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@microsoft/agents-hosting",
|
|
4
|
-
"version": "1.10.
|
|
4
|
+
"version": "1.10.1",
|
|
5
5
|
"homepage": "https://github.com/microsoft/Agents-for-js",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@azure/core-auth": "1.10.1",
|
|
23
23
|
"@azure/msal-node": "5.6.0",
|
|
24
|
-
"@microsoft/agents-activity": "1.10.
|
|
25
|
-
"@microsoft/agents-telemetry": "1.10.
|
|
24
|
+
"@microsoft/agents-activity": "1.10.1",
|
|
25
|
+
"@microsoft/agents-telemetry": "1.10.1",
|
|
26
26
|
"jsonwebtoken": "9.0.3",
|
|
27
27
|
"jwks-rsa": "4.0.1",
|
|
28
28
|
"zod": "3.25.75"
|
package/src/activityHandler.ts
CHANGED
|
@@ -255,9 +255,15 @@ export class ActivityHandler {
|
|
|
255
255
|
* @throws Error if context is missing, activity is missing, or activity type is missing
|
|
256
256
|
*/
|
|
257
257
|
async run (context: TurnContext): Promise<void> {
|
|
258
|
-
if (!context)
|
|
259
|
-
|
|
260
|
-
|
|
258
|
+
if (!context) {
|
|
259
|
+
throw ExceptionHelper.generateException(Error, Errors.MissingTurnContext)
|
|
260
|
+
}
|
|
261
|
+
if (!context.activity) {
|
|
262
|
+
throw ExceptionHelper.generateException(Error, Errors.TurnContextMissingActivity)
|
|
263
|
+
}
|
|
264
|
+
if (!context.activity.type) {
|
|
265
|
+
throw ExceptionHelper.generateException(Error, Errors.ActivityMissingType)
|
|
266
|
+
}
|
|
261
267
|
|
|
262
268
|
await this.handle(context, 'Turn', async () => {
|
|
263
269
|
await this.onTurnActivity(context)
|
|
@@ -24,6 +24,13 @@ import { AGENT_RESPONSE_ROUTE_PATH, createAgentResponseHandler } from './createA
|
|
|
24
24
|
* `post(path, handler)` method structurally matches satisfies it.
|
|
25
25
|
*/
|
|
26
26
|
export interface WebApp {
|
|
27
|
+
/**
|
|
28
|
+
* Registers a handler for HTTP POST requests at the specified path.
|
|
29
|
+
*
|
|
30
|
+
* @param path - Route path to register.
|
|
31
|
+
* @param handler - Request handler invoked for matching requests.
|
|
32
|
+
* @returns A framework-specific registration result.
|
|
33
|
+
*/
|
|
27
34
|
post (
|
|
28
35
|
path: string,
|
|
29
36
|
handler: (req: any, res: any) => unknown | Promise<unknown>
|
|
@@ -33,7 +33,9 @@ interface DelegatedConversationState {
|
|
|
33
33
|
* the framework's URL path parser.
|
|
34
34
|
*/
|
|
35
35
|
export interface AgentResponseHandlerParams {
|
|
36
|
+
/** ID of the conversation receiving the callback activity. */
|
|
36
37
|
conversationId: string
|
|
38
|
+
/** ID to assign to the callback activity. */
|
|
37
39
|
activityId: string
|
|
38
40
|
}
|
|
39
41
|
|
|
@@ -13,6 +13,7 @@ import { AdaptiveCard } from '../../cards/adaptiveCard'
|
|
|
13
13
|
import { Query } from './query'
|
|
14
14
|
import { Errors } from '../../errorHelper'
|
|
15
15
|
|
|
16
|
+
/** Invoke activity name used for Adaptive Card actions. */
|
|
16
17
|
export const ACTION_INVOKE_NAME = 'adaptiveCard/action'
|
|
17
18
|
const ACTION_EXECUTE_TYPE = 'Action.Execute'
|
|
18
19
|
const DEFAULT_ACTION_SUBMIT_FILTER = 'verb'
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ExceptionHelper } from '@microsoft/agents-activity'
|
|
7
|
+
import { debug } from '@microsoft/agents-telemetry'
|
|
8
|
+
import { Errors } from '../errorHelper'
|
|
9
|
+
import { HttpClient, HttpError, HttpResponse } from '../httpClient'
|
|
10
|
+
import { OutboundHostValidator, OutboundUrlPolicy } from '../outboundHostValidator'
|
|
11
|
+
import { getHttpsUrl, hasAllowedOutboundAddresses } from '../utils/outboundUrl'
|
|
12
|
+
|
|
13
|
+
const logger = debug('agents:attachmentDownloader')
|
|
14
|
+
const REDIRECT_STATUSES = new Set([300, 301, 302, 303, 307, 308])
|
|
15
|
+
const MAX_REDIRECTS = 50
|
|
16
|
+
|
|
17
|
+
export class AttachmentDownloadHttpClient {
|
|
18
|
+
public constructor (
|
|
19
|
+
private readonly httpClient: HttpClient,
|
|
20
|
+
private readonly hostValidator: OutboundUrlPolicy
|
|
21
|
+
) {}
|
|
22
|
+
|
|
23
|
+
public async get (url: string, headers: Record<string, string> = {}): Promise<HttpResponse<ArrayBuffer> | undefined> {
|
|
24
|
+
if (!this.hostValidator.enabled) {
|
|
25
|
+
if (!this.hostValidator.isAllowed(url)) {
|
|
26
|
+
return this.blocked(url)
|
|
27
|
+
}
|
|
28
|
+
return this.httpClient.get<ArrayBuffer>(url, { headers, responseType: 'arraybuffer' })
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let currentUrl = url
|
|
32
|
+
for (let redirects = 0; ; redirects++) {
|
|
33
|
+
const parsed = getHttpsUrl(currentUrl)
|
|
34
|
+
const allowed = parsed && (this.hostValidator instanceof OutboundHostValidator
|
|
35
|
+
? await this.hostValidator.isAllowedAsync(parsed)
|
|
36
|
+
: this.hostValidator.isAllowed(currentUrl) && await hasAllowedOutboundAddresses(parsed))
|
|
37
|
+
if (!allowed) {
|
|
38
|
+
return this.blocked(currentUrl)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const requestHeaders = new Headers(redirects === 0 ? headers : undefined)
|
|
42
|
+
const response = await fetch(currentUrl, { method: 'GET', headers: requestHeaders, redirect: 'manual' })
|
|
43
|
+
const location = response.headers.get('location')
|
|
44
|
+
if (REDIRECT_STATUSES.has(response.status) && location) {
|
|
45
|
+
await response.body?.cancel()
|
|
46
|
+
if (redirects >= MAX_REDIRECTS) {
|
|
47
|
+
throw ExceptionHelper.generateException(Error, Errors.AttachmentDownloadRedirectLimit)
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
currentUrl = new URL(location, currentUrl).href
|
|
51
|
+
} catch {
|
|
52
|
+
throw ExceptionHelper.generateException(Error, Errors.AttachmentDownloadInvalidRedirect)
|
|
53
|
+
}
|
|
54
|
+
continue
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const config = { method: 'get', url: currentUrl, responseType: 'arraybuffer' as const }
|
|
58
|
+
const result: HttpResponse<ArrayBuffer> = {
|
|
59
|
+
data: await response.arrayBuffer(),
|
|
60
|
+
status: response.status,
|
|
61
|
+
statusText: response.statusText,
|
|
62
|
+
headers: response.headers,
|
|
63
|
+
config
|
|
64
|
+
}
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
throw new HttpError(`Request failed with status ${response.status}`, result, config)
|
|
67
|
+
}
|
|
68
|
+
return result
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private blocked (input: string): undefined {
|
|
73
|
+
let host = '[invalid-url]'
|
|
74
|
+
try {
|
|
75
|
+
host = new URL(input).hostname
|
|
76
|
+
} catch { /* Invalid URLs have no safe host to log. */ }
|
|
77
|
+
logger.warn(`Attachment destination blocked by outbound policy or address validation. Host='${host}'`)
|
|
78
|
+
return undefined
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -13,6 +13,7 @@ import { debug } from '@microsoft/agents-telemetry'
|
|
|
13
13
|
import { loadAuthConfigFromEnv, MsalTokenProvider } from '../auth'
|
|
14
14
|
import { createOutboundHostValidator, OutboundUrlPolicy } from '../outboundHostValidator'
|
|
15
15
|
import { Connections } from '../auth/connections'
|
|
16
|
+
import { AttachmentDownloadHttpClient } from './attachmentDownloadHttpClient'
|
|
16
17
|
|
|
17
18
|
const logger = debug('agents:attachmentDownloader')
|
|
18
19
|
|
|
@@ -24,6 +25,8 @@ const logger = debug('agents:attachmentDownloader')
|
|
|
24
25
|
* @remarks
|
|
25
26
|
* This class provides functionality to filter and download attachments from a turn context,
|
|
26
27
|
* supporting various content types and handling authentication for secure URLs.
|
|
28
|
+
* Enabled outbound validation requires HTTPS and validates addresses at every redirect.
|
|
29
|
+
* Initial request credentials are not forwarded to redirects when validation is enabled.
|
|
27
30
|
*
|
|
28
31
|
*/
|
|
29
32
|
export class AttachmentDownloader<TState extends TurnState = TurnState> implements InputFileDownloader<TState> {
|
|
@@ -103,18 +106,12 @@ export class AttachmentDownloader<TState extends TurnState = TurnState> implemen
|
|
|
103
106
|
if (accessToken.length > 0) {
|
|
104
107
|
headers.Authorization = `Bearer ${accessToken}`
|
|
105
108
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
logger.warn(`Attachment contentUrl host is not in the configured allowed hosts. Host='${host}'`)
|
|
109
|
+
const response = await new AttachmentDownloadHttpClient(this._httpClient, this._hostValidator)
|
|
110
|
+
.get(attachment.contentUrl, headers)
|
|
111
|
+
if (!response) {
|
|
110
112
|
return undefined
|
|
111
113
|
}
|
|
112
114
|
|
|
113
|
-
const response = await this._httpClient.get(attachment.contentUrl, {
|
|
114
|
-
headers,
|
|
115
|
-
responseType: 'arraybuffer'
|
|
116
|
-
})
|
|
117
|
-
|
|
118
115
|
const content = Buffer.from(response.data as ArrayBuffer)
|
|
119
116
|
|
|
120
117
|
let contentType = attachment.contentType
|
|
@@ -16,14 +16,72 @@ import { AuthorizationHandlerTokenOptions } from './types'
|
|
|
16
16
|
|
|
17
17
|
const logger = debug('agents:authorization')
|
|
18
18
|
|
|
19
|
+
/** Provides user authorization, token exchange, and sign-in lifecycle operations. */
|
|
19
20
|
export interface Authorization {
|
|
21
|
+
/**
|
|
22
|
+
* Gets the user token for an authorization handler.
|
|
23
|
+
*
|
|
24
|
+
* @param context - Context for the current turn.
|
|
25
|
+
* @param authHandlerId - Authorization handler ID.
|
|
26
|
+
* @returns The token response.
|
|
27
|
+
*/
|
|
20
28
|
getToken(context: TurnContext, authHandlerId: string): Promise<TokenResponse>
|
|
29
|
+
/**
|
|
30
|
+
* Creates a credential backed by the current turn's user token.
|
|
31
|
+
*
|
|
32
|
+
* @param context - Context for the current turn.
|
|
33
|
+
* @param authHandlerId - Authorization handler ID.
|
|
34
|
+
* @returns A turn-scoped token credential.
|
|
35
|
+
*/
|
|
21
36
|
getTokenAsTokenCredential?(context: TurnContext, authHandlerId: string): TokenCredential
|
|
37
|
+
/**
|
|
38
|
+
* Exchanges the user token for the requested scopes.
|
|
39
|
+
*
|
|
40
|
+
* @param context - Context for the current turn.
|
|
41
|
+
* @param scopes - Scopes requested for the exchanged token.
|
|
42
|
+
* @param authHandlerId - Authorization handler ID.
|
|
43
|
+
* @returns The exchanged token response.
|
|
44
|
+
* @deprecated Use the overload that accepts an authorization handler ID followed by options.
|
|
45
|
+
*/
|
|
22
46
|
exchangeToken(context: TurnContext, scopes: string[], authHandlerId: string): Promise<TokenResponse>
|
|
47
|
+
/**
|
|
48
|
+
* Exchanges the user token using an authorization handler.
|
|
49
|
+
*
|
|
50
|
+
* @param context - Context for the current turn.
|
|
51
|
+
* @param authHandlerId - Authorization handler ID.
|
|
52
|
+
* @param options - Optional connection and scope overrides.
|
|
53
|
+
* @returns The exchanged token response.
|
|
54
|
+
*/
|
|
23
55
|
exchangeToken(context: TurnContext, authHandlerId: string, options?: AuthorizationHandlerTokenOptions): Promise<TokenResponse>
|
|
56
|
+
/**
|
|
57
|
+
* Creates a credential that exchanges the current turn's user token.
|
|
58
|
+
*
|
|
59
|
+
* @param context - Context for the current turn.
|
|
60
|
+
* @param authHandlerId - Authorization handler ID.
|
|
61
|
+
* @param options - Optional connection and scope overrides.
|
|
62
|
+
* @returns A turn-scoped token credential.
|
|
63
|
+
*/
|
|
24
64
|
exchangeTokenAsTokenCredential?(context: TurnContext, authHandlerId: string, options?: AuthorizationHandlerTokenOptions): TokenCredential
|
|
65
|
+
/**
|
|
66
|
+
* Signs out the user from one or all authorization handlers.
|
|
67
|
+
*
|
|
68
|
+
* @param context - Context for the current turn.
|
|
69
|
+
* @param state - State for the current turn.
|
|
70
|
+
* @param authHandlerId - Handler to sign out from, or `undefined` for all handlers.
|
|
71
|
+
* @returns A promise that resolves after sign-out completes.
|
|
72
|
+
*/
|
|
25
73
|
signOut(context: TurnContext, state: TurnState, authHandlerId?: string): Promise<void>
|
|
74
|
+
/**
|
|
75
|
+
* Registers a callback for successful sign-in.
|
|
76
|
+
*
|
|
77
|
+
* @param handler - Callback invoked after sign-in succeeds.
|
|
78
|
+
*/
|
|
26
79
|
onSignInSuccess(handler: (context: TurnContext, state: TurnState, authHandlerId?: string) => Promise<void>): void
|
|
80
|
+
/**
|
|
81
|
+
* Registers a callback for failed sign-in.
|
|
82
|
+
*
|
|
83
|
+
* @param handler - Callback invoked after sign-in fails.
|
|
84
|
+
*/
|
|
27
85
|
onSignInFailure(handler: (context: TurnContext, state: TurnState, authHandlerId?: string, errorMessage?: string) => Promise<void>): void
|
|
28
86
|
}
|
|
29
87
|
|
|
@@ -12,10 +12,15 @@ import { Errors } from '../../errorHelper'
|
|
|
12
12
|
* `aud` (the agent's client ID) is required; all other fields are optional.
|
|
13
13
|
*/
|
|
14
14
|
export interface ConversationClaims {
|
|
15
|
+
/** Audience identifying the agent client. */
|
|
15
16
|
aud: string
|
|
17
|
+
/** Authorized-party client ID, when supplied by the token. */
|
|
16
18
|
azp?: string
|
|
19
|
+
/** Calling application ID, when supplied by the token. */
|
|
17
20
|
appid?: string
|
|
21
|
+
/** Microsoft Entra tenant ID, when supplied by the token. */
|
|
18
22
|
tid?: string
|
|
23
|
+
/** Additional string-valued identity claims. */
|
|
19
24
|
[key: string]: string | undefined
|
|
20
25
|
}
|
|
21
26
|
|
|
@@ -28,11 +33,30 @@ export interface ConversationClaims {
|
|
|
28
33
|
* `adapter.continueConversation()`.
|
|
29
34
|
*/
|
|
30
35
|
export class Conversation {
|
|
36
|
+
/** Reference used to resume the conversation. */
|
|
31
37
|
reference: ConversationReference
|
|
38
|
+
/** Identity claims used to authenticate proactive operations. */
|
|
32
39
|
claims: ConversationClaims
|
|
33
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Creates a conversation from the current turn.
|
|
43
|
+
*
|
|
44
|
+
* @param context - Turn context from which to capture the reference and identity.
|
|
45
|
+
*/
|
|
34
46
|
constructor (context: TurnContext)
|
|
47
|
+
/**
|
|
48
|
+
* Creates a conversation from explicit claims and a conversation reference.
|
|
49
|
+
*
|
|
50
|
+
* @param claims - Claims used to authenticate proactive operations.
|
|
51
|
+
* @param reference - Reference used to resume the conversation.
|
|
52
|
+
*/
|
|
35
53
|
constructor (claims: ConversationClaims, reference: ConversationReference)
|
|
54
|
+
/**
|
|
55
|
+
* Creates a conversation from a turn context or explicit claims and a reference.
|
|
56
|
+
*
|
|
57
|
+
* @param contextOrClaims - Turn context to capture, or authentication claims.
|
|
58
|
+
* @param reference - Reference paired with explicit claims.
|
|
59
|
+
*/
|
|
36
60
|
constructor (
|
|
37
61
|
contextOrClaims: TurnContext | ConversationClaims,
|
|
38
62
|
reference?: ConversationReference
|
|
@@ -55,7 +55,9 @@ export class ConversationBuilder {
|
|
|
55
55
|
requestorId?: string
|
|
56
56
|
): ConversationBuilder {
|
|
57
57
|
const claims: ConversationClaims = { aud: agentClientId }
|
|
58
|
-
if (requestorId)
|
|
58
|
+
if (requestorId) {
|
|
59
|
+
claims.appid = requestorId
|
|
60
|
+
}
|
|
59
61
|
return new ConversationBuilder(agentClientId, channelId, serviceUrl ?? '', claims, ConversationReferenceBuilder.create(agentClientId, channelId, serviceUrl).build())
|
|
60
62
|
}
|
|
61
63
|
|
|
@@ -71,8 +71,12 @@ export class ConversationReferenceBuilder {
|
|
|
71
71
|
* `https://{channelId}.botframework.com/` pattern (matching C# behavior).
|
|
72
72
|
*/
|
|
73
73
|
static serviceUrlForChannel (channelId: string): string {
|
|
74
|
-
if (!channelId)
|
|
75
|
-
|
|
74
|
+
if (!channelId) {
|
|
75
|
+
return ''
|
|
76
|
+
}
|
|
77
|
+
if (channelId === Channels.Msteams) {
|
|
78
|
+
return TeamsServiceEndpoints.publicGlobal
|
|
79
|
+
}
|
|
76
80
|
if (!knownChannelIds.has(channelId)) {
|
|
77
81
|
logger.warn(
|
|
78
82
|
`serviceUrlForChannel: unrecognized channelId '${channelId}' — constructing fallback URL ` +
|
|
@@ -141,8 +145,12 @@ export class ConversationReferenceBuilder {
|
|
|
141
145
|
user: this._user ?? { role: RoleTypes.User },
|
|
142
146
|
}
|
|
143
147
|
|
|
144
|
-
if (this._activityId !== undefined)
|
|
145
|
-
|
|
148
|
+
if (this._activityId !== undefined) {
|
|
149
|
+
ref.activityId = this._activityId
|
|
150
|
+
}
|
|
151
|
+
if (this._locale !== undefined) {
|
|
152
|
+
ref.locale = this._locale
|
|
153
|
+
}
|
|
146
154
|
|
|
147
155
|
return ref
|
|
148
156
|
}
|
|
@@ -81,6 +81,8 @@ export class CreateConversationOptionsBuilder {
|
|
|
81
81
|
|
|
82
82
|
/** Adds a member (the target user) to `parameters.members`. */
|
|
83
83
|
withUser (userId: string, userName?: string): this
|
|
84
|
+
|
|
85
|
+
/** Adds a channel account as a member in `parameters.members`. */
|
|
84
86
|
withUser (account: ChannelAccount): this
|
|
85
87
|
withUser (userIdOrAccount: string | ChannelAccount, userName?: string): this {
|
|
86
88
|
const account: ChannelAccount =
|
|
@@ -125,7 +127,9 @@ export class CreateConversationOptionsBuilder {
|
|
|
125
127
|
* Only has effect on `msteams` channels.
|
|
126
128
|
*/
|
|
127
129
|
withTeamsChannelId (teamsChannelId: string): this {
|
|
128
|
-
if (this._channelId !== Channels.Msteams)
|
|
130
|
+
if (this._channelId !== Channels.Msteams) {
|
|
131
|
+
return this
|
|
132
|
+
}
|
|
129
133
|
this._parameters = { ...this._parameters, isGroup: true }
|
|
130
134
|
this.withChannelData({ channel: { id: teamsChannelId } })
|
|
131
135
|
return this
|
|
@@ -49,6 +49,12 @@ export class Proactive<TState extends TurnState> {
|
|
|
49
49
|
private readonly _options: ProactiveOptions
|
|
50
50
|
private readonly _storage?: StorageV2
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Creates a proactive conversation manager.
|
|
54
|
+
*
|
|
55
|
+
* @param app - Application that owns the proactive operations.
|
|
56
|
+
* @param options - Proactive messaging configuration.
|
|
57
|
+
*/
|
|
52
58
|
constructor (app: AgentApplication<TState>, options: ProactiveOptions) {
|
|
53
59
|
this._app = app
|
|
54
60
|
this._options = options
|
|
@@ -113,6 +119,12 @@ export class Proactive<TState extends TurnState> {
|
|
|
113
119
|
* ```
|
|
114
120
|
*/
|
|
115
121
|
storeConversation (conversation: Conversation): Promise<string>
|
|
122
|
+
/**
|
|
123
|
+
* Stores a conversation captured from a turn context or supplied explicitly.
|
|
124
|
+
*
|
|
125
|
+
* @param contextOrConversation - Turn context or conversation to store.
|
|
126
|
+
* @returns The stored conversation ID.
|
|
127
|
+
*/
|
|
116
128
|
async storeConversation (contextOrConversation: TurnContext | Conversation): Promise<string> {
|
|
117
129
|
return trace(ProactiveTraceDefinitions.storeConversation, async ({ record, actions }) => {
|
|
118
130
|
const conv =
|
|
@@ -243,6 +255,14 @@ export class Proactive<TState extends TurnState> {
|
|
|
243
255
|
* ```
|
|
244
256
|
*/
|
|
245
257
|
sendActivity (adapter: BaseAdapter, conversation: Conversation, activity: Partial<Activity>): Promise<ResourceResponse>
|
|
258
|
+
/**
|
|
259
|
+
* Sends an activity to a stored or explicitly supplied conversation.
|
|
260
|
+
*
|
|
261
|
+
* @param adapter - Channel adapter used to continue the conversation.
|
|
262
|
+
* @param conversationOrId - Conversation or stored conversation ID.
|
|
263
|
+
* @param activity - Activity fields to send.
|
|
264
|
+
* @returns The channel resource response.
|
|
265
|
+
*/
|
|
246
266
|
async sendActivity (
|
|
247
267
|
adapter: BaseAdapter,
|
|
248
268
|
conversationOrId: Conversation | string,
|
|
@@ -285,7 +305,9 @@ export class Proactive<TState extends TurnState> {
|
|
|
285
305
|
logger.warn('sendActivity: failed for conversation=%s: %s', id, caughtError)
|
|
286
306
|
throw caughtError
|
|
287
307
|
}
|
|
288
|
-
if (response === undefined)
|
|
308
|
+
if (response === undefined) {
|
|
309
|
+
throw ExceptionHelper.generateException(Error, Errors.ProactiveSendActivityNoResponse)
|
|
310
|
+
}
|
|
289
311
|
logger.debug('sendActivity: sent activity id=%s', response.id)
|
|
290
312
|
return response
|
|
291
313
|
})
|
|
@@ -359,6 +381,16 @@ export class Proactive<TState extends TurnState> {
|
|
|
359
381
|
* ```
|
|
360
382
|
*/
|
|
361
383
|
continueConversation (adapter: BaseAdapter, conversation: Conversation, handler: RouteHandler<TState>, autoSignInHandlers?: string[], continuationActivity?: Partial<Activity>): Promise<void>
|
|
384
|
+
/**
|
|
385
|
+
* Continues a stored or explicitly supplied conversation.
|
|
386
|
+
*
|
|
387
|
+
* @param adapter - Channel adapter used to continue the conversation.
|
|
388
|
+
* @param conversationOrId - Conversation or stored conversation ID.
|
|
389
|
+
* @param handler - Handler to execute in the continued turn.
|
|
390
|
+
* @param autoSignInHandlers - Connections for which tokens are acquired before the handler runs.
|
|
391
|
+
* @param continuationActivity - Activity fields merged into the continuation activity.
|
|
392
|
+
* @returns A promise that resolves after the continued turn completes.
|
|
393
|
+
*/
|
|
362
394
|
async continueConversation (
|
|
363
395
|
adapter: BaseAdapter,
|
|
364
396
|
conversationOrId: Conversation | string,
|
package/src/app/routeList.ts
CHANGED
|
@@ -9,9 +9,25 @@ import { RouteRank } from './routeRank'
|
|
|
9
9
|
import { RouteSelector } from './routeSelector'
|
|
10
10
|
import { TurnState } from './turnState'
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Maintains application routes in dispatch priority order.
|
|
14
|
+
*
|
|
15
|
+
* @typeParam TState - Turn state supplied to route handlers.
|
|
16
|
+
*/
|
|
12
17
|
export class RouteList<TState extends TurnState> {
|
|
13
18
|
private _routes: Array<AppRoute<TState>> = []
|
|
14
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Adds a route and orders it by route kind and rank.
|
|
22
|
+
*
|
|
23
|
+
* @param selector - Selector that determines whether the route matches.
|
|
24
|
+
* @param handler - Handler invoked for a matching route.
|
|
25
|
+
* @param isInvokeRoute - Whether the route handles invoke activities.
|
|
26
|
+
* @param rank - Rank used to order routes of the same kind.
|
|
27
|
+
* @param authHandlers - Authentication handlers required by the route.
|
|
28
|
+
* @param isAgenticRoute - Whether the route handles agentic requests.
|
|
29
|
+
* @returns This route list.
|
|
30
|
+
*/
|
|
15
31
|
public addRoute (
|
|
16
32
|
selector: RouteSelector,
|
|
17
33
|
handler: RouteHandler<TState>,
|
|
@@ -30,9 +46,15 @@ export class RouteList<TState extends TurnState> {
|
|
|
30
46
|
// Then by Rank
|
|
31
47
|
this._routes.sort((a, b) => {
|
|
32
48
|
const getPriority = (route: AppRoute<TState>) => {
|
|
33
|
-
if (route.isAgenticRoute && route.isInvokeRoute)
|
|
34
|
-
|
|
35
|
-
|
|
49
|
+
if (route.isAgenticRoute && route.isInvokeRoute) {
|
|
50
|
+
return 0
|
|
51
|
+
}
|
|
52
|
+
if (route.isInvokeRoute) {
|
|
53
|
+
return 1
|
|
54
|
+
}
|
|
55
|
+
if (route.isAgenticRoute) {
|
|
56
|
+
return 2
|
|
57
|
+
}
|
|
36
58
|
return 3
|
|
37
59
|
}
|
|
38
60
|
|
|
@@ -50,6 +72,11 @@ export class RouteList<TState extends TurnState> {
|
|
|
50
72
|
return this
|
|
51
73
|
}
|
|
52
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Iterates over routes in dispatch priority order.
|
|
77
|
+
*
|
|
78
|
+
* @returns An iterator over the registered routes.
|
|
79
|
+
*/
|
|
53
80
|
public [Symbol.iterator] (): Iterator<AppRoute<TState>> {
|
|
54
81
|
return this._routes[Symbol.iterator]()
|
|
55
82
|
}
|