@microsoft/agents-hosting 0.4.1 → 0.5.1-g2e246ff274
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/src/activityWireCompat.js +1 -1
- package/dist/src/activityWireCompat.js.map +1 -1
- package/dist/src/app/adaptiveCards/activityValueParsers.d.ts +115 -0
- package/dist/src/app/adaptiveCards/activityValueParsers.js +224 -0
- package/dist/src/app/adaptiveCards/activityValueParsers.js.map +1 -0
- package/dist/src/app/adaptiveCards/adaptiveCardActionExecuteResponseType.d.ts +21 -0
- package/dist/src/app/adaptiveCards/adaptiveCardActionExecuteResponseType.js +26 -0
- package/dist/src/app/adaptiveCards/adaptiveCardActionExecuteResponseType.js.map +1 -0
- package/dist/src/app/adaptiveCards/adaptiveCardsActions.d.ts +57 -0
- package/dist/src/app/adaptiveCards/adaptiveCardsActions.js +272 -0
- package/dist/src/app/adaptiveCards/adaptiveCardsActions.js.map +1 -0
- package/dist/src/app/adaptiveCards/adaptiveCardsOptions.d.ts +20 -0
- package/dist/src/app/adaptiveCards/adaptiveCardsOptions.js +7 -0
- package/dist/src/app/adaptiveCards/adaptiveCardsOptions.js.map +1 -0
- package/dist/src/app/adaptiveCards/adaptiveCardsSearchParams.d.ts +31 -0
- package/dist/src/app/adaptiveCards/adaptiveCardsSearchParams.js +16 -0
- package/dist/src/app/adaptiveCards/adaptiveCardsSearchParams.js.map +1 -0
- package/dist/src/app/adaptiveCards/index.d.ts +3 -0
- package/dist/src/app/adaptiveCards/index.js +20 -0
- package/dist/src/app/adaptiveCards/index.js.map +1 -0
- package/dist/src/app/adaptiveCards/query.d.ts +22 -0
- package/dist/src/app/adaptiveCards/query.js +7 -0
- package/dist/src/app/adaptiveCards/query.js.map +1 -0
- package/dist/src/app/agentApplication.d.ts +56 -8
- package/dist/src/app/agentApplication.js +88 -11
- 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 +17 -2
- package/dist/src/app/appRoute.d.ts +5 -0
- package/dist/src/app/attachmentDownloader.js +1 -0
- package/dist/src/app/attachmentDownloader.js.map +1 -1
- package/dist/src/app/extensions.d.ts +9 -0
- package/dist/src/app/extensions.js +16 -0
- package/dist/src/app/extensions.js.map +1 -0
- package/dist/src/app/index.d.ts +2 -0
- package/dist/src/app/index.js +2 -0
- package/dist/src/app/index.js.map +1 -1
- package/dist/src/auth/jwt-middleware.js +1 -0
- package/dist/src/auth/jwt-middleware.js.map +1 -1
- package/dist/src/baseAdapter.js +1 -1
- package/dist/src/baseAdapter.js.map +1 -1
- package/dist/src/cards/adaptiveCard.d.ts +15 -0
- package/dist/src/cards/adaptiveCard.js +7 -0
- package/dist/src/cards/adaptiveCard.js.map +1 -0
- package/dist/src/cards/index.d.ts +1 -0
- package/dist/src/cards/index.js +1 -0
- package/dist/src/cards/index.js.map +1 -1
- package/dist/src/cloudAdapter.js +6 -7
- package/dist/src/cloudAdapter.js.map +1 -1
- package/dist/src/connector-client/connectorClient.d.ts +6 -4
- package/dist/src/connector-client/connectorClient.js +34 -17
- package/dist/src/connector-client/connectorClient.js.map +1 -1
- package/package.json +2 -2
- package/src/activityWireCompat.ts +1 -1
- package/src/app/adaptiveCards/activityValueParsers.ts +249 -0
- package/src/app/adaptiveCards/adaptiveCardActionExecuteResponseType.ts +24 -0
- package/src/app/adaptiveCards/adaptiveCardsActions.ts +320 -0
- package/src/app/adaptiveCards/adaptiveCardsOptions.ts +23 -0
- package/src/app/adaptiveCards/adaptiveCardsSearchParams.ts +28 -0
- package/src/app/adaptiveCards/index.ts +3 -0
- package/src/app/adaptiveCards/query.ts +25 -0
- package/src/app/agentApplication.ts +109 -29
- package/src/app/agentApplicationBuilder.ts +2 -2
- package/src/app/agentApplicationOptions.ts +20 -2
- package/src/app/appRoute.ts +6 -0
- package/src/app/attachmentDownloader.ts +1 -0
- package/src/app/extensions.ts +19 -0
- package/src/app/index.ts +2 -0
- package/src/auth/jwt-middleware.ts +1 -1
- package/src/baseAdapter.ts +2 -2
- package/src/cards/adaptiveCard.ts +16 -0
- package/src/cards/index.ts +1 -0
- package/src/cloudAdapter.ts +5 -7
- package/src/connector-client/connectorClient.ts +38 -19
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Activity, ActivityTypes } from '@microsoft/agents-activity'
|
|
7
|
+
import { AdaptiveCardInvokeResponse, AgentApplication, CardFactory, INVOKE_RESPONSE_KEY, InvokeResponse, MessageFactory, RouteSelector, TurnContext, TurnState } from '../../'
|
|
8
|
+
import { AdaptiveCardActionExecuteResponseType } from './adaptiveCardActionExecuteResponseType'
|
|
9
|
+
import { parseAdaptiveCardInvokeAction, parseValueActionExecuteSelector, parseValueDataset, parseValueSearchQuery } from './activityValueParsers'
|
|
10
|
+
import { AdaptiveCardsSearchParams } from './adaptiveCardsSearchParams'
|
|
11
|
+
import { AdaptiveCard } from '../../cards/adaptiveCard'
|
|
12
|
+
import { Query } from './query'
|
|
13
|
+
|
|
14
|
+
export const ACTION_INVOKE_NAME = 'adaptiveCard/action'
|
|
15
|
+
const ACTION_EXECUTE_TYPE = 'Action.Execute'
|
|
16
|
+
const DEFAULT_ACTION_SUBMIT_FILTER = 'verb'
|
|
17
|
+
const SEARCH_INVOKE_NAME = 'application/search'
|
|
18
|
+
|
|
19
|
+
enum AdaptiveCardInvokeResponseType {
|
|
20
|
+
/**
|
|
21
|
+
* Indicates a response containing an Adaptive Card.
|
|
22
|
+
*/
|
|
23
|
+
ADAPTIVE = 'application/vnd.microsoft.card.adaptive',
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Indicates a response containing a message activity.
|
|
27
|
+
*/
|
|
28
|
+
MESSAGE = 'application/vnd.microsoft.activity.message',
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Indicates a response containing a search result.
|
|
32
|
+
*/
|
|
33
|
+
SEARCH = 'application/vnd.microsoft.search.searchResponse'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface AdaptiveCardSearchResult {
|
|
37
|
+
/**
|
|
38
|
+
* The title of the search result.
|
|
39
|
+
*/
|
|
40
|
+
title: string;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The value associated with the search result.
|
|
44
|
+
*/
|
|
45
|
+
value: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* A class to handle Adaptive Card actions such as executing actions, submitting actions, and performing searches.
|
|
50
|
+
* @template TState - The type of the TurnState used in the application.
|
|
51
|
+
*/
|
|
52
|
+
export class AdaptiveCardsActions<TState extends TurnState> {
|
|
53
|
+
/**
|
|
54
|
+
* The Teams application instance associated with this class.
|
|
55
|
+
*/
|
|
56
|
+
private readonly _app: AgentApplication<TState>
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Constructs an instance of AdaptiveCardsActions.
|
|
60
|
+
* @param app - The Teams application instance.
|
|
61
|
+
*/
|
|
62
|
+
public constructor (app: AgentApplication<TState>) {
|
|
63
|
+
this._app = app
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Registers a handler for the Action.Execute event.
|
|
68
|
+
* @template TData - The type of the data passed to the handler.
|
|
69
|
+
* @param verb - A string, RegExp, RouteSelector, or an array of these to match the action verb.
|
|
70
|
+
* @param handler - A function to handle the action execution.
|
|
71
|
+
* @returns The Teams application instance.
|
|
72
|
+
*/
|
|
73
|
+
public actionExecute<TData = Record<string, any>>(
|
|
74
|
+
verb: string | RegExp | RouteSelector | (string | RegExp | RouteSelector)[],
|
|
75
|
+
handler: (context: TurnContext, state: TState, data: TData) => Promise<AdaptiveCard | string>
|
|
76
|
+
): AgentApplication<TState> {
|
|
77
|
+
let actionExecuteResponseType = this._app.options.adaptiveCardsOptions?.actionExecuteResponseType ?? AdaptiveCardActionExecuteResponseType.REPLACE_FOR_INTERACTOR;
|
|
78
|
+
(Array.isArray(verb) ? verb : [verb]).forEach((v) => {
|
|
79
|
+
const selector = createActionExecuteSelector(v)
|
|
80
|
+
this._app.addRoute(
|
|
81
|
+
selector,
|
|
82
|
+
async (context, state) => {
|
|
83
|
+
const a = context?.activity
|
|
84
|
+
const invokeAction = parseValueActionExecuteSelector(a.value)
|
|
85
|
+
if (
|
|
86
|
+
a?.type !== ActivityTypes.Invoke ||
|
|
87
|
+
a?.name !== ACTION_INVOKE_NAME ||
|
|
88
|
+
(invokeAction?.action.type !== ACTION_EXECUTE_TYPE)
|
|
89
|
+
) {
|
|
90
|
+
throw new Error(`Unexpected AdaptiveCards.actionExecute() triggered for activity type: ${invokeAction?.action.type}`
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (invokeAction.action.verb !== v) {
|
|
95
|
+
// TODO: add logger to this class
|
|
96
|
+
console.log(`AdaptiveCards.actionExecute() triggered for verb: ${invokeAction.action.verb} does not match expected verb: ${v}`)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// TODO: review any, and check verb
|
|
100
|
+
const result = await handler(context, state, ((a.value as any).action as TData) ?? {} as TData)
|
|
101
|
+
if (!context.turnState.get(INVOKE_RESPONSE_KEY)) {
|
|
102
|
+
let response: AdaptiveCardInvokeResponse
|
|
103
|
+
if (typeof result === 'string') {
|
|
104
|
+
response = {
|
|
105
|
+
statusCode: 200,
|
|
106
|
+
type: AdaptiveCardInvokeResponseType.MESSAGE,
|
|
107
|
+
value: result as any
|
|
108
|
+
}
|
|
109
|
+
await sendInvokeResponse(context, response)
|
|
110
|
+
} else {
|
|
111
|
+
if (
|
|
112
|
+
result.refresh &&
|
|
113
|
+
actionExecuteResponseType !== AdaptiveCardActionExecuteResponseType.NEW_MESSAGE_FOR_ALL
|
|
114
|
+
) {
|
|
115
|
+
actionExecuteResponseType = AdaptiveCardActionExecuteResponseType.REPLACE_FOR_ALL
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const activity = MessageFactory.attachment(CardFactory.adaptiveCard(result))
|
|
119
|
+
response = {
|
|
120
|
+
statusCode: 200,
|
|
121
|
+
type: AdaptiveCardInvokeResponseType.ADAPTIVE,
|
|
122
|
+
value: result
|
|
123
|
+
}
|
|
124
|
+
if (
|
|
125
|
+
actionExecuteResponseType === AdaptiveCardActionExecuteResponseType.NEW_MESSAGE_FOR_ALL
|
|
126
|
+
) {
|
|
127
|
+
await sendInvokeResponse(context, {
|
|
128
|
+
statusCode: 200,
|
|
129
|
+
type: AdaptiveCardInvokeResponseType.MESSAGE,
|
|
130
|
+
value: 'Your response was sent to the app' as any
|
|
131
|
+
})
|
|
132
|
+
await context.sendActivity(activity)
|
|
133
|
+
} else if (
|
|
134
|
+
actionExecuteResponseType === AdaptiveCardActionExecuteResponseType.REPLACE_FOR_ALL
|
|
135
|
+
) {
|
|
136
|
+
activity.id = context.activity.replyToId
|
|
137
|
+
await context.updateActivity(activity)
|
|
138
|
+
await sendInvokeResponse(context, response)
|
|
139
|
+
} else {
|
|
140
|
+
await sendInvokeResponse(context, response)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
true
|
|
146
|
+
)
|
|
147
|
+
})
|
|
148
|
+
return this._app
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Registers a handler for the Action.Submit event.
|
|
153
|
+
* @template TData - The type of the data passed to the handler.
|
|
154
|
+
* @param verb - A string, RegExp, RouteSelector, or an array of these to match the action verb.
|
|
155
|
+
* @param handler - A function to handle the action submission.
|
|
156
|
+
* @returns The Teams application instance.
|
|
157
|
+
*/
|
|
158
|
+
public actionSubmit<TData = Record<string, any>>(
|
|
159
|
+
verb: string | RegExp | RouteSelector | (string | RegExp | RouteSelector)[],
|
|
160
|
+
handler: (context: TurnContext, state: TState, data: TData) => Promise<void>
|
|
161
|
+
): AgentApplication<TState> {
|
|
162
|
+
const filter = this._app.options.adaptiveCardsOptions?.actionSubmitFilter ?? DEFAULT_ACTION_SUBMIT_FILTER;
|
|
163
|
+
(Array.isArray(verb) ? verb : [verb]).forEach((v) => {
|
|
164
|
+
const selector = createActionSubmitSelector(v, filter)
|
|
165
|
+
this._app.addRoute(selector, async (context, state) => {
|
|
166
|
+
const a = context?.activity
|
|
167
|
+
if (a?.type !== ActivityTypes.Message || a?.text || typeof a?.value !== 'object') {
|
|
168
|
+
throw new Error(`Unexpected AdaptiveCards.actionSubmit() triggered for activity type: ${a?.type}`)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
await handler(context, state as TState, (parseAdaptiveCardInvokeAction(a.value)) as TData ?? {} as TData)
|
|
172
|
+
})
|
|
173
|
+
})
|
|
174
|
+
return this._app
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Registers a handler for the search event.
|
|
179
|
+
* @param dataset - A string, RegExp, RouteSelector, or an array of these to match the dataset.
|
|
180
|
+
* @param handler - A function to handle the search query.
|
|
181
|
+
* @returns The Teams application instance.
|
|
182
|
+
*/
|
|
183
|
+
public search (
|
|
184
|
+
dataset: string | RegExp | RouteSelector | (string | RegExp | RouteSelector)[],
|
|
185
|
+
handler: (
|
|
186
|
+
context: TurnContext,
|
|
187
|
+
state: TState,
|
|
188
|
+
query: Query<AdaptiveCardsSearchParams>
|
|
189
|
+
) => Promise<AdaptiveCardSearchResult[]>
|
|
190
|
+
): AgentApplication<TState> {
|
|
191
|
+
(Array.isArray(dataset) ? dataset : [dataset]).forEach((ds) => {
|
|
192
|
+
const selector = createSearchSelector(ds)
|
|
193
|
+
this._app.addRoute(
|
|
194
|
+
selector,
|
|
195
|
+
async (context, state) => {
|
|
196
|
+
const a = context?.activity
|
|
197
|
+
if (a?.type !== 'invoke' || a?.name !== SEARCH_INVOKE_NAME) {
|
|
198
|
+
throw new Error(`Unexpected AdaptiveCards.search() triggered for activity type: ${a?.type}`)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const parsedQuery = parseValueSearchQuery(a.value)
|
|
202
|
+
const query: Query<AdaptiveCardsSearchParams> = {
|
|
203
|
+
count: parsedQuery.queryOptions?.top ?? 25,
|
|
204
|
+
skip: parsedQuery.queryOptions?.skip ?? 0,
|
|
205
|
+
|
|
206
|
+
parameters: {
|
|
207
|
+
queryText: parsedQuery.queryText ?? '',
|
|
208
|
+
dataset: parsedQuery.dataset ?? ''
|
|
209
|
+
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const results = await handler(context, state, query)
|
|
214
|
+
if (!context.turnState.get(INVOKE_RESPONSE_KEY)) {
|
|
215
|
+
const response = {
|
|
216
|
+
type: AdaptiveCardInvokeResponseType.SEARCH,
|
|
217
|
+
value: {
|
|
218
|
+
results
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
await context.sendActivity({
|
|
223
|
+
value: { body: response, status: 200 } as InvokeResponse,
|
|
224
|
+
type: ActivityTypes.InvokeResponse
|
|
225
|
+
} as Activity)
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
true
|
|
229
|
+
)
|
|
230
|
+
})
|
|
231
|
+
return this._app
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function createActionExecuteSelector (verb: string | RegExp | RouteSelector): RouteSelector {
|
|
236
|
+
if (typeof verb === 'function') {
|
|
237
|
+
return verb
|
|
238
|
+
} else if (verb instanceof RegExp) {
|
|
239
|
+
return (context: TurnContext) => {
|
|
240
|
+
const a = context?.activity
|
|
241
|
+
const valueAction = parseValueActionExecuteSelector(a.value)
|
|
242
|
+
const isInvoke =
|
|
243
|
+
a?.type === ActivityTypes.Invoke &&
|
|
244
|
+
a?.name === ACTION_INVOKE_NAME &&
|
|
245
|
+
valueAction?.action?.type === ACTION_EXECUTE_TYPE
|
|
246
|
+
if (isInvoke && typeof valueAction.action.verb === 'string') {
|
|
247
|
+
return Promise.resolve(verb.test(valueAction.action.verb))
|
|
248
|
+
} else {
|
|
249
|
+
return Promise.resolve(false)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
} else {
|
|
253
|
+
return (context: TurnContext) => {
|
|
254
|
+
const a = context?.activity
|
|
255
|
+
const valueAction = parseValueActionExecuteSelector(a.value)
|
|
256
|
+
const isInvoke =
|
|
257
|
+
a?.type === ActivityTypes.Invoke &&
|
|
258
|
+
a?.name === ACTION_INVOKE_NAME &&
|
|
259
|
+
valueAction?.action?.type === ACTION_EXECUTE_TYPE
|
|
260
|
+
if (isInvoke && valueAction.action?.verb === verb) {
|
|
261
|
+
return Promise.resolve(true)
|
|
262
|
+
} else {
|
|
263
|
+
return Promise.resolve(false)
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function createActionSubmitSelector (verb: string | RegExp | RouteSelector, filter: string): RouteSelector {
|
|
270
|
+
if (typeof verb === 'function') {
|
|
271
|
+
return verb
|
|
272
|
+
} else if (verb instanceof RegExp) {
|
|
273
|
+
return (context: TurnContext) => {
|
|
274
|
+
const a = context?.activity
|
|
275
|
+
const isSubmit = a?.type === ActivityTypes.Message && !a?.text && typeof a?.value === 'object'
|
|
276
|
+
if (isSubmit && typeof (a?.value as any)[filter] === 'string') {
|
|
277
|
+
return Promise.resolve(verb.test((a.value as any)[filter]))
|
|
278
|
+
} else {
|
|
279
|
+
return Promise.resolve(false)
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
} else {
|
|
283
|
+
return (context: TurnContext) => {
|
|
284
|
+
const a = context?.activity
|
|
285
|
+
const isSubmit = a?.type === ActivityTypes.Message && !a?.text && typeof a?.value === 'object'
|
|
286
|
+
return Promise.resolve(isSubmit && (a?.value as any)[filter] === verb)
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function createSearchSelector (dataset: string | RegExp | RouteSelector): RouteSelector {
|
|
292
|
+
if (typeof dataset === 'function') {
|
|
293
|
+
return dataset
|
|
294
|
+
} else if (dataset instanceof RegExp) {
|
|
295
|
+
return (context: TurnContext) => {
|
|
296
|
+
const a = context?.activity
|
|
297
|
+
const valueDataset = parseValueDataset(a.value)
|
|
298
|
+
const isSearch = a?.type === ActivityTypes.Invoke && a?.name === SEARCH_INVOKE_NAME
|
|
299
|
+
if (isSearch && typeof valueDataset?.dataset === 'string') {
|
|
300
|
+
return Promise.resolve(dataset.test(valueDataset?.dataset))
|
|
301
|
+
} else {
|
|
302
|
+
return Promise.resolve(false)
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
} else {
|
|
306
|
+
return (context: TurnContext) => {
|
|
307
|
+
const a = context?.activity
|
|
308
|
+
// const valueDataset = parseAdaptiveCardInvokeAction(a.value)
|
|
309
|
+
const isSearch = a?.type === ActivityTypes.Invoke && a?.name === SEARCH_INVOKE_NAME
|
|
310
|
+
return Promise.resolve(isSearch)
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
async function sendInvokeResponse (context: TurnContext, response: AdaptiveCardInvokeResponse) {
|
|
316
|
+
await context.sendActivity({
|
|
317
|
+
value: { body: response, status: 200 } as InvokeResponse,
|
|
318
|
+
type: ActivityTypes.InvokeResponse
|
|
319
|
+
} as Activity)
|
|
320
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { AdaptiveCardActionExecuteResponseType } from './adaptiveCardActionExecuteResponseType'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Configuration options for Adaptive Cards.
|
|
10
|
+
*/
|
|
11
|
+
export interface AdaptiveCardsOptions {
|
|
12
|
+
/**
|
|
13
|
+
* Specifies the filter key used for Action.Submit events.
|
|
14
|
+
* If not provided, a default filter key will be used.
|
|
15
|
+
*/
|
|
16
|
+
actionSubmitFilter?: string;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Specifies the response type for Action.Execute events.
|
|
20
|
+
* Determines how the response is handled after an action is executed.
|
|
21
|
+
*/
|
|
22
|
+
actionExecuteResponseType?: AdaptiveCardActionExecuteResponseType;
|
|
23
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { z } from 'zod'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Interface representing the search parameters for adaptive cards.
|
|
10
|
+
*/
|
|
11
|
+
export interface AdaptiveCardsSearchParams {
|
|
12
|
+
/**
|
|
13
|
+
* The text query for the search.
|
|
14
|
+
*/
|
|
15
|
+
queryText: string;
|
|
16
|
+
/**
|
|
17
|
+
* The dataset to search within.
|
|
18
|
+
*/
|
|
19
|
+
dataset: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Zod schema for validating AdaptiveCardsSearchParams.
|
|
24
|
+
*/
|
|
25
|
+
export const adaptiveCardsSearchParamsZodSchema = z.object({
|
|
26
|
+
queryText: z.string(),
|
|
27
|
+
dataset: z.string(),
|
|
28
|
+
})
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Represents a query with pagination and parameters.
|
|
8
|
+
* @template TParams - The type of the query parameters.
|
|
9
|
+
*/
|
|
10
|
+
export interface Query<TParams extends Record<string, any>> {
|
|
11
|
+
/**
|
|
12
|
+
* The number of items to retrieve.
|
|
13
|
+
*/
|
|
14
|
+
count: number;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The number of items to skip.
|
|
18
|
+
*/
|
|
19
|
+
skip: number;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The parameters for the query.
|
|
23
|
+
*/
|
|
24
|
+
parameters: TParams;
|
|
25
|
+
}
|
|
@@ -4,18 +4,20 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { Activity, ActivityTypes, ConversationReference } from '@microsoft/agents-activity'
|
|
7
|
-
import { TurnState } from './turnState'
|
|
8
7
|
import { BaseAdapter } from '../baseAdapter'
|
|
9
|
-
import { AgentApplicationOptions } from './agentApplicationOptions'
|
|
10
|
-
import { RouteSelector } from './routeSelector'
|
|
11
|
-
import { RouteHandler } from './routeHandler'
|
|
12
|
-
import { ConversationUpdateEvents } from './conversationUpdateEvents'
|
|
13
|
-
import { TurnEvents } from './turnEvents'
|
|
14
|
-
import { AppRoute } from './appRoute'
|
|
15
|
-
import { TurnContext } from '../turnContext'
|
|
16
8
|
import { ResourceResponse } from '../connector-client'
|
|
17
9
|
import { debug } from '../logger'
|
|
10
|
+
import { TurnContext } from '../turnContext'
|
|
11
|
+
import { AdaptiveCardsActions } from './adaptiveCards'
|
|
12
|
+
import { AgentApplicationOptions } from './agentApplicationOptions'
|
|
13
|
+
import { AppRoute } from './appRoute'
|
|
14
|
+
import { ConversationUpdateEvents } from './conversationUpdateEvents'
|
|
15
|
+
import { AgentExtension } from './extensions'
|
|
18
16
|
import { Authorization } from './oauth/authorization'
|
|
17
|
+
import { RouteHandler } from './routeHandler'
|
|
18
|
+
import { RouteSelector } from './routeSelector'
|
|
19
|
+
import { TurnEvents } from './turnEvents'
|
|
20
|
+
import { TurnState } from './turnState'
|
|
19
21
|
|
|
20
22
|
const logger = debug('agents:agent-application')
|
|
21
23
|
|
|
@@ -46,16 +48,21 @@ export class AgentApplication<TState extends TurnState> {
|
|
|
46
48
|
protected readonly _afterTurn: ApplicationEventHandler<TState>[] = []
|
|
47
49
|
private readonly _adapter?: BaseAdapter
|
|
48
50
|
private readonly _authorization?: Authorization
|
|
49
|
-
private _typingTimer:
|
|
51
|
+
private _typingTimer: NodeJS.Timeout | undefined
|
|
52
|
+
protected readonly _extensions: AgentExtension<TState>[] = []
|
|
53
|
+
private readonly _adaptiveCards: AdaptiveCardsActions<TState>
|
|
50
54
|
|
|
51
55
|
public constructor (options?: Partial<AgentApplicationOptions<TState>>) {
|
|
52
56
|
this._options = {
|
|
53
57
|
...options,
|
|
54
58
|
turnStateFactory: options?.turnStateFactory || (() => new TurnState() as TState),
|
|
55
59
|
startTypingTimer: options?.startTypingTimer !== undefined ? options.startTypingTimer : false,
|
|
56
|
-
longRunningMessages: options?.longRunningMessages !== undefined ? options.longRunningMessages : false
|
|
60
|
+
longRunningMessages: options?.longRunningMessages !== undefined ? options.longRunningMessages : false,
|
|
61
|
+
removeRecipientMention: options?.removeRecipientMention !== undefined ? options.removeRecipientMention : true,
|
|
57
62
|
}
|
|
58
63
|
|
|
64
|
+
this._adaptiveCards = new AdaptiveCardsActions<TState>(this)
|
|
65
|
+
|
|
59
66
|
if (this._options.adapter) {
|
|
60
67
|
this._adapter = this._options.adapter
|
|
61
68
|
}
|
|
@@ -65,9 +72,7 @@ export class AgentApplication<TState extends TurnState> {
|
|
|
65
72
|
}
|
|
66
73
|
|
|
67
74
|
if (this._options.longRunningMessages && !this._adapter && !this._options.agentAppId) {
|
|
68
|
-
throw new Error(
|
|
69
|
-
'The Application.longRunningMessages property is unavailable because no adapter or agentAppId was configured.'
|
|
70
|
-
)
|
|
75
|
+
throw new Error('The Application.longRunningMessages property is unavailable because no adapter was configured in the app.')
|
|
71
76
|
}
|
|
72
77
|
}
|
|
73
78
|
|
|
@@ -76,13 +81,7 @@ export class AgentApplication<TState extends TurnState> {
|
|
|
76
81
|
* @throws Error if the adapter is not configured.
|
|
77
82
|
*/
|
|
78
83
|
public get adapter (): BaseAdapter {
|
|
79
|
-
|
|
80
|
-
throw new Error(
|
|
81
|
-
'The Application.adapter property is unavailable because it was not configured when creating the Application.'
|
|
82
|
-
)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return this._adapter
|
|
84
|
+
return this._adapter!
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
/**
|
|
@@ -91,11 +90,8 @@ export class AgentApplication<TState extends TurnState> {
|
|
|
91
90
|
*/
|
|
92
91
|
public get authorization (): Authorization {
|
|
93
92
|
if (!this._authorization) {
|
|
94
|
-
throw new Error(
|
|
95
|
-
'The Application.authorization property is unavailable because no authentication options were configured.'
|
|
96
|
-
)
|
|
93
|
+
throw new Error('The Application.authorization property is unavailable because no authorization options were configured.')
|
|
97
94
|
}
|
|
98
|
-
|
|
99
95
|
return this._authorization
|
|
100
96
|
}
|
|
101
97
|
|
|
@@ -107,6 +103,10 @@ export class AgentApplication<TState extends TurnState> {
|
|
|
107
103
|
return this._options
|
|
108
104
|
}
|
|
109
105
|
|
|
106
|
+
public get adaptiveCards (): AdaptiveCardsActions<TState> {
|
|
107
|
+
return this._adaptiveCards
|
|
108
|
+
}
|
|
109
|
+
|
|
110
110
|
/**
|
|
111
111
|
* Sets an error handler for the application.
|
|
112
112
|
*
|
|
@@ -129,7 +129,6 @@ export class AgentApplication<TState extends TurnState> {
|
|
|
129
129
|
if (this._adapter) {
|
|
130
130
|
this._adapter.onTurnError = handler
|
|
131
131
|
}
|
|
132
|
-
|
|
133
132
|
return this
|
|
134
133
|
}
|
|
135
134
|
|
|
@@ -153,8 +152,8 @@ export class AgentApplication<TState extends TurnState> {
|
|
|
153
152
|
* );
|
|
154
153
|
* ```
|
|
155
154
|
*/
|
|
156
|
-
public addRoute (selector: RouteSelector, handler: RouteHandler<TState
|
|
157
|
-
this._routes.push({ selector, handler })
|
|
155
|
+
public addRoute (selector: RouteSelector, handler: RouteHandler<TState>, isInvokeRoute: boolean = false): this {
|
|
156
|
+
this._routes.push({ selector, handler, isInvokeRoute })
|
|
158
157
|
return this
|
|
159
158
|
}
|
|
160
159
|
|
|
@@ -316,12 +315,74 @@ export class AgentApplication<TState extends TurnState> {
|
|
|
316
315
|
this.authorization.onSignInSuccess(handler)
|
|
317
316
|
} else {
|
|
318
317
|
throw new Error(
|
|
319
|
-
'The Application.
|
|
318
|
+
'The Application.authorization property is unavailable because no authorization options were configured.'
|
|
320
319
|
)
|
|
321
320
|
}
|
|
322
321
|
return this
|
|
323
322
|
}
|
|
324
323
|
|
|
324
|
+
/**
|
|
325
|
+
* Adds a handler for message reaction added events.
|
|
326
|
+
*
|
|
327
|
+
* @param handler - The handler function that will be called when a message reaction is added.
|
|
328
|
+
* @returns The current instance of the application.
|
|
329
|
+
*
|
|
330
|
+
* @remarks
|
|
331
|
+
* This method registers a handler that will be invoked when a user adds a reaction to a message,
|
|
332
|
+
* such as a like, heart, or other emoji reaction.
|
|
333
|
+
*
|
|
334
|
+
* Example usage:
|
|
335
|
+
* ```typescript
|
|
336
|
+
* app.onMessageReactionAdded(async (context, state) => {
|
|
337
|
+
* const reactionsAdded = context.activity.reactionsAdded;
|
|
338
|
+
* if (reactionsAdded && reactionsAdded.length > 0) {
|
|
339
|
+
* await context.sendActivity(`Thanks for your ${reactionsAdded[0].type} reaction!`);
|
|
340
|
+
* }
|
|
341
|
+
* });
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
public onMessageReactionAdded (handler: (context: TurnContext, state: TState) => Promise<void>): this {
|
|
345
|
+
const selector = async (context: TurnContext): Promise<boolean> => {
|
|
346
|
+
return context.activity.type === ActivityTypes.MessageReaction &&
|
|
347
|
+
Array.isArray(context.activity.reactionsAdded) &&
|
|
348
|
+
context.activity.reactionsAdded.length > 0
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
this.addRoute(selector, handler)
|
|
352
|
+
return this
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Adds a handler for message reaction removed events.
|
|
357
|
+
*
|
|
358
|
+
* @param handler - The handler function that will be called when a message reaction is removed.
|
|
359
|
+
* @returns The current instance of the application.
|
|
360
|
+
*
|
|
361
|
+
* @remarks
|
|
362
|
+
* This method registers a handler that will be invoked when a user removes a reaction from a message,
|
|
363
|
+
* such as unliking or removing an emoji reaction.
|
|
364
|
+
*
|
|
365
|
+
* Example usage:
|
|
366
|
+
* ```typescript
|
|
367
|
+
* app.onMessageReactionRemoved(async (context, state) => {
|
|
368
|
+
* const reactionsRemoved = context.activity.reactionsRemoved;
|
|
369
|
+
* if (reactionsRemoved && reactionsRemoved.length > 0) {
|
|
370
|
+
* await context.sendActivity(`You removed your ${reactionsRemoved[0].type} reaction.`);
|
|
371
|
+
* }
|
|
372
|
+
* });
|
|
373
|
+
* ```
|
|
374
|
+
*/
|
|
375
|
+
public onMessageReactionRemoved (handler: (context: TurnContext, state: TState) => Promise<void>): this {
|
|
376
|
+
const selector = async (context: TurnContext): Promise<boolean> => {
|
|
377
|
+
return context.activity.type === ActivityTypes.MessageReaction &&
|
|
378
|
+
Array.isArray(context.activity.reactionsRemoved) &&
|
|
379
|
+
context.activity.reactionsRemoved.length > 0
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
this.addRoute(selector, handler)
|
|
383
|
+
return this
|
|
384
|
+
}
|
|
385
|
+
|
|
325
386
|
/**
|
|
326
387
|
* Executes the application logic for a given turn context.
|
|
327
388
|
*
|
|
@@ -355,8 +416,19 @@ export class AgentApplication<TState extends TurnState> {
|
|
|
355
416
|
*/
|
|
356
417
|
public async runInternal (turnContext: TurnContext): Promise<boolean> {
|
|
357
418
|
return await this.startLongRunningCall(turnContext, async (context) => {
|
|
358
|
-
this.startTypingTimer(context)
|
|
359
419
|
try {
|
|
420
|
+
if (this._options.startTypingTimer) {
|
|
421
|
+
this.startTypingTimer(context)
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
if (this._options.removeRecipientMention && context.activity.type === ActivityTypes.Message) {
|
|
425
|
+
context.activity.removeRecipientMention()
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (this._options.normalizeMentions && context.activity.type === ActivityTypes.Message) {
|
|
429
|
+
context.activity.normalizeMentions()
|
|
430
|
+
}
|
|
431
|
+
|
|
360
432
|
const { storage, turnStateFactory } = this._options
|
|
361
433
|
const state = turnStateFactory()
|
|
362
434
|
await state.load(context, storage)
|
|
@@ -497,6 +569,14 @@ export class AgentApplication<TState extends TurnState> {
|
|
|
497
569
|
}
|
|
498
570
|
}
|
|
499
571
|
|
|
572
|
+
public registerExtension<T extends AgentExtension<TState>> (extension: T, regcb : (ext:T) => void): void {
|
|
573
|
+
if (this._extensions.includes(extension)) {
|
|
574
|
+
throw new Error('Extension already registered')
|
|
575
|
+
}
|
|
576
|
+
this._extensions.push(extension)
|
|
577
|
+
regcb(extension)
|
|
578
|
+
}
|
|
579
|
+
|
|
500
580
|
/**
|
|
501
581
|
* Stops the typing indicator timer if it's currently running.
|
|
502
582
|
*
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { Storage } from '../storage'
|
|
6
7
|
import { AgentApplication } from './agentApplication'
|
|
7
8
|
import { AgentApplicationOptions } from './agentApplicationOptions'
|
|
8
|
-
import { TurnState } from './turnState'
|
|
9
|
-
import { Storage } from '../storage'
|
|
10
9
|
import { AuthorizationHandlers } from './oauth/authorization'
|
|
10
|
+
import { TurnState } from './turnState'
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Builder class for creating and configuring AgentApplication instances.
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { CloudAdapter } from '../cloudAdapter'
|
|
7
|
-
import { InputFileDownloader } from './inputFileDownloader'
|
|
8
|
-
import { TurnState } from './turnState'
|
|
9
7
|
import { Storage } from '../storage'
|
|
8
|
+
import { AdaptiveCardsOptions } from './adaptiveCards'
|
|
9
|
+
import { InputFileDownloader } from './inputFileDownloader'
|
|
10
10
|
import { AuthorizationHandlers } from './oauth/authorization'
|
|
11
|
+
import { TurnState } from './turnState'
|
|
11
12
|
|
|
12
13
|
export interface AgentApplicationOptions<TState extends TurnState> {
|
|
13
14
|
/**
|
|
@@ -49,4 +50,21 @@ export interface AgentApplicationOptions<TState extends TurnState> {
|
|
|
49
50
|
* Handlers for managing authorization.
|
|
50
51
|
*/
|
|
51
52
|
authorization?: AuthorizationHandlers;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Options for AdaptiveCard actions.
|
|
56
|
+
*/
|
|
57
|
+
adaptiveCardsOptions?: AdaptiveCardsOptions;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Optional. If true, the agent will automatically remove mentions of the bot's name from incoming
|
|
61
|
+
* messages. Defaults to true.
|
|
62
|
+
*/
|
|
63
|
+
removeRecipientMention?: boolean;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Optional. If true, the agent will automatically normalize mentions in incoming messages. Defaults to
|
|
67
|
+
* true.
|
|
68
|
+
*/
|
|
69
|
+
normalizeMentions?: boolean
|
|
52
70
|
}
|