@wingman-ai/gateway 0.4.1 → 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.
- package/README.md +14 -0
- package/dist/agent/config/mcpClientManager.cjs +104 -1
- package/dist/agent/config/mcpClientManager.d.ts +30 -0
- package/dist/agent/config/mcpClientManager.js +104 -1
- package/dist/agent/config/modelFactory.cjs +10 -0
- package/dist/agent/config/modelFactory.js +10 -0
- package/dist/agent/config/xaiImageModel.cjs +242 -0
- package/dist/agent/config/xaiImageModel.d.ts +33 -0
- package/dist/agent/config/xaiImageModel.js +202 -0
- package/dist/agent/tests/mcpClientManager.test.cjs +116 -0
- package/dist/agent/tests/mcpClientManager.test.js +117 -1
- package/dist/agent/tests/mcpResourceTools.test.cjs +101 -0
- package/dist/agent/tests/mcpResourceTools.test.d.ts +1 -0
- package/dist/agent/tests/mcpResourceTools.test.js +95 -0
- package/dist/agent/tests/modelFactory.test.cjs +16 -2
- package/dist/agent/tests/modelFactory.test.js +16 -2
- package/dist/agent/tests/xaiImageModel.test.cjs +194 -0
- package/dist/agent/tests/xaiImageModel.test.d.ts +1 -0
- package/dist/agent/tests/xaiImageModel.test.js +188 -0
- package/dist/agent/tools/mcp_resources.cjs +111 -0
- package/dist/agent/tools/mcp_resources.d.ts +3 -0
- package/dist/agent/tools/mcp_resources.js +77 -0
- package/dist/bench/adapters/commandAdapter.cjs +93 -0
- package/dist/bench/adapters/commandAdapter.d.ts +6 -0
- package/dist/bench/adapters/commandAdapter.js +59 -0
- package/dist/bench/adapters/helpers.cjs +170 -0
- package/dist/bench/adapters/helpers.d.ts +7 -0
- package/dist/bench/adapters/helpers.js +133 -0
- package/dist/bench/adapters/index.cjs +41 -0
- package/dist/bench/adapters/index.d.ts +2 -0
- package/dist/bench/adapters/index.js +7 -0
- package/dist/bench/adapters/wingmanCliAdapter.cjs +100 -0
- package/dist/bench/adapters/wingmanCliAdapter.d.ts +6 -0
- package/dist/bench/adapters/wingmanCliAdapter.js +66 -0
- package/dist/bench/cleanup.cjs +122 -0
- package/dist/bench/cleanup.d.ts +9 -0
- package/dist/bench/cleanup.js +85 -0
- package/dist/bench/config.cjs +190 -0
- package/dist/bench/config.d.ts +2 -0
- package/dist/bench/config.js +156 -0
- package/dist/bench/index.cjs +43 -0
- package/dist/bench/index.d.ts +3 -0
- package/dist/bench/index.js +3 -0
- package/dist/bench/official.cjs +616 -0
- package/dist/bench/official.d.ts +80 -0
- package/dist/bench/official.js +546 -0
- package/dist/bench/officialCli.cjs +204 -0
- package/dist/bench/officialCli.d.ts +5 -0
- package/dist/bench/officialCli.js +170 -0
- package/dist/bench/process.cjs +78 -0
- package/dist/bench/process.d.ts +14 -0
- package/dist/bench/process.js +44 -0
- package/dist/bench/runner.cjs +237 -0
- package/dist/bench/runner.d.ts +7 -0
- package/dist/bench/runner.js +197 -0
- package/dist/bench/scoring.cjs +171 -0
- package/dist/bench/scoring.d.ts +9 -0
- package/dist/bench/scoring.js +137 -0
- package/dist/bench/types.cjs +18 -0
- package/dist/bench/types.d.ts +200 -0
- package/dist/bench/types.js +0 -0
- package/dist/bench/validator.cjs +92 -0
- package/dist/bench/validator.d.ts +2 -0
- package/dist/bench/validator.js +58 -0
- package/dist/cli/commands/init.cjs +135 -1
- package/dist/cli/commands/init.js +136 -2
- package/dist/cli/commands/skill.cjs +7 -3
- package/dist/cli/commands/skill.js +7 -3
- package/dist/cli/config/loader.cjs +7 -3
- package/dist/cli/config/loader.js +7 -3
- package/dist/cli/config/schema.cjs +63 -10
- package/dist/cli/config/schema.d.ts +64 -4
- package/dist/cli/config/schema.js +59 -9
- package/dist/cli/config/warnings.cjs +119 -51
- package/dist/cli/config/warnings.js +119 -51
- package/dist/cli/core/agentInvoker.cjs +58 -13
- package/dist/cli/core/agentInvoker.d.ts +1 -0
- package/dist/cli/core/agentInvoker.js +58 -13
- package/dist/cli/core/imagePersistence.cjs +17 -1
- package/dist/cli/core/imagePersistence.d.ts +2 -0
- package/dist/cli/core/imagePersistence.js +13 -3
- package/dist/cli/core/sessionManager.cjs +2 -0
- package/dist/cli/core/sessionManager.js +3 -1
- package/dist/cli/services/skillRepository.cjs +155 -69
- package/dist/cli/services/skillRepository.d.ts +7 -2
- package/dist/cli/services/skillRepository.js +155 -69
- package/dist/cli/services/skillService.cjs +93 -26
- package/dist/cli/services/skillService.d.ts +7 -0
- package/dist/cli/services/skillService.js +96 -29
- package/dist/cli/types/skill.d.ts +8 -3
- package/dist/cli/types.d.ts +18 -0
- package/dist/gateway/adapters/teams.cjs +419 -0
- package/dist/gateway/adapters/teams.d.ts +47 -0
- package/dist/gateway/adapters/teams.js +361 -0
- package/dist/gateway/http/sms.cjs +286 -0
- package/dist/gateway/http/sms.d.ts +4 -0
- package/dist/gateway/http/sms.js +249 -0
- package/dist/gateway/server.cjs +54 -3
- package/dist/gateway/server.d.ts +2 -0
- package/dist/gateway/server.js +54 -3
- package/dist/gateway/sms/commands.cjs +116 -0
- package/dist/gateway/sms/commands.d.ts +15 -0
- package/dist/gateway/sms/commands.js +79 -0
- package/dist/gateway/sms/control.cjs +118 -0
- package/dist/gateway/sms/control.d.ts +18 -0
- package/dist/gateway/sms/control.js +84 -0
- package/dist/gateway/sms/policyStore.cjs +198 -0
- package/dist/gateway/sms/policyStore.d.ts +37 -0
- package/dist/gateway/sms/policyStore.js +161 -0
- package/dist/providers/registry.cjs +1 -0
- package/dist/providers/registry.js +1 -0
- package/dist/skills/activation.cjs +92 -0
- package/dist/skills/activation.d.ts +12 -0
- package/dist/skills/activation.js +58 -0
- package/dist/skills/bin-requirements.cjs +63 -0
- package/dist/skills/bin-requirements.d.ts +3 -0
- package/dist/skills/bin-requirements.js +26 -0
- package/dist/skills/metadata.cjs +141 -0
- package/dist/skills/metadata.d.ts +29 -0
- package/dist/skills/metadata.js +104 -0
- package/dist/skills/overlay.cjs +75 -0
- package/dist/skills/overlay.d.ts +2 -0
- package/dist/skills/overlay.js +38 -0
- package/dist/tests/cli-config-loader.test.cjs +7 -3
- package/dist/tests/cli-config-loader.test.js +7 -3
- package/dist/tests/cli-config-warnings.test.cjs +41 -0
- package/dist/tests/cli-config-warnings.test.js +41 -0
- package/dist/tests/cli-init.test.cjs +86 -26
- package/dist/tests/cli-init.test.js +86 -26
- package/dist/tests/config-json-schema.test.cjs +12 -0
- package/dist/tests/config-json-schema.test.js +12 -0
- package/dist/tests/gateway-http-security.test.cjs +21 -0
- package/dist/tests/gateway-http-security.test.js +21 -0
- package/dist/tests/gateway-origin-policy.test.cjs +22 -0
- package/dist/tests/gateway-origin-policy.test.js +22 -0
- package/dist/tests/gateway.test.cjs +57 -0
- package/dist/tests/gateway.test.js +57 -0
- package/dist/tests/imagePersistence.test.cjs +26 -0
- package/dist/tests/imagePersistence.test.js +27 -1
- package/dist/tests/run-terminal-bench-official-script.test.cjs +61 -0
- package/dist/tests/run-terminal-bench-official-script.test.d.ts +1 -0
- package/dist/tests/run-terminal-bench-official-script.test.js +55 -0
- package/dist/tests/sessions-api.test.cjs +69 -1
- package/dist/tests/sessions-api.test.js +70 -2
- package/dist/tests/skill-activation.test.cjs +86 -0
- package/dist/tests/skill-activation.test.d.ts +1 -0
- package/dist/tests/skill-activation.test.js +80 -0
- package/dist/tests/skill-metadata.test.cjs +119 -0
- package/dist/tests/skill-metadata.test.d.ts +1 -0
- package/dist/tests/skill-metadata.test.js +113 -0
- package/dist/tests/skill-repository.test.cjs +363 -0
- package/dist/tests/skill-repository.test.js +363 -0
- package/dist/tests/sms-api.test.cjs +183 -0
- package/dist/tests/sms-api.test.d.ts +1 -0
- package/dist/tests/sms-api.test.js +177 -0
- package/dist/tests/sms-commands.test.cjs +90 -0
- package/dist/tests/sms-commands.test.d.ts +1 -0
- package/dist/tests/sms-commands.test.js +84 -0
- package/dist/tests/sms-policy-store.test.cjs +69 -0
- package/dist/tests/sms-policy-store.test.d.ts +1 -0
- package/dist/tests/sms-policy-store.test.js +63 -0
- package/dist/tests/teams-adapter.test.cjs +58 -0
- package/dist/tests/teams-adapter.test.d.ts +1 -0
- package/dist/tests/teams-adapter.test.js +52 -0
- package/dist/tests/terminal-bench-adapters-helpers.test.cjs +64 -0
- package/dist/tests/terminal-bench-adapters-helpers.test.d.ts +1 -0
- package/dist/tests/terminal-bench-adapters-helpers.test.js +58 -0
- package/dist/tests/terminal-bench-cleanup.test.cjs +93 -0
- package/dist/tests/terminal-bench-cleanup.test.d.ts +1 -0
- package/dist/tests/terminal-bench-cleanup.test.js +87 -0
- package/dist/tests/terminal-bench-config.test.cjs +62 -0
- package/dist/tests/terminal-bench-config.test.d.ts +1 -0
- package/dist/tests/terminal-bench-config.test.js +56 -0
- package/dist/tests/terminal-bench-official.test.cjs +194 -0
- package/dist/tests/terminal-bench-official.test.d.ts +1 -0
- package/dist/tests/terminal-bench-official.test.js +188 -0
- package/dist/tests/terminal-bench-runner.test.cjs +82 -0
- package/dist/tests/terminal-bench-runner.test.d.ts +1 -0
- package/dist/tests/terminal-bench-runner.test.js +76 -0
- package/dist/tests/terminal-bench-scoring.test.cjs +128 -0
- package/dist/tests/terminal-bench-scoring.test.d.ts +1 -0
- package/dist/tests/terminal-bench-scoring.test.js +122 -0
- package/dist/tools/mcp-fal-ai.cjs +1 -1
- package/dist/tools/mcp-fal-ai.js +1 -1
- package/dist/webui/assets/index-Cyg_Hs57.css +11 -0
- package/dist/webui/assets/{index-BMekSELC.js → index-DZXLLjaA.js} +109 -109
- package/dist/webui/index.html +2 -2
- package/package.json +14 -5
- package/skills/gog/SKILL.md +1 -1
- package/skills/weather/SKILL.md +1 -1
- package/templates/agents/game-dev/agent.md +122 -63
- package/templates/agents/game-dev/art-director.md +106 -0
- package/templates/agents/game-dev/game-designer.md +87 -0
- package/templates/agents/game-dev/scene-engineer.md +474 -0
- package/dist/webui/assets/index-Cwkg4DKj.css +0 -11
- package/skills/ui-registry/SKILL.md +0 -35
- package/templates/agents/game-dev/art-generation.md +0 -38
- package/templates/agents/game-dev/asset-refinement.md +0 -17
- package/templates/agents/game-dev/planning-idea.md +0 -17
- package/templates/agents/game-dev/ui-specialist.md +0 -17
package/dist/cli/types.d.ts
CHANGED
|
@@ -66,6 +66,24 @@ export interface WingmanConfig {
|
|
|
66
66
|
gatewayPassword?: string;
|
|
67
67
|
responseChunkSize?: number;
|
|
68
68
|
};
|
|
69
|
+
teams?: {
|
|
70
|
+
enabled?: boolean;
|
|
71
|
+
appId?: string;
|
|
72
|
+
appPassword?: string;
|
|
73
|
+
appType?: "MultiTenant" | "SingleTenant" | "UserAssignedMsi" | "UserAssignedMSI";
|
|
74
|
+
tenantId?: string;
|
|
75
|
+
endpointPath?: string;
|
|
76
|
+
mentionOnly?: boolean;
|
|
77
|
+
allowBots?: boolean;
|
|
78
|
+
allowedTeamIds?: string[];
|
|
79
|
+
allowedChannelIds?: string[];
|
|
80
|
+
channelSessions?: Record<string, string>;
|
|
81
|
+
sessionCommand?: string;
|
|
82
|
+
gatewayUrl?: string;
|
|
83
|
+
gatewayToken?: string;
|
|
84
|
+
gatewayPassword?: string;
|
|
85
|
+
responseChunkSize?: number;
|
|
86
|
+
};
|
|
69
87
|
};
|
|
70
88
|
};
|
|
71
89
|
agents?: {
|
|
@@ -0,0 +1,419 @@
|
|
|
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
|
+
TeamsGatewayAdapter: ()=>TeamsGatewayAdapter,
|
|
28
|
+
normalizeTeamsEndpointPath: ()=>normalizeTeamsEndpointPath,
|
|
29
|
+
isTeamsBotMentioned: ()=>isTeamsBotMentioned,
|
|
30
|
+
resolveTeamsChannelSessionKey: ()=>resolveTeamsChannelSessionKey,
|
|
31
|
+
splitTeamsMessage: ()=>splitTeamsMessage,
|
|
32
|
+
extractTeamsMentionTexts: ()=>extractTeamsMentionTexts,
|
|
33
|
+
DEFAULT_TEAMS_RESPONSE_CHUNK: ()=>DEFAULT_TEAMS_RESPONSE_CHUNK,
|
|
34
|
+
DEFAULT_TEAMS_ENDPOINT_PATH: ()=>DEFAULT_TEAMS_ENDPOINT_PATH,
|
|
35
|
+
stripTeamsBotMention: ()=>stripTeamsBotMention
|
|
36
|
+
});
|
|
37
|
+
const external_botbuilder_namespaceObject = require("botbuilder");
|
|
38
|
+
const streamParser_cjs_namespaceObject = require("../../cli/core/streamParser.cjs");
|
|
39
|
+
const external_logger_cjs_namespaceObject = require("../../logger.cjs");
|
|
40
|
+
const external_rpcClient_cjs_namespaceObject = require("../rpcClient.cjs");
|
|
41
|
+
const external_discord_cjs_namespaceObject = require("./discord.cjs");
|
|
42
|
+
function _define_property(obj, key, value) {
|
|
43
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
44
|
+
value: value,
|
|
45
|
+
enumerable: true,
|
|
46
|
+
configurable: true,
|
|
47
|
+
writable: true
|
|
48
|
+
});
|
|
49
|
+
else obj[key] = value;
|
|
50
|
+
return obj;
|
|
51
|
+
}
|
|
52
|
+
const DEFAULT_TEAMS_ENDPOINT_PATH = "/api/adapters/teams/messages";
|
|
53
|
+
const DEFAULT_TEAMS_RESPONSE_CHUNK = 3500;
|
|
54
|
+
function normalizeTeamsEndpointPath(path) {
|
|
55
|
+
const fallback = DEFAULT_TEAMS_ENDPOINT_PATH;
|
|
56
|
+
if (!path || "string" != typeof path) return fallback;
|
|
57
|
+
const trimmed = path.trim();
|
|
58
|
+
if (!trimmed) return fallback;
|
|
59
|
+
return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
60
|
+
}
|
|
61
|
+
function splitTeamsMessage(text, maxLength = DEFAULT_TEAMS_RESPONSE_CHUNK) {
|
|
62
|
+
const normalized = text.trim();
|
|
63
|
+
if (!normalized) return [];
|
|
64
|
+
const chunks = [];
|
|
65
|
+
let current = "";
|
|
66
|
+
for (const char of normalized){
|
|
67
|
+
if (current.length + 1 > maxLength) {
|
|
68
|
+
chunks.push(current);
|
|
69
|
+
current = "";
|
|
70
|
+
}
|
|
71
|
+
current += char;
|
|
72
|
+
}
|
|
73
|
+
if (current) chunks.push(current);
|
|
74
|
+
return chunks;
|
|
75
|
+
}
|
|
76
|
+
function escapeRegex(value) {
|
|
77
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
78
|
+
}
|
|
79
|
+
function getEntities(activity) {
|
|
80
|
+
if (!Array.isArray(activity.entities)) return [];
|
|
81
|
+
return activity.entities;
|
|
82
|
+
}
|
|
83
|
+
function extractTeamsMentionTexts(activity, botAccountId) {
|
|
84
|
+
const recipientName = activity.recipient?.name?.trim().toLowerCase();
|
|
85
|
+
const texts = new Set();
|
|
86
|
+
for (const entity of getEntities(activity)){
|
|
87
|
+
if ("mention" !== entity.type || "string" != typeof entity.text) continue;
|
|
88
|
+
const mentionedId = entity.mentioned?.id?.trim();
|
|
89
|
+
const mentionedName = entity.mentioned?.name?.trim().toLowerCase();
|
|
90
|
+
if (botAccountId && mentionedId === botAccountId || recipientName && mentionedName === recipientName) texts.add(entity.text);
|
|
91
|
+
}
|
|
92
|
+
return Array.from(texts);
|
|
93
|
+
}
|
|
94
|
+
function stripTeamsBotMention(content, mentionTexts = []) {
|
|
95
|
+
if (!content) return content;
|
|
96
|
+
let next = content;
|
|
97
|
+
for (const text of mentionTexts)next = next.replace(new RegExp(escapeRegex(text), "gi"), " ");
|
|
98
|
+
return next.replace(/<at>.*?<\/at>/gi, " ").replace(/\s+/g, " ").trim();
|
|
99
|
+
}
|
|
100
|
+
function isTeamsBotMentioned(activity, botAccountId) {
|
|
101
|
+
if (extractTeamsMentionTexts(activity, botAccountId).length > 0) return true;
|
|
102
|
+
const text = activity.text || "";
|
|
103
|
+
const recipientName = activity.recipient?.name?.trim();
|
|
104
|
+
if (recipientName) {
|
|
105
|
+
const regex = new RegExp(`<at>\\s*${escapeRegex(recipientName)}\\s*</at>`, "i");
|
|
106
|
+
return regex.test(text);
|
|
107
|
+
}
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
function resolveTeamsChannelSessionKey(channelId, channelSessions) {
|
|
111
|
+
if (!channelSessions) return;
|
|
112
|
+
return channelSessions[channelId];
|
|
113
|
+
}
|
|
114
|
+
function toHeaderRecord(headers) {
|
|
115
|
+
const result = {};
|
|
116
|
+
for (const [key, value] of headers.entries())result[key] = value;
|
|
117
|
+
if (!result.Authorization && result.authorization) result.Authorization = result.authorization;
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
function buildBotBuilderResponse(resolve) {
|
|
121
|
+
let statusCode = 200;
|
|
122
|
+
const headers = new Headers();
|
|
123
|
+
let body;
|
|
124
|
+
const finalize = (payload)=>{
|
|
125
|
+
if (void 0 !== payload) if ("string" == typeof payload) body = payload;
|
|
126
|
+
else {
|
|
127
|
+
body = JSON.stringify(payload);
|
|
128
|
+
if (!headers.get("Content-Type")) headers.set("Content-Type", "application/json");
|
|
129
|
+
}
|
|
130
|
+
resolve(new Response(body, {
|
|
131
|
+
status: statusCode,
|
|
132
|
+
headers
|
|
133
|
+
}));
|
|
134
|
+
};
|
|
135
|
+
return {
|
|
136
|
+
status (code) {
|
|
137
|
+
statusCode = code;
|
|
138
|
+
return this;
|
|
139
|
+
},
|
|
140
|
+
header (name, value) {
|
|
141
|
+
headers.set(name, value);
|
|
142
|
+
return this;
|
|
143
|
+
},
|
|
144
|
+
send (payload) {
|
|
145
|
+
finalize(payload);
|
|
146
|
+
},
|
|
147
|
+
end (payload) {
|
|
148
|
+
finalize(payload);
|
|
149
|
+
},
|
|
150
|
+
socket: {}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function extractTeamId(activity) {
|
|
154
|
+
const raw = activity.channelData?.team?.id;
|
|
155
|
+
if ("string" == typeof raw && raw.trim()) return raw;
|
|
156
|
+
}
|
|
157
|
+
function extractChannelId(activity) {
|
|
158
|
+
const channelId = activity.channelData?.channel?.id;
|
|
159
|
+
if ("string" == typeof channelId && channelId.trim()) return channelId;
|
|
160
|
+
const conversationId = activity.conversation?.id;
|
|
161
|
+
if ("string" == typeof conversationId && conversationId.trim()) return conversationId;
|
|
162
|
+
}
|
|
163
|
+
function extractThreadId(activity) {
|
|
164
|
+
if (activity.replyToId && activity.replyToId.trim()) return activity.replyToId;
|
|
165
|
+
const conversationId = activity.conversation?.id;
|
|
166
|
+
if (!conversationId) return;
|
|
167
|
+
const match = conversationId.match(/;messageid=([^;]+)/i);
|
|
168
|
+
if (!match?.[1]) return;
|
|
169
|
+
try {
|
|
170
|
+
return decodeURIComponent(match[1]);
|
|
171
|
+
} catch {
|
|
172
|
+
return match[1];
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function isDirectMessage(activity) {
|
|
176
|
+
return activity.conversation?.conversationType === "personal";
|
|
177
|
+
}
|
|
178
|
+
function buildRoutingInfo(activity, botAccountId) {
|
|
179
|
+
const routing = {
|
|
180
|
+
channel: "teams",
|
|
181
|
+
accountId: botAccountId
|
|
182
|
+
};
|
|
183
|
+
const teamId = extractTeamId(activity);
|
|
184
|
+
if (teamId) routing.teamId = teamId;
|
|
185
|
+
const conversationType = activity.conversation?.conversationType;
|
|
186
|
+
if ("personal" === conversationType) {
|
|
187
|
+
const dmId = activity.from?.aadObjectId || activity.from?.id;
|
|
188
|
+
if (dmId) routing.peer = {
|
|
189
|
+
kind: "dm",
|
|
190
|
+
id: dmId
|
|
191
|
+
};
|
|
192
|
+
} else if ("groupChat" === conversationType) {
|
|
193
|
+
if (activity.conversation?.id) routing.peer = {
|
|
194
|
+
kind: "group",
|
|
195
|
+
id: activity.conversation.id
|
|
196
|
+
};
|
|
197
|
+
} else {
|
|
198
|
+
const channelId = extractChannelId(activity);
|
|
199
|
+
if (channelId) routing.peer = {
|
|
200
|
+
kind: "channel",
|
|
201
|
+
id: channelId
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
const threadId = extractThreadId(activity);
|
|
205
|
+
if (threadId) routing.threadId = threadId;
|
|
206
|
+
return routing;
|
|
207
|
+
}
|
|
208
|
+
function isBotMessage(activity) {
|
|
209
|
+
return activity.from?.role === "bot";
|
|
210
|
+
}
|
|
211
|
+
class TeamsGatewayAdapter {
|
|
212
|
+
get endpointPath() {
|
|
213
|
+
return normalizeTeamsEndpointPath(this.config.endpointPath);
|
|
214
|
+
}
|
|
215
|
+
async start() {
|
|
216
|
+
if (this.started) return;
|
|
217
|
+
if (!this.config.enabled) return;
|
|
218
|
+
if (!this.config.appId || !this.config.appPassword) return void this.logger.warn("Teams adapter enabled but Microsoft app credentials are incomplete.");
|
|
219
|
+
this.gatewayClient = new external_rpcClient_cjs_namespaceObject.GatewayRpcClient(this.gateway.url, {
|
|
220
|
+
token: this.gateway.token,
|
|
221
|
+
password: this.gateway.password,
|
|
222
|
+
clientType: "teams"
|
|
223
|
+
});
|
|
224
|
+
await this.gatewayClient.connect();
|
|
225
|
+
const authConfig = {
|
|
226
|
+
MicrosoftAppId: this.config.appId,
|
|
227
|
+
MicrosoftAppPassword: this.config.appPassword,
|
|
228
|
+
MicrosoftAppType: this.config.appType
|
|
229
|
+
};
|
|
230
|
+
if (this.config.tenantId) authConfig.MicrosoftAppTenantId = this.config.tenantId;
|
|
231
|
+
const authentication = new external_botbuilder_namespaceObject.ConfigurationBotFrameworkAuthentication(authConfig);
|
|
232
|
+
this.adapter = new external_botbuilder_namespaceObject.CloudAdapter(authentication);
|
|
233
|
+
this.adapter.onTurnError = async (context, error)=>{
|
|
234
|
+
this.logger.error("Teams adapter turn error", error);
|
|
235
|
+
try {
|
|
236
|
+
await context.sendActivity("Sorry, I hit an error running that request.");
|
|
237
|
+
} catch {}
|
|
238
|
+
};
|
|
239
|
+
this.started = true;
|
|
240
|
+
}
|
|
241
|
+
async stop() {
|
|
242
|
+
if (!this.started) return;
|
|
243
|
+
this.started = false;
|
|
244
|
+
this.adapter = null;
|
|
245
|
+
if (this.gatewayClient) {
|
|
246
|
+
this.gatewayClient.disconnect();
|
|
247
|
+
this.gatewayClient = null;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
async handleHttpRequest(req, url) {
|
|
251
|
+
if (url.pathname !== this.endpointPath) return null;
|
|
252
|
+
if ("POST" !== req.method) return new Response("Method Not Allowed", {
|
|
253
|
+
status: 405,
|
|
254
|
+
headers: {
|
|
255
|
+
Allow: "POST"
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
if (!this.started || !this.adapter || !this.gatewayClient) return new Response("Teams adapter not started", {
|
|
259
|
+
status: 503
|
|
260
|
+
});
|
|
261
|
+
const adapter = this.adapter;
|
|
262
|
+
let body;
|
|
263
|
+
try {
|
|
264
|
+
body = await req.json();
|
|
265
|
+
} catch {
|
|
266
|
+
return new Response("Invalid JSON payload", {
|
|
267
|
+
status: 400
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
const activity = body;
|
|
271
|
+
return new Promise((resolve)=>{
|
|
272
|
+
const response = buildBotBuilderResponse(resolve);
|
|
273
|
+
adapter.process({
|
|
274
|
+
method: req.method,
|
|
275
|
+
headers: toHeaderRecord(req.headers),
|
|
276
|
+
body: activity
|
|
277
|
+
}, response, async (context)=>this.handleMessage(context)).catch((error)=>{
|
|
278
|
+
this.logger.error("Teams adapter failed to process request", error);
|
|
279
|
+
resolve(new Response("Failed to process Teams request", {
|
|
280
|
+
status: 500
|
|
281
|
+
}));
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
async handleMessage(context) {
|
|
286
|
+
if (!this.gatewayClient) return;
|
|
287
|
+
const activity = context.activity;
|
|
288
|
+
if ("message" !== activity.type) return;
|
|
289
|
+
if (!activity.text && !activity.attachments?.length) return;
|
|
290
|
+
if (isBotMessage(activity)) {
|
|
291
|
+
if (!this.config.allowBots) return;
|
|
292
|
+
if (activity.from?.id && activity.from.id === activity.recipient?.id) return;
|
|
293
|
+
}
|
|
294
|
+
const teamId = extractTeamId(activity);
|
|
295
|
+
if (this.config.allowedTeamIds.length > 0 && teamId) {
|
|
296
|
+
if (!this.config.allowedTeamIds.includes(teamId)) return;
|
|
297
|
+
}
|
|
298
|
+
const channelId = extractChannelId(activity);
|
|
299
|
+
if (this.config.allowedChannelIds.length > 0) {
|
|
300
|
+
if (!channelId || !this.config.allowedChannelIds.includes(channelId)) return;
|
|
301
|
+
}
|
|
302
|
+
const botAccountId = activity.recipient?.id || this.config.appId;
|
|
303
|
+
if (this.config.mentionOnly && !isDirectMessage(activity) && !isTeamsBotMentioned(activity, botAccountId)) return;
|
|
304
|
+
const mentionTexts = extractTeamsMentionTexts(activity, botAccountId);
|
|
305
|
+
const cleaned = stripTeamsBotMention(activity.text || "", mentionTexts);
|
|
306
|
+
const attachments = (activity.attachments || []).map((attachment)=>attachment.contentUrl).filter((url)=>Boolean(url));
|
|
307
|
+
const attachmentText = attachments.length > 0 ? `\n\nAttachments:\n${attachments.map((url)=>`- ${url}`).join("\n")}` : "";
|
|
308
|
+
let content = `${cleaned}${attachmentText}`.trim();
|
|
309
|
+
const { sessionKey, content: nextContent, matched } = (0, external_discord_cjs_namespaceObject.extractSessionOverride)(content, this.config.sessionCommand);
|
|
310
|
+
let resolvedSessionKey = sessionKey;
|
|
311
|
+
let usedChannelMapping = false;
|
|
312
|
+
if (matched) {
|
|
313
|
+
content = nextContent.trim();
|
|
314
|
+
if (!sessionKey) return void await context.sendActivity(`Provide a session key after \`${this.config.sessionCommand}\`.`);
|
|
315
|
+
}
|
|
316
|
+
if (!matched && channelId) {
|
|
317
|
+
resolvedSessionKey = resolveTeamsChannelSessionKey(channelId, this.config.channelSessions);
|
|
318
|
+
usedChannelMapping = Boolean(resolvedSessionKey);
|
|
319
|
+
}
|
|
320
|
+
const inferredAgentId = (0, external_discord_cjs_namespaceObject.parseAgentIdFromSessionKey)(resolvedSessionKey);
|
|
321
|
+
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.`, {
|
|
322
|
+
sessionKey: resolvedSessionKey
|
|
323
|
+
});
|
|
324
|
+
if (!content) return;
|
|
325
|
+
const payload = {
|
|
326
|
+
agentId: inferredAgentId,
|
|
327
|
+
content,
|
|
328
|
+
routing: buildRoutingInfo(activity, botAccountId),
|
|
329
|
+
sessionKey: resolvedSessionKey
|
|
330
|
+
};
|
|
331
|
+
try {
|
|
332
|
+
await context.sendActivity({
|
|
333
|
+
type: "typing"
|
|
334
|
+
});
|
|
335
|
+
let fallbackText = "";
|
|
336
|
+
let uiFallbackText = "";
|
|
337
|
+
let uiOnlyDetected = false;
|
|
338
|
+
const textByMessageId = new Map();
|
|
339
|
+
const messageOrder = [];
|
|
340
|
+
await this.gatewayClient.requestAgent(payload, (event)=>{
|
|
341
|
+
if (!event || "object" != typeof event) return;
|
|
342
|
+
if ("agent-error" === event.type) {
|
|
343
|
+
fallbackText += `\n${event.error || "Agent error"}`;
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
if ("agent-stream" !== event.type) return;
|
|
347
|
+
const parsedChunks = (0, streamParser_cjs_namespaceObject.parseStreamChunk)(event.chunk);
|
|
348
|
+
for (const chunk of parsedChunks){
|
|
349
|
+
if ("tool-result" === chunk.type && chunk.toolResult?.output) {
|
|
350
|
+
const meta = (0, external_discord_cjs_namespaceObject.extractUiMeta)(chunk.toolResult.output);
|
|
351
|
+
if (true === meta.uiOnly) uiOnlyDetected = true;
|
|
352
|
+
if (meta.textFallback) uiFallbackText = meta.textFallback;
|
|
353
|
+
}
|
|
354
|
+
if ("text" === chunk.type && chunk.text) {
|
|
355
|
+
if (chunk.messageId) {
|
|
356
|
+
if (!textByMessageId.has(chunk.messageId)) {
|
|
357
|
+
messageOrder.push(chunk.messageId);
|
|
358
|
+
textByMessageId.set(chunk.messageId, chunk.text);
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
const current = textByMessageId.get(chunk.messageId) || "";
|
|
362
|
+
textByMessageId.set(chunk.messageId, chunk.isDelta ? current + chunk.text : chunk.text);
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
fallbackText += chunk.text;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
const orderedText = messageOrder.map((id)=>textByMessageId.get(id)).filter((value)=>Boolean(value)).join("\n\n");
|
|
370
|
+
let responseText = `${fallbackText}${fallbackText && orderedText ? "\n\n" : ""}${orderedText}`.trim();
|
|
371
|
+
if (uiFallbackText && (uiOnlyDetected || !responseText)) responseText = uiFallbackText.trim();
|
|
372
|
+
if (!responseText) return;
|
|
373
|
+
const chunks = splitTeamsMessage(responseText, this.config.responseChunkSize);
|
|
374
|
+
for (const chunk of chunks)await context.sendActivity(chunk);
|
|
375
|
+
} catch (error) {
|
|
376
|
+
this.logger.error("Teams adapter failed to handle message", error);
|
|
377
|
+
try {
|
|
378
|
+
await context.sendActivity("Sorry, I hit an error running that request.");
|
|
379
|
+
} catch {}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
constructor(config, gateway, logger){
|
|
383
|
+
_define_property(this, "config", void 0);
|
|
384
|
+
_define_property(this, "gateway", void 0);
|
|
385
|
+
_define_property(this, "adapter", void 0);
|
|
386
|
+
_define_property(this, "gatewayClient", void 0);
|
|
387
|
+
_define_property(this, "logger", void 0);
|
|
388
|
+
_define_property(this, "started", void 0);
|
|
389
|
+
this.config = config;
|
|
390
|
+
this.gateway = gateway;
|
|
391
|
+
this.adapter = null;
|
|
392
|
+
this.gatewayClient = null;
|
|
393
|
+
this.started = false;
|
|
394
|
+
this.logger = logger || (0, external_logger_cjs_namespaceObject.createLogger)();
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
exports.DEFAULT_TEAMS_ENDPOINT_PATH = __webpack_exports__.DEFAULT_TEAMS_ENDPOINT_PATH;
|
|
398
|
+
exports.DEFAULT_TEAMS_RESPONSE_CHUNK = __webpack_exports__.DEFAULT_TEAMS_RESPONSE_CHUNK;
|
|
399
|
+
exports.TeamsGatewayAdapter = __webpack_exports__.TeamsGatewayAdapter;
|
|
400
|
+
exports.extractTeamsMentionTexts = __webpack_exports__.extractTeamsMentionTexts;
|
|
401
|
+
exports.isTeamsBotMentioned = __webpack_exports__.isTeamsBotMentioned;
|
|
402
|
+
exports.normalizeTeamsEndpointPath = __webpack_exports__.normalizeTeamsEndpointPath;
|
|
403
|
+
exports.resolveTeamsChannelSessionKey = __webpack_exports__.resolveTeamsChannelSessionKey;
|
|
404
|
+
exports.splitTeamsMessage = __webpack_exports__.splitTeamsMessage;
|
|
405
|
+
exports.stripTeamsBotMention = __webpack_exports__.stripTeamsBotMention;
|
|
406
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
407
|
+
"DEFAULT_TEAMS_ENDPOINT_PATH",
|
|
408
|
+
"DEFAULT_TEAMS_RESPONSE_CHUNK",
|
|
409
|
+
"TeamsGatewayAdapter",
|
|
410
|
+
"extractTeamsMentionTexts",
|
|
411
|
+
"isTeamsBotMentioned",
|
|
412
|
+
"normalizeTeamsEndpointPath",
|
|
413
|
+
"resolveTeamsChannelSessionKey",
|
|
414
|
+
"splitTeamsMessage",
|
|
415
|
+
"stripTeamsBotMention"
|
|
416
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
417
|
+
Object.defineProperty(exports, '__esModule', {
|
|
418
|
+
value: true
|
|
419
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type Activity } from "botbuilder";
|
|
2
|
+
import { type Logger } from "@/logger.js";
|
|
3
|
+
export interface TeamsAdapterConfig {
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
appId?: string;
|
|
6
|
+
appPassword?: string;
|
|
7
|
+
appType: "MultiTenant" | "SingleTenant" | "UserAssignedMsi" | "UserAssignedMSI";
|
|
8
|
+
tenantId?: string;
|
|
9
|
+
endpointPath: string;
|
|
10
|
+
mentionOnly: boolean;
|
|
11
|
+
allowBots: boolean;
|
|
12
|
+
allowedTeamIds: string[];
|
|
13
|
+
allowedChannelIds: string[];
|
|
14
|
+
channelSessions?: Record<string, string>;
|
|
15
|
+
sessionCommand: string;
|
|
16
|
+
gatewayUrl?: string;
|
|
17
|
+
gatewayToken?: string;
|
|
18
|
+
gatewayPassword?: string;
|
|
19
|
+
responseChunkSize: number;
|
|
20
|
+
}
|
|
21
|
+
export interface TeamsAdapterGatewayConfig {
|
|
22
|
+
url: string;
|
|
23
|
+
token?: string;
|
|
24
|
+
password?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare const DEFAULT_TEAMS_ENDPOINT_PATH = "/api/adapters/teams/messages";
|
|
27
|
+
export declare const DEFAULT_TEAMS_RESPONSE_CHUNK = 3500;
|
|
28
|
+
export declare function normalizeTeamsEndpointPath(path: string | undefined): string;
|
|
29
|
+
export declare function splitTeamsMessage(text: string, maxLength?: number): string[];
|
|
30
|
+
export declare function extractTeamsMentionTexts(activity: Activity, botAccountId?: string): string[];
|
|
31
|
+
export declare function stripTeamsBotMention(content: string, mentionTexts?: string[]): string;
|
|
32
|
+
export declare function isTeamsBotMentioned(activity: Activity, botAccountId?: string): boolean;
|
|
33
|
+
export declare function resolveTeamsChannelSessionKey(channelId: string, channelSessions?: Record<string, string>): string | undefined;
|
|
34
|
+
export declare class TeamsGatewayAdapter {
|
|
35
|
+
private config;
|
|
36
|
+
private gateway;
|
|
37
|
+
private adapter;
|
|
38
|
+
private gatewayClient;
|
|
39
|
+
private logger;
|
|
40
|
+
private started;
|
|
41
|
+
constructor(config: TeamsAdapterConfig, gateway: TeamsAdapterGatewayConfig, logger?: Logger);
|
|
42
|
+
get endpointPath(): string;
|
|
43
|
+
start(): Promise<void>;
|
|
44
|
+
stop(): Promise<void>;
|
|
45
|
+
handleHttpRequest(req: Request, url: URL): Promise<Response | null>;
|
|
46
|
+
private handleMessage;
|
|
47
|
+
}
|