Files
openclaw/extensions/msteams/src/welcome-card.ts
Sid Uppal cd90130877 msteams: implement Teams AI agent UX best practices (#51808)
Migrates the Teams extension from @microsoft/agents-hosting to the official Teams SDK (@microsoft/teams.apps + @microsoft/teams.api) and implements Microsoft's AI UX best practices for Teams agents.

- AI-generated label on all bot messages (Teams native badge + thumbs up/down)
- Streaming responses in 1:1 chats via Teams streaminfo protocol
- Welcome card with configurable prompt starters on bot install
- Feedback with reflective learning (negative feedback triggers background reflection)
- Typing indicators for personal + group chats (disabled for channels)
- Informative status updates (progress bar while LLM processes)
- JWT validation via Teams SDK createServiceTokenValidator
- User-Agent: teams.ts[apps]/<sdk-version> OpenClaw/<version> on outbound requests
- Fix copy-pasted image downloads (smba.trafficmanager.net auth allowlist)
- Pre-parse auth gate (reject unauthenticated requests before body parsing)
- Reflection dispatcher lifecycle fix (prevent leaked dispatchers)
- Colon-safe session filenames (Windows compatibility)
- Cooldown cache eviction (prevent unbounded memory growth)

Closes #51806
2026-03-23 22:03:39 -07:00

58 lines
1.5 KiB
TypeScript

/**
* Builds an Adaptive Card for welcoming users when the bot is added to a conversation.
*/
const DEFAULT_PROMPT_STARTERS = [
"What can you do?",
"Summarize my last meeting",
"Help me draft an email",
];
export type WelcomeCardOptions = {
/** Bot display name. Falls back to "OpenClaw". */
botName?: string;
/** Custom prompt starters. Falls back to defaults. */
promptStarters?: string[];
};
/**
* Build a welcome Adaptive Card for 1:1 personal chats.
*/
export function buildWelcomeCard(options?: WelcomeCardOptions): Record<string, unknown> {
const botName = options?.botName || "OpenClaw";
const starters = options?.promptStarters?.length
? options.promptStarters
: DEFAULT_PROMPT_STARTERS;
return {
type: "AdaptiveCard",
version: "1.5",
body: [
{
type: "TextBlock",
text: `Hi! I'm ${botName}.`,
weight: "bolder",
size: "medium",
},
{
type: "TextBlock",
text: "I can help you with questions, tasks, and more. Here are some things to try:",
wrap: true,
},
],
actions: starters.map((label) => ({
type: "Action.Submit",
title: label,
data: { msteams: { type: "imBack", value: label } },
})),
};
}
/**
* Build a brief welcome message for group chats (when the bot is @mentioned).
*/
export function buildGroupWelcomeText(botName?: string): string {
const name = botName || "OpenClaw";
return `Hi! I'm ${name}. Mention me with @${name} to get started.`;
}