@memberjunction/messaging-adapters 0.0.1 → 5.18.0
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/README.md +231 -43
- package/dist/base/BaseMessagingAdapter.d.ts +428 -0
- package/dist/base/BaseMessagingAdapter.d.ts.map +1 -0
- package/dist/base/BaseMessagingAdapter.js +934 -0
- package/dist/base/BaseMessagingAdapter.js.map +1 -0
- package/dist/base/message-formatter.d.ts +70 -0
- package/dist/base/message-formatter.d.ts.map +1 -0
- package/dist/base/message-formatter.js +201 -0
- package/dist/base/message-formatter.js.map +1 -0
- package/dist/base/types.d.ts +211 -0
- package/dist/base/types.d.ts.map +1 -0
- package/dist/base/types.js +6 -0
- package/dist/base/types.js.map +1 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/slack/SlackAdapter.d.ts +141 -0
- package/dist/slack/SlackAdapter.d.ts.map +1 -0
- package/dist/slack/SlackAdapter.js +291 -0
- package/dist/slack/SlackAdapter.js.map +1 -0
- package/dist/slack/SlackMessagingExtension.d.ts +148 -0
- package/dist/slack/SlackMessagingExtension.d.ts.map +1 -0
- package/dist/slack/SlackMessagingExtension.js +433 -0
- package/dist/slack/SlackMessagingExtension.js.map +1 -0
- package/dist/slack/slack-block-builder.d.ts +133 -0
- package/dist/slack/slack-block-builder.d.ts.map +1 -0
- package/dist/slack/slack-block-builder.js +748 -0
- package/dist/slack/slack-block-builder.js.map +1 -0
- package/dist/slack/slack-formatter.d.ts +37 -0
- package/dist/slack/slack-formatter.d.ts.map +1 -0
- package/dist/slack/slack-formatter.js +116 -0
- package/dist/slack/slack-formatter.js.map +1 -0
- package/dist/slack/slack-interactivity.d.ts +38 -0
- package/dist/slack/slack-interactivity.d.ts.map +1 -0
- package/dist/slack/slack-interactivity.js +414 -0
- package/dist/slack/slack-interactivity.js.map +1 -0
- package/dist/slack/slack-routes.d.ts +35 -0
- package/dist/slack/slack-routes.d.ts.map +1 -0
- package/dist/slack/slack-routes.js +98 -0
- package/dist/slack/slack-routes.js.map +1 -0
- package/dist/teams/TeamsAdapter.d.ts +155 -0
- package/dist/teams/TeamsAdapter.d.ts.map +1 -0
- package/dist/teams/TeamsAdapter.js +383 -0
- package/dist/teams/TeamsAdapter.js.map +1 -0
- package/dist/teams/TeamsMessagingExtension.d.ts +75 -0
- package/dist/teams/TeamsMessagingExtension.d.ts.map +1 -0
- package/dist/teams/TeamsMessagingExtension.js +176 -0
- package/dist/teams/TeamsMessagingExtension.js.map +1 -0
- package/dist/teams/teams-card-builder.d.ts +94 -0
- package/dist/teams/teams-card-builder.d.ts.map +1 -0
- package/dist/teams/teams-card-builder.js +648 -0
- package/dist/teams/teams-card-builder.js.map +1 -0
- package/dist/teams/teams-formatter.d.ts +39 -0
- package/dist/teams/teams-formatter.d.ts.map +1 -0
- package/dist/teams/teams-formatter.js +107 -0
- package/dist/teams/teams-formatter.js.map +1 -0
- package/package.json +40 -7
|
@@ -0,0 +1,648 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @memberjunction/messaging-adapters
|
|
3
|
+
* @description Rich Adaptive Card builder functions for Teams agent responses.
|
|
4
|
+
*
|
|
5
|
+
* Composes structured Adaptive Card v1.4 layouts from agent execution results,
|
|
6
|
+
* including agent identity headers, text content, action buttons, explorer
|
|
7
|
+
* deep-links, and metadata footers.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors the layout and feature parity of `slack-block-builder.ts` using
|
|
10
|
+
* Microsoft Adaptive Card elements instead of Slack Block Kit.
|
|
11
|
+
*
|
|
12
|
+
* @see https://adaptivecards.io/designer/
|
|
13
|
+
* @see https://learn.microsoft.com/en-us/adaptive-cards/
|
|
14
|
+
*/
|
|
15
|
+
import { splitMarkdownIntoSections } from '../base/message-formatter.js';
|
|
16
|
+
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
17
|
+
/**
|
|
18
|
+
* Approximate max payload size in bytes for a Teams Adaptive Card.
|
|
19
|
+
* Teams' actual limit is ~28KB for the card itself; we budget 4KB for the
|
|
20
|
+
* Bot Framework activity envelope, leaving 24KB for card content.
|
|
21
|
+
*/
|
|
22
|
+
const TEAMS_MAX_PAYLOAD_BYTES = 24_000;
|
|
23
|
+
/** Adaptive Card schema URL. */
|
|
24
|
+
const ADAPTIVE_CARD_SCHEMA = 'http://adaptivecards.io/schemas/adaptive-card.json';
|
|
25
|
+
/** Adaptive Card version used throughout. */
|
|
26
|
+
const ADAPTIVE_CARD_VERSION = '1.4';
|
|
27
|
+
// ─── Main Composer ───────────────────────────────────────────────────────────
|
|
28
|
+
/**
|
|
29
|
+
* Build the complete Adaptive Card for an agent response.
|
|
30
|
+
*
|
|
31
|
+
* Layout:
|
|
32
|
+
* ```
|
|
33
|
+
* ┌─────────────────────────────────┐
|
|
34
|
+
* │ [Avatar] **Agent Name** │ ← ColumnSet (agent header)
|
|
35
|
+
* │─────────────────────────────────│ ← separator on next element
|
|
36
|
+
* │ Response text (TextBlocks) │ ← from splitMarkdownIntoSections
|
|
37
|
+
* │ │
|
|
38
|
+
* │ ┌─ Artifact link ─────────────┐ │ ← Container (if artifact/conversation)
|
|
39
|
+
* │ │ View in MJ Explorer │ │
|
|
40
|
+
* │ └─────────────────────────────┘ │
|
|
41
|
+
* │ │
|
|
42
|
+
* │ Completed in 4.2s · 1,240 tok │ ← TextBlock (subtle footer)
|
|
43
|
+
* ├─────────────────────────────────┤
|
|
44
|
+
* │ [Action1] [Action2] [Explorer] │ ← actions[] array
|
|
45
|
+
* └─────────────────────────────────┘
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export function buildRichAdaptiveCard(result, agent, responseText, options) {
|
|
49
|
+
const body = [];
|
|
50
|
+
const actions = [];
|
|
51
|
+
// Agent header
|
|
52
|
+
body.push(buildAgentHeader(agent));
|
|
53
|
+
// Text content (with separator from header)
|
|
54
|
+
const textElements = buildTextBody(responseText);
|
|
55
|
+
if (textElements.length > 0) {
|
|
56
|
+
// Add separator to first text element
|
|
57
|
+
textElements[0] = { ...textElements[0], separator: true };
|
|
58
|
+
}
|
|
59
|
+
body.push(...textElements);
|
|
60
|
+
// Media images
|
|
61
|
+
if (result?.mediaOutputs && result.mediaOutputs.length > 0) {
|
|
62
|
+
body.push(...buildMediaElements(result.mediaOutputs));
|
|
63
|
+
}
|
|
64
|
+
// Notification blocks
|
|
65
|
+
const notifications = buildNotificationElements(result?.automaticCommands);
|
|
66
|
+
if (notifications.length > 0) {
|
|
67
|
+
body.push(...notifications);
|
|
68
|
+
}
|
|
69
|
+
// Response form (structured input from agent)
|
|
70
|
+
if (result?.responseForm?.questions && result.responseForm.questions.length > 0) {
|
|
71
|
+
body.push(...buildResponseFormElements(result.responseForm));
|
|
72
|
+
}
|
|
73
|
+
// Metadata footer
|
|
74
|
+
if (result?.agentRun) {
|
|
75
|
+
body.push(buildMetadataFooter(result));
|
|
76
|
+
}
|
|
77
|
+
// Action buttons (go in the card's top-level actions array)
|
|
78
|
+
const commands = result?.actionableCommands;
|
|
79
|
+
if (commands && commands.length > 0) {
|
|
80
|
+
actions.push(...buildActionButtons(commands, options?.explorerBaseURL));
|
|
81
|
+
}
|
|
82
|
+
// "Open in MJ Explorer" action (single action button, no inline body link)
|
|
83
|
+
const explorerAction = buildExplorerLink(options?.explorerBaseURL, options?.artifactId, options?.conversationId);
|
|
84
|
+
if (explorerAction) {
|
|
85
|
+
actions.push(explorerAction);
|
|
86
|
+
}
|
|
87
|
+
// Enforce payload size limit
|
|
88
|
+
const card = assembleCard(body, actions);
|
|
89
|
+
return enforcePayloadSize(card, responseText, options);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Build a ColumnSet showing the agent's avatar and name.
|
|
93
|
+
*/
|
|
94
|
+
export function buildAgentHeader(agent) {
|
|
95
|
+
const agentName = agent.Name ?? 'Agent';
|
|
96
|
+
const columns = [];
|
|
97
|
+
const logoURL = agent.LogoURL;
|
|
98
|
+
if (logoURL && typeof logoURL === 'string' && logoURL.startsWith('https://')) {
|
|
99
|
+
columns.push({
|
|
100
|
+
type: 'Column',
|
|
101
|
+
width: 'auto',
|
|
102
|
+
items: [{
|
|
103
|
+
type: 'Image',
|
|
104
|
+
url: logoURL,
|
|
105
|
+
size: 'Small',
|
|
106
|
+
style: 'Person',
|
|
107
|
+
altText: agentName,
|
|
108
|
+
}],
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
columns.push({
|
|
112
|
+
type: 'Column',
|
|
113
|
+
width: 'stretch',
|
|
114
|
+
verticalContentAlignment: 'Center',
|
|
115
|
+
items: [{
|
|
116
|
+
type: 'TextBlock',
|
|
117
|
+
text: `**${agentName}**`,
|
|
118
|
+
wrap: true,
|
|
119
|
+
weight: 'Bolder',
|
|
120
|
+
}],
|
|
121
|
+
});
|
|
122
|
+
return {
|
|
123
|
+
type: 'ColumnSet',
|
|
124
|
+
columns,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Convert markdown text to Adaptive Card TextBlock elements.
|
|
129
|
+
* Uses `splitMarkdownIntoSections` from the shared message formatter.
|
|
130
|
+
*/
|
|
131
|
+
export function buildTextBody(markdown) {
|
|
132
|
+
const sections = splitMarkdownIntoSections(markdown);
|
|
133
|
+
const elements = [];
|
|
134
|
+
for (const section of sections) {
|
|
135
|
+
switch (section.Type) {
|
|
136
|
+
case 'header':
|
|
137
|
+
elements.push({
|
|
138
|
+
type: 'TextBlock',
|
|
139
|
+
text: section.Content,
|
|
140
|
+
size: 'Large',
|
|
141
|
+
weight: 'Bolder',
|
|
142
|
+
wrap: true,
|
|
143
|
+
spacing: 'Medium',
|
|
144
|
+
});
|
|
145
|
+
break;
|
|
146
|
+
case 'code':
|
|
147
|
+
elements.push({
|
|
148
|
+
type: 'TextBlock',
|
|
149
|
+
text: '```\n' + section.Content + '\n```',
|
|
150
|
+
fontType: 'Monospace',
|
|
151
|
+
wrap: true,
|
|
152
|
+
spacing: 'Small',
|
|
153
|
+
});
|
|
154
|
+
break;
|
|
155
|
+
case 'text':
|
|
156
|
+
elements.push({
|
|
157
|
+
type: 'TextBlock',
|
|
158
|
+
text: section.Content,
|
|
159
|
+
wrap: true,
|
|
160
|
+
});
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Ensure at least one element
|
|
165
|
+
if (elements.length === 0) {
|
|
166
|
+
elements.push({
|
|
167
|
+
type: 'TextBlock',
|
|
168
|
+
text: markdown || '(empty response)',
|
|
169
|
+
wrap: true,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
return elements;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Build an Adaptive Card Container linking to the artifact in MJ Explorer.
|
|
176
|
+
* Returns null if no explorer URL or neither artifact/conversation ID is available.
|
|
177
|
+
*/
|
|
178
|
+
export function buildArtifactCard(artifactId, explorerBaseURL) {
|
|
179
|
+
const base = explorerBaseURL.replace(/\/+$/, '');
|
|
180
|
+
const artifactLink = `${base}/resource/artifact/${encodeURIComponent(artifactId)}`;
|
|
181
|
+
return {
|
|
182
|
+
type: 'Container',
|
|
183
|
+
style: 'emphasis',
|
|
184
|
+
spacing: 'Medium',
|
|
185
|
+
items: [
|
|
186
|
+
{
|
|
187
|
+
type: 'TextBlock',
|
|
188
|
+
text: 'View full artifact in MJ Explorer',
|
|
189
|
+
wrap: true,
|
|
190
|
+
weight: 'Bolder',
|
|
191
|
+
size: 'Small',
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
selectAction: {
|
|
195
|
+
type: 'Action.OpenUrl',
|
|
196
|
+
url: artifactLink,
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Build Action.OpenUrl buttons from actionable commands.
|
|
202
|
+
* Handles `open:url` and `open:resource` command types.
|
|
203
|
+
* Returns at most 5 action buttons.
|
|
204
|
+
*/
|
|
205
|
+
export function buildActionButtons(commands, explorerBaseURL) {
|
|
206
|
+
const actions = [];
|
|
207
|
+
for (const cmd of commands.slice(0, 5)) {
|
|
208
|
+
if (cmd.type === 'open:url' && 'url' in cmd) {
|
|
209
|
+
actions.push({
|
|
210
|
+
type: 'Action.OpenUrl',
|
|
211
|
+
title: truncateToLength(cmd.label ?? 'Open Link', 40),
|
|
212
|
+
url: cmd.url,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
else if (cmd.type === 'open:resource') {
|
|
216
|
+
const resourceCmd = cmd;
|
|
217
|
+
const deepLink = buildExplorerDeepLink(resourceCmd, explorerBaseURL);
|
|
218
|
+
if (deepLink) {
|
|
219
|
+
actions.push({
|
|
220
|
+
type: 'Action.OpenUrl',
|
|
221
|
+
title: truncateToLength(cmd.label ?? 'View in Explorer', 40),
|
|
222
|
+
url: deepLink,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return actions;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Build an "Open in MJ Explorer" Action.OpenUrl.
|
|
231
|
+
* Prefers artifact link; falls back to conversation link.
|
|
232
|
+
* Returns null if neither ID is available or no explorer URL.
|
|
233
|
+
*/
|
|
234
|
+
export function buildExplorerLink(explorerBaseURL, artifactId, conversationId) {
|
|
235
|
+
if (!explorerBaseURL)
|
|
236
|
+
return null;
|
|
237
|
+
if (!conversationId && !artifactId)
|
|
238
|
+
return null;
|
|
239
|
+
const base = explorerBaseURL.replace(/\/+$/, '');
|
|
240
|
+
if (artifactId) {
|
|
241
|
+
return {
|
|
242
|
+
type: 'Action.OpenUrl',
|
|
243
|
+
title: 'View in MJ Explorer',
|
|
244
|
+
url: `${base}/resource/artifact/${encodeURIComponent(artifactId)}`,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
if (conversationId) {
|
|
248
|
+
return {
|
|
249
|
+
type: 'Action.OpenUrl',
|
|
250
|
+
title: 'Open in MJ Explorer',
|
|
251
|
+
url: `${base}/app/Chat/Conversations?conversationId=${encodeURIComponent(conversationId)}`,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Build a subtle metadata footer with timing and token info.
|
|
258
|
+
*/
|
|
259
|
+
export function buildMetadataFooter(result) {
|
|
260
|
+
const parts = [];
|
|
261
|
+
const agentRun = result.agentRun;
|
|
262
|
+
if (agentRun) {
|
|
263
|
+
const startTime = agentRun.StartedAt;
|
|
264
|
+
const endTime = agentRun.CompletedAt;
|
|
265
|
+
if (startTime && endTime) {
|
|
266
|
+
const durationMs = new Date(endTime).getTime() - new Date(startTime).getTime();
|
|
267
|
+
const durationSec = (durationMs / 1000).toFixed(1);
|
|
268
|
+
parts.push(`Completed in ${durationSec}s`);
|
|
269
|
+
}
|
|
270
|
+
const stepCount = agentRun.Steps?.length ?? 0;
|
|
271
|
+
if (stepCount > 0) {
|
|
272
|
+
parts.push(`${stepCount} step${stepCount === 1 ? '' : 's'}`);
|
|
273
|
+
}
|
|
274
|
+
const tokens = agentRun.TotalTokensUsed;
|
|
275
|
+
if (tokens != null && tokens > 0) {
|
|
276
|
+
parts.push(`${tokens.toLocaleString()} tokens`);
|
|
277
|
+
}
|
|
278
|
+
const cost = agentRun.TotalCostRollup ?? agentRun.TotalCost;
|
|
279
|
+
if (cost != null && cost > 0) {
|
|
280
|
+
parts.push(`$${cost.toFixed(cost < 0.01 ? 4 : 2)}`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
type: 'TextBlock',
|
|
285
|
+
text: parts.length > 0 ? parts.join(' · ') : 'Completed',
|
|
286
|
+
size: 'Small',
|
|
287
|
+
isSubtle: true,
|
|
288
|
+
wrap: true,
|
|
289
|
+
spacing: 'Medium',
|
|
290
|
+
separator: true,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Build a full Adaptive Card for an error message.
|
|
295
|
+
*/
|
|
296
|
+
export function buildErrorCard(errorMessage) {
|
|
297
|
+
return {
|
|
298
|
+
type: 'AdaptiveCard',
|
|
299
|
+
version: ADAPTIVE_CARD_VERSION,
|
|
300
|
+
'$schema': ADAPTIVE_CARD_SCHEMA,
|
|
301
|
+
body: [
|
|
302
|
+
{
|
|
303
|
+
type: 'TextBlock',
|
|
304
|
+
text: `⚠️ ${errorMessage}`,
|
|
305
|
+
wrap: true,
|
|
306
|
+
color: 'Attention',
|
|
307
|
+
weight: 'Bolder',
|
|
308
|
+
},
|
|
309
|
+
],
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
// ─── Internal Helpers ────────────────────────────────────────────────────────
|
|
313
|
+
/**
|
|
314
|
+
* Build notification elements from automatic commands.
|
|
315
|
+
*/
|
|
316
|
+
function buildNotificationElements(commands) {
|
|
317
|
+
if (!commands || commands.length === 0)
|
|
318
|
+
return [];
|
|
319
|
+
const elements = [];
|
|
320
|
+
for (const cmd of commands) {
|
|
321
|
+
if (cmd.type !== 'notification')
|
|
322
|
+
continue;
|
|
323
|
+
const icon = NOTIFICATION_ICONS[cmd.severity ?? 'info'];
|
|
324
|
+
elements.push({
|
|
325
|
+
type: 'TextBlock',
|
|
326
|
+
text: `${icon} ${cmd.message}`,
|
|
327
|
+
wrap: true,
|
|
328
|
+
size: 'Small',
|
|
329
|
+
spacing: 'Small',
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
return elements;
|
|
333
|
+
}
|
|
334
|
+
/** Unicode icons for notification severities (Adaptive Cards don't support Slack emoji syntax). */
|
|
335
|
+
const NOTIFICATION_ICONS = {
|
|
336
|
+
success: '✅',
|
|
337
|
+
info: 'ℹ️',
|
|
338
|
+
warning: '⚠️',
|
|
339
|
+
error: '❌',
|
|
340
|
+
};
|
|
341
|
+
/**
|
|
342
|
+
* Build response form elements from an AgentResponseForm.
|
|
343
|
+
*
|
|
344
|
+
* Adaptive Cards support native input elements (Input.Text, Input.Number,
|
|
345
|
+
* Input.Date, Input.Time, Input.ChoiceSet) so we render the form inline
|
|
346
|
+
* in the card body rather than requiring a separate modal.
|
|
347
|
+
*
|
|
348
|
+
* Note: Action.Submit handlers are out of scope — forms are rendered
|
|
349
|
+
* read-only as a summary for now. Full interactivity is follow-up work
|
|
350
|
+
* (requires Task Modules or Action.Submit webhook handling).
|
|
351
|
+
*/
|
|
352
|
+
export function buildResponseFormElements(form) {
|
|
353
|
+
const elements = [];
|
|
354
|
+
// Form title
|
|
355
|
+
if (form.title) {
|
|
356
|
+
elements.push({
|
|
357
|
+
type: 'TextBlock',
|
|
358
|
+
text: `**${form.title}**`,
|
|
359
|
+
wrap: true,
|
|
360
|
+
size: 'Medium',
|
|
361
|
+
weight: 'Bolder',
|
|
362
|
+
spacing: 'Medium',
|
|
363
|
+
separator: true,
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
// Form description
|
|
367
|
+
if (form.description) {
|
|
368
|
+
elements.push({
|
|
369
|
+
type: 'TextBlock',
|
|
370
|
+
text: form.description,
|
|
371
|
+
wrap: true,
|
|
372
|
+
size: 'Small',
|
|
373
|
+
isSubtle: true,
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
// Input elements for each question
|
|
377
|
+
for (const question of form.questions) {
|
|
378
|
+
const inputEl = buildFormInputElement(question);
|
|
379
|
+
if (inputEl) {
|
|
380
|
+
elements.push(inputEl);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
// Submit action rendered as an ActionSet in the body
|
|
384
|
+
// (Action.Submit in an ActionSet is the Adaptive Card pattern for inline forms)
|
|
385
|
+
elements.push({
|
|
386
|
+
type: 'ActionSet',
|
|
387
|
+
actions: [{
|
|
388
|
+
type: 'Action.Submit',
|
|
389
|
+
title: form.submitLabel ?? 'Submit',
|
|
390
|
+
style: 'positive',
|
|
391
|
+
data: { action: 'mj:form_submit' },
|
|
392
|
+
}],
|
|
393
|
+
});
|
|
394
|
+
return elements;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Build the appropriate Adaptive Card input element for a form question.
|
|
398
|
+
*/
|
|
399
|
+
function buildFormInputElement(question) {
|
|
400
|
+
const qType = question.type;
|
|
401
|
+
const baseProps = {
|
|
402
|
+
id: `mj_form_${question.id}`,
|
|
403
|
+
isRequired: question.required ?? false,
|
|
404
|
+
label: question.label,
|
|
405
|
+
errorMessage: question.required ? `${question.label} is required` : undefined,
|
|
406
|
+
};
|
|
407
|
+
switch (qType.type) {
|
|
408
|
+
case 'text':
|
|
409
|
+
case 'email':
|
|
410
|
+
return {
|
|
411
|
+
type: 'Input.Text',
|
|
412
|
+
...baseProps,
|
|
413
|
+
placeholder: qType.placeholder ?? '',
|
|
414
|
+
maxLength: qType.maxLength,
|
|
415
|
+
style: qType.type === 'email' ? 'Email' : 'Text',
|
|
416
|
+
};
|
|
417
|
+
case 'textarea':
|
|
418
|
+
return {
|
|
419
|
+
type: 'Input.Text',
|
|
420
|
+
...baseProps,
|
|
421
|
+
placeholder: qType.placeholder ?? '',
|
|
422
|
+
maxLength: qType.maxLength,
|
|
423
|
+
isMultiline: true,
|
|
424
|
+
};
|
|
425
|
+
case 'number':
|
|
426
|
+
case 'currency':
|
|
427
|
+
return {
|
|
428
|
+
type: 'Input.Number',
|
|
429
|
+
...baseProps,
|
|
430
|
+
min: qType.min,
|
|
431
|
+
max: qType.max,
|
|
432
|
+
placeholder: qType.type === 'currency' ? (qType.prefix ?? '$') + '0.00' : undefined,
|
|
433
|
+
};
|
|
434
|
+
case 'date':
|
|
435
|
+
case 'datetime':
|
|
436
|
+
return {
|
|
437
|
+
type: 'Input.Date',
|
|
438
|
+
...baseProps,
|
|
439
|
+
};
|
|
440
|
+
case 'time':
|
|
441
|
+
return {
|
|
442
|
+
type: 'Input.Time',
|
|
443
|
+
...baseProps,
|
|
444
|
+
};
|
|
445
|
+
case 'buttongroup':
|
|
446
|
+
case 'radio':
|
|
447
|
+
case 'dropdown': {
|
|
448
|
+
const opts = qType.options ?? [];
|
|
449
|
+
return {
|
|
450
|
+
type: 'Input.ChoiceSet',
|
|
451
|
+
...baseProps,
|
|
452
|
+
style: qType.type === 'dropdown' ? 'Compact' : 'Expanded',
|
|
453
|
+
choices: opts.slice(0, 100).map(opt => ({
|
|
454
|
+
title: String(opt.label),
|
|
455
|
+
value: String(opt.value),
|
|
456
|
+
})),
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
case 'checkbox': {
|
|
460
|
+
const opts = qType.options ?? [];
|
|
461
|
+
return {
|
|
462
|
+
type: 'Input.ChoiceSet',
|
|
463
|
+
...baseProps,
|
|
464
|
+
isMultiSelect: true,
|
|
465
|
+
style: 'Expanded',
|
|
466
|
+
choices: opts.slice(0, 100).map(opt => ({
|
|
467
|
+
title: String(opt.label),
|
|
468
|
+
value: String(opt.value),
|
|
469
|
+
})),
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
case 'slider':
|
|
473
|
+
// Adaptive Cards don't have a native slider — use number input with min/max
|
|
474
|
+
return {
|
|
475
|
+
type: 'Input.Number',
|
|
476
|
+
...baseProps,
|
|
477
|
+
min: qType.min,
|
|
478
|
+
max: qType.max,
|
|
479
|
+
placeholder: `${qType.min} - ${qType.max}${qType.suffix ? ' ' + qType.suffix : ''}`,
|
|
480
|
+
};
|
|
481
|
+
case 'daterange':
|
|
482
|
+
// No native date range — render as two date inputs in a ColumnSet
|
|
483
|
+
return {
|
|
484
|
+
type: 'ColumnSet',
|
|
485
|
+
columns: [
|
|
486
|
+
{
|
|
487
|
+
type: 'Column',
|
|
488
|
+
width: 'stretch',
|
|
489
|
+
items: [{
|
|
490
|
+
type: 'Input.Date',
|
|
491
|
+
id: `mj_form_${question.id}_start`,
|
|
492
|
+
label: `${question.label} (Start)`,
|
|
493
|
+
isRequired: question.required ?? false,
|
|
494
|
+
}],
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
type: 'Column',
|
|
498
|
+
width: 'stretch',
|
|
499
|
+
items: [{
|
|
500
|
+
type: 'Input.Date',
|
|
501
|
+
id: `mj_form_${question.id}_end`,
|
|
502
|
+
label: `${question.label} (End)`,
|
|
503
|
+
isRequired: question.required ?? false,
|
|
504
|
+
}],
|
|
505
|
+
},
|
|
506
|
+
],
|
|
507
|
+
};
|
|
508
|
+
default:
|
|
509
|
+
// Fallback to text input
|
|
510
|
+
return {
|
|
511
|
+
type: 'Input.Text',
|
|
512
|
+
...baseProps,
|
|
513
|
+
placeholder: `Enter ${question.label}`,
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Build image elements from media outputs.
|
|
519
|
+
*/
|
|
520
|
+
function buildMediaElements(mediaOutputs) {
|
|
521
|
+
return mediaOutputs
|
|
522
|
+
.filter(m => typeof m.url === 'string' && m.url.startsWith('https://'))
|
|
523
|
+
.slice(0, 5)
|
|
524
|
+
.map(m => ({
|
|
525
|
+
type: 'Image',
|
|
526
|
+
url: m.url,
|
|
527
|
+
altText: m.description ?? m.label ?? 'Agent output',
|
|
528
|
+
size: 'Large',
|
|
529
|
+
spacing: 'Medium',
|
|
530
|
+
}));
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Build a deep link URL into MJ Explorer for an `open:resource` command.
|
|
534
|
+
*/
|
|
535
|
+
function buildExplorerDeepLink(cmd, explorerBaseURL) {
|
|
536
|
+
if (!explorerBaseURL)
|
|
537
|
+
return null;
|
|
538
|
+
const base = explorerBaseURL.replace(/\/+$/, '');
|
|
539
|
+
switch (cmd.resourceType) {
|
|
540
|
+
case 'Record':
|
|
541
|
+
if (cmd.entityName && cmd.resourceId) {
|
|
542
|
+
const entity = encodeURIComponent(cmd.entityName);
|
|
543
|
+
const id = encodeURIComponent(cmd.resourceId);
|
|
544
|
+
return `${base}/resource/record/${entity}/${id}`;
|
|
545
|
+
}
|
|
546
|
+
break;
|
|
547
|
+
case 'Dashboard':
|
|
548
|
+
return `${base}/resource/dashboard/${encodeURIComponent(cmd.resourceId)}`;
|
|
549
|
+
case 'Report':
|
|
550
|
+
return `${base}/resource/report/${encodeURIComponent(cmd.resourceId)}`;
|
|
551
|
+
case 'View':
|
|
552
|
+
return `${base}/resource/view/${encodeURIComponent(cmd.resourceId)}`;
|
|
553
|
+
}
|
|
554
|
+
return null;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Assemble the final Adaptive Card JSON structure.
|
|
558
|
+
*/
|
|
559
|
+
function assembleCard(body, actions) {
|
|
560
|
+
const card = {
|
|
561
|
+
type: 'AdaptiveCard',
|
|
562
|
+
version: ADAPTIVE_CARD_VERSION,
|
|
563
|
+
'$schema': ADAPTIVE_CARD_SCHEMA,
|
|
564
|
+
body,
|
|
565
|
+
};
|
|
566
|
+
if (actions.length > 0) {
|
|
567
|
+
card.actions = actions;
|
|
568
|
+
}
|
|
569
|
+
return card;
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Enforce the Teams payload size limit via progressive truncation.
|
|
573
|
+
*
|
|
574
|
+
* Strategy:
|
|
575
|
+
* 1. If under budget, return as-is
|
|
576
|
+
* 2. Truncate long TextBlocks to 500 chars
|
|
577
|
+
* 3. Truncate to 200 chars
|
|
578
|
+
* 4. Remove tail body elements
|
|
579
|
+
* 5. Add "View full in MJ Explorer" link if available
|
|
580
|
+
*/
|
|
581
|
+
function enforcePayloadSize(card, fullText, options) {
|
|
582
|
+
let serialized = JSON.stringify(card);
|
|
583
|
+
if (serialized.length <= TEAMS_MAX_PAYLOAD_BYTES)
|
|
584
|
+
return card;
|
|
585
|
+
const body = card.body;
|
|
586
|
+
// Pass 1: truncate TextBlocks to 500 chars
|
|
587
|
+
let trimmedBody = truncateTextBlocks(body, 500);
|
|
588
|
+
let trimmedCard = { ...card, body: trimmedBody };
|
|
589
|
+
serialized = JSON.stringify(trimmedCard);
|
|
590
|
+
if (serialized.length <= TEAMS_MAX_PAYLOAD_BYTES)
|
|
591
|
+
return trimmedCard;
|
|
592
|
+
// Pass 2: truncate TextBlocks to 200 chars
|
|
593
|
+
trimmedBody = truncateTextBlocks(body, 200);
|
|
594
|
+
trimmedCard = { ...card, body: trimmedBody };
|
|
595
|
+
serialized = JSON.stringify(trimmedCard);
|
|
596
|
+
if (serialized.length <= TEAMS_MAX_PAYLOAD_BYTES)
|
|
597
|
+
return trimmedCard;
|
|
598
|
+
// Pass 3: remove tail body elements (keep header + at least 1 text element)
|
|
599
|
+
const reduced = [...trimmedBody];
|
|
600
|
+
while (reduced.length > 2 && JSON.stringify({ ...card, body: reduced }).length > TEAMS_MAX_PAYLOAD_BYTES) {
|
|
601
|
+
reduced.splice(reduced.length - 1, 1);
|
|
602
|
+
}
|
|
603
|
+
// Add truncation notice
|
|
604
|
+
reduced.push({
|
|
605
|
+
type: 'TextBlock',
|
|
606
|
+
text: '_Response truncated due to length._',
|
|
607
|
+
wrap: true,
|
|
608
|
+
isSubtle: true,
|
|
609
|
+
size: 'Small',
|
|
610
|
+
spacing: 'Medium',
|
|
611
|
+
});
|
|
612
|
+
// Add "View full in MJ Explorer" action if possible
|
|
613
|
+
const explorerLink = buildExplorerLink(options?.explorerBaseURL, options?.artifactId, options?.conversationId);
|
|
614
|
+
const actions = card.actions ?? [];
|
|
615
|
+
const finalActions = explorerLink
|
|
616
|
+
? [...actions.filter(a => a.title !== 'View in MJ Explorer' && a.title !== 'Open in MJ Explorer'), explorerLink]
|
|
617
|
+
: actions;
|
|
618
|
+
return {
|
|
619
|
+
...card,
|
|
620
|
+
body: reduced,
|
|
621
|
+
...(finalActions.length > 0 ? { actions: finalActions } : {}),
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Clone body elements with TextBlock text fields truncated to maxChars.
|
|
626
|
+
*/
|
|
627
|
+
function truncateTextBlocks(body, maxChars) {
|
|
628
|
+
return body.map(element => {
|
|
629
|
+
if (element.type !== 'TextBlock')
|
|
630
|
+
return element;
|
|
631
|
+
const text = element.text;
|
|
632
|
+
if (typeof text !== 'string' || text.length <= maxChars)
|
|
633
|
+
return element;
|
|
634
|
+
return {
|
|
635
|
+
...element,
|
|
636
|
+
text: text.substring(0, maxChars) + '...',
|
|
637
|
+
};
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Truncate a string to a given length with ellipsis.
|
|
642
|
+
*/
|
|
643
|
+
function truncateToLength(text, maxLength) {
|
|
644
|
+
if (text.length <= maxLength)
|
|
645
|
+
return text;
|
|
646
|
+
return text.substring(0, maxLength - 3) + '...';
|
|
647
|
+
}
|
|
648
|
+
//# sourceMappingURL=teams-card-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teams-card-builder.js","sourceRoot":"","sources":["../../src/teams/teams-card-builder.ts"],"names":[],"mappings":"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"}
|