@hahnfeld/teams-adapter 1.2.0 → 1.3.1
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 +81 -28
- package/dist/adapter.d.ts +16 -25
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +154 -233
- package/dist/adapter.js.map +1 -1
- package/dist/app-package.d.ts.map +1 -1
- package/dist/app-package.js +14 -0
- package/dist/app-package.js.map +1 -1
- package/dist/formatting.d.ts +0 -57
- package/dist/formatting.d.ts.map +1 -1
- package/dist/formatting.js +0 -183
- package/dist/formatting.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/message-composer.d.ts +94 -0
- package/dist/message-composer.d.ts.map +1 -0
- package/dist/message-composer.js +331 -0
- package/dist/message-composer.js.map +1 -0
- package/dist/rate-limiter.d.ts +17 -0
- package/dist/rate-limiter.d.ts.map +1 -0
- package/dist/rate-limiter.js +201 -0
- package/dist/rate-limiter.js.map +1 -0
- package/package.json +13 -5
- package/dist/draft-manager.d.ts +0 -69
- package/dist/draft-manager.d.ts.map +0 -1
- package/dist/draft-manager.js +0 -333
- package/dist/draft-manager.js.map +0 -1
- package/dist/renderer.d.ts +0 -49
- package/dist/renderer.d.ts.map +0 -1
- package/dist/renderer.js +0 -55
- package/dist/renderer.js.map +0 -1
- package/dist/task-modules.d.ts +0 -34
- package/dist/task-modules.d.ts.map +0 -1
- package/dist/task-modules.js +0 -136
- package/dist/task-modules.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# @hahnfeld/teams-adapter
|
|
2
2
|
|
|
3
|
-
Microsoft Teams adapter plugin for [OpenACP](https://github.com/Open-ACP/OpenACP) —
|
|
3
|
+
Microsoft Teams adapter plugin for [OpenACP](https://github.com/Open-ACP/OpenACP) — real-time streaming, rich message composition, slash commands.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **
|
|
7
|
+
- **Streaming Message Composer** — Single message per session with live-updating header (tool activity), body (streamed text), and footer (usage/completion)
|
|
8
|
+
- **Per-conversation Rate Limiter** — Multi-window sliding rate limiter (6/1s, 7/2s, 55/30s, 1700/hr) with operation coalescing
|
|
8
9
|
- **Slash Commands** — Full command suite: `/new`, `/cancel`, `/agents`, `/menu`, and more
|
|
9
|
-
- **Streaming** — Real-time text updates via Teams message editing
|
|
10
10
|
- **Threads** — Session threads within Teams channels
|
|
11
11
|
- **Permissions** — Allow/Deny/Always Allow via Adaptive Card buttons
|
|
12
12
|
- **Output Modes** — Low/Medium/High detail levels
|
|
@@ -185,6 +185,26 @@ Set the tunnel URL as the messaging endpoint in Azure: `https://<id>.devtunnels.
|
|
|
185
185
|
|
|
186
186
|
> **Important:** Always use `--allow-anonymous` — Azure Bot Service cannot authenticate with Dev Tunnel auth.
|
|
187
187
|
|
|
188
|
+
## Security
|
|
189
|
+
|
|
190
|
+
The bot operates within your Azure AD tenant (single-tenant configuration), which prevents external access. However, in a large enterprise with thousands of employees, tenant-level auth alone may not be sufficient — **any user in your organization** who can sideload a Teams app could create their own app manifest pointing to the same bot App ID and gain access to agent sessions, your configured workspace, and any tools available to the agent.
|
|
191
|
+
|
|
192
|
+
**Recommended:** Configure the built-in `@openacp/security` plugin to restrict which users can interact with the bot:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
openacp plugin configure @openacp/security
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Add your Teams user ID to the `allowedUserIds` list. The security plugin registers middleware on all incoming messages at the OpenACP core level, blocking unauthorized users before any adapter code runs. You can find your Teams user ID in the OpenACP logs when you send a message (the `userId` field).
|
|
199
|
+
|
|
200
|
+
**Additional controls:**
|
|
201
|
+
|
|
202
|
+
- **Teams Admin Center** — Use app permission policies to restrict who can install the sideloaded app
|
|
203
|
+
- **Azure Bot Configuration** — Single-tenant bots already reject users outside your Azure AD tenant
|
|
204
|
+
- **Network** — The bot is only reachable via your tunnel URL; restrict tunnel access if your provider supports it
|
|
205
|
+
|
|
206
|
+
> **Important:** Without an `allowedUserIds` configuration, any authenticated user in your tenant can execute agent commands, create sessions, and access your configured workspace through the bot.
|
|
207
|
+
|
|
188
208
|
## Slash Commands
|
|
189
209
|
|
|
190
210
|
| Command | Description |
|
|
@@ -241,35 +261,68 @@ pnpm test
|
|
|
241
261
|
|
|
242
262
|
## Architecture
|
|
243
263
|
|
|
264
|
+
### Message Rendering Model
|
|
265
|
+
|
|
266
|
+
All agent output is consolidated into a single Teams message per turn, edited in place:
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
┌─────────────────────────────────────────────┐
|
|
270
|
+
│ **Session Name** │ ← TITLE (persistent, bold)
|
|
271
|
+
│ *🔧 Reading file src/adapter.ts...* │ ← HEADER (ephemeral, italic)
|
|
272
|
+
│─────────────────────────────────────────────│
|
|
273
|
+
│ │
|
|
274
|
+
│ Here's what I found in the adapter... │ ← BODY (streamed text + attachments)
|
|
275
|
+
│ The function handles three cases: │
|
|
276
|
+
│ │
|
|
277
|
+
│─────────────────────────────────────────────│
|
|
278
|
+
│ *44k tokens · $0.14 · Task completed* │ ← FOOTER (persistent, italic)
|
|
279
|
+
└─────────────────────────────────────────────┘
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
| Message Type | Zone | Behavior |
|
|
283
|
+
|---|---|---|
|
|
284
|
+
| `text` | Body | Streamed, edited in place |
|
|
285
|
+
| `thought` | Header | Ephemeral, 💭 prefix, replaced by next header |
|
|
286
|
+
| `tool_call` | Header | Ephemeral, 🔧 prefix, replaced by next header |
|
|
287
|
+
| `tool_update` | Header | Ephemeral, 🔧 prefix, replaced by next header |
|
|
288
|
+
| `usage` | Footer | Persistent, dot-separated stats + "Task completed" |
|
|
289
|
+
| `plan` | Separate | Single message, updated in place per session |
|
|
290
|
+
| `error` | Separate | Standalone ❌ message |
|
|
291
|
+
| `mode_change` | Separate | ⚙️ prefix |
|
|
292
|
+
| `config_update` | Separate | ⚙️ prefix |
|
|
293
|
+
| `model_update` | Separate | ⚙️ prefix |
|
|
294
|
+
| `system_message` | Separate | ⚙️ prefix |
|
|
295
|
+
|
|
296
|
+
### Source Layout
|
|
297
|
+
|
|
244
298
|
```
|
|
245
299
|
src/
|
|
246
|
-
├── index.ts
|
|
247
|
-
├── plugin.ts
|
|
248
|
-
├── adapter.ts
|
|
249
|
-
├──
|
|
250
|
-
├──
|
|
251
|
-
├──
|
|
252
|
-
├──
|
|
253
|
-
├──
|
|
254
|
-
├── permissions.ts
|
|
255
|
-
├── graph.ts
|
|
256
|
-
├── media.ts
|
|
300
|
+
├── index.ts # Plugin entry point & public exports
|
|
301
|
+
├── plugin.ts # Plugin factory (install wizard, configure, setup/teardown)
|
|
302
|
+
├── adapter.ts # TeamsAdapter — extends MessagingAdapter
|
|
303
|
+
├── message-composer.ts # SessionMessage (title/header/body/footer zones)
|
|
304
|
+
├── rate-limiter.ts # Per-conversation rate limiter with coalescing
|
|
305
|
+
├── app-package.ts # Teams app manifest package generator
|
|
306
|
+
├── activity.ts # Type re-exports from plugin-sdk
|
|
307
|
+
├── formatting.ts # Text formatting helpers (tool summaries, plans, usage)
|
|
308
|
+
├── permissions.ts # PermissionHandler (Adaptive Card buttons)
|
|
309
|
+
├── graph.ts # GraphFileClient (OneDrive file sharing)
|
|
310
|
+
├── media.ts # File download/upload utilities
|
|
257
311
|
├── conversation-store.ts # Conversation reference storage
|
|
258
|
-
├── send-utils.ts
|
|
259
|
-
├──
|
|
260
|
-
├──
|
|
261
|
-
├──
|
|
262
|
-
├── types.ts # TeamsChannelConfig, TeamsPlatformData
|
|
312
|
+
├── send-utils.ts # Message sending helpers (Teams SDK compat)
|
|
313
|
+
├── assistant.ts # Assistant session spawning
|
|
314
|
+
├── validators.ts # Credential & tenant validation, Teams link parsing
|
|
315
|
+
├── types.ts # TeamsChannelConfig, TeamsPlatformData
|
|
263
316
|
└── commands/
|
|
264
|
-
├── index.ts
|
|
265
|
-
├── new-session.ts
|
|
266
|
-
├── session.ts
|
|
267
|
-
├── admin.ts
|
|
268
|
-
├── menu.ts
|
|
269
|
-
├── agents.ts
|
|
270
|
-
├── doctor.ts
|
|
271
|
-
├── integrate.ts
|
|
272
|
-
└── settings.ts
|
|
317
|
+
├── index.ts # Command router + SLASH_COMMANDS registry
|
|
318
|
+
├── new-session.ts # /new, /newchat
|
|
319
|
+
├── session.ts # /cancel, /status, /sessions, /handoff
|
|
320
|
+
├── admin.ts # /bypass, /tts, /restart, /respawn, /update, /outputmode
|
|
321
|
+
├── menu.ts # /menu, /help, /clear
|
|
322
|
+
├── agents.ts # /agents, /install
|
|
323
|
+
├── doctor.ts # /doctor
|
|
324
|
+
├── integrate.ts # /integrate
|
|
325
|
+
└── settings.ts # /settings
|
|
273
326
|
```
|
|
274
327
|
|
|
275
328
|
## Tech Stack
|
package/dist/adapter.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { TurnContext } from "@microsoft/agents-hosting";
|
|
2
|
-
import type { OutgoingMessage, PermissionRequest, NotificationMessage, OpenACPCore, DisplayVerbosity, AdapterCapabilities
|
|
2
|
+
import type { OutgoingMessage, PermissionRequest, NotificationMessage, OpenACPCore, DisplayVerbosity, AdapterCapabilities } from "@openacp/plugin-sdk";
|
|
3
3
|
import { MessagingAdapter } from "@openacp/plugin-sdk";
|
|
4
|
+
import type { IRenderer } from "@openacp/plugin-sdk";
|
|
4
5
|
import type { TeamsChannelConfig } from "./types.js";
|
|
5
6
|
export declare class TeamsAdapter extends MessagingAdapter {
|
|
6
7
|
readonly name = "teams";
|
|
@@ -9,8 +10,8 @@ export declare class TeamsAdapter extends MessagingAdapter {
|
|
|
9
10
|
readonly core: OpenACPCore;
|
|
10
11
|
private app;
|
|
11
12
|
private teamsConfig;
|
|
12
|
-
private
|
|
13
|
-
private
|
|
13
|
+
private rateLimiter;
|
|
14
|
+
private composer;
|
|
14
15
|
private permissionHandler;
|
|
15
16
|
private notificationChannelId?;
|
|
16
17
|
private assistantSession;
|
|
@@ -24,16 +25,6 @@ export declare class TeamsAdapter extends MessagingAdapter {
|
|
|
24
25
|
*/
|
|
25
26
|
private _sessionContexts;
|
|
26
27
|
private _sessionOutputModes;
|
|
27
|
-
/**
|
|
28
|
-
* Per-session serial dispatch queues — matches Telegram's _dispatchQueues pattern.
|
|
29
|
-
* SessionBridge fires sendMessage() as fire-and-forget, so multiple events can arrive
|
|
30
|
-
* concurrently. Without serialization, fast handlers overtake slow ones, causing
|
|
31
|
-
* out-of-order delivery. This queue ensures events are processed in arrival order.
|
|
32
|
-
*
|
|
33
|
-
* Entries are replaced with Promise.resolve() once their chain settles, preventing
|
|
34
|
-
* unbounded closure growth for long-lived sessions.
|
|
35
|
-
*/
|
|
36
|
-
private _dispatchQueues;
|
|
37
28
|
/** Track processed activity IDs to handle Teams 15-second retry deduplication */
|
|
38
29
|
private _processedActivities;
|
|
39
30
|
private _processedCleanupTimer?;
|
|
@@ -113,19 +104,18 @@ export declare class TeamsAdapter extends MessagingAdapter {
|
|
|
113
104
|
/**
|
|
114
105
|
* Primary outbound dispatch — routes agent messages to Teams.
|
|
115
106
|
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* preventing fast handlers from overtaking slower ones (matches Telegram pattern).
|
|
119
|
-
*
|
|
120
|
-
* Context is NOT deleted after dispatch — it persists from the inbound message handler
|
|
121
|
-
* and is available for the entire session lifetime, avoiding the race condition where
|
|
122
|
-
* async handlers lose their context mid-execution.
|
|
107
|
+
* Routes agent messages to Teams. The rate limiter handles per-conversation
|
|
108
|
+
* serialization and throttling.
|
|
123
109
|
*/
|
|
124
110
|
sendMessage(sessionId: string, content: OutgoingMessage): Promise<void>;
|
|
125
|
-
protected handleThought(
|
|
111
|
+
protected handleThought(sessionId: string, content: OutgoingMessage, _verbosity: DisplayVerbosity): Promise<void>;
|
|
126
112
|
protected handleText(sessionId: string, content: OutgoingMessage): Promise<void>;
|
|
127
|
-
protected handleToolCall(sessionId: string, content: OutgoingMessage,
|
|
128
|
-
protected handleToolUpdate(sessionId: string, content: OutgoingMessage,
|
|
113
|
+
protected handleToolCall(sessionId: string, content: OutgoingMessage, _verbosity: DisplayVerbosity): Promise<void>;
|
|
114
|
+
protected handleToolUpdate(sessionId: string, content: OutgoingMessage, _verbosity: DisplayVerbosity): Promise<void>;
|
|
115
|
+
/** Set the session title on the composer if not already set. */
|
|
116
|
+
private ensureSessionTitle;
|
|
117
|
+
/** Per-session plan send mutex to prevent TOCTOU race on first plan message. */
|
|
118
|
+
private _planSending;
|
|
129
119
|
protected handlePlan(sessionId: string, content: OutgoingMessage, _verbosity: DisplayVerbosity): Promise<void>;
|
|
130
120
|
protected handleUsage(sessionId: string, content: OutgoingMessage, _verbosity: DisplayVerbosity): Promise<void>;
|
|
131
121
|
/** Suggested quick-reply actions (Teams restricts these to 1:1 personal chat only) */
|
|
@@ -133,14 +123,15 @@ export declare class TeamsAdapter extends MessagingAdapter {
|
|
|
133
123
|
/** Return QUICK_ACTIONS only if the conversation is 1:1 personal chat (Teams requirement) */
|
|
134
124
|
private getQuickActions;
|
|
135
125
|
/**
|
|
136
|
-
* Clean up all per-session state (contexts,
|
|
137
|
-
* Removes both sessionId and threadId entries from _sessionContexts to prevent leaks.
|
|
126
|
+
* Clean up all per-session state (contexts, composer, output modes).
|
|
138
127
|
*/
|
|
139
128
|
private cleanupSessionState;
|
|
140
129
|
protected handleSessionEnd(sessionId: string, _content: OutgoingMessage): Promise<void>;
|
|
141
130
|
protected handleError(sessionId: string, content: OutgoingMessage): Promise<void>;
|
|
142
131
|
protected handleAttachment(sessionId: string, content: OutgoingMessage): Promise<void>;
|
|
143
132
|
protected handleSystem(sessionId: string, content: OutgoingMessage): Promise<void>;
|
|
133
|
+
/** Sanitize metadata strings for safe markdown interpolation. */
|
|
134
|
+
private static sanitizeMd;
|
|
144
135
|
protected handleModeChange(sessionId: string, content: OutgoingMessage): Promise<void>;
|
|
145
136
|
protected handleConfigUpdate(sessionId: string, content: OutgoingMessage): Promise<void>;
|
|
146
137
|
protected handleModelUpdate(sessionId: string, content: OutgoingMessage): Promise<void>;
|
package/dist/adapter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAQ7D,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EAGnB,WAAW,EAEX,gBAAgB,EAChB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
|