@microsoft/agents-hosting 1.1.4-g8d884129e7 → 1.2.0-alpha.18.g3c104e426a

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 (43) hide show
  1. package/dist/package.json +4 -4
  2. package/dist/src/activityHandler.js +7 -4
  3. package/dist/src/activityHandler.js.map +1 -1
  4. package/dist/src/app/auth/handlers/agenticAuthorization.d.ts +4 -0
  5. package/dist/src/app/auth/handlers/agenticAuthorization.js +12 -7
  6. package/dist/src/app/auth/handlers/agenticAuthorization.js.map +1 -1
  7. package/dist/src/app/index.d.ts +1 -0
  8. package/dist/src/app/index.js +1 -0
  9. package/dist/src/app/index.js.map +1 -1
  10. package/dist/src/app/streaming/streamingResponse.d.ts +138 -88
  11. package/dist/src/app/streaming/streamingResponse.js +241 -107
  12. package/dist/src/app/streaming/streamingResponse.js.map +1 -1
  13. package/dist/src/app/teamsAttachmentDownloader.d.ts +36 -0
  14. package/dist/src/app/teamsAttachmentDownloader.js +103 -0
  15. package/dist/src/app/teamsAttachmentDownloader.js.map +1 -0
  16. package/dist/src/auth/authProvider.d.ts +7 -1
  17. package/dist/src/auth/msalTokenProvider.js +6 -6
  18. package/dist/src/auth/msalTokenProvider.js.map +1 -1
  19. package/dist/src/cloudAdapter.d.ts +39 -14
  20. package/dist/src/cloudAdapter.js +52 -26
  21. package/dist/src/cloudAdapter.js.map +1 -1
  22. package/dist/src/connector-client/connectorClient.js +10 -9
  23. package/dist/src/connector-client/connectorClient.js.map +1 -1
  24. package/dist/src/errorHelper.d.ts +4 -0
  25. package/dist/src/errorHelper.js +588 -0
  26. package/dist/src/errorHelper.js.map +1 -0
  27. package/dist/src/index.d.ts +1 -0
  28. package/dist/src/index.js +3 -1
  29. package/dist/src/index.js.map +1 -1
  30. package/dist/src/oauth/userTokenClient.js.map +1 -1
  31. package/package.json +4 -4
  32. package/src/activityHandler.ts +8 -5
  33. package/src/app/auth/handlers/agenticAuthorization.ts +13 -7
  34. package/src/app/index.ts +1 -0
  35. package/src/app/streaming/streamingResponse.ts +252 -107
  36. package/src/app/teamsAttachmentDownloader.ts +110 -0
  37. package/src/auth/authProvider.ts +8 -1
  38. package/src/auth/msalTokenProvider.ts +7 -6
  39. package/src/cloudAdapter.ts +56 -29
  40. package/src/connector-client/connectorClient.ts +11 -10
  41. package/src/errorHelper.ts +674 -0
  42. package/src/index.ts +1 -0
  43. package/src/oauth/userTokenClient.ts +2 -2
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { Attachment, Channels } from '@microsoft/agents-activity'
7
+ import { debug } from '@microsoft/agents-activity/logger'
8
+ import { ConnectorClient } from '../connector-client'
9
+ import { InputFile, InputFileDownloader } from './inputFileDownloader'
10
+ import { TurnContext } from '../turnContext'
11
+ import { TurnState } from './turnState'
12
+ import axios, { AxiosInstance } from 'axios'
13
+ import { z } from 'zod'
14
+
15
+ const logger = debug('agents:teamsAttachmentDownloader')
16
+
17
+ /**
18
+ * Downloads attachments from Teams using the bots access token.
19
+ */
20
+ export class TeamsAttachmentDownloader<TState extends TurnState = TurnState> implements InputFileDownloader<TState> {
21
+ private _httpClient: AxiosInstance
22
+ private _stateKey: string
23
+
24
+ public constructor (stateKey: string = 'inputFiles') {
25
+ this._httpClient = axios.create()
26
+ this._stateKey = stateKey
27
+ }
28
+
29
+ /**
30
+ * Download any files relative to the current user's input.
31
+ *
32
+ * @param {TurnContext} context Context for the current turn of conversation.
33
+ * @returns {Promise<InputFile[]>} Promise that resolves to an array of downloaded input files.
34
+ */
35
+ public async downloadFiles (context: TurnContext): Promise<InputFile[]> {
36
+ if (context.activity.channelId !== Channels.Msteams && context.activity.channelId !== Channels.M365Copilot) {
37
+ return Promise.resolve([])
38
+ }
39
+ // Filter out HTML attachments
40
+ const attachments = context.activity.attachments?.filter((a) => a.contentType && !a.contentType.startsWith('text/html'))
41
+ if (!attachments || attachments.length === 0) {
42
+ return Promise.resolve([])
43
+ }
44
+
45
+ const connectorClient : ConnectorClient = context.turnState.get<ConnectorClient>(context.adapter.ConnectorClientKey)
46
+ this._httpClient.defaults.headers = connectorClient.axiosInstance.defaults.headers
47
+
48
+ const files: InputFile[] = []
49
+ for (const attachment of attachments) {
50
+ const file = await this.downloadFile(attachment)
51
+ if (file) {
52
+ files.push(file)
53
+ }
54
+ }
55
+
56
+ return files
57
+ }
58
+
59
+ /**
60
+ * @private
61
+ * @param {Attachment} attachment - Attachment to download.
62
+ * @returns {Promise<InputFile>} - Promise that resolves to the downloaded input file.
63
+ */
64
+ private async downloadFile (attachment: Attachment): Promise<InputFile | undefined> {
65
+ let inputFile: InputFile | undefined
66
+
67
+ if (attachment.contentUrl && attachment.contentUrl.startsWith('https://')) {
68
+ try {
69
+ const contentSchema = z.object({ downloadUrl: z.string().url() })
70
+ const parsed = contentSchema.safeParse(attachment.content)
71
+ const downloadUrl = parsed.success ? parsed.data.downloadUrl : attachment.contentUrl
72
+ const response = await this._httpClient.get(downloadUrl, { responseType: 'arraybuffer' })
73
+
74
+ const content = Buffer.from(response.data, 'binary')
75
+ const contentType = response.headers['content-type'] || 'application/octet-stream'
76
+ inputFile = { content, contentType, contentUrl: attachment.contentUrl }
77
+ } catch (error) {
78
+ logger.error(`Failed to download Teams attachment: ${error}`)
79
+ return undefined
80
+ }
81
+ } else {
82
+ if (!attachment.content) {
83
+ logger.error('Attachment missing content')
84
+ return undefined
85
+ }
86
+ if (!(attachment.content instanceof ArrayBuffer) && !Buffer.isBuffer(attachment.content)) {
87
+ logger.error('Attachment content is not ArrayBuffer or Buffer')
88
+ return undefined
89
+ }
90
+ inputFile = {
91
+ content: Buffer.from(attachment.content as ArrayBuffer),
92
+ contentType: attachment.contentType,
93
+ contentUrl: attachment.contentUrl
94
+ }
95
+ }
96
+ return inputFile
97
+ }
98
+
99
+ /**
100
+ * Downloads files from the attachments in the current turn context and stores them in state.
101
+ *
102
+ * @param context The turn context containing the activity with attachments.
103
+ * @param state The turn state to store the files in.
104
+ * @returns A promise that resolves when the downloaded files are stored.
105
+ */
106
+ public async downloadAndStoreFiles (context: TurnContext, state: TState): Promise<void> {
107
+ const files = await this.downloadFiles(context)
108
+ state.setValue(this._stateKey, files)
109
+ }
110
+ }
@@ -9,13 +9,20 @@ import { AuthConfiguration } from './authConfiguration'
9
9
  * Represents an authentication provider.
10
10
  */
11
11
  export interface AuthProvider {
12
+ /**
13
+ * The AuthConfiguration used for token acquisition.
14
+ */
15
+ connectionSettings?: AuthConfiguration
16
+
12
17
  /**
13
18
  * Gets an access token for the specified authentication configuration and scope.
14
19
  * @param authConfig - The authentication configuration.
15
20
  * @param scope - The scope for which the access token is requested.
16
21
  * @returns A promise that resolves to the access token.
17
22
  */
18
- getAccessToken: (authConfig: AuthConfiguration, scope: string) => Promise<string>
23
+ getAccessToken (authConfig: AuthConfiguration, scope: string): Promise<string>
24
+ getAccessToken (scope: string): Promise<string>
25
+ getAccessToken (authConfigOrScope: AuthConfiguration | string, scope?: string): Promise<string>
19
26
 
20
27
  /**
21
28
  * Get an access token for the agentic application
@@ -211,6 +211,10 @@ export class MsalTokenProvider implements AuthProvider {
211
211
  data.client_secret = this.connectionSettings.clientSecret
212
212
  }
213
213
 
214
+ if (data.grant_type !== 'user_fic') {
215
+ data.client_info = '2'
216
+ }
217
+
214
218
  const token = await axios.post(
215
219
  url,
216
220
  data,
@@ -234,7 +238,7 @@ export class MsalTokenProvider implements AuthProvider {
234
238
  const agentToken = await this.getAgenticApplicationToken(tenantId, agentAppInstanceId)
235
239
  const instanceToken = await this.getAgenticInstanceToken(tenantId, agentAppInstanceId)
236
240
 
237
- const token = await this.acquireTokenByForAgenticScenarios(tenantId, agentToken, instanceToken, scopes, {
241
+ const token = await this.acquireTokenByForAgenticScenarios(tenantId, agentAppInstanceId, agentToken, scopes, {
238
242
  user_id: agenticUserId,
239
243
  user_federated_identity_credential: instanceToken,
240
244
  grant_type: 'user_fic',
@@ -252,11 +256,8 @@ export class MsalTokenProvider implements AuthProvider {
252
256
  throw new Error('Connection settings must be provided when calling getAgenticApplicationToken')
253
257
  }
254
258
  logger.debug('Getting agentic application token')
255
- let clientAssertion
256
- if (this.connectionSettings.FICClientId) {
257
- clientAssertion = await this.fetchExternalToken(this.connectionSettings.FICClientId as string)
258
- }
259
- const token = await this.acquireTokenByForAgenticScenarios(tenantId, this.connectionSettings.clientId, clientAssertion, ['api://AzureAdTokenExchange/.default'], { grant_type: 'client_credentials',
259
+ const token = await this.acquireTokenByForAgenticScenarios(tenantId, this.connectionSettings.clientId, undefined, ['api://AzureAdTokenExchange/.default'], {
260
+ grant_type: 'client_credentials',
260
261
  fmi_path: agentAppInstanceId,
261
262
  })
262
263
 
@@ -13,19 +13,21 @@ import { AuthConfiguration, getAuthConfigWithDefaults } from './auth/authConfigu
13
13
  import { AuthProvider } from './auth/authProvider'
14
14
  import { ApxProductionScope } from './auth/authConstants'
15
15
  import { MsalConnectionManager } from './auth/msalConnectionManager'
16
- import { Activity, ActivityEventNames, ActivityTypes, Channels, ConversationReference, DeliveryModes, ConversationParameters, RoleTypes } from '@microsoft/agents-activity'
16
+ import { Activity, ActivityEventNames, ActivityTypes, Channels, ConversationReference, DeliveryModes, ConversationParameters, RoleTypes, ExceptionHelper } from '@microsoft/agents-activity'
17
+ import { Errors } from './errorHelper'
17
18
  import { ResourceResponse } from './connector-client/resourceResponse'
18
19
  import * as uuid from 'uuid'
19
20
  import { debug } from '@microsoft/agents-activity/logger'
20
21
  import { StatusCodes } from './statusCodes'
21
22
  import { InvokeResponse } from './invoke/invokeResponse'
22
- import { AttachmentInfo } from './connector-client/attachmentInfo'
23
23
  import { AttachmentData } from './connector-client/attachmentData'
24
+ import { AttachmentInfo } from './connector-client/attachmentInfo'
24
25
  import { normalizeIncomingActivity } from './activityWireCompat'
25
26
  import { UserTokenClient } from './oauth'
26
27
  import { HeaderPropagation, HeaderPropagationCollection, HeaderPropagationDefinition } from './headerPropagation'
27
28
  import { JwtPayload } from 'jsonwebtoken'
28
29
  import { getTokenServiceEndpoint } from './oauth/customUserTokenAPI'
30
+ import { Connections } from './auth/connections'
29
31
  const logger = debug('agents:cloud-adapter')
30
32
 
31
33
  /**
@@ -41,12 +43,13 @@ export class CloudAdapter extends BaseAdapter {
41
43
  /**
42
44
  * Client for connecting to the Azure Bot Service
43
45
  */
44
- connectionManager: MsalConnectionManager
46
+ connectionManager: Connections
45
47
 
46
48
  /**
47
49
  * Creates an instance of CloudAdapter.
48
- * @param authConfig - The authentication configuration for securing communications
49
- * @param authProvider - No longer used
50
+ * @param authConfig - The authentication configuration for securing communications.
51
+ * @param authProvider - No longer used.
52
+ * @param userTokenClient - No longer used.
50
53
  */
51
54
  constructor (authConfig?: AuthConfiguration, authProvider?: AuthProvider, userTokenClient?: UserTokenClient) {
52
55
  super()
@@ -84,10 +87,11 @@ export class CloudAdapter extends BaseAdapter {
84
87
  /**
85
88
  * Creates a connector client for a specific service URL and scope.
86
89
  *
87
- * @param serviceUrl - The URL of the service to connect to
88
- * @param scope - The authentication scope to use
89
- * @param headers - Optional headers to propagate in the request
90
- * @returns A promise that resolves to a ConnectorClient instance
90
+ * @param serviceUrl - The URL of the service to connect to.
91
+ * @param scope - The authentication scope to use.
92
+ * @param identity - The identity used to select the token provider.
93
+ * @param headers - Optional headers to propagate in the request.
94
+ * @returns A promise that resolves to a ConnectorClient instance.
91
95
  * @protected
92
96
  */
93
97
  protected async createConnectorClient (
@@ -107,6 +111,15 @@ export class CloudAdapter extends BaseAdapter {
107
111
  )
108
112
  }
109
113
 
114
+ /**
115
+ * Creates a connector client for a specific identity and activity.
116
+ *
117
+ * @param identity - The identity used to select the token provider.
118
+ * @param activity - The activity used to select the token provider.
119
+ * @param headers - Optional headers to propagate in the request.
120
+ * @returns A promise that resolves to a ConnectorClient instance.
121
+ * @protected
122
+ */
110
123
  protected async createConnectorClientWithIdentity (
111
124
  identity: JwtPayload,
112
125
  activity: Activity,
@@ -161,6 +174,11 @@ export class CloudAdapter extends BaseAdapter {
161
174
  return connectorClient
162
175
  }
163
176
 
177
+ /**
178
+ * Creates the JwtPayload object with the provided appId.
179
+ * @param appId The bot's appId.
180
+ * @returns The JwtPayload object containing the appId as aud.
181
+ */
164
182
  static createIdentity (appId: string) : JwtPayload {
165
183
  return {
166
184
  aud: appId
@@ -170,7 +188,7 @@ export class CloudAdapter extends BaseAdapter {
170
188
  /**
171
189
  * Sets the connector client on the turn context.
172
190
  *
173
- * @param context - The current turn context
191
+ * @param context - The current turn context.
174
192
  * @protected
175
193
  */
176
194
  protected setConnectorClient (
@@ -183,10 +201,12 @@ export class CloudAdapter extends BaseAdapter {
183
201
  /**
184
202
  * Creates a user token client for a specific service URL and scope.
185
203
  *
186
- * @param serviceUrl - The URL of the service to connect to
187
- * @param scope - The authentication scope to use
204
+ * @param identity - The identity used to select the token provider.
205
+ * @param tokenServiceEndpoint - The endpoint to connect to.
206
+ * @param scope - The authentication scope to use.
207
+ * @param audience - No longer used.
188
208
  * @param headers - Optional headers to propagate in the request
189
- * @returns A promise that resolves to a ConnectorClient instance
209
+ * @returns A promise that resolves to a UserTokenClient instance.
190
210
  * @protected
191
211
  */
192
212
  protected async createUserTokenClient (
@@ -220,7 +240,7 @@ export class CloudAdapter extends BaseAdapter {
220
240
  /**
221
241
  * Sets the user token client on the turn context.
222
242
  *
223
- * @param context - The current turn context
243
+ * @param context - The current turn context.
224
244
  * @protected
225
245
  */
226
246
  protected setUserTokenClient (
@@ -235,6 +255,7 @@ export class CloudAdapter extends BaseAdapter {
235
255
  * Creates a TurnContext for the given activity and logic.
236
256
  * @param activity - The activity to process.
237
257
  * @param logic - The logic to execute.
258
+ * @param identity - The identity used for the new context.
238
259
  * @returns The created TurnContext.
239
260
  */
240
261
  createTurnContext (activity: Activity, logic: AgentHandler, identity?: JwtPayload): TurnContext {
@@ -249,15 +270,15 @@ export class CloudAdapter extends BaseAdapter {
249
270
  */
250
271
  async sendActivities (context: TurnContext, activities: Activity[]): Promise<ResourceResponse[]> {
251
272
  if (!context) {
252
- throw new TypeError('`context` parameter required')
273
+ throw ExceptionHelper.generateException(TypeError, Errors.ContextParameterRequired)
253
274
  }
254
275
 
255
276
  if (!activities) {
256
- throw new TypeError('`activities` parameter required')
277
+ throw ExceptionHelper.generateException(TypeError, Errors.ActivitiesParameterRequired)
257
278
  }
258
279
 
259
280
  if (activities.length === 0) {
260
- throw new Error('Expecting one or more activities, but the array was empty.')
281
+ throw ExceptionHelper.generateException(Error, Errors.EmptyActivitiesArray)
261
282
  }
262
283
 
263
284
  const responses: ResourceResponse[] = []
@@ -271,7 +292,7 @@ export class CloudAdapter extends BaseAdapter {
271
292
  // no-op
272
293
  } else {
273
294
  if (!activity.serviceUrl || (activity.conversation == null) || !activity.conversation.id) {
274
- throw new Error('Invalid activity object')
295
+ throw ExceptionHelper.generateException(Error, Errors.InvalidActivityObject)
275
296
  }
276
297
 
277
298
  if (activity.replyToId) {
@@ -395,7 +416,7 @@ export class CloudAdapter extends BaseAdapter {
395
416
  }
396
417
 
397
418
  if (!activity.serviceUrl || (activity.conversation == null) || !activity.conversation.id || !activity.id) {
398
- throw new Error('Invalid activity object')
419
+ throw ExceptionHelper.generateException(Error, Errors.InvalidActivityObject)
399
420
  }
400
421
 
401
422
  const response = await context.turnState.get(this.ConnectorClientKey).updateActivity(
@@ -419,7 +440,7 @@ export class CloudAdapter extends BaseAdapter {
419
440
  }
420
441
 
421
442
  if (!reference || !reference.serviceUrl || (reference.conversation == null) || !reference.conversation.id || !reference.activityId) {
422
- throw new Error('Invalid conversation reference object')
443
+ throw ExceptionHelper.generateException(Error, Errors.InvalidConversationReference)
423
444
  }
424
445
 
425
446
  await context.turnState.get(this.ConnectorClientKey).deleteActivity(reference.conversation.id, reference.activityId)
@@ -427,8 +448,11 @@ export class CloudAdapter extends BaseAdapter {
427
448
 
428
449
  /**
429
450
  * Continues a conversation.
451
+ * @param botAppIdOrIdentity - The bot identity to use when continuing the conversation. This can be either:
452
+ * a string containing the bot's App ID (botId) or a JwtPayload object containing identity claims (must include aud).
430
453
  * @param reference - The conversation reference to continue.
431
454
  * @param logic - The logic to execute.
455
+ * @param isResponse - No longer used.
432
456
  * @returns A promise representing the completion of the continue operation.
433
457
  */
434
458
  async continueConversation (
@@ -437,7 +461,7 @@ export class CloudAdapter extends BaseAdapter {
437
461
  logic: (revocableContext: TurnContext) => Promise<void>,
438
462
  isResponse: Boolean = false): Promise<void> {
439
463
  if (!reference || !reference.serviceUrl || (reference.conversation == null) || !reference.conversation.id) {
440
- throw new Error('continueConversation: Invalid conversation reference object')
464
+ throw ExceptionHelper.generateException(Error, Errors.ContinueConversationInvalidReference)
441
465
  }
442
466
 
443
467
  if (!botAppIdOrIdentity) {
@@ -572,21 +596,22 @@ export class CloudAdapter extends BaseAdapter {
572
596
  /**
573
597
  * @deprecated This function will not be supported in future versions. Use TurnContext.turnState.get<ConnectorClient>(CloudAdapter.ConnectorClientKey).
574
598
  * Uploads an attachment.
599
+ * @param context - The context for the turn.
575
600
  * @param conversationId - The conversation ID.
576
601
  * @param attachmentData - The attachment data.
577
602
  * @returns A promise representing the ResourceResponse for the uploaded attachment.
578
603
  */
579
604
  async uploadAttachment (context: TurnContext, conversationId: string, attachmentData: AttachmentData): Promise<ResourceResponse> {
580
605
  if (context === undefined) {
581
- throw new Error('context is required')
606
+ throw ExceptionHelper.generateException(Error, Errors.ContextRequired)
582
607
  }
583
608
 
584
609
  if (conversationId === undefined) {
585
- throw new Error('conversationId is required')
610
+ throw ExceptionHelper.generateException(Error, Errors.ConversationIdRequired)
586
611
  }
587
612
 
588
613
  if (attachmentData === undefined) {
589
- throw new Error('attachmentData is required')
614
+ throw ExceptionHelper.generateException(Error, Errors.AttachmentDataRequired)
590
615
  }
591
616
 
592
617
  return await context.turnState.get<ConnectorClient>(this.ConnectorClientKey).uploadAttachment(conversationId, attachmentData)
@@ -595,16 +620,17 @@ export class CloudAdapter extends BaseAdapter {
595
620
  /**
596
621
  * @deprecated This function will not be supported in future versions. Use TurnContext.turnState.get<ConnectorClient>(CloudAdapter.ConnectorClientKey).
597
622
  * Gets attachment information.
623
+ * @param context - The context for the turn.
598
624
  * @param attachmentId - The attachment ID.
599
625
  * @returns A promise representing the AttachmentInfo for the requested attachment.
600
626
  */
601
627
  async getAttachmentInfo (context: TurnContext, attachmentId: string): Promise<AttachmentInfo> {
602
628
  if (context === undefined) {
603
- throw new Error('context is required')
629
+ throw ExceptionHelper.generateException(Error, Errors.ContextRequired)
604
630
  }
605
631
 
606
632
  if (attachmentId === undefined) {
607
- throw new Error('attachmentId is required')
633
+ throw ExceptionHelper.generateException(Error, Errors.AttachmentIdRequired)
608
634
  }
609
635
 
610
636
  return await context.turnState.get<ConnectorClient>(this.ConnectorClientKey).getAttachmentInfo(attachmentId)
@@ -613,21 +639,22 @@ export class CloudAdapter extends BaseAdapter {
613
639
  /**
614
640
  * @deprecated This function will not be supported in future versions. Use TurnContext.turnState.get<ConnectorClient>(CloudAdapter.ConnectorClientKey).
615
641
  * Gets an attachment.
642
+ * @param context - The context for the turn.
616
643
  * @param attachmentId - The attachment ID.
617
644
  * @param viewId - The view ID.
618
645
  * @returns A promise representing the NodeJS.ReadableStream for the requested attachment.
619
646
  */
620
647
  async getAttachment (context: TurnContext, attachmentId: string, viewId: string): Promise<NodeJS.ReadableStream> {
621
648
  if (context === undefined) {
622
- throw new Error('context is required')
649
+ throw ExceptionHelper.generateException(Error, Errors.ContextRequired)
623
650
  }
624
651
 
625
652
  if (attachmentId === undefined) {
626
- throw new Error('attachmentId is required')
653
+ throw ExceptionHelper.generateException(Error, Errors.AttachmentIdRequired)
627
654
  }
628
655
 
629
656
  if (viewId === undefined) {
630
- throw new Error('viewId is required')
657
+ throw ExceptionHelper.generateException(Error, Errors.ViewIdRequired)
631
658
  }
632
659
 
633
660
  return await context.turnState.get<ConnectorClient>(this.ConnectorClientKey).getAttachment(attachmentId, viewId)
@@ -3,7 +3,8 @@ import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
3
3
  import { AuthConfiguration } from '../auth/authConfiguration'
4
4
  import { AuthProvider } from '../auth/authProvider'
5
5
  import { debug } from '@microsoft/agents-activity/logger'
6
- import { Activity, ChannelAccount, ConversationParameters, RoleTypes, Channels } from '@microsoft/agents-activity'
6
+ import { Activity, ChannelAccount, ConversationParameters, RoleTypes, Channels, ExceptionHelper } from '@microsoft/agents-activity'
7
+ import { Errors } from '../errorHelper'
7
8
  import { ConversationsResult } from './conversationsResult'
8
9
  import { ConversationResourceResponse } from './conversationResourceResponse'
9
10
  import { ResourceResponse } from './resourceResponse'
@@ -143,7 +144,7 @@ export class ConnectorClient {
143
144
 
144
145
  public async getConversationMember (userId: string, conversationId: string): Promise<ChannelAccount> {
145
146
  if (!userId || !conversationId) {
146
- throw new Error('userId and conversationId are required')
147
+ throw ExceptionHelper.generateException(Error, Errors.UserIdAndConversationIdRequired)
147
148
  }
148
149
  const config: AxiosRequestConfig = {
149
150
  method: 'get',
@@ -192,7 +193,7 @@ export class ConnectorClient {
192
193
  ): Promise<ResourceResponse> {
193
194
  logger.debug(`Replying to activity: ${activityId} in conversation: ${conversationId}`)
194
195
  if (!conversationId || !activityId) {
195
- throw new Error('conversationId and activityId are required')
196
+ throw ExceptionHelper.generateException(Error, Errors.ConversationIdAndActivityIdRequired)
196
197
  }
197
198
 
198
199
  const trimmedConversationId: string = this.conditionallyTruncateConversationId(conversationId, body)
@@ -242,7 +243,7 @@ export class ConnectorClient {
242
243
  ): Promise<ResourceResponse> {
243
244
  logger.debug(`Send to conversation: ${conversationId} activity: ${body.id}`)
244
245
  if (!conversationId) {
245
- throw new Error('conversationId is required')
246
+ throw ExceptionHelper.generateException(Error, Errors.ConversationIdRequired)
246
247
  }
247
248
 
248
249
  const trimmedConversationId: string = this.conditionallyTruncateConversationId(conversationId, body)
@@ -272,7 +273,7 @@ export class ConnectorClient {
272
273
  body: Activity
273
274
  ): Promise<ResourceResponse> {
274
275
  if (!conversationId || !activityId) {
275
- throw new Error('conversationId and activityId are required')
276
+ throw ExceptionHelper.generateException(Error, Errors.ConversationIdAndActivityIdRequired)
276
277
  }
277
278
  const config: AxiosRequestConfig = {
278
279
  method: 'put',
@@ -297,7 +298,7 @@ export class ConnectorClient {
297
298
  activityId: string
298
299
  ): Promise<void> {
299
300
  if (!conversationId || !activityId) {
300
- throw new Error('conversationId and activityId are required')
301
+ throw ExceptionHelper.generateException(Error, Errors.ConversationIdAndActivityIdRequired)
301
302
  }
302
303
  const config: AxiosRequestConfig = {
303
304
  method: 'delete',
@@ -321,7 +322,7 @@ export class ConnectorClient {
321
322
  body: AttachmentData
322
323
  ): Promise<ResourceResponse> {
323
324
  if (conversationId === undefined) {
324
- throw new Error('conversationId is required')
325
+ throw ExceptionHelper.generateException(Error, Errors.ConversationIdRequired)
325
326
  }
326
327
  const config: AxiosRequestConfig = {
327
328
  method: 'post',
@@ -344,7 +345,7 @@ export class ConnectorClient {
344
345
  attachmentId: string
345
346
  ): Promise<AttachmentInfo> {
346
347
  if (attachmentId === undefined) {
347
- throw new Error('attachmentId is required')
348
+ throw ExceptionHelper.generateException(Error, Errors.AttachmentIdRequired)
348
349
  }
349
350
  const config: AxiosRequestConfig = {
350
351
  method: 'get',
@@ -368,10 +369,10 @@ export class ConnectorClient {
368
369
  viewId: string
369
370
  ): Promise<NodeJS.ReadableStream> {
370
371
  if (attachmentId === undefined) {
371
- throw new Error('attachmentId is required')
372
+ throw ExceptionHelper.generateException(Error, Errors.AttachmentIdRequired)
372
373
  }
373
374
  if (viewId === undefined) {
374
- throw new Error('viewId is required')
375
+ throw ExceptionHelper.generateException(Error, Errors.ViewIdRequired)
375
376
  }
376
377
  const config: AxiosRequestConfig = {
377
378
  method: 'get',