@microsoft/agents-hosting 1.1.0-alpha.5 → 1.1.0-alpha.58
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.
- package/dist/package.json +10 -6
- package/dist/src/activityWireCompat.js +8 -3
- package/dist/src/activityWireCompat.js.map +1 -1
- package/dist/src/agent-client/agentClient.js +7 -3
- package/dist/src/agent-client/agentClient.js.map +1 -1
- package/dist/src/agent-client/agentResponseHandler.js +6 -2
- package/dist/src/agent-client/agentResponseHandler.js.map +1 -1
- package/dist/src/app/agentApplication.d.ts +26 -11
- package/dist/src/app/agentApplication.js +93 -82
- package/dist/src/app/agentApplication.js.map +1 -1
- package/dist/src/app/agentApplicationBuilder.d.ts +2 -2
- package/dist/src/app/agentApplicationBuilder.js.map +1 -1
- package/dist/src/app/agentApplicationOptions.d.ts +9 -2
- package/dist/src/app/appRoute.d.ts +7 -0
- package/dist/src/app/{authorization.d.ts → auth/authorization.d.ts} +33 -139
- package/dist/src/app/auth/authorization.js +188 -0
- package/dist/src/app/auth/authorization.js.map +1 -0
- package/dist/src/app/auth/authorizationManager.d.ts +71 -0
- package/dist/src/app/auth/authorizationManager.js +170 -0
- package/dist/src/app/auth/authorizationManager.js.map +1 -0
- package/dist/src/app/auth/handlerStorage.d.ts +36 -0
- package/dist/src/app/auth/handlerStorage.js +62 -0
- package/dist/src/app/auth/handlerStorage.js.map +1 -0
- package/dist/src/app/auth/handlers/agenticAuthorization.d.ts +97 -0
- package/dist/src/app/auth/handlers/agenticAuthorization.js +145 -0
- package/dist/src/app/auth/handlers/agenticAuthorization.js.map +1 -0
- package/dist/src/app/auth/handlers/azureBotAuthorization.d.ts +222 -0
- package/dist/src/app/auth/handlers/azureBotAuthorization.js +428 -0
- package/dist/src/app/auth/handlers/azureBotAuthorization.js.map +1 -0
- package/dist/src/app/auth/handlers/index.d.ts +2 -0
- package/dist/src/app/auth/handlers/index.js +19 -0
- package/dist/src/app/auth/handlers/index.js.map +1 -0
- package/dist/src/app/auth/index.d.ts +2 -0
- package/dist/src/app/auth/index.js +19 -0
- package/dist/src/app/auth/index.js.map +1 -0
- package/dist/src/app/auth/types.d.ts +104 -0
- package/dist/src/app/auth/types.js +24 -0
- package/dist/src/app/auth/types.js.map +1 -0
- package/dist/src/app/index.d.ts +2 -3
- package/dist/src/app/index.js +2 -3
- package/dist/src/app/index.js.map +1 -1
- package/dist/src/app/routeList.d.ts +1 -1
- package/dist/src/app/routeList.js +22 -5
- package/dist/src/app/routeList.js.map +1 -1
- package/dist/src/app/streaming/streamingResponse.js +2 -1
- package/dist/src/app/streaming/streamingResponse.js.map +1 -1
- package/dist/src/auth/MemoryCache.d.ts +16 -0
- package/dist/src/auth/MemoryCache.js +58 -0
- package/dist/src/auth/MemoryCache.js.map +1 -0
- package/dist/src/auth/authConfiguration.d.ts +44 -2
- package/dist/src/auth/authConfiguration.js +218 -53
- package/dist/src/auth/authConfiguration.js.map +1 -1
- package/dist/src/auth/authConstants.d.ts +11 -0
- package/dist/src/auth/authConstants.js +15 -0
- package/dist/src/auth/authConstants.js.map +1 -0
- package/dist/src/auth/authProvider.d.ts +23 -0
- package/dist/src/auth/connections.d.ts +40 -0
- package/dist/src/auth/connections.js +7 -0
- package/dist/src/auth/connections.js.map +1 -0
- package/dist/src/auth/index.d.ts +2 -0
- package/dist/src/auth/index.js +2 -0
- package/dist/src/auth/index.js.map +1 -1
- package/dist/src/auth/jwt-middleware.js +31 -18
- package/dist/src/auth/jwt-middleware.js.map +1 -1
- package/dist/src/auth/msalConnectionManager.d.ts +63 -0
- package/dist/src/auth/msalConnectionManager.js +124 -0
- package/dist/src/auth/msalConnectionManager.js.map +1 -0
- package/dist/src/auth/msalTokenProvider.d.ts +31 -0
- package/dist/src/auth/msalTokenProvider.js +167 -16
- package/dist/src/auth/msalTokenProvider.js.map +1 -1
- package/dist/src/baseAdapter.d.ts +10 -25
- package/dist/src/baseAdapter.js +2 -15
- package/dist/src/baseAdapter.js.map +1 -1
- package/dist/src/cloudAdapter.d.ts +40 -23
- package/dist/src/cloudAdapter.js +132 -56
- package/dist/src/cloudAdapter.js.map +1 -1
- package/dist/src/connector-client/connectorClient.d.ts +9 -0
- package/dist/src/connector-client/connectorClient.js +39 -9
- package/dist/src/connector-client/connectorClient.js.map +1 -1
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.js +0 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/oauth/index.d.ts +0 -1
- package/dist/src/oauth/index.js +0 -1
- package/dist/src/oauth/index.js.map +1 -1
- package/dist/src/oauth/userTokenClient.d.ts +30 -13
- package/dist/src/oauth/userTokenClient.js +64 -26
- package/dist/src/oauth/userTokenClient.js.map +1 -1
- package/dist/src/oauth/userTokenClient.types.d.ts +19 -6
- package/dist/src/turnContext.d.ts +7 -1
- package/dist/src/turnContext.js +11 -4
- package/dist/src/turnContext.js.map +1 -1
- package/package.json +10 -6
- package/src/activityWireCompat.ts +8 -3
- package/src/agent-client/agentClient.ts +9 -3
- package/src/agent-client/agentResponseHandler.ts +5 -2
- package/src/app/agentApplication.ts +97 -75
- package/src/app/agentApplicationBuilder.ts +2 -2
- package/src/app/agentApplicationOptions.ts +10 -2
- package/src/app/appRoute.ts +8 -0
- package/src/app/auth/authorization.ts +252 -0
- package/src/app/auth/authorizationManager.ts +213 -0
- package/src/app/auth/handlerStorage.ts +61 -0
- package/src/app/auth/handlers/agenticAuthorization.ts +194 -0
- package/src/app/auth/handlers/azureBotAuthorization.ts +599 -0
- package/src/app/auth/handlers/index.ts +2 -0
- package/src/app/auth/index.ts +2 -0
- package/src/app/auth/types.ts +111 -0
- package/src/app/index.ts +2 -3
- package/src/app/routeList.ts +24 -5
- package/src/app/streaming/streamingResponse.ts +2 -1
- package/src/auth/MemoryCache.ts +59 -0
- package/src/auth/authConfiguration.ts +258 -52
- package/src/auth/authConstants.ts +11 -0
- package/src/auth/authProvider.ts +31 -0
- package/src/auth/connections.ts +46 -0
- package/src/auth/index.ts +2 -0
- package/src/auth/jwt-middleware.ts +38 -21
- package/src/auth/msalConnectionManager.ts +150 -0
- package/src/auth/msalTokenProvider.ts +209 -9
- package/src/baseAdapter.ts +10 -29
- package/src/cloudAdapter.ts +192 -67
- package/src/connector-client/connectorClient.ts +49 -10
- package/src/index.ts +0 -1
- package/src/oauth/index.ts +0 -1
- package/src/oauth/userTokenClient.ts +79 -23
- package/src/oauth/userTokenClient.types.ts +20 -8
- package/src/turnContext.ts +16 -5
- package/dist/src/app/authorization.js +0 -387
- package/dist/src/app/authorization.js.map +0 -1
- package/dist/src/claimsIdentity.d.ts +0 -35
- package/dist/src/claimsIdentity.js +0 -43
- package/dist/src/claimsIdentity.js.map +0 -1
- package/dist/src/oauth/oAuthFlow.d.ts +0 -119
- package/dist/src/oauth/oAuthFlow.js +0 -316
- package/dist/src/oauth/oAuthFlow.js.map +0 -1
- package/src/app/authorization.ts +0 -432
- package/src/claimsIdentity.ts +0 -47
- package/src/oauth/oAuthFlow.ts +0 -378
package/src/cloudAdapter.ts
CHANGED
|
@@ -9,11 +9,12 @@ import { TurnContext } from './turnContext'
|
|
|
9
9
|
import { Response } from 'express'
|
|
10
10
|
import { Request } from './auth/request'
|
|
11
11
|
import { ConnectorClient } from './connector-client/connectorClient'
|
|
12
|
-
import { AuthConfiguration,
|
|
12
|
+
import { AuthConfiguration, getAuthConfigWithDefaults } from './auth/authConfiguration'
|
|
13
13
|
import { AuthProvider } from './auth/authProvider'
|
|
14
|
-
import {
|
|
14
|
+
import { ApxProductionScope } from './auth/authConstants'
|
|
15
|
+
import { MsalConnectionManager } from './auth/msalConnectionManager'
|
|
16
|
+
import { Activity, ActivityEventNames, ActivityTypes, Channels, ConversationReference, DeliveryModes, ConversationParameters, RoleTypes } from '@microsoft/agents-activity'
|
|
15
17
|
import { ResourceResponse } from './connector-client/resourceResponse'
|
|
16
|
-
import { MsalTokenProvider } from './auth/msalTokenProvider'
|
|
17
18
|
import * as uuid from 'uuid'
|
|
18
19
|
import { debug } from '@microsoft/agents-activity/logger'
|
|
19
20
|
import { StatusCodes } from './statusCodes'
|
|
@@ -23,6 +24,7 @@ import { AttachmentData } from './connector-client/attachmentData'
|
|
|
23
24
|
import { normalizeIncomingActivity } from './activityWireCompat'
|
|
24
25
|
import { UserTokenClient } from './oauth'
|
|
25
26
|
import { HeaderPropagation, HeaderPropagationCollection, HeaderPropagationDefinition } from './headerPropagation'
|
|
27
|
+
import { JwtPayload } from 'jsonwebtoken'
|
|
26
28
|
|
|
27
29
|
const logger = debug('agents:cloud-adapter')
|
|
28
30
|
|
|
@@ -30,27 +32,26 @@ const logger = debug('agents:cloud-adapter')
|
|
|
30
32
|
* Adapter for handling agent interactions with various channels through cloud-based services.
|
|
31
33
|
*
|
|
32
34
|
* @remarks
|
|
33
|
-
* CloudAdapter processes incoming HTTP requests from
|
|
35
|
+
* CloudAdapter processes incoming HTTP requests from Azure Bot Service channels,
|
|
34
36
|
* authenticates them, and generates outgoing responses. It manages the communication
|
|
35
37
|
* flow between agents and users across different channels, handling activities, attachments,
|
|
36
38
|
* and conversation continuations.
|
|
37
39
|
*/
|
|
38
40
|
export class CloudAdapter extends BaseAdapter {
|
|
39
41
|
/**
|
|
40
|
-
* Client for connecting to the Bot
|
|
42
|
+
* Client for connecting to the Azure Bot Service
|
|
41
43
|
*/
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
connectionManager: MsalConnectionManager
|
|
45
|
+
|
|
44
46
|
/**
|
|
45
47
|
* Creates an instance of CloudAdapter.
|
|
46
48
|
* @param authConfig - The authentication configuration for securing communications
|
|
47
|
-
* @param authProvider -
|
|
49
|
+
* @param authProvider - No longer used
|
|
48
50
|
*/
|
|
49
51
|
constructor (authConfig?: AuthConfiguration, authProvider?: AuthProvider, userTokenClient?: UserTokenClient) {
|
|
50
52
|
super()
|
|
51
|
-
|
|
52
|
-
this.
|
|
53
|
-
this.userTokenClient = userTokenClient ?? new UserTokenClient(this.authConfig.clientId)
|
|
53
|
+
authConfig = getAuthConfigWithDefaults(authConfig)
|
|
54
|
+
this.connectionManager = new MsalConnectionManager(undefined, undefined, authConfig)
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
/**
|
|
@@ -92,17 +93,84 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
92
93
|
protected async createConnectorClient (
|
|
93
94
|
serviceUrl: string,
|
|
94
95
|
scope: string,
|
|
96
|
+
audience: string,
|
|
95
97
|
headers?: HeaderPropagationCollection
|
|
96
98
|
): Promise<ConnectorClient> {
|
|
97
|
-
|
|
99
|
+
// get the correct token provider
|
|
100
|
+
const tokenProvider = this.connectionManager.getTokenProvider(audience, serviceUrl)
|
|
101
|
+
|
|
102
|
+
const token = await tokenProvider.getAccessToken(scope)
|
|
103
|
+
return ConnectorClient.createClientWithToken(
|
|
98
104
|
serviceUrl,
|
|
99
|
-
|
|
100
|
-
this.authProvider,
|
|
101
|
-
scope,
|
|
105
|
+
token,
|
|
102
106
|
headers
|
|
103
107
|
)
|
|
104
108
|
}
|
|
105
109
|
|
|
110
|
+
protected async createConnectorClientWithIdentity (
|
|
111
|
+
identity: JwtPayload,
|
|
112
|
+
activity: Activity,
|
|
113
|
+
scope: string,
|
|
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) {
|
|
123
|
+
// anonymous
|
|
124
|
+
return ConnectorClient.createClientWithToken(
|
|
125
|
+
activity.serviceUrl!,
|
|
126
|
+
null!,
|
|
127
|
+
headers
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
let connectorClient
|
|
132
|
+
const tokenProvider = this.connectionManager.getTokenProvider(audience!, activity.serviceUrl ?? '')
|
|
133
|
+
if (activity.isAgenticRequest()) {
|
|
134
|
+
logger.debug('Activity is from an agentic source, using special scope', activity.recipient)
|
|
135
|
+
|
|
136
|
+
if (activity.recipient?.role === RoleTypes.AgenticIdentity && activity.getAgenticInstanceId()) {
|
|
137
|
+
// get agentic instance token
|
|
138
|
+
const token = await tokenProvider.getAgenticInstanceToken(activity.getAgenticInstanceId() ?? '')
|
|
139
|
+
connectorClient = ConnectorClient.createClientWithToken(
|
|
140
|
+
activity.serviceUrl!,
|
|
141
|
+
token,
|
|
142
|
+
headers
|
|
143
|
+
)
|
|
144
|
+
} else if (activity.recipient?.role === RoleTypes.AgenticUser && activity.getAgenticInstanceId() && activity.getAgenticUser()) {
|
|
145
|
+
const scope = tokenProvider.connectionSettings?.scope ?? ApxProductionScope
|
|
146
|
+
const token = await tokenProvider.getAgenticUserToken(activity.getAgenticInstanceId() ?? '', activity.getAgenticUser() ?? '', [scope])
|
|
147
|
+
|
|
148
|
+
connectorClient = ConnectorClient.createClientWithToken(
|
|
149
|
+
activity.serviceUrl!,
|
|
150
|
+
token,
|
|
151
|
+
headers
|
|
152
|
+
)
|
|
153
|
+
} else {
|
|
154
|
+
throw new Error('Could not create connector client for agentic user')
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
const token = await tokenProvider.getAccessToken(scope)
|
|
158
|
+
connectorClient = ConnectorClient.createClientWithToken(
|
|
159
|
+
activity.serviceUrl!,
|
|
160
|
+
token,
|
|
161
|
+
headers
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return connectorClient
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
static createIdentity (appId: string) : JwtPayload {
|
|
169
|
+
return {
|
|
170
|
+
aud: appId
|
|
171
|
+
} as JwtPayload
|
|
172
|
+
}
|
|
173
|
+
|
|
106
174
|
/**
|
|
107
175
|
* Sets the connector client on the turn context.
|
|
108
176
|
*
|
|
@@ -110,24 +178,60 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
110
178
|
* @protected
|
|
111
179
|
*/
|
|
112
180
|
protected setConnectorClient (
|
|
113
|
-
context: TurnContext
|
|
181
|
+
context: TurnContext,
|
|
182
|
+
connectorClient?: ConnectorClient
|
|
183
|
+
) {
|
|
184
|
+
context.turnState.set(this.ConnectorClientKey, connectorClient)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Creates a user token client for a specific service URL and scope.
|
|
189
|
+
*
|
|
190
|
+
* @param serviceUrl - The URL of the service to connect to
|
|
191
|
+
* @param scope - The authentication scope to use
|
|
192
|
+
* @param headers - Optional headers to propagate in the request
|
|
193
|
+
* @returns A promise that resolves to a ConnectorClient instance
|
|
194
|
+
* @protected
|
|
195
|
+
*/
|
|
196
|
+
protected async createUserTokenClient (
|
|
197
|
+
tokenServiceEndpoint: string = 'https://api.botframework.com',
|
|
198
|
+
scope: string = 'https://api.botframework.com',
|
|
199
|
+
audience: string = 'https://api.botframework.com',
|
|
200
|
+
headers?: HeaderPropagationCollection
|
|
201
|
+
): Promise<UserTokenClient> {
|
|
202
|
+
// get the correct token provider
|
|
203
|
+
const tokenProvider = this.connectionManager.getTokenProvider(audience, tokenServiceEndpoint)
|
|
204
|
+
|
|
205
|
+
return UserTokenClient.createClientWithScope(
|
|
206
|
+
tokenServiceEndpoint,
|
|
207
|
+
tokenProvider,
|
|
208
|
+
scope,
|
|
209
|
+
headers
|
|
210
|
+
)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Sets the user token client on the turn context.
|
|
215
|
+
*
|
|
216
|
+
* @param context - The current turn context
|
|
217
|
+
* @protected
|
|
218
|
+
*/
|
|
219
|
+
protected setUserTokenClient (
|
|
220
|
+
context: TurnContext,
|
|
221
|
+
userTokenClient?: UserTokenClient
|
|
114
222
|
) {
|
|
115
|
-
context.turnState.set(
|
|
223
|
+
context.turnState.set(this.UserTokenClientKey, userTokenClient)
|
|
116
224
|
}
|
|
117
225
|
|
|
118
226
|
/**
|
|
227
|
+
* @deprecated This function will not be supported in future versions. Create TurnContext directly.
|
|
119
228
|
* Creates a TurnContext for the given activity and logic.
|
|
120
229
|
* @param activity - The activity to process.
|
|
121
230
|
* @param logic - The logic to execute.
|
|
122
231
|
* @returns The created TurnContext.
|
|
123
232
|
*/
|
|
124
|
-
createTurnContext (activity: Activity, logic: AgentHandler): TurnContext {
|
|
125
|
-
return new TurnContext(this, activity)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
async createTurnContextWithScope (activity: Activity, logic: AgentHandler, scope: string): Promise<TurnContext> {
|
|
129
|
-
this.connectorClient = await ConnectorClient.createClientWithAuth(activity.serviceUrl!, this.authConfig!, this.authProvider, scope)
|
|
130
|
-
return new TurnContext(this, activity)
|
|
233
|
+
createTurnContext (activity: Activity, logic: AgentHandler, identity?: JwtPayload): TurnContext {
|
|
234
|
+
return new TurnContext(this, activity, identity)
|
|
131
235
|
}
|
|
132
236
|
|
|
133
237
|
/**
|
|
@@ -165,12 +269,10 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
165
269
|
throw new Error('Invalid activity object')
|
|
166
270
|
}
|
|
167
271
|
|
|
168
|
-
this.connectorClient = await this.createConnectorClient(activity.serviceUrl, 'https://api.botframework.com')
|
|
169
|
-
|
|
170
272
|
if (activity.replyToId) {
|
|
171
|
-
response = await this.
|
|
273
|
+
response = await context.turnState.get(this.ConnectorClientKey).replyToActivity(activity.conversation.id, activity.replyToId, activity)
|
|
172
274
|
} else {
|
|
173
|
-
response = await this.
|
|
275
|
+
response = await context.turnState.get(this.ConnectorClientKey).sendToConversation(activity.conversation.id, activity)
|
|
174
276
|
}
|
|
175
277
|
}
|
|
176
278
|
|
|
@@ -184,18 +286,6 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
184
286
|
return responses
|
|
185
287
|
}
|
|
186
288
|
|
|
187
|
-
/**
|
|
188
|
-
* Replies to an activity.
|
|
189
|
-
* @param activity - The activity to reply to.
|
|
190
|
-
* @returns A promise representing the ResourceResponse for the sent activity.
|
|
191
|
-
*/
|
|
192
|
-
async replyToActivity (activity: Activity): Promise<ResourceResponse> {
|
|
193
|
-
if (!activity.serviceUrl || (activity.conversation == null) || !activity.conversation.id || !activity.id) {
|
|
194
|
-
throw new Error('Invalid activity object')
|
|
195
|
-
}
|
|
196
|
-
return await this.connectorClient.replyToActivity(activity.conversation.id, activity.id, activity)
|
|
197
|
-
}
|
|
198
|
-
|
|
199
289
|
/**
|
|
200
290
|
* Processes an incoming request and sends the response.
|
|
201
291
|
* @param request - The incoming request.
|
|
@@ -236,14 +326,18 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
236
326
|
}
|
|
237
327
|
|
|
238
328
|
logger.debug('Received activity: ', activity)
|
|
239
|
-
const context = this.createTurnContext(activity, logic)
|
|
240
|
-
const scope = request.user?.azp ?? request.user?.appid ?? 'https://api.botframework.com'
|
|
241
329
|
|
|
330
|
+
const context = new TurnContext(this, activity, request.user!)
|
|
331
|
+
const scope = request.user?.azp ?? request.user?.appid ?? 'https://api.botframework.com'
|
|
242
332
|
// if Delivery Mode == ExpectReplies, we don't need a connector client.
|
|
243
333
|
if (this.resolveIfConnectorClientIsNeeded(activity)) {
|
|
244
|
-
|
|
245
|
-
this.
|
|
246
|
-
|
|
334
|
+
const connectorClient = await this.createConnectorClientWithIdentity(request.user!, activity, scope, headers)
|
|
335
|
+
this.setConnectorClient(context, connectorClient)
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (!activity.isAgenticRequest()) {
|
|
339
|
+
const userTokenClient = await this.createUserTokenClient()
|
|
340
|
+
this.setUserTokenClient(context, userTokenClient)
|
|
247
341
|
}
|
|
248
342
|
|
|
249
343
|
if (
|
|
@@ -259,7 +353,6 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
259
353
|
|
|
260
354
|
await this.runMiddleware(context, logic)
|
|
261
355
|
const invokeResponse = this.processTurnResults(context)
|
|
262
|
-
|
|
263
356
|
return end(invokeResponse?.status ?? StatusCodes.OK, invokeResponse?.body)
|
|
264
357
|
}
|
|
265
358
|
|
|
@@ -301,7 +394,7 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
301
394
|
throw new Error('Invalid activity object')
|
|
302
395
|
}
|
|
303
396
|
|
|
304
|
-
const response = await this.
|
|
397
|
+
const response = await context.turnState.get(this.ConnectorClientKey).updateActivity(
|
|
305
398
|
activity.conversation.id,
|
|
306
399
|
activity.id,
|
|
307
400
|
activity
|
|
@@ -325,7 +418,7 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
325
418
|
throw new Error('Invalid conversation reference object')
|
|
326
419
|
}
|
|
327
420
|
|
|
328
|
-
await this.
|
|
421
|
+
await context.turnState.get(this.ConnectorClientKey).deleteActivity(reference.conversation.id, reference.activityId)
|
|
329
422
|
}
|
|
330
423
|
|
|
331
424
|
/**
|
|
@@ -334,25 +427,39 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
334
427
|
* @param logic - The logic to execute.
|
|
335
428
|
* @returns A promise representing the completion of the continue operation.
|
|
336
429
|
*/
|
|
337
|
-
async continueConversation (
|
|
430
|
+
async continueConversation (
|
|
431
|
+
botAppIdOrIdentity: string | JwtPayload,
|
|
432
|
+
reference: ConversationReference,
|
|
433
|
+
logic: (revocableContext: TurnContext) => Promise<void>,
|
|
434
|
+
isResponse: Boolean = false): Promise<void> {
|
|
338
435
|
if (!reference || !reference.serviceUrl || (reference.conversation == null) || !reference.conversation.id) {
|
|
339
436
|
throw new Error('Invalid conversation reference object')
|
|
340
437
|
}
|
|
341
438
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
439
|
+
const botAppId = typeof botAppIdOrIdentity === 'string' ? botAppIdOrIdentity : botAppIdOrIdentity.aud as string
|
|
440
|
+
|
|
441
|
+
const identity =
|
|
442
|
+
typeof botAppIdOrIdentity !== 'string'
|
|
443
|
+
? botAppIdOrIdentity
|
|
444
|
+
: CloudAdapter.createIdentity(botAppId)
|
|
445
|
+
|
|
446
|
+
const continuationActivity = Activity.getContinuationActivity(reference)
|
|
447
|
+
const context = new TurnContext(this, Activity.getContinuationActivity(reference), identity)
|
|
448
|
+
const scope = identity.azp ?? identity.appid ?? 'https://api.botframework.com'
|
|
449
|
+
const connectorClient = await this.createConnectorClientWithIdentity(identity, continuationActivity, scope)
|
|
450
|
+
this.setConnectorClient(context, connectorClient)
|
|
451
|
+
|
|
452
|
+
const userTokenClient = await this.createUserTokenClient()
|
|
453
|
+
this.setUserTokenClient(context, userTokenClient)
|
|
454
|
+
|
|
348
455
|
await this.runMiddleware(context, logic)
|
|
349
456
|
}
|
|
350
457
|
|
|
351
458
|
/**
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
459
|
+
* Processes the turn results and returns an InvokeResponse if applicable.
|
|
460
|
+
* @param context - The TurnContext for the current turn.
|
|
461
|
+
* @returns The InvokeResponse if applicable, otherwise undefined.
|
|
462
|
+
*/
|
|
356
463
|
protected processTurnResults (context: TurnContext): InvokeResponse | undefined {
|
|
357
464
|
logger.info('<--Sending back turn results')
|
|
358
465
|
// Handle ExpectedReplies scenarios where all activities have been buffered and sent back at once in an invoke response.
|
|
@@ -437,7 +544,8 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
437
544
|
if (!conversationParameters) throw new TypeError('`conversationParameters` must be defined')
|
|
438
545
|
if (!logic) throw new TypeError('`logic` must be defined')
|
|
439
546
|
|
|
440
|
-
const restClient = await this.createConnectorClient(serviceUrl, audience)
|
|
547
|
+
const restClient = await this.createConnectorClient(serviceUrl, audience, audience)
|
|
548
|
+
const userTokenClient = await this.createUserTokenClient()
|
|
441
549
|
const createConversationResult = await restClient.createConversation(conversationParameters)
|
|
442
550
|
const createActivity = this.createCreateActivity(
|
|
443
551
|
createConversationResult.id,
|
|
@@ -445,17 +553,24 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
445
553
|
serviceUrl,
|
|
446
554
|
conversationParameters
|
|
447
555
|
)
|
|
448
|
-
const context = new TurnContext(this, createActivity)
|
|
556
|
+
const context = new TurnContext(this, createActivity, CloudAdapter.createIdentity(agentAppId))
|
|
557
|
+
this.setConnectorClient(context, restClient)
|
|
558
|
+
this.setUserTokenClient(context, userTokenClient)
|
|
449
559
|
await this.runMiddleware(context, logic)
|
|
450
560
|
}
|
|
451
561
|
|
|
452
562
|
/**
|
|
563
|
+
* @deprecated This function will not be supported in future versions. Use TurnContext.turnState.get<ConnectorClient>(CloudAdapter.ConnectorClientKey).
|
|
453
564
|
* Uploads an attachment.
|
|
454
565
|
* @param conversationId - The conversation ID.
|
|
455
566
|
* @param attachmentData - The attachment data.
|
|
456
567
|
* @returns A promise representing the ResourceResponse for the uploaded attachment.
|
|
457
568
|
*/
|
|
458
|
-
async uploadAttachment (conversationId: string, attachmentData: AttachmentData): Promise<ResourceResponse> {
|
|
569
|
+
async uploadAttachment (context: TurnContext, conversationId: string, attachmentData: AttachmentData): Promise<ResourceResponse> {
|
|
570
|
+
if (context === undefined) {
|
|
571
|
+
throw new Error('context is required')
|
|
572
|
+
}
|
|
573
|
+
|
|
459
574
|
if (conversationId === undefined) {
|
|
460
575
|
throw new Error('conversationId is required')
|
|
461
576
|
}
|
|
@@ -464,29 +579,39 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
464
579
|
throw new Error('attachmentData is required')
|
|
465
580
|
}
|
|
466
581
|
|
|
467
|
-
return await this.
|
|
582
|
+
return await context.turnState.get<ConnectorClient>(this.ConnectorClientKey).uploadAttachment(conversationId, attachmentData)
|
|
468
583
|
}
|
|
469
584
|
|
|
470
585
|
/**
|
|
586
|
+
* @deprecated This function will not be supported in future versions. Use TurnContext.turnState.get<ConnectorClient>(CloudAdapter.ConnectorClientKey).
|
|
471
587
|
* Gets attachment information.
|
|
472
588
|
* @param attachmentId - The attachment ID.
|
|
473
589
|
* @returns A promise representing the AttachmentInfo for the requested attachment.
|
|
474
590
|
*/
|
|
475
|
-
async getAttachmentInfo (attachmentId: string): Promise<AttachmentInfo> {
|
|
591
|
+
async getAttachmentInfo (context: TurnContext, attachmentId: string): Promise<AttachmentInfo> {
|
|
592
|
+
if (context === undefined) {
|
|
593
|
+
throw new Error('context is required')
|
|
594
|
+
}
|
|
595
|
+
|
|
476
596
|
if (attachmentId === undefined) {
|
|
477
597
|
throw new Error('attachmentId is required')
|
|
478
598
|
}
|
|
479
599
|
|
|
480
|
-
return await this.
|
|
600
|
+
return await context.turnState.get<ConnectorClient>(this.ConnectorClientKey).getAttachmentInfo(attachmentId)
|
|
481
601
|
}
|
|
482
602
|
|
|
483
603
|
/**
|
|
604
|
+
* @deprecated This function will not be supported in future versions. Use TurnContext.turnState.get<ConnectorClient>(CloudAdapter.ConnectorClientKey).
|
|
484
605
|
* Gets an attachment.
|
|
485
606
|
* @param attachmentId - The attachment ID.
|
|
486
607
|
* @param viewId - The view ID.
|
|
487
608
|
* @returns A promise representing the NodeJS.ReadableStream for the requested attachment.
|
|
488
609
|
*/
|
|
489
|
-
async getAttachment (attachmentId: string, viewId: string): Promise<NodeJS.ReadableStream> {
|
|
610
|
+
async getAttachment (context: TurnContext, attachmentId: string, viewId: string): Promise<NodeJS.ReadableStream> {
|
|
611
|
+
if (context === undefined) {
|
|
612
|
+
throw new Error('context is required')
|
|
613
|
+
}
|
|
614
|
+
|
|
490
615
|
if (attachmentId === undefined) {
|
|
491
616
|
throw new Error('attachmentId is required')
|
|
492
617
|
}
|
|
@@ -495,6 +620,6 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
495
620
|
throw new Error('viewId is required')
|
|
496
621
|
}
|
|
497
622
|
|
|
498
|
-
return await this.
|
|
623
|
+
return await context.turnState.get<ConnectorClient>(this.ConnectorClientKey).getAttachment(attachmentId, viewId)
|
|
499
624
|
}
|
|
500
625
|
}
|
|
@@ -3,7 +3,7 @@ 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 } from '@microsoft/agents-activity'
|
|
6
|
+
import { Activity, ChannelAccount, ConversationParameters, RoleTypes, Channels } from '@microsoft/agents-activity'
|
|
7
7
|
import { ConversationsResult } from './conversationsResult'
|
|
8
8
|
import { ConversationResourceResponse } from './conversationResourceResponse'
|
|
9
9
|
import { ResourceResponse } from './resourceResponse'
|
|
@@ -91,9 +91,28 @@ export class ConnectorClient {
|
|
|
91
91
|
scope: string,
|
|
92
92
|
headers?: HeaderPropagationCollection
|
|
93
93
|
): Promise<ConnectorClient> {
|
|
94
|
+
const token = await authProvider.getAccessToken(authConfig, scope)
|
|
95
|
+
return this.createClientWithToken(baseURL, token, headers)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Creates a new instance of ConnectorClient with token.
|
|
100
|
+
* @param baseURL - The base URL for the API.
|
|
101
|
+
* @param token - The authentication token.
|
|
102
|
+
* @param headers - Optional headers to propagate in the request.
|
|
103
|
+
* @returns A new instance of ConnectorClient.
|
|
104
|
+
*/
|
|
105
|
+
static createClientWithToken (
|
|
106
|
+
baseURL: string,
|
|
107
|
+
token: string,
|
|
108
|
+
headers?: HeaderPropagationCollection
|
|
109
|
+
): ConnectorClient {
|
|
94
110
|
const headerPropagation = headers ?? new HeaderPropagation({ 'User-Agent': '' })
|
|
95
111
|
headerPropagation.concat({ 'User-Agent': getProductInfo() })
|
|
96
|
-
headerPropagation.override({
|
|
112
|
+
headerPropagation.override({
|
|
113
|
+
Accept: 'application/json',
|
|
114
|
+
'Content-Type': 'application/json', // Required by transformRequest
|
|
115
|
+
})
|
|
97
116
|
|
|
98
117
|
const axiosInstance = axios.create({
|
|
99
118
|
baseURL,
|
|
@@ -104,10 +123,10 @@ export class ConnectorClient {
|
|
|
104
123
|
}]
|
|
105
124
|
})
|
|
106
125
|
|
|
107
|
-
|
|
108
|
-
if (token.length > 1) {
|
|
126
|
+
if (token && token.length > 1) {
|
|
109
127
|
axiosInstance.defaults.headers.common.Authorization = `Bearer ${token}`
|
|
110
128
|
}
|
|
129
|
+
|
|
111
130
|
return new ConnectorClient(axiosInstance)
|
|
112
131
|
}
|
|
113
132
|
|
|
@@ -147,14 +166,14 @@ export class ConnectorClient {
|
|
|
147
166
|
* @returns The conversation resource response.
|
|
148
167
|
*/
|
|
149
168
|
public async createConversation (body: ConversationParameters): Promise<ConversationResourceResponse> {
|
|
150
|
-
|
|
169
|
+
const payload = normalizeOutgoingActivity(body)
|
|
151
170
|
const config: AxiosRequestConfig = {
|
|
152
171
|
method: 'post',
|
|
153
172
|
url: '/v3/conversations',
|
|
154
173
|
headers: {
|
|
155
174
|
'Content-Type': 'application/json'
|
|
156
175
|
},
|
|
157
|
-
data:
|
|
176
|
+
data: payload
|
|
158
177
|
}
|
|
159
178
|
const response: AxiosResponse = await this._axiosInstance(config)
|
|
160
179
|
return response.data
|
|
@@ -176,19 +195,36 @@ export class ConnectorClient {
|
|
|
176
195
|
if (!conversationId || !activityId) {
|
|
177
196
|
throw new Error('conversationId and activityId are required')
|
|
178
197
|
}
|
|
198
|
+
|
|
199
|
+
const trimmedConversationId: string = this.conditionallyTruncateConversationId(conversationId, body)
|
|
200
|
+
|
|
179
201
|
const config: AxiosRequestConfig = {
|
|
180
202
|
method: 'post',
|
|
181
|
-
url: `v3/conversations/${
|
|
203
|
+
url: `v3/conversations/${trimmedConversationId}/activities/${encodeURIComponent(activityId)}`,
|
|
182
204
|
headers: {
|
|
183
205
|
'Content-Type': 'application/json'
|
|
184
206
|
},
|
|
185
|
-
data: body
|
|
207
|
+
data: normalizeOutgoingActivity(body)
|
|
186
208
|
}
|
|
187
209
|
const response = await this._axiosInstance(config)
|
|
188
210
|
logger.info('Reply to conversation/activity: ', response.data.id!, activityId)
|
|
189
211
|
return response.data
|
|
190
212
|
}
|
|
191
213
|
|
|
214
|
+
private conditionallyTruncateConversationId (conversationId: string, activity: Activity): string {
|
|
215
|
+
if (
|
|
216
|
+
(activity.channelIdChannel === Channels.Msteams || activity.channelIdChannel === Channels.Agents) &&
|
|
217
|
+
(activity.from?.role === RoleTypes.AgenticIdentity || activity.from?.role === RoleTypes.AgenticUser)) {
|
|
218
|
+
let maxLength = 150
|
|
219
|
+
if (process.env.MAX_APX_CONVERSATION_ID_LENGTH && !isNaN(parseInt(process.env.MAX_APX_CONVERSATION_ID_LENGTH, 10))) {
|
|
220
|
+
maxLength = parseInt(process.env.MAX_APX_CONVERSATION_ID_LENGTH, 10)
|
|
221
|
+
}
|
|
222
|
+
return conversationId.length > maxLength ? conversationId.substring(0, maxLength) : conversationId
|
|
223
|
+
} else {
|
|
224
|
+
return conversationId
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
192
228
|
/**
|
|
193
229
|
* Sends an activity to a conversation.
|
|
194
230
|
* @param conversationId - The ID of the conversation.
|
|
@@ -203,13 +239,16 @@ export class ConnectorClient {
|
|
|
203
239
|
if (!conversationId) {
|
|
204
240
|
throw new Error('conversationId is required')
|
|
205
241
|
}
|
|
242
|
+
|
|
243
|
+
const trimmedConversationId: string = this.conditionallyTruncateConversationId(conversationId, body)
|
|
244
|
+
|
|
206
245
|
const config: AxiosRequestConfig = {
|
|
207
246
|
method: 'post',
|
|
208
|
-
url: `v3/conversations/${
|
|
247
|
+
url: `v3/conversations/${trimmedConversationId}/activities`,
|
|
209
248
|
headers: {
|
|
210
249
|
'Content-Type': 'application/json'
|
|
211
250
|
},
|
|
212
|
-
data: body
|
|
251
|
+
data: normalizeOutgoingActivity(body)
|
|
213
252
|
}
|
|
214
253
|
const response = await this._axiosInstance(config)
|
|
215
254
|
return response.data
|
package/src/index.ts
CHANGED
|
@@ -19,7 +19,6 @@ export * from './activityHandler'
|
|
|
19
19
|
export * from './baseAdapter'
|
|
20
20
|
export * from './cloudAdapter'
|
|
21
21
|
export * from './middlewareSet'
|
|
22
|
-
export * from './claimsIdentity'
|
|
23
22
|
export * from './messageFactory'
|
|
24
23
|
export * from './statusCodes'
|
|
25
24
|
export * from './turnContext'
|
package/src/oauth/index.ts
CHANGED