fix: msteams attachments + plugin prompt hints
Co-authored-by: Christof <10854026+Evizero@users.noreply.github.com>
This commit is contained in:
@@ -17,7 +17,7 @@ import {
|
||||
resolveMSTeamsChannelAllowlist,
|
||||
resolveMSTeamsUserAllowlist,
|
||||
} from "./resolve-allowlist.js";
|
||||
import { sendMessageMSTeams } from "./send.js";
|
||||
import { sendAdaptiveCardMSTeams, sendMessageMSTeams } from "./send.js";
|
||||
import { resolveMSTeamsCredentials } from "./token.js";
|
||||
import {
|
||||
listMSTeamsDirectoryGroupsLive,
|
||||
@@ -64,6 +64,19 @@ export const msteamsPlugin: ChannelPlugin<ResolvedMSTeamsAccount> = {
|
||||
threads: true,
|
||||
media: true,
|
||||
},
|
||||
agentPrompt: {
|
||||
messageToolHints: () => [
|
||||
"- Adaptive Cards supported. Use `action=send` with `card={type,version,body}` to send rich cards.",
|
||||
"- MSTeams targeting: omit `target` to reply to the current conversation (auto-inferred). Explicit targets: `user:ID` or `user:Display Name` (requires Graph API) for DMs, `conversation:19:...@thread.tacv2` for groups/channels. Prefer IDs over display names for speed.",
|
||||
],
|
||||
},
|
||||
threading: {
|
||||
buildToolContext: ({ context, hasRepliedRef }) => ({
|
||||
currentChannelId: context.To?.trim() || undefined,
|
||||
currentThreadTs: context.ReplyToId,
|
||||
hasRepliedRef,
|
||||
}),
|
||||
},
|
||||
reload: { configPrefixes: ["channels.msteams"] },
|
||||
configSchema: buildChannelConfigSchema(MSTeamsConfigSchema),
|
||||
config: {
|
||||
@@ -137,7 +150,12 @@ export const msteamsPlugin: ChannelPlugin<ResolvedMSTeamsAccount> = {
|
||||
looksLikeId: (raw) => {
|
||||
const trimmed = raw.trim();
|
||||
if (!trimmed) return false;
|
||||
if (/^(conversation:|user:)/i.test(trimmed)) return true;
|
||||
if (/^conversation:/i.test(trimmed)) return true;
|
||||
if (/^user:/i.test(trimmed)) {
|
||||
// Only treat as ID if the value after user: looks like a UUID
|
||||
const id = trimmed.slice("user:".length).trim();
|
||||
return /^[0-9a-fA-F-]{16,}$/.test(id);
|
||||
}
|
||||
return trimmed.includes("@thread");
|
||||
},
|
||||
hint: "<conversationId|user:ID|conversation:ID>",
|
||||
@@ -320,6 +338,50 @@ export const msteamsPlugin: ChannelPlugin<ResolvedMSTeamsAccount> = {
|
||||
if (!enabled) return [];
|
||||
return ["poll"] satisfies ChannelMessageActionName[];
|
||||
},
|
||||
supportsCards: ({ cfg }) => {
|
||||
return (
|
||||
cfg.channels?.msteams?.enabled !== false &&
|
||||
Boolean(resolveMSTeamsCredentials(cfg.channels?.msteams))
|
||||
);
|
||||
},
|
||||
handleAction: async (ctx) => {
|
||||
// Handle send action with card parameter
|
||||
if (ctx.action === "send" && ctx.params.card) {
|
||||
const card = ctx.params.card as Record<string, unknown>;
|
||||
const to =
|
||||
typeof ctx.params.to === "string"
|
||||
? ctx.params.to.trim()
|
||||
: typeof ctx.params.target === "string"
|
||||
? ctx.params.target.trim()
|
||||
: "";
|
||||
if (!to) {
|
||||
return {
|
||||
isError: true,
|
||||
content: [{ type: "text", text: "Card send requires a target (to)." }],
|
||||
};
|
||||
}
|
||||
const result = await sendAdaptiveCardMSTeams({
|
||||
cfg: ctx.cfg,
|
||||
to,
|
||||
card,
|
||||
});
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify({
|
||||
ok: true,
|
||||
channel: "msteams",
|
||||
messageId: result.messageId,
|
||||
conversationId: result.conversationId,
|
||||
}),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
// Return null to fall through to default handler
|
||||
return null as never;
|
||||
},
|
||||
},
|
||||
outbound: msteamsOutbound,
|
||||
status: {
|
||||
|
||||
Reference in New Issue
Block a user