@wingman-ai/gateway 0.4.2 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/README.md +14 -0
  2. package/dist/agent/config/mcpClientManager.cjs +104 -1
  3. package/dist/agent/config/mcpClientManager.d.ts +30 -0
  4. package/dist/agent/config/mcpClientManager.js +104 -1
  5. package/dist/agent/config/modelFactory.cjs +10 -0
  6. package/dist/agent/config/modelFactory.js +10 -0
  7. package/dist/agent/config/xaiImageModel.cjs +242 -0
  8. package/dist/agent/config/xaiImageModel.d.ts +33 -0
  9. package/dist/agent/config/xaiImageModel.js +202 -0
  10. package/dist/agent/tests/mcpClientManager.test.cjs +116 -0
  11. package/dist/agent/tests/mcpClientManager.test.js +117 -1
  12. package/dist/agent/tests/mcpResourceTools.test.cjs +101 -0
  13. package/dist/agent/tests/mcpResourceTools.test.d.ts +1 -0
  14. package/dist/agent/tests/mcpResourceTools.test.js +95 -0
  15. package/dist/agent/tests/modelFactory.test.cjs +16 -2
  16. package/dist/agent/tests/modelFactory.test.js +16 -2
  17. package/dist/agent/tests/xaiImageModel.test.cjs +194 -0
  18. package/dist/agent/tests/xaiImageModel.test.d.ts +1 -0
  19. package/dist/agent/tests/xaiImageModel.test.js +188 -0
  20. package/dist/agent/tools/mcp_resources.cjs +111 -0
  21. package/dist/agent/tools/mcp_resources.d.ts +3 -0
  22. package/dist/agent/tools/mcp_resources.js +77 -0
  23. package/dist/bench/adapters/commandAdapter.cjs +93 -0
  24. package/dist/bench/adapters/commandAdapter.d.ts +6 -0
  25. package/dist/bench/adapters/commandAdapter.js +59 -0
  26. package/dist/bench/adapters/helpers.cjs +170 -0
  27. package/dist/bench/adapters/helpers.d.ts +7 -0
  28. package/dist/bench/adapters/helpers.js +133 -0
  29. package/dist/bench/adapters/index.cjs +41 -0
  30. package/dist/bench/adapters/index.d.ts +2 -0
  31. package/dist/bench/adapters/index.js +7 -0
  32. package/dist/bench/adapters/wingmanCliAdapter.cjs +100 -0
  33. package/dist/bench/adapters/wingmanCliAdapter.d.ts +6 -0
  34. package/dist/bench/adapters/wingmanCliAdapter.js +66 -0
  35. package/dist/bench/cleanup.cjs +122 -0
  36. package/dist/bench/cleanup.d.ts +9 -0
  37. package/dist/bench/cleanup.js +85 -0
  38. package/dist/bench/config.cjs +190 -0
  39. package/dist/bench/config.d.ts +2 -0
  40. package/dist/bench/config.js +156 -0
  41. package/dist/bench/index.cjs +43 -0
  42. package/dist/bench/index.d.ts +3 -0
  43. package/dist/bench/index.js +3 -0
  44. package/dist/bench/official.cjs +616 -0
  45. package/dist/bench/official.d.ts +80 -0
  46. package/dist/bench/official.js +546 -0
  47. package/dist/bench/officialCli.cjs +204 -0
  48. package/dist/bench/officialCli.d.ts +5 -0
  49. package/dist/bench/officialCli.js +170 -0
  50. package/dist/bench/process.cjs +78 -0
  51. package/dist/bench/process.d.ts +14 -0
  52. package/dist/bench/process.js +44 -0
  53. package/dist/bench/runner.cjs +237 -0
  54. package/dist/bench/runner.d.ts +7 -0
  55. package/dist/bench/runner.js +197 -0
  56. package/dist/bench/scoring.cjs +171 -0
  57. package/dist/bench/scoring.d.ts +9 -0
  58. package/dist/bench/scoring.js +137 -0
  59. package/dist/bench/types.cjs +18 -0
  60. package/dist/bench/types.d.ts +200 -0
  61. package/dist/bench/types.js +0 -0
  62. package/dist/bench/validator.cjs +92 -0
  63. package/dist/bench/validator.d.ts +2 -0
  64. package/dist/bench/validator.js +58 -0
  65. package/dist/cli/config/schema.cjs +36 -1
  66. package/dist/cli/config/schema.d.ts +46 -0
  67. package/dist/cli/config/schema.js +36 -1
  68. package/dist/cli/config/warnings.cjs +119 -51
  69. package/dist/cli/config/warnings.js +119 -51
  70. package/dist/cli/core/agentInvoker.cjs +9 -2
  71. package/dist/cli/core/agentInvoker.d.ts +1 -0
  72. package/dist/cli/core/agentInvoker.js +9 -2
  73. package/dist/cli/core/imagePersistence.cjs +17 -1
  74. package/dist/cli/core/imagePersistence.d.ts +2 -0
  75. package/dist/cli/core/imagePersistence.js +13 -3
  76. package/dist/cli/core/sessionManager.cjs +2 -0
  77. package/dist/cli/core/sessionManager.js +3 -1
  78. package/dist/cli/types.d.ts +18 -0
  79. package/dist/gateway/adapters/teams.cjs +419 -0
  80. package/dist/gateway/adapters/teams.d.ts +47 -0
  81. package/dist/gateway/adapters/teams.js +361 -0
  82. package/dist/gateway/http/sms.cjs +286 -0
  83. package/dist/gateway/http/sms.d.ts +4 -0
  84. package/dist/gateway/http/sms.js +249 -0
  85. package/dist/gateway/server.cjs +54 -3
  86. package/dist/gateway/server.d.ts +2 -0
  87. package/dist/gateway/server.js +54 -3
  88. package/dist/gateway/sms/commands.cjs +116 -0
  89. package/dist/gateway/sms/commands.d.ts +15 -0
  90. package/dist/gateway/sms/commands.js +79 -0
  91. package/dist/gateway/sms/control.cjs +118 -0
  92. package/dist/gateway/sms/control.d.ts +18 -0
  93. package/dist/gateway/sms/control.js +84 -0
  94. package/dist/gateway/sms/policyStore.cjs +198 -0
  95. package/dist/gateway/sms/policyStore.d.ts +37 -0
  96. package/dist/gateway/sms/policyStore.js +161 -0
  97. package/dist/providers/registry.cjs +1 -0
  98. package/dist/providers/registry.js +1 -0
  99. package/dist/tests/cli-config-warnings.test.cjs +41 -0
  100. package/dist/tests/cli-config-warnings.test.js +41 -0
  101. package/dist/tests/cli-init.test.cjs +32 -26
  102. package/dist/tests/cli-init.test.js +32 -26
  103. package/dist/tests/gateway-http-security.test.cjs +21 -0
  104. package/dist/tests/gateway-http-security.test.js +21 -0
  105. package/dist/tests/gateway-origin-policy.test.cjs +22 -0
  106. package/dist/tests/gateway-origin-policy.test.js +22 -0
  107. package/dist/tests/gateway.test.cjs +57 -0
  108. package/dist/tests/gateway.test.js +57 -0
  109. package/dist/tests/imagePersistence.test.cjs +26 -0
  110. package/dist/tests/imagePersistence.test.js +27 -1
  111. package/dist/tests/run-terminal-bench-official-script.test.cjs +61 -0
  112. package/dist/tests/run-terminal-bench-official-script.test.d.ts +1 -0
  113. package/dist/tests/run-terminal-bench-official-script.test.js +55 -0
  114. package/dist/tests/sessions-api.test.cjs +69 -1
  115. package/dist/tests/sessions-api.test.js +70 -2
  116. package/dist/tests/sms-api.test.cjs +183 -0
  117. package/dist/tests/sms-api.test.d.ts +1 -0
  118. package/dist/tests/sms-api.test.js +177 -0
  119. package/dist/tests/sms-commands.test.cjs +90 -0
  120. package/dist/tests/sms-commands.test.d.ts +1 -0
  121. package/dist/tests/sms-commands.test.js +84 -0
  122. package/dist/tests/sms-policy-store.test.cjs +69 -0
  123. package/dist/tests/sms-policy-store.test.d.ts +1 -0
  124. package/dist/tests/sms-policy-store.test.js +63 -0
  125. package/dist/tests/teams-adapter.test.cjs +58 -0
  126. package/dist/tests/teams-adapter.test.d.ts +1 -0
  127. package/dist/tests/teams-adapter.test.js +52 -0
  128. package/dist/tests/terminal-bench-adapters-helpers.test.cjs +64 -0
  129. package/dist/tests/terminal-bench-adapters-helpers.test.d.ts +1 -0
  130. package/dist/tests/terminal-bench-adapters-helpers.test.js +58 -0
  131. package/dist/tests/terminal-bench-cleanup.test.cjs +93 -0
  132. package/dist/tests/terminal-bench-cleanup.test.d.ts +1 -0
  133. package/dist/tests/terminal-bench-cleanup.test.js +87 -0
  134. package/dist/tests/terminal-bench-config.test.cjs +62 -0
  135. package/dist/tests/terminal-bench-config.test.d.ts +1 -0
  136. package/dist/tests/terminal-bench-config.test.js +56 -0
  137. package/dist/tests/terminal-bench-official.test.cjs +194 -0
  138. package/dist/tests/terminal-bench-official.test.d.ts +1 -0
  139. package/dist/tests/terminal-bench-official.test.js +188 -0
  140. package/dist/tests/terminal-bench-runner.test.cjs +82 -0
  141. package/dist/tests/terminal-bench-runner.test.d.ts +1 -0
  142. package/dist/tests/terminal-bench-runner.test.js +76 -0
  143. package/dist/tests/terminal-bench-scoring.test.cjs +128 -0
  144. package/dist/tests/terminal-bench-scoring.test.d.ts +1 -0
  145. package/dist/tests/terminal-bench-scoring.test.js +122 -0
  146. package/dist/tools/mcp-fal-ai.cjs +1 -1
  147. package/dist/tools/mcp-fal-ai.js +1 -1
  148. package/dist/webui/assets/index-Cyg_Hs57.css +11 -0
  149. package/dist/webui/assets/{index-BMekSELC.js → index-DZXLLjaA.js} +109 -109
  150. package/dist/webui/index.html +2 -2
  151. package/package.json +11 -2
  152. package/templates/agents/game-dev/agent.md +110 -63
  153. package/templates/agents/game-dev/art-director.md +106 -0
  154. package/templates/agents/game-dev/game-designer.md +87 -0
  155. package/templates/agents/game-dev/scene-engineer.md +474 -0
  156. package/dist/webui/assets/index-Cwkg4DKj.css +0 -11
  157. package/templates/agents/game-dev/art-generation.md +0 -38
  158. package/templates/agents/game-dev/asset-refinement.md +0 -17
  159. package/templates/agents/game-dev/planning-idea.md +0 -17
  160. package/templates/agents/game-dev/ui-specialist.md +0 -17
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 = null;
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 = null;
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 {};