@microsoft/agents-hosting 1.7.2 → 1.8.0-beta.36.gb033f0abc1
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 +64 -2
- package/dist/package.json +3 -3
- package/dist/src/agent-client/agentClient.d.ts +18 -6
- package/dist/src/agent-client/agentClient.js +34 -18
- package/dist/src/agent-client/agentClient.js.map +1 -1
- package/dist/src/agent-client/agentResponseHandler.d.ts +14 -9
- package/dist/src/agent-client/agentResponseHandler.js +10 -5
- package/dist/src/agent-client/agentResponseHandler.js.map +1 -1
- package/dist/src/agent-client/createAgentResponseHandler.d.ts +7 -2
- package/dist/src/agent-client/createAgentResponseHandler.js +55 -8
- package/dist/src/agent-client/createAgentResponseHandler.js.map +1 -1
- package/dist/src/app/adaptiveCards/activityValueParsers.d.ts +1 -4
- package/dist/src/app/adaptiveCards/activityValueParsers.js +2 -5
- package/dist/src/app/adaptiveCards/activityValueParsers.js.map +1 -1
- package/dist/src/app/adaptiveCards/adaptiveCardsActions.d.ts +18 -0
- package/dist/src/app/adaptiveCards/adaptiveCardsActions.js +53 -23
- package/dist/src/app/adaptiveCards/adaptiveCardsActions.js.map +1 -1
- package/dist/src/app/agentApplication.d.ts +3 -0
- package/dist/src/app/agentApplication.js +140 -81
- package/dist/src/app/agentApplication.js.map +1 -1
- package/dist/src/app/attachmentDownloader.d.ts +4 -1
- package/dist/src/app/attachmentDownloader.js +27 -5
- package/dist/src/app/attachmentDownloader.js.map +1 -1
- package/dist/src/app/auth/handlers/agenticAuthorization.d.ts +1 -1
- package/dist/src/app/auth/handlers/azureBotAuthorization.d.ts +1 -1
- package/dist/src/app/auth/types.d.ts +3 -4
- package/dist/src/app/index.d.ts +2 -0
- package/dist/src/app/index.js.map +1 -1
- package/dist/src/app/streaming/streamingResponse.d.ts +56 -0
- package/dist/src/app/streaming/streamingResponse.js +250 -26
- package/dist/src/app/streaming/streamingResponse.js.map +1 -1
- package/dist/src/app/teamsAttachmentDownloader.d.ts +3 -1
- package/dist/src/app/teamsAttachmentDownloader.js +12 -1
- package/dist/src/app/teamsAttachmentDownloader.js.map +1 -1
- package/dist/src/auth/authConfiguration.js +12 -0
- package/dist/src/auth/authConfiguration.js.map +1 -1
- package/dist/src/auth/index.d.ts +2 -1
- package/dist/src/auth/index.js +2 -1
- package/dist/src/auth/index.js.map +1 -1
- package/dist/src/auth/jwt-middleware.d.ts +6 -0
- package/dist/src/auth/jwt-middleware.js +263 -13
- package/dist/src/auth/jwt-middleware.js.map +1 -1
- package/dist/src/auth/msal/msalConnectionSettings.d.ts +8 -0
- package/dist/src/auth/msal/msalHttpRetryHandlerHelper.d.ts +34 -0
- package/dist/src/auth/msal/msalHttpRetryHandlerHelper.js +126 -0
- package/dist/src/auth/msal/msalHttpRetryHandlerHelper.js.map +1 -0
- package/dist/src/auth/msal/msalTokenProvider.d.ts +1 -0
- package/dist/src/auth/msal/msalTokenProvider.js +23 -14
- package/dist/src/auth/msal/msalTokenProvider.js.map +1 -1
- package/dist/src/auth/settings.d.ts +18 -0
- package/dist/src/auth/settings.js +8 -2
- package/dist/src/auth/settings.js.map +1 -1
- package/dist/src/cloudAdapter.d.ts +29 -2
- package/dist/src/cloudAdapter.js +44 -2
- package/dist/src/cloudAdapter.js.map +1 -1
- package/dist/src/errorHelper.js +137 -101
- package/dist/src/errorHelper.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/invoke/adaptiveCardInvokeValue.d.ts +5 -0
- package/dist/src/oauth/userTokenClient.d.ts +0 -1
- package/dist/src/oauth/userTokenClient.js +0 -1
- package/dist/src/oauth/userTokenClient.js.map +1 -1
- package/dist/src/observability/traces.d.ts +6 -0
- package/dist/src/observability/traces.js +20 -2
- package/dist/src/observability/traces.js.map +1 -1
- package/dist/src/outboundHostValidator.d.ts +47 -0
- package/dist/src/outboundHostValidator.js +149 -0
- package/dist/src/outboundHostValidator.js.map +1 -0
- package/dist/src/state/agentState.d.ts +5 -0
- package/dist/src/state/agentState.js +16 -3
- package/dist/src/state/agentState.js.map +1 -1
- package/package.json +3 -3
- package/src/agent-client/agentClient.ts +46 -23
- package/src/agent-client/agentResponseHandler.ts +14 -9
- package/src/agent-client/createAgentResponseHandler.ts +70 -9
- package/src/app/adaptiveCards/activityValueParsers.ts +3 -9
- package/src/app/adaptiveCards/adaptiveCardsActions.ts +52 -24
- package/src/app/agentApplication.ts +149 -77
- package/src/app/attachmentDownloader.ts +25 -5
- package/src/app/auth/handlers/agenticAuthorization.ts +1 -1
- package/src/app/auth/handlers/azureBotAuthorization.ts +1 -1
- package/src/app/auth/types.ts +3 -3
- package/src/app/index.ts +8 -0
- package/src/app/streaming/streamingResponse.ts +276 -22
- package/src/app/teamsAttachmentDownloader.ts +11 -1
- package/src/auth/authConfiguration.ts +12 -0
- package/src/auth/index.ts +2 -1
- package/src/auth/jwt-middleware.ts +298 -14
- package/src/auth/msal/msalConnectionSettings.ts +10 -0
- package/src/auth/msal/msalHttpRetryHandlerHelper.ts +161 -0
- package/src/auth/msal/msalTokenProvider.ts +32 -14
- package/src/auth/settings.ts +18 -3
- package/src/cloudAdapter.ts +56 -3
- package/src/errorHelper.ts +155 -114
- package/src/index.ts +1 -0
- package/src/invoke/adaptiveCardInvokeValue.ts +5 -0
- package/src/oauth/userTokenClient.ts +0 -1
- package/src/observability/traces.ts +19 -1
- package/src/outboundHostValidator.ts +172 -0
- package/src/state/agentState.ts +24 -6
|
@@ -8,6 +8,7 @@ exports.AttachmentDownloader = void 0;
|
|
|
8
8
|
const httpClient_1 = require("../httpClient");
|
|
9
9
|
const agents_telemetry_1 = require("@microsoft/agents-telemetry");
|
|
10
10
|
const auth_1 = require("../auth");
|
|
11
|
+
const outboundHostValidator_1 = require("../outboundHostValidator");
|
|
11
12
|
const logger = (0, agents_telemetry_1.debug)('agents:attachmentDownloader');
|
|
12
13
|
/**
|
|
13
14
|
* A utility class for downloading input files from activity attachments.
|
|
@@ -25,10 +26,12 @@ class AttachmentDownloader {
|
|
|
25
26
|
* This class is responsible for downloading input files from attachments.
|
|
26
27
|
*
|
|
27
28
|
* @param stateKey The key to store files in state. Defaults to 'inputFiles'.
|
|
29
|
+
* @param outboundHostValidator Optional shared policy used to validate outbound attachment URLs.
|
|
28
30
|
*/
|
|
29
|
-
constructor(stateKey = 'inputFiles') {
|
|
31
|
+
constructor(stateKey = 'inputFiles', outboundHostValidator) {
|
|
30
32
|
this._httpClient = new httpClient_1.HttpClient();
|
|
31
33
|
this._stateKey = stateKey;
|
|
34
|
+
this._hostValidator = outboundHostValidator !== null && outboundHostValidator !== void 0 ? outboundHostValidator : (0, outboundHostValidator_1.createOutboundHostValidator)();
|
|
32
35
|
}
|
|
33
36
|
/**
|
|
34
37
|
* Downloads files from the attachments in the current turn context.
|
|
@@ -37,15 +40,25 @@ class AttachmentDownloader {
|
|
|
37
40
|
* @returns A promise that resolves to an array of downloaded input files.
|
|
38
41
|
*/
|
|
39
42
|
async downloadFiles(context) {
|
|
40
|
-
var _a;
|
|
43
|
+
var _a, _b, _c, _d;
|
|
41
44
|
const attachments = (_a = context.activity.attachments) === null || _a === void 0 ? void 0 : _a.filter((a) => !a.contentType.startsWith('text/html'));
|
|
42
45
|
if (!attachments || attachments.length === 0) {
|
|
43
46
|
logger.info('No Attachments to download');
|
|
44
47
|
return Promise.resolve([]);
|
|
45
48
|
}
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
+
let accessToken = '';
|
|
50
|
+
const connectionManager = (_b = context.adapter) === null || _b === void 0 ? void 0 : _b.connectionManager;
|
|
51
|
+
const identity = context.identity;
|
|
52
|
+
if (connectionManager && identity) {
|
|
53
|
+
const scope = (_d = (_c = identity.azp) !== null && _c !== void 0 ? _c : identity.appid) !== null && _d !== void 0 ? _d : 'https://api.botframework.com';
|
|
54
|
+
logger.debug(`Using adapter connection manager token provider for attachment downloads with scope ${scope}`);
|
|
55
|
+
accessToken = await connectionManager.getTokenProviderFromActivity(identity, context.activity).getAccessToken(scope);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
logger.debug('Using MsalTokenProvider fallback for attachment downloads');
|
|
59
|
+
const authProvider = new auth_1.MsalTokenProvider();
|
|
60
|
+
accessToken = await authProvider.getAccessToken((0, auth_1.loadAuthConfigFromEnv)(), 'https://api.botframework.com');
|
|
61
|
+
}
|
|
49
62
|
const files = [];
|
|
50
63
|
for (const attachment of attachments) {
|
|
51
64
|
const file = await this.downloadFile(attachment, accessToken);
|
|
@@ -74,6 +87,15 @@ class AttachmentDownloader {
|
|
|
74
87
|
if (accessToken.length > 0) {
|
|
75
88
|
headers.Authorization = `Bearer ${accessToken}`;
|
|
76
89
|
}
|
|
90
|
+
if (!this._hostValidator.isAllowed(attachment.contentUrl)) {
|
|
91
|
+
let host = '[invalid-url]';
|
|
92
|
+
try {
|
|
93
|
+
host = new URL(attachment.contentUrl).hostname;
|
|
94
|
+
}
|
|
95
|
+
catch { /* invalid */ }
|
|
96
|
+
logger.warn(`Attachment contentUrl host is not in the configured allowed hosts. Host='${host}'`);
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
77
99
|
const response = await this._httpClient.get(attachment.contentUrl, {
|
|
78
100
|
headers,
|
|
79
101
|
responseType: 'arraybuffer'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachmentDownloader.js","sourceRoot":"","sources":["../../../src/app/attachmentDownloader.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,8CAA0C;AAM1C,kEAAmD;AACnD,kCAAkE;
|
|
1
|
+
{"version":3,"file":"attachmentDownloader.js","sourceRoot":"","sources":["../../../src/app/attachmentDownloader.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@ import { TokenResponse } from '../../../oauth';
|
|
|
13
13
|
* where `{handlerId}` is the handler's unique identifier and `{propertyName}` matches the property name.
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
|
-
* ```
|
|
16
|
+
* ```
|
|
17
17
|
* # For a handler with id "myAuth":
|
|
18
18
|
* AgentApplication__UserAuthorization__handlers__myAuth__settings__type=AgenticUserAuthorization
|
|
19
19
|
* AgentApplication__UserAuthorization__handlers__myAuth__settings__scopes=api://scope1 api://scope2
|
|
@@ -30,7 +30,7 @@ interface AzureBotActiveHandler extends ActiveAuthorizationHandler {
|
|
|
30
30
|
* where `{handlerId}` is the handler's unique identifier and `{propertyName}` matches the property name.
|
|
31
31
|
*
|
|
32
32
|
* @example
|
|
33
|
-
* ```
|
|
33
|
+
* ```
|
|
34
34
|
* # For a handler with id "myAuth":
|
|
35
35
|
* AgentApplication__UserAuthorization__handlers__myAuth__settings__azureBotOAuthConnectionName=MyConnection
|
|
36
36
|
* AgentApplication__UserAuthorization__handlers__myAuth__settings__oboScopes=api://scope1 api://scope2
|
|
@@ -118,7 +118,7 @@ export interface AuthorizationHandlerTokenOptions {
|
|
|
118
118
|
* where `{handlerId}` is the handler's unique identifier and `{propertyName}` matches the property name.
|
|
119
119
|
*
|
|
120
120
|
* @example
|
|
121
|
-
* ```
|
|
121
|
+
* ```
|
|
122
122
|
* # For a handler with id "myAuth":
|
|
123
123
|
* AgentApplication__UserAuthorization__handlers__myAuth__settings__azureBotOAuthConnectionName=MyConnection
|
|
124
124
|
* AgentApplication__UserAuthorization__handlers__myAuth__settings__oboScopes=api://scope1 api://scope2
|
|
@@ -161,7 +161,7 @@ export interface AzureBotAuthorizationOptionsLegacy {
|
|
|
161
161
|
* @deprecated
|
|
162
162
|
* Messages configuration for the AzureBotAuthorization handler.
|
|
163
163
|
*/
|
|
164
|
-
interface AzureBotAuthorizationOptionsMessages {
|
|
164
|
+
export interface AzureBotAuthorizationOptionsMessages {
|
|
165
165
|
/**
|
|
166
166
|
* @deprecated Use `invalidSignInRetryMessage` instead.
|
|
167
167
|
* Message displayed when an invalid code is entered.
|
|
@@ -188,7 +188,7 @@ interface AzureBotAuthorizationOptionsMessages {
|
|
|
188
188
|
* @deprecated
|
|
189
189
|
* Settings for on-behalf-of token acquisition.
|
|
190
190
|
*/
|
|
191
|
-
interface AzureBotAuthorizationOptionsOBO {
|
|
191
|
+
export interface AzureBotAuthorizationOptionsOBO {
|
|
192
192
|
/**
|
|
193
193
|
* @deprecated Use `oboConnectionName` instead.
|
|
194
194
|
* Connection name to use for on-behalf-of token acquisition.
|
|
@@ -200,4 +200,3 @@ interface AzureBotAuthorizationOptionsOBO {
|
|
|
200
200
|
*/
|
|
201
201
|
scopes?: string[];
|
|
202
202
|
}
|
|
203
|
-
export {};
|
package/dist/src/app/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export * from './agentApplicationBuilder';
|
|
|
3
3
|
export * from './agentApplicationOptions';
|
|
4
4
|
export * from './appRoute';
|
|
5
5
|
export { Authorization } from './auth/authorization';
|
|
6
|
+
export type { AgenticAuthorizationOptions, AzureBotAuthorizationOptions } from './auth/handlers';
|
|
7
|
+
export type { AuthorizationOptions, AuthorizationHandlerTokenOptions, AzureBotAuthorizationOptionsLegacy, AzureBotAuthorizationOptionsMessages, AzureBotAuthorizationOptionsOBO } from './auth/types';
|
|
6
8
|
export * from './routeHandler';
|
|
7
9
|
export * from './routeList';
|
|
8
10
|
export * from './routeRank';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/app/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAkC;AAClC,4DAAyC;AACzC,4DAAyC;AACzC,6CAA0B;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/app/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAkC;AAClC,4DAAyC;AACzC,4DAAyC;AACzC,6CAA0B;AAU1B,iDAA8B;AAC9B,8CAA2B;AAC3B,8CAA2B;AAC3B,kDAA+B;AAC/B,yDAAsC;AACtC,6DAA0C;AAC1C,8CAA2B;AAC3B,+CAA4B;AAC5B,mDAAgC;AAChC,wDAAqC;AACrC,8CAA2B;AAC3B,+CAA4B;AAC5B,kDAA+B;AAC/B,gEAA6C;AAC7C,uDAAoC;AACpC,8DAA2C;AAC3C,8CAA2B"}
|
|
@@ -49,6 +49,13 @@ export declare class StreamingResponse {
|
|
|
49
49
|
private _finalMessage?;
|
|
50
50
|
private _canceled;
|
|
51
51
|
private _userCanceled;
|
|
52
|
+
private _streamTimedOut;
|
|
53
|
+
private _streamTimeoutNotificationSent;
|
|
54
|
+
private _lastInformationalMessageSent;
|
|
55
|
+
private _streamStartedAt?;
|
|
56
|
+
private _keepAliveTimer?;
|
|
57
|
+
private _streamTimeoutTimer?;
|
|
58
|
+
private _streamingTakingTooLongMessage;
|
|
52
59
|
private _queue;
|
|
53
60
|
private _queueSync;
|
|
54
61
|
private _chunkQueued;
|
|
@@ -95,6 +102,14 @@ export declare class StreamingResponse {
|
|
|
95
102
|
* Gets whether the channel supports streaming.
|
|
96
103
|
*/
|
|
97
104
|
get isStreamingChannel(): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Gets the message sent when streaming takes longer than the channel allows.
|
|
107
|
+
*/
|
|
108
|
+
get streamingTakingTooLongMessage(): string;
|
|
109
|
+
/**
|
|
110
|
+
* Sets the message sent when streaming takes longer than the channel allows.
|
|
111
|
+
*/
|
|
112
|
+
set streamingTakingTooLongMessage(message: string);
|
|
98
113
|
/**
|
|
99
114
|
* Queues an informative update to be sent to the client.
|
|
100
115
|
*
|
|
@@ -189,6 +204,13 @@ export declare class StreamingResponse {
|
|
|
189
204
|
* @returns The streamed message.
|
|
190
205
|
*/
|
|
191
206
|
getMessage(): string;
|
|
207
|
+
/**
|
|
208
|
+
* Ends the streaming portion of a response while allowing the underlying operation to continue.
|
|
209
|
+
*
|
|
210
|
+
* @param message Message sent to notify the user that streaming has stopped.
|
|
211
|
+
* @returns Whether the streaming response was stopped.
|
|
212
|
+
*/
|
|
213
|
+
sendStreamTimedOutNotification(message: string): Promise<boolean>;
|
|
192
214
|
/**
|
|
193
215
|
* Waits for the outgoing activity queue to be empty.
|
|
194
216
|
*
|
|
@@ -216,6 +238,19 @@ export declare class StreamingResponse {
|
|
|
216
238
|
* Creates the final message to be sent at the end of the stream.
|
|
217
239
|
*/
|
|
218
240
|
private createFinalMessage;
|
|
241
|
+
/**
|
|
242
|
+
* Creates the final streaming notification used when streaming stops but processing continues.
|
|
243
|
+
*/
|
|
244
|
+
private createStreamStoppedMessage;
|
|
245
|
+
/**
|
|
246
|
+
* Creates a checkpoint or final notification for a channel streaming timeout.
|
|
247
|
+
*/
|
|
248
|
+
private createStreamTimedOutMessage;
|
|
249
|
+
/**
|
|
250
|
+
* Creates the last streaming update sent before proactively finalizing an
|
|
251
|
+
* M365 Copilot stream.
|
|
252
|
+
*/
|
|
253
|
+
private createStreamTimedOutStreamingUpdate;
|
|
219
254
|
/**
|
|
220
255
|
* Sends an activity to the client and saves the stream ID returned.
|
|
221
256
|
*
|
|
@@ -224,6 +259,27 @@ export declare class StreamingResponse {
|
|
|
224
259
|
* @private
|
|
225
260
|
*/
|
|
226
261
|
private sendActivity;
|
|
262
|
+
/**
|
|
263
|
+
* Updates the existing streaming activity without allowing failures to escape the queue.
|
|
264
|
+
*/
|
|
265
|
+
private updateActivity;
|
|
266
|
+
/**
|
|
267
|
+
* Starts M365 Copilot keep-alive and maximum-duration timers.
|
|
268
|
+
*/
|
|
269
|
+
private startStreamTimers;
|
|
270
|
+
/**
|
|
271
|
+
* Schedules an informative update before M365 Copilot's idle timeout.
|
|
272
|
+
*/
|
|
273
|
+
private scheduleKeepAlive;
|
|
274
|
+
/**
|
|
275
|
+
* Finalizes an M365 Copilot stream that reached the channel duration limit.
|
|
276
|
+
*/
|
|
277
|
+
private handleM365StreamTimeout;
|
|
278
|
+
/**
|
|
279
|
+
* Stops active channel timeout timers.
|
|
280
|
+
*/
|
|
281
|
+
private clearStreamTimers;
|
|
282
|
+
private isM365Copilot;
|
|
227
283
|
/**
|
|
228
284
|
* Loads default values for the streaming response.
|
|
229
285
|
*/
|
|
@@ -10,6 +10,10 @@ const citationUtil_1 = require("./citationUtil");
|
|
|
10
10
|
const agents_telemetry_1 = require("@microsoft/agents-telemetry");
|
|
11
11
|
const errorHelper_1 = require("../../errorHelper");
|
|
12
12
|
const logger = (0, agents_telemetry_1.debug)('agents:streamingResponse');
|
|
13
|
+
const teamsStreamTimedOut = 'Content stream finished due to exceeded streaming time.';
|
|
14
|
+
const defaultStreamingTakingTooLongMessage = 'The response is taking longer than expected. Please wait while we continue to generate the response.';
|
|
15
|
+
const m365StreamingTimeoutMs = 105000;
|
|
16
|
+
const m365WorkingNoticeIntervalMs = 35000;
|
|
13
17
|
/**
|
|
14
18
|
* Results for streaming response operations.
|
|
15
19
|
*/
|
|
@@ -58,6 +62,10 @@ class StreamingResponse {
|
|
|
58
62
|
this._isStreamingChannel = true;
|
|
59
63
|
this._canceled = false;
|
|
60
64
|
this._userCanceled = false;
|
|
65
|
+
this._streamTimedOut = false;
|
|
66
|
+
this._streamTimeoutNotificationSent = false;
|
|
67
|
+
this._lastInformationalMessageSent = '';
|
|
68
|
+
this._streamingTakingTooLongMessage = defaultStreamingTakingTooLongMessage;
|
|
61
69
|
// Queue for outgoing activities
|
|
62
70
|
this._queue = [];
|
|
63
71
|
this._chunkQueued = false;
|
|
@@ -109,12 +117,27 @@ class StreamingResponse {
|
|
|
109
117
|
get isStreamingChannel() {
|
|
110
118
|
return this._isStreamingChannel;
|
|
111
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Gets the message sent when streaming takes longer than the channel allows.
|
|
122
|
+
*/
|
|
123
|
+
get streamingTakingTooLongMessage() {
|
|
124
|
+
return this._streamingTakingTooLongMessage;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Sets the message sent when streaming takes longer than the channel allows.
|
|
128
|
+
*/
|
|
129
|
+
set streamingTakingTooLongMessage(message) {
|
|
130
|
+
this._streamingTakingTooLongMessage = message;
|
|
131
|
+
}
|
|
112
132
|
/**
|
|
113
133
|
* Queues an informative update to be sent to the client.
|
|
114
134
|
*
|
|
115
135
|
* @param {string} text Text of the update to send.
|
|
116
136
|
*/
|
|
117
137
|
queueInformativeUpdate(text) {
|
|
138
|
+
if (this.isM365Copilot()) {
|
|
139
|
+
this._lastInformationalMessageSent = text;
|
|
140
|
+
}
|
|
118
141
|
if (!this.isStreamingChannel || !text.trim() || this._canceled) {
|
|
119
142
|
return;
|
|
120
143
|
}
|
|
@@ -166,6 +189,7 @@ class StreamingResponse {
|
|
|
166
189
|
* @returns {Promise<StreamingResponseResult>} - StreamingResponseResult with the result of the streaming response.
|
|
167
190
|
*/
|
|
168
191
|
async endStream() {
|
|
192
|
+
var _a;
|
|
169
193
|
if (this._ended) {
|
|
170
194
|
return StreamingResponseResult.AlreadyEnded;
|
|
171
195
|
}
|
|
@@ -174,14 +198,33 @@ class StreamingResponse {
|
|
|
174
198
|
}
|
|
175
199
|
// Queue final message
|
|
176
200
|
this._ended = true;
|
|
201
|
+
this.clearStreamTimers();
|
|
177
202
|
if (!this.isStreamingChannel) {
|
|
178
|
-
|
|
203
|
+
// A failed streaming send may still be updating the timed-out activity.
|
|
204
|
+
// Preserve ordering so that the completed response is always the last update.
|
|
205
|
+
await this.waitForQueue();
|
|
206
|
+
if (this._streamTimeoutNotificationSent && !this._message && !this._finalMessage && !((_a = this._attachments) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
207
|
+
return StreamingResponseResult.Success;
|
|
208
|
+
}
|
|
209
|
+
const finalMessage = this.createFinalMessage();
|
|
210
|
+
if (this._streamTimedOut) {
|
|
211
|
+
await this.updateActivity(finalMessage);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
await this.sendActivity(finalMessage);
|
|
215
|
+
}
|
|
179
216
|
return StreamingResponseResult.Success;
|
|
180
217
|
}
|
|
181
218
|
// Queue final message
|
|
182
219
|
this.queueNextChunk();
|
|
183
220
|
// Wait for the queue to drain
|
|
184
221
|
await this.waitForQueue();
|
|
222
|
+
// The final streaming send itself can report that the channel timed out. In
|
|
223
|
+
// that case the queued final activity is discarded and must be applied as
|
|
224
|
+
// an update after the timeout recovery has completed.
|
|
225
|
+
if (this._streamTimedOut) {
|
|
226
|
+
await this.updateActivity(this.createFinalMessage());
|
|
227
|
+
}
|
|
185
228
|
return StreamingResponseResult.Success;
|
|
186
229
|
}
|
|
187
230
|
/**
|
|
@@ -190,12 +233,17 @@ class StreamingResponse {
|
|
|
190
233
|
*/
|
|
191
234
|
async reset() {
|
|
192
235
|
await this.waitForQueue();
|
|
236
|
+
this.clearStreamTimers();
|
|
193
237
|
this._queueSync = undefined;
|
|
194
238
|
this._queue = [];
|
|
195
239
|
this._chunkQueued = false;
|
|
196
240
|
this._ended = false;
|
|
197
241
|
this._canceled = false;
|
|
198
242
|
this._userCanceled = false;
|
|
243
|
+
this._streamTimedOut = false;
|
|
244
|
+
this._streamTimeoutNotificationSent = false;
|
|
245
|
+
this._lastInformationalMessageSent = '';
|
|
246
|
+
this._streamStartedAt = undefined;
|
|
199
247
|
this._message = '';
|
|
200
248
|
this._nextSequence = 1;
|
|
201
249
|
this._streamId = undefined;
|
|
@@ -311,6 +359,26 @@ class StreamingResponse {
|
|
|
311
359
|
getMessage() {
|
|
312
360
|
return this._message;
|
|
313
361
|
}
|
|
362
|
+
/**
|
|
363
|
+
* Ends the streaming portion of a response while allowing the underlying operation to continue.
|
|
364
|
+
*
|
|
365
|
+
* @param message Message sent to notify the user that streaming has stopped.
|
|
366
|
+
* @returns Whether the streaming response was stopped.
|
|
367
|
+
*/
|
|
368
|
+
async sendStreamTimedOutNotification(message) {
|
|
369
|
+
if (this._ended || this._canceled || !this.isStreamingChannel) {
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
// Ensure any in-flight queued sends complete before we send the timeout notification.
|
|
373
|
+
await this.waitForQueue();
|
|
374
|
+
await this.sendActivity(this.createStreamStoppedMessage(message));
|
|
375
|
+
this._streamTimeoutNotificationSent = true;
|
|
376
|
+
this._isStreamingChannel = false;
|
|
377
|
+
this._queue = [];
|
|
378
|
+
this._chunkQueued = false;
|
|
379
|
+
this.clearStreamTimers();
|
|
380
|
+
return true;
|
|
381
|
+
}
|
|
314
382
|
/**
|
|
315
383
|
* Waits for the outgoing activity queue to be empty.
|
|
316
384
|
*
|
|
@@ -395,6 +463,9 @@ class StreamingResponse {
|
|
|
395
463
|
(_b = activity.entities) !== null && _b !== void 0 ? _b : (activity.entities = []);
|
|
396
464
|
activity.attachments = this._attachments;
|
|
397
465
|
this._nextSequence++; // Increment sequence for final message, even if not streaming.
|
|
466
|
+
if (this._streamTimedOut && this._streamId) {
|
|
467
|
+
activity.id = this._streamId;
|
|
468
|
+
}
|
|
398
469
|
if (this.isStreamingChannel) {
|
|
399
470
|
activity.entities.push({
|
|
400
471
|
type: 'streaminfo',
|
|
@@ -404,6 +475,65 @@ class StreamingResponse {
|
|
|
404
475
|
}
|
|
405
476
|
return activity;
|
|
406
477
|
}
|
|
478
|
+
/**
|
|
479
|
+
* Creates the final streaming notification used when streaming stops but processing continues.
|
|
480
|
+
*/
|
|
481
|
+
createStreamStoppedMessage(message) {
|
|
482
|
+
return agents_activity_1.Activity.fromObject({
|
|
483
|
+
type: 'message',
|
|
484
|
+
text: message || 'No text was streamed',
|
|
485
|
+
entities: [{
|
|
486
|
+
type: 'streaminfo',
|
|
487
|
+
streamType: 'final',
|
|
488
|
+
streamResult: this._message ? 'success' : 'error',
|
|
489
|
+
streamSequence: this._nextSequence++
|
|
490
|
+
}]
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Creates a checkpoint or final notification for a channel streaming timeout.
|
|
495
|
+
*/
|
|
496
|
+
createStreamTimedOutMessage(addStreamFinal = false) {
|
|
497
|
+
const text = this._message
|
|
498
|
+
? `${this._message}\n\n${this.streamingTakingTooLongMessage}\n`
|
|
499
|
+
: this.streamingTakingTooLongMessage;
|
|
500
|
+
const activity = agents_activity_1.Activity.fromObject({
|
|
501
|
+
type: 'message',
|
|
502
|
+
text,
|
|
503
|
+
entities: []
|
|
504
|
+
});
|
|
505
|
+
if (this._streamId) {
|
|
506
|
+
activity.id = this._streamId;
|
|
507
|
+
}
|
|
508
|
+
if (addStreamFinal) {
|
|
509
|
+
activity.entities.push({
|
|
510
|
+
type: 'streaminfo',
|
|
511
|
+
streamType: 'final',
|
|
512
|
+
streamId: this._streamId,
|
|
513
|
+
streamResult: this._message ? 'success' : 'error',
|
|
514
|
+
streamSequence: this._nextSequence++
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
return activity;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Creates the last streaming update sent before proactively finalizing an
|
|
521
|
+
* M365 Copilot stream.
|
|
522
|
+
*/
|
|
523
|
+
createStreamTimedOutStreamingUpdate() {
|
|
524
|
+
const text = this._message
|
|
525
|
+
? `${this._message}\n\n${this.streamingTakingTooLongMessage}\n`
|
|
526
|
+
: this.streamingTakingTooLongMessage;
|
|
527
|
+
return agents_activity_1.Activity.fromObject({
|
|
528
|
+
type: 'typing',
|
|
529
|
+
text,
|
|
530
|
+
entities: [{
|
|
531
|
+
type: 'streaminfo',
|
|
532
|
+
streamType: 'streaming',
|
|
533
|
+
streamSequence: this._nextSequence++
|
|
534
|
+
}]
|
|
535
|
+
});
|
|
536
|
+
}
|
|
407
537
|
/**
|
|
408
538
|
* Sends an activity to the client and saves the stream ID returned.
|
|
409
539
|
*
|
|
@@ -412,21 +542,19 @@ class StreamingResponse {
|
|
|
412
542
|
* @private
|
|
413
543
|
*/
|
|
414
544
|
async sendActivity(activity) {
|
|
415
|
-
var _a, _b;
|
|
416
|
-
|
|
417
|
-
|
|
545
|
+
var _a, _b, _c;
|
|
546
|
+
this.startStreamTimers();
|
|
547
|
+
// Only streaming activities should carry stream metadata. Once streaming
|
|
548
|
+
// has stopped, the completed response must be sent as an independent
|
|
549
|
+
// message without an orphaned streamId entity.
|
|
550
|
+
const streamInfo = (_a = activity.entities) === null || _a === void 0 ? void 0 : _a.find(entity => { var _a; return ((_a = entity.type) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'streaminfo'; });
|
|
551
|
+
if (this._streamId && streamInfo) {
|
|
418
552
|
activity.id = this._streamId;
|
|
419
|
-
|
|
420
|
-
activity.entities = [];
|
|
421
|
-
}
|
|
422
|
-
if (!activity.entities[0]) {
|
|
423
|
-
activity.entities[0] = {};
|
|
424
|
-
}
|
|
425
|
-
activity.entities[0].streamId = this._streamId;
|
|
553
|
+
streamInfo.streamId = this._streamId;
|
|
426
554
|
}
|
|
427
555
|
if (this._citations && this._citations.length > 0 && !this._ended) {
|
|
428
556
|
// Filter out the citations unused in content.
|
|
429
|
-
const currCitations = (
|
|
557
|
+
const currCitations = (_b = citationUtil_1.CitationUtil.getUsedCitations(this._message, this._citations)) !== null && _b !== void 0 ? _b : undefined;
|
|
430
558
|
activity.entities.push({
|
|
431
559
|
type: 'https://schema.org/Message',
|
|
432
560
|
'@type': 'Message',
|
|
@@ -438,7 +566,7 @@ class StreamingResponse {
|
|
|
438
566
|
// Add in Powered by AI feature flags
|
|
439
567
|
if (this._ended) {
|
|
440
568
|
activity.channelData = {
|
|
441
|
-
feedbackLoopEnabled: (
|
|
569
|
+
feedbackLoopEnabled: (_c = this._enableFeedbackLoop) !== null && _c !== void 0 ? _c : false,
|
|
442
570
|
...(this._feedbackLoopType ? { type: this._feedbackLoopType } : {})
|
|
443
571
|
};
|
|
444
572
|
// Add in Generated by AI
|
|
@@ -451,24 +579,127 @@ class StreamingResponse {
|
|
|
451
579
|
if (!this._streamId) {
|
|
452
580
|
this._streamId = response === null || response === void 0 ? void 0 : response.id;
|
|
453
581
|
}
|
|
582
|
+
if (this.isM365Copilot() && this.isStreamingChannel && !this._ended) {
|
|
583
|
+
this.scheduleKeepAlive();
|
|
584
|
+
}
|
|
454
585
|
await new Promise((resolve) => setTimeout(resolve, this.delayInMs));
|
|
455
586
|
}
|
|
456
587
|
catch (error) {
|
|
457
|
-
const
|
|
588
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
458
589
|
this._canceled = true;
|
|
459
|
-
this._queueSync = undefined;
|
|
460
590
|
this._queue = [];
|
|
591
|
+
this._chunkQueued = false;
|
|
592
|
+
this.clearStreamTimers();
|
|
461
593
|
// MS Teams code list: https://learn.microsoft.com/en-us/microsoftteams/platform/bots/streaming-ux?tabs=jsts#error-codes
|
|
462
|
-
|
|
594
|
+
const normalizedMessage = message.toLowerCase();
|
|
595
|
+
if (normalizedMessage.includes('contentstreamnotallowed') && normalizedMessage.includes(teamsStreamTimedOut.toLowerCase())) {
|
|
596
|
+
logger.warn('Client canceled due to exceeded allowed streaming time.', { originalError: message });
|
|
597
|
+
this._streamTimedOut = true;
|
|
598
|
+
this._canceled = false;
|
|
599
|
+
this._isStreamingChannel = false;
|
|
600
|
+
await this.updateActivity(this.createStreamTimedOutMessage());
|
|
601
|
+
}
|
|
602
|
+
else if (normalizedMessage.includes('contentstreamnotallowed')) {
|
|
463
603
|
logger.warn('Streaming content is not allowed by the client side.', { originalError: message });
|
|
464
604
|
this._userCanceled = true;
|
|
465
605
|
}
|
|
466
|
-
else if (
|
|
606
|
+
else if (normalizedMessage.includes('badargument') && normalizedMessage.includes('streaming api is not enabled')) {
|
|
467
607
|
logger.warn('Interaction does not support streaming. Defaulting to non-streaming response.', { originalError: message });
|
|
468
608
|
this._canceled = false;
|
|
469
609
|
this._isStreamingChannel = false;
|
|
470
610
|
}
|
|
611
|
+
else {
|
|
612
|
+
logger.error('Exception during StreamingResponse sendActivity.', { originalError: message });
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Updates the existing streaming activity without allowing failures to escape the queue.
|
|
618
|
+
*/
|
|
619
|
+
async updateActivity(activity) {
|
|
620
|
+
try {
|
|
621
|
+
await this._context.updateActivity(activity);
|
|
622
|
+
}
|
|
623
|
+
catch (error) {
|
|
624
|
+
logger.warn('Exception during StreamingResponse updateActivity.', { originalError: error.message });
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Starts M365 Copilot keep-alive and maximum-duration timers.
|
|
629
|
+
*/
|
|
630
|
+
startStreamTimers() {
|
|
631
|
+
if (!this.isM365Copilot() || !this.isStreamingChannel || this._streamStartedAt !== undefined) {
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
this._streamStartedAt = Date.now();
|
|
635
|
+
this.scheduleKeepAlive();
|
|
636
|
+
this._streamTimeoutTimer = setTimeout(() => {
|
|
637
|
+
this.handleM365StreamTimeout().catch(error => {
|
|
638
|
+
logger.error('Error handling the M365 Copilot streaming timeout.', { originalError: error.message });
|
|
639
|
+
});
|
|
640
|
+
}, m365StreamingTimeoutMs);
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Schedules an informative update before M365 Copilot's idle timeout.
|
|
644
|
+
*/
|
|
645
|
+
scheduleKeepAlive() {
|
|
646
|
+
if (!this.isM365Copilot() || !this.isStreamingChannel || this._ended) {
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
if (this._keepAliveTimer) {
|
|
650
|
+
clearTimeout(this._keepAliveTimer);
|
|
651
|
+
}
|
|
652
|
+
this._keepAliveTimer = setTimeout(() => {
|
|
653
|
+
this._keepAliveTimer = undefined;
|
|
654
|
+
if (!this._ended && this.isStreamingChannel && this._queue.length === 0) {
|
|
655
|
+
this.queueInformativeUpdate(this._lastInformationalMessageSent.trim()
|
|
656
|
+
? this._lastInformationalMessageSent
|
|
657
|
+
: this.streamingTakingTooLongMessage);
|
|
658
|
+
}
|
|
659
|
+
}, m365WorkingNoticeIntervalMs);
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Finalizes an M365 Copilot stream that reached the channel duration limit.
|
|
663
|
+
*/
|
|
664
|
+
async handleM365StreamTimeout() {
|
|
665
|
+
if (this._ended || this._canceled || !this.isStreamingChannel || !this.isM365Copilot()) {
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
logger.warn('M365 Copilot streaming response reached the maximum duration. Finalizing the stream and continuing in non-streaming mode.', {
|
|
669
|
+
streamId: this._streamId,
|
|
670
|
+
elapsedMs: this._streamStartedAt === undefined ? undefined : Date.now() - this._streamStartedAt
|
|
671
|
+
});
|
|
672
|
+
const timedOutActivities = this._message
|
|
673
|
+
? [this.createStreamTimedOutStreamingUpdate(), this.createStreamTimedOutMessage(true)]
|
|
674
|
+
: [this.createStreamTimedOutMessage(true)];
|
|
675
|
+
this._streamTimeoutNotificationSent = true;
|
|
676
|
+
this._isStreamingChannel = false;
|
|
677
|
+
this._queue = [];
|
|
678
|
+
this._chunkQueued = false;
|
|
679
|
+
this.clearStreamTimers();
|
|
680
|
+
// Queue these behind any in-flight send. Clearing pending activities and
|
|
681
|
+
// using the same drain prevents out-of-order stream sequences.
|
|
682
|
+
for (const activity of timedOutActivities) {
|
|
683
|
+
this.queueActivity(() => activity);
|
|
471
684
|
}
|
|
685
|
+
await this.waitForQueue();
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Stops active channel timeout timers.
|
|
689
|
+
*/
|
|
690
|
+
clearStreamTimers() {
|
|
691
|
+
if (this._keepAliveTimer) {
|
|
692
|
+
clearTimeout(this._keepAliveTimer);
|
|
693
|
+
this._keepAliveTimer = undefined;
|
|
694
|
+
}
|
|
695
|
+
if (this._streamTimeoutTimer) {
|
|
696
|
+
clearTimeout(this._streamTimeoutTimer);
|
|
697
|
+
this._streamTimeoutTimer = undefined;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
isM365Copilot() {
|
|
701
|
+
var _a;
|
|
702
|
+
return ((_a = this._context.activity.channelId) === null || _a === void 0 ? void 0 : _a.toLocaleLowerCase()) === agents_activity_1.Channels.M365Copilot.toLocaleLowerCase();
|
|
472
703
|
}
|
|
473
704
|
/**
|
|
474
705
|
* Loads default values for the streaming response.
|
|
@@ -481,15 +712,8 @@ class StreamingResponse {
|
|
|
481
712
|
this._isStreamingChannel = false;
|
|
482
713
|
}
|
|
483
714
|
else if (agents_activity_1.Channels.Msteams === activity.channelIdChannel) {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
// TODO: Enable streaming for agentic requests when supported.
|
|
487
|
-
this._isStreamingChannel = false;
|
|
488
|
-
}
|
|
489
|
-
else {
|
|
490
|
-
this._isStreamingChannel = true;
|
|
491
|
-
this._delayInMs = 1000;
|
|
492
|
-
}
|
|
715
|
+
this._isStreamingChannel = true;
|
|
716
|
+
this._delayInMs = 1000;
|
|
493
717
|
}
|
|
494
718
|
else if (agents_activity_1.Channels.Webchat === activity.channelId || agents_activity_1.Channels.Directline === activity.channelId || agents_activity_1.Channels.Emulator === activity.channelId) {
|
|
495
719
|
this._isStreamingChannel = true;
|