@microsoft/agents-hosting 1.5.0-beta.6.ga236d9a19c → 1.5.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.
Files changed (157) hide show
  1. package/dist/package.json +10 -9
  2. package/dist/src/activityHandler.js +2 -2
  3. package/dist/src/activityHandler.js.map +1 -1
  4. package/dist/src/agent-client/agentClient.js +49 -40
  5. package/dist/src/agent-client/agentClient.js.map +1 -1
  6. package/dist/src/agent-client/agentResponseHandler.js +2 -2
  7. package/dist/src/agent-client/agentResponseHandler.js.map +1 -1
  8. package/dist/src/app/agentApplication.d.ts +36 -10
  9. package/dist/src/app/agentApplication.js +169 -99
  10. package/dist/src/app/agentApplication.js.map +1 -1
  11. package/dist/src/app/agentApplicationBuilder.d.ts +15 -0
  12. package/dist/src/app/agentApplicationBuilder.js +22 -4
  13. package/dist/src/app/agentApplicationBuilder.js.map +1 -1
  14. package/dist/src/app/agentApplicationOptions.d.ts +38 -0
  15. package/dist/src/app/attachmentDownloader.js +2 -2
  16. package/dist/src/app/attachmentDownloader.js.map +1 -1
  17. package/dist/src/app/auth/authorization.js +12 -9
  18. package/dist/src/app/auth/authorization.js.map +1 -1
  19. package/dist/src/app/auth/authorizationManager.d.ts +18 -5
  20. package/dist/src/app/auth/authorizationManager.js +258 -45
  21. package/dist/src/app/auth/authorizationManager.js.map +1 -1
  22. package/dist/src/app/auth/handlerStorage.js +3 -1
  23. package/dist/src/app/auth/handlerStorage.js.map +1 -1
  24. package/dist/src/app/auth/handlers/agenticAuthorization.d.ts +19 -16
  25. package/dist/src/app/auth/handlers/agenticAuthorization.js +46 -52
  26. package/dist/src/app/auth/handlers/agenticAuthorization.js.map +1 -1
  27. package/dist/src/app/auth/handlers/azureBotAuthorization.d.ts +51 -75
  28. package/dist/src/app/auth/handlers/azureBotAuthorization.js +217 -192
  29. package/dist/src/app/auth/handlers/azureBotAuthorization.js.map +1 -1
  30. package/dist/src/app/auth/types.d.ts +100 -1
  31. package/dist/src/app/auth/utils.d.ts +10 -0
  32. package/dist/src/app/auth/utils.js +21 -0
  33. package/dist/src/app/auth/utils.js.map +1 -0
  34. package/dist/src/app/index.d.ts +1 -0
  35. package/dist/src/app/index.js +1 -0
  36. package/dist/src/app/index.js.map +1 -1
  37. package/dist/src/app/proactive/conversation.d.ts +43 -0
  38. package/dist/src/app/proactive/conversation.js +67 -0
  39. package/dist/src/app/proactive/conversation.js.map +1 -0
  40. package/dist/src/app/proactive/conversationBuilder.d.ts +54 -0
  41. package/dist/src/app/proactive/conversationBuilder.js +110 -0
  42. package/dist/src/app/proactive/conversationBuilder.js.map +1 -0
  43. package/dist/src/app/proactive/conversationReferenceBuilder.d.ts +68 -0
  44. package/dist/src/app/proactive/conversationReferenceBuilder.js +125 -0
  45. package/dist/src/app/proactive/conversationReferenceBuilder.js.map +1 -0
  46. package/dist/src/app/proactive/createConversationOptions.d.ts +30 -0
  47. package/dist/src/app/proactive/createConversationOptions.js +10 -0
  48. package/dist/src/app/proactive/createConversationOptions.js.map +1 -0
  49. package/dist/src/app/proactive/createConversationOptionsBuilder.d.ts +69 -0
  50. package/dist/src/app/proactive/createConversationOptionsBuilder.js +141 -0
  51. package/dist/src/app/proactive/createConversationOptionsBuilder.js.map +1 -0
  52. package/dist/src/app/proactive/index.d.ts +7 -0
  53. package/dist/src/app/proactive/index.js +26 -0
  54. package/dist/src/app/proactive/index.js.map +1 -0
  55. package/dist/src/app/proactive/proactive.d.ts +248 -0
  56. package/dist/src/app/proactive/proactive.js +310 -0
  57. package/dist/src/app/proactive/proactive.js.map +1 -0
  58. package/dist/src/app/proactive/proactiveOptions.d.ts +19 -0
  59. package/dist/src/app/proactive/proactiveOptions.js +5 -0
  60. package/dist/src/app/proactive/proactiveOptions.js.map +1 -0
  61. package/dist/src/app/streaming/streamingResponse.js +2 -2
  62. package/dist/src/app/streaming/streamingResponse.js.map +1 -1
  63. package/dist/src/app/teamsAttachmentDownloader.js +2 -2
  64. package/dist/src/app/teamsAttachmentDownloader.js.map +1 -1
  65. package/dist/src/app/turnState.js +2 -2
  66. package/dist/src/app/turnState.js.map +1 -1
  67. package/dist/src/auth/authConfiguration.d.ts +61 -0
  68. package/dist/src/auth/authConfiguration.js +52 -3
  69. package/dist/src/auth/authConfiguration.js.map +1 -1
  70. package/dist/src/auth/jwt-middleware.js +2 -2
  71. package/dist/src/auth/jwt-middleware.js.map +1 -1
  72. package/dist/src/auth/msalConnectionManager.js +20 -0
  73. package/dist/src/auth/msalConnectionManager.js.map +1 -1
  74. package/dist/src/auth/msalTokenCredential.js +3 -0
  75. package/dist/src/auth/msalTokenCredential.js.map +1 -1
  76. package/dist/src/auth/msalTokenProvider.js +136 -110
  77. package/dist/src/auth/msalTokenProvider.js.map +1 -1
  78. package/dist/src/baseAdapter.js +2 -2
  79. package/dist/src/baseAdapter.js.map +1 -1
  80. package/dist/src/cloudAdapter.js +201 -154
  81. package/dist/src/cloudAdapter.js.map +1 -1
  82. package/dist/src/connector-client/connectorClient.js +176 -127
  83. package/dist/src/connector-client/connectorClient.js.map +1 -1
  84. package/dist/src/errorHelper.js +108 -0
  85. package/dist/src/errorHelper.js.map +1 -1
  86. package/dist/src/middlewareSet.js +2 -2
  87. package/dist/src/middlewareSet.js.map +1 -1
  88. package/dist/src/oauth/userTokenClient.js +78 -48
  89. package/dist/src/oauth/userTokenClient.js.map +1 -1
  90. package/dist/src/observability/index.d.ts +2 -0
  91. package/dist/src/observability/index.js +21 -0
  92. package/dist/src/observability/index.js.map +1 -0
  93. package/dist/src/observability/metrics.d.ts +21 -0
  94. package/dist/src/observability/metrics.js +87 -0
  95. package/dist/src/observability/metrics.js.map +1 -0
  96. package/dist/src/observability/traces.d.ts +234 -0
  97. package/dist/src/observability/traces.js +962 -0
  98. package/dist/src/observability/traces.js.map +1 -0
  99. package/dist/src/state/agentState.js +2 -2
  100. package/dist/src/state/agentState.js.map +1 -1
  101. package/dist/src/storage/fileStorage.js +38 -28
  102. package/dist/src/storage/fileStorage.js.map +1 -1
  103. package/dist/src/storage/memoryStorage.js +41 -30
  104. package/dist/src/storage/memoryStorage.js.map +1 -1
  105. package/dist/src/transcript/fileTranscriptLogger.js +2 -2
  106. package/dist/src/transcript/fileTranscriptLogger.js.map +1 -1
  107. package/dist/src/transcript/transcriptLoggerMiddleware.js +2 -2
  108. package/dist/src/transcript/transcriptLoggerMiddleware.js.map +1 -1
  109. package/dist/src/turnContext.js +48 -42
  110. package/dist/src/turnContext.js.map +1 -1
  111. package/package.json +10 -9
  112. package/src/activityHandler.ts +1 -1
  113. package/src/agent-client/agentClient.ts +53 -42
  114. package/src/agent-client/agentResponseHandler.ts +1 -1
  115. package/src/app/agentApplication.ts +212 -86
  116. package/src/app/agentApplicationBuilder.ts +26 -4
  117. package/src/app/agentApplicationOptions.ts +43 -0
  118. package/src/app/attachmentDownloader.ts +1 -1
  119. package/src/app/auth/authorization.ts +11 -8
  120. package/src/app/auth/authorizationManager.ts +297 -45
  121. package/src/app/auth/handlerStorage.ts +3 -1
  122. package/src/app/auth/handlers/agenticAuthorization.ts +68 -72
  123. package/src/app/auth/handlers/azureBotAuthorization.ts +260 -264
  124. package/src/app/auth/types.ts +102 -1
  125. package/src/app/auth/utils.ts +22 -0
  126. package/src/app/index.ts +1 -0
  127. package/src/app/proactive/conversation.ts +87 -0
  128. package/src/app/proactive/conversationBuilder.ts +139 -0
  129. package/src/app/proactive/conversationReferenceBuilder.ts +161 -0
  130. package/src/app/proactive/createConversationOptions.ts +35 -0
  131. package/src/app/proactive/createConversationOptionsBuilder.ts +181 -0
  132. package/src/app/proactive/index.ts +10 -0
  133. package/src/app/proactive/proactive.ts +524 -0
  134. package/src/app/proactive/proactiveOptions.ts +24 -0
  135. package/src/app/streaming/streamingResponse.ts +1 -1
  136. package/src/app/teamsAttachmentDownloader.ts +1 -1
  137. package/src/app/turnState.ts +1 -1
  138. package/src/auth/authConfiguration.ts +58 -1
  139. package/src/auth/jwt-middleware.ts +1 -1
  140. package/src/auth/msalConnectionManager.ts +22 -0
  141. package/src/auth/msalTokenCredential.ts +4 -0
  142. package/src/auth/msalTokenProvider.ts +138 -107
  143. package/src/baseAdapter.ts +1 -1
  144. package/src/cloudAdapter.ts +239 -184
  145. package/src/connector-client/connectorClient.ts +169 -126
  146. package/src/errorHelper.ts +124 -0
  147. package/src/middlewareSet.ts +1 -1
  148. package/src/oauth/userTokenClient.ts +70 -46
  149. package/src/observability/index.ts +5 -0
  150. package/src/observability/metrics.ts +103 -0
  151. package/src/observability/traces.ts +988 -0
  152. package/src/state/agentState.ts +1 -1
  153. package/src/storage/fileStorage.ts +36 -26
  154. package/src/storage/memoryStorage.ts +40 -29
  155. package/src/transcript/fileTranscriptLogger.ts +1 -1
  156. package/src/transcript/transcriptLoggerMiddleware.ts +1 -1
  157. package/src/turnContext.ts +47 -41
@@ -17,7 +17,7 @@ import { Activity, ActivityEventNames, ActivityTypes, Channels, ConversationRefe
17
17
  import { Errors } from './errorHelper'
18
18
  import { ResourceResponse } from './connector-client/resourceResponse'
19
19
  import * as uuid from 'uuid'
20
- import { debug } from '@microsoft/agents-activity/logger'
20
+ import { debug } from '@microsoft/agents-telemetry'
21
21
  import { StatusCodes } from './statusCodes'
22
22
  import { InvokeResponse } from './invoke/invokeResponse'
23
23
  import { AttachmentData } from './connector-client/attachmentData'
@@ -28,6 +28,8 @@ import { HeaderPropagation, HeaderPropagationCollection, HeaderPropagationDefini
28
28
  import { JwtPayload } from 'jsonwebtoken'
29
29
  import { getTokenServiceEndpoint } from './oauth/customUserTokenAPI'
30
30
  import { Connections } from './auth/connections'
31
+ import { trace } from '@microsoft/agents-telemetry'
32
+ import { AdapterTraceDefinitions } from './observability'
31
33
  const logger = debug('agents:cloud-adapter')
32
34
 
33
35
  /**
@@ -100,15 +102,19 @@ export class CloudAdapter extends BaseAdapter {
100
102
  identity: JwtPayload,
101
103
  headers?: HeaderPropagationCollection
102
104
  ): Promise<ConnectorClient> {
103
- // get the correct token provider
104
- const tokenProvider = this.connectionManager.getTokenProvider(identity, serviceUrl)
105
+ return trace(AdapterTraceDefinitions.createConnectorClient, async ({ record }) => {
106
+ record({ serviceUrl, scope })
105
107
 
106
- const token = await tokenProvider.getAccessToken(scope)
107
- return ConnectorClient.createClientWithToken(
108
- serviceUrl,
109
- token,
110
- headers
111
- )
108
+ // get the correct token provider
109
+ const tokenProvider = this.connectionManager.getTokenProvider(identity, serviceUrl)
110
+
111
+ const token = await tokenProvider.getAccessToken(scope)
112
+ return ConnectorClient.createClientWithToken(
113
+ serviceUrl,
114
+ token,
115
+ headers
116
+ )
117
+ })
112
118
  }
113
119
 
114
120
  /**
@@ -124,55 +130,64 @@ export class CloudAdapter extends BaseAdapter {
124
130
  identity: JwtPayload,
125
131
  activity: Activity,
126
132
  headers?: HeaderPropagationCollection) {
127
- if (!identity?.aud) {
128
- // anonymous
129
- logger.warn('Missing identity or identity.aud when creating connector client. Using anonymous identity')
130
- return ConnectorClient.createClientWithToken(
131
- activity.serviceUrl!,
132
- null!,
133
- headers
134
- )
135
- }
136
-
137
- let connectorClient
138
- const tokenProvider = this.connectionManager.getTokenProviderFromActivity(identity, activity)
139
- if (activity.isAgenticRequest()) {
140
- logger.debug('Activity is from an agentic source, using special scope', activity.recipient)
141
- const agenticInstanceId = activity.getAgenticInstanceId()
142
- const agenticUserId = activity.getAgenticUser()
143
-
144
- if (activity.recipient?.role?.toLowerCase() === RoleTypes.AgenticIdentity.toLowerCase() && agenticInstanceId) {
145
- // get agentic instance token
146
- const token = await tokenProvider.getAgenticInstanceToken(activity.getAgenticTenantId() ?? '', agenticInstanceId)
147
- connectorClient = ConnectorClient.createClientWithToken(
133
+ return trace(AdapterTraceDefinitions.createConnectorClient, async ({ record }) => {
134
+ if (!identity?.aud) {
135
+ // anonymous
136
+ logger.warn('Missing identity or identity.aud when creating connector client. Using anonymous identity')
137
+ return ConnectorClient.createClientWithToken(
148
138
  activity.serviceUrl!,
149
- token,
139
+ null!,
150
140
  headers
151
141
  )
152
- } else if (activity.recipient?.role?.toLowerCase() === RoleTypes.AgenticUser.toLowerCase() && agenticInstanceId && agenticUserId) {
153
- const scope = tokenProvider.connectionSettings?.scope ?? ApxProductionScope
154
- const token = await tokenProvider.getAgenticUserToken(activity.getAgenticTenantId() ?? '', agenticInstanceId, agenticUserId, [scope])
142
+ }
155
143
 
144
+ let connectorClient
145
+ const tokenProvider = this.connectionManager.getTokenProviderFromActivity(identity, activity)
146
+ const isAgentic = activity.isAgenticRequest()
147
+ let scope
148
+ if (isAgentic) {
149
+ logger.debug('Activity is from an agentic source, using special scope', activity.recipient)
150
+ const agenticInstanceId = activity.getAgenticInstanceId()
151
+ const agenticUserId = activity.getAgenticUser()
152
+
153
+ if (activity.recipient?.role?.toLowerCase() === RoleTypes.AgenticIdentity.toLowerCase() && agenticInstanceId) {
154
+ // get agentic instance token
155
+ const token = await tokenProvider.getAgenticInstanceToken(activity.getAgenticTenantId() ?? '', agenticInstanceId)
156
+ connectorClient = ConnectorClient.createClientWithToken(
157
+ activity.serviceUrl!,
158
+ token,
159
+ headers
160
+ )
161
+ } else if (activity.recipient?.role?.toLowerCase() === RoleTypes.AgenticUser.toLowerCase() && agenticInstanceId && agenticUserId) {
162
+ scope = tokenProvider.connectionSettings?.scope ?? ApxProductionScope
163
+ const token = await tokenProvider.getAgenticUserToken(activity.getAgenticTenantId() ?? '', agenticInstanceId, agenticUserId, [scope])
164
+
165
+ connectorClient = ConnectorClient.createClientWithToken(
166
+ activity.serviceUrl!,
167
+ token,
168
+ headers
169
+ )
170
+ } else {
171
+ throw new Error('Could not create connector client for agentic user')
172
+ }
173
+ } else {
174
+ // ABS tokens will not have an azp/appid so use the botframework scope.
175
+ // Otherwise use the appId. This will happen when communicating back to another agent.
176
+ scope = identity.azp ?? identity.appid ?? 'https://api.botframework.com'
177
+ const token = await tokenProvider.getAccessToken(scope)
156
178
  connectorClient = ConnectorClient.createClientWithToken(
157
179
  activity.serviceUrl!,
158
180
  token,
159
181
  headers
160
182
  )
161
- } else {
162
- throw new Error('Could not create connector client for agentic user')
163
183
  }
164
- } else {
165
- // ABS tokens will not have an azp/appid so use the botframework scope.
166
- // Otherwise use the appId. This will happen when communicating back to another agent.
167
- const scope = identity.azp ?? identity.appid ?? 'https://api.botframework.com'
168
- const token = await tokenProvider.getAccessToken(scope)
169
- connectorClient = ConnectorClient.createClientWithToken(
170
- activity.serviceUrl!,
171
- token,
172
- headers
173
- )
174
- }
175
- return connectorClient
184
+ record({
185
+ serviceUrl: activity.serviceUrl,
186
+ scope,
187
+ activityIsAgentic: isAgentic
188
+ })
189
+ return connectorClient
190
+ })
176
191
  }
177
192
 
178
193
  /**
@@ -217,25 +232,28 @@ export class CloudAdapter extends BaseAdapter {
217
232
  audience: string = 'https://api.botframework.com',
218
233
  headers?: HeaderPropagationCollection
219
234
  ): Promise<UserTokenClient> {
220
- if (!identity?.aud) {
221
- // anonymous
235
+ return trace(AdapterTraceDefinitions.createUserTokenClient, async ({ record }) => {
236
+ record({ tokenServiceEndpoint, authScope: scope })
237
+ if (!identity?.aud) {
238
+ // anonymous
239
+ return UserTokenClient.createClientWithScope(
240
+ tokenServiceEndpoint,
241
+ null!,
242
+ scope,
243
+ headers
244
+ )
245
+ }
246
+
247
+ // get the correct token provider
248
+ const tokenProvider = this.connectionManager.getTokenProvider(identity, tokenServiceEndpoint)
249
+
222
250
  return UserTokenClient.createClientWithScope(
223
251
  tokenServiceEndpoint,
224
- null!,
252
+ tokenProvider,
225
253
  scope,
226
254
  headers
227
255
  )
228
- }
229
-
230
- // get the correct token provider
231
- const tokenProvider = this.connectionManager.getTokenProvider(identity, tokenServiceEndpoint)
232
-
233
- return UserTokenClient.createClientWithScope(
234
- tokenServiceEndpoint,
235
- tokenProvider,
236
- scope,
237
- headers
238
- )
256
+ })
239
257
  }
240
258
 
241
259
  /**
@@ -270,47 +288,51 @@ export class CloudAdapter extends BaseAdapter {
270
288
  * @returns A promise representing the array of ResourceResponses for the sent activities.
271
289
  */
272
290
  async sendActivities (context: TurnContext, activities: Activity[]): Promise<ResourceResponse[]> {
273
- if (!context) {
274
- throw ExceptionHelper.generateException(TypeError, Errors.ContextParameterRequired)
275
- }
291
+ return trace(AdapterTraceDefinitions.sendActivities, async ({ record, actions }) => {
292
+ record({ activityCount: activities?.length })
293
+ if (!context) {
294
+ throw ExceptionHelper.generateException(TypeError, Errors.ContextParameterRequired)
295
+ }
276
296
 
277
- if (!activities) {
278
- throw ExceptionHelper.generateException(TypeError, Errors.ActivitiesParameterRequired)
279
- }
297
+ if (!activities) {
298
+ throw ExceptionHelper.generateException(TypeError, Errors.ActivitiesParameterRequired)
299
+ }
280
300
 
281
- if (activities.length === 0) {
282
- throw ExceptionHelper.generateException(Error, Errors.EmptyActivitiesArray)
283
- }
301
+ if (activities.length === 0) {
302
+ throw ExceptionHelper.generateException(Error, Errors.EmptyActivitiesArray)
303
+ }
284
304
 
285
- const responses: ResourceResponse[] = []
286
- for (const activity of activities) {
287
- delete activity.id
288
- let response: ResourceResponse = { id: '' }
305
+ const responses: ResourceResponse[] = []
306
+ for (const activity of activities) {
307
+ actions.recordActivity(activity)
308
+ delete activity.id
309
+ let response: ResourceResponse = { id: '' }
289
310
 
290
- if (activity.type === ActivityTypes.InvokeResponse) {
291
- context.turnState.set(INVOKE_RESPONSE_KEY, activity)
292
- } else if (activity.type === ActivityTypes.Trace && activity.channelId !== Channels.Emulator) {
293
- // no-op
294
- } else {
295
- if (!activity.serviceUrl || (activity.conversation == null) || !activity.conversation.id) {
296
- throw ExceptionHelper.generateException(Error, Errors.InvalidActivityObject)
311
+ if (activity.type === ActivityTypes.InvokeResponse) {
312
+ context.turnState.set(INVOKE_RESPONSE_KEY, activity)
313
+ } else if (activity.type === ActivityTypes.Trace && activity.channelId !== Channels.Emulator) {
314
+ // no-op
315
+ } else {
316
+ if (!activity.serviceUrl || (activity.conversation == null) || !activity.conversation.id) {
317
+ throw ExceptionHelper.generateException(Error, Errors.InvalidActivityObject)
318
+ }
319
+
320
+ if (activity.replyToId) {
321
+ response = await context.turnState.get(this.ConnectorClientKey).replyToActivity(activity.conversation.id, activity.replyToId, activity)
322
+ } else {
323
+ response = await context.turnState.get(this.ConnectorClientKey).sendToConversation(activity.conversation.id, activity)
324
+ }
297
325
  }
298
326
 
299
- if (activity.replyToId) {
300
- response = await context.turnState.get(this.ConnectorClientKey).replyToActivity(activity.conversation.id, activity.replyToId, activity)
301
- } else {
302
- response = await context.turnState.get(this.ConnectorClientKey).sendToConversation(activity.conversation.id, activity)
327
+ if (!response) {
328
+ response = { id: activity.id ?? '' }
303
329
  }
304
- }
305
330
 
306
- if (!response) {
307
- response = { id: activity.id ?? '' }
331
+ responses.push(response)
308
332
  }
309
333
 
310
- responses.push(response)
311
- }
312
-
313
- return responses
334
+ return responses
335
+ })
314
336
  }
315
337
 
316
338
  /**
@@ -329,61 +351,75 @@ export class CloudAdapter extends BaseAdapter {
329
351
  res: Response,
330
352
  logic: (context: TurnContext) => Promise<void>,
331
353
  headerPropagation?: HeaderPropagationDefinition): Promise<void> {
332
- const headers = new HeaderPropagation(request.headers)
333
- if (headerPropagation && typeof headerPropagation === 'function') {
334
- headerPropagation(headers)
335
- logger.debug('Headers to propagate: ', headers)
336
- }
354
+ return trace(AdapterTraceDefinitions.process, async ({ record }) => {
355
+ const headers = new HeaderPropagation(request.headers)
356
+ if (headerPropagation && typeof headerPropagation === 'function') {
357
+ headerPropagation(headers)
358
+ logger.debug('Headers to propagate: ', headers)
359
+ }
360
+
361
+ const end = (status: StatusCodes, body?: unknown, isInvokeResponseOrExpectReplies: boolean = false) => {
362
+ if (res.writableEnded) {
363
+ return
364
+ }
337
365
 
338
- const end = (status: StatusCodes, body?: unknown, isInvokeResponseOrExpectReplies: boolean = false) => {
339
- res.status(status)
340
- if (isInvokeResponseOrExpectReplies) {
341
- res.setHeader('content-type', 'application/json')
366
+ if (res.headersSent) {
367
+ res.end()
368
+ return
369
+ }
370
+ res.status(status)
371
+ if (isInvokeResponseOrExpectReplies) {
372
+ res.setHeader('content-type', 'application/json')
373
+ }
374
+ if (body) {
375
+ res.send(body)
376
+ }
377
+ res.end()
342
378
  }
343
- if (body) {
344
- res.send(body)
379
+ if (!request.body) {
380
+ throw new TypeError('`request.body` parameter required, make sure express.json() is used as middleware')
345
381
  }
346
- res.end()
347
- }
348
- if (!request.body) {
349
- throw new TypeError('`request.body` parameter required, make sure express.json() is used as middleware')
350
- }
351
- const incoming = normalizeIncomingActivity(request.body!)
352
- const activity = Activity.fromObject(incoming)
353
- logger.info(`--> Processing incoming activity, type:${activity.type} channel:${activity.channelId}`)
382
+ const incoming = normalizeIncomingActivity(request.body!)
383
+ const activity = Activity.fromObject(incoming)
384
+ logger.info(`--> Processing incoming activity, type:${activity.type} channel:${activity.channelId}`)
354
385
 
355
- if (!this.isValidChannelActivity(activity)) {
356
- return end(StatusCodes.BAD_REQUEST)
357
- }
386
+ const isAgentic = activity.isAgenticRequest()
358
387
 
359
- logger.debug('Received activity: ', activity)
388
+ record({ activity })
360
389
 
361
- const context = new TurnContext(this, activity, request.user!)
362
- // if Delivery Mode == ExpectReplies, we don't need a connector client.
363
- if (this.resolveIfConnectorClientIsNeeded(activity)) {
364
- const connectorClient = await this.createConnectorClientWithIdentity(request.user!, activity, headers)
365
- this.setConnectorClient(context, connectorClient)
366
- }
390
+ if (!this.isValidChannelActivity(activity)) {
391
+ return end(StatusCodes.BAD_REQUEST)
392
+ }
367
393
 
368
- if (!activity.isAgenticRequest()) {
369
- const userTokenClient = await this.createUserTokenClient(request.user!, undefined, undefined, undefined, headers)
370
- this.setUserTokenClient(context, userTokenClient)
371
- }
394
+ logger.debug('Received activity: ', activity)
395
+
396
+ const context = new TurnContext(this, activity, request.user!)
397
+ // if Delivery Mode == ExpectReplies, we don't need a connector client.
398
+ if (this.resolveIfConnectorClientIsNeeded(activity)) {
399
+ const connectorClient = await this.createConnectorClientWithIdentity(request.user!, activity, headers)
400
+ this.setConnectorClient(context, connectorClient)
401
+ }
402
+
403
+ if (!isAgentic) {
404
+ const userTokenClient = await this.createUserTokenClient(request.user!, undefined, undefined, undefined, headers)
405
+ this.setUserTokenClient(context, userTokenClient)
406
+ }
407
+
408
+ if (
409
+ activity?.type === ActivityTypes.InvokeResponse ||
410
+ activity?.type === ActivityTypes.Invoke ||
411
+ activity?.deliveryMode === DeliveryModes.ExpectReplies
412
+ ) {
413
+ await this.runMiddleware(context, logic)
414
+ const invokeResponse = this.processTurnResults(context)
415
+ logger.debug('Activity Response (invoke/expect replies): ', invokeResponse)
416
+ return end(invokeResponse?.status ?? StatusCodes.OK, invokeResponse?.body, true)
417
+ }
372
418
 
373
- if (
374
- activity?.type === ActivityTypes.InvokeResponse ||
375
- activity?.type === ActivityTypes.Invoke ||
376
- activity?.deliveryMode === DeliveryModes.ExpectReplies
377
- ) {
378
419
  await this.runMiddleware(context, logic)
379
420
  const invokeResponse = this.processTurnResults(context)
380
- logger.debug('Activity Response (invoke/expect replies): ', invokeResponse)
381
- return end(invokeResponse?.status ?? StatusCodes.OK, invokeResponse?.body, true)
382
- }
383
-
384
- await this.runMiddleware(context, logic)
385
- const invokeResponse = this.processTurnResults(context)
386
- return end(invokeResponse?.status ?? StatusCodes.OK, invokeResponse?.body)
421
+ return end(invokeResponse?.status ?? StatusCodes.OK, invokeResponse?.body)
422
+ })
387
423
  }
388
424
 
389
425
  private isValidChannelActivity (activity: Activity): Boolean {
@@ -412,25 +448,29 @@ export class CloudAdapter extends BaseAdapter {
412
448
  * @returns A promise representing the ResourceResponse for the updated activity.
413
449
  */
414
450
  async updateActivity (context: TurnContext, activity: Activity): Promise<ResourceResponse | void> {
415
- if (!context) {
416
- throw new TypeError('`context` parameter required')
417
- }
451
+ return trace(AdapterTraceDefinitions.updateActivity, async ({ record }) => {
452
+ if (!context) {
453
+ throw new TypeError('`context` parameter required')
454
+ }
418
455
 
419
- if (!activity) {
420
- throw new TypeError('`activity` parameter required')
421
- }
456
+ if (!activity) {
457
+ throw new TypeError('`activity` parameter required')
458
+ }
422
459
 
423
- if (!activity.serviceUrl || (activity.conversation == null) || !activity.conversation.id || !activity.id) {
424
- throw ExceptionHelper.generateException(Error, Errors.InvalidActivityObject)
425
- }
460
+ record({ activity })
426
461
 
427
- const response = await context.turnState.get(this.ConnectorClientKey).updateActivity(
428
- activity.conversation.id,
429
- activity.id,
430
- activity
431
- )
462
+ if (!activity.serviceUrl || (activity.conversation == null) || !activity.conversation.id || !activity.id) {
463
+ throw ExceptionHelper.generateException(Error, Errors.InvalidActivityObject)
464
+ }
432
465
 
433
- return response.id ? { id: response.id } : undefined
466
+ const response = await context.turnState.get(this.ConnectorClientKey).updateActivity(
467
+ activity.conversation.id,
468
+ activity.id,
469
+ activity
470
+ )
471
+
472
+ return response.id ? { id: response.id } : undefined
473
+ })
434
474
  }
435
475
 
436
476
  /**
@@ -440,15 +480,19 @@ export class CloudAdapter extends BaseAdapter {
440
480
  * @returns A promise representing the completion of the delete operation.
441
481
  */
442
482
  async deleteActivity (context: TurnContext, reference: Partial<ConversationReference>): Promise<void> {
443
- if (!context) {
444
- throw new TypeError('`context` parameter required')
445
- }
483
+ return trace(AdapterTraceDefinitions.deleteActivity, async ({ record }) => {
484
+ if (!context) {
485
+ throw new TypeError('`context` parameter required')
486
+ }
446
487
 
447
- if (!reference || !reference.serviceUrl || (reference.conversation == null) || !reference.conversation.id || !reference.activityId) {
448
- throw ExceptionHelper.generateException(Error, Errors.InvalidConversationReference)
449
- }
488
+ if (!reference || !reference.serviceUrl || (reference.conversation == null) || !reference.conversation.id || !reference.activityId) {
489
+ throw ExceptionHelper.generateException(Error, Errors.InvalidConversationReference)
490
+ }
491
+
492
+ record({ reference })
450
493
 
451
- await context.turnState.get(this.ConnectorClientKey).deleteActivity(reference.conversation.id, reference.activityId)
494
+ await context.turnState.get(this.ConnectorClientKey).deleteActivity(reference.conversation.id, reference.activityId)
495
+ })
452
496
  }
453
497
 
454
498
  /**
@@ -465,32 +509,43 @@ export class CloudAdapter extends BaseAdapter {
465
509
  reference: ConversationReference,
466
510
  logic: (revocableContext: TurnContext) => Promise<void>,
467
511
  isResponse: Boolean = false): Promise<void> {
468
- if (!reference || !reference.serviceUrl || (reference.conversation == null) || !reference.conversation.id) {
469
- throw ExceptionHelper.generateException(Error, Errors.ContinueConversationInvalidReference)
470
- }
512
+ return trace(AdapterTraceDefinitions.continueConversation, async ({ record }) => {
513
+ if (!reference || !reference.serviceUrl || (reference.conversation == null) || !reference.conversation.id) {
514
+ throw ExceptionHelper.generateException(Error, Errors.ContinueConversationInvalidReference)
515
+ }
471
516
 
472
- if (!botAppIdOrIdentity) {
473
- throw new TypeError('continueConversation: botAppIdOrIdentity is required')
474
- }
475
- const botAppId = typeof botAppIdOrIdentity === 'string' ? botAppIdOrIdentity : botAppIdOrIdentity.aud as string
476
-
477
- // Only having the botId will only work against ABS or Agentic. Proactive to other agents will
478
- // not work with just botId. Use a JwtPayload with property aud (which is botId) and appid populated.
479
- const identity =
480
- typeof botAppIdOrIdentity !== 'string'
481
- ? botAppIdOrIdentity
482
- : CloudAdapter.createIdentity(botAppId)
483
-
484
- const context = new TurnContext(this, Activity.getContinuationActivity(reference), identity)
485
- const connectorClient = await this.createConnectorClientWithIdentity(identity, context.activity)
486
- this.setConnectorClient(context, connectorClient)
487
-
488
- if (!context.activity.isAgenticRequest()) {
489
- const userTokenClient = await this.createUserTokenClient(identity)
490
- this.setUserTokenClient(context, userTokenClient)
491
- }
517
+ if (!botAppIdOrIdentity) {
518
+ throw new TypeError('continueConversation: botAppIdOrIdentity is required')
519
+ }
520
+ const botAppId = typeof botAppIdOrIdentity === 'string' ? botAppIdOrIdentity : botAppIdOrIdentity.aud as string
492
521
 
493
- await this.runMiddleware(context, logic)
522
+ // Only having the botId will only work against ABS or Agentic. Proactive to other agents will
523
+ // not work with just botId. Use a JwtPayload with property aud (which is botId) and appid populated.
524
+ const identity =
525
+ typeof botAppIdOrIdentity !== 'string'
526
+ ? botAppIdOrIdentity
527
+ : CloudAdapter.createIdentity(botAppId)
528
+
529
+ const context = new TurnContext(this, Activity.getContinuationActivity(reference), identity)
530
+
531
+ const connectorClient = await this.createConnectorClientWithIdentity(identity, context.activity)
532
+ this.setConnectorClient(context, connectorClient)
533
+
534
+ const isAgentic = context.activity.isAgenticRequest()
535
+
536
+ record({
537
+ botAppId,
538
+ conversationId: reference.conversation?.id,
539
+ isAgentic
540
+ })
541
+
542
+ if (!isAgentic) {
543
+ const userTokenClient = await this.createUserTokenClient(identity)
544
+ this.setUserTokenClient(context, userTokenClient)
545
+ }
546
+
547
+ await this.runMiddleware(context, logic)
548
+ })
494
549
  }
495
550
 
496
551
  /**