@hahnfeld/teams-adapter 1.1.1 → 1.3.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.
Files changed (71) hide show
  1. package/README.md +81 -28
  2. package/dist/activity.d.ts +0 -20
  3. package/dist/activity.d.ts.map +1 -1
  4. package/dist/adapter.d.ts +15 -24
  5. package/dist/adapter.d.ts.map +1 -1
  6. package/dist/adapter.js +161 -222
  7. package/dist/adapter.js.map +1 -1
  8. package/dist/assistant.d.ts +0 -1
  9. package/dist/assistant.d.ts.map +1 -1
  10. package/dist/assistant.js +0 -3
  11. package/dist/assistant.js.map +1 -1
  12. package/dist/commands/agents.d.ts +0 -1
  13. package/dist/commands/agents.d.ts.map +1 -1
  14. package/dist/commands/agents.js +0 -3
  15. package/dist/commands/agents.js.map +1 -1
  16. package/dist/commands/doctor.d.ts +0 -1
  17. package/dist/commands/doctor.d.ts.map +1 -1
  18. package/dist/commands/doctor.js +0 -3
  19. package/dist/commands/doctor.js.map +1 -1
  20. package/dist/commands/integrate.d.ts +0 -1
  21. package/dist/commands/integrate.d.ts.map +1 -1
  22. package/dist/commands/integrate.js +0 -3
  23. package/dist/commands/integrate.js.map +1 -1
  24. package/dist/commands/menu.d.ts +0 -1
  25. package/dist/commands/menu.d.ts.map +1 -1
  26. package/dist/commands/menu.js +0 -3
  27. package/dist/commands/menu.js.map +1 -1
  28. package/dist/commands/new-session.d.ts +0 -1
  29. package/dist/commands/new-session.d.ts.map +1 -1
  30. package/dist/commands/new-session.js +0 -3
  31. package/dist/commands/new-session.js.map +1 -1
  32. package/dist/commands/session.d.ts +0 -1
  33. package/dist/commands/session.d.ts.map +1 -1
  34. package/dist/commands/session.js +0 -3
  35. package/dist/commands/session.js.map +1 -1
  36. package/dist/commands/settings.d.ts +0 -1
  37. package/dist/commands/settings.d.ts.map +1 -1
  38. package/dist/commands/settings.js +0 -3
  39. package/dist/commands/settings.js.map +1 -1
  40. package/dist/formatting.d.ts +0 -62
  41. package/dist/formatting.d.ts.map +1 -1
  42. package/dist/formatting.js +0 -190
  43. package/dist/formatting.js.map +1 -1
  44. package/dist/index.d.ts +2 -2
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +2 -1
  47. package/dist/index.js.map +1 -1
  48. package/dist/message-composer.d.ts +94 -0
  49. package/dist/message-composer.d.ts.map +1 -0
  50. package/dist/message-composer.js +331 -0
  51. package/dist/message-composer.js.map +1 -0
  52. package/dist/plugin.d.ts.map +1 -1
  53. package/dist/plugin.js +33 -6
  54. package/dist/plugin.js.map +1 -1
  55. package/dist/rate-limiter.d.ts +17 -0
  56. package/dist/rate-limiter.d.ts.map +1 -0
  57. package/dist/rate-limiter.js +201 -0
  58. package/dist/rate-limiter.js.map +1 -0
  59. package/package.json +2 -2
  60. package/dist/draft-manager.d.ts +0 -56
  61. package/dist/draft-manager.d.ts.map +0 -1
  62. package/dist/draft-manager.js +0 -268
  63. package/dist/draft-manager.js.map +0 -1
  64. package/dist/renderer.d.ts +0 -49
  65. package/dist/renderer.d.ts.map +0 -1
  66. package/dist/renderer.js +0 -55
  67. package/dist/renderer.js.map +0 -1
  68. package/dist/task-modules.d.ts +0 -34
  69. package/dist/task-modules.d.ts.map +0 -1
  70. package/dist/task-modules.js +0 -136
  71. package/dist/task-modules.js.map +0 -1
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Per-conversation rate limiter for Teams Bot Framework API.
3
+ *
4
+ * Teams enforces rate limits per bot per conversation thread:
5
+ * 7 ops/1s, 8 ops/2s, 60 ops/30s, 1800 ops/3600s
6
+ *
7
+ * This limiter tracks sliding windows and queues operations when any
8
+ * window would be exceeded. Supports coalescing — queued operations
9
+ * with the same key replace earlier ones (e.g., rapid message edits
10
+ * collapse into a single PUT).
11
+ */
12
+ import { log } from "@openacp/plugin-sdk";
13
+ /** Our targets — slightly under Teams limits to leave headroom. */
14
+ const RATE_WINDOWS = [
15
+ { windowMs: 1_000, max: 6 },
16
+ { windowMs: 2_000, max: 7 },
17
+ { windowMs: 30_000, max: 55 },
18
+ { windowMs: 3_600_000, max: 1_700 },
19
+ ];
20
+ /** Per-conversation queue state. */
21
+ class ConversationQueue {
22
+ /** Timestamps of completed operations (for sliding window tracking). */
23
+ timestamps = [];
24
+ queue = [];
25
+ draining = false;
26
+ destroyed = false;
27
+ pausedUntil = 0;
28
+ drainTimer;
29
+ /** Resolves the inner drain-wait promise on destroy, preventing coroutine leak. */
30
+ drainWaitResolve;
31
+ /** Enqueue an operation. If key matches a pending op, replace it (coalescing). */
32
+ enqueue(fn, key) {
33
+ if (this.destroyed)
34
+ return Promise.resolve(undefined);
35
+ return new Promise((resolve, reject) => {
36
+ if (key) {
37
+ const idx = this.queue.findIndex((op) => op.key === key);
38
+ if (idx !== -1) {
39
+ // Coalesce: resolve the old op as undefined (skipped), replace with new
40
+ this.queue[idx].resolve(undefined);
41
+ this.queue[idx] = { fn, key, resolve: resolve, reject };
42
+ return;
43
+ }
44
+ }
45
+ this.queue.push({ fn, key, resolve: resolve, reject });
46
+ this.scheduleDrain();
47
+ });
48
+ }
49
+ get pending() {
50
+ return this.queue.length;
51
+ }
52
+ destroy() {
53
+ this.destroyed = true;
54
+ if (this.drainTimer) {
55
+ clearTimeout(this.drainTimer);
56
+ this.drainTimer = undefined;
57
+ }
58
+ // Unblock any suspended drain-wait so the coroutine can exit
59
+ if (this.drainWaitResolve) {
60
+ this.drainWaitResolve();
61
+ this.drainWaitResolve = undefined;
62
+ }
63
+ // Resolve all pending as undefined
64
+ for (const op of this.queue)
65
+ op.resolve(undefined);
66
+ this.queue.length = 0;
67
+ }
68
+ scheduleDrain() {
69
+ if (this.draining)
70
+ return;
71
+ if (this.drainTimer)
72
+ return;
73
+ const delay = this.getDelay();
74
+ this.drainTimer = setTimeout(() => {
75
+ this.drainTimer = undefined;
76
+ this.drain();
77
+ }, delay);
78
+ }
79
+ /** Calculate how long to wait before next op is allowed. */
80
+ getDelay() {
81
+ const now = Date.now();
82
+ // Respect 429 pause
83
+ if (now < this.pausedUntil) {
84
+ return this.pausedUntil - now;
85
+ }
86
+ let maxDelay = 0;
87
+ for (const { windowMs, max } of RATE_WINDOWS) {
88
+ const cutoff = now - windowMs;
89
+ // Timestamps are in ascending order — find the first one in the window
90
+ const firstIdx = this.timestamps.findIndex((t) => t > cutoff);
91
+ if (firstIdx === -1)
92
+ continue;
93
+ const opsInWindow = this.timestamps.length - firstIdx;
94
+ if (opsInWindow >= max) {
95
+ const oldest = this.timestamps[firstIdx];
96
+ const wait = oldest + windowMs - now + 1;
97
+ maxDelay = Math.max(maxDelay, wait);
98
+ }
99
+ }
100
+ return maxDelay;
101
+ }
102
+ async drain() {
103
+ if (this.draining)
104
+ return;
105
+ this.draining = true;
106
+ try {
107
+ while (this.queue.length > 0 && !this.destroyed) {
108
+ const delay = this.getDelay();
109
+ if (delay > 0) {
110
+ await new Promise((r) => {
111
+ this.drainWaitResolve = r;
112
+ this.drainTimer = setTimeout(() => {
113
+ this.drainTimer = undefined;
114
+ this.drainWaitResolve = undefined;
115
+ r();
116
+ }, delay);
117
+ });
118
+ // Check if destroyed while waiting
119
+ if (this.destroyed)
120
+ break;
121
+ continue;
122
+ }
123
+ const op = this.queue.shift();
124
+ try {
125
+ const result = await op.fn();
126
+ // Record timestamp only on success — 429s should not consume quota
127
+ const now = Date.now();
128
+ this.timestamps.push(now);
129
+ this.pruneTimestamps(now);
130
+ op.resolve(result);
131
+ }
132
+ catch (err) {
133
+ const statusCode = err?.statusCode;
134
+ if (statusCode === 429) {
135
+ // Do NOT record a timestamp — the call was rejected
136
+ const retryAfterRaw = err?.headers?.["retry-after"];
137
+ const retryAfterSec = retryAfterRaw ? parseInt(retryAfterRaw, 10) : NaN;
138
+ const retryMs = !isNaN(retryAfterSec) && retryAfterSec > 0
139
+ ? retryAfterSec * 1000
140
+ : 2000;
141
+ log.warn({ retryMs }, "[RateLimiter] 429 received, pausing");
142
+ this.pausedUntil = Date.now() + retryMs;
143
+ // Re-queue the failed op at the front
144
+ this.queue.unshift(op);
145
+ continue;
146
+ }
147
+ // Non-429 errors still consumed a slot
148
+ const now = Date.now();
149
+ this.timestamps.push(now);
150
+ this.pruneTimestamps(now);
151
+ op.reject(err);
152
+ }
153
+ }
154
+ }
155
+ finally {
156
+ this.draining = false;
157
+ }
158
+ }
159
+ /** Remove timestamps older than the largest window. */
160
+ pruneTimestamps(now) {
161
+ const maxWindow = RATE_WINDOWS[RATE_WINDOWS.length - 1].windowMs;
162
+ const cutoff = now - maxWindow;
163
+ while (this.timestamps.length > 0 && this.timestamps[0] <= cutoff) {
164
+ this.timestamps.shift();
165
+ }
166
+ }
167
+ }
168
+ /**
169
+ * Manages per-conversation rate-limited queues.
170
+ *
171
+ * Usage:
172
+ * const limiter = new ConversationRateLimiter();
173
+ * await limiter.enqueue(conversationId, () => sendText(ctx, text), "main-msg");
174
+ */
175
+ export class ConversationRateLimiter {
176
+ queues = new Map();
177
+ /** Enqueue an operation for a conversation. Key enables coalescing. */
178
+ enqueue(conversationId, fn, key) {
179
+ let queue = this.queues.get(conversationId);
180
+ if (!queue) {
181
+ queue = new ConversationQueue();
182
+ this.queues.set(conversationId, queue);
183
+ }
184
+ return queue.enqueue(fn, key);
185
+ }
186
+ /** Clean up a conversation's queue (e.g., on session end). */
187
+ cleanup(conversationId) {
188
+ const queue = this.queues.get(conversationId);
189
+ if (queue) {
190
+ queue.destroy();
191
+ this.queues.delete(conversationId);
192
+ }
193
+ }
194
+ /** Clean up all queues. */
195
+ destroy() {
196
+ for (const queue of this.queues.values())
197
+ queue.destroy();
198
+ this.queues.clear();
199
+ }
200
+ }
201
+ //# sourceMappingURL=rate-limiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../src/rate-limiter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hahnfeld/teams-adapter",
3
- "version": "1.1.1",
4
- "description": "Teams adapter plugin for OpenACP — Adaptive Cards, commands, streaming",
3
+ "version": "1.3.0",
4
+ "description": "Teams adapter plugin for OpenACP — streaming message composer, rate limiter, commands",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -1,56 +0,0 @@
1
- import type { TurnContext } from "@microsoft/agents-hosting";
2
- export interface MessageRef {
3
- activityId?: string;
4
- conversationId?: string;
5
- serviceUrl?: string;
6
- }
7
- /** Function signature for acquiring a bot token — injected from the adapter */
8
- export type AcquireBotToken = () => Promise<string | null>;
9
- export declare class TeamsMessageDraft {
10
- private context;
11
- private sendQueue;
12
- private sessionId;
13
- private acquireBotToken?;
14
- private buffer;
15
- private ref?;
16
- private flushTimer?;
17
- private flushPromise;
18
- private lastSentBuffer;
19
- private firstFlushPending;
20
- private finalizing;
21
- constructor(context: TurnContext, sendQueue: {
22
- enqueue<T>(fn: () => Promise<T>, opts?: {
23
- type?: string;
24
- }): Promise<T | undefined>;
25
- }, sessionId: string, acquireBotToken?: AcquireBotToken | undefined);
26
- /** Update the TurnContext to the latest inbound turn (prevents stale context refs) */
27
- updateContext(context: TurnContext): void;
28
- append(text: string): void;
29
- getBuffer(): string;
30
- private scheduleFlush;
31
- flush(): Promise<void>;
32
- /**
33
- * Update an existing message via the Bot Framework REST API.
34
- * Bypasses the teams.apps SDK context which doesn't support updateActivity.
35
- */
36
- private updateActivityViaRest;
37
- stripPattern(pattern: RegExp): Promise<void>;
38
- finalize(): Promise<void>;
39
- private _finalizeInner;
40
- }
41
- export declare class TeamsDraftManager {
42
- private sendQueue;
43
- private acquireBotToken?;
44
- private drafts;
45
- constructor(sendQueue: {
46
- enqueue<T>(fn: () => Promise<T>, opts?: {
47
- type?: string;
48
- }): Promise<T | undefined>;
49
- }, acquireBotToken?: AcquireBotToken | undefined);
50
- getOrCreate(sessionId: string, context: TurnContext): TeamsMessageDraft;
51
- hasDraft(sessionId: string): boolean;
52
- getDraft(sessionId: string): TeamsMessageDraft | undefined;
53
- finalize(sessionId: string, _context?: TurnContext, _isAssistant?: boolean): Promise<void>;
54
- cleanup(sessionId: string): void;
55
- }
56
- //# sourceMappingURL=draft-manager.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"draft-manager.d.ts","sourceRoot":"","sources":["../src/draft-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAW7D,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,+EAA+E;AAC/E,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAE3D,qBAAa,iBAAiB;IAU1B,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,eAAe,CAAC;IAZ1B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,GAAG,CAAC,CAAa;IACzB,OAAO,CAAC,UAAU,CAAC,CAAgC;IACnD,OAAO,CAAC,YAAY,CAAoC;IACxD,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,UAAU,CAAS;gBAGjB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE;QAAE,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;KAAE,EACjG,SAAS,EAAE,MAAM,EACjB,eAAe,CAAC,EAAE,eAAe,YAAA;IAG3C,sFAAsF;IACtF,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIzC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM1B,SAAS,IAAI,MAAM;IAInB,OAAO,CAAC,aAAa;IASf,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkF5B;;;OAGG;YACW,qBAAqB;IA8B7B,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YAUjB,cAAc;CAsD7B;AAED,qBAAa,iBAAiB;IAI1B,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,eAAe,CAAC;IAJ1B,OAAO,CAAC,MAAM,CAAwC;gBAG5C,SAAS,EAAE;QAAE,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;KAAE,EACjG,eAAe,CAAC,EAAE,eAAe,YAAA;IAG3C,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,iBAAiB;IAavE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIpC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIpD,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAUhG,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAGjC"}
@@ -1,268 +0,0 @@
1
- import { log } from "@openacp/plugin-sdk";
2
- import { splitMessage } from "./formatting.js";
3
- import { sendText } from "./send-utils.js";
4
- /** First flush fires quickly so the user sees content fast */
5
- const FIRST_FLUSH_INTERVAL = 500;
6
- /** Subsequent flushes are slower to avoid rate limits (Teams: 7 ops/sec/conversation) */
7
- const UPDATE_FLUSH_INTERVAL = 2000;
8
- const MAX_DISPLAY_LENGTH = 25000;
9
- export class TeamsMessageDraft {
10
- context;
11
- sendQueue;
12
- sessionId;
13
- acquireBotToken;
14
- buffer = "";
15
- ref;
16
- flushTimer;
17
- flushPromise = Promise.resolve();
18
- lastSentBuffer = "";
19
- firstFlushPending = false;
20
- finalizing = false;
21
- constructor(context, sendQueue, sessionId, acquireBotToken) {
22
- this.context = context;
23
- this.sendQueue = sendQueue;
24
- this.sessionId = sessionId;
25
- this.acquireBotToken = acquireBotToken;
26
- }
27
- /** Update the TurnContext to the latest inbound turn (prevents stale context refs) */
28
- updateContext(context) {
29
- this.context = context;
30
- }
31
- append(text) {
32
- if (!text)
33
- return;
34
- this.buffer += text;
35
- this.scheduleFlush();
36
- }
37
- getBuffer() {
38
- return this.buffer;
39
- }
40
- scheduleFlush() {
41
- if (this.flushTimer)
42
- return;
43
- const interval = this.ref?.activityId ? UPDATE_FLUSH_INTERVAL : FIRST_FLUSH_INTERVAL;
44
- this.flushTimer = setTimeout(() => {
45
- this.flushTimer = undefined;
46
- this.flushPromise = this.flushPromise.then(() => this.flush()).catch(() => { });
47
- }, interval);
48
- }
49
- async flush() {
50
- if (!this.buffer)
51
- return;
52
- if (this.firstFlushPending)
53
- return;
54
- // If buffer exceeds limit, finalize the current message with its portion
55
- // and start a new streaming message for the overflow.
56
- if (this.buffer.length > MAX_DISPLAY_LENGTH && this.ref?.activityId) {
57
- const finalChunk = this.buffer.slice(0, MAX_DISPLAY_LENGTH);
58
- const overflow = this.buffer.slice(MAX_DISPLAY_LENGTH);
59
- // Update current message with its final content
60
- await this.updateActivityViaRest(finalChunk).catch(() => { });
61
- // Reset for a new message
62
- this.ref = undefined;
63
- this.lastSentBuffer = "";
64
- this.firstFlushPending = false;
65
- this.buffer = overflow;
66
- // Immediately send the overflow as a new message to resume streaming
67
- if (overflow) {
68
- this.firstFlushPending = true;
69
- try {
70
- const result = await this.sendQueue.enqueue(() => sendText(this.context, overflow), { type: "other" });
71
- if (result) {
72
- this.ref = {
73
- activityId: result.id,
74
- conversationId: this.context.activity.conversation?.id,
75
- serviceUrl: this.context.activity.serviceUrl,
76
- };
77
- this.lastSentBuffer = overflow;
78
- }
79
- }
80
- catch (err) {
81
- log.warn({ err, sessionId: this.sessionId }, "[TeamsMessageDraft] flush: overflow send failed");
82
- }
83
- finally {
84
- this.firstFlushPending = false;
85
- }
86
- }
87
- return;
88
- }
89
- const snapshot = this.buffer;
90
- if (!this.ref?.activityId) {
91
- // First message — send via context.send() to get the activityId
92
- this.firstFlushPending = true;
93
- try {
94
- const result = await this.sendQueue.enqueue(() => sendText(this.context, snapshot), { type: "other" });
95
- if (result) {
96
- this.ref = {
97
- activityId: result.id,
98
- conversationId: this.context.activity.conversation?.id,
99
- serviceUrl: this.context.activity.serviceUrl,
100
- };
101
- this.lastSentBuffer = snapshot;
102
- }
103
- }
104
- catch (err) {
105
- log.warn({ err, sessionId: this.sessionId }, "[TeamsMessageDraft] flush: initial send failed");
106
- }
107
- finally {
108
- this.firstFlushPending = false;
109
- }
110
- }
111
- else {
112
- // Subsequent updates — use Bot Framework REST API to edit the message
113
- if (snapshot === this.lastSentBuffer)
114
- return;
115
- try {
116
- const success = await this.updateActivityViaRest(snapshot);
117
- if (success) {
118
- this.lastSentBuffer = snapshot;
119
- }
120
- }
121
- catch (err) {
122
- log.warn({ err, sessionId: this.sessionId }, "[TeamsMessageDraft] flush: update failed");
123
- }
124
- }
125
- }
126
- /**
127
- * Update an existing message via the Bot Framework REST API.
128
- * Bypasses the teams.apps SDK context which doesn't support updateActivity.
129
- */
130
- async updateActivityViaRest(text) {
131
- if (!this.ref?.activityId || !this.ref.serviceUrl || !this.ref.conversationId)
132
- return false;
133
- if (!this.acquireBotToken)
134
- return false;
135
- const token = await this.acquireBotToken();
136
- if (!token)
137
- return false;
138
- const url = `${this.ref.serviceUrl}/v3/conversations/${encodeURIComponent(this.ref.conversationId)}/activities/${encodeURIComponent(this.ref.activityId)}`;
139
- const response = await fetch(url, {
140
- method: "PUT",
141
- headers: {
142
- "Content-Type": "application/json",
143
- "Authorization": `Bearer ${token}`,
144
- },
145
- body: JSON.stringify({
146
- type: "message",
147
- text: text.replace(/(?<!\n)\n(?!\n)/g, "\n\n"), // Teams newline normalization
148
- textFormat: "markdown",
149
- }),
150
- });
151
- if (!response.ok) {
152
- log.warn({ status: response.status, sessionId: this.sessionId }, "[TeamsMessageDraft] REST updateActivity failed");
153
- return false;
154
- }
155
- return true;
156
- }
157
- async stripPattern(pattern) {
158
- if (!this.buffer)
159
- return;
160
- try {
161
- this.buffer = this.buffer.replace(pattern, "").trim();
162
- }
163
- catch {
164
- // Regex failed — leave buffer unchanged
165
- }
166
- }
167
- async finalize() {
168
- if (this.finalizing)
169
- return;
170
- this.finalizing = true;
171
- try {
172
- await this._finalizeInner();
173
- }
174
- finally {
175
- this.finalizing = false;
176
- }
177
- }
178
- async _finalizeInner() {
179
- if (this.flushTimer) {
180
- clearTimeout(this.flushTimer);
181
- this.flushTimer = undefined;
182
- }
183
- // Wait for any in-flight flush to complete
184
- await this.flushPromise;
185
- if (!this.buffer)
186
- return;
187
- // If we have an activityId and the buffer fits in one message, do a final update
188
- if (this.ref?.activityId && this.buffer.length <= MAX_DISPLAY_LENGTH) {
189
- if (this.buffer !== this.lastSentBuffer) {
190
- try {
191
- const success = await this.updateActivityViaRest(this.buffer);
192
- if (success)
193
- return;
194
- }
195
- catch {
196
- // Fall through to send as new message
197
- }
198
- }
199
- else {
200
- return; // Already sent, nothing to update
201
- }
202
- }
203
- // Buffer exceeds single message limit or update failed — send as new message(s).
204
- // If we have an existing streaming message, update it with the first chunk,
205
- // then send the rest as new messages.
206
- const chunks = splitMessage(this.buffer, MAX_DISPLAY_LENGTH);
207
- for (let i = 0; i < chunks.length; i++) {
208
- const content = chunks[i];
209
- try {
210
- if (i === 0 && this.ref?.activityId) {
211
- // Update the existing streaming message with the first chunk
212
- const success = await this.updateActivityViaRest(content);
213
- if (!success) {
214
- // Update failed — send as new message instead
215
- await this.sendQueue.enqueue(() => sendText(this.context, content), { type: "other" });
216
- }
217
- }
218
- else {
219
- await this.sendQueue.enqueue(() => sendText(this.context, content), { type: "other" });
220
- }
221
- }
222
- catch (err) {
223
- log.warn({ err, sessionId: this.sessionId, chunk: i }, "[TeamsMessageDraft] finalize: chunk send failed");
224
- }
225
- }
226
- }
227
- }
228
- export class TeamsDraftManager {
229
- sendQueue;
230
- acquireBotToken;
231
- drafts = new Map();
232
- constructor(sendQueue, acquireBotToken) {
233
- this.sendQueue = sendQueue;
234
- this.acquireBotToken = acquireBotToken;
235
- }
236
- getOrCreate(sessionId, context) {
237
- let draft = this.drafts.get(sessionId);
238
- if (!draft) {
239
- draft = new TeamsMessageDraft(context, this.sendQueue, sessionId, this.acquireBotToken);
240
- this.drafts.set(sessionId, draft);
241
- }
242
- else {
243
- // Re-bind to the latest TurnContext to prevent stale context references
244
- // when a new inbound message arrives on the same session (new turn).
245
- draft.updateContext(context);
246
- }
247
- return draft;
248
- }
249
- hasDraft(sessionId) {
250
- return this.drafts.has(sessionId);
251
- }
252
- getDraft(sessionId) {
253
- return this.drafts.get(sessionId);
254
- }
255
- async finalize(sessionId, _context, _isAssistant) {
256
- const draft = this.drafts.get(sessionId);
257
- if (!draft)
258
- return;
259
- // Delete BEFORE awaiting to prevent concurrent finalize() calls
260
- // from double-finalizing the same draft (matches Telegram pattern)
261
- this.drafts.delete(sessionId);
262
- await draft.finalize();
263
- }
264
- cleanup(sessionId) {
265
- this.drafts.delete(sessionId);
266
- }
267
- }
268
- //# sourceMappingURL=draft-manager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"draft-manager.js","sourceRoot":"","sources":["../src/draft-manager.ts"],"names":[],"mappings":"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"}
@@ -1,49 +0,0 @@
1
- import type { OutgoingMessage, NotificationMessage, DisplayVerbosity } from "@openacp/plugin-sdk";
2
- import { BaseRenderer } from "@openacp/plugin-sdk";
3
- export declare class TeamsRenderer extends BaseRenderer {
4
- renderToolCall(content: OutgoingMessage, verbosity: DisplayVerbosity): {
5
- body: string;
6
- format: "markdown";
7
- };
8
- renderToolUpdate(content: OutgoingMessage, verbosity: DisplayVerbosity): {
9
- body: string;
10
- format: "markdown";
11
- };
12
- renderPlan(content: OutgoingMessage): {
13
- body: string;
14
- format: "markdown";
15
- };
16
- renderUsage(content: OutgoingMessage, verbosity: DisplayVerbosity): {
17
- body: string;
18
- format: "markdown";
19
- };
20
- renderError(content: OutgoingMessage): {
21
- body: string;
22
- format: "markdown";
23
- };
24
- renderNotification(notification: NotificationMessage): {
25
- body: string;
26
- format: "markdown";
27
- };
28
- renderSystemMessage(content: OutgoingMessage): {
29
- body: string;
30
- format: "markdown";
31
- };
32
- renderSessionEnd(_content: OutgoingMessage): {
33
- body: string;
34
- format: "markdown";
35
- };
36
- renderModeChange(content: OutgoingMessage): {
37
- body: string;
38
- format: "markdown";
39
- };
40
- renderConfigUpdate(content?: OutgoingMessage): {
41
- body: string;
42
- format: "markdown";
43
- };
44
- renderModelUpdate(content: OutgoingMessage): {
45
- body: string;
46
- format: "markdown";
47
- };
48
- }
49
- //# sourceMappingURL=renderer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,gBAAgB,EAA2C,MAAM,qBAAqB,CAAC;AAC3I,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,qBAAa,aAAc,SAAQ,YAAY;IAC7C,cAAc,CAAC,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,gBAAgB,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE;IAK3G,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,gBAAgB,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE;IAK7G,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE;IAK1E,WAAW,CAAC,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,gBAAgB,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE;IAKxG,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE;IAI3E,kBAAkB,CAAC,YAAY,EAAE,mBAAmB,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE;IAa3F,mBAAmB,CAAC,OAAO,EAAE,eAAe,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE;IAInF,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE;IAIjF,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE;IAKhF,kBAAkB,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE;IAMnF,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE;CAIlF"}