@wingman-ai/gateway 0.4.2 → 0.4.3

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 (160) hide show
  1. package/README.md +14 -0
  2. package/dist/agent/config/mcpClientManager.cjs +104 -1
  3. package/dist/agent/config/mcpClientManager.d.ts +30 -0
  4. package/dist/agent/config/mcpClientManager.js +104 -1
  5. package/dist/agent/config/modelFactory.cjs +10 -0
  6. package/dist/agent/config/modelFactory.js +10 -0
  7. package/dist/agent/config/xaiImageModel.cjs +242 -0
  8. package/dist/agent/config/xaiImageModel.d.ts +33 -0
  9. package/dist/agent/config/xaiImageModel.js +202 -0
  10. package/dist/agent/tests/mcpClientManager.test.cjs +116 -0
  11. package/dist/agent/tests/mcpClientManager.test.js +117 -1
  12. package/dist/agent/tests/mcpResourceTools.test.cjs +101 -0
  13. package/dist/agent/tests/mcpResourceTools.test.d.ts +1 -0
  14. package/dist/agent/tests/mcpResourceTools.test.js +95 -0
  15. package/dist/agent/tests/modelFactory.test.cjs +16 -2
  16. package/dist/agent/tests/modelFactory.test.js +16 -2
  17. package/dist/agent/tests/xaiImageModel.test.cjs +194 -0
  18. package/dist/agent/tests/xaiImageModel.test.d.ts +1 -0
  19. package/dist/agent/tests/xaiImageModel.test.js +188 -0
  20. package/dist/agent/tools/mcp_resources.cjs +111 -0
  21. package/dist/agent/tools/mcp_resources.d.ts +3 -0
  22. package/dist/agent/tools/mcp_resources.js +77 -0
  23. package/dist/bench/adapters/commandAdapter.cjs +93 -0
  24. package/dist/bench/adapters/commandAdapter.d.ts +6 -0
  25. package/dist/bench/adapters/commandAdapter.js +59 -0
  26. package/dist/bench/adapters/helpers.cjs +170 -0
  27. package/dist/bench/adapters/helpers.d.ts +7 -0
  28. package/dist/bench/adapters/helpers.js +133 -0
  29. package/dist/bench/adapters/index.cjs +41 -0
  30. package/dist/bench/adapters/index.d.ts +2 -0
  31. package/dist/bench/adapters/index.js +7 -0
  32. package/dist/bench/adapters/wingmanCliAdapter.cjs +100 -0
  33. package/dist/bench/adapters/wingmanCliAdapter.d.ts +6 -0
  34. package/dist/bench/adapters/wingmanCliAdapter.js +66 -0
  35. package/dist/bench/cleanup.cjs +122 -0
  36. package/dist/bench/cleanup.d.ts +9 -0
  37. package/dist/bench/cleanup.js +85 -0
  38. package/dist/bench/config.cjs +190 -0
  39. package/dist/bench/config.d.ts +2 -0
  40. package/dist/bench/config.js +156 -0
  41. package/dist/bench/index.cjs +43 -0
  42. package/dist/bench/index.d.ts +3 -0
  43. package/dist/bench/index.js +3 -0
  44. package/dist/bench/official.cjs +616 -0
  45. package/dist/bench/official.d.ts +80 -0
  46. package/dist/bench/official.js +546 -0
  47. package/dist/bench/officialCli.cjs +204 -0
  48. package/dist/bench/officialCli.d.ts +5 -0
  49. package/dist/bench/officialCli.js +170 -0
  50. package/dist/bench/process.cjs +78 -0
  51. package/dist/bench/process.d.ts +14 -0
  52. package/dist/bench/process.js +44 -0
  53. package/dist/bench/runner.cjs +237 -0
  54. package/dist/bench/runner.d.ts +7 -0
  55. package/dist/bench/runner.js +197 -0
  56. package/dist/bench/scoring.cjs +171 -0
  57. package/dist/bench/scoring.d.ts +9 -0
  58. package/dist/bench/scoring.js +137 -0
  59. package/dist/bench/types.cjs +18 -0
  60. package/dist/bench/types.d.ts +200 -0
  61. package/dist/bench/types.js +0 -0
  62. package/dist/bench/validator.cjs +92 -0
  63. package/dist/bench/validator.d.ts +2 -0
  64. package/dist/bench/validator.js +58 -0
  65. package/dist/cli/config/schema.cjs +36 -1
  66. package/dist/cli/config/schema.d.ts +46 -0
  67. package/dist/cli/config/schema.js +36 -1
  68. package/dist/cli/config/warnings.cjs +119 -51
  69. package/dist/cli/config/warnings.js +119 -51
  70. package/dist/cli/core/agentInvoker.cjs +9 -2
  71. package/dist/cli/core/agentInvoker.d.ts +1 -0
  72. package/dist/cli/core/agentInvoker.js +9 -2
  73. package/dist/cli/core/imagePersistence.cjs +17 -1
  74. package/dist/cli/core/imagePersistence.d.ts +2 -0
  75. package/dist/cli/core/imagePersistence.js +13 -3
  76. package/dist/cli/core/sessionManager.cjs +2 -0
  77. package/dist/cli/core/sessionManager.js +3 -1
  78. package/dist/cli/types.d.ts +18 -0
  79. package/dist/gateway/adapters/teams.cjs +419 -0
  80. package/dist/gateway/adapters/teams.d.ts +47 -0
  81. package/dist/gateway/adapters/teams.js +361 -0
  82. package/dist/gateway/http/sms.cjs +286 -0
  83. package/dist/gateway/http/sms.d.ts +4 -0
  84. package/dist/gateway/http/sms.js +249 -0
  85. package/dist/gateway/server.cjs +54 -3
  86. package/dist/gateway/server.d.ts +2 -0
  87. package/dist/gateway/server.js +54 -3
  88. package/dist/gateway/sms/commands.cjs +116 -0
  89. package/dist/gateway/sms/commands.d.ts +15 -0
  90. package/dist/gateway/sms/commands.js +79 -0
  91. package/dist/gateway/sms/control.cjs +118 -0
  92. package/dist/gateway/sms/control.d.ts +18 -0
  93. package/dist/gateway/sms/control.js +84 -0
  94. package/dist/gateway/sms/policyStore.cjs +198 -0
  95. package/dist/gateway/sms/policyStore.d.ts +37 -0
  96. package/dist/gateway/sms/policyStore.js +161 -0
  97. package/dist/providers/registry.cjs +1 -0
  98. package/dist/providers/registry.js +1 -0
  99. package/dist/tests/cli-config-warnings.test.cjs +41 -0
  100. package/dist/tests/cli-config-warnings.test.js +41 -0
  101. package/dist/tests/cli-init.test.cjs +32 -26
  102. package/dist/tests/cli-init.test.js +32 -26
  103. package/dist/tests/gateway-http-security.test.cjs +21 -0
  104. package/dist/tests/gateway-http-security.test.js +21 -0
  105. package/dist/tests/gateway-origin-policy.test.cjs +22 -0
  106. package/dist/tests/gateway-origin-policy.test.js +22 -0
  107. package/dist/tests/gateway.test.cjs +57 -0
  108. package/dist/tests/gateway.test.js +57 -0
  109. package/dist/tests/imagePersistence.test.cjs +26 -0
  110. package/dist/tests/imagePersistence.test.js +27 -1
  111. package/dist/tests/run-terminal-bench-official-script.test.cjs +61 -0
  112. package/dist/tests/run-terminal-bench-official-script.test.d.ts +1 -0
  113. package/dist/tests/run-terminal-bench-official-script.test.js +55 -0
  114. package/dist/tests/sessions-api.test.cjs +69 -1
  115. package/dist/tests/sessions-api.test.js +70 -2
  116. package/dist/tests/sms-api.test.cjs +183 -0
  117. package/dist/tests/sms-api.test.d.ts +1 -0
  118. package/dist/tests/sms-api.test.js +177 -0
  119. package/dist/tests/sms-commands.test.cjs +90 -0
  120. package/dist/tests/sms-commands.test.d.ts +1 -0
  121. package/dist/tests/sms-commands.test.js +84 -0
  122. package/dist/tests/sms-policy-store.test.cjs +69 -0
  123. package/dist/tests/sms-policy-store.test.d.ts +1 -0
  124. package/dist/tests/sms-policy-store.test.js +63 -0
  125. package/dist/tests/teams-adapter.test.cjs +58 -0
  126. package/dist/tests/teams-adapter.test.d.ts +1 -0
  127. package/dist/tests/teams-adapter.test.js +52 -0
  128. package/dist/tests/terminal-bench-adapters-helpers.test.cjs +64 -0
  129. package/dist/tests/terminal-bench-adapters-helpers.test.d.ts +1 -0
  130. package/dist/tests/terminal-bench-adapters-helpers.test.js +58 -0
  131. package/dist/tests/terminal-bench-cleanup.test.cjs +93 -0
  132. package/dist/tests/terminal-bench-cleanup.test.d.ts +1 -0
  133. package/dist/tests/terminal-bench-cleanup.test.js +87 -0
  134. package/dist/tests/terminal-bench-config.test.cjs +62 -0
  135. package/dist/tests/terminal-bench-config.test.d.ts +1 -0
  136. package/dist/tests/terminal-bench-config.test.js +56 -0
  137. package/dist/tests/terminal-bench-official.test.cjs +194 -0
  138. package/dist/tests/terminal-bench-official.test.d.ts +1 -0
  139. package/dist/tests/terminal-bench-official.test.js +188 -0
  140. package/dist/tests/terminal-bench-runner.test.cjs +82 -0
  141. package/dist/tests/terminal-bench-runner.test.d.ts +1 -0
  142. package/dist/tests/terminal-bench-runner.test.js +76 -0
  143. package/dist/tests/terminal-bench-scoring.test.cjs +128 -0
  144. package/dist/tests/terminal-bench-scoring.test.d.ts +1 -0
  145. package/dist/tests/terminal-bench-scoring.test.js +122 -0
  146. package/dist/tools/mcp-fal-ai.cjs +1 -1
  147. package/dist/tools/mcp-fal-ai.js +1 -1
  148. package/dist/webui/assets/index-Cyg_Hs57.css +11 -0
  149. package/dist/webui/assets/{index-BMekSELC.js → index-DZXLLjaA.js} +109 -109
  150. package/dist/webui/index.html +2 -2
  151. package/package.json +11 -2
  152. package/templates/agents/game-dev/agent.md +122 -63
  153. package/templates/agents/game-dev/art-director.md +106 -0
  154. package/templates/agents/game-dev/game-designer.md +87 -0
  155. package/templates/agents/game-dev/scene-engineer.md +474 -0
  156. package/dist/webui/assets/index-Cwkg4DKj.css +0 -11
  157. package/templates/agents/game-dev/art-generation.md +0 -38
  158. package/templates/agents/game-dev/asset-refinement.md +0 -17
  159. package/templates/agents/game-dev/planning-idea.md +0 -17
  160. package/templates/agents/game-dev/ui-specialist.md +0 -17
@@ -0,0 +1,361 @@
1
+ import { CloudAdapter, ConfigurationBotFrameworkAuthentication } from "botbuilder";
2
+ import { parseStreamChunk } from "../../cli/core/streamParser.js";
3
+ import { createLogger } from "../../logger.js";
4
+ import { GatewayRpcClient } from "../rpcClient.js";
5
+ import { extractSessionOverride, extractUiMeta, parseAgentIdFromSessionKey } from "./discord.js";
6
+ function _define_property(obj, key, value) {
7
+ if (key in obj) Object.defineProperty(obj, key, {
8
+ value: value,
9
+ enumerable: true,
10
+ configurable: true,
11
+ writable: true
12
+ });
13
+ else obj[key] = value;
14
+ return obj;
15
+ }
16
+ const DEFAULT_TEAMS_ENDPOINT_PATH = "/api/adapters/teams/messages";
17
+ const DEFAULT_TEAMS_RESPONSE_CHUNK = 3500;
18
+ function normalizeTeamsEndpointPath(path) {
19
+ const fallback = DEFAULT_TEAMS_ENDPOINT_PATH;
20
+ if (!path || "string" != typeof path) return fallback;
21
+ const trimmed = path.trim();
22
+ if (!trimmed) return fallback;
23
+ return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
24
+ }
25
+ function splitTeamsMessage(text, maxLength = DEFAULT_TEAMS_RESPONSE_CHUNK) {
26
+ const normalized = text.trim();
27
+ if (!normalized) return [];
28
+ const chunks = [];
29
+ let current = "";
30
+ for (const char of normalized){
31
+ if (current.length + 1 > maxLength) {
32
+ chunks.push(current);
33
+ current = "";
34
+ }
35
+ current += char;
36
+ }
37
+ if (current) chunks.push(current);
38
+ return chunks;
39
+ }
40
+ function escapeRegex(value) {
41
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
42
+ }
43
+ function getEntities(activity) {
44
+ if (!Array.isArray(activity.entities)) return [];
45
+ return activity.entities;
46
+ }
47
+ function extractTeamsMentionTexts(activity, botAccountId) {
48
+ const recipientName = activity.recipient?.name?.trim().toLowerCase();
49
+ const texts = new Set();
50
+ for (const entity of getEntities(activity)){
51
+ if ("mention" !== entity.type || "string" != typeof entity.text) continue;
52
+ const mentionedId = entity.mentioned?.id?.trim();
53
+ const mentionedName = entity.mentioned?.name?.trim().toLowerCase();
54
+ if (botAccountId && mentionedId === botAccountId || recipientName && mentionedName === recipientName) texts.add(entity.text);
55
+ }
56
+ return Array.from(texts);
57
+ }
58
+ function stripTeamsBotMention(content, mentionTexts = []) {
59
+ if (!content) return content;
60
+ let next = content;
61
+ for (const text of mentionTexts)next = next.replace(new RegExp(escapeRegex(text), "gi"), " ");
62
+ return next.replace(/<at>.*?<\/at>/gi, " ").replace(/\s+/g, " ").trim();
63
+ }
64
+ function isTeamsBotMentioned(activity, botAccountId) {
65
+ if (extractTeamsMentionTexts(activity, botAccountId).length > 0) return true;
66
+ const text = activity.text || "";
67
+ const recipientName = activity.recipient?.name?.trim();
68
+ if (recipientName) {
69
+ const regex = new RegExp(`<at>\\s*${escapeRegex(recipientName)}\\s*</at>`, "i");
70
+ return regex.test(text);
71
+ }
72
+ return false;
73
+ }
74
+ function resolveTeamsChannelSessionKey(channelId, channelSessions) {
75
+ if (!channelSessions) return;
76
+ return channelSessions[channelId];
77
+ }
78
+ function toHeaderRecord(headers) {
79
+ const result = {};
80
+ for (const [key, value] of headers.entries())result[key] = value;
81
+ if (!result.Authorization && result.authorization) result.Authorization = result.authorization;
82
+ return result;
83
+ }
84
+ function buildBotBuilderResponse(resolve) {
85
+ let statusCode = 200;
86
+ const headers = new Headers();
87
+ let body;
88
+ const finalize = (payload)=>{
89
+ if (void 0 !== payload) if ("string" == typeof payload) body = payload;
90
+ else {
91
+ body = JSON.stringify(payload);
92
+ if (!headers.get("Content-Type")) headers.set("Content-Type", "application/json");
93
+ }
94
+ resolve(new Response(body, {
95
+ status: statusCode,
96
+ headers
97
+ }));
98
+ };
99
+ return {
100
+ status (code) {
101
+ statusCode = code;
102
+ return this;
103
+ },
104
+ header (name, value) {
105
+ headers.set(name, value);
106
+ return this;
107
+ },
108
+ send (payload) {
109
+ finalize(payload);
110
+ },
111
+ end (payload) {
112
+ finalize(payload);
113
+ },
114
+ socket: {}
115
+ };
116
+ }
117
+ function extractTeamId(activity) {
118
+ const raw = activity.channelData?.team?.id;
119
+ if ("string" == typeof raw && raw.trim()) return raw;
120
+ }
121
+ function extractChannelId(activity) {
122
+ const channelId = activity.channelData?.channel?.id;
123
+ if ("string" == typeof channelId && channelId.trim()) return channelId;
124
+ const conversationId = activity.conversation?.id;
125
+ if ("string" == typeof conversationId && conversationId.trim()) return conversationId;
126
+ }
127
+ function extractThreadId(activity) {
128
+ if (activity.replyToId && activity.replyToId.trim()) return activity.replyToId;
129
+ const conversationId = activity.conversation?.id;
130
+ if (!conversationId) return;
131
+ const match = conversationId.match(/;messageid=([^;]+)/i);
132
+ if (!match?.[1]) return;
133
+ try {
134
+ return decodeURIComponent(match[1]);
135
+ } catch {
136
+ return match[1];
137
+ }
138
+ }
139
+ function isDirectMessage(activity) {
140
+ return activity.conversation?.conversationType === "personal";
141
+ }
142
+ function buildRoutingInfo(activity, botAccountId) {
143
+ const routing = {
144
+ channel: "teams",
145
+ accountId: botAccountId
146
+ };
147
+ const teamId = extractTeamId(activity);
148
+ if (teamId) routing.teamId = teamId;
149
+ const conversationType = activity.conversation?.conversationType;
150
+ if ("personal" === conversationType) {
151
+ const dmId = activity.from?.aadObjectId || activity.from?.id;
152
+ if (dmId) routing.peer = {
153
+ kind: "dm",
154
+ id: dmId
155
+ };
156
+ } else if ("groupChat" === conversationType) {
157
+ if (activity.conversation?.id) routing.peer = {
158
+ kind: "group",
159
+ id: activity.conversation.id
160
+ };
161
+ } else {
162
+ const channelId = extractChannelId(activity);
163
+ if (channelId) routing.peer = {
164
+ kind: "channel",
165
+ id: channelId
166
+ };
167
+ }
168
+ const threadId = extractThreadId(activity);
169
+ if (threadId) routing.threadId = threadId;
170
+ return routing;
171
+ }
172
+ function isBotMessage(activity) {
173
+ return activity.from?.role === "bot";
174
+ }
175
+ class TeamsGatewayAdapter {
176
+ get endpointPath() {
177
+ return normalizeTeamsEndpointPath(this.config.endpointPath);
178
+ }
179
+ async start() {
180
+ if (this.started) return;
181
+ if (!this.config.enabled) return;
182
+ if (!this.config.appId || !this.config.appPassword) return void this.logger.warn("Teams adapter enabled but Microsoft app credentials are incomplete.");
183
+ this.gatewayClient = new GatewayRpcClient(this.gateway.url, {
184
+ token: this.gateway.token,
185
+ password: this.gateway.password,
186
+ clientType: "teams"
187
+ });
188
+ await this.gatewayClient.connect();
189
+ const authConfig = {
190
+ MicrosoftAppId: this.config.appId,
191
+ MicrosoftAppPassword: this.config.appPassword,
192
+ MicrosoftAppType: this.config.appType
193
+ };
194
+ if (this.config.tenantId) authConfig.MicrosoftAppTenantId = this.config.tenantId;
195
+ const authentication = new ConfigurationBotFrameworkAuthentication(authConfig);
196
+ this.adapter = new CloudAdapter(authentication);
197
+ this.adapter.onTurnError = async (context, error)=>{
198
+ this.logger.error("Teams adapter turn error", error);
199
+ try {
200
+ await context.sendActivity("Sorry, I hit an error running that request.");
201
+ } catch {}
202
+ };
203
+ this.started = true;
204
+ }
205
+ async stop() {
206
+ if (!this.started) return;
207
+ this.started = false;
208
+ this.adapter = null;
209
+ if (this.gatewayClient) {
210
+ this.gatewayClient.disconnect();
211
+ this.gatewayClient = null;
212
+ }
213
+ }
214
+ async handleHttpRequest(req, url) {
215
+ if (url.pathname !== this.endpointPath) return null;
216
+ if ("POST" !== req.method) return new Response("Method Not Allowed", {
217
+ status: 405,
218
+ headers: {
219
+ Allow: "POST"
220
+ }
221
+ });
222
+ if (!this.started || !this.adapter || !this.gatewayClient) return new Response("Teams adapter not started", {
223
+ status: 503
224
+ });
225
+ const adapter = this.adapter;
226
+ let body;
227
+ try {
228
+ body = await req.json();
229
+ } catch {
230
+ return new Response("Invalid JSON payload", {
231
+ status: 400
232
+ });
233
+ }
234
+ const activity = body;
235
+ return new Promise((resolve)=>{
236
+ const response = buildBotBuilderResponse(resolve);
237
+ adapter.process({
238
+ method: req.method,
239
+ headers: toHeaderRecord(req.headers),
240
+ body: activity
241
+ }, response, async (context)=>this.handleMessage(context)).catch((error)=>{
242
+ this.logger.error("Teams adapter failed to process request", error);
243
+ resolve(new Response("Failed to process Teams request", {
244
+ status: 500
245
+ }));
246
+ });
247
+ });
248
+ }
249
+ async handleMessage(context) {
250
+ if (!this.gatewayClient) return;
251
+ const activity = context.activity;
252
+ if ("message" !== activity.type) return;
253
+ if (!activity.text && !activity.attachments?.length) return;
254
+ if (isBotMessage(activity)) {
255
+ if (!this.config.allowBots) return;
256
+ if (activity.from?.id && activity.from.id === activity.recipient?.id) return;
257
+ }
258
+ const teamId = extractTeamId(activity);
259
+ if (this.config.allowedTeamIds.length > 0 && teamId) {
260
+ if (!this.config.allowedTeamIds.includes(teamId)) return;
261
+ }
262
+ const channelId = extractChannelId(activity);
263
+ if (this.config.allowedChannelIds.length > 0) {
264
+ if (!channelId || !this.config.allowedChannelIds.includes(channelId)) return;
265
+ }
266
+ const botAccountId = activity.recipient?.id || this.config.appId;
267
+ if (this.config.mentionOnly && !isDirectMessage(activity) && !isTeamsBotMentioned(activity, botAccountId)) return;
268
+ const mentionTexts = extractTeamsMentionTexts(activity, botAccountId);
269
+ const cleaned = stripTeamsBotMention(activity.text || "", mentionTexts);
270
+ const attachments = (activity.attachments || []).map((attachment)=>attachment.contentUrl).filter((url)=>Boolean(url));
271
+ const attachmentText = attachments.length > 0 ? `\n\nAttachments:\n${attachments.map((url)=>`- ${url}`).join("\n")}` : "";
272
+ let content = `${cleaned}${attachmentText}`.trim();
273
+ const { sessionKey, content: nextContent, matched } = extractSessionOverride(content, this.config.sessionCommand);
274
+ let resolvedSessionKey = sessionKey;
275
+ let usedChannelMapping = false;
276
+ if (matched) {
277
+ content = nextContent.trim();
278
+ if (!sessionKey) return void await context.sendActivity(`Provide a session key after \`${this.config.sessionCommand}\`.`);
279
+ }
280
+ if (!matched && channelId) {
281
+ resolvedSessionKey = resolveTeamsChannelSessionKey(channelId, this.config.channelSessions);
282
+ usedChannelMapping = Boolean(resolvedSessionKey);
283
+ }
284
+ const inferredAgentId = parseAgentIdFromSessionKey(resolvedSessionKey);
285
+ if (usedChannelMapping && !inferredAgentId) this.logger.warn(`Teams channel session mapping for channel ${channelId} does not include an agent prefix. Use "agent:<id>:..." to auto-select an agent.`, {
286
+ sessionKey: resolvedSessionKey
287
+ });
288
+ if (!content) return;
289
+ const payload = {
290
+ agentId: inferredAgentId,
291
+ content,
292
+ routing: buildRoutingInfo(activity, botAccountId),
293
+ sessionKey: resolvedSessionKey
294
+ };
295
+ try {
296
+ await context.sendActivity({
297
+ type: "typing"
298
+ });
299
+ let fallbackText = "";
300
+ let uiFallbackText = "";
301
+ let uiOnlyDetected = false;
302
+ const textByMessageId = new Map();
303
+ const messageOrder = [];
304
+ await this.gatewayClient.requestAgent(payload, (event)=>{
305
+ if (!event || "object" != typeof event) return;
306
+ if ("agent-error" === event.type) {
307
+ fallbackText += `\n${event.error || "Agent error"}`;
308
+ return;
309
+ }
310
+ if ("agent-stream" !== event.type) return;
311
+ const parsedChunks = parseStreamChunk(event.chunk);
312
+ for (const chunk of parsedChunks){
313
+ if ("tool-result" === chunk.type && chunk.toolResult?.output) {
314
+ const meta = extractUiMeta(chunk.toolResult.output);
315
+ if (true === meta.uiOnly) uiOnlyDetected = true;
316
+ if (meta.textFallback) uiFallbackText = meta.textFallback;
317
+ }
318
+ if ("text" === chunk.type && chunk.text) {
319
+ if (chunk.messageId) {
320
+ if (!textByMessageId.has(chunk.messageId)) {
321
+ messageOrder.push(chunk.messageId);
322
+ textByMessageId.set(chunk.messageId, chunk.text);
323
+ continue;
324
+ }
325
+ const current = textByMessageId.get(chunk.messageId) || "";
326
+ textByMessageId.set(chunk.messageId, chunk.isDelta ? current + chunk.text : chunk.text);
327
+ continue;
328
+ }
329
+ fallbackText += chunk.text;
330
+ }
331
+ }
332
+ });
333
+ const orderedText = messageOrder.map((id)=>textByMessageId.get(id)).filter((value)=>Boolean(value)).join("\n\n");
334
+ let responseText = `${fallbackText}${fallbackText && orderedText ? "\n\n" : ""}${orderedText}`.trim();
335
+ if (uiFallbackText && (uiOnlyDetected || !responseText)) responseText = uiFallbackText.trim();
336
+ if (!responseText) return;
337
+ const chunks = splitTeamsMessage(responseText, this.config.responseChunkSize);
338
+ for (const chunk of chunks)await context.sendActivity(chunk);
339
+ } catch (error) {
340
+ this.logger.error("Teams adapter failed to handle message", error);
341
+ try {
342
+ await context.sendActivity("Sorry, I hit an error running that request.");
343
+ } catch {}
344
+ }
345
+ }
346
+ constructor(config, gateway, logger){
347
+ _define_property(this, "config", void 0);
348
+ _define_property(this, "gateway", void 0);
349
+ _define_property(this, "adapter", void 0);
350
+ _define_property(this, "gatewayClient", void 0);
351
+ _define_property(this, "logger", void 0);
352
+ _define_property(this, "started", void 0);
353
+ this.config = config;
354
+ this.gateway = gateway;
355
+ this.adapter = null;
356
+ this.gatewayClient = null;
357
+ this.started = false;
358
+ this.logger = logger || createLogger();
359
+ }
360
+ }
361
+ export { DEFAULT_TEAMS_ENDPOINT_PATH, DEFAULT_TEAMS_RESPONSE_CHUNK, TeamsGatewayAdapter, extractTeamsMentionTexts, isTeamsBotMentioned, normalizeTeamsEndpointPath, resolveTeamsChannelSessionKey, splitTeamsMessage, stripTeamsBotMention };
@@ -0,0 +1,286 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ handleSmsApi: ()=>handleSmsApi,
28
+ createSmsPolicyStateStore: ()=>createSmsPolicyStateStore
29
+ });
30
+ const control_cjs_namespaceObject = require("../sms/control.cjs");
31
+ const policyStore_cjs_namespaceObject = require("../sms/policyStore.cjs");
32
+ const MAX_PAUSE_FOR_MS = 2592000000;
33
+ const createSmsPolicyStateStore = (resolveConfigDirPath)=>(0, policyStore_cjs_namespaceObject.createSmsPolicyStore)(resolveConfigDirPath);
34
+ function decodeTarget(raw) {
35
+ let decoded = "";
36
+ try {
37
+ decoded = decodeURIComponent(raw);
38
+ } catch {
39
+ return null;
40
+ }
41
+ return (0, policyStore_cjs_namespaceObject.normalizeSmsPolicyTarget)(decoded);
42
+ }
43
+ function parsePauseForMs(raw) {
44
+ if ("number" != typeof raw || !Number.isFinite(raw)) return null;
45
+ const value = Math.trunc(raw);
46
+ if (value <= 0 || value > MAX_PAUSE_FOR_MS) return null;
47
+ return value;
48
+ }
49
+ function toResponsePayload(resolution, nowMs) {
50
+ return {
51
+ ...resolution,
52
+ policy: {
53
+ ...resolution.policy,
54
+ pauseExpiresInMs: resolution.policy.paused && resolution.policy.pausedUntil ? Math.max(resolution.policy.pausedUntil - nowMs, 0) : null
55
+ }
56
+ };
57
+ }
58
+ function parseRoutingTarget(rawTarget) {
59
+ const trimmed = rawTarget.trim();
60
+ if (!trimmed) return null;
61
+ const normalized = (0, policyStore_cjs_namespaceObject.normalizeSmsPolicyTarget)(trimmed);
62
+ if (!normalized) return null;
63
+ const separatorIndex = normalized.indexOf(":");
64
+ let channel = "sms-macos";
65
+ let peerId = normalized;
66
+ if (separatorIndex > 0 && separatorIndex < normalized.length - 1) {
67
+ const candidateChannel = normalized.slice(0, separatorIndex).trim();
68
+ const candidatePeer = normalized.slice(separatorIndex + 1).trim();
69
+ if (candidateChannel && candidatePeer) {
70
+ channel = candidateChannel;
71
+ peerId = candidatePeer;
72
+ }
73
+ }
74
+ return {
75
+ normalizedTarget: normalized,
76
+ routing: {
77
+ channel,
78
+ peer: {
79
+ kind: "dm",
80
+ id: peerId
81
+ }
82
+ }
83
+ };
84
+ }
85
+ const handleSmsApi = async (ctx, store, req, url)=>{
86
+ if ("/api/sms/messages" === url.pathname) {
87
+ if ("POST" !== req.method) return new Response("Method Not Allowed", {
88
+ status: 405
89
+ });
90
+ let body;
91
+ try {
92
+ body = await req.json();
93
+ } catch {
94
+ return new Response("Invalid JSON body", {
95
+ status: 400
96
+ });
97
+ }
98
+ const parsed = parseRoutingTarget("string" == typeof body.target ? body.target : "");
99
+ if (!parsed) return new Response("valid target required", {
100
+ status: 400
101
+ });
102
+ const nowMs = Date.now();
103
+ const text = "string" == typeof body.text ? body.text : "";
104
+ const control = (0, control_cjs_namespaceObject.applySmsControlCommand)({
105
+ store,
106
+ target: parsed.normalizedTarget,
107
+ text,
108
+ nowMs
109
+ });
110
+ if (control.handled) return new Response(JSON.stringify({
111
+ kind: "command",
112
+ ...toResponsePayload(control, nowMs)
113
+ }, null, 2), {
114
+ headers: {
115
+ "Content-Type": "application/json"
116
+ }
117
+ });
118
+ if (!control.passThroughText.trim()) return new Response("text required", {
119
+ status: 400
120
+ });
121
+ if (control.policy.stopEnabled) return new Response(JSON.stringify({
122
+ kind: "stopped",
123
+ responseText: "SMS chat is stopped for this sender. Re-enable in Wingman settings/API.",
124
+ policy: control.policy
125
+ }, null, 2), {
126
+ headers: {
127
+ "Content-Type": "application/json"
128
+ }
129
+ });
130
+ const routing = {
131
+ ...parsed.routing
132
+ };
133
+ if ("string" == typeof body.accountId && body.accountId.trim()) routing.accountId = body.accountId.trim();
134
+ if ("string" == typeof body.threadId && body.threadId.trim()) routing.threadId = body.threadId.trim();
135
+ const selectedAgentId = ctx.router.selectAgent("string" == typeof body.agentId ? body.agentId.trim() : void 0, routing);
136
+ if (!selectedAgentId) return new Response("Unable to resolve agent", {
137
+ status: 400
138
+ });
139
+ const explicitSessionKey = "string" == typeof body.sessionKey ? body.sessionKey.trim() : "";
140
+ const sessionKey = explicitSessionKey || ctx.router.buildSessionKey(selectedAgentId, routing);
141
+ const request = {
142
+ agentId: selectedAgentId,
143
+ content: control.passThroughText,
144
+ routing,
145
+ sessionKey
146
+ };
147
+ if ("boolean" == typeof body.queueIfBusy) request.queueIfBusy = body.queueIfBusy;
148
+ return new Response(JSON.stringify({
149
+ kind: "agent",
150
+ target: parsed.normalizedTarget,
151
+ policy: control.policy,
152
+ request
153
+ }, null, 2), {
154
+ headers: {
155
+ "Content-Type": "application/json"
156
+ }
157
+ });
158
+ }
159
+ if ("/api/sms/policies" === url.pathname && "GET" === req.method) {
160
+ const targetRaw = url.searchParams.get("target");
161
+ if (targetRaw) {
162
+ const target = (0, policyStore_cjs_namespaceObject.normalizeSmsPolicyTarget)(targetRaw);
163
+ if (!target) return new Response("valid target query required", {
164
+ status: 400
165
+ });
166
+ const record = store.resolve(target);
167
+ return new Response(JSON.stringify(record, null, 2), {
168
+ headers: {
169
+ "Content-Type": "application/json"
170
+ }
171
+ });
172
+ }
173
+ const policies = store.list();
174
+ return new Response(JSON.stringify({
175
+ policies
176
+ }, null, 2), {
177
+ headers: {
178
+ "Content-Type": "application/json"
179
+ }
180
+ });
181
+ }
182
+ const commandMatch = url.pathname.match(/^\/api\/sms\/policies\/([^/]+)\/command$/);
183
+ if (commandMatch) {
184
+ if ("POST" !== req.method) return new Response("Method Not Allowed", {
185
+ status: 405
186
+ });
187
+ const target = decodeTarget(commandMatch[1]);
188
+ if (!target) return new Response("valid target required", {
189
+ status: 400
190
+ });
191
+ let body;
192
+ try {
193
+ body = await req.json();
194
+ } catch {
195
+ return new Response("Invalid JSON body", {
196
+ status: 400
197
+ });
198
+ }
199
+ const text = "string" == typeof body.text ? body.text : "";
200
+ const nowMs = "number" == typeof body.nowMs && Number.isFinite(body.nowMs) ? Math.trunc(body.nowMs) : Date.now();
201
+ const result = (0, control_cjs_namespaceObject.applySmsControlCommand)({
202
+ store,
203
+ target,
204
+ text,
205
+ nowMs
206
+ });
207
+ return new Response(JSON.stringify(toResponsePayload(result, nowMs), null, 2), {
208
+ headers: {
209
+ "Content-Type": "application/json"
210
+ }
211
+ });
212
+ }
213
+ const targetMatch = url.pathname.match(/^\/api\/sms\/policies\/([^/]+)$/);
214
+ if (!targetMatch) return null;
215
+ const target = decodeTarget(targetMatch[1]);
216
+ if (!target) return new Response("valid target required", {
217
+ status: 400
218
+ });
219
+ if ("GET" === req.method) return new Response(JSON.stringify(store.resolve(target), null, 2), {
220
+ headers: {
221
+ "Content-Type": "application/json"
222
+ }
223
+ });
224
+ if ("DELETE" === req.method) {
225
+ store.reset(target);
226
+ return new Response(JSON.stringify(store.resolve(target), null, 2), {
227
+ headers: {
228
+ "Content-Type": "application/json"
229
+ }
230
+ });
231
+ }
232
+ if ("PUT" !== req.method) return new Response("Method Not Allowed", {
233
+ status: 405
234
+ });
235
+ let body;
236
+ try {
237
+ body = await req.json();
238
+ } catch {
239
+ return new Response("Invalid JSON body", {
240
+ status: 400
241
+ });
242
+ }
243
+ const patch = {};
244
+ const hasPauseForMs = Object.hasOwn(body ?? {}, "pauseForMs");
245
+ if (hasPauseForMs) {
246
+ const duration = parsePauseForMs(body.pauseForMs);
247
+ if (null === duration) return new Response("pauseForMs must be a positive duration", {
248
+ status: 400
249
+ });
250
+ const nowMs = Date.now();
251
+ patch.paused = true;
252
+ patch.pausedUntil = nowMs + duration;
253
+ }
254
+ if ("boolean" == typeof body.paused) patch.paused = body.paused;
255
+ if (Object.hasOwn(body ?? {}, "pausedUntil")) {
256
+ const value = body.pausedUntil;
257
+ if (null === value) {
258
+ patch.paused = false;
259
+ patch.pausedUntil = null;
260
+ } else {
261
+ if (!("number" == typeof value && Number.isFinite(value))) return new Response("pausedUntil must be a number or null", {
262
+ status: 400
263
+ });
264
+ patch.paused = true;
265
+ patch.pausedUntil = Math.trunc(value);
266
+ }
267
+ }
268
+ if ("boolean" == typeof body.stopEnabled) patch.stopEnabled = body.stopEnabled;
269
+ if ("off" === body.alertMode || "important-only" === body.alertMode || "all" === body.alertMode) patch.alertMode = body.alertMode;
270
+ if (Object.hasOwn(body ?? {}, "quietHours")) patch.quietHours = body.quietHours ?? null;
271
+ const updated = store.upsert(target, patch);
272
+ return new Response(JSON.stringify(updated, null, 2), {
273
+ headers: {
274
+ "Content-Type": "application/json"
275
+ }
276
+ });
277
+ };
278
+ exports.createSmsPolicyStateStore = __webpack_exports__.createSmsPolicyStateStore;
279
+ exports.handleSmsApi = __webpack_exports__.handleSmsApi;
280
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
281
+ "createSmsPolicyStateStore",
282
+ "handleSmsApi"
283
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
284
+ Object.defineProperty(exports, '__esModule', {
285
+ value: true
286
+ });
@@ -0,0 +1,4 @@
1
+ import { type SmsPolicyStore } from "../sms/policyStore.js";
2
+ import type { GatewayHttpContext } from "./types.js";
3
+ export declare const createSmsPolicyStateStore: (resolveConfigDirPath: () => string) => SmsPolicyStore;
4
+ export declare const handleSmsApi: (ctx: GatewayHttpContext, store: SmsPolicyStore, req: Request, url: URL) => Promise<Response | null>;