@wingman-ai/gateway 0.2.4 → 0.3.0

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 (95) hide show
  1. package/.wingman/agents/coding/agent.md +5 -0
  2. package/.wingman/agents/coding-v2/agent.md +58 -0
  3. package/.wingman/agents/game-dev/agent.md +94 -0
  4. package/.wingman/agents/game-dev/art-generation.md +37 -0
  5. package/.wingman/agents/game-dev/asset-refinement.md +17 -0
  6. package/.wingman/agents/game-dev/planning-idea.md +17 -0
  7. package/.wingman/agents/game-dev/ui-specialist.md +17 -0
  8. package/.wingman/agents/main/agent.md +2 -0
  9. package/README.md +1 -0
  10. package/dist/agent/config/agentConfig.d.ts +4 -0
  11. package/dist/agent/config/mcpClientManager.cjs +44 -10
  12. package/dist/agent/config/mcpClientManager.d.ts +6 -2
  13. package/dist/agent/config/mcpClientManager.js +44 -10
  14. package/dist/agent/config/toolRegistry.cjs +3 -1
  15. package/dist/agent/config/toolRegistry.js +3 -1
  16. package/dist/agent/tests/mcpClientManager.test.cjs +124 -0
  17. package/dist/agent/tests/mcpClientManager.test.d.ts +1 -0
  18. package/dist/agent/tests/mcpClientManager.test.js +118 -0
  19. package/dist/agent/tools/command_execute.cjs +1 -1
  20. package/dist/agent/tools/command_execute.js +1 -1
  21. package/dist/cli/config/schema.d.ts +2 -0
  22. package/dist/cli/core/agentInvoker.cjs +55 -66
  23. package/dist/cli/core/agentInvoker.d.ts +10 -13
  24. package/dist/cli/core/agentInvoker.js +42 -62
  25. package/dist/cli/core/imagePersistence.cjs +125 -0
  26. package/dist/cli/core/imagePersistence.d.ts +24 -0
  27. package/dist/cli/core/imagePersistence.js +85 -0
  28. package/dist/cli/core/sessionManager.cjs +297 -40
  29. package/dist/cli/core/sessionManager.d.ts +9 -0
  30. package/dist/cli/core/sessionManager.js +297 -40
  31. package/dist/debug/terminalProbe.cjs +57 -0
  32. package/dist/debug/terminalProbe.d.ts +10 -0
  33. package/dist/debug/terminalProbe.js +20 -0
  34. package/dist/debug/terminalProbeAuth.cjs +140 -0
  35. package/dist/debug/terminalProbeAuth.d.ts +20 -0
  36. package/dist/debug/terminalProbeAuth.js +97 -0
  37. package/dist/gateway/http/fs.cjs +19 -0
  38. package/dist/gateway/http/fs.js +19 -0
  39. package/dist/gateway/http/sessions.cjs +25 -5
  40. package/dist/gateway/http/sessions.js +25 -5
  41. package/dist/gateway/server.cjs +112 -11
  42. package/dist/gateway/server.d.ts +2 -0
  43. package/dist/gateway/server.js +112 -11
  44. package/dist/providers/codex.cjs +230 -37
  45. package/dist/providers/codex.d.ts +2 -0
  46. package/dist/providers/codex.js +231 -38
  47. package/dist/tests/agentInvokerSummarization.test.cjs +56 -37
  48. package/dist/tests/agentInvokerSummarization.test.js +58 -39
  49. package/dist/tests/agentInvokerWorkdir.test.cjs +50 -0
  50. package/dist/tests/agentInvokerWorkdir.test.js +52 -2
  51. package/dist/tests/cli-init.test.cjs +36 -0
  52. package/dist/tests/cli-init.test.js +36 -0
  53. package/dist/tests/codex-provider.test.cjs +173 -0
  54. package/dist/tests/codex-provider.test.js +174 -1
  55. package/dist/tests/falRuntime.test.cjs +78 -0
  56. package/dist/tests/falRuntime.test.d.ts +1 -0
  57. package/dist/tests/falRuntime.test.js +72 -0
  58. package/dist/tests/falSummary.test.cjs +51 -0
  59. package/dist/tests/falSummary.test.d.ts +1 -0
  60. package/dist/tests/falSummary.test.js +45 -0
  61. package/dist/tests/gateway.test.cjs +109 -1
  62. package/dist/tests/gateway.test.js +109 -1
  63. package/dist/tests/imagePersistence.test.cjs +143 -0
  64. package/dist/tests/imagePersistence.test.d.ts +1 -0
  65. package/dist/tests/imagePersistence.test.js +137 -0
  66. package/dist/tests/sessionMessageAttachments.test.cjs +30 -0
  67. package/dist/tests/sessionMessageAttachments.test.js +30 -0
  68. package/dist/tests/sessionStateMessages.test.cjs +126 -0
  69. package/dist/tests/sessionStateMessages.test.js +126 -0
  70. package/dist/tests/sessions-api.test.cjs +117 -3
  71. package/dist/tests/sessions-api.test.js +118 -4
  72. package/dist/tests/terminalProbe.test.cjs +45 -0
  73. package/dist/tests/terminalProbe.test.d.ts +1 -0
  74. package/dist/tests/terminalProbe.test.js +39 -0
  75. package/dist/tests/terminalProbeAuth.test.cjs +85 -0
  76. package/dist/tests/terminalProbeAuth.test.d.ts +1 -0
  77. package/dist/tests/terminalProbeAuth.test.js +79 -0
  78. package/dist/tools/fal/runtime.cjs +103 -0
  79. package/dist/tools/fal/runtime.d.ts +10 -0
  80. package/dist/tools/fal/runtime.js +60 -0
  81. package/dist/tools/fal/summary.cjs +78 -0
  82. package/dist/tools/fal/summary.d.ts +22 -0
  83. package/dist/tools/fal/summary.js +41 -0
  84. package/dist/tools/mcp-fal-ai.cjs +1041 -0
  85. package/dist/tools/mcp-fal-ai.d.ts +1 -0
  86. package/dist/tools/mcp-fal-ai.js +1025 -0
  87. package/dist/types/mcp.cjs +2 -0
  88. package/dist/types/mcp.d.ts +8 -0
  89. package/dist/types/mcp.js +3 -1
  90. package/dist/webui/assets/index-0nUBsUUq.js +278 -0
  91. package/dist/webui/assets/index-kk7OrD-G.css +11 -0
  92. package/dist/webui/index.html +2 -2
  93. package/package.json +16 -13
  94. package/dist/webui/assets/index-DVWQluit.css +0 -11
  95. package/dist/webui/assets/index-Dlyzwalc.js +0 -270
@@ -0,0 +1,1025 @@
1
+ import * as __rspack_external__fal_runtime_js_230694eb from "./fal/runtime.js";
2
+ import * as __rspack_external__fal_summary_js_64406a32 from "./fal/summary.js";
3
+ import * as __rspack_external__fal_ai_client_24ca7f48 from "@fal-ai/client";
4
+ import * as __rspack_external__modelcontextprotocol_sdk_server_mcp_js_2c42c5d0 from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import * as __rspack_external__modelcontextprotocol_sdk_server_stdio_js_4f861174 from "@modelcontextprotocol/sdk/server/stdio.js";
6
+ import * as __rspack_external_node_crypto_9ba42079 from "node:crypto";
7
+ import * as __rspack_external_node_fs_5ea92f0c from "node:fs";
8
+ import * as __rspack_external_node_path_c5b9b54f from "node:path";
9
+ import * as __rspack_external_zod from "zod";
10
+ var __webpack_modules__ = {
11
+ "./src/tools/mcp-fal-ai.ts" (module, __webpack_exports__, __webpack_require__) {
12
+ __webpack_require__.a(module, async function(__rspack_load_async_deps, __rspack_async_done) {
13
+ try {
14
+ __webpack_require__.r(__webpack_exports__);
15
+ var node_crypto__rspack_import_0 = __webpack_require__("node:crypto");
16
+ var node_fs__rspack_import_1 = __webpack_require__("node:fs");
17
+ var node_path__rspack_import_2 = __webpack_require__("node:path");
18
+ var _fal_ai_client__rspack_import_3 = __webpack_require__("@fal-ai/client");
19
+ var _modelcontextprotocol_sdk_server_mcp_js__rspack_import_4 = __webpack_require__("@modelcontextprotocol/sdk/server/mcp.js");
20
+ var _modelcontextprotocol_sdk_server_stdio_js__rspack_import_5 = __webpack_require__("@modelcontextprotocol/sdk/server/stdio.js");
21
+ var zod__rspack_import_6 = __webpack_require__("zod");
22
+ var _fal_runtime_js__rspack_import_7 = __webpack_require__("./fal/runtime.js");
23
+ var _fal_summary_js__rspack_import_8 = __webpack_require__("./fal/summary.js");
24
+ const FAL_DEFAULT_POLL_INTERVAL_MS = parsePositiveInt(process.env.FAL_MCP_POLL_INTERVAL_MS) || 2500;
25
+ const FAL_DEFAULT_STATUS_TIMEOUT_MS = parsePositiveInt(process.env.FAL_MCP_STATUS_TIMEOUT_MS) || 60000;
26
+ const FAL_HTTP_TIMEOUT_MS = parsePositiveInt(process.env.FAL_MCP_HTTP_TIMEOUT_MS) || 120000;
27
+ const FAL_DEFAULT_LOG_LIMIT = 40;
28
+ const FAL_API_KEY_ENV = process.env.FAL_API_KEY?.trim() || process.env.FAL_KEY?.trim() || "";
29
+ const FAL_REVIEW_MODE = normalizeReviewMode(process.env.FAL_MCP_REVIEW_MODE);
30
+ const FAL_MODELS = {
31
+ imageOrTexture: process.env.FAL_MODEL_IMAGE_OR_TEXTURE?.trim() || "fal-ai/nano-banana-pro",
32
+ imageEdit: process.env.FAL_MODEL_IMAGE_EDIT?.trim() || "fal-ai/kling-image/v3/image-to-image",
33
+ audioMusic: process.env.FAL_MODEL_AUDIO_OR_MUSIC?.trim() || "fal-ai/elevenlabs/music",
34
+ audioSoundEffect: process.env.FAL_MODEL_SOUND_EFFECT?.trim() || "beatoven/sound-effect-generation",
35
+ videoFromImage: process.env.FAL_MODEL_VIDEO_FROM_IMAGE?.trim() || "fal-ai/kling-video/o3/standard/image-to-video"
36
+ };
37
+ const FAL_WORKDIR = (0, _fal_runtime_js__rspack_import_7.resolveFalWorkdir)();
38
+ const FAL_STATE_DIR = (0, _fal_runtime_js__rspack_import_7.resolveFalStateDir)();
39
+ const FAL_OUTPUT_DIR = (0, _fal_runtime_js__rspack_import_7.resolveFalOutputDir)();
40
+ const JOBS_DIR = (0, node_path__rspack_import_2.join)(FAL_STATE_DIR, "jobs");
41
+ const PENDING_DIR = (0, node_path__rspack_import_2.join)(FAL_STATE_DIR, "pending");
42
+ const inMemoryJobs = new Map();
43
+ const server = new _modelcontextprotocol_sdk_server_mcp_js__rspack_import_4.McpServer({
44
+ name: "wingman-fal-ai",
45
+ version: "0.1.0"
46
+ });
47
+ const sharedInputSchema = zod__rspack_import_6.object({
48
+ apiKey: zod__rspack_import_6.string().min(1).optional().describe("Optional FAL API key override for this tool call."),
49
+ modelInput: zod__rspack_import_6.record(zod__rspack_import_6.string(), zod__rspack_import_6.any()).optional().describe("Optional raw model input overrides merged into the default payload."),
50
+ waitForCompletion: zod__rspack_import_6.boolean().optional().default(false).describe("If true, block in-tool and poll status until complete or timeout."),
51
+ timeoutSeconds: zod__rspack_import_6.number().int().min(1).max(3600).optional().describe("Optional timeout in seconds for waitForCompletion mode."),
52
+ pollIntervalMs: zod__rspack_import_6.number().int().min(250).max(30000).optional().describe("Optional polling interval in ms for waitForCompletion mode.")
53
+ });
54
+ const generateImageOrTextureSchema = sharedInputSchema.extend({
55
+ prompt: zod__rspack_import_6.string().min(1)
56
+ });
57
+ const generateImageEditSchema = sharedInputSchema.extend({
58
+ prompt: zod__rspack_import_6.string().min(1),
59
+ sourceImage: zod__rspack_import_6.string().min(1).describe("Source image as data URL, local file path, or http(s) URL.")
60
+ });
61
+ const generateAudioOrMusicSchema = sharedInputSchema.extend({
62
+ prompt: zod__rspack_import_6.string().min(1),
63
+ audioMode: zod__rspack_import_6["enum"]([
64
+ "music",
65
+ "sound_effect"
66
+ ]).optional().default("music").describe("Use 'music' for songs/tracks or 'sound_effect' for effects.")
67
+ });
68
+ const generateVideoFromImageSchema = sharedInputSchema.extend({
69
+ prompt: zod__rspack_import_6.string().min(1),
70
+ sourceImage: zod__rspack_import_6.string().min(1).describe("Source image as data URL, local file path, or http(s) URL.")
71
+ });
72
+ const falGenerationStatusSchema = zod__rspack_import_6.object({
73
+ jobId: zod__rspack_import_6.string().min(1).describe("Job id returned from a generate_* tool."),
74
+ action: zod__rspack_import_6["enum"]([
75
+ "check",
76
+ "wait",
77
+ "cancel",
78
+ "accept",
79
+ "deny"
80
+ ]).optional().default("check").describe("Status action. Use wait for polling, accept/deny for review flow."),
81
+ includeLogs: zod__rspack_import_6.boolean().optional().default(true).describe("Include recent queue logs in the result payload."),
82
+ timeoutSeconds: zod__rspack_import_6.number().int().min(1).max(3600).optional().describe("Timeout in seconds when action=wait."),
83
+ pollIntervalMs: zod__rspack_import_6.number().int().min(250).max(30000).optional().describe("Polling interval in ms when action=wait."),
84
+ apiKey: zod__rspack_import_6.string().min(1).optional().describe("Optional FAL API key override for queue status calls.")
85
+ });
86
+ server.registerTool("generate_image_or_texture", {
87
+ title: "FAL Generate Image Or Texture",
88
+ description: "Generate an image or texture with FAL using a queue-backed async job. Returns a job id. Use fal_generation_status for updates and completion.",
89
+ inputSchema: generateImageOrTextureSchema
90
+ }, async ({ prompt, modelInput, apiKey, waitForCompletion, timeoutSeconds, pollIntervalMs })=>{
91
+ const resolvedApiKey = resolveFalApiKey(apiKey);
92
+ const client = (0, _fal_ai_client__rspack_import_3.createFalClient)({
93
+ credentials: resolvedApiKey
94
+ });
95
+ const payload = mergeModelInput({
96
+ prompt
97
+ }, modelInput);
98
+ const job = await submitFalJob({
99
+ client,
100
+ modelId: FAL_MODELS.imageOrTexture,
101
+ modality: "image",
102
+ toolName: "generate_image_or_texture",
103
+ prompt,
104
+ input: payload
105
+ });
106
+ if (waitForCompletion) return runStatusAction({
107
+ job,
108
+ action: "wait",
109
+ includeLogs: true,
110
+ client,
111
+ timeoutMs: normalizeTimeoutMs(timeoutSeconds),
112
+ pollIntervalMs: normalizePollIntervalMs(pollIntervalMs)
113
+ });
114
+ return toToolResult(job);
115
+ });
116
+ server.registerTool("generate_image_edit", {
117
+ title: "FAL Generate Image Edit",
118
+ description: "Edit an image using FAL image-to-image queue jobs. Returns a job id. Use fal_generation_status for updates and completion.",
119
+ inputSchema: generateImageEditSchema
120
+ }, async ({ prompt, sourceImage, modelInput, apiKey, waitForCompletion, timeoutSeconds, pollIntervalMs })=>{
121
+ const resolvedApiKey = resolveFalApiKey(apiKey);
122
+ const client = (0, _fal_ai_client__rspack_import_3.createFalClient)({
123
+ credentials: resolvedApiKey
124
+ });
125
+ const sourceImageUrl = await resolveImageSourceToFalUrl(sourceImage, client);
126
+ const payload = mergeModelInput({
127
+ prompt,
128
+ image_url: sourceImageUrl
129
+ }, modelInput);
130
+ const job = await submitFalJob({
131
+ client,
132
+ modelId: FAL_MODELS.imageEdit,
133
+ modality: "image",
134
+ toolName: "generate_image_edit",
135
+ prompt,
136
+ input: payload
137
+ });
138
+ if (waitForCompletion) return runStatusAction({
139
+ job,
140
+ action: "wait",
141
+ includeLogs: true,
142
+ client,
143
+ timeoutMs: normalizeTimeoutMs(timeoutSeconds),
144
+ pollIntervalMs: normalizePollIntervalMs(pollIntervalMs)
145
+ });
146
+ return toToolResult(job);
147
+ });
148
+ server.registerTool("generate_audio_or_music", {
149
+ title: "FAL Generate Audio Or Music",
150
+ description: "Generate audio or music through FAL queue jobs. Returns a job id. Use fal_generation_status for updates and completion.",
151
+ inputSchema: generateAudioOrMusicSchema
152
+ }, async ({ prompt, audioMode, modelInput, apiKey, waitForCompletion, timeoutSeconds, pollIntervalMs })=>{
153
+ const resolvedApiKey = resolveFalApiKey(apiKey);
154
+ const client = (0, _fal_ai_client__rspack_import_3.createFalClient)({
155
+ credentials: resolvedApiKey
156
+ });
157
+ const modelId = "sound_effect" === audioMode ? FAL_MODELS.audioSoundEffect : FAL_MODELS.audioMusic;
158
+ const payload = mergeModelInput({
159
+ prompt
160
+ }, modelInput);
161
+ const job = await submitFalJob({
162
+ client,
163
+ modelId,
164
+ modality: "audio",
165
+ toolName: "generate_audio_or_music",
166
+ prompt,
167
+ input: payload
168
+ });
169
+ if (waitForCompletion) return runStatusAction({
170
+ job,
171
+ action: "wait",
172
+ includeLogs: true,
173
+ client,
174
+ timeoutMs: normalizeTimeoutMs(timeoutSeconds),
175
+ pollIntervalMs: normalizePollIntervalMs(pollIntervalMs)
176
+ });
177
+ return toToolResult(job);
178
+ });
179
+ server.registerTool("generate_video_from_image", {
180
+ title: "FAL Generate Video From Image",
181
+ description: "Generate a video from an image using FAL queue jobs. Returns a job id. Use fal_generation_status for updates and completion.",
182
+ inputSchema: generateVideoFromImageSchema
183
+ }, async ({ prompt, sourceImage, modelInput, apiKey, waitForCompletion, timeoutSeconds, pollIntervalMs })=>{
184
+ const resolvedApiKey = resolveFalApiKey(apiKey);
185
+ const client = (0, _fal_ai_client__rspack_import_3.createFalClient)({
186
+ credentials: resolvedApiKey
187
+ });
188
+ const sourceImageUrl = await resolveImageSourceToFalUrl(sourceImage, client);
189
+ const payload = mergeModelInput({
190
+ prompt,
191
+ image_url: sourceImageUrl
192
+ }, modelInput);
193
+ const job = await submitFalJob({
194
+ client,
195
+ modelId: FAL_MODELS.videoFromImage,
196
+ modality: "video",
197
+ toolName: "generate_video_from_image",
198
+ prompt,
199
+ input: payload
200
+ });
201
+ if (waitForCompletion) return runStatusAction({
202
+ job,
203
+ action: "wait",
204
+ includeLogs: true,
205
+ client,
206
+ timeoutMs: normalizeTimeoutMs(timeoutSeconds),
207
+ pollIntervalMs: normalizePollIntervalMs(pollIntervalMs)
208
+ });
209
+ return toToolResult(job);
210
+ });
211
+ server.registerTool("fal_generation_status", {
212
+ title: "FAL Generation Status",
213
+ description: "Check, wait, cancel, or review FAL generation jobs. Use action=wait to poll until completion. Use action=accept/deny when review mode is enabled.",
214
+ inputSchema: falGenerationStatusSchema
215
+ }, async ({ jobId, action, includeLogs, timeoutSeconds, pollIntervalMs, apiKey })=>{
216
+ const existing = loadJobState(jobId);
217
+ if (!existing) throw new Error(`Unknown FAL job "${jobId}". Submit a new generation first or check the job id.`);
218
+ if ("accept" === action || "deny" === action) return runReviewDecision(existing, action);
219
+ if ("check" === action && isTerminal(existing.status)) return toToolResult(existing);
220
+ const resolvedApiKey = resolveFalApiKey(apiKey);
221
+ const client = (0, _fal_ai_client__rspack_import_3.createFalClient)({
222
+ credentials: resolvedApiKey
223
+ });
224
+ return runStatusAction({
225
+ job: existing,
226
+ action,
227
+ includeLogs,
228
+ client,
229
+ timeoutMs: normalizeTimeoutMs(timeoutSeconds),
230
+ pollIntervalMs: normalizePollIntervalMs(pollIntervalMs)
231
+ });
232
+ });
233
+ function normalizeReviewMode(raw) {
234
+ return raw?.trim().toLowerCase() === "hil" ? "hil" : "auto";
235
+ }
236
+ function parsePositiveInt(raw) {
237
+ if (!raw) return null;
238
+ const parsed = Number.parseInt(raw, 10);
239
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
240
+ }
241
+ function normalizeTimeoutMs(timeoutSeconds) {
242
+ if (timeoutSeconds && timeoutSeconds > 0) return 1000 * timeoutSeconds;
243
+ return FAL_DEFAULT_STATUS_TIMEOUT_MS;
244
+ }
245
+ function normalizePollIntervalMs(interval) {
246
+ if (interval && interval >= 250) return interval;
247
+ return FAL_DEFAULT_POLL_INTERVAL_MS;
248
+ }
249
+ function resolveFalApiKey(override) {
250
+ const candidate = override?.trim() || FAL_API_KEY_ENV;
251
+ if (!candidate) throw new Error("FAL API key missing. Set FAL_API_KEY (or FAL_KEY) in MCP env, or pass apiKey in tool input.");
252
+ return candidate;
253
+ }
254
+ function sanitizeJobId(value) {
255
+ const normalized = (value || "").trim();
256
+ if (!normalized) return (0, node_crypto__rspack_import_0.randomUUID)();
257
+ const sanitized = normalized.replace(/[^a-zA-Z0-9._-]/g, "_");
258
+ return sanitized.slice(0, 120) || (0, node_crypto__rspack_import_0.randomUUID)();
259
+ }
260
+ function buildJobPath(jobId) {
261
+ return (0, node_path__rspack_import_2.join)(JOBS_DIR, `${sanitizeJobId(jobId)}.json`);
262
+ }
263
+ function loadJobState(jobId) {
264
+ const normalized = sanitizeJobId(jobId);
265
+ const cached = inMemoryJobs.get(normalized);
266
+ if (cached) return cached;
267
+ const path = buildJobPath(normalized);
268
+ if (!(0, node_fs__rspack_import_1.existsSync)(path)) return null;
269
+ try {
270
+ const parsed = JSON.parse((0, node_fs__rspack_import_1.readFileSync)(path, "utf-8"));
271
+ if (!parsed || "object" != typeof parsed) return null;
272
+ inMemoryJobs.set(normalized, parsed);
273
+ return parsed;
274
+ } catch {
275
+ return null;
276
+ }
277
+ }
278
+ function saveJobState(job) {
279
+ const normalizedId = sanitizeJobId(job.jobId);
280
+ const normalized = {
281
+ ...job,
282
+ jobId: normalizedId,
283
+ updatedAt: new Date().toISOString()
284
+ };
285
+ (0, node_fs__rspack_import_1.mkdirSync)(JOBS_DIR, {
286
+ recursive: true
287
+ });
288
+ (0, node_fs__rspack_import_1.writeFileSync)(buildJobPath(normalizedId), JSON.stringify(normalized, null, 2));
289
+ inMemoryJobs.set(normalizedId, normalized);
290
+ return normalized;
291
+ }
292
+ function mapQueueStatus(status) {
293
+ switch(status){
294
+ case "IN_QUEUE":
295
+ return "in_queue";
296
+ case "IN_PROGRESS":
297
+ return "in_progress";
298
+ case "COMPLETED":
299
+ return "completed";
300
+ default:
301
+ return "failed";
302
+ }
303
+ }
304
+ function isTerminal(status) {
305
+ return "completed" === status || "failed" === status || "cancelled" === status || "awaiting_review" === status || "denied" === status;
306
+ }
307
+ function mergeModelInput(base, overrides) {
308
+ if (!overrides || "object" != typeof overrides) return base;
309
+ return {
310
+ ...base,
311
+ ...overrides
312
+ };
313
+ }
314
+ async function resolveImageSourceToFalUrl(source, client) {
315
+ const trimmed = source.trim();
316
+ if (!trimmed) throw new Error("sourceImage cannot be empty.");
317
+ if (/^https?:\/\//i.test(trimmed)) return trimmed;
318
+ const inline = parseBase64DataUrl(trimmed);
319
+ if (inline) {
320
+ if (!inline.mimeType.startsWith("image/")) throw new Error(`Expected image data URL, got ${inline.mimeType}.`);
321
+ const bytes = Buffer.from(inline.data, "base64");
322
+ if (0 === bytes.length) throw new Error("sourceImage data URL is empty.");
323
+ return uploadToFalStorage(client, bytes, inline.mimeType, "source-image");
324
+ }
325
+ const localPath = (0, _fal_runtime_js__rspack_import_7.resolveFalLocalMediaPath)(trimmed, FAL_WORKDIR);
326
+ if (!(0, node_fs__rspack_import_1.existsSync)(localPath) || !(0, node_fs__rspack_import_1.statSync)(localPath).isFile()) throw new Error(`sourceImage must be a data URL, http(s) URL, or local file path: ${source}`);
327
+ const bytes = (0, node_fs__rspack_import_1.readFileSync)(localPath);
328
+ if (0 === bytes.length) throw new Error(`sourceImage file is empty: ${localPath}`);
329
+ const mimeType = mimeTypeFromPath(localPath) || "image/png";
330
+ if (!mimeType.startsWith("image/")) throw new Error(`sourceImage must be an image file, got ${mimeType}.`);
331
+ return uploadToFalStorage(client, bytes, mimeType, (0, node_path__rspack_import_2.basename)(localPath));
332
+ }
333
+ async function uploadToFalStorage(client, bytes, mimeType, name) {
334
+ const ext = extensionFromMimeType(mimeType);
335
+ const blob = new Blob([
336
+ bytes
337
+ ], {
338
+ type: mimeType
339
+ });
340
+ const file = new File([
341
+ blob
342
+ ], `${sanitizeName(name)}.${ext}`, {
343
+ type: mimeType
344
+ });
345
+ return client.storage.upload(file, {
346
+ lifecycle: {
347
+ expiresIn: "1d"
348
+ }
349
+ });
350
+ }
351
+ async function submitFalJob(input) {
352
+ const queued = await input.client.queue.submit(input.modelId, {
353
+ input: input.input
354
+ });
355
+ const now = new Date().toISOString();
356
+ const job = {
357
+ jobId: sanitizeJobId(queued.request_id || (0, node_crypto__rspack_import_0.randomUUID)()),
358
+ requestId: queued.request_id,
359
+ toolName: input.toolName,
360
+ modelId: input.modelId,
361
+ modality: input.modality,
362
+ prompt: input.prompt,
363
+ status: mapQueueStatus(queued.status),
364
+ reviewRequired: "hil" === FAL_REVIEW_MODE,
365
+ reviewState: null,
366
+ error: null,
367
+ submittedAt: now,
368
+ updatedAt: now,
369
+ queueStatus: queued.status,
370
+ queueStatusUrl: "string" == typeof queued.status_url ? queued.status_url : null,
371
+ queueResponseUrl: "string" == typeof queued.response_url ? queued.response_url : null,
372
+ queueCancelUrl: "string" == typeof queued.cancel_url ? queued.cancel_url : null,
373
+ logs: [],
374
+ media: [],
375
+ rawResult: null
376
+ };
377
+ return saveJobState(job);
378
+ }
379
+ async function runStatusAction(input) {
380
+ let job = input.job;
381
+ if ("cancel" === input.action) {
382
+ if (isTerminal(job.status)) return toToolResult(job);
383
+ await input.client.queue.cancel(job.modelId, {
384
+ requestId: job.requestId
385
+ });
386
+ job = saveJobState({
387
+ ...job,
388
+ status: "cancelled",
389
+ error: null
390
+ });
391
+ return toToolResult(job);
392
+ }
393
+ const deadline = "wait" === input.action ? Date.now() + Math.max(1000, input.timeoutMs) : 0;
394
+ for(;;){
395
+ job = await refreshQueueStatus(job, input.client, input.includeLogs);
396
+ if ("completed" === job.status) job = await materializeCompletedJob(job, input.client);
397
+ if (isTerminal(job.status)) return toToolResult(job);
398
+ if ("wait" !== input.action) return toToolResult(job);
399
+ if (Date.now() >= deadline) return toToolResult(job);
400
+ await sleep(input.pollIntervalMs);
401
+ }
402
+ }
403
+ async function refreshQueueStatus(job, client, includeLogs) {
404
+ const status = await client.queue.status(job.modelId, {
405
+ requestId: job.requestId,
406
+ logs: includeLogs
407
+ });
408
+ const statusWithLogs = status;
409
+ const logs = includeLogs && Array.isArray(statusWithLogs.logs) ? statusWithLogs.logs.map((entry)=>"string" == typeof entry?.message ? entry.message : "").filter((entry)=>entry.trim().length > 0).slice(-FAL_DEFAULT_LOG_LIMIT) : job.logs;
410
+ return saveJobState({
411
+ ...job,
412
+ status: mapQueueStatus(status.status),
413
+ queueStatus: status.status,
414
+ queueStatusUrl: "string" == typeof status.status_url ? status.status_url : null,
415
+ queueResponseUrl: "string" == typeof status.response_url ? status.response_url : null,
416
+ queueCancelUrl: "string" == typeof status.cancel_url ? status.cancel_url : null,
417
+ logs
418
+ });
419
+ }
420
+ async function materializeCompletedJob(job, client) {
421
+ if (job.rawResult && job.media.length > 0) {
422
+ if (job.reviewRequired && "pending" === job.reviewState) return saveJobState({
423
+ ...job,
424
+ status: "awaiting_review"
425
+ });
426
+ return saveJobState({
427
+ ...job,
428
+ status: "completed"
429
+ });
430
+ }
431
+ try {
432
+ const result = await client.queue.result(job.modelId, {
433
+ requestId: job.requestId
434
+ });
435
+ const rawData = result?.data ?? null;
436
+ const candidates = extractMediaCandidates(rawData, job.modality);
437
+ const media = candidates.length > 0 ? await materializeMediaCandidates(job, candidates) : [];
438
+ const nextStatus = job.reviewRequired && media.length > 0 ? "awaiting_review" : "completed";
439
+ const reviewState = job.reviewRequired && media.length > 0 ? "pending" : media.length > 0 ? "accepted" : null;
440
+ return saveJobState({
441
+ ...job,
442
+ status: nextStatus,
443
+ reviewState,
444
+ error: null,
445
+ media,
446
+ rawResult: rawData
447
+ });
448
+ } catch (error) {
449
+ return saveJobState({
450
+ ...job,
451
+ status: "failed",
452
+ error: errorToString(error)
453
+ });
454
+ }
455
+ }
456
+ async function materializeMediaCandidates(job, candidates) {
457
+ const destinationRoot = job.reviewRequired ? (0, node_path__rspack_import_2.join)(PENDING_DIR, job.jobId) : resolveFinalOutputDir(job.modality);
458
+ (0, node_fs__rspack_import_1.mkdirSync)(destinationRoot, {
459
+ recursive: true
460
+ });
461
+ const records = [];
462
+ for (const [index, candidate] of candidates.entries()){
463
+ let bytes;
464
+ let mimeType;
465
+ try {
466
+ const downloaded = await downloadRemoteFile(candidate.url);
467
+ bytes = downloaded.bytes;
468
+ mimeType = normalizeMimeType(downloaded.mimeType) || candidate.mimeType || "application/octet-stream";
469
+ } catch {
470
+ continue;
471
+ }
472
+ const extension = extensionFromMimeType(mimeType) || extensionFromUrl(candidate.url);
473
+ const hash = (0, node_crypto__rspack_import_0.createHash)("sha256").update(bytes).digest("hex").slice(0, 12);
474
+ const filename = `${Date.now()}-${index + 1}-${hash}.${extension || "bin"}`;
475
+ const outputPath = (0, node_path__rspack_import_2.join)(destinationRoot, filename);
476
+ (0, node_fs__rspack_import_1.writeFileSync)(outputPath, bytes);
477
+ records.push({
478
+ id: `${job.jobId}-${index + 1}`,
479
+ modality: classifyModality(candidate, mimeType),
480
+ mimeType,
481
+ remoteUrl: candidate.url,
482
+ path: outputPath,
483
+ name: candidate.label || filename,
484
+ sizeBytes: bytes.length,
485
+ createdAt: new Date().toISOString()
486
+ });
487
+ }
488
+ return records;
489
+ }
490
+ function resolveFinalOutputDir(modality) {
491
+ const folder = "image" === modality ? "images" : "audio" === modality ? "audio" : "video" === modality ? "video" : "files";
492
+ const dir = (0, node_path__rspack_import_2.join)(FAL_OUTPUT_DIR, folder);
493
+ (0, node_fs__rspack_import_1.mkdirSync)(dir, {
494
+ recursive: true
495
+ });
496
+ return dir;
497
+ }
498
+ function runReviewDecision(job, decision) {
499
+ if (true !== job.reviewRequired || "pending" !== job.reviewState) throw new Error(`Job ${job.jobId} is not waiting for review. Current reviewState=${job.reviewState || "none"}.`);
500
+ if ("deny" === decision) {
501
+ for (const media of job.media)if (media.path) try {
502
+ (0, node_fs__rspack_import_1.unlinkSync)(media.path);
503
+ } catch {}
504
+ try {
505
+ (0, node_fs__rspack_import_1.rmSync)((0, node_path__rspack_import_2.join)(PENDING_DIR, job.jobId), {
506
+ recursive: true,
507
+ force: true
508
+ });
509
+ } catch {}
510
+ const denied = saveJobState({
511
+ ...job,
512
+ status: "denied",
513
+ reviewState: "denied",
514
+ media: job.media.map((entry)=>({
515
+ ...entry,
516
+ path: null
517
+ }))
518
+ });
519
+ return toToolResult(denied);
520
+ }
521
+ const acceptedMedia = job.media.map((entry)=>{
522
+ if (!entry.path) return entry;
523
+ const targetDir = resolveFinalOutputDir(entry.modality);
524
+ const targetPath = (0, node_path__rspack_import_2.join)(targetDir, (0, node_path__rspack_import_2.basename)(entry.path));
525
+ moveFile(entry.path, targetPath);
526
+ return {
527
+ ...entry,
528
+ path: targetPath
529
+ };
530
+ });
531
+ try {
532
+ (0, node_fs__rspack_import_1.rmSync)((0, node_path__rspack_import_2.join)(PENDING_DIR, job.jobId), {
533
+ recursive: true,
534
+ force: true
535
+ });
536
+ } catch {}
537
+ const accepted = saveJobState({
538
+ ...job,
539
+ status: "completed",
540
+ reviewState: "accepted",
541
+ media: acceptedMedia
542
+ });
543
+ return toToolResult(accepted);
544
+ }
545
+ function moveFile(sourcePath, targetPath) {
546
+ try {
547
+ (0, node_fs__rspack_import_1.renameSync)(sourcePath, targetPath);
548
+ return;
549
+ } catch {
550
+ (0, node_fs__rspack_import_1.copyFileSync)(sourcePath, targetPath);
551
+ (0, node_fs__rspack_import_1.unlinkSync)(sourcePath);
552
+ }
553
+ }
554
+ function extractMediaCandidates(payload, fallbackModality) {
555
+ const output = [];
556
+ const seen = new Set();
557
+ const walk = (value, path, parent)=>{
558
+ if (!value) return;
559
+ if (Array.isArray(value)) {
560
+ for (const item of value)walk(item, path, parent);
561
+ return;
562
+ }
563
+ if ("string" == typeof value) {
564
+ const trimmed = value.trim();
565
+ if (!/^https?:\/\//i.test(trimmed)) return;
566
+ if (seen.has(trimmed)) return;
567
+ const hint = path[path.length - 1] || "";
568
+ const mimeType = inferMimeTypeFromContext(trimmed, parent);
569
+ if (!looksLikeMediaCandidate(trimmed, hint, mimeType)) return;
570
+ seen.add(trimmed);
571
+ output.push({
572
+ url: trimmed,
573
+ mimeType,
574
+ modality: inferModalityFromHint(hint, mimeType, fallbackModality),
575
+ label: buildCandidateLabel(path)
576
+ });
577
+ return;
578
+ }
579
+ if ("object" != typeof value) return;
580
+ const record = value;
581
+ for (const [key, nested] of Object.entries(record))walk(nested, [
582
+ ...path,
583
+ key
584
+ ], record);
585
+ };
586
+ walk(payload, [], null);
587
+ return output;
588
+ }
589
+ function looksLikeMediaCandidate(url, hint, mimeType) {
590
+ if (mimeType) {
591
+ if (mimeType.startsWith("image/") || mimeType.startsWith("audio/") || mimeType.startsWith("video/")) return true;
592
+ }
593
+ const normalizedHint = hint.toLowerCase();
594
+ for (const fragment of [
595
+ "image",
596
+ "audio",
597
+ "music",
598
+ "video",
599
+ "file",
600
+ "media"
601
+ ])if (normalizedHint.includes(fragment)) return true;
602
+ const extension = extensionFromUrl(url).toLowerCase();
603
+ return Boolean(mimeTypeFromExtension(extension));
604
+ }
605
+ function buildCandidateLabel(path) {
606
+ if (0 === path.length) return;
607
+ return sanitizeName(path.join("-")) || void 0;
608
+ }
609
+ function inferMimeTypeFromContext(url, parent) {
610
+ if (parent) for (const key of [
611
+ "mime_type",
612
+ "mimeType",
613
+ "content_type",
614
+ "contentType"
615
+ ]){
616
+ const value = parent[key];
617
+ if ("string" == typeof value && value.trim()) return normalizeMimeType(value);
618
+ }
619
+ const extension = extensionFromUrl(url);
620
+ if (!extension) return;
621
+ return mimeTypeFromExtension(extension) || void 0;
622
+ }
623
+ function inferModalityFromHint(hint, mimeType, fallback) {
624
+ const normalizedHint = hint.toLowerCase();
625
+ if (mimeType) {
626
+ if (mimeType.startsWith("image/")) return "image";
627
+ if (mimeType.startsWith("audio/")) return "audio";
628
+ if (mimeType.startsWith("video/")) return "video";
629
+ }
630
+ if (normalizedHint.includes("image")) return "image";
631
+ if (normalizedHint.includes("audio") || normalizedHint.includes("music")) return "audio";
632
+ if (normalizedHint.includes("video")) return "video";
633
+ return fallback;
634
+ }
635
+ function classifyModality(candidate, mimeType) {
636
+ if (mimeType.startsWith("image/")) return "image";
637
+ if (mimeType.startsWith("audio/")) return "audio";
638
+ if (mimeType.startsWith("video/")) return "video";
639
+ return candidate.modality;
640
+ }
641
+ async function downloadRemoteFile(url) {
642
+ const response = await fetchWithTimeout(url, {
643
+ method: "GET",
644
+ headers: {
645
+ "User-Agent": "wingman-mcp-fal-ai"
646
+ }
647
+ });
648
+ if (!response.ok) throw new Error(`Failed to download media (${response.status}): ${url}`);
649
+ const mimeType = normalizeMimeType(response.headers.get("content-type") || "");
650
+ const arrayBuffer = await response.arrayBuffer();
651
+ const bytes = Buffer.from(arrayBuffer);
652
+ if (0 === bytes.length) throw new Error(`Downloaded media is empty: ${url}`);
653
+ return {
654
+ bytes,
655
+ mimeType
656
+ };
657
+ }
658
+ function parseBase64DataUrl(dataUrl) {
659
+ const match = dataUrl.match(/^data:([^;,]+);base64,(.+)$/i);
660
+ if (!match) return null;
661
+ return {
662
+ mimeType: normalizeMimeType(match[1]),
663
+ data: match[2].trim()
664
+ };
665
+ }
666
+ function extensionFromUrl(url) {
667
+ try {
668
+ const parsed = new URL(url);
669
+ const extension = (0, node_path__rspack_import_2.extname)(parsed.pathname || "").replace(/^\./, "").toLowerCase();
670
+ return extension;
671
+ } catch {
672
+ return "";
673
+ }
674
+ }
675
+ function normalizeMimeType(raw) {
676
+ return raw.split(";")[0]?.trim().toLowerCase() || "";
677
+ }
678
+ function mimeTypeFromExtension(extension) {
679
+ switch(extension.replace(/^\./, "").toLowerCase()){
680
+ case "png":
681
+ return "image/png";
682
+ case "jpg":
683
+ case "jpeg":
684
+ return "image/jpeg";
685
+ case "webp":
686
+ return "image/webp";
687
+ case "gif":
688
+ return "image/gif";
689
+ case "bmp":
690
+ return "image/bmp";
691
+ case "tif":
692
+ case "tiff":
693
+ return "image/tiff";
694
+ case "avif":
695
+ return "image/avif";
696
+ case "mp3":
697
+ return "audio/mpeg";
698
+ case "wav":
699
+ return "audio/wav";
700
+ case "ogg":
701
+ return "audio/ogg";
702
+ case "m4a":
703
+ return "audio/mp4";
704
+ case "webm":
705
+ return "video/webm";
706
+ case "mp4":
707
+ return "video/mp4";
708
+ case "mov":
709
+ return "video/quicktime";
710
+ default:
711
+ return null;
712
+ }
713
+ }
714
+ function mimeTypeFromPath(pathname) {
715
+ return mimeTypeFromExtension((0, node_path__rspack_import_2.extname)(pathname).replace(/^\./, ""));
716
+ }
717
+ function extensionFromMimeType(mimeType) {
718
+ switch(normalizeMimeType(mimeType)){
719
+ case "image/jpeg":
720
+ return "jpg";
721
+ case "image/png":
722
+ return "png";
723
+ case "image/webp":
724
+ return "webp";
725
+ case "image/gif":
726
+ return "gif";
727
+ case "image/bmp":
728
+ return "bmp";
729
+ case "image/tiff":
730
+ return "tiff";
731
+ case "image/avif":
732
+ return "avif";
733
+ case "audio/mpeg":
734
+ return "mp3";
735
+ case "audio/wav":
736
+ return "wav";
737
+ case "audio/ogg":
738
+ return "ogg";
739
+ case "audio/mp4":
740
+ return "m4a";
741
+ case "video/mp4":
742
+ return "mp4";
743
+ case "video/webm":
744
+ return "webm";
745
+ case "video/quicktime":
746
+ return "mov";
747
+ default:
748
+ {
749
+ const subtype = normalizeMimeType(mimeType).split("/")[1] || "";
750
+ const sanitized = subtype.replace(/[^a-z0-9]/g, "");
751
+ return sanitized || "bin";
752
+ }
753
+ }
754
+ }
755
+ function sanitizeName(value) {
756
+ const normalized = (value || "").trim().toLowerCase();
757
+ const sanitized = normalized.replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
758
+ return sanitized.slice(0, 80) || "asset";
759
+ }
760
+ function toGatewayFileUrl(pathname) {
761
+ return `/api/fs/file?path=${encodeURIComponent(pathname)}`;
762
+ }
763
+ function buildStructuredImages(media) {
764
+ return media.filter((entry)=>"image" === entry.modality).map((entry)=>({
765
+ path: entry.path,
766
+ url: entry.path ? toGatewayFileUrl(entry.path) : entry.remoteUrl,
767
+ mimeType: entry.mimeType,
768
+ name: entry.name
769
+ }));
770
+ }
771
+ function toToolResult(job) {
772
+ const summary = (0, _fal_summary_js__rspack_import_8.buildFalGenerationSummary)({
773
+ toolName: job.toolName,
774
+ jobId: job.jobId,
775
+ status: job.status,
776
+ modelId: job.modelId,
777
+ reviewState: job.reviewState,
778
+ media: job.media.map((entry)=>({
779
+ modality: entry.modality,
780
+ path: entry.path,
781
+ remoteUrl: entry.remoteUrl,
782
+ mimeType: entry.mimeType
783
+ })),
784
+ error: job.error,
785
+ cwd: FAL_WORKDIR
786
+ });
787
+ const content = [
788
+ {
789
+ type: "text",
790
+ text: summary
791
+ }
792
+ ];
793
+ for (const media of job.media)if ("image" === media.modality && media.path) try {
794
+ const bytes = (0, node_fs__rspack_import_1.readFileSync)(media.path);
795
+ if (bytes.length > 0 && bytes.length <= 5242880) content.push({
796
+ type: "image",
797
+ data: bytes.toString("base64"),
798
+ mimeType: media.mimeType || "image/png"
799
+ });
800
+ } catch {}
801
+ return {
802
+ content,
803
+ structuredContent: {
804
+ jobId: job.jobId,
805
+ requestId: job.requestId,
806
+ toolName: job.toolName,
807
+ modelId: job.modelId,
808
+ modality: job.modality,
809
+ status: job.status,
810
+ reviewRequired: job.reviewRequired,
811
+ reviewState: job.reviewState,
812
+ error: job.error,
813
+ submittedAt: job.submittedAt,
814
+ updatedAt: job.updatedAt,
815
+ queueStatus: job.queueStatus,
816
+ queueStatusUrl: job.queueStatusUrl,
817
+ queueResponseUrl: job.queueResponseUrl,
818
+ queueCancelUrl: job.queueCancelUrl,
819
+ logs: job.logs,
820
+ images: buildStructuredImages(job.media),
821
+ media: job.media.map((entry)=>({
822
+ id: entry.id,
823
+ modality: entry.modality,
824
+ mimeType: entry.mimeType,
825
+ name: entry.name,
826
+ path: entry.path,
827
+ url: entry.path ? toGatewayFileUrl(entry.path) : entry.remoteUrl,
828
+ remoteUrl: entry.remoteUrl,
829
+ sizeBytes: entry.sizeBytes,
830
+ createdAt: entry.createdAt
831
+ }))
832
+ }
833
+ };
834
+ }
835
+ async function fetchWithTimeout(url, init, timeoutMs = FAL_HTTP_TIMEOUT_MS) {
836
+ const controller = new AbortController();
837
+ const timeout = setTimeout(()=>controller.abort(), Math.max(1000, timeoutMs));
838
+ try {
839
+ return await fetch(url, {
840
+ ...init,
841
+ signal: controller.signal
842
+ });
843
+ } finally{
844
+ clearTimeout(timeout);
845
+ }
846
+ }
847
+ function sleep(ms) {
848
+ return new Promise((resolve)=>setTimeout(resolve, ms));
849
+ }
850
+ function errorToString(error) {
851
+ if (error instanceof Error) return error.message;
852
+ if ("string" == typeof error) return error;
853
+ try {
854
+ return JSON.stringify(error);
855
+ } catch {
856
+ return String(error);
857
+ }
858
+ }
859
+ (0, node_fs__rspack_import_1.mkdirSync)(FAL_STATE_DIR, {
860
+ recursive: true
861
+ });
862
+ (0, node_fs__rspack_import_1.mkdirSync)(FAL_OUTPUT_DIR, {
863
+ recursive: true
864
+ });
865
+ (0, node_fs__rspack_import_1.mkdirSync)(JOBS_DIR, {
866
+ recursive: true
867
+ });
868
+ (0, node_fs__rspack_import_1.mkdirSync)(PENDING_DIR, {
869
+ recursive: true
870
+ });
871
+ const transport = new _modelcontextprotocol_sdk_server_stdio_js__rspack_import_5.StdioServerTransport();
872
+ await server.connect(transport);
873
+ console.error([
874
+ "wingman-mcp-fal-ai ready",
875
+ `workdir=${FAL_WORKDIR}`,
876
+ `stateDir=${FAL_STATE_DIR}`,
877
+ `outputDir=${FAL_OUTPUT_DIR}`,
878
+ `reviewMode=${FAL_REVIEW_MODE}`,
879
+ `defaultImageModel=${FAL_MODELS.imageOrTexture}`
880
+ ].join(" | "));
881
+ __rspack_async_done();
882
+ } catch (e) {
883
+ __rspack_async_done(e);
884
+ }
885
+ }, 1);
886
+ },
887
+ "./fal/runtime.js" (module) {
888
+ module.exports = __rspack_external__fal_runtime_js_230694eb;
889
+ },
890
+ "./fal/summary.js" (module) {
891
+ module.exports = __rspack_external__fal_summary_js_64406a32;
892
+ },
893
+ "@fal-ai/client" (module) {
894
+ module.exports = __rspack_external__fal_ai_client_24ca7f48;
895
+ },
896
+ "@modelcontextprotocol/sdk/server/mcp.js" (module) {
897
+ module.exports = __rspack_external__modelcontextprotocol_sdk_server_mcp_js_2c42c5d0;
898
+ },
899
+ "@modelcontextprotocol/sdk/server/stdio.js" (module) {
900
+ module.exports = __rspack_external__modelcontextprotocol_sdk_server_stdio_js_4f861174;
901
+ },
902
+ "node:crypto" (module) {
903
+ module.exports = __rspack_external_node_crypto_9ba42079;
904
+ },
905
+ "node:fs" (module) {
906
+ module.exports = __rspack_external_node_fs_5ea92f0c;
907
+ },
908
+ "node:path" (module) {
909
+ module.exports = __rspack_external_node_path_c5b9b54f;
910
+ },
911
+ zod (module) {
912
+ module.exports = __rspack_external_zod;
913
+ }
914
+ };
915
+ var __webpack_module_cache__ = {};
916
+ function __webpack_require__(moduleId) {
917
+ var cachedModule = __webpack_module_cache__[moduleId];
918
+ if (void 0 !== cachedModule) return cachedModule.exports;
919
+ var module = __webpack_module_cache__[moduleId] = {
920
+ exports: {}
921
+ };
922
+ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
923
+ return module.exports;
924
+ }
925
+ (()=>{
926
+ var hasSymbol = "function" == typeof Symbol;
927
+ var rspackQueues = hasSymbol ? Symbol("rspack queues") : "__rspack_queues";
928
+ var rspackExports = __webpack_require__.aE = hasSymbol ? Symbol("rspack exports") : "__webpack_exports__";
929
+ var rspackError = hasSymbol ? Symbol("rspack error") : "__rspack_error";
930
+ var rspackDone = hasSymbol ? Symbol("rspack done") : "__rspack_done";
931
+ var rspackDefer = __webpack_require__.zS = hasSymbol ? Symbol("rspack defer") : "__rspack_defer";
932
+ var resolveQueue = (queue)=>{
933
+ if (queue && queue.d < 1) {
934
+ queue.d = 1;
935
+ queue.forEach((fn)=>fn.r--);
936
+ queue.forEach((fn)=>fn.r-- ? fn.r++ : fn());
937
+ }
938
+ };
939
+ var wrapDeps = (deps)=>deps.map((dep)=>{
940
+ if (null !== dep && "object" == typeof dep) {
941
+ if (!dep[rspackQueues] && dep[rspackDefer]) {
942
+ var asyncDeps = dep[rspackDefer];
943
+ var hasUnresolvedAsyncSubgraph = asyncDeps.some((id)=>{
944
+ var cache = __webpack_module_cache__[id];
945
+ return !cache || false === cache[rspackDone];
946
+ });
947
+ if (!hasUnresolvedAsyncSubgraph) return dep;
948
+ var d = dep;
949
+ dep = {
950
+ then (callback) {
951
+ Promise.all(asyncDeps.map(__webpack_require__)).then(()=>callback(d));
952
+ }
953
+ };
954
+ }
955
+ if (dep[rspackQueues]) return dep;
956
+ if (dep.then) {
957
+ var queue = [];
958
+ queue.d = 0;
959
+ dep.then((r)=>{
960
+ obj[rspackExports] = r;
961
+ resolveQueue(queue);
962
+ }, (e)=>{
963
+ obj[rspackError] = e;
964
+ resolveQueue(queue);
965
+ });
966
+ var obj = {};
967
+ obj[rspackDefer] = false;
968
+ obj[rspackQueues] = (fn)=>fn(queue);
969
+ return obj;
970
+ }
971
+ }
972
+ var ret = {};
973
+ ret[rspackQueues] = ()=>{};
974
+ ret[rspackExports] = dep;
975
+ return ret;
976
+ });
977
+ __webpack_require__.a = (module, body, hasAwait)=>{
978
+ var queue;
979
+ hasAwait && ((queue = []).d = -1);
980
+ var depQueues = new Set();
981
+ var exports = module.exports;
982
+ var currentDeps;
983
+ var outerResolve;
984
+ var reject;
985
+ var promise = new Promise((resolve, rej)=>{
986
+ reject = rej;
987
+ outerResolve = resolve;
988
+ });
989
+ promise[rspackExports] = exports;
990
+ promise[rspackQueues] = (fn)=>{
991
+ queue && fn(queue), depQueues.forEach(fn), promise["catch"](()=>{});
992
+ };
993
+ module.exports = promise;
994
+ var handle = (deps)=>{
995
+ currentDeps = wrapDeps(deps);
996
+ var fn;
997
+ var getResult = ()=>currentDeps.map((d)=>{
998
+ if (d[rspackDefer]) return d;
999
+ if (d[rspackError]) throw d[rspackError];
1000
+ return d[rspackExports];
1001
+ });
1002
+ var promise = new Promise((resolve)=>{
1003
+ fn = ()=>resolve(getResult);
1004
+ fn.r = 0;
1005
+ var fnQueue = (q)=>q !== queue && !depQueues.has(q) && (depQueues.add(q), q && !q.d && (fn.r++, q.push(fn)));
1006
+ currentDeps.map((dep)=>dep[rspackDefer] || dep[rspackQueues](fnQueue));
1007
+ });
1008
+ return fn.r ? promise : getResult();
1009
+ };
1010
+ var done = (err)=>(err ? reject(promise[rspackError] = err) : outerResolve(exports), resolveQueue(queue), promise[rspackDone] = true);
1011
+ body(handle, done);
1012
+ queue && queue.d < 0 && (queue.d = 0);
1013
+ };
1014
+ })();
1015
+ (()=>{
1016
+ __webpack_require__.r = (exports)=>{
1017
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports, Symbol.toStringTag, {
1018
+ value: 'Module'
1019
+ });
1020
+ Object.defineProperty(exports, '__esModule', {
1021
+ value: true
1022
+ });
1023
+ };
1024
+ })();
1025
+ __webpack_require__("./src/tools/mcp-fal-ai.ts");