@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
package/README.md
CHANGED
|
@@ -222,6 +222,20 @@ cd apps/wingman
|
|
|
222
222
|
bun run test
|
|
223
223
|
```
|
|
224
224
|
|
|
225
|
+
### Terminal Bench
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
cd apps/wingman
|
|
229
|
+
bun run bench:terminal:smoke
|
|
230
|
+
bun run bench:terminal:quick
|
|
231
|
+
bun run bench:terminal
|
|
232
|
+
bun run bench:terminal:official
|
|
233
|
+
bun run bench:terminal:official:wingman
|
|
234
|
+
bun run bench:terminal:baseline
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
See `apps/wingman/docs/terminal-bench.md` for config, scoring, and artifacts.
|
|
238
|
+
|
|
225
239
|
### Config and Logs
|
|
226
240
|
|
|
227
241
|
- Config: `apps/wingman/.wingman/wingman.config.json`
|
|
@@ -156,6 +156,56 @@ class MCPClientManager {
|
|
|
156
156
|
return [];
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
|
+
async listResources(serverNames) {
|
|
160
|
+
if (!this.client) {
|
|
161
|
+
this.logger.debug("No MCP client initialized, returning empty resources map");
|
|
162
|
+
return {};
|
|
163
|
+
}
|
|
164
|
+
const targets = normalizeServerNames(serverNames);
|
|
165
|
+
try {
|
|
166
|
+
const resources = targets.length > 0 ? await this.client.listResources(...targets) : await this.client.listResources();
|
|
167
|
+
return Object.fromEntries(Object.entries(resources).map(([serverName, serverResources])=>[
|
|
168
|
+
serverName,
|
|
169
|
+
serverResources.map((resource)=>normalizeResource(resource))
|
|
170
|
+
]));
|
|
171
|
+
} catch (error) {
|
|
172
|
+
this.logger.error(`Failed to list MCP resources: ${error instanceof Error ? error.message : String(error)}`);
|
|
173
|
+
return {};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async listResourceTemplates(serverNames) {
|
|
177
|
+
if (!this.client) {
|
|
178
|
+
this.logger.debug("No MCP client initialized, returning empty resource template map");
|
|
179
|
+
return {};
|
|
180
|
+
}
|
|
181
|
+
const targets = normalizeServerNames(serverNames);
|
|
182
|
+
try {
|
|
183
|
+
const templates = targets.length > 0 ? await this.client.listResourceTemplates(...targets) : await this.client.listResourceTemplates();
|
|
184
|
+
return Object.fromEntries(Object.entries(templates).map(([serverName, serverTemplates])=>[
|
|
185
|
+
serverName,
|
|
186
|
+
serverTemplates.map((template)=>normalizeResourceTemplate(template))
|
|
187
|
+
]));
|
|
188
|
+
} catch (error) {
|
|
189
|
+
this.logger.error(`Failed to list MCP resource templates: ${error instanceof Error ? error.message : String(error)}`);
|
|
190
|
+
return {};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
async readResource(serverName, uri) {
|
|
194
|
+
if (!this.client) {
|
|
195
|
+
this.logger.debug("No MCP client initialized, returning empty resource content");
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
const normalizedServer = serverName.trim();
|
|
199
|
+
const normalizedUri = uri.trim();
|
|
200
|
+
if (!normalizedServer || !normalizedUri) return [];
|
|
201
|
+
try {
|
|
202
|
+
const content = await this.client.readResource(normalizedServer, normalizedUri);
|
|
203
|
+
return content.map((block)=>normalizeResourceContent(block, normalizedUri));
|
|
204
|
+
} catch (error) {
|
|
205
|
+
this.logger.error(`Failed to read MCP resource ${normalizedUri} from ${normalizedServer}: ${error instanceof Error ? error.message : String(error)}`);
|
|
206
|
+
return [];
|
|
207
|
+
}
|
|
208
|
+
}
|
|
159
209
|
sanitizeToolNames(tools) {
|
|
160
210
|
const used = new Map();
|
|
161
211
|
const sanitize = (name)=>{
|
|
@@ -199,10 +249,12 @@ class MCPClientManager {
|
|
|
199
249
|
if (!this.client) return;
|
|
200
250
|
try {
|
|
201
251
|
this.logger.debug("Cleaning up MCP client");
|
|
202
|
-
this.client
|
|
252
|
+
await this.client.close();
|
|
203
253
|
this.logger.debug("MCP client cleanup complete");
|
|
204
254
|
} catch (error) {
|
|
205
255
|
this.logger.warn(`Error during MCP cleanup: ${error instanceof Error ? error.message : String(error)}`);
|
|
256
|
+
} finally{
|
|
257
|
+
this.client = null;
|
|
206
258
|
}
|
|
207
259
|
}
|
|
208
260
|
hasServers() {
|
|
@@ -232,6 +284,57 @@ function getDefaultToolTimeout(server) {
|
|
|
232
284
|
if (!Number.isFinite(candidate) || candidate <= 0) return;
|
|
233
285
|
return Math.floor(candidate);
|
|
234
286
|
}
|
|
287
|
+
function normalizeServerNames(serverNames) {
|
|
288
|
+
if (!serverNames) return [];
|
|
289
|
+
const seen = new Set();
|
|
290
|
+
const normalized = [];
|
|
291
|
+
for (const name of serverNames){
|
|
292
|
+
const trimmed = name.trim();
|
|
293
|
+
if (!(!trimmed || seen.has(trimmed))) {
|
|
294
|
+
seen.add(trimmed);
|
|
295
|
+
normalized.push(trimmed);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return normalized;
|
|
299
|
+
}
|
|
300
|
+
function normalizeResource(value) {
|
|
301
|
+
return {
|
|
302
|
+
uri: value.uri,
|
|
303
|
+
name: value.name || value.uri,
|
|
304
|
+
...value.description ? {
|
|
305
|
+
description: value.description
|
|
306
|
+
} : {},
|
|
307
|
+
...value.mimeType ? {
|
|
308
|
+
mimeType: value.mimeType
|
|
309
|
+
} : {}
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function normalizeResourceTemplate(value) {
|
|
313
|
+
return {
|
|
314
|
+
uriTemplate: value.uriTemplate,
|
|
315
|
+
name: value.name || value.uriTemplate,
|
|
316
|
+
...value.description ? {
|
|
317
|
+
description: value.description
|
|
318
|
+
} : {},
|
|
319
|
+
...value.mimeType ? {
|
|
320
|
+
mimeType: value.mimeType
|
|
321
|
+
} : {}
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
function normalizeResourceContent(value, defaultUri) {
|
|
325
|
+
return {
|
|
326
|
+
uri: value.uri || defaultUri,
|
|
327
|
+
...value.mimeType ? {
|
|
328
|
+
mimeType: value.mimeType
|
|
329
|
+
} : {},
|
|
330
|
+
..."string" == typeof value.text ? {
|
|
331
|
+
text: value.text
|
|
332
|
+
} : {},
|
|
333
|
+
..."string" == typeof value.blob ? {
|
|
334
|
+
blob: value.blob
|
|
335
|
+
} : {}
|
|
336
|
+
};
|
|
337
|
+
}
|
|
235
338
|
exports.MCPClientManager = __webpack_exports__.MCPClientManager;
|
|
236
339
|
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
237
340
|
"MCPClientManager"
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
import type { StructuredTool } from "@langchain/core/tools";
|
|
2
2
|
import type { Logger } from "@/logger.js";
|
|
3
3
|
import type { MCPServersConfig } from "@/types/mcp.js";
|
|
4
|
+
export type MCPResourceDescriptor = {
|
|
5
|
+
uri: string;
|
|
6
|
+
name: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
mimeType?: string;
|
|
9
|
+
};
|
|
10
|
+
export type MCPResourceTemplateDescriptor = {
|
|
11
|
+
uriTemplate: string;
|
|
12
|
+
name: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
mimeType?: string;
|
|
15
|
+
};
|
|
16
|
+
export type MCPResourceContentDescriptor = {
|
|
17
|
+
uri: string;
|
|
18
|
+
mimeType?: string;
|
|
19
|
+
text?: string;
|
|
20
|
+
blob?: string;
|
|
21
|
+
};
|
|
4
22
|
export type MCPProxyConfig = {
|
|
5
23
|
enabled?: boolean;
|
|
6
24
|
command?: string;
|
|
@@ -44,6 +62,18 @@ export declare class MCPClientManager {
|
|
|
44
62
|
* Returns LangChain StructuredTools ready for agent use
|
|
45
63
|
*/
|
|
46
64
|
getTools(): Promise<StructuredTool[]>;
|
|
65
|
+
/**
|
|
66
|
+
* List MCP resources exposed by configured servers.
|
|
67
|
+
*/
|
|
68
|
+
listResources(serverNames?: string[]): Promise<Record<string, MCPResourceDescriptor[]>>;
|
|
69
|
+
/**
|
|
70
|
+
* List MCP resource templates exposed by configured servers.
|
|
71
|
+
*/
|
|
72
|
+
listResourceTemplates(serverNames?: string[]): Promise<Record<string, MCPResourceTemplateDescriptor[]>>;
|
|
73
|
+
/**
|
|
74
|
+
* Read a specific MCP resource from a server.
|
|
75
|
+
*/
|
|
76
|
+
readResource(serverName: string, uri: string): Promise<MCPResourceContentDescriptor[]>;
|
|
47
77
|
private sanitizeToolNames;
|
|
48
78
|
/**
|
|
49
79
|
* Cleanup MCP client resources
|
|
@@ -128,6 +128,56 @@ class MCPClientManager {
|
|
|
128
128
|
return [];
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
+
async listResources(serverNames) {
|
|
132
|
+
if (!this.client) {
|
|
133
|
+
this.logger.debug("No MCP client initialized, returning empty resources map");
|
|
134
|
+
return {};
|
|
135
|
+
}
|
|
136
|
+
const targets = normalizeServerNames(serverNames);
|
|
137
|
+
try {
|
|
138
|
+
const resources = targets.length > 0 ? await this.client.listResources(...targets) : await this.client.listResources();
|
|
139
|
+
return Object.fromEntries(Object.entries(resources).map(([serverName, serverResources])=>[
|
|
140
|
+
serverName,
|
|
141
|
+
serverResources.map((resource)=>normalizeResource(resource))
|
|
142
|
+
]));
|
|
143
|
+
} catch (error) {
|
|
144
|
+
this.logger.error(`Failed to list MCP resources: ${error instanceof Error ? error.message : String(error)}`);
|
|
145
|
+
return {};
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async listResourceTemplates(serverNames) {
|
|
149
|
+
if (!this.client) {
|
|
150
|
+
this.logger.debug("No MCP client initialized, returning empty resource template map");
|
|
151
|
+
return {};
|
|
152
|
+
}
|
|
153
|
+
const targets = normalizeServerNames(serverNames);
|
|
154
|
+
try {
|
|
155
|
+
const templates = targets.length > 0 ? await this.client.listResourceTemplates(...targets) : await this.client.listResourceTemplates();
|
|
156
|
+
return Object.fromEntries(Object.entries(templates).map(([serverName, serverTemplates])=>[
|
|
157
|
+
serverName,
|
|
158
|
+
serverTemplates.map((template)=>normalizeResourceTemplate(template))
|
|
159
|
+
]));
|
|
160
|
+
} catch (error) {
|
|
161
|
+
this.logger.error(`Failed to list MCP resource templates: ${error instanceof Error ? error.message : String(error)}`);
|
|
162
|
+
return {};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async readResource(serverName, uri) {
|
|
166
|
+
if (!this.client) {
|
|
167
|
+
this.logger.debug("No MCP client initialized, returning empty resource content");
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
const normalizedServer = serverName.trim();
|
|
171
|
+
const normalizedUri = uri.trim();
|
|
172
|
+
if (!normalizedServer || !normalizedUri) return [];
|
|
173
|
+
try {
|
|
174
|
+
const content = await this.client.readResource(normalizedServer, normalizedUri);
|
|
175
|
+
return content.map((block)=>normalizeResourceContent(block, normalizedUri));
|
|
176
|
+
} catch (error) {
|
|
177
|
+
this.logger.error(`Failed to read MCP resource ${normalizedUri} from ${normalizedServer}: ${error instanceof Error ? error.message : String(error)}`);
|
|
178
|
+
return [];
|
|
179
|
+
}
|
|
180
|
+
}
|
|
131
181
|
sanitizeToolNames(tools) {
|
|
132
182
|
const used = new Map();
|
|
133
183
|
const sanitize = (name)=>{
|
|
@@ -171,10 +221,12 @@ class MCPClientManager {
|
|
|
171
221
|
if (!this.client) return;
|
|
172
222
|
try {
|
|
173
223
|
this.logger.debug("Cleaning up MCP client");
|
|
174
|
-
this.client
|
|
224
|
+
await this.client.close();
|
|
175
225
|
this.logger.debug("MCP client cleanup complete");
|
|
176
226
|
} catch (error) {
|
|
177
227
|
this.logger.warn(`Error during MCP cleanup: ${error instanceof Error ? error.message : String(error)}`);
|
|
228
|
+
} finally{
|
|
229
|
+
this.client = null;
|
|
178
230
|
}
|
|
179
231
|
}
|
|
180
232
|
hasServers() {
|
|
@@ -204,4 +256,55 @@ function getDefaultToolTimeout(server) {
|
|
|
204
256
|
if (!Number.isFinite(candidate) || candidate <= 0) return;
|
|
205
257
|
return Math.floor(candidate);
|
|
206
258
|
}
|
|
259
|
+
function normalizeServerNames(serverNames) {
|
|
260
|
+
if (!serverNames) return [];
|
|
261
|
+
const seen = new Set();
|
|
262
|
+
const normalized = [];
|
|
263
|
+
for (const name of serverNames){
|
|
264
|
+
const trimmed = name.trim();
|
|
265
|
+
if (!(!trimmed || seen.has(trimmed))) {
|
|
266
|
+
seen.add(trimmed);
|
|
267
|
+
normalized.push(trimmed);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return normalized;
|
|
271
|
+
}
|
|
272
|
+
function normalizeResource(value) {
|
|
273
|
+
return {
|
|
274
|
+
uri: value.uri,
|
|
275
|
+
name: value.name || value.uri,
|
|
276
|
+
...value.description ? {
|
|
277
|
+
description: value.description
|
|
278
|
+
} : {},
|
|
279
|
+
...value.mimeType ? {
|
|
280
|
+
mimeType: value.mimeType
|
|
281
|
+
} : {}
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
function normalizeResourceTemplate(value) {
|
|
285
|
+
return {
|
|
286
|
+
uriTemplate: value.uriTemplate,
|
|
287
|
+
name: value.name || value.uriTemplate,
|
|
288
|
+
...value.description ? {
|
|
289
|
+
description: value.description
|
|
290
|
+
} : {},
|
|
291
|
+
...value.mimeType ? {
|
|
292
|
+
mimeType: value.mimeType
|
|
293
|
+
} : {}
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
function normalizeResourceContent(value, defaultUri) {
|
|
297
|
+
return {
|
|
298
|
+
uri: value.uri || defaultUri,
|
|
299
|
+
...value.mimeType ? {
|
|
300
|
+
mimeType: value.mimeType
|
|
301
|
+
} : {},
|
|
302
|
+
..."string" == typeof value.text ? {
|
|
303
|
+
text: value.text
|
|
304
|
+
} : {},
|
|
305
|
+
..."string" == typeof value.blob ? {
|
|
306
|
+
blob: value.blob
|
|
307
|
+
} : {}
|
|
308
|
+
};
|
|
309
|
+
}
|
|
207
310
|
export { MCPClientManager };
|
|
@@ -30,6 +30,7 @@ const anthropic_namespaceObject = require("@langchain/anthropic");
|
|
|
30
30
|
const openai_namespaceObject = require("@langchain/openai");
|
|
31
31
|
const xai_namespaceObject = require("@langchain/xai");
|
|
32
32
|
const codex_cjs_namespaceObject = require("../../providers/codex.cjs");
|
|
33
|
+
const external_xaiImageModel_cjs_namespaceObject = require("./xaiImageModel.cjs");
|
|
33
34
|
const copilot_cjs_namespaceObject = require("../../providers/copilot.cjs");
|
|
34
35
|
const credentials_cjs_namespaceObject = require("../../providers/credentials.cjs");
|
|
35
36
|
const registry_cjs_namespaceObject = require("../../providers/registry.cjs");
|
|
@@ -172,6 +173,15 @@ class ModelFactory {
|
|
|
172
173
|
}
|
|
173
174
|
static createXAIModel(model, options) {
|
|
174
175
|
const token = (0, credentials_cjs_namespaceObject.resolveProviderToken)("xai").token;
|
|
176
|
+
const provider = (0, registry_cjs_namespaceObject.getProviderSpec)("xai");
|
|
177
|
+
if ((0, external_xaiImageModel_cjs_namespaceObject.isNativeXAIImageModel)(model)) {
|
|
178
|
+
if (options.reasoningEffort) ModelFactory.warnUnsupportedReasoningEffort("xai", model, options.reasoningEffort, options.ownerLabel);
|
|
179
|
+
return new external_xaiImageModel_cjs_namespaceObject.NativeXAIImageModel({
|
|
180
|
+
model,
|
|
181
|
+
apiKey: token,
|
|
182
|
+
baseURL: provider?.baseURL
|
|
183
|
+
});
|
|
184
|
+
}
|
|
175
185
|
const params = {
|
|
176
186
|
model,
|
|
177
187
|
temperature: 1
|
|
@@ -2,6 +2,7 @@ import { ChatAnthropic } from "@langchain/anthropic";
|
|
|
2
2
|
import { ChatOpenAI } from "@langchain/openai";
|
|
3
3
|
import { ChatXAI } from "@langchain/xai";
|
|
4
4
|
import { createCodexFetch, resolveCodexAuthFromFile } from "../../providers/codex.js";
|
|
5
|
+
import { NativeXAIImageModel, isNativeXAIImageModel } from "./xaiImageModel.js";
|
|
5
6
|
import { createCopilotFetch } from "../../providers/copilot.js";
|
|
6
7
|
import { resolveProviderToken } from "../../providers/credentials.js";
|
|
7
8
|
import { getProviderSpec, listProviderSpecs, normalizeProviderName } from "../../providers/registry.js";
|
|
@@ -144,6 +145,15 @@ class ModelFactory {
|
|
|
144
145
|
}
|
|
145
146
|
static createXAIModel(model, options) {
|
|
146
147
|
const token = resolveProviderToken("xai").token;
|
|
148
|
+
const provider = getProviderSpec("xai");
|
|
149
|
+
if (isNativeXAIImageModel(model)) {
|
|
150
|
+
if (options.reasoningEffort) ModelFactory.warnUnsupportedReasoningEffort("xai", model, options.reasoningEffort, options.ownerLabel);
|
|
151
|
+
return new NativeXAIImageModel({
|
|
152
|
+
model,
|
|
153
|
+
apiKey: token,
|
|
154
|
+
baseURL: provider?.baseURL
|
|
155
|
+
});
|
|
156
|
+
}
|
|
147
157
|
const params = {
|
|
148
158
|
model,
|
|
149
159
|
temperature: 1
|
|
@@ -0,0 +1,242 @@
|
|
|
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
|
+
DEFAULT_XAI_BASE_URL: ()=>DEFAULT_XAI_BASE_URL,
|
|
28
|
+
isNativeXAIImageModel: ()=>isNativeXAIImageModel,
|
|
29
|
+
NativeXAIImageModel: ()=>NativeXAIImageModel
|
|
30
|
+
});
|
|
31
|
+
const chat_models_namespaceObject = require("@langchain/core/language_models/chat_models");
|
|
32
|
+
const messages_namespaceObject = require("@langchain/core/messages");
|
|
33
|
+
const outputs_namespaceObject = require("@langchain/core/outputs");
|
|
34
|
+
function _define_property(obj, key, value) {
|
|
35
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
36
|
+
value: value,
|
|
37
|
+
enumerable: true,
|
|
38
|
+
configurable: true,
|
|
39
|
+
writable: true
|
|
40
|
+
});
|
|
41
|
+
else obj[key] = value;
|
|
42
|
+
return obj;
|
|
43
|
+
}
|
|
44
|
+
const DEFAULT_XAI_BASE_URL = "https://api.x.ai/v1";
|
|
45
|
+
const IMAGE_MODEL_NAME_PATTERN = /^grok-imagine-image(?:[-:._].*)?$/i;
|
|
46
|
+
const XAI_IMAGE_PROMPT_MAX_CHARS = 7900;
|
|
47
|
+
function isNativeXAIImageModel(modelName) {
|
|
48
|
+
return IMAGE_MODEL_NAME_PATTERN.test(modelName.trim());
|
|
49
|
+
}
|
|
50
|
+
function normalizeContentText(content) {
|
|
51
|
+
if ("string" == typeof content) return content.trim();
|
|
52
|
+
if (!Array.isArray(content)) return "";
|
|
53
|
+
const parts = content.map((part)=>{
|
|
54
|
+
if (!part || "object" != typeof part || Array.isArray(part)) return "";
|
|
55
|
+
const record = part;
|
|
56
|
+
return "text" === record.type && "string" == typeof record.text ? record.text.trim() : "";
|
|
57
|
+
}).filter(Boolean);
|
|
58
|
+
return parts.join("\n").trim();
|
|
59
|
+
}
|
|
60
|
+
function normalizeRole(message) {
|
|
61
|
+
const type = "string" == typeof message.type ? message.type : "function" == typeof message._getType ? String(message._getType() ?? "").toLowerCase() : "";
|
|
62
|
+
return type.toLowerCase();
|
|
63
|
+
}
|
|
64
|
+
function resolveAdditionalKwargs(message) {
|
|
65
|
+
const direct = message.additional_kwargs;
|
|
66
|
+
if (direct && "object" == typeof direct && !Array.isArray(direct)) return direct;
|
|
67
|
+
const kwargs = message.kwargs;
|
|
68
|
+
if (kwargs && "object" == typeof kwargs && !Array.isArray(kwargs)) {
|
|
69
|
+
const nested = kwargs.additional_kwargs;
|
|
70
|
+
if (nested && "object" == typeof nested && !Array.isArray(nested)) return nested;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function isHiddenMiddlewarePrompt(message, text) {
|
|
74
|
+
const additionalKwargs = resolveAdditionalKwargs(message);
|
|
75
|
+
const uiHidden = additionalKwargs?.ui_hidden === true || additionalKwargs?.uiHidden === true;
|
|
76
|
+
if (uiHidden) return true;
|
|
77
|
+
const source = "string" == typeof additionalKwargs?.source ? additionalKwargs.source.toLowerCase() : "";
|
|
78
|
+
if ("additional-message-middleware" === source) return true;
|
|
79
|
+
const normalized = text.toLowerCase();
|
|
80
|
+
return normalized.includes("# confidentiality (internal)") && normalized.includes("current date time (utc)");
|
|
81
|
+
}
|
|
82
|
+
function clampPromptLength(prompt) {
|
|
83
|
+
if (prompt.length <= XAI_IMAGE_PROMPT_MAX_CHARS) return prompt;
|
|
84
|
+
return prompt.slice(0, XAI_IMAGE_PROMPT_MAX_CHARS);
|
|
85
|
+
}
|
|
86
|
+
function buildPrompt(messages) {
|
|
87
|
+
const systemParts = [];
|
|
88
|
+
const visibleUserParts = [];
|
|
89
|
+
const fallbackUserParts = [];
|
|
90
|
+
for (const message of messages){
|
|
91
|
+
const text = normalizeContentText(message.content);
|
|
92
|
+
if (!text) continue;
|
|
93
|
+
const role = normalizeRole(message);
|
|
94
|
+
if ("system" === role) {
|
|
95
|
+
systemParts.push(text);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if ("human" === role || "user" === role) {
|
|
99
|
+
fallbackUserParts.push(text);
|
|
100
|
+
if (!isHiddenMiddlewarePrompt(message, text)) visibleUserParts.push(text);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const latestUserPrompt = visibleUserParts[visibleUserParts.length - 1] || fallbackUserParts[fallbackUserParts.length - 1];
|
|
104
|
+
if (!latestUserPrompt) throw new Error("xAI image generation requires a user prompt.");
|
|
105
|
+
const systemPrefix = systemParts.join("\n\n").trim();
|
|
106
|
+
if (!systemPrefix) return clampPromptLength(latestUserPrompt);
|
|
107
|
+
const userSection = `User request:\n${latestUserPrompt}`;
|
|
108
|
+
const withSystem = `System instructions:\n${systemPrefix}\n\n${userSection}`;
|
|
109
|
+
if (withSystem.length <= XAI_IMAGE_PROMPT_MAX_CHARS) return withSystem;
|
|
110
|
+
const systemPrefixLabel = "System instructions:\n";
|
|
111
|
+
const userSectionPrefix = `\n\n${userSection}`;
|
|
112
|
+
const availableSystemChars = XAI_IMAGE_PROMPT_MAX_CHARS - systemPrefixLabel.length - userSectionPrefix.length;
|
|
113
|
+
if (availableSystemChars <= 0) return clampPromptLength(userSection);
|
|
114
|
+
const truncatedSystem = systemPrefix.slice(0, availableSystemChars);
|
|
115
|
+
return `${systemPrefixLabel}${truncatedSystem}${userSectionPrefix}`;
|
|
116
|
+
}
|
|
117
|
+
async function readErrorResponse(response) {
|
|
118
|
+
const body = await response.text();
|
|
119
|
+
if (!body.trim()) return `xAI image generation request failed with status ${response.status}.`;
|
|
120
|
+
try {
|
|
121
|
+
const parsed = JSON.parse(body);
|
|
122
|
+
const errorRecord = parsed.error && "object" == typeof parsed.error ? parsed.error : void 0;
|
|
123
|
+
const message = "string" == typeof errorRecord?.message && errorRecord.message || "string" == typeof parsed.message && parsed.message || "string" == typeof parsed.error && parsed.error;
|
|
124
|
+
if (message) return `xAI image generation failed: ${message}`;
|
|
125
|
+
} catch {}
|
|
126
|
+
return `xAI image generation failed: ${body}`;
|
|
127
|
+
}
|
|
128
|
+
class NativeXAIImageModel extends chat_models_namespaceObject.BaseChatModel {
|
|
129
|
+
bindTools(_tools, _options) {
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
_llmType() {
|
|
133
|
+
return "xai-image-native";
|
|
134
|
+
}
|
|
135
|
+
getLsParams() {
|
|
136
|
+
return {
|
|
137
|
+
ls_provider: "xai",
|
|
138
|
+
ls_model_name: this.model,
|
|
139
|
+
ls_model_type: "chat"
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
invocationParams() {
|
|
143
|
+
return {
|
|
144
|
+
provider: "xai",
|
|
145
|
+
model: this.model,
|
|
146
|
+
baseURL: this.baseURL,
|
|
147
|
+
responseFormat: this.responseFormat,
|
|
148
|
+
size: this.size
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
async _generate(messages, options, _runManager) {
|
|
152
|
+
if (!this.apiKey) throw new Error("Missing xAI credentials. Configure XAI_API_KEY before using grok-imagine-image.");
|
|
153
|
+
const prompt = buildPrompt(messages);
|
|
154
|
+
const payload = {
|
|
155
|
+
model: this.model,
|
|
156
|
+
prompt,
|
|
157
|
+
response_format: this.responseFormat
|
|
158
|
+
};
|
|
159
|
+
if (this.size) payload.size = this.size;
|
|
160
|
+
const response = await this.caller.callWithOptions({
|
|
161
|
+
signal: options.signal
|
|
162
|
+
}, async ()=>fetch(`${this.baseURL}/images/generations`, {
|
|
163
|
+
method: "POST",
|
|
164
|
+
headers: {
|
|
165
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
166
|
+
"Content-Type": "application/json"
|
|
167
|
+
},
|
|
168
|
+
body: JSON.stringify(payload),
|
|
169
|
+
signal: options.signal
|
|
170
|
+
}));
|
|
171
|
+
if (!response.ok) throw new Error(await readErrorResponse(response));
|
|
172
|
+
const data = await response.json();
|
|
173
|
+
const first = Array.isArray(data.data) ? data.data[0] : void 0;
|
|
174
|
+
if (!first) throw new Error("xAI image generation returned no image data.");
|
|
175
|
+
const imageUrl = "string" == typeof first.url && first.url.trim() ? first.url.trim() : "string" == typeof first.b64_json && first.b64_json.trim() ? `data:${first.mime_type || "image/png"};base64,${first.b64_json.trim()}` : "";
|
|
176
|
+
if (!imageUrl) throw new Error("xAI image generation response was missing both url and b64_json.");
|
|
177
|
+
const confirmationText = "Image generated.";
|
|
178
|
+
const message = new messages_namespaceObject.AIMessage({
|
|
179
|
+
content: [
|
|
180
|
+
{
|
|
181
|
+
type: "text",
|
|
182
|
+
text: confirmationText
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
type: "output_image",
|
|
186
|
+
image_url: imageUrl
|
|
187
|
+
}
|
|
188
|
+
],
|
|
189
|
+
response_metadata: {
|
|
190
|
+
model: this.model,
|
|
191
|
+
revised_prompt: first.revised_prompt
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
return {
|
|
195
|
+
generations: [
|
|
196
|
+
{
|
|
197
|
+
text: confirmationText,
|
|
198
|
+
message
|
|
199
|
+
}
|
|
200
|
+
],
|
|
201
|
+
llmOutput: {
|
|
202
|
+
model: this.model
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
async *_streamResponseChunks(messages, options, runManager) {
|
|
207
|
+
const result = await this._generate(messages, options, runManager);
|
|
208
|
+
const generation = result.generations[0];
|
|
209
|
+
if (!generation) return;
|
|
210
|
+
const aiMessage = generation.message;
|
|
211
|
+
const chunk = new messages_namespaceObject.AIMessageChunk({
|
|
212
|
+
content: aiMessage.content,
|
|
213
|
+
additional_kwargs: aiMessage.additional_kwargs,
|
|
214
|
+
response_metadata: aiMessage.response_metadata
|
|
215
|
+
});
|
|
216
|
+
if (generation.text) await runManager?.handleLLMNewToken(generation.text);
|
|
217
|
+
yield new outputs_namespaceObject.ChatGenerationChunk({
|
|
218
|
+
text: generation.text || "",
|
|
219
|
+
message: chunk,
|
|
220
|
+
generationInfo: generation.generationInfo
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
constructor(fields){
|
|
224
|
+
super(fields), _define_property(this, "model", void 0), _define_property(this, "apiKey", void 0), _define_property(this, "baseURL", void 0), _define_property(this, "size", void 0), _define_property(this, "responseFormat", void 0);
|
|
225
|
+
this.model = fields.model;
|
|
226
|
+
this.apiKey = fields.apiKey;
|
|
227
|
+
this.baseURL = (fields.baseURL || DEFAULT_XAI_BASE_URL).replace(/\/+$/, "");
|
|
228
|
+
this.size = fields.size;
|
|
229
|
+
this.responseFormat = fields.responseFormat || "url";
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
exports.DEFAULT_XAI_BASE_URL = __webpack_exports__.DEFAULT_XAI_BASE_URL;
|
|
233
|
+
exports.NativeXAIImageModel = __webpack_exports__.NativeXAIImageModel;
|
|
234
|
+
exports.isNativeXAIImageModel = __webpack_exports__.isNativeXAIImageModel;
|
|
235
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
236
|
+
"DEFAULT_XAI_BASE_URL",
|
|
237
|
+
"NativeXAIImageModel",
|
|
238
|
+
"isNativeXAIImageModel"
|
|
239
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
240
|
+
Object.defineProperty(exports, '__esModule', {
|
|
241
|
+
value: true
|
|
242
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { CallbackManagerForLLMRun } from "@langchain/core/callbacks/manager";
|
|
2
|
+
import { BaseChatModel, type BaseChatModelCallOptions, type BaseChatModelParams } from "@langchain/core/language_models/chat_models";
|
|
3
|
+
import { type BaseMessage } from "@langchain/core/messages";
|
|
4
|
+
import { ChatGenerationChunk, type ChatResult } from "@langchain/core/outputs";
|
|
5
|
+
export declare const DEFAULT_XAI_BASE_URL = "https://api.x.ai/v1";
|
|
6
|
+
type XAIImageResponseFormat = "url" | "b64_json";
|
|
7
|
+
type XAIImageModelInput = BaseChatModelParams & {
|
|
8
|
+
model: string;
|
|
9
|
+
apiKey?: string;
|
|
10
|
+
baseURL?: string;
|
|
11
|
+
size?: string;
|
|
12
|
+
responseFormat?: XAIImageResponseFormat;
|
|
13
|
+
};
|
|
14
|
+
export declare function isNativeXAIImageModel(modelName: string): boolean;
|
|
15
|
+
export declare class NativeXAIImageModel extends BaseChatModel<BaseChatModelCallOptions> {
|
|
16
|
+
model: string;
|
|
17
|
+
apiKey?: string;
|
|
18
|
+
baseURL: string;
|
|
19
|
+
size?: string;
|
|
20
|
+
responseFormat: XAIImageResponseFormat;
|
|
21
|
+
constructor(fields: XAIImageModelInput);
|
|
22
|
+
bindTools(_tools: unknown[], _options?: Record<string, unknown>): NativeXAIImageModel;
|
|
23
|
+
_llmType(): string;
|
|
24
|
+
getLsParams(): {
|
|
25
|
+
ls_provider: string;
|
|
26
|
+
ls_model_name: string;
|
|
27
|
+
ls_model_type: "chat";
|
|
28
|
+
};
|
|
29
|
+
invocationParams(): Record<string, unknown>;
|
|
30
|
+
_generate(messages: BaseMessage[], options: this["ParsedCallOptions"], _runManager?: CallbackManagerForLLMRun): Promise<ChatResult>;
|
|
31
|
+
_streamResponseChunks(messages: BaseMessage[], options: this["ParsedCallOptions"], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
|
|
32
|
+
}
|
|
33
|
+
export {};
|