feat(msteams): add MS Teams provider skeleton

- Add Microsoft 365 Agents SDK packages (@microsoft/agents-hosting,
  @microsoft/agents-hosting-express, @microsoft/agents-hosting-extensions-teams)
- Add MSTeamsConfig type and zod schema
- Create src/msteams/ provider with monitor, token, send, probe
- Wire provider into gateway (server-providers.ts, server.ts)
- Add msteams to all provider type unions (hooks, queue, cron, etc.)
- Update implementation guide with new SDK and progress
This commit is contained in:
Onur
2026-01-07 21:29:39 +03:00
committed by Peter Steinberger
parent 7274d6e757
commit d9cbecac7f
16 changed files with 708 additions and 41 deletions

View File

@@ -109,6 +109,8 @@ const requireOpenAllowFrom = (params: {
});
};
const MSTeamsReplyStyleSchema = z.enum(["thread", "top-level"]);
const RetryConfigSchema = z
.object({
attempts: z.number().int().min(1).optional(),
@@ -126,6 +128,7 @@ const QueueModeBySurfaceSchema = z
slack: QueueModeSchema.optional(),
signal: QueueModeSchema.optional(),
imessage: QueueModeSchema.optional(),
msteams: QueueModeSchema.optional(),
webchat: QueueModeSchema.optional(),
})
.optional();
@@ -455,6 +458,48 @@ const IMessageConfigSchema = IMessageAccountSchemaBase.extend({
});
});
const MSTeamsChannelSchema = z.object({
requireMention: z.boolean().optional(),
replyStyle: MSTeamsReplyStyleSchema.optional(),
});
const MSTeamsTeamSchema = z.object({
requireMention: z.boolean().optional(),
replyStyle: MSTeamsReplyStyleSchema.optional(),
channels: z.record(z.string(), MSTeamsChannelSchema.optional()).optional(),
});
const MSTeamsConfigSchema = z
.object({
enabled: z.boolean().optional(),
appId: z.string().optional(),
appPassword: z.string().optional(),
tenantId: z.string().optional(),
webhook: z
.object({
port: z.number().int().positive().optional(),
path: z.string().optional(),
})
.optional(),
dmPolicy: DmPolicySchema.optional().default("pairing"),
allowFrom: z.array(z.string()).optional(),
textChunkLimit: z.number().int().positive().optional(),
mediaAllowHosts: z.array(z.string()).optional(),
requireMention: z.boolean().optional(),
replyStyle: MSTeamsReplyStyleSchema.optional(),
teams: z.record(z.string(), MSTeamsTeamSchema.optional()).optional(),
})
.superRefine((value, ctx) => {
requireOpenAllowFrom({
policy: value.dmPolicy,
allowFrom: value.allowFrom,
ctx,
path: ["allowFrom"],
message:
'msteams.dmPolicy="open" requires msteams.allowFrom to include "*"',
});
});
const SessionSchema = z
.object({
scope: z.union([z.literal("per-sender"), z.literal("global")]).optional(),
@@ -742,6 +787,7 @@ const HookMappingSchema = z
z.literal("slack"),
z.literal("signal"),
z.literal("imessage"),
z.literal("msteams"),
])
.optional(),
to: z.string().optional(),
@@ -1049,6 +1095,7 @@ export const ClawdbotSchema = z.object({
slack: z.array(z.union([z.string(), z.number()])).optional(),
signal: z.array(z.union([z.string(), z.number()])).optional(),
imessage: z.array(z.union([z.string(), z.number()])).optional(),
msteams: z.array(z.union([z.string(), z.number()])).optional(),
webchat: z.array(z.union([z.string(), z.number()])).optional(),
})
.optional(),
@@ -1205,6 +1252,7 @@ export const ClawdbotSchema = z.object({
slack: SlackConfigSchema.optional(),
signal: SignalConfigSchema.optional(),
imessage: IMessageConfigSchema.optional(),
msteams: MSTeamsConfigSchema.optional(),
bridge: z
.object({
enabled: z.boolean().optional(),
@@ -1283,8 +1331,6 @@ export const ClawdbotSchema = z.object({
remote: z
.object({
url: z.string().optional(),
sshTarget: z.string().optional(),
sshIdentity: z.string().optional(),
token: z.string().optional(),
password: z.string().optional(),
})