@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.
Files changed (102) hide show
  1. package/README.md +64 -2
  2. package/dist/package.json +3 -3
  3. package/dist/src/agent-client/agentClient.d.ts +18 -6
  4. package/dist/src/agent-client/agentClient.js +34 -18
  5. package/dist/src/agent-client/agentClient.js.map +1 -1
  6. package/dist/src/agent-client/agentResponseHandler.d.ts +14 -9
  7. package/dist/src/agent-client/agentResponseHandler.js +10 -5
  8. package/dist/src/agent-client/agentResponseHandler.js.map +1 -1
  9. package/dist/src/agent-client/createAgentResponseHandler.d.ts +7 -2
  10. package/dist/src/agent-client/createAgentResponseHandler.js +55 -8
  11. package/dist/src/agent-client/createAgentResponseHandler.js.map +1 -1
  12. package/dist/src/app/adaptiveCards/activityValueParsers.d.ts +1 -4
  13. package/dist/src/app/adaptiveCards/activityValueParsers.js +2 -5
  14. package/dist/src/app/adaptiveCards/activityValueParsers.js.map +1 -1
  15. package/dist/src/app/adaptiveCards/adaptiveCardsActions.d.ts +18 -0
  16. package/dist/src/app/adaptiveCards/adaptiveCardsActions.js +53 -23
  17. package/dist/src/app/adaptiveCards/adaptiveCardsActions.js.map +1 -1
  18. package/dist/src/app/agentApplication.d.ts +3 -0
  19. package/dist/src/app/agentApplication.js +140 -81
  20. package/dist/src/app/agentApplication.js.map +1 -1
  21. package/dist/src/app/attachmentDownloader.d.ts +4 -1
  22. package/dist/src/app/attachmentDownloader.js +27 -5
  23. package/dist/src/app/attachmentDownloader.js.map +1 -1
  24. package/dist/src/app/auth/handlers/agenticAuthorization.d.ts +1 -1
  25. package/dist/src/app/auth/handlers/azureBotAuthorization.d.ts +1 -1
  26. package/dist/src/app/auth/types.d.ts +3 -4
  27. package/dist/src/app/index.d.ts +2 -0
  28. package/dist/src/app/index.js.map +1 -1
  29. package/dist/src/app/streaming/streamingResponse.d.ts +56 -0
  30. package/dist/src/app/streaming/streamingResponse.js +250 -26
  31. package/dist/src/app/streaming/streamingResponse.js.map +1 -1
  32. package/dist/src/app/teamsAttachmentDownloader.d.ts +3 -1
  33. package/dist/src/app/teamsAttachmentDownloader.js +12 -1
  34. package/dist/src/app/teamsAttachmentDownloader.js.map +1 -1
  35. package/dist/src/auth/authConfiguration.js +12 -0
  36. package/dist/src/auth/authConfiguration.js.map +1 -1
  37. package/dist/src/auth/index.d.ts +2 -1
  38. package/dist/src/auth/index.js +2 -1
  39. package/dist/src/auth/index.js.map +1 -1
  40. package/dist/src/auth/jwt-middleware.d.ts +6 -0
  41. package/dist/src/auth/jwt-middleware.js +263 -13
  42. package/dist/src/auth/jwt-middleware.js.map +1 -1
  43. package/dist/src/auth/msal/msalConnectionSettings.d.ts +8 -0
  44. package/dist/src/auth/msal/msalHttpRetryHandlerHelper.d.ts +34 -0
  45. package/dist/src/auth/msal/msalHttpRetryHandlerHelper.js +126 -0
  46. package/dist/src/auth/msal/msalHttpRetryHandlerHelper.js.map +1 -0
  47. package/dist/src/auth/msal/msalTokenProvider.d.ts +1 -0
  48. package/dist/src/auth/msal/msalTokenProvider.js +23 -14
  49. package/dist/src/auth/msal/msalTokenProvider.js.map +1 -1
  50. package/dist/src/auth/settings.d.ts +18 -0
  51. package/dist/src/auth/settings.js +8 -2
  52. package/dist/src/auth/settings.js.map +1 -1
  53. package/dist/src/cloudAdapter.d.ts +29 -2
  54. package/dist/src/cloudAdapter.js +44 -2
  55. package/dist/src/cloudAdapter.js.map +1 -1
  56. package/dist/src/errorHelper.js +137 -101
  57. package/dist/src/errorHelper.js.map +1 -1
  58. package/dist/src/index.d.ts +1 -0
  59. package/dist/src/index.js +1 -0
  60. package/dist/src/index.js.map +1 -1
  61. package/dist/src/invoke/adaptiveCardInvokeValue.d.ts +5 -0
  62. package/dist/src/oauth/userTokenClient.d.ts +0 -1
  63. package/dist/src/oauth/userTokenClient.js +0 -1
  64. package/dist/src/oauth/userTokenClient.js.map +1 -1
  65. package/dist/src/observability/traces.d.ts +6 -0
  66. package/dist/src/observability/traces.js +20 -2
  67. package/dist/src/observability/traces.js.map +1 -1
  68. package/dist/src/outboundHostValidator.d.ts +47 -0
  69. package/dist/src/outboundHostValidator.js +149 -0
  70. package/dist/src/outboundHostValidator.js.map +1 -0
  71. package/dist/src/state/agentState.d.ts +5 -0
  72. package/dist/src/state/agentState.js +16 -3
  73. package/dist/src/state/agentState.js.map +1 -1
  74. package/package.json +3 -3
  75. package/src/agent-client/agentClient.ts +46 -23
  76. package/src/agent-client/agentResponseHandler.ts +14 -9
  77. package/src/agent-client/createAgentResponseHandler.ts +70 -9
  78. package/src/app/adaptiveCards/activityValueParsers.ts +3 -9
  79. package/src/app/adaptiveCards/adaptiveCardsActions.ts +52 -24
  80. package/src/app/agentApplication.ts +149 -77
  81. package/src/app/attachmentDownloader.ts +25 -5
  82. package/src/app/auth/handlers/agenticAuthorization.ts +1 -1
  83. package/src/app/auth/handlers/azureBotAuthorization.ts +1 -1
  84. package/src/app/auth/types.ts +3 -3
  85. package/src/app/index.ts +8 -0
  86. package/src/app/streaming/streamingResponse.ts +276 -22
  87. package/src/app/teamsAttachmentDownloader.ts +11 -1
  88. package/src/auth/authConfiguration.ts +12 -0
  89. package/src/auth/index.ts +2 -1
  90. package/src/auth/jwt-middleware.ts +298 -14
  91. package/src/auth/msal/msalConnectionSettings.ts +10 -0
  92. package/src/auth/msal/msalHttpRetryHandlerHelper.ts +161 -0
  93. package/src/auth/msal/msalTokenProvider.ts +32 -14
  94. package/src/auth/settings.ts +18 -3
  95. package/src/cloudAdapter.ts +56 -3
  96. package/src/errorHelper.ts +155 -114
  97. package/src/index.ts +1 -0
  98. package/src/invoke/adaptiveCardInvokeValue.ts +5 -0
  99. package/src/oauth/userTokenClient.ts +0 -1
  100. package/src/observability/traces.ts +19 -1
  101. package/src/outboundHostValidator.ts +172 -0
  102. 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
- // TODO: from adapter
47
- const authProvider = new auth_1.MsalTokenProvider();
48
- const accessToken = await authProvider.getAccessToken((0, auth_1.loadAuthConfigFromEnv)(), 'https://api.botframework.com');
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":"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"}
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
- * ```env
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
- * ```env
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
- * ```env
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 {};
@@ -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;AAE1B,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"}
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
- await this.sendActivity(this.createFinalMessage());
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
- // Set activity ID to the assigned stream ID
417
- if (this._streamId) {
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
- if (!activity.entities) {
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 = (_a = citationUtil_1.CitationUtil.getUsedCitations(this._message, this._citations)) !== null && _a !== void 0 ? _a : undefined;
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: (_b = this._enableFeedbackLoop) !== null && _b !== void 0 ? _b : false,
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 { message } = error;
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
- if (message.includes('ContentStreamNotAllowed')) {
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 (message.includes('BadArgument') && message.toLowerCase().includes('streaming api is not enabled')) {
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
- if (activity.isAgenticRequest()) {
485
- // Agentic requests do not support streaming responses at this time.
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;