@microsoft/agents-hosting 1.1.0-alpha.58 → 1.1.0-alpha.75

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 (39) hide show
  1. package/dist/package.json +4 -4
  2. package/dist/src/activityWireCompat.d.ts +1 -1
  3. package/dist/src/activityWireCompat.js +3 -0
  4. package/dist/src/activityWireCompat.js.map +1 -1
  5. package/dist/src/app/agentApplication.d.ts +2 -2
  6. package/dist/src/app/agentApplication.js.map +1 -1
  7. package/dist/src/app/auth/authorization.js +1 -1
  8. package/dist/src/app/auth/handlers/agenticAuthorization.d.ts +0 -4
  9. package/dist/src/app/auth/handlers/agenticAuthorization.js +1 -12
  10. package/dist/src/app/auth/handlers/agenticAuthorization.js.map +1 -1
  11. package/dist/src/auth/authConfiguration.js +14 -23
  12. package/dist/src/auth/authConfiguration.js.map +1 -1
  13. package/dist/src/auth/connections.d.ts +5 -4
  14. package/dist/src/auth/msalConnectionManager.d.ts +6 -5
  15. package/dist/src/auth/msalConnectionManager.js +31 -7
  16. package/dist/src/auth/msalConnectionManager.js.map +1 -1
  17. package/dist/src/cloudAdapter.d.ts +2 -2
  18. package/dist/src/cloudAdapter.js +19 -27
  19. package/dist/src/cloudAdapter.js.map +1 -1
  20. package/dist/src/connector-client/connectorClient.d.ts +6 -0
  21. package/dist/src/connector-client/connectorClient.js +11 -7
  22. package/dist/src/connector-client/connectorClient.js.map +1 -1
  23. package/dist/src/oauth/customUserTokenAPI.d.ts +1 -0
  24. package/dist/src/oauth/customUserTokenAPI.js +11 -0
  25. package/dist/src/oauth/customUserTokenAPI.js.map +1 -0
  26. package/dist/src/oauth/userTokenClient.js +2 -6
  27. package/dist/src/oauth/userTokenClient.js.map +1 -1
  28. package/package.json +4 -4
  29. package/src/activityWireCompat.ts +4 -1
  30. package/src/app/agentApplication.ts +1 -2
  31. package/src/app/auth/authorization.ts +1 -1
  32. package/src/app/auth/handlers/agenticAuthorization.ts +1 -13
  33. package/src/auth/authConfiguration.ts +15 -28
  34. package/src/auth/connections.ts +5 -4
  35. package/src/auth/msalConnectionManager.ts +33 -8
  36. package/src/cloudAdapter.ts +14 -21
  37. package/src/connector-client/connectorClient.ts +11 -6
  38. package/src/oauth/customUserTokenAPI.ts +5 -0
  39. package/src/oauth/userTokenClient.ts +3 -7
@@ -5,9 +5,9 @@
5
5
 
6
6
  import { Activity, RoleTypes } from '@microsoft/agents-activity'
7
7
  import { AuthConfiguration } from './authConfiguration'
8
- import { AuthProvider } from './authProvider'
9
8
  import { Connections } from './connections'
10
9
  import { MsalTokenProvider } from './msalTokenProvider'
10
+ import { JwtPayload } from 'jsonwebtoken'
11
11
 
12
12
  export interface ConnectionMapItem {
13
13
  audience?: string
@@ -50,7 +50,7 @@ export class MsalConnectionManager implements Connections {
50
50
  if (!conn) {
51
51
  throw new Error(`Connection not found: ${connectionName}`)
52
52
  }
53
- return conn
53
+ return this.applyConnectionDefaults(conn)
54
54
  }
55
55
 
56
56
  /**
@@ -69,13 +69,15 @@ export class MsalConnectionManager implements Connections {
69
69
  }
70
70
  }
71
71
 
72
- return this._connections.values().next().value as MsalTokenProvider
72
+ const conn = this._connections.values().next().value as MsalTokenProvider
73
+
74
+ return this.applyConnectionDefaults(conn)
73
75
  }
74
76
 
75
77
  /**
76
78
  * Finds a connection based on a map.
77
79
  *
78
- * @param audience The audience.
80
+ * @param identity - The identity. Usually TurnContext.identity.
79
81
  * @param serviceUrl The service URL.
80
82
  * @returns The TokenProvider for the connection.
81
83
  *
@@ -90,7 +92,18 @@ export class MsalConnectionManager implements Connections {
90
92
  * ServiceUrl is: A regex to match with, or "*" for any serviceUrl value.
91
93
  * Connection is: A name in the 'Connections' list.
92
94
  */
93
- getTokenProvider (audience: string, serviceUrl: string): MsalTokenProvider {
95
+ getTokenProvider (identity: JwtPayload, serviceUrl: string): MsalTokenProvider {
96
+ if (!identity) {
97
+ throw new Error('Identity is required to get the token provider.')
98
+ }
99
+
100
+ let audience
101
+ if (Array.isArray(identity?.aud)) {
102
+ audience = identity.aud[0]
103
+ } else {
104
+ audience = identity.aud
105
+ }
106
+
94
107
  if (!audience || !serviceUrl) throw new Error('Audience and Service URL are required to get the token provider.')
95
108
 
96
109
  if (this._connectionsMap.length === 0) {
@@ -121,12 +134,12 @@ export class MsalConnectionManager implements Connections {
121
134
 
122
135
  /**
123
136
  * Finds a connection based on an activity's blueprint.
124
- * @param audience The audience.
137
+ * @param identity - The identity. Usually TurnContext.identity.
125
138
  * @param activity The activity.
126
139
  * @returns The TokenProvider for the connection.
127
140
  */
128
- getTokenProviderFromActivity (audience: string, activity: Activity): AuthProvider {
129
- let connection = this.getTokenProvider(audience, activity.serviceUrl || '')
141
+ getTokenProviderFromActivity (identity: JwtPayload, activity: Activity): MsalTokenProvider {
142
+ let connection = this.getTokenProvider(identity, activity.serviceUrl || '')
130
143
 
131
144
  // This is for the case where the Agentic BlueprintId is not the same as the AppId
132
145
  if (connection &&
@@ -147,4 +160,16 @@ export class MsalConnectionManager implements Connections {
147
160
  getDefaultConnectionConfiguration (): AuthConfiguration {
148
161
  return this._serviceConnectionConfiguration
149
162
  }
163
+
164
+ private applyConnectionDefaults (conn: MsalTokenProvider): MsalTokenProvider {
165
+ if (conn.connectionSettings) {
166
+ conn.connectionSettings.authority ??= 'https://login.microsoftonline.com'
167
+ conn.connectionSettings.issuers ??= [
168
+ 'https://api.botframework.com',
169
+ `https://sts.windows.net/${conn.connectionSettings.tenantId}/`,
170
+ `${conn.connectionSettings.authority}/${conn.connectionSettings.tenantId}/v2.0`
171
+ ]
172
+ }
173
+ return conn
174
+ }
150
175
  }
@@ -25,7 +25,7 @@ import { normalizeIncomingActivity } from './activityWireCompat'
25
25
  import { UserTokenClient } from './oauth'
26
26
  import { HeaderPropagation, HeaderPropagationCollection, HeaderPropagationDefinition } from './headerPropagation'
27
27
  import { JwtPayload } from 'jsonwebtoken'
28
-
28
+ import { getTokenServiceEndpoint } from './oauth/customUserTokenAPI'
29
29
  const logger = debug('agents:cloud-adapter')
30
30
 
31
31
  /**
@@ -93,11 +93,11 @@ export class CloudAdapter extends BaseAdapter {
93
93
  protected async createConnectorClient (
94
94
  serviceUrl: string,
95
95
  scope: string,
96
- audience: string,
96
+ identity: JwtPayload,
97
97
  headers?: HeaderPropagationCollection
98
98
  ): Promise<ConnectorClient> {
99
99
  // get the correct token provider
100
- const tokenProvider = this.connectionManager.getTokenProvider(audience, serviceUrl)
100
+ const tokenProvider = this.connectionManager.getTokenProvider(identity, serviceUrl)
101
101
 
102
102
  const token = await tokenProvider.getAccessToken(scope)
103
103
  return ConnectorClient.createClientWithToken(
@@ -112,14 +112,7 @@ export class CloudAdapter extends BaseAdapter {
112
112
  activity: Activity,
113
113
  scope: string,
114
114
  headers?: HeaderPropagationCollection) {
115
- let audience
116
- if (Array.isArray(identity.aud)) {
117
- audience = identity.aud[0]
118
- } else {
119
- audience = identity.aud
120
- }
121
-
122
- if (!audience) {
115
+ if (!identity?.aud) {
123
116
  // anonymous
124
117
  return ConnectorClient.createClientWithToken(
125
118
  activity.serviceUrl!,
@@ -129,7 +122,7 @@ export class CloudAdapter extends BaseAdapter {
129
122
  }
130
123
 
131
124
  let connectorClient
132
- const tokenProvider = this.connectionManager.getTokenProvider(audience!, activity.serviceUrl ?? '')
125
+ const tokenProvider = this.connectionManager.getTokenProviderFromActivity(identity, activity)
133
126
  if (activity.isAgenticRequest()) {
134
127
  logger.debug('Activity is from an agentic source, using special scope', activity.recipient)
135
128
 
@@ -194,13 +187,14 @@ export class CloudAdapter extends BaseAdapter {
194
187
  * @protected
195
188
  */
196
189
  protected async createUserTokenClient (
197
- tokenServiceEndpoint: string = 'https://api.botframework.com',
190
+ identity: JwtPayload,
191
+ tokenServiceEndpoint: string = getTokenServiceEndpoint(),
198
192
  scope: string = 'https://api.botframework.com',
199
193
  audience: string = 'https://api.botframework.com',
200
194
  headers?: HeaderPropagationCollection
201
195
  ): Promise<UserTokenClient> {
202
196
  // get the correct token provider
203
- const tokenProvider = this.connectionManager.getTokenProvider(audience, tokenServiceEndpoint)
197
+ const tokenProvider = this.connectionManager.getTokenProvider(identity, tokenServiceEndpoint)
204
198
 
205
199
  return UserTokenClient.createClientWithScope(
206
200
  tokenServiceEndpoint,
@@ -258,9 +252,7 @@ export class CloudAdapter extends BaseAdapter {
258
252
  delete activity.id
259
253
  let response: ResourceResponse = { id: '' }
260
254
 
261
- if (activity.type === ActivityTypes.Delay) {
262
- await setTimeout(() => { }, typeof activity.value === 'number' ? activity.value : 1000)
263
- } else if (activity.type === ActivityTypes.InvokeResponse) {
255
+ if (activity.type === ActivityTypes.InvokeResponse) {
264
256
  context.turnState.set(INVOKE_RESPONSE_KEY, activity)
265
257
  } else if (activity.type === ActivityTypes.Trace && activity.channelId !== Channels.Emulator) {
266
258
  // no-op
@@ -336,7 +328,7 @@ export class CloudAdapter extends BaseAdapter {
336
328
  }
337
329
 
338
330
  if (!activity.isAgenticRequest()) {
339
- const userTokenClient = await this.createUserTokenClient()
331
+ const userTokenClient = await this.createUserTokenClient(request.user!)
340
332
  this.setUserTokenClient(context, userTokenClient)
341
333
  }
342
334
 
@@ -449,7 +441,7 @@ export class CloudAdapter extends BaseAdapter {
449
441
  const connectorClient = await this.createConnectorClientWithIdentity(identity, continuationActivity, scope)
450
442
  this.setConnectorClient(context, connectorClient)
451
443
 
452
- const userTokenClient = await this.createUserTokenClient()
444
+ const userTokenClient = await this.createUserTokenClient(identity)
453
445
  this.setUserTokenClient(context, userTokenClient)
454
446
 
455
447
  await this.runMiddleware(context, logic)
@@ -544,8 +536,9 @@ export class CloudAdapter extends BaseAdapter {
544
536
  if (!conversationParameters) throw new TypeError('`conversationParameters` must be defined')
545
537
  if (!logic) throw new TypeError('`logic` must be defined')
546
538
 
547
- const restClient = await this.createConnectorClient(serviceUrl, audience, audience)
548
- const userTokenClient = await this.createUserTokenClient()
539
+ const identity = CloudAdapter.createIdentity(audience)
540
+ const restClient = await this.createConnectorClient(serviceUrl, audience, identity)
541
+ const userTokenClient = await this.createUserTokenClient(identity)
549
542
  const createConversationResult = await restClient.createConversation(conversationParameters)
550
543
  const createActivity = this.createCreateActivity(
551
544
  createConversationResult.id,
@@ -117,10 +117,6 @@ export class ConnectorClient {
117
117
  const axiosInstance = axios.create({
118
118
  baseURL,
119
119
  headers: headerPropagation.outgoing,
120
- transformRequest: [
121
- (data, headers) => {
122
- return JSON.stringify(normalizeOutgoingActivity(data))
123
- }]
124
120
  })
125
121
 
126
122
  if (token && token.length > 1) {
@@ -166,7 +162,10 @@ export class ConnectorClient {
166
162
  * @returns The conversation resource response.
167
163
  */
168
164
  public async createConversation (body: ConversationParameters): Promise<ConversationResourceResponse> {
169
- const payload = normalizeOutgoingActivity(body)
165
+ const payload = {
166
+ ...body,
167
+ activity: normalizeOutgoingActivity(body.activity)
168
+ }
170
169
  const config: AxiosRequestConfig = {
171
170
  method: 'post',
172
171
  url: '/v3/conversations',
@@ -211,6 +210,12 @@ export class ConnectorClient {
211
210
  return response.data
212
211
  }
213
212
 
213
+ /**
214
+ * Trim the conversationId to a fixed length when creating the URL. This is applied only in specific API calls for agentic calls.
215
+ * @param conversationId The ID of the conversation to potentially truncate.
216
+ * @param activity The activity object used to determine if truncation is necessary.
217
+ * @returns The original or truncated conversationId, depending on the channel and activity role.
218
+ */
214
219
  private conditionallyTruncateConversationId (conversationId: string, activity: Activity): string {
215
220
  if (
216
221
  (activity.channelIdChannel === Channels.Msteams || activity.channelIdChannel === Channels.Agents) &&
@@ -275,7 +280,7 @@ export class ConnectorClient {
275
280
  headers: {
276
281
  'Content-Type': 'application/json'
277
282
  },
278
- data: body
283
+ data: normalizeOutgoingActivity(body)
279
284
  }
280
285
  const response = await this._axiosInstance(config)
281
286
  return response.data
@@ -0,0 +1,5 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved.
2
+ // Licensed under the MIT License.
3
+ export const getTokenServiceEndpoint = (): string => {
4
+ return process.env.TOKEN_SERVICE_ENDPOINT ?? 'https://api.botframework.com'
5
+ }
@@ -4,11 +4,12 @@
4
4
  import axios, { AxiosInstance } from 'axios'
5
5
  import { Activity, ConversationReference } from '@microsoft/agents-activity'
6
6
  import { debug } from '@microsoft/agents-activity/logger'
7
- import { normalizeOutgoingActivity, normalizeTokenExchangeState } from '../activityWireCompat'
7
+ import { normalizeTokenExchangeState } from '../activityWireCompat'
8
8
  import { AadResourceUrls, SignInResource, TokenExchangeRequest, TokenOrSinginResourceResponse, TokenResponse, TokenStatus } from './userTokenClient.types'
9
9
  import { getProductInfo } from '../getProductInfo'
10
10
  import { AuthProvider, MsalTokenProvider } from '../auth'
11
11
  import { HeaderPropagationCollection } from '../headerPropagation'
12
+ import { getTokenServiceEndpoint } from './customUserTokenAPI'
12
13
 
13
14
  const logger = debug('agents:user-token-client')
14
15
 
@@ -31,7 +32,7 @@ export class UserTokenClient {
31
32
 
32
33
  constructor (param: string | AxiosInstance) {
33
34
  if (typeof param === 'string') {
34
- const baseURL = 'https://api.botframework.com'
35
+ const baseURL = getTokenServiceEndpoint()
35
36
  this.client = axios.create({
36
37
  baseURL,
37
38
  headers: {
@@ -116,11 +117,6 @@ export class UserTokenClient {
116
117
  'Content-Type': 'application/json', // Required by transformRequest
117
118
  'User-Agent': getProductInfo(),
118
119
  },
119
- transformRequest: [
120
- (data, headers) => {
121
- return JSON.stringify(normalizeOutgoingActivity(data))
122
- },
123
- ],
124
120
  })
125
121
  const token = await (authProvider as MsalTokenProvider).getAccessToken(scope)
126
122
  if (token.length > 1) {