@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.
- 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/config/schema.cjs +36 -1
- package/dist/cli/config/schema.d.ts +46 -0
- package/dist/cli/config/schema.js +36 -1
- package/dist/cli/config/warnings.cjs +119 -51
- package/dist/cli/config/warnings.js +119 -51
- package/dist/cli/core/agentInvoker.cjs +9 -2
- package/dist/cli/core/agentInvoker.d.ts +1 -0
- package/dist/cli/core/agentInvoker.js +9 -2
- 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/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/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 +32 -26
- package/dist/tests/cli-init.test.js +32 -26
- 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/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 +11 -2
- 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/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
|
@@ -32,66 +32,134 @@ const isBlank = (value)=>0 === value.trim().length;
|
|
|
32
32
|
function collectConfigWarnings(config) {
|
|
33
33
|
const warnings = [];
|
|
34
34
|
const discord = config.gateway?.adapters?.discord;
|
|
35
|
-
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (isBlank(discord.sessionCommand || "")) warnings.push({
|
|
41
|
-
code: "discord-session-command-blank",
|
|
42
|
-
message: 'gateway.adapters.discord.sessionCommand is blank; it will fall back to "!session".'
|
|
43
|
-
});
|
|
44
|
-
for (const [rawKey, rawValue] of Object.entries(discord.channelSessions ?? {})){
|
|
45
|
-
const keyLabel = JSON.stringify(rawKey);
|
|
46
|
-
const value = "string" == typeof rawValue ? rawValue : "";
|
|
47
|
-
const valueLabel = JSON.stringify(value);
|
|
48
|
-
if (hasLeadingOrTrailingWhitespace(rawKey)) warnings.push({
|
|
49
|
-
code: "discord-channel-sessions-key-whitespace",
|
|
50
|
-
message: `gateway.adapters.discord.channelSessions key ${keyLabel} has leading/trailing whitespace.`
|
|
35
|
+
const teams = config.gateway?.adapters?.teams;
|
|
36
|
+
if (discord?.enabled) {
|
|
37
|
+
if (!discord.token) warnings.push({
|
|
38
|
+
code: "discord-token-missing",
|
|
39
|
+
message: "gateway.adapters.discord.enabled is true but gateway.adapters.discord.token is not set; the adapter will not start."
|
|
51
40
|
});
|
|
52
|
-
if (
|
|
53
|
-
code: "discord-
|
|
54
|
-
message:
|
|
41
|
+
if (isBlank(discord.sessionCommand || "")) warnings.push({
|
|
42
|
+
code: "discord-session-command-blank",
|
|
43
|
+
message: 'gateway.adapters.discord.sessionCommand is blank; it will fall back to "!session".'
|
|
55
44
|
});
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
45
|
+
for (const [rawKey, rawValue] of Object.entries(discord.channelSessions ?? {})){
|
|
46
|
+
const keyLabel = JSON.stringify(rawKey);
|
|
47
|
+
const value = "string" == typeof rawValue ? rawValue : "";
|
|
48
|
+
const valueLabel = JSON.stringify(value);
|
|
49
|
+
if (hasLeadingOrTrailingWhitespace(rawKey)) warnings.push({
|
|
50
|
+
code: "discord-channel-sessions-key-whitespace",
|
|
51
|
+
message: `gateway.adapters.discord.channelSessions key ${keyLabel} has leading/trailing whitespace.`
|
|
52
|
+
});
|
|
53
|
+
if (hasLeadingOrTrailingWhitespace(value)) warnings.push({
|
|
54
|
+
code: "discord-channel-sessions-value-whitespace",
|
|
55
|
+
message: `gateway.adapters.discord.channelSessions[${keyLabel}] value ${valueLabel} has leading/trailing whitespace.`
|
|
56
|
+
});
|
|
57
|
+
if (isBlank(value)) {
|
|
58
|
+
warnings.push({
|
|
59
|
+
code: "discord-channel-sessions-value-blank",
|
|
60
|
+
message: `gateway.adapters.discord.channelSessions[${keyLabel}] is empty; mapping will fall back to derived session keys.`
|
|
61
|
+
});
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (!AGENT_PREFIX.test(value.trim())) warnings.push({
|
|
65
|
+
code: "discord-channel-sessions-missing-agent",
|
|
66
|
+
message: `gateway.adapters.discord.channelSessions[${keyLabel}] does not include an agent prefix (agent:<id>:...); agent selection will use bindings/default.`
|
|
60
67
|
});
|
|
61
|
-
continue;
|
|
62
68
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
for (const entry of discord.allowedChannels ?? []){
|
|
70
|
+
const label = JSON.stringify(entry);
|
|
71
|
+
if (isBlank(entry)) {
|
|
72
|
+
warnings.push({
|
|
73
|
+
code: "discord-allowed-channels-blank",
|
|
74
|
+
message: "gateway.adapters.discord.allowedChannels contains a blank entry; remove empty strings."
|
|
75
|
+
});
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (hasLeadingOrTrailingWhitespace(entry)) warnings.push({
|
|
79
|
+
code: "discord-allowed-channels-whitespace",
|
|
80
|
+
message: `gateway.adapters.discord.allowedChannels contains ${label} with leading/trailing whitespace.`
|
|
74
81
|
});
|
|
75
|
-
continue;
|
|
76
82
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
for (const entry of discord.allowedGuilds ?? []){
|
|
84
|
+
const label = JSON.stringify(entry);
|
|
85
|
+
if (isBlank(entry)) {
|
|
86
|
+
warnings.push({
|
|
87
|
+
code: "discord-allowed-guilds-blank",
|
|
88
|
+
message: "gateway.adapters.discord.allowedGuilds contains a blank entry; remove empty strings."
|
|
89
|
+
});
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (hasLeadingOrTrailingWhitespace(entry)) warnings.push({
|
|
93
|
+
code: "discord-allowed-guilds-whitespace",
|
|
94
|
+
message: `gateway.adapters.discord.allowedGuilds contains ${label} with leading/trailing whitespace.`
|
|
88
95
|
});
|
|
89
|
-
continue;
|
|
90
96
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
97
|
+
}
|
|
98
|
+
if (teams?.enabled) {
|
|
99
|
+
if (!teams.appId || !teams.appPassword) warnings.push({
|
|
100
|
+
code: "teams-credentials-missing",
|
|
101
|
+
message: "gateway.adapters.teams.enabled is true but gateway.adapters.teams.appId/appPassword are not both set; the adapter will not start."
|
|
102
|
+
});
|
|
103
|
+
if (isBlank(teams.sessionCommand || "")) warnings.push({
|
|
104
|
+
code: "teams-session-command-blank",
|
|
105
|
+
message: 'gateway.adapters.teams.sessionCommand is blank; it will fall back to "!session".'
|
|
106
|
+
});
|
|
107
|
+
if (isBlank(teams.endpointPath || "")) warnings.push({
|
|
108
|
+
code: "teams-endpoint-path-blank",
|
|
109
|
+
message: 'gateway.adapters.teams.endpointPath is blank; it will fall back to "/api/adapters/teams/messages".'
|
|
94
110
|
});
|
|
111
|
+
for (const [rawKey, rawValue] of Object.entries(teams.channelSessions ?? {})){
|
|
112
|
+
const keyLabel = JSON.stringify(rawKey);
|
|
113
|
+
const value = "string" == typeof rawValue ? rawValue : "";
|
|
114
|
+
const valueLabel = JSON.stringify(value);
|
|
115
|
+
if (hasLeadingOrTrailingWhitespace(rawKey)) warnings.push({
|
|
116
|
+
code: "teams-channel-sessions-key-whitespace",
|
|
117
|
+
message: `gateway.adapters.teams.channelSessions key ${keyLabel} has leading/trailing whitespace.`
|
|
118
|
+
});
|
|
119
|
+
if (hasLeadingOrTrailingWhitespace(value)) warnings.push({
|
|
120
|
+
code: "teams-channel-sessions-value-whitespace",
|
|
121
|
+
message: `gateway.adapters.teams.channelSessions[${keyLabel}] value ${valueLabel} has leading/trailing whitespace.`
|
|
122
|
+
});
|
|
123
|
+
if (isBlank(value)) {
|
|
124
|
+
warnings.push({
|
|
125
|
+
code: "teams-channel-sessions-value-blank",
|
|
126
|
+
message: `gateway.adapters.teams.channelSessions[${keyLabel}] is empty; mapping will fall back to derived session keys.`
|
|
127
|
+
});
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (!AGENT_PREFIX.test(value.trim())) warnings.push({
|
|
131
|
+
code: "teams-channel-sessions-missing-agent",
|
|
132
|
+
message: `gateway.adapters.teams.channelSessions[${keyLabel}] does not include an agent prefix (agent:<id>:...); agent selection will use bindings/default.`
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
for (const entry of teams.allowedChannelIds ?? []){
|
|
136
|
+
const label = JSON.stringify(entry);
|
|
137
|
+
if (isBlank(entry)) {
|
|
138
|
+
warnings.push({
|
|
139
|
+
code: "teams-allowed-channel-ids-blank",
|
|
140
|
+
message: "gateway.adapters.teams.allowedChannelIds contains a blank entry; remove empty strings."
|
|
141
|
+
});
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (hasLeadingOrTrailingWhitespace(entry)) warnings.push({
|
|
145
|
+
code: "teams-allowed-channel-ids-whitespace",
|
|
146
|
+
message: `gateway.adapters.teams.allowedChannelIds contains ${label} with leading/trailing whitespace.`
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
for (const entry of teams.allowedTeamIds ?? []){
|
|
150
|
+
const label = JSON.stringify(entry);
|
|
151
|
+
if (isBlank(entry)) {
|
|
152
|
+
warnings.push({
|
|
153
|
+
code: "teams-allowed-team-ids-blank",
|
|
154
|
+
message: "gateway.adapters.teams.allowedTeamIds contains a blank entry; remove empty strings."
|
|
155
|
+
});
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (hasLeadingOrTrailingWhitespace(entry)) warnings.push({
|
|
159
|
+
code: "teams-allowed-team-ids-whitespace",
|
|
160
|
+
message: `gateway.adapters.teams.allowedTeamIds contains ${label} with leading/trailing whitespace.`
|
|
161
|
+
});
|
|
162
|
+
}
|
|
95
163
|
}
|
|
96
164
|
return warnings;
|
|
97
165
|
}
|
|
@@ -4,66 +4,134 @@ const isBlank = (value)=>0 === value.trim().length;
|
|
|
4
4
|
function collectConfigWarnings(config) {
|
|
5
5
|
const warnings = [];
|
|
6
6
|
const discord = config.gateway?.adapters?.discord;
|
|
7
|
-
|
|
8
|
-
if (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (isBlank(discord.sessionCommand || "")) warnings.push({
|
|
13
|
-
code: "discord-session-command-blank",
|
|
14
|
-
message: 'gateway.adapters.discord.sessionCommand is blank; it will fall back to "!session".'
|
|
15
|
-
});
|
|
16
|
-
for (const [rawKey, rawValue] of Object.entries(discord.channelSessions ?? {})){
|
|
17
|
-
const keyLabel = JSON.stringify(rawKey);
|
|
18
|
-
const value = "string" == typeof rawValue ? rawValue : "";
|
|
19
|
-
const valueLabel = JSON.stringify(value);
|
|
20
|
-
if (hasLeadingOrTrailingWhitespace(rawKey)) warnings.push({
|
|
21
|
-
code: "discord-channel-sessions-key-whitespace",
|
|
22
|
-
message: `gateway.adapters.discord.channelSessions key ${keyLabel} has leading/trailing whitespace.`
|
|
7
|
+
const teams = config.gateway?.adapters?.teams;
|
|
8
|
+
if (discord?.enabled) {
|
|
9
|
+
if (!discord.token) warnings.push({
|
|
10
|
+
code: "discord-token-missing",
|
|
11
|
+
message: "gateway.adapters.discord.enabled is true but gateway.adapters.discord.token is not set; the adapter will not start."
|
|
23
12
|
});
|
|
24
|
-
if (
|
|
25
|
-
code: "discord-
|
|
26
|
-
message:
|
|
13
|
+
if (isBlank(discord.sessionCommand || "")) warnings.push({
|
|
14
|
+
code: "discord-session-command-blank",
|
|
15
|
+
message: 'gateway.adapters.discord.sessionCommand is blank; it will fall back to "!session".'
|
|
27
16
|
});
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
for (const [rawKey, rawValue] of Object.entries(discord.channelSessions ?? {})){
|
|
18
|
+
const keyLabel = JSON.stringify(rawKey);
|
|
19
|
+
const value = "string" == typeof rawValue ? rawValue : "";
|
|
20
|
+
const valueLabel = JSON.stringify(value);
|
|
21
|
+
if (hasLeadingOrTrailingWhitespace(rawKey)) warnings.push({
|
|
22
|
+
code: "discord-channel-sessions-key-whitespace",
|
|
23
|
+
message: `gateway.adapters.discord.channelSessions key ${keyLabel} has leading/trailing whitespace.`
|
|
24
|
+
});
|
|
25
|
+
if (hasLeadingOrTrailingWhitespace(value)) warnings.push({
|
|
26
|
+
code: "discord-channel-sessions-value-whitespace",
|
|
27
|
+
message: `gateway.adapters.discord.channelSessions[${keyLabel}] value ${valueLabel} has leading/trailing whitespace.`
|
|
28
|
+
});
|
|
29
|
+
if (isBlank(value)) {
|
|
30
|
+
warnings.push({
|
|
31
|
+
code: "discord-channel-sessions-value-blank",
|
|
32
|
+
message: `gateway.adapters.discord.channelSessions[${keyLabel}] is empty; mapping will fall back to derived session keys.`
|
|
33
|
+
});
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (!AGENT_PREFIX.test(value.trim())) warnings.push({
|
|
37
|
+
code: "discord-channel-sessions-missing-agent",
|
|
38
|
+
message: `gateway.adapters.discord.channelSessions[${keyLabel}] does not include an agent prefix (agent:<id>:...); agent selection will use bindings/default.`
|
|
32
39
|
});
|
|
33
|
-
continue;
|
|
34
40
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
for (const entry of discord.allowedChannels ?? []){
|
|
42
|
+
const label = JSON.stringify(entry);
|
|
43
|
+
if (isBlank(entry)) {
|
|
44
|
+
warnings.push({
|
|
45
|
+
code: "discord-allowed-channels-blank",
|
|
46
|
+
message: "gateway.adapters.discord.allowedChannels contains a blank entry; remove empty strings."
|
|
47
|
+
});
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (hasLeadingOrTrailingWhitespace(entry)) warnings.push({
|
|
51
|
+
code: "discord-allowed-channels-whitespace",
|
|
52
|
+
message: `gateway.adapters.discord.allowedChannels contains ${label} with leading/trailing whitespace.`
|
|
46
53
|
});
|
|
47
|
-
continue;
|
|
48
54
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
for (const entry of discord.allowedGuilds ?? []){
|
|
56
|
+
const label = JSON.stringify(entry);
|
|
57
|
+
if (isBlank(entry)) {
|
|
58
|
+
warnings.push({
|
|
59
|
+
code: "discord-allowed-guilds-blank",
|
|
60
|
+
message: "gateway.adapters.discord.allowedGuilds contains a blank entry; remove empty strings."
|
|
61
|
+
});
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (hasLeadingOrTrailingWhitespace(entry)) warnings.push({
|
|
65
|
+
code: "discord-allowed-guilds-whitespace",
|
|
66
|
+
message: `gateway.adapters.discord.allowedGuilds contains ${label} with leading/trailing whitespace.`
|
|
60
67
|
});
|
|
61
|
-
continue;
|
|
62
68
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
}
|
|
70
|
+
if (teams?.enabled) {
|
|
71
|
+
if (!teams.appId || !teams.appPassword) warnings.push({
|
|
72
|
+
code: "teams-credentials-missing",
|
|
73
|
+
message: "gateway.adapters.teams.enabled is true but gateway.adapters.teams.appId/appPassword are not both set; the adapter will not start."
|
|
74
|
+
});
|
|
75
|
+
if (isBlank(teams.sessionCommand || "")) warnings.push({
|
|
76
|
+
code: "teams-session-command-blank",
|
|
77
|
+
message: 'gateway.adapters.teams.sessionCommand is blank; it will fall back to "!session".'
|
|
78
|
+
});
|
|
79
|
+
if (isBlank(teams.endpointPath || "")) warnings.push({
|
|
80
|
+
code: "teams-endpoint-path-blank",
|
|
81
|
+
message: 'gateway.adapters.teams.endpointPath is blank; it will fall back to "/api/adapters/teams/messages".'
|
|
66
82
|
});
|
|
83
|
+
for (const [rawKey, rawValue] of Object.entries(teams.channelSessions ?? {})){
|
|
84
|
+
const keyLabel = JSON.stringify(rawKey);
|
|
85
|
+
const value = "string" == typeof rawValue ? rawValue : "";
|
|
86
|
+
const valueLabel = JSON.stringify(value);
|
|
87
|
+
if (hasLeadingOrTrailingWhitespace(rawKey)) warnings.push({
|
|
88
|
+
code: "teams-channel-sessions-key-whitespace",
|
|
89
|
+
message: `gateway.adapters.teams.channelSessions key ${keyLabel} has leading/trailing whitespace.`
|
|
90
|
+
});
|
|
91
|
+
if (hasLeadingOrTrailingWhitespace(value)) warnings.push({
|
|
92
|
+
code: "teams-channel-sessions-value-whitespace",
|
|
93
|
+
message: `gateway.adapters.teams.channelSessions[${keyLabel}] value ${valueLabel} has leading/trailing whitespace.`
|
|
94
|
+
});
|
|
95
|
+
if (isBlank(value)) {
|
|
96
|
+
warnings.push({
|
|
97
|
+
code: "teams-channel-sessions-value-blank",
|
|
98
|
+
message: `gateway.adapters.teams.channelSessions[${keyLabel}] is empty; mapping will fall back to derived session keys.`
|
|
99
|
+
});
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (!AGENT_PREFIX.test(value.trim())) warnings.push({
|
|
103
|
+
code: "teams-channel-sessions-missing-agent",
|
|
104
|
+
message: `gateway.adapters.teams.channelSessions[${keyLabel}] does not include an agent prefix (agent:<id>:...); agent selection will use bindings/default.`
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
for (const entry of teams.allowedChannelIds ?? []){
|
|
108
|
+
const label = JSON.stringify(entry);
|
|
109
|
+
if (isBlank(entry)) {
|
|
110
|
+
warnings.push({
|
|
111
|
+
code: "teams-allowed-channel-ids-blank",
|
|
112
|
+
message: "gateway.adapters.teams.allowedChannelIds contains a blank entry; remove empty strings."
|
|
113
|
+
});
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (hasLeadingOrTrailingWhitespace(entry)) warnings.push({
|
|
117
|
+
code: "teams-allowed-channel-ids-whitespace",
|
|
118
|
+
message: `gateway.adapters.teams.allowedChannelIds contains ${label} with leading/trailing whitespace.`
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
for (const entry of teams.allowedTeamIds ?? []){
|
|
122
|
+
const label = JSON.stringify(entry);
|
|
123
|
+
if (isBlank(entry)) {
|
|
124
|
+
warnings.push({
|
|
125
|
+
code: "teams-allowed-team-ids-blank",
|
|
126
|
+
message: "gateway.adapters.teams.allowedTeamIds contains a blank entry; remove empty strings."
|
|
127
|
+
});
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (hasLeadingOrTrailingWhitespace(entry)) warnings.push({
|
|
131
|
+
code: "teams-allowed-team-ids-whitespace",
|
|
132
|
+
message: `gateway.adapters.teams.allowedTeamIds contains ${label} with leading/trailing whitespace.`
|
|
133
|
+
});
|
|
134
|
+
}
|
|
67
135
|
}
|
|
68
136
|
return warnings;
|
|
69
137
|
}
|
|
@@ -57,6 +57,7 @@ const additional_messages_cjs_namespaceObject = require("../../agent/middleware/
|
|
|
57
57
|
const merger_cjs_namespaceObject = require("../../agent/middleware/hooks/merger.cjs");
|
|
58
58
|
const hooks_cjs_namespaceObject = require("../../agent/middleware/hooks.cjs");
|
|
59
59
|
const media_compat_cjs_namespaceObject = require("../../agent/middleware/media-compat.cjs");
|
|
60
|
+
const mcp_resources_cjs_namespaceObject = require("../../agent/tools/mcp_resources.cjs");
|
|
60
61
|
const terminal_session_manager_cjs_namespaceObject = require("../../agent/tools/terminal_session_manager.cjs");
|
|
61
62
|
const uiRegistry_cjs_namespaceObject = require("../../agent/uiRegistry.cjs");
|
|
62
63
|
const activation_cjs_namespaceObject = require("../../skills/activation.cjs");
|
|
@@ -338,6 +339,7 @@ class AgentInvoker {
|
|
|
338
339
|
});
|
|
339
340
|
const targetAgent = await loader.loadAgent(agentName);
|
|
340
341
|
if (!targetAgent) throw new Error(`Agent "${agentName}" not found`);
|
|
342
|
+
if (options?.modelOverride && "string" == typeof options.modelOverride && options.modelOverride.trim().length > 0) targetAgent.model = options.modelOverride.trim();
|
|
341
343
|
this.logger.info(`Invoking agent: ${agentName}`);
|
|
342
344
|
const preview = prompt.trim() || (attachments && attachments.length > 0 ? buildAttachmentPreview(attachments) : "");
|
|
343
345
|
this.outputManager.emitAgentStart(agentName, preview);
|
|
@@ -355,9 +357,14 @@ class AgentInvoker {
|
|
|
355
357
|
});
|
|
356
358
|
await this.mcpManager.initialize();
|
|
357
359
|
const mcpTools = await this.mcpManager.getTools();
|
|
358
|
-
|
|
360
|
+
const mcpResourceTools = (0, mcp_resources_cjs_namespaceObject.createMCPResourceTools)(this.mcpManager);
|
|
361
|
+
const allMcpTools = [
|
|
362
|
+
...mcpTools,
|
|
363
|
+
...mcpResourceTools
|
|
364
|
+
];
|
|
365
|
+
if (allMcpTools.length > 0) {
|
|
359
366
|
const existing = new Set((targetAgent.tools || []).map((tool)=>tool.name));
|
|
360
|
-
const unique =
|
|
367
|
+
const unique = allMcpTools.filter((tool)=>!existing.has(tool.name));
|
|
361
368
|
targetAgent.tools = [
|
|
362
369
|
...targetAgent.tools || [],
|
|
363
370
|
...unique
|
|
@@ -8,6 +8,7 @@ import { additionalMessageMiddleware } from "../../agent/middleware/additional-m
|
|
|
8
8
|
import { mergeHooks } from "../../agent/middleware/hooks/merger.js";
|
|
9
9
|
import { createHooksMiddleware } from "../../agent/middleware/hooks.js";
|
|
10
10
|
import { mediaCompatibilityMiddleware } from "../../agent/middleware/media-compat.js";
|
|
11
|
+
import { createMCPResourceTools } from "../../agent/tools/mcp_resources.js";
|
|
11
12
|
import { getSharedTerminalSessionManager } from "../../agent/tools/terminal_session_manager.js";
|
|
12
13
|
import { getBundledSkillsPath } from "../../agent/uiRegistry.js";
|
|
13
14
|
import { resolveSkillActivation } from "../../skills/activation.js";
|
|
@@ -289,6 +290,7 @@ class AgentInvoker {
|
|
|
289
290
|
});
|
|
290
291
|
const targetAgent = await loader.loadAgent(agentName);
|
|
291
292
|
if (!targetAgent) throw new Error(`Agent "${agentName}" not found`);
|
|
293
|
+
if (options?.modelOverride && "string" == typeof options.modelOverride && options.modelOverride.trim().length > 0) targetAgent.model = options.modelOverride.trim();
|
|
292
294
|
this.logger.info(`Invoking agent: ${agentName}`);
|
|
293
295
|
const preview = prompt.trim() || (attachments && attachments.length > 0 ? buildAttachmentPreview(attachments) : "");
|
|
294
296
|
this.outputManager.emitAgentStart(agentName, preview);
|
|
@@ -306,9 +308,14 @@ class AgentInvoker {
|
|
|
306
308
|
});
|
|
307
309
|
await this.mcpManager.initialize();
|
|
308
310
|
const mcpTools = await this.mcpManager.getTools();
|
|
309
|
-
|
|
311
|
+
const mcpResourceTools = createMCPResourceTools(this.mcpManager);
|
|
312
|
+
const allMcpTools = [
|
|
313
|
+
...mcpTools,
|
|
314
|
+
...mcpResourceTools
|
|
315
|
+
];
|
|
316
|
+
if (allMcpTools.length > 0) {
|
|
310
317
|
const existing = new Set((targetAgent.tools || []).map((tool)=>tool.name));
|
|
311
|
-
const unique =
|
|
318
|
+
const unique = allMcpTools.filter((tool)=>!existing.has(tool.name));
|
|
312
319
|
targetAgent.tools = [
|
|
313
320
|
...targetAgent.tools || [],
|
|
314
321
|
...unique
|
|
@@ -24,6 +24,8 @@ var __webpack_require__ = {};
|
|
|
24
24
|
var __webpack_exports__ = {};
|
|
25
25
|
__webpack_require__.r(__webpack_exports__);
|
|
26
26
|
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
removeSessionMediaDirectory: ()=>removeSessionMediaDirectory,
|
|
28
|
+
getSessionMediaDirectory: ()=>getSessionMediaDirectory,
|
|
27
29
|
persistAssistantImagesToDisk: ()=>persistAssistantImagesToDisk,
|
|
28
30
|
parseBase64DataUrl: ()=>parseBase64DataUrl,
|
|
29
31
|
resolveImageExtension: ()=>resolveImageExtension
|
|
@@ -34,7 +36,7 @@ const external_node_path_namespaceObject = require("node:path");
|
|
|
34
36
|
const DATA_URL_BASE64_PATTERN = /^data:([^;,]+);base64,(.+)$/i;
|
|
35
37
|
function persistAssistantImagesToDisk(input) {
|
|
36
38
|
if (!input.messages.length) return;
|
|
37
|
-
const mediaRoot = (
|
|
39
|
+
const mediaRoot = getSessionMediaDirectory(input.dbPath, input.sessionId);
|
|
38
40
|
for (const message of input.messages)if ("assistant" === message.role) {
|
|
39
41
|
if (Array.isArray(message.attachments) && 0 !== message.attachments.length) for (const attachment of message.attachments){
|
|
40
42
|
if (!attachment || "image" !== attachment.kind) continue;
|
|
@@ -66,6 +68,16 @@ function persistAssistantImagesToDisk(input) {
|
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
70
|
}
|
|
71
|
+
function getSessionMediaDirectory(dbPath, sessionId) {
|
|
72
|
+
return (0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(dbPath), "media", sanitizePathSegment(sessionId));
|
|
73
|
+
}
|
|
74
|
+
function removeSessionMediaDirectory(dbPath, sessionId) {
|
|
75
|
+
const mediaDir = getSessionMediaDirectory(dbPath, sessionId);
|
|
76
|
+
(0, external_node_fs_namespaceObject.rmSync)(mediaDir, {
|
|
77
|
+
recursive: true,
|
|
78
|
+
force: true
|
|
79
|
+
});
|
|
80
|
+
}
|
|
69
81
|
function parseBase64DataUrl(dataUrl) {
|
|
70
82
|
if ("string" != typeof dataUrl) return null;
|
|
71
83
|
const match = dataUrl.match(DATA_URL_BASE64_PATTERN);
|
|
@@ -112,12 +124,16 @@ function sanitizePathSegment(value) {
|
|
|
112
124
|
const sanitized = normalized.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
113
125
|
return sanitized.slice(0, 120) || "default-session";
|
|
114
126
|
}
|
|
127
|
+
exports.getSessionMediaDirectory = __webpack_exports__.getSessionMediaDirectory;
|
|
115
128
|
exports.parseBase64DataUrl = __webpack_exports__.parseBase64DataUrl;
|
|
116
129
|
exports.persistAssistantImagesToDisk = __webpack_exports__.persistAssistantImagesToDisk;
|
|
130
|
+
exports.removeSessionMediaDirectory = __webpack_exports__.removeSessionMediaDirectory;
|
|
117
131
|
exports.resolveImageExtension = __webpack_exports__.resolveImageExtension;
|
|
118
132
|
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
133
|
+
"getSessionMediaDirectory",
|
|
119
134
|
"parseBase64DataUrl",
|
|
120
135
|
"persistAssistantImagesToDisk",
|
|
136
|
+
"removeSessionMediaDirectory",
|
|
121
137
|
"resolveImageExtension"
|
|
122
138
|
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
123
139
|
Object.defineProperty(exports, '__esModule', {
|
|
@@ -19,6 +19,8 @@ export declare function persistAssistantImagesToDisk(input: {
|
|
|
19
19
|
sessionId: string;
|
|
20
20
|
messages: PersistableMessage[];
|
|
21
21
|
}): void;
|
|
22
|
+
export declare function getSessionMediaDirectory(dbPath: string, sessionId: string): string;
|
|
23
|
+
export declare function removeSessionMediaDirectory(dbPath: string, sessionId: string): void;
|
|
22
24
|
export declare function parseBase64DataUrl(dataUrl: string): ParsedDataUrl | null;
|
|
23
25
|
export declare function resolveImageExtension(mimeType: string): string;
|
|
24
26
|
export {};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
const DATA_URL_BASE64_PATTERN = /^data:([^;,]+);base64,(.+)$/i;
|
|
5
5
|
function persistAssistantImagesToDisk(input) {
|
|
6
6
|
if (!input.messages.length) return;
|
|
7
|
-
const mediaRoot =
|
|
7
|
+
const mediaRoot = getSessionMediaDirectory(input.dbPath, input.sessionId);
|
|
8
8
|
for (const message of input.messages)if ("assistant" === message.role) {
|
|
9
9
|
if (Array.isArray(message.attachments) && 0 !== message.attachments.length) for (const attachment of message.attachments){
|
|
10
10
|
if (!attachment || "image" !== attachment.kind) continue;
|
|
@@ -36,6 +36,16 @@ function persistAssistantImagesToDisk(input) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
+
function getSessionMediaDirectory(dbPath, sessionId) {
|
|
40
|
+
return join(dirname(dbPath), "media", sanitizePathSegment(sessionId));
|
|
41
|
+
}
|
|
42
|
+
function removeSessionMediaDirectory(dbPath, sessionId) {
|
|
43
|
+
const mediaDir = getSessionMediaDirectory(dbPath, sessionId);
|
|
44
|
+
rmSync(mediaDir, {
|
|
45
|
+
recursive: true,
|
|
46
|
+
force: true
|
|
47
|
+
});
|
|
48
|
+
}
|
|
39
49
|
function parseBase64DataUrl(dataUrl) {
|
|
40
50
|
if ("string" != typeof dataUrl) return null;
|
|
41
51
|
const match = dataUrl.match(DATA_URL_BASE64_PATTERN);
|
|
@@ -82,4 +92,4 @@ function sanitizePathSegment(value) {
|
|
|
82
92
|
const sanitized = normalized.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
83
93
|
return sanitized.slice(0, 120) || "default-session";
|
|
84
94
|
}
|
|
85
|
-
export { parseBase64DataUrl, persistAssistantImagesToDisk, resolveImageExtension };
|
|
95
|
+
export { getSessionMediaDirectory, parseBase64DataUrl, persistAssistantImagesToDisk, removeSessionMediaDirectory, resolveImageExtension };
|
|
@@ -227,6 +227,7 @@ class SessionManager {
|
|
|
227
227
|
writesStmt.run(sessionId);
|
|
228
228
|
const pendingStmt = this.db.prepare("DELETE FROM session_pending_messages WHERE session_id = ?");
|
|
229
229
|
pendingStmt.run(sessionId);
|
|
230
|
+
(0, external_imagePersistence_cjs_namespaceObject.removeSessionMediaDirectory)(this.dbPath, sessionId);
|
|
230
231
|
}
|
|
231
232
|
clearSessionMessages(sessionId) {
|
|
232
233
|
if (!this.db || !this.checkpointer) throw new Error("SessionManager not initialized");
|
|
@@ -242,6 +243,7 @@ class SessionManager {
|
|
|
242
243
|
WHERE id = ?
|
|
243
244
|
`);
|
|
244
245
|
sessionStmt.run(Date.now(), sessionId);
|
|
246
|
+
(0, external_imagePersistence_cjs_namespaceObject.removeSessionMediaDirectory)(this.dbPath, sessionId);
|
|
245
247
|
}
|
|
246
248
|
persistPendingMessage(input) {
|
|
247
249
|
if (!this.db) throw new Error("SessionManager not initialized");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SqliteSaver } from "@langchain/langgraph-checkpoint-sqlite";
|
|
2
2
|
import { createDeepAgent } from "deepagents";
|
|
3
3
|
import { v4 } from "uuid";
|
|
4
|
-
import { persistAssistantImagesToDisk } from "./imagePersistence.js";
|
|
4
|
+
import { persistAssistantImagesToDisk, removeSessionMediaDirectory } from "./imagePersistence.js";
|
|
5
5
|
function _define_property(obj, key, value) {
|
|
6
6
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
7
7
|
value: value,
|
|
@@ -194,6 +194,7 @@ class SessionManager {
|
|
|
194
194
|
writesStmt.run(sessionId);
|
|
195
195
|
const pendingStmt = this.db.prepare("DELETE FROM session_pending_messages WHERE session_id = ?");
|
|
196
196
|
pendingStmt.run(sessionId);
|
|
197
|
+
removeSessionMediaDirectory(this.dbPath, sessionId);
|
|
197
198
|
}
|
|
198
199
|
clearSessionMessages(sessionId) {
|
|
199
200
|
if (!this.db || !this.checkpointer) throw new Error("SessionManager not initialized");
|
|
@@ -209,6 +210,7 @@ class SessionManager {
|
|
|
209
210
|
WHERE id = ?
|
|
210
211
|
`);
|
|
211
212
|
sessionStmt.run(Date.now(), sessionId);
|
|
213
|
+
removeSessionMediaDirectory(this.dbPath, sessionId);
|
|
212
214
|
}
|
|
213
215
|
persistPendingMessage(input) {
|
|
214
216
|
if (!this.db) throw new Error("SessionManager not initialized");
|
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?: {
|