@microsoft/agents-hosting 1.1.0-alpha.5 → 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.
- package/dist/package.json +10 -6
- package/dist/src/activityWireCompat.d.ts +1 -1
- package/dist/src/activityWireCompat.js +11 -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 +28 -13
- 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 +93 -0
- package/dist/src/app/auth/handlers/agenticAuthorization.js +134 -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 +209 -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 +41 -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 +64 -0
- package/dist/src/auth/msalConnectionManager.js +148 -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 +128 -60
- package/dist/src/cloudAdapter.js.map +1 -1
- package/dist/src/connector-client/connectorClient.d.ts +15 -0
- package/dist/src/connector-client/connectorClient.js +49 -15
- 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/customUserTokenAPI.d.ts +1 -0
- package/dist/src/oauth/customUserTokenAPI.js +11 -0
- package/dist/src/oauth/customUserTokenAPI.js.map +1 -0
- 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 +60 -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 +12 -4
- package/src/agent-client/agentClient.ts +9 -3
- package/src/agent-client/agentResponseHandler.ts +5 -2
- package/src/app/agentApplication.ts +98 -77
- 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 +182 -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 +245 -52
- package/src/auth/authConstants.ts +11 -0
- package/src/auth/authProvider.ts +31 -0
- package/src/auth/connections.ts +47 -0
- package/src/auth/index.ts +2 -0
- package/src/auth/jwt-middleware.ts +38 -21
- package/src/auth/msalConnectionManager.ts +175 -0
- package/src/auth/msalTokenProvider.ts +209 -9
- package/src/baseAdapter.ts +10 -29
- package/src/cloudAdapter.ts +189 -71
- package/src/connector-client/connectorClient.ts +59 -15
- package/src/index.ts +0 -1
- package/src/oauth/customUserTokenAPI.ts +5 -0
- package/src/oauth/index.ts +0 -1
- package/src/oauth/userTokenClient.ts +74 -22
- 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,34 +24,34 @@ 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'
|
|
26
|
-
|
|
27
|
+
import { JwtPayload } from 'jsonwebtoken'
|
|
28
|
+
import { getTokenServiceEndpoint } from './oauth/customUserTokenAPI'
|
|
27
29
|
const logger = debug('agents:cloud-adapter')
|
|
28
30
|
|
|
29
31
|
/**
|
|
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,77 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
92
93
|
protected async createConnectorClient (
|
|
93
94
|
serviceUrl: string,
|
|
94
95
|
scope: string,
|
|
96
|
+
identity: JwtPayload,
|
|
95
97
|
headers?: HeaderPropagationCollection
|
|
96
98
|
): Promise<ConnectorClient> {
|
|
97
|
-
|
|
99
|
+
// get the correct token provider
|
|
100
|
+
const tokenProvider = this.connectionManager.getTokenProvider(identity, 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
|
+
if (!identity?.aud) {
|
|
116
|
+
// anonymous
|
|
117
|
+
return ConnectorClient.createClientWithToken(
|
|
118
|
+
activity.serviceUrl!,
|
|
119
|
+
null!,
|
|
120
|
+
headers
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let connectorClient
|
|
125
|
+
const tokenProvider = this.connectionManager.getTokenProviderFromActivity(identity, activity)
|
|
126
|
+
if (activity.isAgenticRequest()) {
|
|
127
|
+
logger.debug('Activity is from an agentic source, using special scope', activity.recipient)
|
|
128
|
+
|
|
129
|
+
if (activity.recipient?.role === RoleTypes.AgenticIdentity && activity.getAgenticInstanceId()) {
|
|
130
|
+
// get agentic instance token
|
|
131
|
+
const token = await tokenProvider.getAgenticInstanceToken(activity.getAgenticInstanceId() ?? '')
|
|
132
|
+
connectorClient = ConnectorClient.createClientWithToken(
|
|
133
|
+
activity.serviceUrl!,
|
|
134
|
+
token,
|
|
135
|
+
headers
|
|
136
|
+
)
|
|
137
|
+
} else if (activity.recipient?.role === RoleTypes.AgenticUser && activity.getAgenticInstanceId() && activity.getAgenticUser()) {
|
|
138
|
+
const scope = tokenProvider.connectionSettings?.scope ?? ApxProductionScope
|
|
139
|
+
const token = await tokenProvider.getAgenticUserToken(activity.getAgenticInstanceId() ?? '', activity.getAgenticUser() ?? '', [scope])
|
|
140
|
+
|
|
141
|
+
connectorClient = ConnectorClient.createClientWithToken(
|
|
142
|
+
activity.serviceUrl!,
|
|
143
|
+
token,
|
|
144
|
+
headers
|
|
145
|
+
)
|
|
146
|
+
} else {
|
|
147
|
+
throw new Error('Could not create connector client for agentic user')
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
const token = await tokenProvider.getAccessToken(scope)
|
|
151
|
+
connectorClient = ConnectorClient.createClientWithToken(
|
|
152
|
+
activity.serviceUrl!,
|
|
153
|
+
token,
|
|
154
|
+
headers
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return connectorClient
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
static createIdentity (appId: string) : JwtPayload {
|
|
162
|
+
return {
|
|
163
|
+
aud: appId
|
|
164
|
+
} as JwtPayload
|
|
165
|
+
}
|
|
166
|
+
|
|
106
167
|
/**
|
|
107
168
|
* Sets the connector client on the turn context.
|
|
108
169
|
*
|
|
@@ -110,24 +171,61 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
110
171
|
* @protected
|
|
111
172
|
*/
|
|
112
173
|
protected setConnectorClient (
|
|
113
|
-
context: TurnContext
|
|
174
|
+
context: TurnContext,
|
|
175
|
+
connectorClient?: ConnectorClient
|
|
114
176
|
) {
|
|
115
|
-
context.turnState.set(
|
|
177
|
+
context.turnState.set(this.ConnectorClientKey, connectorClient)
|
|
116
178
|
}
|
|
117
179
|
|
|
118
180
|
/**
|
|
181
|
+
* Creates a user token client for a specific service URL and scope.
|
|
182
|
+
*
|
|
183
|
+
* @param serviceUrl - The URL of the service to connect to
|
|
184
|
+
* @param scope - The authentication scope to use
|
|
185
|
+
* @param headers - Optional headers to propagate in the request
|
|
186
|
+
* @returns A promise that resolves to a ConnectorClient instance
|
|
187
|
+
* @protected
|
|
188
|
+
*/
|
|
189
|
+
protected async createUserTokenClient (
|
|
190
|
+
identity: JwtPayload,
|
|
191
|
+
tokenServiceEndpoint: string = getTokenServiceEndpoint(),
|
|
192
|
+
scope: string = 'https://api.botframework.com',
|
|
193
|
+
audience: string = 'https://api.botframework.com',
|
|
194
|
+
headers?: HeaderPropagationCollection
|
|
195
|
+
): Promise<UserTokenClient> {
|
|
196
|
+
// get the correct token provider
|
|
197
|
+
const tokenProvider = this.connectionManager.getTokenProvider(identity, tokenServiceEndpoint)
|
|
198
|
+
|
|
199
|
+
return UserTokenClient.createClientWithScope(
|
|
200
|
+
tokenServiceEndpoint,
|
|
201
|
+
tokenProvider,
|
|
202
|
+
scope,
|
|
203
|
+
headers
|
|
204
|
+
)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Sets the user token client on the turn context.
|
|
209
|
+
*
|
|
210
|
+
* @param context - The current turn context
|
|
211
|
+
* @protected
|
|
212
|
+
*/
|
|
213
|
+
protected setUserTokenClient (
|
|
214
|
+
context: TurnContext,
|
|
215
|
+
userTokenClient?: UserTokenClient
|
|
216
|
+
) {
|
|
217
|
+
context.turnState.set(this.UserTokenClientKey, userTokenClient)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* @deprecated This function will not be supported in future versions. Create TurnContext directly.
|
|
119
222
|
* Creates a TurnContext for the given activity and logic.
|
|
120
223
|
* @param activity - The activity to process.
|
|
121
224
|
* @param logic - The logic to execute.
|
|
122
225
|
* @returns The created TurnContext.
|
|
123
226
|
*/
|
|
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)
|
|
227
|
+
createTurnContext (activity: Activity, logic: AgentHandler, identity?: JwtPayload): TurnContext {
|
|
228
|
+
return new TurnContext(this, activity, identity)
|
|
131
229
|
}
|
|
132
230
|
|
|
133
231
|
/**
|
|
@@ -154,9 +252,7 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
154
252
|
delete activity.id
|
|
155
253
|
let response: ResourceResponse = { id: '' }
|
|
156
254
|
|
|
157
|
-
if (activity.type === ActivityTypes.
|
|
158
|
-
await setTimeout(() => { }, typeof activity.value === 'number' ? activity.value : 1000)
|
|
159
|
-
} else if (activity.type === ActivityTypes.InvokeResponse) {
|
|
255
|
+
if (activity.type === ActivityTypes.InvokeResponse) {
|
|
160
256
|
context.turnState.set(INVOKE_RESPONSE_KEY, activity)
|
|
161
257
|
} else if (activity.type === ActivityTypes.Trace && activity.channelId !== Channels.Emulator) {
|
|
162
258
|
// no-op
|
|
@@ -165,12 +261,10 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
165
261
|
throw new Error('Invalid activity object')
|
|
166
262
|
}
|
|
167
263
|
|
|
168
|
-
this.connectorClient = await this.createConnectorClient(activity.serviceUrl, 'https://api.botframework.com')
|
|
169
|
-
|
|
170
264
|
if (activity.replyToId) {
|
|
171
|
-
response = await this.
|
|
265
|
+
response = await context.turnState.get(this.ConnectorClientKey).replyToActivity(activity.conversation.id, activity.replyToId, activity)
|
|
172
266
|
} else {
|
|
173
|
-
response = await this.
|
|
267
|
+
response = await context.turnState.get(this.ConnectorClientKey).sendToConversation(activity.conversation.id, activity)
|
|
174
268
|
}
|
|
175
269
|
}
|
|
176
270
|
|
|
@@ -184,18 +278,6 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
184
278
|
return responses
|
|
185
279
|
}
|
|
186
280
|
|
|
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
281
|
/**
|
|
200
282
|
* Processes an incoming request and sends the response.
|
|
201
283
|
* @param request - The incoming request.
|
|
@@ -236,14 +318,18 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
236
318
|
}
|
|
237
319
|
|
|
238
320
|
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
321
|
|
|
322
|
+
const context = new TurnContext(this, activity, request.user!)
|
|
323
|
+
const scope = request.user?.azp ?? request.user?.appid ?? 'https://api.botframework.com'
|
|
242
324
|
// if Delivery Mode == ExpectReplies, we don't need a connector client.
|
|
243
325
|
if (this.resolveIfConnectorClientIsNeeded(activity)) {
|
|
244
|
-
|
|
245
|
-
this.
|
|
246
|
-
|
|
326
|
+
const connectorClient = await this.createConnectorClientWithIdentity(request.user!, activity, scope, headers)
|
|
327
|
+
this.setConnectorClient(context, connectorClient)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (!activity.isAgenticRequest()) {
|
|
331
|
+
const userTokenClient = await this.createUserTokenClient(request.user!)
|
|
332
|
+
this.setUserTokenClient(context, userTokenClient)
|
|
247
333
|
}
|
|
248
334
|
|
|
249
335
|
if (
|
|
@@ -259,7 +345,6 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
259
345
|
|
|
260
346
|
await this.runMiddleware(context, logic)
|
|
261
347
|
const invokeResponse = this.processTurnResults(context)
|
|
262
|
-
|
|
263
348
|
return end(invokeResponse?.status ?? StatusCodes.OK, invokeResponse?.body)
|
|
264
349
|
}
|
|
265
350
|
|
|
@@ -301,7 +386,7 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
301
386
|
throw new Error('Invalid activity object')
|
|
302
387
|
}
|
|
303
388
|
|
|
304
|
-
const response = await this.
|
|
389
|
+
const response = await context.turnState.get(this.ConnectorClientKey).updateActivity(
|
|
305
390
|
activity.conversation.id,
|
|
306
391
|
activity.id,
|
|
307
392
|
activity
|
|
@@ -325,7 +410,7 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
325
410
|
throw new Error('Invalid conversation reference object')
|
|
326
411
|
}
|
|
327
412
|
|
|
328
|
-
await this.
|
|
413
|
+
await context.turnState.get(this.ConnectorClientKey).deleteActivity(reference.conversation.id, reference.activityId)
|
|
329
414
|
}
|
|
330
415
|
|
|
331
416
|
/**
|
|
@@ -334,25 +419,39 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
334
419
|
* @param logic - The logic to execute.
|
|
335
420
|
* @returns A promise representing the completion of the continue operation.
|
|
336
421
|
*/
|
|
337
|
-
async continueConversation (
|
|
422
|
+
async continueConversation (
|
|
423
|
+
botAppIdOrIdentity: string | JwtPayload,
|
|
424
|
+
reference: ConversationReference,
|
|
425
|
+
logic: (revocableContext: TurnContext) => Promise<void>,
|
|
426
|
+
isResponse: Boolean = false): Promise<void> {
|
|
338
427
|
if (!reference || !reference.serviceUrl || (reference.conversation == null) || !reference.conversation.id) {
|
|
339
428
|
throw new Error('Invalid conversation reference object')
|
|
340
429
|
}
|
|
341
430
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
431
|
+
const botAppId = typeof botAppIdOrIdentity === 'string' ? botAppIdOrIdentity : botAppIdOrIdentity.aud as string
|
|
432
|
+
|
|
433
|
+
const identity =
|
|
434
|
+
typeof botAppIdOrIdentity !== 'string'
|
|
435
|
+
? botAppIdOrIdentity
|
|
436
|
+
: CloudAdapter.createIdentity(botAppId)
|
|
437
|
+
|
|
438
|
+
const continuationActivity = Activity.getContinuationActivity(reference)
|
|
439
|
+
const context = new TurnContext(this, Activity.getContinuationActivity(reference), identity)
|
|
440
|
+
const scope = identity.azp ?? identity.appid ?? 'https://api.botframework.com'
|
|
441
|
+
const connectorClient = await this.createConnectorClientWithIdentity(identity, continuationActivity, scope)
|
|
442
|
+
this.setConnectorClient(context, connectorClient)
|
|
443
|
+
|
|
444
|
+
const userTokenClient = await this.createUserTokenClient(identity)
|
|
445
|
+
this.setUserTokenClient(context, userTokenClient)
|
|
446
|
+
|
|
348
447
|
await this.runMiddleware(context, logic)
|
|
349
448
|
}
|
|
350
449
|
|
|
351
450
|
/**
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
451
|
+
* Processes the turn results and returns an InvokeResponse if applicable.
|
|
452
|
+
* @param context - The TurnContext for the current turn.
|
|
453
|
+
* @returns The InvokeResponse if applicable, otherwise undefined.
|
|
454
|
+
*/
|
|
356
455
|
protected processTurnResults (context: TurnContext): InvokeResponse | undefined {
|
|
357
456
|
logger.info('<--Sending back turn results')
|
|
358
457
|
// Handle ExpectedReplies scenarios where all activities have been buffered and sent back at once in an invoke response.
|
|
@@ -437,7 +536,9 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
437
536
|
if (!conversationParameters) throw new TypeError('`conversationParameters` must be defined')
|
|
438
537
|
if (!logic) throw new TypeError('`logic` must be defined')
|
|
439
538
|
|
|
440
|
-
const
|
|
539
|
+
const identity = CloudAdapter.createIdentity(audience)
|
|
540
|
+
const restClient = await this.createConnectorClient(serviceUrl, audience, identity)
|
|
541
|
+
const userTokenClient = await this.createUserTokenClient(identity)
|
|
441
542
|
const createConversationResult = await restClient.createConversation(conversationParameters)
|
|
442
543
|
const createActivity = this.createCreateActivity(
|
|
443
544
|
createConversationResult.id,
|
|
@@ -445,17 +546,24 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
445
546
|
serviceUrl,
|
|
446
547
|
conversationParameters
|
|
447
548
|
)
|
|
448
|
-
const context = new TurnContext(this, createActivity)
|
|
549
|
+
const context = new TurnContext(this, createActivity, CloudAdapter.createIdentity(agentAppId))
|
|
550
|
+
this.setConnectorClient(context, restClient)
|
|
551
|
+
this.setUserTokenClient(context, userTokenClient)
|
|
449
552
|
await this.runMiddleware(context, logic)
|
|
450
553
|
}
|
|
451
554
|
|
|
452
555
|
/**
|
|
556
|
+
* @deprecated This function will not be supported in future versions. Use TurnContext.turnState.get<ConnectorClient>(CloudAdapter.ConnectorClientKey).
|
|
453
557
|
* Uploads an attachment.
|
|
454
558
|
* @param conversationId - The conversation ID.
|
|
455
559
|
* @param attachmentData - The attachment data.
|
|
456
560
|
* @returns A promise representing the ResourceResponse for the uploaded attachment.
|
|
457
561
|
*/
|
|
458
|
-
async uploadAttachment (conversationId: string, attachmentData: AttachmentData): Promise<ResourceResponse> {
|
|
562
|
+
async uploadAttachment (context: TurnContext, conversationId: string, attachmentData: AttachmentData): Promise<ResourceResponse> {
|
|
563
|
+
if (context === undefined) {
|
|
564
|
+
throw new Error('context is required')
|
|
565
|
+
}
|
|
566
|
+
|
|
459
567
|
if (conversationId === undefined) {
|
|
460
568
|
throw new Error('conversationId is required')
|
|
461
569
|
}
|
|
@@ -464,29 +572,39 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
464
572
|
throw new Error('attachmentData is required')
|
|
465
573
|
}
|
|
466
574
|
|
|
467
|
-
return await this.
|
|
575
|
+
return await context.turnState.get<ConnectorClient>(this.ConnectorClientKey).uploadAttachment(conversationId, attachmentData)
|
|
468
576
|
}
|
|
469
577
|
|
|
470
578
|
/**
|
|
579
|
+
* @deprecated This function will not be supported in future versions. Use TurnContext.turnState.get<ConnectorClient>(CloudAdapter.ConnectorClientKey).
|
|
471
580
|
* Gets attachment information.
|
|
472
581
|
* @param attachmentId - The attachment ID.
|
|
473
582
|
* @returns A promise representing the AttachmentInfo for the requested attachment.
|
|
474
583
|
*/
|
|
475
|
-
async getAttachmentInfo (attachmentId: string): Promise<AttachmentInfo> {
|
|
584
|
+
async getAttachmentInfo (context: TurnContext, attachmentId: string): Promise<AttachmentInfo> {
|
|
585
|
+
if (context === undefined) {
|
|
586
|
+
throw new Error('context is required')
|
|
587
|
+
}
|
|
588
|
+
|
|
476
589
|
if (attachmentId === undefined) {
|
|
477
590
|
throw new Error('attachmentId is required')
|
|
478
591
|
}
|
|
479
592
|
|
|
480
|
-
return await this.
|
|
593
|
+
return await context.turnState.get<ConnectorClient>(this.ConnectorClientKey).getAttachmentInfo(attachmentId)
|
|
481
594
|
}
|
|
482
595
|
|
|
483
596
|
/**
|
|
597
|
+
* @deprecated This function will not be supported in future versions. Use TurnContext.turnState.get<ConnectorClient>(CloudAdapter.ConnectorClientKey).
|
|
484
598
|
* Gets an attachment.
|
|
485
599
|
* @param attachmentId - The attachment ID.
|
|
486
600
|
* @param viewId - The view ID.
|
|
487
601
|
* @returns A promise representing the NodeJS.ReadableStream for the requested attachment.
|
|
488
602
|
*/
|
|
489
|
-
async getAttachment (attachmentId: string, viewId: string): Promise<NodeJS.ReadableStream> {
|
|
603
|
+
async getAttachment (context: TurnContext, attachmentId: string, viewId: string): Promise<NodeJS.ReadableStream> {
|
|
604
|
+
if (context === undefined) {
|
|
605
|
+
throw new Error('context is required')
|
|
606
|
+
}
|
|
607
|
+
|
|
490
608
|
if (attachmentId === undefined) {
|
|
491
609
|
throw new Error('attachmentId is required')
|
|
492
610
|
}
|
|
@@ -495,6 +613,6 @@ export class CloudAdapter extends BaseAdapter {
|
|
|
495
613
|
throw new Error('viewId is required')
|
|
496
614
|
}
|
|
497
615
|
|
|
498
|
-
return await this.
|
|
616
|
+
return await context.turnState.get<ConnectorClient>(this.ConnectorClientKey).getAttachment(attachmentId, viewId)
|
|
499
617
|
}
|
|
500
618
|
}
|
|
@@ -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,23 +91,38 @@ 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,
|
|
100
119
|
headers: headerPropagation.outgoing,
|
|
101
|
-
transformRequest: [
|
|
102
|
-
(data, headers) => {
|
|
103
|
-
return JSON.stringify(normalizeOutgoingActivity(data))
|
|
104
|
-
}]
|
|
105
120
|
})
|
|
106
121
|
|
|
107
|
-
|
|
108
|
-
if (token.length > 1) {
|
|
122
|
+
if (token && token.length > 1) {
|
|
109
123
|
axiosInstance.defaults.headers.common.Authorization = `Bearer ${token}`
|
|
110
124
|
}
|
|
125
|
+
|
|
111
126
|
return new ConnectorClient(axiosInstance)
|
|
112
127
|
}
|
|
113
128
|
|
|
@@ -147,14 +162,17 @@ export class ConnectorClient {
|
|
|
147
162
|
* @returns The conversation resource response.
|
|
148
163
|
*/
|
|
149
164
|
public async createConversation (body: ConversationParameters): Promise<ConversationResourceResponse> {
|
|
150
|
-
|
|
165
|
+
const payload = {
|
|
166
|
+
...body,
|
|
167
|
+
activity: normalizeOutgoingActivity(body.activity)
|
|
168
|
+
}
|
|
151
169
|
const config: AxiosRequestConfig = {
|
|
152
170
|
method: 'post',
|
|
153
171
|
url: '/v3/conversations',
|
|
154
172
|
headers: {
|
|
155
173
|
'Content-Type': 'application/json'
|
|
156
174
|
},
|
|
157
|
-
data:
|
|
175
|
+
data: payload
|
|
158
176
|
}
|
|
159
177
|
const response: AxiosResponse = await this._axiosInstance(config)
|
|
160
178
|
return response.data
|
|
@@ -176,19 +194,42 @@ export class ConnectorClient {
|
|
|
176
194
|
if (!conversationId || !activityId) {
|
|
177
195
|
throw new Error('conversationId and activityId are required')
|
|
178
196
|
}
|
|
197
|
+
|
|
198
|
+
const trimmedConversationId: string = this.conditionallyTruncateConversationId(conversationId, body)
|
|
199
|
+
|
|
179
200
|
const config: AxiosRequestConfig = {
|
|
180
201
|
method: 'post',
|
|
181
|
-
url: `v3/conversations/${
|
|
202
|
+
url: `v3/conversations/${trimmedConversationId}/activities/${encodeURIComponent(activityId)}`,
|
|
182
203
|
headers: {
|
|
183
204
|
'Content-Type': 'application/json'
|
|
184
205
|
},
|
|
185
|
-
data: body
|
|
206
|
+
data: normalizeOutgoingActivity(body)
|
|
186
207
|
}
|
|
187
208
|
const response = await this._axiosInstance(config)
|
|
188
209
|
logger.info('Reply to conversation/activity: ', response.data.id!, activityId)
|
|
189
210
|
return response.data
|
|
190
211
|
}
|
|
191
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
|
+
*/
|
|
219
|
+
private conditionallyTruncateConversationId (conversationId: string, activity: Activity): string {
|
|
220
|
+
if (
|
|
221
|
+
(activity.channelIdChannel === Channels.Msteams || activity.channelIdChannel === Channels.Agents) &&
|
|
222
|
+
(activity.from?.role === RoleTypes.AgenticIdentity || activity.from?.role === RoleTypes.AgenticUser)) {
|
|
223
|
+
let maxLength = 150
|
|
224
|
+
if (process.env.MAX_APX_CONVERSATION_ID_LENGTH && !isNaN(parseInt(process.env.MAX_APX_CONVERSATION_ID_LENGTH, 10))) {
|
|
225
|
+
maxLength = parseInt(process.env.MAX_APX_CONVERSATION_ID_LENGTH, 10)
|
|
226
|
+
}
|
|
227
|
+
return conversationId.length > maxLength ? conversationId.substring(0, maxLength) : conversationId
|
|
228
|
+
} else {
|
|
229
|
+
return conversationId
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
192
233
|
/**
|
|
193
234
|
* Sends an activity to a conversation.
|
|
194
235
|
* @param conversationId - The ID of the conversation.
|
|
@@ -203,13 +244,16 @@ export class ConnectorClient {
|
|
|
203
244
|
if (!conversationId) {
|
|
204
245
|
throw new Error('conversationId is required')
|
|
205
246
|
}
|
|
247
|
+
|
|
248
|
+
const trimmedConversationId: string = this.conditionallyTruncateConversationId(conversationId, body)
|
|
249
|
+
|
|
206
250
|
const config: AxiosRequestConfig = {
|
|
207
251
|
method: 'post',
|
|
208
|
-
url: `v3/conversations/${
|
|
252
|
+
url: `v3/conversations/${trimmedConversationId}/activities`,
|
|
209
253
|
headers: {
|
|
210
254
|
'Content-Type': 'application/json'
|
|
211
255
|
},
|
|
212
|
-
data: body
|
|
256
|
+
data: normalizeOutgoingActivity(body)
|
|
213
257
|
}
|
|
214
258
|
const response = await this._axiosInstance(config)
|
|
215
259
|
return response.data
|
|
@@ -236,7 +280,7 @@ export class ConnectorClient {
|
|
|
236
280
|
headers: {
|
|
237
281
|
'Content-Type': 'application/json'
|
|
238
282
|
},
|
|
239
|
-
data: body
|
|
283
|
+
data: normalizeOutgoingActivity(body)
|
|
240
284
|
}
|
|
241
285
|
const response = await this._axiosInstance(config)
|
|
242
286
|
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