@microsoft/agents-hosting 0.6.1 → 0.6.16-gc874f0c9d8

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 (148) hide show
  1. package/dist/src/activityHandler.d.ts +29 -5
  2. package/dist/src/activityHandler.js +30 -6
  3. package/dist/src/activityHandler.js.map +1 -1
  4. package/dist/src/agent-client/agentClient.js +1 -1
  5. package/dist/src/agent-client/agentClient.js.map +1 -1
  6. package/dist/src/agent-client/agentResponseHandler.d.ts +34 -0
  7. package/dist/src/agent-client/agentResponseHandler.js +35 -1
  8. package/dist/src/agent-client/agentResponseHandler.js.map +1 -1
  9. package/dist/src/app/adaptiveCards/adaptiveCardsActions.d.ts +23 -2
  10. package/dist/src/app/adaptiveCards/adaptiveCardsActions.js.map +1 -1
  11. package/dist/src/app/adaptiveCards/adaptiveCardsSearchParams.d.ts +1 -1
  12. package/dist/src/app/agentApplication.d.ts +46 -34
  13. package/dist/src/app/agentApplication.js +64 -40
  14. package/dist/src/app/agentApplication.js.map +1 -1
  15. package/dist/src/app/agentApplicationOptions.d.ts +74 -13
  16. package/dist/src/app/appRoute.d.ts +56 -2
  17. package/dist/src/app/attachmentDownloader.d.ts +1 -0
  18. package/dist/src/app/attachmentDownloader.js +2 -1
  19. package/dist/src/app/attachmentDownloader.js.map +1 -1
  20. package/dist/src/app/authorization.d.ts +1 -1
  21. package/dist/src/app/authorization.js +1 -1
  22. package/dist/src/app/authorization.js.map +1 -1
  23. package/dist/src/app/extensions.d.ts +37 -1
  24. package/dist/src/app/extensions.js +38 -2
  25. package/dist/src/app/extensions.js.map +1 -1
  26. package/dist/src/app/index.d.ts +2 -0
  27. package/dist/src/app/index.js +2 -0
  28. package/dist/src/app/index.js.map +1 -1
  29. package/dist/src/app/routeList.d.ts +13 -0
  30. package/dist/src/app/routeList.js +30 -0
  31. package/dist/src/app/routeList.js.map +1 -0
  32. package/dist/src/app/routeRank.d.ts +51 -0
  33. package/dist/src/app/routeRank.js +56 -0
  34. package/dist/src/app/routeRank.js.map +1 -0
  35. package/dist/src/app/streaming/citationUtil.d.ts +1 -1
  36. package/dist/src/app/streaming/streamingResponse.d.ts +1 -2
  37. package/dist/src/app/streaming/streamingResponse.js +29 -41
  38. package/dist/src/app/streaming/streamingResponse.js.map +1 -1
  39. package/dist/src/app/turnState.d.ts +2 -0
  40. package/dist/src/app/turnState.js +3 -1
  41. package/dist/src/app/turnState.js.map +1 -1
  42. package/dist/src/auth/authConfiguration.d.ts +4 -0
  43. package/dist/src/auth/authConfiguration.js +5 -1
  44. package/dist/src/auth/authConfiguration.js.map +1 -1
  45. package/dist/src/auth/authProvider.d.ts +1 -1
  46. package/dist/src/auth/jwt-middleware.js +1 -1
  47. package/dist/src/auth/jwt-middleware.js.map +1 -1
  48. package/dist/src/auth/msalTokenCredential.d.ts +14 -0
  49. package/dist/src/auth/msalTokenCredential.js +14 -0
  50. package/dist/src/auth/msalTokenCredential.js.map +1 -1
  51. package/dist/src/auth/msalTokenProvider.js +4 -2
  52. package/dist/src/auth/msalTokenProvider.js.map +1 -1
  53. package/dist/src/baseAdapter.d.ts +22 -1
  54. package/dist/src/baseAdapter.js +23 -2
  55. package/dist/src/baseAdapter.js.map +1 -1
  56. package/dist/src/cards/adaptiveCard.d.ts +2 -0
  57. package/dist/src/cards/animationCard.d.ts +1 -1
  58. package/dist/src/cards/audioCard.d.ts +1 -1
  59. package/dist/src/cards/cardImage.d.ts +1 -1
  60. package/dist/src/cards/fact.d.ts +1 -1
  61. package/dist/src/cards/heroCard.d.ts +1 -1
  62. package/dist/src/cards/o365ConnectorCardSection.d.ts +5 -0
  63. package/dist/src/cloudAdapter.d.ts +11 -0
  64. package/dist/src/cloudAdapter.js +33 -4
  65. package/dist/src/cloudAdapter.js.map +1 -1
  66. package/dist/src/connector-client/connectorClient.js +1 -1
  67. package/dist/src/connector-client/connectorClient.js.map +1 -1
  68. package/dist/src/getProductInfo.js +2 -2
  69. package/dist/src/getProductInfo.js.map +1 -1
  70. package/dist/src/index.d.ts +0 -2
  71. package/dist/src/index.js +0 -2
  72. package/dist/src/index.js.map +1 -1
  73. package/dist/src/middlewareSet.js +1 -1
  74. package/dist/src/middlewareSet.js.map +1 -1
  75. package/dist/src/oauth/oAuthFlow.js +1 -1
  76. package/dist/src/oauth/oAuthFlow.js.map +1 -1
  77. package/dist/src/oauth/userTokenClient.js +1 -1
  78. package/dist/src/oauth/userTokenClient.js.map +1 -1
  79. package/dist/src/state/agentState.js +1 -1
  80. package/dist/src/state/agentState.js.map +1 -1
  81. package/dist/src/state/agentStatePropertyAccesor.d.ts +269 -38
  82. package/dist/src/state/agentStatePropertyAccesor.js +269 -38
  83. package/dist/src/state/agentStatePropertyAccesor.js.map +1 -1
  84. package/dist/src/statusCodes.d.ts +30 -0
  85. package/dist/src/statusCodes.js +30 -0
  86. package/dist/src/statusCodes.js.map +1 -1
  87. package/dist/src/storage/fileStorage.d.ts +97 -0
  88. package/dist/src/storage/fileStorage.js +97 -0
  89. package/dist/src/storage/fileStorage.js.map +1 -1
  90. package/dist/src/storage/memoryStorage.d.ts +2 -1
  91. package/dist/src/storage/memoryStorage.js +3 -2
  92. package/dist/src/storage/memoryStorage.js.map +1 -1
  93. package/dist/src/storage/storage.d.ts +1 -0
  94. package/dist/src/transcript/transcriptLoggerMiddleware.js +1 -1
  95. package/dist/src/transcript/transcriptLoggerMiddleware.js.map +1 -1
  96. package/dist/src/turnContext.d.ts +1 -0
  97. package/dist/src/turnContext.js +1 -0
  98. package/dist/src/turnContext.js.map +1 -1
  99. package/package.json +4 -5
  100. package/src/activityHandler.ts +30 -6
  101. package/src/agent-client/agentClient.ts +1 -1
  102. package/src/agent-client/agentResponseHandler.ts +35 -1
  103. package/src/app/adaptiveCards/adaptiveCardsActions.ts +23 -2
  104. package/src/app/adaptiveCards/adaptiveCardsSearchParams.ts +1 -1
  105. package/src/app/agentApplication.ts +70 -41
  106. package/src/app/agentApplicationOptions.ts +75 -13
  107. package/src/app/appRoute.ts +57 -2
  108. package/src/app/attachmentDownloader.ts +2 -1
  109. package/src/app/authorization.ts +2 -2
  110. package/src/app/extensions.ts +45 -2
  111. package/src/app/index.ts +2 -0
  112. package/src/app/routeList.ts +37 -0
  113. package/src/app/routeRank.ts +54 -0
  114. package/src/app/streaming/citationUtil.ts +1 -1
  115. package/src/app/streaming/streamingResponse.ts +23 -71
  116. package/src/app/turnState.ts +3 -1
  117. package/src/auth/authConfiguration.ts +5 -1
  118. package/src/auth/authProvider.ts +1 -1
  119. package/src/auth/jwt-middleware.ts +1 -1
  120. package/src/auth/msalTokenCredential.ts +15 -0
  121. package/src/auth/msalTokenProvider.ts +4 -2
  122. package/src/baseAdapter.ts +25 -2
  123. package/src/cards/adaptiveCard.ts +2 -0
  124. package/src/cards/animationCard.ts +1 -1
  125. package/src/cards/audioCard.ts +1 -1
  126. package/src/cards/cardImage.ts +1 -1
  127. package/src/cards/fact.ts +1 -1
  128. package/src/cards/heroCard.ts +1 -1
  129. package/src/cards/o365ConnectorCardSection.ts +5 -0
  130. package/src/cloudAdapter.ts +36 -4
  131. package/src/connector-client/connectorClient.ts +1 -1
  132. package/src/getProductInfo.ts +2 -2
  133. package/src/index.ts +0 -2
  134. package/src/middlewareSet.ts +1 -1
  135. package/src/oauth/oAuthFlow.ts +1 -1
  136. package/src/oauth/userTokenClient.ts +1 -1
  137. package/src/state/agentState.ts +1 -1
  138. package/src/state/agentStatePropertyAccesor.ts +269 -38
  139. package/src/statusCodes.ts +30 -0
  140. package/src/storage/fileStorage.ts +99 -0
  141. package/src/storage/memoryStorage.ts +3 -2
  142. package/src/storage/storage.ts +1 -0
  143. package/src/transcript/transcriptLoggerMiddleware.ts +1 -1
  144. package/src/turnContext.ts +1 -0
  145. package/dist/src/logger.d.ts +0 -44
  146. package/dist/src/logger.js +0 -77
  147. package/dist/src/logger.js.map +0 -1
  148. package/src/logger.ts +0 -76
@@ -1,19 +1,62 @@
1
1
  import { TurnContext } from '../turnContext'
2
2
  import { AgentApplication } from './agentApplication'
3
3
  import { RouteHandler } from './routeHandler'
4
+ import { RouteRank } from './routeRank'
4
5
  import { RouteSelector } from './routeSelector'
5
6
  import { TurnState } from './turnState'
6
7
 
8
+ /**
9
+ * Represents an extension that adds channel-specific routing functionality to an agent application.
10
+ * This class allows you to register routes that are only active for a specific channel.
11
+ *
12
+ * @template TState - The type of turn state that extends TurnState
13
+ */
7
14
  export class AgentExtension<TState extends TurnState> {
15
+ /** The channel ID that this extension is associated with */
8
16
  channelId: string
17
+
18
+ /**
19
+ * Creates a new AgentExtension instance for the specified channel.
20
+ *
21
+ * @param channelId - The channel ID that this extension will be associated with
22
+ */
9
23
  constructor (channelId: string) {
10
24
  this.channelId = channelId
11
25
  }
12
26
 
13
- addRoute (app: AgentApplication<TState>, routeSelector: RouteSelector, routeHandler: RouteHandler<TurnState>, isInvokeRoute: boolean = false) {
27
+ /**
28
+ * Adds a route to the agent application that is only active for the channel specified in this extension.
29
+ * This method creates a channel-specific route by wrapping the provided route selector with an additional
30
+ * check to ensure the incoming activity matches the extension's channel ID.
31
+ *
32
+ * @param app - The agent application instance to add the route to
33
+ * @param routeSelector - A function that determines if the route should handle the incoming activity
34
+ * @param routeHandler - The handler function that will process the activity when the route is matched
35
+ * @param isInvokeRoute - Optional. Whether this route handles invoke activities. Defaults to false
36
+ * @param rank - Optional. The priority rank of this route for routing precedence. Defaults to RouteRank.Unspecified
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const teamsExtension = new AgentExtension<MyState>('msteams');
41
+ * teamsExtension.addRoute(
42
+ * app,
43
+ * (context) => context.activity.type === 'message',
44
+ * async (context, state) => {
45
+ * // Handle Teams-specific message
46
+ * await context.sendActivity('Hello from Teams!');
47
+ * }
48
+ * );
49
+ * ```
50
+ */
51
+ addRoute (
52
+ app: AgentApplication<TState>,
53
+ routeSelector: RouteSelector,
54
+ routeHandler: RouteHandler<TurnState>,
55
+ isInvokeRoute: boolean = false,
56
+ rank: number = RouteRank.Unspecified) {
14
57
  const ensureChannelMatches = async (context: TurnContext) => {
15
58
  return context.activity.channelId === this.channelId && routeSelector(context)
16
59
  }
17
- app.addRoute(ensureChannelMatches, routeHandler)
60
+ app.addRoute(ensureChannelMatches, routeHandler, isInvokeRoute, rank)
18
61
  }
19
62
  }
package/src/app/index.ts CHANGED
@@ -6,6 +6,8 @@ export * from './attachmentDownloader'
6
6
  export * from './authorization'
7
7
  export * from './conversationUpdateEvents'
8
8
  export * from './routeHandler'
9
+ export * from './routeList'
10
+ export * from './routeRank'
9
11
  export * from './routeSelector'
10
12
  export * from './turnState'
11
13
  export * from './turnEvents'
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { AppRoute } from './appRoute'
7
+ import { RouteHandler } from './routeHandler'
8
+ import { RouteRank } from './routeRank'
9
+ import { RouteSelector } from './routeSelector'
10
+ import { TurnState } from './turnState'
11
+
12
+ export class RouteList<TState extends TurnState> {
13
+ private _routes: Array<AppRoute<TState>> = []
14
+
15
+ public addRoute (
16
+ selector: RouteSelector,
17
+ handler: RouteHandler<TState>,
18
+ isInvokeRoute: boolean = false,
19
+ rank: number = RouteRank.Unspecified,
20
+ authHandlers: string[] = []
21
+ ): this {
22
+ this._routes.push({ selector, handler, isInvokeRoute, rank, authHandlers })
23
+
24
+ // Invoke selectors are first, then order by rank ascending
25
+ this._routes.sort((a, b) => {
26
+ if (a.isInvokeRoute !== b.isInvokeRoute) {
27
+ return a.isInvokeRoute ? -1 : 1
28
+ }
29
+ return (a.rank ?? 0) - (b.rank ?? 0)
30
+ })
31
+ return this
32
+ }
33
+
34
+ public [Symbol.iterator] (): Iterator<AppRoute<TState>> {
35
+ return this._routes[Symbol.iterator]()
36
+ }
37
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ /**
7
+ * Defines the priority ranking for route evaluation in the agent hosting framework.
8
+ *
9
+ * @remarks
10
+ * Routes are evaluated in ascending order of their rank values, allowing for precise
11
+ * control over which routes are processed first when multiple routes could match
12
+ * the same request.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * // High priority route that should be evaluated first
17
+ * this.onMessage('urgent', handler, undefined, RouteRank.First);
18
+ *
19
+ * // Normal priority route with default ranking
20
+ * this.onMessage('data', handler, undefined, RouteRank.Unspecified);
21
+ *
22
+ * // Fallback route that should be evaluated last
23
+ * this.onActivity('message', fallbackHandler, undefined, RouteRank.Last);
24
+ *
25
+ * // Multiple routes with same pattern - first ranked executes first
26
+ * this.onMessage('dupText', handler1, undefined, RouteRank.Last);
27
+ * this.onMessage('dupText', handler2, undefined, RouteRank.First); // This executes first
28
+ * ```
29
+ */
30
+ export enum RouteRank {
31
+ /**
32
+ * Highest priority rank (value: 0). Routes with this rank are evaluated first
33
+ * before any other routes. Use this for critical routes that must take precedence
34
+ * over all others, such as high-priority message handlers or override handlers
35
+ * that should execute before any other matching routes.
36
+ */
37
+ First = 0,
38
+
39
+ /**
40
+ * Lowest priority rank (value: Number.MAX_VALUE). Routes with this rank are
41
+ * evaluated last, after all other routes have been considered. Ideal for
42
+ * catch-all message handlers, fallback activity handlers, or default responses
43
+ * that should only match when no other routes apply.
44
+ */
45
+ Last = Number.MAX_VALUE,
46
+
47
+ /**
48
+ * Default priority rank (value: Number.MAX_VALUE / 2). This is the standard
49
+ * rank for most routes that don't require special ordering. Routes with this
50
+ * rank are evaluated after high-priority routes but before low-priority ones.
51
+ * Use this when you don't need to specify a particular evaluation order.
52
+ */
53
+ Unspecified = Number.MAX_VALUE / 2
54
+ }
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { ClientCitation } from '@microsoft/agents-activity/src/entity/AIEntity'
6
+ import { ClientCitation } from '@microsoft/agents-activity'
7
7
 
8
8
  // import { stringify } from 'yaml'
9
9
 
@@ -3,12 +3,11 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { Activity, addAIToActivity, Attachment, Entity } from '@microsoft/agents-activity'
6
+ import { Activity, addAIToActivity, Attachment, Entity, ClientCitation, SensitivityUsageInfo } from '@microsoft/agents-activity'
7
7
  import { TurnContext } from '../../turnContext'
8
8
  import { Citation } from './citation'
9
9
  import { CitationUtil } from './citationUtil'
10
- import { debug } from '../../logger'
11
- import { ClientCitation, SensitivityUsageInfo } from '@microsoft/agents-activity/src/entity/AIEntity'
10
+ import { debug } from '@microsoft/agents-activity/logger'
12
11
 
13
12
  const logger = debug('agents:streamingResponse')
14
13
 
@@ -89,10 +88,11 @@ export class StreamingResponse {
89
88
  this.queueActivity(() => Activity.fromObject({
90
89
  type: 'typing',
91
90
  text,
92
- channelData: {
91
+ entities: [{
92
+ type: 'streaminfo',
93
93
  streamType: 'informative',
94
94
  streamSequence: this._nextSequence++
95
- } as StreamingChannelData
95
+ }]
96
96
  }))
97
97
  }
98
98
 
@@ -242,20 +242,22 @@ export class StreamingResponse {
242
242
  type: 'message',
243
243
  text: this._message || 'end of stream response',
244
244
  attachments: this._attachments,
245
- channelData: {
245
+ entities: [{
246
+ type: 'streaminfo',
246
247
  streamType: 'final',
247
248
  streamSequence: this._nextSequence++
248
- } as StreamingChannelData
249
+ }]
249
250
  })
250
251
  } else {
251
252
  // Send typing activity
252
253
  return Activity.fromObject({
253
254
  type: 'typing',
254
255
  text: this._message,
255
- channelData: {
256
+ entities: [{
257
+ type: 'streaminfo',
256
258
  streamType: 'streaming',
257
259
  streamSequence: this._nextSequence++
258
- } as StreamingChannelData
260
+ }]
259
261
  })
260
262
  }
261
263
  })
@@ -270,7 +272,7 @@ export class StreamingResponse {
270
272
  // If there's no sync in progress, start one
271
273
  if (!this._queueSync) {
272
274
  this._queueSync = this.drainQueue().catch((err) => {
273
- logger.error(`Error occured when sending activity while streaming: "${err}".`)
275
+ logger.error(`Error occurred when sending activity while streaming: "${JSON.stringify(err)}".`)
274
276
  // throw err
275
277
  })
276
278
  }
@@ -311,20 +313,19 @@ export class StreamingResponse {
311
313
  // Set activity ID to the assigned stream ID
312
314
  if (this._streamId) {
313
315
  activity.id = this._streamId
314
- activity.channelData = Object.assign({}, activity.channelData, { streamId: this._streamId })
316
+ if (!activity.entities) {
317
+ activity.entities = []
318
+ }
319
+ if (!activity.entities[0]) {
320
+ activity.entities[0] = {} as Entity
321
+ }
322
+ activity.entities[0].streamId = this._streamId
315
323
  }
316
324
 
317
- activity.entities = [
318
- {
319
- type: 'streaminfo',
320
- ...activity.channelData
321
- } as Entity
322
- ]
323
-
324
325
  if (this._citations && this._citations.length > 0 && !this._ended) {
325
326
  // Filter out the citations unused in content.
326
327
  const currCitations = CitationUtil.getUsedCitations(this._message, this._citations) ?? undefined
327
- activity.entities.push({
328
+ activity.entities!.push({
328
329
  type: 'https://schema.org/Message',
329
330
  '@type': 'Message',
330
331
  '@context': 'https://schema.org',
@@ -335,28 +336,14 @@ export class StreamingResponse {
335
336
 
336
337
  // Add in Powered by AI feature flags
337
338
  if (this._ended) {
338
- if (this._enableFeedbackLoop && this._feedbackLoopType) {
339
- activity.channelData = Object.assign({}, activity.channelData, {
340
- feedbackLoop: { type: this._feedbackLoopType }
341
- })
342
- } else {
343
- activity.channelData = Object.assign({}, activity.channelData, {
344
- feedbackLoopEnabled: this._enableFeedbackLoop
345
- })
339
+ activity.channelData = {
340
+ feedbackLoopEnabled: this._enableFeedbackLoop ?? false,
341
+ ...(this._feedbackLoopType ? { type: this._feedbackLoopType } : {})
346
342
  }
347
343
 
348
344
  // Add in Generated by AI
349
345
  if (this._enableGeneratedByAILabel) {
350
346
  addAIToActivity(activity, this._citations, this._sensitivityLabel)
351
- // activity.entities.push({
352
- // type: 'https://schema.org/Message',
353
- // '@type': 'Message',
354
- // '@context': 'https://schema.org',
355
- // '@id': '',
356
- // additionalType: ['AIGeneratedContent'],
357
- // citation: this._citations && this._citations.length > 0 ? this._citations : [],
358
- // usageInfo: this._sensitivityLabel
359
- // } as unknown as Entity)
360
347
  }
361
348
  }
362
349
 
@@ -370,38 +357,3 @@ export class StreamingResponse {
370
357
  }
371
358
  }
372
359
  }
373
-
374
- /**
375
- * @private
376
- * Structure of the outgoing channelData field for streaming responses.
377
- * @remarks
378
- * The expected sequence of streamTypes is:
379
- *
380
- * `informative`, `streaming`, `streaming`, ..., `final`.
381
- *
382
- * Once a `final` message is sent, the stream is considered ended.
383
- */
384
- interface StreamingChannelData {
385
- /**
386
- * The type of message being sent.
387
- * @remarks
388
- * `informative` - An informative update.
389
- * `streaming` - A chunk of partial message text.
390
- * `final` - The final message.
391
- */
392
- streamType: 'informative' | 'streaming' | 'final';
393
-
394
- /**
395
- * Sequence number of the message in the stream.
396
- * @remarks
397
- * Starts at 1 for the first message and increments from there.
398
- */
399
- streamSequence: number;
400
-
401
- /**
402
- * ID of the stream.
403
- * @remarks
404
- * Assigned after the initial update is sent.
405
- */
406
- streamId?: string;
407
- }
@@ -8,7 +8,7 @@ import { AppMemory } from './appMemory'
8
8
  import { InputFile } from './inputFileDownloader'
9
9
  import { TurnStateEntry } from './turnStateEntry'
10
10
  import { TurnContext } from '../turnContext'
11
- import { debug } from '../logger'
11
+ import { debug } from '@microsoft/agents-activity/logger'
12
12
 
13
13
  const logger = debug('agents:turnState')
14
14
 
@@ -43,6 +43,8 @@ export interface DefaultTempState {
43
43
  * Base class defining a collection of turn state scopes.
44
44
  * @remarks
45
45
  * Developers can create a derived class that extends `TurnState` to add additional state scopes.
46
+ *
47
+ * @example
46
48
  * ```JavaScript
47
49
  * class MyTurnState extends TurnState {
48
50
  * protected async onComputeStorageKeys(context) {
@@ -50,6 +50,8 @@ export interface AuthConfiguration {
50
50
 
51
51
  /**
52
52
  * Loads the authentication configuration from environment variables.
53
+ *
54
+ * @example
53
55
  * ```
54
56
  * tenantId=your-tenant-id
55
57
  * clientId=your-client-id
@@ -94,7 +96,7 @@ export const loadAuthConfigFromEnv: (cnxName?: string) => AuthConfiguration = (c
94
96
  certPemFile: process.env[`${cnxName}_certPemFile`],
95
97
  certKeyFile: process.env[`${cnxName}_certKeyFile`],
96
98
  connectionName: process.env[`${cnxName}_connectionName`],
97
- FICClientId: process.env.FICClientId,
99
+ FICClientId: process.env[`${cnxName}_FICClientId`],
98
100
  issuers: [
99
101
  'https://api.botframework.com',
100
102
  `https://sts.windows.net/${process.env[`${cnxName}_tenantId`]}/`,
@@ -106,6 +108,8 @@ export const loadAuthConfigFromEnv: (cnxName?: string) => AuthConfiguration = (c
106
108
 
107
109
  /**
108
110
  * Loads the agent authentication configuration from previous version environment variables.
111
+ *
112
+ * @example
109
113
  * ```
110
114
  * MicrosoftAppId=your-client-id
111
115
  * MicrosoftAppPassword=your-client-secret
@@ -6,7 +6,7 @@
6
6
  import { AuthConfiguration } from './authConfiguration'
7
7
 
8
8
  /**
9
- * Interface representing an authentication provider.
9
+ * Represents an authentication provider.
10
10
  */
11
11
  export interface AuthProvider {
12
12
  /**
@@ -8,7 +8,7 @@ import { Response, NextFunction } from 'express'
8
8
  import { Request } from './request'
9
9
  import jwksRsa, { JwksClient, SigningKey } from 'jwks-rsa'
10
10
  import jwt, { JwtHeader, JwtPayload, SignCallback, GetPublicKeyOrSecret } from 'jsonwebtoken'
11
- import { debug } from '../logger'
11
+ import { debug } from '@microsoft/agents-activity/logger'
12
12
 
13
13
  const logger = debug('agents:jwt-middleware')
14
14
 
@@ -1,8 +1,23 @@
1
1
  import { GetTokenOptions, TokenCredential } from '@azure/core-auth'
2
2
  import { AuthConfiguration, MsalTokenProvider } from './'
3
3
 
4
+ /**
5
+ * Token credential implementation that uses MSAL (Microsoft Authentication Library) to acquire access tokens.
6
+ * Implements the Azure Core Auth TokenCredential interface for authentication scenarios.
7
+ */
4
8
  export class MsalTokenCredential implements TokenCredential {
9
+ /**
10
+ * Creates a new instance of MsalTokenCredential.
11
+ * @param authConfig The authentication configuration to use for token acquisition.
12
+ */
5
13
  constructor (private authConfig: AuthConfiguration) {}
14
+
15
+ /**
16
+ * Retrieves an access token for the specified scopes using MSAL authentication.
17
+ * @param scopes Array of scopes for which to request an access token. The first scope is used to determine the resource.
18
+ * @param options Optional parameters for token retrieval (currently unused).
19
+ * @returns Promise that resolves to an access token with expiration timestamp.
20
+ */
6
21
  public async getToken (scopes: string[], options?: GetTokenOptions) {
7
22
  const scope = scopes[0].substring(0, scopes[0].lastIndexOf('/'))
8
23
  const token = await new MsalTokenProvider().getAccessToken(this.authConfig, scope)
@@ -6,7 +6,7 @@
6
6
  import { ConfidentialClientApplication, LogLevel, ManagedIdentityApplication, NodeSystemOptions } from '@azure/msal-node'
7
7
  import { AuthConfiguration } from './authConfiguration'
8
8
  import { AuthProvider } from './authProvider'
9
- import { debug } from '../logger'
9
+ import { debug } from '@microsoft/agents-activity/logger'
10
10
  import { v4 } from 'uuid'
11
11
 
12
12
  import fs from 'fs'
@@ -82,7 +82,9 @@ export class MsalTokenProvider implements AuthProvider {
82
82
  logger.info(message)
83
83
  return
84
84
  case LogLevel.Warning:
85
- logger.warn(message)
85
+ if (!message.includes('Warning - No client info in response')) {
86
+ logger.warn(message)
87
+ }
86
88
  return
87
89
  case LogLevel.Verbose:
88
90
  logger.debug(message)
@@ -8,7 +8,7 @@ import { AuthProvider } from './auth/authProvider'
8
8
  import { MsalTokenProvider } from './auth/msalTokenProvider'
9
9
  import { Middleware, MiddlewareHandler, MiddlewareSet } from './middlewareSet'
10
10
  import { TurnContext } from './turnContext'
11
- import { debug } from './logger'
11
+ import { debug } from '@microsoft/agents-activity/logger'
12
12
  import { Activity, ConversationReference } from '@microsoft/agents-activity'
13
13
  import { ResourceResponse } from './connector-client/resourceResponse'
14
14
  import { AttachmentData } from './connector-client/attachmentData'
@@ -17,7 +17,19 @@ import { AttachmentInfo } from './connector-client/attachmentInfo'
17
17
  const logger = debug('agents:base-adapter')
18
18
 
19
19
  /**
20
- * Base class for all adapters, providing middleware and error handling capabilities.
20
+ * Abstract base class for all adapters in the Agents framework.
21
+ *
22
+ * @remarks
23
+ * This class provides core functionality for handling conversations, managing middleware,
24
+ * authentication, and error handling. Adapters are responsible for translating between
25
+ * the Agents framework and specific communication channels (like Teams, Web Chat, etc.).
26
+ *
27
+ * Key features:
28
+ * - Middleware pipeline for processing incoming and outgoing activities
29
+ * - Error handling and recovery mechanisms
30
+ * - Authentication provider integration
31
+ * - Abstract methods for channel-specific operations
32
+ * - Context management with revocable proxies for security
21
33
  */
22
34
  export abstract class BaseAdapter {
23
35
  /**
@@ -41,8 +53,19 @@ export abstract class BaseAdapter {
41
53
  await context.sendActivity('To continue to run this agent, please fix the source code.')
42
54
  }
43
55
 
56
+ /**
57
+ * Symbol key used to store agent identity information in the TurnContext.
58
+ */
44
59
  readonly AgentIdentityKey = Symbol('AgentIdentity')
60
+
61
+ /**
62
+ * Symbol key used to store connector client instances in the TurnContext.
63
+ */
45
64
  readonly ConnectorClientKey = Symbol('ConnectorClient')
65
+
66
+ /**
67
+ * Symbol key used to store OAuth scope information in the TurnContext.
68
+ */
46
69
  readonly OAuthScopeKey = Symbol('OAuthScope')
47
70
 
48
71
  /**
@@ -5,6 +5,8 @@
5
5
 
6
6
  /**
7
7
  * Represents an Adaptive Card, which is a card framework that enables developers to exchange UI content in a common and consistent way.
8
+ *
9
+ * @remarks
8
10
  * @see {@link https://learn.microsoft.com/adaptive-cards/ | Adaptive Cards Documentation}
9
11
  */
10
12
  export interface AdaptiveCard {
@@ -8,7 +8,7 @@ import { MediaUrl } from './mediaUrl'
8
8
  import { ThumbnailUrl } from './thumbnailUrl'
9
9
 
10
10
  /**
11
- * Interface representing an Animation Card.
11
+ * Represents an Animation Card.
12
12
  */
13
13
  export interface AnimationCard {
14
14
  /** The title of the card. */
@@ -8,7 +8,7 @@ import { MediaUrl } from './mediaUrl'
8
8
  import { ThumbnailUrl } from './thumbnailUrl'
9
9
 
10
10
  /**
11
- * Interface representing an Audio Card.
11
+ * Represents an Audio Card.
12
12
  */
13
13
  export interface AudioCard {
14
14
  /** The title of the card. */
@@ -6,7 +6,7 @@
6
6
  import { CardAction } from '@microsoft/agents-activity'
7
7
 
8
8
  /**
9
- * Interface representing a Card Image.
9
+ * Represents a Card Image.
10
10
  */
11
11
  export interface CardImage {
12
12
  /** The URL of the image. */
package/src/cards/fact.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  /**
7
- * Interface representing a Fact.
7
+ * Represents a Fact.
8
8
  */
9
9
  export interface Fact {
10
10
  /** The key of the fact. */
@@ -7,7 +7,7 @@ import { CardAction } from '@microsoft/agents-activity'
7
7
  import { CardImage } from './cardImage'
8
8
 
9
9
  /**
10
- * Interface representing a Hero Card.
10
+ * Represents a Hero Card.
11
11
  */
12
12
  export interface HeroCard {
13
13
  /** The title of the card. */
@@ -7,6 +7,11 @@ import { O365ConnectorCardActionBase } from './o365ConnectorCardActionBase'
7
7
  import { O365ConnectorCardFact } from './o365ConnectorCardFact'
8
8
  import { O365ConnectorCardImage } from './o365ConnectorCardImage'
9
9
 
10
+ /**
11
+ * Defines the type of activity image to display in an O365 connector card section.
12
+ * - 'avatar': Displays the image as a profile avatar (typically circular or small)
13
+ * - 'article': Displays the image as an article thumbnail (typically rectangular or larger)
14
+ */
10
15
  export type ActivityImageType = 'avatar' | 'article'
11
16
 
12
17
  /**
@@ -15,7 +15,7 @@ import { Activity, ActivityEventNames, ActivityTypes, Channels, ConversationRefe
15
15
  import { ResourceResponse } from './connector-client/resourceResponse'
16
16
  import { MsalTokenProvider } from './auth/msalTokenProvider'
17
17
  import * as uuid from 'uuid'
18
- import { debug } from './logger'
18
+ import { debug } from '@microsoft/agents-activity/logger'
19
19
  import { StatusCodes } from './statusCodes'
20
20
  import { InvokeResponse } from './invoke/invokeResponse'
21
21
  import { AttachmentInfo } from './connector-client/attachmentInfo'
@@ -27,6 +27,7 @@ const logger = debug('agents:cloud-adapter')
27
27
  /**
28
28
  * Adapter for handling agent interactions with various channels through cloud-based services.
29
29
  *
30
+ * @remarks
30
31
  * CloudAdapter processes incoming HTTP requests from Microsoft Bot Framework channels,
31
32
  * authenticates them, and generates outgoing responses. It manages the communication
32
33
  * flow between agents and users across different channels, handling activities, attachments,
@@ -55,6 +56,33 @@ export class CloudAdapter extends BaseAdapter {
55
56
  }
56
57
  }
57
58
 
59
+ /**
60
+ * Determines whether a connector client is needed based on the delivery mode and service URL of the given activity.
61
+ *
62
+ * @param activity - The activity to evaluate.
63
+ * @returns true if a ConnectorClient is needed, false otherwise.
64
+ * A connector client is required if the activity's delivery mode is not "ExpectReplies"
65
+ * and the service URL is not null or empty.
66
+ * @protected
67
+ */
68
+ protected resolveIfConnectorClientIsNeeded (activity: Activity): boolean {
69
+ if (!activity) {
70
+ throw new TypeError('`activity` parameter required')
71
+ }
72
+
73
+ switch (activity.deliveryMode) {
74
+ case DeliveryModes.ExpectReplies:
75
+ if (!activity.serviceUrl) {
76
+ logger.debug('DeliveryMode = ExpectReplies, connector client is not needed')
77
+ return false
78
+ }
79
+ break
80
+ default:
81
+ break
82
+ }
83
+ return true
84
+ }
85
+
58
86
  /**
59
87
  * Creates a connector client for a specific service URL and scope.
60
88
  *
@@ -200,9 +228,13 @@ export class CloudAdapter extends BaseAdapter {
200
228
  logger.debug('Received activity: ', activity)
201
229
  const context = this.createTurnContext(activity, logic)
202
230
  const scope = request.user?.azp ?? request.user?.appid ?? 'https://api.botframework.com'
203
- logger.debug('Creating connector client with scope: ', scope)
204
- this.connectorClient = await this.createConnectorClient(activity.serviceUrl!, scope)
205
- this.setConnectorClient(context)
231
+
232
+ // if Delivery Mode == ExpectReplies, we don't need a connector client.
233
+ if (this.resolveIfConnectorClientIsNeeded(activity)) {
234
+ logger.debug('Creating connector client with scope: ', scope)
235
+ this.connectorClient = await this.createConnectorClient(activity.serviceUrl!, scope)
236
+ this.setConnectorClient(context)
237
+ }
206
238
 
207
239
  if (
208
240
  activity?.type === ActivityTypes.InvokeResponse ||
@@ -2,7 +2,7 @@
2
2
  import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
3
3
  import { AuthConfiguration } from '../auth/authConfiguration'
4
4
  import { AuthProvider } from '../auth/authProvider'
5
- import { debug } from '../logger'
5
+ import { debug } from '@microsoft/agents-activity/logger'
6
6
  import { Activity, ChannelAccount, ConversationParameters } from '@microsoft/agents-activity'
7
7
  import { ConversationsResult } from './conversationsResult'
8
8
  import { ConversationResourceResponse } from './conversationResourceResponse'
@@ -1,4 +1,4 @@
1
- import pjson from '@microsoft/agents-hosting/package.json'
1
+ import { version } from '../package.json'
2
2
  import os from 'os'
3
3
 
4
4
  /**
@@ -7,4 +7,4 @@ import os from 'os'
7
7
  *
8
8
  * @returns A formatted string containing the SDK version, Node.js version, and OS details
9
9
  */
10
- export const getProductInfo = () : string => `agents-sdk-js/${pjson.version} nodejs/${process.version} ${os.platform()}-${os.arch()}/${os.release()}`
10
+ export const getProductInfo = () : string => `agents-sdk-js/${version} nodejs/${process.version} ${os.platform()}-${os.arch()}/${os.release()}`